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