xstate 5.0.2 → 5.1.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 (41) 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 +1 -1
  20. package/dist/declarations/src/interpreter.d.ts +4 -8
  21. package/dist/declarations/src/system.d.ts +32 -2
  22. package/dist/declarations/src/types.d.ts +11 -16
  23. package/dist/{log-f196f85f.development.esm.js → log-2cbae8e5.development.esm.js} +12 -8
  24. package/dist/{log-22e678c5.esm.js → log-6e1b5540.esm.js} +12 -8
  25. package/dist/{log-641cd926.development.cjs.js → log-aa639ffe.development.cjs.js} +12 -8
  26. package/dist/{log-5e226275.cjs.js → log-dca6710c.cjs.js} +12 -8
  27. package/dist/{raise-62704519.development.cjs.js → raise-23324e7c.development.cjs.js} +86 -38
  28. package/dist/{raise-8bc422d1.esm.js → raise-525f78b5.esm.js} +86 -38
  29. package/dist/{raise-34e25c2c.cjs.js → raise-9f420f96.cjs.js} +86 -38
  30. package/dist/{raise-89c581c4.development.esm.js → raise-dd0e6cd2.development.esm.js} +86 -38
  31. package/dist/xstate.cjs.js +23 -5
  32. package/dist/xstate.development.cjs.js +23 -5
  33. package/dist/xstate.development.esm.js +25 -7
  34. package/dist/xstate.esm.js +25 -7
  35. package/dist/xstate.umd.min.js +1 -1
  36. package/dist/xstate.umd.min.js.map +1 -1
  37. package/guards/dist/xstate-guards.cjs.js +1 -1
  38. package/guards/dist/xstate-guards.development.cjs.js +1 -1
  39. package/guards/dist/xstate-guards.development.esm.js +1 -1
  40. package/guards/dist/xstate-guards.esm.js +1 -1
  41. package/package.json +1 -1
@@ -1,16 +1,13 @@
1
1
  import { symbolObservable } from "./symbolObservable.js";
2
+ import { AnyActorSystem, Clock } from "./system.js";
2
3
  import { AreAllImplementationsAssumedToBeProvided, MissingImplementationsError } from "./typegenTypes.js";
3
- import type { ActorSystem, AnyActorLogic, AnyStateMachine, EventFromLogic, SnapshotFrom, Snapshot } from "./types.js";
4
- import { ActorRef, EventObject, InteropSubscribable, ActorOptions, Observer, Subscription } from "./types.js";
4
+ import type { AnyActorLogic, AnyStateMachine, EventFromLogic, Snapshot, SnapshotFrom } from "./types.js";
5
+ import { ActorOptions, ActorRef, EventObject, InteropSubscribable, Observer, Subscription } from "./types.js";
5
6
  export declare const $$ACTOR_TYPE = 1;
6
7
  export type SnapshotListener<TLogic extends AnyActorLogic> = (snapshot: SnapshotFrom<TLogic>) => void;
7
8
  export type EventListener<TEvent extends EventObject = EventObject> = (event: TEvent) => void;
8
9
  export type Listener = () => void;
9
10
  export type ErrorListener = (error: any) => void;
10
- export interface Clock {
11
- setTimeout(fn: (...args: any[]) => void, timeout: number): any;
12
- clearTimeout(id: any): void;
13
- }
14
11
  export declare enum ProcessingStatus {
15
12
  NotStarted = 0,
16
13
  Running = 1,
@@ -35,7 +32,6 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorRef<Sna
35
32
  */
36
33
  id: string;
37
34
  private mailbox;
38
- private delayedEventsMap;
39
35
  private observers;
40
36
  private logger;
41
37
  _parent?: ActorRef<any, any>;
@@ -50,7 +46,7 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorRef<Sna
50
46
  /**
51
47
  * The system to which this actor belongs.
52
48
  */
53
- system: ActorSystem<any>;
49
+ system: AnyActorSystem;
54
50
  private _doneEvent?;
55
51
  src: string | AnyActorLogic;
56
52
  /**
@@ -1,5 +1,35 @@
1
- import { AnyEventObject, ActorSystem, ActorSystemInfo, AnyActorRef, Snapshot } from "./types.js";
2
- export declare function createSystem<T extends ActorSystemInfo>(rootActor: AnyActorRef): ActorSystem<T>;
1
+ import { AnyEventObject, ActorSystemInfo, AnyActorRef, Observer, Snapshot, EventObject } from "./types.js";
2
+ export interface ScheduledEvent {
3
+ id: string;
4
+ event: EventObject;
5
+ startedAt: number;
6
+ delay: number;
7
+ source: AnyActorRef;
8
+ target: AnyActorRef;
9
+ }
10
+ export interface Clock {
11
+ setTimeout(fn: (...args: any[]) => void, timeout: number): any;
12
+ clearTimeout(id: any): void;
13
+ }
14
+ export interface Scheduler {
15
+ schedule(source: AnyActorRef, target: AnyActorRef, event: EventObject, delay: number, id: string | undefined): void;
16
+ cancel(source: AnyActorRef, id: string): void;
17
+ cancelAll(actorRef: AnyActorRef): void;
18
+ }
19
+ export interface ActorSystem<T extends ActorSystemInfo> {
20
+ get: <K extends keyof T['actors']>(key: K) => T['actors'][K] | undefined;
21
+ inspect: (observer: Observer<InspectionEvent>) => void;
22
+ scheduler: Scheduler;
23
+ getSnapshot: () => {
24
+ _scheduledEvents: Record<string, ScheduledEvent>;
25
+ };
26
+ start: () => void;
27
+ }
28
+ export type AnyActorSystem = ActorSystem<any>;
29
+ export declare function createSystem<T extends ActorSystemInfo>(rootActor: AnyActorRef, options: {
30
+ clock: Clock;
31
+ snapshot?: unknown;
32
+ }): ActorSystem<T>;
3
33
  export interface BaseInspectionEventProperties {
4
34
  rootId: string;
5
35
  /**
@@ -1,13 +1,13 @@
1
- import type { StateNode } from "./StateNode.js";
2
1
  import type { MachineSnapshot } from "./State.js";
3
- import type { Clock, Actor } from "./interpreter.js";
4
2
  import type { StateMachine } from "./StateMachine.js";
5
- import { TypegenDisabled, ResolveTypegenMeta, TypegenConstraint, MarkAllImplementationsAsProvided, AreAllImplementationsAssumedToBeProvided } from "./typegenTypes.js";
3
+ import type { StateNode } from "./StateNode.js";
4
+ import { AssignArgs } from "./actions/assign.js";
6
5
  import { PromiseActorLogic } from "./actors/promise.js";
7
6
  import { Guard, GuardPredicate, UnknownGuard } from "./guards.js";
7
+ import type { Actor } from "./interpreter.js";
8
8
  import { Spawner } from "./spawn.js";
9
- import { AssignArgs } from "./actions/assign.js";
10
- import { InspectionEvent } from './system.js';
9
+ import { AnyActorSystem, InspectionEvent, Clock } from './system.js';
10
+ import { AreAllImplementationsAssumedToBeProvided, MarkAllImplementationsAsProvided, ResolveTypegenMeta, TypegenConstraint, TypegenDisabled } from "./typegenTypes.js";
11
11
  export type Identity<T> = {
12
12
  [K in keyof T]: T[K];
13
13
  };
@@ -82,7 +82,7 @@ export interface UnifiedArg<TContext extends MachineContext, TExpressionEvent ex
82
82
  event: TExpressionEvent;
83
83
  self: ActorRef<MachineSnapshot<TContext, TEvent, Record<string, AnyActorRef | undefined>, // TODO: this should be replaced with `TChildren`
84
84
  StateValue, string, unknown>, TEvent>;
85
- system: ActorSystem<any>;
85
+ system: AnyActorSystem;
86
86
  }
87
87
  export type MachineContext = Record<string, any>;
88
88
  export interface ActionArgs<TContext extends MachineContext, TExpressionEvent extends EventObject, TEvent extends EventObject> extends UnifiedArg<TContext, TExpressionEvent, TEvent> {
@@ -746,7 +746,7 @@ export interface ActorRef<TSnapshot extends Snapshot<unknown>, TEvent extends Ev
746
746
  stop: () => void;
747
747
  toJSON?: () => any;
748
748
  _parent?: ActorRef<any, any>;
749
- system?: ActorSystem<any>;
749
+ system: AnyActorSystem;
750
750
  src: string | AnyActorLogic;
751
751
  }
752
752
  export type AnyActorRef = ActorRef<any, any>;
@@ -756,7 +756,7 @@ export type DevToolsAdapter = (service: AnyActor) => void;
756
756
  /**
757
757
  * @deprecated Use `Actor<T>` instead.
758
758
  */
759
- export type InterpreterFrom<T extends AnyStateMachine | ((...args: any[]) => AnyStateMachine)> = ReturnTypeOrValue<T> extends StateMachine<infer TContext, infer TEvent, infer TChildren, infer _TActor, infer _TAction, infer _TGuard, infer _TDelay, infer TStateValue, infer TTag, infer TInput, infer TOutput, infer TResolvedTypesMeta> ? Actor<ActorLogic<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TResolvedTypesMeta>, TEvent, TInput, ActorSystem<any>>> : never;
759
+ export type InterpreterFrom<T extends AnyStateMachine | ((...args: any[]) => AnyStateMachine)> = ReturnTypeOrValue<T> extends StateMachine<infer TContext, infer TEvent, infer TChildren, infer _TActor, infer _TAction, infer _TGuard, infer _TDelay, infer TStateValue, infer TTag, infer TInput, infer TOutput, infer TResolvedTypesMeta> ? Actor<ActorLogic<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TResolvedTypesMeta>, TEvent, TInput, AnyActorSystem>> : never;
760
760
  export type MachineImplementationsFrom<T extends AnyStateMachine | ((...args: any[]) => AnyStateMachine), TRequireMissingImplementations extends boolean = false> = ReturnTypeOrValue<T> extends StateMachine<infer TContext, infer _TEvent, infer _TChildren, infer _TActor, infer _TAction, infer _TGuard, infer _TDelay, infer _TStateValue, infer _TTag, infer _TInput, infer _TOutput, infer TResolvedTypesMeta> ? InternalMachineImplementations<TContext, TResolvedTypesMeta, TRequireMissingImplementations> : never;
761
761
  export type __ResolvedTypesMetaFrom<T> = T extends StateMachine<any, // context
762
762
  any, // event
@@ -769,7 +769,7 @@ any, // tag
769
769
  any, // input
770
770
  any, // output
771
771
  infer TResolvedTypesMeta> ? TResolvedTypesMeta : never;
772
- export interface ActorScope<TSnapshot extends Snapshot<unknown>, TEvent extends EventObject, TSystem extends ActorSystem<any> = ActorSystem<any>> {
772
+ export interface ActorScope<TSnapshot extends Snapshot<unknown>, TEvent extends EventObject, TSystem extends AnyActorSystem = AnyActorSystem> {
773
773
  self: ActorRef<TSnapshot, TEvent>;
774
774
  id: string;
775
775
  sessionId: string;
@@ -806,7 +806,7 @@ export type Snapshot<TOutput> = {
806
806
  */
807
807
  export interface ActorLogic<in out TSnapshot extends Snapshot<unknown>, // it's invariant because it's also part of `ActorScope["self"]["getSnapshot"]`
808
808
  in out TEvent extends EventObject, // it's invariant because it's also part of `ActorScope["self"]["send"]`
809
- in TInput = NonReducibleUnknown, TSystem extends ActorSystem<any> = ActorSystem<any>> {
809
+ in TInput = NonReducibleUnknown, TSystem extends AnyActorSystem = AnyActorSystem> {
810
810
  /** The initial setup/configuration used to create the actor logic. */
811
811
  config?: unknown;
812
812
  /**
@@ -851,7 +851,7 @@ export type AnyActorLogic = ActorLogic<any, // snapshot
851
851
  any, // event
852
852
  any, // input
853
853
  any>;
854
- export type UnknownActorLogic = ActorLogic<any, any, never, ActorSystem<any>>;
854
+ export type UnknownActorLogic = ActorLogic<any, any, never, AnyActorSystem>;
855
855
  export type SnapshotFrom<T> = ReturnTypeOrValue<T> extends infer R ? R extends ActorRef<infer TSnapshot, infer _> ? TSnapshot : R extends Actor<infer TLogic> ? SnapshotFrom<TLogic> : R extends ActorLogic<infer _, infer __, infer ___, infer ____> ? ReturnType<R['transition']> : R extends ActorScope<infer TSnapshot, infer _, infer __> ? TSnapshot : never : never;
856
856
  export type EventFromLogic<TLogic extends ActorLogic<any, any, any, any>> = TLogic extends ActorLogic<infer _, infer TEvent, infer __, infer _____> ? TEvent : never;
857
857
  type ResolveEventType<T> = ReturnTypeOrValue<T> extends infer R ? R extends StateMachine<infer _TContext, infer TEvent, infer _TChildren, infer _TActor, infer _TAction, infer _TGuard, infer _TDelay, infer _TStateValue, infer _TTag, infer _TInput, infer _TOutput, infer _TResolvedTypesMeta> ? TEvent : R extends MachineSnapshot<infer _TContext, infer TEvent, infer _TChildren, infer _TTag, infer _TOutput, infer _TResolvedTypesMeta> ? TEvent : R extends ActorRef<infer _, infer TEvent> ? TEvent : never : never;
@@ -870,11 +870,6 @@ export type TagsFrom<TMachine extends AnyStateMachine> = Parameters<StateFrom<TM
870
870
  export interface ActorSystemInfo {
871
871
  actors: Record<string, AnyActorRef>;
872
872
  }
873
- export interface ActorSystem<T extends ActorSystemInfo> {
874
- get: <K extends keyof T['actors']>(key: K) => T['actors'][K] | undefined;
875
- inspect: (observer: Observer<InspectionEvent>) => void;
876
- }
877
- export type AnyActorSystem = ActorSystem<any>;
878
873
  export type RequiredActorOptions<TActor extends ProvidedActor> = (undefined extends TActor['id'] ? never : 'id') | (undefined extends InputFrom<TActor['logic']> ? never : 'input');
879
874
  type ExtractLiteralString<T extends string | undefined> = T extends string ? string extends T ? never : T : never;
880
875
  type ToConcreteChildren<TActor extends ProvidedActor> = {
@@ -1,4 +1,4 @@
1
- import { R as ProcessingStatus, y as resolveReferencedActor, z as createActor, T as cloneMachineSnapshot, U as XSTATE_ERROR, V as createErrorActorEvent, e as evaluateGuard, L as cancel, M as raise, O as spawnChild, Q as stopChild } from './raise-89c581c4.development.esm.js';
1
+ import { R as ProcessingStatus, y as resolveReferencedActor, z as createActor, T as cloneMachineSnapshot, U as XSTATE_ERROR, V as createErrorActorEvent, e as evaluateGuard, L as cancel, M as raise, O as spawnChild, Q as stopChild } from './raise-dd0e6cd2.development.esm.js';
2
2
 
3
3
  function createSpawner(actorScope, {
4
4
  machine,
@@ -217,19 +217,23 @@ function retryResolveSendTo(_, snapshot, params) {
217
217
  }
218
218
  }
219
219
  function executeSendTo(actorScope, params) {
220
- if (typeof params.delay === 'number') {
221
- actorScope.self.delaySend(params);
222
- return;
223
- }
224
-
225
220
  // this forms an outgoing events queue
226
221
  // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
227
222
  actorScope.defer(() => {
228
223
  const {
229
224
  to,
230
- event
225
+ event,
226
+ delay,
227
+ id
231
228
  } = params;
232
- actorScope?.system._relay(actorScope.self, to, event.type === XSTATE_ERROR ? createErrorActorEvent(actorScope.self.id, event.data) : event);
229
+ if (typeof delay === 'number') {
230
+ actorScope.system.scheduler.schedule(actorScope.self, to, event, delay, id);
231
+ return;
232
+ }
233
+ actorScope.system._relay(actorScope.self,
234
+ // at this point, in a deferred task, it should already be mutated by retryResolveSendTo
235
+ // if it initially started as a string
236
+ to, event.type === XSTATE_ERROR ? createErrorActorEvent(actorScope.self.id, event.data) : event);
233
237
  });
234
238
  }
235
239
  /**
@@ -1,4 +1,4 @@
1
- import { R as ProcessingStatus, y as resolveReferencedActor, z as createActor, T as cloneMachineSnapshot, U as XSTATE_ERROR, V as createErrorActorEvent, e as evaluateGuard, L as cancel, M as raise, O as spawnChild, Q as stopChild } from './raise-8bc422d1.esm.js';
1
+ import { R as ProcessingStatus, y as resolveReferencedActor, z as createActor, T as cloneMachineSnapshot, U as XSTATE_ERROR, V as createErrorActorEvent, e as evaluateGuard, L as cancel, M as raise, O as spawnChild, Q as stopChild } from './raise-525f78b5.esm.js';
2
2
 
3
3
  function createSpawner(actorScope, {
4
4
  machine,
@@ -214,19 +214,23 @@ function retryResolveSendTo(_, snapshot, params) {
214
214
  }
215
215
  }
216
216
  function executeSendTo(actorScope, params) {
217
- if (typeof params.delay === 'number') {
218
- actorScope.self.delaySend(params);
219
- return;
220
- }
221
-
222
217
  // this forms an outgoing events queue
223
218
  // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
224
219
  actorScope.defer(() => {
225
220
  const {
226
221
  to,
227
- event
222
+ event,
223
+ delay,
224
+ id
228
225
  } = params;
229
- actorScope?.system._relay(actorScope.self, to, event.type === XSTATE_ERROR ? createErrorActorEvent(actorScope.self.id, event.data) : event);
226
+ if (typeof delay === 'number') {
227
+ actorScope.system.scheduler.schedule(actorScope.self, to, event, delay, id);
228
+ return;
229
+ }
230
+ actorScope.system._relay(actorScope.self,
231
+ // at this point, in a deferred task, it should already be mutated by retryResolveSendTo
232
+ // if it initially started as a string
233
+ to, event.type === XSTATE_ERROR ? createErrorActorEvent(actorScope.self.id, event.data) : event);
230
234
  });
231
235
  }
232
236
  /**
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-62704519.development.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-23324e7c.development.cjs.js');
4
4
 
5
5
  function createSpawner(actorScope, {
6
6
  machine,
@@ -219,19 +219,23 @@ function retryResolveSendTo(_, snapshot, params) {
219
219
  }
220
220
  }
221
221
  function executeSendTo(actorScope, params) {
222
- if (typeof params.delay === 'number') {
223
- actorScope.self.delaySend(params);
224
- return;
225
- }
226
-
227
222
  // this forms an outgoing events queue
228
223
  // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
229
224
  actorScope.defer(() => {
230
225
  const {
231
226
  to,
232
- event
227
+ event,
228
+ delay,
229
+ id
233
230
  } = params;
234
- actorScope?.system._relay(actorScope.self, to, event.type === guards_dist_xstateGuards.XSTATE_ERROR ? guards_dist_xstateGuards.createErrorActorEvent(actorScope.self.id, event.data) : event);
231
+ if (typeof delay === 'number') {
232
+ actorScope.system.scheduler.schedule(actorScope.self, to, event, delay, id);
233
+ return;
234
+ }
235
+ actorScope.system._relay(actorScope.self,
236
+ // at this point, in a deferred task, it should already be mutated by retryResolveSendTo
237
+ // if it initially started as a string
238
+ to, event.type === guards_dist_xstateGuards.XSTATE_ERROR ? guards_dist_xstateGuards.createErrorActorEvent(actorScope.self.id, event.data) : event);
235
239
  });
236
240
  }
237
241
  /**
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var guards_dist_xstateGuards = require('./raise-34e25c2c.cjs.js');
3
+ var guards_dist_xstateGuards = require('./raise-9f420f96.cjs.js');
4
4
 
5
5
  function createSpawner(actorScope, {
6
6
  machine,
@@ -216,19 +216,23 @@ function retryResolveSendTo(_, snapshot, params) {
216
216
  }
217
217
  }
218
218
  function executeSendTo(actorScope, params) {
219
- if (typeof params.delay === 'number') {
220
- actorScope.self.delaySend(params);
221
- return;
222
- }
223
-
224
219
  // this forms an outgoing events queue
225
220
  // thanks to that the recipient actors are able to read the *updated* snapshot value of the sender
226
221
  actorScope.defer(() => {
227
222
  const {
228
223
  to,
229
- event
224
+ event,
225
+ delay,
226
+ id
230
227
  } = params;
231
- actorScope?.system._relay(actorScope.self, to, event.type === guards_dist_xstateGuards.XSTATE_ERROR ? guards_dist_xstateGuards.createErrorActorEvent(actorScope.self.id, event.data) : event);
228
+ if (typeof delay === 'number') {
229
+ actorScope.system.scheduler.schedule(actorScope.self, to, event, delay, id);
230
+ return;
231
+ }
232
+ actorScope.system._relay(actorScope.self,
233
+ // at this point, in a deferred task, it should already be mutated by retryResolveSendTo
234
+ // if it initially started as a string
235
+ to, event.type === guards_dist_xstateGuards.XSTATE_ERROR ? guards_dist_xstateGuards.createErrorActorEvent(actorScope.self.id, event.data) : event);
232
236
  });
233
237
  }
234
238
  /**
@@ -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));
@@ -643,6 +709,9 @@ class Actor {
643
709
  this._error(this._snapshot.error);
644
710
  return this;
645
711
  }
712
+ if (!this._parent) {
713
+ this.system.start();
714
+ }
646
715
  if (this.logic.start) {
647
716
  try {
648
717
  this.logic.start(this._snapshot, this._actorScope);
@@ -771,9 +840,7 @@ class Actor {
771
840
  }
772
841
 
773
842
  // Cancel all delayed events
774
- for (const key of Object.keys(this.delayedEventsMap)) {
775
- this.clock.clearTimeout(this.delayedEventsMap[key]);
776
- }
843
+ this.system.scheduler.cancelAll(this);
777
844
 
778
845
  // TODO: mailbox.reset
779
846
  this.mailbox.clear();
@@ -813,35 +880,6 @@ class Actor {
813
880
  }
814
881
  this.system._relay(undefined, this, event);
815
882
  }
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
883
  attachDevTools() {
846
884
  const {
847
885
  devTools
@@ -953,7 +991,9 @@ function resolveCancel(_, snapshot, actionArgs, actionParams, {
953
991
  return [snapshot, resolvedSendId];
954
992
  }
955
993
  function executeCancel(actorScope, resolvedSendId) {
956
- actorScope.self.cancel(resolvedSendId);
994
+ actorScope.defer(() => {
995
+ actorScope.system.scheduler.cancel(actorScope.self, resolvedSendId);
996
+ });
957
997
  }
958
998
  /**
959
999
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -2344,8 +2384,16 @@ function resolveRaise(_, snapshot, args, actionParams, {
2344
2384
  }];
2345
2385
  }
2346
2386
  function executeRaise(actorScope, params) {
2347
- if (typeof params.delay === 'number') {
2348
- actorScope.self.delaySend(params);
2387
+ const {
2388
+ event,
2389
+ delay,
2390
+ id
2391
+ } = params;
2392
+ if (typeof delay === 'number') {
2393
+ actorScope.defer(() => {
2394
+ const self = actorScope.self;
2395
+ actorScope.system.scheduler.schedule(self, self, event, delay, id);
2396
+ });
2349
2397
  return;
2350
2398
  }
2351
2399
  }