A typed Web Storage adapter factory that centralizes SSR-guarding, JSON serialization, quota-failure handling, and optional namespace partitioning for both `localStorage` and `sessionStorage`. ## Key Components | Export | Type | Description | |--------|------|-------------| | `WebStorageBackend` | Type | `'local' \| 'session'` — selects the storage backend | | `LocalStorageAdapter` | Interface | Runtime API: `load()`, `save()`, `clear()`, `resolveKey()` | | `LocalStorageAdapterOptions` | Interface | Configuration including `key`, `namespace`, `validate`, `logTag`, `backend` | | `createLocalStorageAdapter()` | Function | Factory that returns a typed adapter instance | **Backend guidance:** - `'local'` (default) — persists across sessions; use for UI state, chat history, feature flags - `'session'` — clears on tab close; use for **any auth-adjacent value** (tokens, proxy credentials) to minimize XSS exfiltration window ## Usage Example ```typescript import { createLocalStorageAdapter } from './local-storage-adapter' interface ChatPrefs { theme: 'light' | 'dark' fontSize: number } // Basic persistent adapter const prefsAdapter = createLocalStorageAdapter({ key: 'chat-prefs', validate: (v): v is ChatPrefs => typeof v === 'object' && v !== null && 'theme' in v, logTag: '[chat-prefs]', }) prefsAdapter.save({ theme: 'dark', fontSize: 14 }) const prefs = prefsAdapter.load() // ChatPrefs | null // Auth-adjacent value with session backend + dynamic namespace const tokenAdapter = createLocalStorageAdapter({ key: 'bearer-token', backend: 'session', namespace: () => currentUser?.orgId ?? null, }) tokenAdapter.save('eyJ...') tokenAdapter.resolveKey() // → "org-123.bearer-token" tokenAdapter.clear() ``` > **SSR safe:** All storage access is guarded against `window === undefined` and sandboxed-context throws (e.g. Safari private mode), returning `null` silently instead of crashing.