Paths
Path handles are the unit of read, write, and subscription. This page describes the full API.
A path handle is the unit of read, write, and subscription against the shared store. Each handle targets one key in the native C++ store; two handles to the same key see the same value and the same revision.
Creating handles
const draft = chatStore.path<string>('drafts.release-room');
const messages = chatStore.path<Message[]>(['conversations', conversationId]);A path can be:
- a dot string like
'drafts.release-room' - an array of segments like
['conversations', conversationId]
Both forms reach the same native location.
Reading
const messages = conversationMessages(conversationId);
// Hook (subscribes and re-renders on change)
const value = messages.use();
// One-shot read (no subscription)
const current = messages.get();
// Async hydrate (loads from persistence if needed)
await messages.hydrate();use() accepts a selector:
const count = messages.use(list => list?.length ?? 0);The hook handles subscription cleanup. Subscriptions also fan out to parent paths — see Locking and revisions.
Writing
await messages.set(nextList, true);
await messages.update(current => [...(current ?? []), newMessage]);| Method | What it does | When to use |
|---|---|---|
set(value) | Replace the value at this path | When the new value is computed without reading current |
set(value, true) | Replace and broadcast immediately | For path writes that should not be batched with other updates |
update(fn) | Read-modify-write under the lock | When the new value depends on the current one |
Prefer update over set when value depends on current
update reads the current value through the native lock and writes back
atomically. With set, two writers can clobber each other if they both
read-then-write outside the lock.
Revisions
Every path has a monotonically increasing revision number:
await messages.hydrate();
console.log(messages.getRevision()); // e.g. 17Use the revision to detect whether a value has actually changed since you last looked, even when the value happens to deep-equal the previous one.
Listing the surface
A store can pre-declare subtrees so they're hydrated eagerly. Anything not
declared can still be reached via store.path(...) — it hydrates lazily on
first access or when you call path.hydrate().
See Persistence for the persisted-state counterpart.