xstate 6.0.0-beta.1 → 6.0.0-beta.3
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/README.md +4 -2
- package/dist/{createActor-cbe3abac.esm.js → createActor-49ea55ba.esm.js} +259 -47
- package/dist/{createActor-25900f76.cjs.js → createActor-73aa92ba.cjs.js} +261 -46
- package/dist/{createActor-551369be.development.esm.js → createActor-a085b20b.development.esm.js} +260 -48
- package/dist/{createActor-a49ae0ce.development.cjs.js → createActor-dfb6b790.development.cjs.js} +262 -47
- package/dist/declarations/src/createActor.d.ts +3 -1
- package/dist/declarations/src/createMachine.d.ts +6 -3
- package/dist/declarations/src/durable/index.d.ts +43 -8
- package/dist/declarations/src/effectDescriptor.d.ts +2 -2
- package/dist/declarations/src/fsm.d.ts +7 -7
- package/dist/declarations/src/machineVersion.types.d.ts +2 -2
- package/dist/declarations/src/setup.d.ts +2 -2
- package/dist/declarations/src/systemTransition.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +4 -2
- package/dist/declarations/src/types.v6.d.ts +37 -2
- package/dist/{effectDescriptor-2fa27c54.cjs.js → effectDescriptor-3402f63e.cjs.js} +5 -5
- package/dist/{effectDescriptor-d8b0f749.esm.js → effectDescriptor-65821048.development.esm.js} +5 -5
- package/dist/{effectDescriptor-321a8ce9.development.esm.js → effectDescriptor-72c62058.esm.js} +5 -5
- package/dist/{effectDescriptor-f73da4ec.development.cjs.js → effectDescriptor-d0ea44ad.development.cjs.js} +5 -5
- package/dist/{machineSchemas-b5736804.development.esm.js → legacySnapshot-11aba2d2.development.esm.js} +117 -3
- package/dist/{machineSchemas-6d96bef4.development.cjs.js → legacySnapshot-2e2c1d3b.development.cjs.js} +118 -2
- package/dist/{machineSchemas-88d01821.cjs.js → legacySnapshot-a85dfbe2.cjs.js} +117 -1
- package/dist/{machineSchemas-45c21bc2.esm.js → legacySnapshot-fffe81a0.esm.js} +116 -2
- package/dist/xstate-actors.cjs.js +30 -5
- package/dist/xstate-actors.development.cjs.js +30 -5
- package/dist/xstate-actors.development.esm.js +31 -6
- package/dist/xstate-actors.esm.js +31 -6
- package/dist/xstate-actors.umd.min.js +1 -1
- package/dist/xstate-actors.umd.min.js.map +1 -1
- package/dist/xstate-durable.cjs.js +120 -10
- package/dist/xstate-durable.development.cjs.js +120 -10
- package/dist/xstate-durable.development.esm.js +120 -10
- package/dist/xstate-durable.esm.js +120 -10
- package/dist/xstate-durable.umd.min.js +1 -1
- package/dist/xstate-durable.umd.min.js.map +1 -1
- package/dist/xstate-fsm.cjs.js +61 -31
- package/dist/xstate-fsm.development.cjs.js +61 -31
- package/dist/xstate-fsm.development.esm.js +61 -31
- package/dist/xstate-fsm.esm.js +61 -31
- package/dist/xstate-fsm.umd.min.js +1 -1
- package/dist/xstate-fsm.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +1 -1
- package/dist/xstate-graph.development.cjs.js +1 -1
- package/dist/xstate-graph.development.esm.js +2 -2
- package/dist/xstate-graph.esm.js +2 -2
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate-persist.cjs.js +23 -12
- package/dist/xstate-persist.development.cjs.js +23 -12
- package/dist/xstate-persist.development.esm.js +17 -6
- package/dist/xstate-persist.esm.js +17 -6
- package/dist/xstate-persist.umd.min.js +1 -1
- package/dist/xstate-persist.umd.min.js.map +1 -1
- package/dist/xstate-validation.cjs.js +1 -1
- package/dist/xstate-validation.development.cjs.js +1 -1
- package/dist/xstate-validation.development.esm.js +1 -1
- package/dist/xstate-validation.esm.js +1 -1
- package/dist/xstate.cjs.js +86 -56
- package/dist/xstate.development.cjs.js +86 -56
- package/dist/xstate.development.esm.js +76 -46
- package/dist/xstate.esm.js +76 -46
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/docs/actor-logic.md +1 -1
- package/docs/api-stability.json +335 -305
- package/docs/backend-workflows.md +3 -3
- package/docs/durable-execution.md +72 -48
- package/docs/errors.md +2 -2
- package/docs/examples.md +34 -34
- package/docs/faq.md +1 -1
- package/docs/fsm.md +54 -10
- package/docs/guards.md +1 -1
- package/docs/index.md +2 -1
- package/docs/inspect-actor-systems.md +20 -3
- package/docs/inspection.md +5 -1
- package/docs/invoke.md +36 -4
- package/docs/migrate-inspector.md +141 -0
- package/docs/persistence.md +16 -10
- package/docs/serialization.md +1 -1
- package/docs/setup-and-provide.md +3 -3
- package/docs/spawn.md +1 -1
- package/docs/system-transitions.md +8 -6
- package/docs/transitions.md +5 -1
- package/docs/tutorial.md +5 -5
- package/docs/typescript.md +9 -0
- package/docs/xstate-v5-to-v6.md +23 -21
- package/package.json +1 -1
package/dist/{createActor-551369be.development.esm.js → createActor-a085b20b.development.esm.js}
RENAMED
|
@@ -211,11 +211,11 @@ function isRemoteActorRef(actorRef) {
|
|
|
211
211
|
* JSON (`actor.toJSON()`): plain data carrying an address, not an actor.
|
|
212
212
|
*/
|
|
213
213
|
function isSerializedActorRef(target) {
|
|
214
|
-
if (typeof target !== 'object' || target === null || Array.isArray(target) || typeof target
|
|
214
|
+
if (typeof target !== 'object' || target === null || Array.isArray(target) || typeof target['@actor'] !== 'string') {
|
|
215
215
|
return false;
|
|
216
216
|
}
|
|
217
217
|
for (const key in target) {
|
|
218
|
-
if (key !== '
|
|
218
|
+
if (key !== '@actor' && key !== 'incarnation') {
|
|
219
219
|
return false;
|
|
220
220
|
}
|
|
221
221
|
}
|
|
@@ -231,7 +231,7 @@ function getAddressId(address) {
|
|
|
231
231
|
|
|
232
232
|
/** @internal The error reported when no live actor has a serialized address. */
|
|
233
233
|
function createMissingAddressError(target) {
|
|
234
|
-
return new Error(target.incarnation === undefined ? `Unable to send event to actor '${target
|
|
234
|
+
return new Error(target.incarnation === undefined ? `Unable to send event to actor '${target['@actor']}': no live actor has that address` : `Unable to send event to actor '${target['@actor']}' (incarnation '${target.incarnation}'): no live actor has that address and incarnation`);
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
/**
|
|
@@ -240,7 +240,7 @@ function createMissingAddressError(target) {
|
|
|
240
240
|
* without one follows whichever actor is live at the address.
|
|
241
241
|
*/
|
|
242
242
|
function resolveSerializedActorRef(system, target) {
|
|
243
|
-
const live = system._getByAddress?.(target
|
|
243
|
+
const live = system._getByAddress?.(target['@actor']);
|
|
244
244
|
return live && (target.incarnation === undefined || live.sessionId === target.incarnation) ? live : undefined;
|
|
245
245
|
}
|
|
246
246
|
|
|
@@ -293,7 +293,7 @@ function createInertActorRef(options) {
|
|
|
293
293
|
throw new Error(`Cannot serialize actor ref '${id}': it was returned by a spawn during speculative transition evaluation, which creates no actor and has no parent address.` );
|
|
294
294
|
}
|
|
295
295
|
return {
|
|
296
|
-
|
|
296
|
+
'@actor': address
|
|
297
297
|
};
|
|
298
298
|
}
|
|
299
299
|
};
|
|
@@ -379,7 +379,7 @@ function createRemoteActorRef(system, options) {
|
|
|
379
379
|
// one actor-reference shape whether a child is co-located or remote.
|
|
380
380
|
toJSON() {
|
|
381
381
|
return {
|
|
382
|
-
|
|
382
|
+
'@actor': options.address
|
|
383
383
|
};
|
|
384
384
|
}
|
|
385
385
|
};
|
|
@@ -499,7 +499,7 @@ function deliverEvent(source, target, event) {
|
|
|
499
499
|
throw error;
|
|
500
500
|
}
|
|
501
501
|
void system.deadLetter(source, undefined, event, 'missingTarget', {
|
|
502
|
-
targetId: getAddressId(serialized
|
|
502
|
+
targetId: getAddressId(serialized['@actor']),
|
|
503
503
|
error
|
|
504
504
|
});
|
|
505
505
|
return;
|
|
@@ -953,6 +953,7 @@ function resolveRegisteredActorSource(actors, logic) {
|
|
|
953
953
|
const systemLogicMetadata = Symbol('xstate.systemLogicMetadata');
|
|
954
954
|
|
|
955
955
|
const subscriptions = /* #__PURE__ */new WeakMap();
|
|
956
|
+
const XSTATE_ATTACHED_FORWARD = 'xstate.attached.forward';
|
|
956
957
|
|
|
957
958
|
/**
|
|
958
959
|
* Internal factory for actor logic that attaches to another actor on start
|
|
@@ -1015,9 +1016,11 @@ id) {
|
|
|
1015
1016
|
unsubscribe: teardown
|
|
1016
1017
|
});
|
|
1017
1018
|
},
|
|
1018
|
-
transition: (state, event, {
|
|
1019
|
-
self
|
|
1020
|
-
|
|
1019
|
+
transition: (state, event, scope) => {
|
|
1020
|
+
const self = scope.self;
|
|
1021
|
+
if (event.type === XSTATE_ATTACHED_FORWARD) {
|
|
1022
|
+
return [state, state.status === 'active' && self._parent ? [createSendToEffect(scope, self._parent, event.event)] : []];
|
|
1023
|
+
}
|
|
1021
1024
|
if (event.type === XSTATE_STOP) {
|
|
1022
1025
|
subscriptions.get(self)?.unsubscribe();
|
|
1023
1026
|
subscriptions.delete(self);
|
|
@@ -1032,7 +1035,8 @@ id) {
|
|
|
1032
1035
|
initialTransition,
|
|
1033
1036
|
getInitialSnapshot: (actorScope, input) => initialTransition(input)[0],
|
|
1034
1037
|
getPersistedSnapshot: snapshot => snapshot,
|
|
1035
|
-
restoreSnapshot: snapshot => snapshot
|
|
1038
|
+
restoreSnapshot: snapshot => snapshot,
|
|
1039
|
+
isInternalEventType: eventType => eventType === XSTATE_ATTACHED_FORWARD
|
|
1036
1040
|
};
|
|
1037
1041
|
Object.defineProperty(logic, systemLogicMetadata, {
|
|
1038
1042
|
value: {
|
|
@@ -1050,7 +1054,10 @@ function relayMappedToParent(self, system, getEvent) {
|
|
|
1050
1054
|
if (self.getSnapshot().status === 'stopped' || !self._parent) {
|
|
1051
1055
|
return;
|
|
1052
1056
|
}
|
|
1053
|
-
system._relay(self, self
|
|
1057
|
+
system._relay(self, self, {
|
|
1058
|
+
type: XSTATE_ATTACHED_FORWARD,
|
|
1059
|
+
event: getEvent()
|
|
1060
|
+
});
|
|
1054
1061
|
}
|
|
1055
1062
|
|
|
1056
1063
|
/** @public */
|
|
@@ -2201,6 +2208,18 @@ function withSystemInspector(inspect, fn) {
|
|
|
2201
2208
|
|
|
2202
2209
|
/** Snapshot-scoped actor identity and system view. @internal */
|
|
2203
2210
|
|
|
2211
|
+
// Each view's execution system and whether it forwards inspection. Views
|
|
2212
|
+
// never chain: they all inherit from the execution system directly.
|
|
2213
|
+
const snapshotSystemViews = new WeakMap();
|
|
2214
|
+
// Facilities owned by the execution rather than by one snapshot's view. A view
|
|
2215
|
+
// reads and writes them on the execution system, so timers, listeners and the
|
|
2216
|
+
// runtime installed through any snapshot are visible through every other.
|
|
2217
|
+
const executionFacilities = ['runtime', '_timerMap', '_rejectionListeners', '_inspectionObservers', '_emissionListeners'];
|
|
2218
|
+
// The durable execution that owns each execution system.
|
|
2219
|
+
/** A durable execution, as the owner of the views its transitions create. @internal */
|
|
2220
|
+
|
|
2221
|
+
const executionOwners = new WeakMap();
|
|
2222
|
+
let ambientExecutionOwner;
|
|
2204
2223
|
const snapshotActorRefs = new WeakMap();
|
|
2205
2224
|
const lazySnapshotActorRefs = new WeakMap();
|
|
2206
2225
|
const emptyKeyedActors = new Map();
|
|
@@ -2260,12 +2279,22 @@ function getSnapshotChildren(snapshot) {
|
|
|
2260
2279
|
*
|
|
2261
2280
|
* @internal
|
|
2262
2281
|
*/
|
|
2263
|
-
function createSnapshotSystem(baseSystem, children, baseState) {
|
|
2264
|
-
const
|
|
2282
|
+
function createSnapshotSystem(baseSystem, children, baseState, owner) {
|
|
2283
|
+
const baseView = snapshotSystemViews.get(baseSystem);
|
|
2284
|
+
const baseExecutionSystem = baseView?.executionSystem ?? baseSystem;
|
|
2285
|
+
// The runtime system under every view. A view runs its methods against the
|
|
2286
|
+
// execution system's facilities.
|
|
2287
|
+
const rootSystem = baseView?.rootSystem ?? baseSystem;
|
|
2288
|
+
const forks = owner !== undefined && executionOwners.get(baseExecutionSystem) !== owner;
|
|
2289
|
+
// A view an execution owns reports to that execution's inspector.
|
|
2290
|
+
const forwardInspection = owner ? !!owner.inspect : hasAmbientInspector() && (baseView?.forwardInspection ?? true);
|
|
2265
2291
|
const registeredActors = copyRegisteredActors(baseSystem, baseState);
|
|
2266
2292
|
const keyedActors = new Map(baseState?.keyedActors ?? getKeyedActors(baseSystem));
|
|
2267
2293
|
const reverseKeyedActors = new WeakMap();
|
|
2268
|
-
|
|
2294
|
+
// The view's execution system; adoption can make the view its own.
|
|
2295
|
+
const execution = () => snapshotSystemViews.get(system).executionSystem;
|
|
2296
|
+
const forwards = () => snapshotSystemViews.get(system).forwardInspection;
|
|
2297
|
+
const system = Object.assign(Object.create(baseExecutionSystem), {
|
|
2269
2298
|
children: registeredActors,
|
|
2270
2299
|
keyedActors,
|
|
2271
2300
|
reverseKeyedActors,
|
|
@@ -2300,15 +2329,38 @@ function createSnapshotSystem(baseSystem, children, baseState) {
|
|
|
2300
2329
|
},
|
|
2301
2330
|
get: registryKey => keyedActors.get(registryKey),
|
|
2302
2331
|
getAll: () => Object.fromEntries(keyedActors),
|
|
2303
|
-
onEmitted: listener =>
|
|
2304
|
-
_notifyEmitted: (actorRef, event) =>
|
|
2332
|
+
onEmitted: listener => rootSystem.onEmitted.call(execution(), listener),
|
|
2333
|
+
_notifyEmitted: (actorRef, event) => rootSystem._notifyEmitted.call(execution(), actorRef, event),
|
|
2305
2334
|
// Pure transition resolution must not leak topology inspection events
|
|
2306
2335
|
// into a live runtime system — planning branches stay silent. The one
|
|
2307
2336
|
// exception is a durable execution's own transitions (marked by the
|
|
2308
2337
|
// ambient inspector at creation time): there the pure path IS the
|
|
2309
|
-
// execution, so inspection forwards to the
|
|
2310
|
-
_hasInspectionObservers:
|
|
2311
|
-
_sendInspectionEvent:
|
|
2338
|
+
// execution, so inspection forwards to the execution system's observers.
|
|
2339
|
+
_hasInspectionObservers: () => forwards() && (rootSystem._hasInspectionObservers?.call(execution()) ?? false),
|
|
2340
|
+
_sendInspectionEvent: event => {
|
|
2341
|
+
if (forwards()) {
|
|
2342
|
+
rootSystem._sendInspectionEvent.call(execution(), event);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
});
|
|
2346
|
+
const executionSystem = forks ? system : baseExecutionSystem;
|
|
2347
|
+
if (forks) {
|
|
2348
|
+
forkFacilities(system, baseExecutionSystem, owner);
|
|
2349
|
+
} else {
|
|
2350
|
+
for (const key of executionFacilities) {
|
|
2351
|
+
Object.defineProperty(system, key, {
|
|
2352
|
+
configurable: true,
|
|
2353
|
+
get: () => execution()[key],
|
|
2354
|
+
set: value => {
|
|
2355
|
+
execution()[key] = value;
|
|
2356
|
+
}
|
|
2357
|
+
});
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
snapshotSystemViews.set(system, {
|
|
2361
|
+
executionSystem,
|
|
2362
|
+
rootSystem,
|
|
2363
|
+
forwardInspection
|
|
2312
2364
|
});
|
|
2313
2365
|
for (const [registryKey, actor] of keyedActors) {
|
|
2314
2366
|
if (!actor) {
|
|
@@ -2332,6 +2384,83 @@ function createSnapshotSystem(baseSystem, children, baseState) {
|
|
|
2332
2384
|
return system;
|
|
2333
2385
|
}
|
|
2334
2386
|
|
|
2387
|
+
/**
|
|
2388
|
+
* Makes `system` the execution system of `owner`, a new incarnation: it gets
|
|
2389
|
+
* the owner's runtime and the pending timers it saw, and starts with no
|
|
2390
|
+
* listeners or inspectors, so nothing registered on another execution
|
|
2391
|
+
* observes it.
|
|
2392
|
+
*/
|
|
2393
|
+
function forkFacilities(system, from, owner) {
|
|
2394
|
+
const timers = from._timerMap;
|
|
2395
|
+
for (const key of executionFacilities) {
|
|
2396
|
+
Object.defineProperty(system, key, {
|
|
2397
|
+
configurable: true,
|
|
2398
|
+
writable: true,
|
|
2399
|
+
value: key === 'runtime' ? owner.runtime : key === '_timerMap' && timers ? {
|
|
2400
|
+
...timers
|
|
2401
|
+
} : undefined
|
|
2402
|
+
});
|
|
2403
|
+
}
|
|
2404
|
+
executionOwners.set(system, owner);
|
|
2405
|
+
if (owner.inspect) {
|
|
2406
|
+
system.inspect(owner.inspect);
|
|
2407
|
+
}
|
|
2408
|
+
}
|
|
2409
|
+
|
|
2410
|
+
/**
|
|
2411
|
+
* Makes `owner` own `system` before it installs its runtime there, and
|
|
2412
|
+
* returns whether it does. An unowned view forks in place, so the install
|
|
2413
|
+
* never reaches the system it was derived from. A system another execution
|
|
2414
|
+
* owns is left alone.
|
|
2415
|
+
*
|
|
2416
|
+
* @internal
|
|
2417
|
+
*/
|
|
2418
|
+
function adoptSystem(system, owner) {
|
|
2419
|
+
const view = snapshotSystemViews.get(system);
|
|
2420
|
+
const current = executionOwners.get(view?.executionSystem ?? system);
|
|
2421
|
+
if (current === owner) {
|
|
2422
|
+
if (view) {
|
|
2423
|
+
view.forwardInspection = !!owner.inspect;
|
|
2424
|
+
}
|
|
2425
|
+
return true;
|
|
2426
|
+
}
|
|
2427
|
+
// A system another execution owns stays with it.
|
|
2428
|
+
if (current) {
|
|
2429
|
+
return false;
|
|
2430
|
+
}
|
|
2431
|
+
if (!view) {
|
|
2432
|
+
executionOwners.set(system, owner);
|
|
2433
|
+
return true;
|
|
2434
|
+
}
|
|
2435
|
+
forkFacilities(system, view.executionSystem, owner);
|
|
2436
|
+
view.executionSystem = system;
|
|
2437
|
+
view.forwardInspection = !!owner.inspect;
|
|
2438
|
+
return true;
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
/**
|
|
2442
|
+
* Runs `fn` as a transition of `owner`. A view it derives from a system the
|
|
2443
|
+
* owner does not own forks into the owner's own execution system.
|
|
2444
|
+
*
|
|
2445
|
+
* @internal
|
|
2446
|
+
*/
|
|
2447
|
+
function withExecutionOwner(owner, fn) {
|
|
2448
|
+
const previous = ambientExecutionOwner;
|
|
2449
|
+
ambientExecutionOwner = owner;
|
|
2450
|
+
try {
|
|
2451
|
+
return fn();
|
|
2452
|
+
} finally {
|
|
2453
|
+
ambientExecutionOwner = previous;
|
|
2454
|
+
}
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2457
|
+
/** Hands the ambient owner to the first scope that asks for it. @internal */
|
|
2458
|
+
function takeExecutionOwner() {
|
|
2459
|
+
const owner = ambientExecutionOwner;
|
|
2460
|
+
ambientExecutionOwner = undefined;
|
|
2461
|
+
return owner;
|
|
2462
|
+
}
|
|
2463
|
+
|
|
2335
2464
|
/** Returns the actor identity associated with a transition snapshot. @internal */
|
|
2336
2465
|
function getSnapshotActorRef(snapshot) {
|
|
2337
2466
|
const existing = snapshotActorRefs.get(snapshot);
|
|
@@ -2525,8 +2654,9 @@ function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true)
|
|
|
2525
2654
|
const lazyState = getLazyInertActorState(actorScope);
|
|
2526
2655
|
if (lazyState) {
|
|
2527
2656
|
lazyState.snapshot = snapshot;
|
|
2528
|
-
|
|
2529
|
-
|
|
2657
|
+
const scope = lazyState.materialized ?? lazyState.identityScope;
|
|
2658
|
+
if (scope) {
|
|
2659
|
+
scope.self._snapshot = snapshot;
|
|
2530
2660
|
}
|
|
2531
2661
|
} else {
|
|
2532
2662
|
actorScope.self._snapshot = snapshot;
|
|
@@ -2561,6 +2691,15 @@ function attachSnapshotActorRef(actorScope, snapshot) {
|
|
|
2561
2691
|
setLazySnapshotActorRef(snapshot, create);
|
|
2562
2692
|
return snapshot;
|
|
2563
2693
|
}
|
|
2694
|
+
/** Records the materialized scope and releases its consumed source. */
|
|
2695
|
+
function commitMaterialization(state, scope) {
|
|
2696
|
+
// Dropping the consumed source keeps this scope from retaining earlier snapshots.
|
|
2697
|
+
state.sourceRef = undefined;
|
|
2698
|
+
state.sourceChildren = {};
|
|
2699
|
+
state.materialized = scope;
|
|
2700
|
+
state.materialize = () => scope;
|
|
2701
|
+
return scope;
|
|
2702
|
+
}
|
|
2564
2703
|
const lazyInertActorState = Symbol();
|
|
2565
2704
|
const snapshotActorScopes = new WeakMap();
|
|
2566
2705
|
let inertActorMaterializationObserver;
|
|
@@ -2605,12 +2744,14 @@ const lazyInertActorScopePrototype = {
|
|
|
2605
2744
|
return materializeInertActorScope(this).actionExecutor;
|
|
2606
2745
|
}
|
|
2607
2746
|
};
|
|
2608
|
-
|
|
2747
|
+
|
|
2748
|
+
/** Creates a transactional planning scope backed by an inert actor. */
|
|
2749
|
+
function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren, currentSnapshot, sourceSelf, owner) {
|
|
2609
2750
|
inertActorMaterializationObserver?.();
|
|
2610
2751
|
const snapshotRef = sourceRef?.();
|
|
2611
2752
|
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
2612
2753
|
const baseSystem = previousSelf?.system;
|
|
2613
|
-
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, sourceChildren, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
2754
|
+
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, sourceChildren, sourceSelf ? undefined : snapshotRef?.systemState, owner) : undefined;
|
|
2614
2755
|
const self = createActor(actorLogic, {
|
|
2615
2756
|
_inert: true,
|
|
2616
2757
|
...(previousSelf ? {
|
|
@@ -2630,12 +2771,8 @@ function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren
|
|
|
2630
2771
|
// a future construction-time read cannot pin a root-shaped address.
|
|
2631
2772
|
self._address = undefined;
|
|
2632
2773
|
}
|
|
2633
|
-
if (currentSnapshot) {
|
|
2634
|
-
self._snapshot = currentSnapshot;
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
2774
|
// Reuse the branch actor's scope while keeping planning transactional.
|
|
2638
|
-
|
|
2775
|
+
const scope = Object.create(self._actorScope, {
|
|
2639
2776
|
defer: {
|
|
2640
2777
|
value: () => {}
|
|
2641
2778
|
},
|
|
@@ -2644,8 +2781,20 @@ function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren
|
|
|
2644
2781
|
},
|
|
2645
2782
|
actionExecutor: {
|
|
2646
2783
|
value: () => {}
|
|
2784
|
+
},
|
|
2785
|
+
_snapshot: {
|
|
2786
|
+
enumerable: true,
|
|
2787
|
+
configurable: true,
|
|
2788
|
+
get: () => self._snapshot,
|
|
2789
|
+
set: snapshot => {
|
|
2790
|
+
self._snapshot = snapshot;
|
|
2791
|
+
}
|
|
2647
2792
|
}
|
|
2648
2793
|
});
|
|
2794
|
+
if (currentSnapshot) {
|
|
2795
|
+
scope._snapshot = currentSnapshot;
|
|
2796
|
+
}
|
|
2797
|
+
return scope;
|
|
2649
2798
|
}
|
|
2650
2799
|
|
|
2651
2800
|
/** @internal */
|
|
@@ -2660,22 +2809,34 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf, sourceActorScop
|
|
|
2660
2809
|
sourceChildren: isMachineSnapshot(snapshot) ? snapshot.children : {},
|
|
2661
2810
|
identityProvider: sourceState?.identityProvider ?? sourceRef,
|
|
2662
2811
|
parent: sourceSelf?._parent ?? sourceState?.parent ?? eagerSourceRef?.actor._parent,
|
|
2812
|
+
// Only the outermost scope of an owned transition belongs to the owner;
|
|
2813
|
+
// scopes for its intermediate snapshots inherit it, and nested pure
|
|
2814
|
+
// transitions run unowned.
|
|
2815
|
+
owner: sourceActorScope ? sourceState?.owner : takeExecutionOwner(),
|
|
2663
2816
|
parentKnown: !!sourceSelf || !!sourceState?.parentKnown || !!eagerSourceRef || !snapshot
|
|
2664
2817
|
};
|
|
2665
|
-
state.materialize = () =>
|
|
2818
|
+
state.materialize = () => {
|
|
2819
|
+
const scope = createMaterializedInertActorScope(actorLogic, state.sourceRef, state.sourceChildren, state.snapshot, sourceSelf, state.owner);
|
|
2820
|
+
return commitMaterialization(state, scope);
|
|
2821
|
+
};
|
|
2666
2822
|
if (!state.identityProvider && !snapshot) {
|
|
2667
2823
|
const identitySnapshot = {};
|
|
2668
|
-
const identitySourceRef = state.sourceRef;
|
|
2669
|
-
const identitySourceChildren = state.sourceChildren;
|
|
2670
|
-
let identityScope;
|
|
2671
2824
|
let identityRef;
|
|
2672
|
-
const getIdentityScope = () =>
|
|
2825
|
+
const getIdentityScope = () => {
|
|
2826
|
+
if (!state.identityScope) {
|
|
2827
|
+
state.identityScope = createMaterializedInertActorScope(actorLogic, state.sourceRef, state.sourceChildren, undefined, sourceSelf, state.owner);
|
|
2828
|
+
if (state.snapshot !== undefined) {
|
|
2829
|
+
state.identityScope.self._snapshot = state.snapshot;
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
return state.identityScope;
|
|
2833
|
+
};
|
|
2673
2834
|
state.materialize = () => {
|
|
2674
2835
|
const scope = getIdentityScope();
|
|
2675
2836
|
if (state.snapshot !== undefined) {
|
|
2676
2837
|
scope.self._snapshot = state.snapshot;
|
|
2677
2838
|
}
|
|
2678
|
-
return state
|
|
2839
|
+
return commitMaterialization(state, scope);
|
|
2679
2840
|
};
|
|
2680
2841
|
state.identityProvider = () => {
|
|
2681
2842
|
if (identityRef) {
|
|
@@ -3813,7 +3974,7 @@ function microstep(transitions, currentSnapshot, actorScope, event, isInitial, i
|
|
|
3813
3974
|
}
|
|
3814
3975
|
addAncestorStatesToEnter(ancestors, !transition.source.parent && reenter ? undefined : domain);
|
|
3815
3976
|
}
|
|
3816
|
-
if (reenter && domain === transition.source) {
|
|
3977
|
+
if (targets?.length && reenter && domain === transition.source) {
|
|
3817
3978
|
// A reentering transition whose domain is its own source exits and
|
|
3818
3979
|
// reenters the source, so the source must be entered explicitly —
|
|
3819
3980
|
// it has no ancestor inside the domain to add it.
|
|
@@ -4371,7 +4532,9 @@ function macrostep(snapshot, event, actorScope, internalQueue, initialMicrosteps
|
|
|
4371
4532
|
if (!internalQueue.length && snapshot.machine._hasEventlessTransitions === false) {
|
|
4372
4533
|
return completeMacrostep();
|
|
4373
4534
|
}
|
|
4374
|
-
|
|
4535
|
+
|
|
4536
|
+
// A timer notification must not run eventless transitions before delivery.
|
|
4537
|
+
let shouldSelectEventlessTransitions = event.type !== XSTATE_TIMER;
|
|
4375
4538
|
const maxIterations = snapshot.machine.options?.maxIterations ?? Infinity;
|
|
4376
4539
|
let iterationCount = 0;
|
|
4377
4540
|
// The last few state values visited, for the infinite-loop error.
|
|
@@ -4659,7 +4822,7 @@ function findNonJsonPath(value, path) {
|
|
|
4659
4822
|
};
|
|
4660
4823
|
}
|
|
4661
4824
|
if ('sessionId' in current && 'send' in current && 'ref' in current) {
|
|
4662
|
-
// Actor refs persist as `{
|
|
4825
|
+
// Actor refs persist as `{ "@actor": address }`.
|
|
4663
4826
|
return undefined;
|
|
4664
4827
|
}
|
|
4665
4828
|
if (ancestors.has(current)) {
|
|
@@ -4782,6 +4945,8 @@ const machineSnapshotToJSON = function toJSON() {
|
|
|
4782
4945
|
const {
|
|
4783
4946
|
nodes,
|
|
4784
4947
|
_stateInputs,
|
|
4948
|
+
_nextTimerId,
|
|
4949
|
+
_nextActorIds,
|
|
4785
4950
|
tags,
|
|
4786
4951
|
machine,
|
|
4787
4952
|
getMeta,
|
|
@@ -4906,6 +5071,8 @@ function getPersistedSnapshot(snapshot, options) {
|
|
|
4906
5071
|
const {
|
|
4907
5072
|
nodes,
|
|
4908
5073
|
_stateInputs,
|
|
5074
|
+
_nextTimerId,
|
|
5075
|
+
_nextActorIds,
|
|
4909
5076
|
tags,
|
|
4910
5077
|
machine,
|
|
4911
5078
|
children,
|
|
@@ -5041,6 +5208,11 @@ function getPersistedSnapshot(snapshot, options) {
|
|
|
5041
5208
|
if (_stateInputs && Object.keys(_stateInputs).length > 0) {
|
|
5042
5209
|
persisted.stateInputs = _stateInputs;
|
|
5043
5210
|
}
|
|
5211
|
+
// Stores such as Convex reject `_`-prefixed field names.
|
|
5212
|
+
persisted.nextTimerId = _nextTimerId;
|
|
5213
|
+
if (_nextActorIds && Object.keys(_nextActorIds).length > 0) {
|
|
5214
|
+
persisted.nextActorIds = _nextActorIds;
|
|
5215
|
+
}
|
|
5044
5216
|
if (machine.version !== undefined) {
|
|
5045
5217
|
persisted.machine = {
|
|
5046
5218
|
id: machine.id,
|
|
@@ -5072,7 +5244,7 @@ function persistContext(contextPart, getActorId, path = 'context', ancestors = [
|
|
|
5072
5244
|
};
|
|
5073
5245
|
// The address lets refs to non-children still route after restore.
|
|
5074
5246
|
copy[key] = {
|
|
5075
|
-
|
|
5247
|
+
'@actor': value.address
|
|
5076
5248
|
};
|
|
5077
5249
|
} else {
|
|
5078
5250
|
const valuePath = Array.isArray(contextPart) ? `${path}[${key}]` : `${path}.${key}`;
|
|
@@ -5714,11 +5886,18 @@ class RuntimeSystem {
|
|
|
5714
5886
|
// Records a send on the *sender's* transition for the `sent[]` inspection
|
|
5715
5887
|
// facet. Captures the send when it is initiated (including delayed sends that
|
|
5716
5888
|
// may never deliver), keyed to the source actor's in-flight transition.
|
|
5889
|
+
// A send made with no transition in flight (a callback's `sendBack`, a value
|
|
5890
|
+
// an observable relays to its parent) is not recorded: no transition reports
|
|
5891
|
+
// it, so it would be held until the source's next transition, or for as long
|
|
5892
|
+
// as the source lives if it never makes one.
|
|
5717
5893
|
_recordSent(source, target, event, delay, id) {
|
|
5718
5894
|
if (!this._inspectionObservers?.size || !source) {
|
|
5719
5895
|
return;
|
|
5720
5896
|
}
|
|
5721
5897
|
const inspectionSource = source;
|
|
5898
|
+
if (!inspectionSource._inTransition) {
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5722
5901
|
const collected = inspectionSource._collectedSent ??= [];
|
|
5723
5902
|
collected.push({
|
|
5724
5903
|
targetRef: target,
|
|
@@ -5955,9 +6134,9 @@ class RuntimeSystem {
|
|
|
5955
6134
|
} else if (
|
|
5956
6135
|
// A live actor of another incarnation is stale locally; an
|
|
5957
6136
|
// address this system cannot see may belong to a host runtime.
|
|
5958
|
-
this._getByAddress(target
|
|
6137
|
+
this._getByAddress(target['@actor']) || !this.runtime?.sendEvent) {
|
|
5959
6138
|
return this.deadLetter(source, undefined, event, 'missingTarget', {
|
|
5960
|
-
targetId: getAddressId(target
|
|
6139
|
+
targetId: getAddressId(target['@actor']),
|
|
5961
6140
|
error: createMissingAddressError(target)
|
|
5962
6141
|
});
|
|
5963
6142
|
}
|
|
@@ -6244,6 +6423,12 @@ class Actor {
|
|
|
6244
6423
|
this._collectedActions = void 0;
|
|
6245
6424
|
/** @internal Events relayed to other actors during the in-flight transition. */
|
|
6246
6425
|
this._collectedSent = void 0;
|
|
6426
|
+
/**
|
|
6427
|
+
* @internal Whether a transition is in flight: while the actor starts,
|
|
6428
|
+
* processes an event, or recovers from an execution error. Sends are recorded
|
|
6429
|
+
* for `sent[]` only then.
|
|
6430
|
+
*/
|
|
6431
|
+
this._inTransition = false;
|
|
6247
6432
|
this._initialEffects = void 0;
|
|
6248
6433
|
this.registryKey = void 0;
|
|
6249
6434
|
/** The globally unique process ID for this invocation. */
|
|
@@ -6316,9 +6501,14 @@ class Actor {
|
|
|
6316
6501
|
// transition functions; computing an initial snapshot here would run
|
|
6317
6502
|
// init-time side effects (context factories, entry) a second time.
|
|
6318
6503
|
} else {
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6504
|
+
this._inTransition = true;
|
|
6505
|
+
try {
|
|
6506
|
+
const [snapshot, effects] = finalizeTransitionResult(this._actorScope, undefined, this.logic.initialTransition(this.options?.input, this._actorScope));
|
|
6507
|
+
this._setSnapshot(snapshot);
|
|
6508
|
+
this._initialEffects = effects.length ? effects : undefined;
|
|
6509
|
+
} finally {
|
|
6510
|
+
this._inTransition = false;
|
|
6511
|
+
}
|
|
6322
6512
|
}
|
|
6323
6513
|
} catch (err) {
|
|
6324
6514
|
// Restored logic may keep its snapshot shape on restore failures (e.g.
|
|
@@ -6471,6 +6661,8 @@ class Actor {
|
|
|
6471
6661
|
if (!errorEvent) {
|
|
6472
6662
|
return false;
|
|
6473
6663
|
}
|
|
6664
|
+
const inTransition = this._inTransition;
|
|
6665
|
+
this._inTransition = true;
|
|
6474
6666
|
try {
|
|
6475
6667
|
const [nextSnapshot, effects] = finalizeTransitionResult(this._actorScope, snapshot, this.logic.transition(snapshot, errorEvent, this._actorScope));
|
|
6476
6668
|
this._setSnapshot(nextSnapshot);
|
|
@@ -6479,6 +6671,8 @@ class Actor {
|
|
|
6479
6671
|
return true;
|
|
6480
6672
|
} catch {
|
|
6481
6673
|
return false;
|
|
6674
|
+
} finally {
|
|
6675
|
+
this._inTransition = inTransition;
|
|
6482
6676
|
}
|
|
6483
6677
|
}
|
|
6484
6678
|
_next(snapshot) {
|
|
@@ -6690,6 +6884,15 @@ class Actor {
|
|
|
6690
6884
|
|
|
6691
6885
|
/** Starts the Actor from the initial state */
|
|
6692
6886
|
start() {
|
|
6887
|
+
const inTransition = this._inTransition;
|
|
6888
|
+
this._inTransition = true;
|
|
6889
|
+
try {
|
|
6890
|
+
return this._start();
|
|
6891
|
+
} finally {
|
|
6892
|
+
this._inTransition = inTransition;
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6895
|
+
_start() {
|
|
6693
6896
|
if (this._processingStatus === ProcessingStatus.Running) {
|
|
6694
6897
|
// Do not restart the service if it is already started
|
|
6695
6898
|
return this;
|
|
@@ -6805,7 +7008,16 @@ class Actor {
|
|
|
6805
7008
|
this.mailbox?.start();
|
|
6806
7009
|
return this;
|
|
6807
7010
|
}
|
|
6808
|
-
_process({
|
|
7011
|
+
_process(item) {
|
|
7012
|
+
const inTransition = this._inTransition;
|
|
7013
|
+
this._inTransition = true;
|
|
7014
|
+
try {
|
|
7015
|
+
this._processEvent(item);
|
|
7016
|
+
} finally {
|
|
7017
|
+
this._inTransition = inTransition;
|
|
7018
|
+
}
|
|
7019
|
+
}
|
|
7020
|
+
_processEvent({
|
|
6809
7021
|
event,
|
|
6810
7022
|
sourceRef
|
|
6811
7023
|
}) {
|
|
@@ -7053,12 +7265,12 @@ class Actor {
|
|
|
7053
7265
|
}
|
|
7054
7266
|
|
|
7055
7267
|
/**
|
|
7056
|
-
* Returns the actor's serializable logical identity: `{
|
|
7268
|
+
* Returns the actor's serializable logical identity: `{ "@actor": address }`.
|
|
7057
7269
|
* The result can be used as an `enq.sendTo(...)` target.
|
|
7058
7270
|
*/
|
|
7059
7271
|
toJSON() {
|
|
7060
7272
|
return {
|
|
7061
|
-
|
|
7273
|
+
'@actor': this.address
|
|
7062
7274
|
};
|
|
7063
7275
|
}
|
|
7064
7276
|
|
|
@@ -7172,4 +7384,4 @@ function createActor(logic, ...[options]) {
|
|
|
7172
7384
|
return new Actor(logic, options);
|
|
7173
7385
|
}
|
|
7174
7386
|
|
|
7175
|
-
export {
|
|
7387
|
+
export { resolveRegisteredActorSource as $, isMachineSnapshot as A, listenerLogic as B, subscriptionLogic as C, createListenerLogic as D, createSubscriptionLogic as E, Actor as F, matchesState as G, toObserver as H, InfiniteTransitionError as I, executeEffects as J, isBuiltInExecutableEffect as K, deliverEvent as L, runStep as M, stopActor as N, terminateActor as O, ProcessingStatus as P, createInitEvent as Q, createDeadLetterEffect as R, createCustomEffect as S, XSTATE_LOGIC_EFFECT_START as T, XSTATE_LOGIC_EFFECT_RESOLVE as U, XSTATE_LOGIC_EFFECT_REJECT as V, createEmitEffect as W, XSTATE_ATTACHED_FORWARD as X, createSendToEffect as Y, XSTATE_INIT as Z, publishEmittedEvent as _, assertUnreservedSourceName as a, allocateChildId as a0, assertChildIdFree as a1, reserveChildId as a2, hasUnescapedDot as a3, STATE_DELIMITER as a4, mapValues as a5, createInvokeId as a6, getDelayedTransitions as a7, getCandidates as a8, evaluateCandidate as a9, createSpawnEffect as aA, initialMicrostep as aB, createStartEffect as aC, isStateId as aD, getPersistedSnapshot as aE, detachedScopes as aF, toStatePath as aG, hasAmbientInspector as aH, getProperAncestors as aI, isRemoteActorRef as aJ, getAllOwnEvents as aK, matchesEvent as aL, getRootActorId as aM, RUNTIME_OPERATIONS as aN, createTimerEffect as aO, getSnapshotActorRef as aP, withExecutionOwner as aQ, getTimerStart as aR, recordTimerStart as aS, withSystemInspector as aT, adoptSystem as aU, withExecutionIdentity as aV, diagnoseActorOptions as aW, createRemoteActorRef as aX, createInvokeTimeoutEvent as aY, parseGeneratedActorId as aZ, formatTransition as aa, NULL_EVENT as ab, toTransitionConfigArray as ac, matchesActorSession as ad, describeMachine as ae, formatRouteTransitions as af, resolveStateValue as ag, isInFinalState as ah, createInertActorScope as ai, setInertActorScopeSnapshot as aj, beginSpawnAllocation as ak, attachSnapshotActorRef as al, macrostep as am, isInertActorScope as an, setSnapshotActorRef as ao, cloneMachineSnapshot as ap, transitionNode as aq, XSTATE_TIMER as ar, getTransitionResult as as, hasEffect as at, createErrorPlatformEvent as au, withActorSelf as av, resolveActionsWithContext as aw, freezeContext as ax, takeSpawnAllocationCounters as ay, mergeActorIdCounters as az, getStateNodes as b, isActorRefLike as c, diagnoseAuthorConfig as d, createMachineSnapshot as e, diagnoseSetupConfig as f, getAllStateNodes as g, createActor as h, isAtomicStateNode as i, encodeAddressSegment as j, getActorIdPrefix as k, finalizeTransitionResult as l, matchesEventDescriptor as m, getTimerKey as n, isSerializedActorRef as o, parseDelayToMilliseconds as p, readTimerKey as q, resolveInvokedActorLogic as r, systemLogicMetadata as s, toArray as t, XSTATE_STOP_EFFECT as u, XSTATE_STOP as v, createDoneActorEvent as w, createErrorActorEvent as x, serializeTimerKey as y, matchesTimerKey as z };
|