/** * Module-level cache for the song picker options, shared between the * catalog-items table (where the picker lives) and the Sounds admin page * (which invalidates after an upload/edit/delete). * * Living in `src/lib/` (outside any `[dynamic]` route folder) avoids * cross-route client imports that confused Turbopack's HMR boundaries * and triggered `Router action dispatched before initialization` on * the Sounds page in dev. */ export interface SoundtrackOption { id: number code: string name: string author: string length: number } let cachedOptions: SoundtrackOption[] | null = null let inflight: Promise | null = null export async function loadSongPickerOptions(): Promise { if (cachedOptions) return cachedOptions if (inflight) return inflight inflight = (async () => { const res = await fetch('/api/admin/sounds', { cache: 'no-store' }) if (!res.ok) throw new Error('Failed to load soundtracks') const json = (await res.json()) as { ok: boolean; items?: SoundtrackOption[] } cachedOptions = json.items ?? [] inflight = null return cachedOptions })() return inflight } export function getCachedSongPickerOptions(): SoundtrackOption[] | null { return cachedOptions } /** Clear the cache so new uploads show up on next open. */ export function invalidateSongPickerCache(): void { cachedOptions = null }