xstate 5.0.0-beta.37 → 5.0.0-beta.39

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 (62) hide show
  1. package/actions/dist/xstate-actions.cjs.js +4 -3
  2. package/actions/dist/xstate-actions.cjs.mjs +1 -0
  3. package/actions/dist/xstate-actions.development.cjs.js +4 -3
  4. package/actions/dist/xstate-actions.development.cjs.mjs +1 -0
  5. package/actions/dist/xstate-actions.development.esm.js +3 -3
  6. package/actions/dist/xstate-actions.esm.js +3 -3
  7. package/actions/dist/xstate-actions.umd.min.js +1 -1
  8. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  9. package/actors/dist/xstate-actors.cjs.js +60 -3
  10. package/actors/dist/xstate-actors.development.cjs.js +60 -3
  11. package/actors/dist/xstate-actors.development.esm.js +60 -3
  12. package/actors/dist/xstate-actors.esm.js +60 -3
  13. package/actors/dist/xstate-actors.umd.min.js +1 -1
  14. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  15. package/dist/declarations/src/State.d.ts +2 -2
  16. package/dist/declarations/src/StateMachine.d.ts +7 -7
  17. package/dist/declarations/src/actions/assign.d.ts +4 -4
  18. package/dist/declarations/src/actions/cancel.d.ts +4 -4
  19. package/dist/declarations/src/actions/choose.d.ts +3 -3
  20. package/dist/declarations/src/actions/log.d.ts +4 -4
  21. package/dist/declarations/src/actions/pure.d.ts +4 -4
  22. package/dist/declarations/src/actions/raise.d.ts +3 -3
  23. package/dist/declarations/src/actions/send.d.ts +7 -7
  24. package/dist/declarations/src/actions/spawn.d.ts +34 -0
  25. package/dist/declarations/src/actions/stop.d.ts +4 -4
  26. package/dist/declarations/src/actions.d.ts +1 -0
  27. package/dist/declarations/src/actors/callback.d.ts +76 -2
  28. package/dist/declarations/src/actors/observable.d.ts +2 -3
  29. package/dist/declarations/src/actors/promise.d.ts +0 -1
  30. package/dist/declarations/src/actors/transition.d.ts +3 -3
  31. package/dist/declarations/src/guards.d.ts +9 -10
  32. package/dist/declarations/src/interpreter.d.ts +71 -10
  33. package/dist/declarations/src/spawn.d.ts +3 -4
  34. package/dist/declarations/src/stateUtils.d.ts +4 -9
  35. package/dist/declarations/src/types.d.ts +51 -62
  36. package/dist/{interpreter-e58ca48d.development.cjs.js → interpreter-03a5c3f5.development.cjs.js} +91 -12
  37. package/dist/{interpreter-8def682e.esm.js → interpreter-1e8c1c0c.esm.js} +91 -12
  38. package/dist/{interpreter-97aff8d2.cjs.js → interpreter-5dfcd203.cjs.js} +91 -12
  39. package/dist/{interpreter-1c52b23c.development.esm.js → interpreter-70cd9217.development.esm.js} +91 -12
  40. package/dist/{raise-1fd59c65.development.cjs.js → raise-17cb3d9d.development.cjs.js} +145 -152
  41. package/dist/{raise-800296d7.cjs.js → raise-291d2181.cjs.js} +145 -152
  42. package/dist/{raise-21c417c1.esm.js → raise-62de3670.esm.js} +145 -153
  43. package/dist/{raise-e342a840.development.esm.js → raise-e044f460.development.esm.js} +145 -153
  44. package/dist/{send-92854675.esm.js → send-1249d4ac.esm.js} +45 -44
  45. package/dist/{send-b309ef4e.development.cjs.js → send-33433787.development.cjs.js} +45 -44
  46. package/dist/{send-4cc29786.cjs.js → send-af152aca.cjs.js} +45 -44
  47. package/dist/{send-83ccc98b.development.esm.js → send-f1a2a827.development.esm.js} +45 -44
  48. package/dist/xstate.cjs.js +23 -20
  49. package/dist/xstate.cjs.mjs +1 -0
  50. package/dist/xstate.development.cjs.js +23 -20
  51. package/dist/xstate.development.cjs.mjs +1 -0
  52. package/dist/xstate.development.esm.js +25 -23
  53. package/dist/xstate.esm.js +25 -23
  54. package/dist/xstate.umd.min.js +1 -1
  55. package/dist/xstate.umd.min.js.map +1 -1
  56. package/guards/dist/xstate-guards.cjs.js +2 -2
  57. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  58. package/guards/dist/xstate-guards.development.esm.js +2 -2
  59. package/guards/dist/xstate-guards.esm.js +2 -2
  60. package/guards/dist/xstate-guards.umd.min.js +1 -1
  61. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  62. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var interpreter = require('./interpreter-e58ca48d.development.cjs.js');
3
+ var interpreter = require('./interpreter-03a5c3f5.development.cjs.js');
4
4
 
5
5
  const cache = new WeakMap();
6
6
  function memo(object, key, fn) {
@@ -16,14 +16,14 @@ function memo(object, key, fn) {
16
16
  return memoizedData[key];
17
17
  }
18
18
 
19
- function resolveCancel(_, state, actionArgs, {
19
+ function resolveCancel(_, state, actionArgs, actionParams, {
20
20
  sendId
21
21
  }) {
22
- const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs) : sendId;
22
+ const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
23
23
  return [state, resolvedSendId];
24
24
  }
25
- function executeCancel(actorContext, resolvedSendId) {
26
- actorContext.self.cancel(resolvedSendId);
25
+ function executeCancel(actorScope, resolvedSendId) {
26
+ actorScope.self.cancel(resolvedSendId);
27
27
  }
28
28
  /**
29
29
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -33,7 +33,7 @@ function executeCancel(actorContext, resolvedSendId) {
33
33
  * @param sendId The `id` of the `send(...)` action to cancel.
34
34
  */
35
35
  function cancel(sendId) {
36
- function cancel(_) {
36
+ function cancel(args, params) {
37
37
  {
38
38
  throw new Error(`This isn't supposed to be called`);
39
39
  }
@@ -45,7 +45,7 @@ function cancel(sendId) {
45
45
  return cancel;
46
46
  }
47
47
 
48
- function resolveInvoke(actorContext, state, actionArgs, {
48
+ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
49
49
  id,
50
50
  systemId,
51
51
  src,
@@ -56,99 +56,94 @@ function resolveInvoke(actorContext, state, actionArgs, {
56
56
  src,
57
57
  input: undefined
58
58
  };
59
+ const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
59
60
  let actorRef;
60
61
  if (referenced) {
61
62
  // TODO: inline `input: undefined` should win over the referenced one
62
63
  const configuredInput = input || referenced.input;
63
64
  actorRef = interpreter.createActor(referenced.src, {
64
- id,
65
+ id: resolvedId,
65
66
  src: typeof src === 'string' ? src : undefined,
66
- parent: actorContext?.self,
67
+ parent: actorScope?.self,
67
68
  systemId,
68
69
  input: typeof configuredInput === 'function' ? configuredInput({
69
70
  context: state.context,
70
71
  event: actionArgs.event,
71
- self: actorContext?.self
72
+ self: actorScope?.self
72
73
  }) : configuredInput
73
74
  });
74
75
  if (syncSnapshot) {
75
76
  actorRef.subscribe({
76
77
  next: snapshot => {
77
78
  if (snapshot.status === 'active') {
78
- actorContext.self.send({
79
+ actorScope.self.send({
79
80
  type: `xstate.snapshot.${id}`,
80
81
  snapshot
81
82
  });
82
83
  }
83
84
  },
84
- error: () => {
85
- /* TODO */
86
- }
85
+ error: () => {}
87
86
  });
88
87
  }
89
88
  }
90
89
  if (!actorRef) {
91
- console.warn(`Actor type '${src}' not found in machine '${actorContext.id}'.`);
90
+ console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
92
91
  }
93
92
  return [cloneState(state, {
94
93
  children: {
95
94
  ...state.children,
96
- [id]: actorRef
95
+ [resolvedId]: actorRef
97
96
  }
98
97
  }), {
99
98
  id,
100
99
  actorRef
101
100
  }];
102
101
  }
103
- function executeInvoke(actorContext, {
102
+ function executeSpawn(actorScope, {
104
103
  id,
105
104
  actorRef
106
105
  }) {
107
106
  if (!actorRef) {
108
107
  return;
109
108
  }
110
- actorContext.defer(() => {
109
+ actorScope.defer(() => {
111
110
  if (actorRef.status === interpreter.ActorStatus.Stopped) {
112
111
  return;
113
112
  }
114
113
  try {
115
114
  actorRef.start?.();
116
115
  } catch (err) {
117
- actorContext.self.send(interpreter.createErrorActorEvent(id, err));
116
+ actorScope.self.send(interpreter.createErrorActorEvent(id, err));
118
117
  return;
119
118
  }
120
119
  });
121
120
  }
122
-
123
- // we don't export this since it's an internal action that is not meant to be used in the user's code
124
-
125
- function invoke({
121
+ function spawn(...[src, {
126
122
  id,
127
123
  systemId,
128
- src,
129
124
  input,
130
- onSnapshot
131
- }) {
132
- function invoke(_) {
125
+ syncSnapshot = false
126
+ } = {}]) {
127
+ function spawn(args, params) {
133
128
  {
134
129
  throw new Error(`This isn't supposed to be called`);
135
130
  }
136
131
  }
137
- invoke.type = 'xstate.invoke';
138
- invoke.id = id;
139
- invoke.systemId = systemId;
140
- invoke.src = src;
141
- invoke.input = input;
142
- invoke.syncSnapshot = !!onSnapshot;
143
- invoke.resolve = resolveInvoke;
144
- invoke.execute = executeInvoke;
145
- return invoke;
132
+ spawn.type = 'xstate.spawn';
133
+ spawn.id = id;
134
+ spawn.systemId = systemId;
135
+ spawn.src = src;
136
+ spawn.input = input;
137
+ spawn.syncSnapshot = syncSnapshot;
138
+ spawn.resolve = resolveSpawn;
139
+ spawn.execute = executeSpawn;
140
+ return spawn;
146
141
  }
147
142
 
148
- function resolveStop(_, state, args, {
143
+ function resolveStop(_, state, args, actionParams, {
149
144
  actorRef
150
145
  }) {
151
- const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
146
+ const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
152
147
  const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
153
148
  let children = state.children;
154
149
  if (resolvedActorRef) {
@@ -161,22 +156,28 @@ function resolveStop(_, state, args, {
161
156
  children
162
157
  }), resolvedActorRef];
163
158
  }
164
- function executeStop(actorContext, actorRef) {
159
+ function executeStop(actorScope, actorRef) {
165
160
  if (!actorRef) {
166
161
  return;
167
162
  }
163
+
164
+ // we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
165
+ // since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
166
+ // this could throw on `systemId` collision, for example, when dealing with reentering transitions
167
+ actorScope.system._unregister(actorRef);
168
+
168
169
  // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
169
170
  // this can happen, for example, when the invoking state is being exited immediately by an always transition
170
171
  if (actorRef.status !== interpreter.ActorStatus.Running) {
171
- actorContext.stopChild(actorRef);
172
+ actorScope.stopChild(actorRef);
172
173
  return;
173
174
  }
174
175
  // stopping a child enqueues a stop event in the child actor's mailbox
175
176
  // we need for all of the already enqueued events to be processed before we stop the child
176
177
  // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
177
178
  // and we don't want to ignore those events
178
- actorContext.defer(() => {
179
- actorContext.stopChild(actorRef);
179
+ actorScope.defer(() => {
180
+ actorScope.stopChild(actorRef);
180
181
  });
181
182
  }
182
183
  /**
@@ -185,7 +186,7 @@ function executeStop(actorContext, actorRef) {
185
186
  * @param actorRef The actor to stop.
186
187
  */
187
188
  function stop(actorRef) {
188
- function stop(_) {
189
+ function stop(args, params) {
189
190
  {
190
191
  throw new Error(`This isn't supposed to be called`);
191
192
  }
@@ -207,7 +208,7 @@ function checkStateIn(state, _, {
207
208
  return state.matches(stateValue);
208
209
  }
209
210
  function stateIn(stateValue) {
210
- function stateIn(_) {
211
+ function stateIn(args, params) {
211
212
  {
212
213
  throw new Error(`This isn't supposed to be called`);
213
214
  }
@@ -225,7 +226,7 @@ function checkNot(state, {
225
226
  return !evaluateGuard(guards[0], context, event, state);
226
227
  }
227
228
  function not(guard) {
228
- function not(_) {
229
+ function not(args, params) {
229
230
  {
230
231
  throw new Error(`This isn't supposed to be called`);
231
232
  }
@@ -243,7 +244,7 @@ function checkAnd(state, {
243
244
  return guards.every(guard => evaluateGuard(guard, context, event, state));
244
245
  }
245
246
  function and(guards) {
246
- function and(_) {
247
+ function and(args, params) {
247
248
  {
248
249
  throw new Error(`This isn't supposed to be called`);
249
250
  }
@@ -261,7 +262,7 @@ function checkOr(state, {
261
262
  return guards.some(guard => evaluateGuard(guard, context, event, state));
262
263
  }
263
264
  function or(guards) {
264
- function or(_) {
265
+ function or(args, params) {
265
266
  {
266
267
  throw new Error(`This isn't supposed to be called`);
267
268
  }
@@ -286,22 +287,17 @@ function evaluateGuard(guard, context, event, state) {
286
287
  }
287
288
  const guardArgs = {
288
289
  context,
289
- event,
290
- guard: isInline ? undefined : typeof guard === 'string' ? {
291
- type: guard
292
- } : typeof guard.params === 'function' ? {
293
- type: guard.type,
294
- params: guard.params({
295
- context,
296
- event
297
- })
298
- } : guard
290
+ event
299
291
  };
292
+ const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
293
+ context,
294
+ event
295
+ }) : guard.params : undefined;
300
296
  if (!('check' in resolved)) {
301
297
  // the existing type of `.guards` assumes non-nullable `TExpressionGuard`
302
298
  // inline guards expect `TExpressionGuard` to be set to `undefined`
303
299
  // it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
304
- return resolved(guardArgs);
300
+ return resolved(guardArgs, guardParams);
305
301
  }
306
302
  const builtinGuard = resolved;
307
303
  return builtinGuard.check(state, guardArgs, resolved // this holds all params
@@ -766,15 +762,6 @@ function isDescendant(childStateNode, parentStateNode) {
766
762
  }
767
763
  return marker.parent === parentStateNode;
768
764
  }
769
- function getPathFromRootToNode(stateNode) {
770
- const path = [];
771
- let marker = stateNode.parent;
772
- while (marker) {
773
- path.unshift(marker);
774
- marker = marker.parent;
775
- }
776
- return path;
777
- }
778
765
  function hasIntersection(s1, s2) {
779
766
  const set1 = new Set(s1);
780
767
  const set2 = new Set(s2);
@@ -814,17 +801,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
814
801
  }
815
802
  return Array.from(filteredTransitions);
816
803
  }
817
- function findLCCA(stateNodes) {
818
- const [head] = stateNodes;
819
- let current = getPathFromRootToNode(head);
820
- let candidates = [];
821
- for (const stateNode of stateNodes) {
822
- const path = getPathFromRootToNode(stateNode);
823
- candidates = current.filter(sn => path.includes(sn));
824
- current = candidates;
825
- candidates = [];
804
+ function findLeastCommonAncestor(stateNodes) {
805
+ const [head, ...tail] = stateNodes;
806
+ for (const ancestor of getProperAncestors(head, undefined)) {
807
+ if (tail.every(sn => isDescendant(sn, ancestor))) {
808
+ return ancestor;
809
+ }
826
810
  }
827
- return current[current.length - 1];
828
811
  }
829
812
  function getEffectiveTargetStates(transition, historyValue) {
830
813
  if (!transition.target) {
@@ -856,8 +839,16 @@ function getTransitionDomain(transition, historyValue) {
856
839
  if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
857
840
  return transition.source;
858
841
  }
859
- const lcca = findLCCA(targetStates.concat(transition.source));
860
- return lcca;
842
+ const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
843
+ if (lca) {
844
+ return lca;
845
+ }
846
+
847
+ // at this point we know that it's a root transition since LCA couldn't be found
848
+ if (transition.reenter) {
849
+ return;
850
+ }
851
+ return transition.source.machine.root;
861
852
  }
862
853
  function computeExitSet(transitions, configuration, historyValue) {
863
854
  const statesToExit = new Set();
@@ -890,13 +881,8 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
890
881
 
891
882
  /**
892
883
  * https://www.w3.org/TR/scxml/#microstepProcedure
893
- *
894
- * @private
895
- * @param transitions
896
- * @param currentState
897
- * @param mutConfiguration
898
884
  */
899
- function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
885
+ function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
900
886
  if (!transitions.length) {
901
887
  return currentState;
902
888
  }
@@ -907,17 +893,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
907
893
 
908
894
  // Exit states
909
895
  if (!isInitial) {
910
- [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
896
+ [nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
911
897
  }
912
898
 
913
899
  // Execute transition content
914
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
900
+ nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
915
901
 
916
902
  // Enter states
917
- nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
903
+ nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
918
904
  const nextConfiguration = [...mutConfiguration];
919
905
  if (nextState.status === 'done') {
920
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
906
+ nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
921
907
  }
922
908
  try {
923
909
  if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
@@ -933,14 +919,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
933
919
  throw e;
934
920
  }
935
921
  }
936
- function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
922
+ function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
937
923
  if (!rootNode.output) {
938
924
  return;
939
925
  }
940
- const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
941
- return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
926
+ const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
927
+ return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
942
928
  }
943
- function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
929
+ function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
944
930
  let nextState = currentState;
945
931
  const statesToEnter = new Set();
946
932
  // those are states that were directly targeted or indirectly targeted by the explicit target
@@ -961,19 +947,22 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
961
947
  // Add entry actions
962
948
  actions.push(...stateNodeToEnter.entry);
963
949
  for (const invokeDef of stateNodeToEnter.invoke) {
964
- actions.push(invoke(invokeDef));
950
+ actions.push(spawn(invokeDef.src, {
951
+ ...invokeDef,
952
+ syncSnapshot: !!invokeDef.onSnapshot
953
+ }));
965
954
  }
966
955
  if (statesForDefaultEntry.has(stateNodeToEnter)) {
967
956
  const initialActions = stateNodeToEnter.initial.actions;
968
957
  actions.push(...initialActions);
969
958
  }
970
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
959
+ nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
971
960
  if (stateNodeToEnter.type === 'final') {
972
961
  const parent = stateNodeToEnter.parent;
973
962
  let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
974
963
  let rootCompletionNode = ancestorMarker || stateNodeToEnter;
975
964
  if (parent?.type === 'compound') {
976
- internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
965
+ internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
977
966
  }
978
967
  while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
979
968
  completedNodes.add(ancestorMarker);
@@ -986,7 +975,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
986
975
  }
987
976
  nextState = cloneState(nextState, {
988
977
  status: 'done',
989
- output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
978
+ output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
990
979
  });
991
980
  }
992
981
  }
@@ -1011,7 +1000,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
1011
1000
  }
1012
1001
  const targetStates = getEffectiveTargetStates(t, historyValue);
1013
1002
  for (const s of targetStates) {
1014
- addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
1003
+ const ancestors = getProperAncestors(s, domain);
1004
+ if (domain?.type === 'parallel') {
1005
+ ancestors.push(domain);
1006
+ }
1007
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
1015
1008
  }
1016
1009
  }
1017
1010
  }
@@ -1024,7 +1017,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1024
1017
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1025
1018
  }
1026
1019
  for (const s of historyStateNodes) {
1027
- addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1020
+ addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1028
1021
  }
1029
1022
  } else {
1030
1023
  const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
@@ -1036,7 +1029,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1036
1029
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1037
1030
  }
1038
1031
  for (const s of historyDefaultTransition.target) {
1039
- addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1032
+ addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1040
1033
  }
1041
1034
  }
1042
1035
  } else {
@@ -1047,7 +1040,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1047
1040
  statesForDefaultEntry.add(initialState);
1048
1041
  }
1049
1042
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1050
- addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1043
+ addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1051
1044
  } else {
1052
1045
  if (stateNode.type === 'parallel') {
1053
1046
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
@@ -1063,10 +1056,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1063
1056
  }
1064
1057
  }
1065
1058
  }
1066
- function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1067
- const properAncestors = getProperAncestors(stateNode, toStateNode);
1068
- for (const anc of properAncestors) {
1069
- statesToEnter.add(anc);
1059
+ function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
1060
+ for (const anc of ancestors) {
1061
+ if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
1062
+ statesToEnter.add(anc);
1063
+ }
1070
1064
  if (anc.type === 'parallel') {
1071
1065
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1072
1066
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
@@ -1077,7 +1071,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1077
1071
  }
1078
1072
  }
1079
1073
  }
1080
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1074
+ function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1075
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
1076
+ }
1077
+ function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
1081
1078
  let nextState = currentState;
1082
1079
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1083
1080
  statesToExit.sort((a, b) => b.order - a.order);
@@ -1101,12 +1098,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1101
1098
  }
1102
1099
  }
1103
1100
  for (const s of statesToExit) {
1104
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1101
+ nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1105
1102
  mutConfiguration.delete(s);
1106
1103
  }
1107
1104
  return [nextState, changedHistory || historyValue];
1108
1105
  }
1109
- function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1106
+ function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
1110
1107
  const {
1111
1108
  machine
1112
1109
  } = currentState;
@@ -1124,32 +1121,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1124
1121
  const actionArgs = {
1125
1122
  context: intermediateState.context,
1126
1123
  event,
1127
- self: actorCtx?.self,
1128
- system: actorCtx?.system,
1129
- action: isInline ? undefined : typeof action === 'string' ? {
1130
- type: action
1131
- } : typeof action.params === 'function' ? {
1132
- type: action.type,
1133
- params: action.params({
1134
- context: intermediateState.context,
1135
- event
1136
- })
1137
- } :
1138
- // TS isn't able to narrow it down here
1139
- action
1124
+ self: actorScope?.self,
1125
+ system: actorScope?.system
1140
1126
  };
1127
+ const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
1128
+ context: intermediateState.context,
1129
+ event
1130
+ }) : action.params : undefined;
1141
1131
  if (!('resolve' in resolvedAction)) {
1142
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1143
- resolvedAction(actionArgs);
1132
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1133
+ resolvedAction(actionArgs, actionParams);
1144
1134
  } else {
1145
- actorCtx?.defer(() => {
1146
- resolvedAction(actionArgs);
1135
+ actorScope?.defer(() => {
1136
+ resolvedAction(actionArgs, actionParams);
1147
1137
  });
1148
1138
  }
1149
1139
  continue;
1150
1140
  }
1151
1141
  const builtinAction = resolvedAction;
1152
- const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
1142
+ const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
1153
1143
  // this holds all params
1154
1144
  extra);
1155
1145
  intermediateState = nextState;
@@ -1157,30 +1147,30 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1157
1147
  retries?.push([builtinAction, params]);
1158
1148
  }
1159
1149
  if ('execute' in builtinAction) {
1160
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1161
- builtinAction.execute(actorCtx, params);
1150
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1151
+ builtinAction.execute(actorScope, params);
1162
1152
  } else {
1163
- actorCtx?.defer(builtinAction.execute.bind(null, actorCtx, params));
1153
+ actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
1164
1154
  }
1165
1155
  }
1166
1156
  if (actions) {
1167
- intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorCtx, actions, extra, retries);
1157
+ intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
1168
1158
  }
1169
1159
  }
1170
1160
  return intermediateState;
1171
1161
  }
1172
- function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1162
+ function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
1173
1163
  const retries = deferredActorIds ? [] : undefined;
1174
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1164
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
1175
1165
  internalQueue,
1176
1166
  deferredActorIds
1177
1167
  }, retries);
1178
1168
  retries?.forEach(([builtinAction, params]) => {
1179
- builtinAction.retryResolve(actorCtx, nextState, params);
1169
+ builtinAction.retryResolve(actorScope, nextState, params);
1180
1170
  });
1181
1171
  return nextState;
1182
1172
  }
1183
- function macrostep(state, event, actorCtx, internalQueue = []) {
1173
+ function macrostep(state, event, actorScope, internalQueue = []) {
1184
1174
  if (event.type === interpreter.WILDCARD) {
1185
1175
  throw new Error(`An event cannot have the wildcard type ('${interpreter.WILDCARD}')`);
1186
1176
  }
@@ -1189,7 +1179,9 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1189
1179
 
1190
1180
  // Handle stop event
1191
1181
  if (event.type === interpreter.XSTATE_STOP) {
1192
- nextState = stopChildren(nextState, event, actorCtx);
1182
+ nextState = cloneState(stopChildren(nextState, event, actorScope), {
1183
+ status: 'stopped'
1184
+ });
1193
1185
  states.push(nextState);
1194
1186
  return {
1195
1187
  state: nextState,
@@ -1202,7 +1194,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1202
1194
  // Determine the next state based on the next microstep
1203
1195
  if (nextEvent.type !== interpreter.XSTATE_INIT) {
1204
1196
  const transitions = selectTransitions(nextEvent, nextState);
1205
- nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1197
+ nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
1206
1198
  states.push(nextState);
1207
1199
  }
1208
1200
  let shouldSelectEventlessTransitions = true;
@@ -1219,20 +1211,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1219
1211
  nextEvent = internalQueue.shift();
1220
1212
  enabledTransitions = selectTransitions(nextEvent, nextState);
1221
1213
  }
1222
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1214
+ nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
1223
1215
  shouldSelectEventlessTransitions = nextState !== previousState;
1224
1216
  states.push(nextState);
1225
1217
  }
1226
1218
  if (nextState.status !== 'active') {
1227
- stopChildren(nextState, nextEvent, actorCtx);
1219
+ stopChildren(nextState, nextEvent, actorScope);
1228
1220
  }
1229
1221
  return {
1230
1222
  state: nextState,
1231
1223
  microstates: states
1232
1224
  };
1233
1225
  }
1234
- function stopChildren(nextState, event, actorCtx) {
1235
- return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1226
+ function stopChildren(nextState, event, actorScope) {
1227
+ return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
1236
1228
  }
1237
1229
  function selectTransitions(event, nextState) {
1238
1230
  return nextState.machine.getTransitionData(nextState, event);
@@ -1452,17 +1444,17 @@ function getPersistedState(state) {
1452
1444
  throw new Error('An inline child actor cannot be persisted.');
1453
1445
  }
1454
1446
  childrenJson[id] = {
1455
- state: child.getPersistedState?.(),
1456
- src: child.src
1447
+ state: child.getPersistedState(),
1448
+ src: child.src,
1449
+ systemId: child._systemId
1457
1450
  };
1458
1451
  }
1459
- return {
1452
+ const persisted = {
1460
1453
  ...jsonValues,
1461
- // TODO: this makes `PersistedMachineState`'s type kind of a lie
1462
- // it doesn't truly use `TContext` but rather some kind of a derived form of it
1463
1454
  context: persistContext(context),
1464
1455
  children: childrenJson
1465
1456
  };
1457
+ return persisted;
1466
1458
  }
1467
1459
  function persistContext(contextPart) {
1468
1460
  let copy;
@@ -1491,7 +1483,7 @@ function persistContext(contextPart) {
1491
1483
  return copy ?? contextPart;
1492
1484
  }
1493
1485
 
1494
- function resolveRaise(_, state, args, {
1486
+ function resolveRaise(_, state, args, actionParams, {
1495
1487
  event: eventOrExpr,
1496
1488
  id,
1497
1489
  delay
@@ -1502,13 +1494,13 @@ function resolveRaise(_, state, args, {
1502
1494
  if (typeof eventOrExpr === 'string') {
1503
1495
  throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
1504
1496
  }
1505
- const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
1497
+ const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
1506
1498
  let resolvedDelay;
1507
1499
  if (typeof delay === 'string') {
1508
1500
  const configDelay = delaysMap && delaysMap[delay];
1509
- resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
1501
+ resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
1510
1502
  } else {
1511
- resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1503
+ resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
1512
1504
  }
1513
1505
  if (typeof resolvedDelay !== 'number') {
1514
1506
  internalQueue.push(resolvedEvent);
@@ -1519,9 +1511,9 @@ function resolveRaise(_, state, args, {
1519
1511
  delay: resolvedDelay
1520
1512
  }];
1521
1513
  }
1522
- function executeRaise(actorContext, params) {
1514
+ function executeRaise(actorScope, params) {
1523
1515
  if (typeof params.delay === 'number') {
1524
- actorContext.self.delaySend(params);
1516
+ actorScope.self.delaySend(params);
1525
1517
  return;
1526
1518
  }
1527
1519
  }
@@ -1532,7 +1524,7 @@ function executeRaise(actorContext, params) {
1532
1524
  * @param eventType The event to raise.
1533
1525
  */
1534
1526
  function raise(eventOrExpr, options) {
1535
- function raise(_) {
1527
+ function raise(args, params) {
1536
1528
  {
1537
1529
  throw new Error(`This isn't supposed to be called`);
1538
1530
  }
@@ -1572,6 +1564,7 @@ exports.or = or;
1572
1564
  exports.raise = raise;
1573
1565
  exports.resolveActionsAndContext = resolveActionsAndContext;
1574
1566
  exports.resolveStateValue = resolveStateValue;
1567
+ exports.spawn = spawn;
1575
1568
  exports.stateIn = stateIn;
1576
1569
  exports.stop = stop;
1577
1570
  exports.transitionNode = transitionNode;