Add stale cache for public data
This commit is contained in:
51
src/api.ts
51
src/api.ts
@@ -12,10 +12,59 @@ export function assetUrl(path: string | undefined | null) {
|
||||
return `${apiBase}${path}`;
|
||||
}
|
||||
|
||||
type JsonCacheEntry<T> = {
|
||||
cachedAt: number;
|
||||
value: T;
|
||||
};
|
||||
|
||||
const jsonMemoryCache = new Map<string, JsonCacheEntry<unknown>>();
|
||||
const jsonStoragePrefix = "ark-json-cache:v1:";
|
||||
|
||||
function jsonCacheKey(path: string): string {
|
||||
return `${apiBase}${path}`;
|
||||
}
|
||||
|
||||
export function readJSONCache<T>(path: string): T | null {
|
||||
const key = jsonCacheKey(path);
|
||||
const memoryEntry = jsonMemoryCache.get(key) as JsonCacheEntry<T> | undefined;
|
||||
if (memoryEntry) return memoryEntry.value;
|
||||
|
||||
if (typeof window === "undefined") return null;
|
||||
|
||||
try {
|
||||
const raw = window.localStorage.getItem(`${jsonStoragePrefix}${key}`);
|
||||
if (!raw) return null;
|
||||
const entry = JSON.parse(raw) as JsonCacheEntry<T>;
|
||||
jsonMemoryCache.set(key, entry as JsonCacheEntry<unknown>);
|
||||
return entry.value;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function writeJSONCache<T>(path: string, value: T): void {
|
||||
const key = jsonCacheKey(path);
|
||||
const entry: JsonCacheEntry<T> = { cachedAt: Date.now(), value };
|
||||
jsonMemoryCache.set(key, entry as JsonCacheEntry<unknown>);
|
||||
|
||||
if (typeof window === "undefined") return;
|
||||
|
||||
try {
|
||||
window.localStorage.setItem(
|
||||
`${jsonStoragePrefix}${key}`,
|
||||
JSON.stringify(entry),
|
||||
);
|
||||
} catch {
|
||||
// Ignore storage quota / privacy-mode failures; memory cache still works.
|
||||
}
|
||||
}
|
||||
|
||||
export async function getJSON<T>(path: string): Promise<T> {
|
||||
const res = await fetch(`${apiBase}${path}`);
|
||||
if (!res.ok) throw new Error(await res.text());
|
||||
return res.json() as Promise<T>;
|
||||
const data = (await res.json()) as T;
|
||||
writeJSONCache(path, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
export async function getJSONAuth<T>(path: string, token: string): Promise<T> {
|
||||
|
||||
Reference in New Issue
Block a user