xstate 5.0.0-beta.37 → 5.0.0-beta.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/dist/xstate-actions.cjs.js +4 -3
- package/actions/dist/xstate-actions.cjs.mjs +1 -0
- package/actions/dist/xstate-actions.development.cjs.js +4 -3
- package/actions/dist/xstate-actions.development.cjs.mjs +1 -0
- 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 +60 -3
- package/actors/dist/xstate-actors.development.cjs.js +60 -3
- package/actors/dist/xstate-actors.development.esm.js +60 -3
- package/actors/dist/xstate-actors.esm.js +60 -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/State.d.ts +2 -2
- package/dist/declarations/src/StateMachine.d.ts +7 -7
- package/dist/declarations/src/actions/assign.d.ts +4 -4
- package/dist/declarations/src/actions/cancel.d.ts +4 -4
- package/dist/declarations/src/actions/choose.d.ts +3 -3
- package/dist/declarations/src/actions/log.d.ts +4 -4
- package/dist/declarations/src/actions/pure.d.ts +4 -4
- package/dist/declarations/src/actions/raise.d.ts +3 -3
- package/dist/declarations/src/actions/send.d.ts +7 -7
- package/dist/declarations/src/actions/spawn.d.ts +34 -0
- package/dist/declarations/src/actions/stop.d.ts +4 -4
- package/dist/declarations/src/actions.d.ts +1 -0
- package/dist/declarations/src/actors/callback.d.ts +76 -2
- package/dist/declarations/src/actors/observable.d.ts +2 -3
- package/dist/declarations/src/actors/promise.d.ts +0 -1
- package/dist/declarations/src/actors/transition.d.ts +3 -3
- package/dist/declarations/src/guards.d.ts +9 -10
- package/dist/declarations/src/interpreter.d.ts +71 -10
- package/dist/declarations/src/spawn.d.ts +3 -4
- package/dist/declarations/src/stateUtils.d.ts +4 -9
- package/dist/declarations/src/types.d.ts +51 -62
- package/dist/{interpreter-e58ca48d.development.cjs.js → interpreter-03a5c3f5.development.cjs.js} +91 -12
- package/dist/{interpreter-8def682e.esm.js → interpreter-1e8c1c0c.esm.js} +91 -12
- package/dist/{interpreter-97aff8d2.cjs.js → interpreter-5dfcd203.cjs.js} +91 -12
- package/dist/{interpreter-1c52b23c.development.esm.js → interpreter-70cd9217.development.esm.js} +91 -12
- package/dist/{raise-1fd59c65.development.cjs.js → raise-17cb3d9d.development.cjs.js} +145 -152
- package/dist/{raise-800296d7.cjs.js → raise-291d2181.cjs.js} +145 -152
- package/dist/{raise-21c417c1.esm.js → raise-62de3670.esm.js} +145 -153
- package/dist/{raise-e342a840.development.esm.js → raise-e044f460.development.esm.js} +145 -153
- package/dist/{send-92854675.esm.js → send-1249d4ac.esm.js} +45 -44
- package/dist/{send-b309ef4e.development.cjs.js → send-33433787.development.cjs.js} +45 -44
- package/dist/{send-4cc29786.cjs.js → send-af152aca.cjs.js} +45 -44
- package/dist/{send-83ccc98b.development.esm.js → send-f1a2a827.development.esm.js} +45 -44
- package/dist/xstate.cjs.js +23 -20
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +23 -20
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +25 -23
- package/dist/xstate.esm.js +25 -23
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.cjs.js +2 -2
- package/guards/dist/xstate-guards.development.esm.js +2 -2
- package/guards/dist/xstate-guards.esm.js +2 -2
- package/guards/dist/xstate-guards.umd.min.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-
|
|
1
|
+
import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, X as XSTATE_STOP, u as XSTATE_INIT, W as WILDCARD, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-1e8c1c0c.esm.js';
|
|
2
2
|
|
|
3
3
|
const cache = new WeakMap();
|
|
4
4
|
function memo(object, key, fn) {
|
|
@@ -14,14 +14,14 @@ function memo(object, key, fn) {
|
|
|
14
14
|
return memoizedData[key];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
function resolveCancel(_, state, actionArgs, {
|
|
17
|
+
function resolveCancel(_, state, actionArgs, actionParams, {
|
|
18
18
|
sendId
|
|
19
19
|
}) {
|
|
20
|
-
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs) : sendId;
|
|
20
|
+
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
|
|
21
21
|
return [state, resolvedSendId];
|
|
22
22
|
}
|
|
23
|
-
function executeCancel(
|
|
24
|
-
|
|
23
|
+
function executeCancel(actorScope, resolvedSendId) {
|
|
24
|
+
actorScope.self.cancel(resolvedSendId);
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Cancels an in-flight `send(...)` action. A canceled sent action will not
|
|
@@ -31,7 +31,7 @@ function executeCancel(actorContext, resolvedSendId) {
|
|
|
31
31
|
* @param sendId The `id` of the `send(...)` action to cancel.
|
|
32
32
|
*/
|
|
33
33
|
function cancel(sendId) {
|
|
34
|
-
function cancel(
|
|
34
|
+
function cancel(args, params) {
|
|
35
35
|
}
|
|
36
36
|
cancel.type = 'xstate.cancel';
|
|
37
37
|
cancel.sendId = sendId;
|
|
@@ -40,7 +40,7 @@ function cancel(sendId) {
|
|
|
40
40
|
return cancel;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
function
|
|
43
|
+
function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
44
44
|
id,
|
|
45
45
|
systemId,
|
|
46
46
|
src,
|
|
@@ -51,93 +51,88 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
51
51
|
src,
|
|
52
52
|
input: undefined
|
|
53
53
|
};
|
|
54
|
+
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
54
55
|
let actorRef;
|
|
55
56
|
if (referenced) {
|
|
56
57
|
// TODO: inline `input: undefined` should win over the referenced one
|
|
57
58
|
const configuredInput = input || referenced.input;
|
|
58
59
|
actorRef = createActor(referenced.src, {
|
|
59
|
-
id,
|
|
60
|
+
id: resolvedId,
|
|
60
61
|
src: typeof src === 'string' ? src : undefined,
|
|
61
|
-
parent:
|
|
62
|
+
parent: actorScope?.self,
|
|
62
63
|
systemId,
|
|
63
64
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
64
65
|
context: state.context,
|
|
65
66
|
event: actionArgs.event,
|
|
66
|
-
self:
|
|
67
|
+
self: actorScope?.self
|
|
67
68
|
}) : configuredInput
|
|
68
69
|
});
|
|
69
70
|
if (syncSnapshot) {
|
|
70
71
|
actorRef.subscribe({
|
|
71
72
|
next: snapshot => {
|
|
72
73
|
if (snapshot.status === 'active') {
|
|
73
|
-
|
|
74
|
+
actorScope.self.send({
|
|
74
75
|
type: `xstate.snapshot.${id}`,
|
|
75
76
|
snapshot
|
|
76
77
|
});
|
|
77
78
|
}
|
|
78
79
|
},
|
|
79
|
-
error: () => {
|
|
80
|
-
/* TODO */
|
|
81
|
-
}
|
|
80
|
+
error: () => {}
|
|
82
81
|
});
|
|
83
82
|
}
|
|
84
83
|
}
|
|
85
84
|
return [cloneState(state, {
|
|
86
85
|
children: {
|
|
87
86
|
...state.children,
|
|
88
|
-
[
|
|
87
|
+
[resolvedId]: actorRef
|
|
89
88
|
}
|
|
90
89
|
}), {
|
|
91
90
|
id,
|
|
92
91
|
actorRef
|
|
93
92
|
}];
|
|
94
93
|
}
|
|
95
|
-
function
|
|
94
|
+
function executeSpawn(actorScope, {
|
|
96
95
|
id,
|
|
97
96
|
actorRef
|
|
98
97
|
}) {
|
|
99
98
|
if (!actorRef) {
|
|
100
99
|
return;
|
|
101
100
|
}
|
|
102
|
-
|
|
101
|
+
actorScope.defer(() => {
|
|
103
102
|
if (actorRef.status === ActorStatus.Stopped) {
|
|
104
103
|
return;
|
|
105
104
|
}
|
|
106
105
|
try {
|
|
107
106
|
actorRef.start?.();
|
|
108
107
|
} catch (err) {
|
|
109
|
-
|
|
108
|
+
actorScope.self.send(createErrorActorEvent(id, err));
|
|
110
109
|
return;
|
|
111
110
|
}
|
|
112
111
|
});
|
|
113
112
|
}
|
|
114
|
-
|
|
115
|
-
// we don't export this since it's an internal action that is not meant to be used in the user's code
|
|
116
|
-
|
|
117
|
-
function invoke({
|
|
113
|
+
function spawn(...[src, {
|
|
118
114
|
id,
|
|
119
115
|
systemId,
|
|
120
|
-
src,
|
|
121
116
|
input,
|
|
122
|
-
|
|
123
|
-
}) {
|
|
124
|
-
function
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return
|
|
117
|
+
syncSnapshot = false
|
|
118
|
+
} = {}]) {
|
|
119
|
+
function spawn(args, params) {
|
|
120
|
+
}
|
|
121
|
+
spawn.type = 'xstate.spawn';
|
|
122
|
+
spawn.id = id;
|
|
123
|
+
spawn.systemId = systemId;
|
|
124
|
+
spawn.src = src;
|
|
125
|
+
spawn.input = input;
|
|
126
|
+
spawn.syncSnapshot = syncSnapshot;
|
|
127
|
+
spawn.resolve = resolveSpawn;
|
|
128
|
+
spawn.execute = executeSpawn;
|
|
129
|
+
return spawn;
|
|
135
130
|
}
|
|
136
131
|
|
|
137
|
-
function resolveStop(_, state, args, {
|
|
132
|
+
function resolveStop(_, state, args, actionParams, {
|
|
138
133
|
actorRef
|
|
139
134
|
}) {
|
|
140
|
-
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
|
|
135
|
+
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
|
|
141
136
|
const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
|
|
142
137
|
let children = state.children;
|
|
143
138
|
if (resolvedActorRef) {
|
|
@@ -150,22 +145,28 @@ function resolveStop(_, state, args, {
|
|
|
150
145
|
children
|
|
151
146
|
}), resolvedActorRef];
|
|
152
147
|
}
|
|
153
|
-
function executeStop(
|
|
148
|
+
function executeStop(actorScope, actorRef) {
|
|
154
149
|
if (!actorRef) {
|
|
155
150
|
return;
|
|
156
151
|
}
|
|
152
|
+
|
|
153
|
+
// we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
|
|
154
|
+
// since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
|
|
155
|
+
// this could throw on `systemId` collision, for example, when dealing with reentering transitions
|
|
156
|
+
actorScope.system._unregister(actorRef);
|
|
157
|
+
|
|
157
158
|
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
158
159
|
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
159
160
|
if (actorRef.status !== ActorStatus.Running) {
|
|
160
|
-
|
|
161
|
+
actorScope.stopChild(actorRef);
|
|
161
162
|
return;
|
|
162
163
|
}
|
|
163
164
|
// stopping a child enqueues a stop event in the child actor's mailbox
|
|
164
165
|
// we need for all of the already enqueued events to be processed before we stop the child
|
|
165
166
|
// the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
|
|
166
167
|
// and we don't want to ignore those events
|
|
167
|
-
|
|
168
|
-
|
|
168
|
+
actorScope.defer(() => {
|
|
169
|
+
actorScope.stopChild(actorRef);
|
|
169
170
|
});
|
|
170
171
|
}
|
|
171
172
|
/**
|
|
@@ -174,7 +175,7 @@ function executeStop(actorContext, actorRef) {
|
|
|
174
175
|
* @param actorRef The actor to stop.
|
|
175
176
|
*/
|
|
176
177
|
function stop(actorRef) {
|
|
177
|
-
function stop(
|
|
178
|
+
function stop(args, params) {
|
|
178
179
|
}
|
|
179
180
|
stop.type = 'xstate.stop';
|
|
180
181
|
stop.actorRef = actorRef;
|
|
@@ -193,7 +194,7 @@ function checkStateIn(state, _, {
|
|
|
193
194
|
return state.matches(stateValue);
|
|
194
195
|
}
|
|
195
196
|
function stateIn(stateValue) {
|
|
196
|
-
function stateIn(
|
|
197
|
+
function stateIn(args, params) {
|
|
197
198
|
return false;
|
|
198
199
|
}
|
|
199
200
|
stateIn.check = checkStateIn;
|
|
@@ -209,7 +210,7 @@ function checkNot(state, {
|
|
|
209
210
|
return !evaluateGuard(guards[0], context, event, state);
|
|
210
211
|
}
|
|
211
212
|
function not(guard) {
|
|
212
|
-
function not(
|
|
213
|
+
function not(args, params) {
|
|
213
214
|
return false;
|
|
214
215
|
}
|
|
215
216
|
not.check = checkNot;
|
|
@@ -225,7 +226,7 @@ function checkAnd(state, {
|
|
|
225
226
|
return guards.every(guard => evaluateGuard(guard, context, event, state));
|
|
226
227
|
}
|
|
227
228
|
function and(guards) {
|
|
228
|
-
function and(
|
|
229
|
+
function and(args, params) {
|
|
229
230
|
return false;
|
|
230
231
|
}
|
|
231
232
|
and.check = checkAnd;
|
|
@@ -241,7 +242,7 @@ function checkOr(state, {
|
|
|
241
242
|
return guards.some(guard => evaluateGuard(guard, context, event, state));
|
|
242
243
|
}
|
|
243
244
|
function or(guards) {
|
|
244
|
-
function or(
|
|
245
|
+
function or(args, params) {
|
|
245
246
|
return false;
|
|
246
247
|
}
|
|
247
248
|
or.check = checkOr;
|
|
@@ -264,22 +265,17 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
264
265
|
}
|
|
265
266
|
const guardArgs = {
|
|
266
267
|
context,
|
|
267
|
-
event
|
|
268
|
-
guard: isInline ? undefined : typeof guard === 'string' ? {
|
|
269
|
-
type: guard
|
|
270
|
-
} : typeof guard.params === 'function' ? {
|
|
271
|
-
type: guard.type,
|
|
272
|
-
params: guard.params({
|
|
273
|
-
context,
|
|
274
|
-
event
|
|
275
|
-
})
|
|
276
|
-
} : guard
|
|
268
|
+
event
|
|
277
269
|
};
|
|
270
|
+
const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
|
|
271
|
+
context,
|
|
272
|
+
event
|
|
273
|
+
}) : guard.params : undefined;
|
|
278
274
|
if (!('check' in resolved)) {
|
|
279
275
|
// the existing type of `.guards` assumes non-nullable `TExpressionGuard`
|
|
280
276
|
// inline guards expect `TExpressionGuard` to be set to `undefined`
|
|
281
277
|
// it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
|
|
282
|
-
return resolved(guardArgs);
|
|
278
|
+
return resolved(guardArgs, guardParams);
|
|
283
279
|
}
|
|
284
280
|
const builtinGuard = resolved;
|
|
285
281
|
return builtinGuard.check(state, guardArgs, resolved // this holds all params
|
|
@@ -733,15 +729,6 @@ function isDescendant(childStateNode, parentStateNode) {
|
|
|
733
729
|
}
|
|
734
730
|
return marker.parent === parentStateNode;
|
|
735
731
|
}
|
|
736
|
-
function getPathFromRootToNode(stateNode) {
|
|
737
|
-
const path = [];
|
|
738
|
-
let marker = stateNode.parent;
|
|
739
|
-
while (marker) {
|
|
740
|
-
path.unshift(marker);
|
|
741
|
-
marker = marker.parent;
|
|
742
|
-
}
|
|
743
|
-
return path;
|
|
744
|
-
}
|
|
745
732
|
function hasIntersection(s1, s2) {
|
|
746
733
|
const set1 = new Set(s1);
|
|
747
734
|
const set2 = new Set(s2);
|
|
@@ -781,17 +768,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
|
|
|
781
768
|
}
|
|
782
769
|
return Array.from(filteredTransitions);
|
|
783
770
|
}
|
|
784
|
-
function
|
|
785
|
-
const [head] = stateNodes;
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
candidates = current.filter(sn => path.includes(sn));
|
|
791
|
-
current = candidates;
|
|
792
|
-
candidates = [];
|
|
771
|
+
function findLeastCommonAncestor(stateNodes) {
|
|
772
|
+
const [head, ...tail] = stateNodes;
|
|
773
|
+
for (const ancestor of getProperAncestors(head, undefined)) {
|
|
774
|
+
if (tail.every(sn => isDescendant(sn, ancestor))) {
|
|
775
|
+
return ancestor;
|
|
776
|
+
}
|
|
793
777
|
}
|
|
794
|
-
return current[current.length - 1];
|
|
795
778
|
}
|
|
796
779
|
function getEffectiveTargetStates(transition, historyValue) {
|
|
797
780
|
if (!transition.target) {
|
|
@@ -823,8 +806,16 @@ function getTransitionDomain(transition, historyValue) {
|
|
|
823
806
|
if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
|
|
824
807
|
return transition.source;
|
|
825
808
|
}
|
|
826
|
-
const
|
|
827
|
-
|
|
809
|
+
const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
|
|
810
|
+
if (lca) {
|
|
811
|
+
return lca;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// at this point we know that it's a root transition since LCA couldn't be found
|
|
815
|
+
if (transition.reenter) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
return transition.source.machine.root;
|
|
828
819
|
}
|
|
829
820
|
function computeExitSet(transitions, configuration, historyValue) {
|
|
830
821
|
const statesToExit = new Set();
|
|
@@ -857,13 +848,8 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
|
857
848
|
|
|
858
849
|
/**
|
|
859
850
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
860
|
-
*
|
|
861
|
-
* @private
|
|
862
|
-
* @param transitions
|
|
863
|
-
* @param currentState
|
|
864
|
-
* @param mutConfiguration
|
|
865
851
|
*/
|
|
866
|
-
function microstep(transitions, currentState,
|
|
852
|
+
function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
|
|
867
853
|
if (!transitions.length) {
|
|
868
854
|
return currentState;
|
|
869
855
|
}
|
|
@@ -874,17 +860,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
874
860
|
|
|
875
861
|
// Exit states
|
|
876
862
|
if (!isInitial) {
|
|
877
|
-
[nextState, historyValue] = exitStates(nextState, event,
|
|
863
|
+
[nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
|
|
878
864
|
}
|
|
879
865
|
|
|
880
866
|
// Execute transition content
|
|
881
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
867
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
|
|
882
868
|
|
|
883
869
|
// Enter states
|
|
884
|
-
nextState = enterStates(nextState, event,
|
|
870
|
+
nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
|
|
885
871
|
const nextConfiguration = [...mutConfiguration];
|
|
886
872
|
if (nextState.status === 'done') {
|
|
887
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
873
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
|
|
888
874
|
}
|
|
889
875
|
try {
|
|
890
876
|
if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
|
|
@@ -900,14 +886,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
900
886
|
throw e;
|
|
901
887
|
}
|
|
902
888
|
}
|
|
903
|
-
function getMachineOutput(state, event,
|
|
889
|
+
function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
|
|
904
890
|
if (!rootNode.output) {
|
|
905
891
|
return;
|
|
906
892
|
}
|
|
907
|
-
const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event,
|
|
908
|
-
return resolveOutput(rootNode.output, state.context, doneStateEvent,
|
|
893
|
+
const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
|
|
894
|
+
return resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
|
|
909
895
|
}
|
|
910
|
-
function enterStates(currentState, event,
|
|
896
|
+
function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
911
897
|
let nextState = currentState;
|
|
912
898
|
const statesToEnter = new Set();
|
|
913
899
|
// those are states that were directly targeted or indirectly targeted by the explicit target
|
|
@@ -928,19 +914,22 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
928
914
|
// Add entry actions
|
|
929
915
|
actions.push(...stateNodeToEnter.entry);
|
|
930
916
|
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
931
|
-
actions.push(
|
|
917
|
+
actions.push(spawn(invokeDef.src, {
|
|
918
|
+
...invokeDef,
|
|
919
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
920
|
+
}));
|
|
932
921
|
}
|
|
933
922
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
934
923
|
const initialActions = stateNodeToEnter.initial.actions;
|
|
935
924
|
actions.push(...initialActions);
|
|
936
925
|
}
|
|
937
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
926
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
938
927
|
if (stateNodeToEnter.type === 'final') {
|
|
939
928
|
const parent = stateNodeToEnter.parent;
|
|
940
929
|
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
941
930
|
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
942
931
|
if (parent?.type === 'compound') {
|
|
943
|
-
internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event,
|
|
932
|
+
internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
|
|
944
933
|
}
|
|
945
934
|
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
946
935
|
completedNodes.add(ancestorMarker);
|
|
@@ -953,7 +942,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
953
942
|
}
|
|
954
943
|
nextState = cloneState(nextState, {
|
|
955
944
|
status: 'done',
|
|
956
|
-
output: getMachineOutput(nextState, event,
|
|
945
|
+
output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
|
|
957
946
|
});
|
|
958
947
|
}
|
|
959
948
|
}
|
|
@@ -978,7 +967,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
|
|
|
978
967
|
}
|
|
979
968
|
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
980
969
|
for (const s of targetStates) {
|
|
981
|
-
|
|
970
|
+
const ancestors = getProperAncestors(s, domain);
|
|
971
|
+
if (domain?.type === 'parallel') {
|
|
972
|
+
ancestors.push(domain);
|
|
973
|
+
}
|
|
974
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
|
|
982
975
|
}
|
|
983
976
|
}
|
|
984
977
|
}
|
|
@@ -991,7 +984,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
991
984
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
992
985
|
}
|
|
993
986
|
for (const s of historyStateNodes) {
|
|
994
|
-
|
|
987
|
+
addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
995
988
|
}
|
|
996
989
|
} else {
|
|
997
990
|
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
@@ -1003,7 +996,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1003
996
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1004
997
|
}
|
|
1005
998
|
for (const s of historyDefaultTransition.target) {
|
|
1006
|
-
|
|
999
|
+
addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1007
1000
|
}
|
|
1008
1001
|
}
|
|
1009
1002
|
} else {
|
|
@@ -1014,7 +1007,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1014
1007
|
statesForDefaultEntry.add(initialState);
|
|
1015
1008
|
}
|
|
1016
1009
|
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1017
|
-
|
|
1010
|
+
addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1018
1011
|
} else {
|
|
1019
1012
|
if (stateNode.type === 'parallel') {
|
|
1020
1013
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
@@ -1030,10 +1023,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1030
1023
|
}
|
|
1031
1024
|
}
|
|
1032
1025
|
}
|
|
1033
|
-
function addAncestorStatesToEnter(
|
|
1034
|
-
const
|
|
1035
|
-
|
|
1036
|
-
|
|
1026
|
+
function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
|
|
1027
|
+
for (const anc of ancestors) {
|
|
1028
|
+
if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
|
|
1029
|
+
statesToEnter.add(anc);
|
|
1030
|
+
}
|
|
1037
1031
|
if (anc.type === 'parallel') {
|
|
1038
1032
|
for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
|
|
1039
1033
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
@@ -1044,7 +1038,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1044
1038
|
}
|
|
1045
1039
|
}
|
|
1046
1040
|
}
|
|
1047
|
-
function
|
|
1041
|
+
function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
|
|
1042
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
|
|
1043
|
+
}
|
|
1044
|
+
function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
|
|
1048
1045
|
let nextState = currentState;
|
|
1049
1046
|
const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
|
|
1050
1047
|
statesToExit.sort((a, b) => b.order - a.order);
|
|
@@ -1068,12 +1065,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
|
|
|
1068
1065
|
}
|
|
1069
1066
|
}
|
|
1070
1067
|
for (const s of statesToExit) {
|
|
1071
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
1068
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
|
|
1072
1069
|
mutConfiguration.delete(s);
|
|
1073
1070
|
}
|
|
1074
1071
|
return [nextState, changedHistory || historyValue];
|
|
1075
1072
|
}
|
|
1076
|
-
function resolveActionsAndContextWorker(currentState, event,
|
|
1073
|
+
function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
|
|
1077
1074
|
const {
|
|
1078
1075
|
machine
|
|
1079
1076
|
} = currentState;
|
|
@@ -1091,32 +1088,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1091
1088
|
const actionArgs = {
|
|
1092
1089
|
context: intermediateState.context,
|
|
1093
1090
|
event,
|
|
1094
|
-
self:
|
|
1095
|
-
system:
|
|
1096
|
-
action: isInline ? undefined : typeof action === 'string' ? {
|
|
1097
|
-
type: action
|
|
1098
|
-
} : typeof action.params === 'function' ? {
|
|
1099
|
-
type: action.type,
|
|
1100
|
-
params: action.params({
|
|
1101
|
-
context: intermediateState.context,
|
|
1102
|
-
event
|
|
1103
|
-
})
|
|
1104
|
-
} :
|
|
1105
|
-
// TS isn't able to narrow it down here
|
|
1106
|
-
action
|
|
1091
|
+
self: actorScope?.self,
|
|
1092
|
+
system: actorScope?.system
|
|
1107
1093
|
};
|
|
1094
|
+
const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
|
|
1095
|
+
context: intermediateState.context,
|
|
1096
|
+
event
|
|
1097
|
+
}) : action.params : undefined;
|
|
1108
1098
|
if (!('resolve' in resolvedAction)) {
|
|
1109
|
-
if (
|
|
1110
|
-
resolvedAction(actionArgs);
|
|
1099
|
+
if (actorScope?.self.status === ActorStatus.Running) {
|
|
1100
|
+
resolvedAction(actionArgs, actionParams);
|
|
1111
1101
|
} else {
|
|
1112
|
-
|
|
1113
|
-
resolvedAction(actionArgs);
|
|
1102
|
+
actorScope?.defer(() => {
|
|
1103
|
+
resolvedAction(actionArgs, actionParams);
|
|
1114
1104
|
});
|
|
1115
1105
|
}
|
|
1116
1106
|
continue;
|
|
1117
1107
|
}
|
|
1118
1108
|
const builtinAction = resolvedAction;
|
|
1119
|
-
const [nextState, params, actions] = builtinAction.resolve(
|
|
1109
|
+
const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
|
|
1120
1110
|
// this holds all params
|
|
1121
1111
|
extra);
|
|
1122
1112
|
intermediateState = nextState;
|
|
@@ -1124,36 +1114,38 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1124
1114
|
retries?.push([builtinAction, params]);
|
|
1125
1115
|
}
|
|
1126
1116
|
if ('execute' in builtinAction) {
|
|
1127
|
-
if (
|
|
1128
|
-
builtinAction.execute(
|
|
1117
|
+
if (actorScope?.self.status === ActorStatus.Running) {
|
|
1118
|
+
builtinAction.execute(actorScope, params);
|
|
1129
1119
|
} else {
|
|
1130
|
-
|
|
1120
|
+
actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
|
|
1131
1121
|
}
|
|
1132
1122
|
}
|
|
1133
1123
|
if (actions) {
|
|
1134
|
-
intermediateState = resolveActionsAndContextWorker(intermediateState, event,
|
|
1124
|
+
intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
|
|
1135
1125
|
}
|
|
1136
1126
|
}
|
|
1137
1127
|
return intermediateState;
|
|
1138
1128
|
}
|
|
1139
|
-
function resolveActionsAndContext(currentState, event,
|
|
1129
|
+
function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
|
|
1140
1130
|
const retries = deferredActorIds ? [] : undefined;
|
|
1141
|
-
const nextState = resolveActionsAndContextWorker(currentState, event,
|
|
1131
|
+
const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
|
|
1142
1132
|
internalQueue,
|
|
1143
1133
|
deferredActorIds
|
|
1144
1134
|
}, retries);
|
|
1145
1135
|
retries?.forEach(([builtinAction, params]) => {
|
|
1146
|
-
builtinAction.retryResolve(
|
|
1136
|
+
builtinAction.retryResolve(actorScope, nextState, params);
|
|
1147
1137
|
});
|
|
1148
1138
|
return nextState;
|
|
1149
1139
|
}
|
|
1150
|
-
function macrostep(state, event,
|
|
1140
|
+
function macrostep(state, event, actorScope, internalQueue = []) {
|
|
1151
1141
|
let nextState = state;
|
|
1152
1142
|
const states = [];
|
|
1153
1143
|
|
|
1154
1144
|
// Handle stop event
|
|
1155
1145
|
if (event.type === XSTATE_STOP) {
|
|
1156
|
-
nextState = stopChildren(nextState, event,
|
|
1146
|
+
nextState = cloneState(stopChildren(nextState, event, actorScope), {
|
|
1147
|
+
status: 'stopped'
|
|
1148
|
+
});
|
|
1157
1149
|
states.push(nextState);
|
|
1158
1150
|
return {
|
|
1159
1151
|
state: nextState,
|
|
@@ -1166,7 +1158,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1166
1158
|
// Determine the next state based on the next microstep
|
|
1167
1159
|
if (nextEvent.type !== XSTATE_INIT) {
|
|
1168
1160
|
const transitions = selectTransitions(nextEvent, nextState);
|
|
1169
|
-
nextState = microstep(transitions, state,
|
|
1161
|
+
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
1170
1162
|
states.push(nextState);
|
|
1171
1163
|
}
|
|
1172
1164
|
let shouldSelectEventlessTransitions = true;
|
|
@@ -1183,20 +1175,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1183
1175
|
nextEvent = internalQueue.shift();
|
|
1184
1176
|
enabledTransitions = selectTransitions(nextEvent, nextState);
|
|
1185
1177
|
}
|
|
1186
|
-
nextState = microstep(enabledTransitions, nextState,
|
|
1178
|
+
nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
|
|
1187
1179
|
shouldSelectEventlessTransitions = nextState !== previousState;
|
|
1188
1180
|
states.push(nextState);
|
|
1189
1181
|
}
|
|
1190
1182
|
if (nextState.status !== 'active') {
|
|
1191
|
-
stopChildren(nextState, nextEvent,
|
|
1183
|
+
stopChildren(nextState, nextEvent, actorScope);
|
|
1192
1184
|
}
|
|
1193
1185
|
return {
|
|
1194
1186
|
state: nextState,
|
|
1195
1187
|
microstates: states
|
|
1196
1188
|
};
|
|
1197
1189
|
}
|
|
1198
|
-
function stopChildren(nextState, event,
|
|
1199
|
-
return resolveActionsAndContext(nextState, event,
|
|
1190
|
+
function stopChildren(nextState, event, actorScope) {
|
|
1191
|
+
return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
|
|
1200
1192
|
}
|
|
1201
1193
|
function selectTransitions(event, nextState) {
|
|
1202
1194
|
return nextState.machine.getTransitionData(nextState, event);
|
|
@@ -1410,17 +1402,17 @@ function getPersistedState(state) {
|
|
|
1410
1402
|
for (const id in children) {
|
|
1411
1403
|
const child = children[id];
|
|
1412
1404
|
childrenJson[id] = {
|
|
1413
|
-
state: child.getPersistedState
|
|
1414
|
-
src: child.src
|
|
1405
|
+
state: child.getPersistedState(),
|
|
1406
|
+
src: child.src,
|
|
1407
|
+
systemId: child._systemId
|
|
1415
1408
|
};
|
|
1416
1409
|
}
|
|
1417
|
-
|
|
1410
|
+
const persisted = {
|
|
1418
1411
|
...jsonValues,
|
|
1419
|
-
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1420
|
-
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1421
1412
|
context: persistContext(context),
|
|
1422
1413
|
children: childrenJson
|
|
1423
1414
|
};
|
|
1415
|
+
return persisted;
|
|
1424
1416
|
}
|
|
1425
1417
|
function persistContext(contextPart) {
|
|
1426
1418
|
let copy;
|
|
@@ -1449,7 +1441,7 @@ function persistContext(contextPart) {
|
|
|
1449
1441
|
return copy ?? contextPart;
|
|
1450
1442
|
}
|
|
1451
1443
|
|
|
1452
|
-
function resolveRaise(_, state, args, {
|
|
1444
|
+
function resolveRaise(_, state, args, actionParams, {
|
|
1453
1445
|
event: eventOrExpr,
|
|
1454
1446
|
id,
|
|
1455
1447
|
delay
|
|
@@ -1460,13 +1452,13 @@ function resolveRaise(_, state, args, {
|
|
|
1460
1452
|
if (typeof eventOrExpr === 'string') {
|
|
1461
1453
|
throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
1462
1454
|
}
|
|
1463
|
-
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
|
|
1455
|
+
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
1464
1456
|
let resolvedDelay;
|
|
1465
1457
|
if (typeof delay === 'string') {
|
|
1466
1458
|
const configDelay = delaysMap && delaysMap[delay];
|
|
1467
|
-
resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
|
|
1459
|
+
resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
|
|
1468
1460
|
} else {
|
|
1469
|
-
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1461
|
+
resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
|
|
1470
1462
|
}
|
|
1471
1463
|
if (typeof resolvedDelay !== 'number') {
|
|
1472
1464
|
internalQueue.push(resolvedEvent);
|
|
@@ -1477,9 +1469,9 @@ function resolveRaise(_, state, args, {
|
|
|
1477
1469
|
delay: resolvedDelay
|
|
1478
1470
|
}];
|
|
1479
1471
|
}
|
|
1480
|
-
function executeRaise(
|
|
1472
|
+
function executeRaise(actorScope, params) {
|
|
1481
1473
|
if (typeof params.delay === 'number') {
|
|
1482
|
-
|
|
1474
|
+
actorScope.self.delaySend(params);
|
|
1483
1475
|
return;
|
|
1484
1476
|
}
|
|
1485
1477
|
}
|
|
@@ -1490,7 +1482,7 @@ function executeRaise(actorContext, params) {
|
|
|
1490
1482
|
* @param eventType The event to raise.
|
|
1491
1483
|
*/
|
|
1492
1484
|
function raise(eventOrExpr, options) {
|
|
1493
|
-
function raise(
|
|
1485
|
+
function raise(args, params) {
|
|
1494
1486
|
}
|
|
1495
1487
|
raise.type = 'xstate.raise';
|
|
1496
1488
|
raise.event = eventOrExpr;
|
|
@@ -1501,4 +1493,4 @@ function raise(eventOrExpr, options) {
|
|
|
1501
1493
|
return raise;
|
|
1502
1494
|
}
|
|
1503
1495
|
|
|
1504
|
-
export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
|
|
1496
|
+
export { raise as A, stop as B, spawn as C, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
|