xstate 5.0.2 → 5.2.0

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.
Files changed (45) hide show
  1. package/actions/dist/xstate-actions.cjs.js +2 -2
  2. package/actions/dist/xstate-actions.development.cjs.js +2 -2
  3. package/actions/dist/xstate-actions.development.esm.js +2 -2
  4. package/actions/dist/xstate-actions.esm.js +2 -2
  5. package/actions/dist/xstate-actions.umd.min.js +1 -1
  6. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  7. package/actors/dist/xstate-actors.cjs.js +1 -1
  8. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.esm.js +1 -1
  10. package/actors/dist/xstate-actors.esm.js +1 -1
  11. package/actors/dist/xstate-actors.umd.min.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  13. package/dist/declarations/src/SimulatedClock.d.ts +3 -1
  14. package/dist/declarations/src/actions/send.d.ts +1 -1
  15. package/dist/declarations/src/actors/callback.d.ts +3 -2
  16. package/dist/declarations/src/actors/observable.d.ts +2 -1
  17. package/dist/declarations/src/actors/promise.d.ts +3 -2
  18. package/dist/declarations/src/actors/transition.d.ts +3 -2
  19. package/dist/declarations/src/index.d.ts +6 -5
  20. package/dist/declarations/src/interpreter.d.ts +4 -8
  21. package/dist/declarations/src/spawn.d.ts +3 -2
  22. package/dist/declarations/src/system.d.ts +32 -2
  23. package/dist/declarations/src/toPromise.d.ts +24 -0
  24. package/dist/declarations/src/types.d.ts +13 -16
  25. package/dist/{log-22e678c5.esm.js → log-5409ee89.esm.js} +15 -8
  26. package/dist/{log-f196f85f.development.esm.js → log-557e5fa3.development.esm.js} +15 -8
  27. package/dist/{log-5e226275.cjs.js → log-74467f02.cjs.js} +15 -8
  28. package/dist/{log-641cd926.development.cjs.js → log-a56e34a9.development.cjs.js} +15 -8
  29. package/dist/{raise-89c581c4.development.esm.js → raise-0ff85b7b.development.esm.js} +109 -43
  30. package/dist/{raise-8bc422d1.esm.js → raise-5d7ae4b7.esm.js} +109 -43
  31. package/dist/{raise-62704519.development.cjs.js → raise-6fb30f8b.development.cjs.js} +108 -42
  32. package/dist/{raise-34e25c2c.cjs.js → raise-746abff7.cjs.js} +108 -42
  33. package/dist/xstate.cjs.js +57 -5
  34. package/dist/xstate.cjs.mjs +1 -0
  35. package/dist/xstate.development.cjs.js +57 -5
  36. package/dist/xstate.development.cjs.mjs +1 -0
  37. package/dist/xstate.development.esm.js +59 -8
  38. package/dist/xstate.esm.js +59 -8
  39. package/dist/xstate.umd.min.js +1 -1
  40. package/dist/xstate.umd.min.js.map +1 -1
  41. package/guards/dist/xstate-guards.cjs.js +1 -1
  42. package/guards/dist/xstate-guards.development.cjs.js +1 -1
  43. package/guards/dist/xstate-guards.development.esm.js +1 -1
  44. package/guards/dist/xstate-guards.esm.js +1 -1
  45. package/package.json +1 -1
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var actors_dist_xstateActors = require('../actors/dist/xstate-actors.cjs.js');
6
- var guards_dist_xstateGuards = require('./raise-34e25c2c.cjs.js');
7
- var log = require('./log-5e226275.cjs.js');
6
+ var guards_dist_xstateGuards = require('./raise-746abff7.cjs.js');
7
+ var log = require('./log-74467f02.cjs.js');
8
8
  require('../dev/dist/xstate-dev.cjs.js');
9
9
 
10
10
  class SimulatedClock {
@@ -12,6 +12,8 @@ class SimulatedClock {
12
12
  this.timeouts = new Map();
13
13
  this._now = 0;
14
14
  this._id = 0;
15
+ this._flushing = false;
16
+ this._flushingInvalidated = false;
15
17
  }
16
18
  now() {
17
19
  return this._now;
@@ -20,6 +22,7 @@ class SimulatedClock {
20
22
  return this._id++;
21
23
  }
22
24
  setTimeout(fn, timeout) {
25
+ this._flushingInvalidated = this._flushing;
23
26
  const id = this.getId();
24
27
  this.timeouts.set(id, {
25
28
  start: this.now(),
@@ -29,6 +32,7 @@ class SimulatedClock {
29
32
  return id;
30
33
  }
31
34
  clearTimeout(id) {
35
+ this._flushingInvalidated = this._flushing;
32
36
  this.timeouts.delete(id);
33
37
  }
34
38
  set(time) {
@@ -39,16 +43,29 @@ class SimulatedClock {
39
43
  this.flushTimeouts();
40
44
  }
41
45
  flushTimeouts() {
42
- [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
46
+ if (this._flushing) {
47
+ this._flushingInvalidated = true;
48
+ return;
49
+ }
50
+ this._flushing = true;
51
+ const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
43
52
  const endA = timeoutA.start + timeoutA.timeout;
44
53
  const endB = timeoutB.start + timeoutB.timeout;
45
54
  return endB > endA ? -1 : 1;
46
- }).forEach(([id, timeout]) => {
55
+ });
56
+ for (const [id, timeout] of sorted) {
57
+ if (this._flushingInvalidated) {
58
+ this._flushingInvalidated = false;
59
+ this._flushing = false;
60
+ this.flushTimeouts();
61
+ return;
62
+ }
47
63
  if (this.now() - timeout.start >= timeout.timeout) {
48
64
  this.timeouts.delete(id);
49
65
  timeout.fn.call(null);
50
66
  }
51
- });
67
+ }
68
+ this._flushing = false;
52
69
  }
53
70
  increment(ms) {
54
71
  this._now += ms;
@@ -390,6 +407,7 @@ class StateMachine {
390
407
  this.version = this.config.version;
391
408
  this.transition = this.transition.bind(this);
392
409
  this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
410
+ this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
393
411
  this.restoreSnapshot = this.restoreSnapshot.bind(this);
394
412
  this.start = this.start.bind(this);
395
413
  this.root = new StateNode(config, {
@@ -692,6 +710,39 @@ function setup({
692
710
  };
693
711
  }
694
712
 
713
+ /**
714
+ * Returns a promise that resolves to the `output` of the actor when it is done.
715
+ *
716
+ * @example
717
+ * ```ts
718
+ * const machine = createMachine({
719
+ * // ...
720
+ * output: {
721
+ * count: 42
722
+ * }
723
+ * });
724
+ *
725
+ * const actor = createActor(machine);
726
+ *
727
+ * actor.start();
728
+ *
729
+ * const output = await toPromise(actor);
730
+ *
731
+ * console.log(output);
732
+ * // logs { count: 42 }
733
+ * ```
734
+ */
735
+ function toPromise(actor) {
736
+ return new Promise((resolve, reject) => {
737
+ actor.subscribe({
738
+ complete: () => {
739
+ resolve(actor.getSnapshot().output);
740
+ },
741
+ error: reject
742
+ });
743
+ });
744
+ }
745
+
695
746
  exports.createEmptyActor = actors_dist_xstateActors.createEmptyActor;
696
747
  exports.fromCallback = actors_dist_xstateActors.fromCallback;
697
748
  exports.fromEventObservable = actors_dist_xstateActors.fromEventObservable;
@@ -728,4 +779,5 @@ exports.StateMachine = StateMachine;
728
779
  exports.StateNode = StateNode;
729
780
  exports.createMachine = createMachine;
730
781
  exports.setup = setup;
782
+ exports.toPromise = toPromise;
731
783
  exports.waitFor = waitFor;
@@ -35,5 +35,6 @@ export {
35
35
  stop,
36
36
  stopChild,
37
37
  toObserver,
38
+ toPromise,
38
39
  waitFor
39
40
  } from "./xstate.cjs.js";
@@ -3,8 +3,8 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var actors_dist_xstateActors = require('../actors/dist/xstate-actors.development.cjs.js');
6
- var guards_dist_xstateGuards = require('./raise-62704519.development.cjs.js');
7
- var log = require('./log-641cd926.development.cjs.js');
6
+ var guards_dist_xstateGuards = require('./raise-6fb30f8b.development.cjs.js');
7
+ var log = require('./log-a56e34a9.development.cjs.js');
8
8
  require('../dev/dist/xstate-dev.development.cjs.js');
9
9
 
10
10
  class SimulatedClock {
@@ -12,6 +12,8 @@ class SimulatedClock {
12
12
  this.timeouts = new Map();
13
13
  this._now = 0;
14
14
  this._id = 0;
15
+ this._flushing = false;
16
+ this._flushingInvalidated = false;
15
17
  }
16
18
  now() {
17
19
  return this._now;
@@ -20,6 +22,7 @@ class SimulatedClock {
20
22
  return this._id++;
21
23
  }
22
24
  setTimeout(fn, timeout) {
25
+ this._flushingInvalidated = this._flushing;
23
26
  const id = this.getId();
24
27
  this.timeouts.set(id, {
25
28
  start: this.now(),
@@ -29,6 +32,7 @@ class SimulatedClock {
29
32
  return id;
30
33
  }
31
34
  clearTimeout(id) {
35
+ this._flushingInvalidated = this._flushing;
32
36
  this.timeouts.delete(id);
33
37
  }
34
38
  set(time) {
@@ -39,16 +43,29 @@ class SimulatedClock {
39
43
  this.flushTimeouts();
40
44
  }
41
45
  flushTimeouts() {
42
- [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
46
+ if (this._flushing) {
47
+ this._flushingInvalidated = true;
48
+ return;
49
+ }
50
+ this._flushing = true;
51
+ const sorted = [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
43
52
  const endA = timeoutA.start + timeoutA.timeout;
44
53
  const endB = timeoutB.start + timeoutB.timeout;
45
54
  return endB > endA ? -1 : 1;
46
- }).forEach(([id, timeout]) => {
55
+ });
56
+ for (const [id, timeout] of sorted) {
57
+ if (this._flushingInvalidated) {
58
+ this._flushingInvalidated = false;
59
+ this._flushing = false;
60
+ this.flushTimeouts();
61
+ return;
62
+ }
47
63
  if (this.now() - timeout.start >= timeout.timeout) {
48
64
  this.timeouts.delete(id);
49
65
  timeout.fn.call(null);
50
66
  }
51
- });
67
+ }
68
+ this._flushing = false;
52
69
  }
53
70
  increment(ms) {
54
71
  this._now += ms;
@@ -390,6 +407,7 @@ class StateMachine {
390
407
  this.version = this.config.version;
391
408
  this.transition = this.transition.bind(this);
392
409
  this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
410
+ this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
393
411
  this.restoreSnapshot = this.restoreSnapshot.bind(this);
394
412
  this.start = this.start.bind(this);
395
413
  this.root = new StateNode(config, {
@@ -698,6 +716,39 @@ function setup({
698
716
  };
699
717
  }
700
718
 
719
+ /**
720
+ * Returns a promise that resolves to the `output` of the actor when it is done.
721
+ *
722
+ * @example
723
+ * ```ts
724
+ * const machine = createMachine({
725
+ * // ...
726
+ * output: {
727
+ * count: 42
728
+ * }
729
+ * });
730
+ *
731
+ * const actor = createActor(machine);
732
+ *
733
+ * actor.start();
734
+ *
735
+ * const output = await toPromise(actor);
736
+ *
737
+ * console.log(output);
738
+ * // logs { count: 42 }
739
+ * ```
740
+ */
741
+ function toPromise(actor) {
742
+ return new Promise((resolve, reject) => {
743
+ actor.subscribe({
744
+ complete: () => {
745
+ resolve(actor.getSnapshot().output);
746
+ },
747
+ error: reject
748
+ });
749
+ });
750
+ }
751
+
701
752
  exports.createEmptyActor = actors_dist_xstateActors.createEmptyActor;
702
753
  exports.fromCallback = actors_dist_xstateActors.fromCallback;
703
754
  exports.fromEventObservable = actors_dist_xstateActors.fromEventObservable;
@@ -734,4 +785,5 @@ exports.StateMachine = StateMachine;
734
785
  exports.StateNode = StateNode;
735
786
  exports.createMachine = createMachine;
736
787
  exports.setup = setup;
788
+ exports.toPromise = toPromise;
737
789
  exports.waitFor = waitFor;
@@ -35,5 +35,6 @@ export {
35
35
  stop,
36
36
  stopChild,
37
37
  toObserver,
38
+ toPromise,
38
39
  waitFor
39
40
  } from "./xstate.development.cjs.js";
@@ -1,8 +1,8 @@
1
1
  export { createEmptyActor, fromCallback, fromEventObservable, fromObservable, fromPromise, fromTransition } from '../actors/dist/xstate-actors.development.esm.js';
2
- 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 isStateId, w as getStateNodeByPath, x as getPersistedSnapshot, y as resolveReferencedActor, z as createActor, $ as $$ACTOR_TYPE } from './raise-89c581c4.development.esm.js';
3
- export { A as Actor, G as __unsafe_getAllOwnEventDescriptors, H as and, L as cancel, z as createActor, j as getStateNodes, B as interpret, C as isMachineSnapshot, D as matchesState, I as not, J as or, E as pathToStateValue, M as raise, O as spawnChild, K as stateIn, P as stop, Q as stopChild, F as toObserver } from './raise-89c581c4.development.esm.js';
4
- import { a as assign } from './log-f196f85f.development.esm.js';
5
- export { S as SpecialTargets, a as assign, e as enqueueActions, f as forwardTo, l as log, s as sendParent, b as sendTo } from './log-f196f85f.development.esm.js';
2
+ 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 isStateId, w as getStateNodeByPath, x as getPersistedSnapshot, y as resolveReferencedActor, z as createActor, $ as $$ACTOR_TYPE } from './raise-0ff85b7b.development.esm.js';
3
+ export { A as Actor, H as __unsafe_getAllOwnEventDescriptors, D as and, L as cancel, z as createActor, j as getStateNodes, B as interpret, C as isMachineSnapshot, I as matchesState, E as not, F as or, J as pathToStateValue, M as raise, O as spawnChild, G as stateIn, P as stop, Q as stopChild, K as toObserver } from './raise-0ff85b7b.development.esm.js';
4
+ import { a as assign } from './log-557e5fa3.development.esm.js';
5
+ export { S as SpecialTargets, a as assign, e as enqueueActions, f as forwardTo, l as log, s as sendParent, b as sendTo } from './log-557e5fa3.development.esm.js';
6
6
  import '../dev/dist/xstate-dev.development.esm.js';
7
7
 
8
8
  class SimulatedClock {
@@ -10,6 +10,8 @@ class SimulatedClock {
10
10
  this.timeouts = new Map();
11
11
  this._now = 0;
12
12
  this._id = 0;
13
+ this._flushing = false;
14
+ this._flushingInvalidated = false;
13
15
  }
14
16
  now() {
15
17
  return this._now;
@@ -18,6 +20,7 @@ class SimulatedClock {
18
20
  return this._id++;
19
21
  }
20
22
  setTimeout(fn, timeout) {
23
+ this._flushingInvalidated = this._flushing;
21
24
  const id = this.getId();
22
25
  this.timeouts.set(id, {
23
26
  start: this.now(),
@@ -27,6 +30,7 @@ class SimulatedClock {
27
30
  return id;
28
31
  }
29
32
  clearTimeout(id) {
33
+ this._flushingInvalidated = this._flushing;
30
34
  this.timeouts.delete(id);
31
35
  }
32
36
  set(time) {
@@ -37,16 +41,29 @@ class SimulatedClock {
37
41
  this.flushTimeouts();
38
42
  }
39
43
  flushTimeouts() {
40
- [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
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]) => {
41
50
  const endA = timeoutA.start + timeoutA.timeout;
42
51
  const endB = timeoutB.start + timeoutB.timeout;
43
52
  return endB > endA ? -1 : 1;
44
- }).forEach(([id, timeout]) => {
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
+ }
45
61
  if (this.now() - timeout.start >= timeout.timeout) {
46
62
  this.timeouts.delete(id);
47
63
  timeout.fn.call(null);
48
64
  }
49
- });
65
+ }
66
+ this._flushing = false;
50
67
  }
51
68
  increment(ms) {
52
69
  this._now += ms;
@@ -388,6 +405,7 @@ class StateMachine {
388
405
  this.version = this.config.version;
389
406
  this.transition = this.transition.bind(this);
390
407
  this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
408
+ this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
391
409
  this.restoreSnapshot = this.restoreSnapshot.bind(this);
392
410
  this.start = this.start.bind(this);
393
411
  this.root = new StateNode(config, {
@@ -696,4 +714,37 @@ function setup({
696
714
  };
697
715
  }
698
716
 
699
- export { SimulatedClock, StateMachine, StateNode, createMachine, setup, waitFor };
717
+ /**
718
+ * Returns a promise that resolves to the `output` of the actor when it is done.
719
+ *
720
+ * @example
721
+ * ```ts
722
+ * const machine = createMachine({
723
+ * // ...
724
+ * output: {
725
+ * count: 42
726
+ * }
727
+ * });
728
+ *
729
+ * const actor = createActor(machine);
730
+ *
731
+ * actor.start();
732
+ *
733
+ * const output = await toPromise(actor);
734
+ *
735
+ * console.log(output);
736
+ * // logs { count: 42 }
737
+ * ```
738
+ */
739
+ function toPromise(actor) {
740
+ return new Promise((resolve, reject) => {
741
+ actor.subscribe({
742
+ complete: () => {
743
+ resolve(actor.getSnapshot().output);
744
+ },
745
+ error: reject
746
+ });
747
+ });
748
+ }
749
+
750
+ export { SimulatedClock, StateMachine, StateNode, createMachine, setup, toPromise, waitFor };
@@ -1,8 +1,8 @@
1
1
  export { createEmptyActor, fromCallback, fromEventObservable, fromObservable, fromPromise, fromTransition } from '../actors/dist/xstate-actors.esm.js';
2
- 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 isStateId, w as getStateNodeByPath, x as getPersistedSnapshot, y as resolveReferencedActor, z as createActor, $ as $$ACTOR_TYPE } from './raise-8bc422d1.esm.js';
3
- export { A as Actor, G as __unsafe_getAllOwnEventDescriptors, H as and, L as cancel, z as createActor, j as getStateNodes, B as interpret, C as isMachineSnapshot, D as matchesState, I as not, J as or, E as pathToStateValue, M as raise, O as spawnChild, K as stateIn, P as stop, Q as stopChild, F as toObserver } from './raise-8bc422d1.esm.js';
4
- import { a as assign } from './log-22e678c5.esm.js';
5
- export { S as SpecialTargets, a as assign, e as enqueueActions, f as forwardTo, l as log, s as sendParent, b as sendTo } from './log-22e678c5.esm.js';
2
+ 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 isStateId, w as getStateNodeByPath, x as getPersistedSnapshot, y as resolveReferencedActor, z as createActor, $ as $$ACTOR_TYPE } from './raise-5d7ae4b7.esm.js';
3
+ export { A as Actor, H as __unsafe_getAllOwnEventDescriptors, D as and, L as cancel, z as createActor, j as getStateNodes, B as interpret, C as isMachineSnapshot, I as matchesState, E as not, F as or, J as pathToStateValue, M as raise, O as spawnChild, G as stateIn, P as stop, Q as stopChild, K as toObserver } from './raise-5d7ae4b7.esm.js';
4
+ import { a as assign } from './log-5409ee89.esm.js';
5
+ export { S as SpecialTargets, a as assign, e as enqueueActions, f as forwardTo, l as log, s as sendParent, b as sendTo } from './log-5409ee89.esm.js';
6
6
  import '../dev/dist/xstate-dev.esm.js';
7
7
 
8
8
  class SimulatedClock {
@@ -10,6 +10,8 @@ class SimulatedClock {
10
10
  this.timeouts = new Map();
11
11
  this._now = 0;
12
12
  this._id = 0;
13
+ this._flushing = false;
14
+ this._flushingInvalidated = false;
13
15
  }
14
16
  now() {
15
17
  return this._now;
@@ -18,6 +20,7 @@ class SimulatedClock {
18
20
  return this._id++;
19
21
  }
20
22
  setTimeout(fn, timeout) {
23
+ this._flushingInvalidated = this._flushing;
21
24
  const id = this.getId();
22
25
  this.timeouts.set(id, {
23
26
  start: this.now(),
@@ -27,6 +30,7 @@ class SimulatedClock {
27
30
  return id;
28
31
  }
29
32
  clearTimeout(id) {
33
+ this._flushingInvalidated = this._flushing;
30
34
  this.timeouts.delete(id);
31
35
  }
32
36
  set(time) {
@@ -37,16 +41,29 @@ class SimulatedClock {
37
41
  this.flushTimeouts();
38
42
  }
39
43
  flushTimeouts() {
40
- [...this.timeouts].sort(([_idA, timeoutA], [_idB, timeoutB]) => {
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]) => {
41
50
  const endA = timeoutA.start + timeoutA.timeout;
42
51
  const endB = timeoutB.start + timeoutB.timeout;
43
52
  return endB > endA ? -1 : 1;
44
- }).forEach(([id, timeout]) => {
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
+ }
45
61
  if (this.now() - timeout.start >= timeout.timeout) {
46
62
  this.timeouts.delete(id);
47
63
  timeout.fn.call(null);
48
64
  }
49
- });
65
+ }
66
+ this._flushing = false;
50
67
  }
51
68
  increment(ms) {
52
69
  this._now += ms;
@@ -388,6 +405,7 @@ class StateMachine {
388
405
  this.version = this.config.version;
389
406
  this.transition = this.transition.bind(this);
390
407
  this.getInitialSnapshot = this.getInitialSnapshot.bind(this);
408
+ this.getPersistedSnapshot = this.getPersistedSnapshot.bind(this);
391
409
  this.restoreSnapshot = this.restoreSnapshot.bind(this);
392
410
  this.start = this.start.bind(this);
393
411
  this.root = new StateNode(config, {
@@ -690,4 +708,37 @@ function setup({
690
708
  };
691
709
  }
692
710
 
693
- export { SimulatedClock, StateMachine, StateNode, createMachine, setup, waitFor };
711
+ /**
712
+ * Returns a promise that resolves to the `output` of the actor when it is done.
713
+ *
714
+ * @example
715
+ * ```ts
716
+ * const machine = createMachine({
717
+ * // ...
718
+ * output: {
719
+ * count: 42
720
+ * }
721
+ * });
722
+ *
723
+ * const actor = createActor(machine);
724
+ *
725
+ * actor.start();
726
+ *
727
+ * const output = await toPromise(actor);
728
+ *
729
+ * console.log(output);
730
+ * // logs { count: 42 }
731
+ * ```
732
+ */
733
+ function toPromise(actor) {
734
+ return new Promise((resolve, reject) => {
735
+ actor.subscribe({
736
+ complete: () => {
737
+ resolve(actor.getSnapshot().output);
738
+ },
739
+ error: reject
740
+ });
741
+ });
742
+ }
743
+
744
+ export { SimulatedClock, StateMachine, StateNode, createMachine, setup, toPromise, waitFor };