rapid-fuzzy 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +291 -14
- package/browser.js +1 -1
- package/highlight.d.mts +2 -0
- package/index.d.mts +5 -5
- package/index.d.ts +129 -6
- package/index.js +74 -52
- package/index.mjs +21 -0
- package/objects.d.mts +8 -0
- package/objects.d.ts +13 -0
- package/objects.js +55 -5
- package/package.json +26 -15
- package/rapid-fuzzy-wasm-bindgen.d.ts +247 -0
- package/rapid-fuzzy-wasm-bindgen.js +9 -0
- package/rapid-fuzzy-wasm-bindgen_bg.js +1609 -0
- package/rapid-fuzzy-wasm-bindgen_bg.wasm.d.ts +76 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Blazing-fast fuzzy search for JavaScript — powered by Rust, works everywhere.
|
|
|
12
12
|
|
|
13
13
|
## Features
|
|
14
14
|
|
|
15
|
-
- **Fast**: Up to 15,000x faster than fuse.js
|
|
15
|
+
- **Fast**: Up to 15,000x faster than fuse.js in indexed mode on large datasets (Rust + napi-rs) — [see benchmarks](#benchmarks)
|
|
16
16
|
- **Universal**: Works in Node.js (native), browsers (WASM), Deno, and Bun
|
|
17
17
|
- **Zero JS dependencies**: Pure Rust core with napi-rs bindings
|
|
18
18
|
- **Type-safe**: Full TypeScript support with auto-generated type definitions
|
|
@@ -51,14 +51,110 @@ pnpm add rapid-fuzzy
|
|
|
51
51
|
### Runtime-specific notes
|
|
52
52
|
|
|
53
53
|
- **Node.js** (>=20): Uses native bindings via napi-rs for best performance.
|
|
54
|
-
- **
|
|
54
|
+
- **Bun**: Uses native napi-rs bindings. WASM fallback also works — see [Bun section](#bun) below.
|
|
55
|
+
- **Browser / CDN / Cloudflare Workers / Deno**: Falls back to the wasm-bindgen WASM build (~195 KB raw). No `SharedArrayBuffer` or COOP/COEP headers required.
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
### Framework Integration (SSR)
|
|
58
|
+
|
|
59
|
+
Native modules need to be externalized in SSR frameworks:
|
|
60
|
+
|
|
61
|
+
**Next.js**
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
// next.config.js
|
|
65
|
+
const nextConfig = {
|
|
66
|
+
serverExternalPackages: ['rapid-fuzzy'],
|
|
67
|
+
};
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Vite SSR**
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
// vite.config.js
|
|
74
|
+
export default {
|
|
75
|
+
ssr: {
|
|
76
|
+
external: ['rapid-fuzzy'],
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
On the client side, rapid-fuzzy automatically falls back to WASM — no additional configuration needed.
|
|
82
|
+
|
|
83
|
+
### Browser and Edge Runtime Usage
|
|
84
|
+
|
|
85
|
+
#### CDN (no bundler required)
|
|
86
|
+
|
|
87
|
+
Import directly from [esm.sh](https://esm.sh) in any `<script type="module">`:
|
|
88
|
+
|
|
89
|
+
```html
|
|
90
|
+
<script type="module">
|
|
91
|
+
import { search, FuzzyIndex } from 'https://esm.sh/rapid-fuzzy';
|
|
92
|
+
|
|
93
|
+
const results = search('typscript', ['TypeScript', 'JavaScript', 'Python']);
|
|
94
|
+
console.log(results[0].item); // 'TypeScript'
|
|
95
|
+
|
|
96
|
+
const index = new FuzzyIndex(['TypeScript', 'JavaScript', 'Python']);
|
|
97
|
+
console.log(index.search('typscript')[0].item); // 'TypeScript'
|
|
98
|
+
index.destroy();
|
|
99
|
+
</script>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
See [`examples/cdn-usage/`](examples/cdn-usage/) for a complete HTML example.
|
|
103
|
+
|
|
104
|
+
#### Cloudflare Workers
|
|
105
|
+
|
|
106
|
+
Install the package and import it in your Worker script. Wrangler bundles the WASM binary automatically:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npm install rapid-fuzzy
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
// worker.js
|
|
114
|
+
import { search, FuzzyIndex } from 'rapid-fuzzy';
|
|
115
|
+
|
|
116
|
+
// Create the index once at module scope (shared across requests)
|
|
117
|
+
const index = new FuzzyIndex(['hello', 'world', 'foo', 'bar']);
|
|
118
|
+
|
|
119
|
+
export default {
|
|
120
|
+
fetch(request) {
|
|
121
|
+
const { searchParams } = new URL(request.url);
|
|
122
|
+
const query = searchParams.get('q') ?? '';
|
|
123
|
+
const results = index.search(query);
|
|
124
|
+
return Response.json(results);
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```toml
|
|
130
|
+
# wrangler.toml
|
|
131
|
+
name = "rapid-fuzzy-worker"
|
|
132
|
+
main = "worker.js"
|
|
133
|
+
compatibility_date = "2025-01-01"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
See [`examples/cloudflare-workers/`](examples/cloudflare-workers/) for a complete example.
|
|
137
|
+
|
|
138
|
+
#### Deno
|
|
139
|
+
|
|
140
|
+
Use rapid-fuzzy via the `npm:` specifier (Deno 1.28+):
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import { search } from 'npm:rapid-fuzzy';
|
|
144
|
+
|
|
145
|
+
const results = search('typscript', ['TypeScript', 'JavaScript', 'Python']);
|
|
146
|
+
console.log(results[0].item); // 'TypeScript'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Or import from a CDN directly:
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { search } from 'https://esm.sh/rapid-fuzzy';
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
#### Bun
|
|
156
|
+
|
|
157
|
+
Bun uses the native napi-rs bindings when available (fastest). You can also use the wasm-bindgen WASM files directly if needed — see [`e2e/wasm-bun.test.ts`](e2e/wasm-bun.test.ts) for the manual initialization pattern.
|
|
62
158
|
|
|
63
159
|
## API
|
|
64
160
|
|
|
@@ -101,12 +197,25 @@ closest('xyz', items, 0.5);
|
|
|
101
197
|
### String Distance
|
|
102
198
|
|
|
103
199
|
```typescript
|
|
104
|
-
import {
|
|
200
|
+
import {
|
|
201
|
+
levenshtein,
|
|
202
|
+
jaro,
|
|
203
|
+
jaroWinkler,
|
|
204
|
+
sorensenDice,
|
|
205
|
+
hamming,
|
|
206
|
+
normalizedHamming,
|
|
207
|
+
indel,
|
|
208
|
+
normalizedIndel,
|
|
209
|
+
} from 'rapid-fuzzy';
|
|
105
210
|
|
|
106
211
|
levenshtein('kitten', 'sitting'); // 3
|
|
107
|
-
|
|
212
|
+
jaro('martha', 'marhta'); // 0.944 (similarity between 0–1)
|
|
213
|
+
jaroWinkler('MARTHA', 'MARHTA'); // 0.961 (jaro + prefix bonus)
|
|
108
214
|
sorensenDice('night', 'nacht'); // 0.25
|
|
109
215
|
hamming('karolin', 'kathrin'); // 3 (null if lengths differ)
|
|
216
|
+
normalizedHamming('karolin', 'kathrin'); // 0.571 (similarity 0–1, null if lengths differ)
|
|
217
|
+
indel('abc', 'ac'); // 1 (insertions + deletions only, no substitutions)
|
|
218
|
+
normalizedIndel('kitten', 'sitting'); // 0.615 (similarity 0–1)
|
|
110
219
|
```
|
|
111
220
|
|
|
112
221
|
### Query Syntax
|
|
@@ -169,6 +278,9 @@ const index = new FuzzyIndex(['TypeScript', 'JavaScript', 'Python', ...]);
|
|
|
169
278
|
index.search('typscript', { maxResults: 5 });
|
|
170
279
|
index.closest('tsc');
|
|
171
280
|
|
|
281
|
+
// Tip: FuzzyIndex caches results internally — extending a previous query
|
|
282
|
+
// (e.g. typing "app" → "apple") reuses cached candidates for faster lookups.
|
|
283
|
+
|
|
172
284
|
// Index-only results (no string cloning — less GC pressure)
|
|
173
285
|
const hits = index.searchIndices('typscript', { maxResults: 5 });
|
|
174
286
|
// → [{ index: 0, score: 0.85, positions: [] }, ...]
|
|
@@ -192,6 +304,38 @@ index.destroy();
|
|
|
192
304
|
userIndex.destroy();
|
|
193
305
|
```
|
|
194
306
|
|
|
307
|
+
#### Incremental Search (Autocomplete)
|
|
308
|
+
|
|
309
|
+
FuzzyIndex automatically caches matching candidates. When a new query extends the previous one, only cached candidates are re-scored:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
const index = new FuzzyIndex(items);
|
|
313
|
+
index.search('app'); // scores all items, caches matches
|
|
314
|
+
index.search('apple'); // only re-scores cached candidates — much faster
|
|
315
|
+
index.search('xyz'); // different query — full scan, new cache
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
This makes FuzzyIndex ideal for search-as-you-type UIs where each keystroke extends the query.
|
|
319
|
+
|
|
320
|
+
#### Index Serialization
|
|
321
|
+
|
|
322
|
+
Save and restore a `FuzzyIndex` to avoid rebuilding on startup:
|
|
323
|
+
|
|
324
|
+
```typescript
|
|
325
|
+
import { FuzzyIndex } from 'rapid-fuzzy';
|
|
326
|
+
|
|
327
|
+
const index = new FuzzyIndex(['apple', 'banana', 'cherry']);
|
|
328
|
+
|
|
329
|
+
// Serialize to Buffer
|
|
330
|
+
const data = index.serialize();
|
|
331
|
+
|
|
332
|
+
// Restore from serialized data
|
|
333
|
+
const restored = FuzzyIndex.deserialize(data);
|
|
334
|
+
restored.search('aple'); // works immediately
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
> **Note:** The serialization format is version-specific. Regenerate the index after updating rapid-fuzzy.
|
|
338
|
+
|
|
195
339
|
### Match Highlighting
|
|
196
340
|
|
|
197
341
|
Convert matched positions into highlighted markup for UI rendering:
|
|
@@ -247,7 +391,10 @@ All token-based functions include `Batch` and `Many` variants (e.g., `tokenSortR
|
|
|
247
391
|
<details>
|
|
248
392
|
<summary><strong>Batch Operations</strong></summary>
|
|
249
393
|
|
|
250
|
-
All distance functions have `Batch` and `Many` variants that amortize FFI overhead
|
|
394
|
+
All distance functions have `Batch` and `Many` variants that amortize FFI overhead. `*Batch` functions compute metrics for multiple pairs at once, while `*Many` functions compare a single reference string against multiple candidates.
|
|
395
|
+
|
|
396
|
+
- **`*Batch`** — compute distances for an array of string pairs (many-to-many)
|
|
397
|
+
- **`*Many`** — compare one reference string against many candidates (one-to-many)
|
|
251
398
|
|
|
252
399
|
```typescript
|
|
253
400
|
import { levenshteinBatch, levenshteinMany } from 'rapid-fuzzy';
|
|
@@ -273,13 +420,142 @@ jaroWinklerMany('MARTHA', candidates, 0.8); // minSimilarity → returns 0
|
|
|
273
420
|
|
|
274
421
|
</details>
|
|
275
422
|
|
|
423
|
+
<details>
|
|
424
|
+
<summary><strong>TypedArray Variants</strong></summary>
|
|
425
|
+
|
|
426
|
+
All `*Many` functions have TypedArray counterparts that return `Uint32Array` or `Float64Array` instead of `Array<number>`. These avoid boxing overhead and GC pressure when processing large candidate sets.
|
|
427
|
+
|
|
428
|
+
- **`*ManyU32`** — returns `Uint32Array` (for integer distances: `levenshteinManyU32`, `damerauLevenshteinManyU32`, `indelManyU32`)
|
|
429
|
+
- **`*ManyF64`** — returns `Float64Array` (for similarity scores: `jaroManyF64`, `jaroWinklerManyF64`, `normalizedLevenshteinManyF64`, `normalizedIndelManyF64`, `sorensenDiceManyF64`, `tokenSortRatioManyF64`, `tokenSetRatioManyF64`, `partialRatioManyF64`, `weightedRatioManyF64`)
|
|
430
|
+
|
|
431
|
+
```typescript
|
|
432
|
+
import { levenshteinManyU32, jaroWinklerManyF64 } from 'rapid-fuzzy';
|
|
433
|
+
|
|
434
|
+
const candidates = ['sitting', 'kittens', 'kitchen'];
|
|
435
|
+
|
|
436
|
+
// Returns Uint32Array instead of Array<number>
|
|
437
|
+
levenshteinManyU32('kitten', candidates); // Uint32Array [3, 1, 2]
|
|
438
|
+
|
|
439
|
+
// Returns Float64Array instead of Array<number>
|
|
440
|
+
jaroWinklerManyF64('kitten', candidates); // Float64Array [0.746, 0.976, 0.933]
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
> **When to use**: Prefer TypedArray variants when comparing against thousands of candidates. The returned typed arrays can also be passed directly to WebGL, WASM, or worker threads without copying.
|
|
444
|
+
|
|
445
|
+
</details>
|
|
446
|
+
|
|
447
|
+
## Framework Integration
|
|
448
|
+
|
|
449
|
+
`FuzzyIndex` and `FuzzyObjectIndex` are designed for repeated search on the same data — build the index once, search many times. The examples below show the recommended pattern for each major framework.
|
|
450
|
+
|
|
451
|
+
### React
|
|
452
|
+
|
|
453
|
+
```tsx
|
|
454
|
+
import { useEffect, useRef, useState } from 'react';
|
|
455
|
+
import { FuzzyObjectIndex } from 'rapid-fuzzy/objects';
|
|
456
|
+
|
|
457
|
+
const users = [
|
|
458
|
+
{ name: 'Alice', email: 'alice@example.com' },
|
|
459
|
+
{ name: 'Bob', email: 'bob@example.com' },
|
|
460
|
+
];
|
|
461
|
+
|
|
462
|
+
function UserSearch() {
|
|
463
|
+
const indexRef = useRef<FuzzyObjectIndex<typeof users[number]> | null>(null);
|
|
464
|
+
const [query, setQuery] = useState('');
|
|
465
|
+
const [results, setResults] = useState(users);
|
|
466
|
+
|
|
467
|
+
useEffect(() => {
|
|
468
|
+
indexRef.current = new FuzzyObjectIndex(users, {
|
|
469
|
+
keys: [{ name: 'name', weight: 2.0 }, 'email'],
|
|
470
|
+
});
|
|
471
|
+
return () => indexRef.current?.destroy();
|
|
472
|
+
}, []); // rebuild only when data changes — pass `users` as dependency if dynamic
|
|
473
|
+
|
|
474
|
+
useEffect(() => {
|
|
475
|
+
if (!indexRef.current) return;
|
|
476
|
+
if (!query) { setResults(users); return; }
|
|
477
|
+
setResults(indexRef.current.search(query).map((r) => r.item));
|
|
478
|
+
}, [query]);
|
|
479
|
+
|
|
480
|
+
return (
|
|
481
|
+
<>
|
|
482
|
+
<input value={query} onChange={(e) => setQuery(e.target.value)} placeholder="Search…" />
|
|
483
|
+
<ul>{results.map((u) => <li key={u.email}>{u.name}</li>)}</ul>
|
|
484
|
+
</>
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
### Vue
|
|
490
|
+
|
|
491
|
+
```vue
|
|
492
|
+
<script setup lang="ts">
|
|
493
|
+
import { ref, watch, onUnmounted } from 'vue';
|
|
494
|
+
import { FuzzyObjectIndex } from 'rapid-fuzzy/objects';
|
|
495
|
+
|
|
496
|
+
const users = [
|
|
497
|
+
{ name: 'Alice', email: 'alice@example.com' },
|
|
498
|
+
{ name: 'Bob', email: 'bob@example.com' },
|
|
499
|
+
];
|
|
500
|
+
|
|
501
|
+
const query = ref('');
|
|
502
|
+
const results = ref(users);
|
|
503
|
+
|
|
504
|
+
const index = new FuzzyObjectIndex(users, {
|
|
505
|
+
keys: [{ name: 'name', weight: 2.0 }, 'email'],
|
|
506
|
+
});
|
|
507
|
+
|
|
508
|
+
watch(query, (q) => {
|
|
509
|
+
results.value = q ? index.search(q).map((r) => r.item) : users;
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
onUnmounted(() => index.destroy());
|
|
513
|
+
</script>
|
|
514
|
+
|
|
515
|
+
<template>
|
|
516
|
+
<input v-model="query" placeholder="Search…" />
|
|
517
|
+
<ul><li v-for="u in results" :key="u.email">{{ u.name }}</li></ul>
|
|
518
|
+
</template>
|
|
519
|
+
```
|
|
520
|
+
|
|
521
|
+
### Svelte
|
|
522
|
+
|
|
523
|
+
```svelte
|
|
524
|
+
<script lang="ts">
|
|
525
|
+
import { onDestroy } from 'svelte';
|
|
526
|
+
import { FuzzyObjectIndex } from 'rapid-fuzzy/objects';
|
|
527
|
+
|
|
528
|
+
const users = [
|
|
529
|
+
{ name: 'Alice', email: 'alice@example.com' },
|
|
530
|
+
{ name: 'Bob', email: 'bob@example.com' },
|
|
531
|
+
];
|
|
532
|
+
|
|
533
|
+
let query = '';
|
|
534
|
+
|
|
535
|
+
const index = new FuzzyObjectIndex(users, {
|
|
536
|
+
keys: [{ name: 'name', weight: 2.0 }, 'email'],
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
$: results = query ? index.search(query).map((r) => r.item) : users;
|
|
540
|
+
|
|
541
|
+
onDestroy(() => index.destroy());
|
|
542
|
+
</script>
|
|
543
|
+
|
|
544
|
+
<input bind:value={query} placeholder="Search…" />
|
|
545
|
+
<ul>{#each results as u}<li>{u.name}</li>{/each}</ul>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
> **Note**: Always call `index.destroy()` in your cleanup handler (`useEffect` return, `onUnmounted`, `onDestroy`) to free Rust-side memory.
|
|
549
|
+
|
|
276
550
|
## Choosing an Algorithm
|
|
277
551
|
|
|
278
552
|
| Use case | Recommended | Why |
|
|
279
553
|
|---|---|---|
|
|
280
554
|
| Typo detection / spell check | `levenshtein`, `damerauLevenshtein` | Counts edits; Damerau adds transposition support |
|
|
281
|
-
|
|
|
555
|
+
| Insertion/deletion only edits | `indel`, `normalizedIndel` | No substitutions — useful for diff-like or DNA alignment scenarios |
|
|
556
|
+
| Fixed-length comparison | `hamming`, `normalizedHamming` | Counts differing positions; only for equal-length strings |
|
|
282
557
|
| Name / address matching | `jaroWinkler`, `tokenSortRatio` | Prefix-weighted or order-independent matching |
|
|
558
|
+
| Character-level similarity | `jaro` | Good baseline similarity without prefix weighting |
|
|
283
559
|
| Document / text similarity | `sorensenDice` | Bigram-based; handles longer text well |
|
|
284
560
|
| Normalized comparison (0–1) | `normalizedLevenshtein` | Length-independent similarity score |
|
|
285
561
|
| Reordered words / messy data | `tokenSortRatio`, `tokenSetRatio` | Handles word order differences and extra tokens |
|
|
@@ -290,8 +566,9 @@ jaroWinklerMany('MARTHA', candidates, 0.8); // minSimilarity → returns 0
|
|
|
290
566
|
|
|
291
567
|
**Return types:**
|
|
292
568
|
|
|
293
|
-
- `levenshtein`, `damerauLevenshtein`, `hamming` → integer (edit/difference count; `hamming` returns `null` if lengths differ)
|
|
294
|
-
- `jaro`, `jaroWinkler`, `sorensenDice`, `normalizedLevenshtein` → float between 0.0 (no match) and 1.0 (identical)
|
|
569
|
+
- `levenshtein`, `damerauLevenshtein`, `hamming`, `indel` → integer (edit/difference count; `hamming` returns `null` if lengths differ)
|
|
570
|
+
- `jaro`, `jaroWinkler`, `sorensenDice`, `normalizedLevenshtein`, `normalizedIndel` → float between 0.0 (no match) and 1.0 (identical)
|
|
571
|
+
- `normalizedHamming` → float between 0.0 and 1.0 (`null` if lengths differ)
|
|
295
572
|
- `tokenSortRatio`, `tokenSetRatio`, `partialRatio`, `weightedRatio` → float between 0.0 and 1.0
|
|
296
573
|
- `search` → array of `{ item, score, index, positions }` sorted by relevance (score: 0.0–1.0)
|
|
297
574
|
|
package/browser.js
CHANGED
package/highlight.d.mts
ADDED
package/index.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
export * from './index.
|
|
2
|
-
export { highlight, highlightRanges } from './highlight.
|
|
3
|
-
export type { HighlightRange } from './highlight.
|
|
4
|
-
export { searchObjects, FuzzyObjectIndex } from './objects';
|
|
1
|
+
export * from './index.js';
|
|
2
|
+
export { highlight, highlightRanges } from './highlight.js';
|
|
3
|
+
export type { HighlightRange } from './highlight.js';
|
|
4
|
+
export { searchObjects, FuzzyObjectIndex } from './objects.js';
|
|
5
5
|
export type {
|
|
6
6
|
KeyConfig,
|
|
7
7
|
ObjectSearchOptions,
|
|
8
8
|
ObjectSearchResult,
|
|
9
9
|
ObjectIndexOptions,
|
|
10
10
|
ObjectIndexSearchOptions,
|
|
11
|
-
} from './objects';
|
|
11
|
+
} from './objects.js';
|
package/index.d.ts
CHANGED
|
@@ -13,6 +13,13 @@
|
|
|
13
13
|
export declare class FuzzyIndex {
|
|
14
14
|
/** Create a new FuzzyIndex from an array of strings. */
|
|
15
15
|
constructor(items: Array<string>)
|
|
16
|
+
/**
|
|
17
|
+
* Construct a FuzzyIndex on the libuv thread pool, returning a Promise.
|
|
18
|
+
*
|
|
19
|
+
* For large datasets this keeps the JavaScript event loop unblocked during
|
|
20
|
+
* index construction. The synchronous constructor is fine for small datasets.
|
|
21
|
+
*/
|
|
22
|
+
static fromAsync(items: Array<string>): Promise<FuzzyIndex>
|
|
16
23
|
/** Return the number of items in the index. */
|
|
17
24
|
get size(): number
|
|
18
25
|
/**
|
|
@@ -44,7 +51,7 @@ export declare class FuzzyIndex {
|
|
|
44
51
|
/**
|
|
45
52
|
* Remove the item at the given index.
|
|
46
53
|
*
|
|
47
|
-
* Returns false if
|
|
54
|
+
* Uses swap-remove for O(1) performance. Returns false if out of bounds.
|
|
48
55
|
*/
|
|
49
56
|
remove(index: number): boolean
|
|
50
57
|
/** Free the internal data. After calling this, the index is empty. */
|
|
@@ -94,6 +101,15 @@ export declare class KeyedFuzzyIndex {
|
|
|
94
101
|
* Returns results sorted by combined weighted score (best match first).
|
|
95
102
|
*/
|
|
96
103
|
search(query: string, options?: SearchOptions | undefined | null): Array<KeySearchResult>
|
|
104
|
+
/**
|
|
105
|
+
* Find the index of the closest matching item.
|
|
106
|
+
*
|
|
107
|
+
* Returns the index of the best match, or null if no match is found.
|
|
108
|
+
* If `min_score` is provided, returns null when the best match scores below the threshold.
|
|
109
|
+
*
|
|
110
|
+
* Use the returned index to look up the item in your own data array.
|
|
111
|
+
*/
|
|
112
|
+
closest(query: string, minScore?: number | undefined | null): number | null
|
|
97
113
|
/**
|
|
98
114
|
* Add a single item to the index.
|
|
99
115
|
*
|
|
@@ -116,6 +132,16 @@ export declare class KeyedFuzzyIndex {
|
|
|
116
132
|
remove(index: number): boolean
|
|
117
133
|
/** Free the internal data. After calling this, the index is empty. */
|
|
118
134
|
destroy(): void
|
|
135
|
+
/**
|
|
136
|
+
* Serialize the index to a compact binary format.
|
|
137
|
+
*
|
|
138
|
+
* The returned Buffer can be written to disk, stored in IndexedDB,
|
|
139
|
+
* or transferred over the network. Use `KeyedFuzzyIndex.deserialize()` to
|
|
140
|
+
* reconstruct the index.
|
|
141
|
+
*/
|
|
142
|
+
serialize(): Buffer
|
|
143
|
+
/** Reconstruct a KeyedFuzzyIndex from a previously serialized Buffer. */
|
|
144
|
+
static deserialize(data: Buffer): KeyedFuzzyIndex
|
|
119
145
|
}
|
|
120
146
|
|
|
121
147
|
/**
|
|
@@ -178,6 +204,35 @@ export declare function hammingBatch(pairs: Array<Array<string>>): Array<number
|
|
|
178
204
|
*/
|
|
179
205
|
export declare function hammingMany(reference: string, candidates: Array<string>, maxDistance?: number | undefined | null): Array<number | undefined | null>
|
|
180
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Compute the Indel distance between two strings.
|
|
209
|
+
*
|
|
210
|
+
* The Indel distance counts the minimum number of insertions and deletions
|
|
211
|
+
* (no substitutions) required to transform one string into the other.
|
|
212
|
+
* It equals `len(a) + len(b) - 2 * LCS_length(a, b)`.
|
|
213
|
+
*
|
|
214
|
+
* Useful when substitutions are semantically two operations (one deletion +
|
|
215
|
+
* one insertion), such as in DNA sequence alignment.
|
|
216
|
+
*/
|
|
217
|
+
export declare function indel(a: string, b: string): number
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Compute the Indel distance for multiple pairs of strings in a single call.
|
|
221
|
+
*
|
|
222
|
+
* Returns an array of distances in the same order as the input pairs.
|
|
223
|
+
* Each pair must be an array of exactly two strings `[a, b]`.
|
|
224
|
+
*/
|
|
225
|
+
export declare function indelBatch(pairs: Array<Array<string>>): Array<number>
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Compute the Indel distance from one reference string to many candidates.
|
|
229
|
+
*
|
|
230
|
+
* Returns an array of distances, one per candidate, in the same order as the input.
|
|
231
|
+
* If `max_distance` is provided, candidates with distance exceeding the threshold
|
|
232
|
+
* will return `max_distance + 1` (enabling early termination for better performance).
|
|
233
|
+
*/
|
|
234
|
+
export declare function indelMany(reference: string, candidates: Array<string>, maxDistance?: number | undefined | null): Array<number>
|
|
235
|
+
|
|
181
236
|
/**
|
|
182
237
|
* A lightweight search result containing only index and score (no item string).
|
|
183
238
|
*
|
|
@@ -304,6 +359,55 @@ export declare const enum MatchType {
|
|
|
304
359
|
Fuzzy = 'Fuzzy'
|
|
305
360
|
}
|
|
306
361
|
|
|
362
|
+
/**
|
|
363
|
+
* Compute the normalized Hamming similarity between two strings.
|
|
364
|
+
*
|
|
365
|
+
* Returns `null` if the strings have different lengths.
|
|
366
|
+
* Returns a value between 0.0 (no matching characters) and 1.0 (identical).
|
|
367
|
+
*/
|
|
368
|
+
export declare function normalizedHamming(a: string, b: string): number | null
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Compute the normalized Hamming similarity for multiple pairs of strings in a single call.
|
|
372
|
+
*
|
|
373
|
+
* Returns an array of scores in the same order as the input pairs.
|
|
374
|
+
* Returns `null` for pairs with different lengths.
|
|
375
|
+
*/
|
|
376
|
+
export declare function normalizedHammingBatch(pairs: Array<Array<string>>): Array<number | undefined | null>
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Compute the normalized Hamming similarity from one reference string to many candidates.
|
|
380
|
+
*
|
|
381
|
+
* Returns an array of scores, one per candidate, in the same order as the input.
|
|
382
|
+
* Returns `null` for candidates with a different length than the reference.
|
|
383
|
+
* If `min_similarity` is provided, candidates with similarity below the threshold
|
|
384
|
+
* will also return `null` (enabling early termination for better performance).
|
|
385
|
+
*/
|
|
386
|
+
export declare function normalizedHammingMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number | undefined | null>
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Compute the normalized Indel similarity between two strings.
|
|
390
|
+
*
|
|
391
|
+
* Returns a value between 0.0 (completely different) and 1.0 (identical).
|
|
392
|
+
*/
|
|
393
|
+
export declare function normalizedIndel(a: string, b: string): number
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Compute the normalized Indel similarity for multiple pairs of strings in a single call.
|
|
397
|
+
*
|
|
398
|
+
* Returns an array of similarity scores in the same order as the input pairs.
|
|
399
|
+
*/
|
|
400
|
+
export declare function normalizedIndelBatch(pairs: Array<Array<string>>): Array<number>
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Compute the normalized Indel similarity from one reference string to many candidates.
|
|
404
|
+
*
|
|
405
|
+
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
406
|
+
* If `min_similarity` is provided, candidates with similarity below the threshold
|
|
407
|
+
* will return `0.0` (enabling early termination for better performance).
|
|
408
|
+
*/
|
|
409
|
+
export declare function normalizedIndelMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
410
|
+
|
|
307
411
|
/**
|
|
308
412
|
* Compute the normalized Levenshtein similarity between two strings.
|
|
309
413
|
*
|
|
@@ -348,8 +452,9 @@ export declare function partialRatioBatch(pairs: Array<Array<string>>): Array<nu
|
|
|
348
452
|
* Compute the partial ratio from one reference string to many candidates.
|
|
349
453
|
*
|
|
350
454
|
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
455
|
+
* If `min_similarity` is provided, candidates scoring below the threshold return `0.0`.
|
|
351
456
|
*/
|
|
352
|
-
export declare function partialRatioMany(reference: string, candidates: Array<string
|
|
457
|
+
export declare function partialRatioMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
353
458
|
|
|
354
459
|
/**
|
|
355
460
|
* Perform fuzzy search over a list of strings.
|
|
@@ -436,8 +541,10 @@ export declare function sorensenDiceBatch(pairs: Array<Array<string>>): Array<nu
|
|
|
436
541
|
* Compute the Sorensen-Dice coefficient from one reference string to many candidates.
|
|
437
542
|
*
|
|
438
543
|
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
544
|
+
* If `min_similarity` is provided, candidates scoring below the threshold return `0.0`.
|
|
545
|
+
* Reference bigrams are pre-computed once and reused for all candidates.
|
|
439
546
|
*/
|
|
440
|
-
export declare function sorensenDiceMany(reference: string, candidates: Array<string
|
|
547
|
+
export declare function sorensenDiceMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
441
548
|
|
|
442
549
|
/**
|
|
443
550
|
* Compute the token set ratio between two strings.
|
|
@@ -460,8 +567,9 @@ export declare function tokenSetRatioBatch(pairs: Array<Array<string>>): Array<n
|
|
|
460
567
|
* Compute the token set ratio from one reference string to many candidates.
|
|
461
568
|
*
|
|
462
569
|
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
570
|
+
* If `min_similarity` is provided, candidates scoring below the threshold return `0.0`.
|
|
463
571
|
*/
|
|
464
|
-
export declare function tokenSetRatioMany(reference: string, candidates: Array<string
|
|
572
|
+
export declare function tokenSetRatioMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
465
573
|
|
|
466
574
|
/**
|
|
467
575
|
* Compute the token sort ratio between two strings.
|
|
@@ -484,8 +592,9 @@ export declare function tokenSortRatioBatch(pairs: Array<Array<string>>): Array<
|
|
|
484
592
|
* Compute the token sort ratio from one reference string to many candidates.
|
|
485
593
|
*
|
|
486
594
|
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
595
|
+
* If `min_similarity` is provided, candidates scoring below the threshold return `0.0`.
|
|
487
596
|
*/
|
|
488
|
-
export declare function tokenSortRatioMany(reference: string, candidates: Array<string
|
|
597
|
+
export declare function tokenSortRatioMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
489
598
|
|
|
490
599
|
/**
|
|
491
600
|
* Compute the weighted ratio between two strings.
|
|
@@ -508,8 +617,22 @@ export declare function weightedRatioBatch(pairs: Array<Array<string>>): Array<n
|
|
|
508
617
|
* Compute the weighted ratio from one reference string to many candidates.
|
|
509
618
|
*
|
|
510
619
|
* Returns an array of similarity scores, one per candidate, in the same order as the input.
|
|
620
|
+
* If `min_similarity` is provided, candidates scoring below the threshold return `0.0`.
|
|
511
621
|
*/
|
|
512
|
-
export declare function weightedRatioMany(reference: string, candidates: Array<string
|
|
622
|
+
export declare function weightedRatioMany(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Array<number>
|
|
513
623
|
|
|
514
624
|
// --- JS utilities (appended by scripts/patch-binding.js) ---
|
|
515
625
|
export { highlight, highlightRanges, HighlightRange } from './highlight';
|
|
626
|
+
/** TypedArray variants — identical to the `*Many` counterparts but return a typed array instead of `Array<number>`, reducing GC pressure for large candidate sets. */
|
|
627
|
+
export declare function levenshteinManyU32(reference: string, candidates: Array<string>, maxDistance?: number | undefined | null): Uint32Array;
|
|
628
|
+
export declare function damerauLevenshteinManyU32(reference: string, candidates: Array<string>, maxDistance?: number | undefined | null): Uint32Array;
|
|
629
|
+
export declare function indelManyU32(reference: string, candidates: Array<string>, maxDistance?: number | undefined | null): Uint32Array;
|
|
630
|
+
export declare function jaroManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
631
|
+
export declare function jaroWinklerManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
632
|
+
export declare function sorensenDiceManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
633
|
+
export declare function normalizedLevenshteinManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
634
|
+
export declare function normalizedIndelManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
635
|
+
export declare function tokenSortRatioManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
636
|
+
export declare function tokenSetRatioManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
637
|
+
export declare function partialRatioManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|
|
638
|
+
export declare function weightedRatioManyF64(reference: string, candidates: Array<string>, minSimilarity?: number | undefined | null): Float64Array;
|