xstate 4.22.0 → 4.23.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.
Files changed (88) hide show
  1. package/CHANGELOG.md +58 -4
  2. package/dist/xstate.interpreter.js +1 -1
  3. package/dist/xstate.js +1 -1
  4. package/dist/xstate.web.js +2 -2
  5. package/es/Actor.js +1 -6
  6. package/es/Machine.d.ts +3 -3
  7. package/es/Machine.js +1 -2
  8. package/es/State.js +1 -3
  9. package/es/StateNode.js +3 -2
  10. package/es/_virtual/_tslib.js +59 -73
  11. package/es/actionTypes.js +3 -2
  12. package/es/actions.d.ts +1 -1
  13. package/es/actions.js +51 -37
  14. package/es/behaviors.js +4 -2
  15. package/es/constants.js +2 -1
  16. package/es/devTools.js +1 -1
  17. package/es/environment.js +2 -1
  18. package/es/index.js +3 -1
  19. package/es/interpreter.d.ts +8 -2
  20. package/es/interpreter.js +8 -6
  21. package/es/invokeUtils.js +4 -3
  22. package/es/mapState.js +1 -1
  23. package/es/match.js +1 -1
  24. package/es/model.d.ts +2 -37
  25. package/es/model.types.d.ts +37 -0
  26. package/es/registry.js +2 -1
  27. package/es/scheduler.js +2 -1
  28. package/es/schema.js +1 -1
  29. package/es/serviceScope.js +1 -3
  30. package/es/stateUtils.js +1 -9
  31. package/es/types.d.ts +12 -2
  32. package/es/types.js +1 -1
  33. package/es/utils.js +1 -41
  34. package/lib/Actor.d.ts +25 -25
  35. package/lib/Actor.js +85 -66
  36. package/lib/Machine.d.ts +17 -17
  37. package/lib/Machine.js +14 -8
  38. package/lib/SimulatedClock.d.ts +16 -16
  39. package/lib/State.d.ts +108 -108
  40. package/lib/State.js +246 -236
  41. package/lib/StateNode.d.ts +279 -279
  42. package/lib/StateNode.js +1535 -1357
  43. package/lib/_virtual/_tslib.js +81 -0
  44. package/lib/actionTypes.d.ts +19 -19
  45. package/lib/actionTypes.js +43 -23
  46. package/lib/actions.d.ts +138 -138
  47. package/lib/actions.js +465 -387
  48. package/lib/behaviors.d.ts +36 -36
  49. package/lib/behaviors.js +65 -106
  50. package/lib/constants.d.ts +5 -5
  51. package/lib/constants.js +13 -7
  52. package/lib/devTools.d.ts +15 -15
  53. package/lib/devTools.js +37 -26
  54. package/lib/each.d.ts +3 -3
  55. package/lib/environment.d.ts +1 -1
  56. package/lib/environment.js +7 -4
  57. package/lib/index.d.ts +30 -30
  58. package/lib/index.js +67 -57
  59. package/lib/interpreter.d.ts +205 -199
  60. package/lib/interpreter.js +1306 -1060
  61. package/lib/invoke.d.ts +10 -10
  62. package/lib/invokeUtils.d.ts +6 -6
  63. package/lib/invokeUtils.js +40 -37
  64. package/lib/json.d.ts +30 -30
  65. package/lib/mapState.d.ts +3 -3
  66. package/lib/mapState.js +31 -32
  67. package/lib/match.d.ts +8 -8
  68. package/lib/match.js +33 -47
  69. package/lib/model.d.ts +4 -39
  70. package/lib/model.types.d.ts +37 -0
  71. package/lib/model.types.js +2 -0
  72. package/lib/patterns.d.ts +13 -13
  73. package/lib/registry.d.ts +8 -8
  74. package/lib/registry.js +21 -18
  75. package/lib/scheduler.d.ts +16 -16
  76. package/lib/scheduler.js +79 -70
  77. package/lib/schema.d.ts +1 -1
  78. package/lib/schema.js +6 -4
  79. package/lib/scxml.d.ts +5 -5
  80. package/lib/serviceScope.d.ts +3 -3
  81. package/lib/serviceScope.js +16 -12
  82. package/lib/stateUtils.d.ts +14 -14
  83. package/lib/stateUtils.js +231 -199
  84. package/lib/types.d.ts +928 -918
  85. package/lib/types.js +29 -29
  86. package/lib/utils.d.ts +68 -68
  87. package/lib/utils.js +528 -534
  88. package/package.json +5 -5
@@ -1,1122 +1,1368 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __values = (this && this.__values) || function(o) {
14
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
15
- if (m) return m.call(o);
16
- if (o && typeof o.length === "number") return {
17
- next: function () {
18
- if (o && i >= o.length) o = void 0;
19
- return { value: o && o[i++], done: !o };
20
- }
21
- };
22
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
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
- };
40
- var __spreadArray = (this && this.__spreadArray) || function (to, from) {
41
- for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
42
- to[j] = from[i];
43
- return to;
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _tslib = require('./_virtual/_tslib.js');
6
+ var environment = require('./environment.js');
7
+ var utils = require('./utils.js');
8
+ var types = require('./types.js');
9
+ var stateUtils = require('./stateUtils.js');
10
+ var actionTypes = require('./actionTypes.js');
11
+ var actions = require('./actions.js');
12
+ var State = require('./State.js');
13
+ var serviceScope = require('./serviceScope.js');
14
+ var Actor = require('./Actor.js');
15
+ var scheduler = require('./scheduler.js');
16
+ var registry = require('./registry.js');
17
+ var devTools = require('./devTools.js');
18
+ var behaviors = require('./behaviors.js');
19
+
20
+ var DEFAULT_SPAWN_OPTIONS = {
21
+ sync: false,
22
+ autoForward: false
44
23
  };
45
- Object.defineProperty(exports, "__esModule", { value: true });
46
- exports.interpret = exports.spawn = exports.Interpreter = exports.InterpreterStatus = void 0;
47
- var types_1 = require("./types");
48
- var State_1 = require("./State");
49
- var actionTypes = require("./actionTypes");
50
- var actions_1 = require("./actions");
51
- var environment_1 = require("./environment");
52
- var utils_1 = require("./utils");
53
- var scheduler_1 = require("./scheduler");
54
- var Actor_1 = require("./Actor");
55
- var stateUtils_1 = require("./stateUtils");
56
- var registry_1 = require("./registry");
57
- var devTools_1 = require("./devTools");
58
- var serviceScope = require("./serviceScope");
59
- var behaviors_1 = require("./behaviors");
60
- var DEFAULT_SPAWN_OPTIONS = { sync: false, autoForward: false };
61
- var InterpreterStatus;
24
+
62
25
  (function (InterpreterStatus) {
63
- InterpreterStatus[InterpreterStatus["NotStarted"] = 0] = "NotStarted";
64
- InterpreterStatus[InterpreterStatus["Running"] = 1] = "Running";
65
- InterpreterStatus[InterpreterStatus["Stopped"] = 2] = "Stopped";
66
- })(InterpreterStatus = exports.InterpreterStatus || (exports.InterpreterStatus = {}));
67
- var Interpreter = /** @class */ (function () {
68
- /**
69
- * Creates a new Interpreter instance (i.e., service) for the given machine with the provided options, if any.
70
- *
71
- * @param machine The machine to be interpreted
72
- * @param options Interpreter options
73
- */
74
- function Interpreter(machine, options) {
75
- var _this = this;
76
- if (options === void 0) { options = Interpreter.defaultOptions; }
77
- this.machine = machine;
78
- this.scheduler = new scheduler_1.Scheduler();
79
- this.delayedEventsMap = {};
80
- this.listeners = new Set();
81
- this.contextListeners = new Set();
82
- this.stopListeners = new Set();
83
- this.doneListeners = new Set();
84
- this.eventListeners = new Set();
85
- this.sendListeners = new Set();
86
- /**
87
- * Whether the service is started.
88
- */
89
- this.initialized = false;
90
- this.status = InterpreterStatus.NotStarted;
91
- this.children = new Map();
92
- this.forwardTo = new Set();
93
- /**
94
- * Alias for Interpreter.prototype.start
95
- */
96
- this.init = this.start;
97
- /**
98
- * Sends an event to the running interpreter to trigger a transition.
99
- *
100
- * An array of events (batched) can be sent as well, which will send all
101
- * batched events to the running interpreter. The listeners will be
102
- * notified only **once** when all events are processed.
103
- *
104
- * @param event The event(s) to send
105
- */
106
- this.send = function (event, payload) {
107
- if (utils_1.isArray(event)) {
108
- _this.batch(event);
109
- return _this.state;
110
- }
111
- var _event = utils_1.toSCXMLEvent(utils_1.toEventObject(event, payload));
112
- if (_this.status === InterpreterStatus.Stopped) {
113
- // do nothing
114
- if (!environment_1.IS_PRODUCTION) {
115
- utils_1.warn(false, "Event \"" + _event.name + "\" was sent to stopped service \"" + _this.machine.id + "\". This service has already reached its final state, and will not transition.\nEvent: " + JSON.stringify(_event.data));
116
- }
117
- return _this.state;
118
- }
119
- if (_this.status !== InterpreterStatus.Running &&
120
- !_this.options.deferEvents) {
121
- throw new Error("Event \"" + _event.name + "\" was sent to uninitialized service \"" + _this.machine.id + "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options.\nEvent: " + JSON.stringify(_event.data));
122
- }
123
- _this.scheduler.schedule(function () {
124
- // Forward copy of event to child actors
125
- _this.forward(_event);
126
- var nextState = _this.nextState(_event);
127
- _this.update(nextState, _event);
128
- });
129
- return _this._state; // TODO: deprecate (should return void)
130
- // tslint:disable-next-line:semicolon
131
- };
132
- this.sendTo = function (event, to) {
133
- var isParent = _this.parent && (to === types_1.SpecialTargets.Parent || _this.parent.id === to);
134
- var target = isParent
135
- ? _this.parent
136
- : utils_1.isString(to)
137
- ? _this.children.get(to) || registry_1.registry.get(to)
138
- : utils_1.isActor(to)
139
- ? to
140
- : undefined;
141
- if (!target) {
142
- if (!isParent) {
143
- throw new Error("Unable to send event to child '" + to + "' from service '" + _this.id + "'.");
144
- }
145
- // tslint:disable-next-line:no-console
146
- if (!environment_1.IS_PRODUCTION) {
147
- utils_1.warn(false, "Service '" + _this.id + "' has no parent: unable to send event " + event.type);
148
- }
149
- return;
150
- }
151
- if ('machine' in target) {
152
- // Send SCXML events to machines
153
- target.send(__assign(__assign({}, event), { name: event.name === actionTypes.error ? "" + actions_1.error(_this.id) : event.name, origin: _this.sessionId }));
154
- }
155
- else {
156
- // Send normal events to other targets
157
- target.send(event.data);
158
- }
159
- };
160
- var resolvedOptions = __assign(__assign({}, Interpreter.defaultOptions), options);
161
- var clock = resolvedOptions.clock, logger = resolvedOptions.logger, parent = resolvedOptions.parent, id = resolvedOptions.id;
162
- var resolvedId = id !== undefined ? id : machine.id;
163
- this.id = resolvedId;
164
- this.logger = logger;
165
- this.clock = clock;
166
- this.parent = parent;
167
- this.options = resolvedOptions;
168
- this.scheduler = new scheduler_1.Scheduler({
169
- deferEvents: this.options.deferEvents
170
- });
171
- this.sessionId = registry_1.registry.bookId();
26
+ InterpreterStatus[InterpreterStatus["NotStarted"] = 0] = "NotStarted";
27
+ InterpreterStatus[InterpreterStatus["Running"] = 1] = "Running";
28
+ InterpreterStatus[InterpreterStatus["Stopped"] = 2] = "Stopped";
29
+ })(exports.InterpreterStatus || (exports.InterpreterStatus = {}));
30
+
31
+ var Interpreter =
32
+ /*#__PURE__*/
33
+
34
+ /** @class */
35
+ function () {
36
+ /**
37
+ * Creates a new Interpreter instance (i.e., service) for the given machine with the provided options, if any.
38
+ *
39
+ * @param machine The machine to be interpreted
40
+ * @param options Interpreter options
41
+ */
42
+ function Interpreter(machine, options) {
43
+ var _this = this;
44
+
45
+ if (options === void 0) {
46
+ options = Interpreter.defaultOptions;
172
47
  }
173
- Object.defineProperty(Interpreter.prototype, "initialState", {
174
- get: function () {
175
- var _this = this;
176
- if (this._initialState) {
177
- return this._initialState;
178
- }
179
- return serviceScope.provide(this, function () {
180
- _this._initialState = _this.machine.initialState;
181
- return _this._initialState;
182
- });
183
- },
184
- enumerable: false,
185
- configurable: true
186
- });
187
- Object.defineProperty(Interpreter.prototype, "state", {
188
- get: function () {
189
- if (!environment_1.IS_PRODUCTION) {
190
- utils_1.warn(this.status !== InterpreterStatus.NotStarted, "Attempted to read state from uninitialized service '" + this.id + "'. Make sure the service is started first.");
191
- }
192
- return this._state;
193
- },
194
- enumerable: false,
195
- configurable: true
196
- });
197
- /**
198
- * Executes the actions of the given state, with that state's `context` and `event`.
199
- *
200
- * @param state The state whose actions will be executed
201
- * @param actionsConfig The action implementations to use
48
+
49
+ this.machine = machine;
50
+ this.scheduler = new scheduler.Scheduler();
51
+ this.delayedEventsMap = {};
52
+ this.listeners = new Set();
53
+ this.contextListeners = new Set();
54
+ this.stopListeners = new Set();
55
+ this.doneListeners = new Set();
56
+ this.eventListeners = new Set();
57
+ this.sendListeners = new Set();
58
+ /**
59
+ * Whether the service is started.
202
60
  */
203
- Interpreter.prototype.execute = function (state, actionsConfig) {
204
- var e_1, _a;
205
- try {
206
- for (var _b = __values(state.actions), _c = _b.next(); !_c.done; _c = _b.next()) {
207
- var action = _c.value;
208
- this.exec(action, state, actionsConfig);
209
- }
210
- }
211
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
212
- finally {
213
- try {
214
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
215
- }
216
- finally { if (e_1) throw e_1.error; }
61
+
62
+ this.initialized = false;
63
+ this.status = exports.InterpreterStatus.NotStarted;
64
+ this.children = new Map();
65
+ this.forwardTo = new Set();
66
+ /**
67
+ * Alias for Interpreter.prototype.start
68
+ */
69
+
70
+ this.init = this.start;
71
+ /**
72
+ * Sends an event to the running interpreter to trigger a transition.
73
+ *
74
+ * An array of events (batched) can be sent as well, which will send all
75
+ * batched events to the running interpreter. The listeners will be
76
+ * notified only **once** when all events are processed.
77
+ *
78
+ * @param event The event(s) to send
79
+ */
80
+
81
+ this.send = function (event, payload) {
82
+ if (utils.isArray(event)) {
83
+ _this.batch(event);
84
+
85
+ return _this.state;
86
+ }
87
+
88
+ var _event = utils.toSCXMLEvent(utils.toEventObject(event, payload));
89
+
90
+ if (_this.status === exports.InterpreterStatus.Stopped) {
91
+ // do nothing
92
+ if (!environment.IS_PRODUCTION) {
93
+ utils.warn(false, "Event \"" + _event.name + "\" was sent to stopped service \"" + _this.machine.id + "\". This service has already reached its final state, and will not transition.\nEvent: " + JSON.stringify(_event.data));
217
94
  }
95
+
96
+ return _this.state;
97
+ }
98
+
99
+ if (_this.status !== exports.InterpreterStatus.Running && !_this.options.deferEvents) {
100
+ throw new Error("Event \"" + _event.name + "\" was sent to uninitialized service \"" + _this.machine.id + "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options.\nEvent: " + JSON.stringify(_event.data));
101
+ }
102
+
103
+ _this.scheduler.schedule(function () {
104
+ // Forward copy of event to child actors
105
+ _this.forward(_event);
106
+
107
+ var nextState = _this.nextState(_event);
108
+
109
+ _this.update(nextState, _event);
110
+ });
111
+
112
+ return _this._state; // TODO: deprecate (should return void)
113
+ // tslint:disable-next-line:semicolon
218
114
  };
219
- Interpreter.prototype.update = function (state, _event) {
220
- var e_2, _a, e_3, _b, e_4, _c, e_5, _d;
221
- var _this = this;
222
- // Attach session ID to state
223
- state._sessionid = this.sessionId;
224
- // Update state
225
- this._state = state;
226
- // Execute actions
227
- if (this.options.execute) {
228
- this.execute(this.state);
229
- }
230
- // Update children
231
- this.children.forEach(function (child) {
232
- _this.state.children[child.id] = child;
233
- });
234
- // Dev tools
235
- if (this.devTools) {
236
- this.devTools.send(_event.data, state);
115
+
116
+ this.sendTo = function (event, to) {
117
+ var isParent = _this.parent && (to === types.SpecialTargets.Parent || _this.parent.id === to);
118
+ var target = isParent ? _this.parent : utils.isString(to) ? _this.children.get(to) || registry.registry.get(to) : utils.isActor(to) ? to : undefined;
119
+
120
+ if (!target) {
121
+ if (!isParent) {
122
+ throw new Error("Unable to send event to child '" + to + "' from service '" + _this.id + "'.");
123
+ } // tslint:disable-next-line:no-console
124
+
125
+
126
+ if (!environment.IS_PRODUCTION) {
127
+ utils.warn(false, "Service '" + _this.id + "' has no parent: unable to send event " + event.type);
237
128
  }
238
- // Execute listeners
239
- if (state.event) {
240
- try {
241
- for (var _e = __values(this.eventListeners), _f = _e.next(); !_f.done; _f = _e.next()) {
242
- var listener = _f.value;
243
- listener(state.event);
244
- }
245
- }
246
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
247
- finally {
248
- try {
249
- if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
250
- }
251
- finally { if (e_2) throw e_2.error; }
252
- }
129
+
130
+ return;
131
+ }
132
+
133
+ if ('machine' in target) {
134
+ // Send SCXML events to machines
135
+ target.send(_tslib.__assign(_tslib.__assign({}, event), {
136
+ name: event.name === actionTypes.error ? "" + actions.error(_this.id) : event.name,
137
+ origin: _this.sessionId
138
+ }));
139
+ } else {
140
+ // Send normal events to other targets
141
+ target.send(event.data);
142
+ }
143
+ };
144
+
145
+ var resolvedOptions = _tslib.__assign(_tslib.__assign({}, Interpreter.defaultOptions), options);
146
+
147
+ var clock = resolvedOptions.clock,
148
+ logger = resolvedOptions.logger,
149
+ parent = resolvedOptions.parent,
150
+ id = resolvedOptions.id;
151
+ var resolvedId = id !== undefined ? id : machine.id;
152
+ this.id = resolvedId;
153
+ this.logger = logger;
154
+ this.clock = clock;
155
+ this.parent = parent;
156
+ this.options = resolvedOptions;
157
+ this.scheduler = new scheduler.Scheduler({
158
+ deferEvents: this.options.deferEvents
159
+ });
160
+ this.sessionId = registry.registry.bookId();
161
+ }
162
+
163
+ Object.defineProperty(Interpreter.prototype, "initialState", {
164
+ get: function () {
165
+ var _this = this;
166
+
167
+ if (this._initialState) {
168
+ return this._initialState;
169
+ }
170
+
171
+ return serviceScope.provide(this, function () {
172
+ _this._initialState = _this.machine.initialState;
173
+ return _this._initialState;
174
+ });
175
+ },
176
+ enumerable: false,
177
+ configurable: true
178
+ });
179
+ Object.defineProperty(Interpreter.prototype, "state", {
180
+ get: function () {
181
+ if (!environment.IS_PRODUCTION) {
182
+ utils.warn(this.status !== exports.InterpreterStatus.NotStarted, "Attempted to read state from uninitialized service '" + this.id + "'. Make sure the service is started first.");
183
+ }
184
+
185
+ return this._state;
186
+ },
187
+ enumerable: false,
188
+ configurable: true
189
+ });
190
+ /**
191
+ * Executes the actions of the given state, with that state's `context` and `event`.
192
+ *
193
+ * @param state The state whose actions will be executed
194
+ * @param actionsConfig The action implementations to use
195
+ */
196
+
197
+ Interpreter.prototype.execute = function (state, actionsConfig) {
198
+ var e_1, _a;
199
+
200
+ try {
201
+ for (var _b = _tslib.__values(state.actions), _c = _b.next(); !_c.done; _c = _b.next()) {
202
+ var action = _c.value;
203
+ this.exec(action, state, actionsConfig);
204
+ }
205
+ } catch (e_1_1) {
206
+ e_1 = {
207
+ error: e_1_1
208
+ };
209
+ } finally {
210
+ try {
211
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
212
+ } finally {
213
+ if (e_1) throw e_1.error;
214
+ }
215
+ }
216
+ };
217
+
218
+ Interpreter.prototype.update = function (state, _event) {
219
+ var e_2, _a, e_3, _b, e_4, _c, e_5, _d;
220
+
221
+ var _this = this; // Attach session ID to state
222
+
223
+
224
+ state._sessionid = this.sessionId; // Update state
225
+
226
+ this._state = state; // Execute actions
227
+
228
+ if (this.options.execute) {
229
+ this.execute(this.state);
230
+ } // Update children
231
+
232
+
233
+ this.children.forEach(function (child) {
234
+ _this.state.children[child.id] = child;
235
+ }); // Dev tools
236
+
237
+ if (this.devTools) {
238
+ this.devTools.send(_event.data, state);
239
+ } // Execute listeners
240
+
241
+
242
+ if (state.event) {
243
+ try {
244
+ for (var _e = _tslib.__values(this.eventListeners), _f = _e.next(); !_f.done; _f = _e.next()) {
245
+ var listener = _f.value;
246
+ listener(state.event);
253
247
  }
248
+ } catch (e_2_1) {
249
+ e_2 = {
250
+ error: e_2_1
251
+ };
252
+ } finally {
254
253
  try {
255
- for (var _g = __values(this.listeners), _h = _g.next(); !_h.done; _h = _g.next()) {
256
- var listener = _h.value;
257
- listener(state, state.event);
258
- }
254
+ if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
255
+ } finally {
256
+ if (e_2) throw e_2.error;
259
257
  }
260
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
261
- finally {
262
- try {
263
- if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
264
- }
265
- finally { if (e_3) throw e_3.error; }
258
+ }
259
+ }
260
+
261
+ try {
262
+ for (var _g = _tslib.__values(this.listeners), _h = _g.next(); !_h.done; _h = _g.next()) {
263
+ var listener = _h.value;
264
+ listener(state, state.event);
265
+ }
266
+ } catch (e_3_1) {
267
+ e_3 = {
268
+ error: e_3_1
269
+ };
270
+ } finally {
271
+ try {
272
+ if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
273
+ } finally {
274
+ if (e_3) throw e_3.error;
275
+ }
276
+ }
277
+
278
+ try {
279
+ for (var _j = _tslib.__values(this.contextListeners), _k = _j.next(); !_k.done; _k = _j.next()) {
280
+ var contextListener = _k.value;
281
+ contextListener(this.state.context, this.state.history ? this.state.history.context : undefined);
282
+ }
283
+ } catch (e_4_1) {
284
+ e_4 = {
285
+ error: e_4_1
286
+ };
287
+ } finally {
288
+ try {
289
+ if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
290
+ } finally {
291
+ if (e_4) throw e_4.error;
292
+ }
293
+ }
294
+
295
+ var isDone = stateUtils.isInFinalState(state.configuration || [], this.machine);
296
+
297
+ if (this.state.configuration && isDone) {
298
+ // get final child state node
299
+ var finalChildStateNode = state.configuration.find(function (sn) {
300
+ return sn.type === 'final' && sn.parent === _this.machine;
301
+ });
302
+ var doneData = finalChildStateNode && finalChildStateNode.doneData ? utils.mapContext(finalChildStateNode.doneData, state.context, _event) : undefined;
303
+
304
+ try {
305
+ for (var _l = _tslib.__values(this.doneListeners), _m = _l.next(); !_m.done; _m = _l.next()) {
306
+ var listener = _m.value;
307
+ listener(actions.doneInvoke(this.id, doneData));
266
308
  }
309
+ } catch (e_5_1) {
310
+ e_5 = {
311
+ error: e_5_1
312
+ };
313
+ } finally {
267
314
  try {
268
- for (var _j = __values(this.contextListeners), _k = _j.next(); !_k.done; _k = _j.next()) {
269
- var contextListener = _k.value;
270
- contextListener(this.state.context, this.state.history ? this.state.history.context : undefined);
271
- }
272
- }
273
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
274
- finally {
275
- try {
276
- if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
277
- }
278
- finally { if (e_4) throw e_4.error; }
279
- }
280
- var isDone = stateUtils_1.isInFinalState(state.configuration || [], this.machine);
281
- if (this.state.configuration && isDone) {
282
- // get final child state node
283
- var finalChildStateNode = state.configuration.find(function (sn) { return sn.type === 'final' && sn.parent === _this.machine; });
284
- var doneData = finalChildStateNode && finalChildStateNode.doneData
285
- ? utils_1.mapContext(finalChildStateNode.doneData, state.context, _event)
286
- : undefined;
287
- try {
288
- for (var _l = __values(this.doneListeners), _m = _l.next(); !_m.done; _m = _l.next()) {
289
- var listener = _m.value;
290
- listener(actions_1.doneInvoke(this.id, doneData));
291
- }
292
- }
293
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
294
- finally {
295
- try {
296
- if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
297
- }
298
- finally { if (e_5) throw e_5.error; }
299
- }
300
- this.stop();
301
- }
302
- };
303
- /*
304
- * Adds a listener that is notified whenever a state transition happens. The listener is called with
305
- * the next state and the event object that caused the state transition.
306
- *
307
- * @param listener The state listener
308
- */
309
- Interpreter.prototype.onTransition = function (listener) {
310
- this.listeners.add(listener);
311
- // Send current state to listener
312
- if (this.status === InterpreterStatus.Running) {
313
- listener(this.state, this.state.event);
314
- }
315
- return this;
316
- };
317
- Interpreter.prototype.subscribe = function (nextListenerOrObserver, _, // TODO: error listener
318
- completeListener) {
319
- var _this = this;
320
- if (!nextListenerOrObserver) {
321
- return { unsubscribe: function () { return void 0; } };
322
- }
323
- var listener;
324
- var resolvedCompleteListener = completeListener;
325
- if (typeof nextListenerOrObserver === 'function') {
326
- listener = nextListenerOrObserver;
327
- }
328
- else {
329
- listener = nextListenerOrObserver.next.bind(nextListenerOrObserver);
330
- resolvedCompleteListener = nextListenerOrObserver.complete.bind(nextListenerOrObserver);
315
+ if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
316
+ } finally {
317
+ if (e_5) throw e_5.error;
331
318
  }
332
- this.listeners.add(listener);
333
- // Send current state to listener
334
- if (this.status === InterpreterStatus.Running) {
335
- listener(this.state);
336
- }
337
- if (resolvedCompleteListener) {
338
- this.onDone(resolvedCompleteListener);
319
+ }
320
+
321
+ this.stop();
322
+ }
323
+ };
324
+ /*
325
+ * Adds a listener that is notified whenever a state transition happens. The listener is called with
326
+ * the next state and the event object that caused the state transition.
327
+ *
328
+ * @param listener The state listener
329
+ */
330
+
331
+
332
+ Interpreter.prototype.onTransition = function (listener) {
333
+ this.listeners.add(listener); // Send current state to listener
334
+
335
+ if (this.status === exports.InterpreterStatus.Running) {
336
+ listener(this.state, this.state.event);
337
+ }
338
+
339
+ return this;
340
+ };
341
+
342
+ Interpreter.prototype.subscribe = function (nextListenerOrObserver, _, // TODO: error listener
343
+ completeListener) {
344
+ var _this = this;
345
+
346
+ if (!nextListenerOrObserver) {
347
+ return {
348
+ unsubscribe: function () {
349
+ return void 0;
339
350
  }
340
- return {
341
- unsubscribe: function () {
342
- listener && _this.listeners.delete(listener);
343
- resolvedCompleteListener &&
344
- _this.doneListeners.delete(resolvedCompleteListener);
345
- }
346
- };
347
- };
348
- /**
349
- * Adds an event listener that is notified whenever an event is sent to the running interpreter.
350
- * @param listener The event listener
351
- */
352
- Interpreter.prototype.onEvent = function (listener) {
353
- this.eventListeners.add(listener);
354
- return this;
355
- };
356
- /**
357
- * Adds an event listener that is notified whenever a `send` event occurs.
358
- * @param listener The event listener
359
- */
360
- Interpreter.prototype.onSend = function (listener) {
361
- this.sendListeners.add(listener);
362
- return this;
363
- };
364
- /**
365
- * Adds a context listener that is notified whenever the state context changes.
366
- * @param listener The context listener
367
- */
368
- Interpreter.prototype.onChange = function (listener) {
369
- this.contextListeners.add(listener);
370
- return this;
371
- };
372
- /**
373
- * Adds a listener that is notified when the machine is stopped.
374
- * @param listener The listener
375
- */
376
- Interpreter.prototype.onStop = function (listener) {
377
- this.stopListeners.add(listener);
378
- return this;
379
- };
380
- /**
381
- * Adds a state listener that is notified when the statechart has reached its final state.
382
- * @param listener The state listener
383
- */
384
- Interpreter.prototype.onDone = function (listener) {
385
- this.doneListeners.add(listener);
386
- return this;
351
+ };
352
+ }
353
+
354
+ var listener;
355
+ var resolvedCompleteListener = completeListener;
356
+
357
+ if (typeof nextListenerOrObserver === 'function') {
358
+ listener = nextListenerOrObserver;
359
+ } else {
360
+ listener = nextListenerOrObserver.next.bind(nextListenerOrObserver);
361
+ resolvedCompleteListener = nextListenerOrObserver.complete.bind(nextListenerOrObserver);
362
+ }
363
+
364
+ this.listeners.add(listener); // Send current state to listener
365
+
366
+ if (this.status === exports.InterpreterStatus.Running) {
367
+ listener(this.state);
368
+ }
369
+
370
+ if (resolvedCompleteListener) {
371
+ this.onDone(resolvedCompleteListener);
372
+ }
373
+
374
+ return {
375
+ unsubscribe: function () {
376
+ listener && _this.listeners.delete(listener);
377
+ resolvedCompleteListener && _this.doneListeners.delete(resolvedCompleteListener);
378
+ }
387
379
  };
388
- /**
389
- * Removes a listener.
390
- * @param listener The listener to remove
391
- */
392
- Interpreter.prototype.off = function (listener) {
380
+ };
381
+ /**
382
+ * Adds an event listener that is notified whenever an event is sent to the running interpreter.
383
+ * @param listener The event listener
384
+ */
385
+
386
+
387
+ Interpreter.prototype.onEvent = function (listener) {
388
+ this.eventListeners.add(listener);
389
+ return this;
390
+ };
391
+ /**
392
+ * Adds an event listener that is notified whenever a `send` event occurs.
393
+ * @param listener The event listener
394
+ */
395
+
396
+
397
+ Interpreter.prototype.onSend = function (listener) {
398
+ this.sendListeners.add(listener);
399
+ return this;
400
+ };
401
+ /**
402
+ * Adds a context listener that is notified whenever the state context changes.
403
+ * @param listener The context listener
404
+ */
405
+
406
+
407
+ Interpreter.prototype.onChange = function (listener) {
408
+ this.contextListeners.add(listener);
409
+ return this;
410
+ };
411
+ /**
412
+ * Adds a listener that is notified when the machine is stopped.
413
+ * @param listener The listener
414
+ */
415
+
416
+
417
+ Interpreter.prototype.onStop = function (listener) {
418
+ this.stopListeners.add(listener);
419
+ return this;
420
+ };
421
+ /**
422
+ * Adds a state listener that is notified when the statechart has reached its final state.
423
+ * @param listener The state listener
424
+ */
425
+
426
+
427
+ Interpreter.prototype.onDone = function (listener) {
428
+ this.doneListeners.add(listener);
429
+ return this;
430
+ };
431
+ /**
432
+ * Removes a listener.
433
+ * @param listener The listener to remove
434
+ */
435
+
436
+
437
+ Interpreter.prototype.off = function (listener) {
438
+ this.listeners.delete(listener);
439
+ this.eventListeners.delete(listener);
440
+ this.sendListeners.delete(listener);
441
+ this.stopListeners.delete(listener);
442
+ this.doneListeners.delete(listener);
443
+ this.contextListeners.delete(listener);
444
+ return this;
445
+ };
446
+ /**
447
+ * Starts the interpreter from the given state, or the initial state.
448
+ * @param initialState The state to start the statechart from
449
+ */
450
+
451
+
452
+ Interpreter.prototype.start = function (initialState) {
453
+ var _this = this;
454
+
455
+ if (this.status === exports.InterpreterStatus.Running) {
456
+ // Do not restart the service if it is already started
457
+ return this;
458
+ }
459
+
460
+ registry.registry.register(this.sessionId, this);
461
+ this.initialized = true;
462
+ this.status = exports.InterpreterStatus.Running;
463
+ var resolvedState = initialState === undefined ? this.initialState : serviceScope.provide(this, function () {
464
+ return State.isState(initialState) ? _this.machine.resolveState(initialState) : _this.machine.resolveState(State.State.from(initialState, _this.machine.context));
465
+ });
466
+
467
+ if (this.options.devTools) {
468
+ this.attachDev();
469
+ }
470
+
471
+ this.scheduler.initialize(function () {
472
+ _this.update(resolvedState, actions.initEvent);
473
+ });
474
+ return this;
475
+ };
476
+ /**
477
+ * Stops the interpreter and unsubscribe all listeners.
478
+ *
479
+ * This will also notify the `onStop` listeners.
480
+ */
481
+
482
+
483
+ Interpreter.prototype.stop = function () {
484
+ var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e;
485
+
486
+ var _this = this;
487
+
488
+ try {
489
+ for (var _f = _tslib.__values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
490
+ var listener = _g.value;
393
491
  this.listeners.delete(listener);
394
- this.eventListeners.delete(listener);
395
- this.sendListeners.delete(listener);
492
+ }
493
+ } catch (e_6_1) {
494
+ e_6 = {
495
+ error: e_6_1
496
+ };
497
+ } finally {
498
+ try {
499
+ if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
500
+ } finally {
501
+ if (e_6) throw e_6.error;
502
+ }
503
+ }
504
+
505
+ try {
506
+ for (var _h = _tslib.__values(this.stopListeners), _j = _h.next(); !_j.done; _j = _h.next()) {
507
+ var listener = _j.value; // call listener, then remove
508
+
509
+ listener();
396
510
  this.stopListeners.delete(listener);
397
- this.doneListeners.delete(listener);
511
+ }
512
+ } catch (e_7_1) {
513
+ e_7 = {
514
+ error: e_7_1
515
+ };
516
+ } finally {
517
+ try {
518
+ if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
519
+ } finally {
520
+ if (e_7) throw e_7.error;
521
+ }
522
+ }
523
+
524
+ try {
525
+ for (var _k = _tslib.__values(this.contextListeners), _l = _k.next(); !_l.done; _l = _k.next()) {
526
+ var listener = _l.value;
398
527
  this.contextListeners.delete(listener);
399
- return this;
400
- };
401
- /**
402
- * Starts the interpreter from the given state, or the initial state.
403
- * @param initialState The state to start the statechart from
404
- */
405
- Interpreter.prototype.start = function (initialState) {
406
- var _this = this;
407
- if (this.status === InterpreterStatus.Running) {
408
- // Do not restart the service if it is already started
409
- return this;
410
- }
411
- registry_1.registry.register(this.sessionId, this);
412
- this.initialized = true;
413
- this.status = InterpreterStatus.Running;
414
- var resolvedState = initialState === undefined
415
- ? this.initialState
416
- : serviceScope.provide(this, function () {
417
- return State_1.isState(initialState)
418
- ? _this.machine.resolveState(initialState)
419
- : _this.machine.resolveState(State_1.State.from(initialState, _this.machine.context));
420
- });
421
- if (this.options.devTools) {
422
- this.attachDev();
423
- }
424
- this.scheduler.initialize(function () {
425
- _this.update(resolvedState, actions_1.initEvent);
426
- });
427
- return this;
428
- };
429
- /**
430
- * Stops the interpreter and unsubscribe all listeners.
431
- *
432
- * This will also notify the `onStop` listeners.
433
- */
434
- Interpreter.prototype.stop = function () {
435
- var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e;
436
- var _this = this;
437
- try {
438
- for (var _f = __values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
439
- var listener = _g.value;
440
- this.listeners.delete(listener);
441
- }
442
- }
443
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
444
- finally {
445
- try {
446
- if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
447
- }
448
- finally { if (e_6) throw e_6.error; }
449
- }
450
- try {
451
- for (var _h = __values(this.stopListeners), _j = _h.next(); !_j.done; _j = _h.next()) {
452
- var listener = _j.value;
453
- // call listener, then remove
454
- listener();
455
- this.stopListeners.delete(listener);
456
- }
457
- }
458
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
459
- finally {
460
- try {
461
- if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
462
- }
463
- finally { if (e_7) throw e_7.error; }
464
- }
465
- try {
466
- for (var _k = __values(this.contextListeners), _l = _k.next(); !_l.done; _l = _k.next()) {
467
- var listener = _l.value;
468
- this.contextListeners.delete(listener);
469
- }
470
- }
471
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
472
- finally {
473
- try {
474
- if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
475
- }
476
- finally { if (e_8) throw e_8.error; }
528
+ }
529
+ } catch (e_8_1) {
530
+ e_8 = {
531
+ error: e_8_1
532
+ };
533
+ } finally {
534
+ try {
535
+ if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
536
+ } finally {
537
+ if (e_8) throw e_8.error;
538
+ }
539
+ }
540
+
541
+ try {
542
+ for (var _m = _tslib.__values(this.doneListeners), _o = _m.next(); !_o.done; _o = _m.next()) {
543
+ var listener = _o.value;
544
+ this.doneListeners.delete(listener);
545
+ }
546
+ } catch (e_9_1) {
547
+ e_9 = {
548
+ error: e_9_1
549
+ };
550
+ } finally {
551
+ try {
552
+ if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
553
+ } finally {
554
+ if (e_9) throw e_9.error;
555
+ }
556
+ }
557
+
558
+ if (!this.initialized) {
559
+ // Interpreter already stopped; do nothing
560
+ return this;
561
+ }
562
+
563
+ this.state.configuration.forEach(function (stateNode) {
564
+ var e_11, _a;
565
+
566
+ try {
567
+ for (var _b = _tslib.__values(stateNode.definition.exit), _c = _b.next(); !_c.done; _c = _b.next()) {
568
+ var action = _c.value;
569
+
570
+ _this.exec(action, _this.state);
477
571
  }
572
+ } catch (e_11_1) {
573
+ e_11 = {
574
+ error: e_11_1
575
+ };
576
+ } finally {
478
577
  try {
479
- for (var _m = __values(this.doneListeners), _o = _m.next(); !_o.done; _o = _m.next()) {
480
- var listener = _o.value;
481
- this.doneListeners.delete(listener);
482
- }
578
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
579
+ } finally {
580
+ if (e_11) throw e_11.error;
483
581
  }
484
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
485
- finally {
486
- try {
487
- if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
488
- }
489
- finally { if (e_9) throw e_9.error; }
490
- }
491
- if (!this.initialized) {
492
- // Interpreter already stopped; do nothing
493
- return this;
494
- }
495
- this.state.configuration.forEach(function (stateNode) {
496
- var e_11, _a;
497
- try {
498
- for (var _b = __values(stateNode.definition.exit), _c = _b.next(); !_c.done; _c = _b.next()) {
499
- var action = _c.value;
500
- _this.exec(action, _this.state);
501
- }
502
- }
503
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
504
- finally {
505
- try {
506
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
507
- }
508
- finally { if (e_11) throw e_11.error; }
509
- }
510
- });
511
- // Stop all children
512
- this.children.forEach(function (child) {
513
- if (utils_1.isFunction(child.stop)) {
514
- child.stop();
515
- }
582
+ }
583
+ }); // Stop all children
584
+
585
+ this.children.forEach(function (child) {
586
+ if (utils.isFunction(child.stop)) {
587
+ child.stop();
588
+ }
589
+ });
590
+
591
+ try {
592
+ // Cancel all delayed events
593
+ for (var _p = _tslib.__values(utils.keys(this.delayedEventsMap)), _q = _p.next(); !_q.done; _q = _p.next()) {
594
+ var key = _q.value;
595
+ this.clock.clearTimeout(this.delayedEventsMap[key]);
596
+ }
597
+ } catch (e_10_1) {
598
+ e_10 = {
599
+ error: e_10_1
600
+ };
601
+ } finally {
602
+ try {
603
+ if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
604
+ } finally {
605
+ if (e_10) throw e_10.error;
606
+ }
607
+ }
608
+
609
+ this.scheduler.clear();
610
+ this.initialized = false;
611
+ this.status = exports.InterpreterStatus.Stopped;
612
+ registry.registry.free(this.sessionId);
613
+ return this;
614
+ };
615
+
616
+ Interpreter.prototype.batch = function (events) {
617
+ var _this = this;
618
+
619
+ if (this.status === exports.InterpreterStatus.NotStarted && this.options.deferEvents) {
620
+ // tslint:disable-next-line:no-console
621
+ if (!environment.IS_PRODUCTION) {
622
+ utils.warn(false, events.length + " event(s) were sent to uninitialized service \"" + this.machine.id + "\" and are deferred. Make sure .start() is called for this service.\nEvent: " + JSON.stringify(event));
623
+ }
624
+ } else if (this.status !== exports.InterpreterStatus.Running) {
625
+ throw new Error( // tslint:disable-next-line:max-line-length
626
+ events.length + " event(s) were sent to uninitialized service \"" + this.machine.id + "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options.");
627
+ }
628
+
629
+ this.scheduler.schedule(function () {
630
+ var e_12, _a;
631
+
632
+ var nextState = _this.state;
633
+ var batchChanged = false;
634
+ var batchedActions = [];
635
+
636
+ var _loop_1 = function (event_1) {
637
+ var _event = utils.toSCXMLEvent(event_1);
638
+
639
+ _this.forward(_event);
640
+
641
+ nextState = serviceScope.provide(_this, function () {
642
+ return _this.machine.transition(nextState, _event);
516
643
  });
517
- try {
518
- // Cancel all delayed events
519
- for (var _p = __values(utils_1.keys(this.delayedEventsMap)), _q = _p.next(); !_q.done; _q = _p.next()) {
520
- var key = _q.value;
521
- this.clock.clearTimeout(this.delayedEventsMap[key]);
522
- }
523
- }
524
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
525
- finally {
526
- try {
527
- if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
528
- }
529
- finally { if (e_10) throw e_10.error; }
644
+ batchedActions.push.apply(batchedActions, _tslib.__spreadArray([], _tslib.__read(nextState.actions.map(function (a) {
645
+ return State.bindActionToState(a, nextState);
646
+ }))));
647
+ batchChanged = batchChanged || !!nextState.changed;
648
+ };
649
+
650
+ try {
651
+ for (var events_1 = _tslib.__values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
652
+ var event_1 = events_1_1.value;
653
+
654
+ _loop_1(event_1);
530
655
  }
531
- this.scheduler.clear();
532
- this.initialized = false;
533
- this.status = InterpreterStatus.Stopped;
534
- registry_1.registry.free(this.sessionId);
535
- return this;
536
- };
537
- Interpreter.prototype.batch = function (events) {
538
- var _this = this;
539
- if (this.status === InterpreterStatus.NotStarted &&
540
- this.options.deferEvents) {
541
- // tslint:disable-next-line:no-console
542
- if (!environment_1.IS_PRODUCTION) {
543
- utils_1.warn(false, events.length + " event(s) were sent to uninitialized service \"" + this.machine.id + "\" and are deferred. Make sure .start() is called for this service.\nEvent: " + JSON.stringify(event));
544
- }
656
+ } catch (e_12_1) {
657
+ e_12 = {
658
+ error: e_12_1
659
+ };
660
+ } finally {
661
+ try {
662
+ if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
663
+ } finally {
664
+ if (e_12) throw e_12.error;
545
665
  }
546
- else if (this.status !== InterpreterStatus.Running) {
547
- throw new Error(
548
- // tslint:disable-next-line:max-line-length
549
- events.length + " event(s) were sent to uninitialized service \"" + this.machine.id + "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options.");
666
+ }
667
+
668
+ nextState.changed = batchChanged;
669
+ nextState.actions = batchedActions;
670
+
671
+ _this.update(nextState, utils.toSCXMLEvent(events[events.length - 1]));
672
+ });
673
+ };
674
+ /**
675
+ * Returns a send function bound to this interpreter instance.
676
+ *
677
+ * @param event The event to be sent by the sender.
678
+ */
679
+
680
+
681
+ Interpreter.prototype.sender = function (event) {
682
+ return this.send.bind(this, event);
683
+ };
684
+ /**
685
+ * Returns the next state given the interpreter's current state and the event.
686
+ *
687
+ * This is a pure method that does _not_ update the interpreter's state.
688
+ *
689
+ * @param event The event to determine the next state
690
+ */
691
+
692
+
693
+ Interpreter.prototype.nextState = function (event) {
694
+ var _this = this;
695
+
696
+ var _event = utils.toSCXMLEvent(event);
697
+
698
+ if (_event.name.indexOf(actionTypes.errorPlatform) === 0 && !this.state.nextEvents.some(function (nextEvent) {
699
+ return nextEvent.indexOf(actionTypes.errorPlatform) === 0;
700
+ })) {
701
+ throw _event.data.data;
702
+ }
703
+
704
+ var nextState = serviceScope.provide(this, function () {
705
+ return _this.machine.transition(_this.state, _event);
706
+ });
707
+ return nextState;
708
+ };
709
+
710
+ Interpreter.prototype.forward = function (event) {
711
+ var e_13, _a;
712
+
713
+ try {
714
+ for (var _b = _tslib.__values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
715
+ var id = _c.value;
716
+ var child = this.children.get(id);
717
+
718
+ if (!child) {
719
+ throw new Error("Unable to forward event '" + event + "' from interpreter '" + this.id + "' to nonexistant child '" + id + "'.");
550
720
  }
551
- this.scheduler.schedule(function () {
552
- var e_12, _a;
553
- var nextState = _this.state;
554
- var batchChanged = false;
555
- var batchedActions = [];
556
- var _loop_1 = function (event_1) {
557
- var _event = utils_1.toSCXMLEvent(event_1);
558
- _this.forward(_event);
559
- nextState = serviceScope.provide(_this, function () {
560
- return _this.machine.transition(nextState, _event);
561
- });
562
- batchedActions.push.apply(batchedActions, __spreadArray([], __read(nextState.actions.map(function (a) {
563
- return State_1.bindActionToState(a, nextState);
564
- }))));
565
- batchChanged = batchChanged || !!nextState.changed;
566
- };
567
- try {
568
- for (var events_1 = __values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
569
- var event_1 = events_1_1.value;
570
- _loop_1(event_1);
571
- }
572
- }
573
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
574
- finally {
575
- try {
576
- if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
577
- }
578
- finally { if (e_12) throw e_12.error; }
579
- }
580
- nextState.changed = batchChanged;
581
- nextState.actions = batchedActions;
582
- _this.update(nextState, utils_1.toSCXMLEvent(events[events.length - 1]));
721
+
722
+ child.send(event);
723
+ }
724
+ } catch (e_13_1) {
725
+ e_13 = {
726
+ error: e_13_1
727
+ };
728
+ } finally {
729
+ try {
730
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
731
+ } finally {
732
+ if (e_13) throw e_13.error;
733
+ }
734
+ }
735
+ };
736
+
737
+ Interpreter.prototype.defer = function (sendAction) {
738
+ var _this = this;
739
+
740
+ this.delayedEventsMap[sendAction.id] = this.clock.setTimeout(function () {
741
+ if (sendAction.to) {
742
+ _this.sendTo(sendAction._event, sendAction.to);
743
+ } else {
744
+ _this.send(sendAction._event);
745
+ }
746
+ }, sendAction.delay);
747
+ };
748
+
749
+ Interpreter.prototype.cancel = function (sendId) {
750
+ this.clock.clearTimeout(this.delayedEventsMap[sendId]);
751
+ delete this.delayedEventsMap[sendId];
752
+ };
753
+
754
+ Interpreter.prototype.exec = function (action, state, actionFunctionMap) {
755
+ if (actionFunctionMap === void 0) {
756
+ actionFunctionMap = this.machine.options.actions;
757
+ }
758
+
759
+ var context = state.context,
760
+ _event = state._event;
761
+ var actionOrExec = action.exec || actions.getActionFunction(action.type, actionFunctionMap);
762
+ var exec = utils.isFunction(actionOrExec) ? actionOrExec : actionOrExec ? actionOrExec.exec : action.exec;
763
+
764
+ if (exec) {
765
+ try {
766
+ return exec(context, _event.data, {
767
+ action: action,
768
+ state: this.state,
769
+ _event: _event
583
770
  });
584
- };
585
- /**
586
- * Returns a send function bound to this interpreter instance.
587
- *
588
- * @param event The event to be sent by the sender.
589
- */
590
- Interpreter.prototype.sender = function (event) {
591
- return this.send.bind(this, event);
592
- };
593
- /**
594
- * Returns the next state given the interpreter's current state and the event.
595
- *
596
- * This is a pure method that does _not_ update the interpreter's state.
597
- *
598
- * @param event The event to determine the next state
599
- */
600
- Interpreter.prototype.nextState = function (event) {
601
- var _this = this;
602
- var _event = utils_1.toSCXMLEvent(event);
603
- if (_event.name.indexOf(actionTypes.errorPlatform) === 0 &&
604
- !this.state.nextEvents.some(function (nextEvent) { return nextEvent.indexOf(actionTypes.errorPlatform) === 0; })) {
605
- throw _event.data.data;
771
+ } catch (err) {
772
+ if (this.parent) {
773
+ this.parent.send({
774
+ type: 'xstate.error',
775
+ data: err
776
+ });
606
777
  }
607
- var nextState = serviceScope.provide(this, function () {
608
- return _this.machine.transition(_this.state, _event);
609
- });
610
- return nextState;
611
- };
612
- Interpreter.prototype.forward = function (event) {
613
- var e_13, _a;
614
- try {
615
- for (var _b = __values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
616
- var id = _c.value;
617
- var child = this.children.get(id);
618
- if (!child) {
619
- throw new Error("Unable to forward event '" + event + "' from interpreter '" + this.id + "' to nonexistant child '" + id + "'.");
620
- }
621
- child.send(event);
622
- }
623
- }
624
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
625
- finally {
626
- try {
627
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
628
- }
629
- finally { if (e_13) throw e_13.error; }
778
+
779
+ throw err;
780
+ }
781
+ }
782
+
783
+ switch (action.type) {
784
+ case actionTypes.send:
785
+ var sendAction = action;
786
+
787
+ if (typeof sendAction.delay === 'number') {
788
+ this.defer(sendAction);
789
+ return;
790
+ } else {
791
+ if (sendAction.to) {
792
+ this.sendTo(sendAction._event, sendAction.to);
793
+ } else {
794
+ this.send(sendAction._event);
795
+ }
630
796
  }
631
- };
632
- Interpreter.prototype.defer = function (sendAction) {
633
- var _this = this;
634
- this.delayedEventsMap[sendAction.id] = this.clock.setTimeout(function () {
635
- if (sendAction.to) {
636
- _this.sendTo(sendAction._event, sendAction.to);
637
- }
638
- else {
639
- _this.send(sendAction._event);
797
+
798
+ break;
799
+
800
+ case actionTypes.cancel:
801
+ this.cancel(action.sendId);
802
+ break;
803
+
804
+ case actionTypes.start:
805
+ {
806
+ var activity = action.activity; // If the activity will be stopped right after it's started
807
+ // (such as in transient states)
808
+ // don't bother starting the activity.
809
+
810
+ if (!this.state.activities[activity.id || activity.type]) {
811
+ break;
812
+ } // Invoked services
813
+
814
+
815
+ if (activity.type === types.ActionTypes.Invoke) {
816
+ var invokeSource = utils.toInvokeSource(activity.src);
817
+ var serviceCreator = this.machine.options.services ? this.machine.options.services[invokeSource.type] : undefined;
818
+ var id = activity.id,
819
+ data = activity.data;
820
+
821
+ if (!environment.IS_PRODUCTION) {
822
+ utils.warn(!('forward' in activity), // tslint:disable-next-line:max-line-length
823
+ "`forward` property is deprecated (found in invocation of '" + activity.src + "' in in machine '" + this.machine.id + "'). " + "Please use `autoForward` instead.");
640
824
  }
641
- }, sendAction.delay);
642
- };
643
- Interpreter.prototype.cancel = function (sendId) {
644
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
645
- delete this.delayedEventsMap[sendId];
646
- };
647
- Interpreter.prototype.exec = function (action, state, actionFunctionMap) {
648
- if (actionFunctionMap === void 0) { actionFunctionMap = this.machine
649
- .options.actions; }
650
- var context = state.context, _event = state._event;
651
- var actionOrExec = action.exec || actions_1.getActionFunction(action.type, actionFunctionMap);
652
- var exec = utils_1.isFunction(actionOrExec)
653
- ? actionOrExec
654
- : actionOrExec
655
- ? actionOrExec.exec
656
- : action.exec;
657
- if (exec) {
658
- try {
659
- return exec(context, _event.data, {
660
- action: action,
661
- state: this.state,
662
- _event: _event
663
- });
825
+
826
+ var autoForward = 'autoForward' in activity ? activity.autoForward : !!activity.forward;
827
+
828
+ if (!serviceCreator) {
829
+ // tslint:disable-next-line:no-console
830
+ if (!environment.IS_PRODUCTION) {
831
+ utils.warn(false, "No service found for invocation '" + activity.src + "' in machine '" + this.machine.id + "'.");
832
+ }
833
+
834
+ return;
664
835
  }
665
- catch (err) {
666
- if (this.parent) {
667
- this.parent.send({
668
- type: 'xstate.error',
669
- data: err
670
- });
671
- }
672
- throw err;
836
+
837
+ var resolvedData = data ? utils.mapContext(data, context, _event) : undefined;
838
+
839
+ if (typeof serviceCreator === 'string') {
840
+ // TODO: warn
841
+ return;
673
842
  }
674
- }
675
- switch (action.type) {
676
- case actionTypes.send:
677
- var sendAction = action;
678
- if (typeof sendAction.delay === 'number') {
679
- this.defer(sendAction);
680
- return;
681
- }
682
- else {
683
- if (sendAction.to) {
684
- this.sendTo(sendAction._event, sendAction.to);
685
- }
686
- else {
687
- this.send(sendAction._event);
688
- }
689
- }
690
- break;
691
- case actionTypes.cancel:
692
- this.cancel(action.sendId);
693
- break;
694
- case actionTypes.start: {
695
- var activity = action
696
- .activity;
697
- // If the activity will be stopped right after it's started
698
- // (such as in transient states)
699
- // don't bother starting the activity.
700
- if (!this.state.activities[activity.id || activity.type]) {
701
- break;
702
- }
703
- // Invoked services
704
- if (activity.type === types_1.ActionTypes.Invoke) {
705
- var invokeSource = utils_1.toInvokeSource(activity.src);
706
- var serviceCreator = this.machine.options.services
707
- ? this.machine.options.services[invokeSource.type]
708
- : undefined;
709
- var id = activity.id, data = activity.data;
710
- if (!environment_1.IS_PRODUCTION) {
711
- utils_1.warn(!('forward' in activity),
712
- // tslint:disable-next-line:max-line-length
713
- "`forward` property is deprecated (found in invocation of '" + activity.src + "' in in machine '" + this.machine.id + "'). " +
714
- "Please use `autoForward` instead.");
715
- }
716
- var autoForward = 'autoForward' in activity
717
- ? activity.autoForward
718
- : !!activity.forward;
719
- if (!serviceCreator) {
720
- // tslint:disable-next-line:no-console
721
- if (!environment_1.IS_PRODUCTION) {
722
- utils_1.warn(false, "No service found for invocation '" + activity.src + "' in machine '" + this.machine.id + "'.");
723
- }
724
- return;
725
- }
726
- var resolvedData = data
727
- ? utils_1.mapContext(data, context, _event)
728
- : undefined;
729
- if (typeof serviceCreator === 'string') {
730
- // TODO: warn
731
- return;
732
- }
733
- var source = utils_1.isFunction(serviceCreator)
734
- ? serviceCreator(context, _event.data, {
735
- data: resolvedData,
736
- src: invokeSource
737
- })
738
- : serviceCreator;
739
- if (!source) {
740
- // TODO: warn?
741
- return;
742
- }
743
- var options = void 0;
744
- if (utils_1.isMachine(source)) {
745
- source = resolvedData ? source.withContext(resolvedData) : source;
746
- options = {
747
- autoForward: autoForward
748
- };
749
- }
750
- this.spawn(source, id, options);
751
- }
752
- else {
753
- this.spawnActivity(activity);
754
- }
755
- break;
843
+
844
+ var source = utils.isFunction(serviceCreator) ? serviceCreator(context, _event.data, {
845
+ data: resolvedData,
846
+ src: invokeSource
847
+ }) : serviceCreator;
848
+
849
+ if (!source) {
850
+ // TODO: warn?
851
+ return;
756
852
  }
757
- case actionTypes.stop: {
758
- this.stopChild(action.activity.id);
759
- break;
853
+
854
+ var options = void 0;
855
+
856
+ if (utils.isMachine(source)) {
857
+ source = resolvedData ? source.withContext(resolvedData) : source;
858
+ options = {
859
+ autoForward: autoForward
860
+ };
760
861
  }
761
- case actionTypes.log:
762
- var label = action.label, value = action.value;
763
- if (label) {
764
- this.logger(label, value);
765
- }
766
- else {
767
- this.logger(value);
768
- }
769
- break;
770
- default:
771
- if (!environment_1.IS_PRODUCTION) {
772
- utils_1.warn(false, "No implementation found for action type '" + action.type + "'");
773
- }
774
- break;
775
- }
776
- return undefined;
777
- };
778
- Interpreter.prototype.removeChild = function (childId) {
779
- this.children.delete(childId);
780
- this.forwardTo.delete(childId);
781
- delete this.state.children[childId];
782
- };
783
- Interpreter.prototype.stopChild = function (childId) {
784
- var child = this.children.get(childId);
785
- if (!child) {
786
- return;
862
+
863
+ this.spawn(source, id, options);
864
+ } else {
865
+ this.spawnActivity(activity);
866
+ }
867
+
868
+ break;
787
869
  }
788
- this.removeChild(childId);
789
- if (utils_1.isFunction(child.stop)) {
790
- child.stop();
870
+
871
+ case actionTypes.stop:
872
+ {
873
+ this.stopChild(action.activity.id);
874
+ break;
791
875
  }
792
- };
793
- Interpreter.prototype.spawn = function (entity, name, options) {
794
- if (utils_1.isPromiseLike(entity)) {
795
- return this.spawnPromise(Promise.resolve(entity), name);
876
+
877
+ case actionTypes.log:
878
+ var label = action.label,
879
+ value = action.value;
880
+
881
+ if (label) {
882
+ this.logger(label, value);
883
+ } else {
884
+ this.logger(value);
796
885
  }
797
- else if (utils_1.isFunction(entity)) {
798
- return this.spawnCallback(entity, name);
886
+
887
+ break;
888
+
889
+ default:
890
+ if (!environment.IS_PRODUCTION) {
891
+ utils.warn(false, "No implementation found for action type '" + action.type + "'");
799
892
  }
800
- else if (Actor_1.isSpawnedActor(entity)) {
801
- return this.spawnActor(entity);
802
- }
803
- else if (utils_1.isObservable(entity)) {
804
- return this.spawnObservable(entity, name);
805
- }
806
- else if (utils_1.isMachine(entity)) {
807
- return this.spawnMachine(entity, __assign(__assign({}, options), { id: name }));
808
- }
809
- else if (utils_1.isBehavior(entity)) {
810
- return this.spawnBehavior(entity, name);
811
- }
812
- else {
813
- throw new Error("Unable to spawn entity \"" + name + "\" of type \"" + typeof entity + "\".");
814
- }
815
- };
816
- Interpreter.prototype.spawnMachine = function (machine, options) {
817
- var _this = this;
818
- if (options === void 0) { options = {}; }
819
- var childService = new Interpreter(machine, __assign(__assign({}, this.options), { parent: this, id: options.id || machine.id }));
820
- var resolvedOptions = __assign(__assign({}, DEFAULT_SPAWN_OPTIONS), options);
821
- if (resolvedOptions.sync) {
822
- childService.onTransition(function (state) {
823
- _this.send(actionTypes.update, {
824
- state: state,
825
- id: childService.id
826
- });
827
- });
828
- }
829
- var actor = childService;
830
- this.children.set(childService.id, actor);
831
- if (resolvedOptions.autoForward) {
832
- this.forwardTo.add(childService.id);
833
- }
834
- childService
835
- .onDone(function (doneEvent) {
836
- _this.removeChild(childService.id);
837
- _this.send(utils_1.toSCXMLEvent(doneEvent, { origin: childService.id }));
838
- })
839
- .start();
840
- return actor;
841
- };
842
- Interpreter.prototype.spawnBehavior = function (behavior, id) {
843
- var actorRef = behaviors_1.spawnBehavior(behavior, { id: id, parent: this });
844
- this.children.set(id, actorRef);
845
- return actorRef;
846
- };
847
- Interpreter.prototype.spawnPromise = function (promise, id) {
848
- var _this = this;
849
- var canceled = false;
850
- var resolvedData;
851
- promise.then(function (response) {
852
- if (!canceled) {
853
- resolvedData = response;
854
- _this.removeChild(id);
855
- _this.send(utils_1.toSCXMLEvent(actions_1.doneInvoke(id, response), { origin: id }));
856
- }
857
- }, function (errorData) {
858
- if (!canceled) {
859
- _this.removeChild(id);
860
- var errorEvent = actions_1.error(id, errorData);
861
- try {
862
- // Send "error.platform.id" to this (parent).
863
- _this.send(utils_1.toSCXMLEvent(errorEvent, { origin: id }));
864
- }
865
- catch (error) {
866
- utils_1.reportUnhandledExceptionOnInvocation(errorData, error, id);
867
- if (_this.devTools) {
868
- _this.devTools.send(errorEvent, _this.state);
869
- }
870
- if (_this.machine.strict) {
871
- // it would be better to always stop the state machine if unhandled
872
- // exception/promise rejection happens but because we don't want to
873
- // break existing code so enforce it on strict mode only especially so
874
- // because documentation says that onError is optional
875
- _this.stop();
876
- }
877
- }
878
- }
893
+
894
+ break;
895
+ }
896
+
897
+ return undefined;
898
+ };
899
+
900
+ Interpreter.prototype.removeChild = function (childId) {
901
+ this.children.delete(childId);
902
+ this.forwardTo.delete(childId);
903
+ delete this.state.children[childId];
904
+ };
905
+
906
+ Interpreter.prototype.stopChild = function (childId) {
907
+ var child = this.children.get(childId);
908
+
909
+ if (!child) {
910
+ return;
911
+ }
912
+
913
+ this.removeChild(childId);
914
+
915
+ if (utils.isFunction(child.stop)) {
916
+ child.stop();
917
+ }
918
+ };
919
+
920
+ Interpreter.prototype.spawn = function (entity, name, options) {
921
+ if (utils.isPromiseLike(entity)) {
922
+ return this.spawnPromise(Promise.resolve(entity), name);
923
+ } else if (utils.isFunction(entity)) {
924
+ return this.spawnCallback(entity, name);
925
+ } else if (Actor.isSpawnedActor(entity)) {
926
+ return this.spawnActor(entity, name);
927
+ } else if (utils.isObservable(entity)) {
928
+ return this.spawnObservable(entity, name);
929
+ } else if (utils.isMachine(entity)) {
930
+ return this.spawnMachine(entity, _tslib.__assign(_tslib.__assign({}, options), {
931
+ id: name
932
+ }));
933
+ } else if (utils.isBehavior(entity)) {
934
+ return this.spawnBehavior(entity, name);
935
+ } else {
936
+ throw new Error("Unable to spawn entity \"" + name + "\" of type \"" + typeof entity + "\".");
937
+ }
938
+ };
939
+
940
+ Interpreter.prototype.spawnMachine = function (machine, options) {
941
+ var _this = this;
942
+
943
+ if (options === void 0) {
944
+ options = {};
945
+ }
946
+
947
+ var childService = new Interpreter(machine, _tslib.__assign(_tslib.__assign({}, this.options), {
948
+ parent: this,
949
+ id: options.id || machine.id
950
+ }));
951
+
952
+ var resolvedOptions = _tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), options);
953
+
954
+ if (resolvedOptions.sync) {
955
+ childService.onTransition(function (state) {
956
+ _this.send(actionTypes.update, {
957
+ state: state,
958
+ id: childService.id
879
959
  });
880
- var actor = {
881
- id: id,
882
- send: function () { return void 0; },
883
- subscribe: function (next, handleError, complete) {
884
- var observer = utils_1.toObserver(next, handleError, complete);
885
- var unsubscribed = false;
886
- promise.then(function (response) {
887
- if (unsubscribed) {
888
- return;
889
- }
890
- observer.next(response);
891
- if (unsubscribed) {
892
- return;
893
- }
894
- observer.complete();
895
- }, function (err) {
896
- if (unsubscribed) {
897
- return;
898
- }
899
- observer.error(err);
900
- });
901
- return {
902
- unsubscribe: function () { return (unsubscribed = true); }
903
- };
904
- },
905
- stop: function () {
906
- canceled = true;
907
- },
908
- toJSON: function () {
909
- return { id: id };
910
- },
911
- getSnapshot: function () { return resolvedData; }
912
- };
913
- this.children.set(id, actor);
914
- return actor;
915
- };
916
- Interpreter.prototype.spawnCallback = function (callback, id) {
917
- var _this = this;
918
- var canceled = false;
919
- var receivers = new Set();
920
- var listeners = new Set();
921
- var emitted;
922
- var receive = function (e) {
923
- emitted = e;
924
- listeners.forEach(function (listener) { return listener(e); });
925
- if (canceled) {
926
- return;
927
- }
928
- _this.send(utils_1.toSCXMLEvent(e, { origin: id }));
929
- };
930
- var callbackStop;
960
+ });
961
+ }
962
+
963
+ var actor = childService;
964
+ this.children.set(childService.id, actor);
965
+
966
+ if (resolvedOptions.autoForward) {
967
+ this.forwardTo.add(childService.id);
968
+ }
969
+
970
+ childService.onDone(function (doneEvent) {
971
+ _this.removeChild(childService.id);
972
+
973
+ _this.send(utils.toSCXMLEvent(doneEvent, {
974
+ origin: childService.id
975
+ }));
976
+ }).start();
977
+ return actor;
978
+ };
979
+
980
+ Interpreter.prototype.spawnBehavior = function (behavior, id) {
981
+ var actorRef = behaviors.spawnBehavior(behavior, {
982
+ id: id,
983
+ parent: this
984
+ });
985
+ this.children.set(id, actorRef);
986
+ return actorRef;
987
+ };
988
+
989
+ Interpreter.prototype.spawnPromise = function (promise, id) {
990
+ var _this = this;
991
+
992
+ var canceled = false;
993
+ var resolvedData;
994
+ promise.then(function (response) {
995
+ if (!canceled) {
996
+ resolvedData = response;
997
+
998
+ _this.removeChild(id);
999
+
1000
+ _this.send(utils.toSCXMLEvent(actions.doneInvoke(id, response), {
1001
+ origin: id
1002
+ }));
1003
+ }
1004
+ }, function (errorData) {
1005
+ if (!canceled) {
1006
+ _this.removeChild(id);
1007
+
1008
+ var errorEvent = actions.error(id, errorData);
1009
+
931
1010
  try {
932
- callbackStop = callback(receive, function (newListener) {
933
- receivers.add(newListener);
934
- });
935
- }
936
- catch (err) {
937
- this.send(actions_1.error(id, err));
938
- }
939
- if (utils_1.isPromiseLike(callbackStop)) {
940
- // it turned out to be an async function, can't reliably check this before calling `callback`
941
- // because transpiled async functions are not recognizable
942
- return this.spawnPromise(callbackStop, id);
1011
+ // Send "error.platform.id" to this (parent).
1012
+ _this.send(utils.toSCXMLEvent(errorEvent, {
1013
+ origin: id
1014
+ }));
1015
+ } catch (error) {
1016
+ utils.reportUnhandledExceptionOnInvocation(errorData, error, id);
1017
+
1018
+ if (_this.devTools) {
1019
+ _this.devTools.send(errorEvent, _this.state);
1020
+ }
1021
+
1022
+ if (_this.machine.strict) {
1023
+ // it would be better to always stop the state machine if unhandled
1024
+ // exception/promise rejection happens but because we don't want to
1025
+ // break existing code so enforce it on strict mode only especially so
1026
+ // because documentation says that onError is optional
1027
+ _this.stop();
1028
+ }
943
1029
  }
944
- var actor = {
945
- id: id,
946
- send: function (event) { return receivers.forEach(function (receiver) { return receiver(event); }); },
947
- subscribe: function (next) {
948
- listeners.add(next);
949
- return {
950
- unsubscribe: function () {
951
- listeners.delete(next);
952
- }
953
- };
954
- },
955
- stop: function () {
956
- canceled = true;
957
- if (utils_1.isFunction(callbackStop)) {
958
- callbackStop();
959
- }
960
- },
961
- toJSON: function () {
962
- return { id: id };
963
- },
964
- getSnapshot: function () { return emitted; }
965
- };
966
- this.children.set(id, actor);
967
- return actor;
968
- };
969
- Interpreter.prototype.spawnObservable = function (source, id) {
970
- var _this = this;
971
- var emitted;
972
- var subscription = source.subscribe(function (value) {
973
- emitted = value;
974
- _this.send(utils_1.toSCXMLEvent(value, { origin: id }));
1030
+ }
1031
+ });
1032
+ var actor = {
1033
+ id: id,
1034
+ send: function () {
1035
+ return void 0;
1036
+ },
1037
+ subscribe: function (next, handleError, complete) {
1038
+ var observer = utils.toObserver(next, handleError, complete);
1039
+ var unsubscribed = false;
1040
+ promise.then(function (response) {
1041
+ if (unsubscribed) {
1042
+ return;
1043
+ }
1044
+
1045
+ observer.next(response);
1046
+
1047
+ if (unsubscribed) {
1048
+ return;
1049
+ }
1050
+
1051
+ observer.complete();
975
1052
  }, function (err) {
976
- _this.removeChild(id);
977
- _this.send(utils_1.toSCXMLEvent(actions_1.error(id, err), { origin: id }));
978
- }, function () {
979
- _this.removeChild(id);
980
- _this.send(utils_1.toSCXMLEvent(actions_1.doneInvoke(id), { origin: id }));
1053
+ if (unsubscribed) {
1054
+ return;
1055
+ }
1056
+
1057
+ observer.error(err);
981
1058
  });
982
- var actor = {
983
- id: id,
984
- send: function () { return void 0; },
985
- subscribe: function (next, handleError, complete) {
986
- return source.subscribe(next, handleError, complete);
987
- },
988
- stop: function () { return subscription.unsubscribe(); },
989
- getSnapshot: function () { return emitted; },
990
- toJSON: function () {
991
- return { id: id };
992
- }
1059
+ return {
1060
+ unsubscribe: function () {
1061
+ return unsubscribed = true;
1062
+ }
993
1063
  };
994
- this.children.set(id, actor);
995
- return actor;
996
- };
997
- Interpreter.prototype.spawnActor = function (actor) {
998
- this.children.set(actor.id, actor);
999
- return actor;
1064
+ },
1065
+ stop: function () {
1066
+ canceled = true;
1067
+ },
1068
+ toJSON: function () {
1069
+ return {
1070
+ id: id
1071
+ };
1072
+ },
1073
+ getSnapshot: function () {
1074
+ return resolvedData;
1075
+ }
1000
1076
  };
1001
- Interpreter.prototype.spawnActivity = function (activity) {
1002
- var implementation = this.machine.options && this.machine.options.activities
1003
- ? this.machine.options.activities[activity.type]
1004
- : undefined;
1005
- if (!implementation) {
1006
- if (!environment_1.IS_PRODUCTION) {
1007
- utils_1.warn(false, "No implementation found for activity '" + activity.type + "'");
1008
- }
1009
- // tslint:disable-next-line:no-console
1010
- return;
1011
- }
1012
- // Start implementation
1013
- var dispose = implementation(this.state.context, activity);
1014
- this.spawnEffect(activity.id, dispose);
1077
+ this.children.set(id, actor);
1078
+ return actor;
1079
+ };
1080
+
1081
+ Interpreter.prototype.spawnCallback = function (callback, id) {
1082
+ var _this = this;
1083
+
1084
+ var canceled = false;
1085
+ var receivers = new Set();
1086
+ var listeners = new Set();
1087
+ var emitted;
1088
+
1089
+ var receive = function (e) {
1090
+ emitted = e;
1091
+ listeners.forEach(function (listener) {
1092
+ return listener(e);
1093
+ });
1094
+
1095
+ if (canceled) {
1096
+ return;
1097
+ }
1098
+
1099
+ _this.send(utils.toSCXMLEvent(e, {
1100
+ origin: id
1101
+ }));
1015
1102
  };
1016
- Interpreter.prototype.spawnEffect = function (id, dispose) {
1017
- this.children.set(id, {
1018
- id: id,
1019
- send: function () { return void 0; },
1020
- subscribe: function () {
1021
- return { unsubscribe: function () { return void 0; } };
1022
- },
1023
- stop: dispose || undefined,
1024
- getSnapshot: function () { return undefined; },
1025
- toJSON: function () {
1026
- return { id: id };
1027
- }
1103
+
1104
+ var callbackStop;
1105
+
1106
+ try {
1107
+ callbackStop = callback(receive, function (newListener) {
1108
+ receivers.add(newListener);
1109
+ });
1110
+ } catch (err) {
1111
+ this.send(actions.error(id, err));
1112
+ }
1113
+
1114
+ if (utils.isPromiseLike(callbackStop)) {
1115
+ // it turned out to be an async function, can't reliably check this before calling `callback`
1116
+ // because transpiled async functions are not recognizable
1117
+ return this.spawnPromise(callbackStop, id);
1118
+ }
1119
+
1120
+ var actor = {
1121
+ id: id,
1122
+ send: function (event) {
1123
+ return receivers.forEach(function (receiver) {
1124
+ return receiver(event);
1028
1125
  });
1029
- };
1030
- Interpreter.prototype.attachDev = function () {
1031
- var global = devTools_1.getGlobal();
1032
- if (this.options.devTools && global) {
1033
- if (global.__REDUX_DEVTOOLS_EXTENSION__) {
1034
- var devToolsOptions = typeof this.options.devTools === 'object'
1035
- ? this.options.devTools
1036
- : undefined;
1037
- this.devTools = global.__REDUX_DEVTOOLS_EXTENSION__.connect(__assign(__assign({ name: this.id, autoPause: true, stateSanitizer: function (state) {
1038
- return {
1039
- value: state.value,
1040
- context: state.context,
1041
- actions: state.actions
1042
- };
1043
- } }, devToolsOptions), { features: __assign({ jump: false, skip: false }, (devToolsOptions
1044
- ? devToolsOptions.features
1045
- : undefined)) }), this.machine);
1046
- this.devTools.init(this.state);
1047
- }
1048
- // add XState-specific dev tooling hook
1049
- devTools_1.registerService(this);
1126
+ },
1127
+ subscribe: function (next) {
1128
+ listeners.add(next);
1129
+ return {
1130
+ unsubscribe: function () {
1131
+ listeners.delete(next);
1132
+ }
1133
+ };
1134
+ },
1135
+ stop: function () {
1136
+ canceled = true;
1137
+
1138
+ if (utils.isFunction(callbackStop)) {
1139
+ callbackStop();
1050
1140
  }
1141
+ },
1142
+ toJSON: function () {
1143
+ return {
1144
+ id: id
1145
+ };
1146
+ },
1147
+ getSnapshot: function () {
1148
+ return emitted;
1149
+ }
1051
1150
  };
1052
- Interpreter.prototype.toJSON = function () {
1151
+ this.children.set(id, actor);
1152
+ return actor;
1153
+ };
1154
+
1155
+ Interpreter.prototype.spawnObservable = function (source, id) {
1156
+ var _this = this;
1157
+
1158
+ var emitted;
1159
+ var subscription = source.subscribe(function (value) {
1160
+ emitted = value;
1161
+
1162
+ _this.send(utils.toSCXMLEvent(value, {
1163
+ origin: id
1164
+ }));
1165
+ }, function (err) {
1166
+ _this.removeChild(id);
1167
+
1168
+ _this.send(utils.toSCXMLEvent(actions.error(id, err), {
1169
+ origin: id
1170
+ }));
1171
+ }, function () {
1172
+ _this.removeChild(id);
1173
+
1174
+ _this.send(utils.toSCXMLEvent(actions.doneInvoke(id), {
1175
+ origin: id
1176
+ }));
1177
+ });
1178
+ var actor = {
1179
+ id: id,
1180
+ send: function () {
1181
+ return void 0;
1182
+ },
1183
+ subscribe: function (next, handleError, complete) {
1184
+ return source.subscribe(next, handleError, complete);
1185
+ },
1186
+ stop: function () {
1187
+ return subscription.unsubscribe();
1188
+ },
1189
+ getSnapshot: function () {
1190
+ return emitted;
1191
+ },
1192
+ toJSON: function () {
1053
1193
  return {
1054
- id: this.id
1194
+ id: id
1055
1195
  };
1196
+ }
1056
1197
  };
1057
- Interpreter.prototype[utils_1.symbolObservable] = function () {
1058
- return this;
1198
+ this.children.set(id, actor);
1199
+ return actor;
1200
+ };
1201
+
1202
+ Interpreter.prototype.spawnActor = function (actor, name) {
1203
+ this.children.set(name, actor);
1204
+ return actor;
1205
+ };
1206
+
1207
+ Interpreter.prototype.spawnActivity = function (activity) {
1208
+ var implementation = this.machine.options && this.machine.options.activities ? this.machine.options.activities[activity.type] : undefined;
1209
+
1210
+ if (!implementation) {
1211
+ if (!environment.IS_PRODUCTION) {
1212
+ utils.warn(false, "No implementation found for activity '" + activity.type + "'");
1213
+ } // tslint:disable-next-line:no-console
1214
+
1215
+
1216
+ return;
1217
+ } // Start implementation
1218
+
1219
+
1220
+ var dispose = implementation(this.state.context, activity);
1221
+ this.spawnEffect(activity.id, dispose);
1222
+ };
1223
+
1224
+ Interpreter.prototype.spawnEffect = function (id, dispose) {
1225
+ this.children.set(id, {
1226
+ id: id,
1227
+ send: function () {
1228
+ return void 0;
1229
+ },
1230
+ subscribe: function () {
1231
+ return {
1232
+ unsubscribe: function () {
1233
+ return void 0;
1234
+ }
1235
+ };
1236
+ },
1237
+ stop: dispose || undefined,
1238
+ getSnapshot: function () {
1239
+ return undefined;
1240
+ },
1241
+ toJSON: function () {
1242
+ return {
1243
+ id: id
1244
+ };
1245
+ }
1246
+ });
1247
+ };
1248
+
1249
+ Interpreter.prototype.attachDev = function () {
1250
+ var global = devTools.getGlobal();
1251
+
1252
+ if (this.options.devTools && global) {
1253
+ if (global.__REDUX_DEVTOOLS_EXTENSION__) {
1254
+ var devToolsOptions = typeof this.options.devTools === 'object' ? this.options.devTools : undefined;
1255
+ this.devTools = global.__REDUX_DEVTOOLS_EXTENSION__.connect(_tslib.__assign(_tslib.__assign({
1256
+ name: this.id,
1257
+ autoPause: true,
1258
+ stateSanitizer: function (state) {
1259
+ return {
1260
+ value: state.value,
1261
+ context: state.context,
1262
+ actions: state.actions
1263
+ };
1264
+ }
1265
+ }, devToolsOptions), {
1266
+ features: _tslib.__assign({
1267
+ jump: false,
1268
+ skip: false
1269
+ }, devToolsOptions ? devToolsOptions.features : undefined)
1270
+ }), this.machine);
1271
+ this.devTools.init(this.state);
1272
+ } // add XState-specific dev tooling hook
1273
+
1274
+
1275
+ devTools.registerService(this);
1276
+ }
1277
+ };
1278
+
1279
+ Interpreter.prototype.toJSON = function () {
1280
+ return {
1281
+ id: this.id
1059
1282
  };
1060
- Interpreter.prototype.getSnapshot = function () {
1061
- if (this.status === InterpreterStatus.NotStarted) {
1062
- return this.initialState;
1283
+ };
1284
+
1285
+ Interpreter.prototype[utils.symbolObservable] = function () {
1286
+ return this;
1287
+ }; // this gets stripped by Babel to avoid having "undefined" property in environments without this non-standard Symbol
1288
+ // it has to be here to be included in the generated .d.ts
1289
+
1290
+
1291
+ Interpreter.prototype.getSnapshot = function () {
1292
+ if (this.status === exports.InterpreterStatus.NotStarted) {
1293
+ return this.initialState;
1294
+ }
1295
+
1296
+ return this._state;
1297
+ };
1298
+ /**
1299
+ * The default interpreter options:
1300
+ *
1301
+ * - `clock` uses the global `setTimeout` and `clearTimeout` functions
1302
+ * - `logger` uses the global `console.log()` method
1303
+ */
1304
+
1305
+
1306
+ Interpreter.defaultOptions = /*#__PURE__*/function (global) {
1307
+ return {
1308
+ execute: true,
1309
+ deferEvents: true,
1310
+ clock: {
1311
+ setTimeout: function (fn, ms) {
1312
+ return setTimeout(fn, ms);
1313
+ },
1314
+ clearTimeout: function (id) {
1315
+ return clearTimeout(id);
1063
1316
  }
1064
- return this._state;
1317
+ },
1318
+ logger: global.console.log.bind(console),
1319
+ devTools: false
1065
1320
  };
1066
- /**
1067
- * The default interpreter options:
1068
- *
1069
- * - `clock` uses the global `setTimeout` and `clearTimeout` functions
1070
- * - `logger` uses the global `console.log()` method
1071
- */
1072
- Interpreter.defaultOptions = (function (global) { return ({
1073
- execute: true,
1074
- deferEvents: true,
1075
- clock: {
1076
- setTimeout: function (fn, ms) {
1077
- return setTimeout(fn, ms);
1078
- },
1079
- clearTimeout: function (id) {
1080
- return clearTimeout(id);
1081
- }
1082
- },
1083
- logger: global.console.log.bind(console),
1084
- devTools: false
1085
- }); })(typeof self !== 'undefined' ? self : global);
1086
- Interpreter.interpret = interpret;
1087
- return Interpreter;
1088
- }());
1089
- exports.Interpreter = Interpreter;
1321
+ }(typeof self !== 'undefined' ? self : global);
1322
+
1323
+ Interpreter.interpret = interpret;
1324
+ return Interpreter;
1325
+ }();
1326
+
1090
1327
  var resolveSpawnOptions = function (nameOrOptions) {
1091
- if (utils_1.isString(nameOrOptions)) {
1092
- return __assign(__assign({}, DEFAULT_SPAWN_OPTIONS), { name: nameOrOptions });
1093
- }
1094
- return __assign(__assign(__assign({}, DEFAULT_SPAWN_OPTIONS), { name: utils_1.uniqueId() }), nameOrOptions);
1328
+ if (utils.isString(nameOrOptions)) {
1329
+ return _tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), {
1330
+ name: nameOrOptions
1331
+ });
1332
+ }
1333
+
1334
+ return _tslib.__assign(_tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), {
1335
+ name: utils.uniqueId()
1336
+ }), nameOrOptions);
1095
1337
  };
1338
+
1096
1339
  function spawn(entity, nameOrOptions) {
1097
- var resolvedOptions = resolveSpawnOptions(nameOrOptions);
1098
- return serviceScope.consume(function (service) {
1099
- if (!environment_1.IS_PRODUCTION) {
1100
- var isLazyEntity = utils_1.isMachine(entity) || utils_1.isFunction(entity);
1101
- utils_1.warn(!!service || isLazyEntity, "Attempted to spawn an Actor (ID: \"" + (utils_1.isMachine(entity) ? entity.id : 'undefined') + "\") outside of a service. This will have no effect.");
1102
- }
1103
- if (service) {
1104
- return service.spawn(entity, resolvedOptions.name, resolvedOptions);
1105
- }
1106
- else {
1107
- return Actor_1.createDeferredActor(entity, resolvedOptions.name);
1108
- }
1109
- });
1340
+ var resolvedOptions = resolveSpawnOptions(nameOrOptions);
1341
+ return serviceScope.consume(function (service) {
1342
+ if (!environment.IS_PRODUCTION) {
1343
+ var isLazyEntity = utils.isMachine(entity) || utils.isFunction(entity);
1344
+ utils.warn(!!service || isLazyEntity, "Attempted to spawn an Actor (ID: \"" + (utils.isMachine(entity) ? entity.id : 'undefined') + "\") outside of a service. This will have no effect.");
1345
+ }
1346
+
1347
+ if (service) {
1348
+ return service.spawn(entity, resolvedOptions.name, resolvedOptions);
1349
+ } else {
1350
+ return Actor.createDeferredActor(entity, resolvedOptions.name);
1351
+ }
1352
+ });
1110
1353
  }
1111
- exports.spawn = spawn;
1112
- /**
1113
- * Creates a new Interpreter instance for the given machine with the provided options, if any.
1114
- *
1115
- * @param machine The machine to interpret
1116
- * @param options Interpreter options
1354
+ /**
1355
+ * Creates a new Interpreter instance for the given machine with the provided options, if any.
1356
+ *
1357
+ * @param machine The machine to interpret
1358
+ * @param options Interpreter options
1117
1359
  */
1360
+
1118
1361
  function interpret(machine, options) {
1119
- var interpreter = new Interpreter(machine, options);
1120
- return interpreter;
1362
+ var interpreter = new Interpreter(machine, options);
1363
+ return interpreter;
1121
1364
  }
1365
+
1366
+ exports.Interpreter = Interpreter;
1122
1367
  exports.interpret = interpret;
1368
+ exports.spawn = spawn;