xstate 5.18.0 → 5.18.2
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.d.mts +1 -1
- package/actions/dist/xstate-actions.cjs.d.ts +1 -1
- 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.d.mts +1 -1
- package/actors/dist/xstate-actors.cjs.d.ts +1 -1
- package/actors/dist/xstate-actors.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.cjs.js +1 -1
- package/actors/dist/xstate-actors.development.esm.js +1 -1
- package/actors/dist/xstate-actors.esm.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dev/dist/xstate-dev.cjs.d.mts +1 -1
- package/dev/dist/xstate-dev.cjs.d.ts +1 -1
- package/dist/declarations/src/State.d.ts +1 -1
- package/dist/declarations/src/createActor.d.ts +3 -4
- package/dist/declarations/src/index.d.ts +5 -5
- package/dist/declarations/src/inspection.d.ts +2 -2
- package/dist/{log-54d038f7.esm.js → log-15d0f775.esm.js} +9 -2
- package/dist/{log-4f8360d3.development.esm.js → log-38475d87.development.esm.js} +9 -2
- package/dist/{log-f7dcaa97.cjs.js → log-98fcce74.cjs.js} +9 -2
- package/dist/{log-40d606d3.development.cjs.js → log-b7ed1b61.development.cjs.js} +9 -2
- package/dist/{State-cdbc7940.esm.js → raise-0f7cf128.esm.js} +191 -192
- package/dist/{State-34039d2a.development.esm.js → raise-5ea71f04.development.esm.js} +206 -207
- package/dist/{State-30c95050.cjs.js → raise-b1e0b9a9.cjs.js} +190 -191
- package/dist/{State-a2464a1e.development.cjs.js → raise-e919c5d4.development.cjs.js} +205 -206
- package/dist/xstate.cjs.d.mts +1 -1
- package/dist/xstate.cjs.d.ts +1 -1
- package/dist/xstate.cjs.js +106 -104
- package/dist/xstate.development.cjs.js +106 -104
- package/dist/xstate.development.esm.js +102 -100
- package/dist/xstate.esm.js +102 -100
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.d.mts +1 -1
- package/guards/dist/xstate-guards.cjs.d.ts +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 +7 -7
- package/actions/dist/xstate-actions.cjs.d.mts.map +0 -1
- package/actions/dist/xstate-actions.cjs.d.ts.map +0 -1
- package/actors/dist/xstate-actors.cjs.d.mts.map +0 -1
- package/actors/dist/xstate-actors.cjs.d.ts.map +0 -1
- package/dev/dist/xstate-dev.cjs.d.mts.map +0 -1
- package/dev/dist/xstate-dev.cjs.d.ts.map +0 -1
- package/dist/xstate.cjs.d.mts.map +0 -1
- package/dist/xstate.cjs.d.ts.map +0 -1
- package/guards/dist/xstate-guards.cjs.d.mts.map +0 -1
- package/guards/dist/xstate-guards.cjs.d.ts.map +0 -1
|
@@ -1,73 +1,38 @@
|
|
|
1
|
-
import { S as STATE_DELIMITER, m as mapValues, t as toArray, f as formatTransitions, a as toTransitionConfigArray, b as formatTransition, N as NULL_EVENT, e as evaluateGuard, c as createInvokeId, g as getDelayedTransitions, d as formatInitialTransition, h as getCandidates, r as resolveStateValue, i as getAllStateNodes, j as getStateNodes, k as createMachineSnapshot, l as isInFinalState, n as macrostep, o as transitionNode, p as resolveActionsAndContext, q as createInitEvent, s as microstep, u as getInitialStateNodes, v as toStatePath, w as isStateId, x as getStateNodeByPath, y as getPersistedSnapshot, z as resolveReferencedActor, A as createActor, $ as $$ACTOR_TYPE } from './State-34039d2a.development.esm.js';
|
|
2
|
-
export { C as Actor, I as __unsafe_getAllOwnEventDescriptors, E as and, M as cancel, A as createActor, j as getStateNodes, D as interpret, B as isMachineSnapshot, J as matchesState, F as not, G as or, K as pathToStateValue, O as raise, P as spawnChild, H as stateIn, Q as stop, R as stopChild, L as toObserver } from './State-34039d2a.development.esm.js';
|
|
3
|
-
import { a as assign } from './log-4f8360d3.development.esm.js';
|
|
4
|
-
export { S as SpecialTargets, a as assign, e as emit, b as enqueueActions, f as forwardTo, l as log, s as sendParent, c as sendTo } from './log-4f8360d3.development.esm.js';
|
|
5
1
|
export { createEmptyActor, fromCallback, fromEventObservable, fromObservable, fromPromise, fromTransition } from '../actors/dist/xstate-actors.development.esm.js';
|
|
2
|
+
import { t as toArray, S as STATE_DELIMITER, m as mapValues, f as formatTransitions, a as toTransitionConfigArray, b as formatTransition, N as NULL_EVENT, e as evaluateGuard, c as createInvokeId, g as getDelayedTransitions, d as formatInitialTransition, h as getCandidates, r as resolveStateValue, i as getAllStateNodes, j as getStateNodes, k as createMachineSnapshot, l as isInFinalState, n as macrostep, o as transitionNode, p as resolveActionsAndContext, q as createInitEvent, s as microstep, u as getInitialStateNodes, v as toStatePath, w as isStateId, x as getStateNodeByPath, y as getPersistedSnapshot, z as resolveReferencedActor, A as createActor, $ as $$ACTOR_TYPE } from './raise-5ea71f04.development.esm.js';
|
|
3
|
+
export { B as Actor, I as __unsafe_getAllOwnEventDescriptors, D as and, M as cancel, A as createActor, j as getStateNodes, C as interpret, H as isMachineSnapshot, J as matchesState, E as not, F as or, K as pathToStateValue, O as raise, P as spawnChild, G as stateIn, Q as stop, R as stopChild, L as toObserver } from './raise-5ea71f04.development.esm.js';
|
|
4
|
+
import { a as assign } from './log-38475d87.development.esm.js';
|
|
5
|
+
export { S as SpecialTargets, a as assign, e as emit, b as enqueueActions, f as forwardTo, l as log, s as sendParent, c as sendTo } from './log-38475d87.development.esm.js';
|
|
6
6
|
import '../dev/dist/xstate-dev.development.esm.js';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
set(time) {
|
|
37
|
-
if (this._now > time) {
|
|
38
|
-
throw new Error('Unable to travel back in time');
|
|
39
|
-
}
|
|
40
|
-
this._now = time;
|
|
41
|
-
this.flushTimeouts();
|
|
42
|
-
}
|
|
43
|
-
flushTimeouts() {
|
|
44
|
-
if (this._flushing) {
|
|
45
|
-
this._flushingInvalidated = true;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
this._flushing = true;
|
|
49
|
-
const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
|
|
50
|
-
const endA = timeoutA.start + timeoutA.timeout;
|
|
51
|
-
const endB = timeoutB.start + timeoutB.timeout;
|
|
52
|
-
return endB > endA ? -1 : 1;
|
|
53
|
-
});
|
|
54
|
-
for (const [id, timeout] of sorted) {
|
|
55
|
-
if (this._flushingInvalidated) {
|
|
56
|
-
this._flushingInvalidated = false;
|
|
57
|
-
this._flushing = false;
|
|
58
|
-
this.flushTimeouts();
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (this.now() - timeout.start >= timeout.timeout) {
|
|
62
|
-
this.timeouts.delete(id);
|
|
63
|
-
timeout.fn.call(null);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
this._flushing = false;
|
|
67
|
-
}
|
|
68
|
-
increment(ms) {
|
|
69
|
-
this._now += ms;
|
|
70
|
-
this.flushTimeouts();
|
|
8
|
+
/**
|
|
9
|
+
* Asserts that the given event object is of the specified type or types. Throws
|
|
10
|
+
* an error if the event object is not of the specified types.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // ...
|
|
16
|
+
* entry: ({ event }) => {
|
|
17
|
+
* assertEvent(event, 'doNothing');
|
|
18
|
+
* // event is { type: 'doNothing' }
|
|
19
|
+
* },
|
|
20
|
+
* // ...
|
|
21
|
+
* exit: ({ event }) => {
|
|
22
|
+
* assertEvent(event, 'greet');
|
|
23
|
+
* // event is { type: 'greet'; message: string }
|
|
24
|
+
*
|
|
25
|
+
* assertEvent(event, ['greet', 'notify']);
|
|
26
|
+
* // event is { type: 'greet'; message: string }
|
|
27
|
+
* // or { type: 'notify'; message: string; level: 'info' | 'error' }
|
|
28
|
+
* },
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function assertEvent(event, type) {
|
|
32
|
+
const types = toArray(type);
|
|
33
|
+
if (!types.includes(event.type)) {
|
|
34
|
+
const typesText = types.length === 1 ? `type "${types[0]}"` : `one of types "${types.join('", "')}"`;
|
|
35
|
+
throw new Error(`Expected event ${JSON.stringify(event)} to have ${typesText}`);
|
|
71
36
|
}
|
|
72
37
|
}
|
|
73
38
|
|
|
@@ -105,7 +70,7 @@ const toSerializableAction = action => {
|
|
|
105
70
|
return action;
|
|
106
71
|
};
|
|
107
72
|
class StateNode {
|
|
108
|
-
constructor(
|
|
73
|
+
constructor(/** The raw config used to create the machine. */
|
|
109
74
|
config, options) {
|
|
110
75
|
this.config = config;
|
|
111
76
|
/**
|
|
@@ -361,7 +326,7 @@ class StateNode {
|
|
|
361
326
|
|
|
362
327
|
const STATE_IDENTIFIER = '#';
|
|
363
328
|
class StateMachine {
|
|
364
|
-
constructor(
|
|
329
|
+
constructor(/** The raw config used to create the machine. */
|
|
365
330
|
config, implementations) {
|
|
366
331
|
this.config = config;
|
|
367
332
|
/** The machine's own version. */
|
|
@@ -599,40 +564,10 @@ class StateMachine {
|
|
|
599
564
|
}
|
|
600
565
|
}
|
|
601
566
|
|
|
602
|
-
/**
|
|
603
|
-
* Asserts that the given event object is of the specified type or types. Throws
|
|
604
|
-
* an error if the event object is not of the specified types.
|
|
605
|
-
*
|
|
606
|
-
* @example
|
|
607
|
-
*
|
|
608
|
-
* ```ts
|
|
609
|
-
* // ...
|
|
610
|
-
* entry: ({ event }) => {
|
|
611
|
-
* assertEvent(event, 'doNothing');
|
|
612
|
-
* // event is { type: 'doNothing' }
|
|
613
|
-
* },
|
|
614
|
-
* // ...
|
|
615
|
-
* exit: ({ event }) => {
|
|
616
|
-
* assertEvent(event, 'greet');
|
|
617
|
-
* // event is { type: 'greet'; message: string }
|
|
618
|
-
*
|
|
619
|
-
* assertEvent(event, ['greet', 'notify']);
|
|
620
|
-
* // event is { type: 'greet'; message: string }
|
|
621
|
-
* // or { type: 'notify'; message: string; level: 'info' | 'error' }
|
|
622
|
-
* },
|
|
623
|
-
* ```
|
|
624
|
-
*/
|
|
625
|
-
function assertEvent(event, type) {
|
|
626
|
-
const types = toArray(type);
|
|
627
|
-
if (!types.includes(event.type)) {
|
|
628
|
-
const typesText = types.length === 1 ? `type "${types[0]}"` : `one of types "${types.join('", "')}"`;
|
|
629
|
-
throw new Error(`Expected event ${JSON.stringify(event)} to have ${typesText}`);
|
|
630
|
-
}
|
|
631
|
-
}
|
|
632
|
-
|
|
633
567
|
// this is not 100% accurate since we can't make parallel regions required in the result
|
|
634
568
|
// `TTestValue` doesn't encode this information anyhow for us to be able to do that
|
|
635
569
|
// this is fine for most practical use cases anyway though
|
|
570
|
+
|
|
636
571
|
/**
|
|
637
572
|
* Creates a state machine (statechart) with the given configuration.
|
|
638
573
|
*
|
|
@@ -739,6 +674,7 @@ function getNextSnapshot(actorLogic, snapshot, event) {
|
|
|
739
674
|
|
|
740
675
|
// at the moment we allow extra actors - ones that are not specified by `children`
|
|
741
676
|
// this could be reconsidered in the future
|
|
677
|
+
|
|
742
678
|
function setup({
|
|
743
679
|
schemas,
|
|
744
680
|
actors,
|
|
@@ -759,6 +695,72 @@ function setup({
|
|
|
759
695
|
};
|
|
760
696
|
}
|
|
761
697
|
|
|
698
|
+
class SimulatedClock {
|
|
699
|
+
constructor() {
|
|
700
|
+
this.timeouts = new Map();
|
|
701
|
+
this._now = 0;
|
|
702
|
+
this._id = 0;
|
|
703
|
+
this._flushing = false;
|
|
704
|
+
this._flushingInvalidated = false;
|
|
705
|
+
}
|
|
706
|
+
now() {
|
|
707
|
+
return this._now;
|
|
708
|
+
}
|
|
709
|
+
getId() {
|
|
710
|
+
return this._id++;
|
|
711
|
+
}
|
|
712
|
+
setTimeout(fn, timeout) {
|
|
713
|
+
this._flushingInvalidated = this._flushing;
|
|
714
|
+
const id = this.getId();
|
|
715
|
+
this.timeouts.set(id, {
|
|
716
|
+
start: this.now(),
|
|
717
|
+
timeout,
|
|
718
|
+
fn
|
|
719
|
+
});
|
|
720
|
+
return id;
|
|
721
|
+
}
|
|
722
|
+
clearTimeout(id) {
|
|
723
|
+
this._flushingInvalidated = this._flushing;
|
|
724
|
+
this.timeouts.delete(id);
|
|
725
|
+
}
|
|
726
|
+
set(time) {
|
|
727
|
+
if (this._now > time) {
|
|
728
|
+
throw new Error('Unable to travel back in time');
|
|
729
|
+
}
|
|
730
|
+
this._now = time;
|
|
731
|
+
this.flushTimeouts();
|
|
732
|
+
}
|
|
733
|
+
flushTimeouts() {
|
|
734
|
+
if (this._flushing) {
|
|
735
|
+
this._flushingInvalidated = true;
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
this._flushing = true;
|
|
739
|
+
const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
|
|
740
|
+
const endA = timeoutA.start + timeoutA.timeout;
|
|
741
|
+
const endB = timeoutB.start + timeoutB.timeout;
|
|
742
|
+
return endB > endA ? -1 : 1;
|
|
743
|
+
});
|
|
744
|
+
for (const [id, timeout] of sorted) {
|
|
745
|
+
if (this._flushingInvalidated) {
|
|
746
|
+
this._flushingInvalidated = false;
|
|
747
|
+
this._flushing = false;
|
|
748
|
+
this.flushTimeouts();
|
|
749
|
+
return;
|
|
750
|
+
}
|
|
751
|
+
if (this.now() - timeout.start >= timeout.timeout) {
|
|
752
|
+
this.timeouts.delete(id);
|
|
753
|
+
timeout.fn.call(null);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
this._flushing = false;
|
|
757
|
+
}
|
|
758
|
+
increment(ms) {
|
|
759
|
+
this._now += ms;
|
|
760
|
+
this.flushTimeouts();
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
|
|
762
764
|
/**
|
|
763
765
|
* Returns a promise that resolves to the `output` of the actor when it is done.
|
|
764
766
|
*
|
package/dist/xstate.esm.js
CHANGED
|
@@ -1,73 +1,38 @@
|
|
|
1
|
-
import { S as STATE_DELIMITER, m as mapValues, t as toArray, f as formatTransitions, a as toTransitionConfigArray, b as formatTransition, N as NULL_EVENT, e as evaluateGuard, c as createInvokeId, g as getDelayedTransitions, d as formatInitialTransition, h as getCandidates, r as resolveStateValue, i as getAllStateNodes, j as getStateNodes, k as createMachineSnapshot, l as isInFinalState, n as macrostep, o as transitionNode, p as resolveActionsAndContext, q as createInitEvent, s as microstep, u as getInitialStateNodes, v as toStatePath, w as isStateId, x as getStateNodeByPath, y as getPersistedSnapshot, z as resolveReferencedActor, A as createActor, $ as $$ACTOR_TYPE } from './State-cdbc7940.esm.js';
|
|
2
|
-
export { C as Actor, I as __unsafe_getAllOwnEventDescriptors, E as and, M as cancel, A as createActor, j as getStateNodes, D as interpret, B as isMachineSnapshot, J as matchesState, F as not, G as or, K as pathToStateValue, O as raise, P as spawnChild, H as stateIn, Q as stop, R as stopChild, L as toObserver } from './State-cdbc7940.esm.js';
|
|
3
|
-
import { a as assign } from './log-54d038f7.esm.js';
|
|
4
|
-
export { S as SpecialTargets, a as assign, e as emit, b as enqueueActions, f as forwardTo, l as log, s as sendParent, c as sendTo } from './log-54d038f7.esm.js';
|
|
5
1
|
export { createEmptyActor, fromCallback, fromEventObservable, fromObservable, fromPromise, fromTransition } from '../actors/dist/xstate-actors.esm.js';
|
|
2
|
+
import { t as toArray, S as STATE_DELIMITER, m as mapValues, f as formatTransitions, a as toTransitionConfigArray, b as formatTransition, N as NULL_EVENT, e as evaluateGuard, c as createInvokeId, g as getDelayedTransitions, d as formatInitialTransition, h as getCandidates, r as resolveStateValue, i as getAllStateNodes, j as getStateNodes, k as createMachineSnapshot, l as isInFinalState, n as macrostep, o as transitionNode, p as resolveActionsAndContext, q as createInitEvent, s as microstep, u as getInitialStateNodes, v as toStatePath, w as isStateId, x as getStateNodeByPath, y as getPersistedSnapshot, z as resolveReferencedActor, A as createActor, $ as $$ACTOR_TYPE } from './raise-0f7cf128.esm.js';
|
|
3
|
+
export { B as Actor, I as __unsafe_getAllOwnEventDescriptors, D as and, M as cancel, A as createActor, j as getStateNodes, C as interpret, H as isMachineSnapshot, J as matchesState, E as not, F as or, K as pathToStateValue, O as raise, P as spawnChild, G as stateIn, Q as stop, R as stopChild, L as toObserver } from './raise-0f7cf128.esm.js';
|
|
4
|
+
import { a as assign } from './log-15d0f775.esm.js';
|
|
5
|
+
export { S as SpecialTargets, a as assign, e as emit, b as enqueueActions, f as forwardTo, l as log, s as sendParent, c as sendTo } from './log-15d0f775.esm.js';
|
|
6
6
|
import '../dev/dist/xstate-dev.esm.js';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
set(time) {
|
|
37
|
-
if (this._now > time) {
|
|
38
|
-
throw new Error('Unable to travel back in time');
|
|
39
|
-
}
|
|
40
|
-
this._now = time;
|
|
41
|
-
this.flushTimeouts();
|
|
42
|
-
}
|
|
43
|
-
flushTimeouts() {
|
|
44
|
-
if (this._flushing) {
|
|
45
|
-
this._flushingInvalidated = true;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
this._flushing = true;
|
|
49
|
-
const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
|
|
50
|
-
const endA = timeoutA.start + timeoutA.timeout;
|
|
51
|
-
const endB = timeoutB.start + timeoutB.timeout;
|
|
52
|
-
return endB > endA ? -1 : 1;
|
|
53
|
-
});
|
|
54
|
-
for (const [id, timeout] of sorted) {
|
|
55
|
-
if (this._flushingInvalidated) {
|
|
56
|
-
this._flushingInvalidated = false;
|
|
57
|
-
this._flushing = false;
|
|
58
|
-
this.flushTimeouts();
|
|
59
|
-
return;
|
|
60
|
-
}
|
|
61
|
-
if (this.now() - timeout.start >= timeout.timeout) {
|
|
62
|
-
this.timeouts.delete(id);
|
|
63
|
-
timeout.fn.call(null);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
this._flushing = false;
|
|
67
|
-
}
|
|
68
|
-
increment(ms) {
|
|
69
|
-
this._now += ms;
|
|
70
|
-
this.flushTimeouts();
|
|
8
|
+
/**
|
|
9
|
+
* Asserts that the given event object is of the specified type or types. Throws
|
|
10
|
+
* an error if the event object is not of the specified types.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* // ...
|
|
16
|
+
* entry: ({ event }) => {
|
|
17
|
+
* assertEvent(event, 'doNothing');
|
|
18
|
+
* // event is { type: 'doNothing' }
|
|
19
|
+
* },
|
|
20
|
+
* // ...
|
|
21
|
+
* exit: ({ event }) => {
|
|
22
|
+
* assertEvent(event, 'greet');
|
|
23
|
+
* // event is { type: 'greet'; message: string }
|
|
24
|
+
*
|
|
25
|
+
* assertEvent(event, ['greet', 'notify']);
|
|
26
|
+
* // event is { type: 'greet'; message: string }
|
|
27
|
+
* // or { type: 'notify'; message: string; level: 'info' | 'error' }
|
|
28
|
+
* },
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
function assertEvent(event, type) {
|
|
32
|
+
const types = toArray(type);
|
|
33
|
+
if (!types.includes(event.type)) {
|
|
34
|
+
const typesText = types.length === 1 ? `type "${types[0]}"` : `one of types "${types.join('", "')}"`;
|
|
35
|
+
throw new Error(`Expected event ${JSON.stringify(event)} to have ${typesText}`);
|
|
71
36
|
}
|
|
72
37
|
}
|
|
73
38
|
|
|
@@ -105,7 +70,7 @@ const toSerializableAction = action => {
|
|
|
105
70
|
return action;
|
|
106
71
|
};
|
|
107
72
|
class StateNode {
|
|
108
|
-
constructor(
|
|
73
|
+
constructor(/** The raw config used to create the machine. */
|
|
109
74
|
config, options) {
|
|
110
75
|
this.config = config;
|
|
111
76
|
/**
|
|
@@ -361,7 +326,7 @@ class StateNode {
|
|
|
361
326
|
|
|
362
327
|
const STATE_IDENTIFIER = '#';
|
|
363
328
|
class StateMachine {
|
|
364
|
-
constructor(
|
|
329
|
+
constructor(/** The raw config used to create the machine. */
|
|
365
330
|
config, implementations) {
|
|
366
331
|
this.config = config;
|
|
367
332
|
/** The machine's own version. */
|
|
@@ -596,40 +561,10 @@ class StateMachine {
|
|
|
596
561
|
}
|
|
597
562
|
}
|
|
598
563
|
|
|
599
|
-
/**
|
|
600
|
-
* Asserts that the given event object is of the specified type or types. Throws
|
|
601
|
-
* an error if the event object is not of the specified types.
|
|
602
|
-
*
|
|
603
|
-
* @example
|
|
604
|
-
*
|
|
605
|
-
* ```ts
|
|
606
|
-
* // ...
|
|
607
|
-
* entry: ({ event }) => {
|
|
608
|
-
* assertEvent(event, 'doNothing');
|
|
609
|
-
* // event is { type: 'doNothing' }
|
|
610
|
-
* },
|
|
611
|
-
* // ...
|
|
612
|
-
* exit: ({ event }) => {
|
|
613
|
-
* assertEvent(event, 'greet');
|
|
614
|
-
* // event is { type: 'greet'; message: string }
|
|
615
|
-
*
|
|
616
|
-
* assertEvent(event, ['greet', 'notify']);
|
|
617
|
-
* // event is { type: 'greet'; message: string }
|
|
618
|
-
* // or { type: 'notify'; message: string; level: 'info' | 'error' }
|
|
619
|
-
* },
|
|
620
|
-
* ```
|
|
621
|
-
*/
|
|
622
|
-
function assertEvent(event, type) {
|
|
623
|
-
const types = toArray(type);
|
|
624
|
-
if (!types.includes(event.type)) {
|
|
625
|
-
const typesText = types.length === 1 ? `type "${types[0]}"` : `one of types "${types.join('", "')}"`;
|
|
626
|
-
throw new Error(`Expected event ${JSON.stringify(event)} to have ${typesText}`);
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
564
|
// this is not 100% accurate since we can't make parallel regions required in the result
|
|
631
565
|
// `TTestValue` doesn't encode this information anyhow for us to be able to do that
|
|
632
566
|
// this is fine for most practical use cases anyway though
|
|
567
|
+
|
|
633
568
|
/**
|
|
634
569
|
* Creates a state machine (statechart) with the given configuration.
|
|
635
570
|
*
|
|
@@ -736,6 +671,7 @@ function getNextSnapshot(actorLogic, snapshot, event) {
|
|
|
736
671
|
|
|
737
672
|
// at the moment we allow extra actors - ones that are not specified by `children`
|
|
738
673
|
// this could be reconsidered in the future
|
|
674
|
+
|
|
739
675
|
function setup({
|
|
740
676
|
schemas,
|
|
741
677
|
actors,
|
|
@@ -756,6 +692,72 @@ function setup({
|
|
|
756
692
|
};
|
|
757
693
|
}
|
|
758
694
|
|
|
695
|
+
class SimulatedClock {
|
|
696
|
+
constructor() {
|
|
697
|
+
this.timeouts = new Map();
|
|
698
|
+
this._now = 0;
|
|
699
|
+
this._id = 0;
|
|
700
|
+
this._flushing = false;
|
|
701
|
+
this._flushingInvalidated = false;
|
|
702
|
+
}
|
|
703
|
+
now() {
|
|
704
|
+
return this._now;
|
|
705
|
+
}
|
|
706
|
+
getId() {
|
|
707
|
+
return this._id++;
|
|
708
|
+
}
|
|
709
|
+
setTimeout(fn, timeout) {
|
|
710
|
+
this._flushingInvalidated = this._flushing;
|
|
711
|
+
const id = this.getId();
|
|
712
|
+
this.timeouts.set(id, {
|
|
713
|
+
start: this.now(),
|
|
714
|
+
timeout,
|
|
715
|
+
fn
|
|
716
|
+
});
|
|
717
|
+
return id;
|
|
718
|
+
}
|
|
719
|
+
clearTimeout(id) {
|
|
720
|
+
this._flushingInvalidated = this._flushing;
|
|
721
|
+
this.timeouts.delete(id);
|
|
722
|
+
}
|
|
723
|
+
set(time) {
|
|
724
|
+
if (this._now > time) {
|
|
725
|
+
throw new Error('Unable to travel back in time');
|
|
726
|
+
}
|
|
727
|
+
this._now = time;
|
|
728
|
+
this.flushTimeouts();
|
|
729
|
+
}
|
|
730
|
+
flushTimeouts() {
|
|
731
|
+
if (this._flushing) {
|
|
732
|
+
this._flushingInvalidated = true;
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
this._flushing = true;
|
|
736
|
+
const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
|
|
737
|
+
const endA = timeoutA.start + timeoutA.timeout;
|
|
738
|
+
const endB = timeoutB.start + timeoutB.timeout;
|
|
739
|
+
return endB > endA ? -1 : 1;
|
|
740
|
+
});
|
|
741
|
+
for (const [id, timeout] of sorted) {
|
|
742
|
+
if (this._flushingInvalidated) {
|
|
743
|
+
this._flushingInvalidated = false;
|
|
744
|
+
this._flushing = false;
|
|
745
|
+
this.flushTimeouts();
|
|
746
|
+
return;
|
|
747
|
+
}
|
|
748
|
+
if (this.now() - timeout.start >= timeout.timeout) {
|
|
749
|
+
this.timeouts.delete(id);
|
|
750
|
+
timeout.fn.call(null);
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
this._flushing = false;
|
|
754
|
+
}
|
|
755
|
+
increment(ms) {
|
|
756
|
+
this._now += ms;
|
|
757
|
+
this.flushTimeouts();
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
|
|
759
761
|
/**
|
|
760
762
|
* Returns a promise that resolves to the `output` of the actor when it is done.
|
|
761
763
|
*
|