interpreter.js 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var _tslib = require('./_virtual/_tslib.js');
  4. var types = require('./types.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 utils = require('./utils.js');
  10. var scheduler = require('./scheduler.js');
  11. var Actor = require('./Actor.js');
  12. var registry = require('./registry.js');
  13. var devTools = require('./devTools.js');
  14. var serviceScope = require('./serviceScope.js');
  15. var behaviors = require('./behaviors.js');
  16. var DEFAULT_SPAWN_OPTIONS = {
  17. sync: false,
  18. autoForward: false
  19. };
  20. exports.InterpreterStatus = void 0;
  21. (function (InterpreterStatus) {
  22. InterpreterStatus[InterpreterStatus["NotStarted"] = 0] = "NotStarted";
  23. InterpreterStatus[InterpreterStatus["Running"] = 1] = "Running";
  24. InterpreterStatus[InterpreterStatus["Stopped"] = 2] = "Stopped";
  25. })(exports.InterpreterStatus || (exports.InterpreterStatus = {}));
  26. var Interpreter =
  27. /*#__PURE__*/
  28. /** @class */
  29. function () {
  30. /**
  31. * Creates a new Interpreter instance (i.e., service) for the given machine with the provided options, if any.
  32. *
  33. * @param machine The machine to be interpreted
  34. * @param options Interpreter options
  35. */
  36. function Interpreter(machine, options) {
  37. if (options === void 0) {
  38. options = Interpreter.defaultOptions;
  39. }
  40. var _this = this;
  41. this.machine = machine;
  42. this.delayedEventsMap = {};
  43. this.listeners = new Set();
  44. this.contextListeners = new Set();
  45. this.stopListeners = new Set();
  46. this.doneListeners = new Set();
  47. this.eventListeners = new Set();
  48. this.sendListeners = new Set();
  49. /**
  50. * Whether the service is started.
  51. */
  52. this.initialized = false;
  53. this.status = exports.InterpreterStatus.NotStarted;
  54. this.children = new Map();
  55. this.forwardTo = new Set();
  56. this._outgoingQueue = [];
  57. /**
  58. * Alias for Interpreter.prototype.start
  59. */
  60. this.init = this.start;
  61. /**
  62. * Sends an event to the running interpreter to trigger a transition.
  63. *
  64. * An array of events (batched) can be sent as well, which will send all
  65. * batched events to the running interpreter. The listeners will be
  66. * notified only **once** when all events are processed.
  67. *
  68. * @param event The event(s) to send
  69. */
  70. this.send = function (event, payload) {
  71. if (utils.isArray(event)) {
  72. _this.batch(event);
  73. return _this.state;
  74. }
  75. var _event = utils.toSCXMLEvent(utils.toEventObject(event, payload));
  76. if (_this.status === exports.InterpreterStatus.Stopped) {
  77. // do nothing
  78. if (!environment.IS_PRODUCTION) {
  79. utils.warn(false, "Event \"".concat(_event.name, "\" was sent to stopped service \"").concat(_this.machine.id, "\". This service has already reached its final state, and will not transition.\nEvent: ").concat(JSON.stringify(_event.data)));
  80. }
  81. return _this.state;
  82. }
  83. if (_this.status !== exports.InterpreterStatus.Running && !_this.options.deferEvents) {
  84. throw new Error("Event \"".concat(_event.name, "\" was sent to uninitialized service \"").concat(_this.machine.id // tslint:disable-next-line:max-line-length
  85. , "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options.\nEvent: ").concat(JSON.stringify(_event.data)));
  86. }
  87. _this.scheduler.schedule(function () {
  88. // Forward copy of event to child actors
  89. _this.forward(_event);
  90. var nextState = _this._nextState(_event);
  91. _this.update(nextState, _event);
  92. });
  93. return _this._state; // TODO: deprecate (should return void)
  94. // tslint:disable-next-line:semicolon
  95. };
  96. this.sendTo = function (event, to, immediate) {
  97. var isParent = _this.parent && (to === types.SpecialTargets.Parent || _this.parent.id === to);
  98. var target = isParent ? _this.parent : utils.isString(to) ? to === types.SpecialTargets.Internal ? _this : _this.children.get(to) || registry.registry.get(to) : utils.isActor(to) ? to : undefined;
  99. if (!target) {
  100. if (!isParent) {
  101. throw new Error("Unable to send event to child '".concat(to, "' from service '").concat(_this.id, "'."));
  102. } // tslint:disable-next-line:no-console
  103. if (!environment.IS_PRODUCTION) {
  104. utils.warn(false, "Service '".concat(_this.id, "' has no parent: unable to send event ").concat(event.type));
  105. }
  106. return;
  107. }
  108. if ('machine' in target) {
  109. // perhaps those events should be rejected in the parent
  110. // but atm it doesn't have easy access to all of the information that is required to do it reliably
  111. if (_this.status !== exports.InterpreterStatus.Stopped || _this.parent !== target || // we need to send events to the parent from exit handlers of a machine that reached its final state
  112. _this.state.done) {
  113. // Send SCXML events to machines
  114. var scxmlEvent = _tslib.__assign(_tslib.__assign({}, event), {
  115. name: event.name === actionTypes.error ? "".concat(actions.error(_this.id)) : event.name,
  116. origin: _this.sessionId
  117. });
  118. if (!immediate && _this.machine.config.predictableActionArguments) {
  119. _this._outgoingQueue.push([target, scxmlEvent]);
  120. } else {
  121. target.send(scxmlEvent);
  122. }
  123. }
  124. } else {
  125. // Send normal events to other targets
  126. if (!immediate && _this.machine.config.predictableActionArguments) {
  127. _this._outgoingQueue.push([target, event.data]);
  128. } else {
  129. target.send(event.data);
  130. }
  131. }
  132. };
  133. this._exec = function (action, context, _event, actionFunctionMap) {
  134. if (actionFunctionMap === void 0) {
  135. actionFunctionMap = _this.machine.options.actions;
  136. }
  137. var actionOrExec = action.exec || actions.getActionFunction(action.type, actionFunctionMap);
  138. var exec = utils.isFunction(actionOrExec) ? actionOrExec : actionOrExec ? actionOrExec.exec : action.exec;
  139. if (exec) {
  140. try {
  141. return exec(context, _event.data, !_this.machine.config.predictableActionArguments ? {
  142. action: action,
  143. state: _this.state,
  144. _event: _event
  145. } : {
  146. action: action,
  147. _event: _event
  148. });
  149. } catch (err) {
  150. if (_this.parent) {
  151. _this.parent.send({
  152. type: 'xstate.error',
  153. data: err
  154. });
  155. }
  156. throw err;
  157. }
  158. }
  159. switch (action.type) {
  160. case actionTypes.raise:
  161. {
  162. // if raise action reached the interpreter then it's a delayed one
  163. var sendAction_1 = action;
  164. _this.defer(sendAction_1);
  165. break;
  166. }
  167. case actionTypes.send:
  168. var sendAction = action;
  169. if (typeof sendAction.delay === 'number') {
  170. _this.defer(sendAction);
  171. return;
  172. } else {
  173. if (sendAction.to) {
  174. _this.sendTo(sendAction._event, sendAction.to, _event === actions.initEvent);
  175. } else {
  176. _this.send(sendAction._event);
  177. }
  178. }
  179. break;
  180. case actionTypes.cancel:
  181. _this.cancel(action.sendId);
  182. break;
  183. case actionTypes.start:
  184. {
  185. if (_this.status !== exports.InterpreterStatus.Running) {
  186. return;
  187. }
  188. var activity = action.activity; // If the activity will be stopped right after it's started
  189. // (such as in transient states)
  190. // don't bother starting the activity.
  191. if ( // in v4 with `predictableActionArguments` invokes are called eagerly when the `this.state` still points to the previous state
  192. !_this.machine.config.predictableActionArguments && !_this.state.activities[activity.id || activity.type]) {
  193. break;
  194. } // Invoked services
  195. if (activity.type === types.ActionTypes.Invoke) {
  196. var invokeSource = utils.toInvokeSource(activity.src);
  197. var serviceCreator = _this.machine.options.services ? _this.machine.options.services[invokeSource.type] : undefined;
  198. var id = activity.id,
  199. data = activity.data;
  200. if (!environment.IS_PRODUCTION) {
  201. utils.warn(!('forward' in activity), // tslint:disable-next-line:max-line-length
  202. "`forward` property is deprecated (found in invocation of '".concat(activity.src, "' in in machine '").concat(_this.machine.id, "'). ") + "Please use `autoForward` instead.");
  203. }
  204. var autoForward = 'autoForward' in activity ? activity.autoForward : !!activity.forward;
  205. if (!serviceCreator) {
  206. // tslint:disable-next-line:no-console
  207. if (!environment.IS_PRODUCTION) {
  208. utils.warn(false, "No service found for invocation '".concat(activity.src, "' in machine '").concat(_this.machine.id, "'."));
  209. }
  210. return;
  211. }
  212. var resolvedData = data ? utils.mapContext(data, context, _event) : undefined;
  213. if (typeof serviceCreator === 'string') {
  214. // TODO: warn
  215. return;
  216. }
  217. var source = utils.isFunction(serviceCreator) ? serviceCreator(context, _event.data, {
  218. data: resolvedData,
  219. src: invokeSource,
  220. meta: activity.meta
  221. }) : serviceCreator;
  222. if (!source) {
  223. // TODO: warn?
  224. return;
  225. }
  226. var options = void 0;
  227. if (utils.isMachine(source)) {
  228. source = resolvedData ? source.withContext(resolvedData) : source;
  229. options = {
  230. autoForward: autoForward
  231. };
  232. }
  233. _this.spawn(source, id, options);
  234. } else {
  235. _this.spawnActivity(activity);
  236. }
  237. break;
  238. }
  239. case actionTypes.stop:
  240. {
  241. _this.stopChild(action.activity.id);
  242. break;
  243. }
  244. case actionTypes.log:
  245. var _a = action,
  246. label = _a.label,
  247. value = _a.value;
  248. if (label) {
  249. _this.logger(label, value);
  250. } else {
  251. _this.logger(value);
  252. }
  253. break;
  254. default:
  255. if (!environment.IS_PRODUCTION) {
  256. utils.warn(false, "No implementation found for action type '".concat(action.type, "'"));
  257. }
  258. break;
  259. }
  260. };
  261. var resolvedOptions = _tslib.__assign(_tslib.__assign({}, Interpreter.defaultOptions), options);
  262. var clock = resolvedOptions.clock,
  263. logger = resolvedOptions.logger,
  264. parent = resolvedOptions.parent,
  265. id = resolvedOptions.id;
  266. var resolvedId = id !== undefined ? id : machine.id;
  267. this.id = resolvedId;
  268. this.logger = logger;
  269. this.clock = clock;
  270. this.parent = parent;
  271. this.options = resolvedOptions;
  272. this.scheduler = new scheduler.Scheduler({
  273. deferEvents: this.options.deferEvents
  274. });
  275. this.sessionId = registry.registry.bookId();
  276. }
  277. Object.defineProperty(Interpreter.prototype, "initialState", {
  278. get: function () {
  279. var _this = this;
  280. if (this._initialState) {
  281. return this._initialState;
  282. }
  283. return serviceScope.provide(this, function () {
  284. _this._initialState = _this.machine.initialState;
  285. return _this._initialState;
  286. });
  287. },
  288. enumerable: false,
  289. configurable: true
  290. });
  291. Object.defineProperty(Interpreter.prototype, "state", {
  292. /**
  293. * @deprecated Use `.getSnapshot()` instead.
  294. */
  295. get: function () {
  296. if (!environment.IS_PRODUCTION) {
  297. utils.warn(this.status !== exports.InterpreterStatus.NotStarted, "Attempted to read state from uninitialized service '".concat(this.id, "'. Make sure the service is started first."));
  298. }
  299. return this._state;
  300. },
  301. enumerable: false,
  302. configurable: true
  303. });
  304. /**
  305. * Executes the actions of the given state, with that state's `context` and `event`.
  306. *
  307. * @param state The state whose actions will be executed
  308. * @param actionsConfig The action implementations to use
  309. */
  310. Interpreter.prototype.execute = function (state, actionsConfig) {
  311. var e_1, _a;
  312. try {
  313. for (var _b = _tslib.__values(state.actions), _c = _b.next(); !_c.done; _c = _b.next()) {
  314. var action = _c.value;
  315. this.exec(action, state, actionsConfig);
  316. }
  317. } catch (e_1_1) {
  318. e_1 = {
  319. error: e_1_1
  320. };
  321. } finally {
  322. try {
  323. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  324. } finally {
  325. if (e_1) throw e_1.error;
  326. }
  327. }
  328. };
  329. Interpreter.prototype.update = function (state, _event) {
  330. var e_2, _a, e_3, _b, e_4, _c, e_5, _d;
  331. var _this = this; // Attach session ID to state
  332. state._sessionid = this.sessionId; // Update state
  333. this._state = state; // Execute actions
  334. if ((!this.machine.config.predictableActionArguments || // this is currently required to execute initial actions as the `initialState` gets cached
  335. // we can't just recompute it (and execute actions while doing so) because we try to preserve identity of actors created within initial assigns
  336. _event === actions.initEvent) && this.options.execute) {
  337. this.execute(this.state);
  338. } else {
  339. var item = void 0;
  340. while (item = this._outgoingQueue.shift()) {
  341. item[0].send(item[1]);
  342. }
  343. } // Update children
  344. this.children.forEach(function (child) {
  345. _this.state.children[child.id] = child;
  346. }); // Dev tools
  347. if (this.devTools) {
  348. this.devTools.send(_event.data, state);
  349. } // Execute listeners
  350. if (state.event) {
  351. try {
  352. for (var _e = _tslib.__values(this.eventListeners), _f = _e.next(); !_f.done; _f = _e.next()) {
  353. var listener = _f.value;
  354. listener(state.event);
  355. }
  356. } catch (e_2_1) {
  357. e_2 = {
  358. error: e_2_1
  359. };
  360. } finally {
  361. try {
  362. if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
  363. } finally {
  364. if (e_2) throw e_2.error;
  365. }
  366. }
  367. }
  368. try {
  369. for (var _g = _tslib.__values(this.listeners), _h = _g.next(); !_h.done; _h = _g.next()) {
  370. var listener = _h.value;
  371. listener(state, state.event);
  372. }
  373. } catch (e_3_1) {
  374. e_3 = {
  375. error: e_3_1
  376. };
  377. } finally {
  378. try {
  379. if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
  380. } finally {
  381. if (e_3) throw e_3.error;
  382. }
  383. }
  384. try {
  385. for (var _j = _tslib.__values(this.contextListeners), _k = _j.next(); !_k.done; _k = _j.next()) {
  386. var contextListener = _k.value;
  387. contextListener(this.state.context, this.state.history ? this.state.history.context : undefined);
  388. }
  389. } catch (e_4_1) {
  390. e_4 = {
  391. error: e_4_1
  392. };
  393. } finally {
  394. try {
  395. if (_k && !_k.done && (_c = _j.return)) _c.call(_j);
  396. } finally {
  397. if (e_4) throw e_4.error;
  398. }
  399. }
  400. if (this.state.done) {
  401. // get final child state node
  402. var finalChildStateNode = state.configuration.find(function (sn) {
  403. return sn.type === 'final' && sn.parent === _this.machine;
  404. });
  405. var doneData = finalChildStateNode && finalChildStateNode.doneData ? utils.mapContext(finalChildStateNode.doneData, state.context, _event) : undefined;
  406. this._doneEvent = actions.doneInvoke(this.id, doneData);
  407. try {
  408. for (var _l = _tslib.__values(this.doneListeners), _m = _l.next(); !_m.done; _m = _l.next()) {
  409. var listener = _m.value;
  410. listener(this._doneEvent);
  411. }
  412. } catch (e_5_1) {
  413. e_5 = {
  414. error: e_5_1
  415. };
  416. } finally {
  417. try {
  418. if (_m && !_m.done && (_d = _l.return)) _d.call(_l);
  419. } finally {
  420. if (e_5) throw e_5.error;
  421. }
  422. }
  423. this._stop();
  424. this._stopChildren();
  425. registry.registry.free(this.sessionId);
  426. }
  427. };
  428. /*
  429. * Adds a listener that is notified whenever a state transition happens. The listener is called with
  430. * the next state and the event object that caused the state transition.
  431. *
  432. * @param listener The state listener
  433. */
  434. Interpreter.prototype.onTransition = function (listener) {
  435. this.listeners.add(listener); // Send current state to listener
  436. if (this.status === exports.InterpreterStatus.Running) {
  437. listener(this.state, this.state.event);
  438. }
  439. return this;
  440. };
  441. Interpreter.prototype.subscribe = function (nextListenerOrObserver, _, // TODO: error listener
  442. completeListener) {
  443. var _this = this;
  444. var observer = utils.toObserver(nextListenerOrObserver, _, completeListener);
  445. this.listeners.add(observer.next); // Send current state to listener
  446. if (this.status !== exports.InterpreterStatus.NotStarted) {
  447. observer.next(this.state);
  448. }
  449. var completeOnce = function () {
  450. _this.doneListeners.delete(completeOnce);
  451. _this.stopListeners.delete(completeOnce);
  452. observer.complete();
  453. };
  454. if (this.status === exports.InterpreterStatus.Stopped) {
  455. observer.complete();
  456. } else {
  457. this.onDone(completeOnce);
  458. this.onStop(completeOnce);
  459. }
  460. return {
  461. unsubscribe: function () {
  462. _this.listeners.delete(observer.next);
  463. _this.doneListeners.delete(completeOnce);
  464. _this.stopListeners.delete(completeOnce);
  465. }
  466. };
  467. };
  468. /**
  469. * Adds an event listener that is notified whenever an event is sent to the running interpreter.
  470. * @param listener The event listener
  471. */
  472. Interpreter.prototype.onEvent = function (listener) {
  473. this.eventListeners.add(listener);
  474. return this;
  475. };
  476. /**
  477. * Adds an event listener that is notified whenever a `send` event occurs.
  478. * @param listener The event listener
  479. */
  480. Interpreter.prototype.onSend = function (listener) {
  481. this.sendListeners.add(listener);
  482. return this;
  483. };
  484. /**
  485. * Adds a context listener that is notified whenever the state context changes.
  486. * @param listener The context listener
  487. */
  488. Interpreter.prototype.onChange = function (listener) {
  489. this.contextListeners.add(listener);
  490. return this;
  491. };
  492. /**
  493. * Adds a listener that is notified when the machine is stopped.
  494. * @param listener The listener
  495. */
  496. Interpreter.prototype.onStop = function (listener) {
  497. this.stopListeners.add(listener);
  498. return this;
  499. };
  500. /**
  501. * Adds a state listener that is notified when the statechart has reached its final state.
  502. * @param listener The state listener
  503. */
  504. Interpreter.prototype.onDone = function (listener) {
  505. if (this.status === exports.InterpreterStatus.Stopped && this._doneEvent) {
  506. listener(this._doneEvent);
  507. } else {
  508. this.doneListeners.add(listener);
  509. }
  510. return this;
  511. };
  512. /**
  513. * Removes a listener.
  514. * @param listener The listener to remove
  515. */
  516. Interpreter.prototype.off = function (listener) {
  517. this.listeners.delete(listener);
  518. this.eventListeners.delete(listener);
  519. this.sendListeners.delete(listener);
  520. this.stopListeners.delete(listener);
  521. this.doneListeners.delete(listener);
  522. this.contextListeners.delete(listener);
  523. return this;
  524. };
  525. /**
  526. * Starts the interpreter from the given state, or the initial state.
  527. * @param initialState The state to start the statechart from
  528. */
  529. Interpreter.prototype.start = function (initialState) {
  530. var _this = this;
  531. if (this.status === exports.InterpreterStatus.Running) {
  532. // Do not restart the service if it is already started
  533. return this;
  534. } // yes, it's a hack but we need the related cache to be populated for some things to work (like delayed transitions)
  535. // this is usually called by `machine.getInitialState` but if we rehydrate from a state we might bypass this call
  536. // we also don't want to call this method here as it resolves the full initial state which might involve calling assign actions
  537. // and that could potentially lead to some unwanted side-effects (even such as creating some rogue actors)
  538. this.machine._init();
  539. registry.registry.register(this.sessionId, this);
  540. this.initialized = true;
  541. this.status = exports.InterpreterStatus.Running;
  542. var resolvedState = initialState === undefined ? this.initialState : serviceScope.provide(this, function () {
  543. return State.isStateConfig(initialState) ? _this.machine.resolveState(initialState) : _this.machine.resolveState(State.State.from(initialState, _this.machine.context));
  544. });
  545. if (this.options.devTools) {
  546. this.attachDev();
  547. }
  548. this.scheduler.initialize(function () {
  549. _this.update(resolvedState, actions.initEvent);
  550. });
  551. return this;
  552. };
  553. Interpreter.prototype._stopChildren = function () {
  554. // TODO: think about converting those to actions
  555. this.children.forEach(function (child) {
  556. if (utils.isFunction(child.stop)) {
  557. child.stop();
  558. }
  559. });
  560. this.children.clear();
  561. };
  562. Interpreter.prototype._stop = function () {
  563. var e_6, _a, e_7, _b, e_8, _c, e_9, _d, e_10, _e;
  564. try {
  565. for (var _f = _tslib.__values(this.listeners), _g = _f.next(); !_g.done; _g = _f.next()) {
  566. var listener = _g.value;
  567. this.listeners.delete(listener);
  568. }
  569. } catch (e_6_1) {
  570. e_6 = {
  571. error: e_6_1
  572. };
  573. } finally {
  574. try {
  575. if (_g && !_g.done && (_a = _f.return)) _a.call(_f);
  576. } finally {
  577. if (e_6) throw e_6.error;
  578. }
  579. }
  580. try {
  581. for (var _h = _tslib.__values(this.stopListeners), _j = _h.next(); !_j.done; _j = _h.next()) {
  582. var listener = _j.value; // call listener, then remove
  583. listener();
  584. this.stopListeners.delete(listener);
  585. }
  586. } catch (e_7_1) {
  587. e_7 = {
  588. error: e_7_1
  589. };
  590. } finally {
  591. try {
  592. if (_j && !_j.done && (_b = _h.return)) _b.call(_h);
  593. } finally {
  594. if (e_7) throw e_7.error;
  595. }
  596. }
  597. try {
  598. for (var _k = _tslib.__values(this.contextListeners), _l = _k.next(); !_l.done; _l = _k.next()) {
  599. var listener = _l.value;
  600. this.contextListeners.delete(listener);
  601. }
  602. } catch (e_8_1) {
  603. e_8 = {
  604. error: e_8_1
  605. };
  606. } finally {
  607. try {
  608. if (_l && !_l.done && (_c = _k.return)) _c.call(_k);
  609. } finally {
  610. if (e_8) throw e_8.error;
  611. }
  612. }
  613. try {
  614. for (var _m = _tslib.__values(this.doneListeners), _o = _m.next(); !_o.done; _o = _m.next()) {
  615. var listener = _o.value;
  616. this.doneListeners.delete(listener);
  617. }
  618. } catch (e_9_1) {
  619. e_9 = {
  620. error: e_9_1
  621. };
  622. } finally {
  623. try {
  624. if (_o && !_o.done && (_d = _m.return)) _d.call(_m);
  625. } finally {
  626. if (e_9) throw e_9.error;
  627. }
  628. }
  629. if (!this.initialized) {
  630. // Interpreter already stopped; do nothing
  631. return this;
  632. }
  633. this.initialized = false;
  634. this.status = exports.InterpreterStatus.Stopped;
  635. this._initialState = undefined;
  636. try {
  637. // we are going to stop within the current sync frame
  638. // so we can safely just cancel this here as nothing async should be fired anyway
  639. for (var _p = _tslib.__values(Object.keys(this.delayedEventsMap)), _q = _p.next(); !_q.done; _q = _p.next()) {
  640. var key = _q.value;
  641. this.clock.clearTimeout(this.delayedEventsMap[key]);
  642. }
  643. } catch (e_10_1) {
  644. e_10 = {
  645. error: e_10_1
  646. };
  647. } finally {
  648. try {
  649. if (_q && !_q.done && (_e = _p.return)) _e.call(_p);
  650. } finally {
  651. if (e_10) throw e_10.error;
  652. }
  653. } // clear everything that might be enqueued
  654. this.scheduler.clear();
  655. this.scheduler = new scheduler.Scheduler({
  656. deferEvents: this.options.deferEvents
  657. });
  658. };
  659. /**
  660. * Stops the interpreter and unsubscribe all listeners.
  661. *
  662. * This will also notify the `onStop` listeners.
  663. */
  664. Interpreter.prototype.stop = function () {
  665. // TODO: add warning for stopping non-root interpreters
  666. var _this = this; // grab the current scheduler as it will be replaced in _stop
  667. var scheduler = this.scheduler;
  668. this._stop(); // let what is currently processed to be finished
  669. scheduler.schedule(function () {
  670. var _a;
  671. if ((_a = _this._state) === null || _a === void 0 ? void 0 : _a.done) {
  672. return;
  673. } // it feels weird to handle this here but we need to handle this even slightly "out of band"
  674. var _event = utils.toSCXMLEvent({
  675. type: 'xstate.stop'
  676. });
  677. var nextState = serviceScope.provide(_this, function () {
  678. var exitActions = utils.flatten(_tslib.__spreadArray([], _tslib.__read(_this.state.configuration), false).sort(function (a, b) {
  679. return b.order - a.order;
  680. }).map(function (stateNode) {
  681. return actions.toActionObjects(stateNode.onExit, _this.machine.options.actions);
  682. }));
  683. var _a = _tslib.__read(actions.resolveActions(_this.machine, _this.state, _this.state.context, _event, [{
  684. type: 'exit',
  685. actions: exitActions
  686. }], _this.machine.config.predictableActionArguments ? _this._exec : undefined, _this.machine.config.predictableActionArguments || _this.machine.config.preserveActionOrder), 2),
  687. resolvedActions = _a[0],
  688. updatedContext = _a[1];
  689. var newState = new State.State({
  690. value: _this.state.value,
  691. context: updatedContext,
  692. _event: _event,
  693. _sessionid: _this.sessionId,
  694. historyValue: undefined,
  695. history: _this.state,
  696. actions: resolvedActions.filter(function (action) {
  697. return !utils.isRaisableAction(action);
  698. }),
  699. activities: {},
  700. events: [],
  701. configuration: [],
  702. transitions: [],
  703. children: {},
  704. done: _this.state.done,
  705. tags: _this.state.tags,
  706. machine: _this.machine
  707. });
  708. newState.changed = true;
  709. return newState;
  710. });
  711. _this.update(nextState, _event);
  712. _this._stopChildren();
  713. registry.registry.free(_this.sessionId);
  714. });
  715. return this;
  716. };
  717. Interpreter.prototype.batch = function (events) {
  718. var _this = this;
  719. if (this.status === exports.InterpreterStatus.NotStarted && this.options.deferEvents) {
  720. // tslint:disable-next-line:no-console
  721. if (!environment.IS_PRODUCTION) {
  722. utils.warn(false, "".concat(events.length, " event(s) were sent to uninitialized service \"").concat(this.machine.id, "\" and are deferred. Make sure .start() is called for this service.\nEvent: ").concat(JSON.stringify(event)));
  723. }
  724. } else if (this.status !== exports.InterpreterStatus.Running) {
  725. throw new Error( // tslint:disable-next-line:max-line-length
  726. "".concat(events.length, " event(s) were sent to uninitialized service \"").concat(this.machine.id, "\". Make sure .start() is called for this service, or set { deferEvents: true } in the service options."));
  727. }
  728. if (!events.length) {
  729. return;
  730. }
  731. var exec = !!this.machine.config.predictableActionArguments && this._exec;
  732. this.scheduler.schedule(function () {
  733. var e_11, _a;
  734. var nextState = _this.state;
  735. var batchChanged = false;
  736. var batchedActions = [];
  737. var _loop_1 = function (event_1) {
  738. var _event = utils.toSCXMLEvent(event_1);
  739. _this.forward(_event);
  740. nextState = serviceScope.provide(_this, function () {
  741. return _this.machine.transition(nextState, _event, undefined, exec || undefined);
  742. });
  743. batchedActions.push.apply(batchedActions, _tslib.__spreadArray([], _tslib.__read(_this.machine.config.predictableActionArguments ? nextState.actions : nextState.actions.map(function (a) {
  744. return State.bindActionToState(a, nextState);
  745. })), false));
  746. batchChanged = batchChanged || !!nextState.changed;
  747. };
  748. try {
  749. for (var events_1 = _tslib.__values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
  750. var event_1 = events_1_1.value;
  751. _loop_1(event_1);
  752. }
  753. } catch (e_11_1) {
  754. e_11 = {
  755. error: e_11_1
  756. };
  757. } finally {
  758. try {
  759. if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
  760. } finally {
  761. if (e_11) throw e_11.error;
  762. }
  763. }
  764. nextState.changed = batchChanged;
  765. nextState.actions = batchedActions;
  766. _this.update(nextState, utils.toSCXMLEvent(events[events.length - 1]));
  767. });
  768. };
  769. /**
  770. * Returns a send function bound to this interpreter instance.
  771. *
  772. * @param event The event to be sent by the sender.
  773. */
  774. Interpreter.prototype.sender = function (event) {
  775. return this.send.bind(this, event);
  776. };
  777. Interpreter.prototype._nextState = function (event, exec) {
  778. var _this = this;
  779. if (exec === void 0) {
  780. exec = !!this.machine.config.predictableActionArguments && this._exec;
  781. }
  782. var _event = utils.toSCXMLEvent(event);
  783. if (_event.name.indexOf(actionTypes.errorPlatform) === 0 && !this.state.nextEvents.some(function (nextEvent) {
  784. return nextEvent.indexOf(actionTypes.errorPlatform) === 0;
  785. })) {
  786. throw _event.data.data;
  787. }
  788. var nextState = serviceScope.provide(this, function () {
  789. return _this.machine.transition(_this.state, _event, undefined, exec || undefined);
  790. });
  791. return nextState;
  792. };
  793. /**
  794. * Returns the next state given the interpreter's current state and the event.
  795. *
  796. * This is a pure method that does _not_ update the interpreter's state.
  797. *
  798. * @param event The event to determine the next state
  799. */
  800. Interpreter.prototype.nextState = function (event) {
  801. return this._nextState(event, false);
  802. };
  803. Interpreter.prototype.forward = function (event) {
  804. var e_12, _a;
  805. try {
  806. for (var _b = _tslib.__values(this.forwardTo), _c = _b.next(); !_c.done; _c = _b.next()) {
  807. var id = _c.value;
  808. var child = this.children.get(id);
  809. if (!child) {
  810. throw new Error("Unable to forward event '".concat(event, "' from interpreter '").concat(this.id, "' to nonexistant child '").concat(id, "'."));
  811. }
  812. child.send(event);
  813. }
  814. } catch (e_12_1) {
  815. e_12 = {
  816. error: e_12_1
  817. };
  818. } finally {
  819. try {
  820. if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
  821. } finally {
  822. if (e_12) throw e_12.error;
  823. }
  824. }
  825. };
  826. Interpreter.prototype.defer = function (sendAction) {
  827. var _this = this;
  828. var timerId = this.clock.setTimeout(function () {
  829. if ('to' in sendAction && sendAction.to) {
  830. _this.sendTo(sendAction._event, sendAction.to, true);
  831. } else {
  832. _this.send(sendAction._event);
  833. }
  834. }, sendAction.delay);
  835. if (sendAction.id) {
  836. this.delayedEventsMap[sendAction.id] = timerId;
  837. }
  838. };
  839. Interpreter.prototype.cancel = function (sendId) {
  840. this.clock.clearTimeout(this.delayedEventsMap[sendId]);
  841. delete this.delayedEventsMap[sendId];
  842. };
  843. Interpreter.prototype.exec = function (action, state, actionFunctionMap) {
  844. if (actionFunctionMap === void 0) {
  845. actionFunctionMap = this.machine.options.actions;
  846. }
  847. this._exec(action, state.context, state._event, actionFunctionMap);
  848. };
  849. Interpreter.prototype.removeChild = function (childId) {
  850. var _a;
  851. this.children.delete(childId);
  852. this.forwardTo.delete(childId); // this.state might not exist at the time this is called,
  853. // such as when a child is added then removed while initializing the state
  854. (_a = this.state) === null || _a === void 0 ? true : delete _a.children[childId];
  855. };
  856. Interpreter.prototype.stopChild = function (childId) {
  857. var child = this.children.get(childId);
  858. if (!child) {
  859. return;
  860. }
  861. this.removeChild(childId);
  862. if (utils.isFunction(child.stop)) {
  863. child.stop();
  864. }
  865. };
  866. Interpreter.prototype.spawn = function (entity, name, options) {
  867. if (this.status !== exports.InterpreterStatus.Running) {
  868. return Actor.createDeferredActor(entity, name);
  869. }
  870. if (utils.isPromiseLike(entity)) {
  871. return this.spawnPromise(Promise.resolve(entity), name);
  872. } else if (utils.isFunction(entity)) {
  873. return this.spawnCallback(entity, name);
  874. } else if (Actor.isSpawnedActor(entity)) {
  875. return this.spawnActor(entity, name);
  876. } else if (utils.isObservable(entity)) {
  877. return this.spawnObservable(entity, name);
  878. } else if (utils.isMachine(entity)) {
  879. return this.spawnMachine(entity, _tslib.__assign(_tslib.__assign({}, options), {
  880. id: name
  881. }));
  882. } else if (utils.isBehavior(entity)) {
  883. return this.spawnBehavior(entity, name);
  884. } else {
  885. throw new Error("Unable to spawn entity \"".concat(name, "\" of type \"").concat(typeof entity, "\"."));
  886. }
  887. };
  888. Interpreter.prototype.spawnMachine = function (machine, options) {
  889. var _this = this;
  890. if (options === void 0) {
  891. options = {};
  892. }
  893. var childService = new Interpreter(machine, _tslib.__assign(_tslib.__assign({}, this.options), {
  894. parent: this,
  895. id: options.id || machine.id
  896. }));
  897. var resolvedOptions = _tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), options);
  898. if (resolvedOptions.sync) {
  899. childService.onTransition(function (state) {
  900. _this.send(actionTypes.update, {
  901. state: state,
  902. id: childService.id
  903. });
  904. });
  905. }
  906. var actor = childService;
  907. this.children.set(childService.id, actor);
  908. if (resolvedOptions.autoForward) {
  909. this.forwardTo.add(childService.id);
  910. }
  911. childService.onDone(function (doneEvent) {
  912. _this.removeChild(childService.id);
  913. _this.send(utils.toSCXMLEvent(doneEvent, {
  914. origin: childService.id
  915. }));
  916. }).start();
  917. return actor;
  918. };
  919. Interpreter.prototype.spawnBehavior = function (behavior, id) {
  920. var actorRef = behaviors.spawnBehavior(behavior, {
  921. id: id,
  922. parent: this
  923. });
  924. this.children.set(id, actorRef);
  925. return actorRef;
  926. };
  927. Interpreter.prototype.spawnPromise = function (promise, id) {
  928. var _a;
  929. var _this = this;
  930. var canceled = false;
  931. var resolvedData;
  932. promise.then(function (response) {
  933. if (!canceled) {
  934. resolvedData = response;
  935. _this.removeChild(id);
  936. _this.send(utils.toSCXMLEvent(actions.doneInvoke(id, response), {
  937. origin: id
  938. }));
  939. }
  940. }, function (errorData) {
  941. if (!canceled) {
  942. _this.removeChild(id);
  943. var errorEvent = actions.error(id, errorData);
  944. try {
  945. // Send "error.platform.id" to this (parent).
  946. _this.send(utils.toSCXMLEvent(errorEvent, {
  947. origin: id
  948. }));
  949. } catch (error) {
  950. utils.reportUnhandledExceptionOnInvocation(errorData, error, id);
  951. if (_this.devTools) {
  952. _this.devTools.send(errorEvent, _this.state);
  953. }
  954. if (_this.machine.strict) {
  955. // it would be better to always stop the state machine if unhandled
  956. // exception/promise rejection happens but because we don't want to
  957. // break existing code so enforce it on strict mode only especially so
  958. // because documentation says that onError is optional
  959. _this.stop();
  960. }
  961. }
  962. }
  963. });
  964. var actor = (_a = {
  965. id: id,
  966. send: function () {
  967. return void 0;
  968. },
  969. subscribe: function (next, handleError, complete) {
  970. var observer = utils.toObserver(next, handleError, complete);
  971. var unsubscribed = false;
  972. promise.then(function (response) {
  973. if (unsubscribed) {
  974. return;
  975. }
  976. observer.next(response);
  977. if (unsubscribed) {
  978. return;
  979. }
  980. observer.complete();
  981. }, function (err) {
  982. if (unsubscribed) {
  983. return;
  984. }
  985. observer.error(err);
  986. });
  987. return {
  988. unsubscribe: function () {
  989. return unsubscribed = true;
  990. }
  991. };
  992. },
  993. stop: function () {
  994. canceled = true;
  995. },
  996. toJSON: function () {
  997. return {
  998. id: id
  999. };
  1000. },
  1001. getSnapshot: function () {
  1002. return resolvedData;
  1003. }
  1004. }, _a[utils.symbolObservable] = function () {
  1005. return this;
  1006. }, _a);
  1007. this.children.set(id, actor);
  1008. return actor;
  1009. };
  1010. Interpreter.prototype.spawnCallback = function (callback, id) {
  1011. var _a;
  1012. var _this = this;
  1013. var canceled = false;
  1014. var receivers = new Set();
  1015. var listeners = new Set();
  1016. var emitted;
  1017. var receive = function (e) {
  1018. emitted = e;
  1019. listeners.forEach(function (listener) {
  1020. return listener(e);
  1021. });
  1022. if (canceled) {
  1023. return;
  1024. }
  1025. _this.send(utils.toSCXMLEvent(e, {
  1026. origin: id
  1027. }));
  1028. };
  1029. var callbackStop;
  1030. try {
  1031. callbackStop = callback(receive, function (newListener) {
  1032. receivers.add(newListener);
  1033. });
  1034. } catch (err) {
  1035. this.send(actions.error(id, err));
  1036. }
  1037. if (utils.isPromiseLike(callbackStop)) {
  1038. // it turned out to be an async function, can't reliably check this before calling `callback`
  1039. // because transpiled async functions are not recognizable
  1040. return this.spawnPromise(callbackStop, id);
  1041. }
  1042. var actor = (_a = {
  1043. id: id,
  1044. send: function (event) {
  1045. return receivers.forEach(function (receiver) {
  1046. return receiver(event);
  1047. });
  1048. },
  1049. subscribe: function (next) {
  1050. var observer = utils.toObserver(next);
  1051. listeners.add(observer.next);
  1052. return {
  1053. unsubscribe: function () {
  1054. listeners.delete(observer.next);
  1055. }
  1056. };
  1057. },
  1058. stop: function () {
  1059. canceled = true;
  1060. if (utils.isFunction(callbackStop)) {
  1061. callbackStop();
  1062. }
  1063. },
  1064. toJSON: function () {
  1065. return {
  1066. id: id
  1067. };
  1068. },
  1069. getSnapshot: function () {
  1070. return emitted;
  1071. }
  1072. }, _a[utils.symbolObservable] = function () {
  1073. return this;
  1074. }, _a);
  1075. this.children.set(id, actor);
  1076. return actor;
  1077. };
  1078. Interpreter.prototype.spawnObservable = function (source, id) {
  1079. var _a;
  1080. var _this = this;
  1081. var emitted;
  1082. var subscription = source.subscribe(function (value) {
  1083. emitted = value;
  1084. _this.send(utils.toSCXMLEvent(value, {
  1085. origin: id
  1086. }));
  1087. }, function (err) {
  1088. _this.removeChild(id);
  1089. _this.send(utils.toSCXMLEvent(actions.error(id, err), {
  1090. origin: id
  1091. }));
  1092. }, function () {
  1093. _this.removeChild(id);
  1094. _this.send(utils.toSCXMLEvent(actions.doneInvoke(id), {
  1095. origin: id
  1096. }));
  1097. });
  1098. var actor = (_a = {
  1099. id: id,
  1100. send: function () {
  1101. return void 0;
  1102. },
  1103. subscribe: function (next, handleError, complete) {
  1104. return source.subscribe(next, handleError, complete);
  1105. },
  1106. stop: function () {
  1107. return subscription.unsubscribe();
  1108. },
  1109. getSnapshot: function () {
  1110. return emitted;
  1111. },
  1112. toJSON: function () {
  1113. return {
  1114. id: id
  1115. };
  1116. }
  1117. }, _a[utils.symbolObservable] = function () {
  1118. return this;
  1119. }, _a);
  1120. this.children.set(id, actor);
  1121. return actor;
  1122. };
  1123. Interpreter.prototype.spawnActor = function (actor, name) {
  1124. this.children.set(name, actor);
  1125. return actor;
  1126. };
  1127. Interpreter.prototype.spawnActivity = function (activity) {
  1128. var implementation = this.machine.options && this.machine.options.activities ? this.machine.options.activities[activity.type] : undefined;
  1129. if (!implementation) {
  1130. if (!environment.IS_PRODUCTION) {
  1131. utils.warn(false, "No implementation found for activity '".concat(activity.type, "'"));
  1132. } // tslint:disable-next-line:no-console
  1133. return;
  1134. } // Start implementation
  1135. var dispose = implementation(this.state.context, activity);
  1136. this.spawnEffect(activity.id, dispose);
  1137. };
  1138. Interpreter.prototype.spawnEffect = function (id, dispose) {
  1139. var _a;
  1140. this.children.set(id, (_a = {
  1141. id: id,
  1142. send: function () {
  1143. return void 0;
  1144. },
  1145. subscribe: function () {
  1146. return {
  1147. unsubscribe: function () {
  1148. return void 0;
  1149. }
  1150. };
  1151. },
  1152. stop: dispose || undefined,
  1153. getSnapshot: function () {
  1154. return undefined;
  1155. },
  1156. toJSON: function () {
  1157. return {
  1158. id: id
  1159. };
  1160. }
  1161. }, _a[utils.symbolObservable] = function () {
  1162. return this;
  1163. }, _a));
  1164. };
  1165. Interpreter.prototype.attachDev = function () {
  1166. var global = devTools.getGlobal();
  1167. if (this.options.devTools && global) {
  1168. if (global.__REDUX_DEVTOOLS_EXTENSION__) {
  1169. var devToolsOptions = typeof this.options.devTools === 'object' ? this.options.devTools : undefined;
  1170. this.devTools = global.__REDUX_DEVTOOLS_EXTENSION__.connect(_tslib.__assign(_tslib.__assign({
  1171. name: this.id,
  1172. autoPause: true,
  1173. stateSanitizer: function (state) {
  1174. return {
  1175. value: state.value,
  1176. context: state.context,
  1177. actions: state.actions
  1178. };
  1179. }
  1180. }, devToolsOptions), {
  1181. features: _tslib.__assign({
  1182. jump: false,
  1183. skip: false
  1184. }, devToolsOptions ? devToolsOptions.features : undefined)
  1185. }), this.machine);
  1186. this.devTools.init(this.state);
  1187. } // add XState-specific dev tooling hook
  1188. devTools.registerService(this);
  1189. }
  1190. };
  1191. Interpreter.prototype.toJSON = function () {
  1192. return {
  1193. id: this.id
  1194. };
  1195. };
  1196. Interpreter.prototype[utils.symbolObservable] = function () {
  1197. return this;
  1198. };
  1199. Interpreter.prototype.getSnapshot = function () {
  1200. if (this.status === exports.InterpreterStatus.NotStarted) {
  1201. return this.initialState;
  1202. }
  1203. return this._state;
  1204. };
  1205. /**
  1206. * The default interpreter options:
  1207. *
  1208. * - `clock` uses the global `setTimeout` and `clearTimeout` functions
  1209. * - `logger` uses the global `console.log()` method
  1210. */
  1211. Interpreter.defaultOptions = {
  1212. execute: true,
  1213. deferEvents: true,
  1214. clock: {
  1215. setTimeout: function (fn, ms) {
  1216. return setTimeout(fn, ms);
  1217. },
  1218. clearTimeout: function (id) {
  1219. return clearTimeout(id);
  1220. }
  1221. },
  1222. logger: /*#__PURE__*/console.log.bind(console),
  1223. devTools: false
  1224. };
  1225. Interpreter.interpret = interpret;
  1226. return Interpreter;
  1227. }();
  1228. var resolveSpawnOptions = function (nameOrOptions) {
  1229. if (utils.isString(nameOrOptions)) {
  1230. return _tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), {
  1231. name: nameOrOptions
  1232. });
  1233. }
  1234. return _tslib.__assign(_tslib.__assign(_tslib.__assign({}, DEFAULT_SPAWN_OPTIONS), {
  1235. name: utils.uniqueId()
  1236. }), nameOrOptions);
  1237. };
  1238. function spawn(entity, nameOrOptions) {
  1239. var resolvedOptions = resolveSpawnOptions(nameOrOptions);
  1240. return serviceScope.consume(function (service) {
  1241. if (!environment.IS_PRODUCTION) {
  1242. var isLazyEntity = utils.isMachine(entity) || utils.isFunction(entity);
  1243. utils.warn(!!service || isLazyEntity, "Attempted to spawn an Actor (ID: \"".concat(utils.isMachine(entity) ? entity.id : 'undefined', "\") outside of a service. This will have no effect."));
  1244. }
  1245. if (service) {
  1246. return service.spawn(entity, resolvedOptions.name, resolvedOptions);
  1247. } else {
  1248. return Actor.createDeferredActor(entity, resolvedOptions.name);
  1249. }
  1250. });
  1251. }
  1252. /**
  1253. * Creates a new Interpreter instance for the given machine with the provided options, if any.
  1254. *
  1255. * @param machine The machine to interpret
  1256. * @param options Interpreter options
  1257. */
  1258. function interpret(machine, options) {
  1259. var interpreter = new Interpreter(machine, options);
  1260. return interpreter;
  1261. }
  1262. exports.Interpreter = Interpreter;
  1263. exports.interpret = interpret;
  1264. exports.spawn = spawn;