xstate 6.0.0-alpha.20 → 6.0.0-alpha.22

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 (43) hide show
  1. package/dist/{StateMachine-6661eb0d.development.cjs.js → StateMachine-1888d034.development.cjs.js} +178 -27
  2. package/dist/{StateMachine-f2b70732.cjs.js → StateMachine-610fe929.cjs.js} +178 -27
  3. package/dist/{StateMachine-ba3ccedf.development.esm.js → StateMachine-9fad7a2b.development.esm.js} +174 -28
  4. package/dist/{StateMachine-42f1d26c.esm.js → StateMachine-ddb5d007.esm.js} +174 -28
  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/setup.d.ts +19 -27
  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/declarations/src/types.v6.d.ts +5 -2
  18. package/dist/declarations/src/utils.d.ts +1 -1
  19. package/dist/{index-d88b0c55.esm.js → index-2fe11873.esm.js} +789 -403
  20. package/dist/{index-49293864.development.cjs.js → index-41c0375c.development.cjs.js} +797 -404
  21. package/dist/{index-42956779.cjs.js → index-434fac23.cjs.js} +796 -403
  22. package/dist/{index-dc3443b6.development.esm.js → index-44d8c2d1.development.esm.js} +790 -404
  23. package/dist/xstate-actors.cjs.js +1 -1
  24. package/dist/xstate-actors.development.cjs.js +1 -1
  25. package/dist/xstate-actors.development.esm.js +1 -1
  26. package/dist/xstate-actors.esm.js +1 -1
  27. package/dist/xstate-actors.umd.min.js +1 -1
  28. package/dist/xstate-actors.umd.min.js.map +1 -1
  29. package/dist/xstate-graph.cjs.js +2 -2
  30. package/dist/xstate-graph.development.cjs.js +2 -2
  31. package/dist/xstate-graph.development.esm.js +2 -2
  32. package/dist/xstate-graph.esm.js +2 -2
  33. package/dist/xstate-graph.umd.min.js +1 -1
  34. package/dist/xstate-graph.umd.min.js.map +1 -1
  35. package/dist/xstate.cjs.js +82 -101
  36. package/dist/xstate.cjs.mjs +1 -0
  37. package/dist/xstate.development.cjs.js +82 -101
  38. package/dist/xstate.development.cjs.mjs +1 -0
  39. package/dist/xstate.development.esm.js +80 -100
  40. package/dist/xstate.esm.js +80 -100
  41. package/dist/xstate.umd.min.js +1 -1
  42. package/dist/xstate.umd.min.js.map +1 -1
  43. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var dist_xstateActors = require('./index-49293864.development.cjs.js');
3
+ var dist_xstateActors = require('./index-41c0375c.development.cjs.js');
4
4
 
5
5
  function createSpawner(actorScope, {
6
6
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorScope, {
12
12
  if (!logic) {
13
13
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
14
14
  }
15
- const actor = dist_xstateActors.createActor(logic, {
15
+ const actor = actorScope.system.createActorRef(logic, {
16
16
  id: options?.id,
17
17
  parent: actorScope.self,
18
18
  syncSnapshot: options?.syncSnapshot,
@@ -27,7 +27,7 @@ function createSpawner(actorScope, {
27
27
  spawnedChildren[actor.id] = actor;
28
28
  return actor;
29
29
  } else {
30
- const actor = dist_xstateActors.createActor(src, {
30
+ const actor = actorScope.system.createActorRef(src, {
31
31
  id: options?.id,
32
32
  parent: actorScope.self,
33
33
  syncSnapshot: options?.syncSnapshot,
@@ -41,16 +41,114 @@ function createSpawner(actorScope, {
41
41
  return (src, options) => {
42
42
  const actor = spawn(src, options); // TODO: fix types
43
43
  spawnedChildren[actor.id] = actor;
44
- actorScope.defer(() => {
45
- if (actor._processingStatus === dist_xstateActors.ProcessingStatus.Stopped) {
46
- return;
47
- }
48
- actor.start();
49
- });
50
44
  return actor;
51
45
  };
52
46
  }
53
47
 
48
+ /** @internal */
49
+ function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
50
+ actorScope.self._snapshot = snapshot;
51
+ if (attachActorRef && snapshot && typeof snapshot === 'object') {
52
+ dist_xstateActors.setSnapshotActorRef(snapshot, actorScope.self);
53
+ }
54
+ return snapshot;
55
+ }
56
+
57
+ /** @internal */
58
+ function isInertActorScope(actorScope) {
59
+ return !!actorScope.self.options?._inert;
60
+ }
61
+
62
+ /** @internal */
63
+ function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
64
+ const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
65
+ return setInertActorScopeSnapshot(snapshotScope, snapshot);
66
+ }
67
+
68
+ /** @internal */
69
+ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
70
+ const snapshotRef = snapshot ? dist_xstateActors.getSnapshotActorRef(snapshot) : undefined;
71
+ const previousSelf = sourceSelf ?? snapshotRef?.actor;
72
+ const baseSystem = previousSelf?.system;
73
+ const system = previousSelf && baseSystem ? dist_xstateActors.createSnapshotSystem(baseSystem, previousSelf, dist_xstateActors.isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
74
+ const self = dist_xstateActors.createActor(actorLogic, {
75
+ _inert: true,
76
+ ...(previousSelf ? {
77
+ id: previousSelf.id
78
+ } : {}),
79
+ ...(system ? {
80
+ _systemRef: {
81
+ current: system
82
+ }
83
+ } : {})
84
+ });
85
+ if (previousSelf?._parent) {
86
+ self._parent = previousSelf._parent;
87
+ }
88
+ if (snapshot) {
89
+ self._snapshot = snapshot;
90
+ }
91
+ const actorScope = {
92
+ self: self,
93
+ defer: () => {},
94
+ id: self.id,
95
+ logger: self.system._logger,
96
+ sessionId: self.sessionId,
97
+ stopChild: child => child._stop(),
98
+ system: self.system,
99
+ emit: event => self.system.emitEvent(self, event),
100
+ actionExecutor: () => {}
101
+ };
102
+ return actorScope;
103
+ }
104
+
105
+ /** @deprecated Use `initialTransition(…)` instead. */
106
+ function getInitialSnapshot(actorLogic, ...[input]) {
107
+ const actorScope = createInertActorScope(actorLogic);
108
+ return actorLogic.initialTransition(input, actorScope)[0];
109
+ }
110
+
111
+ /**
112
+ * Determines the next snapshot for the given `actorLogic` based on the given
113
+ * `snapshot` and `event`.
114
+ *
115
+ * If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
116
+ * used.
117
+ *
118
+ * @deprecated Use `transition(…)` instead.
119
+ * @example
120
+ *
121
+ * ```ts
122
+ * import { getNextSnapshot } from 'xstate';
123
+ * import { trafficLightMachine } from './trafficLightMachine.ts';
124
+ *
125
+ * const nextSnapshot = getNextSnapshot(
126
+ * trafficLightMachine, // actor logic
127
+ * undefined, // snapshot (or initial state if undefined)
128
+ * { type: 'TIMER' }
129
+ * ); // event object
130
+ *
131
+ * console.log(nextSnapshot.value);
132
+ * // => 'yellow'
133
+ *
134
+ * const nextSnapshot2 = getNextSnapshot(
135
+ * trafficLightMachine, // actor logic
136
+ * nextSnapshot, // snapshot
137
+ * { type: 'TIMER' }
138
+ * ); // event object
139
+ *
140
+ * console.log(nextSnapshot2.value);
141
+ * // =>'red'
142
+ * ```
143
+ */
144
+ function getNextSnapshot(actorLogic, snapshot, event) {
145
+ const actorScope = createInertActorScope(actorLogic, snapshot);
146
+ const transitionResult = actorLogic.transition(snapshot, event, actorScope);
147
+ const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
148
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
149
+ return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
150
+ }
151
+
54
152
  const cache = new WeakMap();
55
153
  function memo(object, key, fn) {
56
154
  let memoizedData = cache.get(object);
@@ -572,19 +670,37 @@ class StateMachine {
572
670
  * @param event The received event
573
671
  */
574
672
  transition(snapshot, event, actorScope) {
575
- const fastSnapshot = this._transitionFast(snapshot, event, actorScope);
673
+ const usesInertScope = !actorScope;
674
+ const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
675
+ if (usesInertScope) {
676
+ setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
677
+ }
678
+ const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
576
679
  if (fastSnapshot) {
577
- return [fastSnapshot, []];
680
+ if (usesInertScope) {
681
+ setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
682
+ }
683
+ const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
684
+ return [returnedSnapshot, []];
578
685
  }
579
686
  const {
580
687
  snapshot: nextSnapshot,
581
688
  microsteps
582
- } = dist_xstateActors.macrostep(snapshot, event, actorScope, []);
583
- return [nextSnapshot, this._collectEffects(microsteps)];
689
+ } = dist_xstateActors.macrostep(snapshot, event, resolvedActorScope, []);
690
+ if (usesInertScope) {
691
+ setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
692
+ }
693
+ const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
694
+ return [returnedSnapshot, this._collectEffects(microsteps)];
695
+ }
696
+ _collectEffects(microsteps) {
697
+ return microsteps.flatMap(([, actions]) => actions);
584
698
  }
585
- _collectEffects(microsteps, initialActions = []) {
586
- const effects = [...initialActions, ...microsteps.flatMap(([, actions]) => actions)];
587
- return [...effects, ...dist_xstateActors.deriveDeferredStarts(effects)];
699
+ _attachPureActorRef(snapshot, actorScope) {
700
+ if (isInertActorScope(actorScope)) {
701
+ return snapshot;
702
+ }
703
+ return attachSnapshotActorRef(this, actorScope, snapshot);
588
704
  }
589
705
  _transitionFast(snapshot, event, actorScope) {
590
706
  if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
@@ -645,6 +761,9 @@ class StateMachine {
645
761
  return dist_xstateActors.transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
646
762
  }
647
763
  isInternalEventType(eventType) {
764
+ if (eventType === dist_xstateActors.XSTATE_TIMER) {
765
+ return true;
766
+ }
648
767
  for (const descriptor of this.internalEventDescriptors) {
649
768
  if (dist_xstateActors.matchesEventDescriptor(eventType, descriptor)) {
650
769
  return true;
@@ -711,7 +830,7 @@ class StateMachine {
711
830
  _nodes: [this.root],
712
831
  children: {},
713
832
  status: 'active'
714
- }, this);
833
+ }, this, actorScope.self);
715
834
  if (typeof context === 'function') {
716
835
  const children = {};
717
836
  const spawn = createSpawner(actorScope, preInitial, initEvent, children);
@@ -744,30 +863,37 @@ class StateMachine {
744
863
  return this.initialTransition(input, actorScope)[0];
745
864
  }
746
865
  initialTransition(input, actorScope) {
866
+ const usesInertScope = !actorScope;
867
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
747
868
  const initEvent = dist_xstateActors.createInitEvent(input); // TODO: fix;
748
869
  const internalQueue = [];
749
- const preInitialState = this._getPreInitialState(actorScope, initEvent);
870
+ const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
871
+ const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => dist_xstateActors.createSpawnEffect(actor));
750
872
  let nextState;
751
873
  let initialActions = [];
752
874
  let microsteps = [];
753
875
  let macroState;
754
876
  try {
755
- [nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, actorScope, initEvent, internalQueue);
877
+ [nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
756
878
  ({
757
879
  snapshot: macroState,
758
880
  microsteps
759
- } = dist_xstateActors.macrostep(nextState, initEvent, actorScope, internalQueue));
881
+ } = dist_xstateActors.macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
760
882
  } catch (err) {
761
883
  if (!this.root.config.onError) {
762
884
  throw err;
763
885
  }
764
886
  const errorEvent = dist_xstateActors.createErrorPlatformEvent('execution', err);
765
- const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, actorScope, []);
887
+ const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
766
888
  macroState = errorMacrostep.snapshot;
767
889
  microsteps = errorMacrostep.microsteps;
768
890
  initialActions = [];
769
891
  }
770
- return [macroState, this._collectEffects(microsteps, initialActions)];
892
+ if (usesInertScope) {
893
+ setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
894
+ }
895
+ const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
896
+ return [returnedSnapshot, this._collectEffects(microsteps)];
771
897
  }
772
898
  start(snapshot) {
773
899
  // Start rehydrated children that were active when persisted. Freshly
@@ -795,7 +921,9 @@ class StateMachine {
795
921
  getPersistedSnapshot(snapshot, options) {
796
922
  return dist_xstateActors.getPersistedSnapshot(snapshot, options);
797
923
  }
798
- restoreSnapshot(snapshot, _actorScope) {
924
+ restoreSnapshot(snapshot, actorScope) {
925
+ const usesInertScope = !actorScope;
926
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
799
927
  const persistedVersion = snapshot.version;
800
928
  if (persistedVersion !== this.version) {
801
929
  const migrate = this.config.migrate;
@@ -815,9 +943,9 @@ class StateMachine {
815
943
  if (!logic) {
816
944
  continue;
817
945
  }
818
- const actor = dist_xstateActors.createActor(logic, {
946
+ const actor = resolvedActorScope.system.createActorRef(logic, {
819
947
  id: actorId,
820
- parent: _actorScope.self,
948
+ parent: resolvedActorScope.self,
821
949
  syncSnapshot: actorData.syncSnapshot,
822
950
  snapshot: childState,
823
951
  src,
@@ -828,6 +956,19 @@ class StateMachine {
828
956
  actor._rehydrated = true;
829
957
  children[actorId] = actor;
830
958
  }
959
+ const timers = {};
960
+ const persistedTimers = snapshotData.timers ?? {};
961
+ for (const [id, timer] of Object.entries(persistedTimers)) {
962
+ const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
963
+ if (!target) {
964
+ const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
965
+ throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
966
+ }
967
+ timers[id] = {
968
+ ...timer,
969
+ target
970
+ };
971
+ }
831
972
  const reviveHistoryValue = historyValue => {
832
973
  if (!historyValue || typeof historyValue !== 'object') {
833
974
  return {};
@@ -866,11 +1007,12 @@ class StateMachine {
866
1007
  const restoredSnapshot = dist_xstateActors.createMachineSnapshot({
867
1008
  ...persistedRest,
868
1009
  children,
1010
+ timers,
869
1011
  _nodes: nodes,
870
1012
  value: snapshotData.value,
871
1013
  historyValue: revivedHistoryValue,
872
1014
  _stateInputs: snapshotData.stateInputs ?? {}
873
- }, this);
1015
+ }, this, resolvedActorScope.self);
874
1016
  const seen = new WeakSet();
875
1017
  function reviveContext(contextPart) {
876
1018
  if (seen.has(contextPart)) {
@@ -889,9 +1031,18 @@ class StateMachine {
889
1031
  }
890
1032
  }
891
1033
  reviveContext(restoredSnapshot.context);
892
- return restoredSnapshot;
1034
+ if (usesInertScope) {
1035
+ setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
1036
+ return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
1037
+ }
1038
+ return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
893
1039
  }
894
1040
  }
895
1041
 
896
1042
  exports.StateMachine = StateMachine;
897
1043
  exports.StateNode = StateNode;
1044
+ exports.attachSnapshotActorRef = attachSnapshotActorRef;
1045
+ exports.createInertActorScope = createInertActorScope;
1046
+ exports.getInitialSnapshot = getInitialSnapshot;
1047
+ exports.getNextSnapshot = getNextSnapshot;
1048
+ exports.setInertActorScopeSnapshot = setInertActorScopeSnapshot;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var dist_xstateActors = require('./index-42956779.cjs.js');
3
+ var dist_xstateActors = require('./index-434fac23.cjs.js');
4
4
 
5
5
  function createSpawner(actorScope, {
6
6
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorScope, {
12
12
  if (!logic) {
13
13
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
14
14
  }
15
- const actor = dist_xstateActors.createActor(logic, {
15
+ const actor = actorScope.system.createActorRef(logic, {
16
16
  id: options?.id,
17
17
  parent: actorScope.self,
18
18
  syncSnapshot: options?.syncSnapshot,
@@ -27,7 +27,7 @@ function createSpawner(actorScope, {
27
27
  spawnedChildren[actor.id] = actor;
28
28
  return actor;
29
29
  } else {
30
- const actor = dist_xstateActors.createActor(src, {
30
+ const actor = actorScope.system.createActorRef(src, {
31
31
  id: options?.id,
32
32
  parent: actorScope.self,
33
33
  syncSnapshot: options?.syncSnapshot,
@@ -41,16 +41,114 @@ function createSpawner(actorScope, {
41
41
  return (src, options) => {
42
42
  const actor = spawn(src, options); // TODO: fix types
43
43
  spawnedChildren[actor.id] = actor;
44
- actorScope.defer(() => {
45
- if (actor._processingStatus === dist_xstateActors.ProcessingStatus.Stopped) {
46
- return;
47
- }
48
- actor.start();
49
- });
50
44
  return actor;
51
45
  };
52
46
  }
53
47
 
48
+ /** @internal */
49
+ function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
50
+ actorScope.self._snapshot = snapshot;
51
+ if (attachActorRef && snapshot && typeof snapshot === 'object') {
52
+ dist_xstateActors.setSnapshotActorRef(snapshot, actorScope.self);
53
+ }
54
+ return snapshot;
55
+ }
56
+
57
+ /** @internal */
58
+ function isInertActorScope(actorScope) {
59
+ return !!actorScope.self.options?._inert;
60
+ }
61
+
62
+ /** @internal */
63
+ function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
64
+ const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
65
+ return setInertActorScopeSnapshot(snapshotScope, snapshot);
66
+ }
67
+
68
+ /** @internal */
69
+ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
70
+ const snapshotRef = snapshot ? dist_xstateActors.getSnapshotActorRef(snapshot) : undefined;
71
+ const previousSelf = sourceSelf ?? snapshotRef?.actor;
72
+ const baseSystem = previousSelf?.system;
73
+ const system = previousSelf && baseSystem ? dist_xstateActors.createSnapshotSystem(baseSystem, previousSelf, dist_xstateActors.isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
74
+ const self = dist_xstateActors.createActor(actorLogic, {
75
+ _inert: true,
76
+ ...(previousSelf ? {
77
+ id: previousSelf.id
78
+ } : {}),
79
+ ...(system ? {
80
+ _systemRef: {
81
+ current: system
82
+ }
83
+ } : {})
84
+ });
85
+ if (previousSelf?._parent) {
86
+ self._parent = previousSelf._parent;
87
+ }
88
+ if (snapshot) {
89
+ self._snapshot = snapshot;
90
+ }
91
+ const actorScope = {
92
+ self: self,
93
+ defer: () => {},
94
+ id: self.id,
95
+ logger: self.system._logger,
96
+ sessionId: self.sessionId,
97
+ stopChild: child => child._stop(),
98
+ system: self.system,
99
+ emit: event => self.system.emitEvent(self, event),
100
+ actionExecutor: () => {}
101
+ };
102
+ return actorScope;
103
+ }
104
+
105
+ /** @deprecated Use `initialTransition(…)` instead. */
106
+ function getInitialSnapshot(actorLogic, ...[input]) {
107
+ const actorScope = createInertActorScope(actorLogic);
108
+ return actorLogic.initialTransition(input, actorScope)[0];
109
+ }
110
+
111
+ /**
112
+ * Determines the next snapshot for the given `actorLogic` based on the given
113
+ * `snapshot` and `event`.
114
+ *
115
+ * If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
116
+ * used.
117
+ *
118
+ * @deprecated Use `transition(…)` instead.
119
+ * @example
120
+ *
121
+ * ```ts
122
+ * import { getNextSnapshot } from 'xstate';
123
+ * import { trafficLightMachine } from './trafficLightMachine.ts';
124
+ *
125
+ * const nextSnapshot = getNextSnapshot(
126
+ * trafficLightMachine, // actor logic
127
+ * undefined, // snapshot (or initial state if undefined)
128
+ * { type: 'TIMER' }
129
+ * ); // event object
130
+ *
131
+ * console.log(nextSnapshot.value);
132
+ * // => 'yellow'
133
+ *
134
+ * const nextSnapshot2 = getNextSnapshot(
135
+ * trafficLightMachine, // actor logic
136
+ * nextSnapshot, // snapshot
137
+ * { type: 'TIMER' }
138
+ * ); // event object
139
+ *
140
+ * console.log(nextSnapshot2.value);
141
+ * // =>'red'
142
+ * ```
143
+ */
144
+ function getNextSnapshot(actorLogic, snapshot, event) {
145
+ const actorScope = createInertActorScope(actorLogic, snapshot);
146
+ const transitionResult = actorLogic.transition(snapshot, event, actorScope);
147
+ const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
148
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
149
+ return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
150
+ }
151
+
54
152
  const cache = new WeakMap();
55
153
  function memo(object, key, fn) {
56
154
  let memoizedData = cache.get(object);
@@ -543,19 +641,37 @@ class StateMachine {
543
641
  * @param event The received event
544
642
  */
545
643
  transition(snapshot, event, actorScope) {
546
- const fastSnapshot = this._transitionFast(snapshot, event, actorScope);
644
+ const usesInertScope = !actorScope;
645
+ const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
646
+ if (usesInertScope) {
647
+ setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
648
+ }
649
+ const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
547
650
  if (fastSnapshot) {
548
- return [fastSnapshot, []];
651
+ if (usesInertScope) {
652
+ setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
653
+ }
654
+ const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
655
+ return [returnedSnapshot, []];
549
656
  }
550
657
  const {
551
658
  snapshot: nextSnapshot,
552
659
  microsteps
553
- } = dist_xstateActors.macrostep(snapshot, event, actorScope, []);
554
- return [nextSnapshot, this._collectEffects(microsteps)];
660
+ } = dist_xstateActors.macrostep(snapshot, event, resolvedActorScope, []);
661
+ if (usesInertScope) {
662
+ setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
663
+ }
664
+ const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
665
+ return [returnedSnapshot, this._collectEffects(microsteps)];
666
+ }
667
+ _collectEffects(microsteps) {
668
+ return microsteps.flatMap(([, actions]) => actions);
555
669
  }
556
- _collectEffects(microsteps, initialActions = []) {
557
- const effects = [...initialActions, ...microsteps.flatMap(([, actions]) => actions)];
558
- return [...effects, ...dist_xstateActors.deriveDeferredStarts(effects)];
670
+ _attachPureActorRef(snapshot, actorScope) {
671
+ if (isInertActorScope(actorScope)) {
672
+ return snapshot;
673
+ }
674
+ return attachSnapshotActorRef(this, actorScope, snapshot);
559
675
  }
560
676
  _transitionFast(snapshot, event, actorScope) {
561
677
  if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
@@ -616,6 +732,9 @@ class StateMachine {
616
732
  return dist_xstateActors.transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
617
733
  }
618
734
  isInternalEventType(eventType) {
735
+ if (eventType === dist_xstateActors.XSTATE_TIMER) {
736
+ return true;
737
+ }
619
738
  for (const descriptor of this.internalEventDescriptors) {
620
739
  if (dist_xstateActors.matchesEventDescriptor(eventType, descriptor)) {
621
740
  return true;
@@ -682,7 +801,7 @@ class StateMachine {
682
801
  _nodes: [this.root],
683
802
  children: {},
684
803
  status: 'active'
685
- }, this);
804
+ }, this, actorScope.self);
686
805
  if (typeof context === 'function') {
687
806
  const children = {};
688
807
  const spawn = createSpawner(actorScope, preInitial, initEvent, children);
@@ -715,30 +834,37 @@ class StateMachine {
715
834
  return this.initialTransition(input, actorScope)[0];
716
835
  }
717
836
  initialTransition(input, actorScope) {
837
+ const usesInertScope = !actorScope;
838
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
718
839
  const initEvent = dist_xstateActors.createInitEvent(input); // TODO: fix;
719
840
  const internalQueue = [];
720
- const preInitialState = this._getPreInitialState(actorScope, initEvent);
841
+ const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
842
+ const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => dist_xstateActors.createSpawnEffect(actor));
721
843
  let nextState;
722
844
  let initialActions = [];
723
845
  let microsteps = [];
724
846
  let macroState;
725
847
  try {
726
- [nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, actorScope, initEvent, internalQueue);
848
+ [nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
727
849
  ({
728
850
  snapshot: macroState,
729
851
  microsteps
730
- } = dist_xstateActors.macrostep(nextState, initEvent, actorScope, internalQueue));
852
+ } = dist_xstateActors.macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
731
853
  } catch (err) {
732
854
  if (!this.root.config.onError) {
733
855
  throw err;
734
856
  }
735
857
  const errorEvent = dist_xstateActors.createErrorPlatformEvent('execution', err);
736
- const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, actorScope, []);
858
+ const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
737
859
  macroState = errorMacrostep.snapshot;
738
860
  microsteps = errorMacrostep.microsteps;
739
861
  initialActions = [];
740
862
  }
741
- return [macroState, this._collectEffects(microsteps, initialActions)];
863
+ if (usesInertScope) {
864
+ setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
865
+ }
866
+ const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
867
+ return [returnedSnapshot, this._collectEffects(microsteps)];
742
868
  }
743
869
  start(snapshot) {
744
870
  // Start rehydrated children that were active when persisted. Freshly
@@ -766,7 +892,9 @@ class StateMachine {
766
892
  getPersistedSnapshot(snapshot, options) {
767
893
  return dist_xstateActors.getPersistedSnapshot(snapshot, options);
768
894
  }
769
- restoreSnapshot(snapshot, _actorScope) {
895
+ restoreSnapshot(snapshot, actorScope) {
896
+ const usesInertScope = !actorScope;
897
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
770
898
  const persistedVersion = snapshot.version;
771
899
  if (persistedVersion !== this.version) {
772
900
  const migrate = this.config.migrate;
@@ -786,9 +914,9 @@ class StateMachine {
786
914
  if (!logic) {
787
915
  continue;
788
916
  }
789
- const actor = dist_xstateActors.createActor(logic, {
917
+ const actor = resolvedActorScope.system.createActorRef(logic, {
790
918
  id: actorId,
791
- parent: _actorScope.self,
919
+ parent: resolvedActorScope.self,
792
920
  syncSnapshot: actorData.syncSnapshot,
793
921
  snapshot: childState,
794
922
  src,
@@ -799,6 +927,19 @@ class StateMachine {
799
927
  actor._rehydrated = true;
800
928
  children[actorId] = actor;
801
929
  }
930
+ const timers = {};
931
+ const persistedTimers = snapshotData.timers ?? {};
932
+ for (const [id, timer] of Object.entries(persistedTimers)) {
933
+ const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
934
+ if (!target) {
935
+ const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
936
+ throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
937
+ }
938
+ timers[id] = {
939
+ ...timer,
940
+ target
941
+ };
942
+ }
802
943
  const reviveHistoryValue = historyValue => {
803
944
  if (!historyValue || typeof historyValue !== 'object') {
804
945
  return {};
@@ -834,11 +975,12 @@ class StateMachine {
834
975
  const restoredSnapshot = dist_xstateActors.createMachineSnapshot({
835
976
  ...persistedRest,
836
977
  children,
978
+ timers,
837
979
  _nodes: nodes,
838
980
  value: snapshotData.value,
839
981
  historyValue: revivedHistoryValue,
840
982
  _stateInputs: snapshotData.stateInputs ?? {}
841
- }, this);
983
+ }, this, resolvedActorScope.self);
842
984
  const seen = new WeakSet();
843
985
  function reviveContext(contextPart) {
844
986
  if (seen.has(contextPart)) {
@@ -857,9 +999,18 @@ class StateMachine {
857
999
  }
858
1000
  }
859
1001
  reviveContext(restoredSnapshot.context);
860
- return restoredSnapshot;
1002
+ if (usesInertScope) {
1003
+ setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
1004
+ return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
1005
+ }
1006
+ return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
861
1007
  }
862
1008
  }
863
1009
 
864
1010
  exports.StateMachine = StateMachine;
865
1011
  exports.StateNode = StateNode;
1012
+ exports.attachSnapshotActorRef = attachSnapshotActorRef;
1013
+ exports.createInertActorScope = createInertActorScope;
1014
+ exports.getInitialSnapshot = getInitialSnapshot;
1015
+ exports.getNextSnapshot = getNextSnapshot;
1016
+ exports.setInertActorScopeSnapshot = setInertActorScopeSnapshot;