// A small keyed cache behind the panel: the conversation index and the // last threads land here so the next open paints before the network // answers. localStorage when it exists, memory otherwise. export interface PanelCache { get: (key: string) => T | null; set: (key: string, value: unknown) => void; } const memory = new Map(); function storage(): Pick { try { if (typeof localStorage !== "undefined") { return localStorage; } } catch { /* sandboxed */ } return { getItem: (key) => memory.get(key) ?? null, removeItem: (key) => { memory.delete(key); }, setItem: (key, value) => { memory.set(key, value); }, }; } export function panelCache(prefix: string): PanelCache { const store = storage(); return { get(key: string): T | null { try { const raw = store.getItem(`${prefix}:${key}`); return raw ? (JSON.parse(raw) as T) : null; } catch { return null; } }, set(key: string, value: unknown): void { try { store.setItem(`${prefix}:${key}`, JSON.stringify(value)); } catch { store.removeItem(`${prefix}:${key}`); } }, }; }