xstate 5.0.0-beta.42 → 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.
- package/actions/dist/xstate-actions.cjs.js +2 -3
- package/actions/dist/xstate-actions.development.cjs.js +2 -3
- package/actions/dist/xstate-actions.development.esm.js +2 -3
- package/actions/dist/xstate-actions.esm.js +2 -3
- package/actions/dist/xstate-actions.umd.min.js +1 -1
- package/actions/dist/xstate-actions.umd.min.js.map +1 -1
- package/actors/dist/xstate-actors.cjs.js +50 -6
- package/actors/dist/xstate-actors.development.cjs.js +50 -6
- package/actors/dist/xstate-actors.development.esm.js +45 -1
- package/actors/dist/xstate-actors.esm.js +45 -1
- package/actors/dist/xstate-actors.umd.min.js +1 -1
- package/actors/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/declarations/src/State.d.ts +8 -12
- package/dist/declarations/src/actions/spawn.d.ts +11 -16
- package/dist/declarations/src/actors/promise.d.ts +53 -0
- package/dist/declarations/src/guards.d.ts +2 -2
- package/dist/declarations/src/index.d.ts +1 -1
- package/dist/declarations/src/spawn.d.ts +9 -13
- package/dist/declarations/src/stateUtils.d.ts +4 -4
- package/dist/declarations/src/types.d.ts +56 -22
- package/dist/declarations/src/utils.d.ts +2 -10
- package/dist/{raise-6b64c553.cjs.js → raise-348cc74e.development.esm.js} +1007 -116
- package/dist/{raise-51ae36e5.development.esm.js → raise-5854eaca.esm.js} +925 -101
- package/dist/{raise-8f482ce9.development.cjs.js → raise-ed700d14.development.cjs.js} +986 -87
- package/dist/{raise-d2084327.esm.js → raise-fb6f017b.cjs.js} +972 -54
- package/dist/{send-cc8f864e.development.cjs.js → send-00466e37.development.cjs.js} +14 -17
- package/dist/{send-85b562d8.cjs.js → send-53e5693c.cjs.js} +14 -17
- package/dist/{send-7a350091.development.esm.js → send-a0193bdb.development.esm.js} +7 -10
- package/dist/{send-4e732fa5.esm.js → send-b7b4befa.esm.js} +7 -10
- package/dist/xstate.cjs.js +25 -25
- package/dist/xstate.cjs.mjs +1 -0
- package/dist/xstate.development.cjs.js +25 -25
- package/dist/xstate.development.cjs.mjs +1 -0
- package/dist/xstate.development.esm.js +5 -7
- package/dist/xstate.esm.js +5 -7
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/guards/dist/xstate-guards.cjs.js +1 -2
- package/guards/dist/xstate-guards.development.cjs.js +1 -2
- package/guards/dist/xstate-guards.development.esm.js +1 -2
- package/guards/dist/xstate-guards.esm.js +1 -2
- package/guards/dist/xstate-guards.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/dist/interpreter-23e4041c.development.cjs.js +0 -905
- package/dist/interpreter-3d0c0ff2.esm.js +0 -864
- package/dist/interpreter-b6bdd134.cjs.js +0 -894
- package/dist/interpreter-f2620ea7.development.esm.js +0 -875
|
@@ -1,6 +1,866 @@
|
|
|
1
|
-
|
|
1
|
+
import { devToolsAdapter } from '../dev/dist/xstate-dev.development.esm.js';
|
|
2
2
|
|
|
3
|
-
|
|
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,25 +912,20 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
|
49
912
|
input,
|
|
50
913
|
syncSnapshot
|
|
51
914
|
}) {
|
|
52
|
-
const
|
|
53
|
-
src,
|
|
54
|
-
input: undefined
|
|
55
|
-
};
|
|
915
|
+
const logic = typeof src === 'string' ? resolveReferencedActor(state.machine, src) : src;
|
|
56
916
|
const resolvedId = typeof id === 'function' ? id(actionArgs) : id;
|
|
57
917
|
let actorRef;
|
|
58
|
-
if (
|
|
59
|
-
|
|
60
|
-
const configuredInput = input || referenced.input;
|
|
61
|
-
actorRef = interpreter.createActor(referenced.src, {
|
|
918
|
+
if (logic) {
|
|
919
|
+
actorRef = createActor(logic, {
|
|
62
920
|
id: resolvedId,
|
|
63
921
|
src,
|
|
64
922
|
parent: actorScope?.self,
|
|
65
923
|
systemId,
|
|
66
|
-
input: typeof
|
|
924
|
+
input: typeof input === 'function' ? input({
|
|
67
925
|
context: state.context,
|
|
68
926
|
event: actionArgs.event,
|
|
69
927
|
self: actorScope?.self
|
|
70
|
-
}) :
|
|
928
|
+
}) : input
|
|
71
929
|
});
|
|
72
930
|
if (syncSnapshot) {
|
|
73
931
|
actorRef.subscribe({
|
|
@@ -83,6 +941,9 @@ function resolveSpawn(actorScope, state, actionArgs, _actionParams, {
|
|
|
83
941
|
});
|
|
84
942
|
}
|
|
85
943
|
}
|
|
944
|
+
if (!actorRef) {
|
|
945
|
+
console.warn(`Actor type '${src}' not found in machine '${actorScope.id}'.`);
|
|
946
|
+
}
|
|
86
947
|
return [cloneMachineSnapshot(state, {
|
|
87
948
|
children: {
|
|
88
949
|
...state.children,
|
|
@@ -101,13 +962,13 @@ function executeSpawn(actorScope, {
|
|
|
101
962
|
return;
|
|
102
963
|
}
|
|
103
964
|
actorScope.defer(() => {
|
|
104
|
-
if (actorRef._processingStatus ===
|
|
965
|
+
if (actorRef._processingStatus === ProcessingStatus.Stopped) {
|
|
105
966
|
return;
|
|
106
967
|
}
|
|
107
968
|
try {
|
|
108
969
|
actorRef.start?.();
|
|
109
970
|
} catch (err) {
|
|
110
|
-
actorScope.self.send(
|
|
971
|
+
actorScope.self.send(createErrorActorEvent(id, err));
|
|
111
972
|
return;
|
|
112
973
|
}
|
|
113
974
|
});
|
|
@@ -119,6 +980,9 @@ function spawn(...[src, {
|
|
|
119
980
|
syncSnapshot = false
|
|
120
981
|
} = {}]) {
|
|
121
982
|
function spawn(args, params) {
|
|
983
|
+
{
|
|
984
|
+
throw new Error(`This isn't supposed to be called`);
|
|
985
|
+
}
|
|
122
986
|
}
|
|
123
987
|
spawn.type = 'xstate.spawn';
|
|
124
988
|
spawn.id = id;
|
|
@@ -159,7 +1023,7 @@ function executeStop(actorScope, actorRef) {
|
|
|
159
1023
|
|
|
160
1024
|
// this allows us to prevent an actor from being started if it gets stopped within the same macrostep
|
|
161
1025
|
// this can happen, for example, when the invoking state is being exited immediately by an always transition
|
|
162
|
-
if (actorRef._processingStatus !==
|
|
1026
|
+
if (actorRef._processingStatus !== ProcessingStatus.Running) {
|
|
163
1027
|
actorScope.stopChild(actorRef);
|
|
164
1028
|
return;
|
|
165
1029
|
}
|
|
@@ -178,6 +1042,9 @@ function executeStop(actorScope, actorRef) {
|
|
|
178
1042
|
*/
|
|
179
1043
|
function stop(actorRef) {
|
|
180
1044
|
function stop(args, params) {
|
|
1045
|
+
{
|
|
1046
|
+
throw new Error(`This isn't supposed to be called`);
|
|
1047
|
+
}
|
|
181
1048
|
}
|
|
182
1049
|
stop.type = 'xstate.stop';
|
|
183
1050
|
stop.actorRef = actorRef;
|
|
@@ -197,7 +1064,9 @@ function checkStateIn(state, _, {
|
|
|
197
1064
|
}
|
|
198
1065
|
function stateIn(stateValue) {
|
|
199
1066
|
function stateIn(args, params) {
|
|
200
|
-
|
|
1067
|
+
{
|
|
1068
|
+
throw new Error(`This isn't supposed to be called`);
|
|
1069
|
+
}
|
|
201
1070
|
}
|
|
202
1071
|
stateIn.check = checkStateIn;
|
|
203
1072
|
stateIn.stateValue = stateValue;
|
|
@@ -213,7 +1082,9 @@ function checkNot(state, {
|
|
|
213
1082
|
}
|
|
214
1083
|
function not(guard) {
|
|
215
1084
|
function not(args, params) {
|
|
216
|
-
|
|
1085
|
+
{
|
|
1086
|
+
throw new Error(`This isn't supposed to be called`);
|
|
1087
|
+
}
|
|
217
1088
|
}
|
|
218
1089
|
not.check = checkNot;
|
|
219
1090
|
not.guards = [guard];
|
|
@@ -229,7 +1100,9 @@ function checkAnd(state, {
|
|
|
229
1100
|
}
|
|
230
1101
|
function and(guards) {
|
|
231
1102
|
function and(args, params) {
|
|
232
|
-
|
|
1103
|
+
{
|
|
1104
|
+
throw new Error(`This isn't supposed to be called`);
|
|
1105
|
+
}
|
|
233
1106
|
}
|
|
234
1107
|
and.check = checkAnd;
|
|
235
1108
|
and.guards = guards;
|
|
@@ -245,7 +1118,9 @@ function checkOr(state, {
|
|
|
245
1118
|
}
|
|
246
1119
|
function or(guards) {
|
|
247
1120
|
function or(args, params) {
|
|
248
|
-
|
|
1121
|
+
{
|
|
1122
|
+
throw new Error(`This isn't supposed to be called`);
|
|
1123
|
+
}
|
|
249
1124
|
}
|
|
250
1125
|
or.check = checkOr;
|
|
251
1126
|
or.guards = guards;
|
|
@@ -389,17 +1264,20 @@ function isInFinalState(configuration, stateNode) {
|
|
|
389
1264
|
}
|
|
390
1265
|
return stateNode.type === 'final';
|
|
391
1266
|
}
|
|
392
|
-
const isStateId = str => str[0] ===
|
|
1267
|
+
const isStateId = str => str[0] === STATE_IDENTIFIER;
|
|
393
1268
|
function getCandidates(stateNode, receivedEventType) {
|
|
394
1269
|
const candidates = stateNode.transitions.get(receivedEventType) || [...stateNode.transitions.keys()].filter(descriptor => {
|
|
395
1270
|
// check if transition is a wildcard transition,
|
|
396
1271
|
// which matches any non-transient events
|
|
397
|
-
if (descriptor ===
|
|
1272
|
+
if (descriptor === WILDCARD) {
|
|
398
1273
|
return true;
|
|
399
1274
|
}
|
|
400
1275
|
if (!descriptor.endsWith('.*')) {
|
|
401
1276
|
return false;
|
|
402
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
|
+
}
|
|
403
1281
|
const partialEventTokens = descriptor.split('.');
|
|
404
1282
|
const eventTokens = receivedEventType.split('.');
|
|
405
1283
|
for (let tokenIndex = 0; tokenIndex < partialEventTokens.length; tokenIndex++) {
|
|
@@ -407,6 +1285,9 @@ function getCandidates(stateNode, receivedEventType) {
|
|
|
407
1285
|
const eventToken = eventTokens[tokenIndex];
|
|
408
1286
|
if (partialEventToken === '*') {
|
|
409
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
|
+
}
|
|
410
1291
|
return isLastToken;
|
|
411
1292
|
}
|
|
412
1293
|
if (partialEventToken !== eventToken) {
|
|
@@ -428,7 +1309,7 @@ function getDelayedTransitions(stateNode) {
|
|
|
428
1309
|
}
|
|
429
1310
|
const mutateEntryExit = (delay, i) => {
|
|
430
1311
|
const delayRef = typeof delay === 'function' ? `${stateNode.id}:delay[${i}]` : delay;
|
|
431
|
-
const afterEvent =
|
|
1312
|
+
const afterEvent = createAfterEvent(delayRef, stateNode.id);
|
|
432
1313
|
const eventType = afterEvent.type;
|
|
433
1314
|
stateNode.entry.push(raise(afterEvent, {
|
|
434
1315
|
id: eventType,
|
|
@@ -444,7 +1325,7 @@ function getDelayedTransitions(stateNode) {
|
|
|
444
1325
|
} : configTransition;
|
|
445
1326
|
const resolvedDelay = !isNaN(+delay) ? +delay : delay;
|
|
446
1327
|
const eventType = mutateEntryExit(resolvedDelay, i);
|
|
447
|
-
return
|
|
1328
|
+
return toArray(resolvedTransition).map(transition => ({
|
|
448
1329
|
...transition,
|
|
449
1330
|
event: eventType,
|
|
450
1331
|
delay: resolvedDelay
|
|
@@ -461,12 +1342,17 @@ function getDelayedTransitions(stateNode) {
|
|
|
461
1342
|
});
|
|
462
1343
|
}
|
|
463
1344
|
function formatTransition(stateNode, descriptor, transitionConfig) {
|
|
464
|
-
const normalizedTarget =
|
|
1345
|
+
const normalizedTarget = normalizeTarget(transitionConfig.target);
|
|
465
1346
|
const reenter = transitionConfig.reenter ?? false;
|
|
466
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
|
+
}
|
|
467
1353
|
const transition = {
|
|
468
1354
|
...transitionConfig,
|
|
469
|
-
actions:
|
|
1355
|
+
actions: toArray(transitionConfig.actions),
|
|
470
1356
|
guard: transitionConfig.guard,
|
|
471
1357
|
target,
|
|
472
1358
|
source: stateNode,
|
|
@@ -484,29 +1370,29 @@ function formatTransitions(stateNode) {
|
|
|
484
1370
|
const transitions = new Map();
|
|
485
1371
|
if (stateNode.config.on) {
|
|
486
1372
|
for (const descriptor of Object.keys(stateNode.config.on)) {
|
|
487
|
-
if (descriptor ===
|
|
1373
|
+
if (descriptor === NULL_EVENT) {
|
|
488
1374
|
throw new Error('Null events ("") cannot be specified as a transition key. Use `always: { ... }` instead.');
|
|
489
1375
|
}
|
|
490
1376
|
const transitionsConfig = stateNode.config.on[descriptor];
|
|
491
|
-
transitions.set(descriptor,
|
|
1377
|
+
transitions.set(descriptor, toTransitionConfigArray(transitionsConfig).map(t => formatTransition(stateNode, descriptor, t)));
|
|
492
1378
|
}
|
|
493
1379
|
}
|
|
494
1380
|
if (stateNode.config.onDone) {
|
|
495
1381
|
const descriptor = `xstate.done.state.${stateNode.id}`;
|
|
496
|
-
transitions.set(descriptor,
|
|
1382
|
+
transitions.set(descriptor, toTransitionConfigArray(stateNode.config.onDone).map(t => formatTransition(stateNode, descriptor, t)));
|
|
497
1383
|
}
|
|
498
1384
|
for (const invokeDef of stateNode.invoke) {
|
|
499
1385
|
if (invokeDef.onDone) {
|
|
500
1386
|
const descriptor = `xstate.done.actor.${invokeDef.id}`;
|
|
501
|
-
transitions.set(descriptor,
|
|
1387
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onDone).map(t => formatTransition(stateNode, descriptor, t)));
|
|
502
1388
|
}
|
|
503
1389
|
if (invokeDef.onError) {
|
|
504
1390
|
const descriptor = `xstate.error.actor.${invokeDef.id}`;
|
|
505
|
-
transitions.set(descriptor,
|
|
1391
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onError).map(t => formatTransition(stateNode, descriptor, t)));
|
|
506
1392
|
}
|
|
507
1393
|
if (invokeDef.onSnapshot) {
|
|
508
1394
|
const descriptor = `xstate.snapshot.${invokeDef.id}`;
|
|
509
|
-
transitions.set(descriptor,
|
|
1395
|
+
transitions.set(descriptor, toTransitionConfigArray(invokeDef.onSnapshot).map(t => formatTransition(stateNode, descriptor, t)));
|
|
510
1396
|
}
|
|
511
1397
|
}
|
|
512
1398
|
for (const delayedTransition of stateNode.after) {
|
|
@@ -526,7 +1412,7 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
526
1412
|
}
|
|
527
1413
|
const transition = {
|
|
528
1414
|
source: stateNode,
|
|
529
|
-
actions: !_target || typeof _target === 'string' ? [] :
|
|
1415
|
+
actions: !_target || typeof _target === 'string' ? [] : toArray(_target.actions),
|
|
530
1416
|
eventType: null,
|
|
531
1417
|
reenter: false,
|
|
532
1418
|
target: resolvedTarget ? [resolvedTarget] : [],
|
|
@@ -550,7 +1436,7 @@ function resolveTarget(stateNode, targets) {
|
|
|
550
1436
|
if (isStateId(target)) {
|
|
551
1437
|
return stateNode.machine.getStateNodeById(target);
|
|
552
1438
|
}
|
|
553
|
-
const isInternalTarget = target[0] ===
|
|
1439
|
+
const isInternalTarget = target[0] === STATE_DELIMITER;
|
|
554
1440
|
// If internal target is defined on machine,
|
|
555
1441
|
// do not include machine key on target
|
|
556
1442
|
if (isInternalTarget && !stateNode.parent) {
|
|
@@ -570,7 +1456,7 @@ function resolveTarget(stateNode, targets) {
|
|
|
570
1456
|
});
|
|
571
1457
|
}
|
|
572
1458
|
function resolveHistoryDefaultTransition(stateNode) {
|
|
573
|
-
const normalizedTarget =
|
|
1459
|
+
const normalizedTarget = normalizeTarget(stateNode.config.target);
|
|
574
1460
|
if (!normalizedTarget) {
|
|
575
1461
|
return stateNode.parent.initial;
|
|
576
1462
|
}
|
|
@@ -639,7 +1525,7 @@ function getStateNodeByPath(stateNode, statePath) {
|
|
|
639
1525
|
// throw e;
|
|
640
1526
|
}
|
|
641
1527
|
}
|
|
642
|
-
const arrayStatePath =
|
|
1528
|
+
const arrayStatePath = toStatePath(statePath).slice();
|
|
643
1529
|
let currentStateNode = stateNode;
|
|
644
1530
|
while (arrayStatePath.length) {
|
|
645
1531
|
const key = arrayStatePath.shift();
|
|
@@ -891,8 +1777,8 @@ function getMachineOutput(state, event, actorScope, rootNode, rootCompletionNode
|
|
|
891
1777
|
if (!rootNode.output) {
|
|
892
1778
|
return;
|
|
893
1779
|
}
|
|
894
|
-
const doneStateEvent =
|
|
895
|
-
return
|
|
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);
|
|
896
1782
|
}
|
|
897
1783
|
function enterStates(currentState, event, actorScope, filteredTransitions, mutConfiguration, internalQueue, historyValue, isInitial) {
|
|
898
1784
|
let nextState = currentState;
|
|
@@ -930,11 +1816,11 @@ function enterStates(currentState, event, actorScope, filteredTransitions, mutCo
|
|
|
930
1816
|
let ancestorMarker = parent?.type === 'parallel' ? parent : parent?.parent;
|
|
931
1817
|
let rootCompletionNode = ancestorMarker || stateNodeToEnter;
|
|
932
1818
|
if (parent?.type === 'compound') {
|
|
933
|
-
internalQueue.push(
|
|
1819
|
+
internalQueue.push(createDoneStateEvent(parent.id, stateNodeToEnter.output ? resolveOutput(stateNodeToEnter.output, nextState.context, event, actorScope.self) : undefined));
|
|
934
1820
|
}
|
|
935
1821
|
while (ancestorMarker?.type === 'parallel' && !completedNodes.has(ancestorMarker) && isInFinalState(mutConfiguration, ancestorMarker)) {
|
|
936
1822
|
completedNodes.add(ancestorMarker);
|
|
937
|
-
internalQueue.push(
|
|
1823
|
+
internalQueue.push(createDoneStateEvent(ancestorMarker.id));
|
|
938
1824
|
rootCompletionNode = ancestorMarker;
|
|
939
1825
|
ancestorMarker = ancestorMarker.parent;
|
|
940
1826
|
}
|
|
@@ -1097,7 +1983,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
|
|
|
1097
1983
|
event
|
|
1098
1984
|
}) : action.params : undefined;
|
|
1099
1985
|
if (!('resolve' in resolvedAction)) {
|
|
1100
|
-
if (actorScope?.self._processingStatus ===
|
|
1986
|
+
if (actorScope?.self._processingStatus === ProcessingStatus.Running) {
|
|
1101
1987
|
resolvedAction(actionArgs, actionParams);
|
|
1102
1988
|
} else {
|
|
1103
1989
|
actorScope?.defer(() => {
|
|
@@ -1115,7 +2001,7 @@ function resolveActionsAndContextWorker(currentState, event, actorScope, actions
|
|
|
1115
2001
|
retries?.push([builtinAction, params]);
|
|
1116
2002
|
}
|
|
1117
2003
|
if ('execute' in builtinAction) {
|
|
1118
|
-
if (actorScope?.self._processingStatus ===
|
|
2004
|
+
if (actorScope?.self._processingStatus === ProcessingStatus.Running) {
|
|
1119
2005
|
builtinAction.execute(actorScope, params);
|
|
1120
2006
|
} else {
|
|
1121
2007
|
actorScope?.defer(builtinAction.execute.bind(null, actorScope, params));
|
|
@@ -1139,11 +2025,14 @@ function resolveActionsAndContext(currentState, event, actorScope, actions, inte
|
|
|
1139
2025
|
return nextState;
|
|
1140
2026
|
}
|
|
1141
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
|
+
}
|
|
1142
2031
|
let nextState = state;
|
|
1143
2032
|
const states = [];
|
|
1144
2033
|
|
|
1145
2034
|
// Handle stop event
|
|
1146
|
-
if (event.type ===
|
|
2035
|
+
if (event.type === XSTATE_STOP) {
|
|
1147
2036
|
nextState = cloneMachineSnapshot(stopChildren(nextState, event, actorScope), {
|
|
1148
2037
|
status: 'stopped'
|
|
1149
2038
|
});
|
|
@@ -1157,7 +2046,7 @@ function macrostep(state, event, actorScope, internalQueue = []) {
|
|
|
1157
2046
|
|
|
1158
2047
|
// Assume the state is at rest (no raised events)
|
|
1159
2048
|
// Determine the next state based on the next microstep
|
|
1160
|
-
if (nextEvent.type !==
|
|
2049
|
+
if (nextEvent.type !== XSTATE_INIT) {
|
|
1161
2050
|
const transitions = selectTransitions(nextEvent, nextState);
|
|
1162
2051
|
nextState = microstep(transitions, state, actorScope, nextEvent, false, internalQueue);
|
|
1163
2052
|
states.push(nextState);
|
|
@@ -1223,8 +2112,56 @@ function resolveStateValue(rootNode, stateValue) {
|
|
|
1223
2112
|
return getStateValue(rootNode, [...configuration]);
|
|
1224
2113
|
}
|
|
1225
2114
|
|
|
1226
|
-
function
|
|
2115
|
+
function isMachineSnapshot(value) {
|
|
2116
|
+
return !!value && typeof value === 'object' && 'machine' in value && 'value' in value;
|
|
2117
|
+
}
|
|
2118
|
+
const machineSnapshotMatches = function matches(testValue) {
|
|
2119
|
+
return matchesState(testValue, this.value);
|
|
2120
|
+
};
|
|
2121
|
+
const machineSnapshotHasTag = function hasTag(tag) {
|
|
2122
|
+
return this.tags.has(tag);
|
|
2123
|
+
};
|
|
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
|
+
}
|
|
2128
|
+
const transitionData = this.machine.getTransitionData(this, event);
|
|
2129
|
+
return !!transitionData?.length &&
|
|
2130
|
+
// Check that at least one transition is not forbidden
|
|
2131
|
+
transitionData.some(t => t.target !== undefined || t.actions.length);
|
|
2132
|
+
};
|
|
2133
|
+
const machineSnapshotToJSON = function toJSON() {
|
|
2134
|
+
const {
|
|
2135
|
+
configuration,
|
|
2136
|
+
tags,
|
|
2137
|
+
machine,
|
|
2138
|
+
nextEvents,
|
|
2139
|
+
toJSON,
|
|
2140
|
+
can,
|
|
2141
|
+
hasTag,
|
|
2142
|
+
matches,
|
|
2143
|
+
...jsonValues
|
|
2144
|
+
} = this;
|
|
1227
2145
|
return {
|
|
2146
|
+
...jsonValues,
|
|
2147
|
+
tags: Array.from(tags)
|
|
2148
|
+
};
|
|
2149
|
+
};
|
|
2150
|
+
const machineSnapshotNextEvents = function nextEvents() {
|
|
2151
|
+
return memo(this, 'nextEvents', () => {
|
|
2152
|
+
return [...new Set(flatten([...this.configuration.map(sn => sn.ownEvents)]))];
|
|
2153
|
+
});
|
|
2154
|
+
};
|
|
2155
|
+
const machineSnapshotMeta = function nextEvents() {
|
|
2156
|
+
return this.configuration.reduce((acc, stateNode) => {
|
|
2157
|
+
if (stateNode.meta !== undefined) {
|
|
2158
|
+
acc[stateNode.id] = stateNode.meta;
|
|
2159
|
+
}
|
|
2160
|
+
return acc;
|
|
2161
|
+
}, {});
|
|
2162
|
+
};
|
|
2163
|
+
function createMachineSnapshot(config, machine) {
|
|
2164
|
+
const snapshot = {
|
|
1228
2165
|
status: config.status,
|
|
1229
2166
|
output: config.output,
|
|
1230
2167
|
error: config.error,
|
|
@@ -1232,52 +2169,28 @@ function createMachineSnapshot(config, machine) {
|
|
|
1232
2169
|
context: config.context,
|
|
1233
2170
|
configuration: config.configuration,
|
|
1234
2171
|
value: getStateValue(machine.root, config.configuration),
|
|
1235
|
-
tags: new Set(
|
|
2172
|
+
tags: new Set(flatten(config.configuration.map(sn => sn.tags))),
|
|
1236
2173
|
children: config.children,
|
|
1237
2174
|
historyValue: config.historyValue || {},
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
},
|
|
1250
|
-
get nextEvents() {
|
|
1251
|
-
return memo(this, 'nextEvents', () => {
|
|
1252
|
-
return [...new Set(interpreter.flatten([...this.configuration.map(sn => sn.ownEvents)]))];
|
|
1253
|
-
});
|
|
1254
|
-
},
|
|
1255
|
-
get meta() {
|
|
1256
|
-
return this.configuration.reduce((acc, stateNode) => {
|
|
1257
|
-
if (stateNode.meta !== undefined) {
|
|
1258
|
-
acc[stateNode.id] = stateNode.meta;
|
|
1259
|
-
}
|
|
1260
|
-
return acc;
|
|
1261
|
-
}, {});
|
|
2175
|
+
// this one is generic in the target and it's hard to create a matching non-generic source signature
|
|
2176
|
+
matches: machineSnapshotMatches,
|
|
2177
|
+
hasTag: machineSnapshotHasTag,
|
|
2178
|
+
can: machineSnapshotCan,
|
|
2179
|
+
toJSON: machineSnapshotToJSON
|
|
2180
|
+
};
|
|
2181
|
+
Object.defineProperties(snapshot, {
|
|
2182
|
+
nextEvents: {
|
|
2183
|
+
get: machineSnapshotNextEvents,
|
|
2184
|
+
configurable: true,
|
|
2185
|
+
enumerable: true
|
|
1262
2186
|
},
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
machine,
|
|
1268
|
-
nextEvents,
|
|
1269
|
-
toJSON,
|
|
1270
|
-
can,
|
|
1271
|
-
hasTag,
|
|
1272
|
-
matches,
|
|
1273
|
-
...jsonValues
|
|
1274
|
-
} = this;
|
|
1275
|
-
return {
|
|
1276
|
-
...jsonValues,
|
|
1277
|
-
tags: Array.from(tags)
|
|
1278
|
-
};
|
|
2187
|
+
meta: {
|
|
2188
|
+
get: machineSnapshotMeta,
|
|
2189
|
+
configurable: true,
|
|
2190
|
+
enumerable: true
|
|
1279
2191
|
}
|
|
1280
|
-
};
|
|
2192
|
+
});
|
|
2193
|
+
return snapshot;
|
|
1281
2194
|
}
|
|
1282
2195
|
function cloneMachineSnapshot(state, config = {}) {
|
|
1283
2196
|
return createMachineSnapshot(
|
|
@@ -1304,6 +2217,9 @@ function getPersistedState(state, options) {
|
|
|
1304
2217
|
const childrenJson = {};
|
|
1305
2218
|
for (const id in children) {
|
|
1306
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
|
+
}
|
|
1307
2223
|
childrenJson[id] = {
|
|
1308
2224
|
state: child.getPersistedState(options),
|
|
1309
2225
|
src: child.src,
|
|
@@ -1327,7 +2243,7 @@ function persistContext(contextPart) {
|
|
|
1327
2243
|
...contextPart
|
|
1328
2244
|
};
|
|
1329
2245
|
copy[key] = {
|
|
1330
|
-
xstate$$type:
|
|
2246
|
+
xstate$$type: $$ACTOR_TYPE,
|
|
1331
2247
|
id: value.id
|
|
1332
2248
|
};
|
|
1333
2249
|
} else {
|
|
@@ -1386,6 +2302,9 @@ function executeRaise(actorScope, params) {
|
|
|
1386
2302
|
*/
|
|
1387
2303
|
function raise(eventOrExpr, options) {
|
|
1388
2304
|
function raise(args, params) {
|
|
2305
|
+
{
|
|
2306
|
+
throw new Error(`This isn't supposed to be called`);
|
|
2307
|
+
}
|
|
1389
2308
|
}
|
|
1390
2309
|
raise.type = 'xstate.raise';
|
|
1391
2310
|
raise.event = eventOrExpr;
|
|
@@ -1396,32 +2315,4 @@ function raise(eventOrExpr, options) {
|
|
|
1396
2315
|
return raise;
|
|
1397
2316
|
}
|
|
1398
2317
|
|
|
1399
|
-
|
|
1400
|
-
exports.cancel = cancel;
|
|
1401
|
-
exports.cloneMachineSnapshot = cloneMachineSnapshot;
|
|
1402
|
-
exports.createMachineSnapshot = createMachineSnapshot;
|
|
1403
|
-
exports.evaluateGuard = evaluateGuard;
|
|
1404
|
-
exports.formatInitialTransition = formatInitialTransition;
|
|
1405
|
-
exports.formatTransition = formatTransition;
|
|
1406
|
-
exports.formatTransitions = formatTransitions;
|
|
1407
|
-
exports.getCandidates = getCandidates;
|
|
1408
|
-
exports.getConfiguration = getConfiguration;
|
|
1409
|
-
exports.getDelayedTransitions = getDelayedTransitions;
|
|
1410
|
-
exports.getInitialStateNodes = getInitialStateNodes;
|
|
1411
|
-
exports.getPersistedState = getPersistedState;
|
|
1412
|
-
exports.getStateNodeByPath = getStateNodeByPath;
|
|
1413
|
-
exports.getStateNodes = getStateNodes;
|
|
1414
|
-
exports.isInFinalState = isInFinalState;
|
|
1415
|
-
exports.isStateId = isStateId;
|
|
1416
|
-
exports.macrostep = macrostep;
|
|
1417
|
-
exports.memo = memo;
|
|
1418
|
-
exports.microstep = microstep;
|
|
1419
|
-
exports.not = not;
|
|
1420
|
-
exports.or = or;
|
|
1421
|
-
exports.raise = raise;
|
|
1422
|
-
exports.resolveActionsAndContext = resolveActionsAndContext;
|
|
1423
|
-
exports.resolveStateValue = resolveStateValue;
|
|
1424
|
-
exports.spawn = spawn;
|
|
1425
|
-
exports.stateIn = stateIn;
|
|
1426
|
-
exports.stop = stop;
|
|
1427
|
-
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 };
|