StateNode.js 54 KB

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