aboutsummaryrefslogtreecommitdiff
path: root/src/lib/components/fuzzy-search.ts
blob: ade48fe739a3816016aae17b7590c6ec3e0aba9d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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<T extends FuzzyItem = FuzzyItem> = KeyResult<T>;

/** 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<T extends FuzzyItem>(
	items: T[],
	query: string,
	{
		limit = FUZZ_LIMIT,
		threshold = FUZZ_THRESHOLD,
	}: { limit?: number; threshold?: number } = {},
): FuzzyMatch<T>[] {
	const q = query.trim();
	if (q === '') return [];
	const snap = fuzzysort.snapshot(items, { key: 'name' });
	return Array.from(fuzzysort.go(q, snap, { limit, threshold }));
}