xstate 5.0.0-beta.48 → 5.0.0-beta.50
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 +2 -2
- package/actions/dist/xstate-actions.development.cjs.js +2 -2
- package/actions/dist/xstate-actions.development.esm.js +2 -2
- package/actions/dist/xstate-actions.esm.js +2 -2
- 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 +53 -74
- package/actors/dist/xstate-actors.development.cjs.js +53 -74
- package/actors/dist/xstate-actors.development.esm.js +53 -74
- package/actors/dist/xstate-actors.esm.js +53 -74
- 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 +20 -17
- package/dist/declarations/src/StateMachine.d.ts +13 -14
- package/dist/declarations/src/actors/callback.d.ts +6 -9
- package/dist/declarations/src/actors/index.d.ts +3 -3
- package/dist/declarations/src/actors/observable.d.ts +5 -5
- package/dist/declarations/src/actors/promise.d.ts +6 -6
- package/dist/declarations/src/actors/transition.d.ts +3 -3
- package/dist/declarations/src/createMachine.d.ts +17 -2
- package/dist/declarations/src/interpreter.d.ts +2 -2
- package/dist/declarations/src/setup.d.ts +19 -3
- package/dist/declarations/src/stateUtils.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +19 -13
- package/dist/declarations/src/utils.d.ts +0 -1
- package/dist/{raise-84fd7a92.esm.js → raise-32ec7226.esm.js} +94 -33
- package/dist/{raise-286581d5.development.esm.js → raise-6c05c91b.development.esm.js} +94 -33
- package/dist/{raise-cd0dde81.cjs.js → raise-8176cd35.cjs.js} +93 -33
- package/dist/{raise-0eafc1df.development.cjs.js → raise-dc9c2c58.development.cjs.js} +93 -33
- package/dist/{send-f0a3179c.development.esm.js → send-2b001f05.development.esm.js} +2 -7
- package/dist/{send-355ba004.cjs.js → send-7f3db830.cjs.js} +2 -7
- package/dist/{send-ae491737.esm.js → send-88351a33.esm.js} +2 -7
- package/dist/{send-32a63473.development.cjs.js → send-df1c8ef2.development.cjs.js} +2 -7
- package/dist/xstate.cjs.js +11 -20
- package/dist/xstate.development.cjs.js +11 -20
- package/dist/xstate.development.esm.js +13 -22
- package/dist/xstate.esm.js +13 -22
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.cjs.js +1 -1
- package/guards/dist/xstate-guards.development.esm.js +1 -1
- package/guards/dist/xstate-guards.esm.js +1 -1
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -248,9 +248,6 @@ function mapValues(collection, iteratee) {
|
|
|
248
248
|
}
|
|
249
249
|
return result;
|
|
250
250
|
}
|
|
251
|
-
function flatten(array) {
|
|
252
|
-
return [].concat(...array);
|
|
253
|
-
}
|
|
254
251
|
function toArrayStrict(value) {
|
|
255
252
|
if (isArray(value)) {
|
|
256
253
|
return value;
|
|
@@ -320,7 +317,7 @@ function resolveReferencedActor(machine, src) {
|
|
|
320
317
|
return machine.implementations.actors[src];
|
|
321
318
|
}
|
|
322
319
|
function getAllOwnEventDescriptors(snapshot) {
|
|
323
|
-
return [...new Set(
|
|
320
|
+
return [...new Set([...snapshot._nodes.flatMap(sn => sn.ownEvents)])];
|
|
324
321
|
}
|
|
325
322
|
|
|
326
323
|
const $$ACTOR_TYPE = 1;
|
|
@@ -455,7 +452,18 @@ class Actor {
|
|
|
455
452
|
}
|
|
456
453
|
}
|
|
457
454
|
_initState(persistedState) {
|
|
458
|
-
|
|
455
|
+
try {
|
|
456
|
+
this._state = persistedState ? this.logic.restoreState ? this.logic.restoreState(persistedState, this._actorScope) : persistedState : this.logic.getInitialState(this._actorScope, this.options?.input);
|
|
457
|
+
} catch (err) {
|
|
458
|
+
// if we get here then it means that we assign a value to this._state that is not of the correct type
|
|
459
|
+
// we can't get the true `TSnapshot & { status: 'error'; }`, it's impossible
|
|
460
|
+
// so right now this is a lie of sorts
|
|
461
|
+
this._state = {
|
|
462
|
+
status: 'error',
|
|
463
|
+
output: undefined,
|
|
464
|
+
error: err
|
|
465
|
+
};
|
|
466
|
+
}
|
|
459
467
|
}
|
|
460
468
|
update(snapshot, event) {
|
|
461
469
|
// Update state
|
|
@@ -464,17 +472,46 @@ class Actor {
|
|
|
464
472
|
// Execute deferred effects
|
|
465
473
|
let deferredFn;
|
|
466
474
|
while (deferredFn = this._deferred.shift()) {
|
|
467
|
-
deferredFn();
|
|
468
|
-
}
|
|
469
|
-
for (const observer of this.observers) {
|
|
470
475
|
try {
|
|
471
|
-
|
|
476
|
+
deferredFn();
|
|
472
477
|
} catch (err) {
|
|
473
|
-
|
|
478
|
+
// this error can only be caught when executing *initial* actions
|
|
479
|
+
// it's the only time when we call actions provided by the user through those deferreds
|
|
480
|
+
// when the actor is already running we always execute them synchronously while transitioning
|
|
481
|
+
// no "builtin deferred" should actually throw an error since they are either safe
|
|
482
|
+
// or the control flow is passed through the mailbox and errors should be caught by the `_process` used by the mailbox
|
|
483
|
+
this._deferred.length = 0;
|
|
484
|
+
this._state = {
|
|
485
|
+
...snapshot,
|
|
486
|
+
status: 'error',
|
|
487
|
+
error: err
|
|
488
|
+
};
|
|
474
489
|
}
|
|
475
490
|
}
|
|
476
491
|
switch (this._state.status) {
|
|
492
|
+
case 'active':
|
|
493
|
+
for (const observer of this.observers) {
|
|
494
|
+
try {
|
|
495
|
+
observer.next?.(snapshot);
|
|
496
|
+
} catch (err) {
|
|
497
|
+
reportUnhandledError(err);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
break;
|
|
477
501
|
case 'done':
|
|
502
|
+
// next observers are meant to be notified about done snapshots
|
|
503
|
+
// this can be seen as something that is different from how observable work
|
|
504
|
+
// but with observables `complete` callback is called without any arguments
|
|
505
|
+
// it's more ergonomic for XState to treat a done snapshot as a "next" value
|
|
506
|
+
// and the completion event as something that is separate,
|
|
507
|
+
// something that merely follows emitting that done snapshot
|
|
508
|
+
for (const observer of this.observers) {
|
|
509
|
+
try {
|
|
510
|
+
observer.next?.(snapshot);
|
|
511
|
+
} catch (err) {
|
|
512
|
+
reportUnhandledError(err);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
478
515
|
this._stopProcedure();
|
|
479
516
|
this._complete();
|
|
480
517
|
this._doneEvent = createDoneActorEvent(this.id, this._state.output);
|
|
@@ -483,11 +520,7 @@ class Actor {
|
|
|
483
520
|
}
|
|
484
521
|
break;
|
|
485
522
|
case 'error':
|
|
486
|
-
this._stopProcedure();
|
|
487
523
|
this._error(this._state.error);
|
|
488
|
-
if (this._parent) {
|
|
489
|
-
this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
|
|
490
|
-
}
|
|
491
524
|
break;
|
|
492
525
|
}
|
|
493
526
|
this.system._sendInspectionEvent({
|
|
@@ -577,7 +610,7 @@ class Actor {
|
|
|
577
610
|
this.subscribe({
|
|
578
611
|
next: snapshot => {
|
|
579
612
|
if (snapshot.status === 'active') {
|
|
580
|
-
this.
|
|
613
|
+
this.system._relay(this, this._parent, {
|
|
581
614
|
type: `xstate.snapshot.${this.id}`,
|
|
582
615
|
snapshot
|
|
583
616
|
});
|
|
@@ -606,18 +639,22 @@ class Actor {
|
|
|
606
639
|
// a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
|
|
607
640
|
// we still need to complete observers, flush deferreds etc
|
|
608
641
|
this.update(this._state, initEvent);
|
|
609
|
-
// fallthrough
|
|
610
|
-
case 'error':
|
|
611
642
|
// TODO: rethink cleanup of observers, mailbox, etc
|
|
612
643
|
return this;
|
|
644
|
+
case 'error':
|
|
645
|
+
this._error(this._state.error);
|
|
646
|
+
return this;
|
|
613
647
|
}
|
|
614
648
|
if (this.logic.start) {
|
|
615
649
|
try {
|
|
616
650
|
this.logic.start(this._state, this._actorScope);
|
|
617
651
|
} catch (err) {
|
|
618
|
-
this.
|
|
652
|
+
this._state = {
|
|
653
|
+
...this._state,
|
|
654
|
+
status: 'error',
|
|
655
|
+
error: err
|
|
656
|
+
};
|
|
619
657
|
this._error(err);
|
|
620
|
-
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
621
658
|
return this;
|
|
622
659
|
}
|
|
623
660
|
}
|
|
@@ -633,7 +670,6 @@ class Actor {
|
|
|
633
670
|
return this;
|
|
634
671
|
}
|
|
635
672
|
_process(event) {
|
|
636
|
-
// TODO: reexamine what happens when an action (or a guard or smth) throws
|
|
637
673
|
let nextState;
|
|
638
674
|
let caughtError;
|
|
639
675
|
try {
|
|
@@ -648,9 +684,12 @@ class Actor {
|
|
|
648
684
|
const {
|
|
649
685
|
err
|
|
650
686
|
} = caughtError;
|
|
651
|
-
this.
|
|
687
|
+
this._state = {
|
|
688
|
+
...this._state,
|
|
689
|
+
status: 'error',
|
|
690
|
+
error: err
|
|
691
|
+
};
|
|
652
692
|
this._error(err);
|
|
653
|
-
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
654
693
|
return;
|
|
655
694
|
}
|
|
656
695
|
this.update(nextState, event);
|
|
@@ -693,7 +732,7 @@ class Actor {
|
|
|
693
732
|
}
|
|
694
733
|
this.observers.clear();
|
|
695
734
|
}
|
|
696
|
-
|
|
735
|
+
_reportError(err) {
|
|
697
736
|
if (!this.observers.size) {
|
|
698
737
|
if (!this._parent) {
|
|
699
738
|
reportUnhandledError(err);
|
|
@@ -715,6 +754,18 @@ class Actor {
|
|
|
715
754
|
reportUnhandledError(err);
|
|
716
755
|
}
|
|
717
756
|
}
|
|
757
|
+
_error(err) {
|
|
758
|
+
this._stopProcedure();
|
|
759
|
+
this._reportError(err);
|
|
760
|
+
if (this._parent) {
|
|
761
|
+
this.system._relay(this, this._parent, createErrorActorEvent(this.id, err));
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
// TODO: atm children don't belong entirely to the actor so
|
|
765
|
+
// in a way - it's not even super aware of them
|
|
766
|
+
// so we can't stop them from here but we really should!
|
|
767
|
+
// right now, they are being stopped within the machine's transition
|
|
768
|
+
// but that could throw and leave us with "orphaned" active actors
|
|
718
769
|
_stopProcedure() {
|
|
719
770
|
if (this._processingStatus !== ProcessingStatus.Running) {
|
|
720
771
|
// Actor already stopped; do nothing
|
|
@@ -974,12 +1025,7 @@ function executeSpawn(actorScope, {
|
|
|
974
1025
|
if (actorRef._processingStatus === ProcessingStatus.Stopped) {
|
|
975
1026
|
return;
|
|
976
1027
|
}
|
|
977
|
-
|
|
978
|
-
actorRef.start?.();
|
|
979
|
-
} catch (err) {
|
|
980
|
-
actorScope.self.send(createErrorActorEvent(id, err));
|
|
981
|
-
return;
|
|
982
|
-
}
|
|
1028
|
+
actorRef.start();
|
|
983
1029
|
});
|
|
984
1030
|
}
|
|
985
1031
|
function spawnChild(...[src, {
|
|
@@ -2062,7 +2108,23 @@ function macrostep(state, event, actorScope, internalQueue = []) {
|
|
|
2062
2108
|
// Assume the state is at rest (no raised events)
|
|
2063
2109
|
// Determine the next state based on the next microstep
|
|
2064
2110
|
if (nextEvent.type !== XSTATE_INIT) {
|
|
2065
|
-
const
|
|
2111
|
+
const currentEvent = nextEvent;
|
|
2112
|
+
const isErr = isErrorActorEvent(currentEvent);
|
|
2113
|
+
const transitions = selectTransitions(currentEvent, nextState);
|
|
2114
|
+
if (isErr && !transitions.length) {
|
|
2115
|
+
// TODO: we should likely only allow transitions selected by very explicit descriptors
|
|
2116
|
+
// `*` shouldn't be matched, likely `xstate.error.*` shouldnt be either
|
|
2117
|
+
// similarly `xstate.error.actor.*` and `xstate.error.actor.todo.*` have to be considered too
|
|
2118
|
+
nextState = cloneMachineSnapshot(state, {
|
|
2119
|
+
status: 'error',
|
|
2120
|
+
error: currentEvent.data
|
|
2121
|
+
});
|
|
2122
|
+
states.push(nextState);
|
|
2123
|
+
return {
|
|
2124
|
+
state: nextState,
|
|
2125
|
+
microstates: states
|
|
2126
|
+
};
|
|
2127
|
+
}
|
|
2066
2128
|
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
2067
2129
|
states.push(nextState);
|
|
2068
2130
|
}
|
|
@@ -2179,10 +2241,9 @@ function createMachineSnapshot(config, machine) {
|
|
|
2179
2241
|
context: config.context,
|
|
2180
2242
|
_nodes: config._nodes,
|
|
2181
2243
|
value: getStateValue(machine.root, config._nodes),
|
|
2182
|
-
tags: new Set(
|
|
2244
|
+
tags: new Set(config._nodes.flatMap(sn => sn.tags)),
|
|
2183
2245
|
children: config.children,
|
|
2184
2246
|
historyValue: config.historyValue || {},
|
|
2185
|
-
// this one is generic in the target and it's hard to create a matching non-generic source signature
|
|
2186
2247
|
matches: machineSnapshotMatches,
|
|
2187
2248
|
hasTag: machineSnapshotHasTag,
|
|
2188
2249
|
can: machineSnapshotCan,
|
|
@@ -2312,4 +2373,4 @@ function raise(eventOrExpr, options) {
|
|
|
2312
2373
|
return raise;
|
|
2313
2374
|
}
|
|
2314
2375
|
|
|
2315
|
-
export { $$ACTOR_TYPE as $,
|
|
2376
|
+
export { $$ACTOR_TYPE as $, Actor as A, interpret as B, isMachineSnapshot as C, matchesState as D, pathToStateValue as E, toObserver as F, getAllOwnEventDescriptors as G, and as H, not as I, or as J, stateIn as K, cancel as L, raise as M, NULL_EVENT as N, stop as O, stopChild as P, spawnChild as Q, ProcessingStatus as R, STATE_DELIMITER as S, cloneMachineSnapshot as T, XSTATE_ERROR as U, createErrorActorEvent as V, XSTATE_STOP as X, toTransitionConfigArray as a, formatTransition as b, createInvokeId as c, formatInitialTransition as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, getCandidates as h, getAllStateNodes as i, getStateNodes as j, createMachineSnapshot as k, isInFinalState as l, mapValues as m, macrostep as n, transitionNode as o, resolveActionsAndContext as p, createInitEvent as q, resolveStateValue as r, microstep as s, toArray as t, getInitialStateNodes as u, isStateId as v, getStateNodeByPath as w, getPersistedState as x, resolveReferencedActor as y, createActor as z };
|
|
@@ -250,9 +250,6 @@ function mapValues(collection, iteratee) {
|
|
|
250
250
|
}
|
|
251
251
|
return result;
|
|
252
252
|
}
|
|
253
|
-
function flatten(array) {
|
|
254
|
-
return [].concat(...array);
|
|
255
|
-
}
|
|
256
253
|
function toArrayStrict(value) {
|
|
257
254
|
if (isArray(value)) {
|
|
258
255
|
return value;
|
|
@@ -319,7 +316,7 @@ function resolveReferencedActor(machine, src) {
|
|
|
319
316
|
return machine.implementations.actors[src];
|
|
320
317
|
}
|
|
321
318
|
function getAllOwnEventDescriptors(snapshot) {
|
|
322
|
-
return [...new Set(
|
|
319
|
+
return [...new Set([...snapshot._nodes.flatMap(sn => sn.ownEvents)])];
|
|
323
320
|
}
|
|
324
321
|
|
|
325
322
|
const $$ACTOR_TYPE = 1;
|
|
@@ -454,7 +451,18 @@ class Actor {
|
|
|
454
451
|
}
|
|
455
452
|
}
|
|
456
453
|
_initState(persistedState) {
|
|
457
|
-
|
|
454
|
+
try {
|
|
455
|
+
this._state = persistedState ? this.logic.restoreState ? this.logic.restoreState(persistedState, this._actorScope) : persistedState : this.logic.getInitialState(this._actorScope, this.options?.input);
|
|
456
|
+
} catch (err) {
|
|
457
|
+
// if we get here then it means that we assign a value to this._state that is not of the correct type
|
|
458
|
+
// we can't get the true `TSnapshot & { status: 'error'; }`, it's impossible
|
|
459
|
+
// so right now this is a lie of sorts
|
|
460
|
+
this._state = {
|
|
461
|
+
status: 'error',
|
|
462
|
+
output: undefined,
|
|
463
|
+
error: err
|
|
464
|
+
};
|
|
465
|
+
}
|
|
458
466
|
}
|
|
459
467
|
update(snapshot, event) {
|
|
460
468
|
// Update state
|
|
@@ -463,17 +471,46 @@ class Actor {
|
|
|
463
471
|
// Execute deferred effects
|
|
464
472
|
let deferredFn;
|
|
465
473
|
while (deferredFn = this._deferred.shift()) {
|
|
466
|
-
deferredFn();
|
|
467
|
-
}
|
|
468
|
-
for (const observer of this.observers) {
|
|
469
474
|
try {
|
|
470
|
-
|
|
475
|
+
deferredFn();
|
|
471
476
|
} catch (err) {
|
|
472
|
-
|
|
477
|
+
// this error can only be caught when executing *initial* actions
|
|
478
|
+
// it's the only time when we call actions provided by the user through those deferreds
|
|
479
|
+
// when the actor is already running we always execute them synchronously while transitioning
|
|
480
|
+
// no "builtin deferred" should actually throw an error since they are either safe
|
|
481
|
+
// or the control flow is passed through the mailbox and errors should be caught by the `_process` used by the mailbox
|
|
482
|
+
this._deferred.length = 0;
|
|
483
|
+
this._state = {
|
|
484
|
+
...snapshot,
|
|
485
|
+
status: 'error',
|
|
486
|
+
error: err
|
|
487
|
+
};
|
|
473
488
|
}
|
|
474
489
|
}
|
|
475
490
|
switch (this._state.status) {
|
|
491
|
+
case 'active':
|
|
492
|
+
for (const observer of this.observers) {
|
|
493
|
+
try {
|
|
494
|
+
observer.next?.(snapshot);
|
|
495
|
+
} catch (err) {
|
|
496
|
+
reportUnhandledError(err);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
break;
|
|
476
500
|
case 'done':
|
|
501
|
+
// next observers are meant to be notified about done snapshots
|
|
502
|
+
// this can be seen as something that is different from how observable work
|
|
503
|
+
// but with observables `complete` callback is called without any arguments
|
|
504
|
+
// it's more ergonomic for XState to treat a done snapshot as a "next" value
|
|
505
|
+
// and the completion event as something that is separate,
|
|
506
|
+
// something that merely follows emitting that done snapshot
|
|
507
|
+
for (const observer of this.observers) {
|
|
508
|
+
try {
|
|
509
|
+
observer.next?.(snapshot);
|
|
510
|
+
} catch (err) {
|
|
511
|
+
reportUnhandledError(err);
|
|
512
|
+
}
|
|
513
|
+
}
|
|
477
514
|
this._stopProcedure();
|
|
478
515
|
this._complete();
|
|
479
516
|
this._doneEvent = createDoneActorEvent(this.id, this._state.output);
|
|
@@ -482,11 +519,7 @@ class Actor {
|
|
|
482
519
|
}
|
|
483
520
|
break;
|
|
484
521
|
case 'error':
|
|
485
|
-
this._stopProcedure();
|
|
486
522
|
this._error(this._state.error);
|
|
487
|
-
if (this._parent) {
|
|
488
|
-
this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
|
|
489
|
-
}
|
|
490
523
|
break;
|
|
491
524
|
}
|
|
492
525
|
this.system._sendInspectionEvent({
|
|
@@ -576,7 +609,7 @@ class Actor {
|
|
|
576
609
|
this.subscribe({
|
|
577
610
|
next: snapshot => {
|
|
578
611
|
if (snapshot.status === 'active') {
|
|
579
|
-
this.
|
|
612
|
+
this.system._relay(this, this._parent, {
|
|
580
613
|
type: `xstate.snapshot.${this.id}`,
|
|
581
614
|
snapshot
|
|
582
615
|
});
|
|
@@ -605,18 +638,22 @@ class Actor {
|
|
|
605
638
|
// a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
|
|
606
639
|
// we still need to complete observers, flush deferreds etc
|
|
607
640
|
this.update(this._state, initEvent);
|
|
608
|
-
// fallthrough
|
|
609
|
-
case 'error':
|
|
610
641
|
// TODO: rethink cleanup of observers, mailbox, etc
|
|
611
642
|
return this;
|
|
643
|
+
case 'error':
|
|
644
|
+
this._error(this._state.error);
|
|
645
|
+
return this;
|
|
612
646
|
}
|
|
613
647
|
if (this.logic.start) {
|
|
614
648
|
try {
|
|
615
649
|
this.logic.start(this._state, this._actorScope);
|
|
616
650
|
} catch (err) {
|
|
617
|
-
this.
|
|
651
|
+
this._state = {
|
|
652
|
+
...this._state,
|
|
653
|
+
status: 'error',
|
|
654
|
+
error: err
|
|
655
|
+
};
|
|
618
656
|
this._error(err);
|
|
619
|
-
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
620
657
|
return this;
|
|
621
658
|
}
|
|
622
659
|
}
|
|
@@ -632,7 +669,6 @@ class Actor {
|
|
|
632
669
|
return this;
|
|
633
670
|
}
|
|
634
671
|
_process(event) {
|
|
635
|
-
// TODO: reexamine what happens when an action (or a guard or smth) throws
|
|
636
672
|
let nextState;
|
|
637
673
|
let caughtError;
|
|
638
674
|
try {
|
|
@@ -647,9 +683,12 @@ class Actor {
|
|
|
647
683
|
const {
|
|
648
684
|
err
|
|
649
685
|
} = caughtError;
|
|
650
|
-
this.
|
|
686
|
+
this._state = {
|
|
687
|
+
...this._state,
|
|
688
|
+
status: 'error',
|
|
689
|
+
error: err
|
|
690
|
+
};
|
|
651
691
|
this._error(err);
|
|
652
|
-
this._parent?.send(createErrorActorEvent(this.id, err));
|
|
653
692
|
return;
|
|
654
693
|
}
|
|
655
694
|
this.update(nextState, event);
|
|
@@ -692,7 +731,7 @@ class Actor {
|
|
|
692
731
|
}
|
|
693
732
|
this.observers.clear();
|
|
694
733
|
}
|
|
695
|
-
|
|
734
|
+
_reportError(err) {
|
|
696
735
|
if (!this.observers.size) {
|
|
697
736
|
if (!this._parent) {
|
|
698
737
|
reportUnhandledError(err);
|
|
@@ -714,6 +753,18 @@ class Actor {
|
|
|
714
753
|
reportUnhandledError(err);
|
|
715
754
|
}
|
|
716
755
|
}
|
|
756
|
+
_error(err) {
|
|
757
|
+
this._stopProcedure();
|
|
758
|
+
this._reportError(err);
|
|
759
|
+
if (this._parent) {
|
|
760
|
+
this.system._relay(this, this._parent, createErrorActorEvent(this.id, err));
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
// TODO: atm children don't belong entirely to the actor so
|
|
764
|
+
// in a way - it's not even super aware of them
|
|
765
|
+
// so we can't stop them from here but we really should!
|
|
766
|
+
// right now, they are being stopped within the machine's transition
|
|
767
|
+
// but that could throw and leave us with "orphaned" active actors
|
|
717
768
|
_stopProcedure() {
|
|
718
769
|
if (this._processingStatus !== ProcessingStatus.Running) {
|
|
719
770
|
// Actor already stopped; do nothing
|
|
@@ -959,12 +1010,7 @@ function executeSpawn(actorScope, {
|
|
|
959
1010
|
if (actorRef._processingStatus === ProcessingStatus.Stopped) {
|
|
960
1011
|
return;
|
|
961
1012
|
}
|
|
962
|
-
|
|
963
|
-
actorRef.start?.();
|
|
964
|
-
} catch (err) {
|
|
965
|
-
actorScope.self.send(createErrorActorEvent(id, err));
|
|
966
|
-
return;
|
|
967
|
-
}
|
|
1013
|
+
actorRef.start();
|
|
968
1014
|
});
|
|
969
1015
|
}
|
|
970
1016
|
function spawnChild(...[src, {
|
|
@@ -2019,7 +2065,23 @@ function macrostep(state, event, actorScope, internalQueue = []) {
|
|
|
2019
2065
|
// Assume the state is at rest (no raised events)
|
|
2020
2066
|
// Determine the next state based on the next microstep
|
|
2021
2067
|
if (nextEvent.type !== XSTATE_INIT) {
|
|
2022
|
-
const
|
|
2068
|
+
const currentEvent = nextEvent;
|
|
2069
|
+
const isErr = isErrorActorEvent(currentEvent);
|
|
2070
|
+
const transitions = selectTransitions(currentEvent, nextState);
|
|
2071
|
+
if (isErr && !transitions.length) {
|
|
2072
|
+
// TODO: we should likely only allow transitions selected by very explicit descriptors
|
|
2073
|
+
// `*` shouldn't be matched, likely `xstate.error.*` shouldnt be either
|
|
2074
|
+
// similarly `xstate.error.actor.*` and `xstate.error.actor.todo.*` have to be considered too
|
|
2075
|
+
nextState = cloneMachineSnapshot(state, {
|
|
2076
|
+
status: 'error',
|
|
2077
|
+
error: currentEvent.data
|
|
2078
|
+
});
|
|
2079
|
+
states.push(nextState);
|
|
2080
|
+
return {
|
|
2081
|
+
state: nextState,
|
|
2082
|
+
microstates: states
|
|
2083
|
+
};
|
|
2084
|
+
}
|
|
2023
2085
|
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
2024
2086
|
states.push(nextState);
|
|
2025
2087
|
}
|
|
@@ -2133,10 +2195,9 @@ function createMachineSnapshot(config, machine) {
|
|
|
2133
2195
|
context: config.context,
|
|
2134
2196
|
_nodes: config._nodes,
|
|
2135
2197
|
value: getStateValue(machine.root, config._nodes),
|
|
2136
|
-
tags: new Set(
|
|
2198
|
+
tags: new Set(config._nodes.flatMap(sn => sn.tags)),
|
|
2137
2199
|
children: config.children,
|
|
2138
2200
|
historyValue: config.historyValue || {},
|
|
2139
|
-
// this one is generic in the target and it's hard to create a matching non-generic source signature
|
|
2140
2201
|
matches: machineSnapshotMatches,
|
|
2141
2202
|
hasTag: machineSnapshotHasTag,
|
|
2142
2203
|
can: machineSnapshotCan,
|
|
@@ -2288,7 +2349,6 @@ exports.getPersistedState = getPersistedState;
|
|
|
2288
2349
|
exports.getStateNodeByPath = getStateNodeByPath;
|
|
2289
2350
|
exports.getStateNodes = getStateNodes;
|
|
2290
2351
|
exports.interpret = interpret;
|
|
2291
|
-
exports.isErrorActorEvent = isErrorActorEvent;
|
|
2292
2352
|
exports.isInFinalState = isInFinalState;
|
|
2293
2353
|
exports.isMachineSnapshot = isMachineSnapshot;
|
|
2294
2354
|
exports.isStateId = isStateId;
|