import { useCallback, useEffect, useState } from "react"; const PREFIX = "plate-dyn:"; /** React state mirrored into localStorage under `key`. `validate` rejects stale shapes. */ export function usePersistentState( key: string, initial: () => T, validate?: (v: unknown) => v is T, ): [T, (v: T | ((prev: T) => T)) => void, () => void] { const full = PREFIX + key; const [value, setValue] = useState(() => { try { const raw = localStorage.getItem(full); if (raw !== null) { const parsed: unknown = JSON.parse(raw); if (!validate || validate(parsed)) return parsed as T; } } catch { /* fall back to the default */ } return initial(); }); useEffect(() => { try { localStorage.setItem(full, JSON.stringify(value)); } catch { /* storage unavailable: state simply does not persist */ } }, [full, value]); const reset = useCallback(() => setValue(initial()), [initial]); return [value, setValue, reset]; } /** Forget everything the lab has stored in this browser. */ export function clearPersistentState(): void { try { const keys: string[] = []; for (let i = 0; i < localStorage.length; i++) { const k = localStorage.key(i); if (k && k.startsWith(PREFIX)) keys.push(k); } keys.forEach((k) => localStorage.removeItem(k)); } catch { /* ignore */ } }