feat(ui,api): strip board redesign - island, rail by day, context view, server search, vault graph
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
// 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: <T>(key: string) => T | null;
|
||||
set: (key: string, value: unknown) => void;
|
||||
}
|
||||
|
||||
const memory = new Map<string, string>();
|
||||
|
||||
function storage(): Pick<Storage, "getItem" | "setItem" | "removeItem"> {
|
||||
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<T>(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}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user