JoyStore

class JoyStore(view: <Error class: unknown class>, initialState: <Error class: unknown class> = JsonObject(emptyMap()), resolver: <Error class: unknown class> = Resolver.Default, onEvent: (EmittedEvent) -> Unit? = null, onError: (LoggedEvent, ActionError) -> Unit? = null)

The one state owner: holds the state and the session log, and runs dispatch → apply → resolve serially.

state ──► resolve(view, state) ──► document ──► render
▲ │ interaction
└── dispatchEvent(state, binding, handlers) ◄───┘

Views fire; they never write. A fired binding is looked up by exact name in the document's handlers region — and a binding naming no handler is not an error, it simply emits to onEvent unchanged, which is how a document opts out of owning a given interaction.

A failed interaction is not rolled back: applyAction stops where it failed and everything already applied is committed, with the diagnostic delivered to onError. The store never throws out of dispatch — it runs in gesture callbacks.

Not thread-safe by design: dispatch is serial and re-entrant-safe (an event fired from inside onEvent queues behind the current one), and hosts confine it to one thread the way they already confine their UI.

Constructors

Link copied to clipboard
constructor(view: <Error class: unknown class>, initialState: <Error class: unknown class> = JsonObject(emptyMap()), resolver: <Error class: unknown class> = Resolver.Default, onEvent: (EmittedEvent) -> Unit? = null, onError: (LoggedEvent, ActionError) -> Unit? = null)

Properties

Link copied to clipboard
var document: <Error class: unknown class>

The resolved document for the current state — re-derived on every commit.

Link copied to clipboard

The document's handlers region, decoded. Re-read whenever the document changes.

Link copied to clipboard

The session log: initialState plus these interactions reproduces state.

Link copied to clipboard
var state: <Error class: unknown class>

The authoritative state. Only dispatch and rewind ever change it.

Functions

Link copied to clipboard
fun dispatch(binding: Action.Emit, payload: <Error class: unknown class> = JsonNull)

Feeds one fired binding into the loop.

Link copied to clipboard
fun rewind(entries: Int)

Truncates the log to its first entries interactions and re-folds them from the initial state — undo and time-travel. Nothing is delivered to the host: replaying is not re-living, and firing the events again would repeat effects it already saw.