rapid-fuzzy 1.1.1 → 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 +244 -21
- package/browser.js +1 -1
- package/index.d.ts +128 -5
- package/index.js +74 -52
- package/index.mjs +21 -0
- package/objects.d.ts +13 -0
- package/objects.js +55 -5
- package/package.json +20 -12
- 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
|
@@ -51,14 +51,8 @@ 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
|
-
- **
|
|
55
|
-
|
|
56
|
-
> **Browser WASM requirement**: The WASM build uses `SharedArrayBuffer` for threading, which requires the following HTTP headers on your page:
|
|
57
|
-
> ```
|
|
58
|
-
> Cross-Origin-Opener-Policy: same-origin
|
|
59
|
-
> Cross-Origin-Embedder-Policy: require-corp
|
|
60
|
-
> ```
|
|
61
|
-
> Without these headers, you will see `SharedArrayBuffer is not defined`. See [MDN: SharedArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer#security_requirements) for details.
|
|
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.
|
|
62
56
|
|
|
63
57
|
### Framework Integration (SSR)
|
|
64
58
|
|
|
@@ -84,7 +78,83 @@ export default {
|
|
|
84
78
|
};
|
|
85
79
|
```
|
|
86
80
|
|
|
87
|
-
On the client side, rapid-fuzzy automatically falls back to WASM — no additional configuration needed
|
|
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.
|
|
88
158
|
|
|
89
159
|
## API
|
|
90
160
|
|
|
@@ -127,12 +197,25 @@ closest('xyz', items, 0.5);
|
|
|
127
197
|
### String Distance
|
|
128
198
|
|
|
129
199
|
```typescript
|
|
130
|
-
import {
|
|
200
|
+
import {
|
|
201
|
+
levenshtein,
|
|
202
|
+
jaro,
|
|
203
|
+
jaroWinkler,
|
|
204
|
+
sorensenDice,
|
|
205
|
+
hamming,
|
|
206
|
+
normalizedHamming,
|
|
207
|
+
indel,
|
|
208
|
+
normalizedIndel,
|
|
209
|
+
} from 'rapid-fuzzy';
|
|
131
210
|
|
|
132
211
|
levenshtein('kitten', 'sitting'); // 3
|
|
133
|
-
|
|
212
|
+
jaro('martha', 'marhta'); // 0.944 (similarity between 0–1)
|
|
213
|
+
jaroWinkler('MARTHA', 'MARHTA'); // 0.961 (jaro + prefix bonus)
|
|
134
214
|
sorensenDice('night', 'nacht'); // 0.25
|
|
135
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)
|
|
136
219
|
```
|
|
137
220
|
|
|
138
221
|
### Query Syntax
|
|
@@ -195,6 +278,9 @@ const index = new FuzzyIndex(['TypeScript', 'JavaScript', 'Python', ...]);
|
|
|
195
278
|
index.search('typscript', { maxResults: 5 });
|
|
196
279
|
index.closest('tsc');
|
|
197
280
|
|
|
281
|
+
// Tip: FuzzyIndex caches results internally — extending a previous query
|
|
282
|
+
// (e.g. typing "app" → "apple") reuses cached candidates for faster lookups.
|
|
283
|
+
|
|
198
284
|
// Index-only results (no string cloning — less GC pressure)
|
|
199
285
|
const hits = index.searchIndices('typscript', { maxResults: 5 });
|
|
200
286
|
// → [{ index: 0, score: 0.85, positions: [] }, ...]
|
|
@@ -233,15 +319,19 @@ This makes FuzzyIndex ideal for search-as-you-type UIs where each keystroke exte
|
|
|
233
319
|
|
|
234
320
|
#### Index Serialization
|
|
235
321
|
|
|
236
|
-
Save a FuzzyIndex to avoid rebuilding on startup:
|
|
322
|
+
Save and restore a `FuzzyIndex` to avoid rebuilding on startup:
|
|
237
323
|
|
|
238
324
|
```typescript
|
|
239
|
-
|
|
240
|
-
|
|
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();
|
|
241
331
|
|
|
242
|
-
//
|
|
243
|
-
const restored = FuzzyIndex.deserialize(
|
|
244
|
-
restored.search('
|
|
332
|
+
// Restore from serialized data
|
|
333
|
+
const restored = FuzzyIndex.deserialize(data);
|
|
334
|
+
restored.search('aple'); // works immediately
|
|
245
335
|
```
|
|
246
336
|
|
|
247
337
|
> **Note:** The serialization format is version-specific. Regenerate the index after updating rapid-fuzzy.
|
|
@@ -301,7 +391,10 @@ All token-based functions include `Batch` and `Many` variants (e.g., `tokenSortR
|
|
|
301
391
|
<details>
|
|
302
392
|
<summary><strong>Batch Operations</strong></summary>
|
|
303
393
|
|
|
304
|
-
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)
|
|
305
398
|
|
|
306
399
|
```typescript
|
|
307
400
|
import { levenshteinBatch, levenshteinMany } from 'rapid-fuzzy';
|
|
@@ -327,13 +420,142 @@ jaroWinklerMany('MARTHA', candidates, 0.8); // minSimilarity → returns 0
|
|
|
327
420
|
|
|
328
421
|
</details>
|
|
329
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
|
+
|
|
330
550
|
## Choosing an Algorithm
|
|
331
551
|
|
|
332
552
|
| Use case | Recommended | Why |
|
|
333
553
|
|---|---|---|
|
|
334
554
|
| Typo detection / spell check | `levenshtein`, `damerauLevenshtein` | Counts edits; Damerau adds transposition support |
|
|
335
|
-
|
|
|
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 |
|
|
336
557
|
| Name / address matching | `jaroWinkler`, `tokenSortRatio` | Prefix-weighted or order-independent matching |
|
|
558
|
+
| Character-level similarity | `jaro` | Good baseline similarity without prefix weighting |
|
|
337
559
|
| Document / text similarity | `sorensenDice` | Bigram-based; handles longer text well |
|
|
338
560
|
| Normalized comparison (0–1) | `normalizedLevenshtein` | Length-independent similarity score |
|
|
339
561
|
| Reordered words / messy data | `tokenSortRatio`, `tokenSetRatio` | Handles word order differences and extra tokens |
|
|
@@ -344,8 +566,9 @@ jaroWinklerMany('MARTHA', candidates, 0.8); // minSimilarity → returns 0
|
|
|
344
566
|
|
|
345
567
|
**Return types:**
|
|
346
568
|
|
|
347
|
-
- `levenshtein`, `damerauLevenshtein`, `hamming` → integer (edit/difference count; `hamming` returns `null` if lengths differ)
|
|
348
|
-
- `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)
|
|
349
572
|
- `tokenSortRatio`, `tokenSetRatio`, `partialRatio`, `weightedRatio` → float between 0.0 and 1.0
|
|
350
573
|
- `search` → array of `{ item, score, index, positions }` sorted by relevance (score: 0.0–1.0)
|
|
351
574
|
|
package/browser.js
CHANGED
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
|
/**
|
|
@@ -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;
|