aboutsummaryrefslogtreecommitdiff
path: root/src/lib/components/fuzzy-search.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/components/fuzzy-search.ts')
-rw-r--r--src/lib/components/fuzzy-search.ts25
1 files changed, 25 insertions, 0 deletions
diff --git a/src/lib/components/fuzzy-search.ts b/src/lib/components/fuzzy-search.ts
new file mode 100644
index 0000000..31597b0
--- /dev/null
+++ b/src/lib/components/fuzzy-search.ts
@@ -0,0 +1,25 @@
+import fuzzysort, { type KeyResult } from 'fuzzysort';
+
+export type FuzzyItem = { id: number; name: string };
+
+export const FUZZ_LIMIT = 8;
+export const FUZZ_THRESHOLD = 0.2;
+
+export type FuzzyMatch = KeyResult<FuzzyItem>;
+
+/** Fuzzy-match `items` against `query`, ranked best-first. Empty/whitespace
+ * query returns no matches. Results carry `.score`, `.target`, `.highlight()`
+ * and `.obj` (the matched item). */
+export function matchItems(
+ items: FuzzyItem[],
+ query: string,
+ {
+ limit = FUZZ_LIMIT,
+ threshold = FUZZ_THRESHOLD,
+ }: { limit?: number; threshold?: number } = {},
+): FuzzyMatch[] {
+ const q = query.trim();
+ if (q === '') return [];
+ const snap = fuzzysort.snapshot(items, { key: 'name' });
+ return Array.from(fuzzysort.go(q, snap, { limit, threshold }));
+}