Major Changes
-
3cbcc3f: Serialized output no longer uses field names that start with
$or_. Stores such as Convex reject both prefixes, and MongoDB restricts$-prefixed field names, so persisted snapshots,systemTransitionsnapshots and effect descriptors could not be stored without rewriting them.Before After Where { $actor: address, incarnation }{ '@actor': address, incarnation }SerializedActorRef: persisted context,systemTransitionsnapshots, effect descriptors,sendTotargets, dead letters,@xstate/effectactortoJSON()_nextTimerIdnextTimerIdPersisted snapshots, systemTransitionsnapshots_nextActorIdsnextActorIdsPersisted snapshots, systemTransitionsnapshots_stateInputsstateInputssystemTransitionsnapshots (persisted snapshots already usedstateInputs){ $error: name, message }{ '@error': name, message }systemTransitionsnapshots,@xstate/testtraces{ $stateNode: id },{ $systemMapper: key }{ '@stateNode': id },{ '@systemMapper': key }systemTransitionsnapshots// Before { $actor: 'order/worker', incarnation: 'a:1' } // After { '@actor': 'order/worker', incarnation: 'a:1' }
snapshot.toJSON()no longer includes the private_nextTimerIdand_nextActorIdscounters.Snapshots written by
6.0.0-beta.1with the old field names still restore:restoreActor,restoreMachineSnapshotandsystemTransitionread both shapes. New snapshots use only the new names. Schemas that validate persisted snapshots (for example withmachineVersions) must use the new names.
Minor Changes
-
c558afa:
durable.checkpoint(snapshot)returns a checkpoint thatrestore()accepts: the persisted snapshot, the next transition index, and the inbox of root-addressed events that settledexecuteEffectsbatches captured butwaitForEvent()has not handed out. A child that completed in the last batch before a checkpoint now reaches its parent after restore, instead of leaving the parent waiting.await db.save(durable.checkpoint(state)); const resumed = createDurable(machine, adapter); let [state, effects] = resumed.restore(await db.load()); await resumed.executeEffects(effects);
restore()still accepts a bare persisted snapshot.Long-running durable executions no longer slow down or retain earlier snapshot system views as transitions accumulate. Executions that start from the same snapshot keep separate runtimes, timers and listeners.
Patch Changes
-
c70dd85: fix: apply new context keys and signed-zero updates in
createFSM, and preserve the snapshot for unchangedNaNvalues -
975ba72: An inline invoke's
onDone.event.outputis nowunknownwith no registered
actor sources. Uses.createInvoke({ src, onDone })or register the
actor insetup({ actors })to get its exact output type.const s = setup({}); const machine = s.createMachine({ invoke: s.createInvoke({ src: loadUser, onDone: ({ event }) => ({ context: { user: event.output } }) }) });
A literal invoke ID now types its entry in
snapshot.childrenfrom the invoked
actor. An emptyschemas.events: {}no longer erases the context and input
types in a final state's output callback. Restoring a machine held in Vue
reactive state now keeps its state value consistent after the next transition. -
0ebc550: Transitions that read
selforsystemno longer keep earlier snapshots alive. -
bbc8797: The error for a state key with an unescaped
.now uses plain punctuation:State key "foo.bar" contains ".". Nest the states or escape it as "foo\\.bar". -
757b605:
createFSMignores inherited state definitions when looking up outgoing transitions. Own state definitions, including state maps with a null prototype, continue to work. -
bcd3840: With an inspector attached, events that an actor sends outside a transition, such as a callback actor's
sendBackor an observable's values relayed to its parent, are no longer held in memory until that actor's next transition. They are also no longer listed in thesent[]of that later@xstate.transitionevent.sent[]lists only the events the transition itself sent. The receiving actor's@xstate.transitionstill reports each event with itssourceRef.