xstate 6.0.0-alpha.40 → 6.0.0-alpha.41

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.
Files changed (55) hide show
  1. package/dist/{StateMachine-1464d5e4.cjs.js → StateMachine-8e73d782.cjs.js} +65 -4
  2. package/dist/{StateMachine-76ee1d6e.development.cjs.js → StateMachine-db4e6d4b.development.cjs.js} +65 -4
  3. package/dist/{StateMachine-6082c3cf.esm.js → StateMachine-ee89d49f.esm.js} +65 -4
  4. package/dist/{StateMachine-f8c7feca.development.esm.js → StateMachine-f60abe05.development.esm.js} +65 -4
  5. package/dist/{createActor-c0f78b8a.development.cjs.js → createActor-20615484.development.cjs.js} +787 -62
  6. package/dist/{createActor-a211c276.esm.js → createActor-a3f7750f.esm.js} +757 -55
  7. package/dist/{createActor-2a03d4b2.development.esm.js → createActor-c97c04c9.development.esm.js} +767 -62
  8. package/dist/{createActor-d5305cc9.cjs.js → createActor-f3afd774.cjs.js} +777 -55
  9. package/dist/declarations/src/actors/logic.d.ts +0 -3
  10. package/dist/declarations/src/createActor.d.ts +41 -6
  11. package/dist/declarations/src/durable/index.d.ts +75 -8
  12. package/dist/declarations/src/effectDescriptor.d.ts +81 -0
  13. package/dist/declarations/src/fsm.d.ts +1 -0
  14. package/dist/declarations/src/index.d.ts +3 -1
  15. package/dist/declarations/src/inspection.d.ts +11 -1
  16. package/dist/declarations/src/machineVersion.types.d.ts +1 -0
  17. package/dist/declarations/src/runtimeHelpers.d.ts +35 -0
  18. package/dist/declarations/src/system.d.ts +38 -2
  19. package/dist/declarations/src/transitionActions.d.ts +1 -1
  20. package/dist/declarations/src/types.d.ts +18 -0
  21. package/dist/{transition-e8a13c00.esm.js → effectDescriptor-57ae11fa.esm.js} +110 -2
  22. package/dist/{transition-f581ffa6.development.esm.js → effectDescriptor-b7c48ceb.development.esm.js} +110 -2
  23. package/dist/{transition-4ba58b71.development.cjs.js → effectDescriptor-ba9e14f0.development.cjs.js} +110 -1
  24. package/dist/{transition-2dcabac8.cjs.js → effectDescriptor-e2bb61e2.cjs.js} +110 -1
  25. package/dist/{index-21d08fff.cjs.js → index-7fd92683.cjs.js} +9 -53
  26. package/dist/{index-7020402e.esm.js → index-a8ce72f1.esm.js} +6 -50
  27. package/dist/{index-17f889df.development.esm.js → index-b5b1b2bc.development.esm.js} +6 -50
  28. package/dist/{index-3d1368f7.development.cjs.js → index-d42efc07.development.cjs.js} +9 -53
  29. package/dist/xstate-actors.cjs.js +2 -2
  30. package/dist/xstate-actors.development.cjs.js +2 -2
  31. package/dist/xstate-actors.development.esm.js +2 -2
  32. package/dist/xstate-actors.esm.js +2 -2
  33. package/dist/xstate-actors.umd.min.js +1 -1
  34. package/dist/xstate-actors.umd.min.js.map +1 -1
  35. package/dist/xstate-durable.cjs.js +245 -24
  36. package/dist/xstate-durable.development.cjs.js +245 -24
  37. package/dist/xstate-durable.development.esm.js +243 -22
  38. package/dist/xstate-durable.esm.js +243 -22
  39. package/dist/xstate-durable.umd.min.js +1 -1
  40. package/dist/xstate-durable.umd.min.js.map +1 -1
  41. package/dist/xstate-graph.cjs.js +3 -3
  42. package/dist/xstate-graph.development.cjs.js +3 -3
  43. package/dist/xstate-graph.development.esm.js +3 -3
  44. package/dist/xstate-graph.esm.js +3 -3
  45. package/dist/xstate-graph.umd.min.js +1 -1
  46. package/dist/xstate-graph.umd.min.js.map +1 -1
  47. package/dist/xstate.cjs.js +20 -9
  48. package/dist/xstate.cjs.mjs +5 -0
  49. package/dist/xstate.development.cjs.js +20 -9
  50. package/dist/xstate.development.cjs.mjs +5 -0
  51. package/dist/xstate.development.esm.js +12 -6
  52. package/dist/xstate.esm.js +12 -6
  53. package/dist/xstate.umd.min.js +1 -1
  54. package/dist/xstate.umd.min.js.map +1 -1
  55. package/package.json +1 -1
@@ -1,13 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var createActor = require('./createActor-d5305cc9.cjs.js');
4
- var dist_xstateActors = require('./index-21d08fff.cjs.js');
3
+ var createActor = require('./createActor-f3afd774.cjs.js');
4
+ var dist_xstateActors = require('./index-7fd92683.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: options?.id,
18
+ id,
11
19
  parent: actorScope.self,
12
20
  syncSnapshot: options?.syncSnapshot,
13
21
  input: options?.input,
@@ -697,6 +705,7 @@ class StateMachine {
697
705
  if (usesInertScope) {
698
706
  createActor.setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
699
707
  }
708
+ createActor.beginSpawnAllocation(resolvedActorScope);
700
709
  const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
701
710
  if (fastSnapshot) {
702
711
  if (usesInertScope) {
@@ -892,6 +901,14 @@ class StateMachine {
892
901
  ...nextState.children,
893
902
  ...children
894
903
  };
904
+ // Commit the transaction counters so context-factory allocations
905
+ // persist with the snapshot: a freed id is never handed out again
906
+ // after a restore or in a fresh replay process. (The spawner already
907
+ // registered each child for string-id resolution.)
908
+ const counters = createActor.takeSpawnAllocationCounters(actorScope);
909
+ if (counters) {
910
+ nextState._nextActorIds = createActor.mergeActorIdCounters(nextState._nextActorIds, counters);
911
+ }
895
912
  }
896
913
  return nextState;
897
914
  }
@@ -915,6 +932,7 @@ class StateMachine {
915
932
  }
916
933
  const usesInertScope = !actorScope;
917
934
  const resolvedActorScope = actorScope ?? createActor.createInertActorScope(this);
935
+ createActor.beginSpawnAllocation(resolvedActorScope);
918
936
  const initEvent = createActor.createInitEvent(input); // TODO: fix;
919
937
  const internalQueue = [];
920
938
  const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
@@ -1006,6 +1024,31 @@ class StateMachine {
1006
1024
  const snapshotChildren = snapshotData.children;
1007
1025
  for (const actorId of Object.keys(snapshotChildren)) {
1008
1026
  const actorData = snapshotChildren[actorId];
1027
+ if (actorData.remote === true && actorData.address !== undefined) {
1028
+ if (typeof actorData.src !== 'string') {
1029
+ // Fail loudly instead of fabricating a source key that hosts would
1030
+ // route by.
1031
+ throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
1032
+ }
1033
+ // The child's state lives with another runtime; restore a
1034
+ // location-transparent handle constructed from its identity alone.
1035
+ // The handle keeps its persisted address verbatim: the owning
1036
+ // runtime's identity for the child wins over the local parent chain.
1037
+ const handle = createActor.createRemoteActorRef(resolvedActorScope.system, {
1038
+ id: actorId,
1039
+ address: actorData.address,
1040
+ src: actorData.src,
1041
+ parent: resolvedActorScope.self,
1042
+ registryKey: actorData.registryKey,
1043
+ syncSnapshot: actorData.syncSnapshot,
1044
+ incarnation: actorData.incarnation
1045
+ });
1046
+ if (actorData.registryKey) {
1047
+ resolvedActorScope.system._set(actorData.registryKey, handle);
1048
+ }
1049
+ children[actorId] = handle;
1050
+ continue;
1051
+ }
1009
1052
  const childState = actorData.snapshot;
1010
1053
  const src = actorData.src;
1011
1054
  const logic = typeof src === 'string' ? createActor.resolveReferencedActor(this, src) : src;
@@ -1098,12 +1141,30 @@ class StateMachine {
1098
1141
  const nodes = Array.from(createActor.getAllStateNodes(createActor.getStateNodes(this.root, snapshotData.value)));
1099
1142
  const {
1100
1143
  version: _persistedSnapshotVersion,
1144
+ // The legacy system-wide counter: superseded by per-snapshot
1145
+ // `_nextActorIds` plus the child-id fold below; dropped so old and new
1146
+ // snapshots round-trip to the same shape.
1147
+ _nextActorId: _legacyNextActorId,
1101
1148
  ...persistedRest
1102
1149
  } = snapshot;
1150
+ // Fold generated-shaped child ids into the counters as a floor: snapshots
1151
+ // persisted before per-actor counters (or hand-crafted ones) still must
1152
+ // never reuse a live child's id.
1153
+ let restoredCounters = persistedRest._nextActorIds;
1154
+ for (const childId of Object.keys(snapshotChildren)) {
1155
+ const generated = createActor.parseGeneratedActorId(childId);
1156
+ if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
1157
+ restoredCounters = {
1158
+ ...restoredCounters,
1159
+ [generated.prefix]: generated.index + 1
1160
+ };
1161
+ }
1162
+ }
1103
1163
  const restoredSnapshot = createActor.createMachineSnapshot({
1104
1164
  ...persistedRest,
1105
1165
  children,
1106
1166
  timers,
1167
+ _nextActorIds: restoredCounters,
1107
1168
  _nodes: nodes,
1108
1169
  value: snapshotData.value,
1109
1170
  historyValue: revivedHistoryValue,
@@ -1118,7 +1179,7 @@ class StateMachine {
1118
1179
  for (const key of Object.keys(contextPart)) {
1119
1180
  const value = contextPart[key];
1120
1181
  if (value && typeof value === 'object') {
1121
- if ('xstate$$type' in value && value.xstate$$type === createActor.$$ACTOR_TYPE) {
1182
+ if ('xstate$type' in value && value.xstate$type === createActor.ACTOR_REF_TYPE) {
1122
1183
  contextPart[key] = children[value.id];
1123
1184
  continue;
1124
1185
  }
@@ -1,13 +1,21 @@
1
1
  'use strict';
2
2
 
3
- var createActor = require('./createActor-c0f78b8a.development.cjs.js');
4
- var dist_xstateActors = require('./index-3d1368f7.development.cjs.js');
3
+ var createActor = require('./createActor-20615484.development.cjs.js');
4
+ var dist_xstateActors = require('./index-d42efc07.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: options?.id,
18
+ id,
11
19
  parent: actorScope.self,
12
20
  syncSnapshot: options?.syncSnapshot,
13
21
  input: options?.input,
@@ -726,6 +734,7 @@ class StateMachine {
726
734
  if (usesInertScope) {
727
735
  createActor.setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
728
736
  }
737
+ createActor.beginSpawnAllocation(resolvedActorScope);
729
738
  const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
730
739
  if (fastSnapshot) {
731
740
  if (usesInertScope) {
@@ -921,6 +930,14 @@ class StateMachine {
921
930
  ...nextState.children,
922
931
  ...children
923
932
  };
933
+ // Commit the transaction counters so context-factory allocations
934
+ // persist with the snapshot: a freed id is never handed out again
935
+ // after a restore or in a fresh replay process. (The spawner already
936
+ // registered each child for string-id resolution.)
937
+ const counters = createActor.takeSpawnAllocationCounters(actorScope);
938
+ if (counters) {
939
+ nextState._nextActorIds = createActor.mergeActorIdCounters(nextState._nextActorIds, counters);
940
+ }
924
941
  }
925
942
  return nextState;
926
943
  }
@@ -944,6 +961,7 @@ class StateMachine {
944
961
  }
945
962
  const usesInertScope = !actorScope;
946
963
  const resolvedActorScope = actorScope ?? createActor.createInertActorScope(this);
964
+ createActor.beginSpawnAllocation(resolvedActorScope);
947
965
  const initEvent = createActor.createInitEvent(input); // TODO: fix;
948
966
  const internalQueue = [];
949
967
  const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
@@ -1035,6 +1053,31 @@ class StateMachine {
1035
1053
  const snapshotChildren = snapshotData.children;
1036
1054
  for (const actorId of Object.keys(snapshotChildren)) {
1037
1055
  const actorData = snapshotChildren[actorId];
1056
+ if (actorData.remote === true && actorData.address !== undefined) {
1057
+ if (typeof actorData.src !== 'string') {
1058
+ // Fail loudly instead of fabricating a source key that hosts would
1059
+ // route by.
1060
+ throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
1061
+ }
1062
+ // The child's state lives with another runtime; restore a
1063
+ // location-transparent handle constructed from its identity alone.
1064
+ // The handle keeps its persisted address verbatim: the owning
1065
+ // runtime's identity for the child wins over the local parent chain.
1066
+ const handle = createActor.createRemoteActorRef(resolvedActorScope.system, {
1067
+ id: actorId,
1068
+ address: actorData.address,
1069
+ src: actorData.src,
1070
+ parent: resolvedActorScope.self,
1071
+ registryKey: actorData.registryKey,
1072
+ syncSnapshot: actorData.syncSnapshot,
1073
+ incarnation: actorData.incarnation
1074
+ });
1075
+ if (actorData.registryKey) {
1076
+ resolvedActorScope.system._set(actorData.registryKey, handle);
1077
+ }
1078
+ children[actorId] = handle;
1079
+ continue;
1080
+ }
1038
1081
  const childState = actorData.snapshot;
1039
1082
  const src = actorData.src;
1040
1083
  const logic = typeof src === 'string' ? createActor.resolveReferencedActor(this, src) : src;
@@ -1130,12 +1173,30 @@ class StateMachine {
1130
1173
  const nodes = Array.from(createActor.getAllStateNodes(createActor.getStateNodes(this.root, snapshotData.value)));
1131
1174
  const {
1132
1175
  version: _persistedSnapshotVersion,
1176
+ // The legacy system-wide counter: superseded by per-snapshot
1177
+ // `_nextActorIds` plus the child-id fold below; dropped so old and new
1178
+ // snapshots round-trip to the same shape.
1179
+ _nextActorId: _legacyNextActorId,
1133
1180
  ...persistedRest
1134
1181
  } = snapshot;
1182
+ // Fold generated-shaped child ids into the counters as a floor: snapshots
1183
+ // persisted before per-actor counters (or hand-crafted ones) still must
1184
+ // never reuse a live child's id.
1185
+ let restoredCounters = persistedRest._nextActorIds;
1186
+ for (const childId of Object.keys(snapshotChildren)) {
1187
+ const generated = createActor.parseGeneratedActorId(childId);
1188
+ if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
1189
+ restoredCounters = {
1190
+ ...restoredCounters,
1191
+ [generated.prefix]: generated.index + 1
1192
+ };
1193
+ }
1194
+ }
1135
1195
  const restoredSnapshot = createActor.createMachineSnapshot({
1136
1196
  ...persistedRest,
1137
1197
  children,
1138
1198
  timers,
1199
+ _nextActorIds: restoredCounters,
1139
1200
  _nodes: nodes,
1140
1201
  value: snapshotData.value,
1141
1202
  historyValue: revivedHistoryValue,
@@ -1150,7 +1211,7 @@ class StateMachine {
1150
1211
  for (const key of Object.keys(contextPart)) {
1151
1212
  const value = contextPart[key];
1152
1213
  if (value && typeof value === 'object') {
1153
- if ('xstate$$type' in value && value.xstate$$type === createActor.$$ACTOR_TYPE) {
1214
+ if ('xstate$type' in value && value.xstate$type === createActor.ACTOR_REF_TYPE) {
1154
1215
  contextPart[key] = children[value.id];
1155
1216
  continue;
1156
1217
  }
@@ -1,11 +1,19 @@
1
- import { S as STATE_DELIMITER, I as mapValues, t as toArray, J as createInvokeId, K as getDelayedTransitions, L as getEventDescriptorKey, M as getCandidates, N as evaluateCandidate, O as formatTransition, P as NULL_EVENT, Q as toTransitionConfigArray, R as createInvokeTimeoutEventId, T as matchesActorSession, U as formatRouteTransitions, V as resolveStateValue, W as getAllStateNodes, v as getStateNodes, Y as createMachineSnapshot, Z as isInFinalState, _ as createInertActorScope, $ as setInertActorScopeSnapshot, a0 as attachSnapshotActorRef, a1 as macrostep, a2 as isInertActorScope, a3 as setSnapshotActorRef, a4 as cloneMachineSnapshot, a5 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a6 as getTransitionResult, a7 as hasEffect, a8 as createErrorPlatformEvent, a9 as withActorSelf, r as resolveActionsWithContext, F as createInitEvent, aa as createSpawnEffect, ab as initialMicrostep, ac as toStatePath, ad as isStateId, ae as getStateNodeByPath, af as getPersistedSnapshot, ag as resolveReferencedActor, ah as createInvokeTimeoutEvent, ai as $$ACTOR_TYPE, j as createActor } from './createActor-a211c276.esm.js';
2
- import { g as assertValid } from './index-7020402e.esm.js';
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-a3f7750f.esm.js';
2
+ import { g as assertValid } from './index-a8ce72f1.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: options?.id,
16
+ id,
9
17
  parent: actorScope.self,
10
18
  syncSnapshot: options?.syncSnapshot,
11
19
  input: options?.input,
@@ -695,6 +703,7 @@ class StateMachine {
695
703
  if (usesInertScope) {
696
704
  setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
697
705
  }
706
+ beginSpawnAllocation(resolvedActorScope);
698
707
  const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
699
708
  if (fastSnapshot) {
700
709
  if (usesInertScope) {
@@ -890,6 +899,14 @@ class StateMachine {
890
899
  ...nextState.children,
891
900
  ...children
892
901
  };
902
+ // Commit the transaction counters so context-factory allocations
903
+ // persist with the snapshot: a freed id is never handed out again
904
+ // after a restore or in a fresh replay process. (The spawner already
905
+ // registered each child for string-id resolution.)
906
+ const counters = takeSpawnAllocationCounters(actorScope);
907
+ if (counters) {
908
+ nextState._nextActorIds = mergeActorIdCounters(nextState._nextActorIds, counters);
909
+ }
893
910
  }
894
911
  return nextState;
895
912
  }
@@ -913,6 +930,7 @@ class StateMachine {
913
930
  }
914
931
  const usesInertScope = !actorScope;
915
932
  const resolvedActorScope = actorScope ?? createInertActorScope(this);
933
+ beginSpawnAllocation(resolvedActorScope);
916
934
  const initEvent = createInitEvent(input); // TODO: fix;
917
935
  const internalQueue = [];
918
936
  const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
@@ -1004,6 +1022,31 @@ class StateMachine {
1004
1022
  const snapshotChildren = snapshotData.children;
1005
1023
  for (const actorId of Object.keys(snapshotChildren)) {
1006
1024
  const actorData = snapshotChildren[actorId];
1025
+ if (actorData.remote === true && actorData.address !== undefined) {
1026
+ if (typeof actorData.src !== 'string') {
1027
+ // Fail loudly instead of fabricating a source key that hosts would
1028
+ // route by.
1029
+ throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
1030
+ }
1031
+ // The child's state lives with another runtime; restore a
1032
+ // location-transparent handle constructed from its identity alone.
1033
+ // The handle keeps its persisted address verbatim: the owning
1034
+ // runtime's identity for the child wins over the local parent chain.
1035
+ const handle = createRemoteActorRef(resolvedActorScope.system, {
1036
+ id: actorId,
1037
+ address: actorData.address,
1038
+ src: actorData.src,
1039
+ parent: resolvedActorScope.self,
1040
+ registryKey: actorData.registryKey,
1041
+ syncSnapshot: actorData.syncSnapshot,
1042
+ incarnation: actorData.incarnation
1043
+ });
1044
+ if (actorData.registryKey) {
1045
+ resolvedActorScope.system._set(actorData.registryKey, handle);
1046
+ }
1047
+ children[actorId] = handle;
1048
+ continue;
1049
+ }
1007
1050
  const childState = actorData.snapshot;
1008
1051
  const src = actorData.src;
1009
1052
  const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
@@ -1096,12 +1139,30 @@ class StateMachine {
1096
1139
  const nodes = Array.from(getAllStateNodes(getStateNodes(this.root, snapshotData.value)));
1097
1140
  const {
1098
1141
  version: _persistedSnapshotVersion,
1142
+ // The legacy system-wide counter: superseded by per-snapshot
1143
+ // `_nextActorIds` plus the child-id fold below; dropped so old and new
1144
+ // snapshots round-trip to the same shape.
1145
+ _nextActorId: _legacyNextActorId,
1099
1146
  ...persistedRest
1100
1147
  } = snapshot;
1148
+ // Fold generated-shaped child ids into the counters as a floor: snapshots
1149
+ // persisted before per-actor counters (or hand-crafted ones) still must
1150
+ // never reuse a live child's id.
1151
+ let restoredCounters = persistedRest._nextActorIds;
1152
+ for (const childId of Object.keys(snapshotChildren)) {
1153
+ const generated = parseGeneratedActorId(childId);
1154
+ if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
1155
+ restoredCounters = {
1156
+ ...restoredCounters,
1157
+ [generated.prefix]: generated.index + 1
1158
+ };
1159
+ }
1160
+ }
1101
1161
  const restoredSnapshot = createMachineSnapshot({
1102
1162
  ...persistedRest,
1103
1163
  children,
1104
1164
  timers,
1165
+ _nextActorIds: restoredCounters,
1105
1166
  _nodes: nodes,
1106
1167
  value: snapshotData.value,
1107
1168
  historyValue: revivedHistoryValue,
@@ -1116,7 +1177,7 @@ class StateMachine {
1116
1177
  for (const key of Object.keys(contextPart)) {
1117
1178
  const value = contextPart[key];
1118
1179
  if (value && typeof value === 'object') {
1119
- if ('xstate$$type' in value && value.xstate$$type === $$ACTOR_TYPE) {
1180
+ if ('xstate$type' in value && value.xstate$type === ACTOR_REF_TYPE) {
1120
1181
  contextPart[key] = children[value.id];
1121
1182
  continue;
1122
1183
  }
@@ -1,11 +1,19 @@
1
- import { S as STATE_DELIMITER, I as mapValues, t as toArray, J as createInvokeId, K as getDelayedTransitions, L as getEventDescriptorKey, M as getCandidates, N as evaluateCandidate, O as formatTransition, P as NULL_EVENT, Q as toTransitionConfigArray, R as createInvokeTimeoutEventId, T as matchesActorSession, U as formatRouteTransitions, V as resolveStateValue, W as getAllStateNodes, v as getStateNodes, Y as createMachineSnapshot, Z as isInFinalState, _ as createInertActorScope, $ as setInertActorScopeSnapshot, a0 as attachSnapshotActorRef, a1 as macrostep, a2 as isInertActorScope, a3 as setSnapshotActorRef, a4 as cloneMachineSnapshot, a5 as transitionNode, e as XSTATE_TIMER, m as matchesEventDescriptor, a6 as getTransitionResult, a7 as hasEffect, a8 as createErrorPlatformEvent, a9 as withActorSelf, r as resolveActionsWithContext, F as createInitEvent, aa as createSpawnEffect, ab as initialMicrostep, ac as toStatePath, ad as isStateId, ae as getStateNodeByPath, af as getPersistedSnapshot, ag as resolveReferencedActor, ah as createInvokeTimeoutEvent, ai as $$ACTOR_TYPE, j as createActor } from './createActor-2a03d4b2.development.esm.js';
2
- import { g as assertValid } from './index-17f889df.development.esm.js';
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-c97c04c9.development.esm.js';
2
+ import { g as assertValid } from './index-b5b1b2bc.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: options?.id,
16
+ id,
9
17
  parent: actorScope.self,
10
18
  syncSnapshot: options?.syncSnapshot,
11
19
  input: options?.input,
@@ -724,6 +732,7 @@ class StateMachine {
724
732
  if (usesInertScope) {
725
733
  setInertActorScopeSnapshot(resolvedActorScope, snapshot, false);
726
734
  }
735
+ beginSpawnAllocation(resolvedActorScope);
727
736
  const fastSnapshot = this._transitionFast(snapshot, event, resolvedActorScope);
728
737
  if (fastSnapshot) {
729
738
  if (usesInertScope) {
@@ -919,6 +928,14 @@ class StateMachine {
919
928
  ...nextState.children,
920
929
  ...children
921
930
  };
931
+ // Commit the transaction counters so context-factory allocations
932
+ // persist with the snapshot: a freed id is never handed out again
933
+ // after a restore or in a fresh replay process. (The spawner already
934
+ // registered each child for string-id resolution.)
935
+ const counters = takeSpawnAllocationCounters(actorScope);
936
+ if (counters) {
937
+ nextState._nextActorIds = mergeActorIdCounters(nextState._nextActorIds, counters);
938
+ }
922
939
  }
923
940
  return nextState;
924
941
  }
@@ -942,6 +959,7 @@ class StateMachine {
942
959
  }
943
960
  const usesInertScope = !actorScope;
944
961
  const resolvedActorScope = actorScope ?? createInertActorScope(this);
962
+ beginSpawnAllocation(resolvedActorScope);
945
963
  const initEvent = createInitEvent(input); // TODO: fix;
946
964
  const internalQueue = [];
947
965
  const preInitialState = this._getPreInitialState(resolvedActorScope, initEvent);
@@ -1033,6 +1051,31 @@ class StateMachine {
1033
1051
  const snapshotChildren = snapshotData.children;
1034
1052
  for (const actorId of Object.keys(snapshotChildren)) {
1035
1053
  const actorData = snapshotChildren[actorId];
1054
+ if (actorData.remote === true && actorData.address !== undefined) {
1055
+ if (typeof actorData.src !== 'string') {
1056
+ // Fail loudly instead of fabricating a source key that hosts would
1057
+ // route by.
1058
+ throw new Error(`Unable to restore remote child '${actorId}': a child referenced by address requires a registered source key.`);
1059
+ }
1060
+ // The child's state lives with another runtime; restore a
1061
+ // location-transparent handle constructed from its identity alone.
1062
+ // The handle keeps its persisted address verbatim: the owning
1063
+ // runtime's identity for the child wins over the local parent chain.
1064
+ const handle = createRemoteActorRef(resolvedActorScope.system, {
1065
+ id: actorId,
1066
+ address: actorData.address,
1067
+ src: actorData.src,
1068
+ parent: resolvedActorScope.self,
1069
+ registryKey: actorData.registryKey,
1070
+ syncSnapshot: actorData.syncSnapshot,
1071
+ incarnation: actorData.incarnation
1072
+ });
1073
+ if (actorData.registryKey) {
1074
+ resolvedActorScope.system._set(actorData.registryKey, handle);
1075
+ }
1076
+ children[actorId] = handle;
1077
+ continue;
1078
+ }
1036
1079
  const childState = actorData.snapshot;
1037
1080
  const src = actorData.src;
1038
1081
  const logic = typeof src === 'string' ? resolveReferencedActor(this, src) : src;
@@ -1128,12 +1171,30 @@ class StateMachine {
1128
1171
  const nodes = Array.from(getAllStateNodes(getStateNodes(this.root, snapshotData.value)));
1129
1172
  const {
1130
1173
  version: _persistedSnapshotVersion,
1174
+ // The legacy system-wide counter: superseded by per-snapshot
1175
+ // `_nextActorIds` plus the child-id fold below; dropped so old and new
1176
+ // snapshots round-trip to the same shape.
1177
+ _nextActorId: _legacyNextActorId,
1131
1178
  ...persistedRest
1132
1179
  } = snapshot;
1180
+ // Fold generated-shaped child ids into the counters as a floor: snapshots
1181
+ // persisted before per-actor counters (or hand-crafted ones) still must
1182
+ // never reuse a live child's id.
1183
+ let restoredCounters = persistedRest._nextActorIds;
1184
+ for (const childId of Object.keys(snapshotChildren)) {
1185
+ const generated = parseGeneratedActorId(childId);
1186
+ if (generated && (restoredCounters?.[generated.prefix] ?? 0) <= generated.index) {
1187
+ restoredCounters = {
1188
+ ...restoredCounters,
1189
+ [generated.prefix]: generated.index + 1
1190
+ };
1191
+ }
1192
+ }
1133
1193
  const restoredSnapshot = createMachineSnapshot({
1134
1194
  ...persistedRest,
1135
1195
  children,
1136
1196
  timers,
1197
+ _nextActorIds: restoredCounters,
1137
1198
  _nodes: nodes,
1138
1199
  value: snapshotData.value,
1139
1200
  historyValue: revivedHistoryValue,
@@ -1148,7 +1209,7 @@ class StateMachine {
1148
1209
  for (const key of Object.keys(contextPart)) {
1149
1210
  const value = contextPart[key];
1150
1211
  if (value && typeof value === 'object') {
1151
- if ('xstate$$type' in value && value.xstate$$type === $$ACTOR_TYPE) {
1212
+ if ('xstate$type' in value && value.xstate$type === ACTOR_REF_TYPE) {
1152
1213
  contextPart[key] = children[value.id];
1153
1214
  continue;
1154
1215
  }