Spaces:
Running
Running
| 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<BucketVisualizationSnapshot> | 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<BucketVisualizationSnapshot> | |
| > { | |
| 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<ToolsDataset> { | |
| const state = await getHfBucketToolsState(); | |
| if (state.status === 'unavailable') throw new Error(state.error.message); | |
| return state.data; | |
| } | |
| export async function getHfBucketToolsState(): Promise<BucketDataState<ToolsDataset>> { | |
| 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) | |
| }; | |
| } | |
| } | |