UNPKG

55.4 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var _tslib = require('./_virtual/_tslib.js');
6var utils = require('./utils.js');
7var State = require('./State.js');
8var actionTypes = require('./actionTypes.js');
9var actions = require('./actions.js');
10var environment = require('./environment.js');
11var constants = require('./constants.js');
12var stateUtils = require('./stateUtils.js');
13var Actor = require('./Actor.js');
14var invokeUtils = require('./invokeUtils.js');
15
16var NULL_EVENT = '';
17var STATE_IDENTIFIER = '#';
18var WILDCARD = '*';
19var EMPTY_OBJECT = {};
20
21var isStateId = function (str) {
22 return str[0] === STATE_IDENTIFIER;
23};
24
25var createDefaultOptions = function () {
26 return {
27 actions: {},
28 guards: {},
29 services: {},
30 activities: {},
31 delays: {}
32 };
33};
34
35var validateArrayifiedTransitions = function (stateNode, event, transitions) {
36 var hasNonLastUnguardedTarget = transitions.slice(0, -1).some(function (transition) {
37 return !('cond' in transition) && !('in' in transition) && (utils.isString(transition.target) || utils.isMachine(transition.target));
38 });
39 var eventText = event === NULL_EVENT ? 'the transient event' : "event '".concat(event, "'");
40 utils.warn(!hasNonLastUnguardedTarget, "One or more transitions for ".concat(eventText, " on state '").concat(stateNode.id, "' are unreachable. ") + "Make sure that the default transition is the last one defined.");
41};
42
43var StateNode =
44/*#__PURE__*/
45
46/** @class */
47function () {
48 function StateNode(
49 /**
50 * The raw config used to create the machine.
51 */
52 config, options,
53 /**
54 * The initial extended state
55 */
56 _context, // TODO: this is unsafe, but we're removing it in v5 anyway
57 _stateInfo) {
58 if (_context === void 0) {
59 _context = 'context' in config ? config.context : undefined;
60 }
61
62 var _this = this;
63
64 var _a;
65
66 this.config = config;
67 this._context = _context;
68 /**
69 * The order this state node appears. Corresponds to the implicit SCXML document order.
70 */
71
72 this.order = -1;
73 this.__xstatenode = true;
74 this.__cache = {
75 events: undefined,
76 relativeValue: new Map(),
77 initialStateValue: undefined,
78 initialState: undefined,
79 on: undefined,
80 transitions: undefined,
81 candidates: {},
82 delayedTransitions: undefined
83 };
84 this.idMap = {};
85 this.tags = [];
86 this.options = Object.assign(createDefaultOptions(), options);
87 this.parent = _stateInfo === null || _stateInfo === void 0 ? void 0 : _stateInfo.parent;
88 this.key = this.config.key || (_stateInfo === null || _stateInfo === void 0 ? void 0 : _stateInfo.key) || this.config.id || '(machine)';
89 this.machine = this.parent ? this.parent.machine : this;
90 this.path = this.parent ? this.parent.path.concat(this.key) : [];
91 this.delimiter = this.config.delimiter || (this.parent ? this.parent.delimiter : constants.STATE_DELIMITER);
92 this.id = this.config.id || _tslib.__spreadArray([this.machine.key], _tslib.__read(this.path), false).join(this.delimiter);
93 this.version = this.parent ? this.parent.version : this.config.version;
94 this.type = this.config.type || (this.config.parallel ? 'parallel' : this.config.states && Object.keys(this.config.states).length ? 'compound' : this.config.history ? 'history' : 'atomic');
95 this.schema = this.parent ? this.machine.schema : (_a = this.config.schema) !== null && _a !== void 0 ? _a : {};
96 this.description = this.config.description;
97
98 if (!environment.IS_PRODUCTION) {
99 utils.warn(!('parallel' in this.config), "The \"parallel\" property is deprecated and will be removed in version 4.1. ".concat(this.config.parallel ? "Replace with `type: 'parallel'`" : "Use `type: '".concat(this.type, "'`"), " in the config for state node '").concat(this.id, "' instead."));
100 }
101
102 this.initial = this.config.initial;
103 this.states = this.config.states ? utils.mapValues(this.config.states, function (stateConfig, key) {
104 var _a;
105
106 var stateNode = new StateNode(stateConfig, {}, undefined, {
107 parent: _this,
108 key: key
109 });
110 Object.assign(_this.idMap, _tslib.__assign((_a = {}, _a[stateNode.id] = stateNode, _a), stateNode.idMap));
111 return stateNode;
112 }) : EMPTY_OBJECT; // Document order
113
114 var order = 0;
115
116 function dfs(stateNode) {
117 var e_1, _a;
118
119 stateNode.order = order++;
120
121 try {
122 for (var _b = _tslib.__values(stateUtils.getAllChildren(stateNode)), _c = _b.next(); !_c.done; _c = _b.next()) {
123 var child = _c.value;
124 dfs(child);
125 }
126 } catch (e_1_1) {
127 e_1 = {
128 error: e_1_1
129 };
130 } finally {
131 try {
132 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
133 } finally {
134 if (e_1) throw e_1.error;
135 }
136 }
137 }
138
139 dfs(this); // History config
140
141 this.history = this.config.history === true ? 'shallow' : this.config.history || false;
142 this._transient = !!this.config.always || (!this.config.on ? false : Array.isArray(this.config.on) ? this.config.on.some(function (_a) {
143 var event = _a.event;
144 return event === NULL_EVENT;
145 }) : NULL_EVENT in this.config.on);
146 this.strict = !!this.config.strict; // TODO: deprecate (entry)
147
148 this.onEntry = utils.toArray(this.config.entry || this.config.onEntry).map(function (action) {
149 return actions.toActionObject(action);
150 }); // TODO: deprecate (exit)
151
152 this.onExit = utils.toArray(this.config.exit || this.config.onExit).map(function (action) {
153 return actions.toActionObject(action);
154 });
155 this.meta = this.config.meta;
156 this.doneData = this.type === 'final' ? this.config.data : undefined;
157 this.invoke = utils.toArray(this.config.invoke).map(function (invokeConfig, i) {
158 var _a, _b;
159
160 if (utils.isMachine(invokeConfig)) {
161 var invokeId = utils.createInvokeId(_this.id, i);
162 _this.machine.options.services = _tslib.__assign((_a = {}, _a[invokeId] = invokeConfig, _a), _this.machine.options.services);
163 return invokeUtils.toInvokeDefinition({
164 src: invokeId,
165 id: invokeId
166 });
167 } else if (utils.isString(invokeConfig.src)) {
168 var invokeId = invokeConfig.id || utils.createInvokeId(_this.id, i);
169 return invokeUtils.toInvokeDefinition(_tslib.__assign(_tslib.__assign({}, invokeConfig), {
170 id: invokeId,
171 src: invokeConfig.src
172 }));
173 } else if (utils.isMachine(invokeConfig.src) || utils.isFunction(invokeConfig.src)) {
174 var invokeId = invokeConfig.id || utils.createInvokeId(_this.id, i);
175 _this.machine.options.services = _tslib.__assign((_b = {}, _b[invokeId] = invokeConfig.src, _b), _this.machine.options.services);
176 return invokeUtils.toInvokeDefinition(_tslib.__assign(_tslib.__assign({
177 id: invokeId
178 }, invokeConfig), {
179 src: invokeId
180 }));
181 } else {
182 var invokeSource = invokeConfig.src;
183 return invokeUtils.toInvokeDefinition(_tslib.__assign(_tslib.__assign({
184 id: utils.createInvokeId(_this.id, i)
185 }, invokeConfig), {
186 src: invokeSource
187 }));
188 }
189 });
190 this.activities = utils.toArray(this.config.activities).concat(this.invoke).map(function (activity) {
191 return actions.toActivityDefinition(activity);
192 });
193 this.transition = this.transition.bind(this);
194 this.tags = utils.toArray(this.config.tags); // TODO: this is the real fix for initialization once
195 // state node getters are deprecated
196 // if (!this.parent) {
197 // this._init();
198 // }
199 }
200
201 StateNode.prototype._init = function () {
202 if (this.__cache.transitions) {
203 return;
204 }
205
206 stateUtils.getAllStateNodes(this).forEach(function (stateNode) {
207 return stateNode.on;
208 });
209 };
210 /**
211 * Clones this state machine with custom options and context.
212 *
213 * @param options Options (actions, guards, activities, services) to recursively merge with the existing options.
214 * @param context Custom context (will override predefined context)
215 */
216
217
218 StateNode.prototype.withConfig = function (options, context) {
219 var _a = this.options,
220 actions = _a.actions,
221 activities = _a.activities,
222 guards = _a.guards,
223 services = _a.services,
224 delays = _a.delays;
225 return new StateNode(this.config, {
226 actions: _tslib.__assign(_tslib.__assign({}, actions), options.actions),
227 activities: _tslib.__assign(_tslib.__assign({}, activities), options.activities),
228 guards: _tslib.__assign(_tslib.__assign({}, guards), options.guards),
229 services: _tslib.__assign(_tslib.__assign({}, services), options.services),
230 delays: _tslib.__assign(_tslib.__assign({}, delays), options.delays)
231 }, context !== null && context !== void 0 ? context : this.context);
232 };
233 /**
234 * Clones this state machine with custom context.
235 *
236 * @param context Custom context (will override predefined context, not recursive)
237 */
238
239
240 StateNode.prototype.withContext = function (context) {
241 return new StateNode(this.config, this.options, context);
242 };
243
244 Object.defineProperty(StateNode.prototype, "context", {
245 get: function () {
246 return utils.isFunction(this._context) ? this._context() : this._context;
247 },
248 enumerable: false,
249 configurable: true
250 });
251 Object.defineProperty(StateNode.prototype, "definition", {
252 /**
253 * The well-structured state node definition.
254 */
255 get: function () {
256 return {
257 id: this.id,
258 key: this.key,
259 version: this.version,
260 context: this.context,
261 type: this.type,
262 initial: this.initial,
263 history: this.history,
264 states: utils.mapValues(this.states, function (state) {
265 return state.definition;
266 }),
267 on: this.on,
268 transitions: this.transitions,
269 entry: this.onEntry,
270 exit: this.onExit,
271 activities: this.activities || [],
272 meta: this.meta,
273 order: this.order || -1,
274 data: this.doneData,
275 invoke: this.invoke,
276 description: this.description,
277 tags: this.tags
278 };
279 },
280 enumerable: false,
281 configurable: true
282 });
283
284 StateNode.prototype.toJSON = function () {
285 return this.definition;
286 };
287
288 Object.defineProperty(StateNode.prototype, "on", {
289 /**
290 * The mapping of events to transitions.
291 */
292 get: function () {
293 if (this.__cache.on) {
294 return this.__cache.on;
295 }
296
297 var transitions = this.transitions;
298 return this.__cache.on = transitions.reduce(function (map, transition) {
299 map[transition.eventType] = map[transition.eventType] || [];
300 map[transition.eventType].push(transition);
301 return map;
302 }, {});
303 },
304 enumerable: false,
305 configurable: true
306 });
307 Object.defineProperty(StateNode.prototype, "after", {
308 get: function () {
309 return this.__cache.delayedTransitions || (this.__cache.delayedTransitions = this.getDelayedTransitions(), this.__cache.delayedTransitions);
310 },
311 enumerable: false,
312 configurable: true
313 });
314 Object.defineProperty(StateNode.prototype, "transitions", {
315 /**
316 * All the transitions that can be taken from this state node.
317 */
318 get: function () {
319 return this.__cache.transitions || (this.__cache.transitions = this.formatTransitions(), this.__cache.transitions);
320 },
321 enumerable: false,
322 configurable: true
323 });
324
325 StateNode.prototype.getCandidates = function (eventName) {
326 if (this.__cache.candidates[eventName]) {
327 return this.__cache.candidates[eventName];
328 }
329
330 var transient = eventName === NULL_EVENT;
331 var candidates = this.transitions.filter(function (transition) {
332 var sameEventType = transition.eventType === eventName; // null events should only match against eventless transitions
333
334 return transient ? sameEventType : sameEventType || transition.eventType === WILDCARD;
335 });
336 this.__cache.candidates[eventName] = candidates;
337 return candidates;
338 };
339 /**
340 * All delayed transitions from the config.
341 */
342
343
344 StateNode.prototype.getDelayedTransitions = function () {
345 var _this = this;
346
347 var afterConfig = this.config.after;
348
349 if (!afterConfig) {
350 return [];
351 }
352
353 var mutateEntryExit = function (delay, i) {
354 var delayRef = utils.isFunction(delay) ? "".concat(_this.id, ":delay[").concat(i, "]") : delay;
355 var eventType = actions.after(delayRef, _this.id);
356
357 _this.onEntry.push(actions.send(eventType, {
358 delay: delay
359 }));
360
361 _this.onExit.push(actions.cancel(eventType));
362
363 return eventType;
364 };
365
366 var delayedTransitions = utils.isArray(afterConfig) ? afterConfig.map(function (transition, i) {
367 var eventType = mutateEntryExit(transition.delay, i);
368 return _tslib.__assign(_tslib.__assign({}, transition), {
369 event: eventType
370 });
371 }) : utils.flatten(Object.keys(afterConfig).map(function (delay, i) {
372 var configTransition = afterConfig[delay];
373 var resolvedTransition = utils.isString(configTransition) ? {
374 target: configTransition
375 } : configTransition;
376 var resolvedDelay = !isNaN(+delay) ? +delay : delay;
377 var eventType = mutateEntryExit(resolvedDelay, i);
378 return utils.toArray(resolvedTransition).map(function (transition) {
379 return _tslib.__assign(_tslib.__assign({}, transition), {
380 event: eventType,
381 delay: resolvedDelay
382 });
383 });
384 }));
385 return delayedTransitions.map(function (delayedTransition) {
386 var delay = delayedTransition.delay;
387 return _tslib.__assign(_tslib.__assign({}, _this.formatTransition(delayedTransition)), {
388 delay: delay
389 });
390 });
391 };
392 /**
393 * Returns the state nodes represented by the current state value.
394 *
395 * @param state The state value or State instance
396 */
397
398
399 StateNode.prototype.getStateNodes = function (state) {
400 var _a;
401
402 var _this = this;
403
404 if (!state) {
405 return [];
406 }
407
408 var stateValue = state instanceof State.State ? state.value : utils.toStateValue(state, this.delimiter);
409
410 if (utils.isString(stateValue)) {
411 var initialStateValue = this.getStateNode(stateValue).initial;
412 return initialStateValue !== undefined ? this.getStateNodes((_a = {}, _a[stateValue] = initialStateValue, _a)) : [this, this.states[stateValue]];
413 }
414
415 var subStateKeys = Object.keys(stateValue);
416 var subStateNodes = [this];
417 subStateNodes.push.apply(subStateNodes, _tslib.__spreadArray([], _tslib.__read(utils.flatten(subStateKeys.map(function (subStateKey) {
418 return _this.getStateNode(subStateKey).getStateNodes(stateValue[subStateKey]);
419 }))), false));
420 return subStateNodes;
421 };
422 /**
423 * Returns `true` if this state node explicitly handles the given event.
424 *
425 * @param event The event in question
426 */
427
428
429 StateNode.prototype.handles = function (event) {
430 var eventType = utils.getEventType(event);
431 return this.events.includes(eventType);
432 };
433 /**
434 * Resolves the given `state` to a new `State` instance relative to this machine.
435 *
436 * This ensures that `.events` and `.nextEvents` represent the correct values.
437 *
438 * @param state The state to resolve
439 */
440
441
442 StateNode.prototype.resolveState = function (state) {
443 var stateFromConfig = state instanceof State.State ? state : State.State.create(state);
444 var configuration = Array.from(stateUtils.getConfiguration([], this.getStateNodes(stateFromConfig.value)));
445 return new State.State(_tslib.__assign(_tslib.__assign({}, stateFromConfig), {
446 value: this.resolve(stateFromConfig.value),
447 configuration: configuration,
448 done: stateUtils.isInFinalState(configuration, this),
449 tags: stateUtils.getTagsFromConfiguration(configuration),
450 machine: this.machine
451 }));
452 };
453
454 StateNode.prototype.transitionLeafNode = function (stateValue, state, _event) {
455 var stateNode = this.getStateNode(stateValue);
456 var next = stateNode.next(state, _event);
457
458 if (!next || !next.transitions.length) {
459 return this.next(state, _event);
460 }
461
462 return next;
463 };
464
465 StateNode.prototype.transitionCompoundNode = function (stateValue, state, _event) {
466 var subStateKeys = Object.keys(stateValue);
467 var stateNode = this.getStateNode(subStateKeys[0]);
468
469 var next = stateNode._transition(stateValue[subStateKeys[0]], state, _event);
470
471 if (!next || !next.transitions.length) {
472 return this.next(state, _event);
473 }
474
475 return next;
476 };
477
478 StateNode.prototype.transitionParallelNode = function (stateValue, state, _event) {
479 var e_2, _a;
480
481 var transitionMap = {};
482
483 try {
484 for (var _b = _tslib.__values(Object.keys(stateValue)), _c = _b.next(); !_c.done; _c = _b.next()) {
485 var subStateKey = _c.value;
486 var subStateValue = stateValue[subStateKey];
487
488 if (!subStateValue) {
489 continue;
490 }
491
492 var subStateNode = this.getStateNode(subStateKey);
493
494 var next = subStateNode._transition(subStateValue, state, _event);
495
496 if (next) {
497 transitionMap[subStateKey] = next;
498 }
499 }
500 } catch (e_2_1) {
501 e_2 = {
502 error: e_2_1
503 };
504 } finally {
505 try {
506 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
507 } finally {
508 if (e_2) throw e_2.error;
509 }
510 }
511
512 var stateTransitions = Object.keys(transitionMap).map(function (key) {
513 return transitionMap[key];
514 });
515 var enabledTransitions = utils.flatten(stateTransitions.map(function (st) {
516 return st.transitions;
517 }));
518 var willTransition = stateTransitions.some(function (st) {
519 return st.transitions.length > 0;
520 });
521
522 if (!willTransition) {
523 return this.next(state, _event);
524 }
525
526 var configuration = utils.flatten(Object.keys(transitionMap).map(function (key) {
527 return transitionMap[key].configuration;
528 }));
529 return {
530 transitions: enabledTransitions,
531 exitSet: utils.flatten(stateTransitions.map(function (t) {
532 return t.exitSet;
533 })),
534 configuration: configuration,
535 source: state,
536 actions: utils.flatten(Object.keys(transitionMap).map(function (key) {
537 return transitionMap[key].actions;
538 }))
539 };
540 };
541
542 StateNode.prototype._transition = function (stateValue, state, _event) {
543 // leaf node
544 if (utils.isString(stateValue)) {
545 return this.transitionLeafNode(stateValue, state, _event);
546 } // hierarchical node
547
548
549 if (Object.keys(stateValue).length === 1) {
550 return this.transitionCompoundNode(stateValue, state, _event);
551 } // orthogonal node
552
553
554 return this.transitionParallelNode(stateValue, state, _event);
555 };
556
557 StateNode.prototype.getTransitionData = function (state, event) {
558 return this._transition(state.value, state, utils.toSCXMLEvent(event));
559 };
560
561 StateNode.prototype.next = function (state, _event) {
562 var e_3, _a;
563
564 var _this = this;
565
566 var eventName = _event.name;
567 var actions = [];
568 var nextStateNodes = [];
569 var selectedTransition;
570
571 try {
572 for (var _b = _tslib.__values(this.getCandidates(eventName)), _c = _b.next(); !_c.done; _c = _b.next()) {
573 var candidate = _c.value;
574 var cond = candidate.cond,
575 stateIn = candidate.in;
576 var resolvedContext = state.context;
577 var isInState = stateIn ? utils.isString(stateIn) && isStateId(stateIn) ? // Check if in state by ID
578 state.matches(utils.toStateValue(this.getStateNodeById(stateIn).path, this.delimiter)) : // Check if in state by relative grandparent
579 utils.matchesState(utils.toStateValue(stateIn, this.delimiter), utils.path(this.path.slice(0, -2))(state.value)) : true;
580 var guardPassed = false;
581
582 try {
583 guardPassed = !cond || utils.evaluateGuard(this.machine, cond, resolvedContext, _event, state);
584 } catch (err) {
585 throw new Error("Unable to evaluate guard '".concat(cond.name || cond.type, "' in transition for event '").concat(eventName, "' in state node '").concat(this.id, "':\n").concat(err.message));
586 }
587
588 if (guardPassed && isInState) {
589 if (candidate.target !== undefined) {
590 nextStateNodes = candidate.target;
591 }
592
593 actions.push.apply(actions, _tslib.__spreadArray([], _tslib.__read(candidate.actions), false));
594 selectedTransition = candidate;
595 break;
596 }
597 }
598 } catch (e_3_1) {
599 e_3 = {
600 error: e_3_1
601 };
602 } finally {
603 try {
604 if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
605 } finally {
606 if (e_3) throw e_3.error;
607 }
608 }
609
610 if (!selectedTransition) {
611 return undefined;
612 }
613
614 if (!nextStateNodes.length) {
615 return {
616 transitions: [selectedTransition],
617 exitSet: [],
618 configuration: state.value ? [this] : [],
619 source: state,
620 actions: actions
621 };
622 }
623
624 var allNextStateNodes = utils.flatten(nextStateNodes.map(function (stateNode) {
625 return _this.getRelativeStateNodes(stateNode, state.historyValue);
626 }));
627 var isInternal = !!selectedTransition.internal;
628 return {
629 transitions: [selectedTransition],
630 exitSet: isInternal ? [] : utils.flatten(nextStateNodes.map(function (targetNode) {
631 return _this.getPotentiallyReenteringNodes(targetNode);
632 })),
633 configuration: allNextStateNodes,
634 source: state,
635 actions: actions
636 };
637 }; // even though the name of this function mentions reentry nodes
638 // we are pushing its result into `exitSet`
639 // that's because what we exit might be reentered (it's an invariant of reentrancy)
640
641
642 StateNode.prototype.getPotentiallyReenteringNodes = function (targetNode) {
643 if (this.order < targetNode.order) {
644 return [this];
645 }
646
647 var nodes = [];
648 var marker = this;
649 var possibleAncestor = targetNode;
650
651 while (marker && marker !== possibleAncestor) {
652 nodes.push(marker);
653 marker = marker.parent;
654 }
655
656 if (marker !== possibleAncestor) {
657 // we never got to `possibleAncestor`, therefore the initial `marker` "escapes" it
658 // it's in a different part of the tree so no states will be reentered for such an external transition
659 return [];
660 }
661
662 nodes.push(possibleAncestor);
663 return nodes;
664 };
665
666 StateNode.prototype.getActions = function (resolvedConfig, isDone, transition, currentContext, _event, prevState, predictableExec) {
667 var e_4, _a, e_5, _b;
668
669 var _this = this;
670
671 var prevConfig = prevState ? stateUtils.getConfiguration([], this.getStateNodes(prevState.value)) : [];
672 var entrySet = new Set();
673
674 try {
675 for (var _c = _tslib.__values(Array.from(resolvedConfig).sort(function (a, b) {
676 return a.order - b.order;
677 })), _d = _c.next(); !_d.done; _d = _c.next()) {
678 var sn = _d.value;
679
680 if (!stateUtils.has(prevConfig, sn) || stateUtils.has(transition.exitSet, sn) || sn.parent && entrySet.has(sn.parent)) {
681 entrySet.add(sn);
682 }
683 }
684 } catch (e_4_1) {
685 e_4 = {
686 error: e_4_1
687 };
688 } finally {
689 try {
690 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
691 } finally {
692 if (e_4) throw e_4.error;
693 }
694 }
695
696 try {
697 for (var prevConfig_1 = _tslib.__values(prevConfig), prevConfig_1_1 = prevConfig_1.next(); !prevConfig_1_1.done; prevConfig_1_1 = prevConfig_1.next()) {
698 var sn = prevConfig_1_1.value;
699
700 if (!stateUtils.has(resolvedConfig, sn) || stateUtils.has(transition.exitSet, sn.parent)) {
701 transition.exitSet.push(sn);
702 }
703 }
704 } catch (e_5_1) {
705 e_5 = {
706 error: e_5_1
707 };
708 } finally {
709 try {
710 if (prevConfig_1_1 && !prevConfig_1_1.done && (_b = prevConfig_1.return)) _b.call(prevConfig_1);
711 } finally {
712 if (e_5) throw e_5.error;
713 }
714 }
715
716 transition.exitSet.sort(function (a, b) {
717 return b.order - a.order;
718 });
719 var entryStates = Array.from(entrySet).sort(function (a, b) {
720 return a.order - b.order;
721 });
722 var exitStates = new Set(transition.exitSet);
723 var doneEvents = utils.flatten(entryStates.map(function (sn) {
724 var events = [];
725
726 if (sn.type !== 'final') {
727 return events;
728 }
729
730 var parent = sn.parent;
731
732 if (!parent.parent) {
733 return events;
734 }
735
736 events.push(actions.done(sn.id, sn.doneData), // TODO: deprecate - final states should not emit done events for their own state.
737 actions.done(parent.id, sn.doneData ? utils.mapContext(sn.doneData, currentContext, _event) : undefined));
738 var grandparent = parent.parent;
739
740 if (grandparent.type === 'parallel') {
741 if (stateUtils.getChildren(grandparent).every(function (parentNode) {
742 return stateUtils.isInFinalState(transition.configuration, parentNode);
743 })) {
744 events.push(actions.done(grandparent.id));
745 }
746 }
747
748 return events;
749 }));
750 var entryActions = entryStates.map(function (stateNode) {
751 var entryActions = stateNode.onEntry;
752 var invokeActions = stateNode.activities.map(function (activity) {
753 return actions.start(activity);
754 });
755 return {
756 type: 'entry',
757 actions: actions.toActionObjects(predictableExec ? _tslib.__spreadArray(_tslib.__spreadArray([], _tslib.__read(entryActions), false), _tslib.__read(invokeActions), false) : _tslib.__spreadArray(_tslib.__spreadArray([], _tslib.__read(invokeActions), false), _tslib.__read(entryActions), false), _this.machine.options.actions)
758 };
759 }).concat({
760 type: 'state_done',
761 actions: doneEvents.map(function (event) {
762 return actions.raise(event);
763 })
764 });
765 var exitActions = Array.from(exitStates).map(function (stateNode) {
766 return {
767 type: 'exit',
768 actions: actions.toActionObjects(_tslib.__spreadArray(_tslib.__spreadArray([], _tslib.__read(stateNode.onExit), false), _tslib.__read(stateNode.activities.map(function (activity) {
769 return actions.stop(activity);
770 })), false), _this.machine.options.actions)
771 };
772 });
773 var actions$1 = exitActions.concat({
774 type: 'transition',
775 actions: actions.toActionObjects(transition.actions, this.machine.options.actions)
776 }).concat(entryActions);
777
778 if (isDone) {
779 var stopActions = actions.toActionObjects(utils.flatten(_tslib.__spreadArray([], _tslib.__read(resolvedConfig), false).sort(function (a, b) {
780 return b.order - a.order;
781 }).map(function (stateNode) {
782 return stateNode.onExit;
783 })), this.machine.options.actions).filter(function (action) {
784 return !utils.isRaisableAction(action);
785 });
786 return actions$1.concat({
787 type: 'stop',
788 actions: stopActions
789 });
790 }
791
792 return actions$1;
793 };
794 /**
795 * Determines the next state given the current `state` and sent `event`.
796 *
797 * @param state The current State instance or state value
798 * @param event The event that was sent at the current state
799 * @param context The current context (extended state) of the current state
800 */
801
802
803 StateNode.prototype.transition = function (state, event, context, exec) {
804 if (state === void 0) {
805 state = this.initialState;
806 }
807
808 var _event = utils.toSCXMLEvent(event);
809
810 var currentState;
811
812 if (state instanceof State.State) {
813 currentState = context === undefined ? state : this.resolveState(State.State.from(state, context));
814 } else {
815 var resolvedStateValue = utils.isString(state) ? this.resolve(utils.pathToStateValue(this.getResolvedPath(state))) : this.resolve(state);
816 var resolvedContext = context !== null && context !== void 0 ? context : this.machine.context;
817 currentState = this.resolveState(State.State.from(resolvedStateValue, resolvedContext));
818 }
819
820 if (!environment.IS_PRODUCTION && _event.name === WILDCARD) {
821 throw new Error("An event cannot have the wildcard type ('".concat(WILDCARD, "')"));
822 }
823
824 if (this.strict) {
825 if (!this.events.includes(_event.name) && !utils.isBuiltInEvent(_event.name)) {
826 throw new Error("Machine '".concat(this.id, "' does not accept event '").concat(_event.name, "'"));
827 }
828 }
829
830 var stateTransition = this._transition(currentState.value, currentState, _event) || {
831 transitions: [],
832 configuration: [],
833 exitSet: [],
834 source: currentState,
835 actions: []
836 };
837 var prevConfig = stateUtils.getConfiguration([], this.getStateNodes(currentState.value));
838 var resolvedConfig = stateTransition.configuration.length ? stateUtils.getConfiguration(prevConfig, stateTransition.configuration) : prevConfig;
839 stateTransition.configuration = _tslib.__spreadArray([], _tslib.__read(resolvedConfig), false);
840 return this.resolveTransition(stateTransition, currentState, currentState.context, exec, _event);
841 };
842
843 StateNode.prototype.resolveRaisedTransition = function (state, _event, originalEvent, predictableExec) {
844 var _a;
845
846 var currentActions = state.actions;
847 state = this.transition(state, _event, undefined, predictableExec); // Save original event to state
848 // TODO: this should be the raised event! Delete in V5 (breaking)
849
850 state._event = originalEvent;
851 state.event = originalEvent.data;
852
853 (_a = state.actions).unshift.apply(_a, _tslib.__spreadArray([], _tslib.__read(currentActions), false));
854
855 return state;
856 };
857
858 StateNode.prototype.resolveTransition = function (stateTransition, currentState, context, predictableExec, _event) {
859 var e_6, _a, e_7, _b;
860
861 var _this = this;
862
863 if (_event === void 0) {
864 _event = actions.initEvent;
865 }
866
867 var configuration = stateTransition.configuration; // Transition will "apply" if:
868 // - this is the initial state (there is no current state)
869 // - OR there are transitions
870
871 var willTransition = !currentState || stateTransition.transitions.length > 0;
872 var resolvedConfiguration = willTransition ? stateTransition.configuration : currentState ? currentState.configuration : [];
873 var isDone = stateUtils.isInFinalState(resolvedConfiguration, this);
874 var resolvedStateValue = willTransition ? stateUtils.getValue(this.machine, configuration) : undefined;
875 var historyValue = currentState ? currentState.historyValue ? currentState.historyValue : stateTransition.source ? this.machine.historyValue(currentState.value) : undefined : undefined;
876 var actionBlocks = this.getActions(new Set(resolvedConfiguration), isDone, stateTransition, context, _event, currentState, predictableExec);
877 var activities = currentState ? _tslib.__assign({}, currentState.activities) : {};
878
879 try {
880 for (var actionBlocks_1 = _tslib.__values(actionBlocks), actionBlocks_1_1 = actionBlocks_1.next(); !actionBlocks_1_1.done; actionBlocks_1_1 = actionBlocks_1.next()) {
881 var block = actionBlocks_1_1.value;
882
883 try {
884 for (var _c = (e_7 = void 0, _tslib.__values(block.actions)), _d = _c.next(); !_d.done; _d = _c.next()) {
885 var action = _d.value;
886
887 if (action.type === actionTypes.start) {
888 activities[action.activity.id || action.activity.type] = action;
889 } else if (action.type === actionTypes.stop) {
890 activities[action.activity.id || action.activity.type] = false;
891 }
892 }
893 } catch (e_7_1) {
894 e_7 = {
895 error: e_7_1
896 };
897 } finally {
898 try {
899 if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
900 } finally {
901 if (e_7) throw e_7.error;
902 }
903 }
904 }
905 } catch (e_6_1) {
906 e_6 = {
907 error: e_6_1
908 };
909 } finally {
910 try {
911 if (actionBlocks_1_1 && !actionBlocks_1_1.done && (_a = actionBlocks_1.return)) _a.call(actionBlocks_1);
912 } finally {
913 if (e_6) throw e_6.error;
914 }
915 }
916
917 var _e = _tslib.__read(actions.resolveActions(this, currentState, context, _event, actionBlocks, predictableExec, this.machine.config.predictableActionArguments || this.machine.config.preserveActionOrder), 2),
918 resolvedActions = _e[0],
919 updatedContext = _e[1];
920
921 var _f = _tslib.__read(utils.partition(resolvedActions, utils.isRaisableAction), 2),
922 raisedEvents = _f[0],
923 nonRaisedActions = _f[1];
924
925 var invokeActions = resolvedActions.filter(function (action) {
926 var _a;
927
928 return action.type === actionTypes.start && ((_a = action.activity) === null || _a === void 0 ? void 0 : _a.type) === actionTypes.invoke;
929 });
930 var children = invokeActions.reduce(function (acc, action) {
931 acc[action.activity.id] = Actor.createInvocableActor(action.activity, _this.machine, updatedContext, _event);
932 return acc;
933 }, currentState ? _tslib.__assign({}, currentState.children) : {});
934 var nextState = new State.State({
935 value: resolvedStateValue || currentState.value,
936 context: updatedContext,
937 _event: _event,
938 // Persist _sessionid between states
939 _sessionid: currentState ? currentState._sessionid : null,
940 historyValue: resolvedStateValue ? historyValue ? utils.updateHistoryValue(historyValue, resolvedStateValue) : undefined : currentState ? currentState.historyValue : undefined,
941 history: !resolvedStateValue || stateTransition.source ? currentState : undefined,
942 actions: resolvedStateValue ? nonRaisedActions : [],
943 activities: resolvedStateValue ? activities : currentState ? currentState.activities : {},
944 events: [],
945 configuration: resolvedConfiguration,
946 transitions: stateTransition.transitions,
947 children: children,
948 done: isDone,
949 tags: stateUtils.getTagsFromConfiguration(resolvedConfiguration),
950 machine: this
951 });
952 var didUpdateContext = context !== updatedContext;
953 nextState.changed = _event.name === actionTypes.update || didUpdateContext; // Dispose of penultimate histories to prevent memory leaks
954
955 var history = nextState.history;
956
957 if (history) {
958 delete history.history;
959 } // There are transient transitions if the machine is not in a final state
960 // and if some of the state nodes have transient ("always") transitions.
961
962
963 var hasAlwaysTransitions = !isDone && (this._transient || configuration.some(function (stateNode) {
964 return stateNode._transient;
965 })); // If there are no enabled transitions, check if there are transient transitions.
966 // If there are transient transitions, continue checking for more transitions
967 // because an transient transition should be triggered even if there are no
968 // enabled transitions.
969 //
970 // If we're already working on an transient transition then stop to prevent an infinite loop.
971 //
972 // Otherwise, if there are no enabled nor transient transitions, we are done.
973
974 if (!willTransition && (!hasAlwaysTransitions || _event.name === NULL_EVENT)) {
975 return nextState;
976 }
977
978 var maybeNextState = nextState;
979
980 if (!isDone) {
981 if (hasAlwaysTransitions) {
982 maybeNextState = this.resolveRaisedTransition(maybeNextState, {
983 type: actionTypes.nullEvent
984 }, _event, predictableExec);
985 }
986
987 while (raisedEvents.length) {
988 var raisedEvent = raisedEvents.shift();
989 maybeNextState = this.resolveRaisedTransition(maybeNextState, raisedEvent._event, _event, predictableExec);
990 }
991 } // Detect if state changed
992
993
994 var changed = maybeNextState.changed || (history ? !!maybeNextState.actions.length || didUpdateContext || typeof history.value !== typeof maybeNextState.value || !State.stateValuesEqual(maybeNextState.value, history.value) : undefined);
995 maybeNextState.changed = changed; // Preserve original history after raised events
996
997 maybeNextState.history = history;
998 return maybeNextState;
999 };
1000 /**
1001 * Returns the child state node from its relative `stateKey`, or throws.
1002 */
1003
1004
1005 StateNode.prototype.getStateNode = function (stateKey) {
1006 if (isStateId(stateKey)) {
1007 return this.machine.getStateNodeById(stateKey);
1008 }
1009
1010 if (!this.states) {
1011 throw new Error("Unable to retrieve child state '".concat(stateKey, "' from '").concat(this.id, "'; no child states exist."));
1012 }
1013
1014 var result = this.states[stateKey];
1015
1016 if (!result) {
1017 throw new Error("Child state '".concat(stateKey, "' does not exist on '").concat(this.id, "'"));
1018 }
1019
1020 return result;
1021 };
1022 /**
1023 * Returns the state node with the given `stateId`, or throws.
1024 *
1025 * @param stateId The state ID. The prefix "#" is removed.
1026 */
1027
1028
1029 StateNode.prototype.getStateNodeById = function (stateId) {
1030 var resolvedStateId = isStateId(stateId) ? stateId.slice(STATE_IDENTIFIER.length) : stateId;
1031
1032 if (resolvedStateId === this.id) {
1033 return this;
1034 }
1035
1036 var stateNode = this.machine.idMap[resolvedStateId];
1037
1038 if (!stateNode) {
1039 throw new Error("Child state node '#".concat(resolvedStateId, "' does not exist on machine '").concat(this.id, "'"));
1040 }
1041
1042 return stateNode;
1043 };
1044 /**
1045 * Returns the relative state node from the given `statePath`, or throws.
1046 *
1047 * @param statePath The string or string array relative path to the state node.
1048 */
1049
1050
1051 StateNode.prototype.getStateNodeByPath = function (statePath) {
1052 if (typeof statePath === 'string' && isStateId(statePath)) {
1053 try {
1054 return this.getStateNodeById(statePath.slice(1));
1055 } catch (e) {// try individual paths
1056 // throw e;
1057 }
1058 }
1059
1060 var arrayStatePath = utils.toStatePath(statePath, this.delimiter).slice();
1061 var currentStateNode = this;
1062
1063 while (arrayStatePath.length) {
1064 var key = arrayStatePath.shift();
1065
1066 if (!key.length) {
1067 break;
1068 }
1069
1070 currentStateNode = currentStateNode.getStateNode(key);
1071 }
1072
1073 return currentStateNode;
1074 };
1075 /**
1076 * Resolves a partial state value with its full representation in this machine.
1077 *
1078 * @param stateValue The partial state value to resolve.
1079 */
1080
1081
1082 StateNode.prototype.resolve = function (stateValue) {
1083 var _a;
1084
1085 var _this = this;
1086
1087 if (!stateValue) {
1088 return this.initialStateValue || EMPTY_OBJECT; // TODO: type-specific properties
1089 }
1090
1091 switch (this.type) {
1092 case 'parallel':
1093 return utils.mapValues(this.initialStateValue, function (subStateValue, subStateKey) {
1094 return subStateValue ? _this.getStateNode(subStateKey).resolve(stateValue[subStateKey] || subStateValue) : EMPTY_OBJECT;
1095 });
1096
1097 case 'compound':
1098 if (utils.isString(stateValue)) {
1099 var subStateNode = this.getStateNode(stateValue);
1100
1101 if (subStateNode.type === 'parallel' || subStateNode.type === 'compound') {
1102 return _a = {}, _a[stateValue] = subStateNode.initialStateValue, _a;
1103 }
1104
1105 return stateValue;
1106 }
1107
1108 if (!Object.keys(stateValue).length) {
1109 return this.initialStateValue || {};
1110 }
1111
1112 return utils.mapValues(stateValue, function (subStateValue, subStateKey) {
1113 return subStateValue ? _this.getStateNode(subStateKey).resolve(subStateValue) : EMPTY_OBJECT;
1114 });
1115
1116 default:
1117 return stateValue || EMPTY_OBJECT;
1118 }
1119 };
1120
1121 StateNode.prototype.getResolvedPath = function (stateIdentifier) {
1122 if (isStateId(stateIdentifier)) {
1123 var stateNode = this.machine.idMap[stateIdentifier.slice(STATE_IDENTIFIER.length)];
1124
1125 if (!stateNode) {
1126 throw new Error("Unable to find state node '".concat(stateIdentifier, "'"));
1127 }
1128
1129 return stateNode.path;
1130 }
1131
1132 return utils.toStatePath(stateIdentifier, this.delimiter);
1133 };
1134
1135 Object.defineProperty(StateNode.prototype, "initialStateValue", {
1136 get: function () {
1137 var _a;
1138
1139 if (this.__cache.initialStateValue) {
1140 return this.__cache.initialStateValue;
1141 }
1142
1143 var initialStateValue;
1144
1145 if (this.type === 'parallel') {
1146 initialStateValue = utils.mapFilterValues(this.states, function (state) {
1147 return state.initialStateValue || EMPTY_OBJECT;
1148 }, function (stateNode) {
1149 return !(stateNode.type === 'history');
1150 });
1151 } else if (this.initial !== undefined) {
1152 if (!this.states[this.initial]) {
1153 throw new Error("Initial state '".concat(this.initial, "' not found on '").concat(this.key, "'"));
1154 }
1155
1156 initialStateValue = stateUtils.isLeafNode(this.states[this.initial]) ? this.initial : (_a = {}, _a[this.initial] = this.states[this.initial].initialStateValue, _a);
1157 } else {
1158 // The finite state value of a machine without child states is just an empty object
1159 initialStateValue = {};
1160 }
1161
1162 this.__cache.initialStateValue = initialStateValue;
1163 return this.__cache.initialStateValue;
1164 },
1165 enumerable: false,
1166 configurable: true
1167 });
1168
1169 StateNode.prototype.getInitialState = function (stateValue, context) {
1170 this._init(); // TODO: this should be in the constructor (see note in constructor)
1171
1172
1173 var configuration = this.getStateNodes(stateValue);
1174 return this.resolveTransition({
1175 configuration: configuration,
1176 exitSet: [],
1177 transitions: [],
1178 source: undefined,
1179 actions: []
1180 }, undefined, context !== null && context !== void 0 ? context : this.machine.context, undefined);
1181 };
1182
1183 Object.defineProperty(StateNode.prototype, "initialState", {
1184 /**
1185 * The initial State instance, which includes all actions to be executed from
1186 * entering the initial state.
1187 */
1188 get: function () {
1189 var initialStateValue = this.initialStateValue;
1190
1191 if (!initialStateValue) {
1192 throw new Error("Cannot retrieve initial state from simple state '".concat(this.id, "'."));
1193 }
1194
1195 return this.getInitialState(initialStateValue);
1196 },
1197 enumerable: false,
1198 configurable: true
1199 });
1200 Object.defineProperty(StateNode.prototype, "target", {
1201 /**
1202 * The target state value of the history state node, if it exists. This represents the
1203 * default state value to transition to if no history value exists yet.
1204 */
1205 get: function () {
1206 var target;
1207
1208 if (this.type === 'history') {
1209 var historyConfig = this.config;
1210
1211 if (utils.isString(historyConfig.target)) {
1212 target = isStateId(historyConfig.target) ? utils.pathToStateValue(this.machine.getStateNodeById(historyConfig.target).path.slice(this.path.length - 1)) : historyConfig.target;
1213 } else {
1214 target = historyConfig.target;
1215 }
1216 }
1217
1218 return target;
1219 },
1220 enumerable: false,
1221 configurable: true
1222 });
1223 /**
1224 * Returns the leaf nodes from a state path relative to this state node.
1225 *
1226 * @param relativeStateId The relative state path to retrieve the state nodes
1227 * @param history The previous state to retrieve history
1228 * @param resolve Whether state nodes should resolve to initial child state nodes
1229 */
1230
1231 StateNode.prototype.getRelativeStateNodes = function (relativeStateId, historyValue, resolve) {
1232 if (resolve === void 0) {
1233 resolve = true;
1234 }
1235
1236 return resolve ? relativeStateId.type === 'history' ? relativeStateId.resolveHistory(historyValue) : relativeStateId.initialStateNodes : [relativeStateId];
1237 };
1238
1239 Object.defineProperty(StateNode.prototype, "initialStateNodes", {
1240 get: function () {
1241 var _this = this;
1242
1243 if (stateUtils.isLeafNode(this)) {
1244 return [this];
1245 } // Case when state node is compound but no initial state is defined
1246
1247
1248 if (this.type === 'compound' && !this.initial) {
1249 if (!environment.IS_PRODUCTION) {
1250 utils.warn(false, "Compound state node '".concat(this.id, "' has no initial state."));
1251 }
1252
1253 return [this];
1254 }
1255
1256 var initialStateNodePaths = utils.toStatePaths(this.initialStateValue);
1257 return utils.flatten(initialStateNodePaths.map(function (initialPath) {
1258 return _this.getFromRelativePath(initialPath);
1259 }));
1260 },
1261 enumerable: false,
1262 configurable: true
1263 });
1264 /**
1265 * Retrieves state nodes from a relative path to this state node.
1266 *
1267 * @param relativePath The relative path from this state node
1268 * @param historyValue
1269 */
1270
1271 StateNode.prototype.getFromRelativePath = function (relativePath) {
1272 if (!relativePath.length) {
1273 return [this];
1274 }
1275
1276 var _a = _tslib.__read(relativePath),
1277 stateKey = _a[0],
1278 childStatePath = _a.slice(1);
1279
1280 if (!this.states) {
1281 throw new Error("Cannot retrieve subPath '".concat(stateKey, "' from node with no states"));
1282 }
1283
1284 var childStateNode = this.getStateNode(stateKey);
1285
1286 if (childStateNode.type === 'history') {
1287 return childStateNode.resolveHistory();
1288 }
1289
1290 if (!this.states[stateKey]) {
1291 throw new Error("Child state '".concat(stateKey, "' does not exist on '").concat(this.id, "'"));
1292 }
1293
1294 return this.states[stateKey].getFromRelativePath(childStatePath);
1295 };
1296
1297 StateNode.prototype.historyValue = function (relativeStateValue) {
1298 if (!Object.keys(this.states).length) {
1299 return undefined;
1300 }
1301
1302 return {
1303 current: relativeStateValue || this.initialStateValue,
1304 states: utils.mapFilterValues(this.states, function (stateNode, key) {
1305 if (!relativeStateValue) {
1306 return stateNode.historyValue();
1307 }
1308
1309 var subStateValue = utils.isString(relativeStateValue) ? undefined : relativeStateValue[key];
1310 return stateNode.historyValue(subStateValue || stateNode.initialStateValue);
1311 }, function (stateNode) {
1312 return !stateNode.history;
1313 })
1314 };
1315 };
1316 /**
1317 * Resolves to the historical value(s) of the parent state node,
1318 * represented by state nodes.
1319 *
1320 * @param historyValue
1321 */
1322
1323
1324 StateNode.prototype.resolveHistory = function (historyValue) {
1325 var _this = this;
1326
1327 if (this.type !== 'history') {
1328 return [this];
1329 }
1330
1331 var parent = this.parent;
1332
1333 if (!historyValue) {
1334 var historyTarget = this.target;
1335 return historyTarget ? utils.flatten(utils.toStatePaths(historyTarget).map(function (relativeChildPath) {
1336 return parent.getFromRelativePath(relativeChildPath);
1337 })) : parent.initialStateNodes;
1338 }
1339
1340 var subHistoryValue = utils.nestedPath(parent.path, 'states')(historyValue).current;
1341
1342 if (utils.isString(subHistoryValue)) {
1343 return [parent.getStateNode(subHistoryValue)];
1344 }
1345
1346 return utils.flatten(utils.toStatePaths(subHistoryValue).map(function (subStatePath) {
1347 return _this.history === 'deep' ? parent.getFromRelativePath(subStatePath) : [parent.states[subStatePath[0]]];
1348 }));
1349 };
1350
1351 Object.defineProperty(StateNode.prototype, "stateIds", {
1352 /**
1353 * All the state node IDs of this state node and its descendant state nodes.
1354 */
1355 get: function () {
1356 var _this = this;
1357
1358 var childStateIds = utils.flatten(Object.keys(this.states).map(function (stateKey) {
1359 return _this.states[stateKey].stateIds;
1360 }));
1361 return [this.id].concat(childStateIds);
1362 },
1363 enumerable: false,
1364 configurable: true
1365 });
1366 Object.defineProperty(StateNode.prototype, "events", {
1367 /**
1368 * All the event types accepted by this state node and its descendants.
1369 */
1370 get: function () {
1371 var e_8, _a, e_9, _b;
1372
1373 if (this.__cache.events) {
1374 return this.__cache.events;
1375 }
1376
1377 var states = this.states;
1378 var events = new Set(this.ownEvents);
1379
1380 if (states) {
1381 try {
1382 for (var _c = _tslib.__values(Object.keys(states)), _d = _c.next(); !_d.done; _d = _c.next()) {
1383 var stateId = _d.value;
1384 var state = states[stateId];
1385
1386 if (state.states) {
1387 try {
1388 for (var _e = (e_9 = void 0, _tslib.__values(state.events)), _f = _e.next(); !_f.done; _f = _e.next()) {
1389 var event_1 = _f.value;
1390 events.add("".concat(event_1));
1391 }
1392 } catch (e_9_1) {
1393 e_9 = {
1394 error: e_9_1
1395 };
1396 } finally {
1397 try {
1398 if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
1399 } finally {
1400 if (e_9) throw e_9.error;
1401 }
1402 }
1403 }
1404 }
1405 } catch (e_8_1) {
1406 e_8 = {
1407 error: e_8_1
1408 };
1409 } finally {
1410 try {
1411 if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
1412 } finally {
1413 if (e_8) throw e_8.error;
1414 }
1415 }
1416 }
1417
1418 return this.__cache.events = Array.from(events);
1419 },
1420 enumerable: false,
1421 configurable: true
1422 });
1423 Object.defineProperty(StateNode.prototype, "ownEvents", {
1424 /**
1425 * All the events that have transitions directly from this state node.
1426 *
1427 * Excludes any inert events.
1428 */
1429 get: function () {
1430 var events = new Set(this.transitions.filter(function (transition) {
1431 return !(!transition.target && !transition.actions.length && transition.internal);
1432 }).map(function (transition) {
1433 return transition.eventType;
1434 }));
1435 return Array.from(events);
1436 },
1437 enumerable: false,
1438 configurable: true
1439 });
1440
1441 StateNode.prototype.resolveTarget = function (_target) {
1442 var _this = this;
1443
1444 if (_target === undefined) {
1445 // an undefined target signals that the state node should not transition from that state when receiving that event
1446 return undefined;
1447 }
1448
1449 return _target.map(function (target) {
1450 if (!utils.isString(target)) {
1451 return target;
1452 }
1453
1454 var isInternalTarget = target[0] === _this.delimiter; // If internal target is defined on machine,
1455 // do not include machine key on target
1456
1457 if (isInternalTarget && !_this.parent) {
1458 return _this.getStateNodeByPath(target.slice(1));
1459 }
1460
1461 var resolvedTarget = isInternalTarget ? _this.key + target : target;
1462
1463 if (_this.parent) {
1464 try {
1465 var targetStateNode = _this.parent.getStateNodeByPath(resolvedTarget);
1466
1467 return targetStateNode;
1468 } catch (err) {
1469 throw new Error("Invalid transition definition for state node '".concat(_this.id, "':\n").concat(err.message));
1470 }
1471 } else {
1472 return _this.getStateNodeByPath(resolvedTarget);
1473 }
1474 });
1475 };
1476
1477 StateNode.prototype.formatTransition = function (transitionConfig) {
1478 var _this = this;
1479
1480 var normalizedTarget = utils.normalizeTarget(transitionConfig.target);
1481 var internal = 'internal' in transitionConfig ? transitionConfig.internal : normalizedTarget ? normalizedTarget.some(function (_target) {
1482 return utils.isString(_target) && _target[0] === _this.delimiter;
1483 }) : true;
1484 var guards = this.machine.options.guards;
1485 var target = this.resolveTarget(normalizedTarget);
1486
1487 var transition = _tslib.__assign(_tslib.__assign({}, transitionConfig), {
1488 actions: actions.toActionObjects(utils.toArray(transitionConfig.actions)),
1489 cond: utils.toGuard(transitionConfig.cond, guards),
1490 target: target,
1491 source: this,
1492 internal: internal,
1493 eventType: transitionConfig.event,
1494 toJSON: function () {
1495 return _tslib.__assign(_tslib.__assign({}, transition), {
1496 target: transition.target ? transition.target.map(function (t) {
1497 return "#".concat(t.id);
1498 }) : undefined,
1499 source: "#".concat(_this.id)
1500 });
1501 }
1502 });
1503
1504 return transition;
1505 };
1506
1507 StateNode.prototype.formatTransitions = function () {
1508 var e_10, _a;
1509
1510 var _this = this;
1511
1512 var onConfig;
1513
1514 if (!this.config.on) {
1515 onConfig = [];
1516 } else if (Array.isArray(this.config.on)) {
1517 onConfig = this.config.on;
1518 } else {
1519 var _b = this.config.on,
1520 _c = WILDCARD,
1521 _d = _b[_c],
1522 wildcardConfigs = _d === void 0 ? [] : _d,
1523 strictTransitionConfigs_1 = _tslib.__rest(_b, [typeof _c === "symbol" ? _c : _c + ""]);
1524
1525 onConfig = utils.flatten(Object.keys(strictTransitionConfigs_1).map(function (key) {
1526 if (!environment.IS_PRODUCTION && key === NULL_EVENT) {
1527 utils.warn(false, "Empty string transition configs (e.g., `{ on: { '': ... }}`) for transient transitions are deprecated. Specify the transition in the `{ always: ... }` property instead. " + "Please check the `on` configuration for \"#".concat(_this.id, "\"."));
1528 }
1529
1530 var transitionConfigArray = utils.toTransitionConfigArray(key, strictTransitionConfigs_1[key]);
1531
1532 if (!environment.IS_PRODUCTION) {
1533 validateArrayifiedTransitions(_this, key, transitionConfigArray);
1534 }
1535
1536 return transitionConfigArray;
1537 }).concat(utils.toTransitionConfigArray(WILDCARD, wildcardConfigs)));
1538 }
1539
1540 var eventlessConfig = this.config.always ? utils.toTransitionConfigArray('', this.config.always) : [];
1541 var doneConfig = this.config.onDone ? utils.toTransitionConfigArray(String(actions.done(this.id)), this.config.onDone) : [];
1542
1543 if (!environment.IS_PRODUCTION) {
1544 utils.warn(!(this.config.onDone && !this.parent), "Root nodes cannot have an \".onDone\" transition. Please check the config of \"".concat(this.id, "\"."));
1545 }
1546
1547 var invokeConfig = utils.flatten(this.invoke.map(function (invokeDef) {
1548 var settleTransitions = [];
1549
1550 if (invokeDef.onDone) {
1551 settleTransitions.push.apply(settleTransitions, _tslib.__spreadArray([], _tslib.__read(utils.toTransitionConfigArray(String(actions.doneInvoke(invokeDef.id)), invokeDef.onDone)), false));
1552 }
1553
1554 if (invokeDef.onError) {
1555 settleTransitions.push.apply(settleTransitions, _tslib.__spreadArray([], _tslib.__read(utils.toTransitionConfigArray(String(actions.error(invokeDef.id)), invokeDef.onError)), false));
1556 }
1557
1558 return settleTransitions;
1559 }));
1560 var delayedTransitions = this.after;
1561 var formattedTransitions = utils.flatten(_tslib.__spreadArray(_tslib.__spreadArray(_tslib.__spreadArray(_tslib.__spreadArray([], _tslib.__read(doneConfig), false), _tslib.__read(invokeConfig), false), _tslib.__read(onConfig), false), _tslib.__read(eventlessConfig), false).map(function (transitionConfig) {
1562 return utils.toArray(transitionConfig).map(function (transition) {
1563 return _this.formatTransition(transition);
1564 });
1565 }));
1566
1567 try {
1568 for (var delayedTransitions_1 = _tslib.__values(delayedTransitions), delayedTransitions_1_1 = delayedTransitions_1.next(); !delayedTransitions_1_1.done; delayedTransitions_1_1 = delayedTransitions_1.next()) {
1569 var delayedTransition = delayedTransitions_1_1.value;
1570 formattedTransitions.push(delayedTransition);
1571 }
1572 } catch (e_10_1) {
1573 e_10 = {
1574 error: e_10_1
1575 };
1576 } finally {
1577 try {
1578 if (delayedTransitions_1_1 && !delayedTransitions_1_1.done && (_a = delayedTransitions_1.return)) _a.call(delayedTransitions_1);
1579 } finally {
1580 if (e_10) throw e_10.error;
1581 }
1582 }
1583
1584 return formattedTransitions;
1585 };
1586
1587 return StateNode;
1588}();
1589
1590exports.StateNode = StateNode;