@stll/fuzzy-search
Advanced tools
+153
| //#region src/core.d.ts | ||
| type NativeBinding = { | ||
| FuzzySearch: new (entries: NormalizedEntry[], options?: Options) => NativeFuzzySearch; | ||
| distance: (a: string, b: string, metric: Metric | null) => number; | ||
| }; | ||
| type NativeFuzzySearch = { | ||
| patternCount: number; | ||
| isMatch(haystack: string): boolean; | ||
| _findIterPacked(haystack: string): Uint32Array; | ||
| replaceAll(haystack: string, replacements: string[]): string; | ||
| }; | ||
| type NormalizedEntry = { | ||
| pattern: string; | ||
| distance?: number; | ||
| name?: string; | ||
| }; | ||
| /** Set the native backend. Must be called once | ||
| * before any class constructor. */ | ||
| /** Distance metric for fuzzy matching. */ | ||
| type Metric = "levenshtein" | "damerau-levenshtein"; | ||
| /** Options for constructing a `FuzzySearch`. */ | ||
| type Options = { | ||
| /** | ||
| * Distance metric. | ||
| * - `"levenshtein"`: insertions, deletions, | ||
| * substitutions (default). | ||
| * - `"damerau-levenshtein"`: + transpositions | ||
| * of adjacent characters (ab -> ba = 1 edit). | ||
| * @default "levenshtein" | ||
| */ | ||
| metric?: Metric; | ||
| /** | ||
| * Strip diacritics before matching (NFD | ||
| * decompose + remove combining marks). | ||
| * "Pribram" matches "Pribram" at distance 0. | ||
| * @default false | ||
| */ | ||
| normalizeDiacritics?: boolean; | ||
| /** | ||
| * Use Unicode word boundaries (covers all | ||
| * scripts). CJK characters are treated as | ||
| * standalone words. | ||
| * @default true | ||
| */ | ||
| unicodeBoundaries?: boolean; | ||
| /** | ||
| * Only match whole words. Fuzzy matches on | ||
| * substrings are usually noise; require word | ||
| * boundaries unless opted out. | ||
| * @default true | ||
| */ | ||
| wholeWords?: boolean; | ||
| /** | ||
| * Case-insensitive matching (Unicode-aware). | ||
| * @default false | ||
| */ | ||
| caseInsensitive?: boolean; | ||
| }; | ||
| /** A pattern entry with its edit distance. */ | ||
| type PatternEntry = string | { | ||
| pattern: string; | ||
| /** Max edit distance. Must be less than | ||
| * pattern length. `"auto"` uses the | ||
| * Elasticsearch convention: 1-2 chars -> 0, | ||
| * 3-5 chars -> 1, 6+ chars -> 2. | ||
| * @default 1 */ | ||
| distance?: number | "auto"; /** Optional name for the pattern. */ | ||
| name?: string; | ||
| }; | ||
| /** A single fuzzy match result. */ | ||
| type FuzzyMatch = { | ||
| /** Index into the patterns array. */pattern: number; | ||
| /** Start UTF-16 code unit offset (compatible | ||
| * with `String.prototype.slice()`). */ | ||
| start: number; /** End offset (exclusive). */ | ||
| end: number; | ||
| /** The matched text | ||
| * (`haystack.slice(start, end)`). */ | ||
| text: string; /** Actual Levenshtein edit distance. */ | ||
| distance: number; /** Pattern name (if provided). */ | ||
| name?: string; | ||
| }; | ||
| /** | ||
| * Fuzzy string matcher. Finds approximate | ||
| * matches within edit distance k, immune to | ||
| * typos, OCR errors, and diacritics variants. | ||
| * | ||
| * Uses Myers' bit-parallel algorithm for O(n) | ||
| * scanning per pattern (patterns up to 64 chars). | ||
| * | ||
| * @throws {Error} If a pattern is empty, too | ||
| * long (> 64 chars), or distance > 3. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const fs = new FuzzySearch([ | ||
| * { pattern: "Gaislerova", distance: 1 }, | ||
| * { pattern: "Novak", distance: 1 }, | ||
| * ], { | ||
| * normalizeDiacritics: true, | ||
| * wholeWords: true, | ||
| * }); | ||
| * | ||
| * fs.findIter("Gais1erova a Nowak"); | ||
| * // [ | ||
| * // { pattern: 0, start: 0, end: 10, | ||
| * // text: "Gais1erova", distance: 1 }, | ||
| * // { pattern: 1, start: 13, end: 18, | ||
| * // text: "Nowak", distance: 1 }, | ||
| * // ] | ||
| * ``` | ||
| */ | ||
| declare class FuzzySearch { | ||
| private _names; | ||
| private _inner; | ||
| constructor(patterns: PatternEntry[], options?: Options); | ||
| /** Number of patterns in the matcher. */ | ||
| get patternCount(): number; | ||
| /** | ||
| * Returns `true` if any pattern matches | ||
| * within its edit distance. | ||
| */ | ||
| isMatch(haystack: string): boolean; | ||
| /** Find all non-overlapping fuzzy matches. */ | ||
| findIter(haystack: string): FuzzyMatch[]; | ||
| /** | ||
| * Replace all fuzzy matches. | ||
| * `replacements[i]` replaces pattern `i`. | ||
| * | ||
| * @throws {Error} If `replacements.length` | ||
| * does not equal `patternCount`. | ||
| */ | ||
| replaceAll(haystack: string, replacements: string[]): string; | ||
| } | ||
| /** | ||
| * Compute edit distance between two strings. | ||
| * | ||
| * Uses Unicode characters (not UTF-16 code units), | ||
| * so emoji and supplementary plane characters are | ||
| * handled correctly. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * distance("Novak", "Nowak"); // 1 | ||
| * distance("abcd", "abdc"); // 2 | ||
| * distance("abcd", "abdc", | ||
| * "damerau-levenshtein"); // 1 | ||
| * ``` | ||
| */ | ||
| declare const distance: (a: string, b: string, metric?: Metric) => number; | ||
| //#endregion | ||
| export { type FuzzyMatch, FuzzySearch, type Metric, type NativeBinding, type Options, type PatternEntry, distance }; | ||
| //# sourceMappingURL=index.d.mts.map |
+133
| import { createRequire } from "node:module"; | ||
| //#region src/core.ts | ||
| let binding; | ||
| /** Set the native backend. Must be called once | ||
| * before any class constructor. */ | ||
| const initBinding = (b) => { | ||
| binding = b; | ||
| }; | ||
| const resolveDistance = (dist, patternLength) => { | ||
| if (dist !== "auto") return dist; | ||
| if (patternLength <= 2) return 0; | ||
| if (patternLength <= 5) return 1; | ||
| return 2; | ||
| }; | ||
| const normalizeEntry = (p, i) => { | ||
| if (typeof p === "string") return { pattern: p }; | ||
| if (typeof p === "object" && p !== null && typeof p.pattern === "string") { | ||
| if (p.distance === "auto") return { | ||
| ...p, | ||
| distance: resolveDistance("auto", p.pattern.length) | ||
| }; | ||
| return p; | ||
| } | ||
| throw new TypeError(`Pattern at index ${i} must be a string or { pattern, distance?, name? }`); | ||
| }; | ||
| const unpack = (packed, haystack, names) => { | ||
| const len = packed.length; | ||
| const matches = []; | ||
| for (let i = 0; i < len; i += 4) { | ||
| const idx = packed[i]; | ||
| const start = packed[i + 1]; | ||
| const end = packed[i + 2]; | ||
| const distance = packed[i + 3]; | ||
| if (idx === void 0 || start === void 0 || end === void 0 || distance === void 0) throw new Error(`Malformed packed array at offset ${String(i)}`); | ||
| const m = { | ||
| pattern: idx, | ||
| start, | ||
| end, | ||
| text: haystack.slice(start, end), | ||
| distance | ||
| }; | ||
| if (names[idx] !== void 0) m.name = names[idx]; | ||
| matches.push(m); | ||
| } | ||
| return matches; | ||
| }; | ||
| /** | ||
| * Fuzzy string matcher. Finds approximate | ||
| * matches within edit distance k, immune to | ||
| * typos, OCR errors, and diacritics variants. | ||
| * | ||
| * Uses Myers' bit-parallel algorithm for O(n) | ||
| * scanning per pattern (patterns up to 64 chars). | ||
| * | ||
| * @throws {Error} If a pattern is empty, too | ||
| * long (> 64 chars), or distance > 3. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const fs = new FuzzySearch([ | ||
| * { pattern: "Gaislerova", distance: 1 }, | ||
| * { pattern: "Novak", distance: 1 }, | ||
| * ], { | ||
| * normalizeDiacritics: true, | ||
| * wholeWords: true, | ||
| * }); | ||
| * | ||
| * fs.findIter("Gais1erova a Nowak"); | ||
| * // [ | ||
| * // { pattern: 0, start: 0, end: 10, | ||
| * // text: "Gais1erova", distance: 1 }, | ||
| * // { pattern: 1, start: 13, end: 18, | ||
| * // text: "Nowak", distance: 1 }, | ||
| * // ] | ||
| * ``` | ||
| */ | ||
| var FuzzySearch = class { | ||
| _names; | ||
| _inner; | ||
| constructor(patterns, options) { | ||
| const entries = patterns.map(normalizeEntry); | ||
| this._names = entries.map((e) => e.name); | ||
| this._inner = new binding.FuzzySearch(entries, options); | ||
| } | ||
| /** Number of patterns in the matcher. */ | ||
| get patternCount() { | ||
| return this._inner.patternCount; | ||
| } | ||
| /** | ||
| * Returns `true` if any pattern matches | ||
| * within its edit distance. | ||
| */ | ||
| isMatch(haystack) { | ||
| return this._inner.isMatch(haystack); | ||
| } | ||
| /** Find all non-overlapping fuzzy matches. */ | ||
| findIter(haystack) { | ||
| return unpack(this._inner._findIterPacked(haystack), haystack, this._names); | ||
| } | ||
| /** | ||
| * Replace all fuzzy matches. | ||
| * `replacements[i]` replaces pattern `i`. | ||
| * | ||
| * @throws {Error} If `replacements.length` | ||
| * does not equal `patternCount`. | ||
| */ | ||
| replaceAll(haystack, replacements) { | ||
| return this._inner.replaceAll(haystack, replacements); | ||
| } | ||
| }; | ||
| /** | ||
| * Compute edit distance between two strings. | ||
| * | ||
| * Uses Unicode characters (not UTF-16 code units), | ||
| * so emoji and supplementary plane characters are | ||
| * handled correctly. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * distance("Novak", "Nowak"); // 1 | ||
| * distance("abcd", "abdc"); // 2 | ||
| * distance("abcd", "abdc", | ||
| * "damerau-levenshtein"); // 1 | ||
| * ``` | ||
| */ | ||
| const distance = (a, b, metric) => binding.distance(a, b, metric ?? null); | ||
| //#endregion | ||
| //#region src/index.ts | ||
| initBinding(createRequire(import.meta.url)("../index.js")); | ||
| //#endregion | ||
| export { FuzzySearch, distance }; | ||
| //# sourceMappingURL=index.mjs.map |
| {"version":3,"file":"index.mjs","names":[],"sources":["../src/core.ts","../src/index.ts"],"sourcesContent":["/* Shared core: types, helpers, and classes that\n * use a late-bound native backend (NAPI-RS or WASM).\n * Call initBinding() before constructing classes. */\n\n// -- Native binding types ----------------------------\n\nexport type NativeBinding = {\n FuzzySearch: new (\n entries: NormalizedEntry[],\n options?: Options,\n ) => NativeFuzzySearch;\n distance: (\n a: string,\n b: string,\n metric: Metric | null,\n ) => number;\n};\n\ntype NativeFuzzySearch = {\n patternCount: number;\n isMatch(haystack: string): boolean;\n _findIterPacked(haystack: string): Uint32Array;\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string;\n};\n\ntype NormalizedEntry = {\n pattern: string;\n distance?: number;\n name?: string;\n};\n\n// -- Late-bound native binding -----------------------\n\nlet binding: NativeBinding;\n\n/** Set the native backend. Must be called once\n * before any class constructor. */\nexport const initBinding = (b: NativeBinding) => {\n binding = b;\n};\n\n// -- Public types ------------------------------------\n\n/** Distance metric for fuzzy matching. */\nexport type Metric = \"levenshtein\" | \"damerau-levenshtein\";\n\n/** Options for constructing a `FuzzySearch`. */\nexport type Options = {\n /**\n * Distance metric.\n * - `\"levenshtein\"`: insertions, deletions,\n * substitutions (default).\n * - `\"damerau-levenshtein\"`: + transpositions\n * of adjacent characters (ab -> ba = 1 edit).\n * @default \"levenshtein\"\n */\n metric?: Metric;\n /**\n * Strip diacritics before matching (NFD\n * decompose + remove combining marks).\n * \"Pribram\" matches \"Pribram\" at distance 0.\n * @default false\n */\n normalizeDiacritics?: boolean;\n /**\n * Use Unicode word boundaries (covers all\n * scripts). CJK characters are treated as\n * standalone words.\n * @default true\n */\n unicodeBoundaries?: boolean;\n /**\n * Only match whole words. Fuzzy matches on\n * substrings are usually noise; require word\n * boundaries unless opted out.\n * @default true\n */\n wholeWords?: boolean;\n /**\n * Case-insensitive matching (Unicode-aware).\n * @default false\n */\n caseInsensitive?: boolean;\n};\n\n/** A pattern entry with its edit distance. */\nexport type PatternEntry =\n | string\n | {\n pattern: string;\n /** Max edit distance. Must be less than\n * pattern length. `\"auto\"` uses the\n * Elasticsearch convention: 1-2 chars -> 0,\n * 3-5 chars -> 1, 6+ chars -> 2.\n * @default 1 */\n distance?: number | \"auto\";\n /** Optional name for the pattern. */\n name?: string;\n };\n\n/** A single fuzzy match result. */\nexport type FuzzyMatch = {\n /** Index into the patterns array. */\n pattern: number;\n /** Start UTF-16 code unit offset (compatible\n * with `String.prototype.slice()`). */\n start: number;\n /** End offset (exclusive). */\n end: number;\n /** The matched text\n * (`haystack.slice(start, end)`). */\n text: string;\n /** Actual Levenshtein edit distance. */\n distance: number;\n /** Pattern name (if provided). */\n name?: string;\n};\n\n// -- Internal helpers --------------------------------\n\nconst resolveDistance = (\n dist: number | \"auto\",\n patternLength: number,\n): number => {\n if (dist !== \"auto\") return dist;\n if (patternLength <= 2) return 0;\n if (patternLength <= 5) return 1;\n return 2;\n};\n\nconst normalizeEntry = (\n p: PatternEntry,\n i: number,\n): NormalizedEntry => {\n if (typeof p === \"string\") {\n return { pattern: p };\n }\n if (\n typeof p === \"object\" &&\n p !== null &&\n typeof p.pattern === \"string\"\n ) {\n if (p.distance === \"auto\") {\n return {\n ...p,\n distance: resolveDistance(\"auto\", p.pattern.length),\n };\n }\n // SAFETY: The \"auto\" case was already handled above,\n // so p.distance is number | undefined — matching\n // NormalizedEntry.\n return p as NormalizedEntry;\n }\n throw new TypeError(\n `Pattern at index ${i} must be a string ` +\n `or { pattern, distance?, name? }`,\n );\n};\n\nconst unpack = (\n packed: Uint32Array,\n haystack: string,\n names: (string | undefined)[],\n): FuzzyMatch[] => {\n const len = packed.length;\n const matches: FuzzyMatch[] = [];\n for (let i = 0; i < len; i += 4) {\n const idx = packed[i];\n const start = packed[i + 1];\n const end = packed[i + 2];\n const distance = packed[i + 3];\n if (\n idx === undefined ||\n start === undefined ||\n end === undefined ||\n distance === undefined\n ) {\n throw new Error(\n `Malformed packed array at offset ${String(i)}`,\n );\n }\n const m: FuzzyMatch = {\n pattern: idx,\n start,\n end,\n text: haystack.slice(start, end),\n distance,\n };\n if (names[idx] !== undefined) {\n m.name = names[idx];\n }\n matches.push(m);\n }\n return matches;\n};\n\n// -- Classes -----------------------------------------\n\n/**\n * Fuzzy string matcher. Finds approximate\n * matches within edit distance k, immune to\n * typos, OCR errors, and diacritics variants.\n *\n * Uses Myers' bit-parallel algorithm for O(n)\n * scanning per pattern (patterns up to 64 chars).\n *\n * @throws {Error} If a pattern is empty, too\n * long (> 64 chars), or distance > 3.\n *\n * @example\n * ```ts\n * const fs = new FuzzySearch([\n * { pattern: \"Gaislerova\", distance: 1 },\n * { pattern: \"Novak\", distance: 1 },\n * ], {\n * normalizeDiacritics: true,\n * wholeWords: true,\n * });\n *\n * fs.findIter(\"Gais1erova a Nowak\");\n * // [\n * // { pattern: 0, start: 0, end: 10,\n * // text: \"Gais1erova\", distance: 1 },\n * // { pattern: 1, start: 13, end: 18,\n * // text: \"Nowak\", distance: 1 },\n * // ]\n * ```\n */\nexport class FuzzySearch {\n private _names: (string | undefined)[];\n private _inner: NativeFuzzySearch;\n\n constructor(patterns: PatternEntry[], options?: Options) {\n const entries = patterns.map(normalizeEntry);\n this._names = entries.map((e) => e.name);\n this._inner = new binding.FuzzySearch(entries, options);\n }\n\n /** Number of patterns in the matcher. */\n get patternCount(): number {\n return this._inner.patternCount;\n }\n\n /**\n * Returns `true` if any pattern matches\n * within its edit distance.\n */\n isMatch(haystack: string): boolean {\n return this._inner.isMatch(haystack);\n }\n\n /** Find all non-overlapping fuzzy matches. */\n findIter(haystack: string): FuzzyMatch[] {\n return unpack(\n this._inner._findIterPacked(haystack),\n haystack,\n this._names,\n );\n }\n\n /**\n * Replace all fuzzy matches.\n * `replacements[i]` replaces pattern `i`.\n *\n * @throws {Error} If `replacements.length`\n * does not equal `patternCount`.\n */\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string {\n return this._inner.replaceAll(haystack, replacements);\n }\n}\n\n/**\n * Compute edit distance between two strings.\n *\n * Uses Unicode characters (not UTF-16 code units),\n * so emoji and supplementary plane characters are\n * handled correctly.\n *\n * @example\n * ```ts\n * distance(\"Novak\", \"Nowak\"); // 1\n * distance(\"abcd\", \"abdc\"); // 2\n * distance(\"abcd\", \"abdc\",\n * \"damerau-levenshtein\"); // 1\n * ```\n */\nexport const distance = (\n a: string,\n b: string,\n metric?: Metric,\n): number => binding.distance(a, b, metric ?? null);\n","/* Main entry point — loads the native NAPI-RS\n * binding and re-exports the public API. */\n\nimport { createRequire } from \"node:module\";\n\nimport { initBinding, type NativeBinding } from \"./core\";\n\nconst require = createRequire(import.meta.url);\n// SAFETY: NAPI-RS auto-generated loader returns the\n// native binding object; its shape is validated by\n// usage in the core classes.\nconst native = require(\"../index.js\") as NativeBinding;\n\ninitBinding(native);\n\nexport { FuzzySearch, distance } from \"./core\";\n\nexport type {\n FuzzyMatch,\n Metric,\n NativeBinding,\n Options,\n PatternEntry,\n} from \"./core\";\n"],"mappings":";;AAoCA,IAAI;;;AAIJ,MAAa,eAAe,MAAqB;AAC/C,WAAU;;AAkFZ,MAAM,mBACJ,MACA,kBACW;AACX,KAAI,SAAS,OAAQ,QAAO;AAC5B,KAAI,iBAAiB,EAAG,QAAO;AAC/B,KAAI,iBAAiB,EAAG,QAAO;AAC/B,QAAO;;AAGT,MAAM,kBACJ,GACA,MACoB;AACpB,KAAI,OAAO,MAAM,SACf,QAAO,EAAE,SAAS,GAAG;AAEvB,KACE,OAAO,MAAM,YACb,MAAM,QACN,OAAO,EAAE,YAAY,UACrB;AACA,MAAI,EAAE,aAAa,OACjB,QAAO;GACL,GAAG;GACH,UAAU,gBAAgB,QAAQ,EAAE,QAAQ,OAAO;GACpD;AAKH,SAAO;;AAET,OAAM,IAAI,UACR,oBAAoB,EAAE,oDAEvB;;AAGH,MAAM,UACJ,QACA,UACA,UACiB;CACjB,MAAM,MAAM,OAAO;CACnB,MAAM,UAAwB,EAAE;AAChC,MAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG;EAC/B,MAAM,MAAM,OAAO;EACnB,MAAM,QAAQ,OAAO,IAAI;EACzB,MAAM,MAAM,OAAO,IAAI;EACvB,MAAM,WAAW,OAAO,IAAI;AAC5B,MACE,QAAQ,KAAA,KACR,UAAU,KAAA,KACV,QAAQ,KAAA,KACR,aAAa,KAAA,EAEb,OAAM,IAAI,MACR,oCAAoC,OAAO,EAAE,GAC9C;EAEH,MAAM,IAAgB;GACpB,SAAS;GACT;GACA;GACA,MAAM,SAAS,MAAM,OAAO,IAAI;GAChC;GACD;AACD,MAAI,MAAM,SAAS,KAAA,EACjB,GAAE,OAAO,MAAM;AAEjB,UAAQ,KAAK,EAAE;;AAEjB,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,IAAa,cAAb,MAAyB;CACvB;CACA;CAEA,YAAY,UAA0B,SAAmB;EACvD,MAAM,UAAU,SAAS,IAAI,eAAe;AAC5C,OAAK,SAAS,QAAQ,KAAK,MAAM,EAAE,KAAK;AACxC,OAAK,SAAS,IAAI,QAAQ,YAAY,SAAS,QAAQ;;;CAIzD,IAAI,eAAuB;AACzB,SAAO,KAAK,OAAO;;;;;;CAOrB,QAAQ,UAA2B;AACjC,SAAO,KAAK,OAAO,QAAQ,SAAS;;;CAItC,SAAS,UAAgC;AACvC,SAAO,OACL,KAAK,OAAO,gBAAgB,SAAS,EACrC,UACA,KAAK,OACN;;;;;;;;;CAUH,WACE,UACA,cACQ;AACR,SAAO,KAAK,OAAO,WAAW,UAAU,aAAa;;;;;;;;;;;;;;;;;;AAmBzD,MAAa,YACX,GACA,GACA,WACW,QAAQ,SAAS,GAAG,GAAG,UAAU,KAAK;;;AC5RnD,YANgB,cAAc,OAAO,KAAK,IAAI,CAIvB,cAAc,CAElB"} |
+7
-425
@@ -6,59 +6,5 @@ // prettier-ignore | ||
| const { readFileSync } = require('node:fs') | ||
| let nativeBinding = null | ||
| const loadErrors = [] | ||
| const isMusl = () => { | ||
| let musl = false | ||
| if (process.platform === 'linux') { | ||
| musl = isMuslFromFilesystem() | ||
| if (musl === null) { | ||
| musl = isMuslFromReport() | ||
| } | ||
| if (musl === null) { | ||
| musl = isMuslFromChildProcess() | ||
| } | ||
| } | ||
| return musl | ||
| } | ||
| const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') | ||
| const isMuslFromFilesystem = () => { | ||
| try { | ||
| return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') | ||
| } catch { | ||
| return null | ||
| } | ||
| } | ||
| const isMuslFromReport = () => { | ||
| let report = null | ||
| if (typeof process.report?.getReport === 'function') { | ||
| process.report.excludeNetwork = true | ||
| report = process.report.getReport() | ||
| } | ||
| if (!report) { | ||
| return null | ||
| } | ||
| if (report.header && report.header.glibcVersionRuntime) { | ||
| return false | ||
| } | ||
| if (Array.isArray(report.sharedObjects)) { | ||
| if (report.sharedObjects.some(isFileMusl)) { | ||
| return true | ||
| } | ||
| } | ||
| return false | ||
| } | ||
| const isMuslFromChildProcess = () => { | ||
| try { | ||
| return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') | ||
| } catch (e) { | ||
| // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false | ||
| return false | ||
| } | ||
| } | ||
| function requireNative() { | ||
@@ -71,108 +17,2 @@ if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { | ||
| } | ||
| } else if (process.platform === 'android') { | ||
| if (process.arch === 'arm64') { | ||
| try { | ||
| return require('./fuzzy-search.android-arm64.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-android-arm64') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-android-arm64/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else if (process.arch === 'arm') { | ||
| try { | ||
| return require('./fuzzy-search.android-arm-eabi.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-android-arm-eabi') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-android-arm-eabi/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) | ||
| } | ||
| } else if (process.platform === 'win32') { | ||
| if (process.arch === 'x64') { | ||
| if (process.config?.variables?.shlib_suffix === 'dll.a' || process.config?.variables?.node_target_type === 'shared_library') { | ||
| try { | ||
| return require('./fuzzy-search.win32-x64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-win32-x64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-win32-x64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.win32-x64-msvc.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-win32-x64-msvc') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-win32-x64-msvc/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'ia32') { | ||
| try { | ||
| return require('./fuzzy-search.win32-ia32-msvc.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-win32-ia32-msvc') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-win32-ia32-msvc/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else if (process.arch === 'arm64') { | ||
| try { | ||
| return require('./fuzzy-search.win32-arm64-msvc.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-win32-arm64-msvc') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-win32-arm64-msvc/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) | ||
| } | ||
| } else if (process.platform === 'darwin') { | ||
@@ -229,6 +69,6 @@ try { | ||
| } | ||
| } else if (process.platform === 'freebsd') { | ||
| } else if (process.platform === 'linux') { | ||
| if (process.arch === 'x64') { | ||
| try { | ||
| return require('./fuzzy-search.freebsd-x64.node') | ||
| return require('./fuzzy-search.linux-x64-gnu.node') | ||
| } catch (e) { | ||
@@ -238,4 +78,4 @@ loadErrors.push(e) | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-freebsd-x64') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-freebsd-x64/package.json').version | ||
| const binding = require('@stll/fuzzy-search-linux-x64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-x64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
@@ -250,3 +90,3 @@ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| try { | ||
| return require('./fuzzy-search.freebsd-arm64.node') | ||
| return require('./fuzzy-search.linux-arm64-gnu.node') | ||
| } catch (e) { | ||
@@ -256,4 +96,4 @@ loadErrors.push(e) | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-freebsd-arm64') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-freebsd-arm64/package.json').version | ||
| const binding = require('@stll/fuzzy-search-linux-arm64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-arm64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
@@ -267,262 +107,4 @@ throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } else { | ||
| loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) | ||
| } | ||
| } else if (process.platform === 'linux') { | ||
| if (process.arch === 'x64') { | ||
| if (isMusl()) { | ||
| try { | ||
| return require('./fuzzy-search.linux-x64-musl.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-x64-musl') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-x64-musl/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.linux-x64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-x64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-x64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'arm64') { | ||
| if (isMusl()) { | ||
| try { | ||
| return require('./fuzzy-search.linux-arm64-musl.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-arm64-musl') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-arm64-musl/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.linux-arm64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-arm64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-arm64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'arm') { | ||
| if (isMusl()) { | ||
| try { | ||
| return require('./fuzzy-search.linux-arm-musleabihf.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-arm-musleabihf') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-arm-musleabihf/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.linux-arm-gnueabihf.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-arm-gnueabihf') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-arm-gnueabihf/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'loong64') { | ||
| if (isMusl()) { | ||
| try { | ||
| return require('./fuzzy-search.linux-loong64-musl.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-loong64-musl') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-loong64-musl/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.linux-loong64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-loong64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-loong64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'riscv64') { | ||
| if (isMusl()) { | ||
| try { | ||
| return require('./fuzzy-search.linux-riscv64-musl.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-riscv64-musl') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-riscv64-musl/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| try { | ||
| return require('./fuzzy-search.linux-riscv64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-riscv64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-riscv64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } | ||
| } else if (process.arch === 'ppc64') { | ||
| try { | ||
| return require('./fuzzy-search.linux-ppc64-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-ppc64-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-ppc64-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else if (process.arch === 's390x') { | ||
| try { | ||
| return require('./fuzzy-search.linux-s390x-gnu.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-linux-s390x-gnu') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-linux-s390x-gnu/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) | ||
| } | ||
| } else if (process.platform === 'openharmony') { | ||
| if (process.arch === 'arm64') { | ||
| try { | ||
| return require('./fuzzy-search.openharmony-arm64.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-openharmony-arm64') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-openharmony-arm64/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else if (process.arch === 'x64') { | ||
| try { | ||
| return require('./fuzzy-search.openharmony-x64.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-openharmony-x64') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-openharmony-x64/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else if (process.arch === 'arm') { | ||
| try { | ||
| return require('./fuzzy-search.openharmony-arm.node') | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| try { | ||
| const binding = require('@stll/fuzzy-search-openharmony-arm') | ||
| const bindingPackageVersion = require('@stll/fuzzy-search-openharmony-arm/package.json').version | ||
| if (bindingPackageVersion !== '0.0.1' && process.env.NAPI_RS_ENFORCE_VERSION_CHECK && process.env.NAPI_RS_ENFORCE_VERSION_CHECK !== '0') { | ||
| throw new Error(`Native binding package version mismatch, expected 0.0.1 but got ${bindingPackageVersion}. You can reinstall dependencies to fix this issue.`) | ||
| } | ||
| return binding | ||
| } catch (e) { | ||
| loadErrors.push(e) | ||
| } | ||
| } else { | ||
| loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) | ||
| } | ||
| } else { | ||
@@ -529,0 +111,0 @@ loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) |
+19
-23
| { | ||
| "name": "@stll/fuzzy-search", | ||
| "version": "0.0.2", | ||
| "publishConfig": { | ||
| "access": "restricted" | ||
| }, | ||
| "version": "0.1.1", | ||
| "description": "NAPI-RS bindings for fuzzy string matching via Myers' bit-parallel algorithm for Node.js/Bun", | ||
@@ -31,14 +28,13 @@ "keywords": [ | ||
| "type": "module", | ||
| "types": "dist/index.d.ts", | ||
| "types": "dist/index.d.mts", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/index.d.ts", | ||
| "browser": { | ||
| "types": "./dist/wasm.d.ts", | ||
| "import": "./dist/wasm.js" | ||
| }, | ||
| "import": "./dist/index.js", | ||
| "default": "./dist/index.js" | ||
| "types": "./dist/index.d.mts", | ||
| "import": "./dist/index.mjs", | ||
| "default": "./dist/index.mjs" | ||
| } | ||
| }, | ||
| "publishConfig": { | ||
| "access": "restricted" | ||
| }, | ||
| "scripts": { | ||
@@ -64,19 +60,19 @@ "build": "napi build --platform --release", | ||
| "devDependencies": { | ||
| "@emnapi/core": "^1.9.0", | ||
| "@emnapi/runtime": "^1.9.0", | ||
| "@napi-rs/cli": "^3.0.0", | ||
| "@emnapi/core": "^1.9.1", | ||
| "@emnapi/runtime": "^1.9.1", | ||
| "@napi-rs/cli": "^3.5.1", | ||
| "@tybys/wasm-util": "^0.10.1", | ||
| "@types/node": "^25.5.0", | ||
| "bun-types": "^1.3.10", | ||
| "emnapi": "^1.9.0", | ||
| "bun-types": "^1.3.11", | ||
| "emnapi": "^1.9.1", | ||
| "fast-check": "^4.6.0", | ||
| "oxfmt": "^0.40.0", | ||
| "oxlint": "^1.55.0", | ||
| "tsdown": "^0.12.4" | ||
| "oxfmt": "^0.42.0", | ||
| "oxlint": "^1.57.0", | ||
| "tsdown": "^0.21.6" | ||
| }, | ||
| "optionalDependencies": { | ||
| "@stll/fuzzy-search-darwin-arm64": "0.0.2", | ||
| "@stll/fuzzy-search-darwin-x64": "0.0.2", | ||
| "@stll/fuzzy-search-darwin-arm64": "0.0.2", | ||
| "@stll/fuzzy-search-linux-arm64-gnu": "0.0.2", | ||
| "@stll/fuzzy-search-linux-x64-gnu": "0.0.2", | ||
| "@stll/fuzzy-search-linux-arm64-gnu": "0.0.2", | ||
| "@stll/fuzzy-search-wasm32-wasi": "0.0.2" | ||
@@ -97,2 +93,2 @@ }, | ||
| } | ||
| } | ||
| } |
-159
| //#region src/core.d.ts | ||
| type NativeBinding = { | ||
| FuzzySearch: new (entries: NormalizedEntry[], options?: Options) => NativeFuzzySearch; | ||
| distance: (a: string, b: string, metric: Metric | null) => number; | ||
| }; | ||
| type NativeFuzzySearch = { | ||
| patternCount: number; | ||
| isMatch(haystack: string): boolean; | ||
| _findIterPacked(haystack: string): Uint32Array; | ||
| replaceAll(haystack: string, replacements: string[]): string; | ||
| }; | ||
| type NormalizedEntry = { | ||
| pattern: string; | ||
| distance?: number; | ||
| name?: string; | ||
| }; | ||
| /** Set the native backend. Must be called once | ||
| * before any class constructor. */ | ||
| /** Distance metric for fuzzy matching. */ | ||
| type Metric = "levenshtein" | "damerau-levenshtein"; | ||
| /** Options for constructing a `FuzzySearch`. */ | ||
| type Options = { | ||
| /** | ||
| * Distance metric. | ||
| * - `"levenshtein"`: insertions, deletions, | ||
| * substitutions (default). | ||
| * - `"damerau-levenshtein"`: + transpositions | ||
| * of adjacent characters (ab -> ba = 1 edit). | ||
| * @default "levenshtein" | ||
| */ | ||
| metric?: Metric; | ||
| /** | ||
| * Strip diacritics before matching (NFD | ||
| * decompose + remove combining marks). | ||
| * "Pribram" matches "Pribram" at distance 0. | ||
| * @default false | ||
| */ | ||
| normalizeDiacritics?: boolean; | ||
| /** | ||
| * Use Unicode word boundaries (covers all | ||
| * scripts). CJK characters are treated as | ||
| * standalone words. | ||
| * @default true | ||
| */ | ||
| unicodeBoundaries?: boolean; | ||
| /** | ||
| * Only match whole words. Fuzzy matches on | ||
| * substrings are usually noise; require word | ||
| * boundaries unless opted out. | ||
| * @default true | ||
| */ | ||
| wholeWords?: boolean; | ||
| /** | ||
| * Case-insensitive matching (Unicode-aware). | ||
| * @default false | ||
| */ | ||
| caseInsensitive?: boolean; | ||
| }; | ||
| /** A pattern entry with its edit distance. */ | ||
| type PatternEntry = string | { | ||
| pattern: string; | ||
| /** Max edit distance. Must be less than | ||
| * pattern length. `"auto"` uses the | ||
| * Elasticsearch convention: 1-2 chars -> 0, | ||
| * 3-5 chars -> 1, 6+ chars -> 2. | ||
| * @default 1 */ | ||
| distance?: number | "auto"; | ||
| /** Optional name for the pattern. */ | ||
| name?: string; | ||
| }; | ||
| /** A single fuzzy match result. */ | ||
| type FuzzyMatch = { | ||
| /** Index into the patterns array. */ | ||
| pattern: number; | ||
| /** Start UTF-16 code unit offset (compatible | ||
| * with `String.prototype.slice()`). */ | ||
| start: number; | ||
| /** End offset (exclusive). */ | ||
| end: number; | ||
| /** The matched text | ||
| * (`haystack.slice(start, end)`). */ | ||
| text: string; | ||
| /** Actual Levenshtein edit distance. */ | ||
| distance: number; | ||
| /** Pattern name (if provided). */ | ||
| name?: string; | ||
| }; | ||
| /** | ||
| * Fuzzy string matcher. Finds approximate | ||
| * matches within edit distance k, immune to | ||
| * typos, OCR errors, and diacritics variants. | ||
| * | ||
| * Uses Myers' bit-parallel algorithm for O(n) | ||
| * scanning per pattern (patterns up to 64 chars). | ||
| * | ||
| * @throws {Error} If a pattern is empty, too | ||
| * long (> 64 chars), or distance > 3. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const fs = new FuzzySearch([ | ||
| * { pattern: "Gaislerova", distance: 1 }, | ||
| * { pattern: "Novak", distance: 1 }, | ||
| * ], { | ||
| * normalizeDiacritics: true, | ||
| * wholeWords: true, | ||
| * }); | ||
| * | ||
| * fs.findIter("Gais1erova a Nowak"); | ||
| * // [ | ||
| * // { pattern: 0, start: 0, end: 10, | ||
| * // text: "Gais1erova", distance: 1 }, | ||
| * // { pattern: 1, start: 13, end: 18, | ||
| * // text: "Nowak", distance: 1 }, | ||
| * // ] | ||
| * ``` | ||
| */ | ||
| declare class FuzzySearch { | ||
| private _names; | ||
| private _inner; | ||
| constructor(patterns: PatternEntry[], options?: Options); | ||
| /** Number of patterns in the matcher. */ | ||
| get patternCount(): number; | ||
| /** | ||
| * Returns `true` if any pattern matches | ||
| * within its edit distance. | ||
| */ | ||
| isMatch(haystack: string): boolean; | ||
| /** Find all non-overlapping fuzzy matches. */ | ||
| findIter(haystack: string): FuzzyMatch[]; | ||
| /** | ||
| * Replace all fuzzy matches. | ||
| * `replacements[i]` replaces pattern `i`. | ||
| * | ||
| * @throws {Error} If `replacements.length` | ||
| * does not equal `patternCount`. | ||
| */ | ||
| replaceAll(haystack: string, replacements: string[]): string; | ||
| } | ||
| /** | ||
| * Compute edit distance between two strings. | ||
| * | ||
| * Uses Unicode characters (not UTF-16 code units), | ||
| * so emoji and supplementary plane characters are | ||
| * handled correctly. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * distance("Novak", "Nowak"); // 1 | ||
| * distance("abcd", "abdc"); // 2 | ||
| * distance("abcd", "abdc", | ||
| * "damerau-levenshtein"); // 1 | ||
| * ``` | ||
| */ | ||
| declare const distance: (a: string, b: string, metric?: Metric) => number; | ||
| //#endregion | ||
| export { Options as a, NativeBinding as i, FuzzySearch as n, PatternEntry as o, Metric as r, distance as s, FuzzyMatch as t }; | ||
| //# sourceMappingURL=core.d.ts.map |
-127
| //#region src/core.ts | ||
| let binding; | ||
| /** Set the native backend. Must be called once | ||
| * before any class constructor. */ | ||
| const initBinding = (b) => { | ||
| binding = b; | ||
| }; | ||
| const resolveDistance = (dist, patternLength) => { | ||
| if (dist !== "auto") return dist; | ||
| if (patternLength <= 2) return 0; | ||
| if (patternLength <= 5) return 1; | ||
| return 2; | ||
| }; | ||
| const normalizeEntry = (p, i) => { | ||
| if (typeof p === "string") return { pattern: p }; | ||
| if (typeof p === "object" && p !== null && typeof p.pattern === "string") { | ||
| if (p.distance === "auto") return { | ||
| ...p, | ||
| distance: resolveDistance("auto", p.pattern.length) | ||
| }; | ||
| return p; | ||
| } | ||
| throw new TypeError(`Pattern at index ${i} must be a string or { pattern, distance?, name? }`); | ||
| }; | ||
| const unpack = (packed, haystack, names) => { | ||
| const len = packed.length; | ||
| const matches = new Array(len / 4); | ||
| for (let i = 0, j = 0; i < len; i += 4, j++) { | ||
| const idx = packed[i]; | ||
| const start = packed[i + 1]; | ||
| const end = packed[i + 2]; | ||
| const m = { | ||
| pattern: idx, | ||
| start, | ||
| end, | ||
| text: haystack.slice(start, end), | ||
| distance: packed[i + 3] | ||
| }; | ||
| if (names[idx] !== void 0) m.name = names[idx]; | ||
| matches[j] = m; | ||
| } | ||
| return matches; | ||
| }; | ||
| /** | ||
| * Fuzzy string matcher. Finds approximate | ||
| * matches within edit distance k, immune to | ||
| * typos, OCR errors, and diacritics variants. | ||
| * | ||
| * Uses Myers' bit-parallel algorithm for O(n) | ||
| * scanning per pattern (patterns up to 64 chars). | ||
| * | ||
| * @throws {Error} If a pattern is empty, too | ||
| * long (> 64 chars), or distance > 3. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * const fs = new FuzzySearch([ | ||
| * { pattern: "Gaislerova", distance: 1 }, | ||
| * { pattern: "Novak", distance: 1 }, | ||
| * ], { | ||
| * normalizeDiacritics: true, | ||
| * wholeWords: true, | ||
| * }); | ||
| * | ||
| * fs.findIter("Gais1erova a Nowak"); | ||
| * // [ | ||
| * // { pattern: 0, start: 0, end: 10, | ||
| * // text: "Gais1erova", distance: 1 }, | ||
| * // { pattern: 1, start: 13, end: 18, | ||
| * // text: "Nowak", distance: 1 }, | ||
| * // ] | ||
| * ``` | ||
| */ | ||
| var FuzzySearch = class { | ||
| _names; | ||
| _inner; | ||
| constructor(patterns, options) { | ||
| const entries = patterns.map(normalizeEntry); | ||
| this._names = entries.map((e) => e.name); | ||
| this._inner = new binding.FuzzySearch(entries, options); | ||
| } | ||
| /** Number of patterns in the matcher. */ | ||
| get patternCount() { | ||
| return this._inner.patternCount; | ||
| } | ||
| /** | ||
| * Returns `true` if any pattern matches | ||
| * within its edit distance. | ||
| */ | ||
| isMatch(haystack) { | ||
| return this._inner.isMatch(haystack); | ||
| } | ||
| /** Find all non-overlapping fuzzy matches. */ | ||
| findIter(haystack) { | ||
| return unpack(this._inner._findIterPacked(haystack), haystack, this._names); | ||
| } | ||
| /** | ||
| * Replace all fuzzy matches. | ||
| * `replacements[i]` replaces pattern `i`. | ||
| * | ||
| * @throws {Error} If `replacements.length` | ||
| * does not equal `patternCount`. | ||
| */ | ||
| replaceAll(haystack, replacements) { | ||
| return this._inner.replaceAll(haystack, replacements); | ||
| } | ||
| }; | ||
| /** | ||
| * Compute edit distance between two strings. | ||
| * | ||
| * Uses Unicode characters (not UTF-16 code units), | ||
| * so emoji and supplementary plane characters are | ||
| * handled correctly. | ||
| * | ||
| * @example | ||
| * ```ts | ||
| * distance("Novak", "Nowak"); // 1 | ||
| * distance("abcd", "abdc"); // 2 | ||
| * distance("abcd", "abdc", | ||
| * "damerau-levenshtein"); // 1 | ||
| * ``` | ||
| */ | ||
| const distance = (a, b, metric) => binding.distance(a, b, metric ?? null); | ||
| //#endregion | ||
| export { distance as n, initBinding as r, FuzzySearch as t }; | ||
| //# sourceMappingURL=core.js.map |
| {"version":3,"file":"core.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["/* Shared core: types, helpers, and classes that\n * use a late-bound native backend (NAPI-RS or WASM).\n * Call initBinding() before constructing classes. */\n\n// -- Native binding types ----------------------------\n\nexport type NativeBinding = {\n FuzzySearch: new (\n entries: NormalizedEntry[],\n options?: Options,\n ) => NativeFuzzySearch;\n distance: (\n a: string,\n b: string,\n metric: Metric | null,\n ) => number;\n};\n\ntype NativeFuzzySearch = {\n patternCount: number;\n isMatch(haystack: string): boolean;\n _findIterPacked(haystack: string): Uint32Array;\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string;\n};\n\ntype NormalizedEntry = {\n pattern: string;\n distance?: number;\n name?: string;\n};\n\n// -- Late-bound native binding -----------------------\n\nlet binding: NativeBinding;\n\n/** Set the native backend. Must be called once\n * before any class constructor. */\nexport const initBinding = (b: NativeBinding) => {\n binding = b;\n};\n\n// -- Public types ------------------------------------\n\n/** Distance metric for fuzzy matching. */\nexport type Metric = \"levenshtein\" | \"damerau-levenshtein\";\n\n/** Options for constructing a `FuzzySearch`. */\nexport type Options = {\n /**\n * Distance metric.\n * - `\"levenshtein\"`: insertions, deletions,\n * substitutions (default).\n * - `\"damerau-levenshtein\"`: + transpositions\n * of adjacent characters (ab -> ba = 1 edit).\n * @default \"levenshtein\"\n */\n metric?: Metric;\n /**\n * Strip diacritics before matching (NFD\n * decompose + remove combining marks).\n * \"Pribram\" matches \"Pribram\" at distance 0.\n * @default false\n */\n normalizeDiacritics?: boolean;\n /**\n * Use Unicode word boundaries (covers all\n * scripts). CJK characters are treated as\n * standalone words.\n * @default true\n */\n unicodeBoundaries?: boolean;\n /**\n * Only match whole words. Fuzzy matches on\n * substrings are usually noise; require word\n * boundaries unless opted out.\n * @default true\n */\n wholeWords?: boolean;\n /**\n * Case-insensitive matching (Unicode-aware).\n * @default false\n */\n caseInsensitive?: boolean;\n};\n\n/** A pattern entry with its edit distance. */\nexport type PatternEntry =\n | string\n | {\n pattern: string;\n /** Max edit distance. Must be less than\n * pattern length. `\"auto\"` uses the\n * Elasticsearch convention: 1-2 chars -> 0,\n * 3-5 chars -> 1, 6+ chars -> 2.\n * @default 1 */\n distance?: number | \"auto\";\n /** Optional name for the pattern. */\n name?: string;\n };\n\n/** A single fuzzy match result. */\nexport type FuzzyMatch = {\n /** Index into the patterns array. */\n pattern: number;\n /** Start UTF-16 code unit offset (compatible\n * with `String.prototype.slice()`). */\n start: number;\n /** End offset (exclusive). */\n end: number;\n /** The matched text\n * (`haystack.slice(start, end)`). */\n text: string;\n /** Actual Levenshtein edit distance. */\n distance: number;\n /** Pattern name (if provided). */\n name?: string;\n};\n\n// -- Internal helpers --------------------------------\n\nconst resolveDistance = (\n dist: number | \"auto\",\n patternLength: number,\n): number => {\n if (dist !== \"auto\") return dist;\n if (patternLength <= 2) return 0;\n if (patternLength <= 5) return 1;\n return 2;\n};\n\nconst normalizeEntry = (\n p: PatternEntry,\n i: number,\n): NormalizedEntry => {\n if (typeof p === \"string\") {\n return { pattern: p };\n }\n if (\n typeof p === \"object\" &&\n p !== null &&\n typeof p.pattern === \"string\"\n ) {\n if (p.distance === \"auto\") {\n return {\n ...p,\n distance: resolveDistance(\"auto\", p.pattern.length),\n };\n }\n // SAFETY: The \"auto\" case was already handled above,\n // so p.distance is number | undefined — matching\n // NormalizedEntry.\n return p as NormalizedEntry;\n }\n throw new TypeError(\n `Pattern at index ${i} must be a string ` +\n `or { pattern, distance?, name? }`,\n );\n};\n\nconst unpack = (\n packed: Uint32Array,\n haystack: string,\n names: (string | undefined)[],\n): FuzzyMatch[] => {\n // SAFETY: Loop increments by 4 and terminates at packed.length.\n // Indices i through i+3 are always in bounds.\n const len = packed.length;\n // eslint-disable-next-line unicorn/no-new-array\n const matches = new Array<FuzzyMatch>(len / 4);\n for (let i = 0, j = 0; i < len; i += 4, j++) {\n const idx = packed[i]!;\n const start = packed[i + 1]!;\n const end = packed[i + 2]!;\n const m: FuzzyMatch = {\n pattern: idx,\n start,\n end,\n text: haystack.slice(start, end),\n distance: packed[i + 3]!,\n };\n if (names[idx] !== undefined) {\n m.name = names[idx];\n }\n matches[j] = m;\n }\n return matches;\n};\n\n// -- Classes -----------------------------------------\n\n/**\n * Fuzzy string matcher. Finds approximate\n * matches within edit distance k, immune to\n * typos, OCR errors, and diacritics variants.\n *\n * Uses Myers' bit-parallel algorithm for O(n)\n * scanning per pattern (patterns up to 64 chars).\n *\n * @throws {Error} If a pattern is empty, too\n * long (> 64 chars), or distance > 3.\n *\n * @example\n * ```ts\n * const fs = new FuzzySearch([\n * { pattern: \"Gaislerova\", distance: 1 },\n * { pattern: \"Novak\", distance: 1 },\n * ], {\n * normalizeDiacritics: true,\n * wholeWords: true,\n * });\n *\n * fs.findIter(\"Gais1erova a Nowak\");\n * // [\n * // { pattern: 0, start: 0, end: 10,\n * // text: \"Gais1erova\", distance: 1 },\n * // { pattern: 1, start: 13, end: 18,\n * // text: \"Nowak\", distance: 1 },\n * // ]\n * ```\n */\nexport class FuzzySearch {\n private _names: (string | undefined)[];\n private _inner: NativeFuzzySearch;\n\n constructor(patterns: PatternEntry[], options?: Options) {\n const entries = patterns.map(normalizeEntry);\n this._names = entries.map((e) => e.name);\n this._inner = new binding.FuzzySearch(entries, options);\n }\n\n /** Number of patterns in the matcher. */\n get patternCount(): number {\n return this._inner.patternCount;\n }\n\n /**\n * Returns `true` if any pattern matches\n * within its edit distance.\n */\n isMatch(haystack: string): boolean {\n return this._inner.isMatch(haystack);\n }\n\n /** Find all non-overlapping fuzzy matches. */\n findIter(haystack: string): FuzzyMatch[] {\n return unpack(\n this._inner._findIterPacked(haystack),\n haystack,\n this._names,\n );\n }\n\n /**\n * Replace all fuzzy matches.\n * `replacements[i]` replaces pattern `i`.\n *\n * @throws {Error} If `replacements.length`\n * does not equal `patternCount`.\n */\n replaceAll(\n haystack: string,\n replacements: string[],\n ): string {\n return this._inner.replaceAll(haystack, replacements);\n }\n}\n\n/**\n * Compute edit distance between two strings.\n *\n * Uses Unicode characters (not UTF-16 code units),\n * so emoji and supplementary plane characters are\n * handled correctly.\n *\n * @example\n * ```ts\n * distance(\"Novak\", \"Nowak\"); // 1\n * distance(\"abcd\", \"abdc\"); // 2\n * distance(\"abcd\", \"abdc\",\n * \"damerau-levenshtein\"); // 1\n * ```\n */\nexport const distance = (\n a: string,\n b: string,\n metric?: Metric,\n): number => binding.distance(a, b, metric ?? null);\n"],"mappings":";AAoCA,IAAI;;;AAIJ,MAAa,eAAe,MAAqB;AAC/C,WAAU;;AAkFZ,MAAM,mBACJ,MACA,kBACW;AACX,KAAI,SAAS,OAAQ,QAAO;AAC5B,KAAI,iBAAiB,EAAG,QAAO;AAC/B,KAAI,iBAAiB,EAAG,QAAO;AAC/B,QAAO;;AAGT,MAAM,kBACJ,GACA,MACoB;AACpB,KAAI,OAAO,MAAM,SACf,QAAO,EAAE,SAAS,GAAG;AAEvB,KACE,OAAO,MAAM,YACb,MAAM,QACN,OAAO,EAAE,YAAY,UACrB;AACA,MAAI,EAAE,aAAa,OACjB,QAAO;GACL,GAAG;GACH,UAAU,gBAAgB,QAAQ,EAAE,QAAQ,OAAO;GACpD;AAKH,SAAO;;AAET,OAAM,IAAI,UACR,oBAAoB,EAAE,oDAEvB;;AAGH,MAAM,UACJ,QACA,UACA,UACiB;CAGjB,MAAM,MAAM,OAAO;CAEnB,MAAM,UAAU,IAAI,MAAkB,MAAM,EAAE;AAC9C,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,IAAI,KAAK,KAAK,GAAG,KAAK;EAC3C,MAAM,MAAM,OAAO;EACnB,MAAM,QAAQ,OAAO,IAAI;EACzB,MAAM,MAAM,OAAO,IAAI;EACvB,MAAM,IAAgB;GACpB,SAAS;GACT;GACA;GACA,MAAM,SAAS,MAAM,OAAO,IAAI;GAChC,UAAU,OAAO,IAAI;GACtB;AACD,MAAI,MAAM,SAAS,KAAA,EACjB,GAAE,OAAO,MAAM;AAEjB,UAAQ,KAAK;;AAEf,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,IAAa,cAAb,MAAyB;CACvB;CACA;CAEA,YAAY,UAA0B,SAAmB;EACvD,MAAM,UAAU,SAAS,IAAI,eAAe;AAC5C,OAAK,SAAS,QAAQ,KAAK,MAAM,EAAE,KAAK;AACxC,OAAK,SAAS,IAAI,QAAQ,YAAY,SAAS,QAAQ;;;CAIzD,IAAI,eAAuB;AACzB,SAAO,KAAK,OAAO;;;;;;CAOrB,QAAQ,UAA2B;AACjC,SAAO,KAAK,OAAO,QAAQ,SAAS;;;CAItC,SAAS,UAAgC;AACvC,SAAO,OACL,KAAK,OAAO,gBAAgB,SAAS,EACrC,UACA,KAAK,OACN;;;;;;;;;CAUH,WACE,UACA,cACQ;AACR,SAAO,KAAK,OAAO,WAAW,UAAU,aAAa;;;;;;;;;;;;;;;;;;AAmBzD,MAAa,YACX,GACA,GACA,WACW,QAAQ,SAAS,GAAG,GAAG,UAAU,KAAK"} |
| import { a as Options, i as NativeBinding, n as FuzzySearch, o as PatternEntry, r as Metric, s as distance, t as FuzzyMatch } from "./core.js"; | ||
| export { type FuzzyMatch, FuzzySearch, type Metric, type NativeBinding, type Options, type PatternEntry, distance }; |
| import { n as distance, r as initBinding, t as FuzzySearch } from "./core.js"; | ||
| import { createRequire } from "node:module"; | ||
| //#region src/index.ts | ||
| initBinding(createRequire(import.meta.url)("../index.js")); | ||
| //#endregion | ||
| export { FuzzySearch, distance }; | ||
| //# sourceMappingURL=index.js.map |
| {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/* Main entry point — loads the native NAPI-RS\n * binding and re-exports the public API. */\n\nimport { createRequire } from \"node:module\";\n\nimport { initBinding, type NativeBinding } from \"./core\";\n\nconst require = createRequire(import.meta.url);\n// SAFETY: NAPI-RS auto-generated loader returns the\n// native binding object; its shape is validated by\n// usage in the core classes.\nconst native = require(\"../index.js\") as NativeBinding;\n\ninitBinding(native);\n\nexport { FuzzySearch, distance } from \"./core\";\n\nexport type {\n FuzzyMatch,\n Metric,\n NativeBinding,\n Options,\n PatternEntry,\n} from \"./core\";\n"],"mappings":";;;AAaA,YANgB,cAAc,OAAO,KAAK,IAAI,CAIvB,cAAc,CAElB"} |
| import { a as Options, i as NativeBinding, n as FuzzySearch, o as PatternEntry, r as Metric, s as distance, t as FuzzyMatch } from "./core.js"; | ||
| export { type FuzzyMatch, FuzzySearch, type Metric, type NativeBinding, type Options, type PatternEntry, distance }; |
| import { n as distance, r as initBinding, t as FuzzySearch } from "./core.js"; | ||
| import native from "@stll/fuzzy-search-wasm32-wasi"; | ||
| //#region src/wasm.ts | ||
| initBinding(native); | ||
| //#endregion | ||
| export { FuzzySearch, distance }; | ||
| //# sourceMappingURL=wasm.js.map |
| {"version":3,"file":"wasm.js","names":[],"sources":["../src/wasm.ts"],"sourcesContent":["/* Browser/WASM entry point — loads the binding from\n * the wasm32-wasi sub-package and re-exports the\n * public API through the shared core. */\n\nimport native from \"@stll/fuzzy-search-wasm32-wasi\";\nimport { initBinding, type NativeBinding } from \"./core\";\n\ninitBinding(native as unknown as NativeBinding);\n\nexport { FuzzySearch, distance } from \"./core\";\n\nexport type {\n FuzzyMatch,\n Metric,\n NativeBinding,\n Options,\n PatternEntry,\n} from \"./core\";\n"],"mappings":";;;AAOA,YAAY,OAAmC"} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
19
-68.85%36120
-35.44%7
-46.15%288
-66.74%