xstate 5.0.0-beta.34 → 5.0.0-beta.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- 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/interpreter.d.ts +2 -0
- package/dist/declarations/src/stateUtils.d.ts +8 -7
- package/dist/declarations/src/types.d.ts +3 -6
- package/dist/{interpreter-dee56dc8.development.esm.js → interpreter-5c4e6634.development.esm.js} +59 -57
- package/dist/{interpreter-1301970f.cjs.js → interpreter-69605bf0.cjs.js} +59 -57
- package/dist/{interpreter-70ed62f2.development.cjs.js → interpreter-d3567419.development.cjs.js} +59 -57
- package/dist/{interpreter-83f7f2d4.esm.js → interpreter-de5217bc.esm.js} +59 -57
- package/dist/{raise-38b707c0.development.cjs.js → raise-106ea558.development.cjs.js} +160 -160
- package/dist/{raise-05f8b2a6.development.esm.js → raise-5b7ad3b7.development.esm.js} +160 -160
- package/dist/{raise-1dd65455.cjs.js → raise-c51b81a3.cjs.js} +157 -160
- package/dist/{raise-b5cfe1bb.esm.js → raise-ffe1014a.esm.js} +157 -160
- package/dist/{send-0b5eda0c.esm.js → send-0a7aa74e.esm.js} +5 -3
- package/dist/{send-3764c866.development.cjs.js → send-25e70bd4.development.cjs.js} +5 -3
- package/dist/{send-fe94de2b.cjs.js → send-778692de.cjs.js} +5 -3
- package/dist/{send-9526366e.development.esm.js → send-e93554d6.development.esm.js} +5 -3
- package/dist/xstate.cjs.js +32 -13
- package/dist/xstate.development.cjs.js +32 -13
- package/dist/xstate.development.esm.js +35 -16
- package/dist/xstate.esm.js +35 -16
- 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.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
|
|
1
|
+
import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-5c4e6634.development.esm.js';
|
|
2
2
|
|
|
3
3
|
const cache = new WeakMap();
|
|
4
4
|
function memo(object, key, fn) {
|
|
@@ -297,20 +297,6 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
297
297
|
);
|
|
298
298
|
}
|
|
299
299
|
|
|
300
|
-
function getOutput(configuration, context, event, self) {
|
|
301
|
-
const {
|
|
302
|
-
machine
|
|
303
|
-
} = configuration[0];
|
|
304
|
-
const {
|
|
305
|
-
root
|
|
306
|
-
} = machine;
|
|
307
|
-
if (!root.output) {
|
|
308
|
-
return undefined;
|
|
309
|
-
}
|
|
310
|
-
const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
|
|
311
|
-
const doneStateEvent = createDoneStateEvent(finalChildStateNode.id, finalChildStateNode.output ? resolveOutput(finalChildStateNode.output, context, event, self) : undefined);
|
|
312
|
-
return resolveOutput(root.output, context, doneStateEvent, self);
|
|
313
|
-
}
|
|
314
300
|
const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
|
|
315
301
|
function getChildren(stateNode) {
|
|
316
302
|
return Object.values(stateNode.states).filter(sn => sn.type !== 'history');
|
|
@@ -335,7 +321,7 @@ function getConfiguration(stateNodes) {
|
|
|
335
321
|
for (const s of configuration) {
|
|
336
322
|
// if previously active, add existing child nodes
|
|
337
323
|
if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
|
|
338
|
-
|
|
324
|
+
getInitialStateNodesWithTheirAncestors(s).forEach(sn => configurationSet.add(sn));
|
|
339
325
|
} else {
|
|
340
326
|
if (s.type === 'parallel') {
|
|
341
327
|
for (const child of getChildren(s)) {
|
|
@@ -343,7 +329,8 @@ function getConfiguration(stateNodes) {
|
|
|
343
329
|
continue;
|
|
344
330
|
}
|
|
345
331
|
if (!configurationSet.has(child)) {
|
|
346
|
-
|
|
332
|
+
const initialStates = getInitialStateNodesWithTheirAncestors(child);
|
|
333
|
+
for (const initialStateNode of initialStates) {
|
|
347
334
|
configurationSet.add(initialStateNode);
|
|
348
335
|
}
|
|
349
336
|
}
|
|
@@ -403,14 +390,14 @@ function getStateValue(rootNode, configuration) {
|
|
|
403
390
|
const config = getConfiguration(configuration);
|
|
404
391
|
return getValueFromAdj(rootNode, getAdjList(config));
|
|
405
392
|
}
|
|
406
|
-
function isInFinalState(configuration, stateNode
|
|
393
|
+
function isInFinalState(configuration, stateNode) {
|
|
407
394
|
if (stateNode.type === 'compound') {
|
|
408
|
-
return getChildren(stateNode).some(s => s.type === 'final' && configuration.
|
|
395
|
+
return getChildren(stateNode).some(s => s.type === 'final' && configuration.has(s));
|
|
409
396
|
}
|
|
410
397
|
if (stateNode.type === 'parallel') {
|
|
411
398
|
return getChildren(stateNode).every(sn => isInFinalState(configuration, sn));
|
|
412
399
|
}
|
|
413
|
-
return
|
|
400
|
+
return stateNode.type === 'final';
|
|
414
401
|
}
|
|
415
402
|
const isStateId = str => str[0] === STATE_IDENTIFIER;
|
|
416
403
|
function getCandidates(stateNode, receivedEventType) {
|
|
@@ -466,13 +453,7 @@ function getDelayedTransitions(stateNode) {
|
|
|
466
453
|
stateNode.exit.push(cancel(eventType));
|
|
467
454
|
return eventType;
|
|
468
455
|
};
|
|
469
|
-
const delayedTransitions =
|
|
470
|
-
const eventType = mutateEntryExit(transition.delay, i);
|
|
471
|
-
return {
|
|
472
|
-
...transition,
|
|
473
|
-
event: eventType
|
|
474
|
-
};
|
|
475
|
-
}) : Object.keys(afterConfig).flatMap((delay, i) => {
|
|
456
|
+
const delayedTransitions = Object.keys(afterConfig).flatMap((delay, i) => {
|
|
476
457
|
const configTransition = afterConfig[delay];
|
|
477
458
|
const resolvedTransition = typeof configTransition === 'string' ? {
|
|
478
459
|
target: configTransition
|
|
@@ -560,43 +541,23 @@ function formatTransitions(stateNode) {
|
|
|
560
541
|
return transitions;
|
|
561
542
|
}
|
|
562
543
|
function formatInitialTransition(stateNode, _target) {
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
// to their state node
|
|
567
|
-
const descStateNode = typeof t === 'string' ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
|
|
568
|
-
if (!descStateNode) {
|
|
569
|
-
throw new Error(`Initial state node "${t}" not found on parent state node #${stateNode.id}`);
|
|
570
|
-
}
|
|
571
|
-
if (!isDescendant(descStateNode, stateNode)) {
|
|
572
|
-
throw new Error(`Invalid initial target: state node #${descStateNode.id} is not a descendant of #${stateNode.id}`);
|
|
573
|
-
}
|
|
574
|
-
return descStateNode;
|
|
575
|
-
});
|
|
576
|
-
const resolvedTarget = resolveTarget(stateNode, targets);
|
|
577
|
-
const transition = {
|
|
578
|
-
source: stateNode,
|
|
579
|
-
actions: [],
|
|
580
|
-
eventType: null,
|
|
581
|
-
reenter: false,
|
|
582
|
-
target: resolvedTarget,
|
|
583
|
-
toJSON: () => ({
|
|
584
|
-
...transition,
|
|
585
|
-
source: `#${stateNode.id}`,
|
|
586
|
-
target: resolvedTarget ? resolvedTarget.map(t => `#${t.id}`) : undefined
|
|
587
|
-
})
|
|
588
|
-
};
|
|
589
|
-
return transition;
|
|
544
|
+
const resolvedTarget = typeof _target === 'string' ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : undefined;
|
|
545
|
+
if (!resolvedTarget && _target) {
|
|
546
|
+
throw new Error(`Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
|
|
590
547
|
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
548
|
+
const transition = {
|
|
549
|
+
source: stateNode,
|
|
550
|
+
actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
|
|
551
|
+
eventType: null,
|
|
552
|
+
reenter: false,
|
|
553
|
+
target: resolvedTarget ? [resolvedTarget] : [],
|
|
554
|
+
toJSON: () => ({
|
|
555
|
+
...transition,
|
|
556
|
+
source: `#${stateNode.id}`,
|
|
557
|
+
target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
|
|
558
|
+
})
|
|
559
|
+
};
|
|
560
|
+
return transition;
|
|
600
561
|
}
|
|
601
562
|
function resolveTarget(stateNode, targets) {
|
|
602
563
|
if (targets === undefined) {
|
|
@@ -639,6 +600,15 @@ function resolveHistoryTarget(stateNode) {
|
|
|
639
600
|
function isHistoryNode(stateNode) {
|
|
640
601
|
return stateNode.type === 'history';
|
|
641
602
|
}
|
|
603
|
+
function getInitialStateNodesWithTheirAncestors(stateNode) {
|
|
604
|
+
const states = getInitialStateNodes(stateNode);
|
|
605
|
+
for (const initialState of states) {
|
|
606
|
+
for (const ancestor of getProperAncestors(initialState, stateNode)) {
|
|
607
|
+
states.add(ancestor);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
return states;
|
|
611
|
+
}
|
|
642
612
|
function getInitialStateNodes(stateNode) {
|
|
643
613
|
const set = new Set();
|
|
644
614
|
function iter(descStateNode) {
|
|
@@ -647,12 +617,7 @@ function getInitialStateNodes(stateNode) {
|
|
|
647
617
|
}
|
|
648
618
|
set.add(descStateNode);
|
|
649
619
|
if (descStateNode.type === 'compound') {
|
|
650
|
-
|
|
651
|
-
for (const a of getProperAncestors(targetStateNode, stateNode)) {
|
|
652
|
-
set.add(a);
|
|
653
|
-
}
|
|
654
|
-
iter(targetStateNode);
|
|
655
|
-
}
|
|
620
|
+
iter(descStateNode.initial.target[0]);
|
|
656
621
|
} else if (descStateNode.type === 'parallel') {
|
|
657
622
|
for (const child of getChildren(descStateNode)) {
|
|
658
623
|
iter(child);
|
|
@@ -660,7 +625,7 @@ function getInitialStateNodes(stateNode) {
|
|
|
660
625
|
}
|
|
661
626
|
}
|
|
662
627
|
iter(stateNode);
|
|
663
|
-
return
|
|
628
|
+
return set;
|
|
664
629
|
}
|
|
665
630
|
/**
|
|
666
631
|
* Returns the child state node from its relative `stateKey`, or throws.
|
|
@@ -894,6 +859,17 @@ function computeExitSet(transitions, configuration, historyValue) {
|
|
|
894
859
|
}
|
|
895
860
|
return [...statesToExit];
|
|
896
861
|
}
|
|
862
|
+
function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
863
|
+
if (previousConfiguration.length !== nextConfigurationSet.size) {
|
|
864
|
+
return false;
|
|
865
|
+
}
|
|
866
|
+
for (const node of previousConfiguration) {
|
|
867
|
+
if (!nextConfigurationSet.has(node)) {
|
|
868
|
+
return false;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return true;
|
|
872
|
+
}
|
|
897
873
|
|
|
898
874
|
/**
|
|
899
875
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
@@ -903,56 +879,36 @@ function computeExitSet(transitions, configuration, historyValue) {
|
|
|
903
879
|
* @param currentState
|
|
904
880
|
* @param mutConfiguration
|
|
905
881
|
*/
|
|
906
|
-
|
|
907
|
-
function microstep(transitions, currentState, actorCtx, event, isInitial) {
|
|
908
|
-
const mutConfiguration = new Set(currentState.configuration);
|
|
882
|
+
function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
|
|
909
883
|
if (!transitions.length) {
|
|
910
884
|
return currentState;
|
|
911
885
|
}
|
|
912
|
-
const
|
|
913
|
-
|
|
914
|
-
value: {} // TODO: make optional
|
|
915
|
-
});
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
|
|
919
|
-
const historyValue = {
|
|
920
|
-
...currentState.historyValue
|
|
921
|
-
};
|
|
886
|
+
const mutConfiguration = new Set(currentState.configuration);
|
|
887
|
+
let historyValue = currentState.historyValue;
|
|
922
888
|
const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
|
|
923
|
-
|
|
924
|
-
// TODO: this `cloneState` is really just a hack to prevent infinite loops
|
|
925
|
-
// we need to take another look at how internal queue is managed
|
|
926
|
-
let nextState = cloneState(currentState, {
|
|
927
|
-
_internalQueue: []
|
|
928
|
-
});
|
|
889
|
+
let nextState = currentState;
|
|
929
890
|
|
|
930
891
|
// Exit states
|
|
931
892
|
if (!isInitial) {
|
|
932
|
-
nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
|
|
893
|
+
[nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
|
|
933
894
|
}
|
|
934
895
|
|
|
935
896
|
// Execute transition content
|
|
936
|
-
nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
|
|
897
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
|
|
937
898
|
|
|
938
899
|
// Enter states
|
|
939
900
|
nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
|
|
940
901
|
const nextConfiguration = [...mutConfiguration];
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
|
|
902
|
+
if (nextState.status === 'done') {
|
|
903
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
|
|
944
904
|
}
|
|
945
905
|
try {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
906
|
+
if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
|
|
907
|
+
return nextState;
|
|
908
|
+
}
|
|
909
|
+
return cloneState(nextState, {
|
|
949
910
|
configuration: nextConfiguration,
|
|
950
|
-
historyValue
|
|
951
|
-
_internalQueue: internalQueue,
|
|
952
|
-
context: nextState.context,
|
|
953
|
-
status: done ? 'done' : currentState.status,
|
|
954
|
-
output,
|
|
955
|
-
children: nextState.children
|
|
911
|
+
historyValue
|
|
956
912
|
});
|
|
957
913
|
} catch (e) {
|
|
958
914
|
// TODO: Refactor this once proper error handling is implemented.
|
|
@@ -960,6 +916,13 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
960
916
|
throw e;
|
|
961
917
|
}
|
|
962
918
|
}
|
|
919
|
+
function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
|
|
920
|
+
if (!rootNode.output) {
|
|
921
|
+
return;
|
|
922
|
+
}
|
|
923
|
+
const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
|
|
924
|
+
return resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
|
|
925
|
+
}
|
|
963
926
|
function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
964
927
|
let nextState = currentState;
|
|
965
928
|
const statesToEnter = new Set();
|
|
@@ -970,6 +933,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
970
933
|
if (isInitial) {
|
|
971
934
|
statesForDefaultEntry.add(currentState.machine.root);
|
|
972
935
|
}
|
|
936
|
+
const completedNodes = new Set();
|
|
973
937
|
for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
|
|
974
938
|
mutConfiguration.add(stateNodeToEnter);
|
|
975
939
|
const actions = [];
|
|
@@ -980,26 +944,34 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
980
944
|
actions.push(invoke(invokeDef));
|
|
981
945
|
}
|
|
982
946
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
actions.push(...initialActions);
|
|
986
|
-
}
|
|
947
|
+
const initialActions = stateNodeToEnter.initial.actions;
|
|
948
|
+
actions.push(...initialActions);
|
|
987
949
|
}
|
|
988
|
-
nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
950
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
989
951
|
if (stateNodeToEnter.type === 'final') {
|
|
990
952
|
const parent = stateNodeToEnter.parent;
|
|
991
|
-
if (
|
|
953
|
+
if (completedNodes.has(parent)) {
|
|
992
954
|
continue;
|
|
993
955
|
}
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
956
|
+
completedNodes.add(parent);
|
|
957
|
+
let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
|
|
958
|
+
let ancestorMarker = parent?.parent;
|
|
959
|
+
if (ancestorMarker) {
|
|
960
|
+
internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
|
|
961
|
+
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
962
|
+
completedNodes.add(ancestorMarker);
|
|
963
|
+
internalQueue.push(createDoneStateEvent(ancestorMarker.id));
|
|
964
|
+
rootCompletionNode = ancestorMarker;
|
|
965
|
+
ancestorMarker = ancestorMarker.parent;
|
|
1001
966
|
}
|
|
1002
967
|
}
|
|
968
|
+
if (ancestorMarker) {
|
|
969
|
+
continue;
|
|
970
|
+
}
|
|
971
|
+
nextState = cloneState(nextState, {
|
|
972
|
+
status: 'done',
|
|
973
|
+
output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
|
|
974
|
+
});
|
|
1003
975
|
}
|
|
1004
976
|
}
|
|
1005
977
|
return nextState;
|
|
@@ -1045,13 +1017,9 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1045
1017
|
statesToEnter.add(stateNode);
|
|
1046
1018
|
if (stateNode.type === 'compound') {
|
|
1047
1019
|
statesForDefaultEntry.add(stateNode);
|
|
1048
|
-
const
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
}
|
|
1052
|
-
for (const initialState of initialStates) {
|
|
1053
|
-
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1054
|
-
}
|
|
1020
|
+
const [initialState] = stateNode.initial.target;
|
|
1021
|
+
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1022
|
+
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1055
1023
|
} else {
|
|
1056
1024
|
if (stateNode.type === 'parallel') {
|
|
1057
1025
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
@@ -1076,10 +1044,11 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1076
1044
|
}
|
|
1077
1045
|
}
|
|
1078
1046
|
}
|
|
1079
|
-
function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
|
|
1047
|
+
function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
|
|
1080
1048
|
let nextState = currentState;
|
|
1081
1049
|
const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
|
|
1082
1050
|
statesToExit.sort((a, b) => b.order - a.order);
|
|
1051
|
+
let changedHistory;
|
|
1083
1052
|
|
|
1084
1053
|
// From SCXML algorithm: https://www.w3.org/TR/scxml/#exitStates
|
|
1085
1054
|
for (const exitStateNode of statesToExit) {
|
|
@@ -1092,14 +1061,17 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
|
|
|
1092
1061
|
return sn.parent === exitStateNode;
|
|
1093
1062
|
};
|
|
1094
1063
|
}
|
|
1095
|
-
|
|
1064
|
+
changedHistory ??= {
|
|
1065
|
+
...historyValue
|
|
1066
|
+
};
|
|
1067
|
+
changedHistory[historyNode.id] = Array.from(mutConfiguration).filter(predicate);
|
|
1096
1068
|
}
|
|
1097
1069
|
}
|
|
1098
1070
|
for (const s of statesToExit) {
|
|
1099
|
-
nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))]);
|
|
1071
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
|
|
1100
1072
|
mutConfiguration.delete(s);
|
|
1101
1073
|
}
|
|
1102
|
-
return nextState;
|
|
1074
|
+
return [nextState, changedHistory || historyValue];
|
|
1103
1075
|
}
|
|
1104
1076
|
function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
|
|
1105
1077
|
const {
|
|
@@ -1164,9 +1136,10 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1164
1136
|
}
|
|
1165
1137
|
return intermediateState;
|
|
1166
1138
|
}
|
|
1167
|
-
function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
|
|
1139
|
+
function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
|
|
1168
1140
|
const retries = deferredActorIds ? [] : undefined;
|
|
1169
|
-
const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
1141
|
+
const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
|
|
1142
|
+
internalQueue,
|
|
1170
1143
|
deferredActorIds
|
|
1171
1144
|
}, retries);
|
|
1172
1145
|
retries?.forEach(([builtinAction, params]) => {
|
|
@@ -1174,7 +1147,7 @@ function resolveActionsAndContext(currentState, event, actorCtx, actions, deferr
|
|
|
1174
1147
|
});
|
|
1175
1148
|
return nextState;
|
|
1176
1149
|
}
|
|
1177
|
-
function macrostep(state, event, actorCtx) {
|
|
1150
|
+
function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
1178
1151
|
if (event.type === WILDCARD) {
|
|
1179
1152
|
throw new Error(`An event cannot have the wildcard type ('${WILDCARD}')`);
|
|
1180
1153
|
}
|
|
@@ -1183,7 +1156,7 @@ function macrostep(state, event, actorCtx) {
|
|
|
1183
1156
|
|
|
1184
1157
|
// Handle stop event
|
|
1185
1158
|
if (event.type === XSTATE_STOP) {
|
|
1186
|
-
nextState =
|
|
1159
|
+
nextState = stopChildren(nextState, event, actorCtx);
|
|
1187
1160
|
states.push(nextState);
|
|
1188
1161
|
return {
|
|
1189
1162
|
state: nextState,
|
|
@@ -1196,44 +1169,37 @@ function macrostep(state, event, actorCtx) {
|
|
|
1196
1169
|
// Determine the next state based on the next microstep
|
|
1197
1170
|
if (nextEvent.type !== XSTATE_INIT) {
|
|
1198
1171
|
const transitions = selectTransitions(nextEvent, nextState);
|
|
1199
|
-
nextState = microstep(transitions, state, actorCtx, nextEvent, false);
|
|
1172
|
+
nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
|
|
1200
1173
|
states.push(nextState);
|
|
1201
1174
|
}
|
|
1175
|
+
let shouldSelectEventlessTransitions = true;
|
|
1202
1176
|
while (nextState.status === 'active') {
|
|
1203
|
-
let enabledTransitions = selectEventlessTransitions(nextState, nextEvent);
|
|
1177
|
+
let enabledTransitions = shouldSelectEventlessTransitions ? selectEventlessTransitions(nextState, nextEvent) : [];
|
|
1178
|
+
|
|
1179
|
+
// eventless transitions should always be selected after selecting *regular* transitions
|
|
1180
|
+
// by assigning `undefined` to `previousState` we ensure that `shouldSelectEventlessTransitions` gets always computed to true in such a case
|
|
1181
|
+
const previousState = enabledTransitions.length ? nextState : undefined;
|
|
1204
1182
|
if (!enabledTransitions.length) {
|
|
1205
|
-
if (!
|
|
1183
|
+
if (!internalQueue.length) {
|
|
1206
1184
|
break;
|
|
1207
|
-
} else {
|
|
1208
|
-
nextEvent = nextState._internalQueue[0];
|
|
1209
|
-
const transitions = selectTransitions(nextEvent, nextState);
|
|
1210
|
-
nextState = microstep(transitions, nextState, actorCtx, nextEvent, false);
|
|
1211
|
-
nextState._internalQueue.shift();
|
|
1212
|
-
states.push(nextState);
|
|
1213
1185
|
}
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
states.push(nextState);
|
|
1186
|
+
nextEvent = internalQueue.shift();
|
|
1187
|
+
enabledTransitions = selectTransitions(nextEvent, nextState);
|
|
1217
1188
|
}
|
|
1189
|
+
nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
|
|
1190
|
+
shouldSelectEventlessTransitions = nextState !== previousState;
|
|
1191
|
+
states.push(nextState);
|
|
1218
1192
|
}
|
|
1219
1193
|
if (nextState.status !== 'active') {
|
|
1220
|
-
|
|
1221
|
-
stopStep(nextEvent, nextState, actorCtx);
|
|
1194
|
+
stopChildren(nextState, nextEvent, actorCtx);
|
|
1222
1195
|
}
|
|
1223
1196
|
return {
|
|
1224
1197
|
state: nextState,
|
|
1225
1198
|
microstates: states
|
|
1226
1199
|
};
|
|
1227
1200
|
}
|
|
1228
|
-
function
|
|
1229
|
-
|
|
1230
|
-
for (const stateNode of nextState.configuration.sort((a, b) => b.order - a.order)) {
|
|
1231
|
-
actions.push(...stateNode.exit);
|
|
1232
|
-
}
|
|
1233
|
-
for (const child of Object.values(nextState.children)) {
|
|
1234
|
-
actions.push(stop(child));
|
|
1235
|
-
}
|
|
1236
|
-
return resolveActionsAndContext(nextState, event, actorCtx, actions);
|
|
1201
|
+
function stopChildren(nextState, event, actorCtx) {
|
|
1202
|
+
return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
|
|
1237
1203
|
}
|
|
1238
1204
|
function selectTransitions(event, nextState) {
|
|
1239
1205
|
return nextState.machine.getTransitionData(nextState, event);
|
|
@@ -1339,11 +1305,9 @@ class State {
|
|
|
1339
1305
|
this.error = void 0;
|
|
1340
1306
|
this.context = void 0;
|
|
1341
1307
|
this.historyValue = {};
|
|
1342
|
-
this._internalQueue = void 0;
|
|
1343
1308
|
this.configuration = void 0;
|
|
1344
1309
|
this.children = void 0;
|
|
1345
1310
|
this.context = config.context;
|
|
1346
|
-
this._internalQueue = config._internalQueue ?? [];
|
|
1347
1311
|
this.historyValue = config.historyValue || {};
|
|
1348
1312
|
this.matches = this.matches.bind(this);
|
|
1349
1313
|
this.toStrings = this.toStrings.bind(this);
|
|
@@ -1445,11 +1409,15 @@ function getPersistedState(state) {
|
|
|
1445
1409
|
tags,
|
|
1446
1410
|
machine,
|
|
1447
1411
|
children,
|
|
1412
|
+
context,
|
|
1448
1413
|
...jsonValues
|
|
1449
1414
|
} = state;
|
|
1450
1415
|
const childrenJson = {};
|
|
1451
1416
|
for (const id in children) {
|
|
1452
1417
|
const child = children[id];
|
|
1418
|
+
if (typeof child.src !== 'string') {
|
|
1419
|
+
throw new Error('An inline child actor cannot be persisted.');
|
|
1420
|
+
}
|
|
1453
1421
|
childrenJson[id] = {
|
|
1454
1422
|
state: child.getPersistedState?.(),
|
|
1455
1423
|
src: child.src
|
|
@@ -1457,14 +1425,45 @@ function getPersistedState(state) {
|
|
|
1457
1425
|
}
|
|
1458
1426
|
return {
|
|
1459
1427
|
...jsonValues,
|
|
1428
|
+
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1429
|
+
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1430
|
+
context: persistContext(context),
|
|
1460
1431
|
children: childrenJson
|
|
1461
1432
|
};
|
|
1462
1433
|
}
|
|
1434
|
+
function persistContext(contextPart) {
|
|
1435
|
+
let copy;
|
|
1436
|
+
for (const key in contextPart) {
|
|
1437
|
+
const value = contextPart[key];
|
|
1438
|
+
if (value && typeof value === 'object') {
|
|
1439
|
+
if ('sessionId' in value && 'send' in value && 'ref' in value) {
|
|
1440
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
|
|
1441
|
+
...contextPart
|
|
1442
|
+
};
|
|
1443
|
+
copy[key] = {
|
|
1444
|
+
xstate$$type: $$ACTOR_TYPE,
|
|
1445
|
+
id: value.id
|
|
1446
|
+
};
|
|
1447
|
+
} else {
|
|
1448
|
+
const result = persistContext(value);
|
|
1449
|
+
if (result !== value) {
|
|
1450
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
|
|
1451
|
+
...contextPart
|
|
1452
|
+
};
|
|
1453
|
+
copy[key] = result;
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
return copy ?? contextPart;
|
|
1459
|
+
}
|
|
1463
1460
|
|
|
1464
1461
|
function resolveRaise(_, state, args, {
|
|
1465
1462
|
event: eventOrExpr,
|
|
1466
1463
|
id,
|
|
1467
1464
|
delay
|
|
1465
|
+
}, {
|
|
1466
|
+
internalQueue
|
|
1468
1467
|
}) {
|
|
1469
1468
|
const delaysMap = state.machine.implementations.delays;
|
|
1470
1469
|
if (typeof eventOrExpr === 'string') {
|
|
@@ -1478,9 +1477,10 @@ function resolveRaise(_, state, args, {
|
|
|
1478
1477
|
} else {
|
|
1479
1478
|
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1480
1479
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
}
|
|
1480
|
+
if (typeof resolvedDelay !== 'number') {
|
|
1481
|
+
internalQueue.push(resolvedEvent);
|
|
1482
|
+
}
|
|
1483
|
+
return [state, {
|
|
1484
1484
|
event: resolvedEvent,
|
|
1485
1485
|
id,
|
|
1486
1486
|
delay: resolvedDelay
|
|
@@ -1513,4 +1513,4 @@ function raise(eventOrExpr, options) {
|
|
|
1513
1513
|
return raise;
|
|
1514
1514
|
}
|
|
1515
1515
|
|
|
1516
|
-
export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o,
|
|
1516
|
+
export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
|