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.
- package/actions/dist/xstate-actions.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.cjs.js +3 -3
- package/actions/dist/xstate-actions.development.esm.js +3 -3
- package/actions/dist/xstate-actions.esm.js +3 -3
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.esm.js +1 -1
- package/actors/dist/xstate-actors.esm.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.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/typegenTypes.d.ts +2 -0
- package/dist/declarations/src/types.d.ts +1 -2
- package/dist/declarations/src/utils.d.ts +6 -6
- package/dist/declarations/src/waitFor.d.ts +1 -1
- package/dist/{interpreter-5c4e6634.development.esm.js → interpreter-1c52b23c.development.esm.js} +13 -23
- package/dist/{interpreter-de5217bc.esm.js → interpreter-8def682e.esm.js} +13 -23
- package/dist/{interpreter-69605bf0.cjs.js → interpreter-97aff8d2.cjs.js} +13 -23
- package/dist/{interpreter-d3567419.development.cjs.js → interpreter-e58ca48d.development.cjs.js} +13 -23
- package/dist/{raise-26e4d83c.development.cjs.js → raise-1fd59c65.development.cjs.js} +129 -102
- package/dist/{raise-511399cc.esm.js → raise-21c417c1.esm.js} +129 -102
- package/dist/{raise-0ff57677.cjs.js → raise-800296d7.cjs.js} +129 -102
- package/dist/{raise-cdcdf834.development.esm.js → raise-e342a840.development.esm.js} +129 -102
- package/dist/{send-19ffc568.cjs.js → send-4cc29786.cjs.js} +7 -4
- package/dist/{send-1de74f4d.development.esm.js → send-83ccc98b.development.esm.js} +7 -4
- package/dist/{send-211a2a94.esm.js → send-92854675.esm.js} +7 -4
- package/dist/{send-894c4b18.development.cjs.js → send-b309ef4e.development.cjs.js} +7 -4
- package/dist/xstate.cjs.js +11 -19
- package/dist/xstate.development.cjs.js +11 -19
- package/dist/xstate.development.esm.js +14 -22
- package/dist/xstate.esm.js +14 -22
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.esm.js +2 -2
- package/guards/dist/xstate-guards.esm.js +2 -2
- package/guards/dist/xstate-guards.umd.min.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- 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-
|
|
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
|
|
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
|
-
//
|
|
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
|
-
|
|
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
|
|
605
|
+
function resolveHistoryDefaultTransition(stateNode) {
|
|
594
606
|
const normalizedTarget = normalizeTarget(stateNode.config.target);
|
|
595
607
|
if (!normalizedTarget) {
|
|
596
|
-
return stateNode.parent.initial
|
|
608
|
+
return stateNode.parent.initial;
|
|
597
609
|
}
|
|
598
|
-
return
|
|
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
|
|
852
|
+
return;
|
|
841
853
|
}
|
|
842
|
-
if (!transition.reenter &&
|
|
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
|
|
878
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
957
|
-
|
|
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
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
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,
|
|
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
|
|
1009
|
-
for (const s of
|
|
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
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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 (!
|
|
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
|
-
|
|
1186
|
-
|
|
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
|
-
|
|
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
|
|
1200
|
-
|
|
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,
|
|
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
|
-
|
|
1486
|
-
|
|
1487
|
-
}
|
|
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-
|
|
4
|
-
var interpreter = require('./interpreter-
|
|
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
|
|
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?.
|
|
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-
|
|
2
|
-
import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-
|
|
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
|
|
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?.
|
|
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-
|
|
2
|
-
import { f as ActorStatus, j as createErrorActorEvent, r as resolveReferencedActor, d as createActor, t as toArray, x as XSTATE_ERROR } from './interpreter-
|
|
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
|
|
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?.
|
|
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-
|
|
4
|
-
var interpreter = require('./interpreter-
|
|
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
|
|
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?.
|
|
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,
|