xstate 6.0.0-alpha.21 → 6.0.0-alpha.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/{StateMachine-3c17fe3e.esm.js → StateMachine-022864fd.esm.js} +183 -64
  2. package/dist/{StateMachine-550ff7f2.development.cjs.js → StateMachine-53114dce.development.cjs.js} +187 -63
  3. package/dist/{StateMachine-1b155670.cjs.js → StateMachine-aad57180.cjs.js} +187 -63
  4. package/dist/{StateMachine-e25dd61f.development.esm.js → StateMachine-d2247245.development.esm.js} +183 -64
  5. package/dist/declarations/src/State.d.ts +4 -2
  6. package/dist/declarations/src/StateMachine.d.ts +5 -4
  7. package/dist/declarations/src/actions.d.ts +10 -8
  8. package/dist/declarations/src/actors/logic.d.ts +5 -21
  9. package/dist/declarations/src/createActor.d.ts +3 -1
  10. package/dist/declarations/src/fsm.d.ts +3 -1
  11. package/dist/declarations/src/index.d.ts +2 -2
  12. package/dist/declarations/src/spawn.d.ts +3 -3
  13. package/dist/declarations/src/stateUtils.d.ts +1 -1
  14. package/dist/declarations/src/system.d.ts +34 -9
  15. package/dist/declarations/src/transitionActions.d.ts +5 -1
  16. package/dist/declarations/src/types.d.ts +70 -51
  17. package/dist/{index-3f87408c.esm.js → index-3609e096.esm.js} +782 -389
  18. package/dist/{index-ec7c7a2d.development.cjs.js → index-41c0375c.development.cjs.js} +790 -390
  19. package/dist/{index-e694228c.cjs.js → index-434fac23.cjs.js} +789 -389
  20. package/dist/{index-d39fb138.development.esm.js → index-f5407323.development.esm.js} +783 -390
  21. package/dist/xstate-actors.cjs.js +1 -1
  22. package/dist/xstate-actors.development.cjs.js +1 -1
  23. package/dist/xstate-actors.development.esm.js +1 -1
  24. package/dist/xstate-actors.esm.js +1 -1
  25. package/dist/xstate-actors.umd.min.js +1 -1
  26. package/dist/xstate-actors.umd.min.js.map +1 -1
  27. package/dist/xstate-graph.cjs.js +2 -2
  28. package/dist/xstate-graph.development.cjs.js +2 -2
  29. package/dist/xstate-graph.development.esm.js +2 -2
  30. package/dist/xstate-graph.esm.js +2 -2
  31. package/dist/xstate-graph.umd.min.js +1 -1
  32. package/dist/xstate-graph.umd.min.js.map +1 -1
  33. package/dist/xstate.cjs.js +82 -103
  34. package/dist/xstate.cjs.mjs +1 -0
  35. package/dist/xstate.development.cjs.js +82 -103
  36. package/dist/xstate.development.cjs.mjs +1 -0
  37. package/dist/xstate.development.esm.js +80 -102
  38. package/dist/xstate.esm.js +80 -102
  39. package/dist/xstate.umd.min.js +1 -1
  40. package/dist/xstate.umd.min.js.map +1 -1
  41. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
- import { m as matchesEventDescriptor, t as toArray$1, b as builtInActions, X as XSTATE_INIT, d as deriveDeferredStarts, c as createTransitionEnqueue, a as XSTATE_STOP, r as resolveActionsWithContext, p as parseDelayToMilliseconds, i as isAtomicStateNode, e as createActor, f as macrostep, g as createInitEvent, h as initialMicrostep, j as getProperAncestors } from './index-d39fb138.development.esm.js';
2
- export { A as Actor, T as TimeoutError, n as __unsafe_getAllOwnEventDescriptors, q as checkStateIn, e as createActor, C as createAsyncLogic, x as createCallbackLogic, w as createEmptyActor, z as createEventObservableLogic, D as createListenerLogic, B as createLogic, y as createObservableLogic, F as createSubscriptionLogic, l as getStateNodes, v as isBuiltInExecutableAction, k as isMachineSnapshot, E as listenerLogic, o as matchesState, s as pathToStateValue, G as subscriptionLogic, u as toObserver } from './index-d39fb138.development.esm.js';
3
- import { S as StateMachine } from './StateMachine-e25dd61f.development.esm.js';
4
- export { S as StateMachine, a as StateNode } from './StateMachine-e25dd61f.development.esm.js';
1
+ import { m as matchesEventDescriptor, t as toArray$1, b as builtInActions, X as XSTATE_INIT, f as finalizeTransitionResult, d as deriveDeferredStarts, c as createTransitionEnqueue, a as XSTATE_STOP, r as resolveActionsWithContext, e as XSTATE_TIMER, g as createSendToEffect, p as parseDelayToMilliseconds, i as isAtomicStateNode, h as createActor, j as macrostep, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, o as getProperAncestors } from './index-f5407323.development.esm.js';
2
+ export { A as Actor, T as TimeoutError, u as __unsafe_getAllOwnEventDescriptors, w as checkStateIn, h as createActor, H as createAsyncLogic, D as createCallbackLogic, C as createEmptyActor, F as createEventObservableLogic, I as createListenerLogic, G as createLogic, E as createObservableLogic, K as createSubscriptionLogic, z as executeEffects, s as getStateNodes, B as isBuiltInExecutableAction, q as isMachineSnapshot, J as listenerLogic, v as matchesState, x as pathToStateValue, L as subscriptionLogic, y as toObserver } from './index-f5407323.development.esm.js';
3
+ import { S as StateMachine, c as createInertActorScope, s as setInertActorScopeSnapshot, a as attachSnapshotActorRef } from './StateMachine-d2247245.development.esm.js';
4
+ export { S as StateMachine, d as StateNode, g as getInitialSnapshot, b as getNextSnapshot } from './StateMachine-d2247245.development.esm.js';
5
5
 
6
6
  /**
7
7
  * Asserts that the given event object is of the specified type or types. Throws
@@ -135,6 +135,8 @@ function createSnapshot(value, context, input, machine, stateInput) {
135
135
  context,
136
136
  input,
137
137
  children: {},
138
+ timers: {},
139
+ _nextTimerId: 0,
138
140
  _stateInput: stateInput,
139
141
  machine
140
142
  };
@@ -148,6 +150,8 @@ function cloneSnapshot(snapshot, value, context, stateInput) {
148
150
  context,
149
151
  input: snapshot.input,
150
152
  children: snapshot.children,
153
+ timers: snapshot.timers,
154
+ _nextTimerId: snapshot._nextTimerId,
151
155
  _stateInput: stateInput,
152
156
  machine: snapshot.machine
153
157
  };
@@ -161,6 +165,8 @@ function stopSnapshot(snapshot) {
161
165
  context: snapshot.context,
162
166
  input: undefined,
163
167
  children: snapshot.children,
168
+ timers: snapshot.timers,
169
+ _nextTimerId: snapshot._nextTimerId,
164
170
  _stateInput: snapshot._stateInput,
165
171
  machine: snapshot.machine
166
172
  };
@@ -184,10 +190,14 @@ function resolveSimpleEnqueuedActions(rawActions) {
184
190
  return undefined;
185
191
  }
186
192
  executableActions.push({
193
+ kind: 'action',
187
194
  type: action.action.name || '(anonymous)',
188
195
  params: undefined,
189
196
  args: action.args,
190
- exec: action.args.length ? action.action.bind(null, ...action.args) : action.action
197
+ action: action.action,
198
+ exec() {
199
+ return this.action?.(...this.args);
200
+ }
191
201
  });
192
202
  }
193
203
  return executableActions;
@@ -294,7 +304,32 @@ function createFSM(config) {
294
304
  return [snapshot, []];
295
305
  }
296
306
  if (event.type === XSTATE_STOP) {
297
- return [stopSnapshot(snapshot), emptyExecutableActions];
307
+ const actions = [];
308
+ const enqueue = createTransitionEnqueue(actorScope, actions, []);
309
+ for (const id of Object.keys(snapshot.timers)) {
310
+ enqueue.cancel(id);
311
+ }
312
+ const [withoutTimers, cancelEffects] = resolveActionsWithContext(snapshot, event, actorScope, actions);
313
+ return [stopSnapshot(withoutTimers), cancelEffects];
314
+ }
315
+ if (event.type === XSTATE_TIMER) {
316
+ const timer = snapshot.timers[event.id];
317
+ if (!timer) {
318
+ return [snapshot, emptyExecutableActions];
319
+ }
320
+ const timers = {
321
+ ...snapshot.timers
322
+ };
323
+ delete timers[timer.id];
324
+ const nextSnapshot = {
325
+ ...snapshot,
326
+ timers
327
+ };
328
+ if (timer.type === '@xstate.raise') {
329
+ return transitionCore(nextSnapshot, timer.event, actorScope);
330
+ }
331
+ const target = timer.target === 'self' ? actorScope.self : timer.target;
332
+ return [nextSnapshot, [createSendToEffect(actorScope, target, timer.event)]];
298
333
  }
299
334
  const stateConfig = config.states[snapshot.value];
300
335
  const directTransition = stateConfig?.on?.[event.type];
@@ -390,7 +425,7 @@ function createFSM(config) {
390
425
  };
391
426
  const transition = (...args) => {
392
427
  const [nextSnapshot, effects] = transitionCore(...args);
393
- return [nextSnapshot, [...effects, ...deriveDeferredStarts(effects)]];
428
+ return finalizeTransitionResult(args[2], args[0], [nextSnapshot, [...effects, ...deriveDeferredStarts(effects)]]);
394
429
  };
395
430
  const logic = {
396
431
  id: config.id,
@@ -411,7 +446,7 @@ function createFSM(config) {
411
446
  nextSnapshot = raisedSnapshot;
412
447
  actions.push(...raisedActions);
413
448
  }
414
- return [nextSnapshot, [...actions, ...deriveDeferredStarts(actions)]];
449
+ return finalizeTransitionResult(actorScope, undefined, [nextSnapshot, [...actions, ...deriveDeferredStarts(actions)]]);
415
450
  },
416
451
  getInitialSnapshot: (actorScope, input) => logic.initialTransition(input, actorScope)[0],
417
452
  getPersistedSnapshot: ({
@@ -2180,71 +2215,6 @@ function mergeSetupConfigs(base, extension) {
2180
2215
  };
2181
2216
  }
2182
2217
 
2183
- /** @internal */
2184
- function createInertActorScope(actorLogic) {
2185
- const self = createActor(actorLogic, {
2186
- _inert: true
2187
- });
2188
- const inertActorScope = {
2189
- self: self,
2190
- defer: () => {},
2191
- id: '',
2192
- logger: () => {},
2193
- sessionId: '',
2194
- stopChild: () => {},
2195
- system: self.system,
2196
- emit: () => {},
2197
- actionExecutor: () => {}
2198
- };
2199
- return inertActorScope;
2200
- }
2201
-
2202
- /** @deprecated Use `initialTransition(…)` instead. */
2203
- function getInitialSnapshot(actorLogic, ...[input]) {
2204
- const actorScope = createInertActorScope(actorLogic);
2205
- return actorLogic.initialTransition(input, actorScope)[0];
2206
- }
2207
-
2208
- /**
2209
- * Determines the next snapshot for the given `actorLogic` based on the given
2210
- * `snapshot` and `event`.
2211
- *
2212
- * If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
2213
- * used.
2214
- *
2215
- * @deprecated Use `transition(…)` instead.
2216
- * @example
2217
- *
2218
- * ```ts
2219
- * import { getNextSnapshot } from 'xstate';
2220
- * import { trafficLightMachine } from './trafficLightMachine.ts';
2221
- *
2222
- * const nextSnapshot = getNextSnapshot(
2223
- * trafficLightMachine, // actor logic
2224
- * undefined, // snapshot (or initial state if undefined)
2225
- * { type: 'TIMER' }
2226
- * ); // event object
2227
- *
2228
- * console.log(nextSnapshot.value);
2229
- * // => 'yellow'
2230
- *
2231
- * const nextSnapshot2 = getNextSnapshot(
2232
- * trafficLightMachine, // actor logic
2233
- * nextSnapshot, // snapshot
2234
- * { type: 'TIMER' }
2235
- * ); // event object
2236
- *
2237
- * console.log(nextSnapshot2.value);
2238
- * // =>'red'
2239
- * ```
2240
- */
2241
- function getNextSnapshot(actorLogic, snapshot, event) {
2242
- const inertActorScope = createInertActorScope(actorLogic);
2243
- inertActorScope.self._snapshot = snapshot;
2244
- const transitionResult = actorLogic.transition(snapshot, event, inertActorScope);
2245
- return Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
2246
- }
2247
-
2248
2218
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
2249
2219
 
2250
2220
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
@@ -2401,24 +2371,9 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2401
2371
  return SpecialTargets;
2402
2372
  }({});
2403
2373
 
2404
- /**
2405
- * A pending effect (delayed event/transition that has not fired yet) captured
2406
- * in a persisted snapshot — a serialized built-in action descriptor plus its
2407
- * runtime progress, with enough information to restore it under any strategy.
2408
- */
2374
+ /** A deterministic delayed-delivery declaration owned by a logic snapshot. */
2409
2375
 
2410
- /**
2411
- * How pending effects (timers) from a persisted snapshot are restored on
2412
- * `actor.start()`:
2413
- *
2414
- * - `'resume'` (default) — the clock was "frozen" while persisted: a 5-minute
2415
- * timer persisted with 1 minute elapsed fires after 4 more minutes.
2416
- * - `'restart'` — timers start over with their full delay.
2417
- * - `'absolute'` — timers honor the original wall-clock expiry (`startedAt +
2418
- * delay`); already-expired timers fire immediately.
2419
- * - A custom function receiving the pending effect and returning the remaining
2420
- * delay in ms.
2421
- */
2376
+ /** The logical input delivered to a timer's source when its runtime delay ends. */
2422
2377
 
2423
2378
  /** @deprecated Use `AnyActor` instead. */
2424
2379
 
@@ -2464,8 +2419,6 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2464
2419
 
2465
2420
  /** The concrete actor instance type produced from actor logic. */
2466
2421
 
2467
- // TODO: in v6, this should only accept AnyActorLogic, like ActorRefFromLogic
2468
-
2469
2422
  /**
2470
2423
  * Represents logic which can be used by an actor.
2471
2424
  *
@@ -2483,8 +2436,27 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2483
2436
 
2484
2437
  /** @deprecated */
2485
2438
 
2439
+ /** The terminal result published when an actor completes or errors. */
2440
+
2441
+ /** An executable effect that publishes an actor's terminal result. */
2442
+
2486
2443
  /** Mappers for subscribeTo - maps lifecycle events to machine events */
2487
2444
 
2445
+ function attachMicrostepActorRefs(microsteps, actorScope, inputSnapshot) {
2446
+ if (!microsteps.length) {
2447
+ return microsteps;
2448
+ }
2449
+ const result = microsteps.slice();
2450
+ const finalSnapshot = result.at(-1)[0];
2451
+ setInertActorScopeSnapshot(actorScope, finalSnapshot, false);
2452
+ for (const [snapshot] of result) {
2453
+ if (snapshot !== inputSnapshot) {
2454
+ attachSnapshotActorRef(snapshot.machine, actorScope, snapshot);
2455
+ }
2456
+ }
2457
+ return result;
2458
+ }
2459
+
2488
2460
  /**
2489
2461
  * Given actor `logic`, a `snapshot`, and an `event`, returns a tuple of the
2490
2462
  * `nextSnapshot` and `actions` to execute.
@@ -2492,9 +2464,12 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2492
2464
  * This is a pure function that does not execute `actions`.
2493
2465
  */
2494
2466
  function transition(logic, snapshot, event) {
2495
- const actorScope = createInertActorScope(logic);
2496
- const [nextSnapshot, effects] = logic.transition(snapshot, event, actorScope);
2497
- return [nextSnapshot, effects];
2467
+ const actorScope = createInertActorScope(logic, snapshot);
2468
+ setInertActorScopeSnapshot(actorScope, snapshot, false);
2469
+ const [nextSnapshot, effects] = finalizeTransitionResult(actorScope, snapshot, logic.transition(snapshot, event, actorScope));
2470
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
2471
+ const returnedSnapshot = nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(logic, actorScope, nextSnapshot);
2472
+ return [returnedSnapshot, effects];
2498
2473
  }
2499
2474
 
2500
2475
  /**
@@ -2506,8 +2481,10 @@ function transition(logic, snapshot, event) {
2506
2481
  */
2507
2482
  function initialTransition(logic, ...[input]) {
2508
2483
  const actorScope = createInertActorScope(logic);
2509
- const [nextSnapshot, executableActions] = logic.initialTransition(input, actorScope);
2510
- return [nextSnapshot, executableActions];
2484
+ const [nextSnapshot, executableActions] = finalizeTransitionResult(actorScope, undefined, logic.initialTransition(input, actorScope));
2485
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
2486
+ const returnedSnapshot = attachSnapshotActorRef(logic, actorScope, nextSnapshot);
2487
+ return [returnedSnapshot, executableActions];
2511
2488
  }
2512
2489
 
2513
2490
  /**
@@ -2517,11 +2494,11 @@ function initialTransition(logic, ...[input]) {
2517
2494
  * This is a pure function that does not execute `actions`.
2518
2495
  */
2519
2496
  function getMicrosteps(machine, snapshot, event) {
2520
- const actorScope = createInertActorScope(machine);
2497
+ const actorScope = createInertActorScope(machine, snapshot);
2521
2498
  const {
2522
2499
  microsteps
2523
2500
  } = macrostep(snapshot, event, actorScope, []);
2524
- return microsteps;
2501
+ return attachMicrostepActorRefs(microsteps, actorScope, snapshot);
2525
2502
  }
2526
2503
 
2527
2504
  /**
@@ -2536,11 +2513,12 @@ function getInitialMicrosteps(machine, ...[input]) {
2536
2513
  const initEvent = createInitEvent(input);
2537
2514
  const internalQueue = [];
2538
2515
  const preInitialSnapshot = machine._getPreInitialState(actorScope, initEvent);
2516
+ const contextSpawnEffects = Object.values(preInitialSnapshot.children).filter(Boolean).map(actor => createSpawnEffect(actor));
2539
2517
  const first = initialMicrostep(machine.root, preInitialSnapshot, actorScope, initEvent, internalQueue);
2540
2518
  const {
2541
2519
  microsteps
2542
- } = macrostep(first[0], initEvent, actorScope, internalQueue);
2543
- return [first, ...microsteps];
2520
+ } = macrostep(first[0], initEvent, actorScope, internalQueue, [[first[0], [...contextSpawnEffects, ...first[1]]]]);
2521
+ return attachMicrostepActorRefs(microsteps, actorScope);
2544
2522
  }
2545
2523
 
2546
2524
  /**
@@ -2703,4 +2681,4 @@ function waitFor(actorRef, predicate, options) {
2703
2681
  });
2704
2682
  }
2705
2683
 
2706
- export { SimulatedClock, SpecialTargets, assertEvent, createFSM, createMachine, createMachineFromConfig, createStateConfig, createSystem, getInitialMicrosteps, getInitialSnapshot, getMicrosteps, getNextSnapshot, getNextTransitions, initialTransition, isTypeSchema, machineConfigToJSON, mapState, serializeMachine, setup, toPromise, transition, types, waitFor };
2684
+ export { SimulatedClock, SpecialTargets, assertEvent, createFSM, createMachine, createMachineFromConfig, createStateConfig, createSystem, getInitialMicrosteps, getMicrosteps, getNextTransitions, initialTransition, isTypeSchema, machineConfigToJSON, mapState, serializeMachine, setup, toPromise, transition, types, waitFor };
@@ -1,7 +1,7 @@
1
- import { m as matchesEventDescriptor, t as toArray$1, b as builtInActions, X as XSTATE_INIT, d as deriveDeferredStarts, c as createTransitionEnqueue, a as XSTATE_STOP, r as resolveActionsWithContext, p as parseDelayToMilliseconds, i as isAtomicStateNode, e as createActor, f as macrostep, g as createInitEvent, h as initialMicrostep, j as getProperAncestors } from './index-3f87408c.esm.js';
2
- export { A as Actor, T as TimeoutError, n as __unsafe_getAllOwnEventDescriptors, q as checkStateIn, e as createActor, C as createAsyncLogic, x as createCallbackLogic, w as createEmptyActor, z as createEventObservableLogic, D as createListenerLogic, B as createLogic, y as createObservableLogic, F as createSubscriptionLogic, l as getStateNodes, v as isBuiltInExecutableAction, k as isMachineSnapshot, E as listenerLogic, o as matchesState, s as pathToStateValue, G as subscriptionLogic, u as toObserver } from './index-3f87408c.esm.js';
3
- import { S as StateMachine } from './StateMachine-3c17fe3e.esm.js';
4
- export { S as StateMachine, a as StateNode } from './StateMachine-3c17fe3e.esm.js';
1
+ import { m as matchesEventDescriptor, t as toArray$1, b as builtInActions, X as XSTATE_INIT, f as finalizeTransitionResult, d as deriveDeferredStarts, c as createTransitionEnqueue, a as XSTATE_STOP, r as resolveActionsWithContext, e as XSTATE_TIMER, g as createSendToEffect, p as parseDelayToMilliseconds, i as isAtomicStateNode, h as createActor, j as macrostep, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, o as getProperAncestors } from './index-3609e096.esm.js';
2
+ export { A as Actor, T as TimeoutError, u as __unsafe_getAllOwnEventDescriptors, w as checkStateIn, h as createActor, H as createAsyncLogic, D as createCallbackLogic, C as createEmptyActor, F as createEventObservableLogic, I as createListenerLogic, G as createLogic, E as createObservableLogic, K as createSubscriptionLogic, z as executeEffects, s as getStateNodes, B as isBuiltInExecutableAction, q as isMachineSnapshot, J as listenerLogic, v as matchesState, x as pathToStateValue, L as subscriptionLogic, y as toObserver } from './index-3609e096.esm.js';
3
+ import { S as StateMachine, c as createInertActorScope, s as setInertActorScopeSnapshot, a as attachSnapshotActorRef } from './StateMachine-022864fd.esm.js';
4
+ export { S as StateMachine, d as StateNode, g as getInitialSnapshot, b as getNextSnapshot } from './StateMachine-022864fd.esm.js';
5
5
 
6
6
  /**
7
7
  * Asserts that the given event object is of the specified type or types. Throws
@@ -135,6 +135,8 @@ function createSnapshot(value, context, input, machine, stateInput) {
135
135
  context,
136
136
  input,
137
137
  children: {},
138
+ timers: {},
139
+ _nextTimerId: 0,
138
140
  _stateInput: stateInput,
139
141
  machine
140
142
  };
@@ -148,6 +150,8 @@ function cloneSnapshot(snapshot, value, context, stateInput) {
148
150
  context,
149
151
  input: snapshot.input,
150
152
  children: snapshot.children,
153
+ timers: snapshot.timers,
154
+ _nextTimerId: snapshot._nextTimerId,
151
155
  _stateInput: stateInput,
152
156
  machine: snapshot.machine
153
157
  };
@@ -161,6 +165,8 @@ function stopSnapshot(snapshot) {
161
165
  context: snapshot.context,
162
166
  input: undefined,
163
167
  children: snapshot.children,
168
+ timers: snapshot.timers,
169
+ _nextTimerId: snapshot._nextTimerId,
164
170
  _stateInput: snapshot._stateInput,
165
171
  machine: snapshot.machine
166
172
  };
@@ -184,10 +190,14 @@ function resolveSimpleEnqueuedActions(rawActions) {
184
190
  return undefined;
185
191
  }
186
192
  executableActions.push({
193
+ kind: 'action',
187
194
  type: action.action.name || '(anonymous)',
188
195
  params: undefined,
189
196
  args: action.args,
190
- exec: action.args.length ? action.action.bind(null, ...action.args) : action.action
197
+ action: action.action,
198
+ exec() {
199
+ return this.action?.(...this.args);
200
+ }
191
201
  });
192
202
  }
193
203
  return executableActions;
@@ -294,7 +304,32 @@ function createFSM(config) {
294
304
  return [snapshot, []];
295
305
  }
296
306
  if (event.type === XSTATE_STOP) {
297
- return [stopSnapshot(snapshot), emptyExecutableActions];
307
+ const actions = [];
308
+ const enqueue = createTransitionEnqueue(actorScope, actions, []);
309
+ for (const id of Object.keys(snapshot.timers)) {
310
+ enqueue.cancel(id);
311
+ }
312
+ const [withoutTimers, cancelEffects] = resolveActionsWithContext(snapshot, event, actorScope, actions);
313
+ return [stopSnapshot(withoutTimers), cancelEffects];
314
+ }
315
+ if (event.type === XSTATE_TIMER) {
316
+ const timer = snapshot.timers[event.id];
317
+ if (!timer) {
318
+ return [snapshot, emptyExecutableActions];
319
+ }
320
+ const timers = {
321
+ ...snapshot.timers
322
+ };
323
+ delete timers[timer.id];
324
+ const nextSnapshot = {
325
+ ...snapshot,
326
+ timers
327
+ };
328
+ if (timer.type === '@xstate.raise') {
329
+ return transitionCore(nextSnapshot, timer.event, actorScope);
330
+ }
331
+ const target = timer.target === 'self' ? actorScope.self : timer.target;
332
+ return [nextSnapshot, [createSendToEffect(actorScope, target, timer.event)]];
298
333
  }
299
334
  const stateConfig = config.states[snapshot.value];
300
335
  const directTransition = stateConfig?.on?.[event.type];
@@ -390,7 +425,7 @@ function createFSM(config) {
390
425
  };
391
426
  const transition = (...args) => {
392
427
  const [nextSnapshot, effects] = transitionCore(...args);
393
- return [nextSnapshot, [...effects, ...deriveDeferredStarts(effects)]];
428
+ return finalizeTransitionResult(args[2], args[0], [nextSnapshot, [...effects, ...deriveDeferredStarts(effects)]]);
394
429
  };
395
430
  const logic = {
396
431
  id: config.id,
@@ -411,7 +446,7 @@ function createFSM(config) {
411
446
  nextSnapshot = raisedSnapshot;
412
447
  actions.push(...raisedActions);
413
448
  }
414
- return [nextSnapshot, [...actions, ...deriveDeferredStarts(actions)]];
449
+ return finalizeTransitionResult(actorScope, undefined, [nextSnapshot, [...actions, ...deriveDeferredStarts(actions)]]);
415
450
  },
416
451
  getInitialSnapshot: (actorScope, input) => logic.initialTransition(input, actorScope)[0],
417
452
  getPersistedSnapshot: ({
@@ -2180,71 +2215,6 @@ function mergeSetupConfigs(base, extension) {
2180
2215
  };
2181
2216
  }
2182
2217
 
2183
- /** @internal */
2184
- function createInertActorScope(actorLogic) {
2185
- const self = createActor(actorLogic, {
2186
- _inert: true
2187
- });
2188
- const inertActorScope = {
2189
- self: self,
2190
- defer: () => {},
2191
- id: '',
2192
- logger: () => {},
2193
- sessionId: '',
2194
- stopChild: () => {},
2195
- system: self.system,
2196
- emit: () => {},
2197
- actionExecutor: () => {}
2198
- };
2199
- return inertActorScope;
2200
- }
2201
-
2202
- /** @deprecated Use `initialTransition(…)` instead. */
2203
- function getInitialSnapshot(actorLogic, ...[input]) {
2204
- const actorScope = createInertActorScope(actorLogic);
2205
- return actorLogic.initialTransition(input, actorScope)[0];
2206
- }
2207
-
2208
- /**
2209
- * Determines the next snapshot for the given `actorLogic` based on the given
2210
- * `snapshot` and `event`.
2211
- *
2212
- * If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
2213
- * used.
2214
- *
2215
- * @deprecated Use `transition(…)` instead.
2216
- * @example
2217
- *
2218
- * ```ts
2219
- * import { getNextSnapshot } from 'xstate';
2220
- * import { trafficLightMachine } from './trafficLightMachine.ts';
2221
- *
2222
- * const nextSnapshot = getNextSnapshot(
2223
- * trafficLightMachine, // actor logic
2224
- * undefined, // snapshot (or initial state if undefined)
2225
- * { type: 'TIMER' }
2226
- * ); // event object
2227
- *
2228
- * console.log(nextSnapshot.value);
2229
- * // => 'yellow'
2230
- *
2231
- * const nextSnapshot2 = getNextSnapshot(
2232
- * trafficLightMachine, // actor logic
2233
- * nextSnapshot, // snapshot
2234
- * { type: 'TIMER' }
2235
- * ); // event object
2236
- *
2237
- * console.log(nextSnapshot2.value);
2238
- * // =>'red'
2239
- * ```
2240
- */
2241
- function getNextSnapshot(actorLogic, snapshot, event) {
2242
- const inertActorScope = createInertActorScope(actorLogic);
2243
- inertActorScope.self._snapshot = snapshot;
2244
- const transitionResult = actorLogic.transition(snapshot, event, inertActorScope);
2245
- return Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
2246
- }
2247
-
2248
2218
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
2249
2219
 
2250
2220
  // eslint-disable-next-line @typescript-eslint/no-unsafe-declaration-merging
@@ -2401,24 +2371,9 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2401
2371
  return SpecialTargets;
2402
2372
  }({});
2403
2373
 
2404
- /**
2405
- * A pending effect (delayed event/transition that has not fired yet) captured
2406
- * in a persisted snapshot — a serialized built-in action descriptor plus its
2407
- * runtime progress, with enough information to restore it under any strategy.
2408
- */
2374
+ /** A deterministic delayed-delivery declaration owned by a logic snapshot. */
2409
2375
 
2410
- /**
2411
- * How pending effects (timers) from a persisted snapshot are restored on
2412
- * `actor.start()`:
2413
- *
2414
- * - `'resume'` (default) — the clock was "frozen" while persisted: a 5-minute
2415
- * timer persisted with 1 minute elapsed fires after 4 more minutes.
2416
- * - `'restart'` — timers start over with their full delay.
2417
- * - `'absolute'` — timers honor the original wall-clock expiry (`startedAt +
2418
- * delay`); already-expired timers fire immediately.
2419
- * - A custom function receiving the pending effect and returning the remaining
2420
- * delay in ms.
2421
- */
2376
+ /** The logical input delivered to a timer's source when its runtime delay ends. */
2422
2377
 
2423
2378
  /** @deprecated Use `AnyActor` instead. */
2424
2379
 
@@ -2464,8 +2419,6 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2464
2419
 
2465
2420
  /** The concrete actor instance type produced from actor logic. */
2466
2421
 
2467
- // TODO: in v6, this should only accept AnyActorLogic, like ActorRefFromLogic
2468
-
2469
2422
  /**
2470
2423
  * Represents logic which can be used by an actor.
2471
2424
  *
@@ -2483,8 +2436,27 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2483
2436
 
2484
2437
  /** @deprecated */
2485
2438
 
2439
+ /** The terminal result published when an actor completes or errors. */
2440
+
2441
+ /** An executable effect that publishes an actor's terminal result. */
2442
+
2486
2443
  /** Mappers for subscribeTo - maps lifecycle events to machine events */
2487
2444
 
2445
+ function attachMicrostepActorRefs(microsteps, actorScope, inputSnapshot) {
2446
+ if (!microsteps.length) {
2447
+ return microsteps;
2448
+ }
2449
+ const result = microsteps.slice();
2450
+ const finalSnapshot = result.at(-1)[0];
2451
+ setInertActorScopeSnapshot(actorScope, finalSnapshot, false);
2452
+ for (const [snapshot] of result) {
2453
+ if (snapshot !== inputSnapshot) {
2454
+ attachSnapshotActorRef(snapshot.machine, actorScope, snapshot);
2455
+ }
2456
+ }
2457
+ return result;
2458
+ }
2459
+
2488
2460
  /**
2489
2461
  * Given actor `logic`, a `snapshot`, and an `event`, returns a tuple of the
2490
2462
  * `nextSnapshot` and `actions` to execute.
@@ -2492,9 +2464,12 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
2492
2464
  * This is a pure function that does not execute `actions`.
2493
2465
  */
2494
2466
  function transition(logic, snapshot, event) {
2495
- const actorScope = createInertActorScope(logic);
2496
- const [nextSnapshot, effects] = logic.transition(snapshot, event, actorScope);
2497
- return [nextSnapshot, effects];
2467
+ const actorScope = createInertActorScope(logic, snapshot);
2468
+ setInertActorScopeSnapshot(actorScope, snapshot, false);
2469
+ const [nextSnapshot, effects] = finalizeTransitionResult(actorScope, snapshot, logic.transition(snapshot, event, actorScope));
2470
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
2471
+ const returnedSnapshot = nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(logic, actorScope, nextSnapshot);
2472
+ return [returnedSnapshot, effects];
2498
2473
  }
2499
2474
 
2500
2475
  /**
@@ -2506,8 +2481,10 @@ function transition(logic, snapshot, event) {
2506
2481
  */
2507
2482
  function initialTransition(logic, ...[input]) {
2508
2483
  const actorScope = createInertActorScope(logic);
2509
- const [nextSnapshot, executableActions] = logic.initialTransition(input, actorScope);
2510
- return [nextSnapshot, executableActions];
2484
+ const [nextSnapshot, executableActions] = finalizeTransitionResult(actorScope, undefined, logic.initialTransition(input, actorScope));
2485
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
2486
+ const returnedSnapshot = attachSnapshotActorRef(logic, actorScope, nextSnapshot);
2487
+ return [returnedSnapshot, executableActions];
2511
2488
  }
2512
2489
 
2513
2490
  /**
@@ -2517,11 +2494,11 @@ function initialTransition(logic, ...[input]) {
2517
2494
  * This is a pure function that does not execute `actions`.
2518
2495
  */
2519
2496
  function getMicrosteps(machine, snapshot, event) {
2520
- const actorScope = createInertActorScope(machine);
2497
+ const actorScope = createInertActorScope(machine, snapshot);
2521
2498
  const {
2522
2499
  microsteps
2523
2500
  } = macrostep(snapshot, event, actorScope, []);
2524
- return microsteps;
2501
+ return attachMicrostepActorRefs(microsteps, actorScope, snapshot);
2525
2502
  }
2526
2503
 
2527
2504
  /**
@@ -2536,11 +2513,12 @@ function getInitialMicrosteps(machine, ...[input]) {
2536
2513
  const initEvent = createInitEvent(input);
2537
2514
  const internalQueue = [];
2538
2515
  const preInitialSnapshot = machine._getPreInitialState(actorScope, initEvent);
2516
+ const contextSpawnEffects = Object.values(preInitialSnapshot.children).filter(Boolean).map(actor => createSpawnEffect(actor));
2539
2517
  const first = initialMicrostep(machine.root, preInitialSnapshot, actorScope, initEvent, internalQueue);
2540
2518
  const {
2541
2519
  microsteps
2542
- } = macrostep(first[0], initEvent, actorScope, internalQueue);
2543
- return [first, ...microsteps];
2520
+ } = macrostep(first[0], initEvent, actorScope, internalQueue, [[first[0], [...contextSpawnEffects, ...first[1]]]]);
2521
+ return attachMicrostepActorRefs(microsteps, actorScope);
2544
2522
  }
2545
2523
 
2546
2524
  /**
@@ -2700,4 +2678,4 @@ function waitFor(actorRef, predicate, options) {
2700
2678
  });
2701
2679
  }
2702
2680
 
2703
- export { SimulatedClock, SpecialTargets, assertEvent, createFSM, createMachine, createMachineFromConfig, createStateConfig, createSystem, getInitialMicrosteps, getInitialSnapshot, getMicrosteps, getNextSnapshot, getNextTransitions, initialTransition, isTypeSchema, machineConfigToJSON, mapState, serializeMachine, setup, toPromise, transition, types, waitFor };
2681
+ export { SimulatedClock, SpecialTargets, assertEvent, createFSM, createMachine, createMachineFromConfig, createStateConfig, createSystem, getInitialMicrosteps, getMicrosteps, getNextTransitions, initialTransition, isTypeSchema, machineConfigToJSON, mapState, serializeMachine, setup, toPromise, transition, types, waitFor };