@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 — (no submodules)
- envelope — (no submodules)
- in-memory-storage — (no submodules)
- in-memory-storage — (no submodules)
- key-sanitizer — (no submodules)
- key-sanitizer — (no submodules)
- local-storage — (no submodules) - local-storage.ops —
localStorageis a flat string…- local-storage.errors — Maps every error thrown by the underlying
Storageadapter to the typedLocalStorageErrorsurface. Browsers raise in… - local-storage — (no submodules) - local-storage.ops —
localStorageis a flat string… - local-storage.ops —
localStorageis a flat string keyspace shared across the entire origin.@suaveplan/storage-browser-localstoragepar… - local-storage.partial —
localStorageis an inherently whole-value API — there is no native partial read or partial write. `LocalStorageStorag… - local-storage.slot — The slot module owns the pure functional helpers
LocalStorageStorageneeds but does not benefit from keeping inside t…
- local-storage.errors — Maps every error thrown by the underlying
- local-storage-adapter — (no submodules)
- local-storage-adapter — (no submodules)
- otel — (no submodules)
- otel — (no submodules)
- registry — (no submodules)
- registry — (no submodules)
- error-codes — Single source of truth for every error code the
@suaveplan/storage-browser-localstoragepackage can throw. The regist…
- envelope — (no submodules)- in-memory-storage — (no submodules) - in-memory-storage — (no submodules)- key-sanitizer — (no submodules) - key-sanitizer — (no submodules)- local-storage — (no submodules) - local-storage.errors — Maps every error thrown by the underlying
Storageadapter to the typedLocalStorageErrorsurface. Browsers raise in… - local-storage — (no submodules) - local-storage.ops —
localStorageis a flat string keyspace shared across the entire origin.@suaveplan/storage-browser-localstoragepar… - local-storage.partial —
localStorageis an inherently whole-value API — there is no native partial read or partial write. `LocalStorageStorag… - local-storage.slot — The slot module owns the pure functional helpers
LocalStorageStorageneeds but does not benefit from keeping inside t… - local-storage-adapter — (no submodules) - local-storage-adapter — (no submodules)- otel — (no submodules) - otel — (no submodules)- registry — (no submodules) - registry — (no submodules)- error-codes — Single source of truth for every error code the
@suaveplan/storage-browser-localstoragepackage can throw. The regist…
Install
bun add @suaveplan/storage-browser-localstorage
Quick start
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
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—LOCAL_STORAGE_CODESregistry +LocalStorageError.src/key-sanitizer/key-sanitizer.ts— strict key boundary.src/envelope/envelope.ts— base64 + JSON wire format.src/local-storage-adapter/local-storage-adapter.ts—defaultLocalStorage()+isLocalStorageAvailable().src/local-storage/local-storage.ts— theLocalStorageStorageclass.src/local-storage/local-storage.errors.ts— DOMException mapping.src/local-storage/local-storage.ops.ts— namespacing + pagination helpers.src/local-storage/local-storage.partial.ts— argument validation.src/local-storage/local-storage.slot.ts— option resolution + envelope IO.src/otel/otel.ts— OpenTelemetry instrument set.src/registry/registry.ts—registerLocalStorageProvider().src/in-memory-storage/in-memory-storage.ts— real-implementation test double, exposed under./in-memory-storagefor downstream test packages.src/types/storage-like.types.ts— structural DOM Storage surface.src/types/local-storage-storage.types.ts— option boundary.
License
MIT.