diff --git a/src/lib/apis/knowledge/index.ts b/src/lib/apis/knowledge/index.ts index 3714e46752..e2ac269c00 100644 --- a/src/lib/apis/knowledge/index.ts +++ b/src/lib/apis/knowledge/index.ts @@ -377,7 +377,8 @@ export const searchKnowledgeBases = async ( page: number | null = null, source: string | null = null, orderBy: string | null = null, - direction: string | null = null + direction: string | null = null, + signal?: AbortSignal ) => { let error = null; @@ -391,6 +392,7 @@ export const searchKnowledgeBases = async ( const res = await fetch(`${WEBUI_API_BASE_URL}/knowledge/search?${searchParams.toString()}`, { method: 'GET', + signal, headers: { Accept: 'application/json', 'Content-Type': 'application/json', @@ -405,6 +407,7 @@ export const searchKnowledgeBases = async ( return json; }) .catch((err) => { + if (signal?.aborted) return null; error = err.detail; console.error(err); return null; diff --git a/src/lib/apis/models/index.ts b/src/lib/apis/models/index.ts index 11b3829cc2..5fca52095f 100644 --- a/src/lib/apis/models/index.ts +++ b/src/lib/apis/models/index.ts @@ -18,7 +18,8 @@ export const getModelItems = async ( selectedTag, orderBy, direction, - page + page, + signal?: AbortSignal ) => { let error = null; @@ -44,6 +45,7 @@ export const getModelItems = async ( const res = await fetch(`${WEBUI_API_BASE_URL}/models/list?${searchParams.toString()}`, { method: 'GET', + signal, headers: { Accept: 'application/json', 'Content-Type': 'application/json', @@ -58,6 +60,7 @@ export const getModelItems = async ( return json; }) .catch((err) => { + if (signal?.aborted) return null; error = err; console.error(err); return null; diff --git a/src/lib/apis/prompts/index.ts b/src/lib/apis/prompts/index.ts index 5a966332a1..61dd384a6d 100644 --- a/src/lib/apis/prompts/index.ts +++ b/src/lib/apis/prompts/index.ts @@ -143,7 +143,8 @@ export const getPromptItems = async ( selectedTag: string | null, orderBy: string | null, direction: string | null, - page: number + page: number, + signal?: AbortSignal ) => { let error = null; @@ -169,6 +170,7 @@ export const getPromptItems = async ( const res = await fetch(`${WEBUI_API_BASE_URL}/prompts/list?${searchParams.toString()}`, { method: 'GET', + signal, headers: { Accept: 'application/json', 'Content-Type': 'application/json', @@ -183,6 +185,7 @@ export const getPromptItems = async ( return json; }) .catch((err) => { + if (signal?.aborted) return null; error = err; console.error(err); return null; diff --git a/src/lib/apis/skills/index.ts b/src/lib/apis/skills/index.ts index 5185d5efaf..aba372a1f2 100644 --- a/src/lib/apis/skills/index.ts +++ b/src/lib/apis/skills/index.ts @@ -102,7 +102,8 @@ export const getSkillItems = async ( viewOption: string | null = null, page: number | null = null, orderBy: string | null = null, - direction: string | null = null + direction: string | null = null, + signal?: AbortSignal ) => { let error = null; @@ -115,6 +116,7 @@ export const getSkillItems = async ( const res = await fetch(`${WEBUI_API_BASE_URL}/skills/list?${searchParams.toString()}`, { method: 'GET', + signal, headers: { Accept: 'application/json', 'Content-Type': 'application/json', @@ -129,6 +131,7 @@ export const getSkillItems = async ( return json; }) .catch((err) => { + if (signal?.aborted) return null; error = err; console.error(err); return null; diff --git a/src/lib/components/workspace/Knowledge.svelte b/src/lib/components/workspace/Knowledge.svelte index 479efc699a..30c487d0b7 100644 --- a/src/lib/components/workspace/Knowledge.svelte +++ b/src/lib/components/workspace/Knowledge.svelte @@ -62,6 +62,7 @@ let page = 1; let query = ''; let searchDebounceTimer: ReturnType; + let searchController: AbortController; let viewOption = ''; let sourceOption = ''; let sortKey = 'updated_at'; @@ -86,6 +87,8 @@ } const handleSearchInput = () => { + searchController?.abort(); + itemsLoading = true; clearTimeout(searchDebounceTimer); searchDebounceTimer = setTimeout(() => { init(); @@ -93,6 +96,7 @@ }; onDestroy(() => { + searchController?.abort(); clearTimeout(searchDebounceTimer); }); @@ -137,6 +141,11 @@ }; const getItemsPage = async () => { + clearTimeout(searchDebounceTimer); + searchController?.abort(); + searchController = new AbortController(); + const { signal } = searchController; + itemsLoading = true; const res = await searchKnowledgeBases( localStorage.token, @@ -145,11 +154,14 @@ page, sourceOption, sortKey, - sortDirection + sortDirection, + signal ).catch(() => { return []; }); + if (signal.aborted) return; + if (res) { console.log(res); total = res.total; diff --git a/src/lib/components/workspace/Models.svelte b/src/lib/components/workspace/Models.svelte index 12f8533488..59a2cce8a2 100644 --- a/src/lib/components/workspace/Models.svelte +++ b/src/lib/components/workspace/Models.svelte @@ -7,7 +7,7 @@ import fileSaver from 'file-saver'; const { saveAs } = fileSaver; - import { onMount, getContext, tick } from 'svelte'; + import { onMount, getContext, tick, onDestroy } from 'svelte'; import { goto } from '$app/navigation'; const i18n = getContext('i18n'); dayjs.extend(relativeTime); @@ -97,7 +97,13 @@ let models = null; let total = null; - let searchDebounceTimer; + let searchDebounceTimer: ReturnType; + let searchController: AbortController; + + onDestroy(() => { + clearTimeout(searchDebounceTimer); + searchController?.abort(); + }); $: if (loaded) { workspaceActions.set([ @@ -193,6 +199,11 @@ const getModelList = async () => { if (!loaded) return; + clearTimeout(searchDebounceTimer); + searchController?.abort(); + searchController = new AbortController(); + const { signal } = searchController; + try { const res = await getWorkspaceModels( localStorage.token, @@ -201,22 +212,26 @@ selectedTag, sortKey, sortDirection, - page + page, + signal ).catch((error) => { - toast.error(`${error}`); + if (!signal.aborted) toast.error(`${error}`); return null; }); + if (signal.aborted) return; + if (res) { models = res.items; total = res.total; workspaceCounts.update((counts) => ({ ...counts, models: total })); // get tags - tags = await getModelTags(localStorage.token).catch((error) => { - toast.error(`${error}`); + const fetchedTags = await getModelTags(localStorage.token).catch((error) => { + if (!signal.aborted) toast.error(`${error}`); return []; }); + if (!signal.aborted) tags = fetchedTags; } } catch (err) { console.error(err); @@ -571,6 +586,7 @@ placeholder={$i18n.t('Search Models')} maxlength="500" on:input={() => { + searchController?.abort(); clearTimeout(searchDebounceTimer); searchDebounceTimer = setTimeout(() => { page = 1; diff --git a/src/lib/components/workspace/Prompts.svelte b/src/lib/components/workspace/Prompts.svelte index bd6c095f04..87b19209ee 100644 --- a/src/lib/components/workspace/Prompts.svelte +++ b/src/lib/components/workspace/Prompts.svelte @@ -68,6 +68,7 @@ let importFiles = null; let query = ''; let searchDebounceTimer: ReturnType; + let searchController: AbortController; let prompts = null; let tags = []; @@ -127,6 +128,7 @@ } const handleSearchInput = () => { + searchController?.abort(); loading = true; clearTimeout(searchDebounceTimer); searchDebounceTimer = setTimeout(() => { @@ -170,6 +172,11 @@ const getPromptList = async () => { if (!loaded) return; + clearTimeout(searchDebounceTimer); + searchController?.abort(); + searchController = new AbortController(); + const { signal } = searchController; + loading = true; try { const res = await getPromptItems( @@ -179,27 +186,31 @@ selectedTag, sortKey, sortDirection, - page + page, + signal ).catch((error) => { - toast.error(`${error}`); + if (!signal.aborted) toast.error(`${error}`); return null; }); + if (signal.aborted) return; + if (res) { prompts = res.items; total = res.total; workspaceCounts.update((counts) => ({ ...counts, prompts: total })); // get tags - tags = await getPromptTags(localStorage.token).catch((error) => { - toast.error(`${error}`); + const fetchedTags = await getPromptTags(localStorage.token).catch((error) => { + if (!signal.aborted) toast.error(`${error}`); return []; }); + if (!signal.aborted) tags = fetchedTags; } } catch (err) { console.error(err); } finally { - loading = false; + if (!signal.aborted) loading = false; } }; @@ -361,6 +372,7 @@ }); onDestroy(() => { + searchController?.abort(); clearTimeout(searchDebounceTimer); }); diff --git a/src/lib/components/workspace/Skills.svelte b/src/lib/components/workspace/Skills.svelte index 20dbb211a9..2f5de8bfbf 100644 --- a/src/lib/components/workspace/Skills.svelte +++ b/src/lib/components/workspace/Skills.svelte @@ -55,6 +55,7 @@ let query = ''; let searchDebounceTimer: ReturnType; + let searchController: AbortController; let selectedSkill = null; let showDeleteConfirm = false; @@ -107,6 +108,11 @@ const loadSkillItems = async () => { if (!loaded) return; + clearTimeout(searchDebounceTimer); + searchController?.abort(); + searchController = new AbortController(); + const { signal } = searchController; + loading = true; try { const res = await getSkillItems( @@ -115,12 +121,15 @@ viewOption, page, sortKey, - sortDirection + sortDirection, + signal ).catch((error) => { - toast.error(`${error}`); + if (!signal.aborted) toast.error(`${error}`); return null; }); + if (signal.aborted) return; + if (res) { filteredItems = res.items; total = res.total; @@ -129,11 +138,12 @@ } catch (err) { console.error(err); } finally { - loading = false; + if (!signal.aborted) loading = false; } }; const handleSearchInput = () => { + searchController?.abort(); loading = true; clearTimeout(searchDebounceTimer); searchDebounceTimer = setTimeout(() => { @@ -251,6 +261,7 @@ }); onDestroy(() => { + searchController?.abort(); clearTimeout(searchDebounceTimer); });