{"_id":"@3leaps/string-metrics-wasm","_rev":"6-3efef86b445d7529622d69c8c15f5ea3","name":"@3leaps/string-metrics-wasm","dist-tags":{"latest":"0.3.11"},"versions":{"0.3.5":{"name":"@3leaps/string-metrics-wasm","version":"0.3.5","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","_id":"@3leaps/string-metrics-wasm@0.3.5","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"dist":{"shasum":"6fdc330ca006c7c534d3e04fb0606b854604ba0c","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.5.tgz","fileCount":23,"integrity":"sha512-exE7w3A8s4gusaNVgl3aMy1qe6ry2ymyWrBDKkk/aecUoTgq+wcAFxweRaVofoRLm0rwRa2wEavx/BX2grIW0w==","signatures":[{"sig":"MEYCIQC2hDg7b0Axkx/RAtkiKRAQlr7jOTxeGckH9InSq7+FPQIhAIhWQ+F4aWvB+T6qZ+3jdKXk+q4i1o8G0Qbb1lEozNhu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":159591},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"4b7c52ac76b96497eca6f79cb4f2fa1226039ad6","scripts":{"lint":"biome lint src/","test":"vitest --run","bench":"node bench.js","build":"npm run build:wasm && npm run build:ts","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","prepare":"husky","pretest":"make version-check","quality":"make quality","build:ts":"tsc","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","build:wasm":"wasm-pack build --target web --out-dir pkg/web","test:watch":"vitest","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","version:sync":"make version-sync","license:check":"node scripts/check-licenses.js","test:coverage":"vitest --run --coverage","version:check":"make version-check","prepublishOnly":"make quality && make build"},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"repository":{"url":"git+https://github.com/3leaps/string-metrics-wasm.git","type":"git"},"_npmVersion":"11.6.2","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","vitest":"^1.0.0","js-yaml":"^4.1.0","prettier":"^3.6.0","wasm-pack":"^0.13.0","typescript":"^5.0.0","@types/node":"^20.19.23","@biomejs/biome":"^2.0.0","@types/js-yaml":"^4.0.9","@vitest/browser":"^1.0.0","license-checker":"^25.0.1","@vitest/coverage-v8":"^1.6.1"},"_npmOperationalInternal":{"tmp":"tmp/string-metrics-wasm_0.3.5_1761914300099_0.7707567540114868","host":"s3://npm-registry-packages-npm-production"}},"0.3.7":{"name":"@3leaps/string-metrics-wasm","version":"0.3.7","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","_id":"@3leaps/string-metrics-wasm@0.3.7","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"dist":{"shasum":"72f0d235689992c2151ea06bbd965425213ebf92","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.7.tgz","fileCount":30,"integrity":"sha512-gcy69pyQ5GclNXdGa0CyDGNsD00kYg3VpmDThmpquikEIftfM57NzL5+S/ATilSAtqNQf8u4E8g0LC3WUo3AeQ==","signatures":[{"sig":"MEYCIQDQKesmRpdVVZN2fCm86/YX9nt1qAgVulohsXdgyfHanAIhAORc8fTIuYgIFZXDH/rls7A0SxwVEia1KSDjs55Vg9t6","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":430626},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"c289b42fb602f44abc5de0ddcb7e7a8e915bae9b","scripts":{"lint":"biome lint src/","test":"vitest --run","bench":"node bench.js","build":"npm run build:wasm && npm run build:ts","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","prepare":"husky","pretest":"make version-check","quality":"make quality","build:ts":"tsc","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","build:wasm":"wasm-pack build --target web --out-dir pkg/web && node scripts/prepare-wasm-package.js","test:watch":"vitest","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","version:sync":"make version-sync","license:check":"node scripts/check-licenses.js","test:coverage":"vitest --run --coverage","version:check":"make version-check","prepublishOnly":"make quality && make build"},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"repository":{"url":"git+https://github.com/3leaps/string-metrics-wasm.git","type":"git"},"_npmVersion":"11.6.2","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","vitest":"^1.0.0","js-yaml":"^4.1.0","prettier":"^3.6.0","wasm-pack":"^0.13.0","typescript":"^5.0.0","@types/node":"^20.19.23","@biomejs/biome":"^2.0.0","@types/js-yaml":"^4.0.9","@vitest/browser":"^1.0.0","license-checker":"^25.0.1","@vitest/coverage-v8":"^1.6.1"},"_npmOperationalInternal":{"tmp":"tmp/string-metrics-wasm_0.3.7_1761932069212_0.12916989197119477","host":"s3://npm-registry-packages-npm-production"}},"0.3.8":{"name":"@3leaps/string-metrics-wasm","version":"0.3.8","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","_id":"@3leaps/string-metrics-wasm@0.3.8","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"dist":{"shasum":"7bffbf6da7cc0774dd702c3ead69580eef85107c","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.8.tgz","fileCount":30,"integrity":"sha512-iOz4DtbIrioueluUsR/sMkO5i/o0UMhCX7GNUvZKOIweVA8nHGjbojfuFQCVQGKbckF/L4fvHJtakFMPe7YvWg==","signatures":[{"sig":"MEUCIFrZYa+YjPNo6/eBy+JdzVMiGnJSgCOFZs6Cm4AFvjnVAiEApZNOW92wWFfmUyhSPefsRO0D0iLvXRGaeGc4HUCeUqk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":439004},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"c4c9215d15af848faa2631d760ecdc724fd74b21","scripts":{"lint":"biome lint src/","test":"vitest --run","bench":"node bench.js","build":"npm run build:wasm && npm run build:ts","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","prepare":"husky","pretest":"make version-check","quality":"make quality","build:ts":"tsc","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","build:wasm":"wasm-pack build --target web --out-dir pkg/web && node scripts/prepare-wasm-package.js","test:watch":"vitest","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","version:sync":"make version-sync","license:check":"node scripts/check-licenses.js","test:coverage":"vitest --run --coverage","version:check":"make version-check","prepublishOnly":"make quality && make build"},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"repository":{"url":"git+https://github.com/3leaps/string-metrics-wasm.git","type":"git"},"_npmVersion":"11.6.2","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","vitest":"^1.0.0","js-yaml":"^4.1.0","prettier":"^3.6.0","wasm-pack":"^0.13.0","typescript":"^5.0.0","@types/node":"^20.19.23","@biomejs/biome":"^2.0.0","@types/js-yaml":"^4.0.9","@vitest/browser":"^1.0.0","license-checker":"^25.0.1","@vitest/coverage-v8":"^1.6.1"},"_npmOperationalInternal":{"tmp":"tmp/string-metrics-wasm_0.3.8_1761997469319_0.5911267621792793","host":"s3://npm-registry-packages-npm-production"}},"0.3.9":{"name":"@3leaps/string-metrics-wasm","version":"0.3.9","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","_id":"@3leaps/string-metrics-wasm@0.3.9","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"dist":{"shasum":"5c1ae130d919251335c588c2d189e1506c6f46c7","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.9.tgz","fileCount":33,"integrity":"sha512-UQuBqLTcZqo0acn9rKPyJiv2j/uQ77ncCRkwMIiIGR+BCyVOTtw9QW953HVvpRZkwXL88AqXPQkJ9YKCGSIJGg==","signatures":[{"sig":"MEYCIQDwXA6VO4a7Bhc9Y2Py+kaFdIGRhHst2pPdAe4NtiPEZgIhANjBiXQsqbeXZhlMgAaWiZTSsyXDa93MtWyesM7VSKE/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":524073},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"b2dcaed9f094c88954799c619f6baf6394d72ee8","scripts":{"lint":"biome lint src/","test":"vitest --run","bench":"node bench.js","build":"npm run build:wasm && npm run build:ts","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","prepare":"husky","pretest":"make version-check","quality":"make quality","build:ts":"tsc","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","build:wasm":"wasm-pack build --target web --out-dir pkg/web && node scripts/embed-wasm.js && node scripts/prepare-wasm-package.js","test:watch":"vitest","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","version:sync":"make version-sync","license:check":"node scripts/check-licenses.js","test:coverage":"vitest --run --coverage","version:check":"make version-check","prepublishOnly":"make quality && make build"},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"repository":{"url":"git+https://github.com/3leaps/string-metrics-wasm.git","type":"git"},"_npmVersion":"11.13.0","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","vitest":"^4.1.8","js-yaml":"^4.2.0","prettier":"^3.8.4","wasm-pack":"^0.13.1","typescript":"^5.9.3","@types/node":"^24.13.2","@biomejs/biome":"^2.5.0","@types/js-yaml":"^4.0.9","license-checker":"^25.0.1","@vitest/coverage-v8":"^4.1.8"},"_npmOperationalInternal":{"tmp":"tmp/string-metrics-wasm_0.3.9_1781532726748_0.48216461164051694","host":"s3://npm-registry-packages-npm-production"}},"0.3.10":{"name":"@3leaps/string-metrics-wasm","version":"0.3.10","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","_id":"@3leaps/string-metrics-wasm@0.3.10","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"dist":{"shasum":"35811f2c9cbd87f9b854c5f2437df3ed983636ee","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.10.tgz","fileCount":34,"integrity":"sha512-kzBjyyMvTtCjEljHoHgvbDumS3pYL5N3hrPN2bkD0uK8g7kQonYk6F6H2pRZXTPbV7uMduwQML+Tv3ek7JXtrg==","signatures":[{"sig":"MEQCIFrzJC8BTmd1W1+OLeNn1ZyqhbOSJvRVfIsv+XuadzuxAiBJw9vuSmlH1vNjO/tSM96D2piuFRxhNA1fqW3zh+LHGQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":528900},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"244fd13416981e14e64555c52deb3b0b9c0a67f7","scripts":{"lint":"biome lint src/","test":"vitest --run","bench":"node bench.js","build":"npm run build:wasm && npm run build:ts","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","prepare":"husky","pretest":"make version-check","quality":"make quality","build:ts":"tsc","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","build:wasm":"wasm-pack build --target web --out-dir pkg/web && node scripts/embed-wasm.js && node scripts/prepare-wasm-package.js","test:watch":"vitest","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","version:sync":"make version-sync","license:check":"node scripts/check-licenses.js","test:coverage":"vitest --run --coverage","version:check":"make version-check","prepublishOnly":"make quality && make build"},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"repository":{"url":"git+https://github.com/3leaps/string-metrics-wasm.git","type":"git"},"_npmVersion":"11.13.0","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","directories":{},"_nodeVersion":"22.19.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","vitest":"^4.1.8","js-yaml":"^4.2.0","prettier":"^3.8.4","wasm-pack":"^0.13.1","typescript":"^5.9.3","@types/node":"^24.13.2","@biomejs/biome":"^2.5.0","@types/js-yaml":"^4.0.9","license-checker":"^25.0.1","@vitest/coverage-v8":"^4.1.8"},"_npmOperationalInternal":{"tmp":"tmp/string-metrics-wasm_0.3.10_1781565834683_0.697750808761989","host":"s3://npm-registry-packages-npm-production"}},"0.3.11":{"name":"@3leaps/string-metrics-wasm","version":"0.3.11","description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"scripts":{"build:wasm":"wasm-pack build --target web --out-dir pkg/web && node scripts/embed-wasm.js && node scripts/prepare-wasm-package.js","build:ts":"tsc","build":"npm run build:wasm && npm run build:ts","pretest":"make version-check","test":"vitest --run","test:watch":"vitest","test:coverage":"vitest --run --coverage","bench":"node bench.js","version:check":"make version-check","version:sync":"make version-sync","lint":"biome lint src/","lint:fix":"biome lint --write src/","typecheck":"tsc --noEmit","format":"biome format src/ && prettier --write '**/*.{json,yaml,yml,md}'","format:check":"biome format src/ && prettier --check '**/*.{json,yaml,yml,md}'","license:check":"node scripts/check-licenses.js","quality":"make quality","prepare":"husky","prepublishOnly":"make quality && make build"},"keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"author":{"name":"3leaps"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/3leaps/string-metrics-wasm.git"},"devDependencies":{"@biomejs/biome":"^2.5.0","@types/js-yaml":"^4.0.9","@types/node":"^24.13.2","@vitest/coverage-v8":"^4.1.8","husky":"^9.1.7","js-yaml":"^4.2.0","license-checker":"^25.0.1","prettier":"^3.8.4","typescript":"^5.9.3","vitest":"^4.1.8","wasm-pack":"^0.13.1"},"gitHead":"0719822dd08972fb6adfd991e70dd4c1aa1ff922","_id":"@3leaps/string-metrics-wasm@0.3.11","bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"homepage":"https://github.com/3leaps/string-metrics-wasm#readme","_nodeVersion":"22.19.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-An4O6Dd0ZVSn9/xAPJhnLKfMjDvZ5Pa+YuhwnA0gzPRBtRlLkHvYDvi77p/xZORPOKDpm5CVR153NOa1XL/h/w==","shasum":"209d5b1bd2a2b5e731002606720026d54bb46138","tarball":"https://registry.npmjs.org/@3leaps/string-metrics-wasm/-/string-metrics-wasm-0.3.11.tgz","fileCount":35,"unpackedSize":529996,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCletgNwac15DMVtKbEDT7FiOC8ArRqtXOopFw4A9R7bgIhAKgB9VfKp+K/TqrQUweqFyIm8lnX7r4qFe3aVMDeiM94"}]},"_npmUser":{"name":"3leapsdave","email":"dave.thompson@3leaps.net"},"directories":{},"maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/string-metrics-wasm_0.3.11_1781623524630_0.6152628253425845"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-31T12:38:20.024Z","modified":"2026-06-16T15:25:24.949Z","0.3.5":"2025-10-31T12:38:20.694Z","0.3.7":"2025-10-31T17:34:29.413Z","0.3.8":"2025-11-01T11:44:29.557Z","0.3.9":"2026-06-15T14:12:06.932Z","0.3.10":"2026-06-15T23:23:54.828Z","0.3.11":"2026-06-16T15:25:24.782Z"},"bugs":{"url":"https://github.com/3leaps/string-metrics-wasm/issues"},"author":{"name":"3leaps"},"license":"MIT","homepage":"https://github.com/3leaps/string-metrics-wasm#readme","keywords":["wasm","string","similarity","levenshtein","jaro-winkler"],"repository":{"type":"git","url":"git+https://github.com/3leaps/string-metrics-wasm.git"},"description":"High-performance string similarity metrics via WASM bindings to rapidfuzz-rs","maintainers":[{"name":"3leapsdave","email":"dave.thompson@3leaps.net"}],"readme":"# string-metrics-wasm\n\n[![npm version](https://img.shields.io/npm/v/string-metrics-wasm.svg)](https://www.npmjs.com/package/string-metrics-wasm)\n[![license: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\nHigh-performance string similarity and fuzzy matching via WASM bindings to\n[rapidfuzz-rs](https://github.com/rapidfuzz/rapidfuzz-rs).\n\n## Description\n\nThis library provides blazing-fast string similarity metrics through WASM bindings to the Rust\n[rapidfuzz-rs](https://github.com/rapidfuzz/rapidfuzz-rs) library, plus TypeScript implementations\nof advanced fuzzy matching algorithms. It combines the performance of compiled Rust/WASM with the\nflexibility of TypeScript for a comprehensive text similarity toolkit.\n\n**Features:**\n\n- **WASM-powered distance metrics**: Levenshtein, Damerau-Levenshtein, OSA, Jaro, Jaro-Winkler,\n  Indel, LCS\n- **Fuzzy matching**: Token-based comparison (order-insensitive, set-based)\n- **Process helpers**: Find best matches from arrays with configurable scoring\n- **Unified API**: Consistent interface across all metrics\n- **TypeScript extensions**: Substring similarity, normalization presets, suggestions API\n- **Multi-runtime**: Node.js, Bun, Deno support\n\n## Prerequisites\n\n1. Rust toolchain via [rustup](https://rustup.rs/)\n2. `wasm-pack` (pinned to the version we build against)\n\nInstall `wasm-pack` once per machine:\n\n```bash\ncargo install wasm-pack --version 0.13.1\n```\n\n## Installation\n\n```bash\nnpm install string-metrics-wasm\n```\n\n## Quick Start\n\n```typescript\nimport { levenshtein, ratio, tokenSortRatio, extractOne, score } from 'string-metrics-wasm';\n\n// Basic edit distance\nconst dist = levenshtein('kitten', 'sitting');\nconsole.log(dist); // 3\n\n// Fuzzy matching (0-100 scale)\nconst fuzzy = ratio('hello', 'hallo');\nconsole.log(fuzzy); // 80.0\n\n// Order-insensitive comparison\nconst tokens = tokenSortRatio('new york mets', 'mets york new');\nconsole.log(tokens); // 100.0\n\n// Find best match from array\nconst choices = ['Atlanta Falcons', 'New York Jets', 'Dallas Cowboys'];\nconst best = extractOne('new york', choices);\nconsole.log(best); // { choice: 'New York Jets', score: 57.14, index: 1 }\n\n// Unified scoring API (0-1 scale)\nconst similarity = score('hello', 'world', 'jaroWinkler');\nconsole.log(similarity); // 0.4666...\n```\n\n## API Documentation\n\n> Compatibility: All examples use camelCase option names and metric identifiers. For ecosystems that\n> standardize on snake_case (e.g., Fulmen/Crucible fixtures), the same snake_case names are accepted\n> as aliases and normalized internally.\n\n### Distance Metrics (WASM)\n\nEdit distance metrics return raw integer distances (lower = more similar):\n\n#### `levenshtein(a: string, b: string): number`\n\nMinimum edits (insertions, deletions, substitutions) to transform `a` into `b`.\n\n```typescript\nlevenshtein('kitten', 'sitting'); // 3\n```\n\n#### `damerau_levenshtein(a: string, b: string): number`\n\nLevenshtein + transpositions (unrestricted).\n\n```typescript\ndamerau_levenshtein('abcd', 'abdc'); // 1\n```\n\n#### `osa_distance(a: string, b: string): number`\n\nOptimal String Alignment (restricted Damerau-Levenshtein).\n\n```typescript\nosa_distance('abcd', 'abdc'); // 1\n```\n\n#### `indel_distance(a: string, b: string): number`\n\nInsertions and deletions only (no substitutions).\n\n```typescript\nindel_distance('hello', 'hallo'); // 2\n```\n\n#### `lcs_seq_distance(a: string, b: string): number`\n\nLongest Common Subsequence distance.\n\n```typescript\nlcs_seq_distance('AGGTAB', 'GXTXAYB'); // 3\n```\n\n### Similarity Metrics (WASM)\n\nNormalized similarity scores (0.0-1.0 scale, higher = more similar):\n\n#### `normalized_levenshtein(a: string, b: string): number`\n\nNormalized Levenshtein similarity.\n\n```typescript\nnormalized_levenshtein('kitten', 'sitting'); // 0.5714\n```\n\n#### `jaro(a: string, b: string): number`\n\nJaro similarity.\n\n```typescript\njaro('kitten', 'sitting'); // 0.7460\n```\n\n#### `jaro_winkler(a: string, b: string): number`\n\nJaro-Winkler similarity (boosts prefix matches).\n\n```typescript\njaro_winkler('kitten', 'sitting'); // 0.7460\n```\n\n#### `indel_normalized_similarity(a: string, b: string): number`\n\nNormalized indel similarity.\n\n```typescript\nindel_normalized_similarity('hello', 'hallo'); // 0.8\n```\n\n#### `lcs_seq_normalized_similarity(a: string, b: string): number`\n\nNormalized LCS similarity.\n\n```typescript\nlcs_seq_normalized_similarity('AGGTAB', 'GXTXAYB'); // 0.5714\n```\n\n### Fuzzy Matching (WASM + TypeScript)\n\nFuzzy string comparison metrics (0-100 scale):\n\n#### `ratio(a: string, b: string): number` (WASM)\n\nBasic fuzzy similarity using Indel distance.\n\n```typescript\nratio('kitten', 'sitting'); // 61.54\n```\n\n#### `partialRatio(a: string, b: string): number` (TypeScript)\n\nBest matching substring using sliding window.\n\n```typescript\npartialRatio('fuzzy', 'fuzzy wuzzy was a bear'); // 100.0\n```\n\n#### `tokenSortRatio(a: string, b: string): number` (TypeScript)\n\nOrder-insensitive token comparison (sorts tokens first).\n\n```typescript\ntokenSortRatio('new york mets', 'mets york new'); // 100.0\n```\n\n#### `tokenSetRatio(a: string, b: string): number` (TypeScript)\n\nSet-based token comparison (handles duplicates and order).\n\n```typescript\ntokenSetRatio('hello world world', 'world hello'); // 100.0\n```\n\n### Process Helpers (TypeScript)\n\nFind best matches from arrays:\n\n#### `extractOne(query: string, choices: string[], options?): ExtractResult | null`\n\nFind the single best match.\n\n**Options:**\n\n- `scorer?: (a: string, b: string) => number` - Scoring function (default: `ratio`)\n- `processor?: (str: string) => string` - Preprocessing function\n- `scoreCutoff?: number` - Minimum score threshold (default: 0)\n\n```typescript\nconst choices = ['Atlanta Falcons', 'New York Jets', 'Dallas Cowboys'];\nconst best = extractOne('jets', choices, { scoreCutoff: 30 });\n// { choice: 'New York Jets', score: 35.29, index: 1 }\n```\n\n#### `extract(query: string, choices: string[], options?): ExtractResult[]`\n\nFind top N matches (sorted by score).\n\n**Options:**\n\n- `scorer?: (a: string, b: string) => number` - Scoring function\n- `processor?: (str: string) => string` - Preprocessing function\n- `scoreCutoff?: number` - Minimum score threshold\n- `limit?: number` - Maximum results to return\n\n```typescript\nconst results = extract('new york', choices, { limit: 2, scoreCutoff: 40 });\n// [\n//   { choice: 'New York Jets', score: 57.14, index: 1 },\n//   { choice: 'New York Giants', score: 52.17, index: 2 }\n// ]\n```\n\n### Unified API (TypeScript)\n\nMetric-selectable interface with consistent scales:\n\n#### `distance(a: string, b: string, metric?: DistanceMetric): number`\n\nCalculate edit distance using any metric (returns raw distance).\n\n**Supported metrics:** `'levenshtein'` (default), `'damerauLevenshtein'`, `'osa'`, `'indel'`,\n`'lcsSeq'`\n\n```typescript\ndistance('hello', 'world'); // 4 (default: levenshtein)\ndistance('hello', 'world', 'indel'); // 8\n```\n\n#### `score(a: string, b: string, metric?: SimilarityMetric): number`\n\nCalculate similarity using any metric (returns 0-1 normalized score).\n\n**Supported metrics:** `'jaroWinkler'` (default), `'levenshtein'`, `'damerauLevenshtein'`, `'osa'`,\n`'jaro'`, `'indel'`, `'lcsSeq'`, `'ratio'`, `'partialRatio'`, `'tokenSortRatio'`, `'tokenSetRatio'`\n\n```typescript\nscore('hello', 'world'); // 0.4666... (default: jaroWinkler)\nscore('new york mets', 'mets york new', 'tokenSortRatio'); // 1.0\n\n// Fulmen/Crucible users: override default metric if needed\nscore('hello', 'world', 'levenshtein'); // 0.5714 (edit distance-based)\n```\n\n### Normalization & Suggestions\n\n#### `normalize(input: string, preset?: NormalizationPreset, locale?: NormalizationLocale): string`\n\nNormalize text for comparison with optional locale-specific case folding.\n\n**Presets:** `'none'`, `'minimal'`, `'default'`, `'aggressive'`\n\n**Locales:** `'tr'` (Turkish), `'az'` (Azerbaijani), `'lt'` (Lithuanian), or `undefined` (default\nUnicode casefold)\n\n```typescript\nnormalize('Naïve Café', 'default'); // 'naïve café'\n\n// Turkish/Azerbaijani: dotted/dotless I handling\nnormalize('İstanbul', 'default', 'tr'); // 'istanbul' (İ→i)\nnormalize('IĞDIR', 'default', 'tr'); // 'ığdır' (I→ı dotless)\n\n// Default Unicode casefold (no locale)\nnormalize('İstanbul', 'default'); // 'i̇stanbul' (İ→i + combining dot)\n```\n\n**Note:** Most applications don't need locale-specific normalization. Only use when processing\nTurkish, Azerbaijani, or Lithuanian text where dotted/dotless I distinction matters.\n\n#### `suggest(query: string, candidates: string[], options?): Suggestion[]`\n\nGet ranked suggestions with detailed scoring.\n\n```typescript\nconst suggestions = suggest('pythn', ['python', 'java', 'javascript'], {\n  metric: 'jaroWinkler',\n  minScore: 0.6,\n  maxSuggestions: 3,\n});\n// [\n//   { value: 'python', score: 0.9555, ... },\n//   ...\n// ]\n```\n\nSee [Suggestions API docs](docs/user-guide/suggestions-api.md) for full details.\n\n## Implementation Details\n\n### WASM vs TypeScript\n\nThis library uses a hybrid approach for optimal performance and flexibility:\n\n**WASM Implementations** (fastest):\n\n- Core distance metrics: `levenshtein`, `damerau_levenshtein`, `osa_distance`, `jaro`,\n  `jaro_winkler`\n- RapidFuzz metrics: `ratio`, `indel_*`, `lcs_seq_*`\n\n**TypeScript Implementations** (flexible):\n\n- Token-based fuzzy matching: `partialRatio`, `tokenSortRatio`, `tokenSetRatio`\n- Process helpers: `extractOne`, `extract`\n- Unified API: `distance()`, `score()`\n- Suggestions and normalization\n\nToken-based metrics benefit from TypeScript's array operations and avoid WASM serialization\noverhead. The unified API provides a convenient abstraction over both WASM and TypeScript\nimplementations.\n\n### WASM Initialization\n\nThe WASM binary is embedded in the published JavaScript and initialized **lazily on first use** —\nimporting the package performs no work and reads no files. Initialization is synchronous, so the\npublic API stays synchronous; the first call to a metric triggers a one-time module instantiation.\n\nBecause the bytes are embedded rather than read from a sibling `.wasm` file at runtime, the library\nworks inside bundlers and **standalone compiled binaries** (e.g. `bun build --compile`) without any\nextra asset-handling configuration.\n\n### Supported Runtimes\n\n- **Node.js** 16+ (ESM and CommonJS)\n- **Bun** (native ESM support)\n- **Deno** (use `npm:` specifier)\n\n## Building from Source\n\n1. Install dependencies and tooling: `make bootstrap`\n2. Build WASM: `npm run build:wasm` or `make build`\n3. Build TS: `npm run build:ts`\n\n## Development\n\nThis project uses a Makefile for common tasks:\n\n```bash\nmake help           # Show all available targets\nmake build          # Build WASM and TypeScript (with version check)\nmake test           # Run tests\nmake clean          # Remove build artifacts\n\n# Code quality\nmake quality        # Run all quality checks (format-check, lint, rust checks)\nmake format         # Format all code (Biome + Prettier + rustfmt)\nmake format-check   # Check formatting without changes\nmake lint           # Lint TypeScript code with Biome\nmake lint-fix       # Lint and auto-fix TypeScript code\n\n# Version management\nmake version-check  # Verify package.json and Cargo.toml versions match\nmake bump-patch     # Bump patch version (0.1.0 -> 0.1.1)\nmake bump-minor     # Bump minor version (0.1.0 -> 0.2.0)\nmake bump-major     # Bump major version (0.1.0 -> 1.0.0)\nmake set-version VERSION=x.y.z  # Set explicit version\n```\n\nExplore the rest of the documentation under [`docs/`](docs/). Start with the high-level\n[overview](docs/README.md) or jump straight to the contributor guide in\n[`docs/development.md`](docs/development.md).\n\n### Code Quality Tools\n\nThis project uses modern, fast tooling for code quality:\n\n- **TypeScript/JavaScript**: [Biome](https://biomejs.dev/) for linting and formatting\n- **JSON/YAML/Markdown**: [Prettier](https://prettier.io/) for formatting\n- **Rust**: `rustfmt` for formatting, `clippy` for linting\n\nRun `make quality` before committing to ensure all checks pass.\n\n### Version Management\n\nThis project maintains version sync between `package.json` (npm) and `Cargo.toml` (Rust). The\nMakefile provides targets to bump versions and keep them in sync. Additionally, the test suite\nincludes a version consistency check that will fail if versions drift.\n\n**Important**: Always use `make bump-*` or `make set-version` commands to update versions. This\nensures both files stay synchronized.\n\n## Performance\n\nAll string comparison operations complete in **< 1ms**:\n\n- WASM metrics: **0.0003-0.0005ms** per operation\n- Token-based metrics: **0.0003-0.0017ms** per operation\n- Process helpers: **0.0008-0.001ms** per operation\n- Unified API: **minimal dispatch overhead**\n\nRun `node benchmark-phase1b.js` for detailed benchmarks.\n\n## Testing\n\nThis project includes comprehensive test coverage:\n\n- **119 unit tests** covering all functions\n- **80 YAML fixture test cases** for reproducibility\n- **100% regression-free** across all releases\n\nRun tests with `npm test` or `make test`.\n\n## Related Projects\n\n- [rapidfuzz-rs](https://github.com/rapidfuzz/rapidfuzz-rs) - Rust implementation of RapidFuzz\n- [rapidfuzz](https://github.com/rapidfuzz/RapidFuzz) - Original Python implementation\n- [strsim-rs](https://github.com/dguo/strsim-rs) - String similarity metrics (deprecated in favor of\n  rapidfuzz-rs)\n\n## Versioning\n\nThis project follows [Semantic Versioning](https://semver.org/). Version history is maintained in\n[CHANGELOG.md](CHANGELOG.md).\n\n**Current Status**: See\n[latest release](https://github.com/3leaps/string-metrics-wasm/releases/latest) for the current\nversion and changes.\n\n## License\n\nThis project is licensed under the [MIT License](LICENSE).\n\n## Contributing\n\nContributions welcome! Please see our contributing guidelines:\n\n- **Development setup:** [docs/development.md](docs/development.md)\n- **Release workflow (maintainers):** [docs/publishing.md](docs/publishing.md)\n\n## Governance\n\n- Authoritative policies repository: https://github.com/3leaps/oss-policies/\n- Code of Conduct: https://github.com/3leaps/oss-policies/blob/main/CODE_OF_CONDUCT.md\n- Security Policy: https://github.com/3leaps/oss-policies/blob/main/SECURITY.md\n- Contributing Guide: https://github.com/3leaps/oss-policies/blob/main/CONTRIBUTING.md\n\n---\n\n---\n\n<div align=\"center\">\n\n⚡ **Fast Strings. Accurate Matches.** ⚡\n\n_High-performance text similarity for modern TypeScript applications_\n\n<br><br>\n\n**Built with ⚡ by the 3 Leaps team**\n\n**String Metrics** • **Fuzzy Matching** • **WASM Performance**\n\n</div>\n","readmeFilename":"README.md"}