xstate 6.0.0-alpha.21 → 6.0.0-alpha.22
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/dist/{StateMachine-550ff7f2.development.cjs.js → StateMachine-1888d034.development.cjs.js} +178 -27
- package/dist/{StateMachine-1b155670.cjs.js → StateMachine-610fe929.cjs.js} +178 -27
- package/dist/{StateMachine-e25dd61f.development.esm.js → StateMachine-9fad7a2b.development.esm.js} +174 -28
- package/dist/{StateMachine-3c17fe3e.esm.js → StateMachine-ddb5d007.esm.js} +174 -28
- package/dist/declarations/src/State.d.ts +4 -2
- package/dist/declarations/src/StateMachine.d.ts +5 -4
- package/dist/declarations/src/actions.d.ts +10 -8
- package/dist/declarations/src/actors/logic.d.ts +5 -21
- package/dist/declarations/src/createActor.d.ts +3 -1
- package/dist/declarations/src/fsm.d.ts +3 -1
- package/dist/declarations/src/index.d.ts +2 -2
- package/dist/declarations/src/stateUtils.d.ts +1 -1
- package/dist/declarations/src/system.d.ts +34 -9
- package/dist/declarations/src/transitionActions.d.ts +5 -1
- package/dist/declarations/src/types.d.ts +70 -51
- package/dist/{index-3f87408c.esm.js → index-2fe11873.esm.js} +782 -389
- package/dist/{index-ec7c7a2d.development.cjs.js → index-41c0375c.development.cjs.js} +790 -390
- package/dist/{index-e694228c.cjs.js → index-434fac23.cjs.js} +789 -389
- package/dist/{index-d39fb138.development.esm.js → index-44d8c2d1.development.esm.js} +783 -390
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +1 -1
- package/dist/xstate-actors.esm.js +1 -1
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +2 -2
- package/dist/xstate-graph.development.cjs.js +2 -2
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +82 -101
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +82 -101
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +80 -100
- package/dist/xstate.esm.js +80 -100
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/{StateMachine-e25dd61f.development.esm.js → StateMachine-9fad7a2b.development.esm.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as
|
|
1
|
+
import { M as resolveReferencedActor, N as setSnapshotActorRef, O as getSnapshotActorRef, P as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, Q as mapValues, t as toArray, R as createInvokeId, U as getDelayedTransitions, V as evaluateCandidate, W as formatTransition, Y as NULL_EVENT, Z as toTransitionConfigArray, _ as createInvokeTimeoutEvent, $ as getCandidates, a0 as formatRouteTransitions, a1 as resolveStateValue, a2 as getAllStateNodes, s as getStateNodes, a3 as createMachineSnapshot, a4 as isInFinalState, j as macrostep, a5 as cloneMachineSnapshot, a6 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a7 as getTransitionResult, a8 as hasEffect, a9 as createErrorPlatformEvent, r as resolveActionsWithContext, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, aa as toStatePath, ab as isStateId, ac as getStateNodeByPath, ad as getPersistedSnapshot, ae as $$ACTOR_TYPE } from './index-44d8c2d1.development.esm.js';
|
|
2
2
|
|
|
3
3
|
function createSpawner(actorScope, {
|
|
4
4
|
machine,
|
|
@@ -10,7 +10,7 @@ function createSpawner(actorScope, {
|
|
|
10
10
|
if (!logic) {
|
|
11
11
|
throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
|
|
12
12
|
}
|
|
13
|
-
const actor =
|
|
13
|
+
const actor = actorScope.system.createActorRef(logic, {
|
|
14
14
|
id: options?.id,
|
|
15
15
|
parent: actorScope.self,
|
|
16
16
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -25,7 +25,7 @@ function createSpawner(actorScope, {
|
|
|
25
25
|
spawnedChildren[actor.id] = actor;
|
|
26
26
|
return actor;
|
|
27
27
|
} else {
|
|
28
|
-
const actor =
|
|
28
|
+
const actor = actorScope.system.createActorRef(src, {
|
|
29
29
|
id: options?.id,
|
|
30
30
|
parent: actorScope.self,
|
|
31
31
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -39,16 +39,114 @@ function createSpawner(actorScope, {
|
|
|
39
39
|
return (src, options) => {
|
|
40
40
|
const actor = spawn(src, options); // TODO: fix types
|
|
41
41
|
spawnedChildren[actor.id] = actor;
|
|
42
|
-
actorScope.defer(() => {
|
|
43
|
-
if (actor._processingStatus === ProcessingStatus.Stopped) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
actor.start();
|
|
47
|
-
});
|
|
48
42
|
return actor;
|
|
49
43
|
};
|
|
50
44
|
}
|
|
51
45
|
|
|
46
|
+
/** @internal */
|
|
47
|
+
function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
|
|
48
|
+
actorScope.self._snapshot = snapshot;
|
|
49
|
+
if (attachActorRef && snapshot && typeof snapshot === 'object') {
|
|
50
|
+
setSnapshotActorRef(snapshot, actorScope.self);
|
|
51
|
+
}
|
|
52
|
+
return snapshot;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** @internal */
|
|
56
|
+
function isInertActorScope(actorScope) {
|
|
57
|
+
return !!actorScope.self.options?._inert;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @internal */
|
|
61
|
+
function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
|
|
62
|
+
const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
|
|
63
|
+
return setInertActorScopeSnapshot(snapshotScope, snapshot);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** @internal */
|
|
67
|
+
function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
68
|
+
const snapshotRef = snapshot ? getSnapshotActorRef(snapshot) : undefined;
|
|
69
|
+
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
70
|
+
const baseSystem = previousSelf?.system;
|
|
71
|
+
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, previousSelf, isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
72
|
+
const self = createActor(actorLogic, {
|
|
73
|
+
_inert: true,
|
|
74
|
+
...(previousSelf ? {
|
|
75
|
+
id: previousSelf.id
|
|
76
|
+
} : {}),
|
|
77
|
+
...(system ? {
|
|
78
|
+
_systemRef: {
|
|
79
|
+
current: system
|
|
80
|
+
}
|
|
81
|
+
} : {})
|
|
82
|
+
});
|
|
83
|
+
if (previousSelf?._parent) {
|
|
84
|
+
self._parent = previousSelf._parent;
|
|
85
|
+
}
|
|
86
|
+
if (snapshot) {
|
|
87
|
+
self._snapshot = snapshot;
|
|
88
|
+
}
|
|
89
|
+
const actorScope = {
|
|
90
|
+
self: self,
|
|
91
|
+
defer: () => {},
|
|
92
|
+
id: self.id,
|
|
93
|
+
logger: self.system._logger,
|
|
94
|
+
sessionId: self.sessionId,
|
|
95
|
+
stopChild: child => child._stop(),
|
|
96
|
+
system: self.system,
|
|
97
|
+
emit: event => self.system.emitEvent(self, event),
|
|
98
|
+
actionExecutor: () => {}
|
|
99
|
+
};
|
|
100
|
+
return actorScope;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @deprecated Use `initialTransition(…)` instead. */
|
|
104
|
+
function getInitialSnapshot(actorLogic, ...[input]) {
|
|
105
|
+
const actorScope = createInertActorScope(actorLogic);
|
|
106
|
+
return actorLogic.initialTransition(input, actorScope)[0];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Determines the next snapshot for the given `actorLogic` based on the given
|
|
111
|
+
* `snapshot` and `event`.
|
|
112
|
+
*
|
|
113
|
+
* If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
|
|
114
|
+
* used.
|
|
115
|
+
*
|
|
116
|
+
* @deprecated Use `transition(…)` instead.
|
|
117
|
+
* @example
|
|
118
|
+
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { getNextSnapshot } from 'xstate';
|
|
121
|
+
* import { trafficLightMachine } from './trafficLightMachine.ts';
|
|
122
|
+
*
|
|
123
|
+
* const nextSnapshot = getNextSnapshot(
|
|
124
|
+
* trafficLightMachine, // actor logic
|
|
125
|
+
* undefined, // snapshot (or initial state if undefined)
|
|
126
|
+
* { type: 'TIMER' }
|
|
127
|
+
* ); // event object
|
|
128
|
+
*
|
|
129
|
+
* console.log(nextSnapshot.value);
|
|
130
|
+
* // => 'yellow'
|
|
131
|
+
*
|
|
132
|
+
* const nextSnapshot2 = getNextSnapshot(
|
|
133
|
+
* trafficLightMachine, // actor logic
|
|
134
|
+
* nextSnapshot, // snapshot
|
|
135
|
+
* { type: 'TIMER' }
|
|
136
|
+
* ); // event object
|
|
137
|
+
*
|
|
138
|
+
* console.log(nextSnapshot2.value);
|
|
139
|
+
* // =>'red'
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
function getNextSnapshot(actorLogic, snapshot, event) {
|
|
143
|
+
const actorScope = createInertActorScope(actorLogic, snapshot);
|
|
144
|
+
const transitionResult = actorLogic.transition(snapshot, event, actorScope);
|
|
145
|
+
const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
|
|
146
|
+
setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
|
|
147
|
+
return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
|
|
148
|
+
}
|
|
149
|
+
|
|
52
150
|
const cache = new WeakMap();
|
|
53
151
|
function memo(object, key, fn) {
|
|
54
152
|
let memoizedData = cache.get(object);
|
|
@@ -570,19 +668,37 @@ class StateMachine {
|
|
|
570
668
|
* @param event The received event
|
|
571
669
|
*/
|
|
572
670
|
transition(snapshot, event, actorScope) {
|
|
573
|
-
const
|
|
671
|
+
const usesInertScope = !actorScope;
|
|
672
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
|
|
673
|
+
if (usesInertScope) {
|
|
674
|
+
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
675
|
+
}
|
|
676
|
+
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
574
677
|
if (fastSnapshot) {
|
|
575
|
-
|
|
678
|
+
if (usesInertScope) {
|
|
679
|
+
setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
|
|
680
|
+
}
|
|
681
|
+
const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
|
|
682
|
+
return [returnedSnapshot, []];
|
|
576
683
|
}
|
|
577
684
|
const {
|
|
578
685
|
snapshot: nextSnapshot,
|
|
579
686
|
microsteps
|
|
580
|
-
} = macrostep(snapshot, event,
|
|
581
|
-
|
|
687
|
+
} = macrostep(snapshot, event, resolvedActorScope, []);
|
|
688
|
+
if (usesInertScope) {
|
|
689
|
+
setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
|
|
690
|
+
}
|
|
691
|
+
const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
|
|
692
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
693
|
+
}
|
|
694
|
+
_collectEffects(microsteps) {
|
|
695
|
+
return microsteps.flatMap(([, actions]) => actions);
|
|
582
696
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
697
|
+
_attachPureActorRef(snapshot, actorScope) {
|
|
698
|
+
if (isInertActorScope(actorScope)) {
|
|
699
|
+
return snapshot;
|
|
700
|
+
}
|
|
701
|
+
return attachSnapshotActorRef(this, actorScope, snapshot);
|
|
586
702
|
}
|
|
587
703
|
_transitionFast(snapshot, event, actorScope) {
|
|
588
704
|
if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
|
|
@@ -643,6 +759,9 @@ class StateMachine {
|
|
|
643
759
|
return transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
|
|
644
760
|
}
|
|
645
761
|
isInternalEventType(eventType) {
|
|
762
|
+
if (eventType === XSTATE_TIMER) {
|
|
763
|
+
return true;
|
|
764
|
+
}
|
|
646
765
|
for (const descriptor of this.internalEventDescriptors) {
|
|
647
766
|
if (matchesEventDescriptor(eventType, descriptor)) {
|
|
648
767
|
return true;
|
|
@@ -709,7 +828,7 @@ class StateMachine {
|
|
|
709
828
|
_nodes: [this.root],
|
|
710
829
|
children: {},
|
|
711
830
|
status: 'active'
|
|
712
|
-
}, this);
|
|
831
|
+
}, this, actorScope.self);
|
|
713
832
|
if (typeof context === 'function') {
|
|
714
833
|
const children = {};
|
|
715
834
|
const spawn = createSpawner(actorScope, preInitial, initEvent, children);
|
|
@@ -742,30 +861,37 @@ class StateMachine {
|
|
|
742
861
|
return this.initialTransition(input, actorScope)[0];
|
|
743
862
|
}
|
|
744
863
|
initialTransition(input, actorScope) {
|
|
864
|
+
const usesInertScope = !actorScope;
|
|
865
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
745
866
|
const initEvent = createInitEvent(input); // TODO: fix;
|
|
746
867
|
const internalQueue = [];
|
|
747
|
-
const preInitialState = this._getPreInitialState(
|
|
868
|
+
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
869
|
+
const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => createSpawnEffect(actor));
|
|
748
870
|
let nextState;
|
|
749
871
|
let initialActions = [];
|
|
750
872
|
let microsteps = [];
|
|
751
873
|
let macroState;
|
|
752
874
|
try {
|
|
753
|
-
[nextState, initialActions] = initialMicrostep(this.root, preInitialState,
|
|
875
|
+
[nextState, initialActions] = initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
|
|
754
876
|
({
|
|
755
877
|
snapshot: macroState,
|
|
756
878
|
microsteps
|
|
757
|
-
} = macrostep(nextState, initEvent,
|
|
879
|
+
} = macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
|
|
758
880
|
} catch (err) {
|
|
759
881
|
if (!this.root.config.onError) {
|
|
760
882
|
throw err;
|
|
761
883
|
}
|
|
762
884
|
const errorEvent = createErrorPlatformEvent('execution', err);
|
|
763
|
-
const errorMacrostep = macrostep(preInitialState, errorEvent,
|
|
885
|
+
const errorMacrostep = macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
|
|
764
886
|
macroState = errorMacrostep.snapshot;
|
|
765
887
|
microsteps = errorMacrostep.microsteps;
|
|
766
888
|
initialActions = [];
|
|
767
889
|
}
|
|
768
|
-
|
|
890
|
+
if (usesInertScope) {
|
|
891
|
+
setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
|
|
892
|
+
}
|
|
893
|
+
const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
|
|
894
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
769
895
|
}
|
|
770
896
|
start(snapshot) {
|
|
771
897
|
// Start rehydrated children that were active when persisted. Freshly
|
|
@@ -793,7 +919,9 @@ class StateMachine {
|
|
|
793
919
|
getPersistedSnapshot(snapshot, options) {
|
|
794
920
|
return getPersistedSnapshot(snapshot, options);
|
|
795
921
|
}
|
|
796
|
-
restoreSnapshot(snapshot,
|
|
922
|
+
restoreSnapshot(snapshot, actorScope) {
|
|
923
|
+
const usesInertScope = !actorScope;
|
|
924
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
797
925
|
const persistedVersion = snapshot.version;
|
|
798
926
|
if (persistedVersion !== this.version) {
|
|
799
927
|
const migrate = this.config.migrate;
|
|
@@ -813,9 +941,9 @@ class StateMachine {
|
|
|
813
941
|
if (!logic) {
|
|
814
942
|
continue;
|
|
815
943
|
}
|
|
816
|
-
const actor =
|
|
944
|
+
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
817
945
|
id: actorId,
|
|
818
|
-
parent:
|
|
946
|
+
parent: resolvedActorScope.self,
|
|
819
947
|
syncSnapshot: actorData.syncSnapshot,
|
|
820
948
|
snapshot: childState,
|
|
821
949
|
src,
|
|
@@ -826,6 +954,19 @@ class StateMachine {
|
|
|
826
954
|
actor._rehydrated = true;
|
|
827
955
|
children[actorId] = actor;
|
|
828
956
|
}
|
|
957
|
+
const timers = {};
|
|
958
|
+
const persistedTimers = snapshotData.timers ?? {};
|
|
959
|
+
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
960
|
+
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
961
|
+
if (!target) {
|
|
962
|
+
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
963
|
+
throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
|
|
964
|
+
}
|
|
965
|
+
timers[id] = {
|
|
966
|
+
...timer,
|
|
967
|
+
target
|
|
968
|
+
};
|
|
969
|
+
}
|
|
829
970
|
const reviveHistoryValue = historyValue => {
|
|
830
971
|
if (!historyValue || typeof historyValue !== 'object') {
|
|
831
972
|
return {};
|
|
@@ -864,11 +1005,12 @@ class StateMachine {
|
|
|
864
1005
|
const restoredSnapshot = createMachineSnapshot({
|
|
865
1006
|
...persistedRest,
|
|
866
1007
|
children,
|
|
1008
|
+
timers,
|
|
867
1009
|
_nodes: nodes,
|
|
868
1010
|
value: snapshotData.value,
|
|
869
1011
|
historyValue: revivedHistoryValue,
|
|
870
1012
|
_stateInputs: snapshotData.stateInputs ?? {}
|
|
871
|
-
}, this);
|
|
1013
|
+
}, this, resolvedActorScope.self);
|
|
872
1014
|
const seen = new WeakSet();
|
|
873
1015
|
function reviveContext(contextPart) {
|
|
874
1016
|
if (seen.has(contextPart)) {
|
|
@@ -887,8 +1029,12 @@ class StateMachine {
|
|
|
887
1029
|
}
|
|
888
1030
|
}
|
|
889
1031
|
reviveContext(restoredSnapshot.context);
|
|
890
|
-
|
|
1032
|
+
if (usesInertScope) {
|
|
1033
|
+
setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
|
|
1034
|
+
return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
|
|
1035
|
+
}
|
|
1036
|
+
return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
|
|
891
1037
|
}
|
|
892
1038
|
}
|
|
893
1039
|
|
|
894
|
-
export { StateMachine as S,
|
|
1040
|
+
export { StateMachine as S, attachSnapshotActorRef as a, getNextSnapshot as b, createInertActorScope as c, StateNode as d, getInitialSnapshot as g, setInertActorScopeSnapshot as s };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as
|
|
1
|
+
import { M as resolveReferencedActor, N as setSnapshotActorRef, O as getSnapshotActorRef, P as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, Q as mapValues, t as toArray, R as createInvokeId, U as getDelayedTransitions, V as evaluateCandidate, W as formatTransition, Y as NULL_EVENT, Z as toTransitionConfigArray, _ as createInvokeTimeoutEvent, $ as getCandidates, a0 as formatRouteTransitions, a1 as resolveStateValue, a2 as getAllStateNodes, s as getStateNodes, a3 as createMachineSnapshot, a4 as isInFinalState, j as macrostep, a5 as cloneMachineSnapshot, a6 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a7 as getTransitionResult, a8 as hasEffect, a9 as createErrorPlatformEvent, r as resolveActionsWithContext, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, aa as toStatePath, ab as isStateId, ac as getStateNodeByPath, ad as getPersistedSnapshot, ae as $$ACTOR_TYPE } from './index-2fe11873.esm.js';
|
|
2
2
|
|
|
3
3
|
function createSpawner(actorScope, {
|
|
4
4
|
machine,
|
|
@@ -10,7 +10,7 @@ function createSpawner(actorScope, {
|
|
|
10
10
|
if (!logic) {
|
|
11
11
|
throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
|
|
12
12
|
}
|
|
13
|
-
const actor =
|
|
13
|
+
const actor = actorScope.system.createActorRef(logic, {
|
|
14
14
|
id: options?.id,
|
|
15
15
|
parent: actorScope.self,
|
|
16
16
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -25,7 +25,7 @@ function createSpawner(actorScope, {
|
|
|
25
25
|
spawnedChildren[actor.id] = actor;
|
|
26
26
|
return actor;
|
|
27
27
|
} else {
|
|
28
|
-
const actor =
|
|
28
|
+
const actor = actorScope.system.createActorRef(src, {
|
|
29
29
|
id: options?.id,
|
|
30
30
|
parent: actorScope.self,
|
|
31
31
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -39,16 +39,114 @@ function createSpawner(actorScope, {
|
|
|
39
39
|
return (src, options) => {
|
|
40
40
|
const actor = spawn(src, options); // TODO: fix types
|
|
41
41
|
spawnedChildren[actor.id] = actor;
|
|
42
|
-
actorScope.defer(() => {
|
|
43
|
-
if (actor._processingStatus === ProcessingStatus.Stopped) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
actor.start();
|
|
47
|
-
});
|
|
48
42
|
return actor;
|
|
49
43
|
};
|
|
50
44
|
}
|
|
51
45
|
|
|
46
|
+
/** @internal */
|
|
47
|
+
function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
|
|
48
|
+
actorScope.self._snapshot = snapshot;
|
|
49
|
+
if (attachActorRef && snapshot && typeof snapshot === 'object') {
|
|
50
|
+
setSnapshotActorRef(snapshot, actorScope.self);
|
|
51
|
+
}
|
|
52
|
+
return snapshot;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** @internal */
|
|
56
|
+
function isInertActorScope(actorScope) {
|
|
57
|
+
return !!actorScope.self.options?._inert;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @internal */
|
|
61
|
+
function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
|
|
62
|
+
const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
|
|
63
|
+
return setInertActorScopeSnapshot(snapshotScope, snapshot);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** @internal */
|
|
67
|
+
function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
68
|
+
const snapshotRef = snapshot ? getSnapshotActorRef(snapshot) : undefined;
|
|
69
|
+
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
70
|
+
const baseSystem = previousSelf?.system;
|
|
71
|
+
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, previousSelf, isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
72
|
+
const self = createActor(actorLogic, {
|
|
73
|
+
_inert: true,
|
|
74
|
+
...(previousSelf ? {
|
|
75
|
+
id: previousSelf.id
|
|
76
|
+
} : {}),
|
|
77
|
+
...(system ? {
|
|
78
|
+
_systemRef: {
|
|
79
|
+
current: system
|
|
80
|
+
}
|
|
81
|
+
} : {})
|
|
82
|
+
});
|
|
83
|
+
if (previousSelf?._parent) {
|
|
84
|
+
self._parent = previousSelf._parent;
|
|
85
|
+
}
|
|
86
|
+
if (snapshot) {
|
|
87
|
+
self._snapshot = snapshot;
|
|
88
|
+
}
|
|
89
|
+
const actorScope = {
|
|
90
|
+
self: self,
|
|
91
|
+
defer: () => {},
|
|
92
|
+
id: self.id,
|
|
93
|
+
logger: self.system._logger,
|
|
94
|
+
sessionId: self.sessionId,
|
|
95
|
+
stopChild: child => child._stop(),
|
|
96
|
+
system: self.system,
|
|
97
|
+
emit: event => self.system.emitEvent(self, event),
|
|
98
|
+
actionExecutor: () => {}
|
|
99
|
+
};
|
|
100
|
+
return actorScope;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** @deprecated Use `initialTransition(…)` instead. */
|
|
104
|
+
function getInitialSnapshot(actorLogic, ...[input]) {
|
|
105
|
+
const actorScope = createInertActorScope(actorLogic);
|
|
106
|
+
return actorLogic.initialTransition(input, actorScope)[0];
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Determines the next snapshot for the given `actorLogic` based on the given
|
|
111
|
+
* `snapshot` and `event`.
|
|
112
|
+
*
|
|
113
|
+
* If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
|
|
114
|
+
* used.
|
|
115
|
+
*
|
|
116
|
+
* @deprecated Use `transition(…)` instead.
|
|
117
|
+
* @example
|
|
118
|
+
*
|
|
119
|
+
* ```ts
|
|
120
|
+
* import { getNextSnapshot } from 'xstate';
|
|
121
|
+
* import { trafficLightMachine } from './trafficLightMachine.ts';
|
|
122
|
+
*
|
|
123
|
+
* const nextSnapshot = getNextSnapshot(
|
|
124
|
+
* trafficLightMachine, // actor logic
|
|
125
|
+
* undefined, // snapshot (or initial state if undefined)
|
|
126
|
+
* { type: 'TIMER' }
|
|
127
|
+
* ); // event object
|
|
128
|
+
*
|
|
129
|
+
* console.log(nextSnapshot.value);
|
|
130
|
+
* // => 'yellow'
|
|
131
|
+
*
|
|
132
|
+
* const nextSnapshot2 = getNextSnapshot(
|
|
133
|
+
* trafficLightMachine, // actor logic
|
|
134
|
+
* nextSnapshot, // snapshot
|
|
135
|
+
* { type: 'TIMER' }
|
|
136
|
+
* ); // event object
|
|
137
|
+
*
|
|
138
|
+
* console.log(nextSnapshot2.value);
|
|
139
|
+
* // =>'red'
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
function getNextSnapshot(actorLogic, snapshot, event) {
|
|
143
|
+
const actorScope = createInertActorScope(actorLogic, snapshot);
|
|
144
|
+
const transitionResult = actorLogic.transition(snapshot, event, actorScope);
|
|
145
|
+
const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
|
|
146
|
+
setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
|
|
147
|
+
return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
|
|
148
|
+
}
|
|
149
|
+
|
|
52
150
|
const cache = new WeakMap();
|
|
53
151
|
function memo(object, key, fn) {
|
|
54
152
|
let memoizedData = cache.get(object);
|
|
@@ -541,19 +639,37 @@ class StateMachine {
|
|
|
541
639
|
* @param event The received event
|
|
542
640
|
*/
|
|
543
641
|
transition(snapshot, event, actorScope) {
|
|
544
|
-
const
|
|
642
|
+
const usesInertScope = !actorScope;
|
|
643
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
|
|
644
|
+
if (usesInertScope) {
|
|
645
|
+
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
646
|
+
}
|
|
647
|
+
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
545
648
|
if (fastSnapshot) {
|
|
546
|
-
|
|
649
|
+
if (usesInertScope) {
|
|
650
|
+
setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
|
|
651
|
+
}
|
|
652
|
+
const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
|
|
653
|
+
return [returnedSnapshot, []];
|
|
547
654
|
}
|
|
548
655
|
const {
|
|
549
656
|
snapshot: nextSnapshot,
|
|
550
657
|
microsteps
|
|
551
|
-
} = macrostep(snapshot, event,
|
|
552
|
-
|
|
658
|
+
} = macrostep(snapshot, event, resolvedActorScope, []);
|
|
659
|
+
if (usesInertScope) {
|
|
660
|
+
setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
|
|
661
|
+
}
|
|
662
|
+
const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
|
|
663
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
664
|
+
}
|
|
665
|
+
_collectEffects(microsteps) {
|
|
666
|
+
return microsteps.flatMap(([, actions]) => actions);
|
|
553
667
|
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
668
|
+
_attachPureActorRef(snapshot, actorScope) {
|
|
669
|
+
if (isInertActorScope(actorScope)) {
|
|
670
|
+
return snapshot;
|
|
671
|
+
}
|
|
672
|
+
return attachSnapshotActorRef(this, actorScope, snapshot);
|
|
557
673
|
}
|
|
558
674
|
_transitionFast(snapshot, event, actorScope) {
|
|
559
675
|
if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
|
|
@@ -614,6 +730,9 @@ class StateMachine {
|
|
|
614
730
|
return transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
|
|
615
731
|
}
|
|
616
732
|
isInternalEventType(eventType) {
|
|
733
|
+
if (eventType === XSTATE_TIMER) {
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
617
736
|
for (const descriptor of this.internalEventDescriptors) {
|
|
618
737
|
if (matchesEventDescriptor(eventType, descriptor)) {
|
|
619
738
|
return true;
|
|
@@ -680,7 +799,7 @@ class StateMachine {
|
|
|
680
799
|
_nodes: [this.root],
|
|
681
800
|
children: {},
|
|
682
801
|
status: 'active'
|
|
683
|
-
}, this);
|
|
802
|
+
}, this, actorScope.self);
|
|
684
803
|
if (typeof context === 'function') {
|
|
685
804
|
const children = {};
|
|
686
805
|
const spawn = createSpawner(actorScope, preInitial, initEvent, children);
|
|
@@ -713,30 +832,37 @@ class StateMachine {
|
|
|
713
832
|
return this.initialTransition(input, actorScope)[0];
|
|
714
833
|
}
|
|
715
834
|
initialTransition(input, actorScope) {
|
|
835
|
+
const usesInertScope = !actorScope;
|
|
836
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
716
837
|
const initEvent = createInitEvent(input); // TODO: fix;
|
|
717
838
|
const internalQueue = [];
|
|
718
|
-
const preInitialState = this._getPreInitialState(
|
|
839
|
+
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
840
|
+
const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => createSpawnEffect(actor));
|
|
719
841
|
let nextState;
|
|
720
842
|
let initialActions = [];
|
|
721
843
|
let microsteps = [];
|
|
722
844
|
let macroState;
|
|
723
845
|
try {
|
|
724
|
-
[nextState, initialActions] = initialMicrostep(this.root, preInitialState,
|
|
846
|
+
[nextState, initialActions] = initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
|
|
725
847
|
({
|
|
726
848
|
snapshot: macroState,
|
|
727
849
|
microsteps
|
|
728
|
-
} = macrostep(nextState, initEvent,
|
|
850
|
+
} = macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
|
|
729
851
|
} catch (err) {
|
|
730
852
|
if (!this.root.config.onError) {
|
|
731
853
|
throw err;
|
|
732
854
|
}
|
|
733
855
|
const errorEvent = createErrorPlatformEvent('execution', err);
|
|
734
|
-
const errorMacrostep = macrostep(preInitialState, errorEvent,
|
|
856
|
+
const errorMacrostep = macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
|
|
735
857
|
macroState = errorMacrostep.snapshot;
|
|
736
858
|
microsteps = errorMacrostep.microsteps;
|
|
737
859
|
initialActions = [];
|
|
738
860
|
}
|
|
739
|
-
|
|
861
|
+
if (usesInertScope) {
|
|
862
|
+
setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
|
|
863
|
+
}
|
|
864
|
+
const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
|
|
865
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
740
866
|
}
|
|
741
867
|
start(snapshot) {
|
|
742
868
|
// Start rehydrated children that were active when persisted. Freshly
|
|
@@ -764,7 +890,9 @@ class StateMachine {
|
|
|
764
890
|
getPersistedSnapshot(snapshot, options) {
|
|
765
891
|
return getPersistedSnapshot(snapshot, options);
|
|
766
892
|
}
|
|
767
|
-
restoreSnapshot(snapshot,
|
|
893
|
+
restoreSnapshot(snapshot, actorScope) {
|
|
894
|
+
const usesInertScope = !actorScope;
|
|
895
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
768
896
|
const persistedVersion = snapshot.version;
|
|
769
897
|
if (persistedVersion !== this.version) {
|
|
770
898
|
const migrate = this.config.migrate;
|
|
@@ -784,9 +912,9 @@ class StateMachine {
|
|
|
784
912
|
if (!logic) {
|
|
785
913
|
continue;
|
|
786
914
|
}
|
|
787
|
-
const actor =
|
|
915
|
+
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
788
916
|
id: actorId,
|
|
789
|
-
parent:
|
|
917
|
+
parent: resolvedActorScope.self,
|
|
790
918
|
syncSnapshot: actorData.syncSnapshot,
|
|
791
919
|
snapshot: childState,
|
|
792
920
|
src,
|
|
@@ -797,6 +925,19 @@ class StateMachine {
|
|
|
797
925
|
actor._rehydrated = true;
|
|
798
926
|
children[actorId] = actor;
|
|
799
927
|
}
|
|
928
|
+
const timers = {};
|
|
929
|
+
const persistedTimers = snapshotData.timers ?? {};
|
|
930
|
+
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
931
|
+
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
932
|
+
if (!target) {
|
|
933
|
+
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
934
|
+
throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
|
|
935
|
+
}
|
|
936
|
+
timers[id] = {
|
|
937
|
+
...timer,
|
|
938
|
+
target
|
|
939
|
+
};
|
|
940
|
+
}
|
|
800
941
|
const reviveHistoryValue = historyValue => {
|
|
801
942
|
if (!historyValue || typeof historyValue !== 'object') {
|
|
802
943
|
return {};
|
|
@@ -832,11 +973,12 @@ class StateMachine {
|
|
|
832
973
|
const restoredSnapshot = createMachineSnapshot({
|
|
833
974
|
...persistedRest,
|
|
834
975
|
children,
|
|
976
|
+
timers,
|
|
835
977
|
_nodes: nodes,
|
|
836
978
|
value: snapshotData.value,
|
|
837
979
|
historyValue: revivedHistoryValue,
|
|
838
980
|
_stateInputs: snapshotData.stateInputs ?? {}
|
|
839
|
-
}, this);
|
|
981
|
+
}, this, resolvedActorScope.self);
|
|
840
982
|
const seen = new WeakSet();
|
|
841
983
|
function reviveContext(contextPart) {
|
|
842
984
|
if (seen.has(contextPart)) {
|
|
@@ -855,8 +997,12 @@ class StateMachine {
|
|
|
855
997
|
}
|
|
856
998
|
}
|
|
857
999
|
reviveContext(restoredSnapshot.context);
|
|
858
|
-
|
|
1000
|
+
if (usesInertScope) {
|
|
1001
|
+
setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
|
|
1002
|
+
return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
|
|
1003
|
+
}
|
|
1004
|
+
return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
|
|
859
1005
|
}
|
|
860
1006
|
}
|
|
861
1007
|
|
|
862
|
-
export { StateMachine as S,
|
|
1008
|
+
export { StateMachine as S, attachSnapshotActorRef as a, getNextSnapshot as b, createInertActorScope as c, StateNode as d, getInitialSnapshot as g, setInertActorScopeSnapshot as s };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyMachineSnapshot, AnyStateMachine, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, StateValueMap, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode } from "./types.js";
|
|
1
|
+
import type { AnyMachineSnapshot, AnyStateMachine, AnyActor, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, StateValueMap, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode, LogicalTimer } from "./types.js";
|
|
2
2
|
export declare function isMachineSnapshot(value: unknown): value is AnyMachineSnapshot;
|
|
3
3
|
type Values<T> = T[keyof T];
|
|
4
4
|
type MatchingObjectStateValue<TStateValue extends Record<string, unknown>, TTestStateValue extends Record<string, unknown>> = false extends Values<{
|
|
@@ -45,6 +45,8 @@ interface MachineSnapshotBase<TContext extends MachineContext, TEvent extends Ev
|
|
|
45
45
|
_nodes: Array<AnyStateNode>;
|
|
46
46
|
/** An object mapping actor names to spawned/invoked actors. */
|
|
47
47
|
children: TChildren;
|
|
48
|
+
/** Pending logical timers owned by this machine snapshot. */
|
|
49
|
+
timers: Readonly<Record<string, LogicalTimer>>;
|
|
48
50
|
/**
|
|
49
51
|
* Whether the current state value is a subset of the given partial state
|
|
50
52
|
* value.
|
|
@@ -98,7 +100,7 @@ interface StoppedMachineSnapshot<TContext extends MachineContext, TEvent extends
|
|
|
98
100
|
error: undefined;
|
|
99
101
|
}
|
|
100
102
|
export type MachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TOutput, TMeta extends MetaObject, TStateSchema extends StateSchema> = ActiveMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | DoneMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | ErrorMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | StoppedMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema>;
|
|
101
|
-
export declare function createMachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TMeta extends MetaObject, TStateSchema extends StateSchema>(config: StateConfig<TContext, TEvent>, machine: AnyStateMachine): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, undefined, TMeta, TStateSchema>;
|
|
103
|
+
export declare function createMachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TMeta extends MetaObject, TStateSchema extends StateSchema>(config: StateConfig<TContext, TEvent>, machine: AnyStateMachine, actorRef?: AnyActor): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, undefined, TMeta, TStateSchema>;
|
|
102
104
|
export declare function cloneMachineSnapshot<TState extends AnyMachineSnapshot>(snapshot: TState, config?: Partial<StateConfig<any, any>>): TState;
|
|
103
105
|
export declare function getPersistedSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TOutput, TMeta extends MetaObject>(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, any>, options?: unknown): Snapshot<unknown>;
|
|
104
106
|
export {};
|