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,7 +1,7 @@
1
1
  import { restoreLogicSnapshot } from './xstate-persist.esm.js';
2
- import { j as encodeAddressSegment, aK as getRootActorId, aL as RUNTIME_OPERATIONS, aM as withSystemInspector, aH as isRemoteActorRef, aB as createStartEffect, aN as createTimerEffect, aO as getSnapshotActorRef, aP as withExecutionIdentity, ai as createInertActorScope, aj as setInertActorScopeSnapshot, al as attachSnapshotActorRef, z as matchesTimerKey, aQ as getTimerStart, aR as recordTimerStart, L as deliverEvent } from './createActor-cbe3abac.esm.js';
3
- import { a as initialTransition, t as transition, d as describeExecutableEffect } from './effectDescriptor-d8b0f749.esm.js';
4
- import './machineSchemas-45c21bc2.esm.js';
2
+ import { j as encodeAddressSegment, aK as getRootActorId, aL as RUNTIME_OPERATIONS, aH as isRemoteActorRef, aB as createStartEffect, aM as createTimerEffect, aN as getSnapshotActorRef, A as isMachineSnapshot, aO as withExecutionOwner, z as matchesTimerKey, aP as getTimerStart, aQ as recordTimerStart, L as deliverEvent, aR as withSystemInspector, aS as adoptSystem, aT as withExecutionIdentity, ai as createInertActorScope, aj as setInertActorScopeSnapshot, al as attachSnapshotActorRef } from './createActor-20a97166.esm.js';
3
+ import { d as describeExecutableEffect, a as initialTransition, t as transition } from './effectDescriptor-e93df910.esm.js';
4
+ import './legacySnapshot-9e06feb4.esm.js';
5
5
  import './validation-05f1d517.esm.js';
6
6
 
7
7
  /** @experimental */
@@ -16,6 +16,36 @@ import './validation-05f1d517.esm.js';
16
16
  * @experimental
17
17
  */
18
18
 
19
+ /**
20
+ * A root-addressed event that the execution received but has not processed,
21
+ * stored in a checkpoint. `source` is the sender's logical address.
22
+ *
23
+ * @experimental
24
+ */
25
+
26
+ /**
27
+ * Everything needed to resume an execution: the persisted snapshot, the next
28
+ * transition index and the events received but not yet processed. Persist
29
+ * the whole object atomically and pass it to `restore()`.
30
+ *
31
+ * @experimental
32
+ */
33
+
34
+ // Lifecycle events that address a child by `actorId`. Snapshot updates are
35
+ // not stored: a restored child reports its current snapshot when it starts.
36
+ const storedLifecycleEvents = new Set(['xstate.done.actor', 'xstate.error.actor', 'xstate.timeout.actor']);
37
+ function isCheckpoint(value) {
38
+ return !!value && typeof value === 'object' && 'inbox' in value && 'nextTransitionIndex' in value && 'snapshot' in value;
39
+ }
40
+ function isInboxEntry(item) {
41
+ if (!item || typeof item !== 'object') return false;
42
+ const {
43
+ event,
44
+ source
45
+ } = item;
46
+ return !!event && typeof event.type === 'string' && (source === undefined || !!source && typeof source['@actor'] === 'string' && (source.incarnation === undefined || typeof source.incarnation === 'string'));
47
+ }
48
+
19
49
  /** @experimental */
20
50
 
21
51
  /**
@@ -145,6 +175,15 @@ function createDurable(logic, adapter, options) {
145
175
  // loop to take them through `waitForEvent()`.
146
176
  const pendingRootEvents = [];
147
177
 
178
+ // For a stored lifecycle event: the child it addresses in `snapshot`, or
179
+ // `null` when that child is gone. `undefined` for any other event.
180
+ const lifecycleChild = (snapshot, event) => {
181
+ if (!isMachineSnapshot(snapshot) || !storedLifecycleEvents.has(event.type) || typeof event.actorId !== 'string') {
182
+ return undefined;
183
+ }
184
+ return snapshot.children[event.actorId] ?? null;
185
+ };
186
+
148
187
  // Every inter-actor edge is an async handoff to the runtime, and every
149
188
  // handoff queues behind the last one: hosts whose step or activity model
150
189
  // forbids concurrent entries depend on that, and so does deterministic
@@ -285,6 +324,16 @@ function createDurable(logic, adapter, options) {
285
324
  }
286
325
  const inspect = options?.inspect;
287
326
 
327
+ // Runs a transition as this execution: views it derives belong to this
328
+ // execution, and its systems report to the execution's inspector.
329
+ const owner = {
330
+ runtime: wrappedSystemRuntime,
331
+ inspect
332
+ };
333
+ function inExecution(fn) {
334
+ return withExecutionOwner(owner, () => withSystemInspector(inspect, fn));
335
+ }
336
+
288
337
  // Attaches the execution's inspector to a system that does not have it
289
338
  // yet. Systems constructed inside a transition get it at construction (the
290
339
  // ambient inspector); this covers systems materialized outside that window
@@ -315,10 +364,12 @@ function createDurable(logic, adapter, options) {
315
364
  const visit = actor => {
316
365
  if (!systems.has(actor.system)) {
317
366
  systems.add(actor.system);
318
- if (wrappedSystemRuntime) {
319
- actor.system.runtime = wrappedSystemRuntime;
367
+ if (adoptSystem(actor.system, owner)) {
368
+ if (wrappedSystemRuntime) {
369
+ actor.system.runtime = wrappedSystemRuntime;
370
+ }
371
+ wireInspection(actor.system);
320
372
  }
321
- wireInspection(actor.system);
322
373
  }
323
374
  if (recursive) {
324
375
  const children = actor.getSnapshot().children;
@@ -350,14 +401,55 @@ function createDurable(logic, adapter, options) {
350
401
  get nextTransitionIndex() {
351
402
  return nextTransitionIndex;
352
403
  },
353
- restore(persistedSnapshot) {
404
+ checkpoint(snapshot, persistOptions) {
405
+ const inbox = [];
406
+ for (const {
407
+ event,
408
+ source
409
+ } of pendingRootEvents) {
410
+ const child = lifecycleChild(snapshot, event);
411
+ if (event.type === 'xstate.snapshot.actor' || child !== undefined && (!child || event.sessionId !== undefined && child.sessionId !== undefined && child.sessionId !== event.sessionId)) {
412
+ continue;
413
+ }
414
+ inbox.push({
415
+ event,
416
+ source: source && {
417
+ '@actor': source.address,
418
+ ...(isRemoteActorRef(source) && source.sessionId !== undefined ? {
419
+ incarnation: source.sessionId
420
+ } : {})
421
+ }
422
+ });
423
+ }
424
+ return {
425
+ snapshot: logic.getPersistedSnapshot?.(snapshot, persistOptions) ?? snapshot,
426
+ nextTransitionIndex,
427
+ inbox
428
+ };
429
+ },
430
+ restore(checkpointOrSnapshot) {
431
+ const checkpoint = isCheckpoint(checkpointOrSnapshot) ? checkpointOrSnapshot : undefined;
354
432
  if (restored || nextTransitionIndex !== startingTransitionIndex || currentBatch) {
355
433
  throw new Error('restore() requires a fresh durable execution');
356
434
  }
435
+ if (checkpoint) {
436
+ if (!Array.isArray(checkpoint.inbox) || !checkpoint.inbox.every(isInboxEntry)) {
437
+ throw new TypeError('The checkpoint inbox is invalid.');
438
+ }
439
+ if (adapter.transitionIndex !== undefined && adapter.transitionIndex !== checkpoint.nextTransitionIndex) {
440
+ throw new RangeError(`The adapter's transitionIndex (${adapter.transitionIndex}) does not match the checkpoint's nextTransitionIndex (${checkpoint.nextTransitionIndex}).`);
441
+ }
442
+ if (!Number.isSafeInteger(checkpoint.nextTransitionIndex) || checkpoint.nextTransitionIndex < 0) {
443
+ throw new RangeError('nextTransitionIndex must be a non-negative safe integer');
444
+ }
445
+ nextTransitionIndex = checkpoint.nextTransitionIndex;
446
+ lastTransitionIndex = nextTransitionIndex === 0 ? undefined : nextTransitionIndex - 1;
447
+ }
448
+ const persistedSnapshot = checkpoint ? checkpoint.snapshot : checkpointOrSnapshot;
357
449
  const {
358
450
  snapshot,
359
451
  scope
360
- } = withSystemInspector(inspect, () => withExecutionIdentity(executionIdentity, () => {
452
+ } = inExecution(() => withExecutionIdentity(executionIdentity, () => {
361
453
  const scope = createInertActorScope(logic);
362
454
  const snapshot = restoreLogicSnapshot(logic, persistedSnapshot, scope);
363
455
  setInertActorScopeSnapshot(scope, snapshot, false);
@@ -366,6 +458,24 @@ function createDurable(logic, adapter, options) {
366
458
  scope
367
459
  };
368
460
  }));
461
+ for (const {
462
+ event,
463
+ source
464
+ } of checkpoint?.inbox ?? []) {
465
+ const child = lifecycleChild(snapshot, event);
466
+ if (child === null) {
467
+ continue;
468
+ }
469
+ pendingRootEvents.push({
470
+ // A restored child has a new session; its pending lifecycle events
471
+ // follow it.
472
+ event: child && child.sessionId !== undefined && 'sessionId' in event ? {
473
+ ...event,
474
+ sessionId: child.sessionId
475
+ } : event,
476
+ source: source && execution.getActorRef(snapshot, source['@actor'])
477
+ });
478
+ }
369
479
  const effects = [];
370
480
  if (snapshot.status === 'active') {
371
481
  const {
@@ -395,11 +505,11 @@ function createDurable(logic, adapter, options) {
395
505
  if (restored) {
396
506
  throw new Error('initialTransition() cannot initialize a restored execution');
397
507
  }
398
- const [snapshot, effects] = withSystemInspector(inspect, () => withExecutionIdentity(executionIdentity, () => initialTransition(logic, ...args)));
508
+ const [snapshot, effects] = inExecution(() => withExecutionIdentity(executionIdentity, () => initialTransition(logic, ...args)));
399
509
  return [installSystemRuntime(snapshot), tagEffects(effects)];
400
510
  },
401
511
  transition(snapshot, event) {
402
- const [nextSnapshot, effects] = withSystemInspector(inspect, () => withExecutionIdentity(executionIdentity, () => transition(logic, snapshot, event)));
512
+ const [nextSnapshot, effects] = inExecution(() => withExecutionIdentity(executionIdentity, () => transition(logic, snapshot, event)));
403
513
  return [installSystemRuntime(nextSnapshot), tagEffects(effects)];
404
514
  },
405
515
  getActorRef(snapshot, address) {