store
Signature
store(id?: string, options?: StoreOptions): Store
valdres
Create a store to hold all state
Creates a store instance that holds all atom and selector state and manages subscriptions. The store is the central hub for reading, writing, and subscribing to state.
Usage
import { atom, store } from "valdres"
const myStore = store()
const countAtom = atom(0)
Every store exposes a stable, read-only id. Pass one explicitly when an
adapter or application needs to address the store later; generated IDs are
unique within the loaded Valdres instance.
const checkoutStore = store("checkout")
checkoutStore.id // "checkout"
The Store facade exposes operations and identity, not its mutable graph/cache runtime. Framework and tooling integrations use Valdres' versioned adapter entrypoint instead of reaching through the public Store object.
Options
| Option | Type | Description |
|---|---|---|
batchUpdates | boolean | Batch sequential set() calls within a tick into one notification pass (recommended for React) |
enumerable | boolean | Retain values enumerably so store.snapshot() can list current state |
schemaValidation | boolean | Validate atom/selector values against their schema (off by default). Inherited by scoped stores. See Schema Validation. |
// Enable schema validation (e.g. outside production)
const devStore = store({ schemaValidation: import.meta.env.DEV })
Reading state
myStore.get(countAtom) // 0
Writing state
// Set directly
myStore.set(countAtom, 42)
// Update based on previous value
myStore.set(countAtom, prev => prev + 1)
Subscribing to changes
Subscription callbacks are notifications. Read the current value from the store when the callback runs:
const unsub = myStore.sub(countAtom, () => {
console.log("count changed:", myStore.get(countAtom))
})
// Later: stop listening
unsub()
Transactions
Batch multiple updates so subscribers only fire once:
myStore.txn(({ set }) => {
set(atomA, 1)
set(atomB, 2)
// Subscribers fire once after the transaction completes
})
Valdres owns commit and rollback: a successful callback commits once, while a
callback that throws discards every staged write. Callback transactions
intentionally expose no manual commit() or backing store data.
Disposing request stores
Global atoms remember each store that has materialized them so writes can fan out synchronously. Dispose short-lived stores—such as one store per SSR request or background job—when their work finishes:
const requestStore = store()
try {
return await renderRequest(requestStore)
} finally {
requestStore.dispose()
}
dispose() is terminal. It drains the store and all descendant scopes of active
subscriptions, atom mounts and their timers, onChange / onCommitEnd
listeners, pending batched writes, async selector work, and registrations on the
global atoms they touched. Cleanup stays proportional to lifecycle resources the
store actually created.
Detached scopes are disposed automatically when their last consumer calls
detach(). Every later operation on a disposed store throws
StoreDisposedError; calling dispose() again is a no-op. Create a new store
for later work.
The global store
valdres exports a shared globalStore — the store that global atoms
synchronize through. Import it when you need store access outside of a component
(scripts, tests, workers, cross-framework code):
import { globalStore } from "valdres"
globalStore.get(myAtom)
globalStore.set(myAtom, 1)
globalStore is a process-wide singleton that global atoms use for
synchronization. Calling globalStore.dispose() throws. Only dispose stores
that your application creates with store().Inside a component you normally read and write through your framework's provider/context instead — see createValdres.
See also
- createValdres — provide a store to your component tree
- useStore — access the current store in your components
- Schema Validation — opt-in runtime validation via
the
schemaValidationoption