xstate 4.32.0 → 4.33.1
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 +308 -254
- package/es/stateUtils.d.ts +1 -0
- package/es/stateUtils.js +6 -3
- package/es/types.d.ts +11 -1
- 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 +303 -249
- package/lib/stateUtils.d.ts +1 -0
- package/lib/stateUtils.js +6 -2
- package/lib/types.d.ts +11 -1
- package/lib/utils.d.ts +1 -1
- package/lib/utils.js +6 -10
- package/package.json +1 -1
- package/CHANGELOG.md +0 -1497
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');
|
|
@@ -105,7 +104,7 @@ function () {
|
|
|
105
104
|
// Forward copy of event to child actors
|
|
106
105
|
_this.forward(_event);
|
|
107
106
|
|
|
108
|
-
var nextState = _this.
|
|
107
|
+
var nextState = _this._nextState(_event);
|
|
109
108
|
|
|
110
109
|
_this.update(nextState, _event);
|
|
111
110
|
});
|
|
@@ -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
|
-
}
|
|
505
|
+
var observer = utils.toObserver(nextListenerOrObserver, _, completeListener);
|
|
506
|
+
this.listeners.add(observer.next); // Send current state to listener
|
|
354
507
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
if (typeof nextListenerOrObserver === 'function') {
|
|
359
|
-
listener = nextListenerOrObserver;
|
|
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
638
|
|
|
493
|
-
|
|
494
|
-
Interpreter.prototype.stop = function () {
|
|
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,18 +885,14 @@ 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, exec) {
|
|
713
890
|
var _this = this;
|
|
714
891
|
|
|
892
|
+
if (exec === void 0) {
|
|
893
|
+
exec = !!this.machine.config.predictableActionArguments && this._exec;
|
|
894
|
+
}
|
|
895
|
+
|
|
715
896
|
var _event = utils.toSCXMLEvent(event);
|
|
716
897
|
|
|
717
898
|
if (_event.name.indexOf(actionTypes.errorPlatform) === 0 && !this.state.nextEvents.some(function (nextEvent) {
|
|
@@ -721,13 +902,25 @@ function () {
|
|
|
721
902
|
}
|
|
722
903
|
|
|
723
904
|
var nextState = serviceScope.provide(this, function () {
|
|
724
|
-
return _this.machine.transition(_this.state, _event);
|
|
905
|
+
return _this.machine.transition(_this.state, _event, undefined, exec || undefined);
|
|
725
906
|
});
|
|
726
907
|
return nextState;
|
|
727
908
|
};
|
|
909
|
+
/**
|
|
910
|
+
* Returns the next state given the interpreter's current state and the event.
|
|
911
|
+
*
|
|
912
|
+
* This is a pure method that does _not_ update the interpreter's state.
|
|
913
|
+
*
|
|
914
|
+
* @param event The event to determine the next state
|
|
915
|
+
*/
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
Interpreter.prototype.nextState = function (event) {
|
|
919
|
+
return this._nextState(event, false);
|
|
920
|
+
};
|
|
728
921
|
|
|
729
922
|
Interpreter.prototype.forward = function (event) {
|
|
730
|
-
var
|
|
923
|
+
var e_12, _a;
|
|
731
924
|
|
|
732
925
|
try {
|
|
733
926
|
for (var _b = _tslib.__values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
@@ -740,15 +933,15 @@ function () {
|
|
|
740
933
|
|
|
741
934
|
child.send(event);
|
|
742
935
|
}
|
|
743
|
-
} catch (
|
|
744
|
-
|
|
745
|
-
error:
|
|
936
|
+
} catch (e_12_1) {
|
|
937
|
+
e_12 = {
|
|
938
|
+
error: e_12_1
|
|
746
939
|
};
|
|
747
940
|
} finally {
|
|
748
941
|
try {
|
|
749
942
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
750
943
|
} finally {
|
|
751
|
-
if (
|
|
944
|
+
if (e_12) throw e_12.error;
|
|
752
945
|
}
|
|
753
946
|
}
|
|
754
947
|
};
|
|
@@ -775,150 +968,7 @@ function () {
|
|
|
775
968
|
actionFunctionMap = this.machine.options.actions;
|
|
776
969
|
}
|
|
777
970
|
|
|
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;
|
|
971
|
+
this._exec(action, state.context, state._event, actionFunctionMap);
|
|
922
972
|
};
|
|
923
973
|
|
|
924
974
|
Interpreter.prototype.removeChild = function (childId) {
|
|
@@ -946,6 +996,10 @@ function () {
|
|
|
946
996
|
};
|
|
947
997
|
|
|
948
998
|
Interpreter.prototype.spawn = function (entity, name, options) {
|
|
999
|
+
if (this.status !== exports.InterpreterStatus.Running) {
|
|
1000
|
+
return Actor.createDeferredActor(entity, name);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
949
1003
|
if (utils.isPromiseLike(entity)) {
|
|
950
1004
|
return this.spawnPromise(Promise.resolve(entity), name);
|
|
951
1005
|
} else if (utils.isFunction(entity)) {
|