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-5dfcd203.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
|
cancel.type = 'xstate.cancel';
|
|
39
39
|
cancel.sendId = sendId;
|
|
@@ -42,7 +42,7 @@ function cancel(sendId) {
|
|
|
42
42
|
return cancel;
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
function
|
|
45
|
+
function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
46
46
|
id,
|
|
47
47
|
systemId,
|
|
48
48
|
src,
|
|
@@ -53,93 +53,88 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
53
53
|
src,
|
|
54
54
|
input: undefined
|
|
55
55
|
};
|
|
56
|
+
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
56
57
|
let actorRef;
|
|
57
58
|
if (referenced) {
|
|
58
59
|
// TODO: inline `input: undefined` should win over the referenced one
|
|
59
60
|
const configuredInput = input || referenced.input;
|
|
60
61
|
actorRef = interpreter.createActor(referenced.src, {
|
|
61
|
-
id,
|
|
62
|
+
id: resolvedId,
|
|
62
63
|
src: typeof src === 'string' ? src : undefined,
|
|
63
|
-
parent:
|
|
64
|
+
parent: actorScope?.self,
|
|
64
65
|
systemId,
|
|
65
66
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
66
67
|
context: state.context,
|
|
67
68
|
event: actionArgs.event,
|
|
68
|
-
self:
|
|
69
|
+
self: actorScope?.self
|
|
69
70
|
}) : configuredInput
|
|
70
71
|
});
|
|
71
72
|
if (syncSnapshot) {
|
|
72
73
|
actorRef.subscribe({
|
|
73
74
|
next: snapshot => {
|
|
74
75
|
if (snapshot.status === 'active') {
|
|
75
|
-
|
|
76
|
+
actorScope.self.send({
|
|
76
77
|
type: `xstate.snapshot.${id}`,
|
|
77
78
|
snapshot
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
},
|
|
81
|
-
error: () => {
|
|
82
|
-
/* TODO */
|
|
83
|
-
}
|
|
82
|
+
error: () => {}
|
|
84
83
|
});
|
|
85
84
|
}
|
|
86
85
|
}
|
|
87
86
|
return [cloneState(state, {
|
|
88
87
|
children: {
|
|
89
88
|
...state.children,
|
|
90
|
-
[
|
|
89
|
+
[resolvedId]: actorRef
|
|
91
90
|
}
|
|
92
91
|
}), {
|
|
93
92
|
id,
|
|
94
93
|
actorRef
|
|
95
94
|
}];
|
|
96
95
|
}
|
|
97
|
-
function
|
|
96
|
+
function executeSpawn(actorScope, {
|
|
98
97
|
id,
|
|
99
98
|
actorRef
|
|
100
99
|
}) {
|
|
101
100
|
if (!actorRef) {
|
|
102
101
|
return;
|
|
103
102
|
}
|
|
104
|
-
|
|
103
|
+
actorScope.defer(() => {
|
|
105
104
|
if (actorRef.status === interpreter.ActorStatus.Stopped) {
|
|
106
105
|
return;
|
|
107
106
|
}
|
|
108
107
|
try {
|
|
109
108
|
actorRef.start?.();
|
|
110
109
|
} catch (err) {
|
|
111
|
-
|
|
110
|
+
actorScope.self.send(interpreter.createErrorActorEvent(id, err));
|
|
112
111
|
return;
|
|
113
112
|
}
|
|
114
113
|
});
|
|
115
114
|
}
|
|
116
|
-
|
|
117
|
-
// we don't export this since it's an internal action that is not meant to be used in the user's code
|
|
118
|
-
|
|
119
|
-
function invoke({
|
|
115
|
+
function spawn(...[src, {
|
|
120
116
|
id,
|
|
121
117
|
systemId,
|
|
122
|
-
src,
|
|
123
118
|
input,
|
|
124
|
-
|
|
125
|
-
}) {
|
|
126
|
-
function
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
return
|
|
119
|
+
syncSnapshot = false
|
|
120
|
+
} = {}]) {
|
|
121
|
+
function spawn(args, params) {
|
|
122
|
+
}
|
|
123
|
+
spawn.type = 'xstate.spawn';
|
|
124
|
+
spawn.id = id;
|
|
125
|
+
spawn.systemId = systemId;
|
|
126
|
+
spawn.src = src;
|
|
127
|
+
spawn.input = input;
|
|
128
|
+
spawn.syncSnapshot = syncSnapshot;
|
|
129
|
+
spawn.resolve = resolveSpawn;
|
|
130
|
+
spawn.execute = executeSpawn;
|
|
131
|
+
return spawn;
|
|
137
132
|
}
|
|
138
133
|
|
|
139
|
-
function resolveStop(_, state, args, {
|
|
134
|
+
function resolveStop(_, state, args, actionParams, {
|
|
140
135
|
actorRef
|
|
141
136
|
}) {
|
|
142
|
-
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
|
|
137
|
+
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
|
|
143
138
|
const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
|
|
144
139
|
let children = state.children;
|
|
145
140
|
if (resolvedActorRef) {
|
|
@@ -152,22 +147,28 @@ function resolveStop(_, state, args, {
|
|
|
152
147
|
children
|
|
153
148
|
}), resolvedActorRef];
|
|
154
149
|
}
|
|
155
|
-
function executeStop(
|
|
150
|
+
function executeStop(actorScope, actorRef) {
|
|
156
151
|
if (!actorRef) {
|
|
157
152
|
return;
|
|
158
153
|
}
|
|
154
|
+
|
|
155
|
+
// we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
|
|
156
|
+
// since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
|
|
157
|
+
// this could throw on `systemId` collision, for example, when dealing with reentering transitions
|
|
158
|
+
actorScope.system._unregister(actorRef);
|
|
159
|
+
|
|
159
160
|
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
160
161
|
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
161
162
|
if (actorRef.status !== interpreter.ActorStatus.Running) {
|
|
162
|
-
|
|
163
|
+
actorScope.stopChild(actorRef);
|
|
163
164
|
return;
|
|
164
165
|
}
|
|
165
166
|
// stopping a child enqueues a stop event in the child actor's mailbox
|
|
166
167
|
// we need for all of the already enqueued events to be processed before we stop the child
|
|
167
168
|
// the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
|
|
168
169
|
// and we don't want to ignore those events
|
|
169
|
-
|
|
170
|
-
|
|
170
|
+
actorScope.defer(() => {
|
|
171
|
+
actorScope.stopChild(actorRef);
|
|
171
172
|
});
|
|
172
173
|
}
|
|
173
174
|
/**
|
|
@@ -176,7 +177,7 @@ function executeStop(actorContext, actorRef) {
|
|
|
176
177
|
* @param actorRef The actor to stop.
|
|
177
178
|
*/
|
|
178
179
|
function stop(actorRef) {
|
|
179
|
-
function stop(
|
|
180
|
+
function stop(args, params) {
|
|
180
181
|
}
|
|
181
182
|
stop.type = 'xstate.stop';
|
|
182
183
|
stop.actorRef = actorRef;
|
|
@@ -195,7 +196,7 @@ function checkStateIn(state, _, {
|
|
|
195
196
|
return state.matches(stateValue);
|
|
196
197
|
}
|
|
197
198
|
function stateIn(stateValue) {
|
|
198
|
-
function stateIn(
|
|
199
|
+
function stateIn(args, params) {
|
|
199
200
|
return false;
|
|
200
201
|
}
|
|
201
202
|
stateIn.check = checkStateIn;
|
|
@@ -211,7 +212,7 @@ function checkNot(state, {
|
|
|
211
212
|
return !evaluateGuard(guards[0], context, event, state);
|
|
212
213
|
}
|
|
213
214
|
function not(guard) {
|
|
214
|
-
function not(
|
|
215
|
+
function not(args, params) {
|
|
215
216
|
return false;
|
|
216
217
|
}
|
|
217
218
|
not.check = checkNot;
|
|
@@ -227,7 +228,7 @@ function checkAnd(state, {
|
|
|
227
228
|
return guards.every(guard => evaluateGuard(guard, context, event, state));
|
|
228
229
|
}
|
|
229
230
|
function and(guards) {
|
|
230
|
-
function and(
|
|
231
|
+
function and(args, params) {
|
|
231
232
|
return false;
|
|
232
233
|
}
|
|
233
234
|
and.check = checkAnd;
|
|
@@ -243,7 +244,7 @@ function checkOr(state, {
|
|
|
243
244
|
return guards.some(guard => evaluateGuard(guard, context, event, state));
|
|
244
245
|
}
|
|
245
246
|
function or(guards) {
|
|
246
|
-
function or(
|
|
247
|
+
function or(args, params) {
|
|
247
248
|
return false;
|
|
248
249
|
}
|
|
249
250
|
or.check = checkOr;
|
|
@@ -266,22 +267,17 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
266
267
|
}
|
|
267
268
|
const guardArgs = {
|
|
268
269
|
context,
|
|
269
|
-
event
|
|
270
|
-
guard: isInline ? undefined : typeof guard === 'string' ? {
|
|
271
|
-
type: guard
|
|
272
|
-
} : typeof guard.params === 'function' ? {
|
|
273
|
-
type: guard.type,
|
|
274
|
-
params: guard.params({
|
|
275
|
-
context,
|
|
276
|
-
event
|
|
277
|
-
})
|
|
278
|
-
} : guard
|
|
270
|
+
event
|
|
279
271
|
};
|
|
272
|
+
const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
|
|
273
|
+
context,
|
|
274
|
+
event
|
|
275
|
+
}) : guard.params : undefined;
|
|
280
276
|
if (!('check' in resolved)) {
|
|
281
277
|
// the existing type of `.guards` assumes non-nullable `TExpressionGuard`
|
|
282
278
|
// inline guards expect `TExpressionGuard` to be set to `undefined`
|
|
283
279
|
// it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
|
|
284
|
-
return resolved(guardArgs);
|
|
280
|
+
return resolved(guardArgs, guardParams);
|
|
285
281
|
}
|
|
286
282
|
const builtinGuard = resolved;
|
|
287
283
|
return builtinGuard.check(state, guardArgs, resolved // this holds all params
|
|
@@ -735,15 +731,6 @@ function isDescendant(childStateNode, parentStateNode) {
|
|
|
735
731
|
}
|
|
736
732
|
return marker.parent === parentStateNode;
|
|
737
733
|
}
|
|
738
|
-
function getPathFromRootToNode(stateNode) {
|
|
739
|
-
const path = [];
|
|
740
|
-
let marker = stateNode.parent;
|
|
741
|
-
while (marker) {
|
|
742
|
-
path.unshift(marker);
|
|
743
|
-
marker = marker.parent;
|
|
744
|
-
}
|
|
745
|
-
return path;
|
|
746
|
-
}
|
|
747
734
|
function hasIntersection(s1, s2) {
|
|
748
735
|
const set1 = new Set(s1);
|
|
749
736
|
const set2 = new Set(s2);
|
|
@@ -783,17 +770,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
|
|
|
783
770
|
}
|
|
784
771
|
return Array.from(filteredTransitions);
|
|
785
772
|
}
|
|
786
|
-
function
|
|
787
|
-
const [head] = stateNodes;
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
candidates = current.filter(sn => path.includes(sn));
|
|
793
|
-
current = candidates;
|
|
794
|
-
candidates = [];
|
|
773
|
+
function findLeastCommonAncestor(stateNodes) {
|
|
774
|
+
const [head, ...tail] = stateNodes;
|
|
775
|
+
for (const ancestor of getProperAncestors(head, undefined)) {
|
|
776
|
+
if (tail.every(sn => isDescendant(sn, ancestor))) {
|
|
777
|
+
return ancestor;
|
|
778
|
+
}
|
|
795
779
|
}
|
|
796
|
-
return current[current.length - 1];
|
|
797
780
|
}
|
|
798
781
|
function getEffectiveTargetStates(transition, historyValue) {
|
|
799
782
|
if (!transition.target) {
|
|
@@ -825,8 +808,16 @@ function getTransitionDomain(transition, historyValue) {
|
|
|
825
808
|
if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
|
|
826
809
|
return transition.source;
|
|
827
810
|
}
|
|
828
|
-
const
|
|
829
|
-
|
|
811
|
+
const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
|
|
812
|
+
if (lca) {
|
|
813
|
+
return lca;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
// at this point we know that it's a root transition since LCA couldn't be found
|
|
817
|
+
if (transition.reenter) {
|
|
818
|
+
return;
|
|
819
|
+
}
|
|
820
|
+
return transition.source.machine.root;
|
|
830
821
|
}
|
|
831
822
|
function computeExitSet(transitions, configuration, historyValue) {
|
|
832
823
|
const statesToExit = new Set();
|
|
@@ -859,13 +850,8 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
|
859
850
|
|
|
860
851
|
/**
|
|
861
852
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
862
|
-
*
|
|
863
|
-
* @private
|
|
864
|
-
* @param transitions
|
|
865
|
-
* @param currentState
|
|
866
|
-
* @param mutConfiguration
|
|
867
853
|
*/
|
|
868
|
-
function microstep(transitions, currentState,
|
|
854
|
+
function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
|
|
869
855
|
if (!transitions.length) {
|
|
870
856
|
return currentState;
|
|
871
857
|
}
|
|
@@ -876,17 +862,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
876
862
|
|
|
877
863
|
// Exit states
|
|
878
864
|
if (!isInitial) {
|
|
879
|
-
[nextState, historyValue] = exitStates(nextState, event,
|
|
865
|
+
[nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
|
|
880
866
|
}
|
|
881
867
|
|
|
882
868
|
// Execute transition content
|
|
883
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
869
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
|
|
884
870
|
|
|
885
871
|
// Enter states
|
|
886
|
-
nextState = enterStates(nextState, event,
|
|
872
|
+
nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
|
|
887
873
|
const nextConfiguration = [...mutConfiguration];
|
|
888
874
|
if (nextState.status === 'done') {
|
|
889
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
875
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
|
|
890
876
|
}
|
|
891
877
|
try {
|
|
892
878
|
if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
|
|
@@ -902,14 +888,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
|
|
|
902
888
|
throw e;
|
|
903
889
|
}
|
|
904
890
|
}
|
|
905
|
-
function getMachineOutput(state, event,
|
|
891
|
+
function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
|
|
906
892
|
if (!rootNode.output) {
|
|
907
893
|
return;
|
|
908
894
|
}
|
|
909
|
-
const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event,
|
|
910
|
-
return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent,
|
|
895
|
+
const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
|
|
896
|
+
return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
|
|
911
897
|
}
|
|
912
|
-
function enterStates(currentState, event,
|
|
898
|
+
function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
913
899
|
let nextState = currentState;
|
|
914
900
|
const statesToEnter = new Set();
|
|
915
901
|
// those are states that were directly targeted or indirectly targeted by the explicit target
|
|
@@ -930,19 +916,22 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
930
916
|
// Add entry actions
|
|
931
917
|
actions.push(...stateNodeToEnter.entry);
|
|
932
918
|
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
933
|
-
actions.push(
|
|
919
|
+
actions.push(spawn(invokeDef.src, {
|
|
920
|
+
...invokeDef,
|
|
921
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
922
|
+
}));
|
|
934
923
|
}
|
|
935
924
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
936
925
|
const initialActions = stateNodeToEnter.initial.actions;
|
|
937
926
|
actions.push(...initialActions);
|
|
938
927
|
}
|
|
939
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
928
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
940
929
|
if (stateNodeToEnter.type === 'final') {
|
|
941
930
|
const parent = stateNodeToEnter.parent;
|
|
942
931
|
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
943
932
|
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
944
933
|
if (parent?.type === 'compound') {
|
|
945
|
-
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event,
|
|
934
|
+
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
|
|
946
935
|
}
|
|
947
936
|
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
948
937
|
completedNodes.add(ancestorMarker);
|
|
@@ -955,7 +944,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
955
944
|
}
|
|
956
945
|
nextState = cloneState(nextState, {
|
|
957
946
|
status: 'done',
|
|
958
|
-
output: getMachineOutput(nextState, event,
|
|
947
|
+
output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
|
|
959
948
|
});
|
|
960
949
|
}
|
|
961
950
|
}
|
|
@@ -980,7 +969,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
|
|
|
980
969
|
}
|
|
981
970
|
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
982
971
|
for (const s of targetStates) {
|
|
983
|
-
|
|
972
|
+
const ancestors = getProperAncestors(s, domain);
|
|
973
|
+
if (domain?.type === 'parallel') {
|
|
974
|
+
ancestors.push(domain);
|
|
975
|
+
}
|
|
976
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
|
|
984
977
|
}
|
|
985
978
|
}
|
|
986
979
|
}
|
|
@@ -993,7 +986,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
993
986
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
994
987
|
}
|
|
995
988
|
for (const s of historyStateNodes) {
|
|
996
|
-
|
|
989
|
+
addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
997
990
|
}
|
|
998
991
|
} else {
|
|
999
992
|
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
@@ -1005,7 +998,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1005
998
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1006
999
|
}
|
|
1007
1000
|
for (const s of historyDefaultTransition.target) {
|
|
1008
|
-
|
|
1001
|
+
addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1009
1002
|
}
|
|
1010
1003
|
}
|
|
1011
1004
|
} else {
|
|
@@ -1016,7 +1009,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1016
1009
|
statesForDefaultEntry.add(initialState);
|
|
1017
1010
|
}
|
|
1018
1011
|
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1019
|
-
|
|
1012
|
+
addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1020
1013
|
} else {
|
|
1021
1014
|
if (stateNode.type === 'parallel') {
|
|
1022
1015
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
@@ -1032,10 +1025,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
1032
1025
|
}
|
|
1033
1026
|
}
|
|
1034
1027
|
}
|
|
1035
|
-
function addAncestorStatesToEnter(
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1038
|
-
|
|
1028
|
+
function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
|
|
1029
|
+
for (const anc of ancestors) {
|
|
1030
|
+
if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
|
|
1031
|
+
statesToEnter.add(anc);
|
|
1032
|
+
}
|
|
1039
1033
|
if (anc.type === 'parallel') {
|
|
1040
1034
|
for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
|
|
1041
1035
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
@@ -1046,7 +1040,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1046
1040
|
}
|
|
1047
1041
|
}
|
|
1048
1042
|
}
|
|
1049
|
-
function
|
|
1043
|
+
function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
|
|
1044
|
+
addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
|
|
1045
|
+
}
|
|
1046
|
+
function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
|
|
1050
1047
|
let nextState = currentState;
|
|
1051
1048
|
const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
|
|
1052
1049
|
statesToExit.sort((a, b) => b.order - a.order);
|
|
@@ -1070,12 +1067,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
|
|
|
1070
1067
|
}
|
|
1071
1068
|
}
|
|
1072
1069
|
for (const s of statesToExit) {
|
|
1073
|
-
nextState = resolveActionsAndContext(nextState, event,
|
|
1070
|
+
nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
|
|
1074
1071
|
mutConfiguration.delete(s);
|
|
1075
1072
|
}
|
|
1076
1073
|
return [nextState, changedHistory || historyValue];
|
|
1077
1074
|
}
|
|
1078
|
-
function resolveActionsAndContextWorker(currentState, event,
|
|
1075
|
+
function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
|
|
1079
1076
|
const {
|
|
1080
1077
|
machine
|
|
1081
1078
|
} = currentState;
|
|
@@ -1093,32 +1090,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1093
1090
|
const actionArgs = {
|
|
1094
1091
|
context: intermediateState.context,
|
|
1095
1092
|
event,
|
|
1096
|
-
self:
|
|
1097
|
-
system:
|
|
1098
|
-
action: isInline ? undefined : typeof action === 'string' ? {
|
|
1099
|
-
type: action
|
|
1100
|
-
} : typeof action.params === 'function' ? {
|
|
1101
|
-
type: action.type,
|
|
1102
|
-
params: action.params({
|
|
1103
|
-
context: intermediateState.context,
|
|
1104
|
-
event
|
|
1105
|
-
})
|
|
1106
|
-
} :
|
|
1107
|
-
// TS isn't able to narrow it down here
|
|
1108
|
-
action
|
|
1093
|
+
self: actorScope?.self,
|
|
1094
|
+
system: actorScope?.system
|
|
1109
1095
|
};
|
|
1096
|
+
const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
|
|
1097
|
+
context: intermediateState.context,
|
|
1098
|
+
event
|
|
1099
|
+
}) : action.params : undefined;
|
|
1110
1100
|
if (!('resolve' in resolvedAction)) {
|
|
1111
|
-
if (
|
|
1112
|
-
resolvedAction(actionArgs);
|
|
1101
|
+
if (actorScope?.self.status === interpreter.ActorStatus.Running) {
|
|
1102
|
+
resolvedAction(actionArgs, actionParams);
|
|
1113
1103
|
} else {
|
|
1114
|
-
|
|
1115
|
-
resolvedAction(actionArgs);
|
|
1104
|
+
actorScope?.defer(() => {
|
|
1105
|
+
resolvedAction(actionArgs, actionParams);
|
|
1116
1106
|
});
|
|
1117
1107
|
}
|
|
1118
1108
|
continue;
|
|
1119
1109
|
}
|
|
1120
1110
|
const builtinAction = resolvedAction;
|
|
1121
|
-
const [nextState, params, actions] = builtinAction.resolve(
|
|
1111
|
+
const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
|
|
1122
1112
|
// this holds all params
|
|
1123
1113
|
extra);
|
|
1124
1114
|
intermediateState = nextState;
|
|
@@ -1126,36 +1116,38 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1126
1116
|
retries?.push([builtinAction, params]);
|
|
1127
1117
|
}
|
|
1128
1118
|
if ('execute' in builtinAction) {
|
|
1129
|
-
if (
|
|
1130
|
-
builtinAction.execute(
|
|
1119
|
+
if (actorScope?.self.status === interpreter.ActorStatus.Running) {
|
|
1120
|
+
builtinAction.execute(actorScope, params);
|
|
1131
1121
|
} else {
|
|
1132
|
-
|
|
1122
|
+
actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
|
|
1133
1123
|
}
|
|
1134
1124
|
}
|
|
1135
1125
|
if (actions) {
|
|
1136
|
-
intermediateState = resolveActionsAndContextWorker(intermediateState, event,
|
|
1126
|
+
intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
|
|
1137
1127
|
}
|
|
1138
1128
|
}
|
|
1139
1129
|
return intermediateState;
|
|
1140
1130
|
}
|
|
1141
|
-
function resolveActionsAndContext(currentState, event,
|
|
1131
|
+
function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
|
|
1142
1132
|
const retries = deferredActorIds ? [] : undefined;
|
|
1143
|
-
const nextState = resolveActionsAndContextWorker(currentState, event,
|
|
1133
|
+
const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
|
|
1144
1134
|
internalQueue,
|
|
1145
1135
|
deferredActorIds
|
|
1146
1136
|
}, retries);
|
|
1147
1137
|
retries?.forEach(([builtinAction, params]) => {
|
|
1148
|
-
builtinAction.retryResolve(
|
|
1138
|
+
builtinAction.retryResolve(actorScope, nextState, params);
|
|
1149
1139
|
});
|
|
1150
1140
|
return nextState;
|
|
1151
1141
|
}
|
|
1152
|
-
function macrostep(state, event,
|
|
1142
|
+
function macrostep(state, event, actorScope, internalQueue = []) {
|
|
1153
1143
|
let nextState = state;
|
|
1154
1144
|
const states = [];
|
|
1155
1145
|
|
|
1156
1146
|
// Handle stop event
|
|
1157
1147
|
if (event.type === interpreter.XSTATE_STOP) {
|
|
1158
|
-
nextState = stopChildren(nextState, event,
|
|
1148
|
+
nextState = cloneState(stopChildren(nextState, event, actorScope), {
|
|
1149
|
+
status: 'stopped'
|
|
1150
|
+
});
|
|
1159
1151
|
states.push(nextState);
|
|
1160
1152
|
return {
|
|
1161
1153
|
state: nextState,
|
|
@@ -1168,7 +1160,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1168
1160
|
// Determine the next state based on the next microstep
|
|
1169
1161
|
if (nextEvent.type !== interpreter.XSTATE_INIT) {
|
|
1170
1162
|
const transitions = selectTransitions(nextEvent, nextState);
|
|
1171
|
-
nextState = microstep(transitions, state,
|
|
1163
|
+
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
1172
1164
|
states.push(nextState);
|
|
1173
1165
|
}
|
|
1174
1166
|
let shouldSelectEventlessTransitions = true;
|
|
@@ -1185,20 +1177,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1185
1177
|
nextEvent = internalQueue.shift();
|
|
1186
1178
|
enabledTransitions = selectTransitions(nextEvent, nextState);
|
|
1187
1179
|
}
|
|
1188
|
-
nextState = microstep(enabledTransitions, nextState,
|
|
1180
|
+
nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
|
|
1189
1181
|
shouldSelectEventlessTransitions = nextState !== previousState;
|
|
1190
1182
|
states.push(nextState);
|
|
1191
1183
|
}
|
|
1192
1184
|
if (nextState.status !== 'active') {
|
|
1193
|
-
stopChildren(nextState, nextEvent,
|
|
1185
|
+
stopChildren(nextState, nextEvent, actorScope);
|
|
1194
1186
|
}
|
|
1195
1187
|
return {
|
|
1196
1188
|
state: nextState,
|
|
1197
1189
|
microstates: states
|
|
1198
1190
|
};
|
|
1199
1191
|
}
|
|
1200
|
-
function stopChildren(nextState, event,
|
|
1201
|
-
return resolveActionsAndContext(nextState, event,
|
|
1192
|
+
function stopChildren(nextState, event, actorScope) {
|
|
1193
|
+
return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
|
|
1202
1194
|
}
|
|
1203
1195
|
function selectTransitions(event, nextState) {
|
|
1204
1196
|
return nextState.machine.getTransitionData(nextState, event);
|
|
@@ -1412,17 +1404,17 @@ function getPersistedState(state) {
|
|
|
1412
1404
|
for (const id in children) {
|
|
1413
1405
|
const child = children[id];
|
|
1414
1406
|
childrenJson[id] = {
|
|
1415
|
-
state: child.getPersistedState
|
|
1416
|
-
src: child.src
|
|
1407
|
+
state: child.getPersistedState(),
|
|
1408
|
+
src: child.src,
|
|
1409
|
+
systemId: child._systemId
|
|
1417
1410
|
};
|
|
1418
1411
|
}
|
|
1419
|
-
|
|
1412
|
+
const persisted = {
|
|
1420
1413
|
...jsonValues,
|
|
1421
|
-
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1422
|
-
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1423
1414
|
context: persistContext(context),
|
|
1424
1415
|
children: childrenJson
|
|
1425
1416
|
};
|
|
1417
|
+
return persisted;
|
|
1426
1418
|
}
|
|
1427
1419
|
function persistContext(contextPart) {
|
|
1428
1420
|
let copy;
|
|
@@ -1451,7 +1443,7 @@ function persistContext(contextPart) {
|
|
|
1451
1443
|
return copy ?? contextPart;
|
|
1452
1444
|
}
|
|
1453
1445
|
|
|
1454
|
-
function resolveRaise(_, state, args, {
|
|
1446
|
+
function resolveRaise(_, state, args, actionParams, {
|
|
1455
1447
|
event: eventOrExpr,
|
|
1456
1448
|
id,
|
|
1457
1449
|
delay
|
|
@@ -1462,13 +1454,13 @@ function resolveRaise(_, state, args, {
|
|
|
1462
1454
|
if (typeof eventOrExpr === 'string') {
|
|
1463
1455
|
throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
1464
1456
|
}
|
|
1465
|
-
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
|
|
1457
|
+
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
1466
1458
|
let resolvedDelay;
|
|
1467
1459
|
if (typeof delay === 'string') {
|
|
1468
1460
|
const configDelay = delaysMap && delaysMap[delay];
|
|
1469
|
-
resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
|
|
1461
|
+
resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
|
|
1470
1462
|
} else {
|
|
1471
|
-
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1463
|
+
resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
|
|
1472
1464
|
}
|
|
1473
1465
|
if (typeof resolvedDelay !== 'number') {
|
|
1474
1466
|
internalQueue.push(resolvedEvent);
|
|
@@ -1479,9 +1471,9 @@ function resolveRaise(_, state, args, {
|
|
|
1479
1471
|
delay: resolvedDelay
|
|
1480
1472
|
}];
|
|
1481
1473
|
}
|
|
1482
|
-
function executeRaise(
|
|
1474
|
+
function executeRaise(actorScope, params) {
|
|
1483
1475
|
if (typeof params.delay === 'number') {
|
|
1484
|
-
|
|
1476
|
+
actorScope.self.delaySend(params);
|
|
1485
1477
|
return;
|
|
1486
1478
|
}
|
|
1487
1479
|
}
|
|
@@ -1492,7 +1484,7 @@ function executeRaise(actorContext, params) {
|
|
|
1492
1484
|
* @param eventType The event to raise.
|
|
1493
1485
|
*/
|
|
1494
1486
|
function raise(eventOrExpr, options) {
|
|
1495
|
-
function raise(
|
|
1487
|
+
function raise(args, params) {
|
|
1496
1488
|
}
|
|
1497
1489
|
raise.type = 'xstate.raise';
|
|
1498
1490
|
raise.event = eventOrExpr;
|
|
@@ -1529,6 +1521,7 @@ exports.or = or;
|
|
|
1529
1521
|
exports.raise = raise;
|
|
1530
1522
|
exports.resolveActionsAndContext = resolveActionsAndContext;
|
|
1531
1523
|
exports.resolveStateValue = resolveStateValue;
|
|
1524
|
+
exports.spawn = spawn;
|
|
1532
1525
|
exports.stateIn = stateIn;
|
|
1533
1526
|
exports.stop = stop;
|
|
1534
1527
|
exports.transitionNode = transitionNode;
|