Store
JourneyStore (src/core/store.ts) holds the latest immutable snapshot and distributes it. It has
two jobs:
- Hold the latest snapshot and notify selector listeners when their selected value changes.
- Deliver named lifecycle payloads (
stepEnter,stepLeave,statusChange,contextChange,navigationBlocked,error) to listeners for that event.
The store never derives state itself. Snapshots are rebuilt by the runtime; the store only publishes them.
Notification
Section titled “Notification”subscribe(listener) registers a plain per-commit callback. Publishing replaces the snapshot and
calls every listener; a publish whose snapshot is reference-equal to the current one is skipped
entirely, because structural sharing upstream returns the previous object verbatim when nothing
changed.
The store holds no selectors and no equality functions. Deriving a slice and suppressing unchanged
values is a rendering concern, and it needs to know which renders committed — so it lives in the
framework binding (useSelector in @rxova/journey-react), not here.
Listener isolation
Section titled “Listener isolation”Listener failures are caught per listener, so one subscriber cannot interrupt the runtime, the publish loop, or other subscribers. A throwing listener is reported and the loop continues.
Isolation is unconditional. What you can configure is where the report goes: the onListenerError
creation option receives the thrown value. Without it, the store reports through console.error.
If the configured reporter itself throws, the store falls back to the default console.error
report — a broken reporter can never re-enter the runtime.
const machine = createLinearJourney(definition, { onListenerError: (error) => errorTracker.capture(error)});Disposal
Section titled “Disposal”Disposing the machine drops every selector and event subscription. Later subscribe* calls return
a no-op unsubscribe.