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,4 +1,4 @@
|
|
|
1
|
-
import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-
|
|
1
|
+
import { r as resolveReferencedActor, d as createActor, f as ActorStatus, j as createErrorActorEvent, k as toStateValue, l as STATE_IDENTIFIER, n as normalizeTarget, t as toArray, N as NULL_EVENT, a as toTransitionConfigArray, S as STATE_DELIMITER, o as toStatePath, q as createDoneStateEvent, s as resolveOutput, W as WILDCARD, X as XSTATE_STOP, u as XSTATE_INIT, v as createAfterEvent, w as flatten, e as matchesState, $ as $$ACTOR_TYPE } from './interpreter-4005eb36.development.esm.js';
|
|
2
2
|
|
|
3
3
|
const cache = new WeakMap();
|
|
4
4
|
function memo(object, key, fn) {
|
|
@@ -14,10 +14,10 @@ function memo(object, key, fn) {
|
|
|
14
14
|
return memoizedData[key];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
function resolveCancel(_, state, actionArgs, {
|
|
17
|
+
function resolveCancel(_, state, actionArgs, actionParams, {
|
|
18
18
|
sendId
|
|
19
19
|
}) {
|
|
20
|
-
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs) : sendId;
|
|
20
|
+
const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
|
|
21
21
|
return [state, resolvedSendId];
|
|
22
22
|
}
|
|
23
23
|
function executeCancel(actorContext, resolvedSendId) {
|
|
@@ -31,7 +31,7 @@ function executeCancel(actorContext, resolvedSendId) {
|
|
|
31
31
|
* @param sendId The `id` of the `send(...)` action to cancel.
|
|
32
32
|
*/
|
|
33
33
|
function cancel(sendId) {
|
|
34
|
-
function cancel(
|
|
34
|
+
function cancel(args, params) {
|
|
35
35
|
{
|
|
36
36
|
throw new Error(`This isn't supposed to be called`);
|
|
37
37
|
}
|
|
@@ -43,21 +43,25 @@ function cancel(sendId) {
|
|
|
43
43
|
return cancel;
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
function
|
|
46
|
+
function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
|
|
47
47
|
id,
|
|
48
48
|
systemId,
|
|
49
49
|
src,
|
|
50
50
|
input,
|
|
51
51
|
syncSnapshot
|
|
52
52
|
}) {
|
|
53
|
-
const referenced = resolveReferencedActor(state.machine
|
|
53
|
+
const referenced = typeof src === 'string' ? resolveReferencedActor(state.machine, src) : {
|
|
54
|
+
src,
|
|
55
|
+
input: undefined
|
|
56
|
+
};
|
|
57
|
+
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
54
58
|
let actorRef;
|
|
55
59
|
if (referenced) {
|
|
56
60
|
// TODO: inline `input: undefined` should win over the referenced one
|
|
57
61
|
const configuredInput = input || referenced.input;
|
|
58
62
|
actorRef = createActor(referenced.src, {
|
|
59
|
-
id,
|
|
60
|
-
src,
|
|
63
|
+
id: resolvedId,
|
|
64
|
+
src: typeof src === 'string' ? src : undefined,
|
|
61
65
|
parent: actorContext?.self,
|
|
62
66
|
systemId,
|
|
63
67
|
input: typeof configuredInput === 'function' ? configuredInput({
|
|
@@ -76,9 +80,7 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
76
80
|
});
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
|
-
error: () => {
|
|
80
|
-
/* TODO */
|
|
81
|
-
}
|
|
83
|
+
error: () => {}
|
|
82
84
|
});
|
|
83
85
|
}
|
|
84
86
|
}
|
|
@@ -88,14 +90,14 @@ function resolveInvoke(actorContext, state, actionArgs, {
|
|
|
88
90
|
return [cloneState(state, {
|
|
89
91
|
children: {
|
|
90
92
|
...state.children,
|
|
91
|
-
[
|
|
93
|
+
[resolvedId]: actorRef
|
|
92
94
|
}
|
|
93
95
|
}), {
|
|
94
96
|
id,
|
|
95
97
|
actorRef
|
|
96
98
|
}];
|
|
97
99
|
}
|
|
98
|
-
function
|
|
100
|
+
function executeSpawn(actorContext, {
|
|
99
101
|
id,
|
|
100
102
|
actorRef
|
|
101
103
|
}) {
|
|
@@ -114,36 +116,32 @@ function executeInvoke(actorContext, {
|
|
|
114
116
|
}
|
|
115
117
|
});
|
|
116
118
|
}
|
|
117
|
-
|
|
118
|
-
// we don't export this since it's an internal action that is not meant to be used in the user's code
|
|
119
|
-
|
|
120
|
-
function invoke({
|
|
119
|
+
function spawn(...[src, {
|
|
121
120
|
id,
|
|
122
121
|
systemId,
|
|
123
|
-
src,
|
|
124
122
|
input,
|
|
125
|
-
|
|
126
|
-
}) {
|
|
127
|
-
function
|
|
123
|
+
syncSnapshot = false
|
|
124
|
+
} = {}]) {
|
|
125
|
+
function spawn(args, params) {
|
|
128
126
|
{
|
|
129
127
|
throw new Error(`This isn't supposed to be called`);
|
|
130
128
|
}
|
|
131
129
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return
|
|
130
|
+
spawn.type = 'xstate.spawn';
|
|
131
|
+
spawn.id = id;
|
|
132
|
+
spawn.systemId = systemId;
|
|
133
|
+
spawn.src = src;
|
|
134
|
+
spawn.input = input;
|
|
135
|
+
spawn.syncSnapshot = syncSnapshot;
|
|
136
|
+
spawn.resolve = resolveSpawn;
|
|
137
|
+
spawn.execute = executeSpawn;
|
|
138
|
+
return spawn;
|
|
141
139
|
}
|
|
142
140
|
|
|
143
|
-
function resolveStop(_, state, args, {
|
|
141
|
+
function resolveStop(_, state, args, actionParams, {
|
|
144
142
|
actorRef
|
|
145
143
|
}) {
|
|
146
|
-
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
|
|
144
|
+
const actorRefOrString = typeof actorRef === 'function' ? actorRef(args, actionParams) : actorRef;
|
|
147
145
|
const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
|
|
148
146
|
let children = state.children;
|
|
149
147
|
if (resolvedActorRef) {
|
|
@@ -160,11 +158,22 @@ function executeStop(actorContext, actorRef) {
|
|
|
160
158
|
if (!actorRef) {
|
|
161
159
|
return;
|
|
162
160
|
}
|
|
161
|
+
|
|
162
|
+
// we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
|
|
163
|
+
// since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
|
|
164
|
+
// this could throw on `systemId` collision, for example, when dealing with reentering transitions
|
|
165
|
+
actorContext.system._unregister(actorRef);
|
|
166
|
+
|
|
167
|
+
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
168
|
+
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
163
169
|
if (actorRef.status !== ActorStatus.Running) {
|
|
164
170
|
actorContext.stopChild(actorRef);
|
|
165
171
|
return;
|
|
166
172
|
}
|
|
167
|
-
//
|
|
173
|
+
// stopping a child enqueues a stop event in the child actor's mailbox
|
|
174
|
+
// we need for all of the already enqueued events to be processed before we stop the child
|
|
175
|
+
// the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
|
|
176
|
+
// and we don't want to ignore those events
|
|
168
177
|
actorContext.defer(() => {
|
|
169
178
|
actorContext.stopChild(actorRef);
|
|
170
179
|
});
|
|
@@ -175,7 +184,7 @@ function executeStop(actorContext, actorRef) {
|
|
|
175
184
|
* @param actorRef The actor to stop.
|
|
176
185
|
*/
|
|
177
186
|
function stop(actorRef) {
|
|
178
|
-
function stop(
|
|
187
|
+
function stop(args, params) {
|
|
179
188
|
{
|
|
180
189
|
throw new Error(`This isn't supposed to be called`);
|
|
181
190
|
}
|
|
@@ -191,12 +200,13 @@ function checkStateIn(state, _, {
|
|
|
191
200
|
stateValue
|
|
192
201
|
}) {
|
|
193
202
|
if (typeof stateValue === 'string' && isStateId(stateValue)) {
|
|
194
|
-
|
|
203
|
+
const target = state.machine.getStateNodeById(stateValue);
|
|
204
|
+
return state.configuration.some(sn => sn === target);
|
|
195
205
|
}
|
|
196
206
|
return state.matches(stateValue);
|
|
197
207
|
}
|
|
198
208
|
function stateIn(stateValue) {
|
|
199
|
-
function stateIn(
|
|
209
|
+
function stateIn(args, params) {
|
|
200
210
|
{
|
|
201
211
|
throw new Error(`This isn't supposed to be called`);
|
|
202
212
|
}
|
|
@@ -214,7 +224,7 @@ function checkNot(state, {
|
|
|
214
224
|
return !evaluateGuard(guards[0], context, event, state);
|
|
215
225
|
}
|
|
216
226
|
function not(guard) {
|
|
217
|
-
function not(
|
|
227
|
+
function not(args, params) {
|
|
218
228
|
{
|
|
219
229
|
throw new Error(`This isn't supposed to be called`);
|
|
220
230
|
}
|
|
@@ -232,7 +242,7 @@ function checkAnd(state, {
|
|
|
232
242
|
return guards.every(guard => evaluateGuard(guard, context, event, state));
|
|
233
243
|
}
|
|
234
244
|
function and(guards) {
|
|
235
|
-
function and(
|
|
245
|
+
function and(args, params) {
|
|
236
246
|
{
|
|
237
247
|
throw new Error(`This isn't supposed to be called`);
|
|
238
248
|
}
|
|
@@ -250,7 +260,7 @@ function checkOr(state, {
|
|
|
250
260
|
return guards.some(guard => evaluateGuard(guard, context, event, state));
|
|
251
261
|
}
|
|
252
262
|
function or(guards) {
|
|
253
|
-
function or(
|
|
263
|
+
function or(args, params) {
|
|
254
264
|
{
|
|
255
265
|
throw new Error(`This isn't supposed to be called`);
|
|
256
266
|
}
|
|
@@ -275,22 +285,17 @@ function evaluateGuard(guard, context, event, state) {
|
|
|
275
285
|
}
|
|
276
286
|
const guardArgs = {
|
|
277
287
|
context,
|
|
278
|
-
event
|
|
279
|
-
guard: isInline ? undefined : typeof guard === 'string' ? {
|
|
280
|
-
type: guard
|
|
281
|
-
} : typeof guard.params === 'function' ? {
|
|
282
|
-
type: guard.type,
|
|
283
|
-
params: guard.params({
|
|
284
|
-
context,
|
|
285
|
-
event
|
|
286
|
-
})
|
|
287
|
-
} : guard
|
|
288
|
+
event
|
|
288
289
|
};
|
|
290
|
+
const guardParams = isInline || typeof guard === 'string' ? undefined : 'params' in guard ? typeof guard.params === 'function' ? guard.params({
|
|
291
|
+
context,
|
|
292
|
+
event
|
|
293
|
+
}) : guard.params : undefined;
|
|
289
294
|
if (!('check' in resolved)) {
|
|
290
295
|
// the existing type of `.guards` assumes non-nullable `TExpressionGuard`
|
|
291
296
|
// inline guards expect `TExpressionGuard` to be set to `undefined`
|
|
292
297
|
// it's fine to cast this here, our logic makes sure that we call those 2 "variants" correctly
|
|
293
|
-
return resolved(guardArgs);
|
|
298
|
+
return resolved(guardArgs, guardParams);
|
|
294
299
|
}
|
|
295
300
|
const builtinGuard = resolved;
|
|
296
301
|
return builtinGuard.check(state, guardArgs, resolved // this holds all params
|
|
@@ -303,6 +308,9 @@ function getChildren(stateNode) {
|
|
|
303
308
|
}
|
|
304
309
|
function getProperAncestors(stateNode, toStateNode) {
|
|
305
310
|
const ancestors = [];
|
|
311
|
+
if (toStateNode === stateNode) {
|
|
312
|
+
return ancestors;
|
|
313
|
+
}
|
|
306
314
|
|
|
307
315
|
// add all ancestors
|
|
308
316
|
let m = stateNode.parent;
|
|
@@ -590,12 +598,14 @@ function resolveTarget(stateNode, targets) {
|
|
|
590
598
|
}
|
|
591
599
|
});
|
|
592
600
|
}
|
|
593
|
-
function
|
|
601
|
+
function resolveHistoryDefaultTransition(stateNode) {
|
|
594
602
|
const normalizedTarget = normalizeTarget(stateNode.config.target);
|
|
595
603
|
if (!normalizedTarget) {
|
|
596
|
-
return stateNode.parent.initial
|
|
604
|
+
return stateNode.parent.initial;
|
|
597
605
|
}
|
|
598
|
-
return
|
|
606
|
+
return {
|
|
607
|
+
target: normalizedTarget.map(t => typeof t === 'string' ? getStateNodeByPath(stateNode.parent, t) : t)
|
|
608
|
+
};
|
|
599
609
|
}
|
|
600
610
|
function isHistoryNode(stateNode) {
|
|
601
611
|
return stateNode.type === 'history';
|
|
@@ -822,9 +832,7 @@ function getEffectiveTargetStates(transition, historyValue) {
|
|
|
822
832
|
targets.add(node);
|
|
823
833
|
}
|
|
824
834
|
} else {
|
|
825
|
-
for (const node of getEffectiveTargetStates({
|
|
826
|
-
target: resolveHistoryTarget(targetNode)
|
|
827
|
-
}, historyValue)) {
|
|
835
|
+
for (const node of getEffectiveTargetStates(resolveHistoryDefaultTransition(targetNode), historyValue)) {
|
|
828
836
|
targets.add(node);
|
|
829
837
|
}
|
|
830
838
|
}
|
|
@@ -837,9 +845,9 @@ function getEffectiveTargetStates(transition, historyValue) {
|
|
|
837
845
|
function getTransitionDomain(transition, historyValue) {
|
|
838
846
|
const targetStates = getEffectiveTargetStates(transition, historyValue);
|
|
839
847
|
if (!targetStates) {
|
|
840
|
-
return
|
|
848
|
+
return;
|
|
841
849
|
}
|
|
842
|
-
if (!transition.reenter &&
|
|
850
|
+
if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
|
|
843
851
|
return transition.source;
|
|
844
852
|
}
|
|
845
853
|
const lcca = findLCCA(targetStates.concat(transition.source));
|
|
@@ -850,6 +858,9 @@ function computeExitSet(transitions, configuration, historyValue) {
|
|
|
850
858
|
for (const t of transitions) {
|
|
851
859
|
if (t.target?.length) {
|
|
852
860
|
const domain = getTransitionDomain(t, historyValue);
|
|
861
|
+
if (t.reenter && t.source === domain) {
|
|
862
|
+
statesToExit.add(domain);
|
|
863
|
+
}
|
|
853
864
|
for (const stateNode of configuration) {
|
|
854
865
|
if (isDescendant(stateNode, domain)) {
|
|
855
866
|
statesToExit.add(stateNode);
|
|
@@ -873,11 +884,6 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
|
|
|
873
884
|
|
|
874
885
|
/**
|
|
875
886
|
* https://www.w3.org/TR/scxml/#microstepProcedure
|
|
876
|
-
*
|
|
877
|
-
* @private
|
|
878
|
-
* @param transitions
|
|
879
|
-
* @param currentState
|
|
880
|
-
* @param mutConfiguration
|
|
881
887
|
*/
|
|
882
888
|
function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
|
|
883
889
|
if (!transitions.length) {
|
|
@@ -926,6 +932,9 @@ function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode)
|
|
|
926
932
|
function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
927
933
|
let nextState = currentState;
|
|
928
934
|
const statesToEnter = new Set();
|
|
935
|
+
// those are states that were directly targeted or indirectly targeted by the explicit target
|
|
936
|
+
// in other words, those are states for which initial actions should be executed
|
|
937
|
+
// when we target `#deep_child` initial actions of its ancestors shouldn't be executed
|
|
929
938
|
const statesForDefaultEntry = new Set();
|
|
930
939
|
computeEntrySet(filteredTransitions, historyValue, statesForDefaultEntry, statesToEnter);
|
|
931
940
|
|
|
@@ -941,7 +950,10 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
941
950
|
// Add entry actions
|
|
942
951
|
actions.push(...stateNodeToEnter.entry);
|
|
943
952
|
for (const invokeDef of stateNodeToEnter.invoke) {
|
|
944
|
-
actions.push(
|
|
953
|
+
actions.push(spawn(invokeDef.src, {
|
|
954
|
+
...invokeDef,
|
|
955
|
+
syncSnapshot: !!invokeDef.onSnapshot
|
|
956
|
+
}));
|
|
945
957
|
}
|
|
946
958
|
if (statesForDefaultEntry.has(stateNodeToEnter)) {
|
|
947
959
|
const initialActions = stateNodeToEnter.initial.actions;
|
|
@@ -950,20 +962,16 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
950
962
|
nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
|
|
951
963
|
if (stateNodeToEnter.type === 'final') {
|
|
952
964
|
const parent = stateNodeToEnter.parent;
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
completedNodes.add(parent);
|
|
957
|
-
let rootCompletionNode = parent?.type === 'parallel' ? parent : stateNodeToEnter;
|
|
958
|
-
let ancestorMarker = parent?.parent;
|
|
959
|
-
if (ancestorMarker) {
|
|
965
|
+
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
966
|
+
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
967
|
+
if (parent?.type === 'compound') {
|
|
960
968
|
internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
969
|
+
}
|
|
970
|
+
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
971
|
+
completedNodes.add(ancestorMarker);
|
|
972
|
+
internalQueue.push(createDoneStateEvent(ancestorMarker.id));
|
|
973
|
+
rootCompletionNode = ancestorMarker;
|
|
974
|
+
ancestorMarker = ancestorMarker.parent;
|
|
967
975
|
}
|
|
968
976
|
if (ancestorMarker) {
|
|
969
977
|
continue;
|
|
@@ -978,13 +986,24 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
|
|
|
978
986
|
}
|
|
979
987
|
function computeEntrySet(transitions, historyValue, statesForDefaultEntry, statesToEnter) {
|
|
980
988
|
for (const t of transitions) {
|
|
989
|
+
const domain = getTransitionDomain(t, historyValue);
|
|
981
990
|
for (const s of t.target || []) {
|
|
991
|
+
if (!isHistoryNode(s) && (
|
|
992
|
+
// if the target is different than the source then it will *definitely* be entered
|
|
993
|
+
t.source !== s ||
|
|
994
|
+
// we know that the domain can't lie within the source
|
|
995
|
+
// 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
|
|
996
|
+
t.source !== domain ||
|
|
997
|
+
// reentering transitions always enter the target, even if it's the source itself
|
|
998
|
+
t.reenter)) {
|
|
999
|
+
statesToEnter.add(s);
|
|
1000
|
+
statesForDefaultEntry.add(s);
|
|
1001
|
+
}
|
|
982
1002
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
983
1003
|
}
|
|
984
|
-
const ancestor = getTransitionDomain(t, historyValue);
|
|
985
1004
|
const targetStates = getEffectiveTargetStates(t, historyValue);
|
|
986
1005
|
for (const s of targetStates) {
|
|
987
|
-
addAncestorStatesToEnter(s,
|
|
1006
|
+
addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
|
|
988
1007
|
}
|
|
989
1008
|
}
|
|
990
1009
|
}
|
|
@@ -993,37 +1012,42 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
|
|
|
993
1012
|
if (historyValue[stateNode.id]) {
|
|
994
1013
|
const historyStateNodes = historyValue[stateNode.id];
|
|
995
1014
|
for (const s of historyStateNodes) {
|
|
1015
|
+
statesToEnter.add(s);
|
|
996
1016
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
997
1017
|
}
|
|
998
1018
|
for (const s of historyStateNodes) {
|
|
999
1019
|
addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1000
|
-
for (const stateForDefaultEntry of statesForDefaultEntry) {
|
|
1001
|
-
statesForDefaultEntry.add(stateForDefaultEntry);
|
|
1002
|
-
}
|
|
1003
1020
|
}
|
|
1004
1021
|
} else {
|
|
1005
|
-
const
|
|
1006
|
-
for (const s of
|
|
1022
|
+
const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
|
|
1023
|
+
for (const s of historyDefaultTransition.target) {
|
|
1024
|
+
statesToEnter.add(s);
|
|
1025
|
+
if (historyDefaultTransition === stateNode.parent?.initial) {
|
|
1026
|
+
statesForDefaultEntry.add(stateNode.parent);
|
|
1027
|
+
}
|
|
1007
1028
|
addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1008
1029
|
}
|
|
1009
|
-
for (const s of
|
|
1030
|
+
for (const s of historyDefaultTransition.target) {
|
|
1010
1031
|
addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1011
|
-
for (const stateForDefaultEntry of statesForDefaultEntry) {
|
|
1012
|
-
statesForDefaultEntry.add(stateForDefaultEntry);
|
|
1013
|
-
}
|
|
1014
1032
|
}
|
|
1015
1033
|
}
|
|
1016
1034
|
} else {
|
|
1017
|
-
statesToEnter.add(stateNode);
|
|
1018
1035
|
if (stateNode.type === 'compound') {
|
|
1019
|
-
statesForDefaultEntry.add(stateNode);
|
|
1020
1036
|
const [initialState] = stateNode.initial.target;
|
|
1037
|
+
if (!isHistoryNode(initialState)) {
|
|
1038
|
+
statesToEnter.add(initialState);
|
|
1039
|
+
statesForDefaultEntry.add(initialState);
|
|
1040
|
+
}
|
|
1021
1041
|
addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1022
1042
|
addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
|
|
1023
1043
|
} else {
|
|
1024
1044
|
if (stateNode.type === 'parallel') {
|
|
1025
1045
|
for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
|
|
1026
1046
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
1047
|
+
if (!isHistoryNode(child)) {
|
|
1048
|
+
statesToEnter.add(child);
|
|
1049
|
+
statesForDefaultEntry.add(child);
|
|
1050
|
+
}
|
|
1027
1051
|
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1028
1052
|
}
|
|
1029
1053
|
}
|
|
@@ -1038,6 +1062,7 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
|
|
|
1038
1062
|
if (anc.type === 'parallel') {
|
|
1039
1063
|
for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
|
|
1040
1064
|
if (![...statesToEnter].some(s => isDescendant(s, child))) {
|
|
1065
|
+
statesToEnter.add(child);
|
|
1041
1066
|
addDescendantStatesToEnter(child, historyValue, statesForDefaultEntry, statesToEnter);
|
|
1042
1067
|
}
|
|
1043
1068
|
}
|
|
@@ -1092,31 +1117,24 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
|
|
|
1092
1117
|
context: intermediateState.context,
|
|
1093
1118
|
event,
|
|
1094
1119
|
self: actorCtx?.self,
|
|
1095
|
-
system: actorCtx?.system
|
|
1096
|
-
action: isInline ? undefined : typeof action === 'string' ? {
|
|
1097
|
-
type: action
|
|
1098
|
-
} : typeof action.params === 'function' ? {
|
|
1099
|
-
type: action.type,
|
|
1100
|
-
params: action.params({
|
|
1101
|
-
context: intermediateState.context,
|
|
1102
|
-
event
|
|
1103
|
-
})
|
|
1104
|
-
} :
|
|
1105
|
-
// TS isn't able to narrow it down here
|
|
1106
|
-
action
|
|
1120
|
+
system: actorCtx?.system
|
|
1107
1121
|
};
|
|
1122
|
+
const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
|
|
1123
|
+
context: intermediateState.context,
|
|
1124
|
+
event
|
|
1125
|
+
}) : action.params : undefined;
|
|
1108
1126
|
if (!('resolve' in resolvedAction)) {
|
|
1109
1127
|
if (actorCtx?.self.status === ActorStatus.Running) {
|
|
1110
|
-
resolvedAction(actionArgs);
|
|
1128
|
+
resolvedAction(actionArgs, actionParams);
|
|
1111
1129
|
} else {
|
|
1112
1130
|
actorCtx?.defer(() => {
|
|
1113
|
-
resolvedAction(actionArgs);
|
|
1131
|
+
resolvedAction(actionArgs, actionParams);
|
|
1114
1132
|
});
|
|
1115
1133
|
}
|
|
1116
1134
|
continue;
|
|
1117
1135
|
}
|
|
1118
1136
|
const builtinAction = resolvedAction;
|
|
1119
|
-
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, resolvedAction,
|
|
1137
|
+
const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, actionParams, resolvedAction,
|
|
1120
1138
|
// this holds all params
|
|
1121
1139
|
extra);
|
|
1122
1140
|
intermediateState = nextState;
|
|
@@ -1156,7 +1174,9 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
|
|
|
1156
1174
|
|
|
1157
1175
|
// Handle stop event
|
|
1158
1176
|
if (event.type === XSTATE_STOP) {
|
|
1159
|
-
nextState = stopChildren(nextState, event, actorCtx)
|
|
1177
|
+
nextState = cloneState(stopChildren(nextState, event, actorCtx), {
|
|
1178
|
+
status: 'stopped'
|
|
1179
|
+
});
|
|
1160
1180
|
states.push(nextState);
|
|
1161
1181
|
return {
|
|
1162
1182
|
state: nextState,
|
|
@@ -1208,7 +1228,7 @@ function selectEventlessTransitions(nextState, event) {
|
|
|
1208
1228
|
const enabledTransitionSet = new Set();
|
|
1209
1229
|
const atomicStates = nextState.configuration.filter(isAtomicStateNode);
|
|
1210
1230
|
for (const stateNode of atomicStates) {
|
|
1211
|
-
loop: for (const s of [stateNode].concat(getProperAncestors(stateNode,
|
|
1231
|
+
loop: for (const s of [stateNode].concat(getProperAncestors(stateNode, undefined))) {
|
|
1212
1232
|
if (!s.always) {
|
|
1213
1233
|
continue;
|
|
1214
1234
|
}
|
|
@@ -1419,17 +1439,17 @@ function getPersistedState(state) {
|
|
|
1419
1439
|
throw new Error('An inline child actor cannot be persisted.');
|
|
1420
1440
|
}
|
|
1421
1441
|
childrenJson[id] = {
|
|
1422
|
-
state: child.getPersistedState
|
|
1423
|
-
src: child.src
|
|
1442
|
+
state: child.getPersistedState(),
|
|
1443
|
+
src: child.src,
|
|
1444
|
+
systemId: child._systemId
|
|
1424
1445
|
};
|
|
1425
1446
|
}
|
|
1426
|
-
|
|
1447
|
+
const persisted = {
|
|
1427
1448
|
...jsonValues,
|
|
1428
|
-
// TODO: this makes `PersistedMachineState`'s type kind of a lie
|
|
1429
|
-
// it doesn't truly use `TContext` but rather some kind of a derived form of it
|
|
1430
1449
|
context: persistContext(context),
|
|
1431
1450
|
children: childrenJson
|
|
1432
1451
|
};
|
|
1452
|
+
return persisted;
|
|
1433
1453
|
}
|
|
1434
1454
|
function persistContext(contextPart) {
|
|
1435
1455
|
let copy;
|
|
@@ -1458,7 +1478,7 @@ function persistContext(contextPart) {
|
|
|
1458
1478
|
return copy ?? contextPart;
|
|
1459
1479
|
}
|
|
1460
1480
|
|
|
1461
|
-
function resolveRaise(_, state, args, {
|
|
1481
|
+
function resolveRaise(_, state, args, actionParams, {
|
|
1462
1482
|
event: eventOrExpr,
|
|
1463
1483
|
id,
|
|
1464
1484
|
delay
|
|
@@ -1469,13 +1489,13 @@ function resolveRaise(_, state, args, {
|
|
|
1469
1489
|
if (typeof eventOrExpr === 'string') {
|
|
1470
1490
|
throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
|
|
1471
1491
|
}
|
|
1472
|
-
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
|
|
1492
|
+
const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args, actionParams) : eventOrExpr;
|
|
1473
1493
|
let resolvedDelay;
|
|
1474
1494
|
if (typeof delay === 'string') {
|
|
1475
1495
|
const configDelay = delaysMap && delaysMap[delay];
|
|
1476
|
-
resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
|
|
1496
|
+
resolvedDelay = typeof configDelay === 'function' ? configDelay(args, actionParams) : configDelay;
|
|
1477
1497
|
} else {
|
|
1478
|
-
resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
|
|
1498
|
+
resolvedDelay = typeof delay === 'function' ? delay(args, actionParams) : delay;
|
|
1479
1499
|
}
|
|
1480
1500
|
if (typeof resolvedDelay !== 'number') {
|
|
1481
1501
|
internalQueue.push(resolvedEvent);
|
|
@@ -1499,7 +1519,7 @@ function executeRaise(actorContext, params) {
|
|
|
1499
1519
|
* @param eventType The event to raise.
|
|
1500
1520
|
*/
|
|
1501
1521
|
function raise(eventOrExpr, options) {
|
|
1502
|
-
function raise(
|
|
1522
|
+
function raise(args, params) {
|
|
1503
1523
|
{
|
|
1504
1524
|
throw new Error(`This isn't supposed to be called`);
|
|
1505
1525
|
}
|
|
@@ -1513,4 +1533,4 @@ function raise(eventOrExpr, options) {
|
|
|
1513
1533
|
return raise;
|
|
1514
1534
|
}
|
|
1515
1535
|
|
|
1516
|
-
export { raise as A, stop as B, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
|
|
1536
|
+
export { raise as A, stop as B, spawn as C, State as S, formatTransition as a, formatInitialTransition as b, getCandidates as c, getConfiguration as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getStateNodes as h, isInFinalState as i, cloneState as j, macrostep as k, getInitialConfiguration as l, memo as m, resolveActionsAndContext as n, microstep as o, getInitialStateNodes as p, isStateId as q, resolveStateValue as r, getStateNodeByPath as s, transitionNode as t, getPersistedState as u, and as v, not as w, or as x, stateIn as y, cancel as z };
|