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-550ff7f2.development.cjs.js → StateMachine-1888d034.development.cjs.js}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dist_xstateActors = require('./index-
|
|
3
|
+
var dist_xstateActors = require('./index-41c0375c.development.cjs.js');
|
|
4
4
|
|
|
5
5
|
function createSpawner(actorScope, {
|
|
6
6
|
machine,
|
|
@@ -12,7 +12,7 @@ function createSpawner(actorScope, {
|
|
|
12
12
|
if (!logic) {
|
|
13
13
|
throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
|
|
14
14
|
}
|
|
15
|
-
const actor =
|
|
15
|
+
const actor = actorScope.system.createActorRef(logic, {
|
|
16
16
|
id: options?.id,
|
|
17
17
|
parent: actorScope.self,
|
|
18
18
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -27,7 +27,7 @@ function createSpawner(actorScope, {
|
|
|
27
27
|
spawnedChildren[actor.id] = actor;
|
|
28
28
|
return actor;
|
|
29
29
|
} else {
|
|
30
|
-
const actor =
|
|
30
|
+
const actor = actorScope.system.createActorRef(src, {
|
|
31
31
|
id: options?.id,
|
|
32
32
|
parent: actorScope.self,
|
|
33
33
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -41,16 +41,114 @@ function createSpawner(actorScope, {
|
|
|
41
41
|
return (src, options) => {
|
|
42
42
|
const actor = spawn(src, options); // TODO: fix types
|
|
43
43
|
spawnedChildren[actor.id] = actor;
|
|
44
|
-
actorScope.defer(() => {
|
|
45
|
-
if (actor._processingStatus === dist_xstateActors.ProcessingStatus.Stopped) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
actor.start();
|
|
49
|
-
});
|
|
50
44
|
return actor;
|
|
51
45
|
};
|
|
52
46
|
}
|
|
53
47
|
|
|
48
|
+
/** @internal */
|
|
49
|
+
function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
|
|
50
|
+
actorScope.self._snapshot = snapshot;
|
|
51
|
+
if (attachActorRef && snapshot && typeof snapshot === 'object') {
|
|
52
|
+
dist_xstateActors.setSnapshotActorRef(snapshot, actorScope.self);
|
|
53
|
+
}
|
|
54
|
+
return snapshot;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** @internal */
|
|
58
|
+
function isInertActorScope(actorScope) {
|
|
59
|
+
return !!actorScope.self.options?._inert;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @internal */
|
|
63
|
+
function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
|
|
64
|
+
const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
|
|
65
|
+
return setInertActorScopeSnapshot(snapshotScope, snapshot);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @internal */
|
|
69
|
+
function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
70
|
+
const snapshotRef = snapshot ? dist_xstateActors.getSnapshotActorRef(snapshot) : undefined;
|
|
71
|
+
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
72
|
+
const baseSystem = previousSelf?.system;
|
|
73
|
+
const system = previousSelf && baseSystem ? dist_xstateActors.createSnapshotSystem(baseSystem, previousSelf, dist_xstateActors.isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
74
|
+
const self = dist_xstateActors.createActor(actorLogic, {
|
|
75
|
+
_inert: true,
|
|
76
|
+
...(previousSelf ? {
|
|
77
|
+
id: previousSelf.id
|
|
78
|
+
} : {}),
|
|
79
|
+
...(system ? {
|
|
80
|
+
_systemRef: {
|
|
81
|
+
current: system
|
|
82
|
+
}
|
|
83
|
+
} : {})
|
|
84
|
+
});
|
|
85
|
+
if (previousSelf?._parent) {
|
|
86
|
+
self._parent = previousSelf._parent;
|
|
87
|
+
}
|
|
88
|
+
if (snapshot) {
|
|
89
|
+
self._snapshot = snapshot;
|
|
90
|
+
}
|
|
91
|
+
const actorScope = {
|
|
92
|
+
self: self,
|
|
93
|
+
defer: () => {},
|
|
94
|
+
id: self.id,
|
|
95
|
+
logger: self.system._logger,
|
|
96
|
+
sessionId: self.sessionId,
|
|
97
|
+
stopChild: child => child._stop(),
|
|
98
|
+
system: self.system,
|
|
99
|
+
emit: event => self.system.emitEvent(self, event),
|
|
100
|
+
actionExecutor: () => {}
|
|
101
|
+
};
|
|
102
|
+
return actorScope;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @deprecated Use `initialTransition(…)` instead. */
|
|
106
|
+
function getInitialSnapshot(actorLogic, ...[input]) {
|
|
107
|
+
const actorScope = createInertActorScope(actorLogic);
|
|
108
|
+
return actorLogic.initialTransition(input, actorScope)[0];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determines the next snapshot for the given `actorLogic` based on the given
|
|
113
|
+
* `snapshot` and `event`.
|
|
114
|
+
*
|
|
115
|
+
* If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
|
|
116
|
+
* used.
|
|
117
|
+
*
|
|
118
|
+
* @deprecated Use `transition(…)` instead.
|
|
119
|
+
* @example
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* import { getNextSnapshot } from 'xstate';
|
|
123
|
+
* import { trafficLightMachine } from './trafficLightMachine.ts';
|
|
124
|
+
*
|
|
125
|
+
* const nextSnapshot = getNextSnapshot(
|
|
126
|
+
* trafficLightMachine, // actor logic
|
|
127
|
+
* undefined, // snapshot (or initial state if undefined)
|
|
128
|
+
* { type: 'TIMER' }
|
|
129
|
+
* ); // event object
|
|
130
|
+
*
|
|
131
|
+
* console.log(nextSnapshot.value);
|
|
132
|
+
* // => 'yellow'
|
|
133
|
+
*
|
|
134
|
+
* const nextSnapshot2 = getNextSnapshot(
|
|
135
|
+
* trafficLightMachine, // actor logic
|
|
136
|
+
* nextSnapshot, // snapshot
|
|
137
|
+
* { type: 'TIMER' }
|
|
138
|
+
* ); // event object
|
|
139
|
+
*
|
|
140
|
+
* console.log(nextSnapshot2.value);
|
|
141
|
+
* // =>'red'
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
function getNextSnapshot(actorLogic, snapshot, event) {
|
|
145
|
+
const actorScope = createInertActorScope(actorLogic, snapshot);
|
|
146
|
+
const transitionResult = actorLogic.transition(snapshot, event, actorScope);
|
|
147
|
+
const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
|
|
148
|
+
setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
|
|
149
|
+
return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
|
|
150
|
+
}
|
|
151
|
+
|
|
54
152
|
const cache = new WeakMap();
|
|
55
153
|
function memo(object, key, fn) {
|
|
56
154
|
let memoizedData = cache.get(object);
|
|
@@ -572,19 +670,37 @@ class StateMachine {
|
|
|
572
670
|
* @param event The received event
|
|
573
671
|
*/
|
|
574
672
|
transition(snapshot, event, actorScope) {
|
|
575
|
-
const
|
|
673
|
+
const usesInertScope = !actorScope;
|
|
674
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
|
|
675
|
+
if (usesInertScope) {
|
|
676
|
+
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
677
|
+
}
|
|
678
|
+
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
576
679
|
if (fastSnapshot) {
|
|
577
|
-
|
|
680
|
+
if (usesInertScope) {
|
|
681
|
+
setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
|
|
682
|
+
}
|
|
683
|
+
const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
|
|
684
|
+
return [returnedSnapshot, []];
|
|
578
685
|
}
|
|
579
686
|
const {
|
|
580
687
|
snapshot: nextSnapshot,
|
|
581
688
|
microsteps
|
|
582
|
-
} = dist_xstateActors.macrostep(snapshot, event,
|
|
583
|
-
|
|
689
|
+
} = dist_xstateActors.macrostep(snapshot, event, resolvedActorScope, []);
|
|
690
|
+
if (usesInertScope) {
|
|
691
|
+
setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
|
|
692
|
+
}
|
|
693
|
+
const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
|
|
694
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
695
|
+
}
|
|
696
|
+
_collectEffects(microsteps) {
|
|
697
|
+
return microsteps.flatMap(([, actions]) => actions);
|
|
584
698
|
}
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
699
|
+
_attachPureActorRef(snapshot, actorScope) {
|
|
700
|
+
if (isInertActorScope(actorScope)) {
|
|
701
|
+
return snapshot;
|
|
702
|
+
}
|
|
703
|
+
return attachSnapshotActorRef(this, actorScope, snapshot);
|
|
588
704
|
}
|
|
589
705
|
_transitionFast(snapshot, event, actorScope) {
|
|
590
706
|
if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
|
|
@@ -645,6 +761,9 @@ class StateMachine {
|
|
|
645
761
|
return dist_xstateActors.transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
|
|
646
762
|
}
|
|
647
763
|
isInternalEventType(eventType) {
|
|
764
|
+
if (eventType === dist_xstateActors.XSTATE_TIMER) {
|
|
765
|
+
return true;
|
|
766
|
+
}
|
|
648
767
|
for (const descriptor of this.internalEventDescriptors) {
|
|
649
768
|
if (dist_xstateActors.matchesEventDescriptor(eventType, descriptor)) {
|
|
650
769
|
return true;
|
|
@@ -711,7 +830,7 @@ class StateMachine {
|
|
|
711
830
|
_nodes: [this.root],
|
|
712
831
|
children: {},
|
|
713
832
|
status: 'active'
|
|
714
|
-
}, this);
|
|
833
|
+
}, this, actorScope.self);
|
|
715
834
|
if (typeof context === 'function') {
|
|
716
835
|
const children = {};
|
|
717
836
|
const spawn = createSpawner(actorScope, preInitial, initEvent, children);
|
|
@@ -744,30 +863,37 @@ class StateMachine {
|
|
|
744
863
|
return this.initialTransition(input, actorScope)[0];
|
|
745
864
|
}
|
|
746
865
|
initialTransition(input, actorScope) {
|
|
866
|
+
const usesInertScope = !actorScope;
|
|
867
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
747
868
|
const initEvent = dist_xstateActors.createInitEvent(input); // TODO: fix;
|
|
748
869
|
const internalQueue = [];
|
|
749
|
-
const preInitialState = this._getPreInitialState(
|
|
870
|
+
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
871
|
+
const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => dist_xstateActors.createSpawnEffect(actor));
|
|
750
872
|
let nextState;
|
|
751
873
|
let initialActions = [];
|
|
752
874
|
let microsteps = [];
|
|
753
875
|
let macroState;
|
|
754
876
|
try {
|
|
755
|
-
[nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState,
|
|
877
|
+
[nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
|
|
756
878
|
({
|
|
757
879
|
snapshot: macroState,
|
|
758
880
|
microsteps
|
|
759
|
-
} = dist_xstateActors.macrostep(nextState, initEvent,
|
|
881
|
+
} = dist_xstateActors.macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
|
|
760
882
|
} catch (err) {
|
|
761
883
|
if (!this.root.config.onError) {
|
|
762
884
|
throw err;
|
|
763
885
|
}
|
|
764
886
|
const errorEvent = dist_xstateActors.createErrorPlatformEvent('execution', err);
|
|
765
|
-
const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent,
|
|
887
|
+
const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
|
|
766
888
|
macroState = errorMacrostep.snapshot;
|
|
767
889
|
microsteps = errorMacrostep.microsteps;
|
|
768
890
|
initialActions = [];
|
|
769
891
|
}
|
|
770
|
-
|
|
892
|
+
if (usesInertScope) {
|
|
893
|
+
setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
|
|
894
|
+
}
|
|
895
|
+
const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
|
|
896
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
771
897
|
}
|
|
772
898
|
start(snapshot) {
|
|
773
899
|
// Start rehydrated children that were active when persisted. Freshly
|
|
@@ -795,7 +921,9 @@ class StateMachine {
|
|
|
795
921
|
getPersistedSnapshot(snapshot, options) {
|
|
796
922
|
return dist_xstateActors.getPersistedSnapshot(snapshot, options);
|
|
797
923
|
}
|
|
798
|
-
restoreSnapshot(snapshot,
|
|
924
|
+
restoreSnapshot(snapshot, actorScope) {
|
|
925
|
+
const usesInertScope = !actorScope;
|
|
926
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
799
927
|
const persistedVersion = snapshot.version;
|
|
800
928
|
if (persistedVersion !== this.version) {
|
|
801
929
|
const migrate = this.config.migrate;
|
|
@@ -815,9 +943,9 @@ class StateMachine {
|
|
|
815
943
|
if (!logic) {
|
|
816
944
|
continue;
|
|
817
945
|
}
|
|
818
|
-
const actor =
|
|
946
|
+
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
819
947
|
id: actorId,
|
|
820
|
-
parent:
|
|
948
|
+
parent: resolvedActorScope.self,
|
|
821
949
|
syncSnapshot: actorData.syncSnapshot,
|
|
822
950
|
snapshot: childState,
|
|
823
951
|
src,
|
|
@@ -828,6 +956,19 @@ class StateMachine {
|
|
|
828
956
|
actor._rehydrated = true;
|
|
829
957
|
children[actorId] = actor;
|
|
830
958
|
}
|
|
959
|
+
const timers = {};
|
|
960
|
+
const persistedTimers = snapshotData.timers ?? {};
|
|
961
|
+
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
962
|
+
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
963
|
+
if (!target) {
|
|
964
|
+
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
965
|
+
throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
|
|
966
|
+
}
|
|
967
|
+
timers[id] = {
|
|
968
|
+
...timer,
|
|
969
|
+
target
|
|
970
|
+
};
|
|
971
|
+
}
|
|
831
972
|
const reviveHistoryValue = historyValue => {
|
|
832
973
|
if (!historyValue || typeof historyValue !== 'object') {
|
|
833
974
|
return {};
|
|
@@ -866,11 +1007,12 @@ class StateMachine {
|
|
|
866
1007
|
const restoredSnapshot = dist_xstateActors.createMachineSnapshot({
|
|
867
1008
|
...persistedRest,
|
|
868
1009
|
children,
|
|
1010
|
+
timers,
|
|
869
1011
|
_nodes: nodes,
|
|
870
1012
|
value: snapshotData.value,
|
|
871
1013
|
historyValue: revivedHistoryValue,
|
|
872
1014
|
_stateInputs: snapshotData.stateInputs ?? {}
|
|
873
|
-
}, this);
|
|
1015
|
+
}, this, resolvedActorScope.self);
|
|
874
1016
|
const seen = new WeakSet();
|
|
875
1017
|
function reviveContext(contextPart) {
|
|
876
1018
|
if (seen.has(contextPart)) {
|
|
@@ -889,9 +1031,18 @@ class StateMachine {
|
|
|
889
1031
|
}
|
|
890
1032
|
}
|
|
891
1033
|
reviveContext(restoredSnapshot.context);
|
|
892
|
-
|
|
1034
|
+
if (usesInertScope) {
|
|
1035
|
+
setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
|
|
1036
|
+
return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
|
|
1037
|
+
}
|
|
1038
|
+
return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
|
|
893
1039
|
}
|
|
894
1040
|
}
|
|
895
1041
|
|
|
896
1042
|
exports.StateMachine = StateMachine;
|
|
897
1043
|
exports.StateNode = StateNode;
|
|
1044
|
+
exports.attachSnapshotActorRef = attachSnapshotActorRef;
|
|
1045
|
+
exports.createInertActorScope = createInertActorScope;
|
|
1046
|
+
exports.getInitialSnapshot = getInitialSnapshot;
|
|
1047
|
+
exports.getNextSnapshot = getNextSnapshot;
|
|
1048
|
+
exports.setInertActorScopeSnapshot = setInertActorScopeSnapshot;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dist_xstateActors = require('./index-
|
|
3
|
+
var dist_xstateActors = require('./index-434fac23.cjs.js');
|
|
4
4
|
|
|
5
5
|
function createSpawner(actorScope, {
|
|
6
6
|
machine,
|
|
@@ -12,7 +12,7 @@ function createSpawner(actorScope, {
|
|
|
12
12
|
if (!logic) {
|
|
13
13
|
throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
|
|
14
14
|
}
|
|
15
|
-
const actor =
|
|
15
|
+
const actor = actorScope.system.createActorRef(logic, {
|
|
16
16
|
id: options?.id,
|
|
17
17
|
parent: actorScope.self,
|
|
18
18
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -27,7 +27,7 @@ function createSpawner(actorScope, {
|
|
|
27
27
|
spawnedChildren[actor.id] = actor;
|
|
28
28
|
return actor;
|
|
29
29
|
} else {
|
|
30
|
-
const actor =
|
|
30
|
+
const actor = actorScope.system.createActorRef(src, {
|
|
31
31
|
id: options?.id,
|
|
32
32
|
parent: actorScope.self,
|
|
33
33
|
syncSnapshot: options?.syncSnapshot,
|
|
@@ -41,16 +41,114 @@ function createSpawner(actorScope, {
|
|
|
41
41
|
return (src, options) => {
|
|
42
42
|
const actor = spawn(src, options); // TODO: fix types
|
|
43
43
|
spawnedChildren[actor.id] = actor;
|
|
44
|
-
actorScope.defer(() => {
|
|
45
|
-
if (actor._processingStatus === dist_xstateActors.ProcessingStatus.Stopped) {
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
actor.start();
|
|
49
|
-
});
|
|
50
44
|
return actor;
|
|
51
45
|
};
|
|
52
46
|
}
|
|
53
47
|
|
|
48
|
+
/** @internal */
|
|
49
|
+
function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
|
|
50
|
+
actorScope.self._snapshot = snapshot;
|
|
51
|
+
if (attachActorRef && snapshot && typeof snapshot === 'object') {
|
|
52
|
+
dist_xstateActors.setSnapshotActorRef(snapshot, actorScope.self);
|
|
53
|
+
}
|
|
54
|
+
return snapshot;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** @internal */
|
|
58
|
+
function isInertActorScope(actorScope) {
|
|
59
|
+
return !!actorScope.self.options?._inert;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** @internal */
|
|
63
|
+
function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
|
|
64
|
+
const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
|
|
65
|
+
return setInertActorScopeSnapshot(snapshotScope, snapshot);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @internal */
|
|
69
|
+
function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
70
|
+
const snapshotRef = snapshot ? dist_xstateActors.getSnapshotActorRef(snapshot) : undefined;
|
|
71
|
+
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
72
|
+
const baseSystem = previousSelf?.system;
|
|
73
|
+
const system = previousSelf && baseSystem ? dist_xstateActors.createSnapshotSystem(baseSystem, previousSelf, dist_xstateActors.isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
74
|
+
const self = dist_xstateActors.createActor(actorLogic, {
|
|
75
|
+
_inert: true,
|
|
76
|
+
...(previousSelf ? {
|
|
77
|
+
id: previousSelf.id
|
|
78
|
+
} : {}),
|
|
79
|
+
...(system ? {
|
|
80
|
+
_systemRef: {
|
|
81
|
+
current: system
|
|
82
|
+
}
|
|
83
|
+
} : {})
|
|
84
|
+
});
|
|
85
|
+
if (previousSelf?._parent) {
|
|
86
|
+
self._parent = previousSelf._parent;
|
|
87
|
+
}
|
|
88
|
+
if (snapshot) {
|
|
89
|
+
self._snapshot = snapshot;
|
|
90
|
+
}
|
|
91
|
+
const actorScope = {
|
|
92
|
+
self: self,
|
|
93
|
+
defer: () => {},
|
|
94
|
+
id: self.id,
|
|
95
|
+
logger: self.system._logger,
|
|
96
|
+
sessionId: self.sessionId,
|
|
97
|
+
stopChild: child => child._stop(),
|
|
98
|
+
system: self.system,
|
|
99
|
+
emit: event => self.system.emitEvent(self, event),
|
|
100
|
+
actionExecutor: () => {}
|
|
101
|
+
};
|
|
102
|
+
return actorScope;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** @deprecated Use `initialTransition(…)` instead. */
|
|
106
|
+
function getInitialSnapshot(actorLogic, ...[input]) {
|
|
107
|
+
const actorScope = createInertActorScope(actorLogic);
|
|
108
|
+
return actorLogic.initialTransition(input, actorScope)[0];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Determines the next snapshot for the given `actorLogic` based on the given
|
|
113
|
+
* `snapshot` and `event`.
|
|
114
|
+
*
|
|
115
|
+
* If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
|
|
116
|
+
* used.
|
|
117
|
+
*
|
|
118
|
+
* @deprecated Use `transition(…)` instead.
|
|
119
|
+
* @example
|
|
120
|
+
*
|
|
121
|
+
* ```ts
|
|
122
|
+
* import { getNextSnapshot } from 'xstate';
|
|
123
|
+
* import { trafficLightMachine } from './trafficLightMachine.ts';
|
|
124
|
+
*
|
|
125
|
+
* const nextSnapshot = getNextSnapshot(
|
|
126
|
+
* trafficLightMachine, // actor logic
|
|
127
|
+
* undefined, // snapshot (or initial state if undefined)
|
|
128
|
+
* { type: 'TIMER' }
|
|
129
|
+
* ); // event object
|
|
130
|
+
*
|
|
131
|
+
* console.log(nextSnapshot.value);
|
|
132
|
+
* // => 'yellow'
|
|
133
|
+
*
|
|
134
|
+
* const nextSnapshot2 = getNextSnapshot(
|
|
135
|
+
* trafficLightMachine, // actor logic
|
|
136
|
+
* nextSnapshot, // snapshot
|
|
137
|
+
* { type: 'TIMER' }
|
|
138
|
+
* ); // event object
|
|
139
|
+
*
|
|
140
|
+
* console.log(nextSnapshot2.value);
|
|
141
|
+
* // =>'red'
|
|
142
|
+
* ```
|
|
143
|
+
*/
|
|
144
|
+
function getNextSnapshot(actorLogic, snapshot, event) {
|
|
145
|
+
const actorScope = createInertActorScope(actorLogic, snapshot);
|
|
146
|
+
const transitionResult = actorLogic.transition(snapshot, event, actorScope);
|
|
147
|
+
const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
|
|
148
|
+
setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
|
|
149
|
+
return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
|
|
150
|
+
}
|
|
151
|
+
|
|
54
152
|
const cache = new WeakMap();
|
|
55
153
|
function memo(object, key, fn) {
|
|
56
154
|
let memoizedData = cache.get(object);
|
|
@@ -543,19 +641,37 @@ class StateMachine {
|
|
|
543
641
|
* @param event The received event
|
|
544
642
|
*/
|
|
545
643
|
transition(snapshot, event, actorScope) {
|
|
546
|
-
const
|
|
644
|
+
const usesInertScope = !actorScope;
|
|
645
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
|
|
646
|
+
if (usesInertScope) {
|
|
647
|
+
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
648
|
+
}
|
|
649
|
+
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
547
650
|
if (fastSnapshot) {
|
|
548
|
-
|
|
651
|
+
if (usesInertScope) {
|
|
652
|
+
setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
|
|
653
|
+
}
|
|
654
|
+
const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
|
|
655
|
+
return [returnedSnapshot, []];
|
|
549
656
|
}
|
|
550
657
|
const {
|
|
551
658
|
snapshot: nextSnapshot,
|
|
552
659
|
microsteps
|
|
553
|
-
} = dist_xstateActors.macrostep(snapshot, event,
|
|
554
|
-
|
|
660
|
+
} = dist_xstateActors.macrostep(snapshot, event, resolvedActorScope, []);
|
|
661
|
+
if (usesInertScope) {
|
|
662
|
+
setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
|
|
663
|
+
}
|
|
664
|
+
const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
|
|
665
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
666
|
+
}
|
|
667
|
+
_collectEffects(microsteps) {
|
|
668
|
+
return microsteps.flatMap(([, actions]) => actions);
|
|
555
669
|
}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
670
|
+
_attachPureActorRef(snapshot, actorScope) {
|
|
671
|
+
if (isInertActorScope(actorScope)) {
|
|
672
|
+
return snapshot;
|
|
673
|
+
}
|
|
674
|
+
return attachSnapshotActorRef(this, actorScope, snapshot);
|
|
559
675
|
}
|
|
560
676
|
_transitionFast(snapshot, event, actorScope) {
|
|
561
677
|
if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
|
|
@@ -616,6 +732,9 @@ class StateMachine {
|
|
|
616
732
|
return dist_xstateActors.transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
|
|
617
733
|
}
|
|
618
734
|
isInternalEventType(eventType) {
|
|
735
|
+
if (eventType === dist_xstateActors.XSTATE_TIMER) {
|
|
736
|
+
return true;
|
|
737
|
+
}
|
|
619
738
|
for (const descriptor of this.internalEventDescriptors) {
|
|
620
739
|
if (dist_xstateActors.matchesEventDescriptor(eventType, descriptor)) {
|
|
621
740
|
return true;
|
|
@@ -682,7 +801,7 @@ class StateMachine {
|
|
|
682
801
|
_nodes: [this.root],
|
|
683
802
|
children: {},
|
|
684
803
|
status: 'active'
|
|
685
|
-
}, this);
|
|
804
|
+
}, this, actorScope.self);
|
|
686
805
|
if (typeof context === 'function') {
|
|
687
806
|
const children = {};
|
|
688
807
|
const spawn = createSpawner(actorScope, preInitial, initEvent, children);
|
|
@@ -715,30 +834,37 @@ class StateMachine {
|
|
|
715
834
|
return this.initialTransition(input, actorScope)[0];
|
|
716
835
|
}
|
|
717
836
|
initialTransition(input, actorScope) {
|
|
837
|
+
const usesInertScope = !actorScope;
|
|
838
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
718
839
|
const initEvent = dist_xstateActors.createInitEvent(input); // TODO: fix;
|
|
719
840
|
const internalQueue = [];
|
|
720
|
-
const preInitialState = this._getPreInitialState(
|
|
841
|
+
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
842
|
+
const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => dist_xstateActors.createSpawnEffect(actor));
|
|
721
843
|
let nextState;
|
|
722
844
|
let initialActions = [];
|
|
723
845
|
let microsteps = [];
|
|
724
846
|
let macroState;
|
|
725
847
|
try {
|
|
726
|
-
[nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState,
|
|
848
|
+
[nextState, initialActions] = dist_xstateActors.initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
|
|
727
849
|
({
|
|
728
850
|
snapshot: macroState,
|
|
729
851
|
microsteps
|
|
730
|
-
} = dist_xstateActors.macrostep(nextState, initEvent,
|
|
852
|
+
} = dist_xstateActors.macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
|
|
731
853
|
} catch (err) {
|
|
732
854
|
if (!this.root.config.onError) {
|
|
733
855
|
throw err;
|
|
734
856
|
}
|
|
735
857
|
const errorEvent = dist_xstateActors.createErrorPlatformEvent('execution', err);
|
|
736
|
-
const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent,
|
|
858
|
+
const errorMacrostep = dist_xstateActors.macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
|
|
737
859
|
macroState = errorMacrostep.snapshot;
|
|
738
860
|
microsteps = errorMacrostep.microsteps;
|
|
739
861
|
initialActions = [];
|
|
740
862
|
}
|
|
741
|
-
|
|
863
|
+
if (usesInertScope) {
|
|
864
|
+
setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
|
|
865
|
+
}
|
|
866
|
+
const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
|
|
867
|
+
return [returnedSnapshot, this._collectEffects(microsteps)];
|
|
742
868
|
}
|
|
743
869
|
start(snapshot) {
|
|
744
870
|
// Start rehydrated children that were active when persisted. Freshly
|
|
@@ -766,7 +892,9 @@ class StateMachine {
|
|
|
766
892
|
getPersistedSnapshot(snapshot, options) {
|
|
767
893
|
return dist_xstateActors.getPersistedSnapshot(snapshot, options);
|
|
768
894
|
}
|
|
769
|
-
restoreSnapshot(snapshot,
|
|
895
|
+
restoreSnapshot(snapshot, actorScope) {
|
|
896
|
+
const usesInertScope = !actorScope;
|
|
897
|
+
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
770
898
|
const persistedVersion = snapshot.version;
|
|
771
899
|
if (persistedVersion !== this.version) {
|
|
772
900
|
const migrate = this.config.migrate;
|
|
@@ -786,9 +914,9 @@ class StateMachine {
|
|
|
786
914
|
if (!logic) {
|
|
787
915
|
continue;
|
|
788
916
|
}
|
|
789
|
-
const actor =
|
|
917
|
+
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
790
918
|
id: actorId,
|
|
791
|
-
parent:
|
|
919
|
+
parent: resolvedActorScope.self,
|
|
792
920
|
syncSnapshot: actorData.syncSnapshot,
|
|
793
921
|
snapshot: childState,
|
|
794
922
|
src,
|
|
@@ -799,6 +927,19 @@ class StateMachine {
|
|
|
799
927
|
actor._rehydrated = true;
|
|
800
928
|
children[actorId] = actor;
|
|
801
929
|
}
|
|
930
|
+
const timers = {};
|
|
931
|
+
const persistedTimers = snapshotData.timers ?? {};
|
|
932
|
+
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
933
|
+
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
934
|
+
if (!target) {
|
|
935
|
+
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
936
|
+
throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
|
|
937
|
+
}
|
|
938
|
+
timers[id] = {
|
|
939
|
+
...timer,
|
|
940
|
+
target
|
|
941
|
+
};
|
|
942
|
+
}
|
|
802
943
|
const reviveHistoryValue = historyValue => {
|
|
803
944
|
if (!historyValue || typeof historyValue !== 'object') {
|
|
804
945
|
return {};
|
|
@@ -834,11 +975,12 @@ class StateMachine {
|
|
|
834
975
|
const restoredSnapshot = dist_xstateActors.createMachineSnapshot({
|
|
835
976
|
...persistedRest,
|
|
836
977
|
children,
|
|
978
|
+
timers,
|
|
837
979
|
_nodes: nodes,
|
|
838
980
|
value: snapshotData.value,
|
|
839
981
|
historyValue: revivedHistoryValue,
|
|
840
982
|
_stateInputs: snapshotData.stateInputs ?? {}
|
|
841
|
-
}, this);
|
|
983
|
+
}, this, resolvedActorScope.self);
|
|
842
984
|
const seen = new WeakSet();
|
|
843
985
|
function reviveContext(contextPart) {
|
|
844
986
|
if (seen.has(contextPart)) {
|
|
@@ -857,9 +999,18 @@ class StateMachine {
|
|
|
857
999
|
}
|
|
858
1000
|
}
|
|
859
1001
|
reviveContext(restoredSnapshot.context);
|
|
860
|
-
|
|
1002
|
+
if (usesInertScope) {
|
|
1003
|
+
setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
|
|
1004
|
+
return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
|
|
1005
|
+
}
|
|
1006
|
+
return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
|
|
861
1007
|
}
|
|
862
1008
|
}
|
|
863
1009
|
|
|
864
1010
|
exports.StateMachine = StateMachine;
|
|
865
1011
|
exports.StateNode = StateNode;
|
|
1012
|
+
exports.attachSnapshotActorRef = attachSnapshotActorRef;
|
|
1013
|
+
exports.createInertActorScope = createInertActorScope;
|
|
1014
|
+
exports.getInitialSnapshot = getInitialSnapshot;
|
|
1015
|
+
exports.getNextSnapshot = getNextSnapshot;
|
|
1016
|
+
exports.setInertActorScopeSnapshot = setInertActorScopeSnapshot;
|