<!-- source-hash: 68d691e94558097753faed6dd1e6e15f -->
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<T>` | Interface | Runtime API: `load()`, `save()`, `clear()`, `resolveKey()` |
| `LocalStorageAdapterOptions<T>` | Interface | Configuration including `key`, `namespace`, `validate`, `logTag`, `backend` |
| `createLocalStorageAdapter<T>()` | 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<ChatPrefs>({
  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<string>({
  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.