@@ -65,8 +65,8 @@ class methods or nominal class identity.
6565 transport boundary.
6666- Return snapshots or typed target-builder results from transitions. Do not
6767 return raw decoded state values.
68- - Effects returned by handlers are planning Effects. Wrap external effects in
69- ` Machine.action ` .
68+ - Transition and lifecycle callbacks are synchronous. Put asynchronous work in
69+ an invoked Effect, actor, or child machine and map its result to an event .
7070- Put data on the narrowest state where it is valid. Put data shared by sibling
7171 phases on their compound parent.
7272- Declare finality only in the state definition. Do not put ` type: "final" ` in
@@ -101,9 +101,8 @@ its extra control is required:
101101 ` Machine.childAddress<Event>(id) ` for a low-level process address. An
102102 invocation is addressable only when ` Machine.invoke ` receives that address
103103 explicitly.
104- - Stage external effects with ` Machine.action ` ; its optional second argument is
105- the same operation with a returned transition value, not a separate action
106- API.
104+ - Use the callback's ` enqueue ` argument for ` raise ` , ` emit ` , ` sendTo ` , and
105+ ` stop ` . These operations record closed actor commands and do not run Effects.
107106
108107## Atomic, compound, parallel, and history states
109108
@@ -389,8 +388,8 @@ BufferReady: ({ snapshot, target }) =>
389388
390389Use the existing ` States.matches ` , ` States.get ` , ` States.getWithParents ` , and
391390` States.getSnapshot ` helpers for cross-region reads. Parallel transitions
392- selected in one microstep receive the same capture. Effectful handlers retain
393- that captured value rather than consulting live runtime state.
391+ selected in one microstep receive the same capture. Synchronous handlers use
392+ that captured value and cannot consult live runtime state later .
394393
395394Do not expect ` snapshot ` in entry, exit, invoke, initializer, history-default,
396395or choice contexts. Choice is an important soundness boundary: a startup or
@@ -423,30 +422,25 @@ it through every phase.
423422
424423## Planning, actions, raised events, and emissions
425424
426- A transition may return a target directly or compute it in an Effect :
425+ A transition returns a target synchronously :
427426
428427``` ts
429- Submit : Effect .fn (function * ({ state , target }) {
430- const service = yield * SaveService
431- const canSave = yield * service .validate (state .draft )
432-
433- return canSave ? target .local .Saving (new Saving ({ draft: state .draft })) : undefined
434- })
428+ Submit : ({ state , target }) =>
429+ state .valid ? target .local .Saving (new Saving ({ draft: state .draft })) : undefined
435430```
436431
437- That Effect runs during planning. External side effects must be staged :
432+ Closed statechart and actor operations use ` enqueue ` :
438433
439434``` ts
440- Submit : ({ target }) => Machine .action (writeAuditLog , target .local .Saving (new Saving ({})))
435+ Submit : ({ target }, enqueue ) => {
436+ enqueue .emit (new SaveRequested ({}))
437+ return target .local .Saving (new Saving ({}))
438+ }
441439```
442440
443- ` Machine.action(effect) ` stages the action and returns ` void ` .
444- ` Machine.action(effect, next) ` stages the same action and returns ` next ` , which
445- is convenient when the transition does not otherwise need an Effect generator.
446-
447- The managed runtime executes staged actions before publishing the planned
448- state. If an action fails, it retains the previous state and suppresses planned
449- emissions.
441+ For asynchronous validation or persistence, invoke an Effect or child machine
442+ from the state and handle its typed success or failure event in a later
443+ transition. This keeps ` (state, event) => [nextState, commands] ` synchronous.
450444
451445Plans have a discriminated completion result:
452446
0 commit comments