StorageDBProviderclass
new StorageDBProvider<I, T>(storage: Storage, prefix = "shelving:")
| Param | Type | |
|---|---|---|
storage | Storage | Storage instance to persist to, e.g. localStorage or sessionStorage (required so environments without one, e.g. the server, fail at the callsite). required |
prefix | unknown | Prefix for every storage key written by this provider, so it can share an origin's storage with other code (defaults to "shelving:"). Defaults to "shelving:" |
| Return | |
|---|---|
StorageDBProvider<I, T> | In-memory database provider that persists every collection to a Storage — localStorage, sessionStorage, or anything else with the same interface. |
| Property | Type | |
|---|---|---|
.prefix | string | Prefix for every storage key written by this provider. required readonly |
.persistent | boolean | Whether this provider is actually persisting to storage. - false when storage exists but is unusable (e.g. blocked by browser settings, or private browsing with zero quota) — the provider still works, but data only lives in memory and is lost when the page closes. required readonly |
In-memory database provider that persists every collection to a Storage — localStorage, sessionStorage, or anything else with the same interface.
- Extends
MemoryDBProvider, so all reads, queries, and realtime sequences are served synchronously from memory, and it can seedItemStore/QueryStoreand act as the cache insideCacheDBProvider. The only difference is that collections are backed byStorageTableinstead ofMemoryTable. - The storage is a required argument (there is no default), so server code that constructs this provider must reference
localStorage/sessionStorageitself — surfacing the mistake at the callsite instead of deep inside this class. - Treat the persisted data as best-effort: quota is shared across the origin (typically ~5MB) and users can clear it at any time. Data read back from storage is unvalidated — wrap this provider in
ValidationDBProviderif it may have been written by an older version of your app. - If the storage is unusable (writes blocked by browser settings, or private browsing with zero quota), the provider degrades to memory-only operation — check the
persistentflag to warn users their changes won't be saved.
A MemoryDBProvider that persists every collection to a Storage — localStorage, sessionStorage, or anything else with the same interface. Each collection is hydrated from storage once, lazily, on first access — after that all reads, queries, and realtime sequences are served synchronously from memory, and every write persists to storage before it touches memory.
Because it is a MemoryDBProvider, it plugs into everything that expects one: it seeds ItemStore / QueryStore synchronously (including via DBCache and the React hooks from createDBContext()), and it can be passed as the cache inside CacheDBProvider to give a remote source a persistent local mirror.
storage events from other tabs/windows are applied to memory and notify realtime sequences, so getItemSequence() / getQuerySequence() update live across tabs.
All the persistence logic lives in StorageTable, a self-contained MemoryTable subclass that hydrates itself, persists its own writes, and manages its own storage event listener — the provider is just a MemoryDBProvider whose createTable() returns StorageTable. StorageTable can also be used independently. Dispose the provider (or table) to remove the event listeners.
Usage
The storage to persist to is a required argument — there is no default, so server code that constructs this provider must reference localStorage / sessionStorage itself, surfacing the mistake at the callsite (at compile time, in a project without DOM types) rather than deep inside the class:
import { StorageDBProvider } from "shelving/db";
const provider = new StorageDBProvider(localStorage); // Persists under "shelving:*" keys.
if (!provider.persistent) console.warn("Changes won't be saved on this device.");
const id = await provider.addItem(POSTS, { title: "Hello", body: "First post.", published: false });
const post = await provider.getItem(POSTS, id); // Still there after a reload.Pass sessionStorage for per-tab persistence, and a prefix to namespace keys:
const provider = new StorageDBProvider(sessionStorage, "myapp:");As the persistent cache tier under a remote source:
import { CacheDBProvider, StorageDBProvider } from "shelving/db";
const provider = new CacheDBProvider(new MyRemoteProvider(), new StorageDBProvider(localStorage));Reliability
Treat the persisted data as best-effort, not guaranteed:
- Quota is shared across the whole origin (typically ~5MB) and a write can fail at any time with
QuotaExceededError. The provider persists before updating memory, so a failed write throws and changes nothing — catch it at the app level to warn the user (e.g. "we can't save data locally right now"). - Users can clear storage at any time, and browsers may partition or restrict it.
- Unusable storage (writes blocked by browser settings, or private browsing with zero quota) makes the provider degrade to memory-only operation without throwing. Check
StorageDBProvider.persistentto detect this and warn users their changes won't be saved. - Stored data is unvalidated — it may have been written by an older version of your app. Wrap the provider in
ValidationDBProvider, and useshelving/dbmigrations for upgrading old shapes.
Passing nothing at runtime (a plain-JS caller with no type checking) throws UnsupportedError.
Examples
const provider = new StorageDBProvider(localStorage);
if (!provider.persistent) console.warn("Changes won't be saved on this device.");
const id = await provider.addItem(users, { name: "Dave" });