Pete Dunn
perf: optimize unified KB hot paths and UI session rendering
f71b691
Raw
History Blame Contribute Delete
2.14 kB
const SESSION_PREFIX = "masters_toolkit_tab_session_v2:";
const MAX_SESSION_CHARS = 850_000;
const SAVE_DEBOUNCE_MS = 220;
const saveTimers = new Map<string, number>();
const pendingSerialized = new Map<string, string>();
export function loadTabSession<T>(tabKey: string): T | null {
if (typeof window === "undefined") return null;
try {
const raw = window.localStorage.getItem(`${SESSION_PREFIX}${tabKey}`);
if (!raw) return null;
return JSON.parse(raw) as T;
} catch {
return null;
}
}
export function saveTabSession<T>(tabKey: string, value: T): boolean {
if (typeof window === "undefined") return false;
try {
const serialized = JSON.stringify(value);
if (serialized.length > MAX_SESSION_CHARS) return false;
window.localStorage.setItem(`${SESSION_PREFIX}${tabKey}`, serialized);
return true;
} catch {
return false;
}
}
export function saveTabSessionDebounced<T>(tabKey: string, value: T, debounceMs = SAVE_DEBOUNCE_MS): void {
if (typeof window === "undefined") return;
try {
const serialized = JSON.stringify(value);
if (serialized.length > MAX_SESSION_CHARS) return;
pendingSerialized.set(tabKey, serialized);
const prev = saveTimers.get(tabKey);
if (typeof prev === "number") window.clearTimeout(prev);
const t = window.setTimeout(() => {
const payload = pendingSerialized.get(tabKey);
if (!payload) return;
try {
window.localStorage.setItem(`${SESSION_PREFIX}${tabKey}`, payload);
} catch {
// ignore
} finally {
pendingSerialized.delete(tabKey);
saveTimers.delete(tabKey);
}
}, Math.max(80, debounceMs));
saveTimers.set(tabKey, t);
} catch {
// ignore
}
}
export function clearTabSession(tabKey: string): void {
if (typeof window === "undefined") return;
try {
const pending = saveTimers.get(tabKey);
if (typeof pending === "number") {
window.clearTimeout(pending);
saveTimers.delete(tabKey);
}
pendingSerialized.delete(tabKey);
window.localStorage.removeItem(`${SESSION_PREFIX}${tabKey}`);
} catch {
// ignore
}
}