xstate 4.13.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.
@@ -42,7 +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 = void 0;
45
+ exports.interpret = exports.spawn = exports.Interpreter = exports.InterpreterStatus = void 0;
46
46
  var types_1 = require("./types");
47
47
  var State_1 = require("./State");
48
48
  var actionTypes = require("./actionTypes");
@@ -61,7 +61,7 @@ var InterpreterStatus;
61
61
  InterpreterStatus[InterpreterStatus["NotStarted"] = 0] = "NotStarted";
62
62
  InterpreterStatus[InterpreterStatus["Running"] = 1] = "Running";
63
63
  InterpreterStatus[InterpreterStatus["Stopped"] = 2] = "Stopped";
64
- })(InterpreterStatus || (InterpreterStatus = {}));
64
+ })(InterpreterStatus = exports.InterpreterStatus || (exports.InterpreterStatus = {}));
65
65
  var Interpreter = /** @class */ (function () {
66
66
  /**
67
67
  * Creates a new Interpreter instance (i.e., service) for the given machine with the provided options, if any.
@@ -85,7 +85,7 @@ var Interpreter = /** @class */ (function () {
85
85
  * Whether the service is started.
86
86
  */
87
87
  this.initialized = false;
88
- this._status = InterpreterStatus.NotStarted;
88
+ this.status = InterpreterStatus.NotStarted;
89
89
  this.children = new Map();
90
90
  this.forwardTo = new Set();
91
91
  /**
@@ -107,21 +107,15 @@ var Interpreter = /** @class */ (function () {
107
107
  return _this.state;
108
108
  }
109
109
  var _event = utils_1.toSCXMLEvent(utils_1.toEventObject(event, payload));
110
- if (_this._status === InterpreterStatus.Stopped) {
110
+ if (_this.status === InterpreterStatus.Stopped) {
111
111
  // do nothing
112
112
  if (!environment_1.IS_PRODUCTION) {
113
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));
114
114
  }
115
115
  return _this.state;
116
116
  }
117
- if (_this._status === InterpreterStatus.NotStarted &&
118
- _this.options.deferEvents) {
119
- // tslint:disable-next-line:no-console
120
- if (!environment_1.IS_PRODUCTION) {
121
- 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));
122
- }
123
- }
124
- else if (_this._status !== InterpreterStatus.Running) {
117
+ if (_this.status !== InterpreterStatus.Running &&
118
+ !_this.options.deferEvents) {
125
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));
126
120
  }
127
121
  _this.scheduler.schedule(function () {
@@ -189,7 +183,7 @@ var Interpreter = /** @class */ (function () {
189
183
  Object.defineProperty(Interpreter.prototype, "state", {
190
184
  get: function () {
191
185
  if (!environment_1.IS_PRODUCTION) {
192
- 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.");
193
187
  }
194
188
  return this._state;
195
189
  },
@@ -229,6 +223,10 @@ var Interpreter = /** @class */ (function () {
229
223
  if (this.options.execute) {
230
224
  this.execute(this.state);
231
225
  }
226
+ // Update children
227
+ this.children.forEach(function (child) {
228
+ _this.state.children[child.id] = child;
229
+ });
232
230
  // Dev tools
233
231
  if (this.devTools) {
234
232
  this.devTools.send(_event.data, state);
@@ -277,6 +275,23 @@ var Interpreter = /** @class */ (function () {
277
275
  }
278
276
  var isDone = stateUtils_1.isInFinalState(state.configuration || [], this.machine);
279
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
+ });
280
295
  // get final child state node
281
296
  var finalChildStateNode = state.configuration.find(function (sn) { return sn.type === 'final' && sn.parent === _this.machine; });
282
297
  var doneData = finalChildStateNode && finalChildStateNode.doneData
@@ -307,7 +322,7 @@ var Interpreter = /** @class */ (function () {
307
322
  Interpreter.prototype.onTransition = function (listener) {
308
323
  this.listeners.add(listener);
309
324
  // Send current state to listener
310
- if (this._status === InterpreterStatus.Running) {
325
+ if (this.status === InterpreterStatus.Running) {
311
326
  listener(this.state, this.state.event);
312
327
  }
313
328
  return this;
@@ -329,7 +344,7 @@ var Interpreter = /** @class */ (function () {
329
344
  }
330
345
  this.listeners.add(listener);
331
346
  // Send current state to listener
332
- if (this._status === InterpreterStatus.Running) {
347
+ if (this.status === InterpreterStatus.Running) {
333
348
  listener(this.state);
334
349
  }
335
350
  if (resolvedCompleteListener) {
@@ -402,13 +417,13 @@ var Interpreter = /** @class */ (function () {
402
417
  */
403
418
  Interpreter.prototype.start = function (initialState) {
404
419
  var _this = this;
405
- if (this._status === InterpreterStatus.Running) {
420
+ if (this.status === InterpreterStatus.Running) {
406
421
  // Do not restart the service if it is already started
407
422
  return this;
408
423
  }
409
424
  registry_1.registry.register(this.sessionId, this);
410
425
  this.initialized = true;
411
- this._status = InterpreterStatus.Running;
426
+ this.status = InterpreterStatus.Running;
412
427
  var resolvedState = initialState === undefined
413
428
  ? this.initialState
414
429
  : serviceScope.provide(this, function () {
@@ -430,19 +445,19 @@ var Interpreter = /** @class */ (function () {
430
445
  * This will also notify the `onStop` listeners.
431
446
  */
432
447
  Interpreter.prototype.stop = function () {
433
- 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;
434
449
  try {
435
450
  for (var _f = __values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
436
451
  var listener = _g.value;
437
452
  this.listeners.delete(listener);
438
453
  }
439
454
  }
440
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
455
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
441
456
  finally {
442
457
  try {
443
458
  if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
444
459
  }
445
- finally { if (e_6) throw e_6.error; }
460
+ finally { if (e_7) throw e_7.error; }
446
461
  }
447
462
  try {
448
463
  for (var _h = __values(this.stopListeners), _j = _h.next(); !_j.done; _j = _h.next()) {
@@ -452,12 +467,12 @@ var Interpreter = /** @class */ (function () {
452
467
  this.stopListeners.delete(listener);
453
468
  }
454
469
  }
455
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
470
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
456
471
  finally {
457
472
  try {
458
473
  if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
459
474
  }
460
- finally { if (e_7) throw e_7.error; }
475
+ finally { if (e_8) throw e_8.error; }
461
476
  }
462
477
  try {
463
478
  for (var _k = __values(this.contextListeners), _l = _k.next(); !_l.done; _l = _k.next()) {
@@ -465,12 +480,12 @@ var Interpreter = /** @class */ (function () {
465
480
  this.contextListeners.delete(listener);
466
481
  }
467
482
  }
468
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
483
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
469
484
  finally {
470
485
  try {
471
486
  if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
472
487
  }
473
- finally { if (e_8) throw e_8.error; }
488
+ finally { if (e_9) throw e_9.error; }
474
489
  }
475
490
  try {
476
491
  for (var _m = __values(this.doneListeners), _o = _m.next(); !_o.done; _o = _m.next()) {
@@ -478,12 +493,12 @@ var Interpreter = /** @class */ (function () {
478
493
  this.doneListeners.delete(listener);
479
494
  }
480
495
  }
481
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
496
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
482
497
  finally {
483
498
  try {
484
499
  if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
485
500
  }
486
- finally { if (e_9) throw e_9.error; }
501
+ finally { if (e_10) throw e_10.error; }
487
502
  }
488
503
  // Stop all children
489
504
  this.children.forEach(function (child) {
@@ -498,35 +513,35 @@ var Interpreter = /** @class */ (function () {
498
513
  this.clock.clearTimeout(this.delayedEventsMap[key]);
499
514
  }
500
515
  }
501
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
516
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
502
517
  finally {
503
518
  try {
504
519
  if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
505
520
  }
506
- finally { if (e_10) throw e_10.error; }
521
+ finally { if (e_11) throw e_11.error; }
507
522
  }
508
523
  this.scheduler.clear();
509
524
  this.initialized = false;
510
- this._status = InterpreterStatus.Stopped;
525
+ this.status = InterpreterStatus.Stopped;
511
526
  registry_1.registry.free(this.sessionId);
512
527
  return this;
513
528
  };
514
529
  Interpreter.prototype.batch = function (events) {
515
530
  var _this = this;
516
- if (this._status === InterpreterStatus.NotStarted &&
531
+ if (this.status === InterpreterStatus.NotStarted &&
517
532
  this.options.deferEvents) {
518
533
  // tslint:disable-next-line:no-console
519
534
  if (!environment_1.IS_PRODUCTION) {
520
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));
521
536
  }
522
537
  }
523
- else if (this._status !== InterpreterStatus.Running) {
538
+ else if (this.status !== InterpreterStatus.Running) {
524
539
  throw new Error(
525
540
  // tslint:disable-next-line:max-line-length
526
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.");
527
542
  }
528
543
  this.scheduler.schedule(function () {
529
- var e_11, _a;
544
+ var e_12, _a;
530
545
  var nextState = _this.state;
531
546
  var batchChanged = false;
532
547
  var batchedActions = [];
@@ -547,12 +562,12 @@ var Interpreter = /** @class */ (function () {
547
562
  _loop_1(event_1);
548
563
  }
549
564
  }
550
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
565
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
551
566
  finally {
552
567
  try {
553
568
  if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
554
569
  }
555
- finally { if (e_11) throw e_11.error; }
570
+ finally { if (e_12) throw e_12.error; }
556
571
  }
557
572
  nextState.changed = batchChanged;
558
573
  nextState.actions = batchedActions;
@@ -587,7 +602,7 @@ var Interpreter = /** @class */ (function () {
587
602
  return nextState;
588
603
  };
589
604
  Interpreter.prototype.forward = function (event) {
590
- var e_12, _a;
605
+ var e_13, _a;
591
606
  try {
592
607
  for (var _b = __values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
593
608
  var id = _c.value;
@@ -598,12 +613,12 @@ var Interpreter = /** @class */ (function () {
598
613
  child.send(event);
599
614
  }
600
615
  }
601
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
616
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
602
617
  finally {
603
618
  try {
604
619
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
605
620
  }
606
- finally { if (e_12) throw e_12.error; }
621
+ finally { if (e_13) throw e_13.error; }
607
622
  }
608
623
  };
609
624
  Interpreter.prototype.defer = function (sendAction) {
@@ -710,17 +725,17 @@ var Interpreter = /** @class */ (function () {
710
725
  })
711
726
  : serviceCreator;
712
727
  if (utils_1.isPromiseLike(source)) {
713
- this.state.children[id] = this.spawnPromise(Promise.resolve(source), id);
728
+ this.spawnPromise(Promise.resolve(source), id);
714
729
  }
715
730
  else if (utils_1.isFunction(source)) {
716
- this.state.children[id] = this.spawnCallback(source, id);
731
+ this.spawnCallback(source, id);
717
732
  }
718
733
  else if (utils_1.isObservable(source)) {
719
- this.state.children[id] = this.spawnObservable(source, id);
734
+ this.spawnObservable(source, id);
720
735
  }
721
736
  else if (utils_1.isMachine(source)) {
722
737
  // TODO: try/catch here
723
- this.state.children[id] = this.spawnMachine(resolvedData ? source.withContext(resolvedData) : source, {
738
+ this.spawnMachine(resolvedData ? source.withContext(resolvedData) : source, {
724
739
  id: id,
725
740
  autoForward: autoForward
726
741
  });
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/types.d.ts CHANGED
@@ -116,6 +116,24 @@ export interface ActivityDefinition<TContext, TEvent extends EventObject> extend
116
116
  type: string;
117
117
  }
118
118
  export declare type Sender<TEvent extends EventObject> = (event: Event<TEvent>) => void;
119
+ declare type ExcludeType<A> = {
120
+ [K in Exclude<keyof A, 'type'>]: A[K];
121
+ };
122
+ declare type ExtractExtraParameters<A, T> = A extends {
123
+ type: T;
124
+ } ? ExcludeType<A> : never;
125
+ declare type ExtractSimple<A> = A extends any ? {} extends ExcludeType<A> ? A : never : never;
126
+ declare type NeverIfEmpty<T> = {} extends T ? never : T;
127
+ export interface PayloadSender<TEvent extends EventObject> {
128
+ /**
129
+ * Send an event object or just the event type, if the event has no other payload
130
+ */
131
+ (event: TEvent | ExtractSimple<TEvent>['type']): void;
132
+ /**
133
+ * Send an event type and its payload
134
+ */
135
+ <K extends TEvent['type']>(eventType: K, payload: NeverIfEmpty<ExtractExtraParameters<TEvent, K>>): void;
136
+ }
119
137
  export declare type Receiver<TEvent extends EventObject> = (listener: (event: TEvent) => void) => void;
120
138
  export declare type InvokeCallback = (callback: Sender<any>, onReceive: Receiver<EventObject>) => any;
121
139
  export interface InvokeMeta {
@@ -541,7 +559,7 @@ export interface NullEvent {
541
559
  }
542
560
  export interface ActivityActionObject<TContext, TEvent extends EventObject> extends ActionObject<TContext, TEvent> {
543
561
  type: ActionTypes.Start | ActionTypes.Stop;
544
- activity: ActivityDefinition<TContext, TEvent>;
562
+ activity: ActivityDefinition<TContext, TEvent> | undefined;
545
563
  exec: ActionFunction<TContext, TEvent> | undefined;
546
564
  }
547
565
  export interface InvokeActionObject<TContext, TEvent extends EventObject> extends ActivityActionObject<TContext, TEvent> {
@@ -569,6 +587,20 @@ export interface SendActionObject<TContext, TEvent extends EventObject, TSentEve
569
587
  delay?: number;
570
588
  id: string | number;
571
589
  }
590
+ export interface StopAction<TContext, TEvent extends EventObject> extends ActionObject<TContext, TEvent> {
591
+ type: ActionTypes.Stop;
592
+ activity: string | {
593
+ id: string;
594
+ } | Expr<TContext, TEvent, string | {
595
+ id: string;
596
+ }>;
597
+ }
598
+ export interface StopActionObject {
599
+ type: ActionTypes.Stop;
600
+ activity: {
601
+ id: string;
602
+ };
603
+ }
572
604
  export declare type Expr<TContext, TEvent extends EventObject, T> = (context: TContext, event: TEvent) => T;
573
605
  export declare type ExprWithMeta<TContext, TEvent extends EventObject, T> = (context: TContext, event: TEvent, meta: SCXMLEventMeta<TEvent>) => T;
574
606
  export declare type SendExpr<TContext, TEvent extends EventObject, TSentEvent extends EventObject = AnyEventObject> = ExprWithMeta<TContext, TEvent, TSentEvent>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xstate",
3
- "version": "4.13.0",
3
+ "version": "4.14.0",
4
4
  "description": "Finite State Machines and Statecharts for the Modern Web.",
5
5
  "main": "lib/index.js",
6
6
  "module": "es/index.js",
@@ -52,7 +52,7 @@
52
52
  "@babel/core": "^7.10.5",
53
53
  "@scion-scxml/test-framework": "^2.0.15",
54
54
  "babel-plugin-annotate-pure-calls": "^0.4.0",
55
- "jest": "^24.8.0",
55
+ "jest": "^26.4.2",
56
56
  "jsdom": "^14.0.0",
57
57
  "jsdom-global": "^3.0.2",
58
58
  "lerna-alias": "3.0.3-0",
@@ -64,9 +64,9 @@
64
64
  "rollup-plugin-typescript2": "^0.25.2",
65
65
  "rollup-plugin-uglify": "^6.0.2",
66
66
  "rxjs": "^6.5.1",
67
- "ts-jest": "^24.1.9",
67
+ "ts-jest": "^26.4.0",
68
68
  "tslib": "^1.10.0",
69
- "typescript": "^3.9.7",
69
+ "typescript": "^4.0.3",
70
70
  "xml-js": "^1.6.11"
71
71
  }
72
72
  }