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-97aff8d2.cjs.js');
3
+ var interpreter = require('./interpreter-5dfcd203.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
  cancel.type = 'xstate.cancel';
39
39
  cancel.sendId = sendId;
@@ -42,7 +42,7 @@ function cancel(sendId) {
42
42
  return cancel;
43
43
  }
44
44
 
45
- function resolveInvoke(actorContext, state, actionArgs, {
45
+ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
46
46
  id,
47
47
  systemId,
48
48
  src,
@@ -53,93 +53,88 @@ function resolveInvoke(actorContext, state, actionArgs, {
53
53
  src,
54
54
  input: undefined
55
55
  };
56
+ const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
56
57
  let actorRef;
57
58
  if (referenced) {
58
59
  // TODO: inline `input: undefined` should win over the referenced one
59
60
  const configuredInput = input || referenced.input;
60
61
  actorRef = interpreter.createActor(referenced.src, {
61
- id,
62
+ id: resolvedId,
62
63
  src: typeof src === 'string' ? src : undefined,
63
- parent: actorContext?.self,
64
+ parent: actorScope?.self,
64
65
  systemId,
65
66
  input: typeof configuredInput === 'function' ? configuredInput({
66
67
  context: state.context,
67
68
  event: actionArgs.event,
68
- self: actorContext?.self
69
+ self: actorScope?.self
69
70
  }) : configuredInput
70
71
  });
71
72
  if (syncSnapshot) {
72
73
  actorRef.subscribe({
73
74
  next: snapshot => {
74
75
  if (snapshot.status === 'active') {
75
- actorContext.self.send({
76
+ actorScope.self.send({
76
77
  type: `xstate.snapshot.${id}`,
77
78
  snapshot
78
79
  });
79
80
  }
80
81
  },
81
- error: () => {
82
- /* TODO */
83
- }
82
+ error: () => {}
84
83
  });
85
84
  }
86
85
  }
87
86
  return [cloneState(state, {
88
87
  children: {
89
88
  ...state.children,
90
- [id]: actorRef
89
+ [resolvedId]: actorRef
91
90
  }
92
91
  }), {
93
92
  id,
94
93
  actorRef
95
94
  }];
96
95
  }
97
- function executeInvoke(actorContext, {
96
+ function executeSpawn(actorScope, {
98
97
  id,
99
98
  actorRef
100
99
  }) {
101
100
  if (!actorRef) {
102
101
  return;
103
102
  }
104
- actorContext.defer(() => {
103
+ actorScope.defer(() => {
105
104
  if (actorRef.status === interpreter.ActorStatus.Stopped) {
106
105
  return;
107
106
  }
108
107
  try {
109
108
  actorRef.start?.();
110
109
  } catch (err) {
111
- actorContext.self.send(interpreter.createErrorActorEvent(id, err));
110
+ actorScope.self.send(interpreter.createErrorActorEvent(id, err));
112
111
  return;
113
112
  }
114
113
  });
115
114
  }
116
-
117
- // we don't export this since it's an internal action that is not meant to be used in the user's code
118
-
119
- function invoke({
115
+ function spawn(...[src, {
120
116
  id,
121
117
  systemId,
122
- src,
123
118
  input,
124
- onSnapshot
125
- }) {
126
- function invoke(_) {
127
- }
128
- invoke.type = 'xstate.invoke';
129
- invoke.id = id;
130
- invoke.systemId = systemId;
131
- invoke.src = src;
132
- invoke.input = input;
133
- invoke.syncSnapshot = !!onSnapshot;
134
- invoke.resolve = resolveInvoke;
135
- invoke.execute = executeInvoke;
136
- return invoke;
119
+ syncSnapshot = false
120
+ } = {}]) {
121
+ function spawn(args, params) {
122
+ }
123
+ spawn.type = 'xstate.spawn';
124
+ spawn.id = id;
125
+ spawn.systemId = systemId;
126
+ spawn.src = src;
127
+ spawn.input = input;
128
+ spawn.syncSnapshot = syncSnapshot;
129
+ spawn.resolve = resolveSpawn;
130
+ spawn.execute = executeSpawn;
131
+ return spawn;
137
132
  }
138
133
 
139
- function resolveStop(_, state, args, {
134
+ function resolveStop(_, state, args, actionParams, {
140
135
  actorRef
141
136
  }) {
142
- const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
137
+ const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
143
138
  const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
144
139
  let children = state.children;
145
140
  if (resolvedActorRef) {
@@ -152,22 +147,28 @@ function resolveStop(_, state, args, {
152
147
  children
153
148
  }), resolvedActorRef];
154
149
  }
155
- function executeStop(actorContext, actorRef) {
150
+ function executeStop(actorScope, actorRef) {
156
151
  if (!actorRef) {
157
152
  return;
158
153
  }
154
+
155
+ // we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
156
+ // since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
157
+ // this could throw on `systemId` collision, for example, when dealing with reentering transitions
158
+ actorScope.system._unregister(actorRef);
159
+
159
160
  // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
160
161
  // this can happen, for example, when the invoking state is being exited immediately by an always transition
161
162
  if (actorRef.status !== interpreter.ActorStatus.Running) {
162
- actorContext.stopChild(actorRef);
163
+ actorScope.stopChild(actorRef);
163
164
  return;
164
165
  }
165
166
  // stopping a child enqueues a stop event in the child actor's mailbox
166
167
  // we need for all of the already enqueued events to be processed before we stop the child
167
168
  // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
168
169
  // and we don't want to ignore those events
169
- actorContext.defer(() => {
170
- actorContext.stopChild(actorRef);
170
+ actorScope.defer(() => {
171
+ actorScope.stopChild(actorRef);
171
172
  });
172
173
  }
173
174
  /**
@@ -176,7 +177,7 @@ function executeStop(actorContext, actorRef) {
176
177
  * @param actorRef The actor to stop.
177
178
  */
178
179
  function stop(actorRef) {
179
- function stop(_) {
180
+ function stop(args, params) {
180
181
  }
181
182
  stop.type = 'xstate.stop';
182
183
  stop.actorRef = actorRef;
@@ -195,7 +196,7 @@ function checkStateIn(state, _, {
195
196
  return state.matches(stateValue);
196
197
  }
197
198
  function stateIn(stateValue) {
198
- function stateIn(_) {
199
+ function stateIn(args, params) {
199
200
  return false;
200
201
  }
201
202
  stateIn.check = checkStateIn;
@@ -211,7 +212,7 @@ function checkNot(state, {
211
212
  return !evaluateGuard(guards[0], context, event, state);
212
213
  }
213
214
  function not(guard) {
214
- function not(_) {
215
+ function not(args, params) {
215
216
  return false;
216
217
  }
217
218
  not.check = checkNot;
@@ -227,7 +228,7 @@ function checkAnd(state, {
227
228
  return guards.every(guard => evaluateGuard(guard, context, event, state));
228
229
  }
229
230
  function and(guards) {
230
- function and(_) {
231
+ function and(args, params) {
231
232
  return false;
232
233
  }
233
234
  and.check = checkAnd;
@@ -243,7 +244,7 @@ function checkOr(state, {
243
244
  return guards.some(guard => evaluateGuard(guard, context, event, state));
244
245
  }
245
246
  function or(guards) {
246
- function or(_) {
247
+ function or(args, params) {
247
248
  return false;
248
249
  }
249
250
  or.check = checkOr;
@@ -266,22 +267,17 @@ function evaluateGuard(guard, context, event, state) {
266
267
  }
267
268
  const guardArgs = {
268
269
  context,
269
- event,
270
- guard: isInline ? undefined : typeof guard === 'string' ? {
271
- type: guard
272
- } : typeof guard.params === 'function' ? {
273
- type: guard.type,
274
- params: guard.params({
275
- context,
276
- event
277
- })
278
- } : guard
270
+ event
279
271
  };
272
+ const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
273
+ context,
274
+ event
275
+ }) : guard.params : undefined;
280
276
  if (!('check' in resolved)) {
281
277
  // the existing type of `.guards` assumes non-nullable `TExpressionGuard`
282
278
  // inline guards expect `TExpressionGuard` to be set to `undefined`
283
279
  // it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
284
- return resolved(guardArgs);
280
+ return resolved(guardArgs, guardParams);
285
281
  }
286
282
  const builtinGuard = resolved;
287
283
  return builtinGuard.check(state, guardArgs, resolved // this holds all params
@@ -735,15 +731,6 @@ function isDescendant(childStateNode, parentStateNode) {
735
731
  }
736
732
  return marker.parent === parentStateNode;
737
733
  }
738
- function getPathFromRootToNode(stateNode) {
739
- const path = [];
740
- let marker = stateNode.parent;
741
- while (marker) {
742
- path.unshift(marker);
743
- marker = marker.parent;
744
- }
745
- return path;
746
- }
747
734
  function hasIntersection(s1, s2) {
748
735
  const set1 = new Set(s1);
749
736
  const set2 = new Set(s2);
@@ -783,17 +770,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
783
770
  }
784
771
  return Array.from(filteredTransitions);
785
772
  }
786
- function findLCCA(stateNodes) {
787
- const [head] = stateNodes;
788
- let current = getPathFromRootToNode(head);
789
- let candidates = [];
790
- for (const stateNode of stateNodes) {
791
- const path = getPathFromRootToNode(stateNode);
792
- candidates = current.filter(sn => path.includes(sn));
793
- current = candidates;
794
- candidates = [];
773
+ function findLeastCommonAncestor(stateNodes) {
774
+ const [head, ...tail] = stateNodes;
775
+ for (const ancestor of getProperAncestors(head, undefined)) {
776
+ if (tail.every(sn => isDescendant(sn, ancestor))) {
777
+ return ancestor;
778
+ }
795
779
  }
796
- return current[current.length - 1];
797
780
  }
798
781
  function getEffectiveTargetStates(transition, historyValue) {
799
782
  if (!transition.target) {
@@ -825,8 +808,16 @@ function getTransitionDomain(transition, historyValue) {
825
808
  if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
826
809
  return transition.source;
827
810
  }
828
- const lcca = findLCCA(targetStates.concat(transition.source));
829
- return lcca;
811
+ const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
812
+ if (lca) {
813
+ return lca;
814
+ }
815
+
816
+ // at this point we know that it's a root transition since LCA couldn't be found
817
+ if (transition.reenter) {
818
+ return;
819
+ }
820
+ return transition.source.machine.root;
830
821
  }
831
822
  function computeExitSet(transitions, configuration, historyValue) {
832
823
  const statesToExit = new Set();
@@ -859,13 +850,8 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
859
850
 
860
851
  /**
861
852
  * https://www.w3.org/TR/scxml/#microstepProcedure
862
- *
863
- * @private
864
- * @param transitions
865
- * @param currentState
866
- * @param mutConfiguration
867
853
  */
868
- function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
854
+ function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
869
855
  if (!transitions.length) {
870
856
  return currentState;
871
857
  }
@@ -876,17 +862,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
876
862
 
877
863
  // Exit states
878
864
  if (!isInitial) {
879
- [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
865
+ [nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
880
866
  }
881
867
 
882
868
  // Execute transition content
883
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
869
+ nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
884
870
 
885
871
  // Enter states
886
- nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
872
+ nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
887
873
  const nextConfiguration = [...mutConfiguration];
888
874
  if (nextState.status === 'done') {
889
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
875
+ nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
890
876
  }
891
877
  try {
892
878
  if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
@@ -902,14 +888,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
902
888
  throw e;
903
889
  }
904
890
  }
905
- function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
891
+ function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
906
892
  if (!rootNode.output) {
907
893
  return;
908
894
  }
909
- const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
910
- return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
895
+ const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
896
+ return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
911
897
  }
912
- function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
898
+ function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
913
899
  let nextState = currentState;
914
900
  const statesToEnter = new Set();
915
901
  // those are states that were directly targeted or indirectly targeted by the explicit target
@@ -930,19 +916,22 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
930
916
  // Add entry actions
931
917
  actions.push(...stateNodeToEnter.entry);
932
918
  for (const invokeDef of stateNodeToEnter.invoke) {
933
- actions.push(invoke(invokeDef));
919
+ actions.push(spawn(invokeDef.src, {
920
+ ...invokeDef,
921
+ syncSnapshot: !!invokeDef.onSnapshot
922
+ }));
934
923
  }
935
924
  if (statesForDefaultEntry.has(stateNodeToEnter)) {
936
925
  const initialActions = stateNodeToEnter.initial.actions;
937
926
  actions.push(...initialActions);
938
927
  }
939
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
928
+ nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
940
929
  if (stateNodeToEnter.type === 'final') {
941
930
  const parent = stateNodeToEnter.parent;
942
931
  let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
943
932
  let rootCompletionNode = ancestorMarker || stateNodeToEnter;
944
933
  if (parent?.type === 'compound') {
945
- internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
934
+ internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
946
935
  }
947
936
  while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
948
937
  completedNodes.add(ancestorMarker);
@@ -955,7 +944,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
955
944
  }
956
945
  nextState = cloneState(nextState, {
957
946
  status: 'done',
958
- output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
947
+ output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
959
948
  });
960
949
  }
961
950
  }
@@ -980,7 +969,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
980
969
  }
981
970
  const targetStates = getEffectiveTargetStates(t, historyValue);
982
971
  for (const s of targetStates) {
983
- addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
972
+ const ancestors = getProperAncestors(s, domain);
973
+ if (domain?.type === 'parallel') {
974
+ ancestors.push(domain);
975
+ }
976
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
984
977
  }
985
978
  }
986
979
  }
@@ -993,7 +986,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
993
986
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
994
987
  }
995
988
  for (const s of historyStateNodes) {
996
- addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
989
+ addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
997
990
  }
998
991
  } else {
999
992
  const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
@@ -1005,7 +998,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1005
998
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1006
999
  }
1007
1000
  for (const s of historyDefaultTransition.target) {
1008
- addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1001
+ addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1009
1002
  }
1010
1003
  }
1011
1004
  } else {
@@ -1016,7 +1009,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1016
1009
  statesForDefaultEntry.add(initialState);
1017
1010
  }
1018
1011
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1019
- addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1012
+ addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1020
1013
  } else {
1021
1014
  if (stateNode.type === 'parallel') {
1022
1015
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
@@ -1032,10 +1025,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1032
1025
  }
1033
1026
  }
1034
1027
  }
1035
- function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1036
- const properAncestors = getProperAncestors(stateNode, toStateNode);
1037
- for (const anc of properAncestors) {
1038
- statesToEnter.add(anc);
1028
+ function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
1029
+ for (const anc of ancestors) {
1030
+ if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
1031
+ statesToEnter.add(anc);
1032
+ }
1039
1033
  if (anc.type === 'parallel') {
1040
1034
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1041
1035
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
@@ -1046,7 +1040,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1046
1040
  }
1047
1041
  }
1048
1042
  }
1049
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1043
+ function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1044
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
1045
+ }
1046
+ function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
1050
1047
  let nextState = currentState;
1051
1048
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1052
1049
  statesToExit.sort((a, b) => b.order - a.order);
@@ -1070,12 +1067,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1070
1067
  }
1071
1068
  }
1072
1069
  for (const s of statesToExit) {
1073
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1070
+ nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1074
1071
  mutConfiguration.delete(s);
1075
1072
  }
1076
1073
  return [nextState, changedHistory || historyValue];
1077
1074
  }
1078
- function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1075
+ function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
1079
1076
  const {
1080
1077
  machine
1081
1078
  } = currentState;
@@ -1093,32 +1090,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1093
1090
  const actionArgs = {
1094
1091
  context: intermediateState.context,
1095
1092
  event,
1096
- self: actorCtx?.self,
1097
- system: actorCtx?.system,
1098
- action: isInline ? undefined : typeof action === 'string' ? {
1099
- type: action
1100
- } : typeof action.params === 'function' ? {
1101
- type: action.type,
1102
- params: action.params({
1103
- context: intermediateState.context,
1104
- event
1105
- })
1106
- } :
1107
- // TS isn't able to narrow it down here
1108
- action
1093
+ self: actorScope?.self,
1094
+ system: actorScope?.system
1109
1095
  };
1096
+ const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
1097
+ context: intermediateState.context,
1098
+ event
1099
+ }) : action.params : undefined;
1110
1100
  if (!('resolve' in resolvedAction)) {
1111
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1112
- resolvedAction(actionArgs);
1101
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1102
+ resolvedAction(actionArgs, actionParams);
1113
1103
  } else {
1114
- actorCtx?.defer(() => {
1115
- resolvedAction(actionArgs);
1104
+ actorScope?.defer(() => {
1105
+ resolvedAction(actionArgs, actionParams);
1116
1106
  });
1117
1107
  }
1118
1108
  continue;
1119
1109
  }
1120
1110
  const builtinAction = resolvedAction;
1121
- const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
1111
+ const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
1122
1112
  // this holds all params
1123
1113
  extra);
1124
1114
  intermediateState = nextState;
@@ -1126,36 +1116,38 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1126
1116
  retries?.push([builtinAction, params]);
1127
1117
  }
1128
1118
  if ('execute' in builtinAction) {
1129
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1130
- builtinAction.execute(actorCtx, params);
1119
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1120
+ builtinAction.execute(actorScope, params);
1131
1121
  } else {
1132
- actorCtx?.defer(builtinAction.execute.bind(null, actorCtx, params));
1122
+ actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
1133
1123
  }
1134
1124
  }
1135
1125
  if (actions) {
1136
- intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorCtx, actions, extra, retries);
1126
+ intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
1137
1127
  }
1138
1128
  }
1139
1129
  return intermediateState;
1140
1130
  }
1141
- function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1131
+ function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
1142
1132
  const retries = deferredActorIds ? [] : undefined;
1143
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1133
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
1144
1134
  internalQueue,
1145
1135
  deferredActorIds
1146
1136
  }, retries);
1147
1137
  retries?.forEach(([builtinAction, params]) => {
1148
- builtinAction.retryResolve(actorCtx, nextState, params);
1138
+ builtinAction.retryResolve(actorScope, nextState, params);
1149
1139
  });
1150
1140
  return nextState;
1151
1141
  }
1152
- function macrostep(state, event, actorCtx, internalQueue = []) {
1142
+ function macrostep(state, event, actorScope, internalQueue = []) {
1153
1143
  let nextState = state;
1154
1144
  const states = [];
1155
1145
 
1156
1146
  // Handle stop event
1157
1147
  if (event.type === interpreter.XSTATE_STOP) {
1158
- nextState = stopChildren(nextState, event, actorCtx);
1148
+ nextState = cloneState(stopChildren(nextState, event, actorScope), {
1149
+ status: 'stopped'
1150
+ });
1159
1151
  states.push(nextState);
1160
1152
  return {
1161
1153
  state: nextState,
@@ -1168,7 +1160,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1168
1160
  // Determine the next state based on the next microstep
1169
1161
  if (nextEvent.type !== interpreter.XSTATE_INIT) {
1170
1162
  const transitions = selectTransitions(nextEvent, nextState);
1171
- nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1163
+ nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
1172
1164
  states.push(nextState);
1173
1165
  }
1174
1166
  let shouldSelectEventlessTransitions = true;
@@ -1185,20 +1177,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1185
1177
  nextEvent = internalQueue.shift();
1186
1178
  enabledTransitions = selectTransitions(nextEvent, nextState);
1187
1179
  }
1188
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1180
+ nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
1189
1181
  shouldSelectEventlessTransitions = nextState !== previousState;
1190
1182
  states.push(nextState);
1191
1183
  }
1192
1184
  if (nextState.status !== 'active') {
1193
- stopChildren(nextState, nextEvent, actorCtx);
1185
+ stopChildren(nextState, nextEvent, actorScope);
1194
1186
  }
1195
1187
  return {
1196
1188
  state: nextState,
1197
1189
  microstates: states
1198
1190
  };
1199
1191
  }
1200
- function stopChildren(nextState, event, actorCtx) {
1201
- return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1192
+ function stopChildren(nextState, event, actorScope) {
1193
+ return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
1202
1194
  }
1203
1195
  function selectTransitions(event, nextState) {
1204
1196
  return nextState.machine.getTransitionData(nextState, event);
@@ -1412,17 +1404,17 @@ function getPersistedState(state) {
1412
1404
  for (const id in children) {
1413
1405
  const child = children[id];
1414
1406
  childrenJson[id] = {
1415
- state: child.getPersistedState?.(),
1416
- src: child.src
1407
+ state: child.getPersistedState(),
1408
+ src: child.src,
1409
+ systemId: child._systemId
1417
1410
  };
1418
1411
  }
1419
- return {
1412
+ const persisted = {
1420
1413
  ...jsonValues,
1421
- // TODO: this makes `PersistedMachineState`'s type kind of a lie
1422
- // it doesn't truly use `TContext` but rather some kind of a derived form of it
1423
1414
  context: persistContext(context),
1424
1415
  children: childrenJson
1425
1416
  };
1417
+ return persisted;
1426
1418
  }
1427
1419
  function persistContext(contextPart) {
1428
1420
  let copy;
@@ -1451,7 +1443,7 @@ function persistContext(contextPart) {
1451
1443
  return copy ?? contextPart;
1452
1444
  }
1453
1445
 
1454
- function resolveRaise(_, state, args, {
1446
+ function resolveRaise(_, state, args, actionParams, {
1455
1447
  event: eventOrExpr,
1456
1448
  id,
1457
1449
  delay
@@ -1462,13 +1454,13 @@ function resolveRaise(_, state, args, {
1462
1454
  if (typeof eventOrExpr === 'string') {
1463
1455
  throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
1464
1456
  }
1465
- const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
1457
+ const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
1466
1458
  let resolvedDelay;
1467
1459
  if (typeof delay === 'string') {
1468
1460
  const configDelay = delaysMap && delaysMap[delay];
1469
- resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
1461
+ resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
1470
1462
  } else {
1471
- resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1463
+ resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
1472
1464
  }
1473
1465
  if (typeof resolvedDelay !== 'number') {
1474
1466
  internalQueue.push(resolvedEvent);
@@ -1479,9 +1471,9 @@ function resolveRaise(_, state, args, {
1479
1471
  delay: resolvedDelay
1480
1472
  }];
1481
1473
  }
1482
- function executeRaise(actorContext, params) {
1474
+ function executeRaise(actorScope, params) {
1483
1475
  if (typeof params.delay === 'number') {
1484
- actorContext.self.delaySend(params);
1476
+ actorScope.self.delaySend(params);
1485
1477
  return;
1486
1478
  }
1487
1479
  }
@@ -1492,7 +1484,7 @@ function executeRaise(actorContext, params) {
1492
1484
  * @param eventType The event to raise.
1493
1485
  */
1494
1486
  function raise(eventOrExpr, options) {
1495
- function raise(_) {
1487
+ function raise(args, params) {
1496
1488
  }
1497
1489
  raise.type = 'xstate.raise';
1498
1490
  raise.event = eventOrExpr;
@@ -1529,6 +1521,7 @@ exports.or = or;
1529
1521
  exports.raise = raise;
1530
1522
  exports.resolveActionsAndContext = resolveActionsAndContext;
1531
1523
  exports.resolveStateValue = resolveStateValue;
1524
+ exports.spawn = spawn;
1532
1525
  exports.stateIn = stateIn;
1533
1526
  exports.stop = stop;
1534
1527
  exports.transitionNode = transitionNode;