xstate 4.7.8 → 4.10.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.
package/lib/State.js CHANGED
@@ -97,6 +97,7 @@ var State = /** @class */ (function () {
97
97
  * @param configuration
98
98
  */
99
99
  function State(config) {
100
+ var _this = this;
100
101
  this.actions = [];
101
102
  this.activities = constants_1.EMPTY_ACTIVITY_MAP;
102
103
  this.meta = {};
@@ -120,7 +121,7 @@ var State = /** @class */ (function () {
120
121
  this.done = !!config.done;
121
122
  Object.defineProperty(this, 'nextEvents', {
122
123
  get: function () {
123
- return stateUtils_1.nextEvents(config.configuration);
124
+ return stateUtils_1.nextEvents(_this.configuration);
124
125
  }
125
126
  });
126
127
  }
@@ -125,7 +125,7 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
125
125
  * @param options Options (actions, guards, activities, services) to recursively merge with the existing options.
126
126
  * @param context Custom context (will override predefined context)
127
127
  */
128
- withConfig(options: Partial<MachineOptions<TContext, TEvent>>, context?: TContext | undefined): StateNode<TContext, TStateSchema, TEvent>;
128
+ withConfig(options: Partial<MachineOptions<TContext, TEvent>>, context?: TContext | undefined): StateNode<TContext, TStateSchema, TEvent, TTypestate>;
129
129
  /**
130
130
  * Clones this state machine with custom context.
131
131
  *
@@ -182,7 +182,6 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
182
182
  * this state node, it does not escape.
183
183
  */
184
184
  private escapes;
185
- private evaluateGuard;
186
185
  private getActions;
187
186
  /**
188
187
  * Determines the next state given the current `state` and sent `event`.
@@ -191,7 +190,10 @@ declare class StateNode<TContext = any, TStateSchema extends StateSchema = any,
191
190
  * @param event The event that was sent at the current state
192
191
  * @param context The current context (extended state) of the current state
193
192
  */
194
- transition(state: string | StateValueMap | State<TContext, TEvent, any, any> | undefined, event: Event<TEvent> | SCXML.Event<TEvent>, context?: TContext): State<TContext, TEvent, TStateSchema, TTypestate>;
193
+ transition(state: string | StateValueMap | State<TContext, TEvent, any, {
194
+ value: any;
195
+ context: TContext;
196
+ }> | undefined, event: Event<TEvent> | SCXML.Event<TEvent>, context?: TContext): State<TContext, TEvent, TStateSchema, TTypestate>;
195
197
  private resolveRaisedTransition;
196
198
  private resolveTransition;
197
199
  /**
package/lib/StateNode.js CHANGED
@@ -191,9 +191,7 @@ var StateNode = /** @class */ (function () {
191
191
  // TODO: deprecate (entry)
192
192
  this.onEntry = utils_1.toArray(this.config.entry || this.config.onEntry).map(function (action) { return actions_1.toActionObject(action); });
193
193
  // TODO: deprecate (exit)
194
- this.onExit = utils_1.toArray(this.config.exit || this.config.onExit).map(function (action) {
195
- return actions_1.toActionObject(action);
196
- });
194
+ this.onExit = utils_1.toArray(this.config.exit || this.config.onExit).map(function (action) { return actions_1.toActionObject(action); });
197
195
  this.meta = this.config.meta;
198
196
  this.data =
199
197
  this.type === 'final'
@@ -263,14 +261,15 @@ var StateNode = /** @class */ (function () {
263
261
  id: this.id,
264
262
  key: this.key,
265
263
  version: this.version,
264
+ context: this.context,
266
265
  type: this.type,
267
266
  initial: this.initial,
268
267
  history: this.history,
269
268
  states: utils_1.mapValues(this.states, function (state) { return state.definition; }),
270
269
  on: this.on,
271
270
  transitions: this.transitions,
272
- onEntry: this.onEntry,
273
- onExit: this.onExit,
271
+ entry: this.onEntry,
272
+ exit: this.onExit,
274
273
  activities: this.activities || [],
275
274
  meta: this.meta,
276
275
  order: this.order || -1,
@@ -514,12 +513,11 @@ var StateNode = /** @class */ (function () {
514
513
  var guardPassed = false;
515
514
  try {
516
515
  guardPassed =
517
- !cond || this.evaluateGuard(cond, resolvedContext, _event, state);
516
+ !cond ||
517
+ utils_1.evaluateGuard(this.machine, cond, resolvedContext, _event, state);
518
518
  }
519
519
  catch (err) {
520
- throw new Error("Unable to evaluate guard '" + (cond.name ||
521
- cond
522
- .type) + "' in transition for event '" + eventName + "' in state node '" + this.id + "':\n" + err.message);
520
+ throw new Error("Unable to evaluate guard '" + (cond.name || cond.type) + "' in transition for event '" + eventName + "' in state node '" + this.id + "':\n" + err.message);
523
521
  }
524
522
  if (guardPassed && isInState) {
525
523
  if (candidate.target !== undefined) {
@@ -597,23 +595,6 @@ var StateNode = /** @class */ (function () {
597
595
  }
598
596
  return true;
599
597
  };
600
- StateNode.prototype.evaluateGuard = function (guard, context, _event, state) {
601
- var guards = this.machine.options.guards;
602
- var guardMeta = {
603
- state: state,
604
- cond: guard,
605
- _event: _event
606
- };
607
- // TODO: do not hardcode!
608
- if (guard.type === constants_1.DEFAULT_GUARD_TYPE) {
609
- return guard.predicate(context, _event.data, guardMeta);
610
- }
611
- var condFn = guards[guard.type];
612
- if (!condFn) {
613
- throw new Error("Guard '" + guard.type + "' is not implemented on machine '" + this.machine.id + "'.");
614
- }
615
- return condFn(context, _event.data, guardMeta);
616
- };
617
598
  StateNode.prototype.getActions = function (transition, currentContext, _event, prevState) {
618
599
  var e_4, _a, e_5, _b;
619
600
  var prevConfig = stateUtils_1.getConfiguration([], prevState ? this.getStateNodes(prevState.value) : [this]);
@@ -661,16 +642,17 @@ var StateNode = /** @class */ (function () {
661
642
  return events;
662
643
  }
663
644
  var parent = sn.parent;
645
+ if (!parent.parent) {
646
+ return events;
647
+ }
664
648
  events.push(actions_1.done(sn.id, sn.data), // TODO: deprecate - final states should not emit done events for their own state.
665
649
  actions_1.done(parent.id, sn.data ? utils_1.mapContext(sn.data, currentContext, _event) : undefined));
666
- if (parent.parent) {
667
- var grandparent = parent.parent;
668
- if (grandparent.type === 'parallel') {
669
- if (stateUtils_1.getChildren(grandparent).every(function (parentNode) {
670
- return stateUtils_1.isInFinalState(transition.configuration, parentNode);
671
- })) {
672
- events.push(actions_1.done(grandparent.id, grandparent.data));
673
- }
650
+ var grandparent = parent.parent;
651
+ if (grandparent.type === 'parallel') {
652
+ if (stateUtils_1.getChildren(grandparent).every(function (parentNode) {
653
+ return stateUtils_1.isInFinalState(transition.configuration, parentNode);
654
+ })) {
655
+ events.push(actions_1.done(grandparent.id, grandparent.data));
674
656
  }
675
657
  }
676
658
  return events;
@@ -747,7 +729,6 @@ var StateNode = /** @class */ (function () {
747
729
  };
748
730
  StateNode.prototype.resolveTransition = function (stateTransition, currentState, _event, context) {
749
731
  var e_6, _a;
750
- var _this = this;
751
732
  if (_event === void 0) { _event = actions_1.initEvent; }
752
733
  if (context === void 0) { context = this.machine.context; }
753
734
  var configuration = stateTransition.configuration;
@@ -772,10 +753,10 @@ var StateNode = /** @class */ (function () {
772
753
  for (var actions_2 = __values(actions), actions_2_1 = actions_2.next(); !actions_2_1.done; actions_2_1 = actions_2.next()) {
773
754
  var action = actions_2_1.value;
774
755
  if (action.type === actionTypes.start) {
775
- activities[action.activity.type] = action;
756
+ activities[action.activity.id || action.activity.type] = action;
776
757
  }
777
758
  else if (action.type === actionTypes.stop) {
778
- activities[action.activity.type] = false;
759
+ activities[action.activity.id || action.activity.type] = false;
779
760
  }
780
761
  }
781
762
  }
@@ -786,34 +767,7 @@ var StateNode = /** @class */ (function () {
786
767
  }
787
768
  finally { if (e_6) throw e_6.error; }
788
769
  }
789
- var _b = __read(utils_1.partition(actions, function (action) {
790
- return action.type === actionTypes.assign;
791
- }), 2), assignActions = _b[0], otherActions = _b[1];
792
- var updatedContext = assignActions.length
793
- ? utils_1.updateContext(currentContext, _event, assignActions, currentState)
794
- : currentContext;
795
- var resolvedActions = utils_1.flatten(otherActions.map(function (actionObject) {
796
- switch (actionObject.type) {
797
- case actionTypes.raise:
798
- return actions_1.resolveRaise(actionObject);
799
- case actionTypes.send:
800
- var sendAction = actions_1.resolveSend(actionObject, updatedContext, _event, _this.machine.options.delays); // TODO: fix ActionTypes.Init
801
- if (!environment_1.IS_PRODUCTION) {
802
- // warn after resolving as we can create better contextual message here
803
- utils_1.warn(!utils_1.isString(actionObject.delay) ||
804
- typeof sendAction.delay === 'number',
805
- // tslint:disable-next-line:max-line-length
806
- "No delay reference for delay expression '" + actionObject.delay + "' was found on machine '" + _this.machine.id + "'");
807
- }
808
- return sendAction;
809
- case actionTypes.log:
810
- return actions_1.resolveLog(actionObject, updatedContext, _event);
811
- case actionTypes.pure:
812
- return (actionObject.get(updatedContext, _event.data) || []);
813
- default:
814
- return actions_1.toActionObject(actionObject, _this.options.actions);
815
- }
816
- }));
770
+ var _b = __read(actions_1.resolveActions(this, currentState, currentContext, _event, actions), 2), resolvedActions = _b[0], updatedContext = _b[1];
817
771
  var _c = __read(utils_1.partition(resolvedActions, function (action) {
818
772
  return action.type === actionTypes.raise ||
819
773
  (action.type === actionTypes.send &&
@@ -875,8 +829,8 @@ var StateNode = /** @class */ (function () {
875
829
  children: children,
876
830
  done: isDone
877
831
  });
878
- nextState.changed =
879
- _event.name === actionTypes.update || !!assignActions.length;
832
+ var didUpdateContext = currentContext !== updatedContext;
833
+ nextState.changed = _event.name === actionTypes.update || didUpdateContext;
880
834
  // Dispose of penultimate histories to prevent memory leaks
881
835
  var history = nextState.history;
882
836
  if (history) {
@@ -903,7 +857,7 @@ var StateNode = /** @class */ (function () {
903
857
  var changed = maybeNextState.changed ||
904
858
  (history
905
859
  ? !!maybeNextState.actions.length ||
906
- !!assignActions.length ||
860
+ didUpdateContext ||
907
861
  typeof history.value !== typeof maybeNextState.value ||
908
862
  !State_1.stateValuesEqual(maybeNextState.value, history.value)
909
863
  : undefined);
@@ -1326,7 +1280,10 @@ var StateNode = /** @class */ (function () {
1326
1280
  : true;
1327
1281
  var guards = this.machine.options.guards;
1328
1282
  var target = this.resolveTarget(normalizedTarget);
1329
- return __assign(__assign({}, transitionConfig), { actions: actions_1.toActionObjects(utils_1.toArray(transitionConfig.actions)), cond: utils_1.toGuard(transitionConfig.cond, guards), target: target, source: this, internal: internal, eventType: transitionConfig.event });
1283
+ var transition = __assign(__assign({}, transitionConfig), { actions: actions_1.toActionObjects(utils_1.toArray(transitionConfig.actions)), cond: utils_1.toGuard(transitionConfig.cond, guards), target: target, source: this, internal: internal, eventType: transitionConfig.event, toJSON: function () { return (__assign(__assign({}, transition), { target: transition.target
1284
+ ? transition.target.map(function (t) { return "#" + t.id; })
1285
+ : undefined, source: "#{this.id}" })); } });
1286
+ return transition;
1330
1287
  };
1331
1288
  StateNode.prototype.formatTransitions = function () {
1332
1289
  var e_9, _a;
@@ -1353,6 +1310,9 @@ var StateNode = /** @class */ (function () {
1353
1310
  var doneConfig = this.config.onDone
1354
1311
  ? utils_1.toTransitionConfigArray(String(actions_1.done(this.id)), this.config.onDone)
1355
1312
  : [];
1313
+ if (!environment_1.IS_PRODUCTION) {
1314
+ utils_1.warn(!(this.config.onDone && !this.parent), "Root nodes cannot have an \".onDone\" transition. Please check the config of \"" + this.id + "\".");
1315
+ }
1356
1316
  var invokeConfig = utils_1.flatten(this.invoke.map(function (invokeDef) {
1357
1317
  var settleTransitions = [];
1358
1318
  if (invokeDef.onDone) {
@@ -15,5 +15,6 @@ export declare const errorExecution = ActionTypes.ErrorExecution;
15
15
  export declare const errorPlatform = ActionTypes.ErrorPlatform;
16
16
  export declare const error = ActionTypes.ErrorCustom;
17
17
  export declare const update = ActionTypes.Update;
18
+ export declare const choose = ActionTypes.Choose;
18
19
  export declare const pure = ActionTypes.Pure;
19
20
  //# sourceMappingURL=actionTypes.d.ts.map
@@ -18,4 +18,5 @@ exports.errorExecution = types_1.ActionTypes.ErrorExecution;
18
18
  exports.errorPlatform = types_1.ActionTypes.ErrorPlatform;
19
19
  exports.error = types_1.ActionTypes.ErrorCustom;
20
20
  exports.update = types_1.ActionTypes.Update;
21
+ exports.choose = types_1.ActionTypes.Choose;
21
22
  exports.pure = types_1.ActionTypes.Pure;
package/lib/actions.d.ts CHANGED
@@ -1,12 +1,14 @@
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 } 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, ChooseConditon, ChooseAction, AnyEventObject } from './types';
2
2
  import * as actionTypes from './actionTypes';
3
+ import { State } from './State';
4
+ import { StateNode } from './StateNode';
3
5
  export { actionTypes };
4
6
  export declare const initEvent: SCXML.Event<{
5
- type: ActionTypes.Init;
7
+ type: ActionTypes;
6
8
  }>;
7
9
  export declare function getActionFunction<TContext, TEvent extends EventObject>(actionType: ActionType, actionFunctionMap?: ActionFunctionMap<TContext, TEvent>): ActionObject<TContext, TEvent> | ActionFunction<TContext, TEvent> | undefined;
8
10
  export declare function toActionObject<TContext, TEvent extends EventObject>(action: Action<TContext, TEvent>, actionFunctionMap?: ActionFunctionMap<TContext, TEvent>): ActionObject<TContext, TEvent>;
9
- export declare const toActionObjects: <TContext, TEvent extends EventObject>(action?: string | RaiseAction<import("./types").AnyEventObject> | ActionObject<TContext, TEvent> | ActionFunction<TContext, TEvent> | AssignAction<Required<TContext>, TEvent> | SendAction<TContext, TEvent> | Action<TContext, TEvent>[] | undefined, actionFunctionMap?: Record<string, ActionFunction<TContext, TEvent> | ActionObject<TContext, TEvent>> | undefined) => ActionObject<TContext, TEvent>[];
11
+ export declare const toActionObjects: <TContext, TEvent extends EventObject>(action?: string | RaiseAction<AnyEventObject> | ActionObject<TContext, TEvent> | ActionFunction<TContext, TEvent> | AssignAction<Required<TContext>, TEvent> | SendAction<TContext, TEvent, AnyEventObject> | ChooseAction<TContext, TEvent> | Action<TContext, TEvent>[] | undefined, actionFunctionMap?: Record<string, ActionFunction<TContext, TEvent> | ActionObject<TContext, TEvent>> | undefined) => ActionObject<TContext, TEvent>[];
10
12
  export declare function toActivityDefinition<TContext, TEvent extends EventObject>(action: string | ActivityDefinition<TContext, TEvent>): ActivityDefinition<TContext, TEvent>;
11
13
  /**
12
14
  * Raises an event. This places the event in the internal event queue, so that
@@ -14,7 +16,7 @@ export declare function toActivityDefinition<TContext, TEvent extends EventObjec
14
16
  *
15
17
  * @param eventType The event to raise.
16
18
  */
17
- export declare function raise<TContext, TEvent extends EventObject>(event: Event<TEvent>): RaiseAction<TEvent> | SendAction<TContext, TEvent>;
19
+ export declare function raise<TContext, TEvent extends EventObject>(event: Event<TEvent>): RaiseAction<TEvent> | SendAction<TContext, TEvent, TEvent>;
18
20
  export declare function resolveRaise<TEvent extends EventObject>(action: RaiseAction<TEvent>): RaiseActionObject<TEvent>;
19
21
  /**
20
22
  * Sends an event. This returns an action that will be read by an interpreter to
@@ -26,26 +28,28 @@ export declare function resolveRaise<TEvent extends EventObject>(action: RaiseAc
26
28
  * - `delay` - The number of milliseconds to delay the sending of the event.
27
29
  * - `to` - The target of this event (by default, the machine the event was sent from).
28
30
  */
29
- export declare function send<TContext, TEvent extends EventObject>(event: Event<TEvent> | SendExpr<TContext, TEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent>;
30
- export declare function resolveSend<TContext, TEvent extends EventObject>(action: SendAction<TContext, TEvent>, ctx: TContext, _event: SCXML.Event<TEvent>, delaysMap?: DelayFunctionMap<TContext, TEvent>): SendActionObject<TContext, TEvent>;
31
+ export declare function send<TContext, TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject>(event: Event<TSentEvent> | SendExpr<TContext, TEvent, TSentEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, TSentEvent>;
32
+ export declare function resolveSend<TContext, TEvent extends EventObject, TSentEvent extends EventObject>(action: SendAction<TContext, TEvent, TSentEvent>, ctx: TContext, _event: SCXML.Event<TEvent>, delaysMap?: DelayFunctionMap<TContext, TEvent>): SendActionObject<TContext, TEvent, TSentEvent>;
31
33
  /**
32
34
  * Sends an event to this machine's parent.
33
35
  *
34
36
  * @param event The event to send to the parent machine.
35
37
  * @param options Options to pass into the send event.
36
38
  */
37
- export declare function sendParent<TContext, TEvent extends EventObject>(event: Event<any> | SendExpr<TContext, TEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent>;
39
+ export declare function sendParent<TContext, TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject>(event: Event<TSentEvent> | SendExpr<TContext, TEvent, TSentEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, TSentEvent>;
38
40
  /**
39
41
  * Sends an update event to this machine's parent.
40
42
  */
41
- export declare function sendUpdate<TContext, TEvent extends EventObject>(): SendAction<TContext, TEvent>;
43
+ export declare function sendUpdate<TContext, TEvent extends EventObject>(): SendAction<TContext, TEvent, {
44
+ type: ActionTypes.Update;
45
+ }>;
42
46
  /**
43
47
  * Sends an event back to the sender of the original event.
44
48
  *
45
49
  * @param event The event to send back to the sender
46
50
  * @param options Options to pass into the send event
47
51
  */
48
- export declare function respond<TContext, TEvent extends EventObject>(event: Event<TEvent> | SendExpr<TContext, TEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent>;
52
+ export declare function respond<TContext, TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject>(event: Event<TEvent> | SendExpr<TContext, TEvent, TSentEvent>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, AnyEventObject>;
49
53
  /**
50
54
  *
51
55
  * @param expr The expression function to evaluate which will be logged.
@@ -117,7 +121,7 @@ export declare function pure<TContext, TEvent extends EventObject>(getActions: (
117
121
  * @param target The target service to forward the event to.
118
122
  * @param options Options to pass into the send action creator.
119
123
  */
120
- export declare function forwardTo<TContext, TEvent extends EventObject>(target: Required<SendActionOptions<TContext, TEvent>>['to'], options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent>;
124
+ export declare function forwardTo<TContext, TEvent extends EventObject>(target: Required<SendActionOptions<TContext, TEvent>>['to'], options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, AnyEventObject>;
121
125
  /**
122
126
  * Escalates an error by sending it as an event to this machine's parent.
123
127
  *
@@ -125,5 +129,7 @@ export declare function forwardTo<TContext, TEvent extends EventObject>(target:
125
129
  * takes in the `context`, `event`, and `meta`, and returns the error data to send.
126
130
  * @param options Options to pass into the send action creator.
127
131
  */
128
- export declare function escalate<TContext, TEvent extends EventObject, TErrorData = any>(errorData: TErrorData | ExprWithMeta<TContext, TEvent, TErrorData>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent>;
132
+ export declare function escalate<TContext, TEvent extends EventObject, TErrorData = any>(errorData: TErrorData | ExprWithMeta<TContext, TEvent, TErrorData>, options?: SendActionOptions<TContext, TEvent>): SendAction<TContext, TEvent, AnyEventObject>;
133
+ export declare function choose<TContext, TEvent extends EventObject>(conds: Array<ChooseConditon<TContext, TEvent>>): ChooseAction<TContext, TEvent>;
134
+ export declare function resolveActions<TContext, TEvent extends EventObject>(machine: StateNode<TContext, any, TEvent>, currentState: State<TContext, TEvent> | undefined, currentContext: TContext, _event: SCXML.Event<TEvent>, actions: Array<ActionObject<TContext, TEvent>>): [Array<ActionObject<TContext, TEvent>>, TContext];
129
135
  //# sourceMappingURL=actions.d.ts.map
package/lib/actions.js CHANGED
@@ -21,12 +21,29 @@ var __rest = (this && this.__rest) || function (s, e) {
21
21
  }
22
22
  return t;
23
23
  };
24
+ var __read = (this && this.__read) || function (o, n) {
25
+ var m = typeof Symbol === "function" && o[Symbol.iterator];
26
+ if (!m) return o;
27
+ var i = m.call(o), r, ar = [], e;
28
+ try {
29
+ while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
30
+ }
31
+ catch (error) { e = { error: error }; }
32
+ finally {
33
+ try {
34
+ if (r && !r.done && (m = i["return"])) m.call(i);
35
+ }
36
+ finally { if (e) throw e.error; }
37
+ }
38
+ return ar;
39
+ };
24
40
  Object.defineProperty(exports, "__esModule", { value: true });
25
41
  var types_1 = require("./types");
26
42
  var actionTypes = require("./actionTypes");
27
43
  exports.actionTypes = actionTypes;
28
44
  var utils_1 = require("./utils");
29
45
  var utils_2 = require("./utils");
46
+ var environment_1 = require("./environment");
30
47
  exports.initEvent = utils_1.toSCXMLEvent({ type: actionTypes.init });
31
48
  function getActionFunction(actionType, actionFunctionMap) {
32
49
  return actionFunctionMap
@@ -84,7 +101,9 @@ exports.toActionObjects = function (action, actionFunctionMap) {
84
101
  return [];
85
102
  }
86
103
  var actions = utils_2.isArray(action) ? action : [action];
87
- return actions.map(function (subAction) { return toActionObject(subAction, actionFunctionMap); });
104
+ return actions.map(function (subAction) {
105
+ return toActionObject(subAction, actionFunctionMap);
106
+ });
88
107
  };
89
108
  function toActivityDefinition(action) {
90
109
  var actionObject = toActionObject(action);
@@ -366,3 +385,64 @@ function escalate(errorData, options) {
366
385
  }, __assign(__assign({}, options), { to: types_1.SpecialTargets.Parent }));
367
386
  }
368
387
  exports.escalate = escalate;
388
+ function choose(conds) {
389
+ return {
390
+ type: types_1.ActionTypes.Choose,
391
+ conds: conds
392
+ };
393
+ }
394
+ exports.choose = choose;
395
+ function resolveActions(machine, currentState, currentContext, _event, actions) {
396
+ var _a = __read(utils_1.partition(actions, function (action) {
397
+ return action.type === actionTypes.assign;
398
+ }), 2), assignActions = _a[0], otherActions = _a[1];
399
+ var updatedContext = assignActions.length
400
+ ? utils_1.updateContext(currentContext, _event, assignActions, currentState)
401
+ : currentContext;
402
+ var resolvedActions = utils_1.flatten(otherActions.map(function (actionObject) {
403
+ var _a;
404
+ switch (actionObject.type) {
405
+ case actionTypes.raise:
406
+ return resolveRaise(actionObject);
407
+ case actionTypes.send:
408
+ var sendAction = resolveSend(actionObject, updatedContext, _event, machine.options.delays); // TODO: fix ActionTypes.Init
409
+ if (!environment_1.IS_PRODUCTION) {
410
+ // warn after resolving as we can create better contextual message here
411
+ utils_1.warn(!utils_1.isString(actionObject.delay) ||
412
+ typeof sendAction.delay === 'number',
413
+ // tslint:disable-next-line:max-line-length
414
+ "No delay reference for delay expression '" + actionObject.delay + "' was found on machine '" + machine.id + "'");
415
+ }
416
+ return sendAction;
417
+ case actionTypes.log:
418
+ return exports.resolveLog(actionObject, updatedContext, _event);
419
+ case actionTypes.choose: {
420
+ var chooseAction = actionObject;
421
+ var matchedActions = (_a = chooseAction.conds.find(function (condition) {
422
+ var guard = utils_1.toGuard(condition.cond, machine.options.guards);
423
+ return (!guard ||
424
+ utils_1.evaluateGuard(machine, guard, updatedContext, _event, currentState));
425
+ })) === null || _a === void 0 ? void 0 : _a.actions;
426
+ if (!matchedActions) {
427
+ return [];
428
+ }
429
+ var resolved = resolveActions(machine, currentState, updatedContext, _event, exports.toActionObjects(utils_1.toArray(matchedActions), machine.options.actions));
430
+ updatedContext = resolved[1];
431
+ return resolved[0];
432
+ }
433
+ case actionTypes.pure: {
434
+ var matchedActions = actionObject.get(updatedContext, _event.data);
435
+ if (!matchedActions) {
436
+ return [];
437
+ }
438
+ var resolved = resolveActions(machine, currentState, updatedContext, _event, exports.toActionObjects(utils_1.toArray(matchedActions), machine.options.actions));
439
+ updatedContext = resolved[1];
440
+ return resolved[0];
441
+ }
442
+ default:
443
+ return toActionObject(actionObject, machine.options.actions);
444
+ }
445
+ }));
446
+ return [resolvedActions, updatedContext];
447
+ }
448
+ exports.resolveActions = resolveActions;
package/lib/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { StateNode } from './StateNode';
4
4
  import { State } from './State';
5
5
  import { Machine, createMachine } from './Machine';
6
6
  import { Actor } from './Actor';
7
- import { raise, send, sendParent, sendUpdate, log, start, stop, assign, after, done, respond, doneInvoke, forwardTo, escalate } from './actions';
7
+ import { raise, send, sendParent, sendUpdate, log, start, stop, assign, after, done, respond, doneInvoke, forwardTo, escalate, choose, pure } from './actions';
8
8
  import { interpret, Interpreter, spawn } from './interpreter';
9
9
  import { matchState } from './match';
10
10
  declare const actions: {
@@ -22,6 +22,8 @@ declare const actions: {
22
22
  respond: typeof respond;
23
23
  forwardTo: typeof forwardTo;
24
24
  escalate: typeof escalate;
25
+ choose: typeof choose;
26
+ pure: typeof pure;
25
27
  };
26
28
  export { Actor, Machine, StateNode, State, matchesState, mapState, actions, assign, send, sendParent, sendUpdate, forwardTo, interpret, Interpreter, matchState, spawn, doneInvoke, createMachine };
27
29
  export * from './types';
package/lib/index.js CHANGED
@@ -41,7 +41,9 @@ var actions = {
41
41
  done: actions_1.done,
42
42
  respond: actions_1.respond,
43
43
  forwardTo: actions_1.forwardTo,
44
- escalate: actions_1.escalate
44
+ escalate: actions_1.escalate,
45
+ choose: actions_1.choose,
46
+ pure: actions_1.pure
45
47
  };
46
48
  exports.actions = actions;
47
49
  __export(require("./types"));
@@ -1,7 +1,7 @@
1
1
  import { StateMachine, Event, EventObject, DefaultContext, StateSchema, StateValue, InterpreterOptions, DoneEvent, Unsubscribable, MachineOptions, SCXML, EventData, Observer, Spawnable, Typestate } from './types';
2
2
  import { State } from './State';
3
3
  import { Actor } from './Actor';
4
- export declare type StateListener<TContext, TEvent extends EventObject, TTypestate extends Typestate<TContext> = any> = (state: State<TContext, TEvent, any, TTypestate>, event: TEvent) => void;
4
+ export declare type StateListener<TContext, TEvent extends EventObject, TStateSchema extends StateSchema<TContext> = any, TTypestate extends Typestate<TContext> = any> = (state: State<TContext, TEvent, TStateSchema, TTypestate>, event: TEvent) => void;
5
5
  export declare type ContextListener<TContext = DefaultContext> = (context: TContext, prevContext: TContext | undefined) => void;
6
6
  export declare type EventListener<TEvent extends EventObject = EventObject> = (event: TEvent) => void;
7
7
  export declare type Listener = () => void;
@@ -14,7 +14,7 @@ interface SpawnOptions {
14
14
  autoForward?: boolean;
15
15
  sync?: boolean;
16
16
  }
17
- export declare class Interpreter<TContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = any> implements Actor<State<TContext, TEvent>, TEvent> {
17
+ export declare class Interpreter<TContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = any> implements Actor<State<TContext, TEvent, TStateSchema, TTypestate>, TEvent> {
18
18
  machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>;
19
19
  /**
20
20
  * The default interpreter options:
@@ -63,8 +63,8 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
63
63
  * @param options Interpreter options
64
64
  */
65
65
  constructor(machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>, options?: Partial<InterpreterOptions>);
66
- get initialState(): State<TContext, TEvent>;
67
- get state(): State<TContext, TEvent>;
66
+ get initialState(): State<TContext, TEvent, TStateSchema, TTypestate>;
67
+ get state(): State<TContext, TEvent, TStateSchema, TTypestate>;
68
68
  static interpret: typeof interpret;
69
69
  /**
70
70
  * Executes the actions of the given state, with that state's `context` and `event`.
@@ -72,9 +72,9 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
72
72
  * @param state The state whose actions will be executed
73
73
  * @param actionsConfig The action implementations to use
74
74
  */
75
- execute(state: State<TContext, TEvent>, actionsConfig?: MachineOptions<TContext, TEvent>['actions']): void;
75
+ execute(state: State<TContext, TEvent, TStateSchema, TTypestate>, actionsConfig?: MachineOptions<TContext, TEvent>['actions']): void;
76
76
  private update;
77
- onTransition(listener: StateListener<TContext, TEvent, TTypestate>): this;
77
+ onTransition(listener: StateListener<TContext, TEvent, TStateSchema, TTypestate>): this;
78
78
  subscribe(observer: Observer<State<TContext, TEvent, any, TTypestate>>): Unsubscribable;
79
79
  subscribe(nextListener?: (state: State<TContext, TEvent, any, TTypestate>) => void, errorListener?: (error: any) => void, completeListener?: () => void): Unsubscribable;
80
80
  /**
@@ -110,12 +110,12 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
110
110
  /**
111
111
  * Alias for Interpreter.prototype.start
112
112
  */
113
- init: (initialState?: string | import("./types").StateValueMap | State<TContext, TEvent, any, any> | undefined) => Interpreter<TContext, TStateSchema, TEvent, any>;
113
+ init: (initialState?: string | import("./types").StateValueMap | State<TContext, TEvent, TStateSchema, TTypestate> | undefined) => Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
114
114
  /**
115
115
  * Starts the interpreter from the given state, or the initial state.
116
116
  * @param initialState The state to start the statechart from
117
117
  */
118
- start(initialState?: State<TContext, TEvent> | StateValue): Interpreter<TContext, TStateSchema, TEvent>;
118
+ start(initialState?: State<TContext, TEvent, TStateSchema, TTypestate> | StateValue): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
119
119
  /**
120
120
  * Stops the interpreter and unsubscribe all listeners.
121
121
  *
@@ -131,14 +131,14 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
131
131
  *
132
132
  * @param event The event(s) to send
133
133
  */
134
- send: (event: TEvent | TEvent["type"] | Event<TEvent>[] | SCXML.Event<TEvent>, payload?: EventData | undefined) => State<TContext, TEvent, any, any>;
134
+ send: (event: TEvent | TEvent["type"] | Event<TEvent>[] | SCXML.Event<TEvent>, payload?: EventData | undefined) => State<TContext, TEvent, TStateSchema, TTypestate>;
135
135
  private batch;
136
136
  /**
137
137
  * Returns a send function bound to this interpreter instance.
138
138
  *
139
139
  * @param event The event to be sent by the sender.
140
140
  */
141
- sender(event: Event<TEvent>): () => State<TContext, TEvent>;
141
+ sender(event: Event<TEvent>): () => State<TContext, TEvent, TStateSchema, TTypestate>;
142
142
  private sendTo;
143
143
  /**
144
144
  * Returns the next state given the interpreter's current state and the event.
@@ -147,11 +147,12 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
147
147
  *
148
148
  * @param event The event to determine the next state
149
149
  */
150
- nextState(event: Event<TEvent> | SCXML.Event<TEvent>): State<TContext, TEvent>;
150
+ nextState(event: Event<TEvent> | SCXML.Event<TEvent>): State<TContext, TEvent, TStateSchema, TTypestate>;
151
151
  private forward;
152
152
  private defer;
153
153
  private cancel;
154
154
  private exec;
155
+ private removeChild;
155
156
  private stopChild;
156
157
  spawn(entity: Spawnable, name: string, options?: SpawnOptions): Actor;
157
158
  spawnMachine<TChildContext, TChildStateSchema, TChildEvent extends EventObject>(machine: StateMachine<TChildContext, TChildStateSchema, TChildEvent>, options?: {
@@ -636,8 +636,10 @@ var Interpreter = /** @class */ (function () {
636
636
  delete this.delayedEventsMap[sendId];
637
637
  };
638
638
  Interpreter.prototype.exec = function (action, state, actionFunctionMap) {
639
+ if (actionFunctionMap === void 0) { actionFunctionMap = this.machine
640
+ .options.actions; }
639
641
  var context = state.context, _event = state._event;
640
- var actionOrExec = actions_1.getActionFunction(action.type, actionFunctionMap) || action.exec;
642
+ var actionOrExec = action.exec || actions_1.getActionFunction(action.type, actionFunctionMap);
641
643
  var exec = utils_1.isFunction(actionOrExec)
642
644
  ? actionOrExec
643
645
  : actionOrExec
@@ -686,7 +688,7 @@ var Interpreter = /** @class */ (function () {
686
688
  // If the activity will be stopped right after it's started
687
689
  // (such as in transient states)
688
690
  // don't bother starting the activity.
689
- if (!this.state.activities[activity.type]) {
691
+ if (!this.state.activities[activity.id || activity.type]) {
690
692
  break;
691
693
  }
692
694
  // Invoked services
@@ -763,14 +765,17 @@ var Interpreter = /** @class */ (function () {
763
765
  }
764
766
  return undefined;
765
767
  };
768
+ Interpreter.prototype.removeChild = function (childId) {
769
+ this.children.delete(childId);
770
+ this.forwardTo.delete(childId);
771
+ delete this.state.children[childId];
772
+ };
766
773
  Interpreter.prototype.stopChild = function (childId) {
767
774
  var child = this.children.get(childId);
768
775
  if (!child) {
769
776
  return;
770
777
  }
771
- this.children.delete(childId);
772
- this.forwardTo.delete(childId);
773
- delete this.state.children[childId];
778
+ this.removeChild(childId);
774
779
  if (utils_1.isFunction(child.stop)) {
775
780
  child.stop();
776
781
  }
@@ -808,16 +813,17 @@ var Interpreter = /** @class */ (function () {
808
813
  });
809
814
  });
810
815
  }
811
- childService
812
- .onDone(function (doneEvent) {
813
- _this.send(utils_1.toSCXMLEvent(doneEvent, { origin: childService.id }));
814
- })
815
- .start();
816
816
  var actor = childService;
817
817
  this.children.set(childService.id, actor);
818
818
  if (resolvedOptions.autoForward) {
819
819
  this.forwardTo.add(childService.id);
820
820
  }
821
+ childService
822
+ .onDone(function (doneEvent) {
823
+ _this.removeChild(childService.id);
824
+ _this.send(utils_1.toSCXMLEvent(doneEvent, { origin: childService.id }));
825
+ })
826
+ .start();
821
827
  return actor;
822
828
  };
823
829
  Interpreter.prototype.spawnPromise = function (promise, id) {
@@ -825,10 +831,12 @@ var Interpreter = /** @class */ (function () {
825
831
  var canceled = false;
826
832
  promise.then(function (response) {
827
833
  if (!canceled) {
834
+ _this.removeChild(id);
828
835
  _this.send(utils_1.toSCXMLEvent(actions_1.doneInvoke(id, response), { origin: id }));
829
836
  }
830
837
  }, function (errorData) {
831
838
  if (!canceled) {
839
+ _this.removeChild(id);
832
840
  var errorEvent = actions_1.error(id, errorData);
833
841
  try {
834
842
  // Send "error.platform.id" to this (parent).
@@ -938,8 +946,10 @@ var Interpreter = /** @class */ (function () {
938
946
  var subscription = source.subscribe(function (value) {
939
947
  _this.send(utils_1.toSCXMLEvent(value, { origin: id }));
940
948
  }, function (err) {
949
+ _this.removeChild(id);
941
950
  _this.send(utils_1.toSCXMLEvent(actions_1.error(id, err), { origin: id }));
942
951
  }, function () {
952
+ _this.removeChild(id);
943
953
  _this.send(utils_1.toSCXMLEvent(actions_1.doneInvoke(id), { origin: id }));
944
954
  });
945
955
  var actor = {