xstate 6.0.0-alpha.2 → 6.0.0-alpha.21
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/README.md +19 -17
- package/bin/xstate.js +36 -0
- package/dist/{StateMachine-64813f46.cjs.js → StateMachine-1b155670.cjs.js} +182 -40
- package/dist/{StateMachine-2dcdb1f5.esm.js → StateMachine-3c17fe3e.esm.js} +182 -40
- package/dist/{StateMachine-8d22a79c.development.cjs.js → StateMachine-550ff7f2.development.cjs.js} +193 -36
- package/dist/{StateMachine-2ea0a7fa.development.esm.js → StateMachine-e25dd61f.development.esm.js} +193 -36
- package/dist/declarations/src/State.d.ts +13 -2
- package/dist/declarations/src/StateMachine.d.ts +23 -13
- package/dist/declarations/src/actions.d.ts +2 -1
- package/dist/declarations/src/actors/promise.d.ts +4 -2
- package/dist/declarations/src/createActor.d.ts +9 -11
- package/dist/declarations/src/createMachine.d.ts +14 -11
- package/dist/declarations/src/createMachineFromConfig.d.ts +61 -28
- package/dist/declarations/src/fsm.d.ts +74 -0
- package/dist/declarations/src/graph/graph.d.ts +3 -3
- package/dist/declarations/src/graph/shortestPaths.d.ts +2 -2
- package/dist/declarations/src/graph/simplePaths.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +6 -5
- package/dist/declarations/src/serialize.d.ts +10 -18
- package/dist/declarations/src/setup.d.ts +277 -65
- package/dist/declarations/src/spawn.d.ts +3 -3
- package/dist/declarations/src/stateUtils.d.ts +4 -1
- package/dist/declarations/src/system.d.ts +1 -1
- package/dist/declarations/src/transition.d.ts +8 -5
- package/dist/declarations/src/transitionActions.d.ts +12 -0
- package/dist/declarations/src/types.d.ts +237 -102
- package/dist/declarations/src/types.v6.d.ts +132 -58
- package/dist/declarations/src/utils.d.ts +4 -3
- package/dist/{index-93edd3bd.esm.js → index-3f87408c.esm.js} +936 -1389
- package/dist/{index-e61170ba.development.esm.js → index-d39fb138.development.esm.js} +968 -1421
- package/dist/{index-9cb3b3a0.cjs.js → index-e694228c.cjs.js} +945 -1394
- package/dist/{index-f6ef20d1.development.cjs.js → index-ec7c7a2d.development.cjs.js} +977 -1426
- 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 +2 -2
- package/dist/xstate-graph.development.cjs.js +2 -2
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +1100 -182
- package/dist/xstate.cjs.mjs +3 -5
- package/dist/xstate.development.cjs.js +1100 -182
- package/dist/xstate.development.cjs.mjs +3 -5
- package/dist/xstate.development.esm.js +1101 -181
- package/dist/xstate.esm.js +1101 -181
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +6 -2
- package/dist/declarations/src/atom.d.ts +0 -81
package/dist/{StateMachine-2ea0a7fa.development.esm.js → StateMachine-e25dd61f.development.esm.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as ProcessingStatus,
|
|
1
|
+
import { P as ProcessingStatus, H as resolveReferencedActor, e as createActor, S as STATE_DELIMITER, I as mapValues, t as toArray, J as createInvokeId, K as getDelayedTransitions, L as evaluateCandidate, M as formatTransition, N as NULL_EVENT, O as toTransitionConfigArray, Q as createInvokeTimeoutEvent, R as getCandidates, U as formatRouteTransitions, V as resolveStateValue, W as getAllStateNodes, l as getStateNodes, Y as createMachineSnapshot, Z as isInFinalState, f as macrostep, d as deriveDeferredStarts, _ as cloneMachineSnapshot, $ as transitionNode, m as matchesEventDescriptor, a0 as getTransitionResult, a1 as hasEffect, a2 as createErrorPlatformEvent, r as resolveActionsWithContext, g as createInitEvent, h as initialMicrostep, a3 as toStatePath, a4 as isStateId, a5 as getStateNodeByPath, a6 as getPersistedSnapshot, a7 as $$ACTOR_TYPE } from './index-d39fb138.development.esm.js';
|
|
2
2
|
|
|
3
3
|
function createSpawner(actorScope, {
|
|
4
4
|
machine,
|
|
@@ -20,7 +20,7 @@ function createSpawner(actorScope, {
|
|
|
20
20
|
self: actorScope.self
|
|
21
21
|
}) : options?.input,
|
|
22
22
|
src,
|
|
23
|
-
|
|
23
|
+
registryKey: options?.registryKey
|
|
24
24
|
});
|
|
25
25
|
spawnedChildren[actor.id] = actor;
|
|
26
26
|
return actor;
|
|
@@ -31,7 +31,7 @@ function createSpawner(actorScope, {
|
|
|
31
31
|
syncSnapshot: options?.syncSnapshot,
|
|
32
32
|
input: options?.input,
|
|
33
33
|
src,
|
|
34
|
-
|
|
34
|
+
registryKey: options?.registryKey
|
|
35
35
|
});
|
|
36
36
|
return actor;
|
|
37
37
|
}
|
|
@@ -171,7 +171,7 @@ class StateNode {
|
|
|
171
171
|
this.invoke = toArray(this.config.invoke).map((invokeConfig, i) => {
|
|
172
172
|
const {
|
|
173
173
|
src,
|
|
174
|
-
|
|
174
|
+
registryKey
|
|
175
175
|
} = invokeConfig;
|
|
176
176
|
const invokeId = createInvokeId(this.id, i);
|
|
177
177
|
const resolvedId = invokeConfig.id ?? invokeId;
|
|
@@ -184,7 +184,7 @@ class StateNode {
|
|
|
184
184
|
src: sourceName,
|
|
185
185
|
logic: src,
|
|
186
186
|
id: resolvedId,
|
|
187
|
-
|
|
187
|
+
registryKey
|
|
188
188
|
};
|
|
189
189
|
});
|
|
190
190
|
}
|
|
@@ -250,11 +250,13 @@ function validateStateNodeConfig(stateNode) {
|
|
|
250
250
|
return;
|
|
251
251
|
}
|
|
252
252
|
if (typeof config.choice !== 'function') {
|
|
253
|
-
throw new Error(`Choice state "${stateNode.id}" must declare a \`choice\` function.`);
|
|
253
|
+
throw new Error(`Choice state "${stateNode.id}" must declare a \`choice\` function.` );
|
|
254
254
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
255
|
+
{
|
|
256
|
+
for (const key of CHOICE_CONFIG_KEYS) {
|
|
257
|
+
if (config[key] !== undefined) {
|
|
258
|
+
throw new Error(`Choice state "${stateNode.id}" cannot declare \`${key}\`.`);
|
|
259
|
+
}
|
|
258
260
|
}
|
|
259
261
|
}
|
|
260
262
|
}
|
|
@@ -262,11 +264,13 @@ function formatChoiceTransitions(stateNode) {
|
|
|
262
264
|
const choice = stateNode.config.choice;
|
|
263
265
|
const validateChoiceResult = result => {
|
|
264
266
|
if (!result || result.target === undefined) {
|
|
265
|
-
throw new Error(`Choice state "${stateNode.id}" must resolve to a target.`);
|
|
267
|
+
throw new Error(`Choice state "${stateNode.id}" must resolve to a target.` );
|
|
266
268
|
}
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
269
|
+
{
|
|
270
|
+
for (const key of ['actions', 'to']) {
|
|
271
|
+
if (result[key] !== undefined) {
|
|
272
|
+
throw new Error(`Choice state "${stateNode.id}" cannot declare \`${key}\` on a choice.`);
|
|
273
|
+
}
|
|
270
274
|
}
|
|
271
275
|
}
|
|
272
276
|
return result;
|
|
@@ -288,7 +292,7 @@ function formatTransitions(stateNode) {
|
|
|
288
292
|
if (stateNode.config.on) {
|
|
289
293
|
for (const descriptor of Object.keys(stateNode.config.on)) {
|
|
290
294
|
if (descriptor === NULL_EVENT) {
|
|
291
|
-
throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');
|
|
295
|
+
throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.' );
|
|
292
296
|
}
|
|
293
297
|
const transitionsConfig = stateNode.config.on[descriptor];
|
|
294
298
|
transitions.set(descriptor, mapTransitionConfigs(transitionsConfig, transition => formatTransition(stateNode, descriptor, transition)));
|
|
@@ -298,6 +302,10 @@ function formatTransitions(stateNode) {
|
|
|
298
302
|
const descriptor = `xstate.done.state.${stateNode.id}`;
|
|
299
303
|
transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => formatTransition(stateNode, descriptor, transition)));
|
|
300
304
|
}
|
|
305
|
+
if (stateNode.config.onError) {
|
|
306
|
+
const descriptor = 'xstate.error.*';
|
|
307
|
+
transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onError, transition => formatTransition(stateNode, descriptor, transition)));
|
|
308
|
+
}
|
|
301
309
|
const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventType) => formatTransition(stateNode, descriptor, {
|
|
302
310
|
to: (_args, enq) => {
|
|
303
311
|
enq.cancel(timeoutEventType);
|
|
@@ -384,7 +392,7 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
384
392
|
const input = typeof _target === 'object' && _target !== null ? _target.input : undefined;
|
|
385
393
|
const resolvedTarget = typeof targetString === 'string' ? stateNode.states[targetString] : undefined;
|
|
386
394
|
if (!resolvedTarget && targetString) {
|
|
387
|
-
throw new Error(`Initial state node "${targetString}" not found on parent state node #${stateNode.id}`);
|
|
395
|
+
throw new Error(`Initial state node "${targetString}" not found on parent state node #${stateNode.id}` );
|
|
388
396
|
}
|
|
389
397
|
const transition = {
|
|
390
398
|
source: stateNode,
|
|
@@ -395,6 +403,45 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
395
403
|
}
|
|
396
404
|
|
|
397
405
|
const STATE_IDENTIFIER = '#';
|
|
406
|
+
let emptyCanActor;
|
|
407
|
+
let emptyCanActorScope;
|
|
408
|
+
function getEmptyCanActor() {
|
|
409
|
+
// A minimal inert actor used purely as the `self`/`parent` argument when
|
|
410
|
+
// dry-running transitions for `snapshot.can(...)`. Intentionally not built
|
|
411
|
+
// on `createLogic` so `can()` does not pull that machinery into bundles.
|
|
412
|
+
return emptyCanActor ??= createActor({
|
|
413
|
+
transition: snapshot => [snapshot, []],
|
|
414
|
+
initialTransition: () => [{
|
|
415
|
+
status: 'active',
|
|
416
|
+
output: undefined,
|
|
417
|
+
error: undefined
|
|
418
|
+
}, []],
|
|
419
|
+
getInitialSnapshot: () => ({
|
|
420
|
+
status: 'active',
|
|
421
|
+
output: undefined,
|
|
422
|
+
error: undefined
|
|
423
|
+
}),
|
|
424
|
+
getPersistedSnapshot: snapshot => snapshot
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
function getEmptyCanActorScope() {
|
|
428
|
+
if (emptyCanActorScope) {
|
|
429
|
+
return emptyCanActorScope;
|
|
430
|
+
}
|
|
431
|
+
const actor = getEmptyCanActor();
|
|
432
|
+
emptyCanActorScope = {
|
|
433
|
+
self: actor,
|
|
434
|
+
logger: () => {},
|
|
435
|
+
id: '',
|
|
436
|
+
sessionId: '',
|
|
437
|
+
defer: () => {},
|
|
438
|
+
system: actor.system,
|
|
439
|
+
stopChild: () => {},
|
|
440
|
+
emit: () => {},
|
|
441
|
+
actionExecutor: () => {}
|
|
442
|
+
};
|
|
443
|
+
return emptyCanActorScope;
|
|
444
|
+
}
|
|
398
445
|
class StateMachine {
|
|
399
446
|
constructor(/** The raw config used to create the machine. */
|
|
400
447
|
config, implementations) {
|
|
@@ -422,7 +469,7 @@ class StateMachine {
|
|
|
422
469
|
this._json = void 0;
|
|
423
470
|
this.id = config.id || '(machine)';
|
|
424
471
|
this.implementations = {
|
|
425
|
-
|
|
472
|
+
actorSources: config.actorSources ?? {},
|
|
426
473
|
actions: config.actions ?? {},
|
|
427
474
|
delays: config.delays ?? {},
|
|
428
475
|
guards: config.guards ?? {},
|
|
@@ -431,7 +478,7 @@ class StateMachine {
|
|
|
431
478
|
{
|
|
432
479
|
// The `@xstate.` prefix is reserved for built-in serialized action and
|
|
433
480
|
// guard descriptors — user implementation names must not collide.
|
|
434
|
-
for (const kind of ['actions', 'guards', '
|
|
481
|
+
for (const kind of ['actions', 'guards', 'actorSources', 'delays']) {
|
|
435
482
|
for (const key of Object.keys(this.implementations[kind])) {
|
|
436
483
|
if (key.startsWith('@xstate.')) {
|
|
437
484
|
throw new Error(`Invalid ${kind} name '${key}': the '@xstate.' prefix is reserved for built-in descriptors.`);
|
|
@@ -447,6 +494,7 @@ class StateMachine {
|
|
|
447
494
|
...this.config.options
|
|
448
495
|
};
|
|
449
496
|
this.transition = this.transition.bind(this);
|
|
497
|
+
this.initialTransition = this.initialTransition.bind(this);
|
|
450
498
|
this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
|
|
451
499
|
this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
|
|
452
500
|
this.restoreSnapshot = this.restoreSnapshot.bind(this);
|
|
@@ -460,23 +508,20 @@ class StateMachine {
|
|
|
460
508
|
this.root._refreshEventMetadata();
|
|
461
509
|
this.states = this.root.states; // TODO: remove!
|
|
462
510
|
this.events = this.root.events;
|
|
463
|
-
if (!('output' in this.root) && Object.values(this.states).some(state => state.type === 'final' && 'output' in state)) {
|
|
464
|
-
console.warn('Missing `machine.output` declaration (top-level final state with output detected)');
|
|
465
|
-
}
|
|
466
511
|
}
|
|
467
512
|
|
|
468
513
|
/**
|
|
469
514
|
* Clones this state machine with the provided implementations.
|
|
470
515
|
*
|
|
471
|
-
* @param implementations Options (`actions`, `guards`, `
|
|
472
|
-
* recursively merge with the existing options.
|
|
516
|
+
* @param implementations Options (`actions`, `guards`, `actorSources`,
|
|
517
|
+
* `delays`) to recursively merge with the existing options.
|
|
473
518
|
* @returns A new `StateMachine` instance with the provided implementations.
|
|
474
519
|
*/
|
|
475
520
|
provide(implementations) {
|
|
476
521
|
const {
|
|
477
522
|
actions,
|
|
478
523
|
guards,
|
|
479
|
-
|
|
524
|
+
actorSources,
|
|
480
525
|
delays
|
|
481
526
|
} = this.implementations;
|
|
482
527
|
const provided = new StateMachine(this.config, {
|
|
@@ -488,9 +533,9 @@ class StateMachine {
|
|
|
488
533
|
...guards,
|
|
489
534
|
...implementations.guards
|
|
490
535
|
},
|
|
491
|
-
|
|
492
|
-
...
|
|
493
|
-
...implementations.
|
|
536
|
+
actorSources: {
|
|
537
|
+
...actorSources,
|
|
538
|
+
...implementations.actorSources
|
|
494
539
|
},
|
|
495
540
|
delays: {
|
|
496
541
|
...delays,
|
|
@@ -525,7 +570,56 @@ class StateMachine {
|
|
|
525
570
|
* @param event The received event
|
|
526
571
|
*/
|
|
527
572
|
transition(snapshot, event, actorScope) {
|
|
528
|
-
|
|
573
|
+
const fastSnapshot = this._transitionFast(snapshot, event, actorScope);
|
|
574
|
+
if (fastSnapshot) {
|
|
575
|
+
return [fastSnapshot, []];
|
|
576
|
+
}
|
|
577
|
+
const {
|
|
578
|
+
snapshot: nextSnapshot,
|
|
579
|
+
microsteps
|
|
580
|
+
} = macrostep(snapshot, event, actorScope, []);
|
|
581
|
+
return [nextSnapshot, this._collectEffects(microsteps)];
|
|
582
|
+
}
|
|
583
|
+
_collectEffects(microsteps, initialActions = []) {
|
|
584
|
+
const effects = [...initialActions, ...microsteps.flatMap(([, actions]) => actions)];
|
|
585
|
+
return [...effects, ...deriveDeferredStarts(effects)];
|
|
586
|
+
}
|
|
587
|
+
_transitionFast(snapshot, event, actorScope) {
|
|
588
|
+
if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
|
|
589
|
+
return undefined;
|
|
590
|
+
}
|
|
591
|
+
const sourceNode = this.root.states[snapshot.value];
|
|
592
|
+
if (!sourceNode || sourceNode.type !== 'atomic' || sourceNode.exit || sourceNode.invoke.length || sourceNode.always?.length || sourceNode.after?.length) {
|
|
593
|
+
return undefined;
|
|
594
|
+
}
|
|
595
|
+
const transitions = sourceNode.transitions.get(event.type);
|
|
596
|
+
if (transitions?.length !== 1) {
|
|
597
|
+
return undefined;
|
|
598
|
+
}
|
|
599
|
+
const selected = transitions[0];
|
|
600
|
+
if (selected.guard || selected.actions || selected.to || selected.reenter || selected.input || typeof selected.context === 'function' || selected.target && selected.target.length !== 1) {
|
|
601
|
+
return undefined;
|
|
602
|
+
}
|
|
603
|
+
const targetNode = selected.target?.[0] ?? sourceNode;
|
|
604
|
+
const stateChanged = targetNode !== sourceNode;
|
|
605
|
+
if (targetNode.parent !== this.root || targetNode.type !== 'atomic' || stateChanged && (targetNode.entry || targetNode.invoke.length || targetNode.always?.length || targetNode.after?.length)) {
|
|
606
|
+
return undefined;
|
|
607
|
+
}
|
|
608
|
+
const context = selected.context !== undefined ? {
|
|
609
|
+
...snapshot.context,
|
|
610
|
+
...selected.context
|
|
611
|
+
} : snapshot.context;
|
|
612
|
+
const collectedMicrosteps = actorScope.self._collectedMicrosteps || [];
|
|
613
|
+
collectedMicrosteps.push(selected);
|
|
614
|
+
actorScope.self._collectedMicrosteps = collectedMicrosteps;
|
|
615
|
+
return cloneMachineSnapshot(snapshot, {
|
|
616
|
+
...(context !== snapshot.context ? {
|
|
617
|
+
context
|
|
618
|
+
} : {}),
|
|
619
|
+
...(stateChanged ? {
|
|
620
|
+
_nodes: [this.root, targetNode]
|
|
621
|
+
} : {})
|
|
622
|
+
});
|
|
529
623
|
}
|
|
530
624
|
|
|
531
625
|
/**
|
|
@@ -557,6 +651,49 @@ class StateMachine {
|
|
|
557
651
|
return false;
|
|
558
652
|
}
|
|
559
653
|
|
|
654
|
+
/**
|
|
655
|
+
* Determines whether sending the `event` to the given snapshot would select a
|
|
656
|
+
* non-forbidden transition. Backs `snapshot.can(...)`; lives here so that
|
|
657
|
+
* non-machine bundles don't pay for the transition-resolution machinery.
|
|
658
|
+
*
|
|
659
|
+
* @internal
|
|
660
|
+
*/
|
|
661
|
+
_canTransition(snapshot, event) {
|
|
662
|
+
const emptyActor = getEmptyCanActor();
|
|
663
|
+
const emptyActorScope = getEmptyCanActorScope();
|
|
664
|
+
const transitionData = this.getTransitionData(snapshot, event, emptyActor);
|
|
665
|
+
if (!transitionData?.length) {
|
|
666
|
+
return false;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
// Check that at least one transition is not forbidden
|
|
670
|
+
for (const transition of transitionData) {
|
|
671
|
+
if (transition.target !== undefined) {
|
|
672
|
+
return true;
|
|
673
|
+
}
|
|
674
|
+
const res = getTransitionResult(transition, snapshot, event, emptyActorScope, {
|
|
675
|
+
resolveActions: false
|
|
676
|
+
});
|
|
677
|
+
if (res.targets?.length || res.context || hasEffect(transition, snapshot.context, event, snapshot, emptyActor)) {
|
|
678
|
+
return true;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
return false;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* Returns the error event that the actor should transition with to recover
|
|
686
|
+
* from an execution error, if any active state node declares `onError`.
|
|
687
|
+
*
|
|
688
|
+
* @internal
|
|
689
|
+
*/
|
|
690
|
+
getExecutionErrorEvent(snapshot, error) {
|
|
691
|
+
if (snapshot?.status !== 'active' || !snapshot._nodes?.some(stateNode => stateNode.config.onError)) {
|
|
692
|
+
return undefined;
|
|
693
|
+
}
|
|
694
|
+
return createErrorPlatformEvent('execution', error);
|
|
695
|
+
}
|
|
696
|
+
|
|
560
697
|
/**
|
|
561
698
|
* The initial state _before_ evaluating any microsteps. This "pre-initial"
|
|
562
699
|
* state is provided to initial actions executed in the initial state.
|
|
@@ -580,9 +717,9 @@ class StateMachine {
|
|
|
580
717
|
spawn,
|
|
581
718
|
input: initEvent.input,
|
|
582
719
|
self: actorScope.self,
|
|
583
|
-
|
|
720
|
+
actorSources: this.implementations.actorSources
|
|
584
721
|
});
|
|
585
|
-
const nextState =
|
|
722
|
+
const [nextState] = resolveActionsWithContext(preInitial, initEvent, actorScope, []);
|
|
586
723
|
if (resolvedContext) {
|
|
587
724
|
nextState.context = resolvedContext;
|
|
588
725
|
}
|
|
@@ -602,14 +739,33 @@ class StateMachine {
|
|
|
602
739
|
* `ActorRef`.
|
|
603
740
|
*/
|
|
604
741
|
getInitialSnapshot(actorScope, input) {
|
|
742
|
+
return this.initialTransition(input, actorScope)[0];
|
|
743
|
+
}
|
|
744
|
+
initialTransition(input, actorScope) {
|
|
605
745
|
const initEvent = createInitEvent(input); // TODO: fix;
|
|
606
746
|
const internalQueue = [];
|
|
607
747
|
const preInitialState = this._getPreInitialState(actorScope, initEvent);
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
748
|
+
let nextState;
|
|
749
|
+
let initialActions = [];
|
|
750
|
+
let microsteps = [];
|
|
751
|
+
let macroState;
|
|
752
|
+
try {
|
|
753
|
+
[nextState, initialActions] = initialMicrostep(this.root, preInitialState, actorScope, initEvent, internalQueue);
|
|
754
|
+
({
|
|
755
|
+
snapshot: macroState,
|
|
756
|
+
microsteps
|
|
757
|
+
} = macrostep(nextState, initEvent, actorScope, internalQueue));
|
|
758
|
+
} catch (err) {
|
|
759
|
+
if (!this.root.config.onError) {
|
|
760
|
+
throw err;
|
|
761
|
+
}
|
|
762
|
+
const errorEvent = createErrorPlatformEvent('execution', err);
|
|
763
|
+
const errorMacrostep = macrostep(preInitialState, errorEvent, actorScope, []);
|
|
764
|
+
macroState = errorMacrostep.snapshot;
|
|
765
|
+
microsteps = errorMacrostep.microsteps;
|
|
766
|
+
initialActions = [];
|
|
767
|
+
}
|
|
768
|
+
return [macroState, this._collectEffects(microsteps, initialActions)];
|
|
613
769
|
}
|
|
614
770
|
start(snapshot) {
|
|
615
771
|
// Start rehydrated children that were active when persisted. Freshly
|
|
@@ -663,7 +819,7 @@ class StateMachine {
|
|
|
663
819
|
syncSnapshot: actorData.syncSnapshot,
|
|
664
820
|
snapshot: childState,
|
|
665
821
|
src,
|
|
666
|
-
|
|
822
|
+
registryKey: actorData.registryKey
|
|
667
823
|
});
|
|
668
824
|
// Mark so `start()` knows to start this child (freshly invoked/spawned
|
|
669
825
|
// children are started via deferred `@xstate.start` actions instead).
|
|
@@ -710,7 +866,8 @@ class StateMachine {
|
|
|
710
866
|
children,
|
|
711
867
|
_nodes: nodes,
|
|
712
868
|
value: snapshotData.value,
|
|
713
|
-
historyValue: revivedHistoryValue
|
|
869
|
+
historyValue: revivedHistoryValue,
|
|
870
|
+
_stateInputs: snapshotData.stateInputs ?? {}
|
|
714
871
|
}, this);
|
|
715
872
|
const seen = new WeakSet();
|
|
716
873
|
function reviveContext(contextPart) {
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import type { AnyMachineSnapshot, AnyStateMachine, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode } from "./types.js";
|
|
1
|
+
import type { AnyMachineSnapshot, AnyStateMachine, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, StateValueMap, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode } from "./types.js";
|
|
2
2
|
export declare function isMachineSnapshot(value: unknown): value is AnyMachineSnapshot;
|
|
3
|
+
type Values<T> = T[keyof T];
|
|
4
|
+
type MatchingObjectStateValue<TStateValue extends Record<string, unknown>, TTestStateValue extends Record<string, unknown>> = false extends Values<{
|
|
5
|
+
[K in keyof TTestStateValue]: K extends keyof TStateValue ? NonNullable<TStateValue[K]> extends StateValue ? NonNullable<TTestStateValue[K]> extends StateValue ? [
|
|
6
|
+
MatchingStateValue<NonNullable<TStateValue[K]>, NonNullable<TTestStateValue[K]>>
|
|
7
|
+
] extends [never] ? false : true : false : false : false;
|
|
8
|
+
}> ? never : {
|
|
9
|
+
[K in keyof TStateValue]: K extends keyof TTestStateValue ? MatchingStateValue<NonNullable<TStateValue[K]>, NonNullable<TTestStateValue[K]>> : TStateValue[K];
|
|
10
|
+
};
|
|
11
|
+
type MatchingStateValue<TStateValue extends StateValue, TTestStateValue extends StateValue> = StateValue extends TTestStateValue ? TStateValue : string extends TTestStateValue ? TStateValue : TStateValue extends unknown ? TTestStateValue extends string ? TStateValue extends string ? TTestStateValue extends TStateValue ? TTestStateValue : Extract<TStateValue, TTestStateValue> : TStateValue extends Record<string, unknown> ? TStateValue & Record<TTestStateValue, StateValue | undefined> : never : TTestStateValue extends Record<string, unknown> ? TStateValue extends Record<string, unknown> ? MatchingObjectStateValue<TStateValue, TTestStateValue> : never : never : never;
|
|
3
12
|
interface MachineSnapshotBase<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, _TOutput, TMeta extends MetaObject, TStateSchema extends StateSchema = StateSchema> {
|
|
4
13
|
/** The state machine that produced this state snapshot. */
|
|
5
14
|
machine: AnyStateMachine;
|
|
@@ -42,7 +51,9 @@ interface MachineSnapshotBase<TContext extends MachineContext, TEvent extends Ev
|
|
|
42
51
|
*
|
|
43
52
|
* @param partialStateValue
|
|
44
53
|
*/
|
|
45
|
-
matches<const TTestStateValue extends
|
|
54
|
+
matches<const TTestStateValue extends string>(partialStateValue: TTestStateValue, ...args: string extends TTestStateValue ? [never] : []): this is MachineSnapshot<StateContextFromStateValue<TStateSchema, TContext, TTestStateValue>, TEvent, TChildren, MatchingStateValue<TStateValue, TTestStateValue>, TTag, _TOutput, TMeta, TStateSchema>;
|
|
55
|
+
matches<const TTestStateValue extends StateValueMap>(partialStateValue: TTestStateValue, ...args: string extends keyof TTestStateValue ? [never] : []): this is MachineSnapshot<StateContextFromStateValue<TStateSchema, TContext, TTestStateValue>, TEvent, TChildren, MatchingStateValue<TStateValue, TTestStateValue>, TTag, _TOutput, TMeta, TStateSchema>;
|
|
56
|
+
matches(partialStateValue: StateValue): boolean;
|
|
46
57
|
/**
|
|
47
58
|
* Whether the current state nodes has a state node with the specified `tag`.
|
|
48
59
|
*
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { MachineSnapshot } from "./State.js";
|
|
2
2
|
import { StateNode } from "./StateNode.js";
|
|
3
3
|
import { AnyActorSystem } from "./system.js";
|
|
4
|
-
import type { ActorLogic, ActorScope, AnyActor, AnyActorRef, AnyActorScope, AnyTransitionDefinition, Equals, EventDescriptor, EventObject, HistoryValue, MachineContext, MetaObject, Snapshot, StateValue, StateSchema, SnapshotStatus } from "./types.js";
|
|
5
|
-
import { Implementations, Next_MachineConfig, MachineOptions } from "./types.v6.js";
|
|
6
|
-
|
|
4
|
+
import type { ActorLogic, ActorLogicTransitionResult, ActorScope, AnyActor, AnyActorLogic, AnyActorRef, AnyActorScope, AnyTransitionDefinition, Equals, EventDescriptor, EmittedFrom, EventObject, EventFromLogic, ExecutableActionObjectFromLogic, HistoryValue, InputFrom, IsAny, MachineContext, MetaObject, OutputFrom, Snapshot, SnapshotFrom, StateValue, StateSchema, SnapshotStatus } from "./types.js";
|
|
5
|
+
import { AnyMachineSchemas, Implementations, Next_MachineConfig, MachineOptions } from "./types.v6.js";
|
|
6
|
+
type CompatibleProvidedActorSource<TExpected extends AnyActorLogic, TActual extends AnyActorLogic> = IsAny<TActual> extends true ? TActual : [OutputFrom<TActual>] extends [OutputFrom<TExpected>] ? [Omit<SnapshotFrom<TActual>, 'input'>] extends [
|
|
7
|
+
Omit<SnapshotFrom<TExpected>, 'input'>
|
|
8
|
+
] ? [InputFrom<TExpected>] extends [InputFrom<TActual>] ? [EventFromLogic<TExpected>] extends [EventFromLogic<TActual>] ? [EmittedFrom<TActual>] extends [EmittedFrom<TExpected>] ? TActual : never : never : never : never : never;
|
|
9
|
+
type ProvidedActorSources<TExpectedActorMap extends Implementations['actorSources'], TProvidedActorMap extends Partial<Record<keyof TExpectedActorMap & string, AnyActorLogic>>> = {
|
|
10
|
+
[K in keyof TProvidedActorMap]: K extends keyof TExpectedActorMap ? TProvidedActorMap[K] extends AnyActorLogic ? CompatibleProvidedActorSource<TExpectedActorMap[K], TProvidedActorMap[K]> : never : never;
|
|
11
|
+
};
|
|
12
|
+
export declare class StateMachine<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TInput, TOutput, TEmitted extends EventObject, TMeta extends MetaObject, TConfig extends StateSchema, TActionMap extends Implementations['actions'], TActorMap extends Implementations['actorSources'], TGuardMap extends Implementations['guards'], TDelayMap extends Implementations['delays']> implements ActorLogic<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, TInput, AnyActorSystem, TEmitted> {
|
|
7
13
|
/** The raw config used to create the machine. */
|
|
8
|
-
config: Next_MachineConfig<any, any, any, any, any, any, any, any, any, any> & {
|
|
9
|
-
schemas?:
|
|
14
|
+
config: Next_MachineConfig<any, any, any, any, any, any, any, any, any, any, any> & {
|
|
15
|
+
schemas?: AnyMachineSchemas;
|
|
10
16
|
internalEvents?: readonly string[];
|
|
11
17
|
};
|
|
12
18
|
/** The machine's own version. */
|
|
13
19
|
version?: string;
|
|
14
|
-
schemas:
|
|
20
|
+
schemas: AnyMachineSchemas | undefined;
|
|
15
21
|
implementations: Implementations;
|
|
16
22
|
/** Runtime options for machine execution. */
|
|
17
23
|
options: MachineOptions;
|
|
@@ -22,20 +28,20 @@ export declare class StateMachine<TContext extends MachineContext, TEvent extend
|
|
|
22
28
|
internalEventDescriptors: ReadonlyArray<string>;
|
|
23
29
|
constructor(
|
|
24
30
|
/** The raw config used to create the machine. */
|
|
25
|
-
config: Next_MachineConfig<any, any, any, any, any, any, any, any, any, any> & {
|
|
26
|
-
schemas?:
|
|
31
|
+
config: Next_MachineConfig<any, any, any, any, any, any, any, any, any, any, any> & {
|
|
32
|
+
schemas?: AnyMachineSchemas;
|
|
27
33
|
internalEvents?: readonly string[];
|
|
28
34
|
}, implementations?: Implementations);
|
|
29
35
|
/**
|
|
30
36
|
* Clones this state machine with the provided implementations.
|
|
31
37
|
*
|
|
32
|
-
* @param implementations Options (`actions`, `guards`, `
|
|
33
|
-
* recursively merge with the existing options.
|
|
38
|
+
* @param implementations Options (`actions`, `guards`, `actorSources`,
|
|
39
|
+
* `delays`) to recursively merge with the existing options.
|
|
34
40
|
* @returns A new `StateMachine` instance with the provided implementations.
|
|
35
41
|
*/
|
|
36
|
-
provide(implementations: {
|
|
42
|
+
provide<const TProvidedActorMap extends Partial<Record<keyof TActorMap & string, AnyActorLogic>> = {}>(implementations: {
|
|
37
43
|
actions?: Partial<TActionMap>;
|
|
38
|
-
|
|
44
|
+
actorSources?: TProvidedActorMap & ProvidedActorSources<TActorMap, TProvidedActorMap>;
|
|
39
45
|
guards?: Partial<TGuardMap>;
|
|
40
46
|
delays?: Partial<TDelayMap>;
|
|
41
47
|
}): StateMachine<TContext, TEvent, TChildren, TStateValue, TTag, TInput, TOutput, TEmitted, TMeta, TConfig, TActionMap, TActorMap, TGuardMap, TDelayMap>;
|
|
@@ -56,7 +62,9 @@ export declare class StateMachine<TContext extends MachineContext, TEvent extend
|
|
|
56
62
|
* @param snapshot The current snapshot
|
|
57
63
|
* @param event The received event
|
|
58
64
|
*/
|
|
59
|
-
transition(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, event: TEvent, actorScope: ActorScope<typeof snapshot, TEvent, AnyActorSystem, TEmitted>): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig
|
|
65
|
+
transition(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, event: TEvent, actorScope: ActorScope<typeof snapshot, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
|
|
66
|
+
private _collectEffects;
|
|
67
|
+
private _transitionFast;
|
|
60
68
|
/**
|
|
61
69
|
* Determines the next state given the current `state` and `event`. Calculates
|
|
62
70
|
* a microstep.
|
|
@@ -72,8 +80,10 @@ export declare class StateMachine<TContext extends MachineContext, TEvent extend
|
|
|
72
80
|
* `ActorRef`.
|
|
73
81
|
*/
|
|
74
82
|
getInitialSnapshot(actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>, input?: TInput): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
|
|
83
|
+
initialTransition(input: TInput | undefined, actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
|
|
75
84
|
start(snapshot?: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>): void;
|
|
76
85
|
getStateNodeById(stateId: string): StateNode<TContext, TEvent>;
|
|
77
86
|
getPersistedSnapshot(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, options?: unknown): Snapshot<unknown>;
|
|
78
87
|
restoreSnapshot(snapshot: Snapshot<unknown>, _actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
|
|
79
88
|
}
|
|
89
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AnyActor, AnyActorScope, EventObject } from "./types.js";
|
|
2
2
|
export declare const builtInActions: {
|
|
3
|
+
"@xstate.spawn": (_actor: AnyActor) => void;
|
|
3
4
|
"@xstate.start": (actor: AnyActor) => void;
|
|
4
5
|
"@xstate.raise": (actorScope: AnyActorScope, event: EventObject, options: {
|
|
5
6
|
id?: string;
|
|
@@ -10,5 +11,5 @@ export declare const builtInActions: {
|
|
|
10
11
|
delay?: number;
|
|
11
12
|
}) => void;
|
|
12
13
|
"@xstate.cancel": (actorScope: AnyActorScope, sendId: string) => void;
|
|
13
|
-
"@xstate.
|
|
14
|
+
"@xstate.stop": (actorScope: AnyActorScope, actor: AnyActor) => void;
|
|
14
15
|
};
|
|
@@ -41,6 +41,7 @@ export interface LogicEnqueue<TEmitted extends EventObject> {
|
|
|
41
41
|
step: <TStepOutput>(key: string, exec: () => TStepOutput | PromiseLike<TStepOutput>) => Promise<TStepOutput>;
|
|
42
42
|
}
|
|
43
43
|
export type LogicFunction<TOutput, TInput = NonReducibleUnknown, TEmitted extends EventObject = EventObject> = (args: LogicArgs<TOutput, TInput>, enq: LogicEnqueue<TEmitted>) => PromiseLike<TOutput>;
|
|
44
|
+
type AsyncLogicFunctionOutput<TLogicFunction extends (...args: any[]) => PromiseLike<any>> = Awaited<ReturnType<TLogicFunction>>;
|
|
44
45
|
export interface LogicConfig<TOutput, TInput = NonReducibleUnknown, TEmitted extends EventObject = EventObject, TInputSchema extends StandardSchemaV1 = StandardSchemaV1, TOutputSchema extends StandardSchemaV1 = StandardSchemaV1> {
|
|
45
46
|
/**
|
|
46
47
|
* Stable identifier for this async logic. This identifies the logic, not a
|
|
@@ -165,12 +166,13 @@ export declare function createAsyncLogic<const TInputSchema extends StandardSche
|
|
|
165
166
|
}): AsyncActorLogic<StandardSchemaV1.InferOutput<TOutputSchema>, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted> & {
|
|
166
167
|
id?: string;
|
|
167
168
|
};
|
|
168
|
-
export declare function createAsyncLogic<
|
|
169
|
+
export declare function createAsyncLogic<const TInputSchema extends StandardSchemaV1, TEmitted extends EventObject = EventObject, TLogicFunction extends LogicFunction<any, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted> = LogicFunction<any, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted>>(asyncLogic: Omit<LogicConfig<never, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted, TInputSchema>, 'run' | 'schemas'> & {
|
|
169
170
|
schemas: {
|
|
170
171
|
input: TInputSchema;
|
|
171
172
|
output?: never;
|
|
172
173
|
};
|
|
173
|
-
|
|
174
|
+
run: TLogicFunction;
|
|
175
|
+
}): AsyncActorLogic<AsyncLogicFunctionOutput<TLogicFunction>, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted> & {
|
|
174
176
|
id?: string;
|
|
175
177
|
};
|
|
176
178
|
export declare function createAsyncLogic<const TOutputSchema extends StandardSchemaV1, TInput = NonReducibleUnknown, TEmitted extends EventObject = EventObject>(asyncLogic: LogicConfig<StandardSchemaV1.InferOutput<TOutputSchema>, TInput, TEmitted, StandardSchemaV1, TOutputSchema> & {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { symbolObservable } from "./symbolObservable.js";
|
|
2
2
|
import { AnyActorSystem, Clock } from "./system.js";
|
|
3
|
-
import type { AnyActor, AnyActorLogic, EmittedFrom, EventFromLogic, SendableEventFromLogic, InputFrom, Snapshot, SnapshotFrom, Readable } from "./types.js";
|
|
3
|
+
import type { ActorTrigger, AnyActor, AnyActorLogic, EmittedFrom, EventFromLogic, SendableEventFromLogic, InputFrom, Snapshot, SnapshotFrom, Readable } from "./types.js";
|
|
4
4
|
import { ActorOptions, ActorInstance, ActorRef, InteropSubscribable, Observer, Subscription } from "./types.js";
|
|
5
5
|
export declare const $$ACTOR_TYPE = 1;
|
|
6
6
|
export declare enum ProcessingStatus {
|
|
@@ -35,21 +35,17 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorInstanc
|
|
|
35
35
|
private observers;
|
|
36
36
|
private eventListeners;
|
|
37
37
|
private logger;
|
|
38
|
+
private _forceDeferredActions;
|
|
38
39
|
_parent?: AnyActor;
|
|
39
40
|
ref: ActorRef<SnapshotFrom<TLogic>, EventFromLogic<TLogic>, EmittedFrom<TLogic>, SendableEventFromLogic<TLogic>>;
|
|
40
41
|
private _actorScope;
|
|
41
|
-
|
|
42
|
+
private _initialEffects;
|
|
43
|
+
registryKey: string | undefined;
|
|
42
44
|
/** The globally unique process ID for this invocation. */
|
|
43
45
|
sessionId: string;
|
|
44
46
|
/** The system to which this actor belongs. */
|
|
45
47
|
system: AnyActorSystem;
|
|
46
|
-
trigger:
|
|
47
|
-
[K in SendableEventFromLogic<TLogic>['type']]: {} extends Omit<Extract<SendableEventFromLogic<TLogic>, {
|
|
48
|
-
type: K;
|
|
49
|
-
}>, 'type'> ? () => void : (payload: Omit<Extract<SendableEventFromLogic<TLogic>, {
|
|
50
|
-
type: K;
|
|
51
|
-
}>, 'type'>) => void;
|
|
52
|
-
};
|
|
48
|
+
trigger: ActorTrigger<SendableEventFromLogic<TLogic>>;
|
|
53
49
|
src: string | AnyActorLogic;
|
|
54
50
|
/**
|
|
55
51
|
* Creates a new actor instance for the given logic with the provided options,
|
|
@@ -62,8 +58,12 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorInstanc
|
|
|
62
58
|
private _deferred;
|
|
63
59
|
private _pendingEffects?;
|
|
64
60
|
private _setErrorSnapshot;
|
|
61
|
+
/** Recover via the logic's error event if possible; otherwise error out. */
|
|
62
|
+
private _recoverOrError;
|
|
63
|
+
private _tryHandleExecutionError;
|
|
65
64
|
private _next;
|
|
66
65
|
private update;
|
|
66
|
+
private _flushInitialEffects;
|
|
67
67
|
/**
|
|
68
68
|
* Subscribe an observer to an actor’s snapshot values.
|
|
69
69
|
*
|
|
@@ -177,8 +177,6 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorInstanc
|
|
|
177
177
|
* @see {@link Actor.getPersistedSnapshot} to persist the internal state of an actor (which is more than just a snapshot).
|
|
178
178
|
*/
|
|
179
179
|
getSnapshot(): SnapshotFrom<TLogic>;
|
|
180
|
-
/** Read the actor's current snapshot as an atom value. */
|
|
181
|
-
get(): SnapshotFrom<TLogic>;
|
|
182
180
|
}
|
|
183
181
|
export type RequiredActorOptionsKeys<TLogic extends AnyActorLogic> = undefined extends InputFrom<TLogic> ? never : 'input';
|
|
184
182
|
/**
|