xstate 6.0.0-alpha.21 → 6.0.0-alpha.23

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/dist/{StateMachine-3c17fe3e.esm.js → StateMachine-022864fd.esm.js} +183 -64
  2. package/dist/{StateMachine-550ff7f2.development.cjs.js → StateMachine-53114dce.development.cjs.js} +187 -63
  3. package/dist/{StateMachine-1b155670.cjs.js → StateMachine-aad57180.cjs.js} +187 -63
  4. package/dist/{StateMachine-e25dd61f.development.esm.js → StateMachine-d2247245.development.esm.js} +183 -64
  5. package/dist/declarations/src/State.d.ts +4 -2
  6. package/dist/declarations/src/StateMachine.d.ts +5 -4
  7. package/dist/declarations/src/actions.d.ts +10 -8
  8. package/dist/declarations/src/actors/logic.d.ts +5 -21
  9. package/dist/declarations/src/createActor.d.ts +3 -1
  10. package/dist/declarations/src/fsm.d.ts +3 -1
  11. package/dist/declarations/src/index.d.ts +2 -2
  12. package/dist/declarations/src/spawn.d.ts +3 -3
  13. package/dist/declarations/src/stateUtils.d.ts +1 -1
  14. package/dist/declarations/src/system.d.ts +34 -9
  15. package/dist/declarations/src/transitionActions.d.ts +5 -1
  16. package/dist/declarations/src/types.d.ts +70 -51
  17. package/dist/{index-3f87408c.esm.js → index-3609e096.esm.js} +782 -389
  18. package/dist/{index-ec7c7a2d.development.cjs.js → index-41c0375c.development.cjs.js} +790 -390
  19. package/dist/{index-e694228c.cjs.js → index-434fac23.cjs.js} +789 -389
  20. package/dist/{index-d39fb138.development.esm.js → index-f5407323.development.esm.js} +783 -390
  21. package/dist/xstate-actors.cjs.js +1 -1
  22. package/dist/xstate-actors.development.cjs.js +1 -1
  23. package/dist/xstate-actors.development.esm.js +1 -1
  24. package/dist/xstate-actors.esm.js +1 -1
  25. package/dist/xstate-actors.umd.min.js +1 -1
  26. package/dist/xstate-actors.umd.min.js.map +1 -1
  27. package/dist/xstate-graph.cjs.js +2 -2
  28. package/dist/xstate-graph.development.cjs.js +2 -2
  29. package/dist/xstate-graph.development.esm.js +2 -2
  30. package/dist/xstate-graph.esm.js +2 -2
  31. package/dist/xstate-graph.umd.min.js +1 -1
  32. package/dist/xstate-graph.umd.min.js.map +1 -1
  33. package/dist/xstate.cjs.js +82 -103
  34. package/dist/xstate.cjs.mjs +1 -0
  35. package/dist/xstate.development.cjs.js +82 -103
  36. package/dist/xstate.development.cjs.mjs +1 -0
  37. package/dist/xstate.development.esm.js +80 -102
  38. package/dist/xstate.esm.js +80 -102
  39. package/dist/xstate.umd.min.js +1 -1
  40. package/dist/xstate.umd.min.js.map +1 -1
  41. package/package.json +1 -1
@@ -1,54 +1,125 @@
1
- import { P as ProcessingStatus, H as resolveReferencedActor, e as createActor, S as STATE_DELIMITER, I as mapValues, t as toArray, J as createInvokeId, K as getDelayedTransitions, L as evaluateCandidate, M as formatTransition, N as NULL_EVENT, O as toTransitionConfigArray, Q as createInvokeTimeoutEvent, R as getCandidates, U as formatRouteTransitions, V as resolveStateValue, W as getAllStateNodes, l as getStateNodes, Y as createMachineSnapshot, Z as isInFinalState, f as macrostep, d as deriveDeferredStarts, _ as cloneMachineSnapshot, $ as transitionNode, m as matchesEventDescriptor, a0 as getTransitionResult, a1 as hasEffect, a2 as createErrorPlatformEvent, r as resolveActionsWithContext, g as createInitEvent, h as initialMicrostep, a3 as toStatePath, a4 as isStateId, a5 as getStateNodeByPath, a6 as getPersistedSnapshot, a7 as $$ACTOR_TYPE } from './index-d39fb138.development.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 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-f5407323.development.esm.js';
2
2
 
3
- function createSpawner(actorScope, {
4
- machine,
5
- context
6
- }, event, spawnedChildren) {
7
- const spawn = (src, options) => {
8
- if (typeof src === 'string') {
9
- const logic = resolveReferencedActor(machine, src);
10
- if (!logic) {
11
- throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
12
- }
13
- const actor = createActor(logic, {
14
- id: options?.id,
15
- parent: actorScope.self,
16
- syncSnapshot: options?.syncSnapshot,
17
- input: typeof options?.input === 'function' ? options.input({
18
- context,
19
- event,
20
- self: actorScope.self
21
- }) : options?.input,
22
- src,
23
- registryKey: options?.registryKey
24
- });
25
- spawnedChildren[actor.id] = actor;
26
- return actor;
27
- } else {
28
- const actor = createActor(src, {
29
- id: options?.id,
30
- parent: actorScope.self,
31
- syncSnapshot: options?.syncSnapshot,
32
- input: options?.input,
33
- src,
34
- registryKey: options?.registryKey
35
- });
36
- return actor;
37
- }
38
- };
3
+ function createSpawner(actorScope, actorSources, spawnedChildren) {
39
4
  return (src, options) => {
40
- const actor = spawn(src, options); // TODO: fix types
41
- spawnedChildren[actor.id] = actor;
42
- actorScope.defer(() => {
43
- if (actor._processingStatus === ProcessingStatus.Stopped) {
44
- return;
45
- }
46
- actor.start();
5
+ const referencedSrc = Object.entries(actorSources).find(([, logic]) => logic === src)?.[0];
6
+ const actor = actorScope.system.createActorRef(src, {
7
+ id: options?.id,
8
+ parent: actorScope.self,
9
+ syncSnapshot: options?.syncSnapshot,
10
+ input: options?.input,
11
+ src: referencedSrc ?? src,
12
+ registryKey: options?.registryKey
47
13
  });
14
+ spawnedChildren[actor.id] = actor;
48
15
  return actor;
49
16
  };
50
17
  }
51
18
 
19
+ /** @internal */
20
+ function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true) {
21
+ actorScope.self._snapshot = snapshot;
22
+ if (attachActorRef && snapshot && typeof snapshot === 'object') {
23
+ setSnapshotActorRef(snapshot, actorScope.self);
24
+ }
25
+ return snapshot;
26
+ }
27
+
28
+ /** @internal */
29
+ function isInertActorScope(actorScope) {
30
+ return !!actorScope.self.options?._inert;
31
+ }
32
+
33
+ /** @internal */
34
+ function attachSnapshotActorRef(actorLogic, actorScope, snapshot) {
35
+ const snapshotScope = createInertActorScope(actorLogic, snapshot, actorScope.self);
36
+ return setInertActorScopeSnapshot(snapshotScope, snapshot);
37
+ }
38
+
39
+ /** @internal */
40
+ function createInertActorScope(actorLogic, snapshot, sourceSelf) {
41
+ const snapshotRef = snapshot ? getSnapshotActorRef(snapshot) : undefined;
42
+ const previousSelf = sourceSelf ?? snapshotRef?.actor;
43
+ const baseSystem = previousSelf?.system;
44
+ const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, previousSelf, isMachineSnapshot(snapshot) ? snapshot.children : {}, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
45
+ const self = createActor(actorLogic, {
46
+ _inert: true,
47
+ ...(previousSelf ? {
48
+ id: previousSelf.id
49
+ } : {}),
50
+ ...(system ? {
51
+ _systemRef: {
52
+ current: system
53
+ }
54
+ } : {})
55
+ });
56
+ if (previousSelf?._parent) {
57
+ self._parent = previousSelf._parent;
58
+ }
59
+ if (snapshot) {
60
+ self._snapshot = snapshot;
61
+ }
62
+ const actorScope = {
63
+ self: self,
64
+ defer: () => {},
65
+ id: self.id,
66
+ logger: self.system._logger,
67
+ sessionId: self.sessionId,
68
+ stopChild: child => child._stop(),
69
+ system: self.system,
70
+ emit: event => self.system.emitEvent(self, event),
71
+ actionExecutor: () => {}
72
+ };
73
+ return actorScope;
74
+ }
75
+
76
+ /** @deprecated Use `initialTransition(…)` instead. */
77
+ function getInitialSnapshot(actorLogic, ...[input]) {
78
+ const actorScope = createInertActorScope(actorLogic);
79
+ return actorLogic.initialTransition(input, actorScope)[0];
80
+ }
81
+
82
+ /**
83
+ * Determines the next snapshot for the given `actorLogic` based on the given
84
+ * `snapshot` and `event`.
85
+ *
86
+ * If the `snapshot` is `undefined`, the initial snapshot of the `actorLogic` is
87
+ * used.
88
+ *
89
+ * @deprecated Use `transition(…)` instead.
90
+ * @example
91
+ *
92
+ * ```ts
93
+ * import { getNextSnapshot } from 'xstate';
94
+ * import { trafficLightMachine } from './trafficLightMachine.ts';
95
+ *
96
+ * const nextSnapshot = getNextSnapshot(
97
+ * trafficLightMachine, // actor logic
98
+ * undefined, // snapshot (or initial state if undefined)
99
+ * { type: 'TIMER' }
100
+ * ); // event object
101
+ *
102
+ * console.log(nextSnapshot.value);
103
+ * // => 'yellow'
104
+ *
105
+ * const nextSnapshot2 = getNextSnapshot(
106
+ * trafficLightMachine, // actor logic
107
+ * nextSnapshot, // snapshot
108
+ * { type: 'TIMER' }
109
+ * ); // event object
110
+ *
111
+ * console.log(nextSnapshot2.value);
112
+ * // =>'red'
113
+ * ```
114
+ */
115
+ function getNextSnapshot(actorLogic, snapshot, event) {
116
+ const actorScope = createInertActorScope(actorLogic, snapshot);
117
+ const transitionResult = actorLogic.transition(snapshot, event, actorScope);
118
+ const nextSnapshot = Array.isArray(transitionResult) ? transitionResult[0] : transitionResult;
119
+ setInertActorScopeSnapshot(actorScope, nextSnapshot, false);
120
+ return nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(actorLogic, actorScope, nextSnapshot);
121
+ }
122
+
52
123
  const cache = new WeakMap();
53
124
  function memo(object, key, fn) {
54
125
  let memoizedData = cache.get(object);
@@ -570,19 +641,37 @@ class StateMachine {
570
641
  * @param event The received event
571
642
  */
572
643
  transition(snapshot, event, actorScope) {
573
- const fastSnapshot = this._transitionFast(snapshot, event, actorScope);
644
+ const usesInertScope = !actorScope;
645
+ const resolvedActorScope = actorScope ?? createInertActorScope(this, snapshot);
646
+ if (usesInertScope) {
647
+ setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
648
+ }
649
+ const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
574
650
  if (fastSnapshot) {
575
- return [fastSnapshot, []];
651
+ if (usesInertScope) {
652
+ setInertActorScopeSnapshot(resolvedActorScope, fastSnapshot, false);
653
+ }
654
+ const returnedSnapshot = usesInertScope && fastSnapshot !== snapshot ? attachSnapshotActorRef(this, resolvedActorScope, fastSnapshot) : this._attachPureActorRef(fastSnapshot, resolvedActorScope);
655
+ return [returnedSnapshot, []];
576
656
  }
577
657
  const {
578
658
  snapshot: nextSnapshot,
579
659
  microsteps
580
- } = macrostep(snapshot, event, actorScope, []);
581
- return [nextSnapshot, this._collectEffects(microsteps)];
660
+ } = macrostep(snapshot, event, resolvedActorScope, []);
661
+ if (usesInertScope) {
662
+ setInertActorScopeSnapshot(resolvedActorScope, nextSnapshot, false);
663
+ }
664
+ const returnedSnapshot = usesInertScope ? nextSnapshot === snapshot ? nextSnapshot : attachSnapshotActorRef(this, resolvedActorScope, nextSnapshot) : this._attachPureActorRef(nextSnapshot, resolvedActorScope);
665
+ return [returnedSnapshot, this._collectEffects(microsteps)];
666
+ }
667
+ _collectEffects(microsteps) {
668
+ return microsteps.flatMap(([, actions]) => actions);
582
669
  }
583
- _collectEffects(microsteps, initialActions = []) {
584
- const effects = [...initialActions, ...microsteps.flatMap(([, actions]) => actions)];
585
- return [...effects, ...deriveDeferredStarts(effects)];
670
+ _attachPureActorRef(snapshot, actorScope) {
671
+ if (isInertActorScope(actorScope)) {
672
+ return snapshot;
673
+ }
674
+ return attachSnapshotActorRef(this, actorScope, snapshot);
586
675
  }
587
676
  _transitionFast(snapshot, event, actorScope) {
588
677
  if (snapshot.status !== 'active' || typeof snapshot.value !== 'string' || this.root.always?.length) {
@@ -643,6 +732,9 @@ class StateMachine {
643
732
  return transitionNode(this.root, snapshot.value, snapshot, event, self) || [];
644
733
  }
645
734
  isInternalEventType(eventType) {
735
+ if (eventType === XSTATE_TIMER) {
736
+ return true;
737
+ }
646
738
  for (const descriptor of this.internalEventDescriptors) {
647
739
  if (matchesEventDescriptor(eventType, descriptor)) {
648
740
  return true;
@@ -709,10 +801,10 @@ class StateMachine {
709
801
  _nodes: [this.root],
710
802
  children: {},
711
803
  status: 'active'
712
- }, this);
804
+ }, this, actorScope.self);
713
805
  if (typeof context === 'function') {
714
806
  const children = {};
715
- const spawn = createSpawner(actorScope, preInitial, initEvent, children);
807
+ const spawn = createSpawner(actorScope, this.implementations.actorSources, children);
716
808
  const resolvedContext = context({
717
809
  spawn,
718
810
  input: initEvent.input,
@@ -742,30 +834,37 @@ class StateMachine {
742
834
  return this.initialTransition(input, actorScope)[0];
743
835
  }
744
836
  initialTransition(input, actorScope) {
837
+ const usesInertScope = !actorScope;
838
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
745
839
  const initEvent = createInitEvent(input); // TODO: fix;
746
840
  const internalQueue = [];
747
- const preInitialState = this._getPreInitialState(actorScope, initEvent);
841
+ const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
842
+ const contextSpawnEffects = Object.values(preInitialState.children).filter(Boolean).map(actor => createSpawnEffect(actor));
748
843
  let nextState;
749
844
  let initialActions = [];
750
845
  let microsteps = [];
751
846
  let macroState;
752
847
  try {
753
- [nextState, initialActions] = initialMicrostep(this.root, preInitialState, actorScope, initEvent, internalQueue);
848
+ [nextState, initialActions] = initialMicrostep(this.root, preInitialState, resolvedActorScope, initEvent, internalQueue);
754
849
  ({
755
850
  snapshot: macroState,
756
851
  microsteps
757
- } = macrostep(nextState, initEvent, actorScope, internalQueue));
852
+ } = macrostep(nextState, initEvent, resolvedActorScope, internalQueue, [[nextState, [...contextSpawnEffects, ...initialActions]]]));
758
853
  } catch (err) {
759
854
  if (!this.root.config.onError) {
760
855
  throw err;
761
856
  }
762
857
  const errorEvent = createErrorPlatformEvent('execution', err);
763
- const errorMacrostep = macrostep(preInitialState, errorEvent, actorScope, []);
858
+ const errorMacrostep = macrostep(preInitialState, errorEvent, resolvedActorScope, [], [[preInitialState, contextSpawnEffects]]);
764
859
  macroState = errorMacrostep.snapshot;
765
860
  microsteps = errorMacrostep.microsteps;
766
861
  initialActions = [];
767
862
  }
768
- return [macroState, this._collectEffects(microsteps, initialActions)];
863
+ if (usesInertScope) {
864
+ setInertActorScopeSnapshot(resolvedActorScope, macroState, false);
865
+ }
866
+ const returnedSnapshot = usesInertScope ? attachSnapshotActorRef(this, resolvedActorScope, macroState) : this._attachPureActorRef(macroState, resolvedActorScope);
867
+ return [returnedSnapshot, this._collectEffects(microsteps)];
769
868
  }
770
869
  start(snapshot) {
771
870
  // Start rehydrated children that were active when persisted. Freshly
@@ -793,7 +892,9 @@ class StateMachine {
793
892
  getPersistedSnapshot(snapshot, options) {
794
893
  return getPersistedSnapshot(snapshot, options);
795
894
  }
796
- restoreSnapshot(snapshot, _actorScope) {
895
+ restoreSnapshot(snapshot, actorScope) {
896
+ const usesInertScope = !actorScope;
897
+ const resolvedActorScope = actorScope ?? createInertActorScope(this);
797
898
  const persistedVersion = snapshot.version;
798
899
  if (persistedVersion !== this.version) {
799
900
  const migrate = this.config.migrate;
@@ -813,9 +914,9 @@ class StateMachine {
813
914
  if (!logic) {
814
915
  continue;
815
916
  }
816
- const actor = createActor(logic, {
917
+ const actor = resolvedActorScope.system.createActorRef(logic, {
817
918
  id: actorId,
818
- parent: _actorScope.self,
919
+ parent: resolvedActorScope.self,
819
920
  syncSnapshot: actorData.syncSnapshot,
820
921
  snapshot: childState,
821
922
  src,
@@ -826,6 +927,19 @@ class StateMachine {
826
927
  actor._rehydrated = true;
827
928
  children[actorId] = actor;
828
929
  }
930
+ const timers = {};
931
+ const persistedTimers = snapshotData.timers ?? {};
932
+ for (const [id, timer] of Object.entries(persistedTimers)) {
933
+ const target = typeof timer.target === 'string' ? timer.target === 'self' ? 'self' : children[timer.target] : resolvedActorScope.self._parent;
934
+ if (!target) {
935
+ const targetDescription = typeof timer.target === 'string' ? timer.target : timer.target.type;
936
+ throw new Error(`Unable to restore timer '${id}': target actor '${targetDescription}' is unavailable.`);
937
+ }
938
+ timers[id] = {
939
+ ...timer,
940
+ target
941
+ };
942
+ }
829
943
  const reviveHistoryValue = historyValue => {
830
944
  if (!historyValue || typeof historyValue !== 'object') {
831
945
  return {};
@@ -864,11 +978,12 @@ class StateMachine {
864
978
  const restoredSnapshot = createMachineSnapshot({
865
979
  ...persistedRest,
866
980
  children,
981
+ timers,
867
982
  _nodes: nodes,
868
983
  value: snapshotData.value,
869
984
  historyValue: revivedHistoryValue,
870
985
  _stateInputs: snapshotData.stateInputs ?? {}
871
- }, this);
986
+ }, this, resolvedActorScope.self);
872
987
  const seen = new WeakSet();
873
988
  function reviveContext(contextPart) {
874
989
  if (seen.has(contextPart)) {
@@ -887,8 +1002,12 @@ class StateMachine {
887
1002
  }
888
1003
  }
889
1004
  reviveContext(restoredSnapshot.context);
890
- return restoredSnapshot;
1005
+ if (usesInertScope) {
1006
+ setInertActorScopeSnapshot(resolvedActorScope, restoredSnapshot, false);
1007
+ return attachSnapshotActorRef(this, resolvedActorScope, restoredSnapshot);
1008
+ }
1009
+ return this._attachPureActorRef(restoredSnapshot, resolvedActorScope);
891
1010
  }
892
1011
  }
893
1012
 
894
- export { StateMachine as S, StateNode as a };
1013
+ export { StateMachine as S, attachSnapshotActorRef as a, getNextSnapshot as b, createInertActorScope as c, StateNode as d, getInitialSnapshot as g, setInertActorScopeSnapshot as s };
@@ -1,4 +1,4 @@
1
- import type { AnyMachineSnapshot, AnyStateMachine, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, StateValueMap, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode } from "./types.js";
1
+ import type { AnyMachineSnapshot, AnyStateMachine, AnyActor, EventObject, HistoryValue, MachineContext, StateConfig, StateValue, StateValueMap, AnyActorRef, Snapshot, MetaObject, StateSchema, StateId, StateIdInputs, StateContextFromStateValue, SnapshotStatus, AnyStateNode, LogicalTimer } from "./types.js";
2
2
  export declare function isMachineSnapshot(value: unknown): value is AnyMachineSnapshot;
3
3
  type Values<T> = T[keyof T];
4
4
  type MatchingObjectStateValue<TStateValue extends Record<string, unknown>, TTestStateValue extends Record<string, unknown>> = false extends Values<{
@@ -45,6 +45,8 @@ interface MachineSnapshotBase<TContext extends MachineContext, TEvent extends Ev
45
45
  _nodes: Array<AnyStateNode>;
46
46
  /** An object mapping actor names to spawned/invoked actors. */
47
47
  children: TChildren;
48
+ /** Pending logical timers owned by this machine snapshot. */
49
+ timers: Readonly<Record<string, LogicalTimer>>;
48
50
  /**
49
51
  * Whether the current state value is a subset of the given partial state
50
52
  * value.
@@ -98,7 +100,7 @@ interface StoppedMachineSnapshot<TContext extends MachineContext, TEvent extends
98
100
  error: undefined;
99
101
  }
100
102
  export type MachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TOutput, TMeta extends MetaObject, TStateSchema extends StateSchema> = ActiveMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | DoneMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | ErrorMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema> | StoppedMachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TStateSchema>;
101
- export declare function createMachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TMeta extends MetaObject, TStateSchema extends StateSchema>(config: StateConfig<TContext, TEvent>, machine: AnyStateMachine): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, undefined, TMeta, TStateSchema>;
103
+ export declare function createMachineSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TMeta extends MetaObject, TStateSchema extends StateSchema>(config: StateConfig<TContext, TEvent>, machine: AnyStateMachine, actorRef?: AnyActor): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, undefined, TMeta, TStateSchema>;
102
104
  export declare function cloneMachineSnapshot<TState extends AnyMachineSnapshot>(snapshot: TState, config?: Partial<StateConfig<any, any>>): TState;
103
105
  export declare function getPersistedSnapshot<TContext extends MachineContext, TEvent extends EventObject, TChildren extends Record<string, AnyActorRef | undefined>, TStateValue extends StateValue, TTag extends string, TOutput, TMeta extends MetaObject>(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, any>, options?: unknown): Snapshot<unknown>;
104
106
  export {};
@@ -62,8 +62,9 @@ export declare class StateMachine<TContext extends MachineContext, TEvent extend
62
62
  * @param snapshot The current snapshot
63
63
  * @param event The received event
64
64
  */
65
- transition(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, event: TEvent, actorScope: ActorScope<typeof snapshot, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
65
+ transition(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, event: TEvent, actorScope?: ActorScope<typeof snapshot, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
66
66
  private _collectEffects;
67
+ private _attachPureActorRef;
67
68
  private _transitionFast;
68
69
  /**
69
70
  * Determines the next state given the current `state` and `event`. Calculates
@@ -79,11 +80,11 @@ export declare class StateMachine<TContext extends MachineContext, TEvent extend
79
80
  * Returns the initial `State` instance, with reference to `self` as an
80
81
  * `ActorRef`.
81
82
  */
82
- getInitialSnapshot(actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>, input?: TInput): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
83
- initialTransition(input: TInput | undefined, actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
83
+ getInitialSnapshot(actorScope?: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>, input?: TInput): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
84
+ initialTransition(input: TInput | undefined, actorScope?: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): ActorLogicTransitionResult<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, ExecutableActionObjectFromLogic<this>>;
84
85
  start(snapshot?: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>): void;
85
86
  getStateNodeById(stateId: string): StateNode<TContext, TEvent>;
86
87
  getPersistedSnapshot(snapshot: MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, options?: unknown): Snapshot<unknown>;
87
- restoreSnapshot(snapshot: Snapshot<unknown>, _actorScope: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
88
+ restoreSnapshot(snapshot: Snapshot<unknown>, actorScope?: ActorScope<MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>, TEvent, AnyActorSystem, TEmitted>): MachineSnapshot<TContext, TEvent, TChildren, TStateValue, TTag, TOutput, TMeta, TConfig>;
88
89
  }
89
90
  export {};
@@ -1,15 +1,17 @@
1
- import { AnyActor, AnyActorScope, EventObject } from "./types.js";
1
+ import { type ActorTermination, AnyActor, AnyActorScope, EventObject } from "./types.js";
2
+ export declare function assertSendToEvent(event: EventObject): void;
2
3
  export declare const builtInActions: {
3
- "@xstate.spawn": (_actor: AnyActor) => void;
4
- "@xstate.start": (actor: AnyActor) => void;
5
- "@xstate.raise": (actorScope: AnyActorScope, event: EventObject, options: {
4
+ "@xstate.spawn": (actor: AnyActor) => any;
5
+ "@xstate.start": (actor: AnyActor) => any;
6
+ "@xstate.raise": (actorScope: AnyActorScope, _event: EventObject, options: {
6
7
  id?: string;
7
8
  delay?: number;
8
- }) => void;
9
+ }) => void | PromiseLike<void>;
9
10
  "@xstate.sendTo": (actorScope: AnyActorScope, actor: AnyActor, event: EventObject, options: {
10
11
  id?: string;
11
12
  delay?: number;
12
- }) => void;
13
- "@xstate.cancel": (actorScope: AnyActorScope, sendId: string) => void;
14
- "@xstate.stop": (actorScope: AnyActorScope, actor: AnyActor) => void;
13
+ }) => void | PromiseLike<void>;
14
+ "@xstate.cancel": (actorScope: AnyActorScope, sendId: string) => void | PromiseLike<void>;
15
+ "@xstate.stop": (actorScope: AnyActorScope, actor: AnyActor) => void | PromiseLike<void>;
16
+ "@xstate.terminate": (actor: AnyActor, termination: ActorTermination) => any;
15
17
  };
@@ -1,6 +1,6 @@
1
1
  import { StandardSchemaV1 } from "../schema.types.js";
2
- import { AnyActorSystem } from "../system.js";
3
- import { ActorLogic, ActorRefFromLogic, ActorScope, EventObject, NonReducibleUnknown, Snapshot } from "../types.js";
2
+ import { ActorSystemRuntime, AnyActorSystem } from "../system.js";
3
+ import { ActorLogic, ActorRefFromLogic, ActorScope, EventObject, ExecutableActionObject, NonReducibleUnknown, Snapshot } from "../types.js";
4
4
  export type LogicSnapshot<TContext, TOutput, TInput> = Snapshot<TOutput> & {
5
5
  context: TContext;
6
6
  input: TInput | undefined;
@@ -22,29 +22,14 @@ export interface LogicArgs<TContext, TEvent extends EventObject, TInput> {
22
22
  system: AnyActorSystem;
23
23
  self: LogicActorRef<TContext, unknown, TEvent, TInput>;
24
24
  }
25
- export type LogicEffect<TEvent extends EventObject, TEmitted extends EventObject> = {
26
- type: 'emit';
27
- event: TEmitted;
28
- } | {
29
- type: 'sendBack';
30
- event: EventObject;
31
- } | {
32
- type: 'raise';
33
- event: TEvent;
34
- } | {
35
- type: 'effect';
36
- key?: string;
37
- exec: () => void | (() => void);
38
- } | {
39
- type: 'cleanupEffects';
40
- };
25
+ export type LogicEffect<_TEvent extends EventObject, _TEmitted extends EventObject> = ExecutableActionObject;
41
26
  export interface LogicEnqueue<TEvent extends EventObject, TEmitted extends EventObject> {
42
27
  emit: (emitted: TEmitted) => void;
43
28
  sendBack: (event: EventObject) => void;
44
29
  raise: (event: TEvent) => void;
45
30
  effect: {
46
- (exec: () => void | (() => void)): void;
47
- (key: string, exec: () => void | (() => void)): void;
31
+ (exec: (runtime?: Partial<ActorSystemRuntime>) => void | (() => void)): void;
32
+ (key: string, exec: (runtime?: Partial<ActorSystemRuntime>) => void | (() => void)): void;
48
33
  };
49
34
  }
50
35
  export type LogicPatch<TContext, TOutput, TInput> = Partial<{
@@ -82,7 +67,6 @@ export type LogicActorRef<TContext, TOutput, TEvent extends EventObject, TInput>
82
67
  export declare const XSTATE_LOGIC_EFFECT_RESOLVE = "xstate.logic.effect.resolve";
83
68
  export declare const XSTATE_LOGIC_EFFECT_REJECT = "xstate.logic.effect.reject";
84
69
  export declare const XSTATE_LOGIC_EFFECT_START = "xstate.logic.effect.start";
85
- export declare function executeLogicEffects(effects: readonly unknown[] | undefined, actorScope: ActorScope<any, any, any, any>): void;
86
70
  export declare function createLogic<TContext, const TInputSchema extends StandardSchemaV1, const TOutputSchema extends StandardSchemaV1, TEvent extends EventObject = EventObject, TEmitted extends EventObject = EventObject>(config: LogicConfig<TContext, StandardSchemaV1.InferOutput<TOutputSchema>, TEvent, StandardSchemaV1.InferOutput<TInputSchema>, TEmitted, TInputSchema, TOutputSchema> & {
87
71
  schemas: {
88
72
  input: TInputSchema;
@@ -56,7 +56,9 @@ export declare class Actor<TLogic extends AnyActorLogic> implements ActorInstanc
56
56
  */
57
57
  constructor(logic: TLogic, options?: ActorOptions<TLogic>);
58
58
  private _deferred;
59
- private _pendingEffects?;
59
+ private _restored;
60
+ /** Associates each live snapshot with this actor for later pure transitions. */
61
+ private _setSnapshot;
60
62
  private _setErrorSnapshot;
61
63
  /** Recover via the logic's error event if possible; otherwise error out. */
62
64
  private _recoverOrError;
@@ -1,10 +1,12 @@
1
1
  import { createTransitionEnqueue } from "./transitionActions.js";
2
- import type { ActorLogic, EventObject, MachineContext, NonReducibleUnknown, Snapshot } from "./types.js";
2
+ import type { ActorLogic, EventObject, MachineContext, LogicalTimer, NonReducibleUnknown, Snapshot } from "./types.js";
3
3
  export type FSMSnapshot<TContext extends MachineContext, TState extends string, TInput = unknown> = Snapshot<undefined> & {
4
4
  value: TState;
5
5
  context: TContext;
6
6
  input: TInput | undefined;
7
7
  children: {};
8
+ timers: Record<string, LogicalTimer>;
9
+ _nextTimerId: number;
8
10
  _stateInput: Record<string, unknown> | undefined;
9
11
  machine: {
10
12
  id: string;
@@ -18,13 +18,13 @@ export { isMachineSnapshot, type MachineSnapshot } from "./State.js";
18
18
  export { StateMachine } from "./StateMachine.js";
19
19
  export { StateNode } from "./StateNode.js";
20
20
  export { getStateNodes } from "./stateUtils.js";
21
- export type { ActorSystem, AnyActorSystem } from "./system.js";
21
+ export type { ActorSystem, ActorSystemRuntime, AnyActorSystem } from "./system.js";
22
22
  export { toPromise } from "./toPromise.js";
23
23
  export * from "./types.js";
24
24
  export type { Next_MachineConfig as MachineConfig, Next_StateNodeConfig as StateNodeConfig, Next_InvokeConfig as InvokeConfig, Next_TransitionConfigOrTarget as TransitionConfigOrTarget, Implementations, InferEvents, WidenLiterals } from "./types.v6.js";
25
25
  export { getAllOwnEventDescriptors as __unsafe_getAllOwnEventDescriptors, matchesState, checkStateIn, pathToStateValue, toObserver } from "./utils.js";
26
26
  export { transition, initialTransition, getMicrosteps, getInitialMicrosteps, getNextTransitions } from "./transition.js";
27
- export { isBuiltInExecutableAction } from "./transitionActions.js";
27
+ export { executeEffects, isBuiltInExecutableAction } from "./transitionActions.js";
28
28
  export { waitFor } from "./waitFor.js";
29
29
  declare global {
30
30
  interface SymbolConstructor {
@@ -1,12 +1,12 @@
1
- import { ActorFromLogic, AnyActorLogic, AnyActorRef, AnyActorScope, AnyEventObject, AnyMachineSnapshot, ConditionalRequired, InputFrom, IsNotNever, RegistryKeyForLogic, SystemRegistry, type RequiredLogicInput } from "./types.js";
1
+ import { ActorFromLogic, AnyActorLogic, AnyActorRef, AnyActorScope, ConditionalRequired, InputFrom, IsNotNever, RegistryKeyForLogic, SystemRegistry, type RequiredLogicInput } from "./types.js";
2
2
  export type Spawner<TSystemRegistry extends SystemRegistry = SystemRegistry> = <TLogic extends AnyActorLogic>(src: TLogic, ...[options]: ConditionalRequired<[
3
3
  options?: {
4
4
  id?: string;
5
5
  registryKey?: RegistryKeyForLogic<TLogic, TSystemRegistry>;
6
- input?: TLogic extends string ? unknown : InputFrom<TLogic>;
6
+ input?: InputFrom<TLogic>;
7
7
  syncSnapshot?: boolean;
8
8
  } & {
9
9
  [K in RequiredLogicInput<TLogic>]: unknown;
10
10
  }
11
11
  ], IsNotNever<RequiredLogicInput<TLogic>>>) => ActorFromLogic<TLogic>;
12
- export declare function createSpawner(actorScope: AnyActorScope, { machine, context }: AnyMachineSnapshot, event: AnyEventObject, spawnedChildren: Record<string, AnyActorRef>): Spawner;
12
+ export declare function createSpawner(actorScope: AnyActorScope, actorSources: Record<string, AnyActorLogic>, spawnedChildren: Record<string, AnyActorRef>): Spawner;
@@ -50,7 +50,7 @@ export declare function getTransitionResult(transition: Pick<AnyTransitionDefini
50
50
  internalEvents: EventObject[] | undefined;
51
51
  input: Record<string, unknown> | undefined;
52
52
  };
53
- export declare function macrostep(snapshot: AnyMachineSnapshot, event: EventObject, actorScope: AnyActorScope, internalQueue: AnyEventObject[]): {
53
+ export declare function macrostep(snapshot: AnyMachineSnapshot, event: EventObject, actorScope: AnyActorScope, internalQueue: AnyEventObject[], initialMicrosteps?: Microstep[]): {
54
54
  snapshot: typeof snapshot;
55
55
  microsteps: Microstep[];
56
56
  };
@@ -1,29 +1,54 @@
1
1
  import { InspectionEvent } from "./inspection.js";
2
- import { ActorSystemInfo, AnyActor, Observer, EventObject, Subscription, TimersRestoreStrategy } from "./types.js";
3
- interface ScheduledEvent {
2
+ import { AnyEventObject, ActorTermination, ActorSystemInfo, AnyActor, Observer, EventObject, Subscription } from "./types.js";
3
+ interface ScheduledTimer {
4
4
  id: string;
5
- event: EventObject;
6
- startedAt: number;
5
+ scheduledAt: number;
6
+ dueAt: number;
7
7
  delay: number;
8
8
  source: AnyActor;
9
- target: AnyActor;
10
9
  }
11
10
  export interface Clock {
12
11
  setTimeout(fn: (...args: any[]) => void, timeout: number): any;
13
12
  clearTimeout(id: any): void;
14
13
  }
15
14
  interface Scheduler {
16
- schedule(source: AnyActor, target: AnyActor, event: EventObject, delay: number, id: string | undefined): void;
15
+ schedule(source: AnyActor, id: string, delay: number): void;
17
16
  cancel(source: AnyActor, id: string): void;
18
17
  cancelAll(actor: AnyActor): void;
19
18
  }
20
- export interface ActorSystem<T extends ActorSystemInfo> {
19
+ /**
20
+ * Runtime operations used to execute effects.
21
+ *
22
+ * An external interpreter can override these operations while the default actor
23
+ * system provides the local in-memory implementation.
24
+ */
25
+ export interface ActorSystemRuntime {
26
+ /** Publishes a newly created actor to the runtime. */
27
+ spawnActor(source: AnyActor | undefined, actor: AnyActor): void | PromiseLike<void>;
28
+ /** Starts an actor. */
29
+ startActor(actor: AnyActor): void | PromiseLike<void>;
30
+ /** Stops an actor without producing a completion result. */
31
+ stopActor(actor: AnyActor): void | PromiseLike<void>;
32
+ /** Completes or errors an actor and publishes its terminal result. */
33
+ terminateActor(actor: AnyActor, termination: ActorTermination): void | PromiseLike<void>;
34
+ /** Delivers an event between actors. */
35
+ sendEvent(source: AnyActor | undefined, target: AnyActor, event: AnyEventObject): void | PromiseLike<void>;
36
+ /** Publishes an emitted event. */
37
+ emitEvent(source: AnyActor, event: EventObject): void | PromiseLike<void>;
38
+ /** Schedules a logical timer. */
39
+ scheduleTimer(source: AnyActor, id: string, delay: number): void | PromiseLike<void>;
40
+ /** Cancels one logical timer. */
41
+ cancelTimer(source: AnyActor, id: string): void | PromiseLike<void>;
42
+ /** Cancels all logical timers owned by an actor. */
43
+ cancelAllTimers(source: AnyActor): void | PromiseLike<void>;
44
+ }
45
+ export interface ActorSystem<T extends ActorSystemInfo> extends ActorSystemRuntime {
21
46
  get: <K extends keyof T['actors']>(key: K) => T['actors'][K] | undefined;
22
47
  getAll: () => Partial<T['actors']>;
23
48
  inspect: (observer: Observer<InspectionEvent> | ((inspectionEvent: InspectionEvent) => void)) => Subscription;
24
49
  scheduler: Scheduler;
25
50
  getSnapshot: () => {
26
- _scheduledEvents: Record<string, ScheduledEvent>;
51
+ _scheduledTimers: Record<string, ScheduledTimer>;
27
52
  };
28
53
  start: () => void;
29
54
  _clock: Clock;
@@ -34,6 +59,6 @@ export declare function createRuntimeSystem<T extends ActorSystemInfo>(rootActor
34
59
  clock: Clock;
35
60
  logger: (...args: any[]) => void;
36
61
  snapshot?: unknown;
37
- timers?: TimersRestoreStrategy;
62
+ createActorRef: ActorSystem<T>['createActorRef'];
38
63
  }): ActorSystem<T>;
39
64
  export {};
@@ -1,6 +1,8 @@
1
- import type { AnyAction, AnyActorScope, AnyEventObject, AnyMachineSnapshot, EnqueueObject, EventObject, ExecutableActionObject, MachineContext, SpecialExecutableAction, StartExecutableActionObject } from "./types.js";
1
+ import type { ActorSystemRuntime } from "./system.js";
2
+ import type { AnyAction, AnyActor, AnyActorScope, AnyEventObject, AnyMachineSnapshot, EnqueueObject, EventObject, ExecutableActionObject, MachineContext, SpecialExecutableAction, SpawnExecutableActionObject, StartExecutableActionObject } from "./types.js";
2
3
  export declare function mergeContextPatch(context: MachineContext, patch: MachineContext): MachineContext;
3
4
  export declare function createTransitionEnqueue(actorScope: AnyActorScope, actions: any[], internalEvents: EventObject[], actorSubscriptions?: boolean, createActors?: boolean): EnqueueObject<any, any>;
5
+ export declare function createSpawnEffect(actor: AnyActor): SpawnExecutableActionObject;
4
6
  /**
5
7
  * Attached (listener/subscription) starts are ordered before child starts so
6
8
  * that a listener/subscription captures events emitted synchronously as its
@@ -8,5 +10,7 @@ export declare function createTransitionEnqueue(actorScope: AnyActorScope, actio
8
10
  */
9
11
  export declare function deriveDeferredStarts(effects: ReadonlyArray<ExecutableActionObject>): StartExecutableActionObject[];
10
12
  export declare function isBuiltInExecutableAction(action: ExecutableActionObject): action is SpecialExecutableAction;
13
+ /** Executes transition effects sequentially, awaiting each runtime operation. */
14
+ export declare function executeEffects(effects: readonly ExecutableActionObject[], runtime?: Partial<ActorSystemRuntime>): Promise<void>;
11
15
  export declare function resolveActionsWithContext(currentSnapshot: AnyMachineSnapshot, event: AnyEventObject, actorScope: AnyActorScope, actions: AnyAction[]): [AnyMachineSnapshot, ExecutableActionObject[]];
12
16
  export declare function createEnqueueObject(props: Partial<EnqueueObject<any, any>>, action: <T extends (...args: any[]) => any>(fn: T, ...args: Parameters<T>) => void): EnqueueObject<any, any>;