xstate 5.0.0-beta.34 → 5.0.0-beta.36

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 (41) hide show
  1. package/README.md +1 -1
  2. package/actions/dist/xstate-actions.cjs.js +3 -3
  3. package/actions/dist/xstate-actions.development.cjs.js +3 -3
  4. package/actions/dist/xstate-actions.development.esm.js +3 -3
  5. package/actions/dist/xstate-actions.esm.js +3 -3
  6. package/actions/dist/xstate-actions.umd.min.js +1 -1
  7. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  8. package/actors/dist/xstate-actors.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  10. package/actors/dist/xstate-actors.development.esm.js +1 -1
  11. package/actors/dist/xstate-actors.esm.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js +1 -1
  13. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  14. package/dist/declarations/src/State.d.ts +0 -1
  15. package/dist/declarations/src/interpreter.d.ts +2 -0
  16. package/dist/declarations/src/stateUtils.d.ts +8 -7
  17. package/dist/declarations/src/types.d.ts +3 -6
  18. package/dist/{interpreter-dee56dc8.development.esm.js → interpreter-5c4e6634.development.esm.js} +59 -57
  19. package/dist/{interpreter-1301970f.cjs.js → interpreter-69605bf0.cjs.js} +59 -57
  20. package/dist/{interpreter-70ed62f2.development.cjs.js → interpreter-d3567419.development.cjs.js} +59 -57
  21. package/dist/{interpreter-83f7f2d4.esm.js → interpreter-de5217bc.esm.js} +59 -57
  22. package/dist/{raise-38b707c0.development.cjs.js → raise-106ea558.development.cjs.js} +160 -160
  23. package/dist/{raise-05f8b2a6.development.esm.js → raise-5b7ad3b7.development.esm.js} +160 -160
  24. package/dist/{raise-1dd65455.cjs.js → raise-c51b81a3.cjs.js} +157 -160
  25. package/dist/{raise-b5cfe1bb.esm.js → raise-ffe1014a.esm.js} +157 -160
  26. package/dist/{send-0b5eda0c.esm.js → send-0a7aa74e.esm.js} +5 -3
  27. package/dist/{send-3764c866.development.cjs.js → send-25e70bd4.development.cjs.js} +5 -3
  28. package/dist/{send-fe94de2b.cjs.js → send-778692de.cjs.js} +5 -3
  29. package/dist/{send-9526366e.development.esm.js → send-e93554d6.development.esm.js} +5 -3
  30. package/dist/xstate.cjs.js +32 -13
  31. package/dist/xstate.development.cjs.js +32 -13
  32. package/dist/xstate.development.esm.js +35 -16
  33. package/dist/xstate.esm.js +35 -16
  34. package/dist/xstate.umd.min.js +1 -1
  35. package/dist/xstate.umd.min.js.map +1 -1
  36. package/guards/dist/xstate-guards.cjs.js +2 -2
  37. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  38. package/guards/dist/xstate-guards.development.esm.js +2 -2
  39. package/guards/dist/xstate-guards.esm.js +2 -2
  40. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  41. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as isArray, w as createAfterEvent, x as flatten, e as matchesState } from './interpreter-83f7f2d4.esm.js';
1
+ import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-de5217bc.esm.js';
2
2
 
3
3
  const cache = new WeakMap();
4
4
  function memo(object, key, fn) {
@@ -277,20 +277,6 @@ function evaluateGuard(guard, context, event, state) {
277
277
  );
278
278
  }
279
279
 
280
- function getOutput(configuration, context, event, self) {
281
- const {
282
- machine
283
- } = configuration[0];
284
- const {
285
- root
286
- } = machine;
287
- if (!root.output) {
288
- return undefined;
289
- }
290
- const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
291
- const doneStateEvent = createDoneStateEvent(finalChildStateNode.id, finalChildStateNode.output ? resolveOutput(finalChildStateNode.output, context, event, self) : undefined);
292
- return resolveOutput(root.output, context, doneStateEvent, self);
293
- }
294
280
  const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
295
281
  function getChildren(stateNode) {
296
282
  return Object.values(stateNode.states).filter(sn => sn.type !== 'history');
@@ -315,7 +301,7 @@ function getConfiguration(stateNodes) {
315
301
  for (const s of configuration) {
316
302
  // if previously active, add existing child nodes
317
303
  if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
318
- getInitialStateNodes(s).forEach(sn => configurationSet.add(sn));
304
+ getInitialStateNodesWithTheirAncestors(s).forEach(sn => configurationSet.add(sn));
319
305
  } else {
320
306
  if (s.type === 'parallel') {
321
307
  for (const child of getChildren(s)) {
@@ -323,7 +309,8 @@ function getConfiguration(stateNodes) {
323
309
  continue;
324
310
  }
325
311
  if (!configurationSet.has(child)) {
326
- for (const initialStateNode of getInitialStateNodes(child)) {
312
+ const initialStates = getInitialStateNodesWithTheirAncestors(child);
313
+ for (const initialStateNode of initialStates) {
327
314
  configurationSet.add(initialStateNode);
328
315
  }
329
316
  }
@@ -383,14 +370,14 @@ function getStateValue(rootNode, configuration) {
383
370
  const config = getConfiguration(configuration);
384
371
  return getValueFromAdj(rootNode, getAdjList(config));
385
372
  }
386
- function isInFinalState(configuration, stateNode = configuration[0].machine.root) {
373
+ function isInFinalState(configuration, stateNode) {
387
374
  if (stateNode.type === 'compound') {
388
- return getChildren(stateNode).some(s => s.type === 'final' && configuration.includes(s));
375
+ return getChildren(stateNode).some(s => s.type === 'final' && configuration.has(s));
389
376
  }
390
377
  if (stateNode.type === 'parallel') {
391
378
  return getChildren(stateNode).every(sn => isInFinalState(configuration, sn));
392
379
  }
393
- return false;
380
+ return stateNode.type === 'final';
394
381
  }
395
382
  const isStateId = str => str[0] === STATE_IDENTIFIER;
396
383
  function getCandidates(stateNode, receivedEventType) {
@@ -440,13 +427,7 @@ function getDelayedTransitions(stateNode) {
440
427
  stateNode.exit.push(cancel(eventType));
441
428
  return eventType;
442
429
  };
443
- const delayedTransitions = isArray(afterConfig) ? afterConfig.map((transition, i) => {
444
- const eventType = mutateEntryExit(transition.delay, i);
445
- return {
446
- ...transition,
447
- event: eventType
448
- };
449
- }) : Object.keys(afterConfig).flatMap((delay, i) => {
430
+ const delayedTransitions = Object.keys(afterConfig).flatMap((delay, i) => {
450
431
  const configTransition = afterConfig[delay];
451
432
  const resolvedTransition = typeof configTransition === 'string' ? {
452
433
  target: configTransition
@@ -529,43 +510,23 @@ function formatTransitions(stateNode) {
529
510
  return transitions;
530
511
  }
531
512
  function formatInitialTransition(stateNode, _target) {
532
- if (typeof _target === 'string' || isArray(_target)) {
533
- const targets = toArray(_target).map(t => {
534
- // Resolve state string keys (which represent children)
535
- // to their state node
536
- const descStateNode = typeof t === 'string' ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
537
- if (!descStateNode) {
538
- throw new Error(`Initial state node "${t}" not found on parent state node #${stateNode.id}`);
539
- }
540
- if (!isDescendant(descStateNode, stateNode)) {
541
- throw new Error(`Invalid initial target: state node #${descStateNode.id} is not a descendant of #${stateNode.id}`);
542
- }
543
- return descStateNode;
544
- });
545
- const resolvedTarget = resolveTarget(stateNode, targets);
546
- const transition = {
547
- source: stateNode,
548
- actions: [],
549
- eventType: null,
550
- reenter: false,
551
- target: resolvedTarget,
552
- toJSON: () => ({
553
- ...transition,
554
- source: `#${stateNode.id}`,
555
- target: resolvedTarget ? resolvedTarget.map(t => `#${t.id}`) : undefined
556
- })
557
- };
558
- return transition;
513
+ const resolvedTarget = typeof _target === 'string' ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : undefined;
514
+ if (!resolvedTarget && _target) {
515
+ throw new Error(`Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
559
516
  }
560
- return formatTransition(stateNode, '__INITIAL__', {
561
- target: toArray(_target.target).map(t => {
562
- if (typeof t === 'string') {
563
- return isStateId(t) ? t : `${STATE_DELIMITER}${t}`;
564
- }
565
- return t;
566
- }),
567
- actions: _target.actions
568
- });
517
+ const transition = {
518
+ source: stateNode,
519
+ actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
520
+ eventType: null,
521
+ reenter: false,
522
+ target: resolvedTarget ? [resolvedTarget] : [],
523
+ toJSON: () => ({
524
+ ...transition,
525
+ source: `#${stateNode.id}`,
526
+ target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
527
+ })
528
+ };
529
+ return transition;
569
530
  }
570
531
  function resolveTarget(stateNode, targets) {
571
532
  if (targets === undefined) {
@@ -608,6 +569,15 @@ function resolveHistoryTarget(stateNode) {
608
569
  function isHistoryNode(stateNode) {
609
570
  return stateNode.type === 'history';
610
571
  }
572
+ function getInitialStateNodesWithTheirAncestors(stateNode) {
573
+ const states = getInitialStateNodes(stateNode);
574
+ for (const initialState of states) {
575
+ for (const ancestor of getProperAncestors(initialState, stateNode)) {
576
+ states.add(ancestor);
577
+ }
578
+ }
579
+ return states;
580
+ }
611
581
  function getInitialStateNodes(stateNode) {
612
582
  const set = new Set();
613
583
  function iter(descStateNode) {
@@ -616,12 +586,7 @@ function getInitialStateNodes(stateNode) {
616
586
  }
617
587
  set.add(descStateNode);
618
588
  if (descStateNode.type === 'compound') {
619
- for (const targetStateNode of descStateNode.initial.target) {
620
- for (const a of getProperAncestors(targetStateNode, stateNode)) {
621
- set.add(a);
622
- }
623
- iter(targetStateNode);
624
- }
589
+ iter(descStateNode.initial.target[0]);
625
590
  } else if (descStateNode.type === 'parallel') {
626
591
  for (const child of getChildren(descStateNode)) {
627
592
  iter(child);
@@ -629,7 +594,7 @@ function getInitialStateNodes(stateNode) {
629
594
  }
630
595
  }
631
596
  iter(stateNode);
632
- return [...set];
597
+ return set;
633
598
  }
634
599
  /**
635
600
  * Returns the child state node from its relative `stateKey`, or throws.
@@ -863,6 +828,17 @@ function computeExitSet(transitions, configuration, historyValue) {
863
828
  }
864
829
  return [...statesToExit];
865
830
  }
831
+ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
832
+ if (previousConfiguration.length !== nextConfigurationSet.size) {
833
+ return false;
834
+ }
835
+ for (const node of previousConfiguration) {
836
+ if (!nextConfigurationSet.has(node)) {
837
+ return false;
838
+ }
839
+ }
840
+ return true;
841
+ }
866
842
 
867
843
  /**
868
844
  * https://www.w3.org/TR/scxml/#microstepProcedure
@@ -872,56 +848,36 @@ function computeExitSet(transitions, configuration, historyValue) {
872
848
  * @param currentState
873
849
  * @param mutConfiguration
874
850
  */
875
-
876
- function microstep(transitions, currentState, actorCtx, event, isInitial) {
877
- const mutConfiguration = new Set(currentState.configuration);
851
+ function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
878
852
  if (!transitions.length) {
879
853
  return currentState;
880
854
  }
881
- const microstate = microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial);
882
- return cloneState(microstate, {
883
- value: {} // TODO: make optional
884
- });
885
- }
886
-
887
- function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
888
- const historyValue = {
889
- ...currentState.historyValue
890
- };
855
+ const mutConfiguration = new Set(currentState.configuration);
856
+ let historyValue = currentState.historyValue;
891
857
  const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
892
- const internalQueue = [...currentState._internalQueue];
893
- // TODO: this `cloneState` is really just a hack to prevent infinite loops
894
- // we need to take another look at how internal queue is managed
895
- let nextState = cloneState(currentState, {
896
- _internalQueue: []
897
- });
858
+ let nextState = currentState;
898
859
 
899
860
  // Exit states
900
861
  if (!isInitial) {
901
- nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
862
+ [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
902
863
  }
903
864
 
904
865
  // Execute transition content
905
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
866
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
906
867
 
907
868
  // Enter states
908
869
  nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
909
870
  const nextConfiguration = [...mutConfiguration];
910
- const done = isInFinalState(nextConfiguration);
911
- if (done) {
912
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
871
+ if (nextState.status === 'done') {
872
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
913
873
  }
914
874
  try {
915
- const output = done ? getOutput(nextConfiguration, nextState.context, event, actorCtx.self) : undefined;
916
- internalQueue.push(...nextState._internalQueue);
917
- return cloneState(currentState, {
875
+ if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
876
+ return nextState;
877
+ }
878
+ return cloneState(nextState, {
918
879
  configuration: nextConfiguration,
919
- historyValue,
920
- _internalQueue: internalQueue,
921
- context: nextState.context,
922
- status: done ? 'done' : currentState.status,
923
- output,
924
- children: nextState.children
880
+ historyValue
925
881
  });
926
882
  } catch (e) {
927
883
  // TODO: Refactor this once proper error handling is implemented.
@@ -929,6 +885,13 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
929
885
  throw e;
930
886
  }
931
887
  }
888
+ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
889
+ if (!rootNode.output) {
890
+ return;
891
+ }
892
+ const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
893
+ return resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
894
+ }
932
895
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
933
896
  let nextState = currentState;
934
897
  const statesToEnter = new Set();
@@ -939,6 +902,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
939
902
  if (isInitial) {
940
903
  statesForDefaultEntry.add(currentState.machine.root);
941
904
  }
905
+ const completedNodes = new Set();
942
906
  for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
943
907
  mutConfiguration.add(stateNodeToEnter);
944
908
  const actions = [];
@@ -949,26 +913,34 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
949
913
  actions.push(invoke(invokeDef));
950
914
  }
951
915
  if (statesForDefaultEntry.has(stateNodeToEnter)) {
952
- for (const stateNode of statesForDefaultEntry) {
953
- const initialActions = stateNode.initial.actions;
954
- actions.push(...initialActions);
955
- }
916
+ const initialActions = stateNodeToEnter.initial.actions;
917
+ actions.push(...initialActions);
956
918
  }
957
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
919
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
958
920
  if (stateNodeToEnter.type === 'final') {
959
921
  const parent = stateNodeToEnter.parent;
960
- if (!parent.parent) {
922
+ if (completedNodes.has(parent)) {
961
923
  continue;
962
924
  }
963
- internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
964
- if (parent.parent) {
965
- const grandparent = parent.parent;
966
- if (grandparent.type === 'parallel') {
967
- if (getChildren(grandparent).every(parentNode => isInFinalState([...mutConfiguration], parentNode))) {
968
- internalQueue.push(createDoneStateEvent(grandparent.id));
969
- }
925
+ completedNodes.add(parent);
926
+ let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
927
+ let ancestorMarker = parent?.parent;
928
+ if (ancestorMarker) {
929
+ internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
930
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
931
+ completedNodes.add(ancestorMarker);
932
+ internalQueue.push(createDoneStateEvent(ancestorMarker.id));
933
+ rootCompletionNode = ancestorMarker;
934
+ ancestorMarker = ancestorMarker.parent;
970
935
  }
971
936
  }
937
+ if (ancestorMarker) {
938
+ continue;
939
+ }
940
+ nextState = cloneState(nextState, {
941
+ status: 'done',
942
+ output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
943
+ });
972
944
  }
973
945
  }
974
946
  return nextState;
@@ -1014,13 +986,9 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1014
986
  statesToEnter.add(stateNode);
1015
987
  if (stateNode.type === 'compound') {
1016
988
  statesForDefaultEntry.add(stateNode);
1017
- const initialStates = stateNode.initial.target;
1018
- for (const initialState of initialStates) {
1019
- addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1020
- }
1021
- for (const initialState of initialStates) {
1022
- addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1023
- }
989
+ const [initialState] = stateNode.initial.target;
990
+ addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
991
+ addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1024
992
  } else {
1025
993
  if (stateNode.type === 'parallel') {
1026
994
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
@@ -1045,10 +1013,11 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1045
1013
  }
1046
1014
  }
1047
1015
  }
1048
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
1016
+ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1049
1017
  let nextState = currentState;
1050
1018
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1051
1019
  statesToExit.sort((a, b) => b.order - a.order);
1020
+ let changedHistory;
1052
1021
 
1053
1022
  // From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
1054
1023
  for (const exitStateNode of statesToExit) {
@@ -1061,14 +1030,17 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1061
1030
  return sn.parent === exitStateNode;
1062
1031
  };
1063
1032
  }
1064
- historyValue[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1033
+ changedHistory ??= {
1034
+ ...historyValue
1035
+ };
1036
+ changedHistory[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1065
1037
  }
1066
1038
  }
1067
1039
  for (const s of statesToExit) {
1068
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))]);
1040
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1069
1041
  mutConfiguration.delete(s);
1070
1042
  }
1071
- return nextState;
1043
+ return [nextState, changedHistory || historyValue];
1072
1044
  }
1073
1045
  function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1074
1046
  const {
@@ -1133,9 +1105,10 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1133
1105
  }
1134
1106
  return intermediateState;
1135
1107
  }
1136
- function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
1108
+ function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1137
1109
  const retries = deferredActorIds ? [] : undefined;
1138
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, deferredActorIds && {
1110
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1111
+ internalQueue,
1139
1112
  deferredActorIds
1140
1113
  }, retries);
1141
1114
  retries?.forEach(([builtinAction, params]) => {
@@ -1143,13 +1116,13 @@ function resolveActionsAndContext(currentState, event, actorCtx, actions, deferr
1143
1116
  });
1144
1117
  return nextState;
1145
1118
  }
1146
- function macrostep(state, event, actorCtx) {
1119
+ function macrostep(state, event, actorCtx, internalQueue = []) {
1147
1120
  let nextState = state;
1148
1121
  const states = [];
1149
1122
 
1150
1123
  // Handle stop event
1151
1124
  if (event.type === XSTATE_STOP) {
1152
- nextState = stopStep(event, nextState, actorCtx);
1125
+ nextState = stopChildren(nextState, event, actorCtx);
1153
1126
  states.push(nextState);
1154
1127
  return {
1155
1128
  state: nextState,
@@ -1162,44 +1135,37 @@ function macrostep(state, event, actorCtx) {
1162
1135
  // Determine the next state based on the next microstep
1163
1136
  if (nextEvent.type !== XSTATE_INIT) {
1164
1137
  const transitions = selectTransitions(nextEvent, nextState);
1165
- nextState = microstep(transitions, state, actorCtx, nextEvent, false);
1138
+ nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1166
1139
  states.push(nextState);
1167
1140
  }
1141
+ let shouldSelectEventlessTransitions = true;
1168
1142
  while (nextState.status === 'active') {
1169
- let enabledTransitions = selectEventlessTransitions(nextState, nextEvent);
1143
+ let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextState, nextEvent) : [];
1144
+
1145
+ // eventless transitions should always be selected after selecting *regular* transitions
1146
+ // by assigning `undefined` to `previousState` we ensure that `shouldSelectEventlessTransitions` gets always computed to true in such a case
1147
+ const previousState = enabledTransitions.length ? nextState : undefined;
1170
1148
  if (!enabledTransitions.length) {
1171
- if (!nextState._internalQueue.length) {
1149
+ if (!internalQueue.length) {
1172
1150
  break;
1173
- } else {
1174
- nextEvent = nextState._internalQueue[0];
1175
- const transitions = selectTransitions(nextEvent, nextState);
1176
- nextState = microstep(transitions, nextState, actorCtx, nextEvent, false);
1177
- nextState._internalQueue.shift();
1178
- states.push(nextState);
1179
1151
  }
1180
- } else {
1181
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false);
1182
- states.push(nextState);
1152
+ nextEvent = internalQueue.shift();
1153
+ enabledTransitions = selectTransitions(nextEvent, nextState);
1183
1154
  }
1155
+ nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1156
+ shouldSelectEventlessTransitions = nextState !== previousState;
1157
+ states.push(nextState);
1184
1158
  }
1185
1159
  if (nextState.status !== 'active') {
1186
- // Perform the stop step to ensure that child actors are stopped
1187
- stopStep(nextEvent, nextState, actorCtx);
1160
+ stopChildren(nextState, nextEvent, actorCtx);
1188
1161
  }
1189
1162
  return {
1190
1163
  state: nextState,
1191
1164
  microstates: states
1192
1165
  };
1193
1166
  }
1194
- function stopStep(event, nextState, actorCtx) {
1195
- const actions = [];
1196
- for (const stateNode of nextState.configuration.sort((a, b) => b.order - a.order)) {
1197
- actions.push(...stateNode.exit);
1198
- }
1199
- for (const child of Object.values(nextState.children)) {
1200
- actions.push(stop(child));
1201
- }
1202
- return resolveActionsAndContext(nextState, event, actorCtx, actions);
1167
+ function stopChildren(nextState, event, actorCtx) {
1168
+ return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1203
1169
  }
1204
1170
  function selectTransitions(event, nextState) {
1205
1171
  return nextState.machine.getTransitionData(nextState, event);
@@ -1305,11 +1271,9 @@ class State {
1305
1271
  this.error = void 0;
1306
1272
  this.context = void 0;
1307
1273
  this.historyValue = {};
1308
- this._internalQueue = void 0;
1309
1274
  this.configuration = void 0;
1310
1275
  this.children = void 0;
1311
1276
  this.context = config.context;
1312
- this._internalQueue = config._internalQueue ?? [];
1313
1277
  this.historyValue = config.historyValue || {};
1314
1278
  this.matches = this.matches.bind(this);
1315
1279
  this.toStrings = this.toStrings.bind(this);
@@ -1408,6 +1372,7 @@ function getPersistedState(state) {
1408
1372
  tags,
1409
1373
  machine,
1410
1374
  children,
1375
+ context,
1411
1376
  ...jsonValues
1412
1377
  } = state;
1413
1378
  const childrenJson = {};
@@ -1420,14 +1385,45 @@ function getPersistedState(state) {
1420
1385
  }
1421
1386
  return {
1422
1387
  ...jsonValues,
1388
+ // TODO: this makes `PersistedMachineState`'s type kind of a lie
1389
+ // it doesn't truly use `TContext` but rather some kind of a derived form of it
1390
+ context: persistContext(context),
1423
1391
  children: childrenJson
1424
1392
  };
1425
1393
  }
1394
+ function persistContext(contextPart) {
1395
+ let copy;
1396
+ for (const key in contextPart) {
1397
+ const value = contextPart[key];
1398
+ if (value && typeof value === 'object') {
1399
+ if ('sessionId' in value && 'send' in value && 'ref' in value) {
1400
+ copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
1401
+ ...contextPart
1402
+ };
1403
+ copy[key] = {
1404
+ xstate$$type: $$ACTOR_TYPE,
1405
+ id: value.id
1406
+ };
1407
+ } else {
1408
+ const result = persistContext(value);
1409
+ if (result !== value) {
1410
+ copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
1411
+ ...contextPart
1412
+ };
1413
+ copy[key] = result;
1414
+ }
1415
+ }
1416
+ }
1417
+ }
1418
+ return copy ?? contextPart;
1419
+ }
1426
1420
 
1427
1421
  function resolveRaise(_, state, args, {
1428
1422
  event: eventOrExpr,
1429
1423
  id,
1430
1424
  delay
1425
+ }, {
1426
+ internalQueue
1431
1427
  }) {
1432
1428
  const delaysMap = state.machine.implementations.delays;
1433
1429
  if (typeof eventOrExpr === 'string') {
@@ -1441,9 +1437,10 @@ function resolveRaise(_, state, args, {
1441
1437
  } else {
1442
1438
  resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1443
1439
  }
1444
- return [typeof resolvedDelay !== 'number' ? cloneState(state, {
1445
- _internalQueue: state._internalQueue.concat(resolvedEvent)
1446
- }) : state, {
1440
+ if (typeof resolvedDelay !== 'number') {
1441
+ internalQueue.push(resolvedEvent);
1442
+ }
1443
+ return [state, {
1447
1444
  event: resolvedEvent,
1448
1445
  id,
1449
1446
  delay: resolvedDelay
@@ -1473,4 +1470,4 @@ function raise(eventOrExpr, options) {
1473
1470
  return raise;
1474
1471
  }
1475
1472
 
1476
- export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, isAtomicStateNode as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
1473
+ export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
@@ -1,5 +1,5 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-b5cfe1bb.esm.js';
2
- import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, y as XSTATE_ERROR } from './interpreter-83f7f2d4.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-ffe1014a.esm.js';
2
+ import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-de5217bc.esm.js';
3
3
 
4
4
  function createSpawner(actorContext, {
5
5
  machine,
@@ -25,6 +25,7 @@ function createSpawner(actorContext, {
25
25
  event,
26
26
  self: actorContext.self
27
27
  }) : input,
28
+ src,
28
29
  systemId
29
30
  });
30
31
  spawnedChildren[actorRef.id] = actorRef;
@@ -50,6 +51,7 @@ function createSpawner(actorContext, {
50
51
  id: options.id,
51
52
  parent: actorContext.self,
52
53
  input: options.input,
54
+ src: undefined,
53
55
  systemId
54
56
  });
55
57
  if (options.syncSnapshot) {
@@ -281,7 +283,7 @@ function resolveSendTo(actorContext, state, args, {
281
283
  // #_invokeid. If the target is the special term '#_invokeid', where invokeid is the invokeid of an SCXML session that the sending session has created by <invoke>, the Processor must add the event to the external queue of that session.
282
284
  targetActorRef = state.children[resolvedTarget.slice(2)];
283
285
  } else {
284
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
286
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
285
287
  }
286
288
  if (!targetActorRef) {
287
289
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-38b707c0.development.cjs.js');
4
- var interpreter = require('./interpreter-70ed62f2.development.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-106ea558.development.cjs.js');
4
+ var interpreter = require('./interpreter-d3567419.development.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -27,6 +27,7 @@ function createSpawner(actorContext, {
27
27
  event,
28
28
  self: actorContext.self
29
29
  }) : input,
30
+ src,
30
31
  systemId
31
32
  });
32
33
  spawnedChildren[actorRef.id] = actorRef;
@@ -52,6 +53,7 @@ function createSpawner(actorContext, {
52
53
  id: options.id,
53
54
  parent: actorContext.self,
54
55
  input: options.input,
56
+ src: undefined,
55
57
  systemId
56
58
  });
57
59
  if (options.syncSnapshot) {
@@ -295,7 +297,7 @@ function resolveSendTo(actorContext, state, args, {
295
297
  // #_invokeid. If the target is the special term '#_invokeid', where invokeid is the invokeid of an SCXML session that the sending session has created by <invoke>, the Processor must add the event to the external queue of that session.
296
298
  targetActorRef = state.children[resolvedTarget.slice(2)];
297
299
  } else {
298
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
300
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
299
301
  }
300
302
  if (!targetActorRef) {
301
303
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-1dd65455.cjs.js');
4
- var interpreter = require('./interpreter-1301970f.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-c51b81a3.cjs.js');
4
+ var interpreter = require('./interpreter-69605bf0.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -27,6 +27,7 @@ function createSpawner(actorContext, {
27
27
  event,
28
28
  self: actorContext.self
29
29
  }) : input,
30
+ src,
30
31
  systemId
31
32
  });
32
33
  spawnedChildren[actorRef.id] = actorRef;
@@ -52,6 +53,7 @@ function createSpawner(actorContext, {
52
53
  id: options.id,
53
54
  parent: actorContext.self,
54
55
  input: options.input,
56
+ src: undefined,
55
57
  systemId
56
58
  });
57
59
  if (options.syncSnapshot) {
@@ -283,7 +285,7 @@ function resolveSendTo(actorContext, state, args, {
283
285
  // #_invokeid. If the target is the special term '#_invokeid', where invokeid is the invokeid of an SCXML session that the sending session has created by <invoke>, the Processor must add the event to the external queue of that session.
284
286
  targetActorRef = state.children[resolvedTarget.slice(2)];
285
287
  } else {
286
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
288
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
287
289
  }
288
290
  if (!targetActorRef) {
289
291
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);