xstate 4.32.1 → 4.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import { StateNode } from './StateNode';
3
3
  declare type Configuration<TC, TE extends EventObject> = Iterable<StateNode<TC, any, TE>>;
4
4
  declare type AdjList<TC, TE extends EventObject> = Map<StateNode<TC, any, TE>, Array<StateNode<TC, any, TE>>>;
5
5
  export declare const isLeafNode: (stateNode: StateNode<any, any, any, any, any, any>) => boolean;
6
+ export declare function getAllChildren<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE>): Array<StateNode<TC, any, TE>>;
6
7
  export declare function getChildren<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE>): Array<StateNode<TC, any, TE>>;
7
8
  export declare function getAllStateNodes<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE, any, any, any>): Array<StateNode<TC, any, TE, any, any, any>>;
8
9
  export declare function getConfiguration<TC, TE extends EventObject>(prevStateNodes: Iterable<StateNode<TC, any, TE, any, any, any>>, stateNodes: Iterable<StateNode<TC, any, TE, any, any, any>>): Set<StateNode<TC, any, TE, any, any, any>>;
package/es/stateUtils.js CHANGED
@@ -4,10 +4,13 @@ import { flatten } from './utils.js';
4
4
  var isLeafNode = function (stateNode) {
5
5
  return stateNode.type === 'atomic' || stateNode.type === 'final';
6
6
  };
7
- function getChildren(stateNode) {
7
+ function getAllChildren(stateNode) {
8
8
  return Object.keys(stateNode.states).map(function (key) {
9
9
  return stateNode.states[key];
10
- }).filter(function (sn) {
10
+ });
11
+ }
12
+ function getChildren(stateNode) {
13
+ return getAllChildren(stateNode).filter(function (sn) {
11
14
  return sn.type !== 'history';
12
15
  });
13
16
  }
@@ -256,4 +259,4 @@ function getTagsFromConfiguration(configuration) {
256
259
  })));
257
260
  }
258
261
 
259
- export { getAdjList, getAllStateNodes, getChildren, getConfiguration, getMeta, getTagsFromConfiguration, getValue, has, isInFinalState, isLeafNode, nextEvents };
262
+ export { getAdjList, getAllChildren, getAllStateNodes, getChildren, getConfiguration, getMeta, getTagsFromConfiguration, getValue, has, isInFinalState, isLeafNode, nextEvents };
package/es/types.d.ts CHANGED
@@ -422,6 +422,12 @@ export interface StateNodeConfig<TContext, TStateSchema extends StateSchema, TEv
422
422
  * @default false
423
423
  */
424
424
  preserveActionOrder?: boolean;
425
+ /**
426
+ * Whether XState calls actions with the event directly responsible for the related transition.
427
+ *
428
+ * @default false
429
+ */
430
+ predictableActionArguments?: boolean;
425
431
  /**
426
432
  * A text description of the state node
427
433
  */
@@ -856,6 +862,9 @@ export interface StateConfig<TContext, TEvent extends EventObject> {
856
862
  */
857
863
  activities?: ActivityMap;
858
864
  meta?: any;
865
+ /**
866
+ * @deprecated
867
+ */
859
868
  events?: TEvent[];
860
869
  configuration: Array<StateNode<TContext, any, TEvent>>;
861
870
  transitions: Array<TransitionDefinition<TContext, TEvent>>;
@@ -1027,5 +1036,6 @@ declare type Matches<TypegenEnabledArg, TypegenDisabledArg> = {
1027
1036
  (stateValue: TypegenDisabledArg): any;
1028
1037
  };
1029
1038
  export declare type StateValueFrom<TMachine extends AnyStateMachine> = StateFrom<TMachine>['matches'] extends Matches<infer TypegenEnabledArg, infer TypegenDisabledArg> ? TMachine['__TResolvedTypesMeta'] extends TypegenEnabled ? TypegenEnabledArg : TypegenDisabledArg : never;
1039
+ export declare type PredictableActionArgumentsExec = (action: ActionObject<unknown, EventObject>, context: unknown, _event: SCXML.Event<EventObject>) => void;
1030
1040
  export {};
1031
1041
  //# sourceMappingURL=types.d.ts.map
package/es/utils.d.ts CHANGED
@@ -67,6 +67,6 @@ export declare function normalizeTarget<TContext, TEvent extends EventObject>(ta
67
67
  export declare function reportUnhandledExceptionOnInvocation(originalError: any, currentError: any, id: string): void;
68
68
  export declare function evaluateGuard<TContext, TEvent extends EventObject>(machine: StateNode<TContext, any, TEvent, any, any>, guard: Guard<TContext, TEvent>, context: TContext, _event: SCXML.Event<TEvent>, state: State<TContext, TEvent>): boolean;
69
69
  export declare function toInvokeSource(src: string | InvokeSourceDefinition): InvokeSourceDefinition;
70
- export declare function toObserver<T>(nextHandler: Observer<T> | ((value: T) => void), errorHandler?: (error: any) => void, completionHandler?: () => void): Observer<T>;
70
+ export declare function toObserver<T>(nextHandler?: Partial<Observer<T>> | ((value: T) => void), errorHandler?: (error: any) => void, completionHandler?: () => void): Observer<T>;
71
71
  export declare function createInvokeId(stateNodeId: string, index: number): string;
72
72
  //# sourceMappingURL=utils.d.ts.map
package/es/utils.js CHANGED
@@ -605,18 +605,14 @@ function toInvokeSource(src) {
605
605
  return src;
606
606
  }
607
607
  function toObserver(nextHandler, errorHandler, completionHandler) {
608
- if (typeof nextHandler === 'object') {
609
- return nextHandler;
610
- }
611
-
612
- var noop = function () {
613
- return void 0;
614
- };
608
+ var noop = function () {};
615
609
 
610
+ var isObserver = typeof nextHandler === 'object';
611
+ var self = isObserver ? nextHandler : null;
616
612
  return {
617
- next: nextHandler,
618
- error: errorHandler || noop,
619
- complete: completionHandler || noop
613
+ next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
614
+ error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
615
+ complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
620
616
  };
621
617
  }
622
618
  function createInvokeId(stateNodeId, index) {
package/lib/Machine.js CHANGED
@@ -3,7 +3,9 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var StateNode = require('./StateNode.js');
6
+ var environment = require('./environment.js');
6
7
 
8
+ var warned = false;
7
9
  function Machine(config, options, initialContext) {
8
10
  if (initialContext === void 0) {
9
11
  initialContext = config.context;
@@ -12,6 +14,11 @@ function Machine(config, options, initialContext) {
12
14
  return new StateNode.StateNode(config, options, initialContext);
13
15
  }
14
16
  function createMachine(config, options) {
17
+ if (!environment.IS_PRODUCTION && !config.predictableActionArguments && !warned) {
18
+ warned = true;
19
+ console.warn('It is highly recommended to set `predictableActionArguments` to `true` when using `createMachine`. https://xstate.js.org/docs/guides/actions.html');
20
+ }
21
+
15
22
  return new StateNode.StateNode(config, options);
16
23
  }
17
24
 
package/lib/State.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { StateValue, ActivityMap, EventObject, HistoryValue, ActionObject, EventType, StateConfig, SCXML, StateSchema, TransitionDefinition, Typestate, ActorRef, StateMachine, SimpleEventsOf } from './types';
1
+ import { StateValue, ActivityMap, EventObject, HistoryValue, ActionObject, StateConfig, SCXML, StateSchema, TransitionDefinition, Typestate, ActorRef, StateMachine, SimpleEventsOf } from './types';
2
2
  import { StateNode } from './StateNode';
3
3
  import { TypegenDisabled, TypegenEnabled } from './typegenTypes';
4
4
  import { BaseActionObject, Prop } from './types';
@@ -44,7 +44,7 @@ export declare class State<TContext, TEvent extends EventObject = EventObject, T
44
44
  /**
45
45
  * The next events that will cause a transition from the current state.
46
46
  */
47
- nextEvents: EventType[];
47
+ nextEvents: Array<TEvent['type']>;
48
48
  /**
49
49
  * The transition definitions that resulted in this state.
50
50
  */
@@ -1,4 +1,4 @@
1
- import { Event, StateValue, StateTransition, MachineOptions, EventObject, HistoryValue, StateNodeDefinition, TransitionDefinition, DelayedTransitionDefinition, ActivityDefinition, StateNodeConfig, StateSchema, StateNodesConfig, InvokeDefinition, ActionObject, Mapper, PropertyMapper, SCXML, Typestate, TransitionDefinitionMap, MachineSchema, InternalMachineOptions, ServiceMap, StateConfig } from './types';
1
+ import { Event, StateValue, StateTransition, MachineOptions, EventObject, HistoryValue, StateNodeDefinition, TransitionDefinition, DelayedTransitionDefinition, ActivityDefinition, StateNodeConfig, StateSchema, StateNodesConfig, InvokeDefinition, ActionObject, Mapper, PropertyMapper, SCXML, Typestate, TransitionDefinitionMap, MachineSchema, InternalMachineOptions, ServiceMap, StateConfig, PredictableActionArgumentsExec } from './types';
2
2
  import { State } from './State';
3
3
  import { TypegenDisabled } from './typegenTypes';
4
4
  declare class StateNode<TContext = any, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = {
@@ -189,12 +189,7 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
189
189
  private _transition;
190
190
  getTransitionData(state: State<TContext, TEvent, any, any, any>, event: Event<TEvent> | SCXML.Event<TEvent>): StateTransition<TContext, TEvent> | undefined;
191
191
  private next;
192
- private nodesFromChild;
193
- /**
194
- * Whether the given state node "escapes" this state node. If the `stateNode` is equal to or the parent of
195
- * this state node, it does not escape.
196
- */
197
- private escapes;
192
+ private getExternalReentryNodes;
198
193
  private getActions;
199
194
  /**
200
195
  * Determines the next state given the current `state` and sent `event`.
@@ -203,7 +198,7 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
203
198
  * @param event The event that was sent at the current state
204
199
  * @param context The current context (extended state) of the current state
205
200
  */
206
- transition(state: StateValue | State<TContext, TEvent, any, TTypestate, TResolvedTypesMeta> | undefined, event: Event<TEvent> | SCXML.Event<TEvent>, context?: TContext): State<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta>;
201
+ transition(state: StateValue | State<TContext, TEvent, any, TTypestate, TResolvedTypesMeta> | undefined, event: Event<TEvent> | SCXML.Event<TEvent>, context?: TContext, exec?: PredictableActionArgumentsExec): State<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta>;
207
202
  private resolveRaisedTransition;
208
203
  private resolveTransition;
209
204
  /**
package/lib/StateNode.js CHANGED
@@ -120,7 +120,7 @@ function () {
120
120
  stateNode.order = order++;
121
121
 
122
122
  try {
123
- for (var _b = _tslib.__values(stateUtils.getChildren(stateNode)), _c = _b.next(); !_c.done; _c = _b.next()) {
123
+ for (var _b = _tslib.__values(stateUtils.getAllChildren(stateNode)), _c = _b.next(); !_c.done; _c = _b.next()) {
124
124
  var child = _c.value;
125
125
  dfs(child);
126
126
  }
@@ -631,9 +631,14 @@ function () {
631
631
  return _this.getRelativeStateNodes(stateNode, state.historyValue);
632
632
  }));
633
633
  var isInternal = !!selectedTransition.internal;
634
- var reentryNodes = isInternal ? [] : utils.flatten(allNextStateNodes.map(function (n) {
635
- return _this.nodesFromChild(n);
636
- }));
634
+ var reentryNodes = [];
635
+
636
+ if (!isInternal) {
637
+ nextStateNodes.forEach(function (targetNode) {
638
+ reentryNodes.push.apply(reentryNodes, _tslib.__spreadArray([], _tslib.__read(_this.getExternalReentryNodes(targetNode)), false));
639
+ });
640
+ }
641
+
637
642
  return {
638
643
  transitions: [selectedTransition],
639
644
  entrySet: reentryNodes,
@@ -644,58 +649,38 @@ function () {
644
649
  };
645
650
  };
646
651
 
647
- StateNode.prototype.nodesFromChild = function (childStateNode) {
648
- if (childStateNode.escapes(this)) {
649
- return [];
650
- }
651
-
652
+ StateNode.prototype.getExternalReentryNodes = function (targetNode) {
652
653
  var nodes = [];
653
- var marker = childStateNode;
654
654
 
655
- while (marker && marker !== this) {
655
+ var _a = _tslib.__read(targetNode.order > this.order ? [targetNode, this] : [this, targetNode], 2),
656
+ marker = _a[0],
657
+ possibleAncestor = _a[1];
658
+
659
+ while (marker && marker !== possibleAncestor) {
656
660
  nodes.push(marker);
657
661
  marker = marker.parent;
658
662
  }
659
663
 
660
- nodes.push(this); // inclusive
661
-
662
- return nodes;
663
- };
664
- /**
665
- * Whether the given state node "escapes" this state node. If the `stateNode` is equal to or the parent of
666
- * this state node, it does not escape.
667
- */
668
-
669
-
670
- StateNode.prototype.escapes = function (stateNode) {
671
- if (this === stateNode) {
672
- return false;
673
- }
674
-
675
- var parent = this.parent;
676
-
677
- while (parent) {
678
- if (parent === stateNode) {
679
- return false;
680
- }
681
-
682
- parent = parent.parent;
664
+ if (marker !== possibleAncestor) {
665
+ // we never got to `possibleAncestor`, therefore the initial `marker` "escapes" it
666
+ // it's in a different part of the tree so no states will be reentered for such an external transition
667
+ return [];
683
668
  }
684
669
 
685
- return true;
670
+ nodes.push(possibleAncestor);
671
+ return nodes;
686
672
  };
687
673
 
688
- StateNode.prototype.getActions = function (transition, currentContext, _event, prevState) {
674
+ StateNode.prototype.getActions = function (resolvedConfig, isDone, transition, currentContext, _event, prevState) {
689
675
  var e_4, _a, e_5, _b;
690
676
 
691
677
  var prevConfig = stateUtils.getConfiguration([], prevState ? this.getStateNodes(prevState.value) : [this]);
692
- var resolvedConfig = transition.configuration.length ? stateUtils.getConfiguration(prevConfig, transition.configuration) : prevConfig;
693
678
 
694
679
  try {
695
680
  for (var resolvedConfig_1 = _tslib.__values(resolvedConfig), resolvedConfig_1_1 = resolvedConfig_1.next(); !resolvedConfig_1_1.done; resolvedConfig_1_1 = resolvedConfig_1.next()) {
696
681
  var sn = resolvedConfig_1_1.value;
697
682
 
698
- if (!stateUtils.has(prevConfig, sn)) {
683
+ if (!stateUtils.has(prevConfig, sn) || stateUtils.has(transition.entrySet, sn.parent)) {
699
684
  transition.entrySet.push(sn);
700
685
  }
701
686
  }
@@ -780,6 +765,18 @@ function () {
780
765
  exitActions = _c[1];
781
766
 
782
767
  var actions$1 = actions.toActionObjects(exitActions.concat(transition.actions).concat(entryActions), this.machine.options.actions);
768
+
769
+ if (isDone) {
770
+ var stopActions = actions.toActionObjects(utils.flatten(_tslib.__spreadArray([], _tslib.__read(resolvedConfig), false).sort(function (a, b) {
771
+ return b.order - a.order;
772
+ }).map(function (stateNode) {
773
+ return stateNode.onExit;
774
+ })), this.machine.options.actions).filter(function (action) {
775
+ return action.type !== actionTypes.raise && (action.type !== actionTypes.send || !!action.to && action.to !== types.SpecialTargets.Internal);
776
+ });
777
+ return actions$1.concat(stopActions);
778
+ }
779
+
783
780
  return actions$1;
784
781
  };
785
782
  /**
@@ -791,7 +788,7 @@ function () {
791
788
  */
792
789
 
793
790
 
794
- StateNode.prototype.transition = function (state, event, context) {
791
+ StateNode.prototype.transition = function (state, event, context, exec) {
795
792
  if (state === void 0) {
796
793
  state = this.initialState;
797
794
  }
@@ -829,14 +826,14 @@ function () {
829
826
  var prevConfig = stateUtils.getConfiguration([], this.getStateNodes(currentState.value));
830
827
  var resolvedConfig = stateTransition.configuration.length ? stateUtils.getConfiguration(prevConfig, stateTransition.configuration) : prevConfig;
831
828
  stateTransition.configuration = _tslib.__spreadArray([], _tslib.__read(resolvedConfig), false);
832
- return this.resolveTransition(stateTransition, currentState, currentState.context, _event);
829
+ return this.resolveTransition(stateTransition, currentState, currentState.context, exec, _event);
833
830
  };
834
831
 
835
- StateNode.prototype.resolveRaisedTransition = function (state, _event, originalEvent) {
832
+ StateNode.prototype.resolveRaisedTransition = function (state, _event, originalEvent, predictableExec) {
836
833
  var _a;
837
834
 
838
835
  var currentActions = state.actions;
839
- state = this.transition(state, _event); // Save original event to state
836
+ state = this.transition(state, _event, undefined, predictableExec); // Save original event to state
840
837
  // TODO: this should be the raised event! Delete in V5 (breaking)
841
838
 
842
839
  state._event = originalEvent;
@@ -847,7 +844,7 @@ function () {
847
844
  return state;
848
845
  };
849
846
 
850
- StateNode.prototype.resolveTransition = function (stateTransition, currentState, context, _event) {
847
+ StateNode.prototype.resolveTransition = function (stateTransition, currentState, context, predictableExec, _event) {
851
848
  var e_6, _a;
852
849
 
853
850
  var _this = this;
@@ -861,9 +858,11 @@ function () {
861
858
  // - OR there are transitions
862
859
 
863
860
  var willTransition = !currentState || stateTransition.transitions.length > 0;
861
+ var resolvedConfiguration = willTransition ? stateTransition.configuration : currentState ? currentState.configuration : [];
862
+ var isDone = stateUtils.isInFinalState(resolvedConfiguration, this);
864
863
  var resolvedStateValue = willTransition ? stateUtils.getValue(this.machine, configuration) : undefined;
865
864
  var historyValue = currentState ? currentState.historyValue ? currentState.historyValue : stateTransition.source ? this.machine.historyValue(currentState.value) : undefined : undefined;
866
- var actions$1 = this.getActions(stateTransition, context, _event, currentState);
865
+ var actions$1 = this.getActions(new Set(resolvedConfiguration), isDone, stateTransition, context, _event, currentState);
867
866
  var activities = currentState ? _tslib.__assign({}, currentState.activities) : {};
868
867
 
869
868
  try {
@@ -888,7 +887,7 @@ function () {
888
887
  }
889
888
  }
890
889
 
891
- var _b = _tslib.__read(actions.resolveActions(this, currentState, context, _event, actions$1, this.machine.config.preserveActionOrder), 2),
890
+ var _b = _tslib.__read(actions.resolveActions(this, currentState, context, _event, actions$1, predictableExec, this.machine.config.predictableActionArguments || this.machine.config.preserveActionOrder), 2),
892
891
  resolvedActions = _b[0],
893
892
  updatedContext = _b[1];
894
893
 
@@ -907,8 +906,6 @@ function () {
907
906
  acc[action.activity.id] = Actor.createInvocableActor(action.activity, _this.machine, updatedContext, _event);
908
907
  return acc;
909
908
  }, currentState ? _tslib.__assign({}, currentState.children) : {});
910
- var resolvedConfiguration = willTransition ? stateTransition.configuration : currentState ? currentState.configuration : [];
911
- var isDone = stateUtils.isInFinalState(resolvedConfiguration, this);
912
909
  var nextState = new State.State({
913
910
  value: resolvedStateValue || currentState.value,
914
911
  context: updatedContext,
@@ -938,34 +935,33 @@ function () {
938
935
  // and if some of the state nodes have transient ("always") transitions.
939
936
 
940
937
 
941
- var isTransient = !isDone && (this._transient || configuration.some(function (stateNode) {
938
+ var hasAlwaysTransitions = !isDone && (this._transient || configuration.some(function (stateNode) {
942
939
  return stateNode._transient;
943
940
  })); // If there are no enabled transitions, check if there are transient transitions.
944
941
  // If there are transient transitions, continue checking for more transitions
945
942
  // because an transient transition should be triggered even if there are no
946
943
  // enabled transitions.
947
944
  //
948
- // If we're already working on an transient transition (by checking
949
- // if the event is a NULL_EVENT), then stop to prevent an infinite loop.
945
+ // If we're already working on an transient transition then stop to prevent an infinite loop.
950
946
  //
951
947
  // Otherwise, if there are no enabled nor transient transitions, we are done.
952
948
 
953
- if (!willTransition && (!isTransient || _event.name === NULL_EVENT)) {
949
+ if (!willTransition && (!hasAlwaysTransitions || _event.name === NULL_EVENT)) {
954
950
  return nextState;
955
951
  }
956
952
 
957
953
  var maybeNextState = nextState;
958
954
 
959
955
  if (!isDone) {
960
- if (isTransient) {
956
+ if (hasAlwaysTransitions) {
961
957
  maybeNextState = this.resolveRaisedTransition(maybeNextState, {
962
958
  type: actionTypes.nullEvent
963
- }, _event);
959
+ }, _event, predictableExec);
964
960
  }
965
961
 
966
962
  while (raisedEvents.length) {
967
963
  var raisedEvent = raisedEvents.shift();
968
- maybeNextState = this.resolveRaisedTransition(maybeNextState, raisedEvent._event, _event);
964
+ maybeNextState = this.resolveRaisedTransition(maybeNextState, raisedEvent._event, _event, predictableExec);
969
965
  }
970
966
  } // Detect if state changed
971
967
 
@@ -1152,7 +1148,7 @@ function () {
1152
1148
  var configuration = this.getStateNodes(stateValue);
1153
1149
  return this.resolveTransition({
1154
1150
  configuration: configuration,
1155
- entrySet: configuration,
1151
+ entrySet: _tslib.__spreadArray([], _tslib.__read(configuration), false),
1156
1152
  exitSet: [],
1157
1153
  transitions: [],
1158
1154
  source: undefined,
package/lib/actions.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Action, Event, EventObject, SingleOrArray, SendAction, SendActionOptions, CancelAction, ActionObject, ActionType, Assigner, PropertyAssigner, AssignAction, ActionFunction, ActionFunctionMap, ActivityActionObject, ActionTypes, ActivityDefinition, RaiseAction, RaiseActionObject, DoneEvent, ErrorPlatformEvent, DoneEventObject, SendExpr, SendActionObject, PureAction, LogExpr, LogAction, LogActionObject, DelayFunctionMap, SCXML, ExprWithMeta, ChooseCondition, ChooseAction, AnyEventObject, Expr, StopAction, StopActionObject, Cast, EventFrom, AnyActorRef } from './types';
1
+ import { Action, Event, EventObject, SingleOrArray, SendAction, SendActionOptions, CancelAction, ActionObject, ActionType, Assigner, PropertyAssigner, AssignAction, ActionFunction, ActionFunctionMap, ActivityActionObject, ActionTypes, ActivityDefinition, RaiseAction, RaiseActionObject, DoneEvent, ErrorPlatformEvent, DoneEventObject, SendExpr, SendActionObject, PureAction, LogExpr, LogAction, LogActionObject, DelayFunctionMap, SCXML, ExprWithMeta, ChooseCondition, ChooseAction, AnyEventObject, Expr, StopAction, StopActionObject, Cast, EventFrom, AnyActorRef, PredictableActionArgumentsExec } from './types';
2
2
  import * as actionTypes from './actionTypes';
3
3
  import { State } from './State';
4
4
  import { StateNode } from './StateNode';
@@ -150,5 +150,5 @@ export declare function forwardTo<TContext, TEvent extends EventObject>(target:
150
150
  */
151
151
  export declare function escalate<TContext, TEvent extends EventObject, TErrorData = any>(errorData: TErrorData | ExprWithMeta<TContext, TEvent, TErrorData>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, AnyEventObject>;
152
152
  export declare function choose<TContext, TEvent extends EventObject>(conds: Array<ChooseCondition<TContext, TEvent>>): ChooseAction<TContext, TEvent>;
153
- export declare function resolveActions<TContext, TEvent extends EventObject>(machine: StateNode<TContext, any, TEvent, any, any, any>, currentState: State<TContext, TEvent> | undefined, currentContext: TContext, _event: SCXML.Event<TEvent>, actions: Array<ActionObject<TContext, TEvent>>, preserveActionOrder?: boolean): [Array<ActionObject<TContext, TEvent>>, TContext];
153
+ export declare function resolveActions<TContext, TEvent extends EventObject>(machine: StateNode<TContext, any, TEvent, any, any, any>, currentState: State<TContext, TEvent, any, any, any> | undefined, currentContext: TContext, _event: SCXML.Event<TEvent>, actions: Array<ActionObject<TContext, TEvent>>, predictableExec?: PredictableActionArgumentsExec, preserveActionOrder?: boolean): [Array<ActionObject<TContext, TEvent>>, TContext];
154
154
  //# sourceMappingURL=actions.d.ts.map
package/lib/actions.js CHANGED
@@ -378,6 +378,26 @@ function pure(getActions) {
378
378
  */
379
379
 
380
380
  function forwardTo(target, options) {
381
+ if (!environment.IS_PRODUCTION && (!target || typeof target === 'function')) {
382
+ var originalTarget_1 = target;
383
+
384
+ target = function () {
385
+ var args = [];
386
+
387
+ for (var _i = 0; _i < arguments.length; _i++) {
388
+ args[_i] = arguments[_i];
389
+ }
390
+
391
+ var resolvedTarget = typeof originalTarget_1 === 'function' ? originalTarget_1.apply(void 0, _tslib.__spreadArray([], _tslib.__read(args), false)) : originalTarget_1;
392
+
393
+ if (!resolvedTarget) {
394
+ throw new Error("Attempted to forward event to undefined actor. This risks an infinite loop in the sender.");
395
+ }
396
+
397
+ return resolvedTarget;
398
+ };
399
+ }
400
+
381
401
  return send(function (_, event) {
382
402
  return event;
383
403
  }, _tslib.__assign(_tslib.__assign({}, options), {
@@ -408,7 +428,7 @@ function choose(conds) {
408
428
  conds: conds
409
429
  };
410
430
  }
411
- function resolveActions(machine, currentState, currentContext, _event, actions, preserveActionOrder) {
431
+ function resolveActions(machine, currentState, currentContext, _event, actions, predictableExec, preserveActionOrder) {
412
432
  if (preserveActionOrder === void 0) {
413
433
  preserveActionOrder = false;
414
434
  }
@@ -426,7 +446,9 @@ function resolveActions(machine, currentState, currentContext, _event, actions,
426
446
 
427
447
  switch (actionObject.type) {
428
448
  case actionTypes.raise:
429
- return resolveRaise(actionObject);
449
+ {
450
+ return resolveRaise(actionObject);
451
+ }
430
452
 
431
453
  case actionTypes.send:
432
454
  var sendAction = resolveSend(actionObject, updatedContext, _event, machine.options.delays); // TODO: fix ActionTypes.Init
@@ -437,24 +459,32 @@ function resolveActions(machine, currentState, currentContext, _event, actions,
437
459
  "No delay reference for delay expression '".concat(actionObject.delay, "' was found on machine '").concat(machine.id, "'"));
438
460
  }
439
461
 
462
+ if (sendAction.to !== types.SpecialTargets.Internal) {
463
+ predictableExec === null || predictableExec === void 0 ? void 0 : predictableExec(sendAction, updatedContext, _event);
464
+ }
465
+
440
466
  return sendAction;
441
467
 
442
468
  case actionTypes.log:
443
- return resolveLog(actionObject, updatedContext, _event);
469
+ {
470
+ var resolved = resolveLog(actionObject, updatedContext, _event);
471
+ predictableExec === null || predictableExec === void 0 ? void 0 : predictableExec(resolved, updatedContext, _event);
472
+ return resolved;
473
+ }
444
474
 
445
475
  case actionTypes.choose:
446
476
  {
447
477
  var chooseAction = actionObject;
448
478
  var matchedActions = (_a = chooseAction.conds.find(function (condition) {
449
479
  var guard = utils.toGuard(condition.cond, machine.options.guards);
450
- return !guard || utils.evaluateGuard(machine, guard, updatedContext, _event, currentState);
480
+ return !guard || utils.evaluateGuard(machine, guard, updatedContext, _event, !predictableExec ? currentState : undefined);
451
481
  })) === null || _a === void 0 ? void 0 : _a.actions;
452
482
 
453
483
  if (!matchedActions) {
454
484
  return [];
455
485
  }
456
486
 
457
- var _b = _tslib.__read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(utils.toArray(matchedActions), machine.options.actions), preserveActionOrder), 2),
487
+ var _b = _tslib.__read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(utils.toArray(matchedActions), machine.options.actions), predictableExec, preserveActionOrder), 2),
458
488
  resolvedActionsFromChoose = _b[0],
459
489
  resolvedContextFromChoose = _b[1];
460
490
 
@@ -471,7 +501,7 @@ function resolveActions(machine, currentState, currentContext, _event, actions,
471
501
  return [];
472
502
  }
473
503
 
474
- var _c = _tslib.__read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(utils.toArray(matchedActions), machine.options.actions), preserveActionOrder), 2),
504
+ var _c = _tslib.__read(resolveActions(machine, currentState, updatedContext, _event, toActionObjects(utils.toArray(matchedActions), machine.options.actions), predictableExec, preserveActionOrder), 2),
475
505
  resolvedActionsFromPure = _c[0],
476
506
  resolvedContext = _c[1];
477
507
 
@@ -482,12 +512,14 @@ function resolveActions(machine, currentState, currentContext, _event, actions,
482
512
 
483
513
  case actionTypes.stop:
484
514
  {
485
- return resolveStop(actionObject, updatedContext, _event);
515
+ var resolved = resolveStop(actionObject, updatedContext, _event);
516
+ predictableExec === null || predictableExec === void 0 ? void 0 : predictableExec(resolved, updatedContext, _event);
517
+ return resolved;
486
518
  }
487
519
 
488
520
  case actionTypes.assign:
489
521
  {
490
- updatedContext = utils.updateContext(updatedContext, _event, [actionObject], currentState);
522
+ updatedContext = utils.updateContext(updatedContext, _event, [actionObject], !predictableExec ? currentState : undefined);
491
523
  preservedContexts === null || preservedContexts === void 0 ? void 0 : preservedContexts.push(updatedContext);
492
524
  break;
493
525
  }
@@ -496,7 +528,9 @@ function resolveActions(machine, currentState, currentContext, _event, actions,
496
528
  var resolvedActionObject = toActionObject(actionObject, machine.options.actions);
497
529
  var exec_1 = resolvedActionObject.exec;
498
530
 
499
- if (exec_1 && preservedContexts) {
531
+ if (predictableExec) {
532
+ predictableExec(resolvedActionObject, updatedContext, _event);
533
+ } else if (exec_1 && preservedContexts) {
500
534
  var contextIndex_1 = preservedContexts.length - 1;
501
535
  resolvedActionObject = _tslib.__assign(_tslib.__assign({}, resolvedActionObject), {
502
536
  exec: function (_ctx) {
@@ -93,7 +93,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
93
93
  execute(state: State<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta>, actionsConfig?: MachineOptions<TContext, TEvent>['actions']): void;
94
94
  private update;
95
95
  onTransition(listener: StateListener<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta>): this;
96
- subscribe(observer: Observer<State<TContext, TEvent, any, TTypestate, TResolvedTypesMeta>>): Subscription;
96
+ subscribe(observer: Partial<Observer<State<TContext, TEvent, any, TTypestate, TResolvedTypesMeta>>>): Subscription;
97
97
  subscribe(nextListener?: (state: State<TContext, TEvent, any, TTypestate, TResolvedTypesMeta>) => void, errorListener?: (error: any) => void, completeListener?: () => void): Subscription;
98
98
  /**
99
99
  * Adds an event listener that is notified whenever an event is sent to the running interpreter.
@@ -134,6 +134,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
134
134
  * @param initialState The state to start the statechart from
135
135
  */
136
136
  start(initialState?: State<TContext, TEvent, TStateSchema, TTypestate, TResolvedTypesMeta> | StateConfig<TContext, TEvent> | StateValue): this;
137
+ private _stop;
137
138
  /**
138
139
  * Stops the interpreter and unsubscribe all listeners.
139
140
  *
@@ -158,6 +159,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
158
159
  */
159
160
  sender(event: Event<TEvent>): () => State<TContext, TEvent, TStateSchema, TTypestate>;
160
161
  private sendTo;
162
+ private _nextState;
161
163
  /**
162
164
  * Returns the next state given the interpreter's current state and the event.
163
165
  *
@@ -169,6 +171,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
169
171
  private forward;
170
172
  private defer;
171
173
  private cancel;
174
+ private _exec;
172
175
  private exec;
173
176
  private removeChild;
174
177
  private stopChild;