Anton Malykhin
feat: integrate bucket-backed leaderboard data
c6afb12
Raw
History Blame Contribute Delete
1.28 kB
import { env } from '$env/dynamic/private';
import { fetchHfBucketManifest } from './client';
import type { HfBucketManifestResult } from './types';
const DEFAULT_CACHE_TTL_MS = 5 * 60 * 1000;
type CacheEntry = {
result: HfBucketManifestResult;
expiresAt: number;
};
let cached: CacheEntry | undefined;
let inFlight: Promise<HfBucketManifestResult> | 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 refreshManifest() {
const manifest = await fetchHfBucketManifest();
const result: HfBucketManifestResult = {
manifest,
fetchedAt: new Date().toISOString(),
source: 'remote'
};
cached = { result, expiresAt: Date.now() + cacheTtlMs() };
return result;
}
export async function getHfBucketManifest(options?: { forceRefresh?: boolean }) {
if (!options?.forceRefresh && cached && cached.expiresAt > Date.now()) {
return { ...cached.result, source: 'cache' as const };
}
if (!inFlight) {
inFlight = refreshManifest().finally(() => {
inFlight = undefined;
});
}
try {
return await inFlight;
} catch (error) {
if (cached) return { ...cached.result, source: 'stale' as const };
throw error;
}
}