fuzzy babies

This commit is contained in:
Thomas G. Lopes 2025-06-16 20:19:17 +01:00
parent 8a5c3da385
commit 6b46c49c57
2 changed files with 66 additions and 6 deletions

View file

@ -0,0 +1,64 @@
/**
* Generic fuzzy search function that searches through arrays and returns matching items
*
* @param options Configuration object for the fuzzy search
* @returns Array of items that match the search criteria
*/
export default function fuzzysearch<T>(options: {
needle: string;
haystack: T[];
property: keyof T | ((item: T) => string);
}): T[] {
const { needle, haystack, property } = options;
if (!Array.isArray(haystack)) {
throw new Error('Haystack must be an array');
}
if (!property) {
throw new Error('Property selector is required');
}
// Convert needle to lowercase for case-insensitive matching
const lowerNeedle = needle.toLowerCase();
// Filter the haystack to find matching items
return haystack.filter((item) => {
// Extract the string value from the item based on the property selector
const value = typeof property === 'function' ? property(item) : String(item[property]);
// Convert to lowercase for case-insensitive matching
const lowerValue = value.toLowerCase();
// Perform the fuzzy search
return fuzzyMatchString(lowerNeedle, lowerValue);
});
}
/**
* Internal helper function that performs the actual fuzzy string matching
*/
function fuzzyMatchString(needle: string, haystack: string): boolean {
const hlen = haystack.length;
const nlen = needle.length;
if (nlen > hlen) {
return false;
}
if (nlen === hlen) {
return needle === haystack;
}
outer: for (let i = 0, j = 0; i < nlen; i++) {
const nch = needle.charCodeAt(i);
while (j < hlen) {
if (haystack.charCodeAt(j++) === nch) {
continue outer;
}
}
return false;
}
return true;
}

View file

@ -11,6 +11,7 @@
import XIcon from '~icons/lucide/x';
import PlusIcon from '~icons/lucide/plus';
import { models } from '$lib/state/models.svelte';
import fuzzysearch from '$lib/utils/fuzzy-search';
const openRouterKeyQuery = useCachedQuery(api.user_keys.get, {
provider: Provider.OpenRouter,
@ -30,12 +31,7 @@
});
const openRouterModels = $derived(
models.from(Provider.OpenRouter).filter((model) => {
if (search !== '' && !hasOpenRouterKey) return false;
if (!openRouterToggle.value) return false;
return model.name.toLowerCase().includes(search.toLowerCase());
})
fuzzysearch({ haystack: models.from(Provider.OpenRouter), needle: search, property: 'name' })
);
</script>