Comparing version 4.0.1 to 4.0.2
@@ -0,1 +1,10 @@ | ||
/** | ||
* This functions is used to throw when query or source is not defined as well | ||
* as normalizing and lower casing the input strings. | ||
* | ||
* @param query The fuzzy query string | ||
* @param source The fuzzy source string | ||
* @param opts An options object that can contains `caseSensitive` | ||
* @returns The reshaped query string and the reshaped source string. | ||
*/ | ||
var prepare = function (query, source, opts) { | ||
@@ -23,2 +32,11 @@ if (typeof query !== 'string') { | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. This will returns | ||
* a boolean. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[TestOptions]] | ||
* @returns Wether or not the query fuzzy matches the source | ||
*/ | ||
var test = function (query, source, opts) { | ||
@@ -54,2 +72,11 @@ if (opts === void 0) { opts = {}; } | ||
/** | ||
* Appends to an actual list of ranges a new match. This will only increment | ||
* the last [[MatchRange]] if the actual match and the last match were | ||
* siblings. | ||
* | ||
* @param ranges The previous ranges array | ||
* @param sourcePos The position in source that matched | ||
* @returns The new ranges array | ||
*/ | ||
var pushRange = function (ranges, sourcePos) { | ||
@@ -70,2 +97,14 @@ var lastRange = ranges[ranges.length - 1]; | ||
/** | ||
* Increments a context's score based on the context's values | ||
* This default strategy is based on | ||
* https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/ | ||
* A fuzzy matching scoring function should most of the time push a big score | ||
* when matching a leading letter (ie. a letter that is capital or comes | ||
* after a separator). | ||
* | ||
* @param previousContext The last context given to pushScore | ||
* @param context The actual context | ||
* @returns The new score | ||
*/ | ||
var pushScore = function (previousContext, context) { | ||
@@ -88,4 +127,22 @@ if (!context) { | ||
/** | ||
* Returns a normalized version of the string. This comes from | ||
* https://stackoverflow.com/a/37511463. It converts accented characters into | ||
* two UTF-8 characters (ie. `è` becomes e and `) and strip the accents. | ||
* | ||
* @param str The input string | ||
* @returns The input string without accents | ||
*/ | ||
var toLatin = function (str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); }; | ||
/** | ||
* Returns true when the character is leading; ie. when it's a capital or | ||
* when it's following a separator character. You might also want to test if | ||
* the character comes from an alphabet as you wouldn't want to consider a | ||
* space as a leading character. | ||
* | ||
* @param prevChar The character that appears before `char` | ||
* @param char The actual character you want to test | ||
* @returns Wether or not the character is leading | ||
*/ | ||
var isLeading = function (prevChar, char) { | ||
@@ -102,2 +159,13 @@ var precededBySeparator = prevChar === '-' || | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. Called without | ||
* options would be strictly equivalent as `{ match: test(query, source) }` but | ||
* less optimized. You should use `withScore` or `withRanges` options to get | ||
* additional informations about the match. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[MatchOptions]] | ||
* @returns An object as defined by [[MatchResult]] | ||
*/ | ||
var match = function (query, source, opts) { | ||
@@ -199,5 +267,18 @@ if (opts === void 0) { opts = { withScore: true, strategy: pushScore }; } | ||
/** | ||
* @ignore | ||
*/ | ||
var get = function (source, accessor) { | ||
return typeof accessor === 'function' ? accessor(source) : source; | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.filter` callback as it | ||
* will return true or false when passing it a source string. The only | ||
* difference with `test` is that you can use it with an object, as long as you | ||
* give a `sourceAccessor` in options. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[FilterOptions]] | ||
* @returns A function that you can pass into `Array.prototype.filter` | ||
*/ | ||
var filter = function (query, options) { | ||
@@ -209,5 +290,16 @@ if (options === void 0) { options = {}; } | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.sort` callback as it | ||
* will return `-1`/`0`/`1` when passing it two source strings. It is based on | ||
* match with default options set (`withRanges` to false and `withScore` to | ||
* true). You can also use `sourceAccessor` if you intend to sort over an array | ||
* of objects and `idAccessor` to optimize the performances. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[SortOptions]] | ||
* @returns A function that you can pass into `Array.prototype.sort` | ||
*/ | ||
var sort = function (query, options) { | ||
if (options === void 0) { options = {}; } | ||
var matchOptions = __assign({}, options, { withScore: true }); | ||
var matchOptions = __assign({}, options, { withRanges: false, withScore: true }); | ||
if (!options.idAccessor) { | ||
@@ -244,2 +336,5 @@ return function (leftSource, rightSource) { | ||
/** | ||
* @ignore | ||
*/ | ||
var insertAt = function (input, index, patch) { | ||
@@ -249,2 +344,10 @@ if (patch === void 0) { patch = ''; } | ||
}; | ||
/** | ||
* Surround parts of the string that matched with prefix and suffix. | ||
* Useful to emphasize the parts that matched. | ||
* | ||
* @param source The input source | ||
* @param options Options as defined by [[SurroundOptions]] | ||
* @returns The input source with matching ranges surrounded by prefix and suffix | ||
*/ | ||
var surround = function (source, options) { | ||
@@ -257,3 +360,3 @@ if (typeof source !== 'string') { | ||
} | ||
if (!options.result.ranges || !options.result.ranges.length) { | ||
if (!options || !options.result || !options.result.ranges || !options.result.ranges.length) { | ||
return source; | ||
@@ -260,0 +363,0 @@ } |
@@ -7,2 +7,11 @@ (function (global, factory) { | ||
/** | ||
* This functions is used to throw when query or source is not defined as well | ||
* as normalizing and lower casing the input strings. | ||
* | ||
* @param query The fuzzy query string | ||
* @param source The fuzzy source string | ||
* @param opts An options object that can contains `caseSensitive` | ||
* @returns The reshaped query string and the reshaped source string. | ||
*/ | ||
var prepare = function (query, source, opts) { | ||
@@ -30,2 +39,11 @@ if (typeof query !== 'string') { | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. This will returns | ||
* a boolean. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[TestOptions]] | ||
* @returns Wether or not the query fuzzy matches the source | ||
*/ | ||
var test = function (query, source, opts) { | ||
@@ -61,2 +79,11 @@ if (opts === void 0) { opts = {}; } | ||
/** | ||
* Appends to an actual list of ranges a new match. This will only increment | ||
* the last [[MatchRange]] if the actual match and the last match were | ||
* siblings. | ||
* | ||
* @param ranges The previous ranges array | ||
* @param sourcePos The position in source that matched | ||
* @returns The new ranges array | ||
*/ | ||
var pushRange = function (ranges, sourcePos) { | ||
@@ -77,2 +104,14 @@ var lastRange = ranges[ranges.length - 1]; | ||
/** | ||
* Increments a context's score based on the context's values | ||
* This default strategy is based on | ||
* https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/ | ||
* A fuzzy matching scoring function should most of the time push a big score | ||
* when matching a leading letter (ie. a letter that is capital or comes | ||
* after a separator). | ||
* | ||
* @param previousContext The last context given to pushScore | ||
* @param context The actual context | ||
* @returns The new score | ||
*/ | ||
var pushScore = function (previousContext, context) { | ||
@@ -95,4 +134,22 @@ if (!context) { | ||
/** | ||
* Returns a normalized version of the string. This comes from | ||
* https://stackoverflow.com/a/37511463. It converts accented characters into | ||
* two UTF-8 characters (ie. `è` becomes e and `) and strip the accents. | ||
* | ||
* @param str The input string | ||
* @returns The input string without accents | ||
*/ | ||
var toLatin = function (str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); }; | ||
/** | ||
* Returns true when the character is leading; ie. when it's a capital or | ||
* when it's following a separator character. You might also want to test if | ||
* the character comes from an alphabet as you wouldn't want to consider a | ||
* space as a leading character. | ||
* | ||
* @param prevChar The character that appears before `char` | ||
* @param char The actual character you want to test | ||
* @returns Wether or not the character is leading | ||
*/ | ||
var isLeading = function (prevChar, char) { | ||
@@ -109,2 +166,13 @@ var precededBySeparator = prevChar === '-' || | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. Called without | ||
* options would be strictly equivalent as `{ match: test(query, source) }` but | ||
* less optimized. You should use `withScore` or `withRanges` options to get | ||
* additional informations about the match. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[MatchOptions]] | ||
* @returns An object as defined by [[MatchResult]] | ||
*/ | ||
var match = function (query, source, opts) { | ||
@@ -206,5 +274,18 @@ if (opts === void 0) { opts = { withScore: true, strategy: pushScore }; } | ||
/** | ||
* @ignore | ||
*/ | ||
var get = function (source, accessor) { | ||
return typeof accessor === 'function' ? accessor(source) : source; | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.filter` callback as it | ||
* will return true or false when passing it a source string. The only | ||
* difference with `test` is that you can use it with an object, as long as you | ||
* give a `sourceAccessor` in options. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[FilterOptions]] | ||
* @returns A function that you can pass into `Array.prototype.filter` | ||
*/ | ||
var filter = function (query, options) { | ||
@@ -216,5 +297,16 @@ if (options === void 0) { options = {}; } | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.sort` callback as it | ||
* will return `-1`/`0`/`1` when passing it two source strings. It is based on | ||
* match with default options set (`withRanges` to false and `withScore` to | ||
* true). You can also use `sourceAccessor` if you intend to sort over an array | ||
* of objects and `idAccessor` to optimize the performances. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[SortOptions]] | ||
* @returns A function that you can pass into `Array.prototype.sort` | ||
*/ | ||
var sort = function (query, options) { | ||
if (options === void 0) { options = {}; } | ||
var matchOptions = __assign({}, options, { withScore: true }); | ||
var matchOptions = __assign({}, options, { withRanges: false, withScore: true }); | ||
if (!options.idAccessor) { | ||
@@ -251,2 +343,5 @@ return function (leftSource, rightSource) { | ||
/** | ||
* @ignore | ||
*/ | ||
var insertAt = function (input, index, patch) { | ||
@@ -256,2 +351,10 @@ if (patch === void 0) { patch = ''; } | ||
}; | ||
/** | ||
* Surround parts of the string that matched with prefix and suffix. | ||
* Useful to emphasize the parts that matched. | ||
* | ||
* @param source The input source | ||
* @param options Options as defined by [[SurroundOptions]] | ||
* @returns The input source with matching ranges surrounded by prefix and suffix | ||
*/ | ||
var surround = function (source, options) { | ||
@@ -264,3 +367,3 @@ if (typeof source !== 'string') { | ||
} | ||
if (!options.result.ranges || !options.result.ranges.length) { | ||
if (!options || !options.result || !options.result.ranges || !options.result.ranges.length) { | ||
return source; | ||
@@ -267,0 +370,0 @@ } |
@@ -16,5 +16,18 @@ "use strict"; | ||
var match_1 = require("./match"); | ||
/** | ||
* @ignore | ||
*/ | ||
var get = function (source, accessor) { | ||
return typeof accessor === 'function' ? accessor(source) : source; | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.filter` callback as it | ||
* will return true or false when passing it a source string. The only | ||
* difference with `test` is that you can use it with an object, as long as you | ||
* give a `sourceAccessor` in options. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[FilterOptions]] | ||
* @returns A function that you can pass into `Array.prototype.filter` | ||
*/ | ||
exports.filter = function (query, options) { | ||
@@ -26,5 +39,16 @@ if (options === void 0) { options = {}; } | ||
}; | ||
/** | ||
* This array helper can be used as an `Array.prototype.sort` callback as it | ||
* will return `-1`/`0`/`1` when passing it two source strings. It is based on | ||
* match with default options set (`withRanges` to false and `withScore` to | ||
* true). You can also use `sourceAccessor` if you intend to sort over an array | ||
* of objects and `idAccessor` to optimize the performances. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[SortOptions]] | ||
* @returns A function that you can pass into `Array.prototype.sort` | ||
*/ | ||
exports.sort = function (query, options) { | ||
if (options === void 0) { options = {}; } | ||
var matchOptions = __assign({}, options, { withScore: true }); | ||
var matchOptions = __assign({}, options, { withRanges: false, withScore: true }); | ||
if (!options.idAccessor) { | ||
@@ -31,0 +55,0 @@ return function (leftSource, rightSource) { |
@@ -7,2 +7,13 @@ "use strict"; | ||
var isLeading_1 = require("./utils/isLeading"); | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. Called without | ||
* options would be strictly equivalent as `{ match: test(query, source) }` but | ||
* less optimized. You should use `withScore` or `withRanges` options to get | ||
* additional informations about the match. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[MatchOptions]] | ||
* @returns An object as defined by [[MatchResult]] | ||
*/ | ||
exports.match = function (query, source, opts) { | ||
@@ -9,0 +20,0 @@ if (opts === void 0) { opts = { withScore: true, strategy: defaultStrategy_1.pushScore }; } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Increments a context's score based on the context's values | ||
* This default strategy is based on | ||
* https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/ | ||
* A fuzzy matching scoring function should most of the time push a big score | ||
* when matching a leading letter (ie. a letter that is capital or comes | ||
* after a separator). | ||
* | ||
* @param previousContext The last context given to pushScore | ||
* @param context The actual context | ||
* @returns The new score | ||
*/ | ||
exports.pushScore = function (previousContext, context) { | ||
@@ -4,0 +16,0 @@ if (!context) { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* @ignore | ||
*/ | ||
var insertAt = function (input, index, patch) { | ||
@@ -7,2 +10,10 @@ if (patch === void 0) { patch = ''; } | ||
}; | ||
/** | ||
* Surround parts of the string that matched with prefix and suffix. | ||
* Useful to emphasize the parts that matched. | ||
* | ||
* @param source The input source | ||
* @param options Options as defined by [[SurroundOptions]] | ||
* @returns The input source with matching ranges surrounded by prefix and suffix | ||
*/ | ||
exports.surround = function (source, options) { | ||
@@ -15,3 +26,3 @@ if (typeof source !== 'string') { | ||
} | ||
if (!options.result.ranges || !options.result.ranges.length) { | ||
if (!options || !options.result || !options.result.ranges || !options.result.ranges.length) { | ||
return source; | ||
@@ -18,0 +29,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var prepare_1 = require("./utils/prepare"); | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. This will returns | ||
* a boolean. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[TestOptions]] | ||
* @returns Wether or not the query fuzzy matches the source | ||
*/ | ||
exports.test = function (query, source, opts) { | ||
@@ -5,0 +14,0 @@ if (opts === void 0) { opts = {}; } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var toLatin_1 = require("./toLatin"); | ||
/** | ||
* Returns true when the character is leading; ie. when it's a capital or | ||
* when it's following a separator character. You might also want to test if | ||
* the character comes from an alphabet as you wouldn't want to consider a | ||
* space as a leading character. | ||
* | ||
* @param prevChar The character that appears before `char` | ||
* @param char The actual character you want to test | ||
* @returns Wether or not the character is leading | ||
*/ | ||
exports.isLeading = function (prevChar, char) { | ||
@@ -5,0 +15,0 @@ var precededBySeparator = prevChar === '-' || |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* This functions is used to throw when query or source is not defined as well | ||
* as normalizing and lower casing the input strings. | ||
* | ||
* @param query The fuzzy query string | ||
* @param source The fuzzy source string | ||
* @param opts An options object that can contains `caseSensitive` | ||
* @returns The reshaped query string and the reshaped source string. | ||
*/ | ||
exports.prepare = function (query, source, opts) { | ||
@@ -4,0 +13,0 @@ if (typeof query !== 'string') { |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Appends to an actual list of ranges a new match. This will only increment | ||
* the last [[MatchRange]] if the actual match and the last match were | ||
* siblings. | ||
* | ||
* @param ranges The previous ranges array | ||
* @param sourcePos The position in source that matched | ||
* @returns The new ranges array | ||
*/ | ||
exports.pushRange = function (ranges, sourcePos) { | ||
@@ -4,0 +13,0 @@ var lastRange = ranges[ranges.length - 1]; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* Returns a normalized version of the string. This comes from | ||
* https://stackoverflow.com/a/37511463. It converts accented characters into | ||
* two UTF-8 characters (ie. `è` becomes e and `) and strip the accents. | ||
* | ||
* @param str The input string | ||
* @returns The input string without accents | ||
*/ | ||
exports.toLatin = function (str) { return str.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); }; | ||
//# sourceMappingURL=toLatin.js.map |
import { TestOptions } from './test'; | ||
import { MatchOptions } from './match'; | ||
declare type Accessor = (source: any) => string; | ||
export declare type FilterOptions = TestOptions & { | ||
/** | ||
* This represents an accessor as used with `sourceAccessor` and `idAccessor`. | ||
*/ | ||
export declare type Accessor = (source: any) => string; | ||
/** | ||
* This represents filter util options. It is based on [[TestOptions]] (as | ||
* filter is using test) and extends it with `sourceAccessor` when you filter | ||
* over an object array. | ||
*/ | ||
export interface FilterOptions extends TestOptions { | ||
sourceAccessor?: Accessor; | ||
}; | ||
export declare type SortOptions = MatchOptions & { | ||
} | ||
/** | ||
* This represents sort util options. It is based on [[MatchOptions]] (as sort | ||
* is using match) and extends it with `sourceAccessor` when you filter over an | ||
* object array and `idAccessor` when you want to optimize the sort with | ||
* memoization. | ||
*/ | ||
export interface SortOptions extends MatchOptions { | ||
sourceAccessor?: Accessor; | ||
idAccessor?: Accessor; | ||
}; | ||
} | ||
/** | ||
* This array helper can be used as an `Array.prototype.filter` callback as it | ||
* will return true or false when passing it a source string. The only | ||
* difference with `test` is that you can use it with an object, as long as you | ||
* give a `sourceAccessor` in options. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[FilterOptions]] | ||
* @returns A function that you can pass into `Array.prototype.filter` | ||
*/ | ||
export declare const filter: (query: string, options?: FilterOptions) => (source: any) => boolean; | ||
/** | ||
* This array helper can be used as an `Array.prototype.sort` callback as it | ||
* will return `-1`/`0`/`1` when passing it two source strings. It is based on | ||
* match with default options set (`withRanges` to false and `withScore` to | ||
* true). You can also use `sourceAccessor` if you intend to sort over an array | ||
* of objects and `idAccessor` to optimize the performances. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[SortOptions]] | ||
* @returns A function that you can pass into `Array.prototype.sort` | ||
*/ | ||
export declare const sort: (query: string, options?: SortOptions) => (leftSource: any, rightSource: any) => 0 | 1 | -1; | ||
export {}; |
export { test, TestOptions } from './test'; | ||
export { match, MatchOptions, MatchResult, MatchRange, ScoreContext, ScoreStrategy } from './match'; | ||
export { filter, sort, FilterOptions, SortOptions } from './array'; | ||
export { filter, sort, FilterOptions, SortOptions, Accessor } from './array'; | ||
export { surround, SurroundOptions } from './surround'; |
import { TestOptions } from './test'; | ||
export declare type MatchOptions = TestOptions & { | ||
/** | ||
* This represents match options. It is based on [[TestOptions]] but allows | ||
* scores and ranges to be returned as well. | ||
*/ | ||
export interface MatchOptions extends TestOptions { | ||
strategy?: ScoreStrategy; | ||
withRanges?: boolean; | ||
withScore?: boolean; | ||
}; | ||
export declare type MatchResult = { | ||
} | ||
/** | ||
* This represents match result as returned by the match function. It will | ||
* always contains a `match` boolean (which would be equivalent to `test` | ||
* function). If you set `withRanges` to true, match will return a `ranges` | ||
* array, and if you set `withScore` to true, match will return a `score` | ||
* number. | ||
*/ | ||
export interface MatchResult { | ||
match: boolean; | ||
score?: number; | ||
ranges?: Array<MatchRange>; | ||
}; | ||
export declare type MatchRange = { | ||
ranges?: MatchRange[]; | ||
} | ||
/** | ||
* This represents a Range that you can get if you call match with `withRanges` | ||
* set to true. It is composed of indexes of the source string that are matched | ||
* by the input string. | ||
*/ | ||
export interface MatchRange { | ||
start: number; | ||
stop: number; | ||
}; | ||
export declare type ScoreContext = null | { | ||
} | ||
/** | ||
* This represents a score context that the scoring function will use to | ||
* compute the new score. It must include: | ||
* - `currentScore` the actual score (ie. the result of the last `pushScore` call or 0) | ||
* - `character` the actual source character. It must not be reshaped (ie. lowercased or normalized) | ||
* - `match` wether or not the actual source character is matched by the query | ||
* - `leading` wether or not the actual source character is a leading character (as returned by the `isLeading` function) | ||
*/ | ||
export interface ScoreContext { | ||
currentScore: number; | ||
@@ -21,4 +45,23 @@ character: string; | ||
leading: boolean; | ||
}; | ||
export declare type ScoreStrategy = (previousContext: ScoreContext, context: ScoreContext) => number; | ||
} | ||
/** | ||
* This represents the signature of the `pushScore` function. It requires the | ||
* previous context as long as the actual one (as we want to check for | ||
* concurrent matches), and returns the new score as a number. | ||
* | ||
* The scoring function is not returning a number from 0 to 1 but a whole | ||
* natural number. | ||
*/ | ||
export declare type ScoreStrategy = (previousContext: ScoreContext | null, context: ScoreContext) => number; | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. Called without | ||
* options would be strictly equivalent as `{ match: test(query, source) }` but | ||
* less optimized. You should use `withScore` or `withRanges` options to get | ||
* additional informations about the match. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[MatchOptions]] | ||
* @returns An object as defined by [[MatchResult]] | ||
*/ | ||
export declare const match: (query: string, source: string, opts?: MatchOptions) => MatchResult; |
import { ScoreContext } from '../match'; | ||
export declare const pushScore: (previousContext: ScoreContext, context: ScoreContext) => number; | ||
/** | ||
* Increments a context's score based on the context's values | ||
* This default strategy is based on | ||
* https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/ | ||
* A fuzzy matching scoring function should most of the time push a big score | ||
* when matching a leading letter (ie. a letter that is capital or comes | ||
* after a separator). | ||
* | ||
* @param previousContext The last context given to pushScore | ||
* @param context The actual context | ||
* @returns The new score | ||
*/ | ||
export declare const pushScore: (previousContext: ScoreContext | null, context: ScoreContext) => number; |
import { MatchRange } from './match'; | ||
export declare type SurroundOptions = { | ||
/** | ||
* This represents the options you can pass to surround. | ||
* It requires at least `result` (that you'll get in `match` with the | ||
* `withRanges` option set to true). You can give a prefix and a suffix, which | ||
* will surround every part of the source string that matched the query. | ||
*/ | ||
export interface SurroundOptions { | ||
result: { | ||
ranges: Array<MatchRange>; | ||
ranges: MatchRange[]; | ||
}; | ||
prefix?: string; | ||
suffix?: string; | ||
}; | ||
} | ||
/** | ||
* Surround parts of the string that matched with prefix and suffix. | ||
* Useful to emphasize the parts that matched. | ||
* | ||
* @param source The input source | ||
* @param options Options as defined by [[SurroundOptions]] | ||
* @returns The input source with matching ranges surrounded by prefix and suffix | ||
*/ | ||
export declare const surround: (source: string, options: SurroundOptions) => string; |
@@ -1,4 +0,17 @@ | ||
export declare type TestOptions = { | ||
/** | ||
* This represents test options. You can specify if the source string should be | ||
* lower cased or not (wether you want the test to be case-sensitive or not). | ||
*/ | ||
export interface TestOptions { | ||
caseSensitive?: boolean; | ||
}; | ||
} | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. This will returns | ||
* a boolean. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[TestOptions]] | ||
* @returns Wether or not the query fuzzy matches the source | ||
*/ | ||
export declare const test: (query: string, source: string, opts?: TestOptions) => boolean; |
@@ -0,1 +1,11 @@ | ||
/** | ||
* Returns true when the character is leading; ie. when it's a capital or | ||
* when it's following a separator character. You might also want to test if | ||
* the character comes from an alphabet as you wouldn't want to consider a | ||
* space as a leading character. | ||
* | ||
* @param prevChar The character that appears before `char` | ||
* @param char The actual character you want to test | ||
* @returns Wether or not the character is leading | ||
*/ | ||
export declare const isLeading: (prevChar: string, char: string) => boolean; |
@@ -1,4 +0,11 @@ | ||
export declare type PrepareOptions = { | ||
caseSensitive?: boolean; | ||
}; | ||
export declare const prepare: (query: string, source: string, opts: PrepareOptions) => string[]; | ||
import { TestOptions } from '../test'; | ||
/** | ||
* This functions is used to throw when query or source is not defined as well | ||
* as normalizing and lower casing the input strings. | ||
* | ||
* @param query The fuzzy query string | ||
* @param source The fuzzy source string | ||
* @param opts An options object that can contains `caseSensitive` | ||
* @returns The reshaped query string and the reshaped source string. | ||
*/ | ||
export declare const prepare: (query: string, source: string, opts: TestOptions) => string[]; |
import { MatchRange } from '../match'; | ||
/** | ||
* Appends to an actual list of ranges a new match. This will only increment | ||
* the last [[MatchRange]] if the actual match and the last match were | ||
* siblings. | ||
* | ||
* @param ranges The previous ranges array | ||
* @param sourcePos The position in source that matched | ||
* @returns The new ranges array | ||
*/ | ||
export declare const pushRange: (ranges: MatchRange[], sourcePos: number) => MatchRange[]; |
@@ -0,1 +1,9 @@ | ||
/** | ||
* Returns a normalized version of the string. This comes from | ||
* https://stackoverflow.com/a/37511463. It converts accented characters into | ||
* two UTF-8 characters (ie. `è` becomes e and `) and strip the accents. | ||
* | ||
* @param str The input string | ||
* @returns The input string without accents | ||
*/ | ||
export declare const toLatin: (str: string) => string; |
{ | ||
"name": "fuzzyjs", | ||
"version": "4.0.1", | ||
"version": "4.0.2", | ||
"description": "Fuzzy matching in Javascript", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -62,3 +62,3 @@ # fuzzyjs | ||
score?: number | ||
ranges?: Array<MatchRange> | ||
ranges?: MatchRange[] | ||
} | ||
@@ -94,3 +94,3 @@ ``` | ||
result: { | ||
ranges: Array<MatchRange> | ||
ranges: MatchRange[] | ||
} | ||
@@ -97,0 +97,0 @@ prefix?: string // (default: '') |
import { test, TestOptions } from './test' | ||
import { match, ScoreStrategy, MatchOptions } from './match' | ||
type Accessor = (source: any) => string | ||
/** | ||
* This represents an accessor as used with `sourceAccessor` and `idAccessor`. | ||
*/ | ||
export type Accessor = (source: any) => string | ||
export type FilterOptions = TestOptions & { | ||
/** | ||
* This represents filter util options. It is based on [[TestOptions]] (as | ||
* filter is using test) and extends it with `sourceAccessor` when you filter | ||
* over an object array. | ||
*/ | ||
export interface FilterOptions extends TestOptions { | ||
sourceAccessor?: Accessor | ||
} | ||
export type SortOptions = MatchOptions & { | ||
/** | ||
* This represents sort util options. It is based on [[MatchOptions]] (as sort | ||
* is using match) and extends it with `sourceAccessor` when you filter over an | ||
* object array and `idAccessor` when you want to optimize the sort with | ||
* memoization. | ||
*/ | ||
export interface SortOptions extends MatchOptions { | ||
sourceAccessor?: Accessor | ||
@@ -15,2 +29,5 @@ idAccessor?: Accessor | ||
/** | ||
* @ignore | ||
*/ | ||
const get = (source: any, accessor?: Accessor): string => { | ||
@@ -20,8 +37,30 @@ return typeof accessor === 'function' ? accessor(source) : source | ||
/** | ||
* This array helper can be used as an `Array.prototype.filter` callback as it | ||
* will return true or false when passing it a source string. The only | ||
* difference with `test` is that you can use it with an object, as long as you | ||
* give a `sourceAccessor` in options. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[FilterOptions]] | ||
* @returns A function that you can pass into `Array.prototype.filter` | ||
*/ | ||
export const filter = (query: string, options: FilterOptions = {}) => (source: any) => | ||
test(query, get(source, options.sourceAccessor), options) | ||
/** | ||
* This array helper can be used as an `Array.prototype.sort` callback as it | ||
* will return `-1`/`0`/`1` when passing it two source strings. It is based on | ||
* match with default options set (`withRanges` to false and `withScore` to | ||
* true). You can also use `sourceAccessor` if you intend to sort over an array | ||
* of objects and `idAccessor` to optimize the performances. | ||
* | ||
* @param query The input query | ||
* @param options The options as defined in [[SortOptions]] | ||
* @returns A function that you can pass into `Array.prototype.sort` | ||
*/ | ||
export const sort = (query: string, options: SortOptions = {}) => { | ||
const matchOptions: MatchOptions = { | ||
...options, | ||
withRanges: false, | ||
withScore: true | ||
@@ -28,0 +67,0 @@ } |
export { test, TestOptions } from './test' | ||
export { match, MatchOptions, MatchResult, MatchRange, ScoreContext, ScoreStrategy } from './match' | ||
export { filter, sort, FilterOptions, SortOptions } from './array' | ||
export { filter, sort, FilterOptions, SortOptions, Accessor } from './array' | ||
export { surround, SurroundOptions } from './surround' |
@@ -7,3 +7,7 @@ import { TestOptions } from './test' | ||
export type MatchOptions = TestOptions & { | ||
/** | ||
* This represents match options. It is based on [[TestOptions]] but allows | ||
* scores and ranges to be returned as well. | ||
*/ | ||
export interface MatchOptions extends TestOptions { | ||
strategy?: ScoreStrategy | ||
@@ -14,9 +18,21 @@ withRanges?: boolean | ||
export type MatchResult = { | ||
/** | ||
* This represents match result as returned by the match function. It will | ||
* always contains a `match` boolean (which would be equivalent to `test` | ||
* function). If you set `withRanges` to true, match will return a `ranges` | ||
* array, and if you set `withScore` to true, match will return a `score` | ||
* number. | ||
*/ | ||
export interface MatchResult { | ||
match: boolean | ||
score?: number | ||
ranges?: Array<MatchRange> | ||
ranges?: MatchRange[] | ||
} | ||
export type MatchRange = { | ||
/** | ||
* This represents a Range that you can get if you call match with `withRanges` | ||
* set to true. It is composed of indexes of the source string that are matched | ||
* by the input string. | ||
*/ | ||
export interface MatchRange { | ||
start: number | ||
@@ -26,3 +42,11 @@ stop: number | ||
export type ScoreContext = null | { | ||
/** | ||
* This represents a score context that the scoring function will use to | ||
* compute the new score. It must include: | ||
* - `currentScore` the actual score (ie. the result of the last `pushScore` call or 0) | ||
* - `character` the actual source character. It must not be reshaped (ie. lowercased or normalized) | ||
* - `match` wether or not the actual source character is matched by the query | ||
* - `leading` wether or not the actual source character is a leading character (as returned by the `isLeading` function) | ||
*/ | ||
export interface ScoreContext { | ||
currentScore: number | ||
@@ -34,4 +58,23 @@ character: string | ||
export type ScoreStrategy = (previousContext: ScoreContext, context: ScoreContext) => number | ||
/** | ||
* This represents the signature of the `pushScore` function. It requires the | ||
* previous context as long as the actual one (as we want to check for | ||
* concurrent matches), and returns the new score as a number. | ||
* | ||
* The scoring function is not returning a number from 0 to 1 but a whole | ||
* natural number. | ||
*/ | ||
export type ScoreStrategy = (previousContext: ScoreContext | null, context: ScoreContext) => number | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. Called without | ||
* options would be strictly equivalent as `{ match: test(query, source) }` but | ||
* less optimized. You should use `withScore` or `withRanges` options to get | ||
* additional informations about the match. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[MatchOptions]] | ||
* @returns An object as defined by [[MatchResult]] | ||
*/ | ||
export const match = ( | ||
@@ -68,4 +111,4 @@ query: string, | ||
let score = 0 | ||
let lastContext: ScoreContext = null | ||
let ranges: Array<MatchRange> = [] | ||
let lastContext: ScoreContext | null = null | ||
let ranges: MatchRange[] = [] | ||
@@ -72,0 +115,0 @@ // loop on source string |
import { ScoreContext } from '../match' | ||
export const pushScore = (previousContext: ScoreContext, context: ScoreContext) => { | ||
/** | ||
* Increments a context's score based on the context's values | ||
* This default strategy is based on | ||
* https://www.forrestthewoods.com/blog/reverse_engineering_sublime_texts_fuzzy_match/ | ||
* A fuzzy matching scoring function should most of the time push a big score | ||
* when matching a leading letter (ie. a letter that is capital or comes | ||
* after a separator). | ||
* | ||
* @param previousContext The last context given to pushScore | ||
* @param context The actual context | ||
* @returns The new score | ||
*/ | ||
export const pushScore = (previousContext: ScoreContext | null, context: ScoreContext) => { | ||
if (!context) { | ||
@@ -5,0 +17,0 @@ throw new TypeError('Expecting context to be defined') |
import { MatchRange } from './match' | ||
export type SurroundOptions = { | ||
/** | ||
* This represents the options you can pass to surround. | ||
* It requires at least `result` (that you'll get in `match` with the | ||
* `withRanges` option set to true). You can give a prefix and a suffix, which | ||
* will surround every part of the source string that matched the query. | ||
*/ | ||
export interface SurroundOptions { | ||
result: { | ||
ranges: Array<MatchRange> | ||
ranges: MatchRange[] | ||
} | ||
@@ -11,5 +17,16 @@ prefix?: string | ||
/** | ||
* @ignore | ||
*/ | ||
const insertAt = (input: string, index: number, patch: string = '') => | ||
input.slice(0, index) + patch + input.slice(index) | ||
/** | ||
* Surround parts of the string that matched with prefix and suffix. | ||
* Useful to emphasize the parts that matched. | ||
* | ||
* @param source The input source | ||
* @param options Options as defined by [[SurroundOptions]] | ||
* @returns The input source with matching ranges surrounded by prefix and suffix | ||
*/ | ||
export const surround = (source: string, options: SurroundOptions) => { | ||
@@ -24,3 +41,3 @@ if (typeof source !== 'string') { | ||
if (!options.result.ranges || !options.result.ranges.length) { | ||
if (!options || !options.result || !options.result.ranges || !options.result.ranges.length) { | ||
return source | ||
@@ -27,0 +44,0 @@ } |
import { prepare } from './utils/prepare' | ||
export type TestOptions = { | ||
/** | ||
* This represents test options. You can specify if the source string should be | ||
* lower cased or not (wether you want the test to be case-sensitive or not). | ||
*/ | ||
export interface TestOptions { | ||
caseSensitive?: boolean | ||
} | ||
/** | ||
* Returns wether or not the query fuzzy matches the source. This will returns | ||
* a boolean. | ||
* | ||
* @param query The input query | ||
* @param source The input source | ||
* @param opts Options as defined by [[TestOptions]] | ||
* @returns Wether or not the query fuzzy matches the source | ||
*/ | ||
export const test = (query: string, source: string, opts: TestOptions = {}) => { | ||
@@ -8,0 +21,0 @@ const [reshapedQuery, reshapedSource] = prepare(query, source, opts) |
import { toLatin } from './toLatin' | ||
/** | ||
* Returns true when the character is leading; ie. when it's a capital or | ||
* when it's following a separator character. You might also want to test if | ||
* the character comes from an alphabet as you wouldn't want to consider a | ||
* space as a leading character. | ||
* | ||
* @param prevChar The character that appears before `char` | ||
* @param char The actual character you want to test | ||
* @returns Wether or not the character is leading | ||
*/ | ||
export const isLeading = (prevChar: string, char: string) => { | ||
@@ -4,0 +14,0 @@ const precededBySeparator = |
@@ -1,6 +0,13 @@ | ||
export type PrepareOptions = { | ||
caseSensitive?: boolean | ||
} | ||
import { TestOptions } from '../test' | ||
export const prepare = (query: string, source: string, opts: PrepareOptions) => { | ||
/** | ||
* This functions is used to throw when query or source is not defined as well | ||
* as normalizing and lower casing the input strings. | ||
* | ||
* @param query The fuzzy query string | ||
* @param source The fuzzy source string | ||
* @param opts An options object that can contains `caseSensitive` | ||
* @returns The reshaped query string and the reshaped source string. | ||
*/ | ||
export const prepare = (query: string, source: string, opts: TestOptions) => { | ||
if (typeof query !== 'string') { | ||
@@ -7,0 +14,0 @@ throw new TypeError('Expecting query to be a string') |
import { MatchRange } from '../match' | ||
export const pushRange = (ranges: Array<MatchRange>, sourcePos: number): Array<MatchRange> => { | ||
/** | ||
* Appends to an actual list of ranges a new match. This will only increment | ||
* the last [[MatchRange]] if the actual match and the last match were | ||
* siblings. | ||
* | ||
* @param ranges The previous ranges array | ||
* @param sourcePos The position in source that matched | ||
* @returns The new ranges array | ||
*/ | ||
export const pushRange = (ranges: MatchRange[], sourcePos: number): MatchRange[] => { | ||
const lastRange = ranges[ranges.length - 1] | ||
@@ -5,0 +14,0 @@ |
@@ -0,1 +1,9 @@ | ||
/** | ||
* Returns a normalized version of the string. This comes from | ||
* https://stackoverflow.com/a/37511463. It converts accented characters into | ||
* two UTF-8 characters (ie. `è` becomes e and `) and strip the accents. | ||
* | ||
* @param str The input string | ||
* @returns The input string without accents | ||
*/ | ||
export const toLatin = (str: string) => str.normalize('NFD').replace(/[\u0300-\u036f]/g, '') |
@@ -7,3 +7,3 @@ import { pushScore } from '../src/score/defaultStrategy' | ||
expect(() => pushScore(undefined as any, undefined as any)).toThrow(TypeError) | ||
expect(() => pushScore(null, null)).toThrow(TypeError) | ||
expect(() => pushScore(null, null as any)).toThrow(TypeError) | ||
}) | ||
@@ -10,0 +10,0 @@ }) |
@@ -18,2 +18,9 @@ import { surround } from '../src/surround' | ||
describe('given an invalid result', () => { | ||
it('returns the input', () => { | ||
expect(surround('foo', null as any)).toBe('foo') | ||
expect(surround('foo', { result: null as any })).toBe('foo') | ||
}) | ||
}) | ||
describe('given an empty range set', () => { | ||
@@ -20,0 +27,0 @@ it('returns the input', () => { |
@@ -7,3 +7,3 @@ import { pushRange } from '../src/utils/range' | ||
it('pushes the position', () => { | ||
const source: Array<MatchRange> = [] | ||
const source: MatchRange[] = [] | ||
const result = pushRange(source, 5) | ||
@@ -17,3 +17,3 @@ | ||
it('pushes the position', () => { | ||
const source: Array<MatchRange> = [{ start: 0, stop: 1 }] | ||
const source: MatchRange[] = [{ start: 0, stop: 1 }] | ||
const result = pushRange(source, 5) | ||
@@ -20,0 +20,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
511726
26204