xstate 5.0.0-beta.35 → 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 (29) hide show
  1. package/actions/dist/xstate-actions.cjs.js +2 -2
  2. package/actions/dist/xstate-actions.development.cjs.js +2 -2
  3. package/actions/dist/xstate-actions.development.esm.js +2 -2
  4. package/actions/dist/xstate-actions.esm.js +2 -2
  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/dist/declarations/src/State.d.ts +0 -1
  8. package/dist/declarations/src/stateUtils.d.ts +3 -3
  9. package/dist/declarations/src/types.d.ts +0 -1
  10. package/dist/{raise-26e4d83c.development.cjs.js → raise-106ea558.development.cjs.js} +58 -62
  11. package/dist/{raise-cdcdf834.development.esm.js → raise-5b7ad3b7.development.esm.js} +58 -62
  12. package/dist/{raise-0ff57677.cjs.js → raise-c51b81a3.cjs.js} +58 -62
  13. package/dist/{raise-511399cc.esm.js → raise-ffe1014a.esm.js} +58 -62
  14. package/dist/{send-211a2a94.esm.js → send-0a7aa74e.esm.js} +2 -2
  15. package/dist/{send-894c4b18.development.cjs.js → send-25e70bd4.development.cjs.js} +2 -2
  16. package/dist/{send-19ffc568.cjs.js → send-778692de.cjs.js} +2 -2
  17. package/dist/{send-1de74f4d.development.esm.js → send-e93554d6.development.esm.js} +2 -2
  18. package/dist/xstate.cjs.js +8 -8
  19. package/dist/xstate.development.cjs.js +8 -8
  20. package/dist/xstate.development.esm.js +10 -10
  21. package/dist/xstate.esm.js +10 -10
  22. package/dist/xstate.umd.min.js +1 -1
  23. package/dist/xstate.umd.min.js.map +1 -1
  24. package/guards/dist/xstate-guards.cjs.js +1 -1
  25. package/guards/dist/xstate-guards.development.cjs.js +1 -1
  26. package/guards/dist/xstate-guards.development.esm.js +1 -1
  27. package/guards/dist/xstate-guards.esm.js +1 -1
  28. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  29. package/package.json +1 -1
@@ -830,6 +830,17 @@ function computeExitSet(transitions, configuration, historyValue) {
830
830
  }
831
831
  return [...statesToExit];
832
832
  }
833
+ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
834
+ if (previousConfiguration.length !== nextConfigurationSet.size) {
835
+ return false;
836
+ }
837
+ for (const node of previousConfiguration) {
838
+ if (!nextConfigurationSet.has(node)) {
839
+ return false;
840
+ }
841
+ }
842
+ return true;
843
+ }
833
844
 
834
845
  /**
835
846
  * https://www.w3.org/TR/scxml/#microstepProcedure
@@ -839,50 +850,36 @@ function computeExitSet(transitions, configuration, historyValue) {
839
850
  * @param currentState
840
851
  * @param mutConfiguration
841
852
  */
842
-
843
- function microstep(transitions, currentState, actorCtx, event, isInitial) {
844
- const mutConfiguration = new Set(currentState.configuration);
853
+ function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
845
854
  if (!transitions.length) {
846
855
  return currentState;
847
856
  }
848
- const microstate = microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial);
849
- return cloneState(microstate, {
850
- value: {} // TODO: make optional
851
- });
852
- }
853
-
854
- function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
855
- const historyValue = {
856
- ...currentState.historyValue
857
- };
857
+ const mutConfiguration = new Set(currentState.configuration);
858
+ let historyValue = currentState.historyValue;
858
859
  const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
859
- const internalQueue = [...currentState._internalQueue];
860
- // TODO: this `cloneState` is really just a hack to prevent infinite loops
861
- // we need to take another look at how internal queue is managed
862
- let nextState = cloneState(currentState, {
863
- _internalQueue: []
864
- });
860
+ let nextState = currentState;
865
861
 
866
862
  // Exit states
867
863
  if (!isInitial) {
868
- nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
864
+ [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
869
865
  }
870
866
 
871
867
  // Execute transition content
872
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
868
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
873
869
 
874
870
  // Enter states
875
871
  nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
876
872
  const nextConfiguration = [...mutConfiguration];
877
873
  if (nextState.status === 'done') {
878
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
874
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
879
875
  }
880
876
  try {
881
- internalQueue.push(...nextState._internalQueue);
877
+ if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
878
+ return nextState;
879
+ }
882
880
  return cloneState(nextState, {
883
881
  configuration: nextConfiguration,
884
- historyValue,
885
- _internalQueue: internalQueue
882
+ historyValue
886
883
  });
887
884
  } catch (e) {
888
885
  // TODO: Refactor this once proper error handling is implemented.
@@ -921,7 +918,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
921
918
  const initialActions = stateNodeToEnter.initial.actions;
922
919
  actions.push(...initialActions);
923
920
  }
924
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
921
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
925
922
  if (stateNodeToEnter.type === 'final') {
926
923
  const parent = stateNodeToEnter.parent;
927
924
  if (completedNodes.has(parent)) {
@@ -1018,10 +1015,11 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1018
1015
  }
1019
1016
  }
1020
1017
  }
1021
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
1018
+ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1022
1019
  let nextState = currentState;
1023
1020
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1024
1021
  statesToExit.sort((a, b) => b.order - a.order);
1022
+ let changedHistory;
1025
1023
 
1026
1024
  // From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
1027
1025
  for (const exitStateNode of statesToExit) {
@@ -1034,14 +1032,17 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1034
1032
  return sn.parent === exitStateNode;
1035
1033
  };
1036
1034
  }
1037
- historyValue[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1035
+ changedHistory ??= {
1036
+ ...historyValue
1037
+ };
1038
+ changedHistory[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1038
1039
  }
1039
1040
  }
1040
1041
  for (const s of statesToExit) {
1041
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))]);
1042
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1042
1043
  mutConfiguration.delete(s);
1043
1044
  }
1044
- return nextState;
1045
+ return [nextState, changedHistory || historyValue];
1045
1046
  }
1046
1047
  function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1047
1048
  const {
@@ -1106,9 +1107,10 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1106
1107
  }
1107
1108
  return intermediateState;
1108
1109
  }
1109
- function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
1110
+ function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1110
1111
  const retries = deferredActorIds ? [] : undefined;
1111
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, deferredActorIds && {
1112
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1113
+ internalQueue,
1112
1114
  deferredActorIds
1113
1115
  }, retries);
1114
1116
  retries?.forEach(([builtinAction, params]) => {
@@ -1116,13 +1118,13 @@ function resolveActionsAndContext(currentState, event, actorCtx, actions, deferr
1116
1118
  });
1117
1119
  return nextState;
1118
1120
  }
1119
- function macrostep(state, event, actorCtx) {
1121
+ function macrostep(state, event, actorCtx, internalQueue = []) {
1120
1122
  let nextState = state;
1121
1123
  const states = [];
1122
1124
 
1123
1125
  // Handle stop event
1124
1126
  if (event.type === interpreter.XSTATE_STOP) {
1125
- nextState = stopStep(event, nextState, actorCtx);
1127
+ nextState = stopChildren(nextState, event, actorCtx);
1126
1128
  states.push(nextState);
1127
1129
  return {
1128
1130
  state: nextState,
@@ -1135,44 +1137,37 @@ function macrostep(state, event, actorCtx) {
1135
1137
  // Determine the next state based on the next microstep
1136
1138
  if (nextEvent.type !== interpreter.XSTATE_INIT) {
1137
1139
  const transitions = selectTransitions(nextEvent, nextState);
1138
- nextState = microstep(transitions, state, actorCtx, nextEvent, false);
1140
+ nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1139
1141
  states.push(nextState);
1140
1142
  }
1143
+ let shouldSelectEventlessTransitions = true;
1141
1144
  while (nextState.status === 'active') {
1142
- let enabledTransitions = selectEventlessTransitions(nextState, nextEvent);
1145
+ let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextState, nextEvent) : [];
1146
+
1147
+ // eventless transitions should always be selected after selecting *regular* transitions
1148
+ // by assigning `undefined` to `previousState` we ensure that `shouldSelectEventlessTransitions` gets always computed to true in such a case
1149
+ const previousState = enabledTransitions.length ? nextState : undefined;
1143
1150
  if (!enabledTransitions.length) {
1144
- if (!nextState._internalQueue.length) {
1151
+ if (!internalQueue.length) {
1145
1152
  break;
1146
- } else {
1147
- nextEvent = nextState._internalQueue[0];
1148
- const transitions = selectTransitions(nextEvent, nextState);
1149
- nextState = microstep(transitions, nextState, actorCtx, nextEvent, false);
1150
- nextState._internalQueue.shift();
1151
- states.push(nextState);
1152
1153
  }
1153
- } else {
1154
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false);
1155
- states.push(nextState);
1154
+ nextEvent = internalQueue.shift();
1155
+ enabledTransitions = selectTransitions(nextEvent, nextState);
1156
1156
  }
1157
+ nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1158
+ shouldSelectEventlessTransitions = nextState !== previousState;
1159
+ states.push(nextState);
1157
1160
  }
1158
1161
  if (nextState.status !== 'active') {
1159
- // Perform the stop step to ensure that child actors are stopped
1160
- stopStep(nextEvent, nextState, actorCtx);
1162
+ stopChildren(nextState, nextEvent, actorCtx);
1161
1163
  }
1162
1164
  return {
1163
1165
  state: nextState,
1164
1166
  microstates: states
1165
1167
  };
1166
1168
  }
1167
- function stopStep(event, nextState, actorCtx) {
1168
- const actions = [];
1169
- for (const stateNode of nextState.configuration.sort((a, b) => b.order - a.order)) {
1170
- actions.push(...stateNode.exit);
1171
- }
1172
- for (const child of Object.values(nextState.children)) {
1173
- actions.push(stop(child));
1174
- }
1175
- return resolveActionsAndContext(nextState, event, actorCtx, actions);
1169
+ function stopChildren(nextState, event, actorCtx) {
1170
+ return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1176
1171
  }
1177
1172
  function selectTransitions(event, nextState) {
1178
1173
  return nextState.machine.getTransitionData(nextState, event);
@@ -1278,11 +1273,9 @@ class State {
1278
1273
  this.error = void 0;
1279
1274
  this.context = void 0;
1280
1275
  this.historyValue = {};
1281
- this._internalQueue = void 0;
1282
1276
  this.configuration = void 0;
1283
1277
  this.children = void 0;
1284
1278
  this.context = config.context;
1285
- this._internalQueue = config._internalQueue ?? [];
1286
1279
  this.historyValue = config.historyValue || {};
1287
1280
  this.matches = this.matches.bind(this);
1288
1281
  this.toStrings = this.toStrings.bind(this);
@@ -1431,6 +1424,8 @@ function resolveRaise(_, state, args, {
1431
1424
  event: eventOrExpr,
1432
1425
  id,
1433
1426
  delay
1427
+ }, {
1428
+ internalQueue
1434
1429
  }) {
1435
1430
  const delaysMap = state.machine.implementations.delays;
1436
1431
  if (typeof eventOrExpr === 'string') {
@@ -1444,9 +1439,10 @@ function resolveRaise(_, state, args, {
1444
1439
  } else {
1445
1440
  resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1446
1441
  }
1447
- return [typeof resolvedDelay !== 'number' ? cloneState(state, {
1448
- _internalQueue: state._internalQueue.concat(resolvedEvent)
1449
- }) : state, {
1442
+ if (typeof resolvedDelay !== 'number') {
1443
+ internalQueue.push(resolvedEvent);
1444
+ }
1445
+ return [state, {
1450
1446
  event: resolvedEvent,
1451
1447
  id,
1452
1448
  delay: resolvedDelay
@@ -828,6 +828,17 @@ function computeExitSet(transitions, configuration, historyValue) {
828
828
  }
829
829
  return [...statesToExit];
830
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
+ }
831
842
 
832
843
  /**
833
844
  * https://www.w3.org/TR/scxml/#microstepProcedure
@@ -837,50 +848,36 @@ function computeExitSet(transitions, configuration, historyValue) {
837
848
  * @param currentState
838
849
  * @param mutConfiguration
839
850
  */
840
-
841
- function microstep(transitions, currentState, actorCtx, event, isInitial) {
842
- const mutConfiguration = new Set(currentState.configuration);
851
+ function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
843
852
  if (!transitions.length) {
844
853
  return currentState;
845
854
  }
846
- const microstate = microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial);
847
- return cloneState(microstate, {
848
- value: {} // TODO: make optional
849
- });
850
- }
851
-
852
- function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
853
- const historyValue = {
854
- ...currentState.historyValue
855
- };
855
+ const mutConfiguration = new Set(currentState.configuration);
856
+ let historyValue = currentState.historyValue;
856
857
  const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
857
- const internalQueue = [...currentState._internalQueue];
858
- // TODO: this `cloneState` is really just a hack to prevent infinite loops
859
- // we need to take another look at how internal queue is managed
860
- let nextState = cloneState(currentState, {
861
- _internalQueue: []
862
- });
858
+ let nextState = currentState;
863
859
 
864
860
  // Exit states
865
861
  if (!isInitial) {
866
- nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
862
+ [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
867
863
  }
868
864
 
869
865
  // Execute transition content
870
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
866
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
871
867
 
872
868
  // Enter states
873
869
  nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
874
870
  const nextConfiguration = [...mutConfiguration];
875
871
  if (nextState.status === 'done') {
876
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
872
+ nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
877
873
  }
878
874
  try {
879
- internalQueue.push(...nextState._internalQueue);
875
+ if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
876
+ return nextState;
877
+ }
880
878
  return cloneState(nextState, {
881
879
  configuration: nextConfiguration,
882
- historyValue,
883
- _internalQueue: internalQueue
880
+ historyValue
884
881
  });
885
882
  } catch (e) {
886
883
  // TODO: Refactor this once proper error handling is implemented.
@@ -919,7 +916,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
919
916
  const initialActions = stateNodeToEnter.initial.actions;
920
917
  actions.push(...initialActions);
921
918
  }
922
- 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));
923
920
  if (stateNodeToEnter.type === 'final') {
924
921
  const parent = stateNodeToEnter.parent;
925
922
  if (completedNodes.has(parent)) {
@@ -1016,10 +1013,11 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1016
1013
  }
1017
1014
  }
1018
1015
  }
1019
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
1016
+ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1020
1017
  let nextState = currentState;
1021
1018
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1022
1019
  statesToExit.sort((a, b) => b.order - a.order);
1020
+ let changedHistory;
1023
1021
 
1024
1022
  // From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
1025
1023
  for (const exitStateNode of statesToExit) {
@@ -1032,14 +1030,17 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1032
1030
  return sn.parent === exitStateNode;
1033
1031
  };
1034
1032
  }
1035
- historyValue[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1033
+ changedHistory ??= {
1034
+ ...historyValue
1035
+ };
1036
+ changedHistory[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
1036
1037
  }
1037
1038
  }
1038
1039
  for (const s of statesToExit) {
1039
- 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);
1040
1041
  mutConfiguration.delete(s);
1041
1042
  }
1042
- return nextState;
1043
+ return [nextState, changedHistory || historyValue];
1043
1044
  }
1044
1045
  function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1045
1046
  const {
@@ -1104,9 +1105,10 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1104
1105
  }
1105
1106
  return intermediateState;
1106
1107
  }
1107
- function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
1108
+ function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1108
1109
  const retries = deferredActorIds ? [] : undefined;
1109
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, deferredActorIds && {
1110
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1111
+ internalQueue,
1110
1112
  deferredActorIds
1111
1113
  }, retries);
1112
1114
  retries?.forEach(([builtinAction, params]) => {
@@ -1114,13 +1116,13 @@ function resolveActionsAndContext(currentState, event, actorCtx, actions, deferr
1114
1116
  });
1115
1117
  return nextState;
1116
1118
  }
1117
- function macrostep(state, event, actorCtx) {
1119
+ function macrostep(state, event, actorCtx, internalQueue = []) {
1118
1120
  let nextState = state;
1119
1121
  const states = [];
1120
1122
 
1121
1123
  // Handle stop event
1122
1124
  if (event.type === XSTATE_STOP) {
1123
- nextState = stopStep(event, nextState, actorCtx);
1125
+ nextState = stopChildren(nextState, event, actorCtx);
1124
1126
  states.push(nextState);
1125
1127
  return {
1126
1128
  state: nextState,
@@ -1133,44 +1135,37 @@ function macrostep(state, event, actorCtx) {
1133
1135
  // Determine the next state based on the next microstep
1134
1136
  if (nextEvent.type !== XSTATE_INIT) {
1135
1137
  const transitions = selectTransitions(nextEvent, nextState);
1136
- nextState = microstep(transitions, state, actorCtx, nextEvent, false);
1138
+ nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1137
1139
  states.push(nextState);
1138
1140
  }
1141
+ let shouldSelectEventlessTransitions = true;
1139
1142
  while (nextState.status === 'active') {
1140
- 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;
1141
1148
  if (!enabledTransitions.length) {
1142
- if (!nextState._internalQueue.length) {
1149
+ if (!internalQueue.length) {
1143
1150
  break;
1144
- } else {
1145
- nextEvent = nextState._internalQueue[0];
1146
- const transitions = selectTransitions(nextEvent, nextState);
1147
- nextState = microstep(transitions, nextState, actorCtx, nextEvent, false);
1148
- nextState._internalQueue.shift();
1149
- states.push(nextState);
1150
1151
  }
1151
- } else {
1152
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false);
1153
- states.push(nextState);
1152
+ nextEvent = internalQueue.shift();
1153
+ enabledTransitions = selectTransitions(nextEvent, nextState);
1154
1154
  }
1155
+ nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1156
+ shouldSelectEventlessTransitions = nextState !== previousState;
1157
+ states.push(nextState);
1155
1158
  }
1156
1159
  if (nextState.status !== 'active') {
1157
- // Perform the stop step to ensure that child actors are stopped
1158
- stopStep(nextEvent, nextState, actorCtx);
1160
+ stopChildren(nextState, nextEvent, actorCtx);
1159
1161
  }
1160
1162
  return {
1161
1163
  state: nextState,
1162
1164
  microstates: states
1163
1165
  };
1164
1166
  }
1165
- function stopStep(event, nextState, actorCtx) {
1166
- const actions = [];
1167
- for (const stateNode of nextState.configuration.sort((a, b) => b.order - a.order)) {
1168
- actions.push(...stateNode.exit);
1169
- }
1170
- for (const child of Object.values(nextState.children)) {
1171
- actions.push(stop(child));
1172
- }
1173
- 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)), []);
1174
1169
  }
1175
1170
  function selectTransitions(event, nextState) {
1176
1171
  return nextState.machine.getTransitionData(nextState, event);
@@ -1276,11 +1271,9 @@ class State {
1276
1271
  this.error = void 0;
1277
1272
  this.context = void 0;
1278
1273
  this.historyValue = {};
1279
- this._internalQueue = void 0;
1280
1274
  this.configuration = void 0;
1281
1275
  this.children = void 0;
1282
1276
  this.context = config.context;
1283
- this._internalQueue = config._internalQueue ?? [];
1284
1277
  this.historyValue = config.historyValue || {};
1285
1278
  this.matches = this.matches.bind(this);
1286
1279
  this.toStrings = this.toStrings.bind(this);
@@ -1429,6 +1422,8 @@ function resolveRaise(_, state, args, {
1429
1422
  event: eventOrExpr,
1430
1423
  id,
1431
1424
  delay
1425
+ }, {
1426
+ internalQueue
1432
1427
  }) {
1433
1428
  const delaysMap = state.machine.implementations.delays;
1434
1429
  if (typeof eventOrExpr === 'string') {
@@ -1442,9 +1437,10 @@ function resolveRaise(_, state, args, {
1442
1437
  } else {
1443
1438
  resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
1444
1439
  }
1445
- return [typeof resolvedDelay !== 'number' ? cloneState(state, {
1446
- _internalQueue: state._internalQueue.concat(resolvedEvent)
1447
- }) : state, {
1440
+ if (typeof resolvedDelay !== 'number') {
1441
+ internalQueue.push(resolvedEvent);
1442
+ }
1443
+ return [state, {
1448
1444
  event: resolvedEvent,
1449
1445
  id,
1450
1446
  delay: resolvedDelay
@@ -1,4 +1,4 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-511399cc.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-ffe1014a.esm.js';
2
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, {
@@ -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}'.`);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-26e4d83c.development.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-106ea558.development.cjs.js');
4
4
  var interpreter = require('./interpreter-d3567419.development.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
@@ -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}'.`);
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-0ff57677.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-c51b81a3.cjs.js');
4
4
  var interpreter = require('./interpreter-69605bf0.cjs.js');
5
5
 
6
6
  function createSpawner(actorContext, {
@@ -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}'.`);
@@ -1,4 +1,4 @@
1
- import { j as cloneState, e as evaluateGuard } from './raise-cdcdf834.development.esm.js';
1
+ import { j as cloneState, e as evaluateGuard } from './raise-5b7ad3b7.development.esm.js';
2
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';
3
3
 
4
4
  function createSpawner(actorContext, {
@@ -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}'.`);
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var actors_dist_xstateActors = require('../actors/dist/xstate-actors.cjs.js');
6
6
  var interpreter = require('./interpreter-69605bf0.cjs.js');
7
- var guards_dist_xstateGuards = require('./raise-0ff57677.cjs.js');
8
- var send = require('./send-19ffc568.cjs.js');
7
+ var guards_dist_xstateGuards = require('./raise-c51b81a3.cjs.js');
8
+ var send = require('./send-778692de.cjs.js');
9
9
  require('../dev/dist/xstate-dev.cjs.js');
10
10
 
11
11
  class SimulatedClock {
@@ -518,7 +518,7 @@ class StateMachine {
518
518
  * The initial state _before_ evaluating any microsteps.
519
519
  * This "pre-initial" state is provided to initial actions executed in the initial state.
520
520
  */
521
- getPreInitialState(actorCtx, initEvent) {
521
+ getPreInitialState(actorCtx, initEvent, internalQueue) {
522
522
  const {
523
523
  context
524
524
  } = this.config;
@@ -539,7 +539,7 @@ class StateMachine {
539
539
  spawn,
540
540
  input: event.input
541
541
  });
542
- return guards_dist_xstateGuards.resolveActionsAndContext(preInitial, initEvent, actorCtx, [send.assign(assignment)]);
542
+ return guards_dist_xstateGuards.resolveActionsAndContext(preInitial, initEvent, actorCtx, [send.assign(assignment)], internalQueue);
543
543
  }
544
544
  return preInitial;
545
545
  }
@@ -549,8 +549,8 @@ class StateMachine {
549
549
  */
550
550
  getInitialState(actorCtx, input) {
551
551
  const initEvent = interpreter.createInitEvent(input); // TODO: fix;
552
-
553
- const preInitialState = this.getPreInitialState(actorCtx, initEvent);
552
+ const internalQueue = [];
553
+ const preInitialState = this.getPreInitialState(actorCtx, initEvent, internalQueue);
554
554
  const nextState = guards_dist_xstateGuards.microstep([{
555
555
  target: [...guards_dist_xstateGuards.getInitialStateNodes(this.root)],
556
556
  source: this.root,
@@ -558,10 +558,10 @@ class StateMachine {
558
558
  actions: [],
559
559
  eventType: null,
560
560
  toJSON: null // TODO: fix
561
- }], preInitialState, actorCtx, initEvent, true);
561
+ }], preInitialState, actorCtx, initEvent, true, internalQueue);
562
562
  const {
563
563
  state: macroState
564
- } = guards_dist_xstateGuards.macrostep(nextState, initEvent, actorCtx);
564
+ } = guards_dist_xstateGuards.macrostep(nextState, initEvent, actorCtx, internalQueue);
565
565
  return macroState;
566
566
  }
567
567
  start(state) {
@@ -4,8 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var actors_dist_xstateActors = require('../actors/dist/xstate-actors.development.cjs.js');
6
6
  var interpreter = require('./interpreter-d3567419.development.cjs.js');
7
- var guards_dist_xstateGuards = require('./raise-26e4d83c.development.cjs.js');
8
- var send = require('./send-894c4b18.development.cjs.js');
7
+ var guards_dist_xstateGuards = require('./raise-106ea558.development.cjs.js');
8
+ var send = require('./send-25e70bd4.development.cjs.js');
9
9
  require('../dev/dist/xstate-dev.development.cjs.js');
10
10
 
11
11
  class SimulatedClock {
@@ -521,7 +521,7 @@ class StateMachine {
521
521
  * The initial state _before_ evaluating any microsteps.
522
522
  * This "pre-initial" state is provided to initial actions executed in the initial state.
523
523
  */
524
- getPreInitialState(actorCtx, initEvent) {
524
+ getPreInitialState(actorCtx, initEvent, internalQueue) {
525
525
  const {
526
526
  context
527
527
  } = this.config;
@@ -542,7 +542,7 @@ class StateMachine {
542
542
  spawn,
543
543
  input: event.input
544
544
  });
545
- return guards_dist_xstateGuards.resolveActionsAndContext(preInitial, initEvent, actorCtx, [send.assign(assignment)]);
545
+ return guards_dist_xstateGuards.resolveActionsAndContext(preInitial, initEvent, actorCtx, [send.assign(assignment)], internalQueue);
546
546
  }
547
547
  return preInitial;
548
548
  }
@@ -552,8 +552,8 @@ class StateMachine {
552
552
  */
553
553
  getInitialState(actorCtx, input) {
554
554
  const initEvent = interpreter.createInitEvent(input); // TODO: fix;
555
-
556
- const preInitialState = this.getPreInitialState(actorCtx, initEvent);
555
+ const internalQueue = [];
556
+ const preInitialState = this.getPreInitialState(actorCtx, initEvent, internalQueue);
557
557
  const nextState = guards_dist_xstateGuards.microstep([{
558
558
  target: [...guards_dist_xstateGuards.getInitialStateNodes(this.root)],
559
559
  source: this.root,
@@ -561,10 +561,10 @@ class StateMachine {
561
561
  actions: [],
562
562
  eventType: null,
563
563
  toJSON: null // TODO: fix
564
- }], preInitialState, actorCtx, initEvent, true);
564
+ }], preInitialState, actorCtx, initEvent, true, internalQueue);
565
565
  const {
566
566
  state: macroState
567
- } = guards_dist_xstateGuards.macrostep(nextState, initEvent, actorCtx);
567
+ } = guards_dist_xstateGuards.macrostep(nextState, initEvent, actorCtx, internalQueue);
568
568
  return macroState;
569
569
  }
570
570
  start(state) {