From 4a09c79768efc7c0cb61d98339711ac142bf6fa7 Mon Sep 17 00:00:00 2001 From: Diego Imbert <70353967+diegoimbert@users.noreply.github.com> Date: Tue, 23 Sep 2025 19:40:30 +0200 Subject: [PATCH] fix: flow quick picker refresh (#6666) * Fix Broken flow quick picker refresh button * 60s Cache invalidation --- .../flows/map/InsertModuleInner.svelte | 10 +++++--- .../flows/pickers/PickHubScriptQuick.svelte | 25 +++++++++++-------- .../pickers/WorkspaceScriptPickerQuick.svelte | 5 ++-- frontend/src/lib/utils.ts | 18 +++++++++---- 4 files changed, 36 insertions(+), 22 deletions(-) diff --git a/frontend/src/lib/components/flows/map/InsertModuleInner.svelte b/frontend/src/lib/components/flows/map/InsertModuleInner.svelte index a027fe71f7..132714c104 100644 --- a/frontend/src/lib/components/flows/map/InsertModuleInner.svelte +++ b/frontend/src/lib/components/flows/map/InsertModuleInner.svelte @@ -1,3 +1,7 @@ + + @@ -67,7 +69,7 @@ {#if selectedKind != 'preprocessor' && selectedKind != 'flow'} {/if} - (refreshCount += 1)} /> + (refreshCount.val += 1)} />
@@ -169,7 +171,7 @@ {preFilter} {small} {displayPath} - {refreshCount} + refreshCount={refreshCount.val} />
diff --git a/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte b/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte index feaa82a792..879dbed29c 100644 --- a/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte +++ b/frontend/src/lib/components/flows/pickers/PickHubScriptQuick.svelte @@ -2,7 +2,7 @@ let listHubIntegrationsCached = createCache( ({ kind }: { kind: HubScriptKind & string; refreshCount?: number }) => IntegrationService.listHubIntegrations({ kind }), - { initial: { kind: 'script', refreshCount: 0 } } + { initial: { kind: 'script', refreshCount: 0 }, invalidateMs: 1000 * 60 } ) let listHubScriptsCached = createCache( async ({ @@ -18,7 +18,10 @@ filter.length > 0 ? await ScriptService.queryHubScripts({ text: filter, limit: 40, kind }) : ((await ScriptService.getTopHubScripts({ limit: 40, kind, app: appFilter })).asks ?? []), - { initial: { filter: '', kind: 'script', appFilter: undefined, refreshCount: 0 } } + { + initial: { filter: '', kind: 'script', appFilter: undefined, refreshCount: 0 }, + invalidateMs: 1000 * 60 + } ) @@ -67,7 +70,15 @@ apps = $bindable([]), refreshCount = 0 }: Props = $props() - let allApps: string[] = [] + + let allApps: string[] = $state([]) + $effect(() => { + if (filter.length > 0) { + apps = Array.from(new Set(items?.map((x) => x.app) ?? [])).sort() + } else { + apps = allApps + } + }) async function getAllApps(filterKind: typeof kind) { try { @@ -75,11 +86,9 @@ allApps = (await listHubIntegrationsCached({ kind: filterKind, refreshCount })).map( (x) => x.name ) - apps = allApps } catch (err) { console.error('Hub is not available') allApps = [] - apps = [] hubNotAvailable = true } } @@ -93,7 +102,6 @@ hubScriptsFilteredPromise.refresh() }) $effect(() => { - // TODO: these should be derived ... loading = hubScriptsFilteredPromise.status === 'loading' hubNotAvailable = !!hubScriptsFilteredPromise.error const scripts = hubScriptsFilteredPromise.value @@ -113,11 +121,6 @@ summary: `${x.summary} (${x.app})` }) ) - if (filter.length > 0) { - apps = Array.from(new Set(mappedItems?.map((x) => x.app) ?? [])).sort() - } else { - apps = allApps - } items = appFilter ? mappedItems.filter((x) => x.app === appFilter) : mappedItems }) diff --git a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte index 2f6da65b47..7141c0f816 100644 --- a/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte +++ b/frontend/src/lib/components/flows/pickers/WorkspaceScriptPickerQuick.svelte @@ -23,7 +23,8 @@ kind: 'script', isTemplate: undefined, refreshCount: 0 - } + }, + invalidateMs: 1000 * 60 } : {} ) @@ -52,7 +53,7 @@ let items = usePromise( async () => await loadItemsCached({ workspace: $workspaceStore!, kind, isTemplate, refreshCount }), - { loadInit: false } + { loadInit: false, clearValueOnRefresh: false } ) let filteredItems: (Item & { marked?: string })[] | undefined = $state(undefined) diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 95a59ebe6c..1f4c65d897 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -1587,22 +1587,30 @@ export function assert(msg: string, condition: boolean, value?: any) { export function createCache, T, InitialKeys extends Keys = Keys>( compute: (keys: Keys) => T, - params?: { maxSize?: number; initial?: InitialKeys } + params?: { maxSize?: number; initial?: InitialKeys; invalidateMs?: number } ): (keys: Keys) => T { - let cache = new Map() + let cache = new Map() const maxSize = params?.maxSize ?? 15 if (params?.initial) { let key = JSON.stringify(params.initial, Object.keys(params.initial).sort()) let value = compute(params.initial) - cache.set(key, value) + cache.set(key, { value, timestamp: Date.now() }) } return (keys: Keys) => { + if (typeof params?.invalidateMs === 'number') { + for (const [key, entry] of cache.entries()) { + if (Date.now() - entry.timestamp > params.invalidateMs) { + cache.delete(key) + } + } + } + let key = JSON.stringify(keys, Object.keys(keys).sort()) if (!cache.get(key)) { let value = compute(keys) - cache.set(key, value) + cache.set(key, { value, timestamp: Date.now() }) if (cache.size > maxSize) { // remove the oldest entry (first inserted) @@ -1610,6 +1618,6 @@ export function createCache, T, InitialKeys ext cache.delete(oldestKey) } } - return cache.get(key)! + return cache.get(key)!.value } }