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,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var interpreter = require('./interpreter-
|
|
3
|
+
var interpreter = require('./interpreter-03a5c3f5.development.cjs.js');
|
|
4
4
|
|
|
5
5
|
const cache = new WeakMap();
|
|
6
6
|
function memo(object, key, fn) {
|
|
@@ -16,14 +16,14 @@ function memo(object, key, fn) {
|
|
|
16
16
|
return memoizedData[key];
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
function resolveCancel(_, state, actionArgs, {
|
|
19
|
+
function resolveCancel(_, state, actionArgs, actionParams, {
|
|
20
20
|
sendId
|
|
21
21
|
}) {
|
|
22
|
-
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs) : sendId;
|
|
22
|
+
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
|
|
23
23
|
return [state, resolvedSendId];
|
|
24
24
|
}
|
|
25
|
-
function executeCancel(
|
|
26
|
-
|
|
25
|
+
function executeCancel(actorScope, resolvedSendId) {
|
|
26
|
+
actorScope.self.cancel(resolvedSendId);
|
|
27
27
|
}
|
|
28
28
|
/**
|
|
29
29
|
* Cancels an in-flight `send(...)` action. A canceled sent action will not
|
|
@@ -33,7 +33,7 @@ function executeCancel(actorContext, resolvedSendId) {
|
|
|
33
33
|
* @param sendId The `id` of the `send(...)` action to cancel.
|
|
34
34
|
*/
|
|
35
35
|
function cancel(sendId) {
|
|
36
|
-
function cancel(
|
|
36
|
+
function cancel(args, params) {
|
|
37
37
|
{
|
|
38
38
|
throw new Error(`This isn't supposed to be called`);
|
|
39
39
|
}
|
|
@@ -45,7 +45,7 @@ function cancel(sendId) {
|
|
|
45
45
|
return cancel;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function
|
|
48
|
+
function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
49
49
|
id,
|
|
50
50
|
systemId,
|
|
51
51
|
src,
|
|
@@ -56,99 +56,94 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
56
56
|
src,
|
|
57
57
|
input: undefined
|
|
58
58
|
};
|
|
59
|
+
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
59
60
|
let actorRef;
|
|
60
61
|
if (referenced) {
|
|
61
62
|
// TODO: inline `input: undefined` should win over the referenced one
|
|
62
63
|
const configuredInput = input || referenced.input;
|
|
63
64
|
actorRef = interpreter.createActor(referenced.src, {
|
|
64
|
-
id,
|
|
65
|
+
id: resolvedId,
|
|
65
66
|
src: typeof src === 'string' ? src : undefined,
|
|
66
|
-
parent:
|
|
67
|
+
parent: actorScope?.self,
|
|
67
68
|
systemId,
|
|
68
69
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
69
70
|
context: state.context,
|
|
70
71
|
event: actionArgs.event,
|
|
71
|
-
self:
|
|
72
|
+
self: actorScope?.self
|
|
72
73
|
}) : configuredInput
|
|
73
74
|
});
|
|
74
75
|
if (syncSnapshot) {
|
|
75
76
|
actorRef.subscribe({
|
|
76
77
|
next: snapshot => {
|
|
77
78
|
if (snapshot.status === 'active') {
|
|
78
|
-
|
|
79
|
+
actorScope.self.send({
|
|
79
80
|
type: `xstate.snapshot.${id}`,
|
|
80
81
|
snapshot
|
|
81
82
|
});
|
|
82
83
|
}
|
|
83
84
|
},
|
|
84
|
-
error: () => {
|
|
85
|
-
/* TODO */
|
|
86
|
-
}
|
|
85
|
+
error: () => {}
|
|
87
86
|
});
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
if (!actorRef) {
|
|
91
|
-
console.warn(`Actor type '${src}' not found in machine '${
|
|
90
|
+
console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
|
|
92
91
|
}
|
|
93
92
|
return [cloneState(state, {
|
|
94
93
|
children: {
|
|
95
94
|
...state.children,
|
|
96
|
-
[
|
|
95
|
+
[resolvedId]: actorRef
|
|
97
96
|
}
|
|
98
97
|
}), {
|
|
99
98
|
id,
|
|
100
99
|
actorRef
|
|
101
100
|
}];
|
|
102
101
|
}
|
|
103
|
-
function
|
|
102
|
+
function executeSpawn(actorScope, {
|
|
104
103
|
id,
|
|
105
104
|
actorRef
|
|
106
105
|
}) {
|
|
107
106
|
if (!actorRef) {
|
|
108
107
|
return;
|
|
109
108
|
}
|
|
110
|
-
|
|
109
|
+
actorScope.defer(() => {
|
|
111
110
|
if (actorRef.status === interpreter.ActorStatus.Stopped) {
|
|
112
111
|
return;
|
|
113
112
|
}
|
|
114
113
|
try {
|
|
115
114
|
actorRef.start?.();
|
|
116
115
|
} catch (err) {
|
|
117
|
-
|
|
116
|
+
actorScope.self.send(interpreter.createErrorActorEvent(id, err));
|
|
118
117
|
return;
|
|
119
118
|
}
|
|
120
119
|
});
|
|
121
120
|
}
|
|
122
|
-
|
|
123
|
-
// we don't export this since it's an internal action that is not meant to be used in the user's code
|
|
124
|
-
|
|
125
|
-
function invoke({
|
|
121
|
+
function spawn(...[src, {
|
|
126
122
|
id,
|
|
127
123
|
systemId,
|
|
128
|
-
src,
|
|
129
124
|
input,
|
|
130
|
-
|
|
131
|
-
}) {
|
|
132
|
-
function
|
|
125
|
+
syncSnapshot = false
|
|
126
|
+
} = {}]) {
|
|
127
|
+
function spawn(args, params) {
|
|
133
128
|
{
|
|
134
129
|
throw new Error(`This isn't supposed to be called`);
|
|
135
130
|
}
|
|
136
131
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return
|
|
132
|
+
spawn.type = 'xstate.spawn';
|
|
133
|
+
spawn.id = id;
|
|
134
|
+
spawn.systemId = systemId;
|
|
135
|
+
spawn.src = src;
|
|
136
|
+
spawn.input = input;
|
|
137
|
+
spawn.syncSnapshot = syncSnapshot;
|
|
138
|
+
spawn.resolve = resolveSpawn;
|
|
139
|
+
spawn.execute = executeSpawn;
|
|
140
|
+
return spawn;
|
|
146
141
|
}
|
|
147
142
|
|
|
148
|
-
function resolveStop(_, state, args, {
|
|
143
|
+
function resolveStop(_, state, args, actionParams, {
|
|
149
144
|
actorRef
|
|
150
145
|
}) {
|
|
151
|
-
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
|
|
146
|
+
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
|
|
152
147
|
const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
|
|
153
148
|
let children = state.children;
|
|
154
149
|
if (resolvedActorRef) {
|
|
@@ -161,22 +156,28 @@ function resolveStop(_, state, args, {
|
|
|
161
156
|
children
|
|
162
157
|
}), resolvedActorRef];
|
|
163
158
|
}
|
|
164
|
-
function executeStop(
|
|
159
|
+
function executeStop(actorScope, actorRef) {
|
|
165
160
|
if (!actorRef) {
|
|
166
161
|
return;
|
|
167
162
|
}
|
|
163
|
+
|
|
164
|
+
// we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
|
|
165
|
+
// since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
|
|
166
|
+
// this could throw on `systemId` collision, for example, when dealing with reentering transitions
|
|
167
|
+
actorScope.system._unregister(actorRef);
|
|
168
|
+
|
|
168
169
|
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
169
170
|
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
170
171
|
if (actorRef.status !== interpreter.ActorStatus.Running) {
|
|
171
|
-
|
|
172
|
+
actorScope.stopChild(actorRef);
|
|
172
173
|
return;
|
|
173
174
|
}
|
|
174
175
|
// stopping a child enqueues a stop event in the child actor's mailbox
|
|
175
176
|
// we need for all of the already enqueued events to be processed before we stop the child
|
|
176
177
|
// the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
|
|
177
178
|
// and we don't want to ignore those events
|
|
178
|
-
|
|
179
|
-
|
|
179
|
+
actorScope.defer(() => {
|
|
180
|
+
actorScope.stopChild(actorRef);
|
|
180
181
|
});
|
|
181
182
|
}
|
|
182
183
|
/**
|
|
@@ -185,7 +186,7 @@ function executeStop(actorContext, actorRef) {
|
|
|
185
186
|
* @param actorRef The actor to stop.
|
|
186
187
|
*/
|
|
187
188
|
function stop(actorRef) {
|
|
188
|
-
function stop(
|
|
189
|
+
function stop(args, params) {
|
|
189
190
|
{
|
|
190
191
|
throw new Error(`This isn't supposed to be called`);
|
|
191
192
|
}
|
|
@@ -207,7 +208,7 @@ function checkStateIn(state, _, {
|
|
|
207
208
|
return state.matches(stateValue);
|
|
208
209
|
}
|
|
209
210
|
function stateIn(stateValue) {
|
|
210
|
-
function stateIn(
|
|
211
|
+
function stateIn(args, params) {
|
|
211
212
|
{
|
|
212
213
|
throw new Error(`This isn't supposed to be called`);
|
|
213
214
|
}
|
|
@@ -225,7 +226,7 @@ function checkNot(state, {
|
|
|
225
226
|
return !evaluateGuard(guards[0], context, event, state);
|
|
226
227
|
}
|
|
227
228
|
function not(guard) {
|
|
228
|
-
function not(
|
|
229
|
+
function not(args, params) {
|
|
229
230
|
{
|
|
230
231
|
throw new Error(`This isn't supposed to be called`);
|
|
231
232
|
}
|
|
@@ -243,7 +244,7 @@ function checkAnd(state, {
|
|
|
243
244
|
return guards.every(guard => evaluateGuard(guard, context, event, state));
|
|
244
245
|
}
|
|
245
246
|
function and(guards) {
|
|
246
|
-
function and(
|
|
247
|
+
function and(args, params) {
|
|
247
248
|
{
|
|
248
249
|
throw new Error(`This isn't supposed to be called`);
|
|
249
250
|
}
|
|
@@ -261,7 +262,7 @@ function checkOr(state, {
|
|
|
261
262
|
return guards.some(guard => evaluateGuard(guard, context, event, state));
|
|
262
263
|
}
|
|
263
264
|
function or(guards) {
|
|
264
|
-
function or(
|
|
265
|
+
function or(args, params) {
|
|
265
266
|
{
|
|
266
267
|
throw new Error(`This isn't supposed to be called`);
|
|
267
268
|
}
|
|
@@ -286,22 +287,17 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
286
287
|
}
|
|
287
288
|
const guardArgs = {
|
|
288
289
|
context,
|
|
289
|
-
event
|
|
290
|
-
guard: isInline ? undefined : typeof guard === 'string' ? {
|
|
291
|
-
type: guard
|
|
292
|
-
} : typeof guard.params === 'function' ? {
|
|
293
|
-
type: guard.type,
|
|
294
|
-
params: guard.params({
|
|
295
|
-
context,
|
|
296
|
-
event
|
|
297
|
-
})
|
|
298
|
-
} : guard
|
|
290
|
+
event
|
|
299
291
|
};
|
|
292
|
+
const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
|
|
293
|
+
context,
|
|
294
|
+
event
|
|
295
|
+
}) : guard.params : undefined;
|
|
300
296
|
if (!('check' in resolved)) {
|
|
301
297
|
// the existing type of `.guards` assumes non-nullable `TExpressionGuard`
|
|
302
298
|
// inline guards expect `TExpressionGuard` to be set to `undefined`
|
|
303
299
|
// it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
|
|
304
|
-
return resolved(guardArgs);
|
|
300
|
+
return resolved(guardArgs, guardParams);
|
|
305
301
|
}
|
|
306
302
|
const builtinGuard = resolved;
|
|
307
303
|
return builtinGuard.check(state, guardArgs, resolved // this holds all params
|
|
@@ -766,15 +762,6 @@ function isDescendant(childStateNode, parentStateNode) {
|
|
|
766
762
|
}
|
|
767
763
|
return marker.parent === parentStateNode;
|
|
768
764
|
}
|
|
769
|
-
function getPathFromRootToNode(stateNode) {
|
|
770
|
-
const path = [];
|
|
771
|
-
let marker = stateNode.parent;
|
|
772
|
-
while (marker) {
|
|
773
|
-
path.unshift(marker);
|
|
774
|
-
marker = marker.parent;
|
|
775
|
-
}
|
|
776
|
-
return path;
|
|
777
|
-
}
|
|
778
765
|
function hasIntersection(s1, s2) {
|
|
779
766
|
const set1 = new Set(s1);
|
|
780
767
|
const set2 = new Set(s2);
|
|
@@ -814,17 +801,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
|
|
|
814
801
|
}
|
|
815
802
|
return Array.from(filteredTransitions);
|
|
816
803
|
}
|
|
817
|
-
function
|
|
818
|
-
const [head] = stateNodes;
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
candidates = current.filter(sn => path.includes(sn));
|
|
824
|
-
current = candidates;
|
|
825
|
-
candidates = [];
|
|
804
|
+
function findLeastCommonAncestor(stateNodes) {
|
|
805
|
+
const [head, ...tail] = stateNodes;
|
|
806
|
+
for (const ancestor of getProperAncestors(head, undefined)) {
|
|
807
|
+
if (tail.every(sn => isDescendant(sn, ancestor))) {
|
|
808
|
+
return ancestor;
|
|
809
|
+
}
|
|
826
810
|
}
|
|
827
|
-
return current[current.length - 1];
|
|
828
811
|
}
|
|
829
812
|
function getEffectiveTargetStates(transition, historyValue) {
|
|
830
813
|
if (!transition.target) {
|
|
@@ -856,8 +839,16 @@ function getTransitionDomain(transition, historyValue) {
|
|
|
856
839
|
if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
|
|
857
840
|
return transition.source;
|
|
858
841
|
}
|
|
859
|
-
const
|
|
860
|
-
|
|
842
|
+
const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
|
|
843
|
+
if (lca) {
|
|
844
|
+
return lca;
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
// at this point we know that it's a root transition since LCA couldn't be found
|
|
848
|
+
if (transition.reenter) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
return transition.source.machine.root;
|
|
861
852
|
}
|
|
862
853
|
function computeExitSet(transitions, configuration, historyValue) {
|
|
863
854
|
const statesToExit = new Set();
|
|
@@ -890,13 +881,8 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
|
890
881
|
|
|
891
882
|
/**
|
|
892
883
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
893
|
-
*
|
|
894
|
-
* @private
|
|
895
|
-
* @param transitions
|
|
896
|
-
* @param currentState
|
|
897
|
-
* @param mutConfiguration
|
|
898
884
|
*/
|
|
899
|
-
function microstep(transitions, currentState,
|
|
885
|
+
function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
|
|
900
886
|
if (!transitions.length) {
|
|
901
887
|
return currentState;
|
|
902
888
|
}
|
|
@@ -907,17 +893,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
907
893
|
|
|
908
894
|
// Exit states
|
|
909
895
|
if (!isInitial) {
|
|
910
|
-
[nextState, historyValue] = exitStates(nextState, event,
|
|
896
|
+
[nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
|
|
911
897
|
}
|
|
912
898
|
|
|
913
899
|
// Execute transition content
|
|
914
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
900
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
|
|
915
901
|
|
|
916
902
|
// Enter states
|
|
917
|
-
nextState = enterStates(nextState, event,
|
|
903
|
+
nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
|
|
918
904
|
const nextConfiguration = [...mutConfiguration];
|
|
919
905
|
if (nextState.status === 'done') {
|
|
920
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
906
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
|
|
921
907
|
}
|
|
922
908
|
try {
|
|
923
909
|
if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
|
|
@@ -933,14 +919,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
933
919
|
throw e;
|
|
934
920
|
}
|
|
935
921
|
}
|
|
936
|
-
function getMachineOutput(state, event,
|
|
922
|
+
function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
|
|
937
923
|
if (!rootNode.output) {
|
|
938
924
|
return;
|
|
939
925
|
}
|
|
940
|
-
const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event,
|
|
941
|
-
return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent,
|
|
926
|
+
const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
|
|
927
|
+
return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
|
|
942
928
|
}
|
|
943
|
-
function enterStates(currentState, event,
|
|
929
|
+
function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
944
930
|
let nextState = currentState;
|
|
945
931
|
const statesToEnter = new Set();
|
|
946
932
|
// those are states that were directly targeted or indirectly targeted by the explicit target
|
|
@@ -961,19 +947,22 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
961
947
|
// Add entry actions
|
|
962
948
|
actions.push(...stateNodeToEnter.entry);
|
|
963
949
|
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
964
|
-
actions.push(
|
|
950
|
+
actions.push(spawn(invokeDef.src, {
|
|
951
|
+
...invokeDef,
|
|
952
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
953
|
+
}));
|
|
965
954
|
}
|
|
966
955
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
967
956
|
const initialActions = stateNodeToEnter.initial.actions;
|
|
968
957
|
actions.push(...initialActions);
|
|
969
958
|
}
|
|
970
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
959
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
971
960
|
if (stateNodeToEnter.type === 'final') {
|
|
972
961
|
const parent = stateNodeToEnter.parent;
|
|
973
962
|
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
974
963
|
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
975
964
|
if (parent?.type === 'compound') {
|
|
976
|
-
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event,
|
|
965
|
+
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
|
|
977
966
|
}
|
|
978
967
|
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
979
968
|
completedNodes.add(ancestorMarker);
|
|
@@ -986,7 +975,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
986
975
|
}
|
|
987
976
|
nextState = cloneState(nextState, {
|
|
988
977
|
status: 'done',
|
|
989
|
-
output: getMachineOutput(nextState, event,
|
|
978
|
+
output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
|
|
990
979
|
});
|
|
991
980
|
}
|
|
992
981
|
}
|
|
@@ -1011,7 +1000,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
|
|
|
1011
1000
|
}
|
|
1012
1001
|
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
1013
1002
|
for (const s of targetStates) {
|
|
1014
|
-
|
|
1003
|
+
const ancestors = getProperAncestors(s, domain);
|
|
1004
|
+
if (domain?.type === 'parallel') {
|
|
1005
|
+
ancestors.push(domain);
|
|
1006
|
+
}
|
|
1007
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
|
|
1015
1008
|
}
|
|
1016
1009
|
}
|
|
1017
1010
|
}
|
|
@@ -1024,7 +1017,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1024
1017
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1025
1018
|
}
|
|
1026
1019
|
for (const s of historyStateNodes) {
|
|
1027
|
-
|
|
1020
|
+
addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1028
1021
|
}
|
|
1029
1022
|
} else {
|
|
1030
1023
|
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
@@ -1036,7 +1029,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1036
1029
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1037
1030
|
}
|
|
1038
1031
|
for (const s of historyDefaultTransition.target) {
|
|
1039
|
-
|
|
1032
|
+
addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1040
1033
|
}
|
|
1041
1034
|
}
|
|
1042
1035
|
} else {
|
|
@@ -1047,7 +1040,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1047
1040
|
statesForDefaultEntry.add(initialState);
|
|
1048
1041
|
}
|
|
1049
1042
|
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1050
|
-
|
|
1043
|
+
addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1051
1044
|
} else {
|
|
1052
1045
|
if (stateNode.type === 'parallel') {
|
|
1053
1046
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
@@ -1063,10 +1056,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1063
1056
|
}
|
|
1064
1057
|
}
|
|
1065
1058
|
}
|
|
1066
|
-
function addAncestorStatesToEnter(
|
|
1067
|
-
const
|
|
1068
|
-
|
|
1069
|
-
|
|
1059
|
+
function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
|
|
1060
|
+
for (const anc of ancestors) {
|
|
1061
|
+
if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
|
|
1062
|
+
statesToEnter.add(anc);
|
|
1063
|
+
}
|
|
1070
1064
|
if (anc.type === 'parallel') {
|
|
1071
1065
|
for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
|
|
1072
1066
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
@@ -1077,7 +1071,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1077
1071
|
}
|
|
1078
1072
|
}
|
|
1079
1073
|
}
|
|
1080
|
-
function
|
|
1074
|
+
function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
|
|
1075
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
|
|
1076
|
+
}
|
|
1077
|
+
function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
|
|
1081
1078
|
let nextState = currentState;
|
|
1082
1079
|
const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
|
|
1083
1080
|
statesToExit.sort((a, b) => b.order - a.order);
|
|
@@ -1101,12 +1098,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
|
|
|
1101
1098
|
}
|
|
1102
1099
|
}
|
|
1103
1100
|
for (const s of statesToExit) {
|
|
1104
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
1101
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
|
|
1105
1102
|
mutConfiguration.delete(s);
|
|
1106
1103
|
}
|
|
1107
1104
|
return [nextState, changedHistory || historyValue];
|
|
1108
1105
|
}
|
|
1109
|
-
function resolveActionsAndContextWorker(currentState, event,
|
|
1106
|
+
function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
|
|
1110
1107
|
const {
|
|
1111
1108
|
machine
|
|
1112
1109
|
} = currentState;
|
|
@@ -1124,32 +1121,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1124
1121
|
const actionArgs = {
|
|
1125
1122
|
context: intermediateState.context,
|
|
1126
1123
|
event,
|
|
1127
|
-
self:
|
|
1128
|
-
system:
|
|
1129
|
-
action: isInline ? undefined : typeof action === 'string' ? {
|
|
1130
|
-
type: action
|
|
1131
|
-
} : typeof action.params === 'function' ? {
|
|
1132
|
-
type: action.type,
|
|
1133
|
-
params: action.params({
|
|
1134
|
-
context: intermediateState.context,
|
|
1135
|
-
event
|
|
1136
|
-
})
|
|
1137
|
-
} :
|
|
1138
|
-
// TS isn't able to narrow it down here
|
|
1139
|
-
action
|
|
1124
|
+
self: actorScope?.self,
|
|
1125
|
+
system: actorScope?.system
|
|
1140
1126
|
};
|
|
1127
|
+
const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
|
|
1128
|
+
context: intermediateState.context,
|
|
1129
|
+
event
|
|
1130
|
+
}) : action.params : undefined;
|
|
1141
1131
|
if (!('resolve' in resolvedAction)) {
|
|
1142
|
-
if (
|
|
1143
|
-
resolvedAction(actionArgs);
|
|
1132
|
+
if (actorScope?.self.status === interpreter.ActorStatus.Running) {
|
|
1133
|
+
resolvedAction(actionArgs, actionParams);
|
|
1144
1134
|
} else {
|
|
1145
|
-
|
|
1146
|
-
resolvedAction(actionArgs);
|
|
1135
|
+
actorScope?.defer(() => {
|
|
1136
|
+
resolvedAction(actionArgs, actionParams);
|
|
1147
1137
|
});
|
|
1148
1138
|
}
|
|
1149
1139
|
continue;
|
|
1150
1140
|
}
|
|
1151
1141
|
const builtinAction = resolvedAction;
|
|
1152
|
-
const [nextState, params, actions] = builtinAction.resolve(
|
|
1142
|
+
const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
|
|
1153
1143
|
// this holds all params
|
|
1154
1144
|
extra);
|
|
1155
1145
|
intermediateState = nextState;
|
|
@@ -1157,30 +1147,30 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1157
1147
|
retries?.push([builtinAction, params]);
|
|
1158
1148
|
}
|
|
1159
1149
|
if ('execute' in builtinAction) {
|
|
1160
|
-
if (
|
|
1161
|
-
builtinAction.execute(
|
|
1150
|
+
if (actorScope?.self.status === interpreter.ActorStatus.Running) {
|
|
1151
|
+
builtinAction.execute(actorScope, params);
|
|
1162
1152
|
} else {
|
|
1163
|
-
|
|
1153
|
+
actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
|
|
1164
1154
|
}
|
|
1165
1155
|
}
|
|
1166
1156
|
if (actions) {
|
|
1167
|
-
intermediateState = resolveActionsAndContextWorker(intermediateState, event,
|
|
1157
|
+
intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
|
|
1168
1158
|
}
|
|
1169
1159
|
}
|
|
1170
1160
|
return intermediateState;
|
|
1171
1161
|
}
|
|
1172
|
-
function resolveActionsAndContext(currentState, event,
|
|
1162
|
+
function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
|
|
1173
1163
|
const retries = deferredActorIds ? [] : undefined;
|
|
1174
|
-
const nextState = resolveActionsAndContextWorker(currentState, event,
|
|
1164
|
+
const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
|
|
1175
1165
|
internalQueue,
|
|
1176
1166
|
deferredActorIds
|
|
1177
1167
|
}, retries);
|
|
1178
1168
|
retries?.forEach(([builtinAction, params]) => {
|
|
1179
|
-
builtinAction.retryResolve(
|
|
1169
|
+
builtinAction.retryResolve(actorScope, nextState, params);
|
|
1180
1170
|
});
|
|
1181
1171
|
return nextState;
|
|
1182
1172
|
}
|
|
1183
|
-
function macrostep(state, event,
|
|
1173
|
+
function macrostep(state, event, actorScope, internalQueue = []) {
|
|
1184
1174
|
if (event.type === interpreter.WILDCARD) {
|
|
1185
1175
|
throw new Error(`An event cannot have the wildcard type ('${interpreter.WILDCARD}')`);
|
|
1186
1176
|
}
|
|
@@ -1189,7 +1179,9 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1189
1179
|
|
|
1190
1180
|
// Handle stop event
|
|
1191
1181
|
if (event.type === interpreter.XSTATE_STOP) {
|
|
1192
|
-
nextState = stopChildren(nextState, event,
|
|
1182
|
+
nextState = cloneState(stopChildren(nextState, event, actorScope), {
|
|
1183
|
+
status: 'stopped'
|
|
1184
|
+
});
|
|
1193
1185
|
states.push(nextState);
|
|
1194
1186
|
return {
|
|
1195
1187
|
state: nextState,
|
|
@@ -1202,7 +1194,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1202
1194
|
// Determine the next state based on the next microstep
|
|
1203
1195
|
if (nextEvent.type !== interpreter.XSTATE_INIT) {
|
|
1204
1196
|
const transitions = selectTransitions(nextEvent, nextState);
|
|
1205
|
-
nextState = microstep(transitions, state,
|
|
1197
|
+
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
1206
1198
|
states.push(nextState);
|
|
1207
1199
|
}
|
|
1208
1200
|
let shouldSelectEventlessTransitions = true;
|
|
@@ -1219,20 +1211,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1219
1211
|
nextEvent = internalQueue.shift();
|
|
1220
1212
|
enabledTransitions = selectTransitions(nextEvent, nextState);
|
|
1221
1213
|
}
|
|
1222
|
-
nextState = microstep(enabledTransitions, nextState,
|
|
1214
|
+
nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
|
|
1223
1215
|
shouldSelectEventlessTransitions = nextState !== previousState;
|
|
1224
1216
|
states.push(nextState);
|
|
1225
1217
|
}
|
|
1226
1218
|
if (nextState.status !== 'active') {
|
|
1227
|
-
stopChildren(nextState, nextEvent,
|
|
1219
|
+
stopChildren(nextState, nextEvent, actorScope);
|
|
1228
1220
|
}
|
|
1229
1221
|
return {
|
|
1230
1222
|
state: nextState,
|
|
1231
1223
|
microstates: states
|
|
1232
1224
|
};
|
|
1233
1225
|
}
|
|
1234
|
-
function stopChildren(nextState, event,
|
|
1235
|
-
return resolveActionsAndContext(nextState, event,
|
|
1226
|
+
function stopChildren(nextState, event, actorScope) {
|
|
1227
|
+
return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
|
|
1236
1228
|
}
|
|
1237
1229
|
function selectTransitions(event, nextState) {
|
|
1238
1230
|
return nextState.machine.getTransitionData(nextState, event);
|
|
@@ -1452,17 +1444,17 @@ function getPersistedState(state) {
|
|
|
1452
1444
|
throw new Error('An inline child actor cannot be persisted.');
|
|
1453
1445
|
}
|
|
1454
1446
|
childrenJson[id] = {
|
|
1455
|
-
state: child.getPersistedState
|
|
1456
|
-
src: child.src
|
|
1447
|
+
state: child.getPersistedState(),
|
|
1448
|
+
src: child.src,
|
|
1449
|
+
systemId: child._systemId
|
|
1457
1450
|
};
|
|
1458
1451
|
}
|
|
1459
|
-
|
|
1452
|
+
const persisted = {
|
|
1460
1453
|
...jsonValues,
|
|
1461
|
-
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1462
|
-
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1463
1454
|
context: persistContext(context),
|
|
1464
1455
|
children: childrenJson
|
|
1465
1456
|
};
|
|
1457
|
+
return persisted;
|
|
1466
1458
|
}
|
|
1467
1459
|
function persistContext(contextPart) {
|
|
1468
1460
|
let copy;
|
|
@@ -1491,7 +1483,7 @@ function persistContext(contextPart) {
|
|
|
1491
1483
|
return copy ?? contextPart;
|
|
1492
1484
|
}
|
|
1493
1485
|
|
|
1494
|
-
function resolveRaise(_, state, args, {
|
|
1486
|
+
function resolveRaise(_, state, args, actionParams, {
|
|
1495
1487
|
event: eventOrExpr,
|
|
1496
1488
|
id,
|
|
1497
1489
|
delay
|
|
@@ -1502,13 +1494,13 @@ function resolveRaise(_, state, args, {
|
|
|
1502
1494
|
if (typeof eventOrExpr === 'string') {
|
|
1503
1495
|
throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
1504
1496
|
}
|
|
1505
|
-
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
|
|
1497
|
+
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
1506
1498
|
let resolvedDelay;
|
|
1507
1499
|
if (typeof delay === 'string') {
|
|
1508
1500
|
const configDelay = delaysMap && delaysMap[delay];
|
|
1509
|
-
resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
|
|
1501
|
+
resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
|
|
1510
1502
|
} else {
|
|
1511
|
-
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1503
|
+
resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
|
|
1512
1504
|
}
|
|
1513
1505
|
if (typeof resolvedDelay !== 'number') {
|
|
1514
1506
|
internalQueue.push(resolvedEvent);
|
|
@@ -1519,9 +1511,9 @@ function resolveRaise(_, state, args, {
|
|
|
1519
1511
|
delay: resolvedDelay
|
|
1520
1512
|
}];
|
|
1521
1513
|
}
|
|
1522
|
-
function executeRaise(
|
|
1514
|
+
function executeRaise(actorScope, params) {
|
|
1523
1515
|
if (typeof params.delay === 'number') {
|
|
1524
|
-
|
|
1516
|
+
actorScope.self.delaySend(params);
|
|
1525
1517
|
return;
|
|
1526
1518
|
}
|
|
1527
1519
|
}
|
|
@@ -1532,7 +1524,7 @@ function executeRaise(actorContext, params) {
|
|
|
1532
1524
|
* @param eventType The event to raise.
|
|
1533
1525
|
*/
|
|
1534
1526
|
function raise(eventOrExpr, options) {
|
|
1535
|
-
function raise(
|
|
1527
|
+
function raise(args, params) {
|
|
1536
1528
|
{
|
|
1537
1529
|
throw new Error(`This isn't supposed to be called`);
|
|
1538
1530
|
}
|
|
@@ -1572,6 +1564,7 @@ exports.or = or;
|
|
|
1572
1564
|
exports.raise = raise;
|
|
1573
1565
|
exports.resolveActionsAndContext = resolveActionsAndContext;
|
|
1574
1566
|
exports.resolveStateValue = resolveStateValue;
|
|
1567
|
+
exports.spawn = spawn;
|
|
1575
1568
|
exports.stateIn = stateIn;
|
|
1576
1569
|
exports.stop = stop;
|
|
1577
1570
|
exports.transitionNode = transitionNode;
|