/** * Consume prefetched API promises started in index.html before React loaded. * * Each key is consumed at most once — the first caller gets the promise, * subsequent callers get undefined and should fall back to a normal fetch. */ import type { AppSettings, Channel, Contact, RadioConfig, UnreadCounts } from './types'; interface PrefetchMap { config: Promise; settings: Promise; channels: Promise; contacts: Promise; unreads: Promise; undecryptedCount: Promise<{ count: number }>; } const store: Partial = (window as unknown as { __prefetch?: Partial }).__prefetch ?? {}; type PrefetchResolved = Awaited; /** Take a prefetched promise (consumed once, then gone). */ function takePrefetch(key: K): PrefetchMap[K] | undefined { const p = store[key]; delete store[key]; return p; } /** * Use prefetched data when available. If prefetch failed or was absent, run * the provided fallback fetcher. */ export async function takePrefetchOrFetch( key: K, fallback: () => Promise> ): Promise> { const prefetched = takePrefetch(key); if (!prefetched) { return fallback(); } try { return (await prefetched) as PrefetchResolved; } catch (err) { console.warn(`Prefetch for "${String(key)}" failed, falling back to live fetch.`, err); return fallback(); } }