diff --git a/svelte/src/libs/search-index.ts b/svelte/src/libs/search-index.ts index 706e6e98..026f62e8 100644 --- a/svelte/src/libs/search-index.ts +++ b/svelte/src/libs/search-index.ts @@ -7,6 +7,9 @@ import log from "$libs/logger"; let packagesIndex: Fuse; let ready = false; +// Set search timeout (milliseconds) +const SEARCH_TIMEOUT_MS = 10000; + export function indexPackages(packages: GUIPackage[]) { try { packagesIndex = new Fuse(packages, { @@ -46,22 +49,36 @@ export function indexPackages(packages: GUIPackage[]) { export async function searchPackages(term: string, limit = 5): Promise { await isIndexReady(); if (!term || !packagesIndex) return []; - // TODO: if online, use algolia else use Fuse - const res = packagesIndex.search(term, { limit }); - const matchingPackages: GUIPackage[] = res.map((v) => v.item); - return matchingPackages; + + // Use try-catch to catch exceptions in asynchronous operations + try { + // Set timeout using Promise.race + const matchingPackages = await Promise.race([ + packagesIndex.search(term, { limit }), // TODO: if online, use algolia else use Fuse + new Promise((resolve) => setTimeout(resolve, SEARCH_TIMEOUT_MS)) + ]); + + // Return matching packages + return matchingPackages.map((v) => v.item); + } catch (error) { + console.error("Error searching packages:", error); + return []; + } } -export async function isIndexReady(): Promise { - if (ready) return true; - return new Promise((resolve) => { - const intervalCancel = setInterval(() => { +export async function isIndexReady(): Promise { + // If the index is ready, return immediately + if (ready) return; + + // Set a timer to check whether the index is ready every second + await new Promise((resolve) => { + const interval = setInterval(() => { if (packagesIndex) { const [grep] = packagesIndex.search("grep"); if (grep) { - clearInterval(intervalCancel); + clearInterval(interval); ready = true; - resolve(true); + resolve(); } } }, 1000);