mirror of
https://github.com/jkingsman/Remote-Terminal-for-MeshCore.git
synced 2026-03-28 17:43:05 +01:00
51 lines
1.5 KiB
TypeScript
51 lines
1.5 KiB
TypeScript
/**
|
|
* 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<RadioConfig>;
|
|
settings: Promise<AppSettings>;
|
|
channels: Promise<Channel[]>;
|
|
contacts: Promise<Contact[]>;
|
|
unreads: Promise<UnreadCounts>;
|
|
undecryptedCount: Promise<{ count: number }>;
|
|
}
|
|
|
|
const store: Partial<PrefetchMap> =
|
|
(window as unknown as { __prefetch?: Partial<PrefetchMap> }).__prefetch ?? {};
|
|
|
|
type PrefetchResolved<K extends keyof PrefetchMap> = Awaited<PrefetchMap[K]>;
|
|
|
|
/** Take a prefetched promise (consumed once, then gone). */
|
|
function takePrefetch<K extends keyof PrefetchMap>(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<K extends keyof PrefetchMap>(
|
|
key: K,
|
|
fallback: () => Promise<PrefetchResolved<K>>
|
|
): Promise<PrefetchResolved<K>> {
|
|
const prefetched = takePrefetch(key);
|
|
if (!prefetched) {
|
|
return fallback();
|
|
}
|
|
|
|
try {
|
|
return (await prefetched) as PrefetchResolved<K>;
|
|
} catch (err) {
|
|
console.warn(`Prefetch for "${String(key)}" failed, falling back to live fetch.`, err);
|
|
return fallback();
|
|
}
|
|
}
|