xstate 4.10.0 → 4.14.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 (64) hide show
  1. package/CHANGELOG.md +205 -0
  2. package/LICENSE +22 -0
  3. package/README.md +2 -2
  4. package/dist/xstate.interpreter.js +1 -1
  5. package/dist/xstate.js +1 -1
  6. package/dist/xstate.web.js +2 -2
  7. package/es/Actor.d.ts +5 -3
  8. package/es/Actor.js +26 -4
  9. package/es/State.d.ts +5 -2
  10. package/es/StateNode.d.ts +8 -8
  11. package/es/StateNode.js +61 -41
  12. package/es/actions.d.ts +9 -5
  13. package/es/actions.js +28 -13
  14. package/es/index.d.ts +2 -2
  15. package/es/index.js +1 -1
  16. package/es/interpreter.d.ts +29 -15
  17. package/es/interpreter.js +99 -112
  18. package/es/invokeUtils.d.ts +7 -0
  19. package/es/invokeUtils.js +39 -0
  20. package/es/match.d.ts +4 -1
  21. package/es/serviceScope.d.ts +10 -0
  22. package/es/serviceScope.js +18 -0
  23. package/es/stateUtils.d.ts +1 -1
  24. package/es/types.d.ts +79 -32
  25. package/es/utils.d.ts +4 -3
  26. package/es/utils.js +12 -3
  27. package/lib/Actor.d.ts +5 -3
  28. package/lib/Actor.js +24 -3
  29. package/lib/Machine.js +1 -0
  30. package/lib/SimulatedClock.js +1 -0
  31. package/lib/State.d.ts +5 -2
  32. package/lib/State.js +1 -0
  33. package/lib/StateNode.d.ts +8 -8
  34. package/lib/StateNode.js +69 -42
  35. package/lib/actionTypes.js +1 -0
  36. package/lib/actions.d.ts +9 -5
  37. package/lib/actions.js +27 -19
  38. package/lib/constants.js +1 -0
  39. package/lib/devTools.js +1 -0
  40. package/lib/each.js +1 -0
  41. package/lib/environment.js +1 -0
  42. package/lib/index.d.ts +2 -2
  43. package/lib/index.js +29 -20
  44. package/lib/interpreter.d.ts +28 -14
  45. package/lib/interpreter.js +82 -88
  46. package/lib/invokeUtils.d.ts +7 -0
  47. package/lib/invokeUtils.js +42 -0
  48. package/lib/json.js +1 -0
  49. package/lib/mapState.js +1 -0
  50. package/lib/match.d.ts +4 -1
  51. package/lib/match.js +1 -0
  52. package/lib/patterns.js +1 -0
  53. package/lib/registry.js +1 -0
  54. package/lib/scheduler.js +1 -0
  55. package/lib/scxml.js +1 -0
  56. package/lib/serviceScope.d.ts +10 -0
  57. package/lib/serviceScope.js +15 -0
  58. package/lib/stateUtils.d.ts +1 -1
  59. package/lib/stateUtils.js +1 -0
  60. package/lib/types.d.ts +79 -32
  61. package/lib/types.js +1 -0
  62. package/lib/utils.d.ts +4 -3
  63. package/lib/utils.js +9 -2
  64. package/package.json +6 -6
@@ -1,7 +1,10 @@
1
- import { StateMachine, Event, EventObject, DefaultContext, StateSchema, StateValue, InterpreterOptions, DoneEvent, Unsubscribable, MachineOptions, SCXML, EventData, Observer, Spawnable, Typestate } from './types';
1
+ import { StateMachine, Event, EventObject, DefaultContext, StateSchema, StateValue, InterpreterOptions, SingleOrArray, 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, TStateSchema extends StateSchema<TContext> = any, TTypestate extends Typestate<TContext> = any> = (state: State<TContext, TEvent, TStateSchema, TTypestate>, event: TEvent) => void;
4
+ export declare type StateListener<TContext, TEvent extends EventObject, TStateSchema extends StateSchema<TContext> = any, TTypestate extends Typestate<TContext> = {
5
+ value: any;
6
+ context: TContext;
7
+ }> = (state: State<TContext, TEvent, TStateSchema, TTypestate>, event: TEvent) => void;
5
8
  export declare type ContextListener<TContext = DefaultContext> = (context: TContext, prevContext: TContext | undefined) => void;
6
9
  export declare type EventListener<TEvent extends EventObject = EventObject> = (event: TEvent) => void;
7
10
  export declare type Listener = () => void;
@@ -14,7 +17,15 @@ interface SpawnOptions {
14
17
  autoForward?: boolean;
15
18
  sync?: boolean;
16
19
  }
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> {
20
+ export declare enum InterpreterStatus {
21
+ NotStarted = 0,
22
+ Running = 1,
23
+ Stopped = 2
24
+ }
25
+ export declare class Interpreter<TContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = {
26
+ value: any;
27
+ context: TContext;
28
+ }> implements Actor<State<TContext, TEvent, TStateSchema, TTypestate>, TEvent> {
18
29
  machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>;
19
30
  /**
20
31
  * The default interpreter options:
@@ -46,7 +57,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
46
57
  * Whether the service is started.
47
58
  */
48
59
  initialized: boolean;
49
- private _status;
60
+ status: InterpreterStatus;
50
61
  parent?: Interpreter<any>;
51
62
  id: string;
52
63
  /**
@@ -81,32 +92,32 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
81
92
  * Adds an event listener that is notified whenever an event is sent to the running interpreter.
82
93
  * @param listener The event listener
83
94
  */
84
- onEvent(listener: EventListener): Interpreter<TContext, TStateSchema, TEvent>;
95
+ onEvent(listener: EventListener): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
85
96
  /**
86
97
  * Adds an event listener that is notified whenever a `send` event occurs.
87
98
  * @param listener The event listener
88
99
  */
89
- onSend(listener: EventListener): Interpreter<TContext, TStateSchema, TEvent>;
100
+ onSend(listener: EventListener): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
90
101
  /**
91
102
  * Adds a context listener that is notified whenever the state context changes.
92
103
  * @param listener The context listener
93
104
  */
94
- onChange(listener: ContextListener<TContext>): Interpreter<TContext, TStateSchema, TEvent>;
105
+ onChange(listener: ContextListener<TContext>): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
95
106
  /**
96
107
  * Adds a listener that is notified when the machine is stopped.
97
108
  * @param listener The listener
98
109
  */
99
- onStop(listener: Listener): Interpreter<TContext, TStateSchema, TEvent>;
110
+ onStop(listener: Listener): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
100
111
  /**
101
112
  * Adds a state listener that is notified when the statechart has reached its final state.
102
113
  * @param listener The state listener
103
114
  */
104
- onDone(listener: EventListener<DoneEvent>): Interpreter<TContext, TStateSchema, TEvent>;
115
+ onDone(listener: EventListener<DoneEvent>): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
105
116
  /**
106
117
  * Removes a listener.
107
118
  * @param listener The listener to remove
108
119
  */
109
- off(listener: (...args: any[]) => void): Interpreter<TContext, TStateSchema, TEvent>;
120
+ off(listener: (...args: any[]) => void): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
110
121
  /**
111
122
  * Alias for Interpreter.prototype.start
112
123
  */
@@ -121,7 +132,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
121
132
  *
122
133
  * This will also notify the `onStop` listeners.
123
134
  */
124
- stop(): Interpreter<TContext, TStateSchema, TEvent>;
135
+ stop(): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
125
136
  /**
126
137
  * Sends an event to the running interpreter to trigger a transition.
127
138
  *
@@ -131,7 +142,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
131
142
  *
132
143
  * @param event The event(s) to send
133
144
  */
134
- send: (event: TEvent | TEvent["type"] | Event<TEvent>[] | SCXML.Event<TEvent>, payload?: EventData | undefined) => State<TContext, TEvent, TStateSchema, TTypestate>;
145
+ send: (event: SingleOrArray<Event<TEvent>> | SCXML.Event<TEvent>, payload?: EventData | undefined) => State<TContext, TEvent, TStateSchema, TTypestate>;
135
146
  private batch;
136
147
  /**
137
148
  * Returns a send function bound to this interpreter instance.
@@ -171,7 +182,7 @@ export declare class Interpreter<TContext, TStateSchema extends StateSchema = an
171
182
  id: string;
172
183
  };
173
184
  }
174
- export declare function spawn<TC, TE extends EventObject>(entity: StateMachine<TC, any, TE>, nameOrOptions?: string | SpawnOptions): Interpreter<TC, any, TE>;
185
+ export declare function spawn<TC, TE extends EventObject>(entity: StateMachine<TC, any, TE>, nameOrOptions?: string | SpawnOptions): Actor<State<TC, TE>, TE>;
175
186
  export declare function spawn(entity: Spawnable, nameOrOptions?: string | SpawnOptions): Actor;
176
187
  /**
177
188
  * Creates a new Interpreter instance for the given machine with the provided options, if any.
@@ -179,6 +190,9 @@ export declare function spawn(entity: Spawnable, nameOrOptions?: string | SpawnO
179
190
  * @param machine The machine to interpret
180
191
  * @param options Interpreter options
181
192
  */
182
- export declare function interpret<TContext = DefaultContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = any>(machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>, options?: Partial<InterpreterOptions>): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
193
+ export declare function interpret<TContext = DefaultContext, TStateSchema extends StateSchema = any, TEvent extends EventObject = EventObject, TTypestate extends Typestate<TContext> = {
194
+ value: any;
195
+ context: TContext;
196
+ }>(machine: StateMachine<TContext, TStateSchema, TEvent, TTypestate>, options?: Partial<InterpreterOptions>): Interpreter<TContext, TStateSchema, TEvent, TTypestate>;
183
197
  export {};
184
198
  //# sourceMappingURL=interpreter.d.ts.map
@@ -42,6 +42,7 @@ var __spread = (this && this.__spread) || function () {
42
42
  return ar;
43
43
  };
44
44
  Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.interpret = exports.spawn = exports.Interpreter = exports.InterpreterStatus = void 0;
45
46
  var types_1 = require("./types");
46
47
  var State_1 = require("./State");
47
48
  var actionTypes = require("./actionTypes");
@@ -53,28 +54,14 @@ var Actor_1 = require("./Actor");
53
54
  var stateUtils_1 = require("./stateUtils");
54
55
  var registry_1 = require("./registry");
55
56
  var devTools_1 = require("./devTools");
57
+ var serviceScope = require("./serviceScope");
56
58
  var DEFAULT_SPAWN_OPTIONS = { sync: false, autoForward: false };
57
- /**
58
- * Maintains a stack of the current service in scope.
59
- * This is used to provide the correct service to spawn().
60
- *
61
- * @private
62
- */
63
- var withServiceScope = (function () {
64
- var serviceStack = [];
65
- return function (service, fn) {
66
- service && serviceStack.push(service);
67
- var result = fn(service || serviceStack[serviceStack.length - 1]);
68
- service && serviceStack.pop();
69
- return result;
70
- };
71
- })();
72
59
  var InterpreterStatus;
73
60
  (function (InterpreterStatus) {
74
61
  InterpreterStatus[InterpreterStatus["NotStarted"] = 0] = "NotStarted";
75
62
  InterpreterStatus[InterpreterStatus["Running"] = 1] = "Running";
76
63
  InterpreterStatus[InterpreterStatus["Stopped"] = 2] = "Stopped";
77
- })(InterpreterStatus || (InterpreterStatus = {}));
64
+ })(InterpreterStatus = exports.InterpreterStatus || (exports.InterpreterStatus = {}));
78
65
  var Interpreter = /** @class */ (function () {
79
66
  /**
80
67
  * Creates a new Interpreter instance (i.e., service) for the given machine with the provided options, if any.
@@ -98,7 +85,7 @@ var Interpreter = /** @class */ (function () {
98
85
  * Whether the service is started.
99
86
  */
100
87
  this.initialized = false;
101
- this._status = InterpreterStatus.NotStarted;
88
+ this.status = InterpreterStatus.NotStarted;
102
89
  this.children = new Map();
103
90
  this.forwardTo = new Set();
104
91
  /**
@@ -120,21 +107,15 @@ var Interpreter = /** @class */ (function () {
120
107
  return _this.state;
121
108
  }
122
109
  var _event = utils_1.toSCXMLEvent(utils_1.toEventObject(event, payload));
123
- if (_this._status === InterpreterStatus.Stopped) {
110
+ if (_this.status === InterpreterStatus.Stopped) {
124
111
  // do nothing
125
112
  if (!environment_1.IS_PRODUCTION) {
126
113
  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));
127
114
  }
128
115
  return _this.state;
129
116
  }
130
- if (_this._status === InterpreterStatus.NotStarted &&
131
- _this.options.deferEvents) {
132
- // tslint:disable-next-line:no-console
133
- if (!environment_1.IS_PRODUCTION) {
134
- utils_1.warn(false, "Event \"" + _event.name + "\" was sent to uninitialized service \"" + _this.machine.id + "\" and is deferred. Make sure .start() is called for this service.\nEvent: " + JSON.stringify(_event.data));
135
- }
136
- }
137
- else if (_this._status !== InterpreterStatus.Running) {
117
+ if (_this.status !== InterpreterStatus.Running &&
118
+ !_this.options.deferEvents) {
138
119
  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));
139
120
  }
140
121
  _this.scheduler.schedule(function () {
@@ -191,22 +172,22 @@ var Interpreter = /** @class */ (function () {
191
172
  if (this._initialState) {
192
173
  return this._initialState;
193
174
  }
194
- return withServiceScope(this, function () {
175
+ return serviceScope.provide(this, function () {
195
176
  _this._initialState = _this.machine.initialState;
196
177
  return _this._initialState;
197
178
  });
198
179
  },
199
- enumerable: true,
180
+ enumerable: false,
200
181
  configurable: true
201
182
  });
202
183
  Object.defineProperty(Interpreter.prototype, "state", {
203
184
  get: function () {
204
185
  if (!environment_1.IS_PRODUCTION) {
205
- utils_1.warn(this._status !== InterpreterStatus.NotStarted, "Attempted to read state from uninitialized service '" + this.id + "'. Make sure the service is started first.");
186
+ utils_1.warn(this.status !== InterpreterStatus.NotStarted, "Attempted to read state from uninitialized service '" + this.id + "'. Make sure the service is started first.");
206
187
  }
207
188
  return this._state;
208
189
  },
209
- enumerable: true,
190
+ enumerable: false,
210
191
  configurable: true
211
192
  });
212
193
  /**
@@ -242,6 +223,10 @@ var Interpreter = /** @class */ (function () {
242
223
  if (this.options.execute) {
243
224
  this.execute(this.state);
244
225
  }
226
+ // Update children
227
+ this.children.forEach(function (child) {
228
+ _this.state.children[child.id] = child;
229
+ });
245
230
  // Dev tools
246
231
  if (this.devTools) {
247
232
  this.devTools.send(_event.data, state);
@@ -290,10 +275,27 @@ var Interpreter = /** @class */ (function () {
290
275
  }
291
276
  var isDone = stateUtils_1.isInFinalState(state.configuration || [], this.machine);
292
277
  if (this.state.configuration && isDone) {
278
+ // exit interpreter procedure: https://www.w3.org/TR/scxml/#exitInterpreter
279
+ this.state.configuration.forEach(function (stateNode) {
280
+ var e_6, _a;
281
+ try {
282
+ for (var _b = __values(stateNode.definition.exit), _c = _b.next(); !_c.done; _c = _b.next()) {
283
+ var action = _c.value;
284
+ _this.exec(action, state);
285
+ }
286
+ }
287
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
288
+ finally {
289
+ try {
290
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
291
+ }
292
+ finally { if (e_6) throw e_6.error; }
293
+ }
294
+ });
293
295
  // get final child state node
294
296
  var finalChildStateNode = state.configuration.find(function (sn) { return sn.type === 'final' && sn.parent === _this.machine; });
295
- var doneData = finalChildStateNode && finalChildStateNode.data
296
- ? utils_1.mapContext(finalChildStateNode.data, state.context, _event)
297
+ var doneData = finalChildStateNode && finalChildStateNode.doneData
298
+ ? utils_1.mapContext(finalChildStateNode.doneData, state.context, _event)
297
299
  : undefined;
298
300
  try {
299
301
  for (var _l = __values(this.doneListeners), _m = _l.next(); !_m.done; _m = _l.next()) {
@@ -320,14 +322,13 @@ var Interpreter = /** @class */ (function () {
320
322
  Interpreter.prototype.onTransition = function (listener) {
321
323
  this.listeners.add(listener);
322
324
  // Send current state to listener
323
- if (this._status === InterpreterStatus.Running) {
325
+ if (this.status === InterpreterStatus.Running) {
324
326
  listener(this.state, this.state.event);
325
327
  }
326
328
  return this;
327
329
  };
328
- Interpreter.prototype.subscribe = function (nextListenerOrObserver,
329
- // @ts-ignore
330
- errorListener, completeListener) {
330
+ Interpreter.prototype.subscribe = function (nextListenerOrObserver, _, // TODO: error listener
331
+ completeListener) {
331
332
  var _this = this;
332
333
  if (!nextListenerOrObserver) {
333
334
  return { unsubscribe: function () { return void 0; } };
@@ -343,7 +344,7 @@ var Interpreter = /** @class */ (function () {
343
344
  }
344
345
  this.listeners.add(listener);
345
346
  // Send current state to listener
346
- if (this._status === InterpreterStatus.Running) {
347
+ if (this.status === InterpreterStatus.Running) {
347
348
  listener(this.state);
348
349
  }
349
350
  if (resolvedCompleteListener) {
@@ -416,16 +417,16 @@ var Interpreter = /** @class */ (function () {
416
417
  */
417
418
  Interpreter.prototype.start = function (initialState) {
418
419
  var _this = this;
419
- if (this._status === InterpreterStatus.Running) {
420
+ if (this.status === InterpreterStatus.Running) {
420
421
  // Do not restart the service if it is already started
421
422
  return this;
422
423
  }
423
424
  registry_1.registry.register(this.sessionId, this);
424
425
  this.initialized = true;
425
- this._status = InterpreterStatus.Running;
426
+ this.status = InterpreterStatus.Running;
426
427
  var resolvedState = initialState === undefined
427
428
  ? this.initialState
428
- : withServiceScope(this, function () {
429
+ : serviceScope.provide(this, function () {
429
430
  return State_1.isState(initialState)
430
431
  ? _this.machine.resolveState(initialState)
431
432
  : _this.machine.resolveState(State_1.State.from(initialState, _this.machine.context));
@@ -444,19 +445,19 @@ var Interpreter = /** @class */ (function () {
444
445
  * This will also notify the `onStop` listeners.
445
446
  */
446
447
  Interpreter.prototype.stop = function () {
447
- var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e;
448
+ var e_7, _a, e_8, _b, e_9, _c, e_10, _d, e_11, _e;
448
449
  try {
449
450
  for (var _f = __values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
450
451
  var listener = _g.value;
451
452
  this.listeners.delete(listener);
452
453
  }
453
454
  }
454
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
455
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
455
456
  finally {
456
457
  try {
457
458
  if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
458
459
  }
459
- finally { if (e_6) throw e_6.error; }
460
+ finally { if (e_7) throw e_7.error; }
460
461
  }
461
462
  try {
462
463
  for (var _h = __values(this.stopListeners), _j = _h.next(); !_j.done; _j = _h.next()) {
@@ -466,12 +467,12 @@ var Interpreter = /** @class */ (function () {
466
467
  this.stopListeners.delete(listener);
467
468
  }
468
469
  }
469
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
470
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
470
471
  finally {
471
472
  try {
472
473
  if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
473
474
  }
474
- finally { if (e_7) throw e_7.error; }
475
+ finally { if (e_8) throw e_8.error; }
475
476
  }
476
477
  try {
477
478
  for (var _k = __values(this.contextListeners), _l = _k.next(); !_l.done; _l = _k.next()) {
@@ -479,12 +480,12 @@ var Interpreter = /** @class */ (function () {
479
480
  this.contextListeners.delete(listener);
480
481
  }
481
482
  }
482
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
483
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
483
484
  finally {
484
485
  try {
485
486
  if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
486
487
  }
487
- finally { if (e_8) throw e_8.error; }
488
+ finally { if (e_9) throw e_9.error; }
488
489
  }
489
490
  try {
490
491
  for (var _m = __values(this.doneListeners), _o = _m.next(); !_o.done; _o = _m.next()) {
@@ -492,12 +493,12 @@ var Interpreter = /** @class */ (function () {
492
493
  this.doneListeners.delete(listener);
493
494
  }
494
495
  }
495
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
496
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
496
497
  finally {
497
498
  try {
498
499
  if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
499
500
  }
500
- finally { if (e_9) throw e_9.error; }
501
+ finally { if (e_10) throw e_10.error; }
501
502
  }
502
503
  // Stop all children
503
504
  this.children.forEach(function (child) {
@@ -512,42 +513,42 @@ var Interpreter = /** @class */ (function () {
512
513
  this.clock.clearTimeout(this.delayedEventsMap[key]);
513
514
  }
514
515
  }
515
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
516
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
516
517
  finally {
517
518
  try {
518
519
  if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
519
520
  }
520
- finally { if (e_10) throw e_10.error; }
521
+ finally { if (e_11) throw e_11.error; }
521
522
  }
522
523
  this.scheduler.clear();
523
524
  this.initialized = false;
524
- this._status = InterpreterStatus.Stopped;
525
+ this.status = InterpreterStatus.Stopped;
525
526
  registry_1.registry.free(this.sessionId);
526
527
  return this;
527
528
  };
528
529
  Interpreter.prototype.batch = function (events) {
529
530
  var _this = this;
530
- if (this._status === InterpreterStatus.NotStarted &&
531
+ if (this.status === InterpreterStatus.NotStarted &&
531
532
  this.options.deferEvents) {
532
533
  // tslint:disable-next-line:no-console
533
534
  if (!environment_1.IS_PRODUCTION) {
534
535
  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));
535
536
  }
536
537
  }
537
- else if (this._status !== InterpreterStatus.Running) {
538
+ else if (this.status !== InterpreterStatus.Running) {
538
539
  throw new Error(
539
540
  // tslint:disable-next-line:max-line-length
540
541
  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.");
541
542
  }
542
543
  this.scheduler.schedule(function () {
543
- var e_11, _a;
544
+ var e_12, _a;
544
545
  var nextState = _this.state;
545
546
  var batchChanged = false;
546
547
  var batchedActions = [];
547
548
  var _loop_1 = function (event_1) {
548
549
  var _event = utils_1.toSCXMLEvent(event_1);
549
550
  _this.forward(_event);
550
- nextState = withServiceScope(_this, function () {
551
+ nextState = serviceScope.provide(_this, function () {
551
552
  return _this.machine.transition(nextState, _event);
552
553
  });
553
554
  batchedActions.push.apply(batchedActions, __spread(nextState.actions.map(function (a) {
@@ -561,12 +562,12 @@ var Interpreter = /** @class */ (function () {
561
562
  _loop_1(event_1);
562
563
  }
563
564
  }
564
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
565
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
565
566
  finally {
566
567
  try {
567
568
  if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
568
569
  }
569
- finally { if (e_11) throw e_11.error; }
570
+ finally { if (e_12) throw e_12.error; }
570
571
  }
571
572
  nextState.changed = batchChanged;
572
573
  nextState.actions = batchedActions;
@@ -595,13 +596,13 @@ var Interpreter = /** @class */ (function () {
595
596
  !this.state.nextEvents.some(function (nextEvent) { return nextEvent.indexOf(actionTypes.errorPlatform) === 0; })) {
596
597
  throw _event.data.data;
597
598
  }
598
- var nextState = withServiceScope(this, function () {
599
+ var nextState = serviceScope.provide(this, function () {
599
600
  return _this.machine.transition(_this.state, _event);
600
601
  });
601
602
  return nextState;
602
603
  };
603
604
  Interpreter.prototype.forward = function (event) {
604
- var e_12, _a;
605
+ var e_13, _a;
605
606
  try {
606
607
  for (var _b = __values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
607
608
  var id = _c.value;
@@ -612,12 +613,12 @@ var Interpreter = /** @class */ (function () {
612
613
  child.send(event);
613
614
  }
614
615
  }
615
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
616
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
616
617
  finally {
617
618
  try {
618
619
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
619
620
  }
620
- finally { if (e_12) throw e_12.error; }
621
+ finally { if (e_13) throw e_13.error; }
621
622
  }
622
623
  };
623
624
  Interpreter.prototype.defer = function (sendAction) {
@@ -693,9 +694,9 @@ var Interpreter = /** @class */ (function () {
693
694
  }
694
695
  // Invoked services
695
696
  if (activity.type === types_1.ActionTypes.Invoke) {
696
- var serviceCreator = this
697
- .machine.options.services
698
- ? this.machine.options.services[activity.src]
697
+ var invokeSource = utils_1.toInvokeSource(activity.src);
698
+ var serviceCreator = this.machine.options.services
699
+ ? this.machine.options.services[invokeSource.type]
699
700
  : undefined;
700
701
  var id = activity.id, data = activity.data;
701
702
  if (!environment_1.IS_PRODUCTION) {
@@ -714,23 +715,27 @@ var Interpreter = /** @class */ (function () {
714
715
  }
715
716
  return;
716
717
  }
718
+ var resolvedData = data
719
+ ? utils_1.mapContext(data, context, _event)
720
+ : undefined;
717
721
  var source = utils_1.isFunction(serviceCreator)
718
- ? serviceCreator(context, _event.data)
722
+ ? serviceCreator(context, _event.data, {
723
+ data: resolvedData,
724
+ src: invokeSource
725
+ })
719
726
  : serviceCreator;
720
727
  if (utils_1.isPromiseLike(source)) {
721
- this.state.children[id] = this.spawnPromise(Promise.resolve(source), id);
728
+ this.spawnPromise(Promise.resolve(source), id);
722
729
  }
723
730
  else if (utils_1.isFunction(source)) {
724
- this.state.children[id] = this.spawnCallback(source, id);
731
+ this.spawnCallback(source, id);
725
732
  }
726
733
  else if (utils_1.isObservable(source)) {
727
- this.state.children[id] = this.spawnObservable(source, id);
734
+ this.spawnObservable(source, id);
728
735
  }
729
736
  else if (utils_1.isMachine(source)) {
730
737
  // TODO: try/catch here
731
- this.state.children[id] = this.spawnMachine(data
732
- ? source.withContext(utils_1.mapContext(data, context, _event))
733
- : source, {
738
+ this.spawnMachine(resolvedData ? source.withContext(resolvedData) : source, {
734
739
  id: id,
735
740
  autoForward: autoForward
736
741
  });
@@ -1046,23 +1051,11 @@ var Interpreter = /** @class */ (function () {
1046
1051
  },
1047
1052
  logger: global.console.log.bind(console),
1048
1053
  devTools: false
1049
- }); })(typeof window === 'undefined' ? global : window);
1054
+ }); })(typeof self !== 'undefined' ? self : global);
1050
1055
  Interpreter.interpret = interpret;
1051
1056
  return Interpreter;
1052
1057
  }());
1053
1058
  exports.Interpreter = Interpreter;
1054
- var createNullActor = function (name) {
1055
- if (name === void 0) { name = 'null'; }
1056
- return ({
1057
- id: name,
1058
- send: function () { return void 0; },
1059
- subscribe: function () {
1060
- // tslint:disable-next-line:no-empty
1061
- return { unsubscribe: function () { } };
1062
- },
1063
- toJSON: function () { return ({ id: name }); }
1064
- });
1065
- };
1066
1059
  var resolveSpawnOptions = function (nameOrOptions) {
1067
1060
  if (utils_1.isString(nameOrOptions)) {
1068
1061
  return __assign(__assign({}, DEFAULT_SPAWN_OPTIONS), { name: nameOrOptions });
@@ -1071,15 +1064,16 @@ var resolveSpawnOptions = function (nameOrOptions) {
1071
1064
  };
1072
1065
  function spawn(entity, nameOrOptions) {
1073
1066
  var resolvedOptions = resolveSpawnOptions(nameOrOptions);
1074
- return withServiceScope(undefined, function (service) {
1067
+ return serviceScope.consume(function (service) {
1075
1068
  if (!environment_1.IS_PRODUCTION) {
1076
- utils_1.warn(!!service, "Attempted to spawn an Actor (ID: \"" + (utils_1.isMachine(entity) ? entity.id : 'undefined') + "\") outside of a service. This will have no effect.");
1069
+ var isLazyEntity = utils_1.isMachine(entity) || utils_1.isFunction(entity);
1070
+ 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.");
1077
1071
  }
1078
1072
  if (service) {
1079
1073
  return service.spawn(entity, resolvedOptions.name, resolvedOptions);
1080
1074
  }
1081
1075
  else {
1082
- return createNullActor(resolvedOptions.name);
1076
+ return Actor_1.createDeferredActor(entity, resolvedOptions.name);
1083
1077
  }
1084
1078
  });
1085
1079
  }
@@ -0,0 +1,7 @@
1
+ import { EventObject, InvokeConfig, InvokeDefinition, InvokeSourceDefinition } from './types';
2
+ export declare function toInvokeSource(src: string | InvokeSourceDefinition): InvokeSourceDefinition;
3
+ export declare function toInvokeDefinition<TContext, TEvent extends EventObject>(invokeConfig: InvokeConfig<TContext, TEvent> & {
4
+ src: string | InvokeSourceDefinition;
5
+ id: string;
6
+ }): InvokeDefinition<TContext, TEvent>;
7
+ //# sourceMappingURL=invokeUtils.d.ts.map
@@ -0,0 +1,42 @@
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 __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ Object.defineProperty(exports, "__esModule", { value: true });
25
+ exports.toInvokeDefinition = exports.toInvokeSource = void 0;
26
+ var actions_1 = require("./actions");
27
+ function toInvokeSource(src) {
28
+ if (typeof src === 'string') {
29
+ var simpleSrc = { type: src };
30
+ simpleSrc.toString = function () { return src; }; // v4 compat - TODO: remove in v5
31
+ return simpleSrc;
32
+ }
33
+ return src;
34
+ }
35
+ exports.toInvokeSource = toInvokeSource;
36
+ function toInvokeDefinition(invokeConfig) {
37
+ return __assign(__assign({ type: actions_1.actionTypes.invoke }, invokeConfig), { toJSON: function () {
38
+ var onDone = invokeConfig.onDone, onError = invokeConfig.onError, invokeDef = __rest(invokeConfig, ["onDone", "onError"]);
39
+ return __assign(__assign({}, invokeDef), { type: actions_1.actionTypes.invoke, src: toInvokeSource(invokeConfig.src) });
40
+ } });
41
+ }
42
+ exports.toInvokeDefinition = toInvokeDefinition;
package/lib/json.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.jsonify = exports.parse = exports.stringify = exports.machineToJSON = exports.stringifyFunction = void 0;
3
4
  var utils_1 = require("./utils");
4
5
  // tslint:disable-next-line:ban-types
5
6
  function stringifyFunction(fn) {
package/lib/mapState.js CHANGED
@@ -11,6 +11,7 @@ var __values = (this && this.__values) || function(o) {
11
11
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.mapState = void 0;
14
15
  var utils_1 = require("./utils");
15
16
  function mapState(stateMap, stateId) {
16
17
  var e_1, _a;
package/lib/match.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { State } from './State';
2
2
  import { StateValue, EventObject } from './types';
3
3
  export declare type ValueFromStateGetter<T, TContext, TEvent extends EventObject> = (state: State<TContext, TEvent>) => T;
4
- export declare type StatePatternTuple<T, TContext, TEvent extends EventObject> = [StateValue, ValueFromStateGetter<T, TContext, TEvent>];
4
+ export declare type StatePatternTuple<T, TContext, TEvent extends EventObject> = [
5
+ StateValue,
6
+ ValueFromStateGetter<T, TContext, TEvent>
7
+ ];
5
8
  export declare function matchState<T, TContext, TEvent extends EventObject>(state: State<TContext, TEvent> | StateValue, patterns: Array<StatePatternTuple<T, TContext, TEvent>>, defaultValue: ValueFromStateGetter<T, TContext, TEvent>): T;
6
9
  //# sourceMappingURL=match.d.ts.map
package/lib/match.js CHANGED
@@ -27,6 +27,7 @@ var __read = (this && this.__read) || function (o, n) {
27
27
  return ar;
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
+ exports.matchState = void 0;
30
31
  var State_1 = require("./State");
31
32
  function matchState(state, patterns, defaultValue) {
32
33
  var e_1, _a;
package/lib/patterns.js CHANGED
@@ -11,6 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.sequence = exports.toggle = void 0;
14
15
  var utils_1 = require("./utils");
15
16
  function toggle(onState, offState, eventType) {
16
17
  var _a, _b, _c;