xstate 5.0.0-beta.36 → 5.0.0-beta.38

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 (65) 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 +1 -1
  10. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  11. package/actors/dist/xstate-actors.development.esm.js +1 -1
  12. package/actors/dist/xstate-actors.esm.js +1 -1
  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 +4 -4
  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 +2 -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 +1 -1
  31. package/dist/declarations/src/guards.d.ts +9 -10
  32. package/dist/declarations/src/interpreter.d.ts +2 -2
  33. package/dist/declarations/src/spawn.d.ts +1 -2
  34. package/dist/declarations/src/stateUtils.d.ts +0 -5
  35. package/dist/declarations/src/typegenTypes.d.ts +2 -0
  36. package/dist/declarations/src/types.d.ts +47 -58
  37. package/dist/declarations/src/utils.d.ts +6 -6
  38. package/dist/declarations/src/waitFor.d.ts +1 -1
  39. package/dist/{interpreter-5c4e6634.development.esm.js → interpreter-4005eb36.development.esm.js} +14 -24
  40. package/dist/{interpreter-69605bf0.cjs.js → interpreter-b6f22ee2.cjs.js} +14 -24
  41. package/dist/{interpreter-de5217bc.esm.js → interpreter-c80ce92e.esm.js} +14 -24
  42. package/dist/{interpreter-d3567419.development.cjs.js → interpreter-ed3f81f7.development.cjs.js} +14 -24
  43. package/dist/{raise-5b7ad3b7.development.esm.js → raise-42073973.development.esm.js} +138 -118
  44. package/dist/{raise-c51b81a3.cjs.js → raise-7faa9b3b.cjs.js} +139 -118
  45. package/dist/{raise-106ea558.development.cjs.js → raise-b69a3d16.development.cjs.js} +138 -117
  46. package/dist/{raise-ffe1014a.esm.js → raise-c989c7fb.esm.js} +139 -119
  47. package/dist/{send-778692de.cjs.js → send-34160163.cjs.js} +31 -27
  48. package/dist/{send-0a7aa74e.esm.js → send-4b616da9.esm.js} +31 -27
  49. package/dist/{send-25e70bd4.development.cjs.js → send-58725522.development.cjs.js} +31 -27
  50. package/dist/{send-e93554d6.development.esm.js → send-bff8c910.development.esm.js} +31 -27
  51. package/dist/xstate.cjs.js +11 -16
  52. package/dist/xstate.cjs.mjs +1 -0
  53. package/dist/xstate.development.cjs.js +11 -16
  54. package/dist/xstate.development.cjs.mjs +1 -0
  55. package/dist/xstate.development.esm.js +13 -19
  56. package/dist/xstate.esm.js +13 -19
  57. package/dist/xstate.umd.min.js +1 -1
  58. package/dist/xstate.umd.min.js.map +1 -1
  59. package/guards/dist/xstate-guards.cjs.js +2 -2
  60. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  61. package/guards/dist/xstate-guards.development.esm.js +2 -2
  62. package/guards/dist/xstate-guards.esm.js +2 -2
  63. package/guards/dist/xstate-guards.umd.min.js +1 -1
  64. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  65. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var interpreter = require('./interpreter-d3567419.development.cjs.js');
3
+ var interpreter = require('./interpreter-ed3f81f7.development.cjs.js');
4
4
 
5
5
  const cache = new WeakMap();
6
6
  function memo(object, key, fn) {
@@ -16,10 +16,10 @@ 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
25
  function executeCancel(actorContext, resolvedSendId) {
@@ -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,21 +45,25 @@ function cancel(sendId) {
45
45
  return cancel;
46
46
  }
47
47
 
48
- function resolveInvoke(actorContext, state, actionArgs, {
48
+ function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
49
49
  id,
50
50
  systemId,
51
51
  src,
52
52
  input,
53
53
  syncSnapshot
54
54
  }) {
55
- const referenced = interpreter.resolveReferencedActor(state.machine.implementations.actors[src]);
55
+ const referenced = typeof src === 'string' ? interpreter.resolveReferencedActor(state.machine, src) : {
56
+ src,
57
+ input: undefined
58
+ };
59
+ const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
56
60
  let actorRef;
57
61
  if (referenced) {
58
62
  // TODO: inline `input: undefined` should win over the referenced one
59
63
  const configuredInput = input || referenced.input;
60
64
  actorRef = interpreter.createActor(referenced.src, {
61
- id,
62
- src,
65
+ id: resolvedId,
66
+ src: typeof src === 'string' ? src : undefined,
63
67
  parent: actorContext?.self,
64
68
  systemId,
65
69
  input: typeof configuredInput === 'function' ? configuredInput({
@@ -78,9 +82,7 @@ function resolveInvoke(actorContext, state, actionArgs, {
78
82
  });
79
83
  }
80
84
  },
81
- error: () => {
82
- /* TODO */
83
- }
85
+ error: () => {}
84
86
  });
85
87
  }
86
88
  }
@@ -90,14 +92,14 @@ function resolveInvoke(actorContext, state, actionArgs, {
90
92
  return [cloneState(state, {
91
93
  children: {
92
94
  ...state.children,
93
- [id]: actorRef
95
+ [resolvedId]: actorRef
94
96
  }
95
97
  }), {
96
98
  id,
97
99
  actorRef
98
100
  }];
99
101
  }
100
- function executeInvoke(actorContext, {
102
+ function executeSpawn(actorContext, {
101
103
  id,
102
104
  actorRef
103
105
  }) {
@@ -116,36 +118,32 @@ function executeInvoke(actorContext, {
116
118
  }
117
119
  });
118
120
  }
119
-
120
- // we don't export this since it's an internal action that is not meant to be used in the user's code
121
-
122
- function invoke({
121
+ function spawn(...[src, {
123
122
  id,
124
123
  systemId,
125
- src,
126
124
  input,
127
- onSnapshot
128
- }) {
129
- function invoke(_) {
125
+ syncSnapshot = false
126
+ } = {}]) {
127
+ function spawn(args, params) {
130
128
  {
131
129
  throw new Error(`This isn't supposed to be called`);
132
130
  }
133
131
  }
134
- invoke.type = 'xstate.invoke';
135
- invoke.id = id;
136
- invoke.systemId = systemId;
137
- invoke.src = src;
138
- invoke.input = input;
139
- invoke.syncSnapshot = !!onSnapshot;
140
- invoke.resolve = resolveInvoke;
141
- invoke.execute = executeInvoke;
142
- 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;
143
141
  }
144
142
 
145
- function resolveStop(_, state, args, {
143
+ function resolveStop(_, state, args, actionParams, {
146
144
  actorRef
147
145
  }) {
148
- const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
146
+ const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
149
147
  const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
150
148
  let children = state.children;
151
149
  if (resolvedActorRef) {
@@ -162,11 +160,22 @@ function executeStop(actorContext, actorRef) {
162
160
  if (!actorRef) {
163
161
  return;
164
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
+ actorContext.system._unregister(actorRef);
168
+
169
+ // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
170
+ // this can happen, for example, when the invoking state is being exited immediately by an always transition
165
171
  if (actorRef.status !== interpreter.ActorStatus.Running) {
166
172
  actorContext.stopChild(actorRef);
167
173
  return;
168
174
  }
169
- // TODO: recheck why this one has to be deferred
175
+ // stopping a child enqueues a stop event in the child actor's mailbox
176
+ // we need for all of the already enqueued events to be processed before we stop the child
177
+ // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
178
+ // and we don't want to ignore those events
170
179
  actorContext.defer(() => {
171
180
  actorContext.stopChild(actorRef);
172
181
  });
@@ -177,7 +186,7 @@ function executeStop(actorContext, actorRef) {
177
186
  * @param actorRef The actor to stop.
178
187
  */
179
188
  function stop(actorRef) {
180
- function stop(_) {
189
+ function stop(args, params) {
181
190
  {
182
191
  throw new Error(`This isn't supposed to be called`);
183
192
  }
@@ -193,12 +202,13 @@ function checkStateIn(state, _, {
193
202
  stateValue
194
203
  }) {
195
204
  if (typeof stateValue === 'string' && isStateId(stateValue)) {
196
- return state.configuration.some(sn => sn.id === stateValue.slice(1));
205
+ const target = state.machine.getStateNodeById(stateValue);
206
+ return state.configuration.some(sn => sn === target);
197
207
  }
198
208
  return state.matches(stateValue);
199
209
  }
200
210
  function stateIn(stateValue) {
201
- function stateIn(_) {
211
+ function stateIn(args, params) {
202
212
  {
203
213
  throw new Error(`This isn't supposed to be called`);
204
214
  }
@@ -216,7 +226,7 @@ function checkNot(state, {
216
226
  return !evaluateGuard(guards[0], context, event, state);
217
227
  }
218
228
  function not(guard) {
219
- function not(_) {
229
+ function not(args, params) {
220
230
  {
221
231
  throw new Error(`This isn't supposed to be called`);
222
232
  }
@@ -234,7 +244,7 @@ function checkAnd(state, {
234
244
  return guards.every(guard => evaluateGuard(guard, context, event, state));
235
245
  }
236
246
  function and(guards) {
237
- function and(_) {
247
+ function and(args, params) {
238
248
  {
239
249
  throw new Error(`This isn't supposed to be called`);
240
250
  }
@@ -252,7 +262,7 @@ function checkOr(state, {
252
262
  return guards.some(guard => evaluateGuard(guard, context, event, state));
253
263
  }
254
264
  function or(guards) {
255
- function or(_) {
265
+ function or(args, params) {
256
266
  {
257
267
  throw new Error(`This isn't supposed to be called`);
258
268
  }
@@ -277,22 +287,17 @@ function evaluateGuard(guard, context, event, state) {
277
287
  }
278
288
  const guardArgs = {
279
289
  context,
280
- event,
281
- guard: isInline ? undefined : typeof guard === 'string' ? {
282
- type: guard
283
- } : typeof guard.params === 'function' ? {
284
- type: guard.type,
285
- params: guard.params({
286
- context,
287
- event
288
- })
289
- } : guard
290
+ event
290
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;
291
296
  if (!('check' in resolved)) {
292
297
  // the existing type of `.guards` assumes non-nullable `TExpressionGuard`
293
298
  // inline guards expect `TExpressionGuard` to be set to `undefined`
294
299
  // it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
295
- return resolved(guardArgs);
300
+ return resolved(guardArgs, guardParams);
296
301
  }
297
302
  const builtinGuard = resolved;
298
303
  return builtinGuard.check(state, guardArgs, resolved // this holds all params
@@ -305,6 +310,9 @@ function getChildren(stateNode) {
305
310
  }
306
311
  function getProperAncestors(stateNode, toStateNode) {
307
312
  const ancestors = [];
313
+ if (toStateNode === stateNode) {
314
+ return ancestors;
315
+ }
308
316
 
309
317
  // add all ancestors
310
318
  let m = stateNode.parent;
@@ -592,12 +600,14 @@ function resolveTarget(stateNode, targets) {
592
600
  }
593
601
  });
594
602
  }
595
- function resolveHistoryTarget(stateNode) {
603
+ function resolveHistoryDefaultTransition(stateNode) {
596
604
  const normalizedTarget = interpreter.normalizeTarget(stateNode.config.target);
597
605
  if (!normalizedTarget) {
598
- return stateNode.parent.initial.target;
606
+ return stateNode.parent.initial;
599
607
  }
600
- return normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t);
608
+ return {
609
+ target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
610
+ };
601
611
  }
602
612
  function isHistoryNode(stateNode) {
603
613
  return stateNode.type === 'history';
@@ -824,9 +834,7 @@ function getEffectiveTargetStates(transition, historyValue) {
824
834
  targets.add(node);
825
835
  }
826
836
  } else {
827
- for (const node of getEffectiveTargetStates({
828
- target: resolveHistoryTarget(targetNode)
829
- }, historyValue)) {
837
+ for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
830
838
  targets.add(node);
831
839
  }
832
840
  }
@@ -839,9 +847,9 @@ function getEffectiveTargetStates(transition, historyValue) {
839
847
  function getTransitionDomain(transition, historyValue) {
840
848
  const targetStates = getEffectiveTargetStates(transition, historyValue);
841
849
  if (!targetStates) {
842
- return null;
850
+ return;
843
851
  }
844
- if (!transition.reenter && transition.source.type !== 'parallel' && targetStates.every(targetStateNode => isDescendant(targetStateNode, transition.source))) {
852
+ if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
845
853
  return transition.source;
846
854
  }
847
855
  const lcca = findLCCA(targetStates.concat(transition.source));
@@ -852,6 +860,9 @@ function computeExitSet(transitions, configuration, historyValue) {
852
860
  for (const t of transitions) {
853
861
  if (t.target?.length) {
854
862
  const domain = getTransitionDomain(t, historyValue);
863
+ if (t.reenter && t.source === domain) {
864
+ statesToExit.add(domain);
865
+ }
855
866
  for (const stateNode of configuration) {
856
867
  if (isDescendant(stateNode, domain)) {
857
868
  statesToExit.add(stateNode);
@@ -875,11 +886,6 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
875
886
 
876
887
  /**
877
888
  * https://www.w3.org/TR/scxml/#microstepProcedure
878
- *
879
- * @private
880
- * @param transitions
881
- * @param currentState
882
- * @param mutConfiguration
883
889
  */
884
890
  function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
885
891
  if (!transitions.length) {
@@ -928,6 +934,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
928
934
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
929
935
  let nextState = currentState;
930
936
  const statesToEnter = new Set();
937
+ // those are states that were directly targeted or indirectly targeted by the explicit target
938
+ // in other words, those are states for which initial actions should be executed
939
+ // when we target `#deep_child` initial actions of its ancestors shouldn't be executed
931
940
  const statesForDefaultEntry = new Set();
932
941
  computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
933
942
 
@@ -943,7 +952,10 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
943
952
  // Add entry actions
944
953
  actions.push(...stateNodeToEnter.entry);
945
954
  for (const invokeDef of stateNodeToEnter.invoke) {
946
- actions.push(invoke(invokeDef));
955
+ actions.push(spawn(invokeDef.src, {
956
+ ...invokeDef,
957
+ syncSnapshot: !!invokeDef.onSnapshot
958
+ }));
947
959
  }
948
960
  if (statesForDefaultEntry.has(stateNodeToEnter)) {
949
961
  const initialActions = stateNodeToEnter.initial.actions;
@@ -952,20 +964,16 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
952
964
  nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
953
965
  if (stateNodeToEnter.type === 'final') {
954
966
  const parent = stateNodeToEnter.parent;
955
- if (completedNodes.has(parent)) {
956
- continue;
957
- }
958
- completedNodes.add(parent);
959
- let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
960
- let ancestorMarker = parent?.parent;
961
- if (ancestorMarker) {
967
+ let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
968
+ let rootCompletionNode = ancestorMarker || stateNodeToEnter;
969
+ if (parent?.type === 'compound') {
962
970
  internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
963
- while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
964
- completedNodes.add(ancestorMarker);
965
- internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
966
- rootCompletionNode = ancestorMarker;
967
- ancestorMarker = ancestorMarker.parent;
968
- }
971
+ }
972
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
973
+ completedNodes.add(ancestorMarker);
974
+ internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
975
+ rootCompletionNode = ancestorMarker;
976
+ ancestorMarker = ancestorMarker.parent;
969
977
  }
970
978
  if (ancestorMarker) {
971
979
  continue;
@@ -980,13 +988,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
980
988
  }
981
989
  function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
982
990
  for (const t of transitions) {
991
+ const domain = getTransitionDomain(t, historyValue);
983
992
  for (const s of t.target || []) {
993
+ if (!isHistoryNode(s) && (
994
+ // if the target is different than the source then it will *definitely* be entered
995
+ t.source !== s ||
996
+ // we know that the domain can't lie within the source
997
+ // if it's different than the source then it's outside of it and it means that the target has to be entered as well
998
+ t.source !== domain ||
999
+ // reentering transitions always enter the target, even if it's the source itself
1000
+ t.reenter)) {
1001
+ statesToEnter.add(s);
1002
+ statesForDefaultEntry.add(s);
1003
+ }
984
1004
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
985
1005
  }
986
- const ancestor = getTransitionDomain(t, historyValue);
987
1006
  const targetStates = getEffectiveTargetStates(t, historyValue);
988
1007
  for (const s of targetStates) {
989
- addAncestorStatesToEnter(s, ancestor, statesToEnter, historyValue, statesForDefaultEntry);
1008
+ addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
990
1009
  }
991
1010
  }
992
1011
  }
@@ -995,37 +1014,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
995
1014
  if (historyValue[stateNode.id]) {
996
1015
  const historyStateNodes = historyValue[stateNode.id];
997
1016
  for (const s of historyStateNodes) {
1017
+ statesToEnter.add(s);
998
1018
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
999
1019
  }
1000
1020
  for (const s of historyStateNodes) {
1001
1021
  addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1002
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1003
- statesForDefaultEntry.add(stateForDefaultEntry);
1004
- }
1005
1022
  }
1006
1023
  } else {
1007
- const targets = resolveHistoryTarget(stateNode);
1008
- for (const s of targets) {
1024
+ const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
1025
+ for (const s of historyDefaultTransition.target) {
1026
+ statesToEnter.add(s);
1027
+ if (historyDefaultTransition === stateNode.parent?.initial) {
1028
+ statesForDefaultEntry.add(stateNode.parent);
1029
+ }
1009
1030
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1010
1031
  }
1011
- for (const s of targets) {
1032
+ for (const s of historyDefaultTransition.target) {
1012
1033
  addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1013
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1014
- statesForDefaultEntry.add(stateForDefaultEntry);
1015
- }
1016
1034
  }
1017
1035
  }
1018
1036
  } else {
1019
- statesToEnter.add(stateNode);
1020
1037
  if (stateNode.type === 'compound') {
1021
- statesForDefaultEntry.add(stateNode);
1022
1038
  const [initialState] = stateNode.initial.target;
1039
+ if (!isHistoryNode(initialState)) {
1040
+ statesToEnter.add(initialState);
1041
+ statesForDefaultEntry.add(initialState);
1042
+ }
1023
1043
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1024
1044
  addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1025
1045
  } else {
1026
1046
  if (stateNode.type === 'parallel') {
1027
1047
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
1028
1048
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1049
+ if (!isHistoryNode(child)) {
1050
+ statesToEnter.add(child);
1051
+ statesForDefaultEntry.add(child);
1052
+ }
1029
1053
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1030
1054
  }
1031
1055
  }
@@ -1040,6 +1064,7 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1040
1064
  if (anc.type === 'parallel') {
1041
1065
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1042
1066
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1067
+ statesToEnter.add(child);
1043
1068
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1044
1069
  }
1045
1070
  }
@@ -1094,31 +1119,24 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1094
1119
  context: intermediateState.context,
1095
1120
  event,
1096
1121
  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
1122
+ system: actorCtx?.system
1109
1123
  };
1124
+ const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
1125
+ context: intermediateState.context,
1126
+ event
1127
+ }) : action.params : undefined;
1110
1128
  if (!('resolve' in resolvedAction)) {
1111
1129
  if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1112
- resolvedAction(actionArgs);
1130
+ resolvedAction(actionArgs, actionParams);
1113
1131
  } else {
1114
1132
  actorCtx?.defer(() => {
1115
- resolvedAction(actionArgs);
1133
+ resolvedAction(actionArgs, actionParams);
1116
1134
  });
1117
1135
  }
1118
1136
  continue;
1119
1137
  }
1120
1138
  const builtinAction = resolvedAction;
1121
- const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
1139
+ const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, actionParams, resolvedAction,
1122
1140
  // this holds all params
1123
1141
  extra);
1124
1142
  intermediateState = nextState;
@@ -1158,7 +1176,9 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1158
1176
 
1159
1177
  // Handle stop event
1160
1178
  if (event.type === interpreter.XSTATE_STOP) {
1161
- nextState = stopChildren(nextState, event, actorCtx);
1179
+ nextState = cloneState(stopChildren(nextState, event, actorCtx), {
1180
+ status: 'stopped'
1181
+ });
1162
1182
  states.push(nextState);
1163
1183
  return {
1164
1184
  state: nextState,
@@ -1210,7 +1230,7 @@ function selectEventlessTransitions(nextState, event) {
1210
1230
  const enabledTransitionSet = new Set();
1211
1231
  const atomicStates = nextState.configuration.filter(isAtomicStateNode);
1212
1232
  for (const stateNode of atomicStates) {
1213
- loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, null))) {
1233
+ loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
1214
1234
  if (!s.always) {
1215
1235
  continue;
1216
1236
  }
@@ -1421,17 +1441,17 @@ function getPersistedState(state) {
1421
1441
  throw new Error('An inline child actor cannot be persisted.');
1422
1442
  }
1423
1443
  childrenJson[id] = {
1424
- state: child.getPersistedState?.(),
1425
- src: child.src
1444
+ state: child.getPersistedState(),
1445
+ src: child.src,
1446
+ systemId: child._systemId
1426
1447
  };
1427
1448
  }
1428
- return {
1449
+ const persisted = {
1429
1450
  ...jsonValues,
1430
- // TODO: this makes `PersistedMachineState`'s type kind of a lie
1431
- // it doesn't truly use `TContext` but rather some kind of a derived form of it
1432
1451
  context: persistContext(context),
1433
1452
  children: childrenJson
1434
1453
  };
1454
+ return persisted;
1435
1455
  }
1436
1456
  function persistContext(contextPart) {
1437
1457
  let copy;
@@ -1460,7 +1480,7 @@ function persistContext(contextPart) {
1460
1480
  return copy ?? contextPart;
1461
1481
  }
1462
1482
 
1463
- function resolveRaise(_, state, args, {
1483
+ function resolveRaise(_, state, args, actionParams, {
1464
1484
  event: eventOrExpr,
1465
1485
  id,
1466
1486
  delay
@@ -1471,13 +1491,13 @@ function resolveRaise(_, state, args, {
1471
1491
  if (typeof eventOrExpr === 'string') {
1472
1492
  throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
1473
1493
  }
1474
- const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
1494
+ const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
1475
1495
  let resolvedDelay;
1476
1496
  if (typeof delay === 'string') {
1477
1497
  const configDelay = delaysMap && delaysMap[delay];
1478
- resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
1498
+ resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
1479
1499
  } else {
1480
- resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1500
+ resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
1481
1501
  }
1482
1502
  if (typeof resolvedDelay !== 'number') {
1483
1503
  internalQueue.push(resolvedEvent);
@@ -1501,7 +1521,7 @@ function executeRaise(actorContext, params) {
1501
1521
  * @param eventType The event to raise.
1502
1522
  */
1503
1523
  function raise(eventOrExpr, options) {
1504
- function raise(_) {
1524
+ function raise(args, params) {
1505
1525
  {
1506
1526
  throw new Error(`This isn't supposed to be called`);
1507
1527
  }
@@ -1541,6 +1561,7 @@ exports.or = or;
1541
1561
  exports.raise = raise;
1542
1562
  exports.resolveActionsAndContext = resolveActionsAndContext;
1543
1563
  exports.resolveStateValue = resolveStateValue;
1564
+ exports.spawn = spawn;
1544
1565
  exports.stateIn = stateIn;
1545
1566
  exports.stop = stop;
1546
1567
  exports.transitionNode = transitionNode;