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.
Files changed (79) hide show
  1. package/dist/{createActor-551369be.development.esm.js → createActor-0250284a.development.esm.js} +244 -41
  2. package/dist/{createActor-cbe3abac.esm.js → createActor-20a97166.esm.js} +243 -40
  3. package/dist/{createActor-a49ae0ce.development.cjs.js → createActor-c029d29f.development.cjs.js} +245 -40
  4. package/dist/{createActor-25900f76.cjs.js → createActor-c91c9ffe.cjs.js} +244 -39
  5. package/dist/declarations/src/createActor.d.ts +3 -1
  6. package/dist/declarations/src/createMachine.d.ts +6 -3
  7. package/dist/declarations/src/durable/index.d.ts +43 -8
  8. package/dist/declarations/src/effectDescriptor.d.ts +2 -2
  9. package/dist/declarations/src/machineVersion.types.d.ts +2 -2
  10. package/dist/declarations/src/setup.d.ts +2 -2
  11. package/dist/declarations/src/systemTransition.d.ts +1 -1
  12. package/dist/declarations/src/types.d.ts +4 -2
  13. package/dist/declarations/src/types.v6.d.ts +37 -2
  14. package/dist/{effectDescriptor-f73da4ec.development.cjs.js → effectDescriptor-3fff5c51.development.cjs.js} +5 -5
  15. package/dist/{effectDescriptor-2fa27c54.cjs.js → effectDescriptor-47f73e7e.cjs.js} +5 -5
  16. package/dist/{effectDescriptor-321a8ce9.development.esm.js → effectDescriptor-5ac7dccb.development.esm.js} +5 -5
  17. package/dist/{effectDescriptor-d8b0f749.esm.js → effectDescriptor-e93df910.esm.js} +5 -5
  18. package/dist/{machineSchemas-88d01821.cjs.js → legacySnapshot-8d595687.cjs.js} +117 -1
  19. package/dist/{machineSchemas-45c21bc2.esm.js → legacySnapshot-9e06feb4.esm.js} +116 -2
  20. package/dist/{machineSchemas-b5736804.development.esm.js → legacySnapshot-ae6594a7.development.esm.js} +117 -3
  21. package/dist/{machineSchemas-6d96bef4.development.cjs.js → legacySnapshot-ebf0b2b8.development.cjs.js} +118 -2
  22. package/dist/xstate-actors.cjs.js +1 -1
  23. package/dist/xstate-actors.development.cjs.js +1 -1
  24. package/dist/xstate-actors.development.esm.js +2 -2
  25. package/dist/xstate-actors.esm.js +2 -2
  26. package/dist/xstate-actors.umd.min.js +1 -1
  27. package/dist/xstate-actors.umd.min.js.map +1 -1
  28. package/dist/xstate-durable.cjs.js +120 -10
  29. package/dist/xstate-durable.development.cjs.js +120 -10
  30. package/dist/xstate-durable.development.esm.js +120 -10
  31. package/dist/xstate-durable.esm.js +120 -10
  32. package/dist/xstate-durable.umd.min.js +1 -1
  33. package/dist/xstate-durable.umd.min.js.map +1 -1
  34. package/dist/xstate-fsm.cjs.js +4 -4
  35. package/dist/xstate-fsm.development.cjs.js +4 -4
  36. package/dist/xstate-fsm.development.esm.js +4 -4
  37. package/dist/xstate-fsm.esm.js +4 -4
  38. package/dist/xstate-fsm.umd.min.js +1 -1
  39. package/dist/xstate-fsm.umd.min.js.map +1 -1
  40. package/dist/xstate-graph.cjs.js +1 -1
  41. package/dist/xstate-graph.development.cjs.js +1 -1
  42. package/dist/xstate-graph.development.esm.js +2 -2
  43. package/dist/xstate-graph.esm.js +2 -2
  44. package/dist/xstate-graph.umd.min.js +1 -1
  45. package/dist/xstate-graph.umd.min.js.map +1 -1
  46. package/dist/xstate-persist.cjs.js +23 -12
  47. package/dist/xstate-persist.development.cjs.js +23 -12
  48. package/dist/xstate-persist.development.esm.js +17 -6
  49. package/dist/xstate-persist.esm.js +17 -6
  50. package/dist/xstate-persist.umd.min.js +1 -1
  51. package/dist/xstate-persist.umd.min.js.map +1 -1
  52. package/dist/xstate-validation.cjs.js +1 -1
  53. package/dist/xstate-validation.development.cjs.js +1 -1
  54. package/dist/xstate-validation.development.esm.js +1 -1
  55. package/dist/xstate-validation.esm.js +1 -1
  56. package/dist/xstate.cjs.js +63 -51
  57. package/dist/xstate.development.cjs.js +63 -51
  58. package/dist/xstate.development.esm.js +53 -41
  59. package/dist/xstate.esm.js +53 -41
  60. package/dist/xstate.umd.min.js +1 -1
  61. package/dist/xstate.umd.min.js.map +1 -1
  62. package/docs/api-stability.json +267 -249
  63. package/docs/backend-workflows.md +3 -3
  64. package/docs/durable-execution.md +72 -48
  65. package/docs/errors.md +2 -2
  66. package/docs/examples.md +34 -34
  67. package/docs/fsm.md +2 -1
  68. package/docs/guards.md +1 -1
  69. package/docs/index.md +1 -1
  70. package/docs/invoke.md +34 -2
  71. package/docs/persistence.md +16 -10
  72. package/docs/serialization.md +1 -1
  73. package/docs/setup-and-provide.md +3 -3
  74. package/docs/spawn.md +1 -1
  75. package/docs/system-transitions.md +6 -6
  76. package/docs/tutorial.md +5 -5
  77. package/docs/typescript.md +9 -0
  78. package/docs/xstate-v5-to-v6.md +17 -17
  79. 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-551369be.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-551369be.development.esm.js';
5
- import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema } from './machineSchemas-b5736804.development.esm.js';
6
- export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './machineSchemas-b5736804.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-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-321a8ce9.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-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.$actor, source.incarnation, key ? serializeTimerKey(key) : event.type]);
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.$actor === 'string' && typeof value.incarnation === 'string';
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
- $systemMapper: mappers.get(value)
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
- $actor: value.address,
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
- $stateNode: value.id
2148
+ '@stateNode': value.id
2149
2149
  };
2150
2150
  } else if (value instanceof Error) {
2151
2151
  result = {
2152
- $error: value.name,
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
- $actor: actor.address,
2264
+ '@actor': actor.address,
2256
2265
  incarnation: actor.sessionId
2257
2266
  };
2258
2267
  }
2259
2268
  current(ref) {
2260
- const actor = this.snapshot.actors[ref.$actor];
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.$systemMapper === 'string') {
2267
- const mapper = Object.hasOwn(this.mappers, value.$systemMapper) && this.mappers[value.$systemMapper];
2268
- if (!mapper) throw new Error(`Missing pure mapper '${value.$systemMapper}'.`);
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.$stateNode === 'string') return machine.getStateNodeById(value.$stateNode);
2272
- if (typeof value.$error === 'string') {
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.$error;
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.$actor !== source.$actor || target.incarnation !== source.incarnation || !actor.parent || this.current(actor.parent)?.snapshot.status !== 'active') continue;
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
- $actor: actor.address,
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?.$actor === parent.$actor && actor.parent.incarnation === parent.incarnation) this.stop({
2312
- $actor: actor.address,
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.$actor.split('/').at(-1),
2354
- address: ref.$actor,
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.$actor === actor.address && ref.incarnation === actor.sessionId) delete this.snapshot.registry[key];
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
- $actor: address,
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.$actor + '/' : ''}${encodeAddressSegment(id)}`;
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
- $actor: address,
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
- $actor: address,
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.$actor] = {
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.$actor === ref.$actor && timer.source.incarnation === ref.incarnation && (cancelled === undefined || timerKey === cancelled)) delete this.snapshot.timers[timerKey];
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.$actor];
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
- $actor: target.address,
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.$actor] = {
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.$actor !== ref.$actor || message.target.incarnation !== ref.incarnation);
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.$actor !== ref.$actor || effect.source.incarnation !== ref.incarnation) continue;
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.$actor !== actor.address || message.source.incarnation !== actor.incarnation)) {
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.$actor === path && pending.source.incarnation === actor.incarnation && pending.occurrence === event.occurrence);
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
- $actor: path,
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.$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.');
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);
@@ -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-cbe3abac.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-cbe3abac.esm.js';
5
- import { S as StateMachine, h as historicalEventSchema, s as snapshotSchema } from './machineSchemas-45c21bc2.esm.js';
6
- export { I as InvalidSnapshotError, S as StateMachine, a as StateNode, e as eventSchema } from './machineSchemas-45c21bc2.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-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-d8b0f749.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-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.$actor, source.incarnation, key ? serializeTimerKey(key) : event.type]);
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.$actor === 'string' && typeof value.incarnation === 'string';
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
- $systemMapper: mappers.get(value)
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
- $actor: value.address,
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
- $stateNode: value.id
2148
+ '@stateNode': value.id
2149
2149
  };
2150
2150
  } else if (value instanceof Error) {
2151
2151
  result = {
2152
- $error: value.name,
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
- $actor: actor.address,
2264
+ '@actor': actor.address,
2256
2265
  incarnation: actor.sessionId
2257
2266
  };
2258
2267
  }
2259
2268
  current(ref) {
2260
- const actor = this.snapshot.actors[ref.$actor];
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.$systemMapper === 'string') {
2267
- const mapper = Object.hasOwn(this.mappers, value.$systemMapper) && this.mappers[value.$systemMapper];
2268
- if (!mapper) throw new Error(`Missing pure mapper '${value.$systemMapper}'.`);
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.$stateNode === 'string') return machine.getStateNodeById(value.$stateNode);
2272
- if (typeof value.$error === 'string') {
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.$error;
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.$actor !== source.$actor || target.incarnation !== source.incarnation || !actor.parent || this.current(actor.parent)?.snapshot.status !== 'active') continue;
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
- $actor: actor.address,
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?.$actor === parent.$actor && actor.parent.incarnation === parent.incarnation) this.stop({
2312
- $actor: actor.address,
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.$actor.split('/').at(-1),
2354
- address: ref.$actor,
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.$actor === actor.address && ref.incarnation === actor.sessionId) delete this.snapshot.registry[key];
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
- $actor: address,
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.$actor + '/' : ''}${encodeAddressSegment(id)}`;
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
- $actor: address,
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
- $actor: address,
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.$actor] = {
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.$actor === ref.$actor && timer.source.incarnation === ref.incarnation && (cancelled === undefined || timerKey === cancelled)) delete this.snapshot.timers[timerKey];
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.$actor];
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
- $actor: target.address,
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.$actor] = {
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.$actor !== ref.$actor || message.target.incarnation !== ref.incarnation);
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.$actor !== ref.$actor || effect.source.incarnation !== ref.incarnation) continue;
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.$actor !== actor.address || message.source.incarnation !== actor.incarnation)) {
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.$actor === path && pending.source.incarnation === actor.incarnation && pending.occurrence === event.occurrence);
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
- $actor: path,
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.$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.');
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);