xstate 6.0.0-alpha.65 → 6.0.0-alpha.66

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 (47) hide show
  1. package/README.md +3 -3
  2. package/dist/{createActor-4629a290.esm.js → createActor-18a56099.esm.js} +130 -189
  3. package/dist/{createActor-b987e971.cjs.js → createActor-19ee5e3c.cjs.js} +130 -189
  4. package/dist/{createActor-8f57b47b.development.esm.js → createActor-57ac74ac.development.esm.js} +130 -225
  5. package/dist/{createActor-1df42c9e.development.cjs.js → createActor-ff6a685e.development.cjs.js} +130 -225
  6. package/dist/declarations/src/StateMachine.d.ts +2 -3
  7. package/dist/declarations/src/index.d.ts +1 -1
  8. package/dist/declarations/src/transitionActions.d.ts +1 -1
  9. package/dist/declarations/src/types.d.ts +4 -4
  10. package/dist/declarations/src/types.v6.d.ts +1 -0
  11. package/dist/{effectDescriptor-4cf24593.cjs.js → effectDescriptor-515bb8bd.cjs.js} +1 -1
  12. package/dist/{effectDescriptor-973fc1ba.esm.js → effectDescriptor-c96275e6.esm.js} +1 -1
  13. package/dist/{effectDescriptor-b2b7deaa.development.cjs.js → effectDescriptor-d941b462.development.cjs.js} +1 -1
  14. package/dist/{effectDescriptor-c4671afc.development.esm.js → effectDescriptor-f87ea294.development.esm.js} +1 -1
  15. package/dist/{index-0cf33789.development.cjs.js → index-66c07691.development.cjs.js} +1 -1
  16. package/dist/{index-f201d440.cjs.js → index-72e3c72c.cjs.js} +1 -1
  17. package/dist/{index-15382daf.development.esm.js → index-b0b89ca7.development.esm.js} +1 -1
  18. package/dist/{index-52ad3d45.esm.js → index-e540ddba.esm.js} +1 -1
  19. package/dist/xstate-actors.cjs.js +2 -2
  20. package/dist/xstate-actors.development.cjs.js +2 -2
  21. package/dist/xstate-actors.development.esm.js +2 -2
  22. package/dist/xstate-actors.esm.js +2 -2
  23. package/dist/xstate-actors.umd.min.js +1 -1
  24. package/dist/xstate-actors.umd.min.js.map +1 -1
  25. package/dist/xstate-durable.cjs.js +2 -2
  26. package/dist/xstate-durable.development.cjs.js +2 -2
  27. package/dist/xstate-durable.development.esm.js +2 -2
  28. package/dist/xstate-durable.esm.js +2 -2
  29. package/dist/xstate-durable.umd.min.js +1 -1
  30. package/dist/xstate-durable.umd.min.js.map +1 -1
  31. package/dist/xstate-graph.cjs.js +2 -2
  32. package/dist/xstate-graph.development.cjs.js +2 -2
  33. package/dist/xstate-graph.development.esm.js +3 -3
  34. package/dist/xstate-graph.esm.js +3 -3
  35. package/dist/xstate-graph.umd.min.js +1 -1
  36. package/dist/xstate-graph.umd.min.js.map +1 -1
  37. package/dist/xstate-validation.cjs.js +1 -1
  38. package/dist/xstate-validation.development.cjs.js +1 -1
  39. package/dist/xstate-validation.development.esm.js +1 -1
  40. package/dist/xstate-validation.esm.js +1 -1
  41. package/dist/xstate.cjs.js +3 -11
  42. package/dist/xstate.development.cjs.js +3 -11
  43. package/dist/xstate.development.esm.js +5 -13
  44. package/dist/xstate.esm.js +5 -13
  45. package/dist/xstate.umd.min.js +1 -1
  46. package/dist/xstate.umd.min.js.map +1 -1
  47. package/package.json +1 -1
package/README.md CHANGED
@@ -54,7 +54,7 @@ The helper requires input for actors whose input excludes `undefined`, and check
54
54
 
55
55
  <!-- JSON loading and runtime validation from packages/core/src/createMachineFromConfig.ts -->
56
56
 
57
- Revive JSON definitions with `createMachineFromConfig(json, { schemas, validator, ...sources })` to restore runtime validation. The loader validates structural keys and references and copies its input; serialized definitions are independent copies. See [serialization](../../docs/serialization.md).
57
+ Revive JSON definitions with `createMachineFromConfig(json, { schemas, validator, ...sources })` to restore runtime validation. The loader validates config keys and references. See [serialization](../../docs/serialization.md).
58
58
 
59
59
  For flat finite state machines, `xstate/fsm` provides a tiny pure transition
60
60
  table with context and TypeScript support:
@@ -659,6 +659,6 @@ explicitly configured routes. Payload checks require runtime schemas;
659
659
 
660
660
  <!-- entry effects and terminal transition behavior from packages/core/src/stateUtils.ts and transitionActions.ts -->
661
661
 
662
- Functions passed to `enq(...)` run as effects; their returned context or child patches are ignored, with a development warning. Return a computed patch from the transition, entry, or exit function instead. Entry/exit functions using enqueue must declare exactly `(args, enq)`; default/rest parameter wrappers receive a development diagnostic. See [actions](../../docs/actions.md).
662
+ Use the `enq` argument in transition, entry and exit functions to queue effects. Return context or child patches from those functions; the return value of an enqueued effect is ignored, with a development warning. See [actions](../../docs/actions.md).
663
663
 
664
- Pure transitions preserve terminal snapshots and return no effects. `snapshot.can(...)` returns `false` for terminal snapshots; active dry runs propagate evaluation errors. See [snapshots](../../docs/snapshots.md) and [states](../../docs/states.md).
664
+ For actors that are done, stopped or failed, pure transitions return the same snapshot and no effects, and `snapshot.can(...)` returns `false`. See [snapshots](../../docs/snapshots.md) and [states](../../docs/states.md).
@@ -451,81 +451,6 @@ function createSubscriptionLogic() {
451
451
  /** @public */
452
452
  const subscriptionLogic = /* #__PURE__ */createSubscriptionLogic();
453
453
 
454
- /** Marks the internal lazy scope without imposing structure on custom runtimes. @internal */
455
- const lazyActorScope = Symbol();
456
- /** Whether actor capabilities are represented by a lazy pure-transition scope. @internal */
457
- function isLazyActorScope(actorScope) {
458
- return !!actorScope[lazyActorScope];
459
- }
460
-
461
- /** Reads parent metadata without otherwise touching actor capabilities. @internal */
462
- function getActorScopeParent(actorScope) {
463
- return isLazyActorScope(actorScope) ? actorScope._parent : actorScope.self._parent;
464
- }
465
-
466
- /** Adds only `self`, preserving callback surfaces that expose no other capabilities. @internal */
467
- function withActorSelf(args, actorScope) {
468
- if (!isLazyActorScope(actorScope)) {
469
- return Object.assign(args, {
470
- self: actorScope.self
471
- });
472
- }
473
- Object.defineProperty(args, 'self', {
474
- enumerable: true,
475
- get: () => actorScope.self
476
- });
477
- return args;
478
- }
479
-
480
- /** Adds the actor reference and parent without exposing the system. @internal */
481
- function withActorSelfAndParent(args, actorScope) {
482
- if (!isLazyActorScope(actorScope)) {
483
- const self = actorScope.self;
484
- return Object.assign(args, {
485
- self,
486
- parent: self._parent
487
- });
488
- }
489
- Object.defineProperties(args, {
490
- self: {
491
- enumerable: true,
492
- get: () => actorScope.self
493
- },
494
- parent: {
495
- enumerable: true,
496
- get: () => getActorScopeParent(actorScope)
497
- }
498
- });
499
- return args;
500
- }
501
-
502
- /** Adds actor capabilities without reading them until the callback does. @internal */
503
- function withActorScope(args, actorScope) {
504
- if (!isLazyActorScope(actorScope)) {
505
- const actorArgs = args;
506
- const self = actorScope.self;
507
- actorArgs.self = self;
508
- actorArgs.system = actorScope.system;
509
- actorArgs.parent = self._parent;
510
- return actorArgs;
511
- }
512
- Object.defineProperties(args, {
513
- self: {
514
- enumerable: true,
515
- get: () => actorScope.self
516
- },
517
- system: {
518
- enumerable: true,
519
- get: () => actorScope.system
520
- },
521
- parent: {
522
- enumerable: true,
523
- get: () => getActorScopeParent(actorScope)
524
- }
525
- });
526
- return args;
527
- }
528
-
529
454
  function execCustomEffect() {
530
455
  const result = this.action?.(...this.args);
531
456
  return result;
@@ -1316,28 +1241,10 @@ async function executeEffects(effects, runtime) {
1316
1241
  await effect.exec(runtime);
1317
1242
  }
1318
1243
  }
1319
- function resolveActionsWithContext(currentSnapshot, event, actorScope, actions) {
1244
+ function resolveActionsWithContext(currentSnapshot, _event, actorScope, actions) {
1320
1245
  let intermediateSnapshot = currentSnapshot;
1321
1246
  const executableActions = [];
1322
1247
  for (const action of actions) {
1323
- const actionArgs = isLazyActorScope(actorScope) ? withActorScope({
1324
- context: intermediateSnapshot.context,
1325
- event,
1326
- output: getEventOutput(event),
1327
- children: intermediateSnapshot.children,
1328
- actions: currentSnapshot.machine.sources.actions,
1329
- actors: currentSnapshot.machine.sources.actors
1330
- }, actorScope) : {
1331
- context: intermediateSnapshot.context,
1332
- event,
1333
- output: getEventOutput(event),
1334
- self: actorScope.self,
1335
- system: actorScope.system,
1336
- parent: actorScope.self._parent,
1337
- children: intermediateSnapshot.children,
1338
- actions: currentSnapshot.machine.sources.actions,
1339
- actors: currentSnapshot.machine.sources.actors
1340
- };
1341
1248
  const isInline = typeof action === 'function';
1342
1249
  const actionRecord = getTransitionActionRecord(action);
1343
1250
  let resolvedActionArgs = actionRecord?.args;
@@ -1365,33 +1272,6 @@ function resolveActionsWithContext(currentSnapshot, event, actorScope, actions)
1365
1272
  if (actionRecord?.childUpdate) {
1366
1273
  intermediateSnapshot = applyChildUpdate(intermediateSnapshot, actionRecord.childUpdate, actorScope);
1367
1274
  }
1368
- if (resolvedAction && '_special' in resolvedAction) {
1369
- executableActions.push({
1370
- kind: 'action',
1371
- exec: execCustomEffect,
1372
- type: typeof action === 'object' ? 'action' in action && typeof action.action === 'function' ? action.action.name ?? '(anonymous)' : action.type ?? '(anonymous)' : action.name || '(anonymous)',
1373
- params: actionParams,
1374
- args: [],
1375
- action: undefined
1376
- });
1377
- const specialAction = resolvedAction;
1378
- const res = specialAction(actionArgs, emptyEnqueueObject);
1379
- if (res && ('context' in res || 'children' in res)) {
1380
- // Special-action patches never change `nodes`, so a shallow clone is
1381
- // equivalent to `cloneMachineSnapshot` — and keeps this module (and
1382
- // non-machine logic like `createFSM`) independent of State.ts.
1383
- intermediateSnapshot = {
1384
- ...intermediateSnapshot,
1385
- ...(res.context !== undefined ? {
1386
- context: mergeContextPatch(intermediateSnapshot.context, res.context)
1387
- } : {}),
1388
- ...('children' in res ? {
1389
- children: res.children
1390
- } : {})
1391
- };
1392
- }
1393
- continue;
1394
- }
1395
1275
  if (!resolvedAction || !('resolve' in resolvedAction)) {
1396
1276
  const builtInFields = typeof action === 'object' && action !== null && 'action' in action && typeof action.action === 'function' ? getBuiltInActionFields(action.action, resolvedActionArgs) : undefined;
1397
1277
  const isEmittedEvent = typeof action === 'object' && action !== null && !actionRecord;
@@ -1439,7 +1319,6 @@ function createEnqueueObject(props, action) {
1439
1319
  }
1440
1320
  const noop = () => {};
1441
1321
  const emptyActor = () => ({});
1442
- const emptyEnqueueObject = createEnqueueObject({}, noop);
1443
1322
 
1444
1323
  function parseDurationToMilliseconds(duration) {
1445
1324
  const normalizedDuration = duration.trim();
@@ -1771,6 +1650,81 @@ function setSnapshotActorRef(snapshot, actor, baseSystem = actor.system, previou
1771
1650
  });
1772
1651
  }
1773
1652
 
1653
+ /** Marks the internal lazy scope without imposing structure on custom runtimes. @internal */
1654
+ const lazyActorScope = Symbol();
1655
+ /** Whether actor capabilities are represented by a lazy pure-transition scope. @internal */
1656
+ function isLazyActorScope(actorScope) {
1657
+ return !!actorScope[lazyActorScope];
1658
+ }
1659
+
1660
+ /** Reads parent metadata without otherwise touching actor capabilities. @internal */
1661
+ function getActorScopeParent(actorScope) {
1662
+ return isLazyActorScope(actorScope) ? actorScope._parent : actorScope.self._parent;
1663
+ }
1664
+
1665
+ /** Adds only `self`, preserving callback surfaces that expose no other capabilities. @internal */
1666
+ function withActorSelf(args, actorScope) {
1667
+ if (!isLazyActorScope(actorScope)) {
1668
+ return Object.assign(args, {
1669
+ self: actorScope.self
1670
+ });
1671
+ }
1672
+ Object.defineProperty(args, 'self', {
1673
+ enumerable: true,
1674
+ get: () => actorScope.self
1675
+ });
1676
+ return args;
1677
+ }
1678
+
1679
+ /** Adds the actor reference and parent without exposing the system. @internal */
1680
+ function withActorSelfAndParent(args, actorScope) {
1681
+ if (!isLazyActorScope(actorScope)) {
1682
+ const self = actorScope.self;
1683
+ return Object.assign(args, {
1684
+ self,
1685
+ parent: self._parent
1686
+ });
1687
+ }
1688
+ Object.defineProperties(args, {
1689
+ self: {
1690
+ enumerable: true,
1691
+ get: () => actorScope.self
1692
+ },
1693
+ parent: {
1694
+ enumerable: true,
1695
+ get: () => getActorScopeParent(actorScope)
1696
+ }
1697
+ });
1698
+ return args;
1699
+ }
1700
+
1701
+ /** Adds actor capabilities without reading them until the callback does. @internal */
1702
+ function withActorScope(args, actorScope) {
1703
+ if (!isLazyActorScope(actorScope)) {
1704
+ const actorArgs = args;
1705
+ const self = actorScope.self;
1706
+ actorArgs.self = self;
1707
+ actorArgs.system = actorScope.system;
1708
+ actorArgs.parent = self._parent;
1709
+ return actorArgs;
1710
+ }
1711
+ Object.defineProperties(args, {
1712
+ self: {
1713
+ enumerable: true,
1714
+ get: () => actorScope.self
1715
+ },
1716
+ system: {
1717
+ enumerable: true,
1718
+ get: () => actorScope.system
1719
+ },
1720
+ parent: {
1721
+ enumerable: true,
1722
+ get: () => getActorScopeParent(actorScope)
1723
+ }
1724
+ });
1725
+ return args;
1726
+ }
1727
+
1774
1728
  /** @internal */
1775
1729
  function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
1776
1730
  const lazyState = getLazyInertActorState(actorScope);
@@ -2857,75 +2811,47 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
2857
2811
  return !!targets?.length || !!reenter;
2858
2812
  });
2859
2813
  const getStateActionsAndContext = (transitionFn, context, children, input, kind, stateNode) => {
2860
- if (transitionFn.length === 2) {
2861
- // enqueue action; retrieve
2862
- const actions = [];
2863
- const internalEvents = [];
2864
- let updatedContext;
2865
- const enqueue = createTransitionEnqueue(actorScope, actions, internalEvents, true);
2866
- const args = isLazyActorScope(actorScope) ? withActorScope({
2867
- context,
2868
- event,
2869
- children,
2870
- actions: currentSnapshot.machine.sources.actions,
2871
- actors: currentSnapshot.machine.sources.actors,
2872
- guards: currentSnapshot.machine.sources.guards,
2873
- delays: currentSnapshot.machine.sources.delays,
2874
- input,
2875
- stateNode
2876
- }, actorScope) : {
2877
- context,
2878
- event,
2879
- parent: actorScope.self._parent,
2880
- self: actorScope.self,
2881
- children,
2882
- system: actorScope.system,
2883
- actions: currentSnapshot.machine.sources.actions,
2884
- actors: currentSnapshot.machine.sources.actors,
2885
- guards: currentSnapshot.machine.sources.guards,
2886
- delays: currentSnapshot.machine.sources.delays,
2887
- input,
2888
- stateNode
2889
- };
2890
- let res;
2891
- try {
2892
- res = transitionFn(args, enqueue);
2893
- } finally {
2894
- closeTransitionEnqueue(enqueue);
2895
- }
2896
- assertSyncTransitionResult(res, event, stateNode.id, kind);
2897
- if (res?.context !== undefined) {
2898
- updatedContext = mergeContextPatch(context, res.context);
2899
- }
2900
- return [actions, updatedContext, internalEvents];
2901
- }
2902
-
2903
- // For 1-argument actions, wrap them to include input
2904
- // Preserve _special flag if present (for entry/exit actions)
2905
- const wrappedAction = Object.assign((args, enqueue) => transitionFn(isLazyActorScope(actorScope) ? withActorScope({
2906
- context: args.context,
2907
- event: args.event,
2908
- output: args.output,
2909
- children: args.children,
2910
- actions: args.actions,
2911
- actors: args.actors,
2814
+ const actions = [];
2815
+ const internalEvents = [];
2816
+ let updatedContext;
2817
+ const enqueue = createTransitionEnqueue(actorScope, actions, internalEvents, true);
2818
+ const args = isLazyActorScope(actorScope) ? withActorScope({
2819
+ context,
2820
+ event,
2821
+ output: getEventOutput(event),
2822
+ children,
2823
+ actions: currentSnapshot.machine.sources.actions,
2824
+ actors: currentSnapshot.machine.sources.actors,
2912
2825
  guards: currentSnapshot.machine.sources.guards,
2913
2826
  delays: currentSnapshot.machine.sources.delays,
2914
2827
  input,
2915
2828
  stateNode
2916
2829
  }, actorScope) : {
2917
- ...args,
2830
+ context,
2831
+ event,
2832
+ output: getEventOutput(event),
2833
+ parent: actorScope.self._parent,
2834
+ self: actorScope.self,
2835
+ children,
2836
+ system: actorScope.system,
2837
+ actions: currentSnapshot.machine.sources.actions,
2838
+ actors: currentSnapshot.machine.sources.actors,
2918
2839
  guards: currentSnapshot.machine.sources.guards,
2919
2840
  delays: currentSnapshot.machine.sources.delays,
2920
2841
  input,
2921
2842
  stateNode
2922
- },
2923
- // This function runs during action resolution, where enqueued
2924
- // effects are no longer collected.
2925
- enqueue), '_special' in transitionFn ? {
2926
- _special: true
2927
- } : {});
2928
- return [[wrappedAction], undefined, undefined];
2843
+ };
2844
+ let res;
2845
+ try {
2846
+ res = transitionFn(args, enqueue);
2847
+ } finally {
2848
+ closeTransitionEnqueue(enqueue);
2849
+ }
2850
+ assertSyncTransitionResult(res, event, stateNode.id, kind);
2851
+ if (res?.context !== undefined) {
2852
+ updatedContext = mergeContextPatch(context, res.context);
2853
+ }
2854
+ return [actions, updatedContext, internalEvents, res?.children];
2929
2855
  };
2930
2856
  let nextState = currentSnapshot;
2931
2857
  const getInvokeStopActions = (stateNode, children) => {
@@ -2960,13 +2886,18 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
2960
2886
  }
2961
2887
  for (const exitStateNode of statesToExit) {
2962
2888
  const stateInput = getStateInput(currentSnapshot, exitStateNode.id);
2963
- const [exitActions, nextContext, internalEvents] = exitStateNode.exit ? getStateActionsAndContext(exitStateNode.exit, nextState.context, nextState.children, stateInput, 'exit', exitStateNode) : [[], undefined, undefined];
2889
+ const [exitActions, nextContext, internalEvents, nextChildren] = exitStateNode.exit ? getStateActionsAndContext(exitStateNode.exit, nextState.context, nextState.children, stateInput, 'exit', exitStateNode) : [[], undefined, undefined, undefined];
2964
2890
  if (internalEvents?.length) {
2965
2891
  internalQueue.push(...internalEvents);
2966
2892
  }
2967
- if (nextContext) {
2893
+ if (nextContext || nextChildren) {
2968
2894
  nextState = cloneMachineSnapshot(nextState, {
2969
- context: nextContext
2895
+ ...(nextContext ? {
2896
+ context: nextContext
2897
+ } : {}),
2898
+ ...(nextChildren ? {
2899
+ children: nextChildren
2900
+ } : {})
2970
2901
  });
2971
2902
  }
2972
2903
  const [resolvedState, resolvedActions] = resolveActionsWithContext(nextState, event, actorScope, exitActions);
@@ -3227,7 +3158,7 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
3227
3158
  let contextChangedByEntry = false;
3228
3159
  const stateInput = stateInputMap[stateNodeToEnter.id];
3229
3160
  if (stateNodeToEnter.entry) {
3230
- const [resultActions, nextContext, nextInternalEvents] = getStateActionsAndContext(stateNodeToEnter.entry, context, children, stateInput, 'entry', stateNodeToEnter);
3161
+ const [resultActions, nextContext, nextInternalEvents, nextChildren] = getStateActionsAndContext(stateNodeToEnter.entry, context, children, stateInput, 'entry', stateNodeToEnter);
3231
3162
  actions.push(...resultActions);
3232
3163
  if (nextInternalEvents?.length) {
3233
3164
  internalQueue.push(...nextInternalEvents);
@@ -3236,6 +3167,11 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
3236
3167
  context = nextContext;
3237
3168
  contextChangedByEntry = true;
3238
3169
  }
3170
+ if (nextChildren) {
3171
+ nextState = cloneMachineSnapshot(nextState, {
3172
+ children: nextChildren
3173
+ });
3174
+ }
3239
3175
  }
3240
3176
  if (contextChangedByEntry) {
3241
3177
  nextState.context = context;
@@ -3335,10 +3271,15 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
3335
3271
  nextStateNodesToExit.forEach(stateNode => {
3336
3272
  if (stateNode.exit) {
3337
3273
  const stateInput = getStateInput(nextState, stateNode.id);
3338
- const [exitActions, nextContext, nextInternalEvents] = getStateActionsAndContext(stateNode.exit, nextState.context, nextState.children, stateInput, 'exit', stateNode);
3339
- if (nextContext) {
3274
+ const [exitActions, nextContext, nextInternalEvents, nextChildren] = getStateActionsAndContext(stateNode.exit, nextState.context, nextState.children, stateInput, 'exit', stateNode);
3275
+ if (nextContext || nextChildren) {
3340
3276
  nextState = cloneMachineSnapshot(nextState, {
3341
- context: nextContext
3277
+ ...(nextContext ? {
3278
+ context: nextContext
3279
+ } : {}),
3280
+ ...(nextChildren ? {
3281
+ children: nextChildren
3282
+ } : {})
3342
3283
  });
3343
3284
  }
3344
3285
  allExitActions.push(...exitActions);