xstate 6.0.0-alpha.40 → 6.0.0-alpha.43
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/{StateMachine-76ee1d6e.development.cjs.js → StateMachine-16d7ee93.development.cjs.js} +85 -7
- package/dist/{StateMachine-f8c7feca.development.esm.js → StateMachine-1ea29688.development.esm.js} +85 -7
- package/dist/{StateMachine-6082c3cf.esm.js → StateMachine-b13b4b09.esm.js} +85 -7
- package/dist/{StateMachine-1464d5e4.cjs.js → StateMachine-fcc48e11.cjs.js} +85 -7
- package/dist/{createActor-c0f78b8a.development.cjs.js → createActor-1a3a1d14.development.cjs.js} +827 -63
- package/dist/{createActor-d5305cc9.cjs.js → createActor-9538c7f8.cjs.js} +817 -56
- package/dist/{createActor-a211c276.esm.js → createActor-973c72ad.esm.js} +795 -56
- package/dist/{createActor-2a03d4b2.development.esm.js → createActor-f9cc6590.development.esm.js} +805 -63
- package/dist/declarations/src/StateMachine.d.ts +3 -3
- package/dist/declarations/src/actors/logic.d.ts +0 -3
- package/dist/declarations/src/createActor.d.ts +41 -6
- package/dist/declarations/src/createMachine.d.ts +7 -7
- package/dist/declarations/src/durable/index.d.ts +85 -8
- package/dist/declarations/src/effectDescriptor.d.ts +81 -0
- package/dist/declarations/src/fsm.d.ts +1 -0
- package/dist/declarations/src/index.d.ts +3 -1
- package/dist/declarations/src/inspection.d.ts +11 -1
- package/dist/declarations/src/machineVersion.types.d.ts +1 -0
- package/dist/declarations/src/runtimeHelpers.d.ts +40 -0
- package/dist/declarations/src/setup.d.ts +16 -11
- package/dist/declarations/src/system.d.ts +63 -2
- package/dist/declarations/src/transitionActions.d.ts +1 -1
- package/dist/declarations/src/types.d.ts +27 -8
- package/dist/declarations/src/types.v6.d.ts +13 -8
- package/dist/{transition-e8a13c00.esm.js → effectDescriptor-416ca00a.esm.js} +110 -2
- package/dist/{transition-4ba58b71.development.cjs.js → effectDescriptor-7d6f945a.development.cjs.js} +110 -1
- package/dist/{transition-f581ffa6.development.esm.js → effectDescriptor-e6730c9a.development.esm.js} +110 -2
- package/dist/{transition-2dcabac8.cjs.js → effectDescriptor-f8c9337f.cjs.js} +110 -1
- package/dist/{index-7020402e.esm.js → index-b478f443.esm.js} +12 -51
- package/dist/{index-21d08fff.cjs.js → index-ba7170ba.cjs.js} +15 -54
- package/dist/{index-3d1368f7.development.cjs.js → index-e0ba4813.development.cjs.js} +15 -54
- package/dist/{index-17f889df.development.esm.js → index-f284cc7b.development.esm.js} +12 -51
- package/dist/xstate-actors.cjs.js +2 -2
- package/dist/xstate-actors.development.cjs.js +2 -2
- 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 +255 -24
- package/dist/xstate-durable.development.cjs.js +255 -24
- package/dist/xstate-durable.development.esm.js +255 -24
- package/dist/xstate-durable.esm.js +255 -24
- package/dist/xstate-durable.umd.min.js +1 -1
- package/dist/xstate-durable.umd.min.js.map +1 -1
- package/dist/xstate-graph.cjs.js +3 -3
- package/dist/xstate-graph.development.cjs.js +3 -3
- package/dist/xstate-graph.development.esm.js +3 -3
- package/dist/xstate-graph.esm.js +3 -3
- package/dist/xstate-graph.umd.min.js +1 -1
- package/dist/xstate-graph.umd.min.js.map +1 -1
- package/dist/xstate-validation.cjs.js +20 -2
- package/dist/xstate-validation.development.cjs.js +20 -2
- package/dist/xstate-validation.development.esm.js +20 -2
- package/dist/xstate-validation.esm.js +20 -2
- package/dist/xstate-validation.umd.min.js +1 -1
- package/dist/xstate-validation.umd.min.js.map +1 -1
- package/dist/xstate.cjs.js +21 -9
- package/dist/xstate.cjs.mjs +5 -0
- package/dist/xstate.development.cjs.js +21 -9
- package/dist/xstate.development.cjs.mjs +5 -0
- package/dist/xstate.development.esm.js +13 -6
- package/dist/xstate.esm.js +13 -6
- package/dist/xstate.umd.min.js +1 -1
- package/dist/xstate.umd.min.js.map +1 -1
- package/package.json +1 -1
package/dist/{StateMachine-76ee1d6e.development.cjs.js → StateMachine-16d7ee93.development.cjs.js}
RENAMED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var createActor = require('./createActor-
|
|
4
|
-
var dist_xstateActors = require('./index-
|
|
3
|
+
var createActor = require('./createActor-1a3a1d14.development.cjs.js');
|
|
4
|
+
var dist_xstateActors = require('./index-e0ba4813.development.cjs.js');
|
|
5
5
|
|
|
6
6
|
function createSpawner(actorScope, actors, spawnedChildren) {
|
|
7
7
|
return (src, options) => {
|
|
8
8
|
const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
|
|
9
|
+
// Generated ids come from the same transaction allocator as `enq.spawn`,
|
|
10
|
+
// so context-factory allocations persist with the snapshot and never
|
|
11
|
+
// collide with later spawns.
|
|
12
|
+
const id = options?.id ?? createActor.allocateChildId(actorScope, referencedSrc ?? src).id;
|
|
13
|
+
if (options?.id !== undefined) {
|
|
14
|
+
createActor.assertChildIdFree(actorScope, options.id);
|
|
15
|
+
createActor.reserveChildId(actorScope, options.id);
|
|
16
|
+
}
|
|
9
17
|
const actor = actorScope.system.createActorRef(src, {
|
|
10
|
-
id
|
|
18
|
+
id,
|
|
11
19
|
parent: actorScope.self,
|
|
12
20
|
syncSnapshot: options?.syncSnapshot,
|
|
13
21
|
input: options?.input,
|
|
@@ -410,6 +418,16 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
410
418
|
}
|
|
411
419
|
|
|
412
420
|
const STATE_IDENTIFIER = '#';
|
|
421
|
+
function findEventSchema(schemas, eventType) {
|
|
422
|
+
if (!schemas) {
|
|
423
|
+
return undefined;
|
|
424
|
+
}
|
|
425
|
+
if (Object.hasOwn(schemas, eventType)) {
|
|
426
|
+
return schemas[eventType];
|
|
427
|
+
}
|
|
428
|
+
const descriptor = Object.keys(schemas).find(key => createActor.matchesEventDescriptor(eventType, key));
|
|
429
|
+
return descriptor === undefined ? undefined : schemas[descriptor];
|
|
430
|
+
}
|
|
413
431
|
let emptyCanActor;
|
|
414
432
|
let emptyCanActorScope;
|
|
415
433
|
function getEmptyCanActor() {
|
|
@@ -454,6 +472,12 @@ class StateMachine {
|
|
|
454
472
|
config, sources, validator) {
|
|
455
473
|
this.config = config;
|
|
456
474
|
this.validator = validator;
|
|
475
|
+
/**
|
|
476
|
+
* @internal Type-only marker for the actor's internal event protocol. Not
|
|
477
|
+
* `declare` (the build's babel pipeline rejects declare class fields); the
|
|
478
|
+
* one `undefined` property this emits per machine instance is inert.
|
|
479
|
+
*/
|
|
480
|
+
this._internalEventType = void 0;
|
|
457
481
|
/** The machine's own version. */
|
|
458
482
|
this.version = void 0;
|
|
459
483
|
this.schemas = void 0;
|
|
@@ -592,9 +616,10 @@ class StateMachine {
|
|
|
592
616
|
}
|
|
593
617
|
const event = value;
|
|
594
618
|
const eventSchemas = this.schemas?.events;
|
|
619
|
+
const internalEventSchemas = this.schemas?.internalEvents;
|
|
595
620
|
const isFrameworkEvent = event.type.startsWith('xstate.') || event.type.startsWith('@xstate.');
|
|
596
|
-
const schema =
|
|
597
|
-
if (eventSchemas && !schema && !isFrameworkEvent) {
|
|
621
|
+
const schema = findEventSchema(internalEventSchemas, event.type) ?? findEventSchema(eventSchemas, event.type);
|
|
622
|
+
if ((eventSchemas || internalEventSchemas) && !schema && !isFrameworkEvent) {
|
|
598
623
|
return {
|
|
599
624
|
issues: [{
|
|
600
625
|
message: `Unknown event '${event.type}' for machine '${this.id}' version '${this.version}'.`
|
|
@@ -630,7 +655,7 @@ class StateMachine {
|
|
|
630
655
|
}
|
|
631
656
|
}
|
|
632
657
|
};
|
|
633
|
-
this.internalEventDescriptors = this.config.internalEvents ?? [];
|
|
658
|
+
this.internalEventDescriptors = [...Object.keys(this.schemas?.internalEvents ?? {}), ...(this.config.internalEvents ?? [])];
|
|
634
659
|
this.options = {
|
|
635
660
|
maxIterations: Infinity,
|
|
636
661
|
...this.config.options
|
|
@@ -726,6 +751,7 @@ class StateMachine {
|
|
|
726
751
|
if (usesInertScope) {
|
|
727
752
|
createActor.setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
728
753
|
}
|
|
754
|
+
createActor.beginSpawnAllocation(resolvedActorScope);
|
|
729
755
|
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
730
756
|
if (fastSnapshot) {
|
|
731
757
|
if (usesInertScope) {
|
|
@@ -921,6 +947,14 @@ class StateMachine {
|
|
|
921
947
|
...nextState.children,
|
|
922
948
|
...children
|
|
923
949
|
};
|
|
950
|
+
// Commit the transaction counters so context-factory allocations
|
|
951
|
+
// persist with the snapshot: a freed id is never handed out again
|
|
952
|
+
// after a restore or in a fresh replay process. (The spawner already
|
|
953
|
+
// registered each child for string-id resolution.)
|
|
954
|
+
const counters = createActor.takeSpawnAllocationCounters(actorScope);
|
|
955
|
+
if (counters) {
|
|
956
|
+
nextState._nextActorIds = createActor.mergeActorIdCounters(nextState._nextActorIds, counters);
|
|
957
|
+
}
|
|
924
958
|
}
|
|
925
959
|
return nextState;
|
|
926
960
|
}
|
|
@@ -944,6 +978,7 @@ class StateMachine {
|
|
|
944
978
|
}
|
|
945
979
|
const usesInertScope = !actorScope;
|
|
946
980
|
const resolvedActorScope = actorScope ?? createActor.createInertActorScope(this);
|
|
981
|
+
createActor.beginSpawnAllocation(resolvedActorScope);
|
|
947
982
|
const initEvent = createActor.createInitEvent(input); // TODO: fix;
|
|
948
983
|
const internalQueue = [];
|
|
949
984
|
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
@@ -1035,6 +1070,31 @@ class StateMachine {
|
|
|
1035
1070
|
const snapshotChildren = snapshotData.children;
|
|
1036
1071
|
for (const actorId of Object.keys(snapshotChildren)) {
|
|
1037
1072
|
const actorData = snapshotChildren[actorId];
|
|
1073
|
+
if (actorData.remote === true && actorData.address !== undefined) {
|
|
1074
|
+
if (typeof actorData.src !== 'string') {
|
|
1075
|
+
// Fail loudly instead of fabricating a source key that hosts would
|
|
1076
|
+
// route by.
|
|
1077
|
+
throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
|
|
1078
|
+
}
|
|
1079
|
+
// The child's state lives with another runtime; restore a
|
|
1080
|
+
// location-transparent handle constructed from its identity alone.
|
|
1081
|
+
// The handle keeps its persisted address verbatim: the owning
|
|
1082
|
+
// runtime's identity for the child wins over the local parent chain.
|
|
1083
|
+
const handle = createActor.createRemoteActorRef(resolvedActorScope.system, {
|
|
1084
|
+
id: actorId,
|
|
1085
|
+
address: actorData.address,
|
|
1086
|
+
src: actorData.src,
|
|
1087
|
+
parent: resolvedActorScope.self,
|
|
1088
|
+
registryKey: actorData.registryKey,
|
|
1089
|
+
syncSnapshot: actorData.syncSnapshot,
|
|
1090
|
+
incarnation: actorData.incarnation
|
|
1091
|
+
});
|
|
1092
|
+
if (actorData.registryKey) {
|
|
1093
|
+
resolvedActorScope.system._set(actorData.registryKey, handle);
|
|
1094
|
+
}
|
|
1095
|
+
children[actorId] = handle;
|
|
1096
|
+
continue;
|
|
1097
|
+
}
|
|
1038
1098
|
const childState = actorData.snapshot;
|
|
1039
1099
|
const src = actorData.src;
|
|
1040
1100
|
const logic = typeof src === 'string' ? createActor.resolveReferencedActor(this, src) : src;
|
|
@@ -1130,12 +1190,30 @@ class StateMachine {
|
|
|
1130
1190
|
const nodes = Array.from(createActor.getAllStateNodes(createActor.getStateNodes(this.root, snapshotData.value)));
|
|
1131
1191
|
const {
|
|
1132
1192
|
version: _persistedSnapshotVersion,
|
|
1193
|
+
// The legacy system-wide counter: superseded by per-snapshot
|
|
1194
|
+
// `_nextActorIds` plus the child-id fold below; dropped so old and new
|
|
1195
|
+
// snapshots round-trip to the same shape.
|
|
1196
|
+
_nextActorId: _legacyNextActorId,
|
|
1133
1197
|
...persistedRest
|
|
1134
1198
|
} = snapshot;
|
|
1199
|
+
// Fold generated-shaped child ids into the counters as a floor: snapshots
|
|
1200
|
+
// persisted before per-actor counters (or hand-crafted ones) still must
|
|
1201
|
+
// never reuse a live child's id.
|
|
1202
|
+
let restoredCounters = persistedRest._nextActorIds;
|
|
1203
|
+
for (const childId of Object.keys(snapshotChildren)) {
|
|
1204
|
+
const generated = createActor.parseGeneratedActorId(childId);
|
|
1205
|
+
if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
|
|
1206
|
+
restoredCounters = {
|
|
1207
|
+
...restoredCounters,
|
|
1208
|
+
[generated.prefix]: generated.index + 1
|
|
1209
|
+
};
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1135
1212
|
const restoredSnapshot = createActor.createMachineSnapshot({
|
|
1136
1213
|
...persistedRest,
|
|
1137
1214
|
children,
|
|
1138
1215
|
timers,
|
|
1216
|
+
_nextActorIds: restoredCounters,
|
|
1139
1217
|
_nodes: nodes,
|
|
1140
1218
|
value: snapshotData.value,
|
|
1141
1219
|
historyValue: revivedHistoryValue,
|
|
@@ -1150,7 +1228,7 @@ class StateMachine {
|
|
|
1150
1228
|
for (const key of Object.keys(contextPart)) {
|
|
1151
1229
|
const value = contextPart[key];
|
|
1152
1230
|
if (value && typeof value === 'object') {
|
|
1153
|
-
if ('xstate
|
|
1231
|
+
if ('xstate$type' in value && value.xstate$type === createActor.ACTOR_REF_TYPE) {
|
|
1154
1232
|
contextPart[key] = children[value.id];
|
|
1155
1233
|
continue;
|
|
1156
1234
|
}
|
package/dist/{StateMachine-f8c7feca.development.esm.js → StateMachine-1ea29688.development.esm.js}
RENAMED
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import { S as STATE_DELIMITER,
|
|
2
|
-
import { g as assertValid } from './index-
|
|
1
|
+
import { Q as allocateChildId, R as assertChildIdFree, S as reserveChildId, T as STATE_DELIMITER, U as mapValues, t as toArray, V as createInvokeId, W as getDelayedTransitions, Y as getEventDescriptorKey, Z as getCandidates, _ as evaluateCandidate, $ as formatTransition, a0 as NULL_EVENT, a1 as toTransitionConfigArray, a2 as createInvokeTimeoutEventId, a3 as matchesActorSession, a4 as formatRouteTransitions, a5 as resolveStateValue, a6 as getAllStateNodes, x as getStateNodes, a7 as createMachineSnapshot, a8 as isInFinalState, a9 as createInertActorScope, aa as setInertActorScopeSnapshot, a as beginSpawnAllocation, ab as attachSnapshotActorRef, ac as macrostep, ad as isInertActorScope, ae as setSnapshotActorRef, af as cloneMachineSnapshot, ag as transitionNode, g as XSTATE_TIMER, m as matchesEventDescriptor, ah as getTransitionResult, ai as hasEffect, aj as createErrorPlatformEvent, ak as withActorSelf, r as resolveActionsWithContext, al as takeSpawnAllocationCounters, am as mergeActorIdCounters, K as createInitEvent, an as createSpawnEffect, ao as initialMicrostep, ap as toStatePath, aq as isStateId, ar as getStateNodeByPath, as as getPersistedSnapshot, at as createRemoteActorRef, au as resolveReferencedActor, av as createInvokeTimeoutEvent, aw as parseGeneratedActorId, ax as ACTOR_REF_TYPE, k as createActor } from './createActor-f9cc6590.development.esm.js';
|
|
2
|
+
import { g as assertValid } from './index-f284cc7b.development.esm.js';
|
|
3
3
|
|
|
4
4
|
function createSpawner(actorScope, actors, spawnedChildren) {
|
|
5
5
|
return (src, options) => {
|
|
6
6
|
const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
|
|
7
|
+
// Generated ids come from the same transaction allocator as `enq.spawn`,
|
|
8
|
+
// so context-factory allocations persist with the snapshot and never
|
|
9
|
+
// collide with later spawns.
|
|
10
|
+
const id = options?.id ?? allocateChildId(actorScope, referencedSrc ?? src).id;
|
|
11
|
+
if (options?.id !== undefined) {
|
|
12
|
+
assertChildIdFree(actorScope, options.id);
|
|
13
|
+
reserveChildId(actorScope, options.id);
|
|
14
|
+
}
|
|
7
15
|
const actor = actorScope.system.createActorRef(src, {
|
|
8
|
-
id
|
|
16
|
+
id,
|
|
9
17
|
parent: actorScope.self,
|
|
10
18
|
syncSnapshot: options?.syncSnapshot,
|
|
11
19
|
input: options?.input,
|
|
@@ -408,6 +416,16 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
408
416
|
}
|
|
409
417
|
|
|
410
418
|
const STATE_IDENTIFIER = '#';
|
|
419
|
+
function findEventSchema(schemas, eventType) {
|
|
420
|
+
if (!schemas) {
|
|
421
|
+
return undefined;
|
|
422
|
+
}
|
|
423
|
+
if (Object.hasOwn(schemas, eventType)) {
|
|
424
|
+
return schemas[eventType];
|
|
425
|
+
}
|
|
426
|
+
const descriptor = Object.keys(schemas).find(key => matchesEventDescriptor(eventType, key));
|
|
427
|
+
return descriptor === undefined ? undefined : schemas[descriptor];
|
|
428
|
+
}
|
|
411
429
|
let emptyCanActor;
|
|
412
430
|
let emptyCanActorScope;
|
|
413
431
|
function getEmptyCanActor() {
|
|
@@ -452,6 +470,12 @@ class StateMachine {
|
|
|
452
470
|
config, sources, validator) {
|
|
453
471
|
this.config = config;
|
|
454
472
|
this.validator = validator;
|
|
473
|
+
/**
|
|
474
|
+
* @internal Type-only marker for the actor's internal event protocol. Not
|
|
475
|
+
* `declare` (the build's babel pipeline rejects declare class fields); the
|
|
476
|
+
* one `undefined` property this emits per machine instance is inert.
|
|
477
|
+
*/
|
|
478
|
+
this._internalEventType = void 0;
|
|
455
479
|
/** The machine's own version. */
|
|
456
480
|
this.version = void 0;
|
|
457
481
|
this.schemas = void 0;
|
|
@@ -590,9 +614,10 @@ class StateMachine {
|
|
|
590
614
|
}
|
|
591
615
|
const event = value;
|
|
592
616
|
const eventSchemas = this.schemas?.events;
|
|
617
|
+
const internalEventSchemas = this.schemas?.internalEvents;
|
|
593
618
|
const isFrameworkEvent = event.type.startsWith('xstate.') || event.type.startsWith('@xstate.');
|
|
594
|
-
const schema =
|
|
595
|
-
if (eventSchemas && !schema && !isFrameworkEvent) {
|
|
619
|
+
const schema = findEventSchema(internalEventSchemas, event.type) ?? findEventSchema(eventSchemas, event.type);
|
|
620
|
+
if ((eventSchemas || internalEventSchemas) && !schema && !isFrameworkEvent) {
|
|
596
621
|
return {
|
|
597
622
|
issues: [{
|
|
598
623
|
message: `Unknown event '${event.type}' for machine '${this.id}' version '${this.version}'.`
|
|
@@ -628,7 +653,7 @@ class StateMachine {
|
|
|
628
653
|
}
|
|
629
654
|
}
|
|
630
655
|
};
|
|
631
|
-
this.internalEventDescriptors = this.config.internalEvents ?? [];
|
|
656
|
+
this.internalEventDescriptors = [...Object.keys(this.schemas?.internalEvents ?? {}), ...(this.config.internalEvents ?? [])];
|
|
632
657
|
this.options = {
|
|
633
658
|
maxIterations: Infinity,
|
|
634
659
|
...this.config.options
|
|
@@ -724,6 +749,7 @@ class StateMachine {
|
|
|
724
749
|
if (usesInertScope) {
|
|
725
750
|
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
726
751
|
}
|
|
752
|
+
beginSpawnAllocation(resolvedActorScope);
|
|
727
753
|
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
728
754
|
if (fastSnapshot) {
|
|
729
755
|
if (usesInertScope) {
|
|
@@ -919,6 +945,14 @@ class StateMachine {
|
|
|
919
945
|
...nextState.children,
|
|
920
946
|
...children
|
|
921
947
|
};
|
|
948
|
+
// Commit the transaction counters so context-factory allocations
|
|
949
|
+
// persist with the snapshot: a freed id is never handed out again
|
|
950
|
+
// after a restore or in a fresh replay process. (The spawner already
|
|
951
|
+
// registered each child for string-id resolution.)
|
|
952
|
+
const counters = takeSpawnAllocationCounters(actorScope);
|
|
953
|
+
if (counters) {
|
|
954
|
+
nextState._nextActorIds = mergeActorIdCounters(nextState._nextActorIds, counters);
|
|
955
|
+
}
|
|
922
956
|
}
|
|
923
957
|
return nextState;
|
|
924
958
|
}
|
|
@@ -942,6 +976,7 @@ class StateMachine {
|
|
|
942
976
|
}
|
|
943
977
|
const usesInertScope = !actorScope;
|
|
944
978
|
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
979
|
+
beginSpawnAllocation(resolvedActorScope);
|
|
945
980
|
const initEvent = createInitEvent(input); // TODO: fix;
|
|
946
981
|
const internalQueue = [];
|
|
947
982
|
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
@@ -1033,6 +1068,31 @@ class StateMachine {
|
|
|
1033
1068
|
const snapshotChildren = snapshotData.children;
|
|
1034
1069
|
for (const actorId of Object.keys(snapshotChildren)) {
|
|
1035
1070
|
const actorData = snapshotChildren[actorId];
|
|
1071
|
+
if (actorData.remote === true && actorData.address !== undefined) {
|
|
1072
|
+
if (typeof actorData.src !== 'string') {
|
|
1073
|
+
// Fail loudly instead of fabricating a source key that hosts would
|
|
1074
|
+
// route by.
|
|
1075
|
+
throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
|
|
1076
|
+
}
|
|
1077
|
+
// The child's state lives with another runtime; restore a
|
|
1078
|
+
// location-transparent handle constructed from its identity alone.
|
|
1079
|
+
// The handle keeps its persisted address verbatim: the owning
|
|
1080
|
+
// runtime's identity for the child wins over the local parent chain.
|
|
1081
|
+
const handle = createRemoteActorRef(resolvedActorScope.system, {
|
|
1082
|
+
id: actorId,
|
|
1083
|
+
address: actorData.address,
|
|
1084
|
+
src: actorData.src,
|
|
1085
|
+
parent: resolvedActorScope.self,
|
|
1086
|
+
registryKey: actorData.registryKey,
|
|
1087
|
+
syncSnapshot: actorData.syncSnapshot,
|
|
1088
|
+
incarnation: actorData.incarnation
|
|
1089
|
+
});
|
|
1090
|
+
if (actorData.registryKey) {
|
|
1091
|
+
resolvedActorScope.system._set(actorData.registryKey, handle);
|
|
1092
|
+
}
|
|
1093
|
+
children[actorId] = handle;
|
|
1094
|
+
continue;
|
|
1095
|
+
}
|
|
1036
1096
|
const childState = actorData.snapshot;
|
|
1037
1097
|
const src = actorData.src;
|
|
1038
1098
|
const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
|
|
@@ -1128,12 +1188,30 @@ class StateMachine {
|
|
|
1128
1188
|
const nodes = Array.from(getAllStateNodes(getStateNodes(this.root, snapshotData.value)));
|
|
1129
1189
|
const {
|
|
1130
1190
|
version: _persistedSnapshotVersion,
|
|
1191
|
+
// The legacy system-wide counter: superseded by per-snapshot
|
|
1192
|
+
// `_nextActorIds` plus the child-id fold below; dropped so old and new
|
|
1193
|
+
// snapshots round-trip to the same shape.
|
|
1194
|
+
_nextActorId: _legacyNextActorId,
|
|
1131
1195
|
...persistedRest
|
|
1132
1196
|
} = snapshot;
|
|
1197
|
+
// Fold generated-shaped child ids into the counters as a floor: snapshots
|
|
1198
|
+
// persisted before per-actor counters (or hand-crafted ones) still must
|
|
1199
|
+
// never reuse a live child's id.
|
|
1200
|
+
let restoredCounters = persistedRest._nextActorIds;
|
|
1201
|
+
for (const childId of Object.keys(snapshotChildren)) {
|
|
1202
|
+
const generated = parseGeneratedActorId(childId);
|
|
1203
|
+
if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
|
|
1204
|
+
restoredCounters = {
|
|
1205
|
+
...restoredCounters,
|
|
1206
|
+
[generated.prefix]: generated.index + 1
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1133
1210
|
const restoredSnapshot = createMachineSnapshot({
|
|
1134
1211
|
...persistedRest,
|
|
1135
1212
|
children,
|
|
1136
1213
|
timers,
|
|
1214
|
+
_nextActorIds: restoredCounters,
|
|
1137
1215
|
_nodes: nodes,
|
|
1138
1216
|
value: snapshotData.value,
|
|
1139
1217
|
historyValue: revivedHistoryValue,
|
|
@@ -1148,7 +1226,7 @@ class StateMachine {
|
|
|
1148
1226
|
for (const key of Object.keys(contextPart)) {
|
|
1149
1227
|
const value = contextPart[key];
|
|
1150
1228
|
if (value && typeof value === 'object') {
|
|
1151
|
-
if ('xstate
|
|
1229
|
+
if ('xstate$type' in value && value.xstate$type === ACTOR_REF_TYPE) {
|
|
1152
1230
|
contextPart[key] = children[value.id];
|
|
1153
1231
|
continue;
|
|
1154
1232
|
}
|
|
@@ -1,11 +1,19 @@
|
|
|
1
|
-
import { S as STATE_DELIMITER,
|
|
2
|
-
import { g as assertValid } from './index-
|
|
1
|
+
import { Q as allocateChildId, R as assertChildIdFree, S as reserveChildId, T as STATE_DELIMITER, U as mapValues, t as toArray, V as createInvokeId, W as getDelayedTransitions, Y as getEventDescriptorKey, Z as getCandidates, _ as evaluateCandidate, $ as formatTransition, a0 as NULL_EVENT, a1 as toTransitionConfigArray, a2 as createInvokeTimeoutEventId, a3 as matchesActorSession, a4 as formatRouteTransitions, a5 as resolveStateValue, a6 as getAllStateNodes, x as getStateNodes, a7 as createMachineSnapshot, a8 as isInFinalState, a9 as createInertActorScope, aa as setInertActorScopeSnapshot, a as beginSpawnAllocation, ab as attachSnapshotActorRef, ac as macrostep, ad as isInertActorScope, ae as setSnapshotActorRef, af as cloneMachineSnapshot, ag as transitionNode, g as XSTATE_TIMER, m as matchesEventDescriptor, ah as getTransitionResult, ai as hasEffect, aj as createErrorPlatformEvent, ak as withActorSelf, r as resolveActionsWithContext, al as takeSpawnAllocationCounters, am as mergeActorIdCounters, K as createInitEvent, an as createSpawnEffect, ao as initialMicrostep, ap as toStatePath, aq as isStateId, ar as getStateNodeByPath, as as getPersistedSnapshot, at as createRemoteActorRef, au as resolveReferencedActor, av as createInvokeTimeoutEvent, aw as parseGeneratedActorId, ax as ACTOR_REF_TYPE, k as createActor } from './createActor-973c72ad.esm.js';
|
|
2
|
+
import { g as assertValid } from './index-b478f443.esm.js';
|
|
3
3
|
|
|
4
4
|
function createSpawner(actorScope, actors, spawnedChildren) {
|
|
5
5
|
return (src, options) => {
|
|
6
6
|
const referencedSrc = Object.entries(actors).find(([, logic]) => logic === src)?.[0];
|
|
7
|
+
// Generated ids come from the same transaction allocator as `enq.spawn`,
|
|
8
|
+
// so context-factory allocations persist with the snapshot and never
|
|
9
|
+
// collide with later spawns.
|
|
10
|
+
const id = options?.id ?? allocateChildId(actorScope, referencedSrc ?? src).id;
|
|
11
|
+
if (options?.id !== undefined) {
|
|
12
|
+
assertChildIdFree(actorScope, options.id);
|
|
13
|
+
reserveChildId(actorScope, options.id);
|
|
14
|
+
}
|
|
7
15
|
const actor = actorScope.system.createActorRef(src, {
|
|
8
|
-
id
|
|
16
|
+
id,
|
|
9
17
|
parent: actorScope.self,
|
|
10
18
|
syncSnapshot: options?.syncSnapshot,
|
|
11
19
|
input: options?.input,
|
|
@@ -390,6 +398,16 @@ function formatInitialTransition(stateNode, _target) {
|
|
|
390
398
|
}
|
|
391
399
|
|
|
392
400
|
const STATE_IDENTIFIER = '#';
|
|
401
|
+
function findEventSchema(schemas, eventType) {
|
|
402
|
+
if (!schemas) {
|
|
403
|
+
return undefined;
|
|
404
|
+
}
|
|
405
|
+
if (Object.hasOwn(schemas, eventType)) {
|
|
406
|
+
return schemas[eventType];
|
|
407
|
+
}
|
|
408
|
+
const descriptor = Object.keys(schemas).find(key => matchesEventDescriptor(eventType, key));
|
|
409
|
+
return descriptor === undefined ? undefined : schemas[descriptor];
|
|
410
|
+
}
|
|
393
411
|
let emptyCanActor;
|
|
394
412
|
let emptyCanActorScope;
|
|
395
413
|
function getEmptyCanActor() {
|
|
@@ -434,6 +452,12 @@ class StateMachine {
|
|
|
434
452
|
config, sources, validator) {
|
|
435
453
|
this.config = config;
|
|
436
454
|
this.validator = validator;
|
|
455
|
+
/**
|
|
456
|
+
* @internal Type-only marker for the actor's internal event protocol. Not
|
|
457
|
+
* `declare` (the build's babel pipeline rejects declare class fields); the
|
|
458
|
+
* one `undefined` property this emits per machine instance is inert.
|
|
459
|
+
*/
|
|
460
|
+
this._internalEventType = void 0;
|
|
437
461
|
/** The machine's own version. */
|
|
438
462
|
this.version = void 0;
|
|
439
463
|
this.schemas = void 0;
|
|
@@ -561,9 +585,10 @@ class StateMachine {
|
|
|
561
585
|
}
|
|
562
586
|
const event = value;
|
|
563
587
|
const eventSchemas = this.schemas?.events;
|
|
588
|
+
const internalEventSchemas = this.schemas?.internalEvents;
|
|
564
589
|
const isFrameworkEvent = event.type.startsWith('xstate.') || event.type.startsWith('@xstate.');
|
|
565
|
-
const schema =
|
|
566
|
-
if (eventSchemas && !schema && !isFrameworkEvent) {
|
|
590
|
+
const schema = findEventSchema(internalEventSchemas, event.type) ?? findEventSchema(eventSchemas, event.type);
|
|
591
|
+
if ((eventSchemas || internalEventSchemas) && !schema && !isFrameworkEvent) {
|
|
567
592
|
return {
|
|
568
593
|
issues: [{
|
|
569
594
|
message: `Unknown event '${event.type}' for machine '${this.id}' version '${this.version}'.`
|
|
@@ -599,7 +624,7 @@ class StateMachine {
|
|
|
599
624
|
}
|
|
600
625
|
}
|
|
601
626
|
};
|
|
602
|
-
this.internalEventDescriptors = this.config.internalEvents ?? [];
|
|
627
|
+
this.internalEventDescriptors = [...Object.keys(this.schemas?.internalEvents ?? {}), ...(this.config.internalEvents ?? [])];
|
|
603
628
|
this.options = {
|
|
604
629
|
maxIterations: Infinity,
|
|
605
630
|
...this.config.options
|
|
@@ -695,6 +720,7 @@ class StateMachine {
|
|
|
695
720
|
if (usesInertScope) {
|
|
696
721
|
setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
|
|
697
722
|
}
|
|
723
|
+
beginSpawnAllocation(resolvedActorScope);
|
|
698
724
|
const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
|
|
699
725
|
if (fastSnapshot) {
|
|
700
726
|
if (usesInertScope) {
|
|
@@ -890,6 +916,14 @@ class StateMachine {
|
|
|
890
916
|
...nextState.children,
|
|
891
917
|
...children
|
|
892
918
|
};
|
|
919
|
+
// Commit the transaction counters so context-factory allocations
|
|
920
|
+
// persist with the snapshot: a freed id is never handed out again
|
|
921
|
+
// after a restore or in a fresh replay process. (The spawner already
|
|
922
|
+
// registered each child for string-id resolution.)
|
|
923
|
+
const counters = takeSpawnAllocationCounters(actorScope);
|
|
924
|
+
if (counters) {
|
|
925
|
+
nextState._nextActorIds = mergeActorIdCounters(nextState._nextActorIds, counters);
|
|
926
|
+
}
|
|
893
927
|
}
|
|
894
928
|
return nextState;
|
|
895
929
|
}
|
|
@@ -913,6 +947,7 @@ class StateMachine {
|
|
|
913
947
|
}
|
|
914
948
|
const usesInertScope = !actorScope;
|
|
915
949
|
const resolvedActorScope = actorScope ?? createInertActorScope(this);
|
|
950
|
+
beginSpawnAllocation(resolvedActorScope);
|
|
916
951
|
const initEvent = createInitEvent(input); // TODO: fix;
|
|
917
952
|
const internalQueue = [];
|
|
918
953
|
const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
|
|
@@ -1004,6 +1039,31 @@ class StateMachine {
|
|
|
1004
1039
|
const snapshotChildren = snapshotData.children;
|
|
1005
1040
|
for (const actorId of Object.keys(snapshotChildren)) {
|
|
1006
1041
|
const actorData = snapshotChildren[actorId];
|
|
1042
|
+
if (actorData.remote === true && actorData.address !== undefined) {
|
|
1043
|
+
if (typeof actorData.src !== 'string') {
|
|
1044
|
+
// Fail loudly instead of fabricating a source key that hosts would
|
|
1045
|
+
// route by.
|
|
1046
|
+
throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
|
|
1047
|
+
}
|
|
1048
|
+
// The child's state lives with another runtime; restore a
|
|
1049
|
+
// location-transparent handle constructed from its identity alone.
|
|
1050
|
+
// The handle keeps its persisted address verbatim: the owning
|
|
1051
|
+
// runtime's identity for the child wins over the local parent chain.
|
|
1052
|
+
const handle = createRemoteActorRef(resolvedActorScope.system, {
|
|
1053
|
+
id: actorId,
|
|
1054
|
+
address: actorData.address,
|
|
1055
|
+
src: actorData.src,
|
|
1056
|
+
parent: resolvedActorScope.self,
|
|
1057
|
+
registryKey: actorData.registryKey,
|
|
1058
|
+
syncSnapshot: actorData.syncSnapshot,
|
|
1059
|
+
incarnation: actorData.incarnation
|
|
1060
|
+
});
|
|
1061
|
+
if (actorData.registryKey) {
|
|
1062
|
+
resolvedActorScope.system._set(actorData.registryKey, handle);
|
|
1063
|
+
}
|
|
1064
|
+
children[actorId] = handle;
|
|
1065
|
+
continue;
|
|
1066
|
+
}
|
|
1007
1067
|
const childState = actorData.snapshot;
|
|
1008
1068
|
const src = actorData.src;
|
|
1009
1069
|
const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
|
|
@@ -1096,12 +1156,30 @@ class StateMachine {
|
|
|
1096
1156
|
const nodes = Array.from(getAllStateNodes(getStateNodes(this.root, snapshotData.value)));
|
|
1097
1157
|
const {
|
|
1098
1158
|
version: _persistedSnapshotVersion,
|
|
1159
|
+
// The legacy system-wide counter: superseded by per-snapshot
|
|
1160
|
+
// `_nextActorIds` plus the child-id fold below; dropped so old and new
|
|
1161
|
+
// snapshots round-trip to the same shape.
|
|
1162
|
+
_nextActorId: _legacyNextActorId,
|
|
1099
1163
|
...persistedRest
|
|
1100
1164
|
} = snapshot;
|
|
1165
|
+
// Fold generated-shaped child ids into the counters as a floor: snapshots
|
|
1166
|
+
// persisted before per-actor counters (or hand-crafted ones) still must
|
|
1167
|
+
// never reuse a live child's id.
|
|
1168
|
+
let restoredCounters = persistedRest._nextActorIds;
|
|
1169
|
+
for (const childId of Object.keys(snapshotChildren)) {
|
|
1170
|
+
const generated = parseGeneratedActorId(childId);
|
|
1171
|
+
if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
|
|
1172
|
+
restoredCounters = {
|
|
1173
|
+
...restoredCounters,
|
|
1174
|
+
[generated.prefix]: generated.index + 1
|
|
1175
|
+
};
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1101
1178
|
const restoredSnapshot = createMachineSnapshot({
|
|
1102
1179
|
...persistedRest,
|
|
1103
1180
|
children,
|
|
1104
1181
|
timers,
|
|
1182
|
+
_nextActorIds: restoredCounters,
|
|
1105
1183
|
_nodes: nodes,
|
|
1106
1184
|
value: snapshotData.value,
|
|
1107
1185
|
historyValue: revivedHistoryValue,
|
|
@@ -1116,7 +1194,7 @@ class StateMachine {
|
|
|
1116
1194
|
for (const key of Object.keys(contextPart)) {
|
|
1117
1195
|
const value = contextPart[key];
|
|
1118
1196
|
if (value && typeof value === 'object') {
|
|
1119
|
-
if ('xstate
|
|
1197
|
+
if ('xstate$type' in value && value.xstate$type === ACTOR_REF_TYPE) {
|
|
1120
1198
|
contextPart[key] = children[value.id];
|
|
1121
1199
|
continue;
|
|
1122
1200
|
}
|