xstate 5.0.0-beta.33 → 5.0.0-beta.35
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 +3 -3
- package/actors/dist/xstate-actors.development.cjs.js +3 -3
- package/actors/dist/xstate-actors.development.esm.js +3 -3
- package/actors/dist/xstate-actors.esm.js +3 -3
- 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/index.d.ts +1 -0
- package/dist/declarations/src/interpreter.d.ts +3 -1
- package/dist/declarations/src/stateUtils.d.ts +6 -5
- package/dist/declarations/src/types.d.ts +3 -5
- package/dist/{interpreter-825f3d6e.development.esm.js → interpreter-5c4e6634.development.esm.js} +67 -65
- package/dist/{interpreter-054e9fb7.cjs.js → interpreter-69605bf0.cjs.js} +67 -65
- package/dist/{interpreter-0c630f66.development.cjs.js → interpreter-d3567419.development.cjs.js} +67 -65
- package/dist/{interpreter-03737810.esm.js → interpreter-de5217bc.esm.js} +67 -65
- package/dist/{raise-987c242e.cjs.js → raise-0ff57677.cjs.js} +142 -124
- package/dist/{raise-4c6a5a96.development.cjs.js → raise-26e4d83c.development.cjs.js} +145 -124
- package/dist/{raise-2d92eae8.esm.js → raise-511399cc.esm.js} +142 -124
- package/dist/{raise-46f122aa.development.esm.js → raise-cdcdf834.development.esm.js} +145 -124
- package/dist/{send-bd1bd0e3.cjs.js → send-19ffc568.cjs.js} +16 -8
- package/dist/{send-4d5b92dc.development.esm.js → send-1de74f4d.development.esm.js} +16 -8
- package/dist/{send-0edee2b4.esm.js → send-211a2a94.esm.js} +16 -8
- package/dist/{send-0e8675c8.development.cjs.js → send-894c4b18.development.cjs.js} +16 -8
- package/dist/xstate.cjs.js +28 -9
- package/dist/xstate.development.cjs.js +28 -9
- package/dist/xstate.development.esm.js +31 -12
- package/dist/xstate.esm.js +31 -12
- 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,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var interpreter = require('./interpreter-
|
|
3
|
+
var interpreter = require('./interpreter-d3567419.development.cjs.js');
|
|
4
4
|
|
|
5
5
|
const cache = new WeakMap();
|
|
6
6
|
function memo(object, key, fn) {
|
|
@@ -299,20 +299,6 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
299
299
|
);
|
|
300
300
|
}
|
|
301
301
|
|
|
302
|
-
function getOutput(configuration, context, event, self) {
|
|
303
|
-
const {
|
|
304
|
-
machine
|
|
305
|
-
} = configuration[0];
|
|
306
|
-
const {
|
|
307
|
-
root
|
|
308
|
-
} = machine;
|
|
309
|
-
if (!root.output) {
|
|
310
|
-
return undefined;
|
|
311
|
-
}
|
|
312
|
-
const finalChildStateNode = configuration.find(stateNode => stateNode.type === 'final' && stateNode.parent === machine.root);
|
|
313
|
-
const doneStateEvent = interpreter.createDoneStateEvent(finalChildStateNode.id, finalChildStateNode.output ? interpreter.resolveOutput(finalChildStateNode.output, context, event, self) : undefined);
|
|
314
|
-
return interpreter.resolveOutput(root.output, context, doneStateEvent, self);
|
|
315
|
-
}
|
|
316
302
|
const isAtomicStateNode = stateNode => stateNode.type === 'atomic' || stateNode.type === 'final';
|
|
317
303
|
function getChildren(stateNode) {
|
|
318
304
|
return Object.values(stateNode.states).filter(sn => sn.type !== 'history');
|
|
@@ -337,7 +323,7 @@ function getConfiguration(stateNodes) {
|
|
|
337
323
|
for (const s of configuration) {
|
|
338
324
|
// if previously active, add existing child nodes
|
|
339
325
|
if (s.type === 'compound' && (!adjList.get(s) || !adjList.get(s).length)) {
|
|
340
|
-
|
|
326
|
+
getInitialStateNodesWithTheirAncestors(s).forEach(sn => configurationSet.add(sn));
|
|
341
327
|
} else {
|
|
342
328
|
if (s.type === 'parallel') {
|
|
343
329
|
for (const child of getChildren(s)) {
|
|
@@ -345,7 +331,8 @@ function getConfiguration(stateNodes) {
|
|
|
345
331
|
continue;
|
|
346
332
|
}
|
|
347
333
|
if (!configurationSet.has(child)) {
|
|
348
|
-
|
|
334
|
+
const initialStates = getInitialStateNodesWithTheirAncestors(child);
|
|
335
|
+
for (const initialStateNode of initialStates) {
|
|
349
336
|
configurationSet.add(initialStateNode);
|
|
350
337
|
}
|
|
351
338
|
}
|
|
@@ -405,14 +392,14 @@ function getStateValue(rootNode, configuration) {
|
|
|
405
392
|
const config = getConfiguration(configuration);
|
|
406
393
|
return getValueFromAdj(rootNode, getAdjList(config));
|
|
407
394
|
}
|
|
408
|
-
function isInFinalState(configuration, stateNode
|
|
395
|
+
function isInFinalState(configuration, stateNode) {
|
|
409
396
|
if (stateNode.type === 'compound') {
|
|
410
|
-
return getChildren(stateNode).some(s => s.type === 'final' && configuration.
|
|
397
|
+
return getChildren(stateNode).some(s => s.type === 'final' && configuration.has(s));
|
|
411
398
|
}
|
|
412
399
|
if (stateNode.type === 'parallel') {
|
|
413
400
|
return getChildren(stateNode).every(sn => isInFinalState(configuration, sn));
|
|
414
401
|
}
|
|
415
|
-
return
|
|
402
|
+
return stateNode.type === 'final';
|
|
416
403
|
}
|
|
417
404
|
const isStateId = str => str[0] === interpreter.STATE_IDENTIFIER;
|
|
418
405
|
function getCandidates(stateNode, receivedEventType) {
|
|
@@ -468,13 +455,7 @@ function getDelayedTransitions(stateNode) {
|
|
|
468
455
|
stateNode.exit.push(cancel(eventType));
|
|
469
456
|
return eventType;
|
|
470
457
|
};
|
|
471
|
-
const delayedTransitions =
|
|
472
|
-
const eventType = mutateEntryExit(transition.delay, i);
|
|
473
|
-
return {
|
|
474
|
-
...transition,
|
|
475
|
-
event: eventType
|
|
476
|
-
};
|
|
477
|
-
}) : Object.keys(afterConfig).flatMap((delay, i) => {
|
|
458
|
+
const delayedTransitions = Object.keys(afterConfig).flatMap((delay, i) => {
|
|
478
459
|
const configTransition = afterConfig[delay];
|
|
479
460
|
const resolvedTransition = typeof configTransition === 'string' ? {
|
|
480
461
|
target: configTransition
|
|
@@ -562,43 +543,23 @@ function formatTransitions(stateNode) {
|
|
|
562
543
|
return transitions;
|
|
563
544
|
}
|
|
564
545
|
function formatInitialTransition(stateNode, _target) {
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
// to their state node
|
|
569
|
-
const descStateNode = typeof t === 'string' ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
|
|
570
|
-
if (!descStateNode) {
|
|
571
|
-
throw new Error(`Initial state node "${t}" not found on parent state node #${stateNode.id}`);
|
|
572
|
-
}
|
|
573
|
-
if (!isDescendant(descStateNode, stateNode)) {
|
|
574
|
-
throw new Error(`Invalid initial target: state node #${descStateNode.id} is not a descendant of #${stateNode.id}`);
|
|
575
|
-
}
|
|
576
|
-
return descStateNode;
|
|
577
|
-
});
|
|
578
|
-
const resolvedTarget = resolveTarget(stateNode, targets);
|
|
579
|
-
const transition = {
|
|
580
|
-
source: stateNode,
|
|
581
|
-
actions: [],
|
|
582
|
-
eventType: null,
|
|
583
|
-
reenter: false,
|
|
584
|
-
target: resolvedTarget,
|
|
585
|
-
toJSON: () => ({
|
|
586
|
-
...transition,
|
|
587
|
-
source: `#${stateNode.id}`,
|
|
588
|
-
target: resolvedTarget ? resolvedTarget.map(t => `#${t.id}`) : undefined
|
|
589
|
-
})
|
|
590
|
-
};
|
|
591
|
-
return transition;
|
|
546
|
+
const resolvedTarget = typeof _target === 'string' ? stateNode.states[_target] : _target ? stateNode.states[_target.target] : undefined;
|
|
547
|
+
if (!resolvedTarget && _target) {
|
|
548
|
+
throw new Error(`Initial state node "${_target}" not found on parent state node #${stateNode.id}`);
|
|
592
549
|
}
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
550
|
+
const transition = {
|
|
551
|
+
source: stateNode,
|
|
552
|
+
actions: !_target || typeof _target === 'string' ? [] : interpreter.toArray(_target.actions),
|
|
553
|
+
eventType: null,
|
|
554
|
+
reenter: false,
|
|
555
|
+
target: resolvedTarget ? [resolvedTarget] : [],
|
|
556
|
+
toJSON: () => ({
|
|
557
|
+
...transition,
|
|
558
|
+
source: `#${stateNode.id}`,
|
|
559
|
+
target: resolvedTarget ? [`#${resolvedTarget.id}`] : []
|
|
560
|
+
})
|
|
561
|
+
};
|
|
562
|
+
return transition;
|
|
602
563
|
}
|
|
603
564
|
function resolveTarget(stateNode, targets) {
|
|
604
565
|
if (targets === undefined) {
|
|
@@ -641,6 +602,15 @@ function resolveHistoryTarget(stateNode) {
|
|
|
641
602
|
function isHistoryNode(stateNode) {
|
|
642
603
|
return stateNode.type === 'history';
|
|
643
604
|
}
|
|
605
|
+
function getInitialStateNodesWithTheirAncestors(stateNode) {
|
|
606
|
+
const states = getInitialStateNodes(stateNode);
|
|
607
|
+
for (const initialState of states) {
|
|
608
|
+
for (const ancestor of getProperAncestors(initialState, stateNode)) {
|
|
609
|
+
states.add(ancestor);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return states;
|
|
613
|
+
}
|
|
644
614
|
function getInitialStateNodes(stateNode) {
|
|
645
615
|
const set = new Set();
|
|
646
616
|
function iter(descStateNode) {
|
|
@@ -649,12 +619,7 @@ function getInitialStateNodes(stateNode) {
|
|
|
649
619
|
}
|
|
650
620
|
set.add(descStateNode);
|
|
651
621
|
if (descStateNode.type === 'compound') {
|
|
652
|
-
|
|
653
|
-
for (const a of getProperAncestors(targetStateNode, stateNode)) {
|
|
654
|
-
set.add(a);
|
|
655
|
-
}
|
|
656
|
-
iter(targetStateNode);
|
|
657
|
-
}
|
|
622
|
+
iter(descStateNode.initial.target[0]);
|
|
658
623
|
} else if (descStateNode.type === 'parallel') {
|
|
659
624
|
for (const child of getChildren(descStateNode)) {
|
|
660
625
|
iter(child);
|
|
@@ -662,7 +627,7 @@ function getInitialStateNodes(stateNode) {
|
|
|
662
627
|
}
|
|
663
628
|
}
|
|
664
629
|
iter(stateNode);
|
|
665
|
-
return
|
|
630
|
+
return set;
|
|
666
631
|
}
|
|
667
632
|
/**
|
|
668
633
|
* Returns the child state node from its relative `stateKey`, or throws.
|
|
@@ -918,41 +883,37 @@ function microstep(transitions, currentState, actorCtx, event, isInitial) {
|
|
|
918
883
|
}
|
|
919
884
|
|
|
920
885
|
function microstepProcedure(transitions, currentState, mutConfiguration, event, actorCtx, isInitial) {
|
|
921
|
-
const actions = [];
|
|
922
886
|
const historyValue = {
|
|
923
887
|
...currentState.historyValue
|
|
924
888
|
};
|
|
925
889
|
const filteredTransitions = removeConflictingTransitions(transitions, mutConfiguration, historyValue);
|
|
926
890
|
const internalQueue = [...currentState._internalQueue];
|
|
891
|
+
// TODO: this `cloneState` is really just a hack to prevent infinite loops
|
|
892
|
+
// we need to take another look at how internal queue is managed
|
|
893
|
+
let nextState = cloneState(currentState, {
|
|
894
|
+
_internalQueue: []
|
|
895
|
+
});
|
|
927
896
|
|
|
928
897
|
// Exit states
|
|
929
898
|
if (!isInitial) {
|
|
930
|
-
exitStates(filteredTransitions, mutConfiguration, historyValue
|
|
899
|
+
nextState = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue);
|
|
931
900
|
}
|
|
932
901
|
|
|
933
902
|
// Execute transition content
|
|
934
|
-
|
|
903
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions));
|
|
935
904
|
|
|
936
905
|
// Enter states
|
|
937
|
-
enterStates(event, filteredTransitions, mutConfiguration,
|
|
906
|
+
nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
|
|
938
907
|
const nextConfiguration = [...mutConfiguration];
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
const finalActions = nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit);
|
|
942
|
-
actions.push(...finalActions);
|
|
908
|
+
if (nextState.status === 'done') {
|
|
909
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit));
|
|
943
910
|
}
|
|
944
911
|
try {
|
|
945
|
-
const nextState = resolveActionsAndContext(actions, event, currentState, actorCtx);
|
|
946
|
-
const output = done ? getOutput(nextConfiguration, nextState.context, event, actorCtx.self) : undefined;
|
|
947
912
|
internalQueue.push(...nextState._internalQueue);
|
|
948
|
-
return cloneState(
|
|
913
|
+
return cloneState(nextState, {
|
|
949
914
|
configuration: nextConfiguration,
|
|
950
915
|
historyValue,
|
|
951
|
-
_internalQueue: internalQueue
|
|
952
|
-
context: nextState.context,
|
|
953
|
-
status: done ? 'done' : currentState.status,
|
|
954
|
-
output,
|
|
955
|
-
children: nextState.children
|
|
916
|
+
_internalQueue: internalQueue
|
|
956
917
|
});
|
|
957
918
|
} catch (e) {
|
|
958
919
|
// TODO: Refactor this once proper error handling is implemented.
|
|
@@ -960,7 +921,15 @@ function microstepProcedure(transitions, currentState, mutConfiguration, event,
|
|
|
960
921
|
throw e;
|
|
961
922
|
}
|
|
962
923
|
}
|
|
963
|
-
function
|
|
924
|
+
function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
|
|
925
|
+
if (!rootNode.output) {
|
|
926
|
+
return;
|
|
927
|
+
}
|
|
928
|
+
const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
|
|
929
|
+
return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
|
|
930
|
+
}
|
|
931
|
+
function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
932
|
+
let nextState = currentState;
|
|
964
933
|
const statesToEnter = new Set();
|
|
965
934
|
const statesForDefaultEntry = new Set();
|
|
966
935
|
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
@@ -969,36 +938,48 @@ function enterStates(event, filteredTransitions, mutConfiguration, actions, inte
|
|
|
969
938
|
if (isInitial) {
|
|
970
939
|
statesForDefaultEntry.add(currentState.machine.root);
|
|
971
940
|
}
|
|
941
|
+
const completedNodes = new Set();
|
|
972
942
|
for (const stateNodeToEnter of [...statesToEnter].sort((a, b) => a.order - b.order)) {
|
|
973
943
|
mutConfiguration.add(stateNodeToEnter);
|
|
974
|
-
|
|
975
|
-
actions.push(invoke(invokeDef));
|
|
976
|
-
}
|
|
944
|
+
const actions = [];
|
|
977
945
|
|
|
978
946
|
// Add entry actions
|
|
979
947
|
actions.push(...stateNodeToEnter.entry);
|
|
948
|
+
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
949
|
+
actions.push(invoke(invokeDef));
|
|
950
|
+
}
|
|
980
951
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
actions.push(...initialActions);
|
|
984
|
-
}
|
|
952
|
+
const initialActions = stateNodeToEnter.initial.actions;
|
|
953
|
+
actions.push(...initialActions);
|
|
985
954
|
}
|
|
955
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
986
956
|
if (stateNodeToEnter.type === 'final') {
|
|
987
957
|
const parent = stateNodeToEnter.parent;
|
|
988
|
-
if (
|
|
958
|
+
if (completedNodes.has(parent)) {
|
|
989
959
|
continue;
|
|
990
960
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
961
|
+
completedNodes.add(parent);
|
|
962
|
+
let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
|
|
963
|
+
let ancestorMarker = parent?.parent;
|
|
964
|
+
if (ancestorMarker) {
|
|
965
|
+
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
|
|
966
|
+
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
967
|
+
completedNodes.add(ancestorMarker);
|
|
968
|
+
internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
|
|
969
|
+
rootCompletionNode = ancestorMarker;
|
|
970
|
+
ancestorMarker = ancestorMarker.parent;
|
|
998
971
|
}
|
|
999
972
|
}
|
|
973
|
+
if (ancestorMarker) {
|
|
974
|
+
continue;
|
|
975
|
+
}
|
|
976
|
+
nextState = cloneState(nextState, {
|
|
977
|
+
status: 'done',
|
|
978
|
+
output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
|
|
979
|
+
});
|
|
1000
980
|
}
|
|
1001
981
|
}
|
|
982
|
+
return nextState;
|
|
1002
983
|
}
|
|
1003
984
|
function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
|
|
1004
985
|
for (const t of transitions) {
|
|
@@ -1041,13 +1022,9 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1041
1022
|
statesToEnter.add(stateNode);
|
|
1042
1023
|
if (stateNode.type === 'compound') {
|
|
1043
1024
|
statesForDefaultEntry.add(stateNode);
|
|
1044
|
-
const
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
}
|
|
1048
|
-
for (const initialState of initialStates) {
|
|
1049
|
-
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1050
|
-
}
|
|
1025
|
+
const [initialState] = stateNode.initial.target;
|
|
1026
|
+
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1027
|
+
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1051
1028
|
} else {
|
|
1052
1029
|
if (stateNode.type === 'parallel') {
|
|
1053
1030
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
@@ -1072,7 +1049,8 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1072
1049
|
}
|
|
1073
1050
|
}
|
|
1074
1051
|
}
|
|
1075
|
-
function exitStates(transitions, mutConfiguration, historyValue
|
|
1052
|
+
function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue) {
|
|
1053
|
+
let nextState = currentState;
|
|
1076
1054
|
const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
|
|
1077
1055
|
statesToExit.sort((a, b) => b.order - a.order);
|
|
1078
1056
|
|
|
@@ -1091,19 +1069,16 @@ function exitStates(transitions, mutConfiguration, historyValue, actions) {
|
|
|
1091
1069
|
}
|
|
1092
1070
|
}
|
|
1093
1071
|
for (const s of statesToExit) {
|
|
1094
|
-
|
|
1072
|
+
nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))]);
|
|
1095
1073
|
mutConfiguration.delete(s);
|
|
1096
1074
|
}
|
|
1075
|
+
return nextState;
|
|
1097
1076
|
}
|
|
1098
|
-
function
|
|
1077
|
+
function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
|
|
1099
1078
|
const {
|
|
1100
1079
|
machine
|
|
1101
1080
|
} = currentState;
|
|
1102
|
-
|
|
1103
|
-
// we need to take another look at how internal queue is managed
|
|
1104
|
-
let intermediateState = cloneState(currentState, {
|
|
1105
|
-
_internalQueue: []
|
|
1106
|
-
});
|
|
1081
|
+
let intermediateState = currentState;
|
|
1107
1082
|
for (const action of actions) {
|
|
1108
1083
|
const isInline = typeof action === 'function';
|
|
1109
1084
|
const resolvedAction = isInline ? action :
|
|
@@ -1142,11 +1117,14 @@ function resolveActionsAndContext(actions, event, currentState, actorCtx) {
|
|
|
1142
1117
|
continue;
|
|
1143
1118
|
}
|
|
1144
1119
|
const builtinAction = resolvedAction;
|
|
1145
|
-
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction
|
|
1146
|
-
|
|
1147
|
-
|
|
1120
|
+
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
|
|
1121
|
+
// this holds all params
|
|
1122
|
+
extra);
|
|
1148
1123
|
intermediateState = nextState;
|
|
1149
|
-
if ('
|
|
1124
|
+
if ('retryResolve' in builtinAction) {
|
|
1125
|
+
retries?.push([builtinAction, params]);
|
|
1126
|
+
}
|
|
1127
|
+
if ('execute' in builtinAction) {
|
|
1150
1128
|
if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
|
|
1151
1129
|
builtinAction.execute(actorCtx, params);
|
|
1152
1130
|
} else {
|
|
@@ -1154,11 +1132,21 @@ function resolveActionsAndContext(actions, event, currentState, actorCtx) {
|
|
|
1154
1132
|
}
|
|
1155
1133
|
}
|
|
1156
1134
|
if (actions) {
|
|
1157
|
-
intermediateState =
|
|
1135
|
+
intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorCtx, actions, extra, retries);
|
|
1158
1136
|
}
|
|
1159
1137
|
}
|
|
1160
1138
|
return intermediateState;
|
|
1161
1139
|
}
|
|
1140
|
+
function resolveActionsAndContext(currentState, event, actorCtx, actions, deferredActorIds) {
|
|
1141
|
+
const retries = deferredActorIds ? [] : undefined;
|
|
1142
|
+
const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, deferredActorIds && {
|
|
1143
|
+
deferredActorIds
|
|
1144
|
+
}, retries);
|
|
1145
|
+
retries?.forEach(([builtinAction, params]) => {
|
|
1146
|
+
builtinAction.retryResolve(actorCtx, nextState, params);
|
|
1147
|
+
});
|
|
1148
|
+
return nextState;
|
|
1149
|
+
}
|
|
1162
1150
|
function macrostep(state, event, actorCtx) {
|
|
1163
1151
|
if (event.type === interpreter.WILDCARD) {
|
|
1164
1152
|
throw new Error(`An event cannot have the wildcard type ('${interpreter.WILDCARD}')`);
|
|
@@ -1218,7 +1206,7 @@ function stopStep(event, nextState, actorCtx) {
|
|
|
1218
1206
|
for (const child of Object.values(nextState.children)) {
|
|
1219
1207
|
actions.push(stop(child));
|
|
1220
1208
|
}
|
|
1221
|
-
return resolveActionsAndContext(
|
|
1209
|
+
return resolveActionsAndContext(nextState, event, actorCtx, actions);
|
|
1222
1210
|
}
|
|
1223
1211
|
function selectTransitions(event, nextState) {
|
|
1224
1212
|
return nextState.machine.getTransitionData(nextState, event);
|
|
@@ -1430,11 +1418,15 @@ function getPersistedState(state) {
|
|
|
1430
1418
|
tags,
|
|
1431
1419
|
machine,
|
|
1432
1420
|
children,
|
|
1421
|
+
context,
|
|
1433
1422
|
...jsonValues
|
|
1434
1423
|
} = state;
|
|
1435
1424
|
const childrenJson = {};
|
|
1436
1425
|
for (const id in children) {
|
|
1437
1426
|
const child = children[id];
|
|
1427
|
+
if (typeof child.src !== 'string') {
|
|
1428
|
+
throw new Error('An inline child actor cannot be persisted.');
|
|
1429
|
+
}
|
|
1438
1430
|
childrenJson[id] = {
|
|
1439
1431
|
state: child.getPersistedState?.(),
|
|
1440
1432
|
src: child.src
|
|
@@ -1442,9 +1434,38 @@ function getPersistedState(state) {
|
|
|
1442
1434
|
}
|
|
1443
1435
|
return {
|
|
1444
1436
|
...jsonValues,
|
|
1437
|
+
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1438
|
+
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1439
|
+
context: persistContext(context),
|
|
1445
1440
|
children: childrenJson
|
|
1446
1441
|
};
|
|
1447
1442
|
}
|
|
1443
|
+
function persistContext(contextPart) {
|
|
1444
|
+
let copy;
|
|
1445
|
+
for (const key in contextPart) {
|
|
1446
|
+
const value = contextPart[key];
|
|
1447
|
+
if (value && typeof value === 'object') {
|
|
1448
|
+
if ('sessionId' in value && 'send' in value && 'ref' in value) {
|
|
1449
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
|
|
1450
|
+
...contextPart
|
|
1451
|
+
};
|
|
1452
|
+
copy[key] = {
|
|
1453
|
+
xstate$$type: interpreter.$$ACTOR_TYPE,
|
|
1454
|
+
id: value.id
|
|
1455
|
+
};
|
|
1456
|
+
} else {
|
|
1457
|
+
const result = persistContext(value);
|
|
1458
|
+
if (result !== value) {
|
|
1459
|
+
copy ??= Array.isArray(contextPart) ? contextPart.slice() : {
|
|
1460
|
+
...contextPart
|
|
1461
|
+
};
|
|
1462
|
+
copy[key] = result;
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return copy ?? contextPart;
|
|
1468
|
+
}
|
|
1448
1469
|
|
|
1449
1470
|
function resolveRaise(_, state, args, {
|
|
1450
1471
|
event: eventOrExpr,
|
|
@@ -1510,10 +1531,10 @@ exports.getCandidates = getCandidates;
|
|
|
1510
1531
|
exports.getConfiguration = getConfiguration;
|
|
1511
1532
|
exports.getDelayedTransitions = getDelayedTransitions;
|
|
1512
1533
|
exports.getInitialConfiguration = getInitialConfiguration;
|
|
1534
|
+
exports.getInitialStateNodes = getInitialStateNodes;
|
|
1513
1535
|
exports.getPersistedState = getPersistedState;
|
|
1514
1536
|
exports.getStateNodeByPath = getStateNodeByPath;
|
|
1515
1537
|
exports.getStateNodes = getStateNodes;
|
|
1516
|
-
exports.isAtomicStateNode = isAtomicStateNode;
|
|
1517
1538
|
exports.isInFinalState = isInFinalState;
|
|
1518
1539
|
exports.isStateId = isStateId;
|
|
1519
1540
|
exports.macrostep = macrostep;
|