Minor Changes
-
81dd3dd: Restoring a persisted snapshot moved out of
createActorintorestoreActor, exported from the newxstate/persistentry point.createActoronly starts fresh actors; passingsnapshotthrows with the replacement.// Before const actor = createActor(machine, { snapshot: persisted }); // After import { restoreActor } from 'xstate/persist'; const actor = restoreActor(machine, persisted);
restoreActor(logic, snapshot, options?)works for any actor logic and accepts thecreateActoroptions exceptinput. Passsystemto restore into a system fromcreateSystem():const actor = restoreActor(machine, persisted, { system });
Machine snapshots are validated and migrated, and invoked and spawned children are restored. A snapshot that cannot be restored produces an actor with an
'error'snapshot.machine.restoreSnapshot()is removed.machine.snapshotSchemaandmachine.eventSchemaare now functions:// Before await machine.snapshotSchema['~standard'].validate(value); await machine.eventSchema['~standard'].validate(input); // After import { eventSchema } from 'xstate'; import { snapshotSchema } from 'xstate/persist'; await snapshotSchema(machine)['~standard'].validate(value); await eventSchema(machine)['~standard'].validate(input);
machineVersions([...])accepts machines and{ id, version, snapshotSchema, eventSchema }descriptors as before. -
047cfb5: Leftover v5 configuration now throws in every build instead of only in development, so it cannot be silently ignored:
createMachine(config, implementations)andsetup(...).createMachine(config, implementations)throw. Declare implementations insetup({ ... })or pass them tomachine.provide({ ... }).services,activitiesanddevToolsin a machine config throw. They previously only warned in development.createActor(...)throws on an option it does not read. Removed options (systemId,state,devTools,parent,deferEvents,execute) throw with their replacement; any other unknown option throws with the list of supported options.
createActor(machine, { systemId: 'payments' }); // Error: The "systemId" actor option was renamed. Use "registryKey": createActor(logic, { registryKey }), and look the actor up with system.get(registryKey).
predictableActionArguments,preserveActionOrderandstrictchange nothing in v6 and still only warn in development. -
965c250: Macrosteps are unbounded by default, as in v5.
options.maxIterationsno longer defaults to1000, so a machine whose eventless transitions or raised events take more than 1000 microsteps for one event keeps running instead of erroring. In development builds, a macrostep that passes 1000 microsteps logs a warning once per machine. SetmaxIterationsto turn a runaway macrostep into anInfiniteTransitionError:const machine = createMachine({ options: { maxIterations: 5000 }, // ... });
Patch Changes
-
6cf6982: XState v6 enters beta. No further breaking changes are planned for APIs tagged
@public; any that are needed will be called out with a migration path. APIs tagged@experimentalmay still change. -
308c52d:
selfin actions, transition functions, context factories, input mappers and delay functions is typed as a machine actor ref instead ofanyin its children and meta positions. Delay andafterfunctions now receive the machine's emitted event type. -
a2e4161: Production builds report errors and diagnostics as short codes. Each message names the code, the values that identify the failing state, event, or actor, and a link to its entry in the error code reference:
XState error E1 ("services"). See https://github.com/statelyai/xstate/blob/next/docs/errors.md#e1Development messages are unchanged. Error classes and names are the same in both builds.
-
59fc7cd:
createMachinethrows when anonkey is a v5 suffixed lifecycle event type such as'xstate.done.actor.job','xstate.error.actor.job','xstate.done.state.form'or'xstate.after.1000.loading'. v6 never sends these types, so the transition never fired. The error names the replacement:// Throws: Transition "xstate.done.actor.job" in state "loading" never fires ... on: { 'xstate.done.actor.job': { target: 'done' } } // Use the category type and select the child with `matches` on: { 'xstate.done.actor': { matches: { actorId: 'job' }, target: 'done' } }
Wildcards such as
'xstate.done.actor.*'and the'xstate.snapshot.actor'type are unaffected.