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
@@ -126,13 +126,56 @@ function reportUnhandledError(err) {
126
126
 
127
127
  const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
128
128
 
129
+ function createScheduledEventId(actorRef, id) {
130
+ return `${actorRef.sessionId}.${id}`;
131
+ }
129
132
  let idCounter = 0;
130
- function createSystem(rootActor) {
133
+ function createSystem(rootActor, options) {
131
134
  const children = new Map();
132
135
  const keyedActors = new Map();
133
136
  const reverseKeyedActors = new WeakMap();
134
137
  const observers = new Set();
138
+ const timerMap = {};
139
+ const clock = options.clock;
140
+ const scheduler = {
141
+ schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
142
+ const scheduledEvent = {
143
+ source,
144
+ target,
145
+ event,
146
+ delay,
147
+ id,
148
+ startedAt: Date.now()
149
+ };
150
+ const scheduledEventId = createScheduledEventId(source, id);
151
+ system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
152
+ const timeout = clock.setTimeout(() => {
153
+ delete timerMap[scheduledEventId];
154
+ delete system._snapshot._scheduledEvents[scheduledEventId];
155
+ system._relay(source, target, event);
156
+ }, delay);
157
+ timerMap[scheduledEventId] = timeout;
158
+ },
159
+ cancel: (source, id) => {
160
+ const scheduledEventId = createScheduledEventId(source, id);
161
+ const timeout = timerMap[scheduledEventId];
162
+ delete timerMap[scheduledEventId];
163
+ delete system._snapshot._scheduledEvents[scheduledEventId];
164
+ clock.clearTimeout(timeout);
165
+ },
166
+ cancelAll: actorRef => {
167
+ for (const scheduledEventId in system._snapshot._scheduledEvents) {
168
+ const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
169
+ if (scheduledEvent.source === actorRef) {
170
+ scheduler.cancel(actorRef, scheduledEvent.id);
171
+ }
172
+ }
173
+ }
174
+ };
135
175
  const system = {
176
+ _snapshot: {
177
+ _scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
178
+ },
136
179
  _bookId: () => `x:${idCounter++}`,
137
180
  _register: (sessionId, actorRef) => {
138
181
  children.set(sessionId, actorRef);
@@ -175,6 +218,28 @@ function createSystem(rootActor) {
175
218
  event
176
219
  });
177
220
  target._send(event);
221
+ },
222
+ scheduler,
223
+ getSnapshot: () => {
224
+ return {
225
+ _scheduledEvents: {
226
+ ...system._snapshot._scheduledEvents
227
+ }
228
+ };
229
+ },
230
+ start: () => {
231
+ const scheduledEvets = system._snapshot._scheduledEvents;
232
+ system._snapshot._scheduledEvents = {};
233
+ for (const scheduledId in scheduledEvets) {
234
+ const {
235
+ source,
236
+ target,
237
+ event,
238
+ delay,
239
+ id
240
+ } = scheduledEvets[scheduledId];
241
+ scheduler.schedule(source, target, event, delay, id);
242
+ }
178
243
  }
179
244
  };
180
245
  return system;
@@ -360,7 +425,6 @@ class Actor {
360
425
  */
361
426
  this.id = void 0;
362
427
  this.mailbox = new Mailbox(this._process.bind(this));
363
- this.delayedEventsMap = {};
364
428
  this.observers = new Set();
365
429
  this.logger = void 0;
366
430
  /** @internal */
@@ -397,7 +461,9 @@ class Actor {
397
461
  systemId,
398
462
  inspect
399
463
  } = resolvedOptions;
400
- this.system = parent?.system ?? createSystem(this);
464
+ this.system = parent ? parent.system : createSystem(this, {
465
+ clock
466
+ });
401
467
  if (inspect && !parent) {
402
468
  // Always inspect at the system-level
403
469
  this.system.inspect(toObserver(inspect));
@@ -578,10 +644,28 @@ class Actor {
578
644
  if (this._processingStatus !== ProcessingStatus.Stopped) {
579
645
  this.observers.add(observer);
580
646
  } else {
581
- try {
582
- observer.complete?.();
583
- } catch (err) {
584
- reportUnhandledError(err);
647
+ switch (this._snapshot.status) {
648
+ case 'done':
649
+ try {
650
+ observer.complete?.();
651
+ } catch (err) {
652
+ reportUnhandledError(err);
653
+ }
654
+ break;
655
+ case 'error':
656
+ {
657
+ const err = this._snapshot.error;
658
+ if (!observer.error) {
659
+ reportUnhandledError(err);
660
+ } else {
661
+ try {
662
+ observer.error(err);
663
+ } catch (err) {
664
+ reportUnhandledError(err);
665
+ }
666
+ }
667
+ break;
668
+ }
585
669
  }
586
670
  }
587
671
  return {
@@ -638,6 +722,9 @@ class Actor {
638
722
  this._error(this._snapshot.error);
639
723
  return this;
640
724
  }
725
+ if (!this._parent) {
726
+ this.system.start();
727
+ }
641
728
  if (this.logic.start) {
642
729
  try {
643
730
  this.logic.start(this._snapshot, this._actorScope);
@@ -766,9 +853,7 @@ class Actor {
766
853
  }
767
854
 
768
855
  // Cancel all delayed events
769
- for (const key of Object.keys(this.delayedEventsMap)) {
770
- this.clock.clearTimeout(this.delayedEventsMap[key]);
771
- }
856
+ this.system.scheduler.cancelAll(this);
772
857
 
773
858
  // TODO: mailbox.reset
774
859
  this.mailbox.clear();
@@ -800,35 +885,6 @@ class Actor {
800
885
  send(event) {
801
886
  this.system._relay(undefined, this, event);
802
887
  }
803
-
804
- /**
805
- * TODO: figure out a way to do this within the machine
806
- * @internal
807
- */
808
- delaySend(params) {
809
- const {
810
- event,
811
- id,
812
- delay
813
- } = params;
814
- const timerId = this.clock.setTimeout(() => {
815
- this.system._relay(this, params.to ?? this, event);
816
- }, delay);
817
-
818
- // TODO: consider the rehydration story here
819
- if (id) {
820
- this.delayedEventsMap[id] = timerId;
821
- }
822
- }
823
-
824
- /**
825
- * TODO: figure out a way to do this within the machine
826
- * @internal
827
- */
828
- cancel(sendId) {
829
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
830
- delete this.delayedEventsMap[sendId];
831
- }
832
888
  attachDevTools() {
833
889
  const {
834
890
  devTools
@@ -940,7 +996,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
940
996
  return [snapshot, resolvedSendId];
941
997
  }
942
998
  function executeCancel(actorScope, resolvedSendId) {
943
- actorScope.self.cancel(resolvedSendId);
999
+ actorScope.defer(() => {
1000
+ actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
1001
+ });
944
1002
  }
945
1003
  /**
946
1004
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -2291,8 +2349,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
2291
2349
  }];
2292
2350
  }
2293
2351
  function executeRaise(actorScope, params) {
2294
- if (typeof params.delay === 'number') {
2295
- actorScope.self.delaySend(params);
2352
+ const {
2353
+ event,
2354
+ delay,
2355
+ id
2356
+ } = params;
2357
+ if (typeof delay === 'number') {
2358
+ actorScope.defer(() => {
2359
+ const self = actorScope.self;
2360
+ actorScope.system.scheduler.schedule(self, self, event, delay, id);
2361
+ });
2296
2362
  return;
2297
2363
  }
2298
2364
  }
@@ -2314,4 +2380,4 @@ function raise(eventOrExpr, options) {
2314
2380
  return raise;
2315
2381
  }
2316
2382
 
2317
- 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, spawnChild as O, stop as P, stopChild 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, getPersistedSnapshot as x, resolveReferencedActor as y, createActor as z };
2383
+ export { $$ACTOR_TYPE as $, Actor as A, interpret as B, isMachineSnapshot as C, and as D, not as E, or as F, stateIn as G, getAllOwnEventDescriptors as H, matchesState as I, pathToStateValue as J, toObserver as K, cancel as L, raise as M, NULL_EVENT as N, spawnChild as O, stop as P, stopChild 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, getPersistedSnapshot as x, resolveReferencedActor as y, createActor as z };
@@ -128,13 +128,56 @@ function reportUnhandledError(err) {
128
128
 
129
129
  const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
130
130
 
131
+ function createScheduledEventId(actorRef, id) {
132
+ return `${actorRef.sessionId}.${id}`;
133
+ }
131
134
  let idCounter = 0;
132
- function createSystem(rootActor) {
135
+ function createSystem(rootActor, options) {
133
136
  const children = new Map();
134
137
  const keyedActors = new Map();
135
138
  const reverseKeyedActors = new WeakMap();
136
139
  const observers = new Set();
140
+ const timerMap = {};
141
+ const clock = options.clock;
142
+ const scheduler = {
143
+ schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
144
+ const scheduledEvent = {
145
+ source,
146
+ target,
147
+ event,
148
+ delay,
149
+ id,
150
+ startedAt: Date.now()
151
+ };
152
+ const scheduledEventId = createScheduledEventId(source, id);
153
+ system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
154
+ const timeout = clock.setTimeout(() => {
155
+ delete timerMap[scheduledEventId];
156
+ delete system._snapshot._scheduledEvents[scheduledEventId];
157
+ system._relay(source, target, event);
158
+ }, delay);
159
+ timerMap[scheduledEventId] = timeout;
160
+ },
161
+ cancel: (source, id) => {
162
+ const scheduledEventId = createScheduledEventId(source, id);
163
+ const timeout = timerMap[scheduledEventId];
164
+ delete timerMap[scheduledEventId];
165
+ delete system._snapshot._scheduledEvents[scheduledEventId];
166
+ clock.clearTimeout(timeout);
167
+ },
168
+ cancelAll: actorRef => {
169
+ for (const scheduledEventId in system._snapshot._scheduledEvents) {
170
+ const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
171
+ if (scheduledEvent.source === actorRef) {
172
+ scheduler.cancel(actorRef, scheduledEvent.id);
173
+ }
174
+ }
175
+ }
176
+ };
137
177
  const system = {
178
+ _snapshot: {
179
+ _scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
180
+ },
138
181
  _bookId: () => `x:${idCounter++}`,
139
182
  _register: (sessionId, actorRef) => {
140
183
  children.set(sessionId, actorRef);
@@ -177,6 +220,28 @@ function createSystem(rootActor) {
177
220
  event
178
221
  });
179
222
  target._send(event);
223
+ },
224
+ scheduler,
225
+ getSnapshot: () => {
226
+ return {
227
+ _scheduledEvents: {
228
+ ...system._snapshot._scheduledEvents
229
+ }
230
+ };
231
+ },
232
+ start: () => {
233
+ const scheduledEvets = system._snapshot._scheduledEvents;
234
+ system._snapshot._scheduledEvents = {};
235
+ for (const scheduledId in scheduledEvets) {
236
+ const {
237
+ source,
238
+ target,
239
+ event,
240
+ delay,
241
+ id
242
+ } = scheduledEvets[scheduledId];
243
+ scheduler.schedule(source, target, event, delay, id);
244
+ }
180
245
  }
181
246
  };
182
247
  return system;
@@ -365,7 +430,6 @@ class Actor {
365
430
  */
366
431
  this.id = void 0;
367
432
  this.mailbox = new Mailbox(this._process.bind(this));
368
- this.delayedEventsMap = {};
369
433
  this.observers = new Set();
370
434
  this.logger = void 0;
371
435
  /** @internal */
@@ -402,7 +466,9 @@ class Actor {
402
466
  systemId,
403
467
  inspect
404
468
  } = resolvedOptions;
405
- this.system = parent?.system ?? createSystem(this);
469
+ this.system = parent ? parent.system : createSystem(this, {
470
+ clock
471
+ });
406
472
  if (inspect && !parent) {
407
473
  // Always inspect at the system-level
408
474
  this.system.inspect(toObserver(inspect));
@@ -583,10 +649,28 @@ class Actor {
583
649
  if (this._processingStatus !== ProcessingStatus.Stopped) {
584
650
  this.observers.add(observer);
585
651
  } else {
586
- try {
587
- observer.complete?.();
588
- } catch (err) {
589
- reportUnhandledError(err);
652
+ switch (this._snapshot.status) {
653
+ case 'done':
654
+ try {
655
+ observer.complete?.();
656
+ } catch (err) {
657
+ reportUnhandledError(err);
658
+ }
659
+ break;
660
+ case 'error':
661
+ {
662
+ const err = this._snapshot.error;
663
+ if (!observer.error) {
664
+ reportUnhandledError(err);
665
+ } else {
666
+ try {
667
+ observer.error(err);
668
+ } catch (err) {
669
+ reportUnhandledError(err);
670
+ }
671
+ }
672
+ break;
673
+ }
590
674
  }
591
675
  }
592
676
  return {
@@ -643,6 +727,9 @@ class Actor {
643
727
  this._error(this._snapshot.error);
644
728
  return this;
645
729
  }
730
+ if (!this._parent) {
731
+ this.system.start();
732
+ }
646
733
  if (this.logic.start) {
647
734
  try {
648
735
  this.logic.start(this._snapshot, this._actorScope);
@@ -771,9 +858,7 @@ class Actor {
771
858
  }
772
859
 
773
860
  // Cancel all delayed events
774
- for (const key of Object.keys(this.delayedEventsMap)) {
775
- this.clock.clearTimeout(this.delayedEventsMap[key]);
776
- }
861
+ this.system.scheduler.cancelAll(this);
777
862
 
778
863
  // TODO: mailbox.reset
779
864
  this.mailbox.clear();
@@ -813,35 +898,6 @@ class Actor {
813
898
  }
814
899
  this.system._relay(undefined, this, event);
815
900
  }
816
-
817
- /**
818
- * TODO: figure out a way to do this within the machine
819
- * @internal
820
- */
821
- delaySend(params) {
822
- const {
823
- event,
824
- id,
825
- delay
826
- } = params;
827
- const timerId = this.clock.setTimeout(() => {
828
- this.system._relay(this, params.to ?? this, event);
829
- }, delay);
830
-
831
- // TODO: consider the rehydration story here
832
- if (id) {
833
- this.delayedEventsMap[id] = timerId;
834
- }
835
- }
836
-
837
- /**
838
- * TODO: figure out a way to do this within the machine
839
- * @internal
840
- */
841
- cancel(sendId) {
842
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
843
- delete this.delayedEventsMap[sendId];
844
- }
845
901
  attachDevTools() {
846
902
  const {
847
903
  devTools
@@ -953,7 +1009,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
953
1009
  return [snapshot, resolvedSendId];
954
1010
  }
955
1011
  function executeCancel(actorScope, resolvedSendId) {
956
- actorScope.self.cancel(resolvedSendId);
1012
+ actorScope.defer(() => {
1013
+ actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
1014
+ });
957
1015
  }
958
1016
  /**
959
1017
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -2344,8 +2402,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
2344
2402
  }];
2345
2403
  }
2346
2404
  function executeRaise(actorScope, params) {
2347
- if (typeof params.delay === 'number') {
2348
- actorScope.self.delaySend(params);
2405
+ const {
2406
+ event,
2407
+ delay,
2408
+ id
2409
+ } = params;
2410
+ if (typeof delay === 'number') {
2411
+ actorScope.defer(() => {
2412
+ const self = actorScope.self;
2413
+ actorScope.system.scheduler.schedule(self, self, event, delay, id);
2414
+ });
2349
2415
  return;
2350
2416
  }
2351
2417
  }
@@ -128,13 +128,56 @@ function reportUnhandledError(err) {
128
128
 
129
129
  const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
130
130
 
131
+ function createScheduledEventId(actorRef, id) {
132
+ return `${actorRef.sessionId}.${id}`;
133
+ }
131
134
  let idCounter = 0;
132
- function createSystem(rootActor) {
135
+ function createSystem(rootActor, options) {
133
136
  const children = new Map();
134
137
  const keyedActors = new Map();
135
138
  const reverseKeyedActors = new WeakMap();
136
139
  const observers = new Set();
140
+ const timerMap = {};
141
+ const clock = options.clock;
142
+ const scheduler = {
143
+ schedule: (source, target, event, delay, id = Math.random().toString(36).slice(2)) => {
144
+ const scheduledEvent = {
145
+ source,
146
+ target,
147
+ event,
148
+ delay,
149
+ id,
150
+ startedAt: Date.now()
151
+ };
152
+ const scheduledEventId = createScheduledEventId(source, id);
153
+ system._snapshot._scheduledEvents[scheduledEventId] = scheduledEvent;
154
+ const timeout = clock.setTimeout(() => {
155
+ delete timerMap[scheduledEventId];
156
+ delete system._snapshot._scheduledEvents[scheduledEventId];
157
+ system._relay(source, target, event);
158
+ }, delay);
159
+ timerMap[scheduledEventId] = timeout;
160
+ },
161
+ cancel: (source, id) => {
162
+ const scheduledEventId = createScheduledEventId(source, id);
163
+ const timeout = timerMap[scheduledEventId];
164
+ delete timerMap[scheduledEventId];
165
+ delete system._snapshot._scheduledEvents[scheduledEventId];
166
+ clock.clearTimeout(timeout);
167
+ },
168
+ cancelAll: actorRef => {
169
+ for (const scheduledEventId in system._snapshot._scheduledEvents) {
170
+ const scheduledEvent = system._snapshot._scheduledEvents[scheduledEventId];
171
+ if (scheduledEvent.source === actorRef) {
172
+ scheduler.cancel(actorRef, scheduledEvent.id);
173
+ }
174
+ }
175
+ }
176
+ };
137
177
  const system = {
178
+ _snapshot: {
179
+ _scheduledEvents: (options?.snapshot && options.snapshot.scheduler) ?? {}
180
+ },
138
181
  _bookId: () => `x:${idCounter++}`,
139
182
  _register: (sessionId, actorRef) => {
140
183
  children.set(sessionId, actorRef);
@@ -177,6 +220,28 @@ function createSystem(rootActor) {
177
220
  event
178
221
  });
179
222
  target._send(event);
223
+ },
224
+ scheduler,
225
+ getSnapshot: () => {
226
+ return {
227
+ _scheduledEvents: {
228
+ ...system._snapshot._scheduledEvents
229
+ }
230
+ };
231
+ },
232
+ start: () => {
233
+ const scheduledEvets = system._snapshot._scheduledEvents;
234
+ system._snapshot._scheduledEvents = {};
235
+ for (const scheduledId in scheduledEvets) {
236
+ const {
237
+ source,
238
+ target,
239
+ event,
240
+ delay,
241
+ id
242
+ } = scheduledEvets[scheduledId];
243
+ scheduler.schedule(source, target, event, delay, id);
244
+ }
180
245
  }
181
246
  };
182
247
  return system;
@@ -362,7 +427,6 @@ class Actor {
362
427
  */
363
428
  this.id = void 0;
364
429
  this.mailbox = new Mailbox(this._process.bind(this));
365
- this.delayedEventsMap = {};
366
430
  this.observers = new Set();
367
431
  this.logger = void 0;
368
432
  /** @internal */
@@ -399,7 +463,9 @@ class Actor {
399
463
  systemId,
400
464
  inspect
401
465
  } = resolvedOptions;
402
- this.system = parent?.system ?? createSystem(this);
466
+ this.system = parent ? parent.system : createSystem(this, {
467
+ clock
468
+ });
403
469
  if (inspect && !parent) {
404
470
  // Always inspect at the system-level
405
471
  this.system.inspect(toObserver(inspect));
@@ -580,10 +646,28 @@ class Actor {
580
646
  if (this._processingStatus !== ProcessingStatus.Stopped) {
581
647
  this.observers.add(observer);
582
648
  } else {
583
- try {
584
- observer.complete?.();
585
- } catch (err) {
586
- reportUnhandledError(err);
649
+ switch (this._snapshot.status) {
650
+ case 'done':
651
+ try {
652
+ observer.complete?.();
653
+ } catch (err) {
654
+ reportUnhandledError(err);
655
+ }
656
+ break;
657
+ case 'error':
658
+ {
659
+ const err = this._snapshot.error;
660
+ if (!observer.error) {
661
+ reportUnhandledError(err);
662
+ } else {
663
+ try {
664
+ observer.error(err);
665
+ } catch (err) {
666
+ reportUnhandledError(err);
667
+ }
668
+ }
669
+ break;
670
+ }
587
671
  }
588
672
  }
589
673
  return {
@@ -640,6 +724,9 @@ class Actor {
640
724
  this._error(this._snapshot.error);
641
725
  return this;
642
726
  }
727
+ if (!this._parent) {
728
+ this.system.start();
729
+ }
643
730
  if (this.logic.start) {
644
731
  try {
645
732
  this.logic.start(this._snapshot, this._actorScope);
@@ -768,9 +855,7 @@ class Actor {
768
855
  }
769
856
 
770
857
  // Cancel all delayed events
771
- for (const key of Object.keys(this.delayedEventsMap)) {
772
- this.clock.clearTimeout(this.delayedEventsMap[key]);
773
- }
858
+ this.system.scheduler.cancelAll(this);
774
859
 
775
860
  // TODO: mailbox.reset
776
861
  this.mailbox.clear();
@@ -802,35 +887,6 @@ class Actor {
802
887
  send(event) {
803
888
  this.system._relay(undefined, this, event);
804
889
  }
805
-
806
- /**
807
- * TODO: figure out a way to do this within the machine
808
- * @internal
809
- */
810
- delaySend(params) {
811
- const {
812
- event,
813
- id,
814
- delay
815
- } = params;
816
- const timerId = this.clock.setTimeout(() => {
817
- this.system._relay(this, params.to ?? this, event);
818
- }, delay);
819
-
820
- // TODO: consider the rehydration story here
821
- if (id) {
822
- this.delayedEventsMap[id] = timerId;
823
- }
824
- }
825
-
826
- /**
827
- * TODO: figure out a way to do this within the machine
828
- * @internal
829
- */
830
- cancel(sendId) {
831
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
832
- delete this.delayedEventsMap[sendId];
833
- }
834
890
  attachDevTools() {
835
891
  const {
836
892
  devTools
@@ -942,7 +998,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
942
998
  return [snapshot, resolvedSendId];
943
999
  }
944
1000
  function executeCancel(actorScope, resolvedSendId) {
945
- actorScope.self.cancel(resolvedSendId);
1001
+ actorScope.defer(() => {
1002
+ actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
1003
+ });
946
1004
  }
947
1005
  /**
948
1006
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -2293,8 +2351,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
2293
2351
  }];
2294
2352
  }
2295
2353
  function executeRaise(actorScope, params) {
2296
- if (typeof params.delay === 'number') {
2297
- actorScope.self.delaySend(params);
2354
+ const {
2355
+ event,
2356
+ delay,
2357
+ id
2358
+ } = params;
2359
+ if (typeof delay === 'number') {
2360
+ actorScope.defer(() => {
2361
+ const self = actorScope.self;
2362
+ actorScope.system.scheduler.schedule(self, self, event, delay, id);
2363
+ });
2298
2364
  return;
2299
2365
  }
2300
2366
  }