xstate 6.0.0-alpha.23 → 6.0.0-alpha.25

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 (40) hide show
  1. package/dist/{StateMachine-022864fd.esm.js → StateMachine-69278d2c.esm.js} +87 -50
  2. package/dist/{StateMachine-53114dce.development.cjs.js → StateMachine-ac1167f3.development.cjs.js} +90 -53
  3. package/dist/{StateMachine-aad57180.cjs.js → StateMachine-b20d5a53.cjs.js} +87 -50
  4. package/dist/{StateMachine-d2247245.development.esm.js → StateMachine-bf4ec0f1.development.esm.js} +90 -53
  5. package/dist/declarations/src/StateMachine.d.ts +11 -11
  6. package/dist/declarations/src/StateNode.d.ts +2 -2
  7. package/dist/declarations/src/createMachine.d.ts +6 -6
  8. package/dist/declarations/src/createMachineFromConfig.d.ts +6 -5
  9. package/dist/declarations/src/fsm.d.ts +2 -2
  10. package/dist/declarations/src/index.d.ts +1 -1
  11. package/dist/declarations/src/serialize.d.ts +3 -3
  12. package/dist/declarations/src/setup.d.ts +43 -43
  13. package/dist/declarations/src/spawn.d.ts +1 -1
  14. package/dist/declarations/src/stateUtils.d.ts +3 -1
  15. package/dist/declarations/src/types.d.ts +71 -49
  16. package/dist/declarations/src/types.v6.d.ts +33 -31
  17. package/dist/declarations/src/utils.d.ts +1 -0
  18. package/dist/{index-3609e096.esm.js → index-036a773f.esm.js} +282 -76
  19. package/dist/{index-41c0375c.development.cjs.js → index-1ad8a761.development.cjs.js} +286 -75
  20. package/dist/{index-f5407323.development.esm.js → index-b90ebcd4.development.esm.js} +282 -76
  21. package/dist/{index-434fac23.cjs.js → index-f58cc498.cjs.js} +286 -75
  22. package/dist/xstate-actors.cjs.js +1 -1
  23. package/dist/xstate-actors.development.cjs.js +1 -1
  24. package/dist/xstate-actors.development.esm.js +1 -1
  25. package/dist/xstate-actors.esm.js +1 -1
  26. package/dist/xstate-actors.umd.min.js +1 -1
  27. package/dist/xstate-actors.umd.min.js.map +1 -1
  28. package/dist/xstate-graph.cjs.js +9 -13
  29. package/dist/xstate-graph.development.cjs.js +9 -13
  30. package/dist/xstate-graph.development.esm.js +9 -13
  31. package/dist/xstate-graph.esm.js +9 -13
  32. package/dist/xstate-graph.umd.min.js +1 -1
  33. package/dist/xstate-graph.umd.min.js.map +1 -1
  34. package/dist/xstate.cjs.js +58 -52
  35. package/dist/xstate.development.cjs.js +58 -52
  36. package/dist/xstate.development.esm.js +60 -54
  37. package/dist/xstate.esm.js +60 -54
  38. package/dist/xstate.umd.min.js +1 -1
  39. package/dist/xstate.umd.min.js.map +1 -1
  40. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
- import { M as setSnapshotActorRef, N as getSnapshotActorRef, O as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, P as mapValues, t as toArray, Q as createInvokeId, R as getDelayedTransitions, U as evaluateCandidate, V as formatTransition, W as NULL_EVENT, Y as toTransitionConfigArray, Z as createInvokeTimeoutEvent, _ as getCandidates, $ as formatRouteTransitions, a0 as resolveStateValue, a1 as getAllStateNodes, s as getStateNodes, a2 as createMachineSnapshot, a3 as isInFinalState, j as macrostep, a4 as cloneMachineSnapshot, a5 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a6 as getTransitionResult, a7 as hasEffect, a8 as createErrorPlatformEvent, r as resolveActionsWithContext, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, a9 as toStatePath, aa as isStateId, ab as getStateNodeByPath, ac as getPersistedSnapshot, ad as resolveReferencedActor, ae as $$ACTOR_TYPE } from './index-3609e096.esm.js';
1
+ import { M as setSnapshotActorRef, N as getSnapshotActorRef, O as createSnapshotSystem, q as isMachineSnapshot, h as createActor, S as STATE_DELIMITER, P as mapValues, t as toArray, Q as createInvokeId, R as getDelayedTransitions, U as getEventDescriptorKey, V as evaluateCandidate, W as formatTransition, Y as NULL_EVENT, Z as toTransitionConfigArray, _ as createInvokeTimeoutEventId, $ as getCandidates, a0 as matchesActorSession, a1 as formatRouteTransitions, a2 as resolveStateValue, a3 as getAllStateNodes, s as getStateNodes, a4 as createMachineSnapshot, a5 as isInFinalState, j as macrostep, a6 as cloneMachineSnapshot, a7 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a8 as getTransitionResult, a9 as hasEffect, aa as createErrorPlatformEvent, r as resolveActionsWithContext, k as createInitEvent, l as createSpawnEffect, n as initialMicrostep, ab as toStatePath, ac as isStateId, ad as getStateNodeByPath, ae as getPersistedSnapshot, af as resolveReferencedActor, ag as createInvokeTimeoutEvent, ah as $$ACTOR_TYPE } from './index-036a773f.esm.js';
2
2
 
3
- function createSpawner(actorScope, actorSources, spawnedChildren) {
3
+ function createSpawner(actorScope, actors, spawnedChildren) {
4
4
  return (src, options) => {
5
- const referencedSrc = Object.entries(actorSources).find(([, logic]) => logic === src)?.[0];
5
+ const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
6
6
  const actor = actorScope.system.createActorRef(src, {
7
7
  id: options?.id,
8
8
  parent: actorScope.self,
@@ -45,7 +45,8 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
45
45
  const self = createActor(actorLogic, {
46
46
  _inert: true,
47
47
  ...(previousSelf ? {
48
- id: previousSelf.id
48
+ id: previousSelf.id,
49
+ _sessionId: previousSelf.sessionId
49
50
  } : {}),
50
51
  ...(system ? {
51
52
  _systemRef: {
@@ -182,8 +183,8 @@ class StateNode {
182
183
  */
183
184
  this.meta = void 0;
184
185
  /**
185
- * The output data sent with the "xstate.done.state._id_" event if this is a
186
- * final state node.
186
+ * The output data sent with the `xstate.done.state` event if this is a final
187
+ * state node.
187
188
  */
188
189
  this.output = void 0;
189
190
  /**
@@ -300,8 +301,7 @@ class StateNode {
300
301
 
301
302
  /** @internal */
302
303
  next(snapshot, event, self) {
303
- const eventType = event.type;
304
- const candidates = memo(this, `candidates-${eventType}`, () => getCandidates(this, eventType));
304
+ const candidates = memo(this, `candidates-${getEventDescriptorKey(event)}`, () => getCandidates(this, event));
305
305
  for (const candidate of candidates) {
306
306
  const guardPassed = evaluateCandidate(candidate, event, snapshot, this, self);
307
307
  if (guardPassed) {
@@ -342,6 +342,9 @@ function mapTransitionConfigs(transitionsConfig, mapper) {
342
342
  }
343
343
  function formatTransitions(stateNode) {
344
344
  const transitions = new Map();
345
+ const addTransitions = (descriptor, additions) => {
346
+ transitions.set(descriptor, [...(transitions.get(descriptor) ?? []), ...additions]);
347
+ };
345
348
  if (stateNode.config.on) {
346
349
  for (const descriptor of Object.keys(stateNode.config.on)) {
347
350
  if (descriptor === NULL_EVENT) {
@@ -352,20 +355,30 @@ function formatTransitions(stateNode) {
352
355
  }
353
356
  }
354
357
  if (stateNode.config.onDone) {
355
- const descriptor = `xstate.done.state.${stateNode.id}`;
356
- transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => formatTransition(stateNode, descriptor, transition)));
358
+ const descriptor = 'xstate.done.state';
359
+ addTransitions(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => formatTransition(stateNode, descriptor, {
360
+ ...transition,
361
+ matches: {
362
+ ...transition.matches,
363
+ stateId: stateNode.id
364
+ }
365
+ })));
357
366
  }
358
367
  if (stateNode.config.onError) {
359
368
  const descriptor = 'xstate.error.*';
360
369
  transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onError, transition => formatTransition(stateNode, descriptor, transition)));
361
370
  }
362
- const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventType) => formatTransition(stateNode, descriptor, {
371
+ const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventId, actorId) => formatTransition(stateNode, descriptor, {
372
+ matches: {
373
+ actorId
374
+ },
375
+ _eventMatcher: (event, snapshot) => matchesActorSession(event, snapshot, actorId),
363
376
  to: (_args, enq) => {
364
- enq.cancel(timeoutEventType);
377
+ enq.cancel(timeoutEventId);
365
378
  return {};
366
379
  }
367
380
  });
368
- const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventType) => {
381
+ const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventId) => {
369
382
  const {
370
383
  target,
371
384
  to,
@@ -396,11 +409,11 @@ function formatTransitions(stateNode) {
396
409
  });
397
410
  const result = to(args, trackingEnqueue);
398
411
  if (result !== undefined || didEnqueue) {
399
- enq.cancel(timeoutEventType);
412
+ enq.cancel(timeoutEventId);
400
413
  }
401
414
  return result;
402
415
  }
403
- enq.cancel(timeoutEventType);
416
+ enq.cancel(timeoutEventId);
404
417
  return {
405
418
  target,
406
419
  reenter
@@ -409,25 +422,39 @@ function formatTransitions(stateNode) {
409
422
  });
410
423
  };
411
424
  for (const invokeDef of stateNode.invoke) {
412
- const invokeTimeoutEventType = invokeDef.timeout !== undefined ? createInvokeTimeoutEvent(invokeDef.id).type : undefined;
425
+ const withInvokeMatch = transition => ({
426
+ ...transition,
427
+ matches: {
428
+ ...transition.matches,
429
+ actorId: invokeDef.id
430
+ },
431
+ _eventMatcher: (event, snapshot) => matchesActorSession(event, snapshot, invokeDef.id)
432
+ });
433
+ const invokeTimeoutEventId = invokeDef.timeout !== undefined ? createInvokeTimeoutEventId(invokeDef.id) : undefined;
413
434
  if (invokeDef.onDone) {
414
- const descriptor = `xstate.done.actor.${invokeDef.id}`;
415
- const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, transition => invokeTimeoutEventType ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventType) : formatTransition(stateNode, descriptor, transition));
416
- if (invokeTimeoutEventType) {
417
- invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventType));
435
+ const descriptor = 'xstate.done.actor';
436
+ const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, rawTransition => {
437
+ const transition = withInvokeMatch(rawTransition);
438
+ return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : formatTransition(stateNode, descriptor, transition);
439
+ });
440
+ if (invokeTimeoutEventId) {
441
+ invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id));
418
442
  }
419
- transitions.set(descriptor, invokeDoneTransitions);
420
- } else if (invokeTimeoutEventType) {
421
- const descriptor = `xstate.done.actor.${invokeDef.id}`;
422
- transitions.set(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventType)]);
443
+ addTransitions(descriptor, invokeDoneTransitions);
444
+ } else if (invokeTimeoutEventId) {
445
+ const descriptor = 'xstate.done.actor';
446
+ addTransitions(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id)]);
423
447
  }
424
448
  if (invokeDef.onError) {
425
- const descriptor = `xstate.error.actor.${invokeDef.id}`;
426
- transitions.set(descriptor, mapTransitionConfigs(invokeDef.onError, transition => invokeTimeoutEventType ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventType) : formatTransition(stateNode, descriptor, transition)));
449
+ const descriptor = 'xstate.error.actor';
450
+ addTransitions(descriptor, mapTransitionConfigs(invokeDef.onError, rawTransition => {
451
+ const transition = withInvokeMatch(rawTransition);
452
+ return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : formatTransition(stateNode, descriptor, transition);
453
+ }));
427
454
  }
428
455
  if (invokeDef.onSnapshot) {
429
- const descriptor = `xstate.snapshot.${invokeDef.id}`;
430
- transitions.set(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => formatTransition(stateNode, descriptor, transition)));
456
+ const descriptor = 'xstate.snapshot.actor';
457
+ addTransitions(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => formatTransition(stateNode, descriptor, withInvokeMatch(transition))));
431
458
  }
432
459
  }
433
460
  for (const delayedTransition of stateNode.after) {
@@ -497,12 +524,12 @@ function getEmptyCanActorScope() {
497
524
  }
498
525
  class StateMachine {
499
526
  constructor(/** The raw config used to create the machine. */
500
- config, implementations) {
527
+ config, sources) {
501
528
  this.config = config;
502
529
  /** The machine's own version. */
503
530
  this.version = void 0;
504
531
  this.schemas = void 0;
505
- this.implementations = void 0;
532
+ this.sources = void 0;
506
533
  /** Runtime options for machine execution. */
507
534
  this.options = void 0;
508
535
  /** @internal */
@@ -521,12 +548,12 @@ class StateMachine {
521
548
  */
522
549
  this._json = void 0;
523
550
  this.id = config.id || '(machine)';
524
- this.implementations = {
525
- actorSources: config.actorSources ?? {},
551
+ this.sources = {
552
+ actors: config.actors ?? {},
526
553
  actions: config.actions ?? {},
527
554
  delays: config.delays ?? {},
528
555
  guards: config.guards ?? {},
529
- ...implementations
556
+ ...sources
530
557
  };
531
558
  this.version = this.config.version;
532
559
  this.schemas = this.config.schemas;
@@ -553,38 +580,38 @@ class StateMachine {
553
580
  }
554
581
 
555
582
  /**
556
- * Clones this state machine with the provided implementations.
583
+ * Clones this state machine with the provided sources.
557
584
  *
558
- * @param implementations Options (`actions`, `guards`, `actorSources`,
559
- * `delays`) to recursively merge with the existing options.
560
- * @returns A new `StateMachine` instance with the provided implementations.
585
+ * @param sources Options (`actions`, `guards`, `actors`, `delays`) to
586
+ * recursively merge with the existing options.
587
+ * @returns A new `StateMachine` instance with the provided sources.
561
588
  */
562
- provide(implementations) {
589
+ provide(sources) {
563
590
  const {
564
591
  actions,
565
592
  guards,
566
- actorSources,
593
+ actors,
567
594
  delays
568
- } = this.implementations;
595
+ } = this.sources;
569
596
  const provided = new StateMachine(this.config, {
570
597
  actions: {
571
598
  ...actions,
572
- ...implementations.actions
599
+ ...sources.actions
573
600
  },
574
601
  guards: {
575
602
  ...guards,
576
- ...implementations.guards
603
+ ...sources.guards
577
604
  },
578
- actorSources: {
579
- ...actorSources,
580
- ...implementations.actorSources
605
+ actors: {
606
+ ...actors,
607
+ ...sources.actors
581
608
  },
582
609
  delays: {
583
610
  ...delays,
584
- ...implementations.delays
611
+ ...sources.delays
585
612
  }
586
613
  });
587
- // Providing implementations does not change the serializable definition.
614
+ // Providing sources does not change the serializable definition.
588
615
  provided._json = this._json;
589
616
  return provided;
590
617
  }
@@ -775,12 +802,12 @@ class StateMachine {
775
802
  }, this, actorScope.self);
776
803
  if (typeof context === 'function') {
777
804
  const children = {};
778
- const spawn = createSpawner(actorScope, this.implementations.actorSources, children);
805
+ const spawn = createSpawner(actorScope, this.sources.actors, children);
779
806
  const resolvedContext = context({
780
807
  spawn,
781
808
  input: initEvent.input,
782
809
  self: actorScope.self,
783
- actorSources: this.implementations.actorSources
810
+ actors: this.sources.actors
784
811
  });
785
812
  const [nextState] = resolveActionsWithContext(preInitial, initEvent, actorScope, []);
786
813
  if (resolvedContext) {
@@ -883,7 +910,8 @@ class StateMachine {
883
910
  const src = actorData.src;
884
911
  const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
885
912
  if (!logic) {
886
- continue;
913
+ const sourceId = typeof src === 'string' ? src : '<unknown>';
914
+ throw new Error(`Unable to restore child actor '${actorId}': child source '${sourceId}' is not provided in machine '${this.id}'.`);
887
915
  }
888
916
  const actor = resolvedActorScope.system.createActorRef(logic, {
889
917
  id: actorId,
@@ -901,6 +929,14 @@ class StateMachine {
901
929
  const timers = {};
902
930
  const persistedTimers = snapshotData.timers ?? {};
903
931
  for (const [id, timer] of Object.entries(persistedTimers)) {
932
+ let event = timer.event;
933
+ if (event.type === 'xstate.timeout.actor') {
934
+ const actorId = event.actorId;
935
+ const child = children[actorId];
936
+ if (child) {
937
+ event = createInvokeTimeoutEvent(actorId, child.sessionId);
938
+ }
939
+ }
904
940
  const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
905
941
  if (!target) {
906
942
  const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
@@ -908,6 +944,7 @@ class StateMachine {
908
944
  }
909
945
  timers[id] = {
910
946
  ...timer,
947
+ event,
911
948
  target
912
949
  };
913
950
  }
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var dist_xstateActors = require('./index-41c0375c.development.cjs.js');
3
+ var dist_xstateActors = require('./index-1ad8a761.development.cjs.js');
4
4
 
5
- function createSpawner(actorScope, actorSources, spawnedChildren) {
5
+ function createSpawner(actorScope, actors, spawnedChildren) {
6
6
  return (src, options) => {
7
- const referencedSrc = Object.entries(actorSources).find(([, logic]) => logic === src)?.[0];
7
+ const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
8
8
  const actor = actorScope.system.createActorRef(src, {
9
9
  id: options?.id,
10
10
  parent: actorScope.self,
@@ -47,7 +47,8 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
47
47
  const self = dist_xstateActors.createActor(actorLogic, {
48
48
  _inert: true,
49
49
  ...(previousSelf ? {
50
- id: previousSelf.id
50
+ id: previousSelf.id,
51
+ _sessionId: previousSelf.sessionId
51
52
  } : {}),
52
53
  ...(system ? {
53
54
  _systemRef: {
@@ -185,8 +186,8 @@ class StateNode {
185
186
  */
186
187
  this.meta = void 0;
187
188
  /**
188
- * The output data sent with the "xstate.done.state._id_" event if this is a
189
- * final state node.
189
+ * The output data sent with the `xstate.done.state` event if this is a final
190
+ * state node.
190
191
  */
191
192
  this.output = void 0;
192
193
  /**
@@ -303,8 +304,7 @@ class StateNode {
303
304
 
304
305
  /** @internal */
305
306
  next(snapshot, event, self) {
306
- const eventType = event.type;
307
- const candidates = memo(this, `candidates-${eventType}`, () => dist_xstateActors.getCandidates(this, eventType));
307
+ const candidates = memo(this, `candidates-${dist_xstateActors.getEventDescriptorKey(event)}`, () => dist_xstateActors.getCandidates(this, event));
308
308
  for (const candidate of candidates) {
309
309
  const guardPassed = dist_xstateActors.evaluateCandidate(candidate, event, snapshot, this, self);
310
310
  if (guardPassed) {
@@ -362,6 +362,9 @@ function mapTransitionConfigs(transitionsConfig, mapper) {
362
362
  }
363
363
  function formatTransitions(stateNode) {
364
364
  const transitions = new Map();
365
+ const addTransitions = (descriptor, additions) => {
366
+ transitions.set(descriptor, [...(transitions.get(descriptor) ?? []), ...additions]);
367
+ };
365
368
  if (stateNode.config.on) {
366
369
  for (const descriptor of Object.keys(stateNode.config.on)) {
367
370
  if (descriptor === dist_xstateActors.NULL_EVENT) {
@@ -372,20 +375,30 @@ function formatTransitions(stateNode) {
372
375
  }
373
376
  }
374
377
  if (stateNode.config.onDone) {
375
- const descriptor = `xstate.done.state.${stateNode.id}`;
376
- transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => dist_xstateActors.formatTransition(stateNode, descriptor, transition)));
378
+ const descriptor = 'xstate.done.state';
379
+ addTransitions(descriptor, mapTransitionConfigs(stateNode.config.onDone, transition => dist_xstateActors.formatTransition(stateNode, descriptor, {
380
+ ...transition,
381
+ matches: {
382
+ ...transition.matches,
383
+ stateId: stateNode.id
384
+ }
385
+ })));
377
386
  }
378
387
  if (stateNode.config.onError) {
379
388
  const descriptor = 'xstate.error.*';
380
389
  transitions.set(descriptor, mapTransitionConfigs(stateNode.config.onError, transition => dist_xstateActors.formatTransition(stateNode, descriptor, transition)));
381
390
  }
382
- const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventType) => dist_xstateActors.formatTransition(stateNode, descriptor, {
391
+ const createCancelInvokeTimeoutTransition = (descriptor, timeoutEventId, actorId) => dist_xstateActors.formatTransition(stateNode, descriptor, {
392
+ matches: {
393
+ actorId
394
+ },
395
+ _eventMatcher: (event, snapshot) => dist_xstateActors.matchesActorSession(event, snapshot, actorId),
383
396
  to: (_args, enq) => {
384
- enq.cancel(timeoutEventType);
397
+ enq.cancel(timeoutEventId);
385
398
  return {};
386
399
  }
387
400
  });
388
- const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventType) => {
401
+ const formatInvokeCompletionTransition = (descriptor, transitionConfig, timeoutEventId) => {
389
402
  const {
390
403
  target,
391
404
  to,
@@ -416,11 +429,11 @@ function formatTransitions(stateNode) {
416
429
  });
417
430
  const result = to(args, trackingEnqueue);
418
431
  if (result !== undefined || didEnqueue) {
419
- enq.cancel(timeoutEventType);
432
+ enq.cancel(timeoutEventId);
420
433
  }
421
434
  return result;
422
435
  }
423
- enq.cancel(timeoutEventType);
436
+ enq.cancel(timeoutEventId);
424
437
  return {
425
438
  target,
426
439
  reenter
@@ -429,25 +442,39 @@ function formatTransitions(stateNode) {
429
442
  });
430
443
  };
431
444
  for (const invokeDef of stateNode.invoke) {
432
- const invokeTimeoutEventType = invokeDef.timeout !== undefined ? dist_xstateActors.createInvokeTimeoutEvent(invokeDef.id).type : undefined;
445
+ const withInvokeMatch = transition => ({
446
+ ...transition,
447
+ matches: {
448
+ ...transition.matches,
449
+ actorId: invokeDef.id
450
+ },
451
+ _eventMatcher: (event, snapshot) => dist_xstateActors.matchesActorSession(event, snapshot, invokeDef.id)
452
+ });
453
+ const invokeTimeoutEventId = invokeDef.timeout !== undefined ? dist_xstateActors.createInvokeTimeoutEventId(invokeDef.id) : undefined;
433
454
  if (invokeDef.onDone) {
434
- const descriptor = `xstate.done.actor.${invokeDef.id}`;
435
- const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, transition => invokeTimeoutEventType ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventType) : dist_xstateActors.formatTransition(stateNode, descriptor, transition));
436
- if (invokeTimeoutEventType) {
437
- invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventType));
455
+ const descriptor = 'xstate.done.actor';
456
+ const invokeDoneTransitions = mapTransitionConfigs(invokeDef.onDone, rawTransition => {
457
+ const transition = withInvokeMatch(rawTransition);
458
+ return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : dist_xstateActors.formatTransition(stateNode, descriptor, transition);
459
+ });
460
+ if (invokeTimeoutEventId) {
461
+ invokeDoneTransitions.push(createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id));
438
462
  }
439
- transitions.set(descriptor, invokeDoneTransitions);
440
- } else if (invokeTimeoutEventType) {
441
- const descriptor = `xstate.done.actor.${invokeDef.id}`;
442
- transitions.set(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventType)]);
463
+ addTransitions(descriptor, invokeDoneTransitions);
464
+ } else if (invokeTimeoutEventId) {
465
+ const descriptor = 'xstate.done.actor';
466
+ addTransitions(descriptor, [createCancelInvokeTimeoutTransition(descriptor, invokeTimeoutEventId, invokeDef.id)]);
443
467
  }
444
468
  if (invokeDef.onError) {
445
- const descriptor = `xstate.error.actor.${invokeDef.id}`;
446
- transitions.set(descriptor, mapTransitionConfigs(invokeDef.onError, transition => invokeTimeoutEventType ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventType) : dist_xstateActors.formatTransition(stateNode, descriptor, transition)));
469
+ const descriptor = 'xstate.error.actor';
470
+ addTransitions(descriptor, mapTransitionConfigs(invokeDef.onError, rawTransition => {
471
+ const transition = withInvokeMatch(rawTransition);
472
+ return invokeTimeoutEventId ? formatInvokeCompletionTransition(descriptor, transition, invokeTimeoutEventId) : dist_xstateActors.formatTransition(stateNode, descriptor, transition);
473
+ }));
447
474
  }
448
475
  if (invokeDef.onSnapshot) {
449
- const descriptor = `xstate.snapshot.${invokeDef.id}`;
450
- transitions.set(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => dist_xstateActors.formatTransition(stateNode, descriptor, transition)));
476
+ const descriptor = 'xstate.snapshot.actor';
477
+ addTransitions(descriptor, mapTransitionConfigs(invokeDef.onSnapshot, transition => dist_xstateActors.formatTransition(stateNode, descriptor, withInvokeMatch(transition))));
451
478
  }
452
479
  }
453
480
  for (const delayedTransition of stateNode.after) {
@@ -517,12 +544,12 @@ function getEmptyCanActorScope() {
517
544
  }
518
545
  class StateMachine {
519
546
  constructor(/** The raw config used to create the machine. */
520
- config, implementations) {
547
+ config, sources) {
521
548
  this.config = config;
522
549
  /** The machine's own version. */
523
550
  this.version = void 0;
524
551
  this.schemas = void 0;
525
- this.implementations = void 0;
552
+ this.sources = void 0;
526
553
  /** Runtime options for machine execution. */
527
554
  this.options = void 0;
528
555
  /** @internal */
@@ -541,18 +568,18 @@ class StateMachine {
541
568
  */
542
569
  this._json = void 0;
543
570
  this.id = config.id || '(machine)';
544
- this.implementations = {
545
- actorSources: config.actorSources ?? {},
571
+ this.sources = {
572
+ actors: config.actors ?? {},
546
573
  actions: config.actions ?? {},
547
574
  delays: config.delays ?? {},
548
575
  guards: config.guards ?? {},
549
- ...implementations
576
+ ...sources
550
577
  };
551
578
  {
552
579
  // The `@xstate.` prefix is reserved for built-in serialized action and
553
- // guard descriptors — user implementation names must not collide.
554
- for (const kind of ['actions', 'guards', 'actorSources', 'delays']) {
555
- for (const key of Object.keys(this.implementations[kind])) {
580
+ // guard descriptors — user source names must not collide.
581
+ for (const kind of ['actions', 'guards', 'actors', 'delays']) {
582
+ for (const key of Object.keys(this.sources[kind])) {
556
583
  if (key.startsWith('@xstate.')) {
557
584
  throw new Error(`Invalid ${kind} name '${key}': the '@xstate.' prefix is reserved for built-in descriptors.`);
558
585
  }
@@ -584,38 +611,38 @@ class StateMachine {
584
611
  }
585
612
 
586
613
  /**
587
- * Clones this state machine with the provided implementations.
614
+ * Clones this state machine with the provided sources.
588
615
  *
589
- * @param implementations Options (`actions`, `guards`, `actorSources`,
590
- * `delays`) to recursively merge with the existing options.
591
- * @returns A new `StateMachine` instance with the provided implementations.
616
+ * @param sources Options (`actions`, `guards`, `actors`, `delays`) to
617
+ * recursively merge with the existing options.
618
+ * @returns A new `StateMachine` instance with the provided sources.
592
619
  */
593
- provide(implementations) {
620
+ provide(sources) {
594
621
  const {
595
622
  actions,
596
623
  guards,
597
- actorSources,
624
+ actors,
598
625
  delays
599
- } = this.implementations;
626
+ } = this.sources;
600
627
  const provided = new StateMachine(this.config, {
601
628
  actions: {
602
629
  ...actions,
603
- ...implementations.actions
630
+ ...sources.actions
604
631
  },
605
632
  guards: {
606
633
  ...guards,
607
- ...implementations.guards
634
+ ...sources.guards
608
635
  },
609
- actorSources: {
610
- ...actorSources,
611
- ...implementations.actorSources
636
+ actors: {
637
+ ...actors,
638
+ ...sources.actors
612
639
  },
613
640
  delays: {
614
641
  ...delays,
615
- ...implementations.delays
642
+ ...sources.delays
616
643
  }
617
644
  });
618
- // Providing implementations does not change the serializable definition.
645
+ // Providing sources does not change the serializable definition.
619
646
  provided._json = this._json;
620
647
  return provided;
621
648
  }
@@ -806,12 +833,12 @@ class StateMachine {
806
833
  }, this, actorScope.self);
807
834
  if (typeof context === 'function') {
808
835
  const children = {};
809
- const spawn = createSpawner(actorScope, this.implementations.actorSources, children);
836
+ const spawn = createSpawner(actorScope, this.sources.actors, children);
810
837
  const resolvedContext = context({
811
838
  spawn,
812
839
  input: initEvent.input,
813
840
  self: actorScope.self,
814
- actorSources: this.implementations.actorSources
841
+ actors: this.sources.actors
815
842
  });
816
843
  const [nextState] = dist_xstateActors.resolveActionsWithContext(preInitial, initEvent, actorScope, []);
817
844
  if (resolvedContext) {
@@ -914,7 +941,8 @@ class StateMachine {
914
941
  const src = actorData.src;
915
942
  const logic = typeof src === 'string' ? dist_xstateActors.resolveReferencedActor(this, src) : src;
916
943
  if (!logic) {
917
- continue;
944
+ const sourceId = typeof src === 'string' ? src : '<unknown>';
945
+ throw new Error(`Unable to restore child actor '${actorId}': child source '${sourceId}' is not provided in machine '${this.id}'.`);
918
946
  }
919
947
  const actor = resolvedActorScope.system.createActorRef(logic, {
920
948
  id: actorId,
@@ -932,6 +960,14 @@ class StateMachine {
932
960
  const timers = {};
933
961
  const persistedTimers = snapshotData.timers ?? {};
934
962
  for (const [id, timer] of Object.entries(persistedTimers)) {
963
+ let event = timer.event;
964
+ if (event.type === 'xstate.timeout.actor') {
965
+ const actorId = event.actorId;
966
+ const child = children[actorId];
967
+ if (child) {
968
+ event = dist_xstateActors.createInvokeTimeoutEvent(actorId, child.sessionId);
969
+ }
970
+ }
935
971
  const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
936
972
  if (!target) {
937
973
  const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
@@ -939,6 +975,7 @@ class StateMachine {
939
975
  }
940
976
  timers[id] = {
941
977
  ...timer,
978
+ event,
942
979
  target
943
980
  };
944
981
  }