fix: flow quick picker refresh (#6666)

* Fix Broken flow quick picker refresh button

* 60s Cache invalidation
This commit is contained in:
Diego Imbert
2025-09-23 19:40:30 +02:00
committed by GitHub
parent ae3525e4b3
commit 4a09c79768
4 changed files with 36 additions and 22 deletions
@@ -1,3 +1,7 @@
<script lang="ts" module>
let refreshCount = $state({ val: 0 })
</script>
<script lang="ts">
import { createEventDispatcher, getContext } from 'svelte'
import StepGenQuick from '$lib/components/copilot/StepGenQuick.svelte'
@@ -36,8 +40,6 @@
let width = $state(0)
let height = $state(0)
let refreshCount = $state(0)
let displayPath = $derived(width > 650 || height > 400)
</script>
@@ -67,7 +69,7 @@
{#if selectedKind != 'preprocessor' && selectedKind != 'flow'}
<ToggleHubWorkspaceQuick bind:selected={preFilter} />
{/if}
<RefreshButton {loading} on:click={() => (refreshCount += 1)} />
<RefreshButton {loading} on:click={() => (refreshCount.val += 1)} />
</div>
<div class="flex flex-row grow min-h-0">
@@ -169,7 +171,7 @@
{preFilter}
{small}
{displayPath}
{refreshCount}
refreshCount={refreshCount.val}
/>
</div>
</div>
@@ -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
}
)
</script>
@@ -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
})
@@ -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)
+13 -5
View File
@@ -1587,22 +1587,30 @@ export function assert(msg: string, condition: boolean, value?: any) {
export function createCache<Keys extends Record<string, any>, 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<string, T>()
let cache = new Map<string, { value: T; timestamp: number }>()
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<Keys extends Record<string, any>, T, InitialKeys ext
cache.delete(oldestKey)
}
}
return cache.get(key)!
return cache.get(key)!.value
}
}