Skip to content

Stores

Stores implement Python's read-only collection protocols; synchronous scoped drafts implement their mutable counterparts. See the store guide for versions, identity, snapshots, projections, and optimistic rebasing.

store

Transactional, entity-based reactive mappings and sequences.

A setter opens a scoped mutable draft. Successful synchronous edits are staged together and become visible at the next flush. Read proxies retain entity identity through moves; dictionary methods have normal Python semantics. Use subscription for keys such as items or get.

Classes:

Name Description
DraftExpiredError

A draft was used after its setter or deriving function finished.

Store

Read-only reactive mapping with optional attribute access to data keys.

StoreList

Read-only reactive sequence. Entity proxies survive reorders.

Draft

A mapping draft that expires when its callback returns.

DraftList

A sequence draft with standard Python mutation methods.

StoreSetter

Apply an atomic draft edit. Exceptions discard all changes from the call.

Functions:

Name Description
create_store

Create a reactive mapping or sequence and its atomic draft setter.

create_projection

Create a read-only derived store with memo readiness and refresh semantics.

create_optimistic_store

Layer optimistic draft edits over a reactive authoritative source.

reconcile

Prepare replacement data, preserving matched list entity identities.

snapshot

Return a detached, untracked copy of the currently visible state.

deep

Return a detached snapshot, tracking changes only within this subtree.

DraftExpiredError

Bases: RuntimeError

A draft was used after its setter or deriving function finished.

ListChange dataclass

ListChange(kind: str, index: int = 0, removed: tuple[Any, ...] = (), added: tuple[Any, ...] = ())

Internal sequence edit. Indices refer to the state before this edit.

Store

Store(node: _Node, session: _Session | None = None)

Bases: _Proxy, Mapping[str, Any]

Read-only reactive mapping with optional attribute access to data keys.

Missing subscriptions raise KeyError; missing attributes raise AttributeError. Mapping methods take precedence over data keys: use store["items"].

Methods:

Name Description
get

Return the value for key, or default when absent (tracked either way).

get

get(key: str, default: Any = None) -> Any

Return the value for key, or default when absent (tracked either way).

A tracked read of an absent key subscribes to it, so a computation reading store.get(row_id) re-runs when that key appears.

StoreList

StoreList(node: _Node, session: _Session | None = None)

Bases: _Proxy, Sequence[T]

Read-only reactive sequence. Entity proxies survive reorders.

Draft

Draft(node: _Node, session: _Session | None = None)

Bases: Store[S], MutableMapping[str, Any]

A mapping draft that expires when its callback returns.

DraftList

DraftList(node: _Node, session: _Session | None = None)

Bases: StoreList[T], MutableSequence[T]

A sequence draft with standard Python mutation methods.

Methods:

Name Description
insert

Insert a value at a draft index.

extend

Append values in one recorded splice.

clear

Remove all items in one transactional edit.

sort

Sort entities without changing their identities.

reverse

Reverse entity order in the draft.

move

Move a contiguous range to a final index, preserving its entities.

insert

insert(index: int, value: T) -> None

Insert a value at a draft index.

extend

extend(values: Iterable[T]) -> None

Append values in one recorded splice.

clear

clear() -> None

Remove all items in one transactional edit.

sort

sort(*, key: Callable[[T], Any] | None = None, reverse: bool = False) -> None

Sort entities without changing their identities.

reverse

reverse() -> None

Reverse entity order in the draft.

move

move(start: int, target: int, count: int = 1) -> None

Move a contiguous range to a final index, preserving its entities.

StoreSetter

StoreSetter(node: _Node)

Apply an atomic draft edit. Exceptions discard all changes from the call.

create_store

create_store(initial: list[T], seed: None = None) -> tuple[StoreList[T], StoreSetter[DraftList[T]]]
create_store(initial: S, seed: None = None) -> tuple[Store[S], StoreSetter[Draft[S]]]
create_store(initial: Callable[..., Any], seed: Any = None) -> tuple[Any, StoreSetter[Any]]
create_store(initial: Any, seed: Any = None) -> tuple[Any, StoreSetter]

Create a reactive mapping or sequence and its atomic draft setter.

A deriving function may return data or mutate its draft, synchronously or asynchronously. Its reads are tracked and its writes are staged together.

create_projection

create_projection(fn: Callable[..., Any], initial: Any = None) -> Any

Create a read-only derived store with memo readiness and refresh semantics.

create_optimistic_store

create_optimistic_store(source: Any, initial: Any = None) -> tuple[Any, Callable[[Any], None]]

Layer optimistic draft edits over a reactive authoritative source.

Active edits replay in submission order when the source changes. They are removed when their submitting action settles; other actions keep their edits. Draft callbacks must be deterministic: replay mustn't perform network or other side effects.

reconcile

reconcile(data: Any, key: str | Callable[[Any], Any] | None = 'id') -> Any

Prepare replacement data, preserving matched list entity identities.

key names the field that identifies list entities ("id" by default), or is a function computing the identity from an entity. key=None replaces list entities positionally. Duplicate keys are matched in occurrence order, without assigning the same entity to multiple rows.

snapshot

snapshot(value: Any) -> Any

Return a detached, untracked copy of the currently visible state.

deep

deep(value: Any) -> Any

Return a detached snapshot, tracking changes only within this subtree.