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.
- package/actions/dist/xstate-actions.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.esm.js +2 -2
- package/actions/dist/xstate-actions.esm.js +2 -2
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/dist/declarations/src/State.d.ts +0 -1
- package/dist/declarations/src/stateUtils.d.ts +3 -3
- package/dist/declarations/src/types.d.ts +0 -1
- package/dist/{raise-26e4d83c.development.cjs.js → raise-106ea558.development.cjs.js} +58 -62
- package/dist/{raise-cdcdf834.development.esm.js → raise-5b7ad3b7.development.esm.js} +58 -62
- package/dist/{raise-0ff57677.cjs.js → raise-c51b81a3.cjs.js} +58 -62
- package/dist/{raise-511399cc.esm.js → raise-ffe1014a.esm.js} +58 -62
- package/dist/{send-211a2a94.esm.js → send-0a7aa74e.esm.js} +2 -2
- package/dist/{send-894c4b18.development.cjs.js → send-25e70bd4.development.cjs.js} +2 -2
- package/dist/{send-19ffc568.cjs.js → send-778692de.cjs.js} +2 -2
- package/dist/{send-1de74f4d.development.esm.js → send-e93554d6.development.esm.js} +2 -2
- package/dist/xstate.cjs.js +8 -8
- package/dist/xstate.development.cjs.js +8 -8
- package/dist/xstate.development.esm.js +10 -10
- package/dist/xstate.esm.js +10 -10
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.esm.js +1 -1
- package/guards/dist/xstate-guards.esm.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- 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
|
|
849
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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 (!
|
|
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
|
-
|
|
1154
|
-
|
|
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
|
-
|
|
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
|
|
1168
|
-
|
|
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
|
-
|
|
1448
|
-
|
|
1449
|
-
}
|
|
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
|
|
847
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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 (!
|
|
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
|
-
|
|
1152
|
-
|
|
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
|
-
|
|
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
|
|
1166
|
-
|
|
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
|
-
|
|
1446
|
-
|
|
1447
|
-
}
|
|
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-
|
|
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?.
|
|
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-
|
|
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?.
|
|
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-
|
|
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?.
|
|
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-
|
|
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?.
|
|
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}'.`);
|
package/dist/xstate.cjs.js
CHANGED
|
@@ -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-
|
|
8
|
-
var send = require('./send-
|
|
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-
|
|
8
|
-
var send = require('./send-
|
|
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) {
|