# @suaveplan/storage-browser-localstorage - Browser localStorage AbstractStorage adapter for @suaveplan/storage: namespaced base64 JSON envelopes, TTL expiry on read, AbortSignal everywhere, strict key sanitisation, DOMException → typed LocalStorageError mapping, full OTel surface. Browser-tier `AbstractStorage` adapter backed by the synchronous `Storage` API (`globalThis.localStorage`). Provides namespaced, origin-scoped key-value storage with full `AbstractStorage` conformance, AbortSignal threading, Zod-validated options, structured `LocalStorageError` boundary, lazy TTL eviction, an injectable `StorageLike` adapter for testing, and a complete OpenTelemetry surface. ## Documentation tree - [envelope](./src/envelope/envelope.md) — _(no submodules)_ - [envelope](./src/envelope/envelope.md) — _(no submodules)_ - [in-memory-storage](./src/in-memory-storage/in-memory-storage.md) — _(no submodules)_ - [in-memory-storage](./src/in-memory-storage/in-memory-storage.md) — _(no submodules)_ - [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — _(no submodules)_ - [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — _(no submodules)_ - [local-storage](./src/local-storage/local-storage.md) — _(no submodules)_ - local-storage.ops — `localStorage` is a flat string… - [local-storage.errors](./src/local-storage/local-storage.errors.md) — Maps every error thrown by the underlying `Storage` adapter to the typed `LocalStorageError` surface. Browsers raise in… - [local-storage](./src/local-storage/local-storage.md) — _(no submodules)_ - local-storage.ops — `localStorage` is a flat string… - [local-storage.ops](./src/local-storage/local-storage.ops.md) — `localStorage` is a flat string keyspace shared across the entire origin. `@suaveplan/storage-browser-localstorage` par… - [local-storage.partial](./src/local-storage/local-storage.partial.md) — `localStorage` is an inherently whole-value API — there is no native partial read or partial write. `LocalStorageStorag… - [local-storage.slot](./src/local-storage/local-storage.slot.md) — The slot module owns the pure functional helpers `LocalStorageStorage` needs but does not benefit from keeping inside t… - [local-storage-adapter](./src/local-storage-adapter/local-storage-adapter.md) — _(no submodules)_ - [local-storage-adapter](./src/local-storage-adapter/local-storage-adapter.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_ - [registry](./src/registry/registry.md) — _(no submodules)_ - [registry](./src/registry/registry.md) — _(no submodules)_ - [error-codes](./src/error-codes.md) — Single source of truth for every error code the `@suaveplan/storage-browser-localstorage` package can throw. The regist… - [envelope](./src/envelope/envelope.md) — _(no submodules)_- [in-memory-storage](./src/in-memory-storage/in-memory-storage.md) — _(no submodules)_ - [in-memory-storage](./src/in-memory-storage/in-memory-storage.md) — _(no submodules)_- [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — _(no submodules)_ - [key-sanitizer](./src/key-sanitizer/key-sanitizer.md) — _(no submodules)_- [local-storage](./src/local-storage/local-storage.md) — _(no submodules)_ - [local-storage.errors](./src/local-storage/local-storage.errors.md) — Maps every error thrown by the underlying `Storage` adapter to the typed `LocalStorageError` surface. Browsers raise in… - [local-storage](./src/local-storage/local-storage.md) — _(no submodules)_ - [local-storage.ops](./src/local-storage/local-storage.ops.md) — `localStorage` is a flat string keyspace shared across the entire origin. `@suaveplan/storage-browser-localstorage` par… - [local-storage.partial](./src/local-storage/local-storage.partial.md) — `localStorage` is an inherently whole-value API — there is no native partial read or partial write. `LocalStorageStorag… - [local-storage.slot](./src/local-storage/local-storage.slot.md) — The slot module owns the pure functional helpers `LocalStorageStorage` needs but does not benefit from keeping inside t… - [local-storage-adapter](./src/local-storage-adapter/local-storage-adapter.md) — _(no submodules)_ - [local-storage-adapter](./src/local-storage-adapter/local-storage-adapter.md) — _(no submodules)_- [otel](./src/otel/otel.md) — _(no submodules)_ - [otel](./src/otel/otel.md) — _(no submodules)_- [registry](./src/registry/registry.md) — _(no submodules)_ - [registry](./src/registry/registry.md) — _(no submodules)_- [error-codes](./src/error-codes.md) — Single source of truth for every error code the `@suaveplan/storage-browser-localstorage` package can throw. The regist… ## Install ```bash bun add @suaveplan/storage-browser-localstorage ``` ## Quick start ```ts import { createLocalStorageStorage, isLocalStorageAvailable, } from "@suaveplan/storage-browser-localstorage"; if (!isLocalStorageAvailable()) { throw new Error("This browser blocks localStorage (private mode?)"); } const storage = createLocalStorageStorage({ namespace: "myapp" }); await storage.set("user/42", new TextEncoder().encode("hello")); const back = await storage.get("user/42"); ``` ## Factory integration ```ts import { registerLocalStorageProvider } from "@suaveplan/storage-browser-localstorage/registry"; import { createStorage } from "@suaveplan/storage/factory"; registerLocalStorageProvider(); const storage = createStorage({ type: "localstorage", config: { namespace: "myapp" }, }); ``` The package does NOT self-register at module-evaluation time — call `registerLocalStorageProvider()` explicitly so `sideEffects: false` bundlers can tree-shake the factory path when not used. ## Capabilities | Capability | Value | Notes | |---|---|---| | `partialReads` | `false` | `getPartial` is implemented via the `AbstractStorage` reference helper (load + slice). | | `partialWrites` | `false` | `setPartial` is implemented via the `AbstractStorage` reference helper (load + splice + write). | | `nativeStreams` | `false` | `createReadStream` / `createWriteStream` use the `AbstractStorage` default buffered implementations. | | `atomicWrites` | `true` | A single `setItem` is atomic at the DOM API level. | | `contentAddressable` | `false` | Keys are caller-supplied strings. | ## Modules - [`src/error-codes.ts`](./src/error-codes.md) — `LOCAL_STORAGE_CODES` registry + `LocalStorageError`. - [`src/key-sanitizer/key-sanitizer.ts`](./src/key-sanitizer/key-sanitizer.md) — strict key boundary. - [`src/envelope/envelope.ts`](./src/envelope/envelope.md) — base64 + JSON wire format. - [`src/local-storage-adapter/local-storage-adapter.ts`](./src/local-storage-adapter/local-storage-adapter.md) — `defaultLocalStorage()` + `isLocalStorageAvailable()`. - [`src/local-storage/local-storage.ts`](./src/local-storage/local-storage.md) — the `LocalStorageStorage` class. - [`src/local-storage/local-storage.errors.ts`](./src/local-storage/local-storage.errors.md) — DOMException mapping. - [`src/local-storage/local-storage.ops.ts`](./src/local-storage/local-storage.ops.md) — namespacing + pagination helpers. - [`src/local-storage/local-storage.partial.ts`](./src/local-storage/local-storage.partial.md) — argument validation. - [`src/local-storage/local-storage.slot.ts`](./src/local-storage/local-storage.slot.md) — option resolution + envelope IO. - [`src/otel/otel.ts`](./src/otel/otel.md) — OpenTelemetry instrument set. - [`src/registry/registry.ts`](./src/registry/registry.md) — `registerLocalStorageProvider()`. - [`src/in-memory-storage/in-memory-storage.ts`](./src/in-memory-storage/in-memory-storage.md) — real-implementation test double, exposed under `./in-memory-storage` for downstream test packages. - [`src/types/storage-like.types.ts`](./src/types/storage-like.types.md) — structural DOM Storage surface. - [`src/types/local-storage-storage.types.ts`](./src/types/local-storage-storage.types.md) — option boundary. ## License MIT.