xstate 5.0.0-beta.15 → 5.0.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/actions/dist/xstate-actions.cjs.js +2 -7
  2. package/actions/dist/xstate-actions.cjs.mjs +2 -7
  3. package/actions/dist/xstate-actions.development.cjs.js +2 -7
  4. package/actions/dist/xstate-actions.development.esm.js +1 -1
  5. package/actions/dist/xstate-actions.esm.js +1 -1
  6. package/actions/dist/xstate-actions.umd.min.js +1 -1
  7. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  8. package/actors/dist/xstate-actors.cjs.js +1 -1
  9. package/actors/dist/xstate-actors.development.cjs.js +1 -1
  10. package/actors/dist/xstate-actors.development.esm.js +1 -1
  11. package/actors/dist/xstate-actors.esm.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js +1 -1
  13. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  14. package/dist/{actions-98f362b9.development.esm.js → actions-13190b25.development.esm.js} +1335 -1537
  15. package/dist/{actions-d71ac253.development.cjs.js → actions-40bd643f.development.cjs.js} +1336 -1546
  16. package/dist/{actions-6884fae8.esm.js → actions-4d6514d2.esm.js} +1310 -1539
  17. package/dist/{actions-81cc7f2b.cjs.js → actions-5fb9f10d.cjs.js} +1311 -1548
  18. package/dist/declarations/src/State.d.ts +1 -1
  19. package/dist/declarations/src/StateMachine.d.ts +2 -4
  20. package/dist/declarations/src/StateNode.d.ts +4 -4
  21. package/dist/declarations/src/actions/assign.d.ts +11 -2
  22. package/dist/declarations/src/actions/cancel.d.ts +14 -3
  23. package/dist/declarations/src/actions/choose.d.ts +11 -3
  24. package/dist/declarations/src/actions/log.d.ts +22 -3
  25. package/dist/declarations/src/actions/pure.d.ts +17 -3
  26. package/dist/declarations/src/actions/raise.d.ts +5 -2
  27. package/dist/declarations/src/actions/send.d.ts +64 -22
  28. package/dist/declarations/src/actions/stop.d.ts +14 -2
  29. package/dist/declarations/src/actions.d.ts +5 -11
  30. package/dist/declarations/src/constantPrefixes.d.ts +6 -0
  31. package/dist/declarations/src/interpreter.d.ts +8 -3
  32. package/dist/declarations/src/stateUtils.d.ts +4 -8
  33. package/dist/declarations/src/types.d.ts +38 -223
  34. package/dist/declarations/src/utils.d.ts +1 -6
  35. package/dist/xstate.cjs.js +61 -52
  36. package/dist/xstate.cjs.mjs +1 -1
  37. package/dist/xstate.development.cjs.js +61 -52
  38. package/dist/xstate.development.esm.js +61 -52
  39. package/dist/xstate.esm.js +61 -52
  40. package/dist/xstate.umd.min.js +1 -1
  41. package/dist/xstate.umd.min.js.map +1 -1
  42. package/guards/dist/xstate-guards.cjs.js +1 -1
  43. package/guards/dist/xstate-guards.development.cjs.js +1 -1
  44. package/guards/dist/xstate-guards.development.esm.js +1 -1
  45. package/guards/dist/xstate-guards.esm.js +1 -1
  46. package/guards/dist/xstate-guards.umd.min.js +1 -1
  47. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  48. package/package.json +1 -1
  49. package/actions/dynamicAction.ts +0 -42
  50. package/dist/declarations/src/actionTypes.d.ts +0 -16
  51. package/dist/declarations/src/constants.d.ts +0 -5
@@ -15,12 +15,6 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
15
15
 
16
16
  // TODO: narrow this to logic from machine
17
17
 
18
- // TODO: fix last param
19
-
20
- /**
21
- * Extracts action objects that have no extra properties.
22
- */
23
-
24
18
  /**
25
19
  * The string or object representing the state value relative to the parent state node.
26
20
  *
@@ -32,25 +26,15 @@ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
32
26
 
33
27
  // TODO: possibly refactor this somehow, use even a simpler type, and maybe even make `machine.options` private or something
34
28
 
35
- let ActionTypes = /*#__PURE__*/function (ActionTypes) {
36
- ActionTypes["Stop"] = "xstate.stop";
37
- ActionTypes["Raise"] = "xstate.raise";
38
- ActionTypes["Send"] = "xstate.send";
39
- ActionTypes["Cancel"] = "xstate.cancel";
40
- ActionTypes["Assign"] = "xstate.assign";
41
- ActionTypes["After"] = "xstate.after";
42
- ActionTypes["DoneState"] = "done.state";
43
- ActionTypes["DoneInvoke"] = "done.invoke";
44
- ActionTypes["Log"] = "xstate.log";
45
- ActionTypes["Init"] = "xstate.init";
46
- ActionTypes["Invoke"] = "xstate.invoke";
47
- ActionTypes["ErrorExecution"] = "error.execution";
48
- ActionTypes["ErrorCommunication"] = "error.communication";
49
- ActionTypes["ErrorPlatform"] = "error.platform";
50
- ActionTypes["ErrorCustom"] = "xstate.error";
51
- ActionTypes["Pure"] = "xstate.pure";
52
- ActionTypes["Choose"] = "xstate.choose";
53
- return ActionTypes;
29
+ let ConstantPrefix = /*#__PURE__*/function (ConstantPrefix) {
30
+ ConstantPrefix["After"] = "xstate.after";
31
+ ConstantPrefix["DoneState"] = "done.state";
32
+ ConstantPrefix["DoneInvoke"] = "done.invoke";
33
+ ConstantPrefix["ErrorExecution"] = "error.execution";
34
+ ConstantPrefix["ErrorCommunication"] = "error.communication";
35
+ ConstantPrefix["ErrorPlatform"] = "error.platform";
36
+ ConstantPrefix["ErrorCustom"] = "xstate.error";
37
+ return ConstantPrefix;
54
38
  }({});
55
39
  let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
56
40
  SpecialTargets["Parent"] = "#_parent";
@@ -58,40 +42,19 @@ let SpecialTargets = /*#__PURE__*/function (SpecialTargets) {
58
42
  return SpecialTargets;
59
43
  }({});
60
44
 
61
- // xstate-specific action types
62
- const stop$1 = ActionTypes.Stop;
63
- const raise$1 = ActionTypes.Raise;
64
- const send$1 = ActionTypes.Send;
65
- const cancel$1 = ActionTypes.Cancel;
66
- const assign$1 = ActionTypes.Assign;
67
- const after$1 = ActionTypes.After;
68
- const doneState = ActionTypes.DoneState;
69
- const log$1 = ActionTypes.Log;
70
- const init = ActionTypes.Init;
71
- const invoke$1 = ActionTypes.Invoke;
72
- const errorExecution = ActionTypes.ErrorExecution;
73
- const errorPlatform = ActionTypes.ErrorPlatform;
74
- const error$1 = ActionTypes.ErrorCustom;
75
- const choose$1 = ActionTypes.Choose;
76
- const pure$1 = ActionTypes.Pure;
77
-
78
- var actionTypes = /*#__PURE__*/Object.freeze({
45
+ const after$1 = ConstantPrefix.After;
46
+ const doneState = ConstantPrefix.DoneState;
47
+ const errorExecution = ConstantPrefix.ErrorExecution;
48
+ const errorPlatform = ConstantPrefix.ErrorPlatform;
49
+ const error$1 = ConstantPrefix.ErrorCustom;
50
+
51
+ var constantPrefixes = /*#__PURE__*/Object.freeze({
79
52
  __proto__: null,
80
- stop: stop$1,
81
- raise: raise$1,
82
- send: send$1,
83
- cancel: cancel$1,
84
- assign: assign$1,
85
53
  after: after$1,
86
54
  doneState: doneState,
87
- log: log$1,
88
- init: init,
89
- invoke: invoke$1,
90
55
  errorExecution: errorExecution,
91
56
  errorPlatform: errorPlatform,
92
- error: error$1,
93
- choose: choose$1,
94
- pure: pure$1
57
+ error: error$1
95
58
  });
96
59
 
97
60
  const STATE_DELIMITER = '.';
@@ -99,311 +62,93 @@ const TARGETLESS_KEY = '';
99
62
  const NULL_EVENT = '';
100
63
  const STATE_IDENTIFIER = '#';
101
64
  const WILDCARD = '*';
102
-
103
- function matchesState(parentStateId, childStateId) {
104
- const parentStateValue = toStateValue(parentStateId);
105
- const childStateValue = toStateValue(childStateId);
106
- if (isString(childStateValue)) {
107
- if (isString(parentStateValue)) {
108
- return childStateValue === parentStateValue;
109
- }
110
-
111
- // Parent more specific than child
112
- return false;
113
- }
114
- if (isString(parentStateValue)) {
115
- return parentStateValue in childStateValue;
116
- }
117
- return Object.keys(parentStateValue).every(key => {
118
- if (!(key in childStateValue)) {
119
- return false;
120
- }
121
- return matchesState(parentStateValue[key], childStateValue[key]);
122
- });
123
- }
124
- function toStatePath(stateId) {
125
- try {
126
- if (isArray(stateId)) {
127
- return stateId;
128
- }
129
- return stateId.toString().split(STATE_DELIMITER);
130
- } catch (e) {
131
- throw new Error(`'${stateId}' is not a valid state path.`);
132
- }
133
- }
134
- function isStateLike(state) {
135
- return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
136
- }
137
- function toStateValue(stateValue) {
138
- if (isStateLike(stateValue)) {
139
- return stateValue.value;
140
- }
141
- if (isArray(stateValue)) {
142
- return pathToStateValue(stateValue);
143
- }
144
- if (typeof stateValue !== 'string') {
145
- return stateValue;
146
- }
147
- const statePath = toStatePath(stateValue);
148
- return pathToStateValue(statePath);
149
- }
150
- function pathToStateValue(statePath) {
151
- if (statePath.length === 1) {
152
- return statePath[0];
153
- }
154
- const value = {};
155
- let marker = value;
156
- for (let i = 0; i < statePath.length - 1; i++) {
157
- if (i === statePath.length - 2) {
158
- marker[statePath[i]] = statePath[i + 1];
65
+ const INIT_TYPE = 'xstate.init';
66
+
67
+ function resolve$8(actorContext, state, args, {
68
+ to,
69
+ event: eventOrExpr,
70
+ id,
71
+ delay
72
+ }) {
73
+ const delaysMap = state.machine.implementations.delays;
74
+ if (typeof eventOrExpr === 'string') {
75
+ throw new Error(`Only event objects may be used with sendTo; use sendTo({ type: "${eventOrExpr}" }) instead`);
76
+ }
77
+ const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
78
+ let resolvedDelay;
79
+ if (typeof delay === 'string') {
80
+ const configDelay = delaysMap && delaysMap[delay];
81
+ resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
82
+ } else {
83
+ resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
84
+ }
85
+ const resolvedTarget = typeof to === 'function' ? to(args) : to;
86
+ let targetActorRef;
87
+ if (typeof resolvedTarget === 'string') {
88
+ if (resolvedTarget === SpecialTargets.Parent) {
89
+ targetActorRef = actorContext?.self._parent;
90
+ } else if (resolvedTarget === SpecialTargets.Internal) {
91
+ targetActorRef = actorContext?.self;
92
+ } else if (resolvedTarget.startsWith('#_')) {
93
+ // SCXML compatibility: https://www.w3.org/TR/scxml/#SCXMLEventProcessor
94
+ // #_invokeid. If the target is the special term '#_invokeid', where invokeid is the invokeid of an SCXML session that the sending session has created by <invoke>, the Processor must add the event to the external queue of that session.
95
+ targetActorRef = state.children[resolvedTarget.slice(2)];
159
96
  } else {
160
- const previous = marker;
161
- marker = {};
162
- previous[statePath[i]] = marker;
97
+ targetActorRef = state.children[resolvedTarget];
163
98
  }
164
- }
165
- return value;
166
- }
167
- function mapValues(collection, iteratee) {
168
- const result = {};
169
- const collectionKeys = Object.keys(collection);
170
- for (let i = 0; i < collectionKeys.length; i++) {
171
- const key = collectionKeys[i];
172
- result[key] = iteratee(collection[key], key, collection, i);
173
- }
174
- return result;
175
- }
176
- function flatten(array) {
177
- return [].concat(...array);
178
- }
179
- function toArrayStrict(value) {
180
- if (isArray(value)) {
181
- return value;
182
- }
183
- return [value];
184
- }
185
- function toArray(value) {
186
- if (value === undefined) {
187
- return [];
188
- }
189
- return toArrayStrict(value);
190
- }
191
- function mapContext(mapper, context, event) {
192
- if (isFunction(mapper)) {
193
- return mapper({
194
- context,
195
- event
196
- });
197
- }
198
- const result = {};
199
- const args = {
200
- context,
201
- event
202
- };
203
- for (const key of Object.keys(mapper)) {
204
- const subMapper = mapper[key];
205
- if (isFunction(subMapper)) {
206
- result[key] = subMapper(args);
207
- } else {
208
- result[key] = subMapper;
99
+ if (!targetActorRef) {
100
+ throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
209
101
  }
102
+ } else {
103
+ targetActorRef = resolvedTarget || actorContext?.self;
210
104
  }
211
- return result;
105
+ return [state, {
106
+ to: targetActorRef,
107
+ event: resolvedEvent,
108
+ id,
109
+ delay: resolvedDelay
110
+ }];
212
111
  }
213
- function isPromiseLike(value) {
214
- if (value instanceof Promise) {
215
- return true;
112
+ function execute$5(actorContext, params) {
113
+ if (typeof params.delay === 'number') {
114
+ actorContext.self.delaySend(params);
115
+ return;
216
116
  }
217
- // Check if shape matches the Promise/A+ specification for a "thenable".
218
- if (value !== null && (isFunction(value) || typeof value === 'object') && isFunction(value.then)) {
219
- return true;
220
- }
221
- return false;
222
- }
223
- function isArray(value) {
224
- return Array.isArray(value);
225
- }
226
-
227
- // tslint:disable-next-line:ban-types
228
- function isFunction(value) {
229
- return typeof value === 'function';
230
- }
231
- function isString(value) {
232
- return typeof value === 'string';
233
- }
234
- function isErrorEvent(event) {
235
- return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
236
- }
237
- function toTransitionConfigArray(event, configLike) {
238
- const transitions = toArrayStrict(configLike).map(transitionLike => {
239
- if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
240
- return {
241
- target: transitionLike,
242
- event
243
- };
244
- }
245
- return {
246
- ...transitionLike,
247
- event
248
- };
117
+ const {
118
+ to,
119
+ event
120
+ } = params;
121
+ actorContext.defer(() => {
122
+ to.send(event.type === error$1 ? {
123
+ type: `${error(actorContext.self.id)}`,
124
+ data: event.data
125
+ } : event);
249
126
  });
250
- return transitions;
251
- }
252
- function normalizeTarget(target) {
253
- if (target === undefined || target === TARGETLESS_KEY) {
254
- return undefined;
255
- }
256
- return toArray(target);
257
- }
258
- function toInvokeConfig(invocable, id) {
259
- if (typeof invocable === 'object') {
260
- if ('src' in invocable) {
261
- return invocable;
262
- }
263
- if ('transition' in invocable) {
264
- return {
265
- id,
266
- src: invocable
267
- };
268
- }
269
- }
270
- return {
271
- id,
272
- src: invocable
273
- };
274
- }
275
- function toObserver(nextHandler, errorHandler, completionHandler) {
276
- const noop = () => {};
277
- const isObserver = typeof nextHandler === 'object';
278
- const self = isObserver ? nextHandler : null;
279
- return {
280
- next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
281
- error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
282
- complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
283
- };
284
- }
285
- function createInvokeId(stateNodeId, index) {
286
- return `${stateNodeId}:invocation[${index}]`;
287
- }
288
- function resolveReferencedActor(referenced) {
289
- return referenced ? 'transition' in referenced ? {
290
- src: referenced,
291
- input: undefined
292
- } : referenced : undefined;
293
- }
294
-
295
- function createDynamicAction(action, resolve) {
296
- return {
297
- type: action.type,
298
- params: action.params,
299
- resolve
300
- };
301
- }
302
- function isDynamicAction(action) {
303
- return typeof action === 'object' && action !== null && 'resolve' in action;
304
127
  }
305
128
 
306
129
  /**
307
- * Sends an event. This returns an action that will be read by an interpreter to
308
- * send the event in the next step, after the current step is finished executing.
309
- *
310
- * @deprecated Use the `sendTo(...)` action creator instead.
130
+ * Sends an event to an actor.
311
131
  *
312
- * @param eventOrExpr The event to send.
313
- * @param options Options to pass into the send event:
132
+ * @param actor The `ActorRef` to send the event to.
133
+ * @param event The event to send, or an expression that evaluates to the event to send
134
+ * @param options Send action options
314
135
  * - `id` - The unique send event identifier (used with `cancel()`).
315
136
  * - `delay` - The number of milliseconds to delay the sending of the event.
316
- * - `to` - The target of this event (by default, the machine the event was sent from).
317
137
  */
318
- function send(eventOrExpr, options) {
319
- return createDynamicAction({
320
- type: send$1,
321
- params: {
322
- to: options ? options.to : undefined,
323
- delay: options ? options.delay : undefined,
324
- event: eventOrExpr,
325
- id: options && options.id !== undefined ? options.id : isFunction(eventOrExpr) ? eventOrExpr.name : eventOrExpr.type
326
- }
327
- }, (event, {
328
- actorContext,
329
- state
330
- }) => {
331
- const params = {
332
- to: options ? options.to : undefined,
333
- delay: options ? options.delay : undefined,
334
- event: eventOrExpr,
335
- // TODO: don't auto-generate IDs here like that
336
- // there is too big chance of the ID collision
337
- id: options && options.id !== undefined ? options.id : isFunction(eventOrExpr) ? eventOrExpr.name : eventOrExpr.type
338
- };
339
- const args = {
340
- context: state.context,
341
- event,
342
- self: actorContext?.self ?? null,
343
- system: actorContext?.system
344
- };
345
- const delaysMap = state.machine.implementations.delays;
346
-
347
- // TODO: helper function for resolving Expr
348
- if (typeof eventOrExpr === 'string') {
349
- throw new Error(`Only event objects may be used with sendTo; use sendTo({ type: "${eventOrExpr}" }) instead`);
350
- }
351
- const resolvedEvent = isFunction(eventOrExpr) ? eventOrExpr(args) : eventOrExpr;
352
- let resolvedDelay;
353
- if (isString(params.delay)) {
354
- const configDelay = delaysMap && delaysMap[params.delay];
355
- resolvedDelay = isFunction(configDelay) ? configDelay(args) : configDelay;
356
- } else {
357
- resolvedDelay = isFunction(params.delay) ? params.delay(args) : params.delay;
358
- }
359
- const resolvedTarget = isFunction(params.to) ? params.to(args) : params.to;
360
- let targetActorRef;
361
- if (typeof resolvedTarget === 'string') {
362
- if (resolvedTarget === SpecialTargets.Parent) {
363
- targetActorRef = actorContext?.self._parent;
364
- } else if (resolvedTarget === SpecialTargets.Internal) {
365
- targetActorRef = actorContext?.self;
366
- } else if (resolvedTarget.startsWith('#_')) {
367
- // SCXML compatibility: https://www.w3.org/TR/scxml/#SCXMLEventProcessor
368
- // #_invokeid. If the target is the special term '#_invokeid', where invokeid is the invokeid of an SCXML session that the sending session has created by <invoke>, the Processor must add the event to the external queue of that session.
369
- targetActorRef = state.children[resolvedTarget.slice(2)];
370
- } else {
371
- targetActorRef = state.children[resolvedTarget];
372
- }
373
- if (!targetActorRef) {
374
- throw new Error(`Unable to send event to actor '${resolvedTarget}' from machine '${state.machine.id}'.`);
375
- }
376
- } else {
377
- targetActorRef = resolvedTarget || actorContext?.self;
138
+ function sendTo(to, eventOrExpr, options) {
139
+ function sendTo(_) {
140
+ {
141
+ throw new Error(`This isn't supposed to be called`);
378
142
  }
379
- const resolvedAction = {
380
- type: send$1,
381
- params: {
382
- ...params,
383
- to: targetActorRef,
384
- event: resolvedEvent,
385
- delay: resolvedDelay,
386
- internal: resolvedTarget === SpecialTargets.Internal
387
- },
388
- execute: actorCtx => {
389
- const sendAction = resolvedAction;
390
- if (typeof sendAction.params.delay === 'number') {
391
- actorCtx.self.delaySend(sendAction);
392
- return;
393
- } else {
394
- const target = sendAction.params.to;
395
- const sentEvent = sendAction.params.event;
396
- actorCtx.defer(() => {
397
- target.send(sentEvent.type === error$1 ? {
398
- type: `${error(actorCtx.self.id)}`,
399
- data: sentEvent.data
400
- } : sendAction.params.event);
401
- });
402
- }
403
- }
404
- };
405
- return [state, resolvedAction];
406
- });
143
+ }
144
+ sendTo.type = 'xstate.sendTo';
145
+ sendTo.to = to;
146
+ sendTo.event = eventOrExpr;
147
+ sendTo.id = options?.id;
148
+ sendTo.delay = options?.delay;
149
+ sendTo.resolve = resolve$8;
150
+ sendTo.execute = execute$5;
151
+ return sendTo;
407
152
  }
408
153
 
409
154
  /**
@@ -413,12 +158,8 @@ function send(eventOrExpr, options) {
413
158
  * @param options Options to pass into the send event.
414
159
  */
415
160
  function sendParent(event, options) {
416
- return send(event, {
417
- ...options,
418
- to: SpecialTargets.Parent
419
- });
161
+ return sendTo(SpecialTargets.Parent, event, options);
420
162
  }
421
-
422
163
  /**
423
164
  * Forwards (sends) an event to a specified service.
424
165
  *
@@ -436,12 +177,9 @@ function forwardTo(target, options) {
436
177
  return resolvedTarget;
437
178
  };
438
179
  }
439
- return send(({
180
+ return sendTo(target, ({
440
181
  event
441
- }) => event, {
442
- ...options,
443
- to: target
444
- });
182
+ }) => event, options);
445
183
  }
446
184
 
447
185
  /**
@@ -455,27 +193,9 @@ function escalate(errorData, options) {
455
193
  return sendParent(arg => {
456
194
  return {
457
195
  type: error$1,
458
- data: isFunction(errorData) ? errorData(arg) : errorData
196
+ data: typeof errorData === 'function' ? errorData(arg) : errorData
459
197
  };
460
- }, {
461
- ...options,
462
- to: SpecialTargets.Parent
463
- });
464
- }
465
-
466
- /**
467
- * Sends an event to an actor.
468
- *
469
- * @param actor The `ActorRef` to send the event to.
470
- * @param event The event to send, or an expression that evaluates to the event to send
471
- * @param options Send action options
472
- * @returns An XState send action object
473
- */
474
- function sendTo(actor, event, options) {
475
- return send(event, {
476
- ...options,
477
- to: actor
478
- });
198
+ }, options);
479
199
  }
480
200
 
481
201
  const cache = new WeakMap();
@@ -492,6 +212,16 @@ function memo(object, key, fn) {
492
212
  return memoizedData[key];
493
213
  }
494
214
 
215
+ function resolve$7(_, state, actionArgs, {
216
+ sendId
217
+ }) {
218
+ const resolvedSendId = typeof sendId === 'function' ? sendId(actionArgs) : sendId;
219
+ return [state, resolvedSendId];
220
+ }
221
+ function execute$4(actorContext, resolvedSendId) {
222
+ actorContext.self.cancel(resolvedSendId);
223
+ }
224
+
495
225
  /**
496
226
  * Cancels an in-flight `send(...)` action. A canceled sent action will not
497
227
  * be executed, nor will its event be sent, unless it has already been sent
@@ -499,38 +229,19 @@ function memo(object, key, fn) {
499
229
  *
500
230
  * @param sendId The `id` of the `send(...)` action to cancel.
501
231
  */
502
-
503
232
  function cancel(sendId) {
504
- return createDynamicAction({
505
- type: cancel$1,
506
- params: {
507
- sendId
233
+ function cancel(_) {
234
+ {
235
+ throw new Error(`This isn't supposed to be called`);
508
236
  }
509
- }, (event, {
510
- state,
511
- actorContext
512
- }) => {
513
- const resolvedSendId = isFunction(sendId) ? sendId({
514
- context: state.context,
515
- event,
516
- self: actorContext?.self ?? {},
517
- system: actorContext?.system
518
- }) : sendId;
519
- return [state, {
520
- type: 'xstate.cancel',
521
- params: {
522
- sendId: resolvedSendId
523
- },
524
- execute: actorCtx => {
525
- const interpreter = actorCtx.self;
526
- interpreter.cancel(resolvedSendId);
527
- }
528
- }];
529
- });
237
+ }
238
+ cancel.type = 'xstate.cancel';
239
+ cancel.sendId = sendId;
240
+ cancel.resolve = resolve$7;
241
+ cancel.execute = execute$4;
242
+ return cancel;
530
243
  }
531
244
 
532
- const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
533
-
534
245
  class Mailbox {
535
246
  constructor(_process) {
536
247
  this._process = _process;
@@ -598,528 +309,147 @@ class Mailbox {
598
309
  }
599
310
  }
600
311
 
601
- function createSystem() {
602
- let sessionIdCounter = 0;
603
- const children = new Map();
604
- const keyedActors = new Map();
605
- const reverseKeyedActors = new WeakMap();
606
- const system = {
607
- _bookId: () => `x:${sessionIdCounter++}`,
608
- _register: (sessionId, actorRef) => {
609
- children.set(sessionId, actorRef);
610
- return sessionId;
611
- },
612
- _unregister: actorRef => {
613
- children.delete(actorRef.sessionId);
614
- const systemId = reverseKeyedActors.get(actorRef);
615
- if (systemId !== undefined) {
616
- keyedActors.delete(systemId);
617
- reverseKeyedActors.delete(actorRef);
618
- }
312
+ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
313
+
314
+ /**
315
+ * Returns actor logic from a transition function and its initial state.
316
+ *
317
+ * A transition function is a function that takes the current state and an event and returns the next state.
318
+ *
319
+ * @param transition The transition function that returns the next state given the current state and event.
320
+ * @param initialState The initial state of the transition function.
321
+ * @returns Actor logic
322
+ */
323
+ function fromTransition(transition, initialState) {
324
+ const logic = {
325
+ config: transition,
326
+ transition: (state, event, actorContext) => {
327
+ return transition(state, event, actorContext);
619
328
  },
620
- get: systemId => {
621
- return keyedActors.get(systemId);
329
+ getInitialState: (_, input) => {
330
+ return typeof initialState === 'function' ? initialState({
331
+ input
332
+ }) : initialState;
622
333
  },
623
- _set: (systemId, actorRef) => {
624
- const existing = keyedActors.get(systemId);
625
- if (existing && existing !== actorRef) {
626
- throw new Error(`Actor with system ID '${systemId}' already exists.`);
627
- }
628
- keyedActors.set(systemId, actorRef);
629
- reverseKeyedActors.set(actorRef, systemId);
630
- }
334
+ getSnapshot: state => state,
335
+ getPersistedState: state => state,
336
+ restoreState: state => state
631
337
  };
632
- return system;
338
+ return logic;
633
339
  }
634
340
 
635
- let ActorStatus = /*#__PURE__*/function (ActorStatus) {
636
- ActorStatus[ActorStatus["NotStarted"] = 0] = "NotStarted";
637
- ActorStatus[ActorStatus["Running"] = 1] = "Running";
638
- ActorStatus[ActorStatus["Stopped"] = 2] = "Stopped";
639
- return ActorStatus;
640
- }({});
641
- const defaultOptions = {
642
- deferEvents: true,
643
- clock: {
644
- setTimeout: (fn, ms) => {
645
- return setTimeout(fn, ms);
341
+ const resolveEventType = '$$xstate.resolve';
342
+ const rejectEventType = '$$xstate.reject';
343
+ function fromPromise(
344
+ // TODO: add types
345
+ promiseCreator) {
346
+ // TODO: add event types, consider making the `PromiseEvent` a private type or smth alike
347
+ const logic = {
348
+ config: promiseCreator,
349
+ transition: (state, event) => {
350
+ if (state.status !== 'active') {
351
+ return state;
352
+ }
353
+ switch (event.type) {
354
+ case resolveEventType:
355
+ return {
356
+ ...state,
357
+ status: 'done',
358
+ data: event.data,
359
+ input: undefined
360
+ };
361
+ case rejectEventType:
362
+ return {
363
+ ...state,
364
+ status: 'error',
365
+ data: event.data,
366
+ input: undefined
367
+ };
368
+ case stopSignalType:
369
+ return {
370
+ ...state,
371
+ status: 'canceled',
372
+ input: undefined
373
+ };
374
+ default:
375
+ return state;
376
+ }
646
377
  },
647
- clearTimeout: id => {
648
- return clearTimeout(id);
649
- }
650
- },
651
- logger: console.log.bind(console),
652
- devTools: false
653
- };
654
- class Interpreter {
655
- /**
656
- * The current state of the interpreted logic.
657
- */
658
-
659
- /**
660
- * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions.
661
- */
662
-
663
- /**
664
- * The unique identifier for this actor relative to its parent.
665
- */
666
-
667
- /**
668
- * Whether the service is started.
669
- */
670
-
671
- // Actor Ref
672
-
673
- // TODO: add typings for system
674
-
675
- /**
676
- * The globally unique process ID for this invocation.
677
- */
678
-
679
- /**
680
- * Creates a new Interpreter instance (i.e., service) for the given logic with the provided options, if any.
681
- *
682
- * @param logic The logic to be interpreted
683
- * @param options Interpreter options
684
- */
685
- constructor(logic, options) {
686
- this.logic = logic;
687
- this._state = void 0;
688
- this.clock = void 0;
689
- this.options = void 0;
690
- this.id = void 0;
691
- this.mailbox = new Mailbox(this._process.bind(this));
692
- this.delayedEventsMap = {};
693
- this.observers = new Set();
694
- this.logger = void 0;
695
- this.status = ActorStatus.NotStarted;
696
- this._parent = void 0;
697
- this.ref = void 0;
698
- this._actorContext = void 0;
699
- this._systemId = void 0;
700
- this.sessionId = void 0;
701
- this.system = void 0;
702
- this._doneEvent = void 0;
703
- this.src = void 0;
704
- this._deferred = [];
705
- const resolvedOptions = {
706
- ...defaultOptions,
707
- ...options
708
- };
709
- const {
710
- clock,
711
- logger,
712
- parent,
713
- id,
714
- systemId
715
- } = resolvedOptions;
716
- const self = this;
717
- this.system = parent?.system ?? createSystem();
718
- if (systemId) {
719
- this._systemId = systemId;
720
- this.system._set(systemId, this);
721
- }
722
- this.sessionId = this.system._bookId();
723
- this.id = id ?? this.sessionId;
724
- this.logger = logger;
725
- this.clock = clock;
726
- this._parent = parent;
727
- this.options = resolvedOptions;
728
- this.src = resolvedOptions.src;
729
- this.ref = this;
730
- this._actorContext = {
378
+ start: (state, {
731
379
  self,
732
- id: this.id,
733
- sessionId: this.sessionId,
734
- logger: this.logger,
735
- defer: fn => {
736
- this._deferred.push(fn);
737
- },
738
- system: this.system,
739
- stopChild: child => {
740
- if (child._parent !== this) {
741
- throw new Error(`Cannot stop child actor ${child.id} of ${this.id} because it is not a child`);
742
- }
743
- child._stop();
380
+ system
381
+ }) => {
382
+ // TODO: determine how to allow customizing this so that promises
383
+ // can be restarted if necessary
384
+ if (state.status !== 'active') {
385
+ return;
744
386
  }
745
- };
746
-
747
- // Ensure that the send method is bound to this interpreter instance
748
- // if destructured
749
- this.send = this.send.bind(this);
750
- this._initState();
751
- }
752
- _initState() {
753
- this._state = this.options.state ? this.logic.restoreState ? this.logic.restoreState(this.options.state, this._actorContext) : this.options.state : this.logic.getInitialState(this._actorContext, this.options?.input);
754
- }
755
-
756
- // array of functions to defer
387
+ const resolvedPromise = Promise.resolve(promiseCreator({
388
+ input: state.input,
389
+ system
390
+ }));
391
+ resolvedPromise.then(response => {
392
+ // TODO: remove this condition once dead letter queue lands
393
+ if (self._state.status !== 'active') {
394
+ return;
395
+ }
396
+ self.send({
397
+ type: resolveEventType,
398
+ data: response
399
+ });
400
+ }, errorData => {
401
+ // TODO: remove this condition once dead letter queue lands
402
+ if (self._state.status !== 'active') {
403
+ return;
404
+ }
405
+ self.send({
406
+ type: rejectEventType,
407
+ data: errorData
408
+ });
409
+ });
410
+ },
411
+ getInitialState: (_, input) => {
412
+ return {
413
+ status: 'active',
414
+ data: undefined,
415
+ input
416
+ };
417
+ },
418
+ getSnapshot: state => state.data,
419
+ getStatus: state => state,
420
+ getPersistedState: state => state,
421
+ restoreState: state => state
422
+ };
423
+ return logic;
424
+ }
757
425
 
758
- update(state) {
759
- // Update state
760
- this._state = state;
761
- const snapshot = this.getSnapshot();
426
+ // TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
427
+ function fromObservable(observableCreator) {
428
+ const nextEventType = '$$xstate.next';
429
+ const errorEventType = '$$xstate.error';
430
+ const completeEventType = '$$xstate.complete';
762
431
 
763
- // Execute deferred effects
764
- let deferredFn;
765
- while (deferredFn = this._deferred.shift()) {
766
- deferredFn();
767
- }
768
- for (const observer of this.observers) {
769
- observer.next?.(snapshot);
770
- }
771
- const status = this.logic.getStatus?.(state);
772
- switch (status?.status) {
773
- case 'done':
774
- this._stopProcedure();
775
- this._doneEvent = doneInvoke(this.id, status.data);
776
- this._parent?.send(this._doneEvent);
777
- this._complete();
778
- break;
779
- case 'error':
780
- this._stopProcedure();
781
- this._parent?.send(error(this.id, status.data));
782
- this._error(status.data);
783
- break;
784
- }
785
- }
786
- subscribe(nextListenerOrObserver, errorListener, completeListener) {
787
- const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
788
- this.observers.add(observer);
789
- if (this.status === ActorStatus.Stopped) {
790
- observer.complete?.();
791
- this.observers.delete(observer);
792
- }
793
- return {
794
- unsubscribe: () => {
795
- this.observers.delete(observer);
796
- }
797
- };
798
- }
799
-
800
- /**
801
- * Starts the interpreter from the initial state
802
- */
803
- start() {
804
- if (this.status === ActorStatus.Running) {
805
- // Do not restart the service if it is already started
806
- return this;
807
- }
808
- this.system._register(this.sessionId, this);
809
- if (this._systemId) {
810
- this.system._set(this._systemId, this);
811
- }
812
- this.status = ActorStatus.Running;
813
- if (this.logic.start) {
814
- this.logic.start(this._state, this._actorContext);
815
- }
816
-
817
- // TODO: this notifies all subscribers but usually this is redundant
818
- // there is no real change happening here
819
- // we need to rethink if this needs to be refactored
820
- this.update(this._state);
821
- if (this.options.devTools) {
822
- this.attachDevTools();
823
- }
824
- this.mailbox.start();
825
- return this;
826
- }
827
- _process(event) {
828
- try {
829
- const nextState = this.logic.transition(this._state, event, this._actorContext);
830
- this.update(nextState);
831
- if (event.type === stopSignalType) {
832
- this._stopProcedure();
833
- this._complete();
834
- }
835
- } catch (err) {
836
- // TODO: properly handle errors
837
- if (this.observers.size > 0) {
838
- this.observers.forEach(observer => {
839
- observer.error?.(err);
840
- });
841
- this.stop();
842
- } else {
843
- throw err;
844
- }
845
- }
846
- }
847
- _stop() {
848
- if (this.status === ActorStatus.Stopped) {
849
- return this;
850
- }
851
- this.mailbox.clear();
852
- if (this.status === ActorStatus.NotStarted) {
853
- this.status = ActorStatus.Stopped;
854
- return this;
855
- }
856
- this.mailbox.enqueue({
857
- type: stopSignalType
858
- });
859
- return this;
860
- }
861
-
862
- /**
863
- * Stops the interpreter and unsubscribe all listeners.
864
- */
865
- stop() {
866
- if (this._parent) {
867
- throw new Error('A non-root actor cannot be stopped directly.');
868
- }
869
- return this._stop();
870
- }
871
- _complete() {
872
- for (const observer of this.observers) {
873
- observer.complete?.();
874
- }
875
- this.observers.clear();
876
- }
877
- _error(data) {
878
- for (const observer of this.observers) {
879
- observer.error?.(data);
880
- }
881
- this.observers.clear();
882
- }
883
- _stopProcedure() {
884
- if (this.status !== ActorStatus.Running) {
885
- // Interpreter already stopped; do nothing
886
- return this;
887
- }
888
-
889
- // Cancel all delayed events
890
- for (const key of Object.keys(this.delayedEventsMap)) {
891
- this.clock.clearTimeout(this.delayedEventsMap[key]);
892
- }
893
-
894
- // TODO: mailbox.reset
895
- this.mailbox.clear();
896
- // TODO: after `stop` we must prepare ourselves for receiving events again
897
- // events sent *after* stop signal must be queued
898
- // it seems like this should be the common behavior for all of our consumers
899
- // so perhaps this should be unified somehow for all of them
900
- this.mailbox = new Mailbox(this._process.bind(this));
901
- this.status = ActorStatus.Stopped;
902
- this.system._unregister(this);
903
- return this;
904
- }
905
-
906
- /**
907
- * Sends an event to the running interpreter to trigger a transition.
908
- *
909
- * @param event The event to send
910
- */
911
- send(event) {
912
- if (typeof event === 'string') {
913
- throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
914
- }
915
- if (this.status === ActorStatus.Stopped) {
916
- // do nothing
917
- {
918
- const eventString = JSON.stringify(event);
919
- console.warn(`Event "${event.type.toString()}" was sent to stopped actor "${this.id} (${this.sessionId})". This actor has already reached its final state, and will not transition.\nEvent: ${eventString}`);
920
- }
921
- return;
922
- }
923
- if (this.status !== ActorStatus.Running && !this.options.deferEvents) {
924
- throw new Error(`Event "${event.type}" was sent to uninitialized actor "${this.id
925
- // tslint:disable-next-line:max-line-length
926
- }". Make sure .start() is called for this actor, or set { deferEvents: true } in the actor options.\nEvent: ${JSON.stringify(event)}`);
927
- }
928
- this.mailbox.enqueue(event);
929
- }
930
-
931
- // TODO: make private (and figure out a way to do this within the machine)
932
- delaySend(sendAction) {
933
- this.delayedEventsMap[sendAction.params.id] = this.clock.setTimeout(() => {
934
- if ('to' in sendAction.params && sendAction.params.to) {
935
- sendAction.params.to.send(sendAction.params.event);
936
- } else {
937
- this.send(sendAction.params.event);
938
- }
939
- }, sendAction.params.delay);
940
- }
941
-
942
- // TODO: make private (and figure out a way to do this within the machine)
943
- cancel(sendId) {
944
- this.clock.clearTimeout(this.delayedEventsMap[sendId]);
945
- delete this.delayedEventsMap[sendId];
946
- }
947
- attachDevTools() {
948
- const {
949
- devTools
950
- } = this.options;
951
- if (devTools) {
952
- const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : devToolsAdapter;
953
- resolvedDevToolsAdapter(this);
954
- }
955
- }
956
- toJSON() {
957
- return {
958
- id: this.id
959
- };
960
- }
961
- getPersistedState() {
962
- return this.logic.getPersistedState?.(this._state);
963
- }
964
- [symbolObservable]() {
965
- return this;
966
- }
967
- getSnapshot() {
968
- return this.logic.getSnapshot ? this.logic.getSnapshot(this._state) : this._state;
969
- }
970
- }
971
-
972
- /**
973
- * Creates a new Interpreter instance for the given machine with the provided options, if any.
974
- *
975
- * @param machine The machine to interpret
976
- * @param options Interpreter options
977
- */
978
-
979
- function interpret(logic, options) {
980
- const interpreter = new Interpreter(logic, options);
981
- return interpreter;
982
- }
983
-
984
- /**
985
- * Returns actor logic from a transition function and its initial state.
986
- *
987
- * A transition function is a function that takes the current state and an event and returns the next state.
988
- *
989
- * @param transition The transition function that returns the next state given the current state and event.
990
- * @param initialState The initial state of the transition function.
991
- * @returns Actor logic
992
- */
993
- function fromTransition(transition, initialState) {
994
- const logic = {
995
- config: transition,
996
- transition: (state, event, actorContext) => {
997
- return transition(state, event, actorContext);
998
- },
999
- getInitialState: (_, input) => {
1000
- return typeof initialState === 'function' ? initialState({
1001
- input
1002
- }) : initialState;
1003
- },
1004
- getSnapshot: state => state,
1005
- getPersistedState: state => state,
1006
- restoreState: state => state
1007
- };
1008
- return logic;
1009
- }
1010
-
1011
- const resolveEventType = '$$xstate.resolve';
1012
- const rejectEventType = '$$xstate.reject';
1013
- function fromPromise(
1014
- // TODO: add types
1015
- promiseCreator) {
1016
- // TODO: add event types, consider making the `PromiseEvent` a private type or smth alike
432
+ // TODO: add event types
1017
433
  const logic = {
1018
- config: promiseCreator,
1019
- transition: (state, event) => {
434
+ config: observableCreator,
435
+ transition: (state, event, {
436
+ self,
437
+ id,
438
+ defer
439
+ }) => {
1020
440
  if (state.status !== 'active') {
1021
441
  return state;
1022
442
  }
1023
443
  switch (event.type) {
1024
- case resolveEventType:
1025
- return {
1026
- ...state,
1027
- status: 'done',
1028
- data: event.data,
1029
- input: undefined
1030
- };
1031
- case rejectEventType:
1032
- return {
1033
- ...state,
1034
- status: 'error',
1035
- data: event.data,
1036
- input: undefined
1037
- };
1038
- case stopSignalType:
1039
- return {
1040
- ...state,
1041
- status: 'canceled',
1042
- input: undefined
1043
- };
1044
- default:
1045
- return state;
1046
- }
1047
- },
1048
- start: (state, {
1049
- self,
1050
- system
1051
- }) => {
1052
- // TODO: determine how to allow customizing this so that promises
1053
- // can be restarted if necessary
1054
- if (state.status !== 'active') {
1055
- return;
1056
- }
1057
- const resolvedPromise = Promise.resolve(promiseCreator({
1058
- input: state.input,
1059
- system
1060
- }));
1061
- resolvedPromise.then(response => {
1062
- // TODO: remove this condition once dead letter queue lands
1063
- if (self._state.status !== 'active') {
1064
- return;
1065
- }
1066
- self.send({
1067
- type: resolveEventType,
1068
- data: response
1069
- });
1070
- }, errorData => {
1071
- // TODO: remove this condition once dead letter queue lands
1072
- if (self._state.status !== 'active') {
1073
- return;
1074
- }
1075
- self.send({
1076
- type: rejectEventType,
1077
- data: errorData
1078
- });
1079
- });
1080
- },
1081
- getInitialState: (_, input) => {
1082
- return {
1083
- status: 'active',
1084
- data: undefined,
1085
- input
1086
- };
1087
- },
1088
- getSnapshot: state => state.data,
1089
- getStatus: state => state,
1090
- getPersistedState: state => state,
1091
- restoreState: state => state
1092
- };
1093
- return logic;
1094
- }
1095
-
1096
- // TODO: this likely shouldn't accept TEvent, observable actor doesn't accept external events
1097
- function fromObservable(observableCreator) {
1098
- const nextEventType = '$$xstate.next';
1099
- const errorEventType = '$$xstate.error';
1100
- const completeEventType = '$$xstate.complete';
1101
-
1102
- // TODO: add event types
1103
- const logic = {
1104
- config: observableCreator,
1105
- transition: (state, event, {
1106
- self,
1107
- id,
1108
- defer
1109
- }) => {
1110
- if (state.status !== 'active') {
1111
- return state;
1112
- }
1113
- switch (event.type) {
1114
- case nextEventType:
1115
- // match the exact timing of events sent by machines
1116
- // send actions are not executed immediately
1117
- defer(() => {
1118
- self._parent?.send({
1119
- type: `xstate.snapshot.${id}`,
1120
- data: event.data
1121
- });
1122
- });
444
+ case nextEventType:
445
+ // match the exact timing of events sent by machines
446
+ // send actions are not executed immediately
447
+ defer(() => {
448
+ self._parent?.send({
449
+ type: `xstate.snapshot.${id}`,
450
+ data: event.data
451
+ });
452
+ });
1123
453
  return {
1124
454
  ...state,
1125
455
  data: event.data
@@ -1312,208 +642,770 @@ function fromEventObservable(lazyObservable) {
1312
642
  return logic;
1313
643
  }
1314
644
 
1315
- function fromCallback(invokeCallback) {
1316
- const logic = {
1317
- config: invokeCallback,
1318
- start: (_state, {
1319
- self
1320
- }) => {
1321
- self.send({
1322
- type: startSignalType
1323
- });
1324
- },
1325
- transition: (state, event, {
1326
- self,
1327
- id,
1328
- system
1329
- }) => {
1330
- if (event.type === startSignalType) {
1331
- const sender = eventForParent => {
1332
- if (state.canceled) {
1333
- return;
1334
- }
1335
- self._parent?.send(eventForParent);
1336
- };
1337
- const receiver = newListener => {
1338
- state.receivers.add(newListener);
1339
- };
1340
- state.dispose = invokeCallback(sender, receiver, {
1341
- input: state.input,
1342
- system
1343
- });
1344
- if (isPromiseLike(state.dispose)) {
1345
- state.dispose.then(resolved => {
1346
- self._parent?.send(doneInvoke(id, resolved));
1347
- state.canceled = true;
1348
- }, errorData => {
1349
- state.canceled = true;
1350
- self._parent?.send(error(id, errorData));
1351
- });
1352
- }
1353
- return state;
1354
- }
1355
- if (event.type === stopSignalType) {
1356
- state.canceled = true;
1357
- if (isFunction(state.dispose)) {
1358
- state.dispose();
1359
- }
1360
- return state;
1361
- }
1362
- if (isSignal(event)) {
1363
- // TODO: unrecognized signal
1364
- return state;
1365
- }
1366
- state.receivers.forEach(receiver => receiver(event));
1367
- return state;
1368
- },
1369
- getInitialState: (_, input) => {
1370
- return {
1371
- canceled: false,
1372
- receivers: new Set(),
1373
- dispose: undefined,
1374
- input
1375
- };
1376
- },
1377
- getSnapshot: () => undefined,
1378
- getPersistedState: ({
1379
- input
1380
- }) => input
1381
- };
1382
- return logic;
645
+ function matchesState(parentStateId, childStateId) {
646
+ const parentStateValue = toStateValue(parentStateId);
647
+ const childStateValue = toStateValue(childStateId);
648
+ if (typeof childStateValue === 'string') {
649
+ if (typeof parentStateValue === 'string') {
650
+ return childStateValue === parentStateValue;
651
+ }
652
+
653
+ // Parent more specific than child
654
+ return false;
655
+ }
656
+ if (typeof parentStateValue === 'string') {
657
+ return parentStateValue in childStateValue;
658
+ }
659
+ return Object.keys(parentStateValue).every(key => {
660
+ if (!(key in childStateValue)) {
661
+ return false;
662
+ }
663
+ return matchesState(parentStateValue[key], childStateValue[key]);
664
+ });
665
+ }
666
+ function toStatePath(stateId) {
667
+ try {
668
+ if (isArray(stateId)) {
669
+ return stateId;
670
+ }
671
+ return stateId.toString().split(STATE_DELIMITER);
672
+ } catch (e) {
673
+ throw new Error(`'${stateId}' is not a valid state path.`);
674
+ }
675
+ }
676
+ function isStateLike(state) {
677
+ return typeof state === 'object' && 'value' in state && 'context' in state && 'event' in state;
678
+ }
679
+ function toStateValue(stateValue) {
680
+ if (isStateLike(stateValue)) {
681
+ return stateValue.value;
682
+ }
683
+ if (isArray(stateValue)) {
684
+ return pathToStateValue(stateValue);
685
+ }
686
+ if (typeof stateValue !== 'string') {
687
+ return stateValue;
688
+ }
689
+ const statePath = toStatePath(stateValue);
690
+ return pathToStateValue(statePath);
691
+ }
692
+ function pathToStateValue(statePath) {
693
+ if (statePath.length === 1) {
694
+ return statePath[0];
695
+ }
696
+ const value = {};
697
+ let marker = value;
698
+ for (let i = 0; i < statePath.length - 1; i++) {
699
+ if (i === statePath.length - 2) {
700
+ marker[statePath[i]] = statePath[i + 1];
701
+ } else {
702
+ const previous = marker;
703
+ marker = {};
704
+ previous[statePath[i]] = marker;
705
+ }
706
+ }
707
+ return value;
708
+ }
709
+ function mapValues(collection, iteratee) {
710
+ const result = {};
711
+ const collectionKeys = Object.keys(collection);
712
+ for (let i = 0; i < collectionKeys.length; i++) {
713
+ const key = collectionKeys[i];
714
+ result[key] = iteratee(collection[key], key, collection, i);
715
+ }
716
+ return result;
717
+ }
718
+ function flatten(array) {
719
+ return [].concat(...array);
720
+ }
721
+ function toArrayStrict(value) {
722
+ if (isArray(value)) {
723
+ return value;
724
+ }
725
+ return [value];
726
+ }
727
+ function toArray(value) {
728
+ if (value === undefined) {
729
+ return [];
730
+ }
731
+ return toArrayStrict(value);
732
+ }
733
+ function mapContext(mapper, context, event) {
734
+ if (typeof mapper === 'function') {
735
+ return mapper({
736
+ context,
737
+ event
738
+ });
739
+ }
740
+ const result = {};
741
+ const args = {
742
+ context,
743
+ event
744
+ };
745
+ for (const key of Object.keys(mapper)) {
746
+ const subMapper = mapper[key];
747
+ if (typeof subMapper === 'function') {
748
+ result[key] = subMapper(args);
749
+ } else {
750
+ result[key] = subMapper;
751
+ }
752
+ }
753
+ return result;
754
+ }
755
+ function isPromiseLike(value) {
756
+ if (value instanceof Promise) {
757
+ return true;
758
+ }
759
+ // Check if shape matches the Promise/A+ specification for a "thenable".
760
+ if (value !== null && (typeof value === 'function' || typeof value === 'object') && typeof value.then === 'function') {
761
+ return true;
762
+ }
763
+ return false;
764
+ }
765
+ function isArray(value) {
766
+ return Array.isArray(value);
767
+ }
768
+ function isErrorEvent(event) {
769
+ return typeof event.type === 'string' && (event.type === errorExecution || event.type.startsWith(errorPlatform));
770
+ }
771
+ function toTransitionConfigArray(configLike) {
772
+ return toArrayStrict(configLike).map(transitionLike => {
773
+ if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
774
+ return {
775
+ target: transitionLike
776
+ };
777
+ }
778
+ return transitionLike;
779
+ });
780
+ }
781
+ function normalizeTarget(target) {
782
+ if (target === undefined || target === TARGETLESS_KEY) {
783
+ return undefined;
784
+ }
785
+ return toArray(target);
786
+ }
787
+ function toInvokeConfig(invocable, id) {
788
+ if (typeof invocable === 'object') {
789
+ if ('src' in invocable) {
790
+ return invocable;
791
+ }
792
+ if ('transition' in invocable) {
793
+ return {
794
+ id,
795
+ src: invocable
796
+ };
797
+ }
798
+ }
799
+ return {
800
+ id,
801
+ src: invocable
802
+ };
803
+ }
804
+ function toObserver(nextHandler, errorHandler, completionHandler) {
805
+ const noop = () => {};
806
+ const isObserver = typeof nextHandler === 'object';
807
+ const self = isObserver ? nextHandler : null;
808
+ return {
809
+ next: ((isObserver ? nextHandler.next : nextHandler) || noop).bind(self),
810
+ error: ((isObserver ? nextHandler.error : errorHandler) || noop).bind(self),
811
+ complete: ((isObserver ? nextHandler.complete : completionHandler) || noop).bind(self)
812
+ };
813
+ }
814
+ function createInvokeId(stateNodeId, index) {
815
+ return `${stateNodeId}:invocation[${index}]`;
816
+ }
817
+ function resolveReferencedActor(referenced) {
818
+ return referenced ? 'transition' in referenced ? {
819
+ src: referenced,
820
+ input: undefined
821
+ } : referenced : undefined;
822
+ }
823
+
824
+ function fromCallback(invokeCallback) {
825
+ const logic = {
826
+ config: invokeCallback,
827
+ start: (_state, {
828
+ self
829
+ }) => {
830
+ self.send({
831
+ type: startSignalType
832
+ });
833
+ },
834
+ transition: (state, event, {
835
+ self,
836
+ id,
837
+ system
838
+ }) => {
839
+ if (event.type === startSignalType) {
840
+ const sender = eventForParent => {
841
+ if (state.canceled) {
842
+ return;
843
+ }
844
+ self._parent?.send(eventForParent);
845
+ };
846
+ const receiver = newListener => {
847
+ state.receivers.add(newListener);
848
+ };
849
+ state.dispose = invokeCallback(sender, receiver, {
850
+ input: state.input,
851
+ system
852
+ });
853
+ if (isPromiseLike(state.dispose)) {
854
+ state.dispose.then(resolved => {
855
+ self._parent?.send(doneInvoke(id, resolved));
856
+ state.canceled = true;
857
+ }, errorData => {
858
+ state.canceled = true;
859
+ self._parent?.send(error(id, errorData));
860
+ });
861
+ }
862
+ return state;
863
+ }
864
+ if (event.type === stopSignalType) {
865
+ state.canceled = true;
866
+ if (typeof state.dispose === 'function') {
867
+ state.dispose();
868
+ }
869
+ return state;
870
+ }
871
+ if (isSignal(event)) {
872
+ // TODO: unrecognized signal
873
+ return state;
874
+ }
875
+ state.receivers.forEach(receiver => receiver(event));
876
+ return state;
877
+ },
878
+ getInitialState: (_, input) => {
879
+ return {
880
+ canceled: false,
881
+ receivers: new Set(),
882
+ dispose: undefined,
883
+ input
884
+ };
885
+ },
886
+ getSnapshot: () => undefined,
887
+ getPersistedState: ({
888
+ input
889
+ }) => input
890
+ };
891
+ return logic;
892
+ }
893
+
894
+ const startSignalType = 'xstate.init';
895
+ const stopSignalType = 'xstate.stop';
896
+ const startSignal = {
897
+ type: 'xstate.init'
898
+ };
899
+ const stopSignal = {
900
+ type: 'xstate.stop'
901
+ };
902
+ /**
903
+ * An object that expresses the actor logic in reaction to received events,
904
+ * as well as an optionally emitted stream of values.
905
+ *
906
+ * @template TReceived The received event
907
+ * @template TSnapshot The emitted value
908
+ */
909
+
910
+ function isSignal(event) {
911
+ return event.type === startSignalType || event.type === stopSignalType;
912
+ }
913
+ function isActorRef(item) {
914
+ return !!item && typeof item === 'object' && typeof item.send === 'function';
915
+ }
916
+
917
+ // TODO: refactor the return type, this could be written in a better way
918
+ // but it's best to avoid unneccessary breaking changes now
919
+ // @deprecated use `interpret(actorLogic)` instead
920
+ function toActorRef(actorRefLike) {
921
+ return {
922
+ subscribe: () => ({
923
+ unsubscribe: () => void 0
924
+ }),
925
+ id: 'anonymous',
926
+ sessionId: '',
927
+ getSnapshot: () => undefined,
928
+ [symbolObservable]: function () {
929
+ return this;
930
+ },
931
+ status: ActorStatus.Running,
932
+ stop: () => void 0,
933
+ ...actorRefLike
934
+ };
935
+ }
936
+ const emptyLogic = fromTransition(_ => undefined, undefined);
937
+ function createEmptyActor() {
938
+ return interpret(emptyLogic);
939
+ }
940
+
941
+ function createSystem() {
942
+ let sessionIdCounter = 0;
943
+ const children = new Map();
944
+ const keyedActors = new Map();
945
+ const reverseKeyedActors = new WeakMap();
946
+ const system = {
947
+ _bookId: () => `x:${sessionIdCounter++}`,
948
+ _register: (sessionId, actorRef) => {
949
+ children.set(sessionId, actorRef);
950
+ return sessionId;
951
+ },
952
+ _unregister: actorRef => {
953
+ children.delete(actorRef.sessionId);
954
+ const systemId = reverseKeyedActors.get(actorRef);
955
+ if (systemId !== undefined) {
956
+ keyedActors.delete(systemId);
957
+ reverseKeyedActors.delete(actorRef);
958
+ }
959
+ },
960
+ get: systemId => {
961
+ return keyedActors.get(systemId);
962
+ },
963
+ _set: (systemId, actorRef) => {
964
+ const existing = keyedActors.get(systemId);
965
+ if (existing && existing !== actorRef) {
966
+ throw new Error(`Actor with system ID '${systemId}' already exists.`);
967
+ }
968
+ keyedActors.set(systemId, actorRef);
969
+ reverseKeyedActors.set(actorRef, systemId);
970
+ }
971
+ };
972
+ return system;
973
+ }
974
+
975
+ let ActorStatus = /*#__PURE__*/function (ActorStatus) {
976
+ ActorStatus[ActorStatus["NotStarted"] = 0] = "NotStarted";
977
+ ActorStatus[ActorStatus["Running"] = 1] = "Running";
978
+ ActorStatus[ActorStatus["Stopped"] = 2] = "Stopped";
979
+ return ActorStatus;
980
+ }({});
981
+ const defaultOptions = {
982
+ deferEvents: true,
983
+ clock: {
984
+ setTimeout: (fn, ms) => {
985
+ return setTimeout(fn, ms);
986
+ },
987
+ clearTimeout: id => {
988
+ return clearTimeout(id);
989
+ }
990
+ },
991
+ logger: console.log.bind(console),
992
+ devTools: false
993
+ };
994
+ class Interpreter {
995
+ /**
996
+ * The current state of the interpreted logic.
997
+ */
998
+
999
+ /**
1000
+ * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions.
1001
+ */
1002
+
1003
+ /**
1004
+ * The unique identifier for this actor relative to its parent.
1005
+ */
1006
+
1007
+ /**
1008
+ * Whether the service is started.
1009
+ */
1010
+
1011
+ // Actor Ref
1012
+
1013
+ // TODO: add typings for system
1014
+
1015
+ /**
1016
+ * The globally unique process ID for this invocation.
1017
+ */
1018
+
1019
+ /**
1020
+ * Creates a new Interpreter instance (i.e., service) for the given logic with the provided options, if any.
1021
+ *
1022
+ * @param logic The logic to be interpreted
1023
+ * @param options Interpreter options
1024
+ */
1025
+ constructor(logic, options) {
1026
+ this.logic = logic;
1027
+ this._state = void 0;
1028
+ this.clock = void 0;
1029
+ this.options = void 0;
1030
+ this.id = void 0;
1031
+ this.mailbox = new Mailbox(this._process.bind(this));
1032
+ this.delayedEventsMap = {};
1033
+ this.observers = new Set();
1034
+ this.logger = void 0;
1035
+ this.status = ActorStatus.NotStarted;
1036
+ this._parent = void 0;
1037
+ this.ref = void 0;
1038
+ this._actorContext = void 0;
1039
+ this._systemId = void 0;
1040
+ this.sessionId = void 0;
1041
+ this.system = void 0;
1042
+ this._doneEvent = void 0;
1043
+ this.src = void 0;
1044
+ this._deferred = [];
1045
+ const resolvedOptions = {
1046
+ ...defaultOptions,
1047
+ ...options
1048
+ };
1049
+ const {
1050
+ clock,
1051
+ logger,
1052
+ parent,
1053
+ id,
1054
+ systemId
1055
+ } = resolvedOptions;
1056
+ const self = this;
1057
+ this.system = parent?.system ?? createSystem();
1058
+ if (systemId) {
1059
+ this._systemId = systemId;
1060
+ this.system._set(systemId, this);
1061
+ }
1062
+ this.sessionId = this.system._bookId();
1063
+ this.id = id ?? this.sessionId;
1064
+ this.logger = logger;
1065
+ this.clock = clock;
1066
+ this._parent = parent;
1067
+ this.options = resolvedOptions;
1068
+ this.src = resolvedOptions.src;
1069
+ this.ref = this;
1070
+ this._actorContext = {
1071
+ self,
1072
+ id: this.id,
1073
+ sessionId: this.sessionId,
1074
+ logger: this.logger,
1075
+ defer: fn => {
1076
+ this._deferred.push(fn);
1077
+ },
1078
+ system: this.system,
1079
+ stopChild: child => {
1080
+ if (child._parent !== this) {
1081
+ throw new Error(`Cannot stop child actor ${child.id} of ${this.id} because it is not a child`);
1082
+ }
1083
+ child._stop();
1084
+ }
1085
+ };
1086
+
1087
+ // Ensure that the send method is bound to this interpreter instance
1088
+ // if destructured
1089
+ this.send = this.send.bind(this);
1090
+ this._initState();
1091
+ }
1092
+ _initState() {
1093
+ this._state = this.options.state ? this.logic.restoreState ? this.logic.restoreState(this.options.state, this._actorContext) : this.options.state : this.logic.getInitialState(this._actorContext, this.options?.input);
1094
+ }
1095
+
1096
+ // array of functions to defer
1097
+
1098
+ update(state) {
1099
+ // Update state
1100
+ this._state = state;
1101
+ const snapshot = this.getSnapshot();
1102
+
1103
+ // Execute deferred effects
1104
+ let deferredFn;
1105
+ while (deferredFn = this._deferred.shift()) {
1106
+ deferredFn();
1107
+ }
1108
+ for (const observer of this.observers) {
1109
+ observer.next?.(snapshot);
1110
+ }
1111
+ const status = this.logic.getStatus?.(state);
1112
+ switch (status?.status) {
1113
+ case 'done':
1114
+ this._stopProcedure();
1115
+ this._doneEvent = doneInvoke(this.id, status.data);
1116
+ this._parent?.send(this._doneEvent);
1117
+ this._complete();
1118
+ break;
1119
+ case 'error':
1120
+ this._stopProcedure();
1121
+ this._parent?.send(error(this.id, status.data));
1122
+ this._error(status.data);
1123
+ break;
1124
+ }
1125
+ }
1126
+ subscribe(nextListenerOrObserver, errorListener, completeListener) {
1127
+ const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
1128
+ this.observers.add(observer);
1129
+ if (this.status === ActorStatus.Stopped) {
1130
+ observer.complete?.();
1131
+ this.observers.delete(observer);
1132
+ }
1133
+ return {
1134
+ unsubscribe: () => {
1135
+ this.observers.delete(observer);
1136
+ }
1137
+ };
1138
+ }
1139
+
1140
+ /**
1141
+ * Starts the interpreter from the initial state
1142
+ */
1143
+ start() {
1144
+ if (this.status === ActorStatus.Running) {
1145
+ // Do not restart the service if it is already started
1146
+ return this;
1147
+ }
1148
+ this.system._register(this.sessionId, this);
1149
+ if (this._systemId) {
1150
+ this.system._set(this._systemId, this);
1151
+ }
1152
+ this.status = ActorStatus.Running;
1153
+ if (this.logic.start) {
1154
+ this.logic.start(this._state, this._actorContext);
1155
+ }
1156
+
1157
+ // TODO: this notifies all subscribers but usually this is redundant
1158
+ // there is no real change happening here
1159
+ // we need to rethink if this needs to be refactored
1160
+ this.update(this._state);
1161
+ if (this.options.devTools) {
1162
+ this.attachDevTools();
1163
+ }
1164
+ this.mailbox.start();
1165
+ return this;
1166
+ }
1167
+ _process(event) {
1168
+ try {
1169
+ const nextState = this.logic.transition(this._state, event, this._actorContext);
1170
+ this.update(nextState);
1171
+ if (event.type === stopSignalType) {
1172
+ this._stopProcedure();
1173
+ this._complete();
1174
+ }
1175
+ } catch (err) {
1176
+ // TODO: properly handle errors
1177
+ if (this.observers.size > 0) {
1178
+ this.observers.forEach(observer => {
1179
+ observer.error?.(err);
1180
+ });
1181
+ this.stop();
1182
+ } else {
1183
+ throw err;
1184
+ }
1185
+ }
1186
+ }
1187
+ _stop() {
1188
+ if (this.status === ActorStatus.Stopped) {
1189
+ return this;
1190
+ }
1191
+ this.mailbox.clear();
1192
+ if (this.status === ActorStatus.NotStarted) {
1193
+ this.status = ActorStatus.Stopped;
1194
+ return this;
1195
+ }
1196
+ this.mailbox.enqueue({
1197
+ type: stopSignalType
1198
+ });
1199
+ return this;
1200
+ }
1201
+
1202
+ /**
1203
+ * Stops the interpreter and unsubscribe all listeners.
1204
+ */
1205
+ stop() {
1206
+ if (this._parent) {
1207
+ throw new Error('A non-root actor cannot be stopped directly.');
1208
+ }
1209
+ return this._stop();
1210
+ }
1211
+ _complete() {
1212
+ for (const observer of this.observers) {
1213
+ observer.complete?.();
1214
+ }
1215
+ this.observers.clear();
1216
+ }
1217
+ _error(data) {
1218
+ for (const observer of this.observers) {
1219
+ observer.error?.(data);
1220
+ }
1221
+ this.observers.clear();
1222
+ }
1223
+ _stopProcedure() {
1224
+ if (this.status !== ActorStatus.Running) {
1225
+ // Interpreter already stopped; do nothing
1226
+ return this;
1227
+ }
1228
+
1229
+ // Cancel all delayed events
1230
+ for (const key of Object.keys(this.delayedEventsMap)) {
1231
+ this.clock.clearTimeout(this.delayedEventsMap[key]);
1232
+ }
1233
+
1234
+ // TODO: mailbox.reset
1235
+ this.mailbox.clear();
1236
+ // TODO: after `stop` we must prepare ourselves for receiving events again
1237
+ // events sent *after* stop signal must be queued
1238
+ // it seems like this should be the common behavior for all of our consumers
1239
+ // so perhaps this should be unified somehow for all of them
1240
+ this.mailbox = new Mailbox(this._process.bind(this));
1241
+ this.status = ActorStatus.Stopped;
1242
+ this.system._unregister(this);
1243
+ return this;
1244
+ }
1245
+
1246
+ /**
1247
+ * Sends an event to the running interpreter to trigger a transition.
1248
+ *
1249
+ * @param event The event to send
1250
+ */
1251
+ send(event) {
1252
+ if (typeof event === 'string') {
1253
+ throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
1254
+ }
1255
+ if (this.status === ActorStatus.Stopped) {
1256
+ // do nothing
1257
+ {
1258
+ const eventString = JSON.stringify(event);
1259
+ console.warn(`Event "${event.type.toString()}" was sent to stopped actor "${this.id} (${this.sessionId})". This actor has already reached its final state, and will not transition.\nEvent: ${eventString}`);
1260
+ }
1261
+ return;
1262
+ }
1263
+ if (this.status !== ActorStatus.Running && !this.options.deferEvents) {
1264
+ throw new Error(`Event "${event.type}" was sent to uninitialized actor "${this.id
1265
+ // tslint:disable-next-line:max-line-length
1266
+ }". Make sure .start() is called for this actor, or set { deferEvents: true } in the actor options.\nEvent: ${JSON.stringify(event)}`);
1267
+ }
1268
+ this.mailbox.enqueue(event);
1269
+ }
1270
+
1271
+ // TODO: make private (and figure out a way to do this within the machine)
1272
+ delaySend({
1273
+ event,
1274
+ id,
1275
+ delay,
1276
+ to
1277
+ }) {
1278
+ const timerId = this.clock.setTimeout(() => {
1279
+ if (to) {
1280
+ to.send(event);
1281
+ } else {
1282
+ this.send(event);
1283
+ }
1284
+ }, delay);
1285
+
1286
+ // TODO: consider the rehydration story here
1287
+ if (id) {
1288
+ this.delayedEventsMap[id] = timerId;
1289
+ }
1290
+ }
1291
+
1292
+ // TODO: make private (and figure out a way to do this within the machine)
1293
+ cancel(sendId) {
1294
+ this.clock.clearTimeout(this.delayedEventsMap[sendId]);
1295
+ delete this.delayedEventsMap[sendId];
1296
+ }
1297
+ attachDevTools() {
1298
+ const {
1299
+ devTools
1300
+ } = this.options;
1301
+ if (devTools) {
1302
+ const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : devToolsAdapter;
1303
+ resolvedDevToolsAdapter(this);
1304
+ }
1305
+ }
1306
+ toJSON() {
1307
+ return {
1308
+ id: this.id
1309
+ };
1310
+ }
1311
+ getPersistedState() {
1312
+ return this.logic.getPersistedState?.(this._state);
1313
+ }
1314
+ [symbolObservable]() {
1315
+ return this;
1316
+ }
1317
+ getSnapshot() {
1318
+ return this.logic.getSnapshot ? this.logic.getSnapshot(this._state) : this._state;
1319
+ }
1383
1320
  }
1384
1321
 
1385
- const startSignalType = 'xstate.init';
1386
- const stopSignalType = 'xstate.stop';
1387
- const startSignal = {
1388
- type: 'xstate.init'
1389
- };
1390
- const stopSignal = {
1391
- type: 'xstate.stop'
1392
- };
1393
1322
  /**
1394
- * An object that expresses the actor logic in reaction to received events,
1395
- * as well as an optionally emitted stream of values.
1323
+ * Creates a new Interpreter instance for the given machine with the provided options, if any.
1396
1324
  *
1397
- * @template TReceived The received event
1398
- * @template TSnapshot The emitted value
1325
+ * @param machine The machine to interpret
1326
+ * @param options Interpreter options
1399
1327
  */
1400
1328
 
1401
- function isSignal(event) {
1402
- return event.type === startSignalType || event.type === stopSignalType;
1403
- }
1404
- function isActorRef(item) {
1405
- return !!item && typeof item === 'object' && typeof item.send === 'function';
1406
- }
1407
-
1408
- // TODO: refactor the return type, this could be written in a better way
1409
- // but it's best to avoid unneccessary breaking changes now
1410
- // @deprecated use `interpret(actorLogic)` instead
1411
- function toActorRef(actorRefLike) {
1412
- return {
1413
- subscribe: () => ({
1414
- unsubscribe: () => void 0
1415
- }),
1416
- id: 'anonymous',
1417
- sessionId: '',
1418
- getSnapshot: () => undefined,
1419
- [symbolObservable]: function () {
1420
- return this;
1421
- },
1422
- status: ActorStatus.Running,
1423
- stop: () => void 0,
1424
- ...actorRefLike
1425
- };
1426
- }
1427
- const emptyLogic = fromTransition(_ => undefined, undefined);
1428
- function createEmptyActor() {
1429
- return interpret(emptyLogic);
1329
+ function interpret(logic, options) {
1330
+ const interpreter = new Interpreter(logic, options);
1331
+ return interpreter;
1430
1332
  }
1431
1333
 
1432
- function invoke(invokeDef) {
1433
- return createDynamicAction({
1434
- type: invoke$1,
1435
- params: invokeDef
1436
- }, (event, {
1437
- state,
1438
- actorContext
1439
- }) => {
1440
- const type = invoke$1;
1441
- const {
1334
+ function resolve$6(actorContext, state, actionArgs, {
1335
+ id,
1336
+ systemId,
1337
+ src,
1338
+ input
1339
+ }) {
1340
+ const referenced = resolveReferencedActor(state.machine.implementations.actors[src]);
1341
+ let actorRef;
1342
+ if (referenced) {
1343
+ // TODO: inline `input: undefined` should win over the referenced one
1344
+ const configuredInput = input || referenced.input;
1345
+ actorRef = interpret(referenced.src, {
1442
1346
  id,
1443
- src
1444
- } = invokeDef;
1445
- let resolvedInvokeAction;
1446
- if (isActorRef(src)) {
1447
- resolvedInvokeAction = {
1448
- type,
1449
- params: {
1450
- ...invokeDef,
1451
- ref: src
1452
- }
1453
- };
1454
- } else {
1455
- const referenced = resolveReferencedActor(state.machine.implementations.actors[src]);
1456
- if (!referenced) {
1457
- resolvedInvokeAction = {
1458
- type,
1459
- params: invokeDef
1460
- };
1461
- } else {
1462
- const input = 'input' in invokeDef ? invokeDef.input : referenced.input;
1463
- const ref = interpret(referenced.src, {
1464
- id,
1465
- src,
1466
- parent: actorContext?.self,
1467
- systemId: invokeDef.systemId,
1468
- input: typeof input === 'function' ? input({
1469
- context: state.context,
1470
- event,
1471
- self: actorContext?.self
1472
- }) : input
1473
- });
1474
- resolvedInvokeAction = {
1475
- type,
1476
- params: {
1477
- ...invokeDef,
1478
- ref
1479
- }
1480
- };
1481
- }
1482
- }
1483
- const actorRef = resolvedInvokeAction.params.ref;
1484
- const invokedState = cloneState(state, {
1485
- children: {
1486
- ...state.children,
1487
- [id]: actorRef
1488
- }
1347
+ src,
1348
+ parent: actorContext?.self,
1349
+ systemId,
1350
+ input: typeof configuredInput === 'function' ? configuredInput({
1351
+ context: state.context,
1352
+ event: actionArgs.event,
1353
+ self: actorContext?.self
1354
+ }) : configuredInput
1489
1355
  });
1490
- resolvedInvokeAction.execute = actorCtx => {
1491
- const parent = actorCtx.self;
1492
- const {
1493
- id,
1494
- ref
1495
- } = resolvedInvokeAction.params;
1496
- if (!ref) {
1497
- {
1498
- console.warn(`Actor type '${resolvedInvokeAction.params.src}' not found in machine '${actorCtx.id}'.`);
1499
- }
1500
- return;
1501
- }
1502
- actorCtx.defer(() => {
1503
- if (actorRef.status === ActorStatus.Stopped) {
1504
- return;
1505
- }
1506
- try {
1507
- actorRef.start?.();
1508
- } catch (err) {
1509
- parent.send(error(id, err));
1510
- return;
1511
- }
1512
- });
1513
- };
1514
- return [invokedState, resolvedInvokeAction];
1356
+ }
1357
+ if (!actorRef) {
1358
+ console.warn(`Actor type '${src}' not found in machine '${actorContext.id}'.`);
1359
+ }
1360
+ return [cloneState(state, {
1361
+ children: {
1362
+ ...state.children,
1363
+ [id]: actorRef
1364
+ }
1365
+ }), {
1366
+ id,
1367
+ actorRef
1368
+ }];
1369
+ }
1370
+ function execute$3(actorContext, {
1371
+ id,
1372
+ actorRef
1373
+ }) {
1374
+ if (!actorRef) {
1375
+ return;
1376
+ }
1377
+ actorContext.defer(() => {
1378
+ if (actorRef.status === ActorStatus.Stopped) {
1379
+ return;
1380
+ }
1381
+ try {
1382
+ actorRef.start?.();
1383
+ } catch (err) {
1384
+ actorContext.self.send(error(id, err));
1385
+ return;
1386
+ }
1515
1387
  });
1516
1388
  }
1389
+ function invoke({
1390
+ id,
1391
+ systemId,
1392
+ src,
1393
+ input
1394
+ }) {
1395
+ function invoke(_) {
1396
+ {
1397
+ throw new Error(`This isn't supposed to be called`);
1398
+ }
1399
+ }
1400
+ invoke.type = 'xstate.invoke';
1401
+ invoke.id = id;
1402
+ invoke.systemId = systemId;
1403
+ invoke.src = src;
1404
+ invoke.input = input;
1405
+ invoke.resolve = resolve$6;
1406
+ invoke.execute = execute$3;
1407
+ return invoke;
1408
+ }
1517
1409
 
1518
1410
  function stateIn(stateValue) {
1519
1411
  return {
@@ -1524,7 +1416,7 @@ function stateIn(stateValue) {
1524
1416
  predicate: ({
1525
1417
  state
1526
1418
  }) => {
1527
- if (isString(stateValue) && isStateId(stateValue)) {
1419
+ if (typeof stateValue === 'string' && isStateId(stateValue)) {
1528
1420
  return state.configuration.some(sn => sn.id === stateValue.slice(1));
1529
1421
  }
1530
1422
  return state.matches(stateValue);
@@ -1608,9 +1500,9 @@ function evaluateGuard(guard, context, event, state) {
1608
1500
  function toGuardDefinition(guardConfig, getPredicate) {
1609
1501
  // TODO: check for cycles and consider a refactor to more lazily evaluated guards
1610
1502
  // TODO: resolve this more recursively: https://github.com/statelyai/xstate/pull/4064#discussion_r1229915724
1611
- if (isString(guardConfig)) {
1503
+ if (typeof guardConfig === 'string') {
1612
1504
  const predicateOrDef = getPredicate?.(guardConfig);
1613
- if (isFunction(predicateOrDef)) {
1505
+ if (typeof predicateOrDef === 'function') {
1614
1506
  return {
1615
1507
  type: guardConfig,
1616
1508
  predicate: predicateOrDef,
@@ -1629,7 +1521,7 @@ function toGuardDefinition(guardConfig, getPredicate) {
1629
1521
  };
1630
1522
  }
1631
1523
  }
1632
- if (isFunction(guardConfig)) {
1524
+ if (typeof guardConfig === 'function') {
1633
1525
  return {
1634
1526
  type: guardConfig.name,
1635
1527
  predicate: guardConfig,
@@ -1640,7 +1532,7 @@ function toGuardDefinition(guardConfig, getPredicate) {
1640
1532
  };
1641
1533
  }
1642
1534
  const predicateOrDef = getPredicate?.(guardConfig.type);
1643
- if (isFunction(predicateOrDef)) {
1535
+ if (typeof predicateOrDef === 'function') {
1644
1536
  return {
1645
1537
  type: guardConfig.type,
1646
1538
  params: guardConfig.params || guardConfig,
@@ -1767,27 +1659,19 @@ function isInFinalState(configuration, stateNode = configuration[0].machine.root
1767
1659
  }
1768
1660
  const isStateId = str => str[0] === STATE_IDENTIFIER;
1769
1661
  function getCandidates(stateNode, receivedEventType) {
1770
- const candidates = stateNode.transitions.filter(transition => {
1771
- const {
1772
- eventType
1773
- } = transition;
1774
- // First, check the trivial case: event names are exactly equal
1775
- if (eventType === receivedEventType) {
1776
- return true;
1777
- }
1778
-
1779
- // Then, check if transition is a wildcard transition,
1662
+ const candidates = stateNode.transitions.get(receivedEventType) || [...stateNode.transitions.keys()].filter(descriptor => {
1663
+ // check if transition is a wildcard transition,
1780
1664
  // which matches any non-transient events
1781
- if (eventType === WILDCARD) {
1665
+ if (descriptor === WILDCARD) {
1782
1666
  return true;
1783
1667
  }
1784
- if (!eventType.endsWith('.*')) {
1668
+ if (!descriptor.endsWith('.*')) {
1785
1669
  return false;
1786
1670
  }
1787
- if (/.*\*.+/.test(eventType)) {
1788
- console.warn(`Wildcards can only be the last token of an event descriptor (e.g., "event.*") or the entire event descriptor ("*"). Check the "${eventType}" event.`);
1671
+ if (/.*\*.+/.test(descriptor)) {
1672
+ console.warn(`Wildcards can only be the last token of an event descriptor (e.g., "event.*") or the entire event descriptor ("*"). Check the "${descriptor}" event.`);
1789
1673
  }
1790
- const partialEventTokens = eventType.split('.');
1674
+ const partialEventTokens = descriptor.split('.');
1791
1675
  const eventTokens = receivedEventType.split('.');
1792
1676
  for (let tokenIndex = 0; tokenIndex < partialEventTokens.length; tokenIndex++) {
1793
1677
  const partialEventToken = partialEventTokens[tokenIndex];
@@ -1795,7 +1679,7 @@ function getCandidates(stateNode, receivedEventType) {
1795
1679
  if (partialEventToken === '*') {
1796
1680
  const isLastToken = tokenIndex === partialEventTokens.length - 1;
1797
1681
  if (!isLastToken) {
1798
- console.warn(`Infix wildcards in transition events are not allowed. Check the "${eventType}" event.`);
1682
+ console.warn(`Infix wildcards in transition events are not allowed. Check the "${descriptor}" transition.`);
1799
1683
  }
1800
1684
  return isLastToken;
1801
1685
  }
@@ -1804,7 +1688,7 @@ function getCandidates(stateNode, receivedEventType) {
1804
1688
  }
1805
1689
  }
1806
1690
  return true;
1807
- });
1691
+ }).sort((a, b) => b.length - a.length).flatMap(key => stateNode.transitions.get(key));
1808
1692
  return candidates;
1809
1693
  }
1810
1694
 
@@ -1817,11 +1701,12 @@ function getDelayedTransitions(stateNode) {
1817
1701
  return [];
1818
1702
  }
1819
1703
  const mutateEntryExit = (delay, i) => {
1820
- const delayRef = isFunction(delay) ? `${stateNode.id}:delay[${i}]` : delay;
1704
+ const delayRef = typeof delay === 'function' ? `${stateNode.id}:delay[${i}]` : delay;
1821
1705
  const eventType = after(delayRef, stateNode.id);
1822
1706
  stateNode.entry.push(raise({
1823
1707
  type: eventType
1824
1708
  }, {
1709
+ id: eventType,
1825
1710
  delay
1826
1711
  }));
1827
1712
  stateNode.exit.push(cancel(eventType));
@@ -1835,7 +1720,7 @@ function getDelayedTransitions(stateNode) {
1835
1720
  };
1836
1721
  }) : Object.keys(afterConfig).flatMap((delay, i) => {
1837
1722
  const configTransition = afterConfig[delay];
1838
- const resolvedTransition = isString(configTransition) ? {
1723
+ const resolvedTransition = typeof configTransition === 'string' ? {
1839
1724
  target: configTransition
1840
1725
  } : configTransition;
1841
1726
  const resolvedDelay = !isNaN(+delay) ? +delay : delay;
@@ -1851,12 +1736,12 @@ function getDelayedTransitions(stateNode) {
1851
1736
  delay
1852
1737
  } = delayedTransition;
1853
1738
  return {
1854
- ...formatTransition(stateNode, delayedTransition),
1739
+ ...formatTransition(stateNode, delayedTransition.event, delayedTransition),
1855
1740
  delay
1856
1741
  };
1857
1742
  });
1858
1743
  }
1859
- function formatTransition(stateNode, transitionConfig) {
1744
+ function formatTransition(stateNode, descriptor, transitionConfig) {
1860
1745
  const normalizedTarget = normalizeTarget(transitionConfig.target);
1861
1746
  const reenter = transitionConfig.reenter ?? false;
1862
1747
  const {
@@ -1870,12 +1755,12 @@ function formatTransition(stateNode, transitionConfig) {
1870
1755
  }
1871
1756
  const transition = {
1872
1757
  ...transitionConfig,
1873
- actions: toActionObjects(toArray(transitionConfig.actions)),
1758
+ actions: toArray(transitionConfig.actions),
1874
1759
  guard: transitionConfig.guard ? toGuardDefinition(transitionConfig.guard, guardType => guards[guardType]) : undefined,
1875
1760
  target,
1876
1761
  source: stateNode,
1877
1762
  reenter,
1878
- eventType: transitionConfig.event,
1763
+ eventType: descriptor,
1879
1764
  toJSON: () => ({
1880
1765
  ...transition,
1881
1766
  source: `#${stateNode.id}`,
@@ -1885,52 +1770,50 @@ function formatTransition(stateNode, transitionConfig) {
1885
1770
  return transition;
1886
1771
  }
1887
1772
  function formatTransitions(stateNode) {
1888
- const transitionConfigs = [];
1889
- if (Array.isArray(stateNode.config.on)) {
1890
- transitionConfigs.push(...stateNode.config.on);
1891
- } else if (stateNode.config.on) {
1892
- const {
1893
- [WILDCARD]: wildcardConfigs = [],
1894
- ...namedTransitionConfigs
1895
- } = stateNode.config.on;
1896
- for (const eventType of Object.keys(namedTransitionConfigs)) {
1897
- if (eventType === NULL_EVENT) {
1773
+ const transitions = new Map();
1774
+ if (stateNode.config.on) {
1775
+ for (const descriptor of Object.keys(stateNode.config.on)) {
1776
+ if (descriptor === NULL_EVENT) {
1898
1777
  throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');
1899
1778
  }
1900
- const eventTransitionConfigs = toTransitionConfigArray(eventType, namedTransitionConfigs[eventType]);
1901
- transitionConfigs.push(...eventTransitionConfigs);
1902
- // TODO: add dev-mode validation for unreachable transitions
1779
+ const transitionsConfig = stateNode.config.on[descriptor];
1780
+ transitions.set(descriptor, toTransitionConfigArray(transitionsConfig).map(t => formatTransition(stateNode, descriptor, t)));
1903
1781
  }
1904
-
1905
- transitionConfigs.push(...toTransitionConfigArray(WILDCARD, wildcardConfigs));
1906
1782
  }
1907
- const doneConfig = stateNode.config.onDone ? toTransitionConfigArray(String(done(stateNode.id)), stateNode.config.onDone) : [];
1908
- const invokeConfig = stateNode.invoke.flatMap(invokeDef => {
1909
- const settleTransitions = [];
1783
+ if (stateNode.config.onDone) {
1784
+ const descriptor = String(done(stateNode.id));
1785
+ transitions.set(descriptor, toTransitionConfigArray(stateNode.config.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1786
+ }
1787
+ for (const invokeDef of stateNode.invoke) {
1910
1788
  if (invokeDef.onDone) {
1911
- settleTransitions.push(...toTransitionConfigArray(`done.invoke.${invokeDef.id}`, invokeDef.onDone));
1789
+ const descriptor = `done.invoke.${invokeDef.id}`;
1790
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1912
1791
  }
1913
1792
  if (invokeDef.onError) {
1914
- settleTransitions.push(...toTransitionConfigArray(`error.platform.${invokeDef.id}`, invokeDef.onError));
1793
+ const descriptor = `error.platform.${invokeDef.id}`;
1794
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onError).map(t => formatTransition(stateNode, descriptor, t)));
1915
1795
  }
1916
1796
  if (invokeDef.onSnapshot) {
1917
- settleTransitions.push(...toTransitionConfigArray(`xstate.snapshot.${invokeDef.id}`, invokeDef.onSnapshot));
1797
+ const descriptor = `xstate.snapshot.${invokeDef.id}`;
1798
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onSnapshot).map(t => formatTransition(stateNode, descriptor, t)));
1918
1799
  }
1919
- return settleTransitions;
1920
- });
1921
- const delayedTransitions = stateNode.after;
1922
- const formattedTransitions = [...doneConfig, ...invokeConfig, ...transitionConfigs].flatMap(transitionConfig => toArray(transitionConfig).map(transition => formatTransition(stateNode, transition)));
1923
- for (const delayedTransition of delayedTransitions) {
1924
- formattedTransitions.push(delayedTransition);
1925
1800
  }
1926
- return formattedTransitions;
1801
+ for (const delayedTransition of stateNode.after) {
1802
+ let existing = transitions.get(delayedTransition.eventType);
1803
+ if (!existing) {
1804
+ existing = [];
1805
+ transitions.set(delayedTransition.eventType, existing);
1806
+ }
1807
+ existing.push(delayedTransition);
1808
+ }
1809
+ return transitions;
1927
1810
  }
1928
1811
  function formatInitialTransition(stateNode, _target) {
1929
- if (isString(_target) || isArray(_target)) {
1812
+ if (typeof _target === 'string' || isArray(_target)) {
1930
1813
  const targets = toArray(_target).map(t => {
1931
1814
  // Resolve state string keys (which represent children)
1932
1815
  // to their state node
1933
- const descStateNode = isString(t) ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
1816
+ const descStateNode = typeof t === 'string' ? isStateId(t) ? stateNode.machine.getStateNodeById(t) : stateNode.states[t] : t;
1934
1817
  if (!descStateNode) {
1935
1818
  throw new Error(`Initial state node "${t}" not found on parent state node #${stateNode.id}`);
1936
1819
  }
@@ -1954,15 +1837,14 @@ function formatInitialTransition(stateNode, _target) {
1954
1837
  };
1955
1838
  return transition;
1956
1839
  }
1957
- return formatTransition(stateNode, {
1840
+ return formatTransition(stateNode, '__INITIAL__', {
1958
1841
  target: toArray(_target.target).map(t => {
1959
- if (isString(t)) {
1842
+ if (typeof t === 'string') {
1960
1843
  return isStateId(t) ? t : `${STATE_DELIMITER}${t}`;
1961
1844
  }
1962
1845
  return t;
1963
1846
  }),
1964
- actions: _target.actions,
1965
- event: null
1847
+ actions: _target.actions
1966
1848
  });
1967
1849
  }
1968
1850
  function resolveTarget(stateNode, targets) {
@@ -1971,7 +1853,7 @@ function resolveTarget(stateNode, targets) {
1971
1853
  return undefined;
1972
1854
  }
1973
1855
  return targets.map(target => {
1974
- if (!isString(target)) {
1856
+ if (typeof target !== 'string') {
1975
1857
  return target;
1976
1858
  }
1977
1859
  if (isStateId(target)) {
@@ -2079,7 +1961,7 @@ function getStateNodeByPath(stateNode, statePath) {
2079
1961
  */
2080
1962
  function getStateNodes(stateNode, state) {
2081
1963
  const stateValue = state instanceof State ? state.value : toStateValue(state);
2082
- if (isString(stateValue)) {
1964
+ if (typeof stateValue === 'string') {
2083
1965
  return [stateNode, stateNode.states[stateValue]];
2084
1966
  }
2085
1967
  const childStateKeys = Object.keys(stateValue);
@@ -2130,7 +2012,7 @@ function transitionParallelNode(stateNode, stateValue, state, event) {
2130
2012
  }
2131
2013
  function transitionNode(stateNode, stateValue, state, event) {
2132
2014
  // leaf node
2133
- if (isString(stateValue)) {
2015
+ if (typeof stateValue === 'string') {
2134
2016
  return transitionAtomicNode(stateNode, stateValue, state, event);
2135
2017
  }
2136
2018
 
@@ -2464,44 +2346,55 @@ function resolveActionsAndContext(actions, event, currentState, actorCtx) {
2464
2346
  const {
2465
2347
  machine
2466
2348
  } = currentState;
2467
- const raiseActions = [];
2468
- let intermediateState = currentState;
2469
- function handleAction(action) {
2470
- if (actorCtx?.self.status === ActorStatus.Running) {
2471
- action.execute?.(actorCtx);
2472
- } else {
2473
- actorCtx?.defer(() => action.execute?.(actorCtx));
2349
+ // TODO: this `cloneState` is really just a hack to prevent infinite loops
2350
+ // we need to take another look at how internal queue is managed
2351
+ let intermediateState = cloneState(currentState, {
2352
+ _internalQueue: []
2353
+ });
2354
+ for (const action of actions) {
2355
+ const resolved = typeof action === 'function' ? action : machine.implementations.actions[typeof action === 'string' ? action : action.type];
2356
+ if (!resolved) {
2357
+ continue;
2474
2358
  }
2475
- }
2476
- function resolveAction(actionObject) {
2477
- const executableActionObject = resolveActionObject(actionObject, machine.implementations.actions);
2478
- if (isDynamicAction(executableActionObject)) {
2479
- const [nextState, resolvedAction] = executableActionObject.resolve(event, {
2480
- state: intermediateState,
2481
- action: actionObject,
2482
- actorContext: actorCtx
2483
- });
2484
- const matchedActions = resolvedAction.params?.actions;
2485
- intermediateState = nextState;
2486
- if ((resolvedAction.type === raise$1 || resolvedAction.type === send$1 && resolvedAction.params.internal) && typeof resolvedAction.params.delay !== 'number') {
2487
- raiseActions.push(resolvedAction);
2359
+ const args = {
2360
+ context: intermediateState.context,
2361
+ event,
2362
+ self: actorCtx?.self,
2363
+ system: actorCtx?.system,
2364
+ // TODO: figure out story for `action` and inline actions
2365
+ // what those ones should receive?
2366
+ //
2367
+ // entry: ({ action }) => {}
2368
+ // exit: assign(({ action }) => {})
2369
+ action: typeof action === 'string' ? {
2370
+ type: action
2371
+ } : action
2372
+ };
2373
+ if (!('resolve' in resolved)) {
2374
+ if (actorCtx?.self.status === ActorStatus.Running) {
2375
+ resolved(args);
2376
+ } else {
2377
+ actorCtx?.defer(() => resolved(args));
2488
2378
  }
2379
+ continue;
2380
+ }
2381
+ const builtinAction = resolved;
2382
+ const [nextState, params, actions] = builtinAction.resolve(actorCtx, intermediateState, args, resolved // this holds all params
2383
+ );
2489
2384
 
2490
- // TODO: remove the check; just handleAction
2491
- if (resolvedAction.type !== pure$1) {
2492
- handleAction(resolvedAction);
2385
+ intermediateState = nextState;
2386
+ if ('execute' in resolved) {
2387
+ if (actorCtx?.self.status === ActorStatus.Running) {
2388
+ builtinAction.execute(actorCtx, params);
2389
+ } else {
2390
+ actorCtx?.defer(builtinAction.execute.bind(null, actorCtx, params));
2493
2391
  }
2494
- toActionObjects(matchedActions).forEach(resolveAction);
2495
- return;
2496
2392
  }
2497
- handleAction(executableActionObject);
2498
- }
2499
- for (const actionObject of actions) {
2500
- resolveAction(actionObject);
2393
+ if (actions) {
2394
+ intermediateState = resolveActionsAndContext(actions, event, intermediateState, actorCtx);
2395
+ }
2501
2396
  }
2502
- return cloneState(intermediateState, {
2503
- _internalQueue: raiseActions.map(a => a.params.event)
2504
- });
2397
+ return intermediateState;
2505
2398
  }
2506
2399
  function macrostep(state, event, actorCtx) {
2507
2400
  if (event.type === WILDCARD) {
@@ -2523,7 +2416,7 @@ function macrostep(state, event, actorCtx) {
2523
2416
 
2524
2417
  // Assume the state is at rest (no raised events)
2525
2418
  // Determine the next state based on the next microstep
2526
- if (nextEvent.type !== init) {
2419
+ if (nextEvent.type !== INIT_TYPE) {
2527
2420
  const transitions = selectTransitions(nextEvent, nextState);
2528
2421
  nextState = microstep(transitions, state, actorCtx, nextEvent, false);
2529
2422
  states.push(nextState);
@@ -2689,7 +2582,7 @@ class State {
2689
2582
  * @param delimiter The character(s) that separate each subpath in the string state node path.
2690
2583
  */
2691
2584
  toStrings(stateValue = this.value) {
2692
- if (isString(stateValue)) {
2585
+ if (typeof stateValue === 'string') {
2693
2586
  return [stateValue];
2694
2587
  }
2695
2588
  const valueKeys = Object.keys(stateValue);
@@ -2787,6 +2680,36 @@ function getPersistedState(state) {
2787
2680
  };
2788
2681
  }
2789
2682
 
2683
+ function resolve$5(_, state, args, {
2684
+ actorRef
2685
+ }) {
2686
+ const actorRefOrString = typeof actorRef === 'function' ? actorRef(args) : actorRef;
2687
+ const resolvedActorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
2688
+ let children = state.children;
2689
+ if (resolvedActorRef) {
2690
+ children = {
2691
+ ...children
2692
+ };
2693
+ delete children[resolvedActorRef.id];
2694
+ }
2695
+ return [cloneState(state, {
2696
+ children
2697
+ }), resolvedActorRef];
2698
+ }
2699
+ function execute$2(actorContext, actorRef) {
2700
+ if (!actorRef) {
2701
+ return;
2702
+ }
2703
+ if (actorRef.status !== ActorStatus.Running) {
2704
+ actorContext.stopChild(actorRef);
2705
+ return;
2706
+ }
2707
+ // TODO: recheck why this one has to be deferred
2708
+ actorContext.defer(() => {
2709
+ actorContext.stopChild(actorRef);
2710
+ });
2711
+ }
2712
+
2790
2713
  /**
2791
2714
  * Stops an actor.
2792
2715
  *
@@ -2794,58 +2717,40 @@ function getPersistedState(state) {
2794
2717
  */
2795
2718
 
2796
2719
  function stop(actorRef) {
2797
- const actor = actorRef;
2798
- return createDynamicAction({
2799
- type: stop$1,
2800
- params: {
2801
- actor
2802
- }
2803
- }, (event, {
2804
- state
2805
- }) => {
2806
- const actorRefOrString = isFunction(actor) ? actor({
2807
- context: state.context,
2808
- event
2809
- }) : actor;
2810
- const actorRef = typeof actorRefOrString === 'string' ? state.children[actorRefOrString] : actorRefOrString;
2811
- let children = state.children;
2812
- if (actorRef) {
2813
- children = {
2814
- ...children
2815
- };
2816
- delete children[actorRef.id];
2817
- }
2818
- return [cloneState(state, {
2819
- children
2820
- }), {
2821
- type: 'xstate.stop',
2822
- params: {
2823
- actor: actorRef
2824
- },
2825
- execute: actorCtx => {
2826
- if (!actorRef) {
2827
- return;
2828
- }
2829
- if (actorRef.status !== ActorStatus.Running) {
2830
- actorCtx.stopChild(actorRef);
2831
- return;
2832
- }
2833
- actorCtx.defer(() => {
2834
- actorCtx.stopChild(actorRef);
2835
- });
2836
- }
2837
- }];
2838
- });
2720
+ function stop(_) {
2721
+ {
2722
+ throw new Error(`This isn't supposed to be called`);
2723
+ }
2724
+ }
2725
+ stop.type = 'xstate.stop';
2726
+ stop.actorRef = actorRef;
2727
+ stop.resolve = resolve$5;
2728
+ stop.execute = execute$2;
2729
+ return stop;
2730
+ }
2731
+
2732
+ function resolve$4(_, state, actionArgs, {
2733
+ value,
2734
+ label
2735
+ }) {
2736
+ return [state, {
2737
+ value: typeof value === 'function' ? value(actionArgs) : value,
2738
+ label
2739
+ }];
2740
+ }
2741
+ function execute$1({
2742
+ logger
2743
+ }, {
2744
+ value,
2745
+ label
2746
+ }) {
2747
+ if (label) {
2748
+ logger(label, value);
2749
+ } else {
2750
+ logger(value);
2751
+ }
2839
2752
  }
2840
2753
 
2841
- const defaultLogExpr = ({
2842
- context,
2843
- event
2844
- }) => ({
2845
- context,
2846
- event
2847
- });
2848
-
2849
2754
  /**
2850
2755
  *
2851
2756
  * @param expr The expression function to evaluate which will be logged.
@@ -2854,94 +2759,114 @@ const defaultLogExpr = ({
2854
2759
  * - `event` - the event that caused this action to be executed.
2855
2760
  * @param label The label to give to the logged expression.
2856
2761
  */
2857
-
2858
- function log(expr = defaultLogExpr, label) {
2859
- return createDynamicAction({
2860
- type: log$1,
2861
- params: {
2862
- label,
2863
- expr
2762
+ function log(value = ({
2763
+ context,
2764
+ event
2765
+ }) => ({
2766
+ context,
2767
+ event
2768
+ }), label) {
2769
+ function log(_) {
2770
+ {
2771
+ throw new Error(`This isn't supposed to be called`);
2864
2772
  }
2865
- }, (event, {
2866
- state,
2867
- actorContext
2868
- }) => {
2869
- const resolvedValue = typeof expr === 'function' ? expr({
2870
- context: state.context,
2871
- event,
2872
- self: actorContext?.self ?? {},
2873
- system: actorContext?.system
2874
- }) : expr;
2875
- return [state, {
2876
- type: 'xstate.log',
2877
- params: {
2878
- label,
2879
- value: resolvedValue
2880
- },
2881
- execute: actorCtx => {
2882
- if (label) {
2883
- actorCtx.logger?.(label, resolvedValue);
2884
- } else {
2885
- actorCtx.logger?.(resolvedValue);
2886
- }
2887
- }
2888
- }];
2889
- });
2773
+ }
2774
+ log.type = 'xstate.log';
2775
+ log.value = value;
2776
+ log.label = label;
2777
+ log.resolve = resolve$4;
2778
+ log.execute = execute$1;
2779
+ return log;
2890
2780
  }
2891
2781
 
2892
- function createSpawner(self, machine, context, event, mutCapturedActions) {
2893
- return (src, options = {}) => {
2782
+ function createSpawner(actorContext, {
2783
+ machine,
2784
+ context
2785
+ }, event, spawnedChildren) {
2786
+ const spawn = (src, options = {}) => {
2894
2787
  const {
2895
2788
  systemId
2896
2789
  } = options;
2897
- if (isString(src)) {
2790
+ if (typeof src === 'string') {
2898
2791
  const referenced = resolveReferencedActor(machine.implementations.actors[src]);
2899
- if (referenced) {
2900
- const input = 'input' in options ? options.input : referenced.input;
2901
-
2902
- // TODO: this should also receive `src`
2903
- const actorRef = interpret(referenced.src, {
2904
- id: options.id,
2905
- parent: self,
2906
- input: typeof input === 'function' ? input({
2907
- context,
2908
- event,
2909
- self
2910
- }) : input
2911
- });
2912
- mutCapturedActions.push(invoke({
2913
- id: actorRef.id,
2914
- // @ts-ignore TODO: fix types
2915
- src: actorRef,
2916
- // TODO
2917
- ref: actorRef,
2918
- meta: undefined,
2919
- input,
2920
- systemId
2921
- }));
2922
- return actorRef; // TODO: fix types
2792
+ if (!referenced) {
2793
+ throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
2923
2794
  }
2795
+ const input = 'input' in options ? options.input : referenced.input;
2924
2796
 
2925
- throw new Error(`Actor logic '${src}' not implemented in machine '${machine.id}'`);
2797
+ // TODO: this should also receive `src`
2798
+ const actor = interpret(referenced.src, {
2799
+ id: options.id,
2800
+ parent: actorContext.self,
2801
+ input: typeof input === 'function' ? input({
2802
+ context,
2803
+ event,
2804
+ self: actorContext.self
2805
+ }) : input,
2806
+ systemId
2807
+ });
2808
+ spawnedChildren[actor.id] = actor;
2809
+ return actor;
2926
2810
  } else {
2927
2811
  // TODO: this should also receive `src`
2928
- const actorRef = interpret(src, {
2812
+ return interpret(src, {
2929
2813
  id: options.id,
2930
- parent: self,
2814
+ parent: actorContext.self,
2931
2815
  input: options.input,
2932
2816
  systemId
2933
2817
  });
2934
- mutCapturedActions.push(invoke({
2935
- // @ts-ignore TODO: fix types
2936
- src: actorRef,
2937
- ref: actorRef,
2938
- id: actorRef.id,
2939
- meta: undefined,
2940
- input: options.input
2941
- }));
2942
- return actorRef; // TODO: fix types
2943
2818
  }
2944
2819
  };
2820
+ return (src, options) => {
2821
+ const actorRef = spawn(src, options);
2822
+ spawnedChildren[actorRef.id] = actorRef;
2823
+ actorContext.defer(() => {
2824
+ if (actorRef.status === ActorStatus.Stopped) {
2825
+ return;
2826
+ }
2827
+ try {
2828
+ actorRef.start?.();
2829
+ } catch (err) {
2830
+ actorContext.self.send(error(actorRef.id, err));
2831
+ return;
2832
+ }
2833
+ });
2834
+ return actorRef;
2835
+ };
2836
+ }
2837
+
2838
+ function resolve$3(actorContext, state, actionArgs, {
2839
+ assignment
2840
+ }) {
2841
+ if (!state.context) {
2842
+ throw new Error('Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.');
2843
+ }
2844
+ const spawnedChildren = {};
2845
+ const assignArgs = {
2846
+ context: state.context,
2847
+ event: actionArgs.event,
2848
+ action: actionArgs.action,
2849
+ spawn: createSpawner(actorContext, state, actionArgs.event, spawnedChildren),
2850
+ self: actorContext?.self,
2851
+ system: actorContext?.system
2852
+ };
2853
+ let partialUpdate = {};
2854
+ if (typeof assignment === 'function') {
2855
+ partialUpdate = assignment(assignArgs);
2856
+ } else {
2857
+ for (const key of Object.keys(assignment)) {
2858
+ const propAssignment = assignment[key];
2859
+ partialUpdate[key] = typeof propAssignment === 'function' ? propAssignment(assignArgs) : propAssignment;
2860
+ }
2861
+ }
2862
+ const updatedContext = Object.assign({}, state.context, partialUpdate);
2863
+ return [cloneState(state, {
2864
+ context: updatedContext,
2865
+ children: Object.keys(spawnedChildren).length ? {
2866
+ ...state.children,
2867
+ ...spawnedChildren
2868
+ } : state.children
2869
+ })];
2945
2870
  }
2946
2871
 
2947
2872
  /**
@@ -2950,48 +2875,47 @@ function createSpawner(self, machine, context, event, mutCapturedActions) {
2950
2875
  * @param assignment An object that represents the partial context to update.
2951
2876
  */
2952
2877
  function assign(assignment) {
2953
- return createDynamicAction({
2954
- type: assign$1,
2955
- params: {
2956
- assignment
2957
- }
2958
- }, (event, {
2959
- state,
2960
- action,
2961
- actorContext
2962
- }) => {
2963
- const capturedActions = [];
2964
- if (!state.context) {
2965
- throw new Error('Cannot assign to undefined `context`. Ensure that `context` is defined in the machine config.');
2966
- }
2967
- const args = {
2968
- context: state.context,
2969
- event,
2970
- action,
2971
- spawn: createSpawner(actorContext?.self, state.machine, state.context, event, capturedActions),
2972
- self: actorContext?.self ?? {},
2973
- system: actorContext?.system
2974
- };
2975
- let partialUpdate = {};
2976
- if (isFunction(assignment)) {
2977
- partialUpdate = assignment(args);
2978
- } else {
2979
- for (const key of Object.keys(assignment)) {
2980
- const propAssignment = assignment[key];
2981
- partialUpdate[key] = isFunction(propAssignment) ? propAssignment(args) : propAssignment;
2982
- }
2983
- }
2984
- const updatedContext = Object.assign({}, state.context, partialUpdate);
2985
- return [cloneState(state, {
2986
- context: updatedContext
2987
- }), {
2988
- type: assign$1,
2989
- params: {
2990
- context: updatedContext,
2991
- actions: capturedActions
2992
- }
2993
- }];
2994
- });
2878
+ function assign(_) {
2879
+ {
2880
+ throw new Error(`This isn't supposed to be called`);
2881
+ }
2882
+ }
2883
+ assign.type = 'xstate.assign';
2884
+ assign.assignment = assignment;
2885
+ assign.resolve = resolve$3;
2886
+ return assign;
2887
+ }
2888
+
2889
+ function resolve$2(_, state, args, {
2890
+ event: eventOrExpr,
2891
+ id,
2892
+ delay
2893
+ }) {
2894
+ const delaysMap = state.machine.implementations.delays;
2895
+ if (typeof eventOrExpr === 'string') {
2896
+ throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
2897
+ }
2898
+ const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
2899
+ let resolvedDelay;
2900
+ if (typeof delay === 'string') {
2901
+ const configDelay = delaysMap && delaysMap[delay];
2902
+ resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
2903
+ } else {
2904
+ resolvedDelay = typeof delay === 'function' ? delay(args) : delay;
2905
+ }
2906
+ return [typeof resolvedDelay !== 'number' ? cloneState(state, {
2907
+ _internalQueue: state._internalQueue.concat(resolvedEvent)
2908
+ }) : state, {
2909
+ event: resolvedEvent,
2910
+ id,
2911
+ delay: resolvedDelay
2912
+ }];
2913
+ }
2914
+ function execute(actorContext, params) {
2915
+ if (typeof params.delay === 'number') {
2916
+ actorContext.self.delaySend(params);
2917
+ return;
2918
+ }
2995
2919
  }
2996
2920
 
2997
2921
  /**
@@ -3002,186 +2926,60 @@ function assign(assignment) {
3002
2926
  */
3003
2927
 
3004
2928
  function raise(eventOrExpr, options) {
3005
- return createDynamicAction({
3006
- type: raise$1,
3007
- params: {
3008
- delay: options ? options.delay : undefined,
3009
- event: eventOrExpr,
3010
- id: options && options.id !== undefined ? options.id : typeof eventOrExpr === 'function' ? eventOrExpr.name : eventOrExpr.type
3011
- }
3012
- }, (event, {
3013
- state,
3014
- actorContext
3015
- }) => {
3016
- const params = {
3017
- delay: options ? options.delay : undefined,
3018
- event: eventOrExpr,
3019
- id: options && options.id !== undefined ? options.id : typeof eventOrExpr === 'function' ? eventOrExpr.name : eventOrExpr.type
3020
- };
3021
- const args = {
3022
- context: state.context,
3023
- event,
3024
- self: actorContext?.self ?? {},
3025
- system: actorContext?.system
3026
- };
3027
- const delaysMap = state.machine.implementations.delays;
3028
-
3029
- // TODO: helper function for resolving Expr
3030
- if (typeof eventOrExpr === 'string') {
3031
- throw new Error(`Only event objects may be used with raise; use raise({ type: "${eventOrExpr}" }) instead`);
2929
+ function raise(_) {
2930
+ {
2931
+ throw new Error(`This isn't supposed to be called`);
3032
2932
  }
3033
- const resolvedEvent = typeof eventOrExpr === 'function' ? eventOrExpr(args) : eventOrExpr;
3034
- let resolvedDelay;
3035
- if (typeof params.delay === 'string') {
3036
- const configDelay = delaysMap && delaysMap[params.delay];
3037
- resolvedDelay = typeof configDelay === 'function' ? configDelay(args) : configDelay;
3038
- } else {
3039
- resolvedDelay = typeof params.delay === 'function' ? params.delay(args) : params.delay;
3040
- }
3041
- const resolvedAction = {
3042
- type: raise$1,
3043
- params: {
3044
- ...params,
3045
- event: resolvedEvent,
3046
- delay: resolvedDelay
3047
- },
3048
- execute: actorCtx => {
3049
- if (typeof resolvedAction.params.delay === 'number') {
3050
- actorCtx.self.delaySend(resolvedAction);
3051
- return;
3052
- }
3053
- }
3054
- };
3055
- return [state, resolvedAction];
3056
- });
2933
+ }
2934
+ raise.type = 'xstate.raise';
2935
+ raise.event = eventOrExpr;
2936
+ raise.id = options?.id;
2937
+ raise.delay = options?.delay;
2938
+ raise.resolve = resolve$2;
2939
+ raise.execute = execute;
2940
+ return raise;
3057
2941
  }
3058
2942
 
3059
- function choose(guards) {
3060
- return createDynamicAction({
3061
- type: choose$1,
3062
- params: {
3063
- guards
3064
- }
3065
- }, (event, {
3066
- state
3067
- }) => {
3068
- const matchedActions = guards.find(condition => {
3069
- const guard = condition.guard && toGuardDefinition(condition.guard, guardType => state.machine.implementations.guards[guardType]);
3070
- return !guard || evaluateGuard(guard, state.context, event, state);
3071
- })?.actions;
3072
- return [state, {
3073
- type: choose$1,
3074
- params: {
3075
- actions: toActionObjects(matchedActions)
3076
- }
3077
- }];
3078
- });
2943
+ function resolve$1(_, state, actionArgs, {
2944
+ branches
2945
+ }) {
2946
+ const matchedActions = branches.find(condition => {
2947
+ const guard = condition.guard && toGuardDefinition(condition.guard, guardType => state.machine.implementations.guards[guardType]);
2948
+ return !guard || evaluateGuard(guard, state.context, actionArgs.event, state);
2949
+ })?.actions;
2950
+ return [state, undefined, toArray(matchedActions)];
3079
2951
  }
3080
-
3081
- function pure(getActions) {
3082
- return createDynamicAction({
3083
- type: pure$1,
3084
- params: {
3085
- get: getActions
2952
+ function choose(branches) {
2953
+ function choose(_) {
2954
+ {
2955
+ throw new Error(`This isn't supposed to be called`);
3086
2956
  }
3087
- }, (event, {
3088
- state
3089
- }) => {
3090
- return [state, {
3091
- type: pure$1,
3092
- params: {
3093
- actions: toArray(toActionObjects(getActions({
3094
- context: state.context,
3095
- event
3096
- }))) ?? []
3097
- }
3098
- }];
3099
- });
3100
- }
3101
-
3102
- const initEvent = {
3103
- type: init
3104
- };
3105
- function resolveActionObject(actionObject, actionFunctionMap) {
3106
- if (isDynamicAction(actionObject)) {
3107
- return actionObject;
3108
- }
3109
- const dereferencedAction = actionFunctionMap[actionObject.type];
3110
- if (typeof dereferencedAction === 'function') {
3111
- return createDynamicAction({
3112
- type: 'xstate.function',
3113
- params: actionObject.params ?? {}
3114
- }, (event, {
3115
- state
3116
- }) => {
3117
- const a = {
3118
- type: actionObject.type,
3119
- params: actionObject.params,
3120
- execute: actorCtx => {
3121
- return dereferencedAction({
3122
- context: state.context,
3123
- event,
3124
- action: a,
3125
- system: actorCtx.system,
3126
- self: actorCtx.self
3127
- });
3128
- }
3129
- };
3130
- return [state, a];
3131
- });
3132
- } else if (dereferencedAction) {
3133
- return dereferencedAction;
3134
- } else {
3135
- return actionObject;
3136
2957
  }
2958
+ choose.type = 'xstate.choose';
2959
+ choose.branches = branches;
2960
+ choose.resolve = resolve$1;
2961
+ return choose;
3137
2962
  }
3138
- function toActionObject(action) {
3139
- if (isDynamicAction(action)) {
3140
- return action;
3141
- }
3142
- if (typeof action === 'string') {
3143
- return {
3144
- type: action,
3145
- params: {}
3146
- };
3147
- }
3148
- if (typeof action === 'function') {
3149
- const type = 'xstate.function';
3150
- return createDynamicAction({
3151
- type,
3152
- params: {}
3153
- }, (event, {
3154
- state
3155
- }) => {
3156
- const actionObject = {
3157
- type,
3158
- params: {
3159
- function: action
3160
- },
3161
- execute: actorCtx => {
3162
- return action({
3163
- context: state.context,
3164
- event: event,
3165
- action: actionObject,
3166
- self: actorCtx.self,
3167
- system: actorCtx.system
3168
- });
3169
- }
3170
- };
3171
- return [state, actionObject];
3172
- });
3173
- }
3174
2963
 
3175
- // action is already a BaseActionObject
3176
- return action;
2964
+ function resolve(_, state, args, {
2965
+ get
2966
+ }) {
2967
+ return [state, undefined, toArray(get({
2968
+ context: state.context,
2969
+ event: args.event
2970
+ }))];
3177
2971
  }
3178
- const toActionObjects = action => {
3179
- if (!action) {
3180
- return [];
2972
+ function pure(getActions) {
2973
+ function pure(_) {
2974
+ {
2975
+ throw new Error(`This isn't supposed to be called`);
2976
+ }
3181
2977
  }
3182
- const actions = isArray(action) ? action : [action];
3183
- return actions.map(toActionObject);
3184
- };
2978
+ pure.type = 'xstate.pure';
2979
+ pure.get = getActions;
2980
+ pure.resolve = resolve;
2981
+ return pure;
2982
+ }
3185
2983
 
3186
2984
  /**
3187
2985
  * Returns an event type that represents an implicit event that
@@ -3192,7 +2990,7 @@ const toActionObjects = action => {
3192
2990
  */
3193
2991
  function after(delayRef, id) {
3194
2992
  const idSuffix = id ? `#${id}` : '';
3195
- return `${ActionTypes.After}(${delayRef})${idSuffix}`;
2993
+ return `${ConstantPrefix.After}(${delayRef})${idSuffix}`;
3196
2994
  }
3197
2995
 
3198
2996
  /**
@@ -3203,7 +3001,7 @@ function after(delayRef, id) {
3203
3001
  * @param output The data to pass into the event
3204
3002
  */
3205
3003
  function done(id, output) {
3206
- const type = `${ActionTypes.DoneState}.${id}`;
3004
+ const type = `${ConstantPrefix.DoneState}.${id}`;
3207
3005
  const eventObject = {
3208
3006
  type,
3209
3007
  output
@@ -3222,7 +3020,7 @@ function done(id, output) {
3222
3020
  * @param output The data to pass into the event
3223
3021
  */
3224
3022
  function doneInvoke(invokeId, output) {
3225
- const type = `${ActionTypes.DoneInvoke}.${invokeId}`;
3023
+ const type = `${ConstantPrefix.DoneInvoke}.${invokeId}`;
3226
3024
  const eventObject = {
3227
3025
  type,
3228
3026
  output
@@ -3231,7 +3029,7 @@ function doneInvoke(invokeId, output) {
3231
3029
  return eventObject;
3232
3030
  }
3233
3031
  function error(id, data) {
3234
- const type = `${ActionTypes.ErrorPlatform}.${id}`;
3032
+ const type = `${ConstantPrefix.ErrorPlatform}.${id}`;
3235
3033
  const eventObject = {
3236
3034
  type,
3237
3035
  data
@@ -3241,9 +3039,9 @@ function error(id, data) {
3241
3039
  }
3242
3040
  function createInitEvent(input) {
3243
3041
  return {
3244
- type: init,
3042
+ type: INIT_TYPE,
3245
3043
  input
3246
3044
  };
3247
3045
  }
3248
3046
 
3249
- export { pathToStateValue as $, resolveActionsAndContext as A, microstep as B, isAtomicStateNode as C, error as D, isStateId as E, getStateNodeByPath as F, getPersistedState as G, resolveReferencedActor as H, interpret as I, createInitEvent as J, initEvent as K, matchesState as L, sendTo as M, NULL_EVENT as N, sendParent as O, forwardTo as P, Interpreter as Q, ActorStatus as R, STATE_DELIMITER as S, doneInvoke as T, assign as U, cancel as V, choose as W, log as X, pure as Y, raise as Z, stop as _, toArray as a, toObserver as a0, fromPromise as a1, fromObservable as a2, fromCallback as a3, fromEventObservable as a4, fromTransition as a5, stateIn as a6, not as a7, and as a8, or as a9, ActionTypes as aa, SpecialTargets as ab, startSignalType as ac, stopSignalType as ad, startSignal as ae, stopSignal as af, isSignal as ag, isActorRef as ah, toActorRef as ai, createEmptyActor as aj, toGuardDefinition as ak, actionTypes as al, resolveActionObject as am, toActionObject as an, after as ao, done as ap, send as aq, escalate as ar, toTransitionConfigArray as b, formatTransition as c, memo as d, evaluateGuard as e, formatTransitions as f, flatten as g, createInvokeId as h, isString as i, invoke$1 as j, getDelayedTransitions as k, formatInitialTransition as l, mapValues as m, getCandidates as n, toInvokeConfig as o, createSpawner as p, getConfiguration as q, getStateNodes as r, resolveStateValue as s, toActionObjects as t, isInFinalState as u, State as v, isErrorEvent as w, macrostep as x, transitionNode as y, getInitialConfiguration as z };
3047
+ export { fromEventObservable as $, isAtomicStateNode as A, error as B, isStateId as C, getStateNodeByPath as D, getPersistedState as E, resolveReferencedActor as F, interpret as G, matchesState as H, sendTo as I, sendParent as J, forwardTo as K, Interpreter as L, ActorStatus as M, NULL_EVENT as N, doneInvoke as O, cancel as P, choose as Q, log as R, STATE_DELIMITER as S, pure as T, raise as U, stop as V, pathToStateValue as W, toObserver as X, fromPromise as Y, fromObservable as Z, fromCallback as _, toTransitionConfigArray as a, fromTransition as a0, stateIn as a1, not as a2, and as a3, or as a4, ConstantPrefix as a5, SpecialTargets as a6, startSignalType as a7, stopSignalType as a8, startSignal as a9, stopSignal as aa, isSignal as ab, isActorRef as ac, toActorRef as ad, createEmptyActor as ae, toGuardDefinition as af, constantPrefixes as ag, after as ah, done as ai, escalate as aj, formatTransition as b, memo as c, flatten as d, evaluateGuard as e, formatTransitions as f, createInvokeId as g, getDelayedTransitions as h, formatInitialTransition as i, getCandidates as j, toInvokeConfig as k, getConfiguration as l, mapValues as m, getStateNodes as n, isInFinalState as o, State as p, isErrorEvent as q, resolveStateValue as r, macrostep as s, toArray as t, transitionNode as u, getInitialConfiguration as v, resolveActionsAndContext as w, assign as x, createInitEvent as y, microstep as z };