xstate 6.0.0-alpha.23 → 6.0.0-alpha.25
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/dist/{StateMachine-022864fd.esm.js → StateMachine-69278d2c.esm.js} +87 -50
- package/dist/{StateMachine-53114dce.development.cjs.js → StateMachine-ac1167f3.development.cjs.js} +90 -53
- package/dist/{StateMachine-aad57180.cjs.js → StateMachine-b20d5a53.cjs.js} +87 -50
- package/dist/{StateMachine-d2247245.development.esm.js → StateMachine-bf4ec0f1.development.esm.js} +90 -53
- package/dist/declarations/src/StateMachine.d.ts +11 -11
- package/dist/declarations/src/StateNode.d.ts +2 -2
- package/dist/declarations/src/createMachine.d.ts +6 -6
- package/dist/declarations/src/createMachineFromConfig.d.ts +6 -5
- package/dist/declarations/src/fsm.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +1 -1
- package/dist/declarations/src/serialize.d.ts +3 -3
- package/dist/declarations/src/setup.d.ts +43 -43
- package/dist/declarations/src/spawn.d.ts +1 -1
- package/dist/declarations/src/stateUtils.d.ts +3 -1
- package/dist/declarations/src/types.d.ts +71 -49
- package/dist/declarations/src/types.v6.d.ts +33 -31
- package/dist/declarations/src/utils.d.ts +1 -0
- package/dist/{index-3609e096.esm.js → index-036a773f.esm.js} +282 -76
- package/dist/{index-41c0375c.development.cjs.js → index-1ad8a761.development.cjs.js} +286 -75
- package/dist/{index-f5407323.development.esm.js → index-b90ebcd4.development.esm.js} +282 -76
- package/dist/{index-434fac23.cjs.js → index-f58cc498.cjs.js} +286 -75
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +1 -1
- package/dist/xstate-actors.esm.js +1 -1
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +9 -13
- package/dist/xstate-graph.development.cjs.js +9 -13
- package/dist/xstate-graph.development.esm.js +9 -13
- package/dist/xstate-graph.esm.js +9 -13
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +58 -52
- package/dist/xstate.development.cjs.js +58 -52
- package/dist/xstate.development.esm.js +60 -54
- package/dist/xstate.esm.js +60 -54
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { M as setSnapshotActorRef, N as getSnapshotActorRef, O as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, P as mapValues, t as toArray, Q as createInvokeId, R as getDelayedTransitions, U as
|
|
1
|
+
import { M as setSnapshotActorRef, N as getSnapshotActorRef, O as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, P as mapValues, t as toArray, Q as createInvokeId, R as getDelayedTransitions, U as getEventDescriptorKey, V as evaluateCandidate, W as formatTransition, Y as NULL_EVENT, Z as toTransitionConfigArray, _ as createInvokeTimeoutEventId, $ as getCandidates, a0 as matchesActorSession, a1 as formatRouteTransitions, a2 as resolveStateValue, a3 as getAllStateNodes, s as getStateNodes, a4 as createMachineSnapshot, a5 as isInFinalState, j as macrostep, a6 as cloneMachineSnapshot, a7 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a8 as getTransitionResult, a9 as hasEffect, aa as createErrorPlatformEvent, r as resolveActionsWithContext, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, ab as toStatePath, ac as isStateId, ad as getStateNodeByPath, ae as getPersistedSnapshot, af as resolveReferencedActor, ag as createInvokeTimeoutEvent, ah as $$ACTOR_TYPE } from './index-036a773f.esm.js';
|
|
2
2
|
|
|
3
|
-
function createSpawner(actorScope,
|
|
3
|
+
function createSpawner(actorScope, actors, spawnedChildren) {
|
|
4
4
|
return (src, options) => {
|
|
5
|
-
const referencedSrc = Object.entries(
|
|
5
|
+
const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
|
|
6
6
|
const actor = actorScope.system.createActorRef(src, {
|
|
7
7
|
id: options?.id,
|
|
8
8
|
parent: actorScope.self,
|
|
@@ -45,7 +45,8 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
|
45
45
|
const self = createActor(actorLogic, {
|
|
46
46
|
_inert: true,
|
|
47
47
|
...(previousSelf ? {
|
|
48
|
-
id: previousSelf.id
|
|
48
|
+
id: previousSelf.id,
|
|
49
|
+
_sessionId: previousSelf.sessionId
|
|
49
50
|
} : {}),
|
|
50
51
|
...(system ? {
|
|
51
52
|
_systemRef: {
|
|
@@ -182,8 +183,8 @@ class StateNode {
|
|
|
182
183
|
*/
|
|
183
184
|
this.meta = void 0;
|
|
184
185
|
/**
|
|
185
|
-
* The output data sent with the
|
|
186
|
-
*
|
|
186
|
+
* The output data sent with the `xstate.done.state` event if this is a final
|
|
187
|
+
* state node.
|
|
187
188
|
*/
|
|
188
189
|
this.output = void 0;
|
|
189
190
|
/**
|
|
@@ -300,8 +301,7 @@ class StateNode {
|
|
|
300
301
|
|
|
301
302
|
/** @internal */
|
|
302
303
|
next(snapshot, event, self) {
|
|
303
|
-
const
|
|
304
|
-
const candidates = memo(this, `candidates-${eventType}`, () => getCandidates(this, eventType));
|
|
304
|
+
const candidates = memo(this, `candidates-${getEventDescriptorKey(event)}`, () => getCandidates(this, event));
|
|
305
305
|
for (const candidate of candidates) {
|
|
306
306
|
const guardPassed = evaluateCandidate(candidate, event, snapshot, this, self);
|
|
307
307
|
if (guardPassed) {
|
|
@@ -342,6 +342,9 @@ function mapTransitionConfigs(transitionsConfig, mapper) {
|
|
|
342
342
|
}
|
|
343
343
|
function formatTransitions(stateNode) {
|
|
344
344
|
const transitions = new Map();
|
|
345
|
+
const addTransitions = (descriptor, additions) => {
|
|
346
|
+
transitions.set(descriptor, [...(transitions.get(descriptor) ?? []), ...additions]);
|
|
347
|
+
};
|
|
345
348
|
if (stateNode.config.on) {
|
|
346
349
|
for (const descriptor of Object.keys(stateNode.config.on)) {
|
|
347
350
|
if (descriptor === NULL_EVENT) {
|
|
@@ -352,20 +355,30 @@ function formatTransitions(stateNode) {
|
|
|
352
355
|
}
|
|
353
356
|
}
|
|
354
357
|
if (stateNode.config.onDone) {
|
|
355
|
-
const descriptor =
|
|
356
|
-
|
|
358
|
+
const descriptor = 'xstate.done.state';
|
|
359
|
+
addTransitions(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => formatTransition(stateNode, descriptor, {
|
|
360
|
+
...transition,
|
|
361
|
+
matches: {
|
|
362
|
+
...transition.matches,
|
|
363
|
+
stateId: stateNode.id
|
|
364
|
+
}
|
|
365
|
+
})));
|
|
357
366
|
}
|
|
358
367
|
if (stateNode.config.onError) {
|
|
359
368
|
const descriptor = 'xstate.error.*';
|
|
360
369
|
transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onError, transition => formatTransition(stateNode, descriptor, transition)));
|
|
361
370
|
}
|
|
362
|
-
const createCancelInvokeTimeoutTransition = (descriptor,
|
|
371
|
+
const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventId, actorId) => formatTransition(stateNode, descriptor, {
|
|
372
|
+
matches: {
|
|
373
|
+
actorId
|
|
374
|
+
},
|
|
375
|
+
_eventMatcher: (event, snapshot) => matchesActorSession(event, snapshot, actorId),
|
|
363
376
|
to: (_args, enq) => {
|
|
364
|
-
enq.cancel(
|
|
377
|
+
enq.cancel(timeoutEventId);
|
|
365
378
|
return {};
|
|
366
379
|
}
|
|
367
380
|
});
|
|
368
|
-
const formatInvokeCompletionTransition = (descriptor, transitionConfig,
|
|
381
|
+
const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventId) => {
|
|
369
382
|
const {
|
|
370
383
|
target,
|
|
371
384
|
to,
|
|
@@ -396,11 +409,11 @@ function formatTransitions(stateNode) {
|
|
|
396
409
|
});
|
|
397
410
|
const result = to(args, trackingEnqueue);
|
|
398
411
|
if (result !== undefined || didEnqueue) {
|
|
399
|
-
enq.cancel(
|
|
412
|
+
enq.cancel(timeoutEventId);
|
|
400
413
|
}
|
|
401
414
|
return result;
|
|
402
415
|
}
|
|
403
|
-
enq.cancel(
|
|
416
|
+
enq.cancel(timeoutEventId);
|
|
404
417
|
return {
|
|
405
418
|
target,
|
|
406
419
|
reenter
|
|
@@ -409,25 +422,39 @@ function formatTransitions(stateNode) {
|
|
|
409
422
|
});
|
|
410
423
|
};
|
|
411
424
|
for (const invokeDef of stateNode.invoke) {
|
|
412
|
-
const
|
|
425
|
+
const withInvokeMatch = transition => ({
|
|
426
|
+
...transition,
|
|
427
|
+
matches: {
|
|
428
|
+
...transition.matches,
|
|
429
|
+
actorId: invokeDef.id
|
|
430
|
+
},
|
|
431
|
+
_eventMatcher: (event, snapshot) => matchesActorSession(event, snapshot, invokeDef.id)
|
|
432
|
+
});
|
|
433
|
+
const invokeTimeoutEventId = invokeDef.timeout !== undefined ? createInvokeTimeoutEventId(invokeDef.id) : undefined;
|
|
413
434
|
if (invokeDef.onDone) {
|
|
414
|
-
const descriptor =
|
|
415
|
-
const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone,
|
|
416
|
-
|
|
417
|
-
|
|
435
|
+
const descriptor = 'xstate.done.actor';
|
|
436
|
+
const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, rawTransition => {
|
|
437
|
+
const transition = withInvokeMatch(rawTransition);
|
|
438
|
+
return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : formatTransition(stateNode, descriptor, transition);
|
|
439
|
+
});
|
|
440
|
+
if (invokeTimeoutEventId) {
|
|
441
|
+
invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id));
|
|
418
442
|
}
|
|
419
|
-
|
|
420
|
-
} else if (
|
|
421
|
-
const descriptor =
|
|
422
|
-
|
|
443
|
+
addTransitions(descriptor, invokeDoneTransitions);
|
|
444
|
+
} else if (invokeTimeoutEventId) {
|
|
445
|
+
const descriptor = 'xstate.done.actor';
|
|
446
|
+
addTransitions(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id)]);
|
|
423
447
|
}
|
|
424
448
|
if (invokeDef.onError) {
|
|
425
|
-
const descriptor =
|
|
426
|
-
|
|
449
|
+
const descriptor = 'xstate.error.actor';
|
|
450
|
+
addTransitions(descriptor, mapTransitionConfigs(invokeDef.onError, rawTransition => {
|
|
451
|
+
const transition = withInvokeMatch(rawTransition);
|
|
452
|
+
return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : formatTransition(stateNode, descriptor, transition);
|
|
453
|
+
}));
|
|
427
454
|
}
|
|
428
455
|
if (invokeDef.onSnapshot) {
|
|
429
|
-
const descriptor =
|
|
430
|
-
|
|
456
|
+
const descriptor = 'xstate.snapshot.actor';
|
|
457
|
+
addTransitions(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => formatTransition(stateNode, descriptor, withInvokeMatch(transition))));
|
|
431
458
|
}
|
|
432
459
|
}
|
|
433
460
|
for (const delayedTransition of stateNode.after) {
|
|
@@ -497,12 +524,12 @@ function getEmptyCanActorScope() {
|
|
|
497
524
|
}
|
|
498
525
|
class StateMachine {
|
|
499
526
|
constructor(/** The raw config used to create the machine. */
|
|
500
|
-
config,
|
|
527
|
+
config, sources) {
|
|
501
528
|
this.config = config;
|
|
502
529
|
/** The machine's own version. */
|
|
503
530
|
this.version = void 0;
|
|
504
531
|
this.schemas = void 0;
|
|
505
|
-
this.
|
|
532
|
+
this.sources = void 0;
|
|
506
533
|
/** Runtime options for machine execution. */
|
|
507
534
|
this.options = void 0;
|
|
508
535
|
/** @internal */
|
|
@@ -521,12 +548,12 @@ class StateMachine {
|
|
|
521
548
|
*/
|
|
522
549
|
this._json = void 0;
|
|
523
550
|
this.id = config.id || '(machine)';
|
|
524
|
-
this.
|
|
525
|
-
|
|
551
|
+
this.sources = {
|
|
552
|
+
actors: config.actors ?? {},
|
|
526
553
|
actions: config.actions ?? {},
|
|
527
554
|
delays: config.delays ?? {},
|
|
528
555
|
guards: config.guards ?? {},
|
|
529
|
-
...
|
|
556
|
+
...sources
|
|
530
557
|
};
|
|
531
558
|
this.version = this.config.version;
|
|
532
559
|
this.schemas = this.config.schemas;
|
|
@@ -553,38 +580,38 @@ class StateMachine {
|
|
|
553
580
|
}
|
|
554
581
|
|
|
555
582
|
/**
|
|
556
|
-
* Clones this state machine with the provided
|
|
583
|
+
* Clones this state machine with the provided sources.
|
|
557
584
|
*
|
|
558
|
-
* @param
|
|
559
|
-
*
|
|
560
|
-
* @returns A new `StateMachine` instance with the provided
|
|
585
|
+
* @param sources Options (`actions`, `guards`, `actors`, `delays`) to
|
|
586
|
+
* recursively merge with the existing options.
|
|
587
|
+
* @returns A new `StateMachine` instance with the provided sources.
|
|
561
588
|
*/
|
|
562
|
-
provide(
|
|
589
|
+
provide(sources) {
|
|
563
590
|
const {
|
|
564
591
|
actions,
|
|
565
592
|
guards,
|
|
566
|
-
|
|
593
|
+
actors,
|
|
567
594
|
delays
|
|
568
|
-
} = this.
|
|
595
|
+
} = this.sources;
|
|
569
596
|
const provided = new StateMachine(this.config, {
|
|
570
597
|
actions: {
|
|
571
598
|
...actions,
|
|
572
|
-
...
|
|
599
|
+
...sources.actions
|
|
573
600
|
},
|
|
574
601
|
guards: {
|
|
575
602
|
...guards,
|
|
576
|
-
...
|
|
603
|
+
...sources.guards
|
|
577
604
|
},
|
|
578
|
-
|
|
579
|
-
...
|
|
580
|
-
...
|
|
605
|
+
actors: {
|
|
606
|
+
...actors,
|
|
607
|
+
...sources.actors
|
|
581
608
|
},
|
|
582
609
|
delays: {
|
|
583
610
|
...delays,
|
|
584
|
-
...
|
|
611
|
+
...sources.delays
|
|
585
612
|
}
|
|
586
613
|
});
|
|
587
|
-
// Providing
|
|
614
|
+
// Providing sources does not change the serializable definition.
|
|
588
615
|
provided._json = this._json;
|
|
589
616
|
return provided;
|
|
590
617
|
}
|
|
@@ -775,12 +802,12 @@ class StateMachine {
|
|
|
775
802
|
}, this, actorScope.self);
|
|
776
803
|
if (typeof context === 'function') {
|
|
777
804
|
const children = {};
|
|
778
|
-
const spawn = createSpawner(actorScope, this.
|
|
805
|
+
const spawn = createSpawner(actorScope, this.sources.actors, children);
|
|
779
806
|
const resolvedContext = context({
|
|
780
807
|
spawn,
|
|
781
808
|
input: initEvent.input,
|
|
782
809
|
self: actorScope.self,
|
|
783
|
-
|
|
810
|
+
actors: this.sources.actors
|
|
784
811
|
});
|
|
785
812
|
const [nextState] = resolveActionsWithContext(preInitial, initEvent, actorScope, []);
|
|
786
813
|
if (resolvedContext) {
|
|
@@ -883,7 +910,8 @@ class StateMachine {
|
|
|
883
910
|
const src = actorData.src;
|
|
884
911
|
const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
|
|
885
912
|
if (!logic) {
|
|
886
|
-
|
|
913
|
+
const sourceId = typeof src === 'string' ? src : '<unknown>';
|
|
914
|
+
throw new Error(`Unable to restore child actor '${actorId}': child source '${sourceId}' is not provided in machine '${this.id}'.`);
|
|
887
915
|
}
|
|
888
916
|
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
889
917
|
id: actorId,
|
|
@@ -901,6 +929,14 @@ class StateMachine {
|
|
|
901
929
|
const timers = {};
|
|
902
930
|
const persistedTimers = snapshotData.timers ?? {};
|
|
903
931
|
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
932
|
+
let event = timer.event;
|
|
933
|
+
if (event.type === 'xstate.timeout.actor') {
|
|
934
|
+
const actorId = event.actorId;
|
|
935
|
+
const child = children[actorId];
|
|
936
|
+
if (child) {
|
|
937
|
+
event = createInvokeTimeoutEvent(actorId, child.sessionId);
|
|
938
|
+
}
|
|
939
|
+
}
|
|
904
940
|
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
905
941
|
if (!target) {
|
|
906
942
|
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
@@ -908,6 +944,7 @@ class StateMachine {
|
|
|
908
944
|
}
|
|
909
945
|
timers[id] = {
|
|
910
946
|
...timer,
|
|
947
|
+
event,
|
|
911
948
|
target
|
|
912
949
|
};
|
|
913
950
|
}
|
package/dist/{StateMachine-53114dce.development.cjs.js → StateMachine-ac1167f3.development.cjs.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var dist_xstateActors = require('./index-
|
|
3
|
+
var dist_xstateActors = require('./index-1ad8a761.development.cjs.js');
|
|
4
4
|
|
|
5
|
-
function createSpawner(actorScope,
|
|
5
|
+
function createSpawner(actorScope, actors, spawnedChildren) {
|
|
6
6
|
return (src, options) => {
|
|
7
|
-
const referencedSrc = Object.entries(
|
|
7
|
+
const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
|
|
8
8
|
const actor = actorScope.system.createActorRef(src, {
|
|
9
9
|
id: options?.id,
|
|
10
10
|
parent: actorScope.self,
|
|
@@ -47,7 +47,8 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
|
|
|
47
47
|
const self = dist_xstateActors.createActor(actorLogic, {
|
|
48
48
|
_inert: true,
|
|
49
49
|
...(previousSelf ? {
|
|
50
|
-
id: previousSelf.id
|
|
50
|
+
id: previousSelf.id,
|
|
51
|
+
_sessionId: previousSelf.sessionId
|
|
51
52
|
} : {}),
|
|
52
53
|
...(system ? {
|
|
53
54
|
_systemRef: {
|
|
@@ -185,8 +186,8 @@ class StateNode {
|
|
|
185
186
|
*/
|
|
186
187
|
this.meta = void 0;
|
|
187
188
|
/**
|
|
188
|
-
* The output data sent with the
|
|
189
|
-
*
|
|
189
|
+
* The output data sent with the `xstate.done.state` event if this is a final
|
|
190
|
+
* state node.
|
|
190
191
|
*/
|
|
191
192
|
this.output = void 0;
|
|
192
193
|
/**
|
|
@@ -303,8 +304,7 @@ class StateNode {
|
|
|
303
304
|
|
|
304
305
|
/** @internal */
|
|
305
306
|
next(snapshot, event, self) {
|
|
306
|
-
const
|
|
307
|
-
const candidates = memo(this, `candidates-${eventType}`, () => dist_xstateActors.getCandidates(this, eventType));
|
|
307
|
+
const candidates = memo(this, `candidates-${dist_xstateActors.getEventDescriptorKey(event)}`, () => dist_xstateActors.getCandidates(this, event));
|
|
308
308
|
for (const candidate of candidates) {
|
|
309
309
|
const guardPassed = dist_xstateActors.evaluateCandidate(candidate, event, snapshot, this, self);
|
|
310
310
|
if (guardPassed) {
|
|
@@ -362,6 +362,9 @@ function mapTransitionConfigs(transitionsConfig, mapper) {
|
|
|
362
362
|
}
|
|
363
363
|
function formatTransitions(stateNode) {
|
|
364
364
|
const transitions = new Map();
|
|
365
|
+
const addTransitions = (descriptor, additions) => {
|
|
366
|
+
transitions.set(descriptor, [...(transitions.get(descriptor) ?? []), ...additions]);
|
|
367
|
+
};
|
|
365
368
|
if (stateNode.config.on) {
|
|
366
369
|
for (const descriptor of Object.keys(stateNode.config.on)) {
|
|
367
370
|
if (descriptor === dist_xstateActors.NULL_EVENT) {
|
|
@@ -372,20 +375,30 @@ function formatTransitions(stateNode) {
|
|
|
372
375
|
}
|
|
373
376
|
}
|
|
374
377
|
if (stateNode.config.onDone) {
|
|
375
|
-
const descriptor =
|
|
376
|
-
|
|
378
|
+
const descriptor = 'xstate.done.state';
|
|
379
|
+
addTransitions(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => dist_xstateActors.formatTransition(stateNode, descriptor, {
|
|
380
|
+
...transition,
|
|
381
|
+
matches: {
|
|
382
|
+
...transition.matches,
|
|
383
|
+
stateId: stateNode.id
|
|
384
|
+
}
|
|
385
|
+
})));
|
|
377
386
|
}
|
|
378
387
|
if (stateNode.config.onError) {
|
|
379
388
|
const descriptor = 'xstate.error.*';
|
|
380
389
|
transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onError, transition => dist_xstateActors.formatTransition(stateNode, descriptor, transition)));
|
|
381
390
|
}
|
|
382
|
-
const createCancelInvokeTimeoutTransition = (descriptor,
|
|
391
|
+
const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventId, actorId) => dist_xstateActors.formatTransition(stateNode, descriptor, {
|
|
392
|
+
matches: {
|
|
393
|
+
actorId
|
|
394
|
+
},
|
|
395
|
+
_eventMatcher: (event, snapshot) => dist_xstateActors.matchesActorSession(event, snapshot, actorId),
|
|
383
396
|
to: (_args, enq) => {
|
|
384
|
-
enq.cancel(
|
|
397
|
+
enq.cancel(timeoutEventId);
|
|
385
398
|
return {};
|
|
386
399
|
}
|
|
387
400
|
});
|
|
388
|
-
const formatInvokeCompletionTransition = (descriptor, transitionConfig,
|
|
401
|
+
const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventId) => {
|
|
389
402
|
const {
|
|
390
403
|
target,
|
|
391
404
|
to,
|
|
@@ -416,11 +429,11 @@ function formatTransitions(stateNode) {
|
|
|
416
429
|
});
|
|
417
430
|
const result = to(args, trackingEnqueue);
|
|
418
431
|
if (result !== undefined || didEnqueue) {
|
|
419
|
-
enq.cancel(
|
|
432
|
+
enq.cancel(timeoutEventId);
|
|
420
433
|
}
|
|
421
434
|
return result;
|
|
422
435
|
}
|
|
423
|
-
enq.cancel(
|
|
436
|
+
enq.cancel(timeoutEventId);
|
|
424
437
|
return {
|
|
425
438
|
target,
|
|
426
439
|
reenter
|
|
@@ -429,25 +442,39 @@ function formatTransitions(stateNode) {
|
|
|
429
442
|
});
|
|
430
443
|
};
|
|
431
444
|
for (const invokeDef of stateNode.invoke) {
|
|
432
|
-
const
|
|
445
|
+
const withInvokeMatch = transition => ({
|
|
446
|
+
...transition,
|
|
447
|
+
matches: {
|
|
448
|
+
...transition.matches,
|
|
449
|
+
actorId: invokeDef.id
|
|
450
|
+
},
|
|
451
|
+
_eventMatcher: (event, snapshot) => dist_xstateActors.matchesActorSession(event, snapshot, invokeDef.id)
|
|
452
|
+
});
|
|
453
|
+
const invokeTimeoutEventId = invokeDef.timeout !== undefined ? dist_xstateActors.createInvokeTimeoutEventId(invokeDef.id) : undefined;
|
|
433
454
|
if (invokeDef.onDone) {
|
|
434
|
-
const descriptor =
|
|
435
|
-
const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone,
|
|
436
|
-
|
|
437
|
-
|
|
455
|
+
const descriptor = 'xstate.done.actor';
|
|
456
|
+
const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, rawTransition => {
|
|
457
|
+
const transition = withInvokeMatch(rawTransition);
|
|
458
|
+
return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : dist_xstateActors.formatTransition(stateNode, descriptor, transition);
|
|
459
|
+
});
|
|
460
|
+
if (invokeTimeoutEventId) {
|
|
461
|
+
invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id));
|
|
438
462
|
}
|
|
439
|
-
|
|
440
|
-
} else if (
|
|
441
|
-
const descriptor =
|
|
442
|
-
|
|
463
|
+
addTransitions(descriptor, invokeDoneTransitions);
|
|
464
|
+
} else if (invokeTimeoutEventId) {
|
|
465
|
+
const descriptor = 'xstate.done.actor';
|
|
466
|
+
addTransitions(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id)]);
|
|
443
467
|
}
|
|
444
468
|
if (invokeDef.onError) {
|
|
445
|
-
const descriptor =
|
|
446
|
-
|
|
469
|
+
const descriptor = 'xstate.error.actor';
|
|
470
|
+
addTransitions(descriptor, mapTransitionConfigs(invokeDef.onError, rawTransition => {
|
|
471
|
+
const transition = withInvokeMatch(rawTransition);
|
|
472
|
+
return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : dist_xstateActors.formatTransition(stateNode, descriptor, transition);
|
|
473
|
+
}));
|
|
447
474
|
}
|
|
448
475
|
if (invokeDef.onSnapshot) {
|
|
449
|
-
const descriptor =
|
|
450
|
-
|
|
476
|
+
const descriptor = 'xstate.snapshot.actor';
|
|
477
|
+
addTransitions(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => dist_xstateActors.formatTransition(stateNode, descriptor, withInvokeMatch(transition))));
|
|
451
478
|
}
|
|
452
479
|
}
|
|
453
480
|
for (const delayedTransition of stateNode.after) {
|
|
@@ -517,12 +544,12 @@ function getEmptyCanActorScope() {
|
|
|
517
544
|
}
|
|
518
545
|
class StateMachine {
|
|
519
546
|
constructor(/** The raw config used to create the machine. */
|
|
520
|
-
config,
|
|
547
|
+
config, sources) {
|
|
521
548
|
this.config = config;
|
|
522
549
|
/** The machine's own version. */
|
|
523
550
|
this.version = void 0;
|
|
524
551
|
this.schemas = void 0;
|
|
525
|
-
this.
|
|
552
|
+
this.sources = void 0;
|
|
526
553
|
/** Runtime options for machine execution. */
|
|
527
554
|
this.options = void 0;
|
|
528
555
|
/** @internal */
|
|
@@ -541,18 +568,18 @@ class StateMachine {
|
|
|
541
568
|
*/
|
|
542
569
|
this._json = void 0;
|
|
543
570
|
this.id = config.id || '(machine)';
|
|
544
|
-
this.
|
|
545
|
-
|
|
571
|
+
this.sources = {
|
|
572
|
+
actors: config.actors ?? {},
|
|
546
573
|
actions: config.actions ?? {},
|
|
547
574
|
delays: config.delays ?? {},
|
|
548
575
|
guards: config.guards ?? {},
|
|
549
|
-
...
|
|
576
|
+
...sources
|
|
550
577
|
};
|
|
551
578
|
{
|
|
552
579
|
// The `@xstate.` prefix is reserved for built-in serialized action and
|
|
553
|
-
// guard descriptors — user
|
|
554
|
-
for (const kind of ['actions', 'guards', '
|
|
555
|
-
for (const key of Object.keys(this.
|
|
580
|
+
// guard descriptors — user source names must not collide.
|
|
581
|
+
for (const kind of ['actions', 'guards', 'actors', 'delays']) {
|
|
582
|
+
for (const key of Object.keys(this.sources[kind])) {
|
|
556
583
|
if (key.startsWith('@xstate.')) {
|
|
557
584
|
throw new Error(`Invalid ${kind} name '${key}': the '@xstate.' prefix is reserved for built-in descriptors.`);
|
|
558
585
|
}
|
|
@@ -584,38 +611,38 @@ class StateMachine {
|
|
|
584
611
|
}
|
|
585
612
|
|
|
586
613
|
/**
|
|
587
|
-
* Clones this state machine with the provided
|
|
614
|
+
* Clones this state machine with the provided sources.
|
|
588
615
|
*
|
|
589
|
-
* @param
|
|
590
|
-
*
|
|
591
|
-
* @returns A new `StateMachine` instance with the provided
|
|
616
|
+
* @param sources Options (`actions`, `guards`, `actors`, `delays`) to
|
|
617
|
+
* recursively merge with the existing options.
|
|
618
|
+
* @returns A new `StateMachine` instance with the provided sources.
|
|
592
619
|
*/
|
|
593
|
-
provide(
|
|
620
|
+
provide(sources) {
|
|
594
621
|
const {
|
|
595
622
|
actions,
|
|
596
623
|
guards,
|
|
597
|
-
|
|
624
|
+
actors,
|
|
598
625
|
delays
|
|
599
|
-
} = this.
|
|
626
|
+
} = this.sources;
|
|
600
627
|
const provided = new StateMachine(this.config, {
|
|
601
628
|
actions: {
|
|
602
629
|
...actions,
|
|
603
|
-
...
|
|
630
|
+
...sources.actions
|
|
604
631
|
},
|
|
605
632
|
guards: {
|
|
606
633
|
...guards,
|
|
607
|
-
...
|
|
634
|
+
...sources.guards
|
|
608
635
|
},
|
|
609
|
-
|
|
610
|
-
...
|
|
611
|
-
...
|
|
636
|
+
actors: {
|
|
637
|
+
...actors,
|
|
638
|
+
...sources.actors
|
|
612
639
|
},
|
|
613
640
|
delays: {
|
|
614
641
|
...delays,
|
|
615
|
-
...
|
|
642
|
+
...sources.delays
|
|
616
643
|
}
|
|
617
644
|
});
|
|
618
|
-
// Providing
|
|
645
|
+
// Providing sources does not change the serializable definition.
|
|
619
646
|
provided._json = this._json;
|
|
620
647
|
return provided;
|
|
621
648
|
}
|
|
@@ -806,12 +833,12 @@ class StateMachine {
|
|
|
806
833
|
}, this, actorScope.self);
|
|
807
834
|
if (typeof context === 'function') {
|
|
808
835
|
const children = {};
|
|
809
|
-
const spawn = createSpawner(actorScope, this.
|
|
836
|
+
const spawn = createSpawner(actorScope, this.sources.actors, children);
|
|
810
837
|
const resolvedContext = context({
|
|
811
838
|
spawn,
|
|
812
839
|
input: initEvent.input,
|
|
813
840
|
self: actorScope.self,
|
|
814
|
-
|
|
841
|
+
actors: this.sources.actors
|
|
815
842
|
});
|
|
816
843
|
const [nextState] = dist_xstateActors.resolveActionsWithContext(preInitial, initEvent, actorScope, []);
|
|
817
844
|
if (resolvedContext) {
|
|
@@ -914,7 +941,8 @@ class StateMachine {
|
|
|
914
941
|
const src = actorData.src;
|
|
915
942
|
const logic = typeof src === 'string' ? dist_xstateActors.resolveReferencedActor(this, src) : src;
|
|
916
943
|
if (!logic) {
|
|
917
|
-
|
|
944
|
+
const sourceId = typeof src === 'string' ? src : '<unknown>';
|
|
945
|
+
throw new Error(`Unable to restore child actor '${actorId}': child source '${sourceId}' is not provided in machine '${this.id}'.`);
|
|
918
946
|
}
|
|
919
947
|
const actor = resolvedActorScope.system.createActorRef(logic, {
|
|
920
948
|
id: actorId,
|
|
@@ -932,6 +960,14 @@ class StateMachine {
|
|
|
932
960
|
const timers = {};
|
|
933
961
|
const persistedTimers = snapshotData.timers ?? {};
|
|
934
962
|
for (const [id, timer] of Object.entries(persistedTimers)) {
|
|
963
|
+
let event = timer.event;
|
|
964
|
+
if (event.type === 'xstate.timeout.actor') {
|
|
965
|
+
const actorId = event.actorId;
|
|
966
|
+
const child = children[actorId];
|
|
967
|
+
if (child) {
|
|
968
|
+
event = dist_xstateActors.createInvokeTimeoutEvent(actorId, child.sessionId);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
935
971
|
const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
|
|
936
972
|
if (!target) {
|
|
937
973
|
const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
|
|
@@ -939,6 +975,7 @@ class StateMachine {
|
|
|
939
975
|
}
|
|
940
976
|
timers[id] = {
|
|
941
977
|
...timer,
|
|
978
|
+
event,
|
|
942
979
|
target
|
|
943
980
|
};
|
|
944
981
|
}
|