IndexedDBStorage
Data is stored in IndexedDB and survives reloads. Asynchronous API — read/write operations return a Promise.
The same end-to-end todo domain (TodoState, initialTodoState — see MemoryStorage),
but in a persistent asynchronous storage.
Creating
import { IndexedDBStorage } from 'synapse-storage/core'
// options is a required field (may be an empty object)
const storage = new IndexedDBStorage<TodoState>({
name: 'todo-idb',
initialState: initialTodoState,
options: {},
})
// With a custom dbName
const storage = new IndexedDBStorage<TodoState>({
name: 'todo-idb',
initialState: initialTodoState,
options: { dbName: 'my_app_db' }, // defaults to 'app_storage'
})
// Or via the static .create()
const storage = IndexedDBStorage.create<TodoState>({
name: 'todo-idb',
initialState: initialTodoState,
options: {},
})
await storage.initialize()Synchronous vs asynchronous API
The key difference from Memory/LocalStorage: operations return a Promise.
// Writing
await storage.set('filter', 'active')
await storage.update((s) => { s.todos.push(createTodo('Новая задача')) })
// Reading
const todos = await storage.get<Todo[]>('todos')
const state = await storage.getState()
// getStateSync() — synchronous read from the cache, always available (including in render)
const cached = storage.getStateSync()Subscriptions (subscribe, subscribeToAll, useStorageSubscribe) are identical to synchronous storages.
When to use
Large amounts of data, arrays of thousands of items, binary data (Blob/ArrayBuffer).
You need persistence beyond the localStorage limit (~5 MB).
When not to use
Small state where you don't want asynchrony → LocalStorage.
Ephemeral UI state → MemoryStorage.
Working with data
A full walkthrough of the operations is in the "Working with data" section: Reading, Writing, remove/has/keys, Subscriptions. Everywhere a synchronous storage returns a value, IndexedDB returns a Promise.
Persist migrations and SSR
IndexedDB is persistent, so it supports schema migration via version + migrate
(the version is stored as a reserved record in the same store and isn't visible in
getState()/keys()) — see Persist migrations. Server state is seeded via
hydrate(state) (for IndexedDB — await storage.hydrate(...)).