xstate 5.0.0-beta.36 → 5.0.0-beta.38
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 +1 -1
- package/actors/dist/xstate-actors.development.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.esm.js +1 -1
- package/actors/dist/xstate-actors.esm.js +1 -1
- 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 +4 -4
- 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 +2 -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 +1 -1
- package/dist/declarations/src/guards.d.ts +9 -10
- package/dist/declarations/src/interpreter.d.ts +2 -2
- package/dist/declarations/src/spawn.d.ts +1 -2
- package/dist/declarations/src/stateUtils.d.ts +0 -5
- package/dist/declarations/src/typegenTypes.d.ts +2 -0
- package/dist/declarations/src/types.d.ts +47 -58
- package/dist/declarations/src/utils.d.ts +6 -6
- package/dist/declarations/src/waitFor.d.ts +1 -1
- package/dist/{interpreter-5c4e6634.development.esm.js → interpreter-4005eb36.development.esm.js} +14 -24
- package/dist/{interpreter-69605bf0.cjs.js → interpreter-b6f22ee2.cjs.js} +14 -24
- package/dist/{interpreter-de5217bc.esm.js → interpreter-c80ce92e.esm.js} +14 -24
- package/dist/{interpreter-d3567419.development.cjs.js → interpreter-ed3f81f7.development.cjs.js} +14 -24
- package/dist/{raise-5b7ad3b7.development.esm.js → raise-42073973.development.esm.js} +138 -118
- package/dist/{raise-c51b81a3.cjs.js → raise-7faa9b3b.cjs.js} +139 -118
- package/dist/{raise-106ea558.development.cjs.js → raise-b69a3d16.development.cjs.js} +138 -117
- package/dist/{raise-ffe1014a.esm.js → raise-c989c7fb.esm.js} +139 -119
- package/dist/{send-778692de.cjs.js → send-34160163.cjs.js} +31 -27
- package/dist/{send-0a7aa74e.esm.js → send-4b616da9.esm.js} +31 -27
- package/dist/{send-25e70bd4.development.cjs.js → send-58725522.development.cjs.js} +31 -27
- package/dist/{send-e93554d6.development.esm.js → send-bff8c910.development.esm.js} +31 -27
- package/dist/xstate.cjs.js +11 -16
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +11 -16
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +13 -19
- package/dist/xstate.esm.js +13 -19
- 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-ed3f81f7.development.cjs.js');
|
|
4
4
|
|
|
5
5
|
const cache = new WeakMap();
|
|
6
6
|
function memo(object, key, fn) {
|
|
@@ -16,10 +16,10 @@ 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
25
|
function executeCancel(actorContext, resolvedSendId) {
|
|
@@ -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,21 +45,25 @@ function cancel(sendId) {
|
|
|
45
45
|
return cancel;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
function
|
|
48
|
+
function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
|
|
49
49
|
id,
|
|
50
50
|
systemId,
|
|
51
51
|
src,
|
|
52
52
|
input,
|
|
53
53
|
syncSnapshot
|
|
54
54
|
}) {
|
|
55
|
-
const referenced = interpreter.resolveReferencedActor(state.machine
|
|
55
|
+
const referenced = typeof src === 'string' ? interpreter.resolveReferencedActor(state.machine, src) : {
|
|
56
|
+
src,
|
|
57
|
+
input: undefined
|
|
58
|
+
};
|
|
59
|
+
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
56
60
|
let actorRef;
|
|
57
61
|
if (referenced) {
|
|
58
62
|
// TODO: inline `input: undefined` should win over the referenced one
|
|
59
63
|
const configuredInput = input || referenced.input;
|
|
60
64
|
actorRef = interpreter.createActor(referenced.src, {
|
|
61
|
-
id,
|
|
62
|
-
src,
|
|
65
|
+
id: resolvedId,
|
|
66
|
+
src: typeof src === 'string' ? src : undefined,
|
|
63
67
|
parent: actorContext?.self,
|
|
64
68
|
systemId,
|
|
65
69
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
@@ -78,9 +82,7 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
78
82
|
});
|
|
79
83
|
}
|
|
80
84
|
},
|
|
81
|
-
error: () => {
|
|
82
|
-
/* TODO */
|
|
83
|
-
}
|
|
85
|
+
error: () => {}
|
|
84
86
|
});
|
|
85
87
|
}
|
|
86
88
|
}
|
|
@@ -90,14 +92,14 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
90
92
|
return [cloneState(state, {
|
|
91
93
|
children: {
|
|
92
94
|
...state.children,
|
|
93
|
-
[
|
|
95
|
+
[resolvedId]: actorRef
|
|
94
96
|
}
|
|
95
97
|
}), {
|
|
96
98
|
id,
|
|
97
99
|
actorRef
|
|
98
100
|
}];
|
|
99
101
|
}
|
|
100
|
-
function
|
|
102
|
+
function executeSpawn(actorContext, {
|
|
101
103
|
id,
|
|
102
104
|
actorRef
|
|
103
105
|
}) {
|
|
@@ -116,36 +118,32 @@ function executeInvoke(actorContext, {
|
|
|
116
118
|
}
|
|
117
119
|
});
|
|
118
120
|
}
|
|
119
|
-
|
|
120
|
-
// we don't export this since it's an internal action that is not meant to be used in the user's code
|
|
121
|
-
|
|
122
|
-
function invoke({
|
|
121
|
+
function spawn(...[src, {
|
|
123
122
|
id,
|
|
124
123
|
systemId,
|
|
125
|
-
src,
|
|
126
124
|
input,
|
|
127
|
-
|
|
128
|
-
}) {
|
|
129
|
-
function
|
|
125
|
+
syncSnapshot = false
|
|
126
|
+
} = {}]) {
|
|
127
|
+
function spawn(args, params) {
|
|
130
128
|
{
|
|
131
129
|
throw new Error(`This isn't supposed to be called`);
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
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;
|
|
143
141
|
}
|
|
144
142
|
|
|
145
|
-
function resolveStop(_, state, args, {
|
|
143
|
+
function resolveStop(_, state, args, actionParams, {
|
|
146
144
|
actorRef
|
|
147
145
|
}) {
|
|
148
|
-
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
|
|
146
|
+
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
|
|
149
147
|
const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
|
|
150
148
|
let children = state.children;
|
|
151
149
|
if (resolvedActorRef) {
|
|
@@ -162,11 +160,22 @@ function executeStop(actorContext, actorRef) {
|
|
|
162
160
|
if (!actorRef) {
|
|
163
161
|
return;
|
|
164
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
|
+
actorContext.system._unregister(actorRef);
|
|
168
|
+
|
|
169
|
+
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
170
|
+
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
165
171
|
if (actorRef.status !== interpreter.ActorStatus.Running) {
|
|
166
172
|
actorContext.stopChild(actorRef);
|
|
167
173
|
return;
|
|
168
174
|
}
|
|
169
|
-
//
|
|
175
|
+
// stopping a child enqueues a stop event in the child actor's mailbox
|
|
176
|
+
// we need for all of the already enqueued events to be processed before we stop the child
|
|
177
|
+
// the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
|
|
178
|
+
// and we don't want to ignore those events
|
|
170
179
|
actorContext.defer(() => {
|
|
171
180
|
actorContext.stopChild(actorRef);
|
|
172
181
|
});
|
|
@@ -177,7 +186,7 @@ function executeStop(actorContext, actorRef) {
|
|
|
177
186
|
* @param actorRef The actor to stop.
|
|
178
187
|
*/
|
|
179
188
|
function stop(actorRef) {
|
|
180
|
-
function stop(
|
|
189
|
+
function stop(args, params) {
|
|
181
190
|
{
|
|
182
191
|
throw new Error(`This isn't supposed to be called`);
|
|
183
192
|
}
|
|
@@ -193,12 +202,13 @@ function checkStateIn(state, _, {
|
|
|
193
202
|
stateValue
|
|
194
203
|
}) {
|
|
195
204
|
if (typeof stateValue === 'string' && isStateId(stateValue)) {
|
|
196
|
-
|
|
205
|
+
const target = state.machine.getStateNodeById(stateValue);
|
|
206
|
+
return state.configuration.some(sn => sn === target);
|
|
197
207
|
}
|
|
198
208
|
return state.matches(stateValue);
|
|
199
209
|
}
|
|
200
210
|
function stateIn(stateValue) {
|
|
201
|
-
function stateIn(
|
|
211
|
+
function stateIn(args, params) {
|
|
202
212
|
{
|
|
203
213
|
throw new Error(`This isn't supposed to be called`);
|
|
204
214
|
}
|
|
@@ -216,7 +226,7 @@ function checkNot(state, {
|
|
|
216
226
|
return !evaluateGuard(guards[0], context, event, state);
|
|
217
227
|
}
|
|
218
228
|
function not(guard) {
|
|
219
|
-
function not(
|
|
229
|
+
function not(args, params) {
|
|
220
230
|
{
|
|
221
231
|
throw new Error(`This isn't supposed to be called`);
|
|
222
232
|
}
|
|
@@ -234,7 +244,7 @@ function checkAnd(state, {
|
|
|
234
244
|
return guards.every(guard => evaluateGuard(guard, context, event, state));
|
|
235
245
|
}
|
|
236
246
|
function and(guards) {
|
|
237
|
-
function and(
|
|
247
|
+
function and(args, params) {
|
|
238
248
|
{
|
|
239
249
|
throw new Error(`This isn't supposed to be called`);
|
|
240
250
|
}
|
|
@@ -252,7 +262,7 @@ function checkOr(state, {
|
|
|
252
262
|
return guards.some(guard => evaluateGuard(guard, context, event, state));
|
|
253
263
|
}
|
|
254
264
|
function or(guards) {
|
|
255
|
-
function or(
|
|
265
|
+
function or(args, params) {
|
|
256
266
|
{
|
|
257
267
|
throw new Error(`This isn't supposed to be called`);
|
|
258
268
|
}
|
|
@@ -277,22 +287,17 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
277
287
|
}
|
|
278
288
|
const guardArgs = {
|
|
279
289
|
context,
|
|
280
|
-
event
|
|
281
|
-
guard: isInline ? undefined : typeof guard === 'string' ? {
|
|
282
|
-
type: guard
|
|
283
|
-
} : typeof guard.params === 'function' ? {
|
|
284
|
-
type: guard.type,
|
|
285
|
-
params: guard.params({
|
|
286
|
-
context,
|
|
287
|
-
event
|
|
288
|
-
})
|
|
289
|
-
} : guard
|
|
290
|
+
event
|
|
290
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;
|
|
291
296
|
if (!('check' in resolved)) {
|
|
292
297
|
// the existing type of `.guards` assumes non-nullable `TExpressionGuard`
|
|
293
298
|
// inline guards expect `TExpressionGuard` to be set to `undefined`
|
|
294
299
|
// it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
|
|
295
|
-
return resolved(guardArgs);
|
|
300
|
+
return resolved(guardArgs, guardParams);
|
|
296
301
|
}
|
|
297
302
|
const builtinGuard = resolved;
|
|
298
303
|
return builtinGuard.check(state, guardArgs, resolved // this holds all params
|
|
@@ -305,6 +310,9 @@ function getChildren(stateNode) {
|
|
|
305
310
|
}
|
|
306
311
|
function getProperAncestors(stateNode, toStateNode) {
|
|
307
312
|
const ancestors = [];
|
|
313
|
+
if (toStateNode === stateNode) {
|
|
314
|
+
return ancestors;
|
|
315
|
+
}
|
|
308
316
|
|
|
309
317
|
// add all ancestors
|
|
310
318
|
let m = stateNode.parent;
|
|
@@ -592,12 +600,14 @@ function resolveTarget(stateNode, targets) {
|
|
|
592
600
|
}
|
|
593
601
|
});
|
|
594
602
|
}
|
|
595
|
-
function
|
|
603
|
+
function resolveHistoryDefaultTransition(stateNode) {
|
|
596
604
|
const normalizedTarget = interpreter.normalizeTarget(stateNode.config.target);
|
|
597
605
|
if (!normalizedTarget) {
|
|
598
|
-
return stateNode.parent.initial
|
|
606
|
+
return stateNode.parent.initial;
|
|
599
607
|
}
|
|
600
|
-
return
|
|
608
|
+
return {
|
|
609
|
+
target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
|
|
610
|
+
};
|
|
601
611
|
}
|
|
602
612
|
function isHistoryNode(stateNode) {
|
|
603
613
|
return stateNode.type === 'history';
|
|
@@ -824,9 +834,7 @@ function getEffectiveTargetStates(transition, historyValue) {
|
|
|
824
834
|
targets.add(node);
|
|
825
835
|
}
|
|
826
836
|
} else {
|
|
827
|
-
for (const node of getEffectiveTargetStates({
|
|
828
|
-
target: resolveHistoryTarget(targetNode)
|
|
829
|
-
}, historyValue)) {
|
|
837
|
+
for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
|
|
830
838
|
targets.add(node);
|
|
831
839
|
}
|
|
832
840
|
}
|
|
@@ -839,9 +847,9 @@ function getEffectiveTargetStates(transition, historyValue) {
|
|
|
839
847
|
function getTransitionDomain(transition, historyValue) {
|
|
840
848
|
const targetStates = getEffectiveTargetStates(transition, historyValue);
|
|
841
849
|
if (!targetStates) {
|
|
842
|
-
return
|
|
850
|
+
return;
|
|
843
851
|
}
|
|
844
|
-
if (!transition.reenter &&
|
|
852
|
+
if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
|
|
845
853
|
return transition.source;
|
|
846
854
|
}
|
|
847
855
|
const lcca = findLCCA(targetStates.concat(transition.source));
|
|
@@ -852,6 +860,9 @@ function computeExitSet(transitions, configuration, historyValue) {
|
|
|
852
860
|
for (const t of transitions) {
|
|
853
861
|
if (t.target?.length) {
|
|
854
862
|
const domain = getTransitionDomain(t, historyValue);
|
|
863
|
+
if (t.reenter && t.source === domain) {
|
|
864
|
+
statesToExit.add(domain);
|
|
865
|
+
}
|
|
855
866
|
for (const stateNode of configuration) {
|
|
856
867
|
if (isDescendant(stateNode, domain)) {
|
|
857
868
|
statesToExit.add(stateNode);
|
|
@@ -875,11 +886,6 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
|
875
886
|
|
|
876
887
|
/**
|
|
877
888
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
878
|
-
*
|
|
879
|
-
* @private
|
|
880
|
-
* @param transitions
|
|
881
|
-
* @param currentState
|
|
882
|
-
* @param mutConfiguration
|
|
883
889
|
*/
|
|
884
890
|
function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
|
|
885
891
|
if (!transitions.length) {
|
|
@@ -928,6 +934,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
|
|
|
928
934
|
function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
929
935
|
let nextState = currentState;
|
|
930
936
|
const statesToEnter = new Set();
|
|
937
|
+
// those are states that were directly targeted or indirectly targeted by the explicit target
|
|
938
|
+
// in other words, those are states for which initial actions should be executed
|
|
939
|
+
// when we target `#deep_child` initial actions of its ancestors shouldn't be executed
|
|
931
940
|
const statesForDefaultEntry = new Set();
|
|
932
941
|
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
933
942
|
|
|
@@ -943,7 +952,10 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
943
952
|
// Add entry actions
|
|
944
953
|
actions.push(...stateNodeToEnter.entry);
|
|
945
954
|
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
946
|
-
actions.push(
|
|
955
|
+
actions.push(spawn(invokeDef.src, {
|
|
956
|
+
...invokeDef,
|
|
957
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
958
|
+
}));
|
|
947
959
|
}
|
|
948
960
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
949
961
|
const initialActions = stateNodeToEnter.initial.actions;
|
|
@@ -952,20 +964,16 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
952
964
|
nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
953
965
|
if (stateNodeToEnter.type === 'final') {
|
|
954
966
|
const parent = stateNodeToEnter.parent;
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
completedNodes.add(parent);
|
|
959
|
-
let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
|
|
960
|
-
let ancestorMarker = parent?.parent;
|
|
961
|
-
if (ancestorMarker) {
|
|
967
|
+
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
968
|
+
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
969
|
+
if (parent?.type === 'compound') {
|
|
962
970
|
internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
971
|
+
}
|
|
972
|
+
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
973
|
+
completedNodes.add(ancestorMarker);
|
|
974
|
+
internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
|
|
975
|
+
rootCompletionNode = ancestorMarker;
|
|
976
|
+
ancestorMarker = ancestorMarker.parent;
|
|
969
977
|
}
|
|
970
978
|
if (ancestorMarker) {
|
|
971
979
|
continue;
|
|
@@ -980,13 +988,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
980
988
|
}
|
|
981
989
|
function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
|
|
982
990
|
for (const t of transitions) {
|
|
991
|
+
const domain = getTransitionDomain(t, historyValue);
|
|
983
992
|
for (const s of t.target || []) {
|
|
993
|
+
if (!isHistoryNode(s) && (
|
|
994
|
+
// if the target is different than the source then it will *definitely* be entered
|
|
995
|
+
t.source !== s ||
|
|
996
|
+
// we know that the domain can't lie within the source
|
|
997
|
+
// if it's different than the source then it's outside of it and it means that the target has to be entered as well
|
|
998
|
+
t.source !== domain ||
|
|
999
|
+
// reentering transitions always enter the target, even if it's the source itself
|
|
1000
|
+
t.reenter)) {
|
|
1001
|
+
statesToEnter.add(s);
|
|
1002
|
+
statesForDefaultEntry.add(s);
|
|
1003
|
+
}
|
|
984
1004
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
985
1005
|
}
|
|
986
|
-
const ancestor = getTransitionDomain(t, historyValue);
|
|
987
1006
|
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
988
1007
|
for (const s of targetStates) {
|
|
989
|
-
addAncestorStatesToEnter(s,
|
|
1008
|
+
addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
|
|
990
1009
|
}
|
|
991
1010
|
}
|
|
992
1011
|
}
|
|
@@ -995,37 +1014,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
995
1014
|
if (historyValue[stateNode.id]) {
|
|
996
1015
|
const historyStateNodes = historyValue[stateNode.id];
|
|
997
1016
|
for (const s of historyStateNodes) {
|
|
1017
|
+
statesToEnter.add(s);
|
|
998
1018
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
999
1019
|
}
|
|
1000
1020
|
for (const s of historyStateNodes) {
|
|
1001
1021
|
addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1002
|
-
for (const stateForDefaultEntry of statesForDefaultEntry) {
|
|
1003
|
-
statesForDefaultEntry.add(stateForDefaultEntry);
|
|
1004
|
-
}
|
|
1005
1022
|
}
|
|
1006
1023
|
} else {
|
|
1007
|
-
const
|
|
1008
|
-
for (const s of
|
|
1024
|
+
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
1025
|
+
for (const s of historyDefaultTransition.target) {
|
|
1026
|
+
statesToEnter.add(s);
|
|
1027
|
+
if (historyDefaultTransition === stateNode.parent?.initial) {
|
|
1028
|
+
statesForDefaultEntry.add(stateNode.parent);
|
|
1029
|
+
}
|
|
1009
1030
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1010
1031
|
}
|
|
1011
|
-
for (const s of
|
|
1032
|
+
for (const s of historyDefaultTransition.target) {
|
|
1012
1033
|
addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1013
|
-
for (const stateForDefaultEntry of statesForDefaultEntry) {
|
|
1014
|
-
statesForDefaultEntry.add(stateForDefaultEntry);
|
|
1015
|
-
}
|
|
1016
1034
|
}
|
|
1017
1035
|
}
|
|
1018
1036
|
} else {
|
|
1019
|
-
statesToEnter.add(stateNode);
|
|
1020
1037
|
if (stateNode.type === 'compound') {
|
|
1021
|
-
statesForDefaultEntry.add(stateNode);
|
|
1022
1038
|
const [initialState] = stateNode.initial.target;
|
|
1039
|
+
if (!isHistoryNode(initialState)) {
|
|
1040
|
+
statesToEnter.add(initialState);
|
|
1041
|
+
statesForDefaultEntry.add(initialState);
|
|
1042
|
+
}
|
|
1023
1043
|
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1024
1044
|
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1025
1045
|
} else {
|
|
1026
1046
|
if (stateNode.type === 'parallel') {
|
|
1027
1047
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
1028
1048
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
1049
|
+
if (!isHistoryNode(child)) {
|
|
1050
|
+
statesToEnter.add(child);
|
|
1051
|
+
statesForDefaultEntry.add(child);
|
|
1052
|
+
}
|
|
1029
1053
|
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1030
1054
|
}
|
|
1031
1055
|
}
|
|
@@ -1040,6 +1064,7 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1040
1064
|
if (anc.type === 'parallel') {
|
|
1041
1065
|
for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
|
|
1042
1066
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
1067
|
+
statesToEnter.add(child);
|
|
1043
1068
|
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1044
1069
|
}
|
|
1045
1070
|
}
|
|
@@ -1094,31 +1119,24 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1094
1119
|
context: intermediateState.context,
|
|
1095
1120
|
event,
|
|
1096
1121
|
self: actorCtx?.self,
|
|
1097
|
-
system: actorCtx?.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
|
|
1122
|
+
system: actorCtx?.system
|
|
1109
1123
|
};
|
|
1124
|
+
const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
|
|
1125
|
+
context: intermediateState.context,
|
|
1126
|
+
event
|
|
1127
|
+
}) : action.params : undefined;
|
|
1110
1128
|
if (!('resolve' in resolvedAction)) {
|
|
1111
1129
|
if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
|
|
1112
|
-
resolvedAction(actionArgs);
|
|
1130
|
+
resolvedAction(actionArgs, actionParams);
|
|
1113
1131
|
} else {
|
|
1114
1132
|
actorCtx?.defer(() => {
|
|
1115
|
-
resolvedAction(actionArgs);
|
|
1133
|
+
resolvedAction(actionArgs, actionParams);
|
|
1116
1134
|
});
|
|
1117
1135
|
}
|
|
1118
1136
|
continue;
|
|
1119
1137
|
}
|
|
1120
1138
|
const builtinAction = resolvedAction;
|
|
1121
|
-
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
|
|
1139
|
+
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, actionParams, resolvedAction,
|
|
1122
1140
|
// this holds all params
|
|
1123
1141
|
extra);
|
|
1124
1142
|
intermediateState = nextState;
|
|
@@ -1158,7 +1176,9 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1158
1176
|
|
|
1159
1177
|
// Handle stop event
|
|
1160
1178
|
if (event.type === interpreter.XSTATE_STOP) {
|
|
1161
|
-
nextState = stopChildren(nextState, event, actorCtx)
|
|
1179
|
+
nextState = cloneState(stopChildren(nextState, event, actorCtx), {
|
|
1180
|
+
status: 'stopped'
|
|
1181
|
+
});
|
|
1162
1182
|
states.push(nextState);
|
|
1163
1183
|
return {
|
|
1164
1184
|
state: nextState,
|
|
@@ -1210,7 +1230,7 @@ function selectEventlessTransitions(nextState, event) {
|
|
|
1210
1230
|
const enabledTransitionSet = new Set();
|
|
1211
1231
|
const atomicStates = nextState.configuration.filter(isAtomicStateNode);
|
|
1212
1232
|
for (const stateNode of atomicStates) {
|
|
1213
|
-
loop: for (const s of [stateNode].concat(getProperAncestors(stateNode,
|
|
1233
|
+
loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
|
|
1214
1234
|
if (!s.always) {
|
|
1215
1235
|
continue;
|
|
1216
1236
|
}
|
|
@@ -1421,17 +1441,17 @@ function getPersistedState(state) {
|
|
|
1421
1441
|
throw new Error('An inline child actor cannot be persisted.');
|
|
1422
1442
|
}
|
|
1423
1443
|
childrenJson[id] = {
|
|
1424
|
-
state: child.getPersistedState
|
|
1425
|
-
src: child.src
|
|
1444
|
+
state: child.getPersistedState(),
|
|
1445
|
+
src: child.src,
|
|
1446
|
+
systemId: child._systemId
|
|
1426
1447
|
};
|
|
1427
1448
|
}
|
|
1428
|
-
|
|
1449
|
+
const persisted = {
|
|
1429
1450
|
...jsonValues,
|
|
1430
|
-
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1431
|
-
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1432
1451
|
context: persistContext(context),
|
|
1433
1452
|
children: childrenJson
|
|
1434
1453
|
};
|
|
1454
|
+
return persisted;
|
|
1435
1455
|
}
|
|
1436
1456
|
function persistContext(contextPart) {
|
|
1437
1457
|
let copy;
|
|
@@ -1460,7 +1480,7 @@ function persistContext(contextPart) {
|
|
|
1460
1480
|
return copy ?? contextPart;
|
|
1461
1481
|
}
|
|
1462
1482
|
|
|
1463
|
-
function resolveRaise(_, state, args, {
|
|
1483
|
+
function resolveRaise(_, state, args, actionParams, {
|
|
1464
1484
|
event: eventOrExpr,
|
|
1465
1485
|
id,
|
|
1466
1486
|
delay
|
|
@@ -1471,13 +1491,13 @@ function resolveRaise(_, state, args, {
|
|
|
1471
1491
|
if (typeof eventOrExpr === 'string') {
|
|
1472
1492
|
throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
1473
1493
|
}
|
|
1474
|
-
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
|
|
1494
|
+
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
1475
1495
|
let resolvedDelay;
|
|
1476
1496
|
if (typeof delay === 'string') {
|
|
1477
1497
|
const configDelay = delaysMap && delaysMap[delay];
|
|
1478
|
-
resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
|
|
1498
|
+
resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
|
|
1479
1499
|
} else {
|
|
1480
|
-
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1500
|
+
resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
|
|
1481
1501
|
}
|
|
1482
1502
|
if (typeof resolvedDelay !== 'number') {
|
|
1483
1503
|
internalQueue.push(resolvedEvent);
|
|
@@ -1501,7 +1521,7 @@ function executeRaise(actorContext, params) {
|
|
|
1501
1521
|
* @param eventType The event to raise.
|
|
1502
1522
|
*/
|
|
1503
1523
|
function raise(eventOrExpr, options) {
|
|
1504
|
-
function raise(
|
|
1524
|
+
function raise(args, params) {
|
|
1505
1525
|
{
|
|
1506
1526
|
throw new Error(`This isn't supposed to be called`);
|
|
1507
1527
|
}
|
|
@@ -1541,6 +1561,7 @@ exports.or = or;
|
|
|
1541
1561
|
exports.raise = raise;
|
|
1542
1562
|
exports.resolveActionsAndContext = resolveActionsAndContext;
|
|
1543
1563
|
exports.resolveStateValue = resolveStateValue;
|
|
1564
|
+
exports.spawn = spawn;
|
|
1544
1565
|
exports.stateIn = stateIn;
|
|
1545
1566
|
exports.stop = stop;
|
|
1546
1567
|
exports.transitionNode = transitionNode;
|