xstate 5.0.0-beta.38 → 5.0.0-beta.39

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 (43) hide show
  1. package/actions/dist/xstate-actions.cjs.js +3 -3
  2. package/actions/dist/xstate-actions.development.cjs.js +3 -3
  3. package/actions/dist/xstate-actions.development.esm.js +3 -3
  4. package/actions/dist/xstate-actions.esm.js +3 -3
  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 +60 -3
  8. package/actors/dist/xstate-actors.development.cjs.js +60 -3
  9. package/actors/dist/xstate-actors.development.esm.js +60 -3
  10. package/actors/dist/xstate-actors.esm.js +60 -3
  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/StateMachine.d.ts +5 -5
  14. package/dist/declarations/src/actors/callback.d.ts +74 -0
  15. package/dist/declarations/src/actors/transition.d.ts +2 -2
  16. package/dist/declarations/src/interpreter.d.ts +70 -9
  17. package/dist/declarations/src/spawn.d.ts +2 -2
  18. package/dist/declarations/src/stateUtils.d.ts +4 -4
  19. package/dist/declarations/src/types.d.ts +7 -7
  20. package/dist/{interpreter-ed3f81f7.development.cjs.js → interpreter-03a5c3f5.development.cjs.js} +90 -11
  21. package/dist/{interpreter-c80ce92e.esm.js → interpreter-1e8c1c0c.esm.js} +90 -11
  22. package/dist/{interpreter-b6f22ee2.cjs.js → interpreter-5dfcd203.cjs.js} +90 -11
  23. package/dist/{interpreter-4005eb36.development.esm.js → interpreter-70cd9217.development.esm.js} +90 -11
  24. package/dist/{raise-b69a3d16.development.cjs.js → raise-17cb3d9d.development.cjs.js} +84 -81
  25. package/dist/{raise-7faa9b3b.cjs.js → raise-291d2181.cjs.js} +83 -80
  26. package/dist/{raise-c989c7fb.esm.js → raise-62de3670.esm.js} +83 -80
  27. package/dist/{raise-42073973.development.esm.js → raise-e044f460.development.esm.js} +84 -81
  28. package/dist/{send-4b616da9.esm.js → send-1249d4ac.esm.js} +22 -22
  29. package/dist/{send-58725522.development.cjs.js → send-33433787.development.cjs.js} +22 -22
  30. package/dist/{send-34160163.cjs.js → send-af152aca.cjs.js} +22 -22
  31. package/dist/{send-bff8c910.development.esm.js → send-f1a2a827.development.esm.js} +22 -22
  32. package/dist/xstate.cjs.js +17 -17
  33. package/dist/xstate.development.cjs.js +17 -17
  34. package/dist/xstate.development.esm.js +20 -20
  35. package/dist/xstate.esm.js +20 -20
  36. package/dist/xstate.umd.min.js +1 -1
  37. package/dist/xstate.umd.min.js.map +1 -1
  38. package/guards/dist/xstate-guards.cjs.js +2 -2
  39. package/guards/dist/xstate-guards.development.cjs.js +2 -2
  40. package/guards/dist/xstate-guards.development.esm.js +2 -2
  41. package/guards/dist/xstate-guards.esm.js +2 -2
  42. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  43. package/package.json +1 -1
@@ -357,6 +357,10 @@ const defaultOptions = {
357
357
  logger: console.log.bind(console),
358
358
  devTools: false
359
359
  };
360
+
361
+ /**
362
+ * An Actor is a running process that can receive events, send events and change its behavior based on the events it receives, which can cause effects outside of the actor. When you run a state machine, it becomes an actor.
363
+ */
360
364
  class Actor {
361
365
  /**
362
366
  * The current internal state of the actor.
@@ -382,6 +386,10 @@ class Actor {
382
386
  * The globally unique process ID for this invocation.
383
387
  */
384
388
 
389
+ /**
390
+ * The system to which this actor belongs.
391
+ */
392
+
385
393
  /**
386
394
  * Creates a new actor instance for the given logic with the provided options, if any.
387
395
  *
@@ -401,7 +409,7 @@ class Actor {
401
409
  this.status = ActorStatus.NotStarted;
402
410
  this._parent = void 0;
403
411
  this.ref = void 0;
404
- this._actorContext = void 0;
412
+ this._actorScope = void 0;
405
413
  this._systemId = void 0;
406
414
  this.sessionId = void 0;
407
415
  this.system = void 0;
@@ -425,10 +433,6 @@ class Actor {
425
433
  // Always inspect at the system-level
426
434
  this.system.inspect(toObserver(inspect));
427
435
  }
428
- if (systemId) {
429
- this._systemId = systemId;
430
- this.system._set(systemId, this);
431
- }
432
436
  this.sessionId = this.system._bookId();
433
437
  this.id = id ?? this.sessionId;
434
438
  this.logger = logger;
@@ -437,7 +441,7 @@ class Actor {
437
441
  this.options = resolvedOptions;
438
442
  this.src = resolvedOptions.src;
439
443
  this.ref = this;
440
- this._actorContext = {
444
+ this._actorScope = {
441
445
  self: this,
442
446
  id: this.id,
443
447
  sessionId: this.sessionId,
@@ -462,9 +466,13 @@ class Actor {
462
466
  actorRef: this
463
467
  });
464
468
  this._initState();
469
+ if (systemId && this._state.status === 'active') {
470
+ this._systemId = systemId;
471
+ this.system._set(systemId, this);
472
+ }
465
473
  }
466
474
  _initState() {
467
- this._state = this.options.state ? this.logic.restoreState ? this.logic.restoreState(this.options.state, this._actorContext) : this.options.state : this.logic.getInitialState(this._actorContext, this.options?.input);
475
+ this._state = this.options.state ? this.logic.restoreState ? this.logic.restoreState(this.options.state, this._actorScope) : this.options.state : this.logic.getInitialState(this._actorScope, this.options?.input);
468
476
  }
469
477
 
470
478
  // array of functions to defer
@@ -510,6 +518,56 @@ class Actor {
510
518
  snapshot
511
519
  });
512
520
  }
521
+
522
+ /**
523
+ * Subscribe an observer to an actor’s snapshot values.
524
+ *
525
+ * @remarks
526
+ * The observer will receive the actor’s snapshot value when it is emitted. The observer can be:
527
+ * - A plain function that receives the latest snapshot, or
528
+ * - An observer object whose `.next(snapshot)` method receives the latest snapshot
529
+ *
530
+ * @example
531
+ * ```ts
532
+ * // Observer as a plain function
533
+ * const subscription = actor.subscribe((snapshot) => {
534
+ * console.log(snapshot);
535
+ * });
536
+ * ```
537
+ *
538
+ * @example
539
+ * ```ts
540
+ * // Observer as an object
541
+ * const subscription = actor.subscribe({
542
+ * next(snapshot) {
543
+ * console.log(snapshot);
544
+ * },
545
+ * error(err) {
546
+ * // ...
547
+ * },
548
+ * complete() {
549
+ * // ...
550
+ * },
551
+ * });
552
+ * ```
553
+ *
554
+ * The return value of `actor.subscribe(observer)` is a subscription object that has an `.unsubscribe()` method. You can call `subscription.unsubscribe()` to unsubscribe the observer:
555
+ *
556
+ * @example
557
+ * ```ts
558
+ * const subscription = actor.subscribe((snapshot) => {
559
+ * // ...
560
+ * });
561
+ *
562
+ * // Unsubscribe the observer
563
+ * subscription.unsubscribe();
564
+ * ```
565
+ *
566
+ * When the actor is stopped, all of its observers will automatically be unsubscribed.
567
+ *
568
+ * @param observer - Either a plain function that receives the latest snapshot, or an observer object whose `.next(snapshot)` method receives the latest snapshot
569
+ */
570
+
513
571
  subscribe(nextListenerOrObserver, errorListener, completeListener) {
514
572
  const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
515
573
  if (this.status !== ActorStatus.Stopped) {
@@ -561,7 +619,7 @@ class Actor {
561
619
  }
562
620
  if (this.logic.start) {
563
621
  try {
564
- this.logic.start(this._state, this._actorContext);
622
+ this.logic.start(this._state, this._actorScope);
565
623
  } catch (err) {
566
624
  this._stopProcedure();
567
625
  this._error(err);
@@ -585,7 +643,7 @@ class Actor {
585
643
  let nextState;
586
644
  let caughtError;
587
645
  try {
588
- nextState = this.logic.transition(this._state, event, this._actorContext);
646
+ nextState = this.logic.transition(this._state, event, this._actorScope);
589
647
  } catch (err) {
590
648
  // we wrap it in a box so we can rethrow it later even if falsy value gets caught here
591
649
  caughtError = {
@@ -713,7 +771,10 @@ class Actor {
713
771
  this.system._relay(undefined, this, event);
714
772
  }
715
773
 
716
- // TODO: make private (and figure out a way to do this within the machine)
774
+ /**
775
+ * TODO: figure out a way to do this within the machine
776
+ * @internal
777
+ */
717
778
  delaySend(params) {
718
779
  const {
719
780
  event,
@@ -730,7 +791,10 @@ class Actor {
730
791
  }
731
792
  }
732
793
 
733
- // TODO: make private (and figure out a way to do this within the machine)
794
+ /**
795
+ * TODO: figure out a way to do this within the machine
796
+ * @internal
797
+ */
734
798
  cancel(sendId) {
735
799
  this.clock.clearTimeout(this.delayedEventsMap[sendId]);
736
800
  delete this.delayedEventsMap[sendId];
@@ -756,6 +820,21 @@ class Actor {
756
820
  [symbolObservable]() {
757
821
  return this;
758
822
  }
823
+
824
+ /**
825
+ * Read an actor’s snapshot synchronously.
826
+ *
827
+ * @remarks
828
+ * The snapshot represent an actor's last emitted value.
829
+ *
830
+ * When an actor receives an event, its internal state may change.
831
+ * An actor may emit a snapshot when a state transition occurs.
832
+ *
833
+ * Note that some actors, such as callback actors generated with `fromCallback`, will not emit snapshots.
834
+ *
835
+ * @see {@link Actor.subscribe} to subscribe to an actor’s snapshot values.
836
+ * @see {@link Actor.getPersistedState} to persist the internal state of an actor (which is more than just a snapshot).
837
+ */
759
838
  getSnapshot() {
760
839
  return this._state;
761
840
  }
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var interpreter = require('./interpreter-ed3f81f7.development.cjs.js');
3
+ var interpreter = require('./interpreter-03a5c3f5.development.cjs.js');
4
4
 
5
5
  const cache = new WeakMap();
6
6
  function memo(object, key, fn) {
@@ -22,8 +22,8 @@ function resolveCancel(_, state, actionArgs, actionParams, {
22
22
  const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs, actionParams) : sendId;
23
23
  return [state, resolvedSendId];
24
24
  }
25
- function executeCancel(actorContext, resolvedSendId) {
26
- actorContext.self.cancel(resolvedSendId);
25
+ function executeCancel(actorScope, resolvedSendId) {
26
+ actorScope.self.cancel(resolvedSendId);
27
27
  }
28
28
  /**
29
29
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
@@ -45,7 +45,7 @@ function cancel(sendId) {
45
45
  return cancel;
46
46
  }
47
47
 
48
- function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
48
+ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
49
49
  id,
50
50
  systemId,
51
51
  src,
@@ -64,19 +64,19 @@ function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
64
64
  actorRef = interpreter.createActor(referenced.src, {
65
65
  id: resolvedId,
66
66
  src: typeof src === 'string' ? src : undefined,
67
- parent: actorContext?.self,
67
+ parent: actorScope?.self,
68
68
  systemId,
69
69
  input: typeof configuredInput === 'function' ? configuredInput({
70
70
  context: state.context,
71
71
  event: actionArgs.event,
72
- self: actorContext?.self
72
+ self: actorScope?.self
73
73
  }) : configuredInput
74
74
  });
75
75
  if (syncSnapshot) {
76
76
  actorRef.subscribe({
77
77
  next: snapshot => {
78
78
  if (snapshot.status === 'active') {
79
- actorContext.self.send({
79
+ actorScope.self.send({
80
80
  type: `xstate.snapshot.${id}`,
81
81
  snapshot
82
82
  });
@@ -87,7 +87,7 @@ function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
87
87
  }
88
88
  }
89
89
  if (!actorRef) {
90
- console.warn(`Actor type '${src}' not found in machine '${actorContext.id}'.`);
90
+ console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
91
91
  }
92
92
  return [cloneState(state, {
93
93
  children: {
@@ -99,21 +99,21 @@ function resolveSpawn(actorContext, state, actionArgs, _actionParams, {
99
99
  actorRef
100
100
  }];
101
101
  }
102
- function executeSpawn(actorContext, {
102
+ function executeSpawn(actorScope, {
103
103
  id,
104
104
  actorRef
105
105
  }) {
106
106
  if (!actorRef) {
107
107
  return;
108
108
  }
109
- actorContext.defer(() => {
109
+ actorScope.defer(() => {
110
110
  if (actorRef.status === interpreter.ActorStatus.Stopped) {
111
111
  return;
112
112
  }
113
113
  try {
114
114
  actorRef.start?.();
115
115
  } catch (err) {
116
- actorContext.self.send(interpreter.createErrorActorEvent(id, err));
116
+ actorScope.self.send(interpreter.createErrorActorEvent(id, err));
117
117
  return;
118
118
  }
119
119
  });
@@ -156,7 +156,7 @@ function resolveStop(_, state, args, actionParams, {
156
156
  children
157
157
  }), resolvedActorRef];
158
158
  }
159
- function executeStop(actorContext, actorRef) {
159
+ function executeStop(actorScope, actorRef) {
160
160
  if (!actorRef) {
161
161
  return;
162
162
  }
@@ -164,20 +164,20 @@ function executeStop(actorContext, actorRef) {
164
164
  // we need to eagerly unregister it here so a new actor with the same systemId can be registered immediately
165
165
  // since we defer actual stopping of the actor but we don't defer actor creations (and we can't do that)
166
166
  // this could throw on `systemId` collision, for example, when dealing with reentering transitions
167
- actorContext.system._unregister(actorRef);
167
+ actorScope.system._unregister(actorRef);
168
168
 
169
169
  // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
170
170
  // this can happen, for example, when the invoking state is being exited immediately by an always transition
171
171
  if (actorRef.status !== interpreter.ActorStatus.Running) {
172
- actorContext.stopChild(actorRef);
172
+ actorScope.stopChild(actorRef);
173
173
  return;
174
174
  }
175
175
  // stopping a child enqueues a stop event in the child actor's mailbox
176
176
  // we need for all of the already enqueued events to be processed before we stop the child
177
177
  // the parent itself might want to send some events to a child (for example from exit actions on the invoking state)
178
178
  // and we don't want to ignore those events
179
- actorContext.defer(() => {
180
- actorContext.stopChild(actorRef);
179
+ actorScope.defer(() => {
180
+ actorScope.stopChild(actorRef);
181
181
  });
182
182
  }
183
183
  /**
@@ -762,15 +762,6 @@ function isDescendant(childStateNode, parentStateNode) {
762
762
  }
763
763
  return marker.parent === parentStateNode;
764
764
  }
765
- function getPathFromRootToNode(stateNode) {
766
- const path = [];
767
- let marker = stateNode.parent;
768
- while (marker) {
769
- path.unshift(marker);
770
- marker = marker.parent;
771
- }
772
- return path;
773
- }
774
765
  function hasIntersection(s1, s2) {
775
766
  const set1 = new Set(s1);
776
767
  const set2 = new Set(s2);
@@ -810,17 +801,13 @@ function removeConflictingTransitions(enabledTransitions, configuration, history
810
801
  }
811
802
  return Array.from(filteredTransitions);
812
803
  }
813
- function findLCCA(stateNodes) {
814
- const [head] = stateNodes;
815
- let current = getPathFromRootToNode(head);
816
- let candidates = [];
817
- for (const stateNode of stateNodes) {
818
- const path = getPathFromRootToNode(stateNode);
819
- candidates = current.filter(sn => path.includes(sn));
820
- current = candidates;
821
- candidates = [];
804
+ function findLeastCommonAncestor(stateNodes) {
805
+ const [head, ...tail] = stateNodes;
806
+ for (const ancestor of getProperAncestors(head, undefined)) {
807
+ if (tail.every(sn => isDescendant(sn, ancestor))) {
808
+ return ancestor;
809
+ }
822
810
  }
823
- return current[current.length - 1];
824
811
  }
825
812
  function getEffectiveTargetStates(transition, historyValue) {
826
813
  if (!transition.target) {
@@ -852,8 +839,16 @@ function getTransitionDomain(transition, historyValue) {
852
839
  if (!transition.reenter && targetStates.every(target => target === transition.source || isDescendant(target, transition.source))) {
853
840
  return transition.source;
854
841
  }
855
- const lcca = findLCCA(targetStates.concat(transition.source));
856
- return lcca;
842
+ const lca = findLeastCommonAncestor(targetStates.concat(transition.source));
843
+ if (lca) {
844
+ return lca;
845
+ }
846
+
847
+ // at this point we know that it's a root transition since LCA couldn't be found
848
+ if (transition.reenter) {
849
+ return;
850
+ }
851
+ return transition.source.machine.root;
857
852
  }
858
853
  function computeExitSet(transitions, configuration, historyValue) {
859
854
  const statesToExit = new Set();
@@ -887,7 +882,7 @@ function areConfigurationsEqual(previousConfiguration, nextConfigurationSet) {
887
882
  /**
888
883
  * https://www.w3.org/TR/scxml/#microstepProcedure
889
884
  */
890
- function microstep(transitions, currentState, actorCtx, event, isInitial, internalQueue) {
885
+ function microstep(transitions, currentState, actorScope, event, isInitial, internalQueue) {
891
886
  if (!transitions.length) {
892
887
  return currentState;
893
888
  }
@@ -898,17 +893,17 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
898
893
 
899
894
  // Exit states
900
895
  if (!isInitial) {
901
- [nextState, historyValue] = exitStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, historyValue, internalQueue);
896
+ [nextState, historyValue] = exitStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, historyValue, internalQueue);
902
897
  }
903
898
 
904
899
  // Execute transition content
905
- nextState = resolveActionsAndContext(nextState, event, actorCtx, filteredTransitions.flatMap(t => t.actions), internalQueue);
900
+ nextState = resolveActionsAndContext(nextState, event, actorScope, filteredTransitions.flatMap(t => t.actions), internalQueue);
906
901
 
907
902
  // Enter states
908
- nextState = enterStates(nextState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
903
+ nextState = enterStates(nextState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial);
909
904
  const nextConfiguration = [...mutConfiguration];
910
905
  if (nextState.status === 'done') {
911
- nextState = resolveActionsAndContext(nextState, event, actorCtx, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
906
+ nextState = resolveActionsAndContext(nextState, event, actorScope, nextConfiguration.sort((a, b) => b.order - a.order).flatMap(state => state.exit), internalQueue);
912
907
  }
913
908
  try {
914
909
  if (historyValue === currentState.historyValue && areConfigurationsEqual(currentState.configuration, mutConfiguration)) {
@@ -924,14 +919,14 @@ function microstep(transitions, currentState, actorCtx, event, isInitial, intern
924
919
  throw e;
925
920
  }
926
921
  }
927
- function getMachineOutput(state, event, actorCtx, rootNode, rootCompletionNode) {
922
+ function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode) {
928
923
  if (!rootNode.output) {
929
924
  return;
930
925
  }
931
- const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorCtx.self) : undefined);
932
- return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorCtx.self);
926
+ const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
927
+ return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
933
928
  }
934
- function enterStates(currentState, event, actorCtx, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
929
+ function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
935
930
  let nextState = currentState;
936
931
  const statesToEnter = new Set();
937
932
  // those are states that were directly targeted or indirectly targeted by the explicit target
@@ -961,13 +956,13 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
961
956
  const initialActions = stateNodeToEnter.initial.actions;
962
957
  actions.push(...initialActions);
963
958
  }
964
- nextState = resolveActionsAndContext(nextState, event, actorCtx, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
959
+ nextState = resolveActionsAndContext(nextState, event, actorScope, actions, internalQueue, stateNodeToEnter.invoke.map(invokeDef => invokeDef.id));
965
960
  if (stateNodeToEnter.type === 'final') {
966
961
  const parent = stateNodeToEnter.parent;
967
962
  let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
968
963
  let rootCompletionNode = ancestorMarker || stateNodeToEnter;
969
964
  if (parent?.type === 'compound') {
970
- internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorCtx.self) : undefined));
965
+ internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
971
966
  }
972
967
  while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
973
968
  completedNodes.add(ancestorMarker);
@@ -980,7 +975,7 @@ function enterStates(currentState, event, actorCtx, filteredTransitions, mutConf
980
975
  }
981
976
  nextState = cloneState(nextState, {
982
977
  status: 'done',
983
- output: getMachineOutput(nextState, event, actorCtx, currentState.configuration[0].machine.root, rootCompletionNode)
978
+ output: getMachineOutput(nextState, event, actorScope, currentState.configuration[0].machine.root, rootCompletionNode)
984
979
  });
985
980
  }
986
981
  }
@@ -1005,7 +1000,11 @@ function computeEntrySet(transitions, historyValue, statesForDefaultEntry, state
1005
1000
  }
1006
1001
  const targetStates = getEffectiveTargetStates(t, historyValue);
1007
1002
  for (const s of targetStates) {
1008
- addAncestorStatesToEnter(s, domain, statesToEnter, historyValue, statesForDefaultEntry);
1003
+ const ancestors = getProperAncestors(s, domain);
1004
+ if (domain?.type === 'parallel') {
1005
+ ancestors.push(domain);
1006
+ }
1007
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, !t.source.parent && t.reenter ? undefined : domain);
1009
1008
  }
1010
1009
  }
1011
1010
  }
@@ -1018,7 +1017,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1018
1017
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1019
1018
  }
1020
1019
  for (const s of historyStateNodes) {
1021
- addAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1020
+ addProperAncestorStatesToEnter(s, stateNode.parent, statesToEnter, historyValue, statesForDefaultEntry);
1022
1021
  }
1023
1022
  } else {
1024
1023
  const historyDefaultTransition = resolveHistoryDefaultTransition(stateNode);
@@ -1030,7 +1029,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1030
1029
  addDescendantStatesToEnter(s, historyValue, statesForDefaultEntry, statesToEnter);
1031
1030
  }
1032
1031
  for (const s of historyDefaultTransition.target) {
1033
- addAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1032
+ addProperAncestorStatesToEnter(s, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1034
1033
  }
1035
1034
  }
1036
1035
  } else {
@@ -1041,7 +1040,7 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1041
1040
  statesForDefaultEntry.add(initialState);
1042
1041
  }
1043
1042
  addDescendantStatesToEnter(initialState, historyValue, statesForDefaultEntry, statesToEnter);
1044
- addAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1043
+ addProperAncestorStatesToEnter(initialState, stateNode, statesToEnter, historyValue, statesForDefaultEntry);
1045
1044
  } else {
1046
1045
  if (stateNode.type === 'parallel') {
1047
1046
  for (const child of getChildren(stateNode).filter(sn => !isHistoryNode(sn))) {
@@ -1057,10 +1056,11 @@ function addDescendantStatesToEnter(stateNode, historyValue, statesForDefaultEnt
1057
1056
  }
1058
1057
  }
1059
1058
  }
1060
- function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1061
- const properAncestors = getProperAncestors(stateNode, toStateNode);
1062
- for (const anc of properAncestors) {
1063
- statesToEnter.add(anc);
1059
+ function addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, ancestors, reentrancyDomain) {
1060
+ for (const anc of ancestors) {
1061
+ if (!reentrancyDomain || isDescendant(anc, reentrancyDomain)) {
1062
+ statesToEnter.add(anc);
1063
+ }
1064
1064
  if (anc.type === 'parallel') {
1065
1065
  for (const child of getChildren(anc).filter(sn => !isHistoryNode(sn))) {
1066
1066
  if (![...statesToEnter].some(s => isDescendant(s, child))) {
@@ -1071,7 +1071,10 @@ function addAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, history
1071
1071
  }
1072
1072
  }
1073
1073
  }
1074
- function exitStates(currentState, event, actorCtx, transitions, mutConfiguration, historyValue, internalQueue) {
1074
+ function addProperAncestorStatesToEnter(stateNode, toStateNode, statesToEnter, historyValue, statesForDefaultEntry) {
1075
+ addAncestorStatesToEnter(statesToEnter, historyValue, statesForDefaultEntry, getProperAncestors(stateNode, toStateNode));
1076
+ }
1077
+ function exitStates(currentState, event, actorScope, transitions, mutConfiguration, historyValue, internalQueue) {
1075
1078
  let nextState = currentState;
1076
1079
  const statesToExit = computeExitSet(transitions, mutConfiguration, historyValue);
1077
1080
  statesToExit.sort((a, b) => b.order - a.order);
@@ -1095,12 +1098,12 @@ function exitStates(currentState, event, actorCtx, transitions, mutConfiguration
1095
1098
  }
1096
1099
  }
1097
1100
  for (const s of statesToExit) {
1098
- nextState = resolveActionsAndContext(nextState, event, actorCtx, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1101
+ nextState = resolveActionsAndContext(nextState, event, actorScope, [...s.exit, ...s.invoke.map(def => stop(def.id))], internalQueue);
1099
1102
  mutConfiguration.delete(s);
1100
1103
  }
1101
1104
  return [nextState, changedHistory || historyValue];
1102
1105
  }
1103
- function resolveActionsAndContextWorker(currentState, event, actorCtx, actions, extra, retries) {
1106
+ function resolveActionsAndContextWorker(currentState, event, actorScope, actions, extra, retries) {
1104
1107
  const {
1105
1108
  machine
1106
1109
  } = currentState;
@@ -1118,25 +1121,25 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1118
1121
  const actionArgs = {
1119
1122
  context: intermediateState.context,
1120
1123
  event,
1121
- self: actorCtx?.self,
1122
- system: actorCtx?.system
1124
+ self: actorScope?.self,
1125
+ system: actorScope?.system
1123
1126
  };
1124
1127
  const actionParams = isInline || typeof action === 'string' ? undefined : 'params' in action ? typeof action.params === 'function' ? action.params({
1125
1128
  context: intermediateState.context,
1126
1129
  event
1127
1130
  }) : action.params : undefined;
1128
1131
  if (!('resolve' in resolvedAction)) {
1129
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1132
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1130
1133
  resolvedAction(actionArgs, actionParams);
1131
1134
  } else {
1132
- actorCtx?.defer(() => {
1135
+ actorScope?.defer(() => {
1133
1136
  resolvedAction(actionArgs, actionParams);
1134
1137
  });
1135
1138
  }
1136
1139
  continue;
1137
1140
  }
1138
1141
  const builtinAction = resolvedAction;
1139
- const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, actionArgs, actionParams, resolvedAction,
1142
+ const [nextState, params, actions] = builtinAction.resolve(actorScope, intermediateState, actionArgs, actionParams, resolvedAction,
1140
1143
  // this holds all params
1141
1144
  extra);
1142
1145
  intermediateState = nextState;
@@ -1144,30 +1147,30 @@ function resolveActionsAndContextWorker(currentState, event, actorCtx, actions,
1144
1147
  retries?.push([builtinAction, params]);
1145
1148
  }
1146
1149
  if ('execute' in builtinAction) {
1147
- if (actorCtx?.self.status === interpreter.ActorStatus.Running) {
1148
- builtinAction.execute(actorCtx, params);
1150
+ if (actorScope?.self.status === interpreter.ActorStatus.Running) {
1151
+ builtinAction.execute(actorScope, params);
1149
1152
  } else {
1150
- actorCtx?.defer(builtinAction.execute.bind(null, actorCtx, params));
1153
+ actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
1151
1154
  }
1152
1155
  }
1153
1156
  if (actions) {
1154
- intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorCtx, actions, extra, retries);
1157
+ intermediateState = resolveActionsAndContextWorker(intermediateState, event, actorScope, actions, extra, retries);
1155
1158
  }
1156
1159
  }
1157
1160
  return intermediateState;
1158
1161
  }
1159
- function resolveActionsAndContext(currentState, event, actorCtx, actions, internalQueue, deferredActorIds) {
1162
+ function resolveActionsAndContext(currentState, event, actorScope, actions, internalQueue, deferredActorIds) {
1160
1163
  const retries = deferredActorIds ? [] : undefined;
1161
- const nextState = resolveActionsAndContextWorker(currentState, event, actorCtx, actions, {
1164
+ const nextState = resolveActionsAndContextWorker(currentState, event, actorScope, actions, {
1162
1165
  internalQueue,
1163
1166
  deferredActorIds
1164
1167
  }, retries);
1165
1168
  retries?.forEach(([builtinAction, params]) => {
1166
- builtinAction.retryResolve(actorCtx, nextState, params);
1169
+ builtinAction.retryResolve(actorScope, nextState, params);
1167
1170
  });
1168
1171
  return nextState;
1169
1172
  }
1170
- function macrostep(state, event, actorCtx, internalQueue = []) {
1173
+ function macrostep(state, event, actorScope, internalQueue = []) {
1171
1174
  if (event.type === interpreter.WILDCARD) {
1172
1175
  throw new Error(`An event cannot have the wildcard type ('${interpreter.WILDCARD}')`);
1173
1176
  }
@@ -1176,7 +1179,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1176
1179
 
1177
1180
  // Handle stop event
1178
1181
  if (event.type === interpreter.XSTATE_STOP) {
1179
- nextState = cloneState(stopChildren(nextState, event, actorCtx), {
1182
+ nextState = cloneState(stopChildren(nextState, event, actorScope), {
1180
1183
  status: 'stopped'
1181
1184
  });
1182
1185
  states.push(nextState);
@@ -1191,7 +1194,7 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1191
1194
  // Determine the next state based on the next microstep
1192
1195
  if (nextEvent.type !== interpreter.XSTATE_INIT) {
1193
1196
  const transitions = selectTransitions(nextEvent, nextState);
1194
- nextState = microstep(transitions, state, actorCtx, nextEvent, false, internalQueue);
1197
+ nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
1195
1198
  states.push(nextState);
1196
1199
  }
1197
1200
  let shouldSelectEventlessTransitions = true;
@@ -1208,20 +1211,20 @@ function macrostep(state, event, actorCtx, internalQueue = []) {
1208
1211
  nextEvent = internalQueue.shift();
1209
1212
  enabledTransitions = selectTransitions(nextEvent, nextState);
1210
1213
  }
1211
- nextState = microstep(enabledTransitions, nextState, actorCtx, nextEvent, false, internalQueue);
1214
+ nextState = microstep(enabledTransitions, nextState, actorScope, nextEvent, false, internalQueue);
1212
1215
  shouldSelectEventlessTransitions = nextState !== previousState;
1213
1216
  states.push(nextState);
1214
1217
  }
1215
1218
  if (nextState.status !== 'active') {
1216
- stopChildren(nextState, nextEvent, actorCtx);
1219
+ stopChildren(nextState, nextEvent, actorScope);
1217
1220
  }
1218
1221
  return {
1219
1222
  state: nextState,
1220
1223
  microstates: states
1221
1224
  };
1222
1225
  }
1223
- function stopChildren(nextState, event, actorCtx) {
1224
- return resolveActionsAndContext(nextState, event, actorCtx, Object.values(nextState.children).map(child => stop(child)), []);
1226
+ function stopChildren(nextState, event, actorScope) {
1227
+ return resolveActionsAndContext(nextState, event, actorScope, Object.values(nextState.children).map(child => stop(child)), []);
1225
1228
  }
1226
1229
  function selectTransitions(event, nextState) {
1227
1230
  return nextState.machine.getTransitionData(nextState, event);
@@ -1508,9 +1511,9 @@ function resolveRaise(_, state, args, actionParams, {
1508
1511
  delay: resolvedDelay
1509
1512
  }];
1510
1513
  }
1511
- function executeRaise(actorContext, params) {
1514
+ function executeRaise(actorScope, params) {
1512
1515
  if (typeof params.delay === 'number') {
1513
- actorContext.self.delaySend(params);
1516
+ actorScope.self.delaySend(params);
1514
1517
  return;
1515
1518
  }
1516
1519
  }