StateNode.js 53 KB

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