xstate 4.32.1 → 4.33.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/xstate.interpreter.js +1 -1
- package/dist/xstate.js +1 -1
- package/dist/xstate.web.js +2 -2
- package/es/Machine.js +7 -0
- package/es/State.d.ts +2 -2
- package/es/StateNode.d.ts +3 -8
- package/es/StateNode.js +53 -57
- package/es/actions.d.ts +2 -2
- package/es/actions.js +43 -9
- package/es/interpreter.d.ts +4 -1
- package/es/interpreter.js +303 -253
- package/es/stateUtils.d.ts +1 -0
- package/es/stateUtils.js +6 -3
- package/es/types.d.ts +10 -0
- package/es/utils.d.ts +1 -1
- package/es/utils.js +6 -10
- package/lib/Machine.js +7 -0
- package/lib/State.d.ts +2 -2
- package/lib/StateNode.d.ts +3 -8
- package/lib/StateNode.js +51 -55
- package/lib/actions.d.ts +2 -2
- package/lib/actions.js +43 -9
- package/lib/interpreter.d.ts +4 -1
- package/lib/interpreter.js +298 -248
- package/lib/stateUtils.d.ts +1 -0
- package/lib/stateUtils.js +6 -2
- package/lib/types.d.ts +10 -0
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +6 -10
- package/package.json +1 -1
- package/CHANGELOG.md +0 -1503
package/lib/interpreter.js
CHANGED
|
@@ -11,7 +11,6 @@ var environment = require('./environment.js');
|
|
|
11
11
|
var utils = require('./utils.js');
|
|
12
12
|
var scheduler = require('./scheduler.js');
|
|
13
13
|
var Actor = require('./Actor.js');
|
|
14
|
-
var stateUtils = require('./stateUtils.js');
|
|
15
14
|
var registry = require('./registry.js');
|
|
16
15
|
var devTools = require('./devTools.js');
|
|
17
16
|
var serviceScope = require('./serviceScope.js');
|
|
@@ -132,17 +131,176 @@ function () {
|
|
|
132
131
|
}
|
|
133
132
|
|
|
134
133
|
if ('machine' in target) {
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
134
|
+
// perhaps those events should be rejected in the parent
|
|
135
|
+
// but atm it doesn't have easy access to all of the information that is required to do it reliably
|
|
136
|
+
if (_this.status !== exports.InterpreterStatus.Stopped || _this.parent !== target || // we need to send events to the parent from exit handlers of a machine that reached its final state
|
|
137
|
+
_this.state.done) {
|
|
138
|
+
// Send SCXML events to machines
|
|
139
|
+
target.send(_tslib.__assign(_tslib.__assign({}, event), {
|
|
140
|
+
name: event.name === actionTypes.error ? "".concat(actions.error(_this.id)) : event.name,
|
|
141
|
+
origin: _this.sessionId
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
140
144
|
} else {
|
|
141
145
|
// Send normal events to other targets
|
|
142
146
|
target.send(event.data);
|
|
143
147
|
}
|
|
144
148
|
};
|
|
145
149
|
|
|
150
|
+
this._exec = function (action, context, _event, actionFunctionMap) {
|
|
151
|
+
if (actionFunctionMap === void 0) {
|
|
152
|
+
actionFunctionMap = _this.machine.options.actions;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
var actionOrExec = action.exec || actions.getActionFunction(action.type, actionFunctionMap);
|
|
156
|
+
var exec = utils.isFunction(actionOrExec) ? actionOrExec : actionOrExec ? actionOrExec.exec : action.exec;
|
|
157
|
+
|
|
158
|
+
if (exec) {
|
|
159
|
+
try {
|
|
160
|
+
return exec(context, _event.data, !_this.machine.config.predictableActionArguments ? {
|
|
161
|
+
action: action,
|
|
162
|
+
state: _this.state,
|
|
163
|
+
_event: _event
|
|
164
|
+
} : {
|
|
165
|
+
action: action,
|
|
166
|
+
_event: _event
|
|
167
|
+
});
|
|
168
|
+
} catch (err) {
|
|
169
|
+
if (_this.parent) {
|
|
170
|
+
_this.parent.send({
|
|
171
|
+
type: 'xstate.error',
|
|
172
|
+
data: err
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
throw err;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
switch (action.type) {
|
|
181
|
+
case actionTypes.send:
|
|
182
|
+
var sendAction = action;
|
|
183
|
+
|
|
184
|
+
if (typeof sendAction.delay === 'number') {
|
|
185
|
+
_this.defer(sendAction);
|
|
186
|
+
|
|
187
|
+
return;
|
|
188
|
+
} else {
|
|
189
|
+
if (sendAction.to) {
|
|
190
|
+
_this.sendTo(sendAction._event, sendAction.to);
|
|
191
|
+
} else {
|
|
192
|
+
_this.send(sendAction._event);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
break;
|
|
197
|
+
|
|
198
|
+
case actionTypes.cancel:
|
|
199
|
+
_this.cancel(action.sendId);
|
|
200
|
+
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case actionTypes.start:
|
|
204
|
+
{
|
|
205
|
+
if (_this.status !== exports.InterpreterStatus.Running) {
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
var activity = action.activity; // If the activity will be stopped right after it's started
|
|
210
|
+
// (such as in transient states)
|
|
211
|
+
// don't bother starting the activity.
|
|
212
|
+
|
|
213
|
+
if ( // in v4 with `predictableActionArguments` invokes are called eagerly when the `this.state` still points to the previous state
|
|
214
|
+
!_this.machine.config.predictableActionArguments && !_this.state.activities[activity.id || activity.type]) {
|
|
215
|
+
break;
|
|
216
|
+
} // Invoked services
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
if (activity.type === types.ActionTypes.Invoke) {
|
|
220
|
+
var invokeSource = utils.toInvokeSource(activity.src);
|
|
221
|
+
var serviceCreator = _this.machine.options.services ? _this.machine.options.services[invokeSource.type] : undefined;
|
|
222
|
+
var id = activity.id,
|
|
223
|
+
data = activity.data;
|
|
224
|
+
|
|
225
|
+
if (!environment.IS_PRODUCTION) {
|
|
226
|
+
utils.warn(!('forward' in activity), // tslint:disable-next-line:max-line-length
|
|
227
|
+
"`forward` property is deprecated (found in invocation of '".concat(activity.src, "' in in machine '").concat(_this.machine.id, "'). ") + "Please use `autoForward` instead.");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
var autoForward = 'autoForward' in activity ? activity.autoForward : !!activity.forward;
|
|
231
|
+
|
|
232
|
+
if (!serviceCreator) {
|
|
233
|
+
// tslint:disable-next-line:no-console
|
|
234
|
+
if (!environment.IS_PRODUCTION) {
|
|
235
|
+
utils.warn(false, "No service found for invocation '".concat(activity.src, "' in machine '").concat(_this.machine.id, "'."));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
var resolvedData = data ? utils.mapContext(data, context, _event) : undefined;
|
|
242
|
+
|
|
243
|
+
if (typeof serviceCreator === 'string') {
|
|
244
|
+
// TODO: warn
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var source = utils.isFunction(serviceCreator) ? serviceCreator(context, _event.data, {
|
|
249
|
+
data: resolvedData,
|
|
250
|
+
src: invokeSource,
|
|
251
|
+
meta: activity.meta
|
|
252
|
+
}) : serviceCreator;
|
|
253
|
+
|
|
254
|
+
if (!source) {
|
|
255
|
+
// TODO: warn?
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
var options = void 0;
|
|
260
|
+
|
|
261
|
+
if (utils.isMachine(source)) {
|
|
262
|
+
source = resolvedData ? source.withContext(resolvedData) : source;
|
|
263
|
+
options = {
|
|
264
|
+
autoForward: autoForward
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
_this.spawn(source, id, options);
|
|
269
|
+
} else {
|
|
270
|
+
_this.spawnActivity(activity);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
break;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
case actionTypes.stop:
|
|
277
|
+
{
|
|
278
|
+
_this.stopChild(action.activity.id);
|
|
279
|
+
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
case actionTypes.log:
|
|
284
|
+
var label = action.label,
|
|
285
|
+
value = action.value;
|
|
286
|
+
|
|
287
|
+
if (label) {
|
|
288
|
+
_this.logger(label, value);
|
|
289
|
+
} else {
|
|
290
|
+
_this.logger(value);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
break;
|
|
294
|
+
|
|
295
|
+
default:
|
|
296
|
+
if (!environment.IS_PRODUCTION) {
|
|
297
|
+
utils.warn(false, "No implementation found for action type '".concat(action.type, "'"));
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
};
|
|
303
|
+
|
|
146
304
|
var resolvedOptions = _tslib.__assign(_tslib.__assign({}, Interpreter.defaultOptions), options);
|
|
147
305
|
|
|
148
306
|
var clock = resolvedOptions.clock,
|
|
@@ -226,7 +384,9 @@ function () {
|
|
|
226
384
|
|
|
227
385
|
this._state = state; // Execute actions
|
|
228
386
|
|
|
229
|
-
if (this.
|
|
387
|
+
if ((!this.machine.config.predictableActionArguments || // this is currently required to execute initial actions as the `initialState` gets cached
|
|
388
|
+
// we can't just recompute it (and execute actions while doing so) because we try to preserve identity of actors created within initial assigns
|
|
389
|
+
_event === actions.initEvent) && this.options.execute) {
|
|
230
390
|
this.execute(this.state);
|
|
231
391
|
} // Update children
|
|
232
392
|
|
|
@@ -293,9 +453,7 @@ function () {
|
|
|
293
453
|
}
|
|
294
454
|
}
|
|
295
455
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
if (this.state.configuration && isDone) {
|
|
456
|
+
if (this.state.done) {
|
|
299
457
|
// get final child state node
|
|
300
458
|
var finalChildStateNode = state.configuration.find(function (sn) {
|
|
301
459
|
return sn.type === 'final' && sn.parent === _this.machine;
|
|
@@ -319,7 +477,7 @@ function () {
|
|
|
319
477
|
}
|
|
320
478
|
}
|
|
321
479
|
|
|
322
|
-
this.
|
|
480
|
+
this._stop();
|
|
323
481
|
}
|
|
324
482
|
};
|
|
325
483
|
/*
|
|
@@ -344,42 +502,35 @@ function () {
|
|
|
344
502
|
completeListener) {
|
|
345
503
|
var _this = this;
|
|
346
504
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
unsubscribe: function () {
|
|
350
|
-
return void 0;
|
|
351
|
-
}
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
var listener;
|
|
356
|
-
var resolvedCompleteListener = completeListener;
|
|
505
|
+
var observer = utils.toObserver(nextListenerOrObserver, _, completeListener);
|
|
506
|
+
this.listeners.add(observer.next); // Send current state to listener
|
|
357
507
|
|
|
358
|
-
if (
|
|
359
|
-
|
|
360
|
-
} else {
|
|
361
|
-
listener = nextListenerOrObserver.next.bind(nextListenerOrObserver);
|
|
362
|
-
resolvedCompleteListener = nextListenerOrObserver.complete.bind(nextListenerOrObserver);
|
|
508
|
+
if (this.status !== exports.InterpreterStatus.NotStarted) {
|
|
509
|
+
observer.next(this.state);
|
|
363
510
|
}
|
|
364
511
|
|
|
365
|
-
|
|
512
|
+
var completeOnce = function () {
|
|
513
|
+
_this.doneListeners.delete(completeOnce);
|
|
366
514
|
|
|
367
|
-
|
|
368
|
-
listener(this.state);
|
|
369
|
-
}
|
|
515
|
+
_this.stopListeners.delete(completeOnce);
|
|
370
516
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
517
|
+
observer.complete();
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
if (this.status === exports.InterpreterStatus.Stopped) {
|
|
521
|
+
observer.complete();
|
|
522
|
+
} else {
|
|
523
|
+
this.onDone(completeOnce);
|
|
524
|
+
this.onStop(completeOnce);
|
|
377
525
|
}
|
|
378
526
|
|
|
379
527
|
return {
|
|
380
528
|
unsubscribe: function () {
|
|
381
|
-
|
|
382
|
-
|
|
529
|
+
_this.listeners.delete(observer.next);
|
|
530
|
+
|
|
531
|
+
_this.doneListeners.delete(completeOnce);
|
|
532
|
+
|
|
533
|
+
_this.stopListeners.delete(completeOnce);
|
|
383
534
|
}
|
|
384
535
|
};
|
|
385
536
|
};
|
|
@@ -484,18 +635,10 @@ function () {
|
|
|
484
635
|
});
|
|
485
636
|
return this;
|
|
486
637
|
};
|
|
487
|
-
/**
|
|
488
|
-
* Stops the interpreter and unsubscribe all listeners.
|
|
489
|
-
*
|
|
490
|
-
* This will also notify the `onStop` listeners.
|
|
491
|
-
*/
|
|
492
|
-
|
|
493
638
|
|
|
494
|
-
Interpreter.prototype.
|
|
639
|
+
Interpreter.prototype._stop = function () {
|
|
495
640
|
var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e;
|
|
496
641
|
|
|
497
|
-
var _this = this;
|
|
498
|
-
|
|
499
642
|
try {
|
|
500
643
|
for (var _f = _tslib.__values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
|
|
501
644
|
var listener = _g.value;
|
|
@@ -571,40 +714,13 @@ function () {
|
|
|
571
714
|
return this;
|
|
572
715
|
}
|
|
573
716
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
var e_11, _a;
|
|
578
|
-
|
|
579
|
-
try {
|
|
580
|
-
for (var _b = _tslib.__values(stateNode.definition.exit), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
581
|
-
var action = _c.value;
|
|
582
|
-
|
|
583
|
-
_this.exec(action, _this.state);
|
|
584
|
-
}
|
|
585
|
-
} catch (e_11_1) {
|
|
586
|
-
e_11 = {
|
|
587
|
-
error: e_11_1
|
|
588
|
-
};
|
|
589
|
-
} finally {
|
|
590
|
-
try {
|
|
591
|
-
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
592
|
-
} finally {
|
|
593
|
-
if (e_11) throw e_11.error;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}); // Stop all children
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
this.children.forEach(function (child) {
|
|
600
|
-
if (utils.isFunction(child.stop)) {
|
|
601
|
-
child.stop();
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
this.children.clear();
|
|
717
|
+
this.initialized = false;
|
|
718
|
+
this.status = exports.InterpreterStatus.Stopped;
|
|
719
|
+
this._initialState = undefined;
|
|
605
720
|
|
|
606
721
|
try {
|
|
607
|
-
//
|
|
722
|
+
// we are going to stop within the current sync frame
|
|
723
|
+
// so we can safely just cancel this here as nothing async should be fired anyway
|
|
608
724
|
for (var _p = _tslib.__values(Object.keys(this.delayedEventsMap)), _q = _p.next(); !_q.done; _q = _p.next()) {
|
|
609
725
|
var key = _q.value;
|
|
610
726
|
this.clock.clearTimeout(this.delayedEventsMap[key]);
|
|
@@ -619,16 +735,85 @@ function () {
|
|
|
619
735
|
} finally {
|
|
620
736
|
if (e_10) throw e_10.error;
|
|
621
737
|
}
|
|
622
|
-
}
|
|
738
|
+
} // clear everything that might be enqueued
|
|
739
|
+
|
|
623
740
|
|
|
624
741
|
this.scheduler.clear();
|
|
625
742
|
this.scheduler = new scheduler.Scheduler({
|
|
626
743
|
deferEvents: this.options.deferEvents
|
|
627
744
|
});
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
745
|
+
};
|
|
746
|
+
/**
|
|
747
|
+
* Stops the interpreter and unsubscribe all listeners.
|
|
748
|
+
*
|
|
749
|
+
* This will also notify the `onStop` listeners.
|
|
750
|
+
*/
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
Interpreter.prototype.stop = function () {
|
|
754
|
+
// TODO: add warning for stopping non-root interpreters
|
|
755
|
+
var _this = this; // grab the current scheduler as it will be replaced in _stop
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
var scheduler = this.scheduler;
|
|
759
|
+
|
|
760
|
+
this._stop(); // let what is currently processed to be finished
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
scheduler.schedule(function () {
|
|
764
|
+
// it feels weird to handle this here but we need to handle this even slightly "out of band"
|
|
765
|
+
var _event = utils.toSCXMLEvent({
|
|
766
|
+
type: 'xstate.stop'
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
var nextState = serviceScope.provide(_this, function () {
|
|
770
|
+
var exitActions = utils.flatten(_tslib.__spreadArray([], _tslib.__read(_this.state.configuration), false).sort(function (a, b) {
|
|
771
|
+
return b.order - a.order;
|
|
772
|
+
}).map(function (stateNode) {
|
|
773
|
+
return actions.toActionObjects(stateNode.onExit, _this.machine.options.actions);
|
|
774
|
+
}));
|
|
775
|
+
|
|
776
|
+
var _a = _tslib.__read(actions.resolveActions(_this.machine, _this.state, _this.state.context, _event, exitActions, _this.machine.config.predictableActionArguments ? _this._exec : undefined, _this.machine.config.predictableActionArguments || _this.machine.config.preserveActionOrder), 2),
|
|
777
|
+
resolvedActions = _a[0],
|
|
778
|
+
updatedContext = _a[1];
|
|
779
|
+
|
|
780
|
+
var newState = new State.State({
|
|
781
|
+
value: _this.state.value,
|
|
782
|
+
context: updatedContext,
|
|
783
|
+
_event: _event,
|
|
784
|
+
_sessionid: _this.sessionId,
|
|
785
|
+
historyValue: undefined,
|
|
786
|
+
history: _this.state,
|
|
787
|
+
actions: resolvedActions.filter(function (action) {
|
|
788
|
+
return action.type !== actionTypes.raise && (action.type !== actionTypes.send || !!action.to && action.to !== types.SpecialTargets.Internal);
|
|
789
|
+
}),
|
|
790
|
+
activities: {},
|
|
791
|
+
events: [],
|
|
792
|
+
configuration: [],
|
|
793
|
+
transitions: [],
|
|
794
|
+
children: {},
|
|
795
|
+
done: _this.state.done,
|
|
796
|
+
tags: _this.state.tags,
|
|
797
|
+
machine: _this.machine
|
|
798
|
+
});
|
|
799
|
+
newState.changed = true;
|
|
800
|
+
return newState;
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
_this.update(nextState, _event); // TODO: think about converting those to actions
|
|
804
|
+
// Stop all children
|
|
805
|
+
|
|
806
|
+
|
|
807
|
+
_this.children.forEach(function (child) {
|
|
808
|
+
if (utils.isFunction(child.stop)) {
|
|
809
|
+
child.stop();
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
|
|
813
|
+
_this.children.clear();
|
|
814
|
+
|
|
815
|
+
registry.registry.free(_this.sessionId);
|
|
816
|
+
});
|
|
632
817
|
return this;
|
|
633
818
|
};
|
|
634
819
|
|
|
@@ -646,7 +831,7 @@ function () {
|
|
|
646
831
|
}
|
|
647
832
|
|
|
648
833
|
this.scheduler.schedule(function () {
|
|
649
|
-
var
|
|
834
|
+
var e_11, _a;
|
|
650
835
|
|
|
651
836
|
var nextState = _this.state;
|
|
652
837
|
var batchChanged = false;
|
|
@@ -672,15 +857,15 @@ function () {
|
|
|
672
857
|
|
|
673
858
|
_loop_1(event_1);
|
|
674
859
|
}
|
|
675
|
-
} catch (
|
|
676
|
-
|
|
677
|
-
error:
|
|
860
|
+
} catch (e_11_1) {
|
|
861
|
+
e_11 = {
|
|
862
|
+
error: e_11_1
|
|
678
863
|
};
|
|
679
864
|
} finally {
|
|
680
865
|
try {
|
|
681
866
|
if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
|
|
682
867
|
} finally {
|
|
683
|
-
if (
|
|
868
|
+
if (e_11) throw e_11.error;
|
|
684
869
|
}
|
|
685
870
|
}
|
|
686
871
|
|
|
@@ -700,16 +885,8 @@ function () {
|
|
|
700
885
|
Interpreter.prototype.sender = function (event) {
|
|
701
886
|
return this.send.bind(this, event);
|
|
702
887
|
};
|
|
703
|
-
/**
|
|
704
|
-
* Returns the next state given the interpreter's current state and the event.
|
|
705
|
-
*
|
|
706
|
-
* This is a pure method that does _not_ update the interpreter's state.
|
|
707
|
-
*
|
|
708
|
-
* @param event The event to determine the next state
|
|
709
|
-
*/
|
|
710
|
-
|
|
711
888
|
|
|
712
|
-
Interpreter.prototype.
|
|
889
|
+
Interpreter.prototype._nextState = function (event) {
|
|
713
890
|
var _this = this;
|
|
714
891
|
|
|
715
892
|
var _event = utils.toSCXMLEvent(event);
|
|
@@ -721,13 +898,25 @@ function () {
|
|
|
721
898
|
}
|
|
722
899
|
|
|
723
900
|
var nextState = serviceScope.provide(this, function () {
|
|
724
|
-
return _this.machine.transition(_this.state, _event);
|
|
901
|
+
return _this.machine.transition(_this.state, _event, undefined, _this.machine.config.predictableActionArguments ? _this._exec : undefined);
|
|
725
902
|
});
|
|
726
903
|
return nextState;
|
|
727
904
|
};
|
|
905
|
+
/**
|
|
906
|
+
* Returns the next state given the interpreter's current state and the event.
|
|
907
|
+
*
|
|
908
|
+
* This is a pure method that does _not_ update the interpreter's state.
|
|
909
|
+
*
|
|
910
|
+
* @param event The event to determine the next state
|
|
911
|
+
*/
|
|
912
|
+
|
|
913
|
+
|
|
914
|
+
Interpreter.prototype.nextState = function (event) {
|
|
915
|
+
return this._nextState(event);
|
|
916
|
+
};
|
|
728
917
|
|
|
729
918
|
Interpreter.prototype.forward = function (event) {
|
|
730
|
-
var
|
|
919
|
+
var e_12, _a;
|
|
731
920
|
|
|
732
921
|
try {
|
|
733
922
|
for (var _b = _tslib.__values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
@@ -740,15 +929,15 @@ function () {
|
|
|
740
929
|
|
|
741
930
|
child.send(event);
|
|
742
931
|
}
|
|
743
|
-
} catch (
|
|
744
|
-
|
|
745
|
-
error:
|
|
932
|
+
} catch (e_12_1) {
|
|
933
|
+
e_12 = {
|
|
934
|
+
error: e_12_1
|
|
746
935
|
};
|
|
747
936
|
} finally {
|
|
748
937
|
try {
|
|
749
938
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
750
939
|
} finally {
|
|
751
|
-
if (
|
|
940
|
+
if (e_12) throw e_12.error;
|
|
752
941
|
}
|
|
753
942
|
}
|
|
754
943
|
};
|
|
@@ -775,150 +964,7 @@ function () {
|
|
|
775
964
|
actionFunctionMap = this.machine.options.actions;
|
|
776
965
|
}
|
|
777
966
|
|
|
778
|
-
|
|
779
|
-
_event = state._event;
|
|
780
|
-
var actionOrExec = action.exec || actions.getActionFunction(action.type, actionFunctionMap);
|
|
781
|
-
var exec = utils.isFunction(actionOrExec) ? actionOrExec : actionOrExec ? actionOrExec.exec : action.exec;
|
|
782
|
-
|
|
783
|
-
if (exec) {
|
|
784
|
-
try {
|
|
785
|
-
return exec(context, _event.data, {
|
|
786
|
-
action: action,
|
|
787
|
-
state: this.state,
|
|
788
|
-
_event: _event
|
|
789
|
-
});
|
|
790
|
-
} catch (err) {
|
|
791
|
-
if (this.parent) {
|
|
792
|
-
this.parent.send({
|
|
793
|
-
type: 'xstate.error',
|
|
794
|
-
data: err
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
throw err;
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
|
|
802
|
-
switch (action.type) {
|
|
803
|
-
case actionTypes.send:
|
|
804
|
-
var sendAction = action;
|
|
805
|
-
|
|
806
|
-
if (typeof sendAction.delay === 'number') {
|
|
807
|
-
this.defer(sendAction);
|
|
808
|
-
return;
|
|
809
|
-
} else {
|
|
810
|
-
if (sendAction.to) {
|
|
811
|
-
this.sendTo(sendAction._event, sendAction.to);
|
|
812
|
-
} else {
|
|
813
|
-
this.send(sendAction._event);
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
break;
|
|
818
|
-
|
|
819
|
-
case actionTypes.cancel:
|
|
820
|
-
this.cancel(action.sendId);
|
|
821
|
-
break;
|
|
822
|
-
|
|
823
|
-
case actionTypes.start:
|
|
824
|
-
{
|
|
825
|
-
if (this.status !== exports.InterpreterStatus.Running) {
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
var activity = action.activity; // If the activity will be stopped right after it's started
|
|
830
|
-
// (such as in transient states)
|
|
831
|
-
// don't bother starting the activity.
|
|
832
|
-
|
|
833
|
-
if (!this.state.activities[activity.id || activity.type]) {
|
|
834
|
-
break;
|
|
835
|
-
} // Invoked services
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
if (activity.type === types.ActionTypes.Invoke) {
|
|
839
|
-
var invokeSource = utils.toInvokeSource(activity.src);
|
|
840
|
-
var serviceCreator = this.machine.options.services ? this.machine.options.services[invokeSource.type] : undefined;
|
|
841
|
-
var id = activity.id,
|
|
842
|
-
data = activity.data;
|
|
843
|
-
|
|
844
|
-
if (!environment.IS_PRODUCTION) {
|
|
845
|
-
utils.warn(!('forward' in activity), // tslint:disable-next-line:max-line-length
|
|
846
|
-
"`forward` property is deprecated (found in invocation of '".concat(activity.src, "' in in machine '").concat(this.machine.id, "'). ") + "Please use `autoForward` instead.");
|
|
847
|
-
}
|
|
848
|
-
|
|
849
|
-
var autoForward = 'autoForward' in activity ? activity.autoForward : !!activity.forward;
|
|
850
|
-
|
|
851
|
-
if (!serviceCreator) {
|
|
852
|
-
// tslint:disable-next-line:no-console
|
|
853
|
-
if (!environment.IS_PRODUCTION) {
|
|
854
|
-
utils.warn(false, "No service found for invocation '".concat(activity.src, "' in machine '").concat(this.machine.id, "'."));
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
return;
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
var resolvedData = data ? utils.mapContext(data, context, _event) : undefined;
|
|
861
|
-
|
|
862
|
-
if (typeof serviceCreator === 'string') {
|
|
863
|
-
// TODO: warn
|
|
864
|
-
return;
|
|
865
|
-
}
|
|
866
|
-
|
|
867
|
-
var source = utils.isFunction(serviceCreator) ? serviceCreator(context, _event.data, {
|
|
868
|
-
data: resolvedData,
|
|
869
|
-
src: invokeSource,
|
|
870
|
-
meta: activity.meta
|
|
871
|
-
}) : serviceCreator;
|
|
872
|
-
|
|
873
|
-
if (!source) {
|
|
874
|
-
// TODO: warn?
|
|
875
|
-
return;
|
|
876
|
-
}
|
|
877
|
-
|
|
878
|
-
var options = void 0;
|
|
879
|
-
|
|
880
|
-
if (utils.isMachine(source)) {
|
|
881
|
-
source = resolvedData ? source.withContext(resolvedData) : source;
|
|
882
|
-
options = {
|
|
883
|
-
autoForward: autoForward
|
|
884
|
-
};
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
this.spawn(source, id, options);
|
|
888
|
-
} else {
|
|
889
|
-
this.spawnActivity(activity);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
break;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
case actionTypes.stop:
|
|
896
|
-
{
|
|
897
|
-
this.stopChild(action.activity.id);
|
|
898
|
-
break;
|
|
899
|
-
}
|
|
900
|
-
|
|
901
|
-
case actionTypes.log:
|
|
902
|
-
var label = action.label,
|
|
903
|
-
value = action.value;
|
|
904
|
-
|
|
905
|
-
if (label) {
|
|
906
|
-
this.logger(label, value);
|
|
907
|
-
} else {
|
|
908
|
-
this.logger(value);
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
break;
|
|
912
|
-
|
|
913
|
-
default:
|
|
914
|
-
if (!environment.IS_PRODUCTION) {
|
|
915
|
-
utils.warn(false, "No implementation found for action type '".concat(action.type, "'"));
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
break;
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
return undefined;
|
|
967
|
+
this._exec(action, state.context, state._event, actionFunctionMap);
|
|
922
968
|
};
|
|
923
969
|
|
|
924
970
|
Interpreter.prototype.removeChild = function (childId) {
|
|
@@ -946,6 +992,10 @@ function () {
|
|
|
946
992
|
};
|
|
947
993
|
|
|
948
994
|
Interpreter.prototype.spawn = function (entity, name, options) {
|
|
995
|
+
if (this.status !== exports.InterpreterStatus.Running) {
|
|
996
|
+
return Actor.createDeferredActor(entity, name);
|
|
997
|
+
}
|
|
998
|
+
|
|
949
999
|
if (utils.isPromiseLike(entity)) {
|
|
950
1000
|
return this.spawnPromise(Promise.resolve(entity), name);
|
|
951
1001
|
} else if (utils.isFunction(entity)) {
|
package/lib/stateUtils.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { StateNode } from './StateNode';
|
|
|
3
3
|
declare type Configuration<TC, TE extends EventObject> = Iterable<StateNode<TC, any, TE>>;
|
|
4
4
|
declare type AdjList<TC, TE extends EventObject> = Map<StateNode<TC, any, TE>, Array<StateNode<TC, any, TE>>>;
|
|
5
5
|
export declare const isLeafNode: (stateNode: StateNode<any, any, any, any, any, any>) => boolean;
|
|
6
|
+
export declare function getAllChildren<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE>): Array<StateNode<TC, any, TE>>;
|
|
6
7
|
export declare function getChildren<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE>): Array<StateNode<TC, any, TE>>;
|
|
7
8
|
export declare function getAllStateNodes<TC, TE extends EventObject>(stateNode: StateNode<TC, any, TE, any, any, any>): Array<StateNode<TC, any, TE, any, any, any>>;
|
|
8
9
|
export declare function getConfiguration<TC, TE extends EventObject>(prevStateNodes: Iterable<StateNode<TC, any, TE, any, any, any>>, stateNodes: Iterable<StateNode<TC, any, TE, any, any, any>>): Set<StateNode<TC, any, TE, any, any, any>>;
|