xstate 6.0.0-beta.1 → 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/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 +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-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/api-stability.json +267 -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 +17 -17
- package/package.json +1 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createAsyncLogic, TimeoutError } from './xstate-actors.development.esm.js';
|
|
2
2
|
export { TimeoutError, createAsyncLogic, createCallbackLogic, createEmptyActor, createEventObservableLogic, createObservableLogic, createStepLogic } from './xstate-actors.development.esm.js';
|
|
3
|
-
import { m as matchesEventDescriptor, t as toArray, d as diagnoseAuthorConfig, p as parseDelayToMilliseconds, a as assertUnreservedSourceName, i as isAtomicStateNode, P as ProcessingStatus, g as getAllStateNodes, b as getStateNodes, r as resolveInvokedActorLogic, c as isActorRefLike, e as createMachineSnapshot, f as diagnoseSetupConfig, h as createActor, j as encodeAddressSegment, s as systemLogicMetadata, k as getActorIdPrefix, l as finalizeTransitionResult, n as getTimerKey, o as isSerializedActorRef, q as readTimerKey, X as XSTATE_STOP_EFFECT, u as XSTATE_STOP, v as createDoneActorEvent, w as createErrorActorEvent, x as serializeTimerKey, y as matchesTimerKey, z as isMachineSnapshot, A as listenerLogic, B as subscriptionLogic } from './createActor-
|
|
4
|
-
export { E as Actor, I as InfiniteTransitionError, p as _parseDelayToMilliseconds, G as _toObserver, h as createActor, C as createListenerLogic, D as createSubscriptionLogic, K as deliverEvent, H as executeEffects, b as getStateNodes, J as isBuiltInExecutableEffect, z as isMachineSnapshot, F as matchesState, L as runStep, M as stopActor, N as terminateActor } from './createActor-
|
|
5
|
-
import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema } from './
|
|
6
|
-
export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './
|
|
3
|
+
import { m as matchesEventDescriptor, t as toArray, d as diagnoseAuthorConfig, p as parseDelayToMilliseconds, a as assertUnreservedSourceName, i as isAtomicStateNode, P as ProcessingStatus, g as getAllStateNodes, b as getStateNodes, r as resolveInvokedActorLogic, c as isActorRefLike, e as createMachineSnapshot, f as diagnoseSetupConfig, h as createActor, j as encodeAddressSegment, s as systemLogicMetadata, k as getActorIdPrefix, l as finalizeTransitionResult, n as getTimerKey, o as isSerializedActorRef, q as readTimerKey, X as XSTATE_STOP_EFFECT, u as XSTATE_STOP, v as createDoneActorEvent, w as createErrorActorEvent, x as serializeTimerKey, y as matchesTimerKey, z as isMachineSnapshot, A as listenerLogic, B as subscriptionLogic } from './createActor-0250284a.development.esm.js';
|
|
4
|
+
export { E as Actor, I as InfiniteTransitionError, p as _parseDelayToMilliseconds, G as _toObserver, h as createActor, C as createListenerLogic, D as createSubscriptionLogic, K as deliverEvent, H as executeEffects, b as getStateNodes, J as isBuiltInExecutableEffect, z as isMachineSnapshot, F as matchesState, L as runStep, M as stopActor, N as terminateActor } from './createActor-0250284a.development.esm.js';
|
|
5
|
+
import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema, u as upgradeLegacySystemSnapshot } from './legacySnapshot-ae6594a7.development.esm.js';
|
|
6
|
+
export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './legacySnapshot-ae6594a7.development.esm.js';
|
|
7
7
|
export { i as isTypeSchema, t as types } from './schema.types-1cd4652e.development.esm.js';
|
|
8
|
-
export { d as describeExecutableEffect, b as getInitialMicrosteps, g as getMicrosteps, c as getNextTransitions, a as initialTransition, i as isUnhandled, t as transition } from './effectDescriptor-
|
|
8
|
+
export { d as describeExecutableEffect, b as getInitialMicrosteps, g as getMicrosteps, c as getNextTransitions, a as initialTransition, i as isUnhandled, t as transition } from './effectDescriptor-5ac7dccb.development.esm.js';
|
|
9
9
|
import './validation-e69470ad.development.esm.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -2110,13 +2110,13 @@ class SimulatedClock {
|
|
|
2110
2110
|
// logical timer key (or, for a directly delivered event, the event type).
|
|
2111
2111
|
function systemTimerKey(source, event) {
|
|
2112
2112
|
const key = event.type === 'xstate.timer' ? readTimerKey(event) : undefined;
|
|
2113
|
-
return JSON.stringify([source
|
|
2113
|
+
return JSON.stringify([source['@actor'], source.incarnation, key ? serializeTimerKey(key) : event.type]);
|
|
2114
2114
|
}
|
|
2115
2115
|
function isLogicalTimerPending(snapshot, key) {
|
|
2116
2116
|
return (snapshot.timers ?? []).some(timer => matchesTimerKey(timer, key));
|
|
2117
2117
|
}
|
|
2118
2118
|
function isReference(value) {
|
|
2119
|
-
return !!value && typeof value
|
|
2119
|
+
return !!value && typeof value['@actor'] === 'string' && typeof value.incarnation === 'string';
|
|
2120
2120
|
}
|
|
2121
2121
|
function isHandle(value) {
|
|
2122
2122
|
return !!value && typeof value.address === 'string' && typeof value.getSnapshot === 'function';
|
|
@@ -2127,12 +2127,12 @@ const systemLogger = () => {};
|
|
|
2127
2127
|
/** Converts runtime-shaped, reduction-local capabilities to snapshot data. */
|
|
2128
2128
|
function encode(value, seen = new Set(), mappers) {
|
|
2129
2129
|
if (typeof value === 'function' && mappers?.has(value)) return {
|
|
2130
|
-
|
|
2130
|
+
'@systemMapper': mappers.get(value)
|
|
2131
2131
|
};
|
|
2132
2132
|
if (isHandle(value)) {
|
|
2133
2133
|
if (!value[systemActorHandle]) throw new Error('Live actors cannot be stored in a pure system snapshot.');
|
|
2134
2134
|
return {
|
|
2135
|
-
|
|
2135
|
+
'@actor': value.address,
|
|
2136
2136
|
incarnation: value.sessionId
|
|
2137
2137
|
};
|
|
2138
2138
|
}
|
|
@@ -2145,11 +2145,11 @@ function encode(value, seen = new Set(), mappers) {
|
|
|
2145
2145
|
let result;
|
|
2146
2146
|
if (value.machine && typeof value.machine.transition === 'function' && typeof value.id === 'string' && Array.isArray(value.path)) {
|
|
2147
2147
|
result = {
|
|
2148
|
-
|
|
2148
|
+
'@stateNode': value.id
|
|
2149
2149
|
};
|
|
2150
2150
|
} else if (value instanceof Error) {
|
|
2151
2151
|
result = {
|
|
2152
|
-
|
|
2152
|
+
'@error': value.name,
|
|
2153
2153
|
message: value.message
|
|
2154
2154
|
};
|
|
2155
2155
|
} else if (Array.isArray(value)) {
|
|
@@ -2175,10 +2175,17 @@ function snapshotData(snapshot, mappers) {
|
|
|
2175
2175
|
getMeta,
|
|
2176
2176
|
getInputs,
|
|
2177
2177
|
toJSON,
|
|
2178
|
+
// Stores such as Convex reject `_`-prefixed field names.
|
|
2179
|
+
_stateInputs: stateInputs,
|
|
2180
|
+
_nextTimerId: nextTimerId,
|
|
2181
|
+
_nextActorIds: nextActorIds,
|
|
2178
2182
|
...data
|
|
2179
2183
|
} = snapshot;
|
|
2180
2184
|
return encode({
|
|
2181
2185
|
...data,
|
|
2186
|
+
stateInputs,
|
|
2187
|
+
nextTimerId,
|
|
2188
|
+
nextActorIds,
|
|
2182
2189
|
nodeIds: nodes.map(node => node.id)
|
|
2183
2190
|
}, new Set(), mappers);
|
|
2184
2191
|
}
|
|
@@ -2222,6 +2229,8 @@ class SystemReduction {
|
|
|
2222
2229
|
this.mappers = void 0;
|
|
2223
2230
|
this.remaining = void 0;
|
|
2224
2231
|
if (!Number.isSafeInteger(maxSteps) || maxSteps < 1) throw new Error('maxSteps must be a positive integer.');
|
|
2232
|
+
// TODO(v7): remove with legacySnapshot.ts.
|
|
2233
|
+
snapshot = upgradeLegacySystemSnapshot(snapshot);
|
|
2225
2234
|
this.logic = definitions(logic);
|
|
2226
2235
|
this.mappers = logic.mappers ?? {};
|
|
2227
2236
|
this.mapperNames = new Map(Object.entries(this.mappers).map(([key, mapper]) => [mapper, key]));
|
|
@@ -2252,26 +2261,26 @@ class SystemReduction {
|
|
|
2252
2261
|
}
|
|
2253
2262
|
reference(actor) {
|
|
2254
2263
|
return {
|
|
2255
|
-
|
|
2264
|
+
'@actor': actor.address,
|
|
2256
2265
|
incarnation: actor.sessionId
|
|
2257
2266
|
};
|
|
2258
2267
|
}
|
|
2259
2268
|
current(ref) {
|
|
2260
|
-
const actor = this.snapshot.actors[ref
|
|
2269
|
+
const actor = this.snapshot.actors[ref['@actor']];
|
|
2261
2270
|
return actor?.incarnation === ref.incarnation ? actor : undefined;
|
|
2262
2271
|
}
|
|
2263
2272
|
decode(value, machine) {
|
|
2264
2273
|
if (isReference(value)) return this.handle(value);
|
|
2265
2274
|
if (!value || typeof value !== 'object') return value;
|
|
2266
|
-
if (typeof value
|
|
2267
|
-
const mapper = Object.hasOwn(this.mappers, value
|
|
2268
|
-
if (!mapper) throw new Error(`Missing pure mapper '${value
|
|
2275
|
+
if (typeof value['@systemMapper'] === 'string') {
|
|
2276
|
+
const mapper = Object.hasOwn(this.mappers, value['@systemMapper']) && this.mappers[value['@systemMapper']];
|
|
2277
|
+
if (!mapper) throw new Error(`Missing pure mapper '${value['@systemMapper']}'.`);
|
|
2269
2278
|
return mapper;
|
|
2270
2279
|
}
|
|
2271
|
-
if (typeof value
|
|
2272
|
-
if (typeof value
|
|
2280
|
+
if (typeof value['@stateNode'] === 'string') return machine.getStateNodeById(value['@stateNode']);
|
|
2281
|
+
if (typeof value['@error'] === 'string') {
|
|
2273
2282
|
const error = new Error(value.message);
|
|
2274
|
-
error.name = value
|
|
2283
|
+
error.name = value['@error'];
|
|
2275
2284
|
if (error.name === 'TimeoutError') Object.setPrototypeOf(error, TimeoutError.prototype);
|
|
2276
2285
|
return error;
|
|
2277
2286
|
}
|
|
@@ -2289,7 +2298,7 @@ class SystemReduction {
|
|
|
2289
2298
|
const kind = this.attachedKind(actor);
|
|
2290
2299
|
if (!actor.started || actor.snapshot.status !== 'active' || kind !== '@xstate.listener' && kind !== '@xstate.subscription') continue;
|
|
2291
2300
|
const target = actor.input.actor;
|
|
2292
|
-
if (!target || target
|
|
2301
|
+
if (!target || target['@actor'] !== source['@actor'] || target.incarnation !== source.incarnation || !actor.parent || this.current(actor.parent)?.snapshot.status !== 'active') continue;
|
|
2293
2302
|
const input = this.decode(actor.input);
|
|
2294
2303
|
let event;
|
|
2295
2304
|
if (kind === '@xstate.listener') {
|
|
@@ -2300,7 +2309,7 @@ class SystemReduction {
|
|
|
2300
2309
|
if (mapper) event = mapper(snapshot.status === 'done' ? snapshot.output : snapshot.status === 'error' ? snapshot.error : snapshot);
|
|
2301
2310
|
}
|
|
2302
2311
|
if (event) this.enqueue({
|
|
2303
|
-
|
|
2312
|
+
'@actor': actor.address,
|
|
2304
2313
|
incarnation: actor.incarnation
|
|
2305
2314
|
}, actor.parent, event);
|
|
2306
2315
|
}
|
|
@@ -2308,8 +2317,8 @@ class SystemReduction {
|
|
|
2308
2317
|
stopAttachments(parent) {
|
|
2309
2318
|
for (const actor of Object.values(this.snapshot.actors)) {
|
|
2310
2319
|
const kind = this.attachedKind(actor);
|
|
2311
|
-
if ((kind === '@xstate.listener' || kind === '@xstate.subscription') && actor.parent
|
|
2312
|
-
|
|
2320
|
+
if ((kind === '@xstate.listener' || kind === '@xstate.subscription') && actor.parent?.['@actor'] === parent['@actor'] && actor.parent.incarnation === parent.incarnation) this.stop({
|
|
2321
|
+
'@actor': actor.address,
|
|
2313
2322
|
incarnation: actor.incarnation
|
|
2314
2323
|
});
|
|
2315
2324
|
}
|
|
@@ -2328,6 +2337,9 @@ class SystemReduction {
|
|
|
2328
2337
|
const data = this.decode(actor.snapshot, logic);
|
|
2329
2338
|
const snapshot = typeof logic.getStateNodeById === 'function' && data.nodeIds ? createMachineSnapshot({
|
|
2330
2339
|
...data,
|
|
2340
|
+
_stateInputs: data.stateInputs,
|
|
2341
|
+
_nextTimerId: data.nextTimerId,
|
|
2342
|
+
_nextActorIds: data.nextActorIds,
|
|
2331
2343
|
_nodes: data.nodeIds.map(id => logic.getStateNodeById(id))
|
|
2332
2344
|
}, logic) : data;
|
|
2333
2345
|
this.snapshots.set(key, snapshot);
|
|
@@ -2350,8 +2362,8 @@ class SystemReduction {
|
|
|
2350
2362
|
};
|
|
2351
2363
|
const handle = {
|
|
2352
2364
|
[systemActorHandle]: true,
|
|
2353
|
-
id: actor?.id ?? ref
|
|
2354
|
-
address: ref
|
|
2365
|
+
id: actor?.id ?? ref['@actor'].split('/').at(-1),
|
|
2366
|
+
address: ref['@actor'],
|
|
2355
2367
|
sessionId: ref.incarnation,
|
|
2356
2368
|
options: {
|
|
2357
2369
|
_inert: true,
|
|
@@ -2390,13 +2402,13 @@ class SystemReduction {
|
|
|
2390
2402
|
_unregister: actor => {
|
|
2391
2403
|
this.stopping.add(JSON.stringify(this.reference(actor)));
|
|
2392
2404
|
for (const [key, ref] of Object.entries(this.snapshot.registry)) {
|
|
2393
|
-
if (ref
|
|
2405
|
+
if (ref['@actor'] === actor.address && ref.incarnation === actor.sessionId) delete this.snapshot.registry[key];
|
|
2394
2406
|
}
|
|
2395
2407
|
},
|
|
2396
2408
|
_getByAddress: address => {
|
|
2397
2409
|
const actor = this.snapshot.actors[address];
|
|
2398
2410
|
return actor?.snapshot.status === 'active' ? this.handle({
|
|
2399
|
-
|
|
2411
|
+
'@actor': address,
|
|
2400
2412
|
incarnation: actor.incarnation
|
|
2401
2413
|
}) : undefined;
|
|
2402
2414
|
},
|
|
@@ -2442,11 +2454,11 @@ class SystemReduction {
|
|
|
2442
2454
|
if (!definition) throw new Error('Register dynamically spawned logic in systemLogic.actors.');
|
|
2443
2455
|
const parent = options.parent && this.reference(options.parent);
|
|
2444
2456
|
const id = options.id ?? `${getActorIdPrefix(options.src ?? logic)}:${this.snapshot.counters.actor}`;
|
|
2445
|
-
const address = `${parent ? parent
|
|
2457
|
+
const address = `${parent ? parent['@actor'] + '/' : ''}${encodeAddressSegment(id)}`;
|
|
2446
2458
|
const occupied = this.snapshot.actors[address];
|
|
2447
2459
|
if (occupied?.snapshot.status === 'active') {
|
|
2448
2460
|
const previous = {
|
|
2449
|
-
|
|
2461
|
+
'@actor': address,
|
|
2450
2462
|
incarnation: occupied.incarnation
|
|
2451
2463
|
};
|
|
2452
2464
|
if (!this.stopping.has(JSON.stringify(previous))) throw new Error(`Actor address '${address}' is already occupied.`);
|
|
@@ -2454,7 +2466,7 @@ class SystemReduction {
|
|
|
2454
2466
|
}
|
|
2455
2467
|
const incarnation = String(this.snapshot.counters.actor++);
|
|
2456
2468
|
const ref = {
|
|
2457
|
-
|
|
2469
|
+
'@actor': address,
|
|
2458
2470
|
incarnation
|
|
2459
2471
|
};
|
|
2460
2472
|
const state = {
|
|
@@ -2492,7 +2504,7 @@ class SystemReduction {
|
|
|
2492
2504
|
const actor = this.current(ref);
|
|
2493
2505
|
if (!actor) return;
|
|
2494
2506
|
this.snapshots.set(JSON.stringify(ref), snapshot);
|
|
2495
|
-
this.snapshot.actors[ref
|
|
2507
|
+
this.snapshot.actors[ref['@actor']] = {
|
|
2496
2508
|
...actor,
|
|
2497
2509
|
snapshot: snapshotData(snapshot, this.mapperNames)
|
|
2498
2510
|
};
|
|
@@ -2542,7 +2554,7 @@ class SystemReduction {
|
|
|
2542
2554
|
...key
|
|
2543
2555
|
});
|
|
2544
2556
|
for (const [timerKey, timer] of Object.entries(this.snapshot.timers)) {
|
|
2545
|
-
if (timer.source
|
|
2557
|
+
if (timer.source['@actor'] === ref['@actor'] && timer.source.incarnation === ref.incarnation && (cancelled === undefined || timerKey === cancelled)) delete this.snapshot.timers[timerKey];
|
|
2546
2558
|
}
|
|
2547
2559
|
}
|
|
2548
2560
|
effectsFor(ref, effects) {
|
|
@@ -2580,9 +2592,9 @@ class SystemReduction {
|
|
|
2580
2592
|
} else if (isSerializedActorRef(value.target)) {
|
|
2581
2593
|
// A ref that went through JSON targets the current incarnation
|
|
2582
2594
|
// at its address; without one the event is a dead letter.
|
|
2583
|
-
const target = this.snapshot.actors[value.target
|
|
2595
|
+
const target = this.snapshot.actors[value.target['@actor']];
|
|
2584
2596
|
if (target?.snapshot.status === 'active' && (value.target.incarnation === undefined || value.target.incarnation === target.incarnation)) this.enqueue(ref, {
|
|
2585
|
-
|
|
2597
|
+
'@actor': target.address,
|
|
2586
2598
|
incarnation: target.incarnation
|
|
2587
2599
|
}, value.event);else this.external(ref, {
|
|
2588
2600
|
kind: 'builtin',
|
|
@@ -2622,7 +2634,7 @@ class SystemReduction {
|
|
|
2622
2634
|
start(ref) {
|
|
2623
2635
|
const actor = this.current(ref);
|
|
2624
2636
|
if (!actor || actor.started || actor.snapshot.status === 'stopped') return;
|
|
2625
|
-
this.snapshot.actors[ref
|
|
2637
|
+
this.snapshot.actors[ref['@actor']] = {
|
|
2626
2638
|
...actor,
|
|
2627
2639
|
started: true
|
|
2628
2640
|
};
|
|
@@ -2662,13 +2674,13 @@ class SystemReduction {
|
|
|
2662
2674
|
});
|
|
2663
2675
|
this.cancel(ref);
|
|
2664
2676
|
this.handle(ref).system._unregister(this.handle(ref));
|
|
2665
|
-
this.snapshot.messages = this.snapshot.messages.filter(message => message.target
|
|
2677
|
+
this.snapshot.messages = this.snapshot.messages.filter(message => message.target['@actor'] !== ref['@actor'] || message.target.incarnation !== ref.incarnation);
|
|
2666
2678
|
this.cancelExternal(ref);
|
|
2667
2679
|
this.stopAttachments(ref);
|
|
2668
2680
|
}
|
|
2669
2681
|
cancelExternal(ref) {
|
|
2670
2682
|
for (const [id, effect] of Object.entries(this.snapshot.externalEffects)) {
|
|
2671
|
-
if (effect.kind !== 'action' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup' || effect.source
|
|
2683
|
+
if (effect.kind !== 'action' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup' || effect.source['@actor'] !== ref['@actor'] || effect.source.incarnation !== ref.incarnation) continue;
|
|
2672
2684
|
delete this.snapshot.externalEffects[id];
|
|
2673
2685
|
const cancellation = {
|
|
2674
2686
|
id: `${this.snapshot.executionId}:${this.snapshot.counters.effect++}`,
|
|
@@ -2705,7 +2717,7 @@ class SystemReduction {
|
|
|
2705
2717
|
}
|
|
2706
2718
|
const logic = this.logic.get(actor.src);
|
|
2707
2719
|
if (!logic) throw new Error(`Missing actor definition '${actor.src}'.`);
|
|
2708
|
-
if (logic.isInternalEventType?.(message.event.type) && (!message.source || message.source
|
|
2720
|
+
if (logic.isInternalEventType?.(message.event.type) && (!message.source || message.source['@actor'] !== actor.address || message.source.incarnation !== actor.incarnation)) {
|
|
2709
2721
|
throw new Error(`Internal event '${message.event.type}' cannot be injected into a pure system.`);
|
|
2710
2722
|
}
|
|
2711
2723
|
if (!message.source && /^(xstate\.after(?:\.|$)|xstate\.timeout(?:\.|$))/.test(message.event.type)) throw new Error('Select a pending timer instead of injecting its internal event.');
|
|
@@ -2762,7 +2774,7 @@ class SystemReduction {
|
|
|
2762
2774
|
if (event.type === 'xstate.timer') {
|
|
2763
2775
|
const actor = this.snapshot.actors[path];
|
|
2764
2776
|
if (!actor) throw new Error(`Unknown actor address '${path}'.`);
|
|
2765
|
-
const timer = Object.values(this.snapshot.timers).find(pending => pending.source
|
|
2777
|
+
const timer = Object.values(this.snapshot.timers).find(pending => pending.source['@actor'] === path && pending.source.incarnation === actor.incarnation && pending.occurrence === event.occurrence);
|
|
2766
2778
|
if (!timer) throw new Error('Select a current timer occurrence.');
|
|
2767
2779
|
this.advance(timer.dueAt);
|
|
2768
2780
|
return;
|
|
@@ -2771,12 +2783,12 @@ class SystemReduction {
|
|
|
2771
2783
|
const actor = this.snapshot.actors[path];
|
|
2772
2784
|
if (!actor) throw new Error(`Unknown actor address '${path}'.`);
|
|
2773
2785
|
const ref = {
|
|
2774
|
-
|
|
2786
|
+
'@actor': path,
|
|
2775
2787
|
incarnation: actor.incarnation
|
|
2776
2788
|
};
|
|
2777
2789
|
if (event.type === 'xstate.system.effect.result') {
|
|
2778
2790
|
const effect = this.snapshot.externalEffects[event.effectId];
|
|
2779
|
-
if (!effect || effect.source
|
|
2791
|
+
if (!effect || effect.source['@actor'] !== path || event.event && (effect.source.incarnation !== actor.incarnation || actor.snapshot.status !== 'active' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup')) throw new Error('External effect result does not match its owner or is stale.');
|
|
2780
2792
|
delete this.snapshot.externalEffects[event.effectId];
|
|
2781
2793
|
if (event.event) {
|
|
2782
2794
|
this.enqueue(ref, ref, event.event);
|
package/dist/xstate.esm.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createAsyncLogic, TimeoutError } from './xstate-actors.esm.js';
|
|
2
2
|
export { TimeoutError, createAsyncLogic, createCallbackLogic, createEmptyActor, createEventObservableLogic, createObservableLogic, createStepLogic } from './xstate-actors.esm.js';
|
|
3
|
-
import { m as matchesEventDescriptor, x as xstateError, t as toArray, d as diagnoseAuthorConfig, p as parseDelayToMilliseconds, a as assertUnreservedSourceName, i as isAtomicStateNode, P as ProcessingStatus, g as getAllStateNodes, b as getStateNodes, r as resolveInvokedActorLogic, c as isActorRefLike, e as createMachineSnapshot, f as diagnoseSetupConfig, h as createActor, j as encodeAddressSegment, s as systemLogicMetadata, k as getActorIdPrefix, l as finalizeTransitionResult, n as getTimerKey, o as isSerializedActorRef, q as readTimerKey, X as XSTATE_STOP_EFFECT, u as XSTATE_STOP, v as createDoneActorEvent, w as createErrorActorEvent, y as serializeTimerKey, z as matchesTimerKey, A as isMachineSnapshot, B as listenerLogic, C as subscriptionLogic } from './createActor-
|
|
4
|
-
export { F as Actor, I as InfiniteTransitionError, p as _parseDelayToMilliseconds, H as _toObserver, h as createActor, D as createListenerLogic, E as createSubscriptionLogic, L as deliverEvent, J as executeEffects, b as getStateNodes, K as isBuiltInExecutableEffect, A as isMachineSnapshot, G as matchesState, M as runStep, N as stopActor, O as terminateActor } from './createActor-
|
|
5
|
-
import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema } from './
|
|
6
|
-
export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './
|
|
3
|
+
import { m as matchesEventDescriptor, x as xstateError, t as toArray, d as diagnoseAuthorConfig, p as parseDelayToMilliseconds, a as assertUnreservedSourceName, i as isAtomicStateNode, P as ProcessingStatus, g as getAllStateNodes, b as getStateNodes, r as resolveInvokedActorLogic, c as isActorRefLike, e as createMachineSnapshot, f as diagnoseSetupConfig, h as createActor, j as encodeAddressSegment, s as systemLogicMetadata, k as getActorIdPrefix, l as finalizeTransitionResult, n as getTimerKey, o as isSerializedActorRef, q as readTimerKey, X as XSTATE_STOP_EFFECT, u as XSTATE_STOP, v as createDoneActorEvent, w as createErrorActorEvent, y as serializeTimerKey, z as matchesTimerKey, A as isMachineSnapshot, B as listenerLogic, C as subscriptionLogic } from './createActor-20a97166.esm.js';
|
|
4
|
+
export { F as Actor, I as InfiniteTransitionError, p as _parseDelayToMilliseconds, H as _toObserver, h as createActor, D as createListenerLogic, E as createSubscriptionLogic, L as deliverEvent, J as executeEffects, b as getStateNodes, K as isBuiltInExecutableEffect, A as isMachineSnapshot, G as matchesState, M as runStep, N as stopActor, O as terminateActor } from './createActor-20a97166.esm.js';
|
|
5
|
+
import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema, u as upgradeLegacySystemSnapshot } from './legacySnapshot-9e06feb4.esm.js';
|
|
6
|
+
export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './legacySnapshot-9e06feb4.esm.js';
|
|
7
7
|
export { i as isTypeSchema, t as types } from './schema.types-0ecd17b8.esm.js';
|
|
8
|
-
export { d as describeExecutableEffect, b as getInitialMicrosteps, g as getMicrosteps, c as getNextTransitions, a as initialTransition, i as isUnhandled, t as transition } from './effectDescriptor-
|
|
8
|
+
export { d as describeExecutableEffect, b as getInitialMicrosteps, g as getMicrosteps, c as getNextTransitions, a as initialTransition, i as isUnhandled, t as transition } from './effectDescriptor-e93df910.esm.js';
|
|
9
9
|
import './validation-05f1d517.esm.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
@@ -2110,13 +2110,13 @@ class SimulatedClock {
|
|
|
2110
2110
|
// logical timer key (or, for a directly delivered event, the event type).
|
|
2111
2111
|
function systemTimerKey(source, event) {
|
|
2112
2112
|
const key = event.type === 'xstate.timer' ? readTimerKey(event) : undefined;
|
|
2113
|
-
return JSON.stringify([source
|
|
2113
|
+
return JSON.stringify([source['@actor'], source.incarnation, key ? serializeTimerKey(key) : event.type]);
|
|
2114
2114
|
}
|
|
2115
2115
|
function isLogicalTimerPending(snapshot, key) {
|
|
2116
2116
|
return (snapshot.timers ?? []).some(timer => matchesTimerKey(timer, key));
|
|
2117
2117
|
}
|
|
2118
2118
|
function isReference(value) {
|
|
2119
|
-
return !!value && typeof value
|
|
2119
|
+
return !!value && typeof value['@actor'] === 'string' && typeof value.incarnation === 'string';
|
|
2120
2120
|
}
|
|
2121
2121
|
function isHandle(value) {
|
|
2122
2122
|
return !!value && typeof value.address === 'string' && typeof value.getSnapshot === 'function';
|
|
@@ -2127,12 +2127,12 @@ const systemLogger = () => {};
|
|
|
2127
2127
|
/** Converts runtime-shaped, reduction-local capabilities to snapshot data. */
|
|
2128
2128
|
function encode(value, seen = new Set(), mappers) {
|
|
2129
2129
|
if (typeof value === 'function' && mappers?.has(value)) return {
|
|
2130
|
-
|
|
2130
|
+
'@systemMapper': mappers.get(value)
|
|
2131
2131
|
};
|
|
2132
2132
|
if (isHandle(value)) {
|
|
2133
2133
|
if (!value[systemActorHandle]) throw new Error('Live actors cannot be stored in a pure system snapshot.');
|
|
2134
2134
|
return {
|
|
2135
|
-
|
|
2135
|
+
'@actor': value.address,
|
|
2136
2136
|
incarnation: value.sessionId
|
|
2137
2137
|
};
|
|
2138
2138
|
}
|
|
@@ -2145,11 +2145,11 @@ function encode(value, seen = new Set(), mappers) {
|
|
|
2145
2145
|
let result;
|
|
2146
2146
|
if (value.machine && typeof value.machine.transition === 'function' && typeof value.id === 'string' && Array.isArray(value.path)) {
|
|
2147
2147
|
result = {
|
|
2148
|
-
|
|
2148
|
+
'@stateNode': value.id
|
|
2149
2149
|
};
|
|
2150
2150
|
} else if (value instanceof Error) {
|
|
2151
2151
|
result = {
|
|
2152
|
-
|
|
2152
|
+
'@error': value.name,
|
|
2153
2153
|
message: value.message
|
|
2154
2154
|
};
|
|
2155
2155
|
} else if (Array.isArray(value)) {
|
|
@@ -2175,10 +2175,17 @@ function snapshotData(snapshot, mappers) {
|
|
|
2175
2175
|
getMeta,
|
|
2176
2176
|
getInputs,
|
|
2177
2177
|
toJSON,
|
|
2178
|
+
// Stores such as Convex reject `_`-prefixed field names.
|
|
2179
|
+
_stateInputs: stateInputs,
|
|
2180
|
+
_nextTimerId: nextTimerId,
|
|
2181
|
+
_nextActorIds: nextActorIds,
|
|
2178
2182
|
...data
|
|
2179
2183
|
} = snapshot;
|
|
2180
2184
|
return encode({
|
|
2181
2185
|
...data,
|
|
2186
|
+
stateInputs,
|
|
2187
|
+
nextTimerId,
|
|
2188
|
+
nextActorIds,
|
|
2182
2189
|
nodeIds: nodes.map(node => node.id)
|
|
2183
2190
|
}, new Set(), mappers);
|
|
2184
2191
|
}
|
|
@@ -2222,6 +2229,8 @@ class SystemReduction {
|
|
|
2222
2229
|
this.mappers = void 0;
|
|
2223
2230
|
this.remaining = void 0;
|
|
2224
2231
|
if (!Number.isSafeInteger(maxSteps) || maxSteps < 1) throw new Error('maxSteps must be a positive integer.');
|
|
2232
|
+
// TODO(v7): remove with legacySnapshot.ts.
|
|
2233
|
+
snapshot = upgradeLegacySystemSnapshot(snapshot);
|
|
2225
2234
|
this.logic = definitions(logic);
|
|
2226
2235
|
this.mappers = logic.mappers ?? {};
|
|
2227
2236
|
this.mapperNames = new Map(Object.entries(this.mappers).map(([key, mapper]) => [mapper, key]));
|
|
@@ -2252,26 +2261,26 @@ class SystemReduction {
|
|
|
2252
2261
|
}
|
|
2253
2262
|
reference(actor) {
|
|
2254
2263
|
return {
|
|
2255
|
-
|
|
2264
|
+
'@actor': actor.address,
|
|
2256
2265
|
incarnation: actor.sessionId
|
|
2257
2266
|
};
|
|
2258
2267
|
}
|
|
2259
2268
|
current(ref) {
|
|
2260
|
-
const actor = this.snapshot.actors[ref
|
|
2269
|
+
const actor = this.snapshot.actors[ref['@actor']];
|
|
2261
2270
|
return actor?.incarnation === ref.incarnation ? actor : undefined;
|
|
2262
2271
|
}
|
|
2263
2272
|
decode(value, machine) {
|
|
2264
2273
|
if (isReference(value)) return this.handle(value);
|
|
2265
2274
|
if (!value || typeof value !== 'object') return value;
|
|
2266
|
-
if (typeof value
|
|
2267
|
-
const mapper = Object.hasOwn(this.mappers, value
|
|
2268
|
-
if (!mapper) throw new Error(`Missing pure mapper '${value
|
|
2275
|
+
if (typeof value['@systemMapper'] === 'string') {
|
|
2276
|
+
const mapper = Object.hasOwn(this.mappers, value['@systemMapper']) && this.mappers[value['@systemMapper']];
|
|
2277
|
+
if (!mapper) throw new Error(`Missing pure mapper '${value['@systemMapper']}'.`);
|
|
2269
2278
|
return mapper;
|
|
2270
2279
|
}
|
|
2271
|
-
if (typeof value
|
|
2272
|
-
if (typeof value
|
|
2280
|
+
if (typeof value['@stateNode'] === 'string') return machine.getStateNodeById(value['@stateNode']);
|
|
2281
|
+
if (typeof value['@error'] === 'string') {
|
|
2273
2282
|
const error = new Error(value.message);
|
|
2274
|
-
error.name = value
|
|
2283
|
+
error.name = value['@error'];
|
|
2275
2284
|
if (error.name === 'TimeoutError') Object.setPrototypeOf(error, TimeoutError.prototype);
|
|
2276
2285
|
return error;
|
|
2277
2286
|
}
|
|
@@ -2289,7 +2298,7 @@ class SystemReduction {
|
|
|
2289
2298
|
const kind = this.attachedKind(actor);
|
|
2290
2299
|
if (!actor.started || actor.snapshot.status !== 'active' || kind !== '@xstate.listener' && kind !== '@xstate.subscription') continue;
|
|
2291
2300
|
const target = actor.input.actor;
|
|
2292
|
-
if (!target || target
|
|
2301
|
+
if (!target || target['@actor'] !== source['@actor'] || target.incarnation !== source.incarnation || !actor.parent || this.current(actor.parent)?.snapshot.status !== 'active') continue;
|
|
2293
2302
|
const input = this.decode(actor.input);
|
|
2294
2303
|
let event;
|
|
2295
2304
|
if (kind === '@xstate.listener') {
|
|
@@ -2300,7 +2309,7 @@ class SystemReduction {
|
|
|
2300
2309
|
if (mapper) event = mapper(snapshot.status === 'done' ? snapshot.output : snapshot.status === 'error' ? snapshot.error : snapshot);
|
|
2301
2310
|
}
|
|
2302
2311
|
if (event) this.enqueue({
|
|
2303
|
-
|
|
2312
|
+
'@actor': actor.address,
|
|
2304
2313
|
incarnation: actor.incarnation
|
|
2305
2314
|
}, actor.parent, event);
|
|
2306
2315
|
}
|
|
@@ -2308,8 +2317,8 @@ class SystemReduction {
|
|
|
2308
2317
|
stopAttachments(parent) {
|
|
2309
2318
|
for (const actor of Object.values(this.snapshot.actors)) {
|
|
2310
2319
|
const kind = this.attachedKind(actor);
|
|
2311
|
-
if ((kind === '@xstate.listener' || kind === '@xstate.subscription') && actor.parent
|
|
2312
|
-
|
|
2320
|
+
if ((kind === '@xstate.listener' || kind === '@xstate.subscription') && actor.parent?.['@actor'] === parent['@actor'] && actor.parent.incarnation === parent.incarnation) this.stop({
|
|
2321
|
+
'@actor': actor.address,
|
|
2313
2322
|
incarnation: actor.incarnation
|
|
2314
2323
|
});
|
|
2315
2324
|
}
|
|
@@ -2328,6 +2337,9 @@ class SystemReduction {
|
|
|
2328
2337
|
const data = this.decode(actor.snapshot, logic);
|
|
2329
2338
|
const snapshot = typeof logic.getStateNodeById === 'function' && data.nodeIds ? createMachineSnapshot({
|
|
2330
2339
|
...data,
|
|
2340
|
+
_stateInputs: data.stateInputs,
|
|
2341
|
+
_nextTimerId: data.nextTimerId,
|
|
2342
|
+
_nextActorIds: data.nextActorIds,
|
|
2331
2343
|
_nodes: data.nodeIds.map(id => logic.getStateNodeById(id))
|
|
2332
2344
|
}, logic) : data;
|
|
2333
2345
|
this.snapshots.set(key, snapshot);
|
|
@@ -2350,8 +2362,8 @@ class SystemReduction {
|
|
|
2350
2362
|
};
|
|
2351
2363
|
const handle = {
|
|
2352
2364
|
[systemActorHandle]: true,
|
|
2353
|
-
id: actor?.id ?? ref
|
|
2354
|
-
address: ref
|
|
2365
|
+
id: actor?.id ?? ref['@actor'].split('/').at(-1),
|
|
2366
|
+
address: ref['@actor'],
|
|
2355
2367
|
sessionId: ref.incarnation,
|
|
2356
2368
|
options: {
|
|
2357
2369
|
_inert: true,
|
|
@@ -2390,13 +2402,13 @@ class SystemReduction {
|
|
|
2390
2402
|
_unregister: actor => {
|
|
2391
2403
|
this.stopping.add(JSON.stringify(this.reference(actor)));
|
|
2392
2404
|
for (const [key, ref] of Object.entries(this.snapshot.registry)) {
|
|
2393
|
-
if (ref
|
|
2405
|
+
if (ref['@actor'] === actor.address && ref.incarnation === actor.sessionId) delete this.snapshot.registry[key];
|
|
2394
2406
|
}
|
|
2395
2407
|
},
|
|
2396
2408
|
_getByAddress: address => {
|
|
2397
2409
|
const actor = this.snapshot.actors[address];
|
|
2398
2410
|
return actor?.snapshot.status === 'active' ? this.handle({
|
|
2399
|
-
|
|
2411
|
+
'@actor': address,
|
|
2400
2412
|
incarnation: actor.incarnation
|
|
2401
2413
|
}) : undefined;
|
|
2402
2414
|
},
|
|
@@ -2442,11 +2454,11 @@ class SystemReduction {
|
|
|
2442
2454
|
if (!definition) throw new Error('Register dynamically spawned logic in systemLogic.actors.');
|
|
2443
2455
|
const parent = options.parent && this.reference(options.parent);
|
|
2444
2456
|
const id = options.id ?? `${getActorIdPrefix(options.src ?? logic)}:${this.snapshot.counters.actor}`;
|
|
2445
|
-
const address = `${parent ? parent
|
|
2457
|
+
const address = `${parent ? parent['@actor'] + '/' : ''}${encodeAddressSegment(id)}`;
|
|
2446
2458
|
const occupied = this.snapshot.actors[address];
|
|
2447
2459
|
if (occupied?.snapshot.status === 'active') {
|
|
2448
2460
|
const previous = {
|
|
2449
|
-
|
|
2461
|
+
'@actor': address,
|
|
2450
2462
|
incarnation: occupied.incarnation
|
|
2451
2463
|
};
|
|
2452
2464
|
if (!this.stopping.has(JSON.stringify(previous))) throw new Error(`Actor address '${address}' is already occupied.`);
|
|
@@ -2454,7 +2466,7 @@ class SystemReduction {
|
|
|
2454
2466
|
}
|
|
2455
2467
|
const incarnation = String(this.snapshot.counters.actor++);
|
|
2456
2468
|
const ref = {
|
|
2457
|
-
|
|
2469
|
+
'@actor': address,
|
|
2458
2470
|
incarnation
|
|
2459
2471
|
};
|
|
2460
2472
|
const state = {
|
|
@@ -2492,7 +2504,7 @@ class SystemReduction {
|
|
|
2492
2504
|
const actor = this.current(ref);
|
|
2493
2505
|
if (!actor) return;
|
|
2494
2506
|
this.snapshots.set(JSON.stringify(ref), snapshot);
|
|
2495
|
-
this.snapshot.actors[ref
|
|
2507
|
+
this.snapshot.actors[ref['@actor']] = {
|
|
2496
2508
|
...actor,
|
|
2497
2509
|
snapshot: snapshotData(snapshot, this.mapperNames)
|
|
2498
2510
|
};
|
|
@@ -2542,7 +2554,7 @@ class SystemReduction {
|
|
|
2542
2554
|
...key
|
|
2543
2555
|
});
|
|
2544
2556
|
for (const [timerKey, timer] of Object.entries(this.snapshot.timers)) {
|
|
2545
|
-
if (timer.source
|
|
2557
|
+
if (timer.source['@actor'] === ref['@actor'] && timer.source.incarnation === ref.incarnation && (cancelled === undefined || timerKey === cancelled)) delete this.snapshot.timers[timerKey];
|
|
2546
2558
|
}
|
|
2547
2559
|
}
|
|
2548
2560
|
effectsFor(ref, effects) {
|
|
@@ -2580,9 +2592,9 @@ class SystemReduction {
|
|
|
2580
2592
|
} else if (isSerializedActorRef(value.target)) {
|
|
2581
2593
|
// A ref that went through JSON targets the current incarnation
|
|
2582
2594
|
// at its address; without one the event is a dead letter.
|
|
2583
|
-
const target = this.snapshot.actors[value.target
|
|
2595
|
+
const target = this.snapshot.actors[value.target['@actor']];
|
|
2584
2596
|
if (target?.snapshot.status === 'active' && (value.target.incarnation === undefined || value.target.incarnation === target.incarnation)) this.enqueue(ref, {
|
|
2585
|
-
|
|
2597
|
+
'@actor': target.address,
|
|
2586
2598
|
incarnation: target.incarnation
|
|
2587
2599
|
}, value.event);else this.external(ref, {
|
|
2588
2600
|
kind: 'builtin',
|
|
@@ -2622,7 +2634,7 @@ class SystemReduction {
|
|
|
2622
2634
|
start(ref) {
|
|
2623
2635
|
const actor = this.current(ref);
|
|
2624
2636
|
if (!actor || actor.started || actor.snapshot.status === 'stopped') return;
|
|
2625
|
-
this.snapshot.actors[ref
|
|
2637
|
+
this.snapshot.actors[ref['@actor']] = {
|
|
2626
2638
|
...actor,
|
|
2627
2639
|
started: true
|
|
2628
2640
|
};
|
|
@@ -2662,13 +2674,13 @@ class SystemReduction {
|
|
|
2662
2674
|
});
|
|
2663
2675
|
this.cancel(ref);
|
|
2664
2676
|
this.handle(ref).system._unregister(this.handle(ref));
|
|
2665
|
-
this.snapshot.messages = this.snapshot.messages.filter(message => message.target
|
|
2677
|
+
this.snapshot.messages = this.snapshot.messages.filter(message => message.target['@actor'] !== ref['@actor'] || message.target.incarnation !== ref.incarnation);
|
|
2666
2678
|
this.cancelExternal(ref);
|
|
2667
2679
|
this.stopAttachments(ref);
|
|
2668
2680
|
}
|
|
2669
2681
|
cancelExternal(ref) {
|
|
2670
2682
|
for (const [id, effect] of Object.entries(this.snapshot.externalEffects)) {
|
|
2671
|
-
if (effect.kind !== 'action' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup' || effect.source
|
|
2683
|
+
if (effect.kind !== 'action' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup' || effect.source['@actor'] !== ref['@actor'] || effect.source.incarnation !== ref.incarnation) continue;
|
|
2672
2684
|
delete this.snapshot.externalEffects[id];
|
|
2673
2685
|
const cancellation = {
|
|
2674
2686
|
id: `${this.snapshot.executionId}:${this.snapshot.counters.effect++}`,
|
|
@@ -2705,7 +2717,7 @@ class SystemReduction {
|
|
|
2705
2717
|
}
|
|
2706
2718
|
const logic = this.logic.get(actor.src);
|
|
2707
2719
|
if (!logic) throw new Error(`Missing actor definition '${actor.src}'.`);
|
|
2708
|
-
if (logic.isInternalEventType?.(message.event.type) && (!message.source || message.source
|
|
2720
|
+
if (logic.isInternalEventType?.(message.event.type) && (!message.source || message.source['@actor'] !== actor.address || message.source.incarnation !== actor.incarnation)) {
|
|
2709
2721
|
throw new Error(`Internal event '${message.event.type}' cannot be injected into a pure system.`);
|
|
2710
2722
|
}
|
|
2711
2723
|
if (!message.source && /^(xstate\.after(?:\.|$)|xstate\.timeout(?:\.|$))/.test(message.event.type)) throw new Error('Select a pending timer instead of injecting its internal event.');
|
|
@@ -2762,7 +2774,7 @@ class SystemReduction {
|
|
|
2762
2774
|
if (event.type === 'xstate.timer') {
|
|
2763
2775
|
const actor = this.snapshot.actors[path];
|
|
2764
2776
|
if (!actor) throw new Error(`Unknown actor address '${path}'.`);
|
|
2765
|
-
const timer = Object.values(this.snapshot.timers).find(pending => pending.source
|
|
2777
|
+
const timer = Object.values(this.snapshot.timers).find(pending => pending.source['@actor'] === path && pending.source.incarnation === actor.incarnation && pending.occurrence === event.occurrence);
|
|
2766
2778
|
if (!timer) throw new Error('Select a current timer occurrence.');
|
|
2767
2779
|
this.advance(timer.dueAt);
|
|
2768
2780
|
return;
|
|
@@ -2771,12 +2783,12 @@ class SystemReduction {
|
|
|
2771
2783
|
const actor = this.snapshot.actors[path];
|
|
2772
2784
|
if (!actor) throw new Error(`Unknown actor address '${path}'.`);
|
|
2773
2785
|
const ref = {
|
|
2774
|
-
|
|
2786
|
+
'@actor': path,
|
|
2775
2787
|
incarnation: actor.incarnation
|
|
2776
2788
|
};
|
|
2777
2789
|
if (event.type === 'xstate.system.effect.result') {
|
|
2778
2790
|
const effect = this.snapshot.externalEffects[event.effectId];
|
|
2779
|
-
if (!effect || effect.source
|
|
2791
|
+
if (!effect || effect.source['@actor'] !== path || event.event && (effect.source.incarnation !== actor.incarnation || actor.snapshot.status !== 'active' || effect.type === '@xstate.cancelEffect' || effect.type === '@xstate.cleanup')) throw new Error('External effect result does not match its owner or is stale.');
|
|
2780
2792
|
delete this.snapshot.externalEffects[event.effectId];
|
|
2781
2793
|
if (event.event) {
|
|
2782
2794
|
this.enqueue(ref, ref, event.event);
|