import Fuse from 'fuse.js' import type { Ref } from 'vue' import { isRef, watch } from 'vue' type Path = T extends object ? { [K in keyof T]: `${Exclude}${'' | `.${Path}`}` }[keyof T] : never export const useFuzzySearch = (items: T[] | Ref, keys: Path[] | string[]) => { const fuse = new Fuse([], { keys }) let documents = items const setDocuments = (newDocuments: T[]) => { documents = newDocuments fuse.setCollection(documents) } if (isRef(items)) { fuse.setCollection(items.value) watch(items, () => setDocuments(items.value)) } else { setDocuments(items) } const search = (query: string | null) => { query = query?.trim() ?? null return query ? fuse.search(query).map(result => result.item) : isRef(documents) ? documents.value : documents } return { search, setDocuments, } }