xstate 6.0.0-beta.0 → 6.0.0-beta.2
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/bin/xstate.js +10 -4
- package/dist/{createActor-551369be.development.esm.js → createActor-0250284a.development.esm.js} +244 -41
- package/dist/{createActor-cbe3abac.esm.js → createActor-20a97166.esm.js} +243 -40
- package/dist/{createActor-a49ae0ce.development.cjs.js → createActor-c029d29f.development.cjs.js} +245 -40
- package/dist/{createActor-25900f76.cjs.js → createActor-c91c9ffe.cjs.js} +244 -39
- 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/machineVersion.types.d.ts +2 -2
- package/dist/declarations/src/setup.d.ts +5 -5
- package/dist/declarations/src/systemTransition.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +11 -3
- package/dist/declarations/src/types.v6.d.ts +37 -2
- package/dist/{effectDescriptor-f73da4ec.development.cjs.js → effectDescriptor-3fff5c51.development.cjs.js} +5 -5
- package/dist/{effectDescriptor-2fa27c54.cjs.js → effectDescriptor-47f73e7e.cjs.js} +5 -5
- package/dist/{effectDescriptor-321a8ce9.development.esm.js → effectDescriptor-5ac7dccb.development.esm.js} +5 -5
- package/dist/{effectDescriptor-d8b0f749.esm.js → effectDescriptor-e93df910.esm.js} +5 -5
- package/dist/{machineSchemas-88d01821.cjs.js → legacySnapshot-8d595687.cjs.js} +117 -1
- package/dist/{machineSchemas-45c21bc2.esm.js → legacySnapshot-9e06feb4.esm.js} +116 -2
- package/dist/{machineSchemas-b5736804.development.esm.js → legacySnapshot-ae6594a7.development.esm.js} +117 -3
- package/dist/{machineSchemas-6d96bef4.development.cjs.js → legacySnapshot-ebf0b2b8.development.cjs.js} +118 -2
- package/dist/xstate-actors.cjs.js +1 -1
- package/dist/xstate-actors.development.cjs.js +1 -1
- package/dist/xstate-actors.development.esm.js +2 -2
- package/dist/xstate-actors.esm.js +2 -2
- 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 +4 -4
- package/dist/xstate-fsm.development.cjs.js +4 -4
- package/dist/xstate-fsm.development.esm.js +4 -4
- package/dist/xstate-fsm.esm.js +4 -4
- 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 +63 -51
- package/dist/xstate.development.cjs.js +63 -51
- package/dist/xstate.development.esm.js +53 -41
- package/dist/xstate.esm.js +53 -41
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/docs/agents.md +9 -0
- package/docs/api-stability.json +273 -249
- 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/fsm.md +2 -1
- package/docs/guards.md +1 -1
- package/docs/index.md +1 -1
- package/docs/invoke.md +34 -2
- 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 +6 -6
- package/docs/tutorial.md +5 -5
- package/docs/typescript.md +9 -0
- package/docs/xstate-v5-to-v6.md +176 -19
- package/package.json +1 -1
package/bin/xstate.js
CHANGED
|
@@ -15,11 +15,14 @@ switch (command) {
|
|
|
15
15
|
case 'diff':
|
|
16
16
|
require('./agent.js')(command, rest);
|
|
17
17
|
break;
|
|
18
|
-
case 'migrate':
|
|
19
|
-
|
|
18
|
+
case 'migrate':
|
|
19
|
+
case 'baseline':
|
|
20
|
+
case 'verify': {
|
|
21
|
+
// Delegates to @xstate/codemod (ts-morph based v5 → v6 codemods plus the
|
|
22
|
+
// baseline/verify trace-equivalence loop).
|
|
20
23
|
const result = spawnSync(
|
|
21
24
|
process.platform === 'win32' ? 'npx.cmd' : 'npx',
|
|
22
|
-
['-y', '@xstate/codemod',
|
|
25
|
+
['-y', '@xstate/codemod', command, ...rest],
|
|
23
26
|
{ stdio: 'inherit' }
|
|
24
27
|
);
|
|
25
28
|
process.exit(result.status ?? 1);
|
|
@@ -41,7 +44,10 @@ switch (command) {
|
|
|
41
44
|
' replay <machine> <fixture> Replay a matching counterexample (JSON)',
|
|
42
45
|
' diff <before> <after> Structural definition changes (JSON)',
|
|
43
46
|
' migrate [globs...] [--dry] Migrate source files to the current XState version',
|
|
44
|
-
' (delegates to @xstate/codemod)'
|
|
47
|
+
' (delegates to @xstate/codemod)',
|
|
48
|
+
' baseline <v5-file> Record a v5 behavior baseline before migrating',
|
|
49
|
+
' verify --baseline <json> <v6-file>',
|
|
50
|
+
' Replay the baseline against the migrated module'
|
|
45
51
|
].join('\n')
|
|
46
52
|
);
|
|
47
53
|
process.exit(command ? 0 : 1);
|
package/dist/{createActor-551369be.development.esm.js → createActor-0250284a.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;
|
|
@@ -2201,6 +2201,18 @@ function withSystemInspector(inspect, fn) {
|
|
|
2201
2201
|
|
|
2202
2202
|
/** Snapshot-scoped actor identity and system view. @internal */
|
|
2203
2203
|
|
|
2204
|
+
// Each view's execution system and whether it forwards inspection. Views
|
|
2205
|
+
// never chain: they all inherit from the execution system directly.
|
|
2206
|
+
const snapshotSystemViews = new WeakMap();
|
|
2207
|
+
// Facilities owned by the execution rather than by one snapshot's view. A view
|
|
2208
|
+
// reads and writes them on the execution system, so timers, listeners and the
|
|
2209
|
+
// runtime installed through any snapshot are visible through every other.
|
|
2210
|
+
const executionFacilities = ['runtime', '_timerMap', '_rejectionListeners', '_inspectionObservers', '_emissionListeners'];
|
|
2211
|
+
// The durable execution that owns each execution system.
|
|
2212
|
+
/** A durable execution, as the owner of the views its transitions create. @internal */
|
|
2213
|
+
|
|
2214
|
+
const executionOwners = new WeakMap();
|
|
2215
|
+
let ambientExecutionOwner;
|
|
2204
2216
|
const snapshotActorRefs = new WeakMap();
|
|
2205
2217
|
const lazySnapshotActorRefs = new WeakMap();
|
|
2206
2218
|
const emptyKeyedActors = new Map();
|
|
@@ -2260,12 +2272,22 @@ function getSnapshotChildren(snapshot) {
|
|
|
2260
2272
|
*
|
|
2261
2273
|
* @internal
|
|
2262
2274
|
*/
|
|
2263
|
-
function createSnapshotSystem(baseSystem, children, baseState) {
|
|
2264
|
-
const
|
|
2275
|
+
function createSnapshotSystem(baseSystem, children, baseState, owner) {
|
|
2276
|
+
const baseView = snapshotSystemViews.get(baseSystem);
|
|
2277
|
+
const baseExecutionSystem = baseView?.executionSystem ?? baseSystem;
|
|
2278
|
+
// The runtime system under every view. A view runs its methods against the
|
|
2279
|
+
// execution system's facilities.
|
|
2280
|
+
const rootSystem = baseView?.rootSystem ?? baseSystem;
|
|
2281
|
+
const forks = owner !== undefined && executionOwners.get(baseExecutionSystem) !== owner;
|
|
2282
|
+
// A view an execution owns reports to that execution's inspector.
|
|
2283
|
+
const forwardInspection = owner ? !!owner.inspect : hasAmbientInspector() && (baseView?.forwardInspection ?? true);
|
|
2265
2284
|
const registeredActors = copyRegisteredActors(baseSystem, baseState);
|
|
2266
2285
|
const keyedActors = new Map(baseState?.keyedActors ?? getKeyedActors(baseSystem));
|
|
2267
2286
|
const reverseKeyedActors = new WeakMap();
|
|
2268
|
-
|
|
2287
|
+
// The view's execution system; adoption can make the view its own.
|
|
2288
|
+
const execution = () => snapshotSystemViews.get(system).executionSystem;
|
|
2289
|
+
const forwards = () => snapshotSystemViews.get(system).forwardInspection;
|
|
2290
|
+
const system = Object.assign(Object.create(baseExecutionSystem), {
|
|
2269
2291
|
children: registeredActors,
|
|
2270
2292
|
keyedActors,
|
|
2271
2293
|
reverseKeyedActors,
|
|
@@ -2300,15 +2322,38 @@ function createSnapshotSystem(baseSystem, children, baseState) {
|
|
|
2300
2322
|
},
|
|
2301
2323
|
get: registryKey => keyedActors.get(registryKey),
|
|
2302
2324
|
getAll: () => Object.fromEntries(keyedActors),
|
|
2303
|
-
onEmitted: listener =>
|
|
2304
|
-
_notifyEmitted: (actorRef, event) =>
|
|
2325
|
+
onEmitted: listener => rootSystem.onEmitted.call(execution(), listener),
|
|
2326
|
+
_notifyEmitted: (actorRef, event) => rootSystem._notifyEmitted.call(execution(), actorRef, event),
|
|
2305
2327
|
// Pure transition resolution must not leak topology inspection events
|
|
2306
2328
|
// into a live runtime system — planning branches stay silent. The one
|
|
2307
2329
|
// exception is a durable execution's own transitions (marked by the
|
|
2308
2330
|
// ambient inspector at creation time): there the pure path IS the
|
|
2309
|
-
// execution, so inspection forwards to the
|
|
2310
|
-
_hasInspectionObservers:
|
|
2311
|
-
_sendInspectionEvent:
|
|
2331
|
+
// execution, so inspection forwards to the execution system's observers.
|
|
2332
|
+
_hasInspectionObservers: () => forwards() && (rootSystem._hasInspectionObservers?.call(execution()) ?? false),
|
|
2333
|
+
_sendInspectionEvent: event => {
|
|
2334
|
+
if (forwards()) {
|
|
2335
|
+
rootSystem._sendInspectionEvent.call(execution(), event);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
});
|
|
2339
|
+
const executionSystem = forks ? system : baseExecutionSystem;
|
|
2340
|
+
if (forks) {
|
|
2341
|
+
forkFacilities(system, baseExecutionSystem, owner);
|
|
2342
|
+
} else {
|
|
2343
|
+
for (const key of executionFacilities) {
|
|
2344
|
+
Object.defineProperty(system, key, {
|
|
2345
|
+
configurable: true,
|
|
2346
|
+
get: () => execution()[key],
|
|
2347
|
+
set: value => {
|
|
2348
|
+
execution()[key] = value;
|
|
2349
|
+
}
|
|
2350
|
+
});
|
|
2351
|
+
}
|
|
2352
|
+
}
|
|
2353
|
+
snapshotSystemViews.set(system, {
|
|
2354
|
+
executionSystem,
|
|
2355
|
+
rootSystem,
|
|
2356
|
+
forwardInspection
|
|
2312
2357
|
});
|
|
2313
2358
|
for (const [registryKey, actor] of keyedActors) {
|
|
2314
2359
|
if (!actor) {
|
|
@@ -2332,6 +2377,83 @@ function createSnapshotSystem(baseSystem, children, baseState) {
|
|
|
2332
2377
|
return system;
|
|
2333
2378
|
}
|
|
2334
2379
|
|
|
2380
|
+
/**
|
|
2381
|
+
* Makes `system` the execution system of `owner`, a new incarnation: it gets
|
|
2382
|
+
* the owner's runtime and the pending timers it saw, and starts with no
|
|
2383
|
+
* listeners or inspectors, so nothing registered on another execution
|
|
2384
|
+
* observes it.
|
|
2385
|
+
*/
|
|
2386
|
+
function forkFacilities(system, from, owner) {
|
|
2387
|
+
const timers = from._timerMap;
|
|
2388
|
+
for (const key of executionFacilities) {
|
|
2389
|
+
Object.defineProperty(system, key, {
|
|
2390
|
+
configurable: true,
|
|
2391
|
+
writable: true,
|
|
2392
|
+
value: key === 'runtime' ? owner.runtime : key === '_timerMap' && timers ? {
|
|
2393
|
+
...timers
|
|
2394
|
+
} : undefined
|
|
2395
|
+
});
|
|
2396
|
+
}
|
|
2397
|
+
executionOwners.set(system, owner);
|
|
2398
|
+
if (owner.inspect) {
|
|
2399
|
+
system.inspect(owner.inspect);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
/**
|
|
2404
|
+
* Makes `owner` own `system` before it installs its runtime there, and
|
|
2405
|
+
* returns whether it does. An unowned view forks in place, so the install
|
|
2406
|
+
* never reaches the system it was derived from. A system another execution
|
|
2407
|
+
* owns is left alone.
|
|
2408
|
+
*
|
|
2409
|
+
* @internal
|
|
2410
|
+
*/
|
|
2411
|
+
function adoptSystem(system, owner) {
|
|
2412
|
+
const view = snapshotSystemViews.get(system);
|
|
2413
|
+
const current = executionOwners.get(view?.executionSystem ?? system);
|
|
2414
|
+
if (current === owner) {
|
|
2415
|
+
if (view) {
|
|
2416
|
+
view.forwardInspection = !!owner.inspect;
|
|
2417
|
+
}
|
|
2418
|
+
return true;
|
|
2419
|
+
}
|
|
2420
|
+
// A system another execution owns stays with it.
|
|
2421
|
+
if (current) {
|
|
2422
|
+
return false;
|
|
2423
|
+
}
|
|
2424
|
+
if (!view) {
|
|
2425
|
+
executionOwners.set(system, owner);
|
|
2426
|
+
return true;
|
|
2427
|
+
}
|
|
2428
|
+
forkFacilities(system, view.executionSystem, owner);
|
|
2429
|
+
view.executionSystem = system;
|
|
2430
|
+
view.forwardInspection = !!owner.inspect;
|
|
2431
|
+
return true;
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
/**
|
|
2435
|
+
* Runs `fn` as a transition of `owner`. A view it derives from a system the
|
|
2436
|
+
* owner does not own forks into the owner's own execution system.
|
|
2437
|
+
*
|
|
2438
|
+
* @internal
|
|
2439
|
+
*/
|
|
2440
|
+
function withExecutionOwner(owner, fn) {
|
|
2441
|
+
const previous = ambientExecutionOwner;
|
|
2442
|
+
ambientExecutionOwner = owner;
|
|
2443
|
+
try {
|
|
2444
|
+
return fn();
|
|
2445
|
+
} finally {
|
|
2446
|
+
ambientExecutionOwner = previous;
|
|
2447
|
+
}
|
|
2448
|
+
}
|
|
2449
|
+
|
|
2450
|
+
/** Hands the ambient owner to the first scope that asks for it. @internal */
|
|
2451
|
+
function takeExecutionOwner() {
|
|
2452
|
+
const owner = ambientExecutionOwner;
|
|
2453
|
+
ambientExecutionOwner = undefined;
|
|
2454
|
+
return owner;
|
|
2455
|
+
}
|
|
2456
|
+
|
|
2335
2457
|
/** Returns the actor identity associated with a transition snapshot. @internal */
|
|
2336
2458
|
function getSnapshotActorRef(snapshot) {
|
|
2337
2459
|
const existing = snapshotActorRefs.get(snapshot);
|
|
@@ -2525,8 +2647,9 @@ function setInertActorScopeSnapshot(actorScope, snapshot, attachActorRef = true)
|
|
|
2525
2647
|
const lazyState = getLazyInertActorState(actorScope);
|
|
2526
2648
|
if (lazyState) {
|
|
2527
2649
|
lazyState.snapshot = snapshot;
|
|
2528
|
-
|
|
2529
|
-
|
|
2650
|
+
const scope = lazyState.materialized ?? lazyState.identityScope;
|
|
2651
|
+
if (scope) {
|
|
2652
|
+
scope.self._snapshot = snapshot;
|
|
2530
2653
|
}
|
|
2531
2654
|
} else {
|
|
2532
2655
|
actorScope.self._snapshot = snapshot;
|
|
@@ -2561,6 +2684,15 @@ function attachSnapshotActorRef(actorScope, snapshot) {
|
|
|
2561
2684
|
setLazySnapshotActorRef(snapshot, create);
|
|
2562
2685
|
return snapshot;
|
|
2563
2686
|
}
|
|
2687
|
+
/** Records the materialized scope and releases its consumed source. */
|
|
2688
|
+
function commitMaterialization(state, scope) {
|
|
2689
|
+
// Dropping the consumed source keeps this scope from retaining earlier snapshots.
|
|
2690
|
+
state.sourceRef = undefined;
|
|
2691
|
+
state.sourceChildren = {};
|
|
2692
|
+
state.materialized = scope;
|
|
2693
|
+
state.materialize = () => scope;
|
|
2694
|
+
return scope;
|
|
2695
|
+
}
|
|
2564
2696
|
const lazyInertActorState = Symbol();
|
|
2565
2697
|
const snapshotActorScopes = new WeakMap();
|
|
2566
2698
|
let inertActorMaterializationObserver;
|
|
@@ -2605,12 +2737,14 @@ const lazyInertActorScopePrototype = {
|
|
|
2605
2737
|
return materializeInertActorScope(this).actionExecutor;
|
|
2606
2738
|
}
|
|
2607
2739
|
};
|
|
2608
|
-
|
|
2740
|
+
|
|
2741
|
+
/** Creates a transactional planning scope backed by an inert actor. */
|
|
2742
|
+
function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren, currentSnapshot, sourceSelf, owner) {
|
|
2609
2743
|
inertActorMaterializationObserver?.();
|
|
2610
2744
|
const snapshotRef = sourceRef?.();
|
|
2611
2745
|
const previousSelf = sourceSelf ?? snapshotRef?.actor;
|
|
2612
2746
|
const baseSystem = previousSelf?.system;
|
|
2613
|
-
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, sourceChildren, sourceSelf ? undefined : snapshotRef?.systemState) : undefined;
|
|
2747
|
+
const system = previousSelf && baseSystem ? createSnapshotSystem(baseSystem, sourceChildren, sourceSelf ? undefined : snapshotRef?.systemState, owner) : undefined;
|
|
2614
2748
|
const self = createActor(actorLogic, {
|
|
2615
2749
|
_inert: true,
|
|
2616
2750
|
...(previousSelf ? {
|
|
@@ -2630,12 +2764,8 @@ function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren
|
|
|
2630
2764
|
// a future construction-time read cannot pin a root-shaped address.
|
|
2631
2765
|
self._address = undefined;
|
|
2632
2766
|
}
|
|
2633
|
-
if (currentSnapshot) {
|
|
2634
|
-
self._snapshot = currentSnapshot;
|
|
2635
|
-
}
|
|
2636
|
-
|
|
2637
2767
|
// Reuse the branch actor's scope while keeping planning transactional.
|
|
2638
|
-
|
|
2768
|
+
const scope = Object.create(self._actorScope, {
|
|
2639
2769
|
defer: {
|
|
2640
2770
|
value: () => {}
|
|
2641
2771
|
},
|
|
@@ -2644,8 +2774,20 @@ function createMaterializedInertActorScope(actorLogic, sourceRef, sourceChildren
|
|
|
2644
2774
|
},
|
|
2645
2775
|
actionExecutor: {
|
|
2646
2776
|
value: () => {}
|
|
2777
|
+
},
|
|
2778
|
+
_snapshot: {
|
|
2779
|
+
enumerable: true,
|
|
2780
|
+
configurable: true,
|
|
2781
|
+
get: () => self._snapshot,
|
|
2782
|
+
set: snapshot => {
|
|
2783
|
+
self._snapshot = snapshot;
|
|
2784
|
+
}
|
|
2647
2785
|
}
|
|
2648
2786
|
});
|
|
2787
|
+
if (currentSnapshot) {
|
|
2788
|
+
scope._snapshot = currentSnapshot;
|
|
2789
|
+
}
|
|
2790
|
+
return scope;
|
|
2649
2791
|
}
|
|
2650
2792
|
|
|
2651
2793
|
/** @internal */
|
|
@@ -2660,22 +2802,34 @@ function createInertActorScope(actorLogic, snapshot, sourceSelf, sourceActorScop
|
|
|
2660
2802
|
sourceChildren: isMachineSnapshot(snapshot) ? snapshot.children : {},
|
|
2661
2803
|
identityProvider: sourceState?.identityProvider ?? sourceRef,
|
|
2662
2804
|
parent: sourceSelf?._parent ?? sourceState?.parent ?? eagerSourceRef?.actor._parent,
|
|
2805
|
+
// Only the outermost scope of an owned transition belongs to the owner;
|
|
2806
|
+
// scopes for its intermediate snapshots inherit it, and nested pure
|
|
2807
|
+
// transitions run unowned.
|
|
2808
|
+
owner: sourceActorScope ? sourceState?.owner : takeExecutionOwner(),
|
|
2663
2809
|
parentKnown: !!sourceSelf || !!sourceState?.parentKnown || !!eagerSourceRef || !snapshot
|
|
2664
2810
|
};
|
|
2665
|
-
state.materialize = () =>
|
|
2811
|
+
state.materialize = () => {
|
|
2812
|
+
const scope = createMaterializedInertActorScope(actorLogic, state.sourceRef, state.sourceChildren, state.snapshot, sourceSelf, state.owner);
|
|
2813
|
+
return commitMaterialization(state, scope);
|
|
2814
|
+
};
|
|
2666
2815
|
if (!state.identityProvider && !snapshot) {
|
|
2667
2816
|
const identitySnapshot = {};
|
|
2668
|
-
const identitySourceRef = state.sourceRef;
|
|
2669
|
-
const identitySourceChildren = state.sourceChildren;
|
|
2670
|
-
let identityScope;
|
|
2671
2817
|
let identityRef;
|
|
2672
|
-
const getIdentityScope = () =>
|
|
2818
|
+
const getIdentityScope = () => {
|
|
2819
|
+
if (!state.identityScope) {
|
|
2820
|
+
state.identityScope = createMaterializedInertActorScope(actorLogic, state.sourceRef, state.sourceChildren, undefined, sourceSelf, state.owner);
|
|
2821
|
+
if (state.snapshot !== undefined) {
|
|
2822
|
+
state.identityScope.self._snapshot = state.snapshot;
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
return state.identityScope;
|
|
2826
|
+
};
|
|
2673
2827
|
state.materialize = () => {
|
|
2674
2828
|
const scope = getIdentityScope();
|
|
2675
2829
|
if (state.snapshot !== undefined) {
|
|
2676
2830
|
scope.self._snapshot = state.snapshot;
|
|
2677
2831
|
}
|
|
2678
|
-
return state
|
|
2832
|
+
return commitMaterialization(state, scope);
|
|
2679
2833
|
};
|
|
2680
2834
|
state.identityProvider = () => {
|
|
2681
2835
|
if (identityRef) {
|
|
@@ -4659,7 +4813,7 @@ function findNonJsonPath(value, path) {
|
|
|
4659
4813
|
};
|
|
4660
4814
|
}
|
|
4661
4815
|
if ('sessionId' in current && 'send' in current && 'ref' in current) {
|
|
4662
|
-
// Actor refs persist as `{
|
|
4816
|
+
// Actor refs persist as `{ "@actor": address }`.
|
|
4663
4817
|
return undefined;
|
|
4664
4818
|
}
|
|
4665
4819
|
if (ancestors.has(current)) {
|
|
@@ -4782,6 +4936,8 @@ const machineSnapshotToJSON = function toJSON() {
|
|
|
4782
4936
|
const {
|
|
4783
4937
|
nodes,
|
|
4784
4938
|
_stateInputs,
|
|
4939
|
+
_nextTimerId,
|
|
4940
|
+
_nextActorIds,
|
|
4785
4941
|
tags,
|
|
4786
4942
|
machine,
|
|
4787
4943
|
getMeta,
|
|
@@ -4906,6 +5062,8 @@ function getPersistedSnapshot(snapshot, options) {
|
|
|
4906
5062
|
const {
|
|
4907
5063
|
nodes,
|
|
4908
5064
|
_stateInputs,
|
|
5065
|
+
_nextTimerId,
|
|
5066
|
+
_nextActorIds,
|
|
4909
5067
|
tags,
|
|
4910
5068
|
machine,
|
|
4911
5069
|
children,
|
|
@@ -5041,6 +5199,11 @@ function getPersistedSnapshot(snapshot, options) {
|
|
|
5041
5199
|
if (_stateInputs && Object.keys(_stateInputs).length > 0) {
|
|
5042
5200
|
persisted.stateInputs = _stateInputs;
|
|
5043
5201
|
}
|
|
5202
|
+
// Stores such as Convex reject `_`-prefixed field names.
|
|
5203
|
+
persisted.nextTimerId = _nextTimerId;
|
|
5204
|
+
if (_nextActorIds && Object.keys(_nextActorIds).length > 0) {
|
|
5205
|
+
persisted.nextActorIds = _nextActorIds;
|
|
5206
|
+
}
|
|
5044
5207
|
if (machine.version !== undefined) {
|
|
5045
5208
|
persisted.machine = {
|
|
5046
5209
|
id: machine.id,
|
|
@@ -5072,7 +5235,7 @@ function persistContext(contextPart, getActorId, path = 'context', ancestors = [
|
|
|
5072
5235
|
};
|
|
5073
5236
|
// The address lets refs to non-children still route after restore.
|
|
5074
5237
|
copy[key] = {
|
|
5075
|
-
|
|
5238
|
+
'@actor': value.address
|
|
5076
5239
|
};
|
|
5077
5240
|
} else {
|
|
5078
5241
|
const valuePath = Array.isArray(contextPart) ? `${path}[${key}]` : `${path}.${key}`;
|
|
@@ -5714,11 +5877,18 @@ class RuntimeSystem {
|
|
|
5714
5877
|
// Records a send on the *sender's* transition for the `sent[]` inspection
|
|
5715
5878
|
// facet. Captures the send when it is initiated (including delayed sends that
|
|
5716
5879
|
// may never deliver), keyed to the source actor's in-flight transition.
|
|
5880
|
+
// A send made with no transition in flight (a callback's `sendBack`, a value
|
|
5881
|
+
// an observable relays to its parent) is not recorded: no transition reports
|
|
5882
|
+
// it, so it would be held until the source's next transition, or for as long
|
|
5883
|
+
// as the source lives if it never makes one.
|
|
5717
5884
|
_recordSent(source, target, event, delay, id) {
|
|
5718
5885
|
if (!this._inspectionObservers?.size || !source) {
|
|
5719
5886
|
return;
|
|
5720
5887
|
}
|
|
5721
5888
|
const inspectionSource = source;
|
|
5889
|
+
if (!inspectionSource._inTransition) {
|
|
5890
|
+
return;
|
|
5891
|
+
}
|
|
5722
5892
|
const collected = inspectionSource._collectedSent ??= [];
|
|
5723
5893
|
collected.push({
|
|
5724
5894
|
targetRef: target,
|
|
@@ -5955,9 +6125,9 @@ class RuntimeSystem {
|
|
|
5955
6125
|
} else if (
|
|
5956
6126
|
// A live actor of another incarnation is stale locally; an
|
|
5957
6127
|
// address this system cannot see may belong to a host runtime.
|
|
5958
|
-
this._getByAddress(target
|
|
6128
|
+
this._getByAddress(target['@actor']) || !this.runtime?.sendEvent) {
|
|
5959
6129
|
return this.deadLetter(source, undefined, event, 'missingTarget', {
|
|
5960
|
-
targetId: getAddressId(target
|
|
6130
|
+
targetId: getAddressId(target['@actor']),
|
|
5961
6131
|
error: createMissingAddressError(target)
|
|
5962
6132
|
});
|
|
5963
6133
|
}
|
|
@@ -6244,6 +6414,12 @@ class Actor {
|
|
|
6244
6414
|
this._collectedActions = void 0;
|
|
6245
6415
|
/** @internal Events relayed to other actors during the in-flight transition. */
|
|
6246
6416
|
this._collectedSent = void 0;
|
|
6417
|
+
/**
|
|
6418
|
+
* @internal Whether a transition is in flight: while the actor starts,
|
|
6419
|
+
* processes an event, or recovers from an execution error. Sends are recorded
|
|
6420
|
+
* for `sent[]` only then.
|
|
6421
|
+
*/
|
|
6422
|
+
this._inTransition = false;
|
|
6247
6423
|
this._initialEffects = void 0;
|
|
6248
6424
|
this.registryKey = void 0;
|
|
6249
6425
|
/** The globally unique process ID for this invocation. */
|
|
@@ -6316,9 +6492,14 @@ class Actor {
|
|
|
6316
6492
|
// transition functions; computing an initial snapshot here would run
|
|
6317
6493
|
// init-time side effects (context factories, entry) a second time.
|
|
6318
6494
|
} else {
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6495
|
+
this._inTransition = true;
|
|
6496
|
+
try {
|
|
6497
|
+
const [snapshot, effects] = finalizeTransitionResult(this._actorScope, undefined, this.logic.initialTransition(this.options?.input, this._actorScope));
|
|
6498
|
+
this._setSnapshot(snapshot);
|
|
6499
|
+
this._initialEffects = effects.length ? effects : undefined;
|
|
6500
|
+
} finally {
|
|
6501
|
+
this._inTransition = false;
|
|
6502
|
+
}
|
|
6322
6503
|
}
|
|
6323
6504
|
} catch (err) {
|
|
6324
6505
|
// Restored logic may keep its snapshot shape on restore failures (e.g.
|
|
@@ -6471,6 +6652,8 @@ class Actor {
|
|
|
6471
6652
|
if (!errorEvent) {
|
|
6472
6653
|
return false;
|
|
6473
6654
|
}
|
|
6655
|
+
const inTransition = this._inTransition;
|
|
6656
|
+
this._inTransition = true;
|
|
6474
6657
|
try {
|
|
6475
6658
|
const [nextSnapshot, effects] = finalizeTransitionResult(this._actorScope, snapshot, this.logic.transition(snapshot, errorEvent, this._actorScope));
|
|
6476
6659
|
this._setSnapshot(nextSnapshot);
|
|
@@ -6479,6 +6662,8 @@ class Actor {
|
|
|
6479
6662
|
return true;
|
|
6480
6663
|
} catch {
|
|
6481
6664
|
return false;
|
|
6665
|
+
} finally {
|
|
6666
|
+
this._inTransition = inTransition;
|
|
6482
6667
|
}
|
|
6483
6668
|
}
|
|
6484
6669
|
_next(snapshot) {
|
|
@@ -6690,6 +6875,15 @@ class Actor {
|
|
|
6690
6875
|
|
|
6691
6876
|
/** Starts the Actor from the initial state */
|
|
6692
6877
|
start() {
|
|
6878
|
+
const inTransition = this._inTransition;
|
|
6879
|
+
this._inTransition = true;
|
|
6880
|
+
try {
|
|
6881
|
+
return this._start();
|
|
6882
|
+
} finally {
|
|
6883
|
+
this._inTransition = inTransition;
|
|
6884
|
+
}
|
|
6885
|
+
}
|
|
6886
|
+
_start() {
|
|
6693
6887
|
if (this._processingStatus === ProcessingStatus.Running) {
|
|
6694
6888
|
// Do not restart the service if it is already started
|
|
6695
6889
|
return this;
|
|
@@ -6805,7 +6999,16 @@ class Actor {
|
|
|
6805
6999
|
this.mailbox?.start();
|
|
6806
7000
|
return this;
|
|
6807
7001
|
}
|
|
6808
|
-
_process({
|
|
7002
|
+
_process(item) {
|
|
7003
|
+
const inTransition = this._inTransition;
|
|
7004
|
+
this._inTransition = true;
|
|
7005
|
+
try {
|
|
7006
|
+
this._processEvent(item);
|
|
7007
|
+
} finally {
|
|
7008
|
+
this._inTransition = inTransition;
|
|
7009
|
+
}
|
|
7010
|
+
}
|
|
7011
|
+
_processEvent({
|
|
6809
7012
|
event,
|
|
6810
7013
|
sourceRef
|
|
6811
7014
|
}) {
|
|
@@ -7053,12 +7256,12 @@ class Actor {
|
|
|
7053
7256
|
}
|
|
7054
7257
|
|
|
7055
7258
|
/**
|
|
7056
|
-
* Returns the actor's serializable logical identity: `{
|
|
7259
|
+
* Returns the actor's serializable logical identity: `{ "@actor": address }`.
|
|
7057
7260
|
* The result can be used as an `enq.sendTo(...)` target.
|
|
7058
7261
|
*/
|
|
7059
7262
|
toJSON() {
|
|
7060
7263
|
return {
|
|
7061
|
-
|
|
7264
|
+
'@actor': this.address
|
|
7062
7265
|
};
|
|
7063
7266
|
}
|
|
7064
7267
|
|
|
@@ -7172,4 +7375,4 @@ function createActor(logic, ...[options]) {
|
|
|
7172
7375
|
return new Actor(logic, options);
|
|
7173
7376
|
}
|
|
7174
7377
|
|
|
7175
|
-
export { allocateChildId as $, listenerLogic as A, subscriptionLogic as B, createListenerLogic as C, createSubscriptionLogic as D, Actor as E, matchesState as F, toObserver as G, executeEffects as H, InfiniteTransitionError as I, isBuiltInExecutableEffect as J, deliverEvent as K, runStep as L, stopActor as M, terminateActor as N, createInitEvent as O, ProcessingStatus as P, createDeadLetterEffect as Q, createCustomEffect as R, XSTATE_LOGIC_EFFECT_START as S, XSTATE_LOGIC_EFFECT_RESOLVE as T, XSTATE_LOGIC_EFFECT_REJECT as U, createEmitEffect as V, createSendToEffect as W, XSTATE_STOP_EFFECT as X, XSTATE_INIT as Y, publishEmittedEvent as Z, resolveRegisteredActorSource as _, assertUnreservedSourceName as a, assertChildIdFree as a0, reserveChildId as a1, hasUnescapedDot as a2, STATE_DELIMITER as a3, mapValues as a4, createInvokeId as a5, getDelayedTransitions as a6, getCandidates as a7, evaluateCandidate as a8, formatTransition as a9, initialMicrostep as aA, createStartEffect as aB, isStateId as aC, getPersistedSnapshot as aD, detachedScopes as aE, toStatePath as aF, hasAmbientInspector as aG, getProperAncestors as aH, isRemoteActorRef as aI, getAllOwnEvents as aJ, matchesEvent as aK, getRootActorId as aL, RUNTIME_OPERATIONS as aM,
|
|
7378
|
+
export { allocateChildId as $, listenerLogic as A, subscriptionLogic as B, createListenerLogic as C, createSubscriptionLogic as D, Actor as E, matchesState as F, toObserver as G, executeEffects as H, InfiniteTransitionError as I, isBuiltInExecutableEffect as J, deliverEvent as K, runStep as L, stopActor as M, terminateActor as N, createInitEvent as O, ProcessingStatus as P, createDeadLetterEffect as Q, createCustomEffect as R, XSTATE_LOGIC_EFFECT_START as S, XSTATE_LOGIC_EFFECT_RESOLVE as T, XSTATE_LOGIC_EFFECT_REJECT as U, createEmitEffect as V, createSendToEffect as W, XSTATE_STOP_EFFECT as X, XSTATE_INIT as Y, publishEmittedEvent as Z, resolveRegisteredActorSource as _, assertUnreservedSourceName as a, assertChildIdFree as a0, reserveChildId as a1, hasUnescapedDot as a2, STATE_DELIMITER as a3, mapValues as a4, createInvokeId as a5, getDelayedTransitions as a6, getCandidates as a7, evaluateCandidate as a8, formatTransition as a9, initialMicrostep as aA, createStartEffect as aB, isStateId as aC, getPersistedSnapshot as aD, detachedScopes as aE, toStatePath as aF, hasAmbientInspector as aG, getProperAncestors as aH, isRemoteActorRef as aI, getAllOwnEvents as aJ, matchesEvent as aK, getRootActorId as aL, RUNTIME_OPERATIONS as aM, createTimerEffect as aN, getSnapshotActorRef as aO, withExecutionOwner as aP, getTimerStart as aQ, recordTimerStart as aR, withSystemInspector as aS, adoptSystem as aT, withExecutionIdentity as aU, diagnoseActorOptions as aV, createRemoteActorRef as aW, createInvokeTimeoutEvent as aX, parseGeneratedActorId as aY, NULL_EVENT as aa, toTransitionConfigArray as ab, matchesActorSession as ac, describeMachine as ad, formatRouteTransitions as ae, resolveStateValue as af, isInFinalState as ag, createInertActorScope as ah, setInertActorScopeSnapshot as ai, beginSpawnAllocation as aj, attachSnapshotActorRef as ak, macrostep as al, isInertActorScope as am, setSnapshotActorRef as an, cloneMachineSnapshot as ao, transitionNode as ap, XSTATE_TIMER as aq, getTransitionResult as ar, hasEffect as as, createErrorPlatformEvent as at, withActorSelf as au, resolveActionsWithContext as av, freezeContext as aw, takeSpawnAllocationCounters as ax, mergeActorIdCounters as ay, createSpawnEffect 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 as u, createDoneActorEvent as v, createErrorActorEvent as w, serializeTimerKey as x, matchesTimerKey as y, isMachineSnapshot as z };
|