import { env } from '$env/dynamic/private'; import type { BucketDataState } from '$lib/types/bucket-state'; import type { ToolsDataset } from '$lib/types/tools-data'; import { adaptBucketTools } from './adapt-tools'; import { emptyToolsDataset } from './fallback-data'; import { toPublicBucketError } from './public-error'; import { fetchBucketRankingSnapshot } from './ranking-snapshot'; import { fetchBucketVisualizationSnapshot } from './tools-snapshot'; import type { BucketVisualizationSnapshot } from './types'; const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000; let cached: { value: BucketVisualizationSnapshot; snapshotId: string; expiresAt: number } | undefined; let adaptedCached: { value: ToolsDataset; snapshotId: string } | undefined; let inFlight: Promise | undefined; function cacheTtlMs() { const configured = Number(env.HF_BUCKET_CACHE_TTL_MS); return Number.isInteger(configured) && configured > 0 ? configured : DEFAULT_CACHE_TTL_MS; } async function refreshToolsSnapshot() { const rankingSnapshot = await fetchBucketRankingSnapshot({ refreshManifest: true }); if (cached?.snapshotId === rankingSnapshot.manifest.snapshot_id) { cached.expiresAt = Date.now() + cacheTtlMs(); return cached.value; } const value = await fetchBucketVisualizationSnapshot(rankingSnapshot); cached = { value, snapshotId: rankingSnapshot.manifest.snapshot_id, expiresAt: Date.now() + cacheTtlMs() }; return value; } export async function getHfBucketToolsSnapshot() { if (cached && cached.expiresAt > Date.now()) return cached.value; if (!inFlight) { inFlight = refreshToolsSnapshot().finally(() => { inFlight = undefined; }); } try { return await inFlight; } catch (error) { if (cached) { console.warn( '[hf-bucket] Serving stale Tools visualization data after refresh failure.', error ); return cached.value; } throw error; } } async function getHfBucketToolsSnapshotState(): Promise< BucketDataState > { if (!inFlight) { inFlight = refreshToolsSnapshot().finally(() => { inFlight = undefined; }); } try { return { status: 'ok', source: 'remote', data: await inFlight }; } catch (error) { if (cached) { console.warn( '[hf-bucket] Serving stale Tools visualization data after refresh failure.', error ); return { status: 'stale', source: 'stale', data: cached.value, error: toPublicBucketError(error) }; } console.error('[hf-bucket] Tools visualization data is unavailable.', error); return { status: 'unavailable', source: 'unavailable', data: emptyToolsDataset() as unknown as BucketVisualizationSnapshot, error: toPublicBucketError(error) }; } } export async function getHfBucketTools(): Promise { const state = await getHfBucketToolsState(); if (state.status === 'unavailable') throw new Error(state.error.message); return state.data; } export async function getHfBucketToolsState(): Promise> { const snapshotState = await getHfBucketToolsSnapshotState(); if (snapshotState.status === 'unavailable') { return { ...snapshotState, data: emptyToolsDataset() }; } try { const snapshotId = snapshotState.data.manifest.snapshot_id; const data = adaptedCached?.snapshotId === snapshotId ? adaptedCached.value : adaptBucketTools(snapshotState.data); adaptedCached = { value: data, snapshotId }; if (snapshotState.status === 'stale') { return { status: 'stale', source: 'stale', data, error: snapshotState.error }; } return { status: 'ok', source: snapshotState.source, data }; } catch (error) { if (cached) { console.warn( '[hf-bucket] Serving stale Tools visualization data after adapt failure.', error ); return { status: 'stale', source: 'stale', data: adaptBucketTools(cached.value), error: toPublicBucketError(error) }; } console.error('[hf-bucket] Tools visualization data is unavailable.', error); return { status: 'unavailable', source: 'unavailable', data: emptyToolsDataset(), error: toPublicBucketError(error) }; } }