xstate 6.0.0-alpha.8 → 6.0.0-beta.0

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 (235) hide show
  1. package/README.md +223 -78
  2. package/bin/agent.js +347 -0
  3. package/bin/xstate.js +52 -0
  4. package/dist/createActor-25900f76.cjs.js +7015 -0
  5. package/dist/createActor-551369be.development.esm.js +7175 -0
  6. package/dist/createActor-a49ae0ce.development.cjs.js +7289 -0
  7. package/dist/createActor-cbe3abac.esm.js +6902 -0
  8. package/dist/declarations/src/SimulatedClock.d.ts +2 -1
  9. package/dist/declarations/src/State.d.ts +66 -5
  10. package/dist/declarations/src/StateMachine.d.ts +107 -32
  11. package/dist/declarations/src/StateNode.d.ts +21 -16
  12. package/dist/declarations/src/actions.d.ts +11 -6
  13. package/dist/declarations/src/actors/callback.d.ts +11 -2
  14. package/dist/declarations/src/actors/index.d.ts +6 -5
  15. package/dist/declarations/src/actors/listener.d.ts +8 -3
  16. package/dist/declarations/src/actors/logic.d.ts +42 -52
  17. package/dist/declarations/src/actors/observable.d.ts +15 -2
  18. package/dist/declarations/src/actors/promise.d.ts +90 -22
  19. package/dist/declarations/src/actors/subscription.d.ts +9 -3
  20. package/dist/declarations/src/assert.d.ts +1 -0
  21. package/dist/declarations/src/base.types.d.ts +102 -0
  22. package/dist/declarations/src/createActor.d.ts +101 -27
  23. package/dist/declarations/src/createMachine.d.ts +38 -17
  24. package/dist/declarations/src/delay.d.ts +8 -0
  25. package/dist/declarations/src/durable/index.d.ts +231 -0
  26. package/dist/declarations/src/effectDescriptor.d.ts +95 -0
  27. package/dist/declarations/src/eventTypes.d.ts +9 -0
  28. package/dist/declarations/src/fsm/index.d.ts +2 -0
  29. package/dist/declarations/src/fsm.d.ts +169 -0
  30. package/dist/declarations/src/graph/adjacency.d.ts +6 -3
  31. package/dist/declarations/src/graph/graph.d.ts +6 -3
  32. package/dist/declarations/src/graph/index.d.ts +2 -3
  33. package/dist/declarations/src/graph/pathFromEvents.d.ts +5 -2
  34. package/dist/declarations/src/graph/shortestPaths.d.ts +5 -3
  35. package/dist/declarations/src/graph/simplePaths.d.ts +5 -3
  36. package/dist/declarations/src/graph/types.d.ts +113 -59
  37. package/dist/declarations/src/hotSwap.d.ts +18 -0
  38. package/dist/declarations/src/index.d.ts +28 -19
  39. package/dist/declarations/src/inspection.d.ts +24 -1
  40. package/dist/declarations/src/machineFromJSON.d.ts +171 -0
  41. package/dist/declarations/src/machineSchemas.d.ts +27 -0
  42. package/dist/declarations/src/machineVersion.types.d.ts +53 -0
  43. package/dist/declarations/src/machineVersions.d.ts +103 -0
  44. package/dist/declarations/src/mapState.d.ts +2 -0
  45. package/dist/declarations/src/persist/index.d.ts +36 -0
  46. package/dist/declarations/src/persistedSnapshotValidation.d.ts +18 -0
  47. package/dist/declarations/src/runtimeHelpers.d.ts +43 -0
  48. package/dist/declarations/src/schema.types.d.ts +31 -4
  49. package/dist/declarations/src/serialize.d.ts +39 -28
  50. package/dist/declarations/src/setup.d.ts +1086 -147
  51. package/dist/declarations/src/spawn.d.ts +6 -4
  52. package/dist/declarations/src/stateUtils.d.ts +57 -14
  53. package/dist/declarations/src/system.d.ts +178 -17
  54. package/dist/declarations/src/systemTransition.d.ts +108 -0
  55. package/dist/declarations/src/toPromise.d.ts +1 -0
  56. package/dist/declarations/src/transition.d.ts +48 -10
  57. package/dist/declarations/src/transitionActions.d.ts +22 -4
  58. package/dist/declarations/src/typeUtils.d.ts +51 -0
  59. package/dist/declarations/src/types.d.ts +835 -318
  60. package/dist/declarations/src/types.v6.d.ts +547 -104
  61. package/dist/declarations/src/utils.d.ts +38 -8
  62. package/dist/declarations/src/validation/index.d.ts +49 -0
  63. package/dist/declarations/src/validation.types.d.ts +29 -0
  64. package/dist/declarations/src/waitFor.d.ts +1 -0
  65. package/dist/effectDescriptor-2fa27c54.cjs.js +351 -0
  66. package/dist/effectDescriptor-321a8ce9.development.esm.js +343 -0
  67. package/dist/effectDescriptor-d8b0f749.esm.js +343 -0
  68. package/dist/effectDescriptor-f73da4ec.development.cjs.js +351 -0
  69. package/dist/machineSchemas-45c21bc2.esm.js +1292 -0
  70. package/dist/machineSchemas-6d96bef4.development.cjs.js +1379 -0
  71. package/dist/machineSchemas-88d01821.cjs.js +1300 -0
  72. package/dist/machineSchemas-b5736804.development.esm.js +1371 -0
  73. package/dist/schema.types-0ecd17b8.esm.js +71 -0
  74. package/dist/schema.types-15a68ddc.cjs.js +74 -0
  75. package/dist/schema.types-1c16f035.development.cjs.js +74 -0
  76. package/dist/schema.types-1cd4652e.development.esm.js +71 -0
  77. package/dist/validation-05f1d517.esm.js +8 -0
  78. package/dist/validation-4561b43c.cjs.js +10 -0
  79. package/dist/validation-e69470ad.development.esm.js +8 -0
  80. package/dist/validation-f2714a35.development.cjs.js +10 -0
  81. package/dist/xstate-actors.cjs.js +1068 -12
  82. package/dist/xstate-actors.cjs.mjs +2 -4
  83. package/dist/xstate-actors.development.cjs.js +1068 -12
  84. package/dist/xstate-actors.development.cjs.mjs +2 -4
  85. package/dist/xstate-actors.development.esm.js +1064 -1
  86. package/dist/xstate-actors.esm.js +1064 -1
  87. package/dist/xstate-actors.umd.min.js +1 -1
  88. package/dist/xstate-actors.umd.min.js.map +1 -1
  89. package/dist/xstate-durable.cjs.d.mts +2 -0
  90. package/dist/xstate-durable.cjs.d.ts +2 -0
  91. package/dist/xstate-durable.cjs.js +513 -0
  92. package/dist/xstate-durable.cjs.mjs +5 -0
  93. package/dist/xstate-durable.development.cjs.js +513 -0
  94. package/dist/xstate-durable.development.cjs.mjs +5 -0
  95. package/dist/xstate-durable.development.esm.js +507 -0
  96. package/dist/xstate-durable.esm.js +507 -0
  97. package/dist/xstate-durable.umd.min.js +2 -0
  98. package/dist/xstate-durable.umd.min.js.map +1 -0
  99. package/dist/xstate-fsm.cjs.d.mts +2 -0
  100. package/dist/xstate-fsm.cjs.d.ts +2 -0
  101. package/dist/xstate-fsm.cjs.js +111 -0
  102. package/dist/xstate-fsm.cjs.mjs +5 -0
  103. package/dist/xstate-fsm.development.cjs.js +111 -0
  104. package/dist/xstate-fsm.development.cjs.mjs +5 -0
  105. package/dist/xstate-fsm.development.esm.js +105 -0
  106. package/dist/xstate-fsm.esm.js +105 -0
  107. package/dist/xstate-fsm.umd.min.js +2 -0
  108. package/dist/xstate-fsm.umd.min.js.map +1 -0
  109. package/dist/xstate-graph.cjs.js +173 -457
  110. package/dist/xstate-graph.cjs.mjs +2 -5
  111. package/dist/xstate-graph.development.cjs.js +173 -457
  112. package/dist/xstate-graph.development.cjs.mjs +2 -5
  113. package/dist/xstate-graph.development.esm.js +171 -451
  114. package/dist/xstate-graph.esm.js +171 -451
  115. package/dist/xstate-graph.umd.min.js +1 -1
  116. package/dist/xstate-graph.umd.min.js.map +1 -1
  117. package/dist/xstate-persist.cjs.d.mts +2 -0
  118. package/dist/xstate-persist.cjs.d.ts +2 -0
  119. package/dist/xstate-persist.cjs.js +314 -0
  120. package/dist/xstate-persist.cjs.mjs +6 -0
  121. package/dist/xstate-persist.development.cjs.js +325 -0
  122. package/dist/xstate-persist.development.cjs.mjs +6 -0
  123. package/dist/xstate-persist.development.esm.js +319 -0
  124. package/dist/xstate-persist.esm.js +308 -0
  125. package/dist/xstate-persist.umd.min.js +2 -0
  126. package/dist/xstate-persist.umd.min.js.map +1 -0
  127. package/dist/xstate-validation.cjs.d.mts +2 -0
  128. package/dist/xstate-validation.cjs.d.ts +2 -0
  129. package/dist/xstate-validation.cjs.js +330 -0
  130. package/dist/xstate-validation.cjs.mjs +5 -0
  131. package/dist/xstate-validation.development.cjs.js +330 -0
  132. package/dist/xstate-validation.development.cjs.mjs +5 -0
  133. package/dist/xstate-validation.development.esm.js +324 -0
  134. package/dist/xstate-validation.esm.js +324 -0
  135. package/dist/xstate-validation.umd.min.js +2 -0
  136. package/dist/xstate-validation.umd.min.js.map +1 -0
  137. package/dist/xstate.cjs.js +2486 -1430
  138. package/dist/xstate.cjs.mjs +23 -13
  139. package/dist/xstate.development.cjs.js +2486 -1430
  140. package/dist/xstate.development.cjs.mjs +23 -13
  141. package/dist/xstate.development.esm.js +2445 -1398
  142. package/dist/xstate.esm.js +2445 -1398
  143. package/dist/xstate.umd.min.js +1 -1
  144. package/dist/xstate.umd.min.js.map +1 -1
  145. package/docs/actions.md +75 -0
  146. package/docs/actor-logic.md +250 -0
  147. package/docs/actors.md +64 -0
  148. package/docs/agents.md +132 -0
  149. package/docs/api-stability.json +4287 -0
  150. package/docs/async-logic.md +75 -0
  151. package/docs/async-requests.md +157 -0
  152. package/docs/backend-workflows.md +124 -0
  153. package/docs/cancellation.md +42 -0
  154. package/docs/cheatsheet.md +563 -0
  155. package/docs/choice-states.md +109 -0
  156. package/docs/choose-xstate.md +47 -0
  157. package/docs/configuration.md +161 -0
  158. package/docs/context.md +67 -0
  159. package/docs/create-actor.md +159 -0
  160. package/docs/data-and-effects.md +48 -0
  161. package/docs/delays.md +81 -0
  162. package/docs/durable-execution.md +520 -0
  163. package/docs/emitted-events.md +146 -0
  164. package/docs/errors.md +812 -0
  165. package/docs/examples.md +75 -0
  166. package/docs/faq.md +60 -0
  167. package/docs/final-states.md +149 -0
  168. package/docs/forms-and-wizards.md +166 -0
  169. package/docs/frameworks.md +69 -0
  170. package/docs/fsm.md +164 -0
  171. package/docs/glossary.md +68 -0
  172. package/docs/guards.md +137 -0
  173. package/docs/history-states.md +161 -0
  174. package/docs/how-xstate-runs-machines.md +86 -0
  175. package/docs/index.md +74 -0
  176. package/docs/input-output.md +69 -0
  177. package/docs/inspect-actor-systems.md +118 -0
  178. package/docs/inspection.md +75 -0
  179. package/docs/internal-events.md +156 -0
  180. package/docs/invoke.md +371 -0
  181. package/docs/lifecycle-and-errors.md +48 -0
  182. package/docs/listen-and-subscribe.md +126 -0
  183. package/docs/model-based-testing.md +321 -0
  184. package/docs/modeling.md +40 -0
  185. package/docs/parallel-states.md +182 -0
  186. package/docs/persist-and-restore-actors.md +120 -0
  187. package/docs/persistence.md +312 -0
  188. package/docs/quick-start.md +55 -0
  189. package/docs/retries-and-timeouts.md +122 -0
  190. package/docs/route-states.md +104 -0
  191. package/docs/scxml.md +92 -0
  192. package/docs/selectors.md +99 -0
  193. package/docs/serialization.md +127 -0
  194. package/docs/setup-and-provide.md +273 -0
  195. package/docs/snapshots.md +134 -0
  196. package/docs/spawn.md +212 -0
  197. package/docs/state-input.md +162 -0
  198. package/docs/statecharts.md +54 -0
  199. package/docs/states-events-transitions.md +82 -0
  200. package/docs/states.md +168 -0
  201. package/docs/system-transitions.md +172 -0
  202. package/docs/systems.md +166 -0
  203. package/docs/testing.md +152 -0
  204. package/docs/timeouts.md +125 -0
  205. package/docs/transition-functions.md +89 -0
  206. package/docs/transitions.md +187 -0
  207. package/docs/troubleshooting.md +56 -0
  208. package/docs/tutorial.md +481 -0
  209. package/docs/typescript.md +213 -0
  210. package/docs/typestates.md +112 -0
  211. package/docs/utilities.md +39 -0
  212. package/docs/why-state-machines.md +59 -0
  213. package/docs/xstate-v5-to-v6.md +1923 -0
  214. package/docs/your-first-machine.md +79 -0
  215. package/durable/package.json +8 -0
  216. package/fsm/package.json +8 -0
  217. package/package.json +72 -10
  218. package/persist/package.json +8 -0
  219. package/validation/package.json +8 -0
  220. package/actions/package.json +0 -8
  221. package/dev/package.json +0 -8
  222. package/dist/StateMachine-0aa98f54.development.esm.js +0 -746
  223. package/dist/StateMachine-aef700df.cjs.js +0 -732
  224. package/dist/StateMachine-d4931336.esm.js +0 -729
  225. package/dist/StateMachine-da872dde.development.cjs.js +0 -749
  226. package/dist/declarations/src/createMachineFromConfig.d.ts +0 -177
  227. package/dist/declarations/src/getNextSnapshot.d.ts +0 -37
  228. package/dist/declarations/src/graph/TestModel.d.ts +0 -70
  229. package/dist/declarations/src/graph/pathGenerators.d.ts +0 -4
  230. package/dist/index-219cb621.development.cjs.js +0 -4476
  231. package/dist/index-2f2fbd9b.development.esm.js +0 -4421
  232. package/dist/index-559ceab3.cjs.js +0 -4437
  233. package/dist/index-8828376f.esm.js +0 -4382
  234. package/guards/package.json +0 -8
  235. package/invoke/package.json +0 -4
@@ -0,0 +1,2 @@
1
+ export * from "./declarations/src/durable/index.js";
2
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHN0YXRlLWR1cmFibGUuY2pzLmQubXRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi9kZWNsYXJhdGlvbnMvc3JjL2R1cmFibGUvaW5kZXguZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSJ9
@@ -0,0 +1,2 @@
1
+ export * from "./declarations/src/durable/index.js";
2
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieHN0YXRlLWR1cmFibGUuY2pzLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuL2RlY2xhcmF0aW9ucy9zcmMvZHVyYWJsZS9pbmRleC5kLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBIn0=
@@ -0,0 +1,513 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var dist_xstatePersist = require('./xstate-persist.cjs.js');
6
+ var createActor = require('./createActor-25900f76.cjs.js');
7
+ var effectDescriptor = require('./effectDescriptor-2fa27c54.cjs.js');
8
+ require('./machineSchemas-88d01821.cjs.js');
9
+ require('./validation-4561b43c.cjs.js');
10
+
11
+ /** @experimental */
12
+
13
+ /** @experimental */
14
+
15
+ /**
16
+ * An event addressed to a durable execution's root actor, captured while
17
+ * effects settled. `source` is the live reference of the sending actor when
18
+ * one initiated the send.
19
+ *
20
+ * @experimental
21
+ */
22
+
23
+ /** @experimental */
24
+
25
+ /**
26
+ * A durable host adapter: the runtime operations that execute this
27
+ * execution's effects, plus the durable loop hooks.
28
+ *
29
+ * The runtime operations (`sendEvent`, `scheduleTimer`, …) are installed on
30
+ * the actor system of every snapshot the execution produces, including
31
+ * children created during transitions and actors rehydrated from restored
32
+ * snapshots. Operations initiated by live child actors (parent sends,
33
+ * timers, terminations) route to them without any per-actor wiring; omitted
34
+ * operations keep their default local behavior.
35
+ *
36
+ * By default, events addressed to this execution's root actor do not reach
37
+ * `sendEvent` during `executeEffects`: the execution captures and retains
38
+ * them, and `waitForEvent()` hands them out before deferring to this adapter. While the loop is parked, a root-addressed event reaches
39
+ * `enqueueRootEvent`, or the broader `sendEvent` override when implemented,
40
+ * so the host can place it in its own mailbox.
41
+ *
42
+ * @experimental
43
+ */
44
+
45
+ /** @experimental */
46
+ class DurableExecutionCancelledError extends Error {
47
+ constructor() {
48
+ super('Durable execution was stopped');
49
+ this.name = 'DurableExecutionCancelledError';
50
+ }
51
+ }
52
+
53
+ /** @experimental */
54
+ class DurableExecutionResumeError extends Error {
55
+ constructor() {
56
+ super('run() can only start a fresh durable execution; resume checkpoints with restore() and the explicit transition loop');
57
+ this.name = 'DurableExecutionResumeError';
58
+ }
59
+ }
60
+
61
+ /**
62
+ * The snapshot type a durable execution hands back: the logic's own snapshot,
63
+ * intersected with the base `Snapshot` union so the `status`/`output`/`error`
64
+ * discriminant stays visible even when `TLogic` is an unresolved type
65
+ * parameter (a generic host library), where `SnapshotFrom` alone is opaque.
66
+ *
67
+ * @experimental
68
+ */
69
+
70
+ /** @experimental */
71
+
72
+ /**
73
+ * Creates a host-neutral durable execution around pure actor transitions.
74
+ *
75
+ * The returned transition methods only calculate snapshots and tag their
76
+ * effects. Persistence, retries, messaging, timers and child execution remain
77
+ * responsibilities of the adapter.
78
+ *
79
+ * @experimental
80
+ */
81
+
82
+ /** @experimental */
83
+ function createDurable(logic, adapter, options) {
84
+ let nextTransitionIndex = adapter.transitionIndex ?? 0;
85
+ const startingTransitionIndex = nextTransitionIndex;
86
+ let restored = false;
87
+ const now = () => adapter.now?.() ?? Date.now();
88
+ const observedRoots = new WeakSet();
89
+ let lastTransitionIndex = nextTransitionIndex === 0 ? undefined : nextTransitionIndex - 1;
90
+ const restoredTimerDeadlines = new WeakMap();
91
+ if (!Number.isSafeInteger(nextTransitionIndex) || nextTransitionIndex < 0) {
92
+ throw new RangeError('transitionIndex must be a non-negative safe integer');
93
+ }
94
+ const tagEffects = (effects, restoring = false) => {
95
+ const transitionIndex = restoring ? nextTransitionIndex : nextTransitionIndex++;
96
+ lastTransitionIndex = restoring ? lastTransitionIndex ?? transitionIndex : transitionIndex;
97
+ return effects.map((effect, effectIndex) => {
98
+ const tagged = {
99
+ id: `${restoring ? 'restore:' : ''}${transitionIndex}:${effectIndex}`,
100
+ transitionIndex,
101
+ effectIndex,
102
+ effect
103
+ };
104
+ // Journaling hosts read the descriptor; executing hosts never do, so
105
+ // compute it (and its address walks) lazily, once.
106
+ let descriptor;
107
+ Object.defineProperty(tagged, 'descriptor', {
108
+ enumerable: true,
109
+ get: () => descriptor ??= effectDescriptor.describeExecutableEffect(effect)
110
+ });
111
+ return tagged;
112
+ });
113
+ };
114
+
115
+ // The root's address as the root actor reports it: root-event capture
116
+ // compares against `target.address`, which percent-encodes each segment.
117
+ const rootAddress = createActor.encodeAddressSegment(createActor.getRootActorId(logic));
118
+ const machineId = logic.id ?? rootAddress;
119
+ const machineVersion = logic.version;
120
+ // One identity object for the whole execution: session numbering continues
121
+ // across this execution's transitions, and a replay (a fresh createDurable
122
+ // with the same executionId) re-numbers identically.
123
+ const executionIdentity = adapter.executionId ? {
124
+ executionId: adapter.executionId,
125
+ nextSessionId: 0
126
+ } : undefined;
127
+
128
+ // The adapter's runtime operations, picked off the flat adapter shape.
129
+ const systemRuntime = {};
130
+ for (const operation of [...createActor.RUNTIME_OPERATIONS, 'sendEvent', 'runStep', 'runLogic']) {
131
+ const impl = adapter[operation];
132
+ if (impl) {
133
+ systemRuntime[operation] = impl.bind(adapter);
134
+ }
135
+ }
136
+ const hasSystemRuntime = Object.keys(systemRuntime).length > 0 || !!adapter.enqueueRootEvent;
137
+
138
+ // One batch per `executeEffects` call. The wrapped runtime stays installed
139
+ // on the actor system for the whole execution, so it also sees operations
140
+ // initiated while the loop is parked in `waitForEvent()` (for example a
141
+ // live child reacting to a host-originated delivery). Those belong to the
142
+ // host's domain: they run untracked and uncaptured, so a parked-window
143
+ // failure cannot be attributed to an unrelated later batch. Discarding a
144
+ // failed batch discards its captures and failures with it.
145
+
146
+ let currentBatch;
147
+
148
+ // Root-addressed events captured by settled batches, waiting for the drive
149
+ // loop to take them through `waitForEvent()`.
150
+ const pendingRootEvents = [];
151
+
152
+ // Every inter-actor edge is an async handoff to the runtime, and every
153
+ // handoff queues behind the last one: hosts whose step or activity model
154
+ // forbids concurrent entries depend on that, and so does deterministic
155
+ // replay. An operation must therefore never await another operation of the
156
+ // same execution through the actor system — it would wait behind itself.
157
+ let operationTail = Promise.resolve();
158
+ const track = (batch, operation) => {
159
+ batch.pending.add(operation);
160
+ void operation.catch(error => {
161
+ // Collect the failure so it reaches `executeEffects` even when the
162
+ // operation leaves the pending set before settle() samples it.
163
+ batch.failures.push(error);
164
+ }).then(() => batch.pending.delete(operation));
165
+ return operation;
166
+ };
167
+ const handOff = (batch, run) => {
168
+ const operation = operationTail.then(run).then(() => undefined);
169
+ operationTail = operation.catch(() => {});
170
+ return track(batch, operation);
171
+ };
172
+
173
+ // Hands an operation over according to where it was initiated: batched
174
+ // during `executeEffects`, immediate while the loop is parked.
175
+ const dispatch = run => currentBatch ? handOff(currentBatch, run) : run();
176
+ const drain = async batch => {
177
+ while (batch.pending.size) {
178
+ await Promise.allSettled([...batch.pending]);
179
+ }
180
+ };
181
+ const settle = async batch => {
182
+ await drain(batch);
183
+ if (batch.failures.length) {
184
+ throw batch.failures[0];
185
+ }
186
+ };
187
+ function wrapRuntime(runtime, localDeliveryFallback,
188
+ // When set, operations neither this runtime nor the adapter implements
189
+ // keep the behavior they would have had without a per-effect runtime,
190
+ // running against the operation's own actor's system (per-system timer
191
+ // bookkeeping must land on that system, not the root's). Safe from
192
+ // re-entrant dispatch: that system's installed runtime lacks these
193
+ // operations by construction, so the call falls through to local
194
+ // behavior.
195
+ fallbackToActorSystem = false, timerDeadline) {
196
+ const wrapped = {};
197
+ for (const operation of createActor.RUNTIME_OPERATIONS) {
198
+ const impl = runtime[operation] ?? (fallbackToActorSystem ? (...args) => {
199
+ const owner = operation === 'spawnActor' ? args[1] : args[0];
200
+ return owner.system[operation](...args);
201
+ } : undefined);
202
+ if (impl) {
203
+ wrapped[operation] = (...args) => dispatch(() => {
204
+ // Runtime operations can queue behind asynchronous child startup.
205
+ // Calculate the remaining time when dispatching to the adapter.
206
+ if (operation === 'scheduleTimer' && timerDeadline) {
207
+ args[2] = Math.min(timerDeadline.delay, Math.max(0, timerDeadline.deadline - now()));
208
+ }
209
+ if (operation === 'scheduleTimer') {
210
+ const source = args[0];
211
+ const key = args[1];
212
+ const timer = source.getSnapshot()?.timers?.find(pending => createActor.matchesTimerKey(pending, key));
213
+ if (timer) {
214
+ const previousStart = createActor.getTimerStart(timer);
215
+ if (previousStart !== undefined && !timerDeadline) {
216
+ args[2] = Math.min(timer.delay, Math.max(0, previousStart + timer.delay - now()));
217
+ }
218
+ const result = impl(...args);
219
+ if (result) {
220
+ return Promise.resolve(result).then(() => {
221
+ createActor.recordTimerStart(timer, previousStart ?? now());
222
+ });
223
+ }
224
+ createActor.recordTimerStart(timer, previousStart ?? now());
225
+ return;
226
+ }
227
+ }
228
+ return impl(...args);
229
+ });
230
+ }
231
+ }
232
+ // A step is an orchestration frame: it may itself await runtime
233
+ // operations of this execution, so it passes through undispatched —
234
+ // queuing it on the operation tail would make it wait behind (and
235
+ // deadlock with) the operations its own body initiates.
236
+ if (runtime.runStep) {
237
+ wrapped.runStep = runtime.runStep;
238
+ }
239
+ if (runtime.runLogic) {
240
+ wrapped.runLogic = runtime.runLogic;
241
+ }
242
+ wrapped.sendEvent = (source, target, event) => {
243
+ const captureBatch = options?.captureRootEvents !== false ? currentBatch : undefined;
244
+ if (!captureBatch && target.address === rootAddress && !runtime.sendEvent && adapter.enqueueRootEvent) {
245
+ return dispatch(() => adapter.enqueueRootEvent(source, event));
246
+ }
247
+ if (!captureBatch && target.address === rootAddress && !runtime.sendEvent) {
248
+ // The root actor is inert; delivering locally would enqueue into a
249
+ // mailbox that never runs, silently losing the event.
250
+ throw new Error(`A root-addressed event ("${event.type}") was produced outside batch capture (for example, while the durable loop was parked), but the adapter has no enqueueRootEvent or sendEvent to receive it. Implement enqueueRootEvent to place root-addressed events in the host's mailbox.`);
251
+ }
252
+ if (captureBatch && target.address === rootAddress) {
253
+ captureBatch.rootEvents.push({
254
+ event,
255
+ source
256
+ });
257
+ return;
258
+ }
259
+ const impl = runtime.sendEvent;
260
+ if (impl) {
261
+ return dispatch(() => impl(source, target, event));
262
+ }
263
+ if (localDeliveryFallback) {
264
+ return dispatch(() => createActor.deliverEvent(source, target, event));
265
+ }
266
+ throw new TypeError(`The durable runtime does not support the sendEvent operation (target '${target.address}')`);
267
+ };
268
+ return wrapped;
269
+ }
270
+ const wrappedSystemRuntime = hasSystemRuntime ? wrapRuntime(systemRuntime, true) : undefined;
271
+
272
+ // Depth-first walk of the live actor tree by logical address. Subtrees
273
+ // whose address is not a prefix of the target are pruned.
274
+ function findByAddress(actor, address) {
275
+ if (actor.address === address) {
276
+ return actor;
277
+ }
278
+ if (!address.startsWith(`${actor.address}/`)) {
279
+ return undefined;
280
+ }
281
+ const children = actor.getSnapshot().children;
282
+ for (const child of Object.values(children ?? {})) {
283
+ const found = child && findByAddress(child, address);
284
+ if (found) {
285
+ return found;
286
+ }
287
+ }
288
+ return undefined;
289
+ }
290
+ const inspect = options?.inspect;
291
+
292
+ // Attaches the execution's inspector to a system that does not have it
293
+ // yet. Systems constructed inside a transition get it at construction (the
294
+ // ambient inspector); this covers systems materialized outside that window
295
+ // — a snapshot's system first touched here, or a restored child's foreign
296
+ // system. Observer presence doubles as the dedup check: this execution is
297
+ // the only thing attaching observers to its systems.
298
+ function wireInspection(system) {
299
+ if (inspect && !system._hasInspectionObservers?.()) {
300
+ system.inspect(inspect);
301
+ }
302
+ }
303
+ function installSystemRuntime(snapshot, recursive = false) {
304
+ if (snapshot.status === 'error') {
305
+ const root = createActor.getSnapshotActorRef(snapshot)?.actor;
306
+ if (root && !observedRoots.has(root)) {
307
+ // The host consumes error snapshots (run() rejects with their error).
308
+ // Observe before termination effects execute, without materializing
309
+ // otherwise lazy roots during successful pure transitions.
310
+ root.subscribe({
311
+ error() {}
312
+ });
313
+ observedRoots.add(root);
314
+ }
315
+ }
316
+ if (wrappedSystemRuntime || inspect) {
317
+ const ref = createActor.getSnapshotActorRef(snapshot)?.actor;
318
+ const systems = new Set();
319
+ const visit = actor => {
320
+ if (!systems.has(actor.system)) {
321
+ systems.add(actor.system);
322
+ if (wrappedSystemRuntime) {
323
+ actor.system.runtime = wrappedSystemRuntime;
324
+ }
325
+ wireInspection(actor.system);
326
+ }
327
+ if (recursive) {
328
+ const children = actor.getSnapshot().children;
329
+ for (const child of Object.values(children ?? {})) {
330
+ if (child) {
331
+ visit(child);
332
+ }
333
+ }
334
+ }
335
+ };
336
+ if (ref) {
337
+ visit(ref);
338
+ }
339
+ if (!recursive || !ref) {
340
+ const children = snapshot.children;
341
+ for (const child of Object.values(children ?? {})) {
342
+ if (child) {
343
+ visit(child);
344
+ }
345
+ }
346
+ }
347
+ }
348
+ return snapshot;
349
+ }
350
+ const execution = {
351
+ rootAddress,
352
+ machineId,
353
+ machineVersion,
354
+ get nextTransitionIndex() {
355
+ return nextTransitionIndex;
356
+ },
357
+ restore(persistedSnapshot) {
358
+ if (restored || nextTransitionIndex !== startingTransitionIndex || currentBatch) {
359
+ throw new Error('restore() requires a fresh durable execution');
360
+ }
361
+ const {
362
+ snapshot,
363
+ scope
364
+ } = createActor.withSystemInspector(inspect, () => createActor.withExecutionIdentity(executionIdentity, () => {
365
+ const scope = createActor.createInertActorScope(logic);
366
+ const snapshot = dist_xstatePersist.restoreLogicSnapshot(logic, persistedSnapshot, scope);
367
+ createActor.setInertActorScopeSnapshot(scope, snapshot, false);
368
+ return {
369
+ snapshot: installSystemRuntime(createActor.attachSnapshotActorRef(scope, snapshot), true),
370
+ scope
371
+ };
372
+ }));
373
+ const effects = [];
374
+ if (snapshot.status === 'active') {
375
+ const {
376
+ children,
377
+ timers
378
+ } = snapshot;
379
+ for (const child of Object.values(children ?? {})) {
380
+ if (child && !createActor.isRemoteActorRef(child) && child.getSnapshot().status === 'active') {
381
+ effects.push(createActor.createStartEffect(child));
382
+ }
383
+ }
384
+ for (const timer of timers ?? []) {
385
+ const effect = createActor.createTimerEffect(scope, timer, timer.delay);
386
+ if (timer.scheduledAt !== undefined) {
387
+ restoredTimerDeadlines.set(effect, {
388
+ deadline: timer.scheduledAt + timer.delay,
389
+ delay: timer.delay
390
+ });
391
+ }
392
+ effects.push(effect);
393
+ }
394
+ }
395
+ restored = true;
396
+ return [snapshot, tagEffects(effects, true)];
397
+ },
398
+ initialTransition(...args) {
399
+ if (restored) {
400
+ throw new Error('initialTransition() cannot initialize a restored execution');
401
+ }
402
+ const [snapshot, effects] = createActor.withSystemInspector(inspect, () => createActor.withExecutionIdentity(executionIdentity, () => effectDescriptor.initialTransition(logic, ...args)));
403
+ return [installSystemRuntime(snapshot), tagEffects(effects)];
404
+ },
405
+ transition(snapshot, event) {
406
+ const [nextSnapshot, effects] = createActor.withSystemInspector(inspect, () => createActor.withExecutionIdentity(executionIdentity, () => effectDescriptor.transition(logic, snapshot, event)));
407
+ return [installSystemRuntime(nextSnapshot), tagEffects(effects)];
408
+ },
409
+ getActorRef(snapshot, address) {
410
+ const root = createActor.getSnapshotActorRef(snapshot)?.actor;
411
+ if (!root || address === undefined) {
412
+ return root;
413
+ }
414
+ return findByAddress(root, address);
415
+ },
416
+ async executeEffects(effects) {
417
+ if (currentBatch) {
418
+ throw new Error('executeEffects calls must not overlap: await the previous call before starting the next batch.');
419
+ }
420
+ const batch = {
421
+ rootEvents: [],
422
+ failures: [],
423
+ pending: new Set()
424
+ };
425
+ currentBatch = batch;
426
+ // `undefined` lets the effect's default parameter (the actor's system,
427
+ // and through it the installed `systemRuntime`) apply; without any
428
+ // runtime, the empty object makes unsupported operations throw instead
429
+ // of silently running local behavior on a durable host.
430
+ const fallbackRuntime = hasSystemRuntime ? undefined : {};
431
+ try {
432
+ for (const tagged of effects) {
433
+ const {
434
+ effect
435
+ } = tagged;
436
+ const metadata = {
437
+ id: tagged.id,
438
+ transitionIndex: tagged.transitionIndex,
439
+ effectIndex: tagged.effectIndex
440
+ };
441
+ const perEffectRuntime = adapter.runtime?.(metadata, effect);
442
+ const timerDeadline = restoredTimerDeadlines.get(effect);
443
+ // A per-effect runtime overrides the system runtime
444
+ // operation-by-operation; operations it omits keep the system
445
+ // runtime's behavior.
446
+ const runtime = perEffectRuntime || timerDeadline ? wrapRuntime({
447
+ ...systemRuntime,
448
+ ...perEffectRuntime
449
+ }, hasSystemRuntime, !!perEffectRuntime || hasSystemRuntime, timerDeadline) : fallbackRuntime;
450
+ if (effect.kind === 'action') {
451
+ // Custom actions have no default-parameter fallback to the actor's
452
+ // system, so hand them the wrapped system runtime directly.
453
+ await adapter.executeAction(effect, metadata, runtime ?? wrappedSystemRuntime ?? {});
454
+ } else {
455
+ await effect.exec(runtime);
456
+ }
457
+ }
458
+ await settle(batch);
459
+ pendingRootEvents.push(...batch.rootEvents);
460
+ } catch (error) {
461
+ // Drain before discarding so batch-initiated operations are not still
462
+ // running when the retrying host re-executes the effects. The failed
463
+ // batch's captures and failures are discarded with it.
464
+ await drain(batch);
465
+ throw error;
466
+ } finally {
467
+ // Runs after `settle()`/`drain()`, so operations the batch initiated
468
+ // are still treated as in-batch while they finish.
469
+ currentBatch = undefined;
470
+ }
471
+ },
472
+ async waitForEvent() {
473
+ if (lastTransitionIndex === undefined) {
474
+ throw new Error('Cannot wait for an event before the first transition or restore');
475
+ }
476
+ // Root-bound events produced while effects executed are handed out
477
+ // before durably waiting for an external event.
478
+ const queued = pendingRootEvents.shift();
479
+ if (queued) {
480
+ return queued.event;
481
+ }
482
+ return adapter.waitForEvent({
483
+ id: restored && nextTransitionIndex === 0 ? 'event:restore:0' : `event:${lastTransitionIndex}`,
484
+ transitionIndex: lastTransitionIndex
485
+ });
486
+ },
487
+ async run(...args) {
488
+ if (restored || startingTransitionIndex !== 0 || nextTransitionIndex !== startingTransitionIndex) {
489
+ throw new DurableExecutionResumeError();
490
+ }
491
+ let [snapshot, effects] = execution.initialTransition(...args);
492
+ await execution.executeEffects(effects);
493
+ while (snapshot.status === 'active') {
494
+ const event = await execution.waitForEvent();
495
+ [snapshot, effects] = execution.transition(snapshot, event);
496
+ await execution.executeEffects(effects);
497
+ }
498
+ const terminalSnapshot = snapshot;
499
+ if (terminalSnapshot.status === 'done') {
500
+ return terminalSnapshot.output;
501
+ }
502
+ if (terminalSnapshot.status === 'error') {
503
+ throw terminalSnapshot.error;
504
+ }
505
+ throw new DurableExecutionCancelledError();
506
+ }
507
+ };
508
+ return execution;
509
+ }
510
+
511
+ exports.DurableExecutionCancelledError = DurableExecutionCancelledError;
512
+ exports.DurableExecutionResumeError = DurableExecutionResumeError;
513
+ exports.createDurable = createDurable;
@@ -0,0 +1,5 @@
1
+ export {
2
+ DurableExecutionCancelledError,
3
+ DurableExecutionResumeError,
4
+ createDurable
5
+ } from "./xstate-durable.cjs.js";