xstate 5.0.0-beta.43 → 5.0.0-beta.44

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 (46) hide show
  1. package/actions/dist/xstate-actions.cjs.js +2 -3
  2. package/actions/dist/xstate-actions.development.cjs.js +2 -3
  3. package/actions/dist/xstate-actions.development.esm.js +2 -3
  4. package/actions/dist/xstate-actions.esm.js +2 -3
  5. package/actions/dist/xstate-actions.umd.min.js +1 -1
  6. package/actions/dist/xstate-actions.umd.min.js.map +1 -1
  7. package/actors/dist/xstate-actors.cjs.js +6 -6
  8. package/actors/dist/xstate-actors.development.cjs.js +6 -6
  9. package/actors/dist/xstate-actors.development.esm.js +1 -1
  10. package/actors/dist/xstate-actors.esm.js +1 -1
  11. package/actors/dist/xstate-actors.umd.min.js +1 -1
  12. package/actors/dist/xstate-actors.umd.min.js.map +1 -1
  13. package/dist/declarations/src/State.d.ts +3 -7
  14. package/dist/declarations/src/actions/spawn.d.ts +11 -16
  15. package/dist/declarations/src/guards.d.ts +2 -2
  16. package/dist/declarations/src/index.d.ts +1 -1
  17. package/dist/declarations/src/spawn.d.ts +9 -13
  18. package/dist/declarations/src/stateUtils.d.ts +4 -4
  19. package/dist/declarations/src/types.d.ts +15 -16
  20. package/dist/declarations/src/utils.d.ts +1 -3
  21. package/dist/{raise-e0fe5c2d.cjs.js → raise-348cc74e.development.esm.js} +946 -68
  22. package/dist/{raise-f4ad5a87.development.esm.js → raise-5854eaca.esm.js} +860 -49
  23. package/dist/{raise-23dea0d7.development.cjs.js → raise-ed700d14.development.cjs.js} +922 -36
  24. package/dist/{raise-8dc8e1aa.esm.js → raise-fb6f017b.cjs.js} +907 -2
  25. package/dist/{send-0174c155.development.cjs.js → send-00466e37.development.cjs.js} +11 -12
  26. package/dist/{send-87bbaaab.cjs.js → send-53e5693c.cjs.js} +11 -12
  27. package/dist/{send-5d129d95.development.esm.js → send-a0193bdb.development.esm.js} +2 -3
  28. package/dist/{send-84e2e742.esm.js → send-b7b4befa.esm.js} +2 -3
  29. package/dist/xstate.cjs.js +25 -25
  30. package/dist/xstate.cjs.mjs +1 -0
  31. package/dist/xstate.development.cjs.js +25 -25
  32. package/dist/xstate.development.cjs.mjs +1 -0
  33. package/dist/xstate.development.esm.js +4 -6
  34. package/dist/xstate.esm.js +4 -6
  35. package/dist/xstate.umd.min.js +1 -1
  36. package/dist/xstate.umd.min.js.map +1 -1
  37. package/guards/dist/xstate-guards.cjs.js +1 -2
  38. package/guards/dist/xstate-guards.development.cjs.js +1 -2
  39. package/guards/dist/xstate-guards.development.esm.js +1 -2
  40. package/guards/dist/xstate-guards.esm.js +1 -2
  41. package/guards/dist/xstate-guards.umd.min.js.map +1 -1
  42. package/package.json +1 -1
  43. package/dist/interpreter-36d5556e.cjs.js +0 -887
  44. package/dist/interpreter-4e8e2a0d.development.cjs.js +0 -898
  45. package/dist/interpreter-63c80754.esm.js +0 -857
  46. package/dist/interpreter-80eb3bec.development.esm.js +0 -868
@@ -1,6 +1,866 @@
1
- 'use strict';
1
+ import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
2
2
 
3
- var interpreter = require('./interpreter-36d5556e.cjs.js');
3
+ class Mailbox {
4
+ constructor(_process) {
5
+ this._process = _process;
6
+ this._active = false;
7
+ this._current = null;
8
+ this._last = null;
9
+ }
10
+ start() {
11
+ this._active = true;
12
+ this.flush();
13
+ }
14
+ clear() {
15
+ // we can't set _current to null because we might be currently processing
16
+ // and enqueue following clear shouldnt start processing the enqueued item immediately
17
+ if (this._current) {
18
+ this._current.next = null;
19
+ this._last = this._current;
20
+ }
21
+ }
22
+ enqueue(event) {
23
+ const enqueued = {
24
+ value: event,
25
+ next: null
26
+ };
27
+ if (this._current) {
28
+ this._last.next = enqueued;
29
+ this._last = enqueued;
30
+ return;
31
+ }
32
+ this._current = enqueued;
33
+ this._last = enqueued;
34
+ if (this._active) {
35
+ this.flush();
36
+ }
37
+ }
38
+ flush() {
39
+ while (this._current) {
40
+ // atm the given _process is responsible for implementing proper try/catch handling
41
+ // we assume here that this won't throw in a way that can affect this mailbox
42
+ const consumed = this._current;
43
+ this._process(consumed.value);
44
+ this._current = consumed.next;
45
+ }
46
+ this._last = null;
47
+ }
48
+ }
49
+
50
+ const STATE_DELIMITER = '.';
51
+ const TARGETLESS_KEY = '';
52
+ const NULL_EVENT = '';
53
+ const STATE_IDENTIFIER = '#';
54
+ const WILDCARD = '*';
55
+ const XSTATE_INIT = 'xstate.init';
56
+ const XSTATE_ERROR = 'xstate.error';
57
+ const XSTATE_STOP = 'xstate.stop';
58
+
59
+ /**
60
+ * Returns an event that represents an implicit event that
61
+ * is sent after the specified `delay`.
62
+ *
63
+ * @param delayRef The delay in milliseconds
64
+ * @param id The state node ID where this event is handled
65
+ */
66
+ function createAfterEvent(delayRef, id) {
67
+ const idSuffix = id ? `#${id}` : '';
68
+ return {
69
+ type: `xstate.after(${delayRef})${idSuffix}`
70
+ };
71
+ }
72
+
73
+ /**
74
+ * Returns an event that represents that a final state node
75
+ * has been reached in the parent state node.
76
+ *
77
+ * @param id The final state node's parent state node `id`
78
+ * @param output The data to pass into the event
79
+ */
80
+ function createDoneStateEvent(id, output) {
81
+ return {
82
+ type: `xstate.done.state.${id}`,
83
+ output
84
+ };
85
+ }
86
+
87
+ /**
88
+ * Returns an event that represents that an invoked service has terminated.
89
+ *
90
+ * An invoked service is terminated when it has reached a top-level final state node,
91
+ * but not when it is canceled.
92
+ *
93
+ * @param invokeId The invoked service ID
94
+ * @param output The data to pass into the event
95
+ */
96
+ function createDoneActorEvent(invokeId, output) {
97
+ return {
98
+ type: `xstate.done.actor.${invokeId}`,
99
+ output
100
+ };
101
+ }
102
+ function createErrorActorEvent(id, data) {
103
+ return {
104
+ type: `xstate.error.actor.${id}`,
105
+ data
106
+ };
107
+ }
108
+ function createInitEvent(input) {
109
+ return {
110
+ type: XSTATE_INIT,
111
+ input
112
+ };
113
+ }
114
+
115
+ /**
116
+ * This function makes sure that unhandled errors are thrown in a separate macrotask.
117
+ * It allows those errors to be detected by global error handlers and reported to bug tracking services
118
+ * without interrupting our own stack of execution.
119
+ *
120
+ * @param err error to be thrown
121
+ */
122
+ function reportUnhandledError(err) {
123
+ setTimeout(() => {
124
+ throw err;
125
+ });
126
+ }
127
+
128
+ const symbolObservable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();
129
+
130
+ let idCounter = 0;
131
+ function createSystem(rootActor) {
132
+ const children = new Map();
133
+ const keyedActors = new Map();
134
+ const reverseKeyedActors = new WeakMap();
135
+ const observers = new Set();
136
+ const system = {
137
+ _bookId: () => `x:${idCounter++}`,
138
+ _register: (sessionId, actorRef) => {
139
+ children.set(sessionId, actorRef);
140
+ return sessionId;
141
+ },
142
+ _unregister: actorRef => {
143
+ children.delete(actorRef.sessionId);
144
+ const systemId = reverseKeyedActors.get(actorRef);
145
+ if (systemId !== undefined) {
146
+ keyedActors.delete(systemId);
147
+ reverseKeyedActors.delete(actorRef);
148
+ }
149
+ },
150
+ get: systemId => {
151
+ return keyedActors.get(systemId);
152
+ },
153
+ _set: (systemId, actorRef) => {
154
+ const existing = keyedActors.get(systemId);
155
+ if (existing && existing !== actorRef) {
156
+ throw new Error(`Actor with system ID '${systemId}' already exists.`);
157
+ }
158
+ keyedActors.set(systemId, actorRef);
159
+ reverseKeyedActors.set(actorRef, systemId);
160
+ },
161
+ inspect: observer => {
162
+ observers.add(observer);
163
+ },
164
+ _sendInspectionEvent: event => {
165
+ const resolvedInspectionEvent = {
166
+ ...event,
167
+ rootId: rootActor.sessionId
168
+ };
169
+ observers.forEach(observer => observer.next?.(resolvedInspectionEvent));
170
+ },
171
+ _relay: (source, target, event) => {
172
+ system._sendInspectionEvent({
173
+ type: '@xstate.event',
174
+ sourceRef: source,
175
+ actorRef: target,
176
+ event
177
+ });
178
+ target._send(event);
179
+ }
180
+ };
181
+ return system;
182
+ }
183
+
184
+ function matchesState(parentStateId, childStateId) {
185
+ const parentStateValue = toStateValue(parentStateId);
186
+ const childStateValue = toStateValue(childStateId);
187
+ if (typeof childStateValue === 'string') {
188
+ if (typeof parentStateValue === 'string') {
189
+ return childStateValue === parentStateValue;
190
+ }
191
+
192
+ // Parent more specific than child
193
+ return false;
194
+ }
195
+ if (typeof parentStateValue === 'string') {
196
+ return parentStateValue in childStateValue;
197
+ }
198
+ return Object.keys(parentStateValue).every(key => {
199
+ if (!(key in childStateValue)) {
200
+ return false;
201
+ }
202
+ return matchesState(parentStateValue[key], childStateValue[key]);
203
+ });
204
+ }
205
+ function toStatePath(stateId) {
206
+ try {
207
+ if (isArray(stateId)) {
208
+ return stateId;
209
+ }
210
+ return stateId.split(STATE_DELIMITER);
211
+ } catch (e) {
212
+ throw new Error(`'${stateId}' is not a valid state path.`);
213
+ }
214
+ }
215
+ function toStateValue(stateValue) {
216
+ if (isMachineSnapshot(stateValue)) {
217
+ return stateValue.value;
218
+ }
219
+ if (typeof stateValue !== 'string') {
220
+ return stateValue;
221
+ }
222
+ const statePath = toStatePath(stateValue);
223
+ return pathToStateValue(statePath);
224
+ }
225
+ function pathToStateValue(statePath) {
226
+ if (statePath.length === 1) {
227
+ return statePath[0];
228
+ }
229
+ const value = {};
230
+ let marker = value;
231
+ for (let i = 0; i < statePath.length - 1; i++) {
232
+ if (i === statePath.length - 2) {
233
+ marker[statePath[i]] = statePath[i + 1];
234
+ } else {
235
+ const previous = marker;
236
+ marker = {};
237
+ previous[statePath[i]] = marker;
238
+ }
239
+ }
240
+ return value;
241
+ }
242
+ function mapValues(collection, iteratee) {
243
+ const result = {};
244
+ const collectionKeys = Object.keys(collection);
245
+ for (let i = 0; i < collectionKeys.length; i++) {
246
+ const key = collectionKeys[i];
247
+ result[key] = iteratee(collection[key], key, collection, i);
248
+ }
249
+ return result;
250
+ }
251
+ function flatten(array) {
252
+ return [].concat(...array);
253
+ }
254
+ function toArrayStrict(value) {
255
+ if (isArray(value)) {
256
+ return value;
257
+ }
258
+ return [value];
259
+ }
260
+ function toArray(value) {
261
+ if (value === undefined) {
262
+ return [];
263
+ }
264
+ return toArrayStrict(value);
265
+ }
266
+ function resolveOutput(mapper, context, event, self) {
267
+ if (typeof mapper === 'function') {
268
+ return mapper({
269
+ context,
270
+ event,
271
+ self
272
+ });
273
+ }
274
+ if (!!mapper && typeof mapper === 'object' && Object.values(mapper).some(val => typeof val === 'function')) {
275
+ console.warn(`Dynamically mapping values to individual properties is deprecated. Use a single function that returns the mapped object instead.\nFound object containing properties whose values are possibly mapping functions: ${Object.entries(mapper).filter(([key, value]) => typeof value === 'function').map(([key, value]) => `\n - ${key}: ${value.toString().replace(/\n\s*/g, '')}`).join('')}`);
276
+ }
277
+ return mapper;
278
+ }
279
+ function isArray(value) {
280
+ return Array.isArray(value);
281
+ }
282
+ function isErrorActorEvent(event) {
283
+ return event.type.startsWith('xstate.error.actor');
284
+ }
285
+ function toTransitionConfigArray(configLike) {
286
+ return toArrayStrict(configLike).map(transitionLike => {
287
+ if (typeof transitionLike === 'undefined' || typeof transitionLike === 'string') {
288
+ return {
289
+ target: transitionLike
290
+ };
291
+ }
292
+ return transitionLike;
293
+ });
294
+ }
295
+ function normalizeTarget(target) {
296
+ if (target === undefined || target === TARGETLESS_KEY) {
297
+ return undefined;
298
+ }
299
+ return toArray(target);
300
+ }
301
+ function toObserver(nextHandler, errorHandler, completionHandler) {
302
+ const isObserver = typeof nextHandler === 'object';
303
+ const self = isObserver ? nextHandler : undefined;
304
+ return {
305
+ next: (isObserver ? nextHandler.next : nextHandler)?.bind(self),
306
+ error: (isObserver ? nextHandler.error : errorHandler)?.bind(self),
307
+ complete: (isObserver ? nextHandler.complete : completionHandler)?.bind(self)
308
+ };
309
+ }
310
+ function createInvokeId(stateNodeId, index) {
311
+ return `${stateNodeId}[${index}]`;
312
+ }
313
+ function resolveReferencedActor(machine, src) {
314
+ if (src.startsWith('xstate#')) {
315
+ const [, indexStr] = src.match(/\[(\d+)\]$/);
316
+ const node = machine.getStateNodeById(src.slice(7, -(indexStr.length + 2)));
317
+ const invokeConfig = node.config.invoke;
318
+ return (Array.isArray(invokeConfig) ? invokeConfig[indexStr] : invokeConfig).src;
319
+ }
320
+ return machine.implementations.actors[src];
321
+ }
322
+
323
+ const $$ACTOR_TYPE = 1;
324
+ // those values are currently used by @xstate/react directly so it's important to keep the assigned values in sync
325
+ let ProcessingStatus = /*#__PURE__*/function (ProcessingStatus) {
326
+ ProcessingStatus[ProcessingStatus["NotStarted"] = 0] = "NotStarted";
327
+ ProcessingStatus[ProcessingStatus["Running"] = 1] = "Running";
328
+ ProcessingStatus[ProcessingStatus["Stopped"] = 2] = "Stopped";
329
+ return ProcessingStatus;
330
+ }({});
331
+ const defaultOptions = {
332
+ clock: {
333
+ setTimeout: (fn, ms) => {
334
+ return setTimeout(fn, ms);
335
+ },
336
+ clearTimeout: id => {
337
+ return clearTimeout(id);
338
+ }
339
+ },
340
+ logger: console.log.bind(console),
341
+ devTools: false
342
+ };
343
+
344
+ /**
345
+ * An Actor is a running process that can receive events, send events and change its behavior based on the events it receives, which can cause effects outside of the actor. When you run a state machine, it becomes an actor.
346
+ */
347
+ class Actor {
348
+ /**
349
+ * The current internal state of the actor.
350
+ */
351
+
352
+ /**
353
+ * The clock that is responsible for setting and clearing timeouts, such as delayed events and transitions.
354
+ */
355
+
356
+ /**
357
+ * The unique identifier for this actor relative to its parent.
358
+ */
359
+
360
+ /** @internal */
361
+
362
+ // Actor Ref
363
+
364
+ // TODO: add typings for system
365
+
366
+ /**
367
+ * The globally unique process ID for this invocation.
368
+ */
369
+
370
+ /**
371
+ * The system to which this actor belongs.
372
+ */
373
+
374
+ /**
375
+ * Creates a new actor instance for the given logic with the provided options, if any.
376
+ *
377
+ * @param logic The logic to create an actor from
378
+ * @param options Actor options
379
+ */
380
+ constructor(logic, options) {
381
+ this.logic = logic;
382
+ this._state = void 0;
383
+ this.clock = void 0;
384
+ this.options = void 0;
385
+ this.id = void 0;
386
+ this.mailbox = new Mailbox(this._process.bind(this));
387
+ this.delayedEventsMap = {};
388
+ this.observers = new Set();
389
+ this.logger = void 0;
390
+ this._processingStatus = ProcessingStatus.NotStarted;
391
+ this._parent = void 0;
392
+ this.ref = void 0;
393
+ this._actorScope = void 0;
394
+ this._systemId = void 0;
395
+ this.sessionId = void 0;
396
+ this.system = void 0;
397
+ this._doneEvent = void 0;
398
+ this.src = void 0;
399
+ this._deferred = [];
400
+ const resolvedOptions = {
401
+ ...defaultOptions,
402
+ ...options
403
+ };
404
+ const {
405
+ clock,
406
+ logger,
407
+ parent,
408
+ id,
409
+ systemId,
410
+ inspect
411
+ } = resolvedOptions;
412
+ this.system = parent?.system ?? createSystem(this);
413
+ if (inspect && !parent) {
414
+ // Always inspect at the system-level
415
+ this.system.inspect(toObserver(inspect));
416
+ }
417
+ this.sessionId = this.system._bookId();
418
+ this.id = id ?? this.sessionId;
419
+ this.logger = logger;
420
+ this.clock = clock;
421
+ this._parent = parent;
422
+ this.options = resolvedOptions;
423
+ this.src = resolvedOptions.src ?? logic;
424
+ this.ref = this;
425
+ this._actorScope = {
426
+ self: this,
427
+ id: this.id,
428
+ sessionId: this.sessionId,
429
+ logger: this.logger,
430
+ defer: fn => {
431
+ this._deferred.push(fn);
432
+ },
433
+ system: this.system,
434
+ stopChild: child => {
435
+ if (child._parent !== this) {
436
+ throw new Error(`Cannot stop child actor ${child.id} of ${this.id} because it is not a child`);
437
+ }
438
+ child._stop();
439
+ }
440
+ };
441
+
442
+ // Ensure that the send method is bound to this Actor instance
443
+ // if destructured
444
+ this.send = this.send.bind(this);
445
+ this.system._sendInspectionEvent({
446
+ type: '@xstate.actor',
447
+ actorRef: this
448
+ });
449
+ if (systemId) {
450
+ this._systemId = systemId;
451
+ this.system._set(systemId, this);
452
+ }
453
+ this._initState(options?.state);
454
+ if (systemId && this._state.status !== 'active') {
455
+ this.system._unregister(this);
456
+ }
457
+ }
458
+ _initState(persistedState) {
459
+ this._state = persistedState ? this.logic.restoreState ? this.logic.restoreState(persistedState, this._actorScope) : persistedState : this.logic.getInitialState(this._actorScope, this.options?.input);
460
+ }
461
+
462
+ // array of functions to defer
463
+
464
+ update(snapshot, event) {
465
+ // Update state
466
+ this._state = snapshot;
467
+
468
+ // Execute deferred effects
469
+ let deferredFn;
470
+ while (deferredFn = this._deferred.shift()) {
471
+ deferredFn();
472
+ }
473
+ for (const observer of this.observers) {
474
+ try {
475
+ observer.next?.(snapshot);
476
+ } catch (err) {
477
+ reportUnhandledError(err);
478
+ }
479
+ }
480
+ switch (this._state.status) {
481
+ case 'done':
482
+ this._stopProcedure();
483
+ this._complete();
484
+ this._doneEvent = createDoneActorEvent(this.id, this._state.output);
485
+ if (this._parent) {
486
+ this.system._relay(this, this._parent, this._doneEvent);
487
+ }
488
+ break;
489
+ case 'error':
490
+ this._stopProcedure();
491
+ this._error(this._state.error);
492
+ if (this._parent) {
493
+ this.system._relay(this, this._parent, createErrorActorEvent(this.id, this._state.error));
494
+ }
495
+ break;
496
+ }
497
+ this.system._sendInspectionEvent({
498
+ type: '@xstate.snapshot',
499
+ actorRef: this,
500
+ event,
501
+ snapshot
502
+ });
503
+ }
504
+
505
+ /**
506
+ * Subscribe an observer to an actor’s snapshot values.
507
+ *
508
+ * @remarks
509
+ * The observer will receive the actor’s snapshot value when it is emitted. The observer can be:
510
+ * - A plain function that receives the latest snapshot, or
511
+ * - An observer object whose `.next(snapshot)` method receives the latest snapshot
512
+ *
513
+ * @example
514
+ * ```ts
515
+ * // Observer as a plain function
516
+ * const subscription = actor.subscribe((snapshot) => {
517
+ * console.log(snapshot);
518
+ * });
519
+ * ```
520
+ *
521
+ * @example
522
+ * ```ts
523
+ * // Observer as an object
524
+ * const subscription = actor.subscribe({
525
+ * next(snapshot) {
526
+ * console.log(snapshot);
527
+ * },
528
+ * error(err) {
529
+ * // ...
530
+ * },
531
+ * complete() {
532
+ * // ...
533
+ * },
534
+ * });
535
+ * ```
536
+ *
537
+ * The return value of `actor.subscribe(observer)` is a subscription object that has an `.unsubscribe()` method. You can call `subscription.unsubscribe()` to unsubscribe the observer:
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * const subscription = actor.subscribe((snapshot) => {
542
+ * // ...
543
+ * });
544
+ *
545
+ * // Unsubscribe the observer
546
+ * subscription.unsubscribe();
547
+ * ```
548
+ *
549
+ * When the actor is stopped, all of its observers will automatically be unsubscribed.
550
+ *
551
+ * @param observer - Either a plain function that receives the latest snapshot, or an observer object whose `.next(snapshot)` method receives the latest snapshot
552
+ */
553
+
554
+ subscribe(nextListenerOrObserver, errorListener, completeListener) {
555
+ const observer = toObserver(nextListenerOrObserver, errorListener, completeListener);
556
+ if (this._processingStatus !== ProcessingStatus.Stopped) {
557
+ this.observers.add(observer);
558
+ } else {
559
+ try {
560
+ observer.complete?.();
561
+ } catch (err) {
562
+ reportUnhandledError(err);
563
+ }
564
+ }
565
+ return {
566
+ unsubscribe: () => {
567
+ this.observers.delete(observer);
568
+ }
569
+ };
570
+ }
571
+
572
+ /**
573
+ * Starts the Actor from the initial state
574
+ */
575
+ start() {
576
+ if (this._processingStatus === ProcessingStatus.Running) {
577
+ // Do not restart the service if it is already started
578
+ return this;
579
+ }
580
+ this.system._register(this.sessionId, this);
581
+ if (this._systemId) {
582
+ this.system._set(this._systemId, this);
583
+ }
584
+ this._processingStatus = ProcessingStatus.Running;
585
+
586
+ // TODO: this isn't correct when rehydrating
587
+ const initEvent = createInitEvent(this.options.input);
588
+ this.system._sendInspectionEvent({
589
+ type: '@xstate.event',
590
+ sourceRef: this._parent,
591
+ actorRef: this,
592
+ event: initEvent
593
+ });
594
+ const status = this._state.status;
595
+ switch (status) {
596
+ case 'done':
597
+ // a state machine can be "done" upon initialization (it could reach a final state using initial microsteps)
598
+ // we still need to complete observers, flush deferreds etc
599
+ this.update(this._state, initEvent);
600
+ // fallthrough
601
+ case 'error':
602
+ // TODO: rethink cleanup of observers, mailbox, etc
603
+ return this;
604
+ }
605
+ if (this.logic.start) {
606
+ try {
607
+ this.logic.start(this._state, this._actorScope);
608
+ } catch (err) {
609
+ this._stopProcedure();
610
+ this._error(err);
611
+ this._parent?.send(createErrorActorEvent(this.id, err));
612
+ return this;
613
+ }
614
+ }
615
+
616
+ // TODO: this notifies all subscribers but usually this is redundant
617
+ // there is no real change happening here
618
+ // we need to rethink if this needs to be refactored
619
+ this.update(this._state, initEvent);
620
+ if (this.options.devTools) {
621
+ this.attachDevTools();
622
+ }
623
+ this.mailbox.start();
624
+ return this;
625
+ }
626
+ _process(event) {
627
+ // TODO: reexamine what happens when an action (or a guard or smth) throws
628
+ let nextState;
629
+ let caughtError;
630
+ try {
631
+ nextState = this.logic.transition(this._state, event, this._actorScope);
632
+ } catch (err) {
633
+ // we wrap it in a box so we can rethrow it later even if falsy value gets caught here
634
+ caughtError = {
635
+ err
636
+ };
637
+ }
638
+ if (caughtError) {
639
+ const {
640
+ err
641
+ } = caughtError;
642
+ this._stopProcedure();
643
+ this._error(err);
644
+ this._parent?.send(createErrorActorEvent(this.id, err));
645
+ return;
646
+ }
647
+ this.update(nextState, event);
648
+ if (event.type === XSTATE_STOP) {
649
+ this._stopProcedure();
650
+ this._complete();
651
+ }
652
+ }
653
+ _stop() {
654
+ if (this._processingStatus === ProcessingStatus.Stopped) {
655
+ return this;
656
+ }
657
+ this.mailbox.clear();
658
+ if (this._processingStatus === ProcessingStatus.NotStarted) {
659
+ this._processingStatus = ProcessingStatus.Stopped;
660
+ return this;
661
+ }
662
+ this.mailbox.enqueue({
663
+ type: XSTATE_STOP
664
+ });
665
+ return this;
666
+ }
667
+
668
+ /**
669
+ * Stops the Actor and unsubscribe all listeners.
670
+ */
671
+ stop() {
672
+ if (this._parent) {
673
+ throw new Error('A non-root actor cannot be stopped directly.');
674
+ }
675
+ return this._stop();
676
+ }
677
+ _complete() {
678
+ for (const observer of this.observers) {
679
+ try {
680
+ observer.complete?.();
681
+ } catch (err) {
682
+ reportUnhandledError(err);
683
+ }
684
+ }
685
+ this.observers.clear();
686
+ }
687
+ _error(err) {
688
+ if (!this.observers.size) {
689
+ if (!this._parent) {
690
+ reportUnhandledError(err);
691
+ }
692
+ return;
693
+ }
694
+ let reportError = false;
695
+ for (const observer of this.observers) {
696
+ const errorListener = observer.error;
697
+ reportError ||= !errorListener;
698
+ try {
699
+ errorListener?.(err);
700
+ } catch (err2) {
701
+ reportUnhandledError(err2);
702
+ }
703
+ }
704
+ this.observers.clear();
705
+ if (reportError) {
706
+ reportUnhandledError(err);
707
+ }
708
+ }
709
+ _stopProcedure() {
710
+ if (this._processingStatus !== ProcessingStatus.Running) {
711
+ // Actor already stopped; do nothing
712
+ return this;
713
+ }
714
+
715
+ // Cancel all delayed events
716
+ for (const key of Object.keys(this.delayedEventsMap)) {
717
+ this.clock.clearTimeout(this.delayedEventsMap[key]);
718
+ }
719
+
720
+ // TODO: mailbox.reset
721
+ this.mailbox.clear();
722
+ // TODO: after `stop` we must prepare ourselves for receiving events again
723
+ // events sent *after* stop signal must be queued
724
+ // it seems like this should be the common behavior for all of our consumers
725
+ // so perhaps this should be unified somehow for all of them
726
+ this.mailbox = new Mailbox(this._process.bind(this));
727
+ this._processingStatus = ProcessingStatus.Stopped;
728
+ this.system._unregister(this);
729
+ return this;
730
+ }
731
+
732
+ /**
733
+ * @internal
734
+ */
735
+ _send(event) {
736
+ if (this._processingStatus === ProcessingStatus.Stopped) {
737
+ // do nothing
738
+ {
739
+ const eventString = JSON.stringify(event);
740
+ console.warn(`Event "${event.type}" was sent to stopped actor "${this.id} (${this.sessionId})". This actor has already reached its final state, and will not transition.\nEvent: ${eventString}`);
741
+ }
742
+ return;
743
+ }
744
+ this.mailbox.enqueue(event);
745
+ }
746
+
747
+ /**
748
+ * Sends an event to the running Actor to trigger a transition.
749
+ *
750
+ * @param event The event to send
751
+ */
752
+ send(event) {
753
+ if (typeof event === 'string') {
754
+ throw new Error(`Only event objects may be sent to actors; use .send({ type: "${event}" }) instead`);
755
+ }
756
+ this.system._relay(undefined, this, event);
757
+ }
758
+
759
+ /**
760
+ * TODO: figure out a way to do this within the machine
761
+ * @internal
762
+ */
763
+ delaySend(params) {
764
+ const {
765
+ event,
766
+ id,
767
+ delay
768
+ } = params;
769
+ const timerId = this.clock.setTimeout(() => {
770
+ this.system._relay(this, params.to ?? this, event);
771
+ }, delay);
772
+
773
+ // TODO: consider the rehydration story here
774
+ if (id) {
775
+ this.delayedEventsMap[id] = timerId;
776
+ }
777
+ }
778
+
779
+ /**
780
+ * TODO: figure out a way to do this within the machine
781
+ * @internal
782
+ */
783
+ cancel(sendId) {
784
+ this.clock.clearTimeout(this.delayedEventsMap[sendId]);
785
+ delete this.delayedEventsMap[sendId];
786
+ }
787
+ attachDevTools() {
788
+ const {
789
+ devTools
790
+ } = this.options;
791
+ if (devTools) {
792
+ const resolvedDevToolsAdapter = typeof devTools === 'function' ? devTools : devToolsAdapter;
793
+ resolvedDevToolsAdapter(this);
794
+ }
795
+ }
796
+ toJSON() {
797
+ return {
798
+ xstate$$type: $$ACTOR_TYPE,
799
+ id: this.id
800
+ };
801
+ }
802
+
803
+ /**
804
+ * Obtain the internal state of the actor, which can be persisted.
805
+ *
806
+ * @remarks
807
+ * The internal state can be persisted from any actor, not only machines.
808
+ *
809
+ * Note that the persisted state is not the same as the snapshot from {@link Actor.getSnapshot}. Persisted state represents the internal state of the actor, while snapshots represent the actor's last emitted value.
810
+ *
811
+ * Can be restored with {@link ActorOptions.state}
812
+ *
813
+ * @see https://stately.ai/docs/persistence
814
+ */
815
+
816
+ getPersistedState(options) {
817
+ return this.logic.getPersistedState(this._state, options);
818
+ }
819
+ [symbolObservable]() {
820
+ return this;
821
+ }
822
+
823
+ /**
824
+ * Read an actor’s snapshot synchronously.
825
+ *
826
+ * @remarks
827
+ * The snapshot represent an actor's last emitted value.
828
+ *
829
+ * When an actor receives an event, its internal state may change.
830
+ * An actor may emit a snapshot when a state transition occurs.
831
+ *
832
+ * Note that some actors, such as callback actors generated with `fromCallback`, will not emit snapshots.
833
+ *
834
+ * @see {@link Actor.subscribe} to subscribe to an actor’s snapshot values.
835
+ * @see {@link Actor.getPersistedState} to persist the internal state of an actor (which is more than just a snapshot).
836
+ */
837
+ getSnapshot() {
838
+ return this._state;
839
+ }
840
+ }
841
+
842
+ /**
843
+ * Creates a new `ActorRef` instance for the given machine with the provided options, if any.
844
+ *
845
+ * @param machine The machine to create an actor from
846
+ * @param options `ActorRef` options
847
+ */
848
+
849
+ function createActor(logic, options) {
850
+ const interpreter = new Actor(logic, options);
851
+ return interpreter;
852
+ }
853
+
854
+ /**
855
+ * Creates a new Interpreter instance for the given machine with the provided options, if any.
856
+ *
857
+ * @deprecated Use `createActor` instead
858
+ */
859
+ const interpret = createActor;
860
+
861
+ /**
862
+ * @deprecated Use `Actor` instead.
863
+ */
4
864
 
5
865
  const cache = new WeakMap();
6
866
  function memo(object, key, fn) {
@@ -34,6 +894,9 @@ function executeCancel(actorScope, resolvedSendId) {
34
894
  */
35
895
  function cancel(sendId) {
36
896
  function cancel(args, params) {
897
+ {
898
+ throw new Error(`This isn't supposed to be called`);
899
+ }
37
900
  }
38
901
  cancel.type = 'xstate.cancel';
39
902
  cancel.sendId = sendId;
@@ -49,11 +912,11 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
49
912
  input,
50
913
  syncSnapshot
51
914
  }) {
52
- const logic = typeof src === 'string' ? interpreter.resolveReferencedActor(state.machine, src) : src;
915
+ const logic = typeof src === 'string' ? resolveReferencedActor(state.machine, src) : src;
53
916
  const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
54
917
  let actorRef;
55
918
  if (logic) {
56
- actorRef = interpreter.createActor(logic, {
919
+ actorRef = createActor(logic, {
57
920
  id: resolvedId,
58
921
  src,
59
922
  parent: actorScope?.self,
@@ -78,6 +941,9 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
78
941
  });
79
942
  }
80
943
  }
944
+ if (!actorRef) {
945
+ console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
946
+ }
81
947
  return [cloneMachineSnapshot(state, {
82
948
  children: {
83
949
  ...state.children,
@@ -96,13 +962,13 @@ function executeSpawn(actorScope, {
96
962
  return;
97
963
  }
98
964
  actorScope.defer(() => {
99
- if (actorRef._processingStatus === interpreter.ProcessingStatus.Stopped) {
965
+ if (actorRef._processingStatus === ProcessingStatus.Stopped) {
100
966
  return;
101
967
  }
102
968
  try {
103
969
  actorRef.start?.();
104
970
  } catch (err) {
105
- actorScope.self.send(interpreter.createErrorActorEvent(id, err));
971
+ actorScope.self.send(createErrorActorEvent(id, err));
106
972
  return;
107
973
  }
108
974
  });
@@ -114,6 +980,9 @@ function spawn(...[src, {
114
980
  syncSnapshot = false
115
981
  } = {}]) {
116
982
  function spawn(args, params) {
983
+ {
984
+ throw new Error(`This isn't supposed to be called`);
985
+ }
117
986
  }
118
987
  spawn.type = 'xstate.spawn';
119
988
  spawn.id = id;
@@ -154,7 +1023,7 @@ function executeStop(actorScope, actorRef) {
154
1023
 
155
1024
  // this allows us to prevent an actor from being started if it gets stopped within the same macrostep
156
1025
  // this can happen, for example, when the invoking state is being exited immediately by an always transition
157
- if (actorRef._processingStatus !== interpreter.ProcessingStatus.Running) {
1026
+ if (actorRef._processingStatus !== ProcessingStatus.Running) {
158
1027
  actorScope.stopChild(actorRef);
159
1028
  return;
160
1029
  }
@@ -173,6 +1042,9 @@ function executeStop(actorScope, actorRef) {
173
1042
  */
174
1043
  function stop(actorRef) {
175
1044
  function stop(args, params) {
1045
+ {
1046
+ throw new Error(`This isn't supposed to be called`);
1047
+ }
176
1048
  }
177
1049
  stop.type = 'xstate.stop';
178
1050
  stop.actorRef = actorRef;
@@ -192,7 +1064,9 @@ function checkStateIn(state, _, {
192
1064
  }
193
1065
  function stateIn(stateValue) {
194
1066
  function stateIn(args, params) {
195
- return false;
1067
+ {
1068
+ throw new Error(`This isn't supposed to be called`);
1069
+ }
196
1070
  }
197
1071
  stateIn.check = checkStateIn;
198
1072
  stateIn.stateValue = stateValue;
@@ -208,7 +1082,9 @@ function checkNot(state, {
208
1082
  }
209
1083
  function not(guard) {
210
1084
  function not(args, params) {
211
- return false;
1085
+ {
1086
+ throw new Error(`This isn't supposed to be called`);
1087
+ }
212
1088
  }
213
1089
  not.check = checkNot;
214
1090
  not.guards = [guard];
@@ -224,7 +1100,9 @@ function checkAnd(state, {
224
1100
  }
225
1101
  function and(guards) {
226
1102
  function and(args, params) {
227
- return false;
1103
+ {
1104
+ throw new Error(`This isn't supposed to be called`);
1105
+ }
228
1106
  }
229
1107
  and.check = checkAnd;
230
1108
  and.guards = guards;
@@ -240,7 +1118,9 @@ function checkOr(state, {
240
1118
  }
241
1119
  function or(guards) {
242
1120
  function or(args, params) {
243
- return false;
1121
+ {
1122
+ throw new Error(`This isn't supposed to be called`);
1123
+ }
244
1124
  }
245
1125
  or.check = checkOr;
246
1126
  or.guards = guards;
@@ -384,17 +1264,20 @@ function isInFinalState(configuration, stateNode) {
384
1264
  }
385
1265
  return stateNode.type === 'final';
386
1266
  }
387
- const isStateId = str => str[0] === interpreter.STATE_IDENTIFIER;
1267
+ const isStateId = str => str[0] === STATE_IDENTIFIER;
388
1268
  function getCandidates(stateNode, receivedEventType) {
389
1269
  const candidates = stateNode.transitions.get(receivedEventType) || [...stateNode.transitions.keys()].filter(descriptor => {
390
1270
  // check if transition is a wildcard transition,
391
1271
  // which matches any non-transient events
392
- if (descriptor === interpreter.WILDCARD) {
1272
+ if (descriptor === WILDCARD) {
393
1273
  return true;
394
1274
  }
395
1275
  if (!descriptor.endsWith('.*')) {
396
1276
  return false;
397
1277
  }
1278
+ if (/.*\*.+/.test(descriptor)) {
1279
+ 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.`);
1280
+ }
398
1281
  const partialEventTokens = descriptor.split('.');
399
1282
  const eventTokens = receivedEventType.split('.');
400
1283
  for (let tokenIndex = 0; tokenIndex < partialEventTokens.length; tokenIndex++) {
@@ -402,6 +1285,9 @@ function getCandidates(stateNode, receivedEventType) {
402
1285
  const eventToken = eventTokens[tokenIndex];
403
1286
  if (partialEventToken === '*') {
404
1287
  const isLastToken = tokenIndex === partialEventTokens.length - 1;
1288
+ if (!isLastToken) {
1289
+ console.warn(`Infix wildcards in transition events are not allowed. Check the "${descriptor}" transition.`);
1290
+ }
405
1291
  return isLastToken;
406
1292
  }
407
1293
  if (partialEventToken !== eventToken) {
@@ -423,7 +1309,7 @@ function getDelayedTransitions(stateNode) {
423
1309
  }
424
1310
  const mutateEntryExit = (delay, i) => {
425
1311
  const delayRef = typeof delay === 'function' ? `${stateNode.id}:delay[${i}]` : delay;
426
- const afterEvent = interpreter.createAfterEvent(delayRef, stateNode.id);
1312
+ const afterEvent = createAfterEvent(delayRef, stateNode.id);
427
1313
  const eventType = afterEvent.type;
428
1314
  stateNode.entry.push(raise(afterEvent, {
429
1315
  id: eventType,
@@ -439,7 +1325,7 @@ function getDelayedTransitions(stateNode) {
439
1325
  } : configTransition;
440
1326
  const resolvedDelay = !isNaN(+delay) ? +delay : delay;
441
1327
  const eventType = mutateEntryExit(resolvedDelay, i);
442
- return interpreter.toArray(resolvedTransition).map(transition => ({
1328
+ return toArray(resolvedTransition).map(transition => ({
443
1329
  ...transition,
444
1330
  event: eventType,
445
1331
  delay: resolvedDelay
@@ -456,12 +1342,17 @@ function getDelayedTransitions(stateNode) {
456
1342
  });
457
1343
  }
458
1344
  function formatTransition(stateNode, descriptor, transitionConfig) {
459
- const normalizedTarget = interpreter.normalizeTarget(transitionConfig.target);
1345
+ const normalizedTarget = normalizeTarget(transitionConfig.target);
460
1346
  const reenter = transitionConfig.reenter ?? false;
461
1347
  const target = resolveTarget(stateNode, normalizedTarget);
1348
+
1349
+ // TODO: should this be part of a lint rule instead?
1350
+ if (transitionConfig.cond) {
1351
+ throw new Error(`State "${stateNode.id}" has declared \`cond\` for one of its transitions. This property has been renamed to \`guard\`. Please update your code.`);
1352
+ }
462
1353
  const transition = {
463
1354
  ...transitionConfig,
464
- actions: interpreter.toArray(transitionConfig.actions),
1355
+ actions: toArray(transitionConfig.actions),
465
1356
  guard: transitionConfig.guard,
466
1357
  target,
467
1358
  source: stateNode,
@@ -479,29 +1370,29 @@ function formatTransitions(stateNode) {
479
1370
  const transitions = new Map();
480
1371
  if (stateNode.config.on) {
481
1372
  for (const descriptor of Object.keys(stateNode.config.on)) {
482
- if (descriptor === interpreter.NULL_EVENT) {
1373
+ if (descriptor === NULL_EVENT) {
483
1374
  throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');
484
1375
  }
485
1376
  const transitionsConfig = stateNode.config.on[descriptor];
486
- transitions.set(descriptor, interpreter.toTransitionConfigArray(transitionsConfig).map(t => formatTransition(stateNode, descriptor, t)));
1377
+ transitions.set(descriptor, toTransitionConfigArray(transitionsConfig).map(t => formatTransition(stateNode, descriptor, t)));
487
1378
  }
488
1379
  }
489
1380
  if (stateNode.config.onDone) {
490
1381
  const descriptor = `xstate.done.state.${stateNode.id}`;
491
- transitions.set(descriptor, interpreter.toTransitionConfigArray(stateNode.config.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1382
+ transitions.set(descriptor, toTransitionConfigArray(stateNode.config.onDone).map(t => formatTransition(stateNode, descriptor, t)));
492
1383
  }
493
1384
  for (const invokeDef of stateNode.invoke) {
494
1385
  if (invokeDef.onDone) {
495
1386
  const descriptor = `xstate.done.actor.${invokeDef.id}`;
496
- transitions.set(descriptor, interpreter.toTransitionConfigArray(invokeDef.onDone).map(t => formatTransition(stateNode, descriptor, t)));
1387
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onDone).map(t => formatTransition(stateNode, descriptor, t)));
497
1388
  }
498
1389
  if (invokeDef.onError) {
499
1390
  const descriptor = `xstate.error.actor.${invokeDef.id}`;
500
- transitions.set(descriptor, interpreter.toTransitionConfigArray(invokeDef.onError).map(t => formatTransition(stateNode, descriptor, t)));
1391
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onError).map(t => formatTransition(stateNode, descriptor, t)));
501
1392
  }
502
1393
  if (invokeDef.onSnapshot) {
503
1394
  const descriptor = `xstate.snapshot.${invokeDef.id}`;
504
- transitions.set(descriptor, interpreter.toTransitionConfigArray(invokeDef.onSnapshot).map(t => formatTransition(stateNode, descriptor, t)));
1395
+ transitions.set(descriptor, toTransitionConfigArray(invokeDef.onSnapshot).map(t => formatTransition(stateNode, descriptor, t)));
505
1396
  }
506
1397
  }
507
1398
  for (const delayedTransition of stateNode.after) {
@@ -521,7 +1412,7 @@ function formatInitialTransition(stateNode, _target) {
521
1412
  }
522
1413
  const transition = {
523
1414
  source: stateNode,
524
- actions: !_target || typeof _target === 'string' ? [] : interpreter.toArray(_target.actions),
1415
+ actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
525
1416
  eventType: null,
526
1417
  reenter: false,
527
1418
  target: resolvedTarget ? [resolvedTarget] : [],
@@ -545,7 +1436,7 @@ function resolveTarget(stateNode, targets) {
545
1436
  if (isStateId(target)) {
546
1437
  return stateNode.machine.getStateNodeById(target);
547
1438
  }
548
- const isInternalTarget = target[0] === interpreter.STATE_DELIMITER;
1439
+ const isInternalTarget = target[0] === STATE_DELIMITER;
549
1440
  // If internal target is defined on machine,
550
1441
  // do not include machine key on target
551
1442
  if (isInternalTarget && !stateNode.parent) {
@@ -565,7 +1456,7 @@ function resolveTarget(stateNode, targets) {
565
1456
  });
566
1457
  }
567
1458
  function resolveHistoryDefaultTransition(stateNode) {
568
- const normalizedTarget = interpreter.normalizeTarget(stateNode.config.target);
1459
+ const normalizedTarget = normalizeTarget(stateNode.config.target);
569
1460
  if (!normalizedTarget) {
570
1461
  return stateNode.parent.initial;
571
1462
  }
@@ -634,7 +1525,7 @@ function getStateNodeByPath(stateNode, statePath) {
634
1525
  // throw e;
635
1526
  }
636
1527
  }
637
- const arrayStatePath = interpreter.toStatePath(statePath).slice();
1528
+ const arrayStatePath = toStatePath(statePath).slice();
638
1529
  let currentStateNode = stateNode;
639
1530
  while (arrayStatePath.length) {
640
1531
  const key = arrayStatePath.shift();
@@ -886,8 +1777,8 @@ function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode
886
1777
  if (!rootNode.output) {
887
1778
  return;
888
1779
  }
889
- const doneStateEvent = interpreter.createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? interpreter.resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
890
- return interpreter.resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
1780
+ const doneStateEvent = createDoneStateEvent(rootCompletionNode.id, rootCompletionNode.output && rootCompletionNode.parent ? resolveOutput(rootCompletionNode.output, state.context, event, actorScope.self) : undefined);
1781
+ return resolveOutput(rootNode.output, state.context, doneStateEvent, actorScope.self);
891
1782
  }
892
1783
  function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
893
1784
  let nextState = currentState;
@@ -925,11 +1816,11 @@ function enterStates(currentState, event, actorScope, filteredTransitions, mutCo
925
1816
  let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
926
1817
  let rootCompletionNode = ancestorMarker || stateNodeToEnter;
927
1818
  if (parent?.type === 'compound') {
928
- internalQueue.push(interpreter.createDoneStateEvent(parent.id, stateNodeToEnter.output ? interpreter.resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
1819
+ internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
929
1820
  }
930
1821
  while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
931
1822
  completedNodes.add(ancestorMarker);
932
- internalQueue.push(interpreter.createDoneStateEvent(ancestorMarker.id));
1823
+ internalQueue.push(createDoneStateEvent(ancestorMarker.id));
933
1824
  rootCompletionNode = ancestorMarker;
934
1825
  ancestorMarker = ancestorMarker.parent;
935
1826
  }
@@ -1092,7 +1983,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
1092
1983
  event
1093
1984
  }) : action.params : undefined;
1094
1985
  if (!('resolve' in resolvedAction)) {
1095
- if (actorScope?.self._processingStatus === interpreter.ProcessingStatus.Running) {
1986
+ if (actorScope?.self._processingStatus === ProcessingStatus.Running) {
1096
1987
  resolvedAction(actionArgs, actionParams);
1097
1988
  } else {
1098
1989
  actorScope?.defer(() => {
@@ -1110,7 +2001,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
1110
2001
  retries?.push([builtinAction, params]);
1111
2002
  }
1112
2003
  if ('execute' in builtinAction) {
1113
- if (actorScope?.self._processingStatus === interpreter.ProcessingStatus.Running) {
2004
+ if (actorScope?.self._processingStatus === ProcessingStatus.Running) {
1114
2005
  builtinAction.execute(actorScope, params);
1115
2006
  } else {
1116
2007
  actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
@@ -1134,11 +2025,14 @@ function resolveActionsAndContext(currentState, event, actorScope, actions, inte
1134
2025
  return nextState;
1135
2026
  }
1136
2027
  function macrostep(state, event, actorScope, internalQueue = []) {
2028
+ if (event.type === WILDCARD) {
2029
+ throw new Error(`An event cannot have the wildcard type ('${WILDCARD}')`);
2030
+ }
1137
2031
  let nextState = state;
1138
2032
  const states = [];
1139
2033
 
1140
2034
  // Handle stop event
1141
- if (event.type === interpreter.XSTATE_STOP) {
2035
+ if (event.type === XSTATE_STOP) {
1142
2036
  nextState = cloneMachineSnapshot(stopChildren(nextState, event, actorScope), {
1143
2037
  status: 'stopped'
1144
2038
  });
@@ -1152,7 +2046,7 @@ function macrostep(state, event, actorScope, internalQueue = []) {
1152
2046
 
1153
2047
  // Assume the state is at rest (no raised events)
1154
2048
  // Determine the next state based on the next microstep
1155
- if (nextEvent.type !== interpreter.XSTATE_INIT) {
2049
+ if (nextEvent.type !== XSTATE_INIT) {
1156
2050
  const transitions = selectTransitions(nextEvent, nextState);
1157
2051
  nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
1158
2052
  states.push(nextState);
@@ -1218,13 +2112,19 @@ function resolveStateValue(rootNode, stateValue) {
1218
2112
  return getStateValue(rootNode, [...configuration]);
1219
2113
  }
1220
2114
 
2115
+ function isMachineSnapshot(value) {
2116
+ return !!value && typeof value === 'object' && 'machine' in value && 'value' in value;
2117
+ }
1221
2118
  const machineSnapshotMatches = function matches(testValue) {
1222
- return interpreter.matchesState(testValue, this.value);
2119
+ return matchesState(testValue, this.value);
1223
2120
  };
1224
2121
  const machineSnapshotHasTag = function hasTag(tag) {
1225
2122
  return this.tags.has(tag);
1226
2123
  };
1227
2124
  const machineSnapshotCan = function can(event) {
2125
+ if (!this.machine) {
2126
+ console.warn(`state.can(...) used outside of a machine-created State object; this will always return false.`);
2127
+ }
1228
2128
  const transitionData = this.machine.getTransitionData(this, event);
1229
2129
  return !!transitionData?.length &&
1230
2130
  // Check that at least one transition is not forbidden
@@ -1249,7 +2149,7 @@ const machineSnapshotToJSON = function toJSON() {
1249
2149
  };
1250
2150
  const machineSnapshotNextEvents = function nextEvents() {
1251
2151
  return memo(this, 'nextEvents', () => {
1252
- return [...new Set(interpreter.flatten([...this.configuration.map(sn => sn.ownEvents)]))];
2152
+ return [...new Set(flatten([...this.configuration.map(sn => sn.ownEvents)]))];
1253
2153
  });
1254
2154
  };
1255
2155
  const machineSnapshotMeta = function nextEvents() {
@@ -1269,7 +2169,7 @@ function createMachineSnapshot(config, machine) {
1269
2169
  context: config.context,
1270
2170
  configuration: config.configuration,
1271
2171
  value: getStateValue(machine.root, config.configuration),
1272
- tags: new Set(interpreter.flatten(config.configuration.map(sn => sn.tags))),
2172
+ tags: new Set(flatten(config.configuration.map(sn => sn.tags))),
1273
2173
  children: config.children,
1274
2174
  historyValue: config.historyValue || {},
1275
2175
  // this one is generic in the target and it's hard to create a matching non-generic source signature
@@ -1317,6 +2217,9 @@ function getPersistedState(state, options) {
1317
2217
  const childrenJson = {};
1318
2218
  for (const id in children) {
1319
2219
  const child = children[id];
2220
+ if (typeof child.src !== 'string' && (!options || !('__unsafeAllowInlineActors' in options))) {
2221
+ throw new Error('An inline child actor cannot be persisted.');
2222
+ }
1320
2223
  childrenJson[id] = {
1321
2224
  state: child.getPersistedState(options),
1322
2225
  src: child.src,
@@ -1340,7 +2243,7 @@ function persistContext(contextPart) {
1340
2243
  ...contextPart
1341
2244
  };
1342
2245
  copy[key] = {
1343
- xstate$$type: interpreter.$$ACTOR_TYPE,
2246
+ xstate$$type: $$ACTOR_TYPE,
1344
2247
  id: value.id
1345
2248
  };
1346
2249
  } else {
@@ -1399,6 +2302,9 @@ function executeRaise(actorScope, params) {
1399
2302
  */
1400
2303
  function raise(eventOrExpr, options) {
1401
2304
  function raise(args, params) {
2305
+ {
2306
+ throw new Error(`This isn't supposed to be called`);
2307
+ }
1402
2308
  }
1403
2309
  raise.type = 'xstate.raise';
1404
2310
  raise.event = eventOrExpr;
@@ -1409,32 +2315,4 @@ function raise(eventOrExpr, options) {
1409
2315
  return raise;
1410
2316
  }
1411
2317
 
1412
- exports.and = and;
1413
- exports.cancel = cancel;
1414
- exports.cloneMachineSnapshot = cloneMachineSnapshot;
1415
- exports.createMachineSnapshot = createMachineSnapshot;
1416
- exports.evaluateGuard = evaluateGuard;
1417
- exports.formatInitialTransition = formatInitialTransition;
1418
- exports.formatTransition = formatTransition;
1419
- exports.formatTransitions = formatTransitions;
1420
- exports.getCandidates = getCandidates;
1421
- exports.getConfiguration = getConfiguration;
1422
- exports.getDelayedTransitions = getDelayedTransitions;
1423
- exports.getInitialStateNodes = getInitialStateNodes;
1424
- exports.getPersistedState = getPersistedState;
1425
- exports.getStateNodeByPath = getStateNodeByPath;
1426
- exports.getStateNodes = getStateNodes;
1427
- exports.isInFinalState = isInFinalState;
1428
- exports.isStateId = isStateId;
1429
- exports.macrostep = macrostep;
1430
- exports.memo = memo;
1431
- exports.microstep = microstep;
1432
- exports.not = not;
1433
- exports.or = or;
1434
- exports.raise = raise;
1435
- exports.resolveActionsAndContext = resolveActionsAndContext;
1436
- exports.resolveStateValue = resolveStateValue;
1437
- exports.spawn = spawn;
1438
- exports.stateIn = stateIn;
1439
- exports.stop = stop;
1440
- exports.transitionNode = transitionNode;
2318
+ export { $$ACTOR_TYPE as $, getPersistedState as A, resolveReferencedActor as B, createActor as C, Actor as D, interpret as E, isMachineSnapshot as F, matchesState as G, pathToStateValue as H, toObserver as I, and as J, not as K, or as L, stateIn as M, NULL_EVENT as N, cancel as O, raise as P, stop as Q, spawn as R, STATE_DELIMITER as S, ProcessingStatus as T, createErrorActorEvent as U, XSTATE_ERROR as V, XSTATE_STOP as X, toTransitionConfigArray as a, formatTransition as b, memo as c, createInvokeId as d, evaluateGuard as e, formatTransitions as f, getDelayedTransitions as g, formatInitialTransition as h, getCandidates as i, getConfiguration as j, getStateNodes as k, createMachineSnapshot as l, mapValues as m, isInFinalState as n, isErrorActorEvent as o, cloneMachineSnapshot as p, macrostep as q, resolveStateValue as r, transitionNode as s, toArray as t, resolveActionsAndContext as u, createInitEvent as v, microstep as w, getInitialStateNodes as x, isStateId as y, getStateNodeByPath as z };