xstate 5.0.0-beta.35 → 5.0.0-beta.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/actions/dist/xstate-actions.cjs.js +3 -3
  2. package/actions/dist/xstate-actions.development.cjs.js +3 -3
  3. package/actions/dist/xstate-actions.development.esm.js +3 -3
  4. package/actions/dist/xstate-actions.esm.js +3 -3
  5. package/actions/dist/xstate-actions.umd.min.js +1 -1
  6. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  7. package/actors/dist/xstate-actors.cjs.js +1 -1
  8. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.esm.js +1 -1
  10. package/actors/dist/xstate-actors.esm.js +1 -1
  11. package/actors/dist/xstate-actors.umd.min.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  13. package/dist/declarations/src/State.d.ts +0 -1
  14. package/dist/declarations/src/stateUtils.d.ts +3 -3
  15. package/dist/declarations/src/typegenTypes.d.ts +2 -0
  16. package/dist/declarations/src/types.d.ts +1 -2
  17. package/dist/declarations/src/utils.d.ts +6 -6
  18. package/dist/declarations/src/waitFor.d.ts +1 -1
  19. package/dist/{interpreter-5c4e6634.development.esm.js → interpreter-1c52b23c.development.esm.js} +13 -23
  20. package/dist/{interpreter-de5217bc.esm.js → interpreter-8def682e.esm.js} +13 -23
  21. package/dist/{interpreter-69605bf0.cjs.js → interpreter-97aff8d2.cjs.js} +13 -23
  22. package/dist/{interpreter-d3567419.development.cjs.js → interpreter-e58ca48d.development.cjs.js} +13 -23
  23. package/dist/{raise-26e4d83c.development.cjs.js → raise-1fd59c65.development.cjs.js} +129 -102
  24. package/dist/{raise-511399cc.esm.js → raise-21c417c1.esm.js} +129 -102
  25. package/dist/{raise-0ff57677.cjs.js → raise-800296d7.cjs.js} +129 -102
  26. package/dist/{raise-cdcdf834.development.esm.js → raise-e342a840.development.esm.js} +129 -102
  27. package/dist/{send-19ffc568.cjs.js → send-4cc29786.cjs.js} +7 -4
  28. package/dist/{send-1de74f4d.development.esm.js → send-83ccc98b.development.esm.js} +7 -4
  29. package/dist/{send-211a2a94.esm.js → send-92854675.esm.js} +7 -4
  30. package/dist/{send-894c4b18.development.cjs.js → send-b309ef4e.development.cjs.js} +7 -4
  31. package/dist/xstate.cjs.js +11 -19
  32. package/dist/xstate.development.cjs.js +11 -19
  33. package/dist/xstate.development.esm.js +14 -22
  34. package/dist/xstate.esm.js +14 -22
  35. package/dist/xstate.umd.min.js +1 -1
  36. package/dist/xstate.umd.min.js.map +1 -1
  37. package/guards/dist/xstate-guards.cjs.js +2 -2
  38. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  39. package/guards/dist/xstate-guards.development.esm.js +2 -2
  40. package/guards/dist/xstate-guards.esm.js +2 -2
  41. package/guards/dist/xstate-guards.umd.min.js +1 -1
  42. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  43. 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, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-5c4e6634.development.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, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-1c52b23c.development.esm.js';
2
2
 
3
3
  const cache = new WeakMap();
4
4
  function memo(object, key, fn) {
@@ -50,14 +50,17 @@ function resolveInvoke(actorContext, state, actionArgs, {
50
50
  input,
51
51
  syncSnapshot
52
52
  }) {
53
- const referenced = resolveReferencedActor(state.machine.implementations.actors[src]);
53
+ const referenced = typeof src === 'string' ? resolveReferencedActor(state.machine, src) : {
54
+ src,
55
+ input: undefined
56
+ };
54
57
  let actorRef;
55
58
  if (referenced) {
56
59
  // TODO: inline `input: undefined` should win over the referenced one
57
60
  const configuredInput = input || referenced.input;
58
61
  actorRef = createActor(referenced.src, {
59
62
  id,
60
- src,
63
+ src: typeof src === 'string' ? src : undefined,
61
64
  parent: actorContext?.self,
62
65
  systemId,
63
66
  input: typeof configuredInput === 'function' ? configuredInput({
@@ -160,11 +163,16 @@ function executeStop(actorContext, actorRef) {
160
163
  if (!actorRef) {
161
164
  return;
162
165
  }
166
+ // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
167
+ // this can happen, for example, when the invoking state is being exited immediately by an always transition
163
168
  if (actorRef.status !== ActorStatus.Running) {
164
169
  actorContext.stopChild(actorRef);
165
170
  return;
166
171
  }
167
- // TODO: recheck why this one has to be deferred
172
+ // stopping a child enqueues a stop event in the child actor's mailbox
173
+ // we need for all of the already enqueued events to be processed before we stop the child
174
+ // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
175
+ // and we don't want to ignore those events
168
176
  actorContext.defer(() => {
169
177
  actorContext.stopChild(actorRef);
170
178
  });
@@ -191,7 +199,8 @@ function checkStateIn(state, _, {
191
199
  stateValue
192
200
  }) {
193
201
  if (typeof stateValue === 'string' && isStateId(stateValue)) {
194
- return state.configuration.some(sn => sn.id === stateValue.slice(1));
202
+ const target = state.machine.getStateNodeById(stateValue);
203
+ return state.configuration.some(sn => sn === target);
195
204
  }
196
205
  return state.matches(stateValue);
197
206
  }
@@ -303,6 +312,9 @@ function getChildren(stateNode) {
303
312
  }
304
313
  function getProperAncestors(stateNode, toStateNode) {
305
314
  const ancestors = [];
315
+ if (toStateNode === stateNode) {
316
+ return ancestors;
317
+ }
306
318
 
307
319
  // add all ancestors
308
320
  let m = stateNode.parent;
@@ -590,12 +602,14 @@ function resolveTarget(stateNode, targets) {
590
602
  }
591
603
  });
592
604
  }
593
- function resolveHistoryTarget(stateNode) {
605
+ function resolveHistoryDefaultTransition(stateNode) {
594
606
  const normalizedTarget = normalizeTarget(stateNode.config.target);
595
607
  if (!normalizedTarget) {
596
- return stateNode.parent.initial.target;
608
+ return stateNode.parent.initial;
597
609
  }
598
- return normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t);
610
+ return {
611
+ target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
612
+ };
599
613
  }
600
614
  function isHistoryNode(stateNode) {
601
615
  return stateNode.type === 'history';
@@ -822,9 +836,7 @@ function getEffectiveTargetStates(transition, historyValue) {
822
836
  targets.add(node);
823
837
  }
824
838
  } else {
825
- for (const node of getEffectiveTargetStates({
826
- target: resolveHistoryTarget(targetNode)
827
- }, historyValue)) {
839
+ for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
828
840
  targets.add(node);
829
841
  }
830
842
  }
@@ -837,9 +849,9 @@ function getEffectiveTargetStates(transition, historyValue) {
837
849
  function getTransitionDomain(transition, historyValue) {
838
850
  const targetStates = getEffectiveTargetStates(transition, historyValue);
839
851
  if (!targetStates) {
840
- return null;
852
+ return;
841
853
  }
842
- if (!transition.reenter && transition.source.type !== 'parallel' && targetStates.every(targetStateNode => isDescendant(targetStateNode, transition.source))) {
854
+ if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
843
855
  return transition.source;
844
856
  }
845
857
  const lcca = findLCCA(targetStates.concat(transition.source));
@@ -850,6 +862,9 @@ function computeExitSet(transitions, configuration, historyValue) {
850
862
  for (const t of transitions) {
851
863
  if (t.target?.length) {
852
864
  const domain = getTransitionDomain(t, historyValue);
865
+ if (t.reenter && t.source === domain) {
866
+ statesToExit.add(domain);
867
+ }
853
868
  for (const stateNode of configuration) {
854
869
  if (isDescendant(stateNode, domain)) {
855
870
  statesToExit.add(stateNode);
@@ -859,6 +874,17 @@ function computeExitSet(transitions, configuration, historyValue) {
859
874
  }
860
875
  return [...statesToExit];
861
876
  }
877
+ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
878
+ if (previousConfiguration.length !== nextConfigurationSet.size) {
879
+ return false;
880
+ }
881
+ for (const node of previousConfiguration) {
882
+ if (!nextConfigurationSet.has(node)) {
883
+ return false;
884
+ }
885
+ }
886
+ return true;
887
+ }
862
888
 
863
889
  /**
864
890
  * https://www.w3.org/TR/scxml/#microstepProcedure
@@ -868,50 +894,36 @@ function computeExitSet(transitions, configuration, historyValue) {
868
894
  * @param currentState
869
895
  * @param mutConfiguration
870
896
  */
871
-
872
- function microstep(transitions, currentState, actorCtx, event, isInitial) {
873
- const mutConfiguration = new Set(currentState.configuration);
897
+ function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
874
898
  if (!transitions.length) {
875
899
  return currentState;
876
900
  }
877
- const microstate = microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial);
878
- return cloneState(microstate, {
879
- value: {} // TODO: make optional
880
- });
881
- }
882
-
883
- function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
884
- const historyValue = {
885
- ...currentState.historyValue
886
- };
901
+ const mutConfiguration = new Set(currentState.configuration);
902
+ let historyValue = currentState.historyValue;
887
903
  const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
888
- const internalQueue = [...currentState._internalQueue];
889
- // TODO: this `cloneState` is really just a hack to prevent infinite loops
890
- // we need to take another look at how internal queue is managed
891
- let nextState = cloneState(currentState, {
892
- _internalQueue: []
893
- });
904
+ let nextState = currentState;
894
905
 
895
906
  // Exit states
896
907
  if (!isInitial) {
897
- nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
908
+ [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
898
909
  }
899
910
 
900
911
  // Execute transition content
901
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
912
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
902
913
 
903
914
  // Enter states
904
915
  nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
905
916
  const nextConfiguration = [...mutConfiguration];
906
917
  if (nextState.status === 'done') {
907
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
918
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
908
919
  }
909
920
  try {
910
- internalQueue.push(...nextState._internalQueue);
921
+ if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
922
+ return nextState;
923
+ }
911
924
  return cloneState(nextState, {
912
925
  configuration: nextConfiguration,
913
- historyValue,
914
- _internalQueue: internalQueue
926
+ historyValue
915
927
  });
916
928
  } catch (e) {
917
929
  // TODO: Refactor this once proper error handling is implemented.
@@ -929,6 +941,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
929
941
  function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
930
942
  let nextState = currentState;
931
943
  const statesToEnter = new Set();
944
+ // those are states that were directly targeted or indirectly targeted by the explicit target
945
+ // in other words, those are states for which initial actions should be executed
946
+ // when we target `#deep_child` initial actions of its ancestors shouldn't be executed
932
947
  const statesForDefaultEntry = new Set();
933
948
  computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
934
949
 
@@ -950,23 +965,19 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
950
965
  const initialActions = stateNodeToEnter.initial.actions;
951
966
  actions.push(...initialActions);
952
967
  }
953
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
968
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
954
969
  if (stateNodeToEnter.type === 'final') {
955
970
  const parent = stateNodeToEnter.parent;
956
- if (completedNodes.has(parent)) {
957
- continue;
958
- }
959
- completedNodes.add(parent);
960
- let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
961
- let ancestorMarker = parent?.parent;
962
- if (ancestorMarker) {
971
+ let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
972
+ let rootCompletionNode = ancestorMarker || stateNodeToEnter;
973
+ if (parent?.type === 'compound') {
963
974
  internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
964
- while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
965
- completedNodes.add(ancestorMarker);
966
- internalQueue.push(createDoneStateEvent(ancestorMarker.id));
967
- rootCompletionNode = ancestorMarker;
968
- ancestorMarker = ancestorMarker.parent;
969
- }
975
+ }
976
+ while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
977
+ completedNodes.add(ancestorMarker);
978
+ internalQueue.push(createDoneStateEvent(ancestorMarker.id));
979
+ rootCompletionNode = ancestorMarker;
980
+ ancestorMarker = ancestorMarker.parent;
970
981
  }
971
982
  if (ancestorMarker) {
972
983
  continue;
@@ -981,13 +992,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
981
992
  }
982
993
  function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
983
994
  for (const t of transitions) {
995
+ const domain = getTransitionDomain(t, historyValue);
984
996
  for (const s of t.target || []) {
997
+ if (!isHistoryNode(s) && (
998
+ // if the target is different than the source then it will *definitely* be entered
999
+ t.source !== s ||
1000
+ // we know that the domain can't lie within the source
1001
+ // 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
1002
+ t.source !== domain ||
1003
+ // reentering transitions always enter the target, even if it's the source itself
1004
+ t.reenter)) {
1005
+ statesToEnter.add(s);
1006
+ statesForDefaultEntry.add(s);
1007
+ }
985
1008
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
986
1009
  }
987
- const ancestor = getTransitionDomain(t, historyValue);
988
1010
  const targetStates = getEffectiveTargetStates(t, historyValue);
989
1011
  for (const s of targetStates) {
990
- addAncestorStatesToEnter(s, ancestor, statesToEnter, historyValue, statesForDefaultEntry);
1012
+ addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
991
1013
  }
992
1014
  }
993
1015
  }
@@ -996,37 +1018,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
996
1018
  if (historyValue[stateNode.id]) {
997
1019
  const historyStateNodes = historyValue[stateNode.id];
998
1020
  for (const s of historyStateNodes) {
1021
+ statesToEnter.add(s);
999
1022
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1000
1023
  }
1001
1024
  for (const s of historyStateNodes) {
1002
1025
  addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1003
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1004
- statesForDefaultEntry.add(stateForDefaultEntry);
1005
- }
1006
1026
  }
1007
1027
  } else {
1008
- const targets = resolveHistoryTarget(stateNode);
1009
- for (const s of targets) {
1028
+ const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
1029
+ for (const s of historyDefaultTransition.target) {
1030
+ statesToEnter.add(s);
1031
+ if (historyDefaultTransition === stateNode.parent?.initial) {
1032
+ statesForDefaultEntry.add(stateNode.parent);
1033
+ }
1010
1034
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1011
1035
  }
1012
- for (const s of targets) {
1036
+ for (const s of historyDefaultTransition.target) {
1013
1037
  addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1014
- for (const stateForDefaultEntry of statesForDefaultEntry) {
1015
- statesForDefaultEntry.add(stateForDefaultEntry);
1016
- }
1017
1038
  }
1018
1039
  }
1019
1040
  } else {
1020
- statesToEnter.add(stateNode);
1021
1041
  if (stateNode.type === 'compound') {
1022
- statesForDefaultEntry.add(stateNode);
1023
1042
  const [initialState] = stateNode.initial.target;
1043
+ if (!isHistoryNode(initialState)) {
1044
+ statesToEnter.add(initialState);
1045
+ statesForDefaultEntry.add(initialState);
1046
+ }
1024
1047
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1025
1048
  addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1026
1049
  } else {
1027
1050
  if (stateNode.type === 'parallel') {
1028
1051
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
1029
1052
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1053
+ if (!isHistoryNode(child)) {
1054
+ statesToEnter.add(child);
1055
+ statesForDefaultEntry.add(child);
1056
+ }
1030
1057
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1031
1058
  }
1032
1059
  }
@@ -1041,16 +1068,18 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1041
1068
  if (anc.type === 'parallel') {
1042
1069
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1043
1070
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
1071
+ statesToEnter.add(child);
1044
1072
  addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
1045
1073
  }
1046
1074
  }
1047
1075
  }
1048
1076
  }
1049
1077
  }
1050
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
1078
+ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1051
1079
  let nextState = currentState;
1052
1080
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1053
1081
  statesToExit.sort((a, b) => b.order - a.order);
1082
+ let changedHistory;
1054
1083
 
1055
1084
  // From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
1056
1085
  for (const exitStateNode of statesToExit) {
@@ -1063,14 +1092,17 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1063
1092
  return sn.parent === exitStateNode;
1064
1093
  };
1065
1094
  }
1066
- historyValue[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1095
+ changedHistory ??= {
1096
+ ...historyValue
1097
+ };
1098
+ changedHistory[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1067
1099
  }
1068
1100
  }
1069
1101
  for (const s of statesToExit) {
1070
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))]);
1102
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1071
1103
  mutConfiguration.delete(s);
1072
1104
  }
1073
- return nextState;
1105
+ return [nextState, changedHistory || historyValue];
1074
1106
  }
1075
1107
  function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1076
1108
  const {
@@ -1135,9 +1167,10 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1135
1167
  }
1136
1168
  return intermediateState;
1137
1169
  }
1138
- function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
1170
+ function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1139
1171
  const retries = deferredActorIds ? [] : undefined;
1140
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, deferredActorIds && {
1172
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1173
+ internalQueue,
1141
1174
  deferredActorIds
1142
1175
  }, retries);
1143
1176
  retries?.forEach(([builtinAction, params]) => {
@@ -1145,7 +1178,7 @@ function resolveActionsAndContext(currentState, event, actorCtx, actions, deferr
1145
1178
  });
1146
1179
  return nextState;
1147
1180
  }
1148
- function macrostep(state, event, actorCtx) {
1181
+ function macrostep(state, event, actorCtx, internalQueue = []) {
1149
1182
  if (event.type === WILDCARD) {
1150
1183
  throw new Error(`An event cannot have the wildcard type ('${WILDCARD}')`);
1151
1184
  }
@@ -1154,7 +1187,7 @@ function macrostep(state, event, actorCtx) {
1154
1187
 
1155
1188
  // Handle stop event
1156
1189
  if (event.type === XSTATE_STOP) {
1157
- nextState = stopStep(event, nextState, actorCtx);
1190
+ nextState = stopChildren(nextState, event, actorCtx);
1158
1191
  states.push(nextState);
1159
1192
  return {
1160
1193
  state: nextState,
@@ -1167,44 +1200,37 @@ function macrostep(state, event, actorCtx) {
1167
1200
  // Determine the next state based on the next microstep
1168
1201
  if (nextEvent.type !== XSTATE_INIT) {
1169
1202
  const transitions = selectTransitions(nextEvent, nextState);
1170
- nextState = microstep(transitions, state, actorCtx, nextEvent, false);
1203
+ nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1171
1204
  states.push(nextState);
1172
1205
  }
1206
+ let shouldSelectEventlessTransitions = true;
1173
1207
  while (nextState.status === 'active') {
1174
- let enabledTransitions = selectEventlessTransitions(nextState, nextEvent);
1208
+ let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextState, nextEvent) : [];
1209
+
1210
+ // eventless transitions should always be selected after selecting *regular* transitions
1211
+ // by assigning `undefined` to `previousState` we ensure that `shouldSelectEventlessTransitions` gets always computed to true in such a case
1212
+ const previousState = enabledTransitions.length ? nextState : undefined;
1175
1213
  if (!enabledTransitions.length) {
1176
- if (!nextState._internalQueue.length) {
1214
+ if (!internalQueue.length) {
1177
1215
  break;
1178
- } else {
1179
- nextEvent = nextState._internalQueue[0];
1180
- const transitions = selectTransitions(nextEvent, nextState);
1181
- nextState = microstep(transitions, nextState, actorCtx, nextEvent, false);
1182
- nextState._internalQueue.shift();
1183
- states.push(nextState);
1184
1216
  }
1185
- } else {
1186
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false);
1187
- states.push(nextState);
1217
+ nextEvent = internalQueue.shift();
1218
+ enabledTransitions = selectTransitions(nextEvent, nextState);
1188
1219
  }
1220
+ nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1221
+ shouldSelectEventlessTransitions = nextState !== previousState;
1222
+ states.push(nextState);
1189
1223
  }
1190
1224
  if (nextState.status !== 'active') {
1191
- // Perform the stop step to ensure that child actors are stopped
1192
- stopStep(nextEvent, nextState, actorCtx);
1225
+ stopChildren(nextState, nextEvent, actorCtx);
1193
1226
  }
1194
1227
  return {
1195
1228
  state: nextState,
1196
1229
  microstates: states
1197
1230
  };
1198
1231
  }
1199
- function stopStep(event, nextState, actorCtx) {
1200
- const actions = [];
1201
- for (const stateNode of nextState.configuration.sort((a, b) => b.order - a.order)) {
1202
- actions.push(...stateNode.exit);
1203
- }
1204
- for (const child of Object.values(nextState.children)) {
1205
- actions.push(stop(child));
1206
- }
1207
- return resolveActionsAndContext(nextState, event, actorCtx, actions);
1232
+ function stopChildren(nextState, event, actorCtx) {
1233
+ return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1208
1234
  }
1209
1235
  function selectTransitions(event, nextState) {
1210
1236
  return nextState.machine.getTransitionData(nextState, event);
@@ -1213,7 +1239,7 @@ function selectEventlessTransitions(nextState, event) {
1213
1239
  const enabledTransitionSet = new Set();
1214
1240
  const atomicStates = nextState.configuration.filter(isAtomicStateNode);
1215
1241
  for (const stateNode of atomicStates) {
1216
- loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, null))) {
1242
+ loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
1217
1243
  if (!s.always) {
1218
1244
  continue;
1219
1245
  }
@@ -1310,11 +1336,9 @@ class State {
1310
1336
  this.error = void 0;
1311
1337
  this.context = void 0;
1312
1338
  this.historyValue = {};
1313
- this._internalQueue = void 0;
1314
1339
  this.configuration = void 0;
1315
1340
  this.children = void 0;
1316
1341
  this.context = config.context;
1317
- this._internalQueue = config._internalQueue ?? [];
1318
1342
  this.historyValue = config.historyValue || {};
1319
1343
  this.matches = this.matches.bind(this);
1320
1344
  this.toStrings = this.toStrings.bind(this);
@@ -1469,6 +1493,8 @@ function resolveRaise(_, state, args, {
1469
1493
  event: eventOrExpr,
1470
1494
  id,
1471
1495
  delay
1496
+ }, {
1497
+ internalQueue
1472
1498
  }) {
1473
1499
  const delaysMap = state.machine.implementations.delays;
1474
1500
  if (typeof eventOrExpr === 'string') {
@@ -1482,9 +1508,10 @@ function resolveRaise(_, state, args, {
1482
1508
  } else {
1483
1509
  resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1484
1510
  }
1485
- return [typeof resolvedDelay !== 'number' ? cloneState(state, {
1486
- _internalQueue: state._internalQueue.concat(resolvedEvent)
1487
- }) : state, {
1511
+ if (typeof resolvedDelay !== 'number') {
1512
+ internalQueue.push(resolvedEvent);
1513
+ }
1514
+ return [state, {
1488
1515
  event: resolvedEvent,
1489
1516
  id,
1490
1517
  delay: resolvedDelay
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-0ff57677.cjs.js');
4
- var interpreter = require('./interpreter-69605bf0.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-800296d7.cjs.js');
4
+ var interpreter = require('./interpreter-97aff8d2.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorContext, {
12
12
  systemId
13
13
  } = options;
14
14
  if (typeof src === 'string') {
15
- const referenced = interpreter.resolveReferencedActor(machine.implementations.actors[src]);
15
+ const referenced = interpreter.resolveReferencedActor(machine, src);
16
16
  if (!referenced) {
17
17
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
18
18
  }
@@ -285,7 +285,7 @@ function resolveSendTo(actorContext, state, args, {
285
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.
286
286
  targetActorRef = state.children[resolvedTarget.slice(2)];
287
287
  } else {
288
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
288
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
289
289
  }
290
290
  if (!targetActorRef) {
291
291
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -310,6 +310,9 @@ function executeSendTo(actorContext, params) {
310
310
  actorContext.self.delaySend(params);
311
311
  return;
312
312
  }
313
+
314
+ // this forms an outgoing events queue
315
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
313
316
  actorContext.defer(() => {
314
317
  const {
315
318
  to,
@@ -1,5 +1,5 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-cdcdf834.development.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-5c4e6634.development.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-e342a840.development.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-1c52b23c.development.esm.js';
3
3
 
4
4
  function createSpawner(actorContext, {
5
5
  machine,
@@ -10,7 +10,7 @@ function createSpawner(actorContext, {
10
10
  systemId
11
11
  } = options;
12
12
  if (typeof src === 'string') {
13
- const referenced = resolveReferencedActor(machine.implementations.actors[src]);
13
+ const referenced = resolveReferencedActor(machine, src);
14
14
  if (!referenced) {
15
15
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
16
16
  }
@@ -295,7 +295,7 @@ function resolveSendTo(actorContext, state, args, {
295
295
  // #_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
296
  targetActorRef = state.children[resolvedTarget.slice(2)];
297
297
  } else {
298
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
298
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
299
299
  }
300
300
  if (!targetActorRef) {
301
301
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -320,6 +320,9 @@ function executeSendTo(actorContext, params) {
320
320
  actorContext.self.delaySend(params);
321
321
  return;
322
322
  }
323
+
324
+ // this forms an outgoing events queue
325
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
323
326
  actorContext.defer(() => {
324
327
  const {
325
328
  to,
@@ -1,5 +1,5 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-511399cc.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';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-21c417c1.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-8def682e.esm.js';
3
3
 
4
4
  function createSpawner(actorContext, {
5
5
  machine,
@@ -10,7 +10,7 @@ function createSpawner(actorContext, {
10
10
  systemId
11
11
  } = options;
12
12
  if (typeof src === 'string') {
13
- const referenced = resolveReferencedActor(machine.implementations.actors[src]);
13
+ const referenced = resolveReferencedActor(machine, src);
14
14
  if (!referenced) {
15
15
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
16
16
  }
@@ -283,7 +283,7 @@ function resolveSendTo(actorContext, state, args, {
283
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.
284
284
  targetActorRef = state.children[resolvedTarget.slice(2)];
285
285
  } else {
286
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
286
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
287
287
  }
288
288
  if (!targetActorRef) {
289
289
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -308,6 +308,9 @@ function executeSendTo(actorContext, params) {
308
308
  actorContext.self.delaySend(params);
309
309
  return;
310
310
  }
311
+
312
+ // this forms an outgoing events queue
313
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
311
314
  actorContext.defer(() => {
312
315
  const {
313
316
  to,
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-26e4d83c.development.cjs.js');
4
- var interpreter = require('./interpreter-d3567419.development.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-1fd59c65.development.cjs.js');
4
+ var interpreter = require('./interpreter-e58ca48d.development.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
7
7
  machine,
@@ -12,7 +12,7 @@ function createSpawner(actorContext, {
12
12
  systemId
13
13
  } = options;
14
14
  if (typeof src === 'string') {
15
- const referenced = interpreter.resolveReferencedActor(machine.implementations.actors[src]);
15
+ const referenced = interpreter.resolveReferencedActor(machine, src);
16
16
  if (!referenced) {
17
17
  throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
18
18
  }
@@ -297,7 +297,7 @@ function resolveSendTo(actorContext, state, args, {
297
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.
298
298
  targetActorRef = state.children[resolvedTarget.slice(2)];
299
299
  } else {
300
- targetActorRef = extra?.deferredActorIds.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
300
+ targetActorRef = extra.deferredActorIds?.includes(resolvedTarget) ? resolvedTarget : state.children[resolvedTarget];
301
301
  }
302
302
  if (!targetActorRef) {
303
303
  throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
@@ -322,6 +322,9 @@ function executeSendTo(actorContext, params) {
322
322
  actorContext.self.delaySend(params);
323
323
  return;
324
324
  }
325
+
326
+ // this forms an outgoing events queue
327
+ // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
325
328
  actorContext.defer(() => {
326
329
  const {
327
330
  to,