@workflow/core 5.0.0-beta.4 → 5.0.0-beta.41

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (322) hide show
  1. package/dist/attribute-changes.d.ts +7 -0
  2. package/dist/attribute-changes.d.ts.map +1 -0
  3. package/dist/attribute-changes.js +25 -0
  4. package/dist/capabilities.d.ts +33 -1
  5. package/dist/capabilities.d.ts.map +1 -1
  6. package/dist/capabilities.js +71 -4
  7. package/dist/capture-stack.d.ts +16 -0
  8. package/dist/capture-stack.d.ts.map +1 -0
  9. package/dist/capture-stack.js +21 -0
  10. package/dist/class-serialization.d.ts +32 -0
  11. package/dist/class-serialization.d.ts.map +1 -1
  12. package/dist/class-serialization.js +37 -1
  13. package/dist/classify-error.d.ts +26 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +109 -6
  16. package/dist/context-errors.d.ts +27 -0
  17. package/dist/context-errors.d.ts.map +1 -0
  18. package/dist/context-errors.js +101 -0
  19. package/dist/context-violation-error.d.ts +97 -0
  20. package/dist/context-violation-error.d.ts.map +1 -0
  21. package/dist/context-violation-error.js +149 -0
  22. package/dist/create-hook.d.ts +62 -4
  23. package/dist/create-hook.d.ts.map +1 -1
  24. package/dist/create-hook.js +4 -3
  25. package/dist/define-hook.d.ts.map +1 -1
  26. package/dist/define-hook.js +20 -5
  27. package/dist/describe-error.d.ts +70 -0
  28. package/dist/describe-error.d.ts.map +1 -0
  29. package/dist/describe-error.js +189 -0
  30. package/dist/encryption.d.ts +37 -3
  31. package/dist/encryption.d.ts.map +1 -1
  32. package/dist/encryption.js +97 -31
  33. package/dist/events-consumer.d.ts +147 -1
  34. package/dist/events-consumer.d.ts.map +1 -1
  35. package/dist/events-consumer.js +444 -43
  36. package/dist/flushable-stream.d.ts +65 -10
  37. package/dist/flushable-stream.d.ts.map +1 -1
  38. package/dist/flushable-stream.js +131 -18
  39. package/dist/global.d.ts +37 -1
  40. package/dist/global.d.ts.map +1 -1
  41. package/dist/global.js +21 -3
  42. package/dist/index.d.ts +1 -0
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +2 -1
  45. package/dist/log-format.d.ts +25 -0
  46. package/dist/log-format.d.ts.map +1 -0
  47. package/dist/log-format.js +250 -0
  48. package/dist/logger.d.ts +29 -30
  49. package/dist/logger.d.ts.map +1 -1
  50. package/dist/logger.js +82 -32
  51. package/dist/private.d.ts +246 -8
  52. package/dist/private.d.ts.map +1 -1
  53. package/dist/private.js +345 -9
  54. package/dist/replay-payload-cache.d.ts +68 -0
  55. package/dist/replay-payload-cache.d.ts.map +1 -0
  56. package/dist/replay-payload-cache.js +160 -0
  57. package/dist/runtime/compute-instance.d.ts +12 -0
  58. package/dist/runtime/compute-instance.d.ts.map +1 -0
  59. package/dist/runtime/compute-instance.js +13 -0
  60. package/dist/runtime/constants.d.ts +251 -0
  61. package/dist/runtime/constants.d.ts.map +1 -1
  62. package/dist/runtime/constants.js +425 -16
  63. package/dist/runtime/count-step-started-events.d.ts +52 -0
  64. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  65. package/dist/runtime/count-step-started-events.js +72 -0
  66. package/dist/runtime/deployment-guard.d.ts +99 -0
  67. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  68. package/dist/runtime/deployment-guard.js +154 -0
  69. package/dist/runtime/get-port-lazy.d.ts +25 -0
  70. package/dist/runtime/get-port-lazy.d.ts.map +1 -0
  71. package/dist/runtime/get-port-lazy.js +92 -0
  72. package/dist/runtime/get-world-lazy.d.ts +23 -0
  73. package/dist/runtime/get-world-lazy.d.ts.map +1 -0
  74. package/dist/runtime/get-world-lazy.js +46 -0
  75. package/dist/runtime/helpers.d.ts +327 -10
  76. package/dist/runtime/helpers.d.ts.map +1 -1
  77. package/dist/runtime/helpers.js +586 -40
  78. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  79. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  80. package/dist/runtime/quickjs-assets.generated.js +30 -0
  81. package/dist/runtime/quickjs-entrypoint.d.ts +124 -0
  82. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  83. package/dist/runtime/quickjs-entrypoint.js +1437 -0
  84. package/dist/runtime/quickjs-runtime.d.ts +228 -0
  85. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  86. package/dist/runtime/quickjs-runtime.js +2372 -0
  87. package/dist/runtime/quickjs-serde.d.ts +107 -0
  88. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  89. package/dist/runtime/quickjs-serde.js +2098 -0
  90. package/dist/runtime/replay-budget.d.ts +89 -0
  91. package/dist/runtime/replay-budget.d.ts.map +1 -0
  92. package/dist/runtime/replay-budget.js +139 -0
  93. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  94. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  95. package/dist/runtime/replay-recovery-reporter.js +64 -0
  96. package/dist/runtime/resume-hook.d.ts +27 -4
  97. package/dist/runtime/resume-hook.d.ts.map +1 -1
  98. package/dist/runtime/resume-hook.js +452 -76
  99. package/dist/runtime/run-id-time.d.ts +19 -0
  100. package/dist/runtime/run-id-time.d.ts.map +1 -0
  101. package/dist/runtime/run-id-time.js +42 -0
  102. package/dist/runtime/run.d.ts +8 -2
  103. package/dist/runtime/run.d.ts.map +1 -1
  104. package/dist/runtime/run.js +62 -15
  105. package/dist/runtime/runs.d.ts +54 -3
  106. package/dist/runtime/runs.d.ts.map +1 -1
  107. package/dist/runtime/runs.js +119 -13
  108. package/dist/runtime/start.d.ts +70 -1
  109. package/dist/runtime/start.d.ts.map +1 -1
  110. package/dist/runtime/start.js +313 -60
  111. package/dist/runtime/step-executor.d.ts +177 -0
  112. package/dist/runtime/step-executor.d.ts.map +1 -0
  113. package/dist/runtime/step-executor.js +946 -0
  114. package/dist/runtime/step-latency.d.ts +197 -0
  115. package/dist/runtime/step-latency.d.ts.map +1 -0
  116. package/dist/runtime/step-latency.js +207 -0
  117. package/dist/runtime/step-ownership.d.ts +72 -0
  118. package/dist/runtime/step-ownership.d.ts.map +1 -0
  119. package/dist/runtime/step-ownership.js +114 -0
  120. package/dist/runtime/step-single-flight.d.ts +12 -0
  121. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  122. package/dist/runtime/step-single-flight.js +69 -0
  123. package/dist/runtime/suspension-handler.d.ts +109 -7
  124. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  125. package/dist/runtime/suspension-handler.js +486 -140
  126. package/dist/runtime/vm-mode.d.ts +44 -0
  127. package/dist/runtime/vm-mode.d.ts.map +1 -0
  128. package/dist/runtime/vm-mode.js +62 -0
  129. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  130. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  131. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  132. package/dist/runtime/wait-continuation.d.ts +84 -0
  133. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  134. package/dist/runtime/wait-continuation.js +105 -0
  135. package/dist/runtime/wait-until.d.ts +18 -0
  136. package/dist/runtime/wait-until.d.ts.map +1 -0
  137. package/dist/runtime/wait-until.js +42 -0
  138. package/dist/runtime/world-compatibility.d.ts +20 -0
  139. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  140. package/dist/runtime/world-compatibility.js +32 -0
  141. package/dist/runtime/world-init.d.ts +50 -0
  142. package/dist/runtime/world-init.d.ts.map +1 -0
  143. package/dist/runtime/world-init.js +50 -0
  144. package/dist/runtime/world.d.ts +14 -2
  145. package/dist/runtime/world.d.ts.map +1 -1
  146. package/dist/runtime/world.js +101 -26
  147. package/dist/runtime.d.ts +17 -12
  148. package/dist/runtime.d.ts.map +1 -1
  149. package/dist/runtime.js +3135 -328
  150. package/dist/schemas.d.ts +1 -1
  151. package/dist/schemas.d.ts.map +1 -1
  152. package/dist/schemas.js +1 -1
  153. package/dist/sealed-box.d.ts +167 -0
  154. package/dist/sealed-box.d.ts.map +1 -0
  155. package/dist/sealed-box.js +571 -0
  156. package/dist/serialization/client.d.ts +17 -0
  157. package/dist/serialization/client.d.ts.map +1 -0
  158. package/dist/serialization/client.js +48 -0
  159. package/dist/serialization/codec-devalue-vm.d.ts +16 -0
  160. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  161. package/dist/serialization/codec-devalue-vm.js +148 -0
  162. package/dist/serialization/codec-devalue.d.ts +14 -0
  163. package/dist/serialization/codec-devalue.d.ts.map +1 -0
  164. package/dist/serialization/codec-devalue.js +105 -0
  165. package/dist/serialization/codec.d.ts +125 -0
  166. package/dist/serialization/codec.d.ts.map +1 -0
  167. package/dist/serialization/codec.js +17 -0
  168. package/dist/serialization/compression.d.ts +104 -0
  169. package/dist/serialization/compression.d.ts.map +1 -0
  170. package/dist/serialization/compression.js +260 -0
  171. package/dist/serialization/encryption.d.ts +134 -0
  172. package/dist/serialization/encryption.d.ts.map +1 -0
  173. package/dist/serialization/encryption.js +186 -0
  174. package/dist/serialization/errors.d.ts +34 -0
  175. package/dist/serialization/errors.d.ts.map +1 -0
  176. package/dist/serialization/errors.js +59 -0
  177. package/dist/serialization/format.d.ts +60 -0
  178. package/dist/serialization/format.d.ts.map +1 -0
  179. package/dist/serialization/format.js +97 -0
  180. package/dist/serialization/hardened.d.ts +155 -0
  181. package/dist/serialization/hardened.d.ts.map +1 -0
  182. package/dist/serialization/hardened.js +523 -0
  183. package/dist/serialization/index.d.ts +20 -0
  184. package/dist/serialization/index.d.ts.map +1 -0
  185. package/dist/serialization/index.js +22 -0
  186. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  187. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  188. package/dist/serialization/reducers/class-vm.js +77 -0
  189. package/dist/serialization/reducers/class.d.ts +11 -0
  190. package/dist/serialization/reducers/class.d.ts.map +1 -0
  191. package/dist/serialization/reducers/class.js +73 -0
  192. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  193. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  194. package/dist/serialization/reducers/common-vm.js +579 -0
  195. package/dist/serialization/reducers/common.d.ts +16 -0
  196. package/dist/serialization/reducers/common.d.ts.map +1 -0
  197. package/dist/serialization/reducers/common.js +478 -0
  198. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  199. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  200. package/dist/serialization/reducers/step-function-vm.js +97 -0
  201. package/dist/serialization/reducers/step-function.d.ts +35 -0
  202. package/dist/serialization/reducers/step-function.d.ts.map +1 -0
  203. package/dist/serialization/reducers/step-function.js +104 -0
  204. package/dist/serialization/step.d.ts +17 -0
  205. package/dist/serialization/step.d.ts.map +1 -0
  206. package/dist/serialization/step.js +48 -0
  207. package/dist/serialization/types.d.ts +273 -0
  208. package/dist/serialization/types.d.ts.map +1 -0
  209. package/dist/serialization/types.js +35 -0
  210. package/dist/serialization/workflow-vm.d.ts +29 -0
  211. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  212. package/dist/serialization/workflow-vm.js +71 -0
  213. package/dist/serialization/workflow.d.ts +29 -0
  214. package/dist/serialization/workflow.d.ts.map +1 -0
  215. package/dist/serialization/workflow.js +54 -0
  216. package/dist/serialization-format.d.ts +60 -4
  217. package/dist/serialization-format.d.ts.map +1 -1
  218. package/dist/serialization-format.js +276 -56
  219. package/dist/serialization.d.ts +374 -221
  220. package/dist/serialization.d.ts.map +1 -1
  221. package/dist/serialization.js +2300 -783
  222. package/dist/set-attributes.d.ts +13 -0
  223. package/dist/set-attributes.d.ts.map +1 -0
  224. package/dist/set-attributes.js +60 -0
  225. package/dist/sleep.d.ts.map +1 -1
  226. package/dist/sleep.js +3 -2
  227. package/dist/source-map.d.ts +25 -0
  228. package/dist/source-map.d.ts.map +1 -1
  229. package/dist/source-map.js +148 -10
  230. package/dist/step/context-storage.d.ts +61 -2
  231. package/dist/step/context-storage.d.ts.map +1 -1
  232. package/dist/step/context-storage.js +7 -5
  233. package/dist/step/get-closure-vars.d.ts.map +1 -1
  234. package/dist/step/get-closure-vars.js +3 -2
  235. package/dist/step/get-step-metadata.d.ts.map +1 -1
  236. package/dist/step/get-step-metadata.js +3 -2
  237. package/dist/step/get-workflow-metadata.d.ts.map +1 -1
  238. package/dist/step/get-workflow-metadata.js +3 -2
  239. package/dist/step/writable-stream.d.ts.map +1 -1
  240. package/dist/step/writable-stream.js +71 -7
  241. package/dist/step.d.ts.map +1 -1
  242. package/dist/step.js +225 -29
  243. package/dist/symbols.d.ts +54 -0
  244. package/dist/symbols.d.ts.map +1 -1
  245. package/dist/symbols.js +55 -1
  246. package/dist/telemetry/semantic-conventions.d.ts +265 -2
  247. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  248. package/dist/telemetry/semantic-conventions.js +190 -1
  249. package/dist/telemetry.d.ts +73 -0
  250. package/dist/telemetry.d.ts.map +1 -1
  251. package/dist/telemetry.js +153 -16
  252. package/dist/types.d.ts +6 -0
  253. package/dist/types.d.ts.map +1 -1
  254. package/dist/types.js +23 -1
  255. package/dist/util.d.ts +16 -6
  256. package/dist/util.d.ts.map +1 -1
  257. package/dist/util.js +25 -16
  258. package/dist/version.d.ts +1 -1
  259. package/dist/version.d.ts.map +1 -1
  260. package/dist/version.js +2 -2
  261. package/dist/vm/index.d.ts.map +1 -1
  262. package/dist/vm/index.js +85 -14
  263. package/dist/vm/script-cache.d.ts +28 -0
  264. package/dist/vm/script-cache.d.ts.map +1 -0
  265. package/dist/vm/script-cache.js +140 -0
  266. package/dist/workflow/abort-controller.d.ts +65 -0
  267. package/dist/workflow/abort-controller.d.ts.map +1 -0
  268. package/dist/workflow/abort-controller.js +312 -0
  269. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  270. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  271. package/dist/workflow/attribute-dispatcher.js +48 -0
  272. package/dist/workflow/create-hook.d.ts.map +1 -1
  273. package/dist/workflow/create-hook.js +25 -3
  274. package/dist/workflow/define-hook.d.ts +1 -1
  275. package/dist/workflow/define-hook.d.ts.map +1 -1
  276. package/dist/workflow/define-hook.js +8 -4
  277. package/dist/workflow/get-workflow-metadata.d.ts.map +1 -1
  278. package/dist/workflow/get-workflow-metadata.js +14 -3
  279. package/dist/workflow/hook.d.ts.map +1 -1
  280. package/dist/workflow/hook.js +302 -36
  281. package/dist/workflow/index.d.ts +1 -0
  282. package/dist/workflow/index.d.ts.map +1 -1
  283. package/dist/workflow/index.js +5 -3
  284. package/dist/workflow/set-attributes.d.ts +68 -0
  285. package/dist/workflow/set-attributes.d.ts.map +1 -0
  286. package/dist/workflow/set-attributes.js +60 -0
  287. package/dist/workflow/sleep.d.ts.map +1 -1
  288. package/dist/workflow/sleep.js +57 -8
  289. package/dist/workflow/world-init-stub.d.ts +15 -0
  290. package/dist/workflow/world-init-stub.d.ts.map +1 -0
  291. package/dist/workflow/world-init-stub.js +15 -0
  292. package/dist/workflow.d.ts +79 -3
  293. package/dist/workflow.d.ts.map +1 -1
  294. package/dist/workflow.js +831 -553
  295. package/docs/api-reference/create-hook.mdx +79 -0
  296. package/docs/api-reference/create-webhook.mdx +1 -0
  297. package/docs/api-reference/define-hook.mdx +26 -24
  298. package/docs/api-reference/fatal-error.mdx +29 -7
  299. package/docs/api-reference/fetch.mdx +8 -4
  300. package/docs/api-reference/index.mdx +3 -0
  301. package/docs/api-reference/set-attributes.mdx +61 -0
  302. package/docs/api-reference/sleep.mdx +1 -1
  303. package/docs/foundations/cancellation.mdx +459 -0
  304. package/docs/foundations/errors-and-retries.mdx +7 -3
  305. package/docs/foundations/hooks.mdx +29 -0
  306. package/docs/foundations/idempotency.mdx +243 -11
  307. package/docs/foundations/index.mdx +1 -23
  308. package/docs/foundations/meta.json +3 -1
  309. package/docs/foundations/serialization.mdx +77 -41
  310. package/docs/foundations/starting-workflows.mdx +79 -2
  311. package/docs/foundations/streaming.mdx +14 -23
  312. package/docs/foundations/versioning.mdx +263 -0
  313. package/docs/how-it-works/cancellation.mdx +287 -0
  314. package/docs/how-it-works/code-transform.mdx +21 -17
  315. package/docs/how-it-works/encryption.mdx +5 -5
  316. package/docs/how-it-works/event-sourcing.mdx +17 -9
  317. package/docs/how-it-works/framework-integrations.mdx +96 -337
  318. package/docs/how-it-works/meta.json +2 -1
  319. package/package.json +31 -13
  320. package/dist/runtime/step-handler.d.ts +0 -2
  321. package/dist/runtime/step-handler.d.ts.map +0 -1
  322. package/dist/runtime/step-handler.js +0 -678
@@ -0,0 +1,114 @@
1
+ import { getInlineOwnershipLeaseSeconds } from './constants.js';
2
+ /**
3
+ * Inline step ownership helpers for the pending-step dispatch decision table
4
+ * in runtime.ts (workflow#2780). Ownership state itself is derived per-replay
5
+ * from the event log by the step consumer in step.ts and surfaced on
6
+ * StepInvocationQueueItem; these functions interpret that state at dispatch
7
+ * time.
8
+ */
9
+ /**
10
+ * Whether inline step ownership is active for a pending step: created,
11
+ * latest `step_started` carries an owner stamp, and no `step_retrying` has
12
+ * been observed (from `step_retrying` on, the step is queue-owned by its
13
+ * delayed retry handoff / replay requeue, so ownership is permanently
14
+ * lapsed for the correlation ID).
15
+ */
16
+ export function isStepOwnershipActive(step) {
17
+ return (step.hasCreatedEvent === true &&
18
+ step.ownerMessageId !== undefined &&
19
+ step.sawRetrying !== true);
20
+ }
21
+ /**
22
+ * Seconds left on an owned step's liveness lease, anchored at its latest
23
+ * `step_started`. 0 means the lease has expired (or the start timestamp is
24
+ * missing — the degraded mode for worlds whose events lack usable
25
+ * timestamps), in which case dispatch falls back to the immediate enqueue.
26
+ *
27
+ * The result is clamped to the configured lease: `lastStartedAt` is the
28
+ * server-stamped event `createdAt` while `nowMs` is the local clock, so a
29
+ * client running behind the server would otherwise compute a remainder
30
+ * LONGER than the lease itself — and with the lease tuned to the 900s cap,
31
+ * a `delaySeconds` above the queue's per-message maximum, which SQS-backed
32
+ * worlds reject outright (the wake replay's enqueue would throw and ride
33
+ * the redelivery loop). The clamp makes skew strictly harmless; remaining
34
+ * time can never legitimately exceed the full lease anyway.
35
+ */
36
+ export function stepLeaseRemainingSeconds(step, nowMs) {
37
+ if (step.lastStartedAt === undefined)
38
+ return 0;
39
+ const leaseSeconds = getInlineOwnershipLeaseSeconds();
40
+ const remainingMs = step.lastStartedAt + leaseSeconds * 1000 - nowMs;
41
+ return Math.min(leaseSeconds, Math.max(0, Math.ceil(remainingMs / 1000)));
42
+ }
43
+ /**
44
+ * Idempotency key for the delayed backstop wake of an inline-owned step.
45
+ *
46
+ * The key is scoped to the current OWNERSHIP EPOCH — the timestamp of the
47
+ * latest `step_started` — not just the correlation ID. Within one epoch,
48
+ * every wake replay derives the same key, so fan-out stays capped at one
49
+ * pending backstop per step. But when owner recovery re-stamps the step
50
+ * (queue redelivery of the owning message → new `step_started` → new
51
+ * `lastStartedAt`), the key CHANGES. This is load-bearing for liveness:
52
+ * queues dedupe an idempotency key for the lifetime of the original
53
+ * message — including while a delivery of it is in flight — so a backstop
54
+ * that fires during a refreshed lease and tries to re-arm under a fixed key
55
+ * would dedupe against ITSELF and be dropped, leaving no escape hatch if
56
+ * the recovered owner later dies without further redeliveries. The epoch
57
+ * suffix gives the re-arm a fresh key. Pending backstops are bounded by the
58
+ * number of ownership epochs, i.e. the queue's redelivery budget for the
59
+ * owning message.
60
+ *
61
+ * The epoch value comes from the persisted event's `createdAt`, so every
62
+ * replayer derives the same key. Callers only build backstops when the
63
+ * lease has time remaining, which requires `lastStartedAt` to be set.
64
+ *
65
+ * The key must also never be the step message's own `idempotencyKey`
66
+ * (the bare correlation ID): the owner's retry handoff enqueues the step
67
+ * under that key with a short backoff, and a pending backstop sharing it
68
+ * would absorb the retry — turning a 1s backoff into a full-lease stall.
69
+ */
70
+ export function backstopIdempotencyKey(step) {
71
+ return `${step.correlationId}:backstop:${step.lastStartedAt}`;
72
+ }
73
+ /**
74
+ * Whether any of the given pending correlation IDs is inline-owned by
75
+ * `messageId` per the raw event log: its LATEST `step_started` carries
76
+ * `ownerMessageId === messageId` and no `step_retrying` follows it. Used by
77
+ * the background-step fast path, which sees raw events (not the replay's
78
+ * queueItems), to decide whether to fall through to the main loop so this
79
+ * invocation can recover a step it owns instead of returning and leaving it
80
+ * to the delayed backstop.
81
+ */
82
+ export function hasPendingStepOwnedByMessage(events, pendingCorrelationIds, messageId) {
83
+ // Latest-wins scan: events are in log order, so later entries overwrite.
84
+ // A step_retrying lapses ownership permanently (matching the sawRetrying
85
+ // semantics of the replay consumer in step.ts) — from that point the step
86
+ // is queue-owned, whatever starts follow.
87
+ const latestOwner = new Map();
88
+ const sawRetrying = new Set();
89
+ for (const e of events) {
90
+ if (e.correlationId === undefined)
91
+ continue;
92
+ if (e.eventType === 'step_started') {
93
+ const owner = 'eventData' in e &&
94
+ e.eventData &&
95
+ 'ownerMessageId' in e.eventData &&
96
+ typeof e.eventData.ownerMessageId === 'string'
97
+ ? e.eventData.ownerMessageId
98
+ : undefined;
99
+ latestOwner.set(e.correlationId, owner);
100
+ }
101
+ else if (e.eventType === 'step_retrying') {
102
+ sawRetrying.add(e.correlationId);
103
+ }
104
+ }
105
+ for (const id of pendingCorrelationIds) {
106
+ if (id !== undefined &&
107
+ !sawRetrying.has(id) &&
108
+ latestOwner.get(id) === messageId) {
109
+ return true;
110
+ }
111
+ }
112
+ return false;
113
+ }
114
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1vd25lcnNoaXAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvcnVudGltZS9zdGVwLW93bmVyc2hpcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVoRTs7Ozs7O0dBTUc7QUFFSDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsSUFBNkI7SUFDakUsT0FBTyxDQUNMLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSTtRQUM3QixJQUFJLENBQUMsY0FBYyxLQUFLLFNBQVM7UUFDakMsSUFBSSxDQUFDLFdBQVcsS0FBSyxJQUFJLENBQzFCLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxNQUFNLFVBQVUseUJBQXlCLENBQ3ZDLElBQTZCLEVBQzdCLEtBQWE7SUFFYixJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssU0FBUztRQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQy9DLE1BQU0sWUFBWSxHQUFHLDhCQUE4QixFQUFFLENBQUM7SUFDdEQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxZQUFZLEdBQUcsSUFBSSxHQUFHLEtBQUssQ0FBQztJQUNyRSxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM1RSxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLElBQTZCO0lBQ2xFLE9BQU8sR0FBRyxJQUFJLENBQUMsYUFBYSxhQUFhLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztBQUNoRSxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsNEJBQTRCLENBQzFDLE1BQWUsRUFDZixxQkFBOEMsRUFDOUMsU0FBaUI7SUFFakIseUVBQXlFO0lBQ3pFLHlFQUF5RTtJQUN6RSwwRUFBMEU7SUFDMUUsMENBQTBDO0lBQzFDLE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUE4QixDQUFDO0lBQzFELE1BQU0sV0FBVyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDdEMsS0FBSyxNQUFNLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsQ0FBQyxhQUFhLEtBQUssU0FBUztZQUFFLFNBQVM7UUFDNUMsSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLGNBQWMsRUFBRSxDQUFDO1lBQ25DLE1BQU0sS0FBSyxHQUNULFdBQVcsSUFBSSxDQUFDO2dCQUNoQixDQUFDLENBQUMsU0FBUztnQkFDWCxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsU0FBUztnQkFDL0IsT0FBTyxDQUFDLENBQUMsU0FBUyxDQUFDLGNBQWMsS0FBSyxRQUFRO2dCQUM1QyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxjQUFjO2dCQUM1QixDQUFDLENBQUMsU0FBUyxDQUFDO1lBQ2hCLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMxQyxDQUFDO2FBQU0sSUFBSSxDQUFDLENBQUMsU0FBUyxLQUFLLGVBQWUsRUFBRSxDQUFDO1lBQzNDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBQ0QsS0FBSyxNQUFNLEVBQUUsSUFBSSxxQkFBcUIsRUFBRSxDQUFDO1FBQ3ZDLElBQ0UsRUFBRSxLQUFLLFNBQVM7WUFDaEIsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNwQixXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLFNBQVMsRUFDakMsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLEtBQUssQ0FBQztBQUNmLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IEV2ZW50IH0gZnJvbSAnQHdvcmtmbG93L3dvcmxkJztcbmltcG9ydCB0eXBlIHsgU3RlcEludm9jYXRpb25RdWV1ZUl0ZW0gfSBmcm9tICcuLi9nbG9iYWwuanMnO1xuaW1wb3J0IHsgZ2V0SW5saW5lT3duZXJzaGlwTGVhc2VTZWNvbmRzIH0gZnJvbSAnLi9jb25zdGFudHMuanMnO1xuXG4vKipcbiAqIElubGluZSBzdGVwIG93bmVyc2hpcCBoZWxwZXJzIGZvciB0aGUgcGVuZGluZy1zdGVwIGRpc3BhdGNoIGRlY2lzaW9uIHRhYmxlXG4gKiBpbiBydW50aW1lLnRzICh3b3JrZmxvdyMyNzgwKS4gT3duZXJzaGlwIHN0YXRlIGl0c2VsZiBpcyBkZXJpdmVkIHBlci1yZXBsYXlcbiAqIGZyb20gdGhlIGV2ZW50IGxvZyBieSB0aGUgc3RlcCBjb25zdW1lciBpbiBzdGVwLnRzIGFuZCBzdXJmYWNlZCBvblxuICogU3RlcEludm9jYXRpb25RdWV1ZUl0ZW07IHRoZXNlIGZ1bmN0aW9ucyBpbnRlcnByZXQgdGhhdCBzdGF0ZSBhdCBkaXNwYXRjaFxuICogdGltZS5cbiAqL1xuXG4vKipcbiAqIFdoZXRoZXIgaW5saW5lIHN0ZXAgb3duZXJzaGlwIGlzIGFjdGl2ZSBmb3IgYSBwZW5kaW5nIHN0ZXA6IGNyZWF0ZWQsXG4gKiBsYXRlc3QgYHN0ZXBfc3RhcnRlZGAgY2FycmllcyBhbiBvd25lciBzdGFtcCwgYW5kIG5vIGBzdGVwX3JldHJ5aW5nYCBoYXNcbiAqIGJlZW4gb2JzZXJ2ZWQgKGZyb20gYHN0ZXBfcmV0cnlpbmdgIG9uLCB0aGUgc3RlcCBpcyBxdWV1ZS1vd25lZCBieSBpdHNcbiAqIGRlbGF5ZWQgcmV0cnkgaGFuZG9mZiAvIHJlcGxheSByZXF1ZXVlLCBzbyBvd25lcnNoaXAgaXMgcGVybWFuZW50bHlcbiAqIGxhcHNlZCBmb3IgdGhlIGNvcnJlbGF0aW9uIElEKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3RlcE93bmVyc2hpcEFjdGl2ZShzdGVwOiBTdGVwSW52b2NhdGlvblF1ZXVlSXRlbSk6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIHN0ZXAuaGFzQ3JlYXRlZEV2ZW50ID09PSB0cnVlICYmXG4gICAgc3RlcC5vd25lck1lc3NhZ2VJZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgc3RlcC5zYXdSZXRyeWluZyAhPT0gdHJ1ZVxuICApO1xufVxuXG4vKipcbiAqIFNlY29uZHMgbGVmdCBvbiBhbiBvd25lZCBzdGVwJ3MgbGl2ZW5lc3MgbGVhc2UsIGFuY2hvcmVkIGF0IGl0cyBsYXRlc3RcbiAqIGBzdGVwX3N0YXJ0ZWRgLiAwIG1lYW5zIHRoZSBsZWFzZSBoYXMgZXhwaXJlZCAob3IgdGhlIHN0YXJ0IHRpbWVzdGFtcCBpc1xuICogbWlzc2luZyDigJQgdGhlIGRlZ3JhZGVkIG1vZGUgZm9yIHdvcmxkcyB3aG9zZSBldmVudHMgbGFjayB1c2FibGVcbiAqIHRpbWVzdGFtcHMpLCBpbiB3aGljaCBjYXNlIGRpc3BhdGNoIGZhbGxzIGJhY2sgdG8gdGhlIGltbWVkaWF0ZSBlbnF1ZXVlLlxuICpcbiAqIFRoZSByZXN1bHQgaXMgY2xhbXBlZCB0byB0aGUgY29uZmlndXJlZCBsZWFzZTogYGxhc3RTdGFydGVkQXRgIGlzIHRoZVxuICogc2VydmVyLXN0YW1wZWQgZXZlbnQgYGNyZWF0ZWRBdGAgd2hpbGUgYG5vd01zYCBpcyB0aGUgbG9jYWwgY2xvY2ssIHNvIGFcbiAqIGNsaWVudCBydW5uaW5nIGJlaGluZCB0aGUgc2VydmVyIHdvdWxkIG90aGVyd2lzZSBjb21wdXRlIGEgcmVtYWluZGVyXG4gKiBMT05HRVIgdGhhbiB0aGUgbGVhc2UgaXRzZWxmIOKAlCBhbmQgd2l0aCB0aGUgbGVhc2UgdHVuZWQgdG8gdGhlIDkwMHMgY2FwLFxuICogYSBgZGVsYXlTZWNvbmRzYCBhYm92ZSB0aGUgcXVldWUncyBwZXItbWVzc2FnZSBtYXhpbXVtLCB3aGljaCBTUVMtYmFja2VkXG4gKiB3b3JsZHMgcmVqZWN0IG91dHJpZ2h0ICh0aGUgd2FrZSByZXBsYXkncyBlbnF1ZXVlIHdvdWxkIHRocm93IGFuZCByaWRlXG4gKiB0aGUgcmVkZWxpdmVyeSBsb29wKS4gVGhlIGNsYW1wIG1ha2VzIHNrZXcgc3RyaWN0bHkgaGFybWxlc3M7IHJlbWFpbmluZ1xuICogdGltZSBjYW4gbmV2ZXIgbGVnaXRpbWF0ZWx5IGV4Y2VlZCB0aGUgZnVsbCBsZWFzZSBhbnl3YXkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdGVwTGVhc2VSZW1haW5pbmdTZWNvbmRzKFxuICBzdGVwOiBTdGVwSW52b2NhdGlvblF1ZXVlSXRlbSxcbiAgbm93TXM6IG51bWJlclxuKTogbnVtYmVyIHtcbiAgaWYgKHN0ZXAubGFzdFN0YXJ0ZWRBdCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMDtcbiAgY29uc3QgbGVhc2VTZWNvbmRzID0gZ2V0SW5saW5lT3duZXJzaGlwTGVhc2VTZWNvbmRzKCk7XG4gIGNvbnN0IHJlbWFpbmluZ01zID0gc3RlcC5sYXN0U3RhcnRlZEF0ICsgbGVhc2VTZWNvbmRzICogMTAwMCAtIG5vd01zO1xuICByZXR1cm4gTWF0aC5taW4obGVhc2VTZWNvbmRzLCBNYXRoLm1heCgwLCBNYXRoLmNlaWwocmVtYWluaW5nTXMgLyAxMDAwKSkpO1xufVxuXG4vKipcbiAqIElkZW1wb3RlbmN5IGtleSBmb3IgdGhlIGRlbGF5ZWQgYmFja3N0b3Agd2FrZSBvZiBhbiBpbmxpbmUtb3duZWQgc3RlcC5cbiAqXG4gKiBUaGUga2V5IGlzIHNjb3BlZCB0byB0aGUgY3VycmVudCBPV05FUlNISVAgRVBPQ0gg4oCUIHRoZSB0aW1lc3RhbXAgb2YgdGhlXG4gKiBsYXRlc3QgYHN0ZXBfc3RhcnRlZGAg4oCUIG5vdCBqdXN0IHRoZSBjb3JyZWxhdGlvbiBJRC4gV2l0aGluIG9uZSBlcG9jaCxcbiAqIGV2ZXJ5IHdha2UgcmVwbGF5IGRlcml2ZXMgdGhlIHNhbWUga2V5LCBzbyBmYW4tb3V0IHN0YXlzIGNhcHBlZCBhdCBvbmVcbiAqIHBlbmRpbmcgYmFja3N0b3AgcGVyIHN0ZXAuIEJ1dCB3aGVuIG93bmVyIHJlY292ZXJ5IHJlLXN0YW1wcyB0aGUgc3RlcFxuICogKHF1ZXVlIHJlZGVsaXZlcnkgb2YgdGhlIG93bmluZyBtZXNzYWdlIOKGkiBuZXcgYHN0ZXBfc3RhcnRlZGAg4oaSIG5ld1xuICogYGxhc3RTdGFydGVkQXRgKSwgdGhlIGtleSBDSEFOR0VTLiBUaGlzIGlzIGxvYWQtYmVhcmluZyBmb3IgbGl2ZW5lc3M6XG4gKiBxdWV1ZXMgZGVkdXBlIGFuIGlkZW1wb3RlbmN5IGtleSBmb3IgdGhlIGxpZmV0aW1lIG9mIHRoZSBvcmlnaW5hbFxuICogbWVzc2FnZSDigJQgaW5jbHVkaW5nIHdoaWxlIGEgZGVsaXZlcnkgb2YgaXQgaXMgaW4gZmxpZ2h0IOKAlCBzbyBhIGJhY2tzdG9wXG4gKiB0aGF0IGZpcmVzIGR1cmluZyBhIHJlZnJlc2hlZCBsZWFzZSBhbmQgdHJpZXMgdG8gcmUtYXJtIHVuZGVyIGEgZml4ZWQga2V5XG4gKiB3b3VsZCBkZWR1cGUgYWdhaW5zdCBJVFNFTEYgYW5kIGJlIGRyb3BwZWQsIGxlYXZpbmcgbm8gZXNjYXBlIGhhdGNoIGlmXG4gKiB0aGUgcmVjb3ZlcmVkIG93bmVyIGxhdGVyIGRpZXMgd2l0aG91dCBmdXJ0aGVyIHJlZGVsaXZlcmllcy4gVGhlIGVwb2NoXG4gKiBzdWZmaXggZ2l2ZXMgdGhlIHJlLWFybSBhIGZyZXNoIGtleS4gUGVuZGluZyBiYWNrc3RvcHMgYXJlIGJvdW5kZWQgYnkgdGhlXG4gKiBudW1iZXIgb2Ygb3duZXJzaGlwIGVwb2NocywgaS5lLiB0aGUgcXVldWUncyByZWRlbGl2ZXJ5IGJ1ZGdldCBmb3IgdGhlXG4gKiBvd25pbmcgbWVzc2FnZS5cbiAqXG4gKiBUaGUgZXBvY2ggdmFsdWUgY29tZXMgZnJvbSB0aGUgcGVyc2lzdGVkIGV2ZW50J3MgYGNyZWF0ZWRBdGAsIHNvIGV2ZXJ5XG4gKiByZXBsYXllciBkZXJpdmVzIHRoZSBzYW1lIGtleS4gQ2FsbGVycyBvbmx5IGJ1aWxkIGJhY2tzdG9wcyB3aGVuIHRoZVxuICogbGVhc2UgaGFzIHRpbWUgcmVtYWluaW5nLCB3aGljaCByZXF1aXJlcyBgbGFzdFN0YXJ0ZWRBdGAgdG8gYmUgc2V0LlxuICpcbiAqIFRoZSBrZXkgbXVzdCBhbHNvIG5ldmVyIGJlIHRoZSBzdGVwIG1lc3NhZ2UncyBvd24gYGlkZW1wb3RlbmN5S2V5YFxuICogKHRoZSBiYXJlIGNvcnJlbGF0aW9uIElEKTogdGhlIG93bmVyJ3MgcmV0cnkgaGFuZG9mZiBlbnF1ZXVlcyB0aGUgc3RlcFxuICogdW5kZXIgdGhhdCBrZXkgd2l0aCBhIHNob3J0IGJhY2tvZmYsIGFuZCBhIHBlbmRpbmcgYmFja3N0b3Agc2hhcmluZyBpdFxuICogd291bGQgYWJzb3JiIHRoZSByZXRyeSDigJQgdHVybmluZyBhIDFzIGJhY2tvZmYgaW50byBhIGZ1bGwtbGVhc2Ugc3RhbGwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBiYWNrc3RvcElkZW1wb3RlbmN5S2V5KHN0ZXA6IFN0ZXBJbnZvY2F0aW9uUXVldWVJdGVtKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke3N0ZXAuY29ycmVsYXRpb25JZH06YmFja3N0b3A6JHtzdGVwLmxhc3RTdGFydGVkQXR9YDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGFueSBvZiB0aGUgZ2l2ZW4gcGVuZGluZyBjb3JyZWxhdGlvbiBJRHMgaXMgaW5saW5lLW93bmVkIGJ5XG4gKiBgbWVzc2FnZUlkYCBwZXIgdGhlIHJhdyBldmVudCBsb2c6IGl0cyBMQVRFU1QgYHN0ZXBfc3RhcnRlZGAgY2Fycmllc1xuICogYG93bmVyTWVzc2FnZUlkID09PSBtZXNzYWdlSWRgIGFuZCBubyBgc3RlcF9yZXRyeWluZ2AgZm9sbG93cyBpdC4gVXNlZCBieVxuICogdGhlIGJhY2tncm91bmQtc3RlcCBmYXN0IHBhdGgsIHdoaWNoIHNlZXMgcmF3IGV2ZW50cyAobm90IHRoZSByZXBsYXknc1xuICogcXVldWVJdGVtcyksIHRvIGRlY2lkZSB3aGV0aGVyIHRvIGZhbGwgdGhyb3VnaCB0byB0aGUgbWFpbiBsb29wIHNvIHRoaXNcbiAqIGludm9jYXRpb24gY2FuIHJlY292ZXIgYSBzdGVwIGl0IG93bnMgaW5zdGVhZCBvZiByZXR1cm5pbmcgYW5kIGxlYXZpbmcgaXRcbiAqIHRvIHRoZSBkZWxheWVkIGJhY2tzdG9wLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzUGVuZGluZ1N0ZXBPd25lZEJ5TWVzc2FnZShcbiAgZXZlbnRzOiBFdmVudFtdLFxuICBwZW5kaW5nQ29ycmVsYXRpb25JZHM6IFNldDxzdHJpbmcgfCB1bmRlZmluZWQ+LFxuICBtZXNzYWdlSWQ6IHN0cmluZ1xuKTogYm9vbGVhbiB7XG4gIC8vIExhdGVzdC13aW5zIHNjYW46IGV2ZW50cyBhcmUgaW4gbG9nIG9yZGVyLCBzbyBsYXRlciBlbnRyaWVzIG92ZXJ3cml0ZS5cbiAgLy8gQSBzdGVwX3JldHJ5aW5nIGxhcHNlcyBvd25lcnNoaXAgcGVybWFuZW50bHkgKG1hdGNoaW5nIHRoZSBzYXdSZXRyeWluZ1xuICAvLyBzZW1hbnRpY3Mgb2YgdGhlIHJlcGxheSBjb25zdW1lciBpbiBzdGVwLnRzKSDigJQgZnJvbSB0aGF0IHBvaW50IHRoZSBzdGVwXG4gIC8vIGlzIHF1ZXVlLW93bmVkLCB3aGF0ZXZlciBzdGFydHMgZm9sbG93LlxuICBjb25zdCBsYXRlc3RPd25lciA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+KCk7XG4gIGNvbnN0IHNhd1JldHJ5aW5nID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgZSBvZiBldmVudHMpIHtcbiAgICBpZiAoZS5jb3JyZWxhdGlvbklkID09PSB1bmRlZmluZWQpIGNvbnRpbnVlO1xuICAgIGlmIChlLmV2ZW50VHlwZSA9PT0gJ3N0ZXBfc3RhcnRlZCcpIHtcbiAgICAgIGNvbnN0IG93bmVyID1cbiAgICAgICAgJ2V2ZW50RGF0YScgaW4gZSAmJlxuICAgICAgICBlLmV2ZW50RGF0YSAmJlxuICAgICAgICAnb3duZXJNZXNzYWdlSWQnIGluIGUuZXZlbnREYXRhICYmXG4gICAgICAgIHR5cGVvZiBlLmV2ZW50RGF0YS5vd25lck1lc3NhZ2VJZCA9PT0gJ3N0cmluZydcbiAgICAgICAgICA/IGUuZXZlbnREYXRhLm93bmVyTWVzc2FnZUlkXG4gICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICBsYXRlc3RPd25lci5zZXQoZS5jb3JyZWxhdGlvbklkLCBvd25lcik7XG4gICAgfSBlbHNlIGlmIChlLmV2ZW50VHlwZSA9PT0gJ3N0ZXBfcmV0cnlpbmcnKSB7XG4gICAgICBzYXdSZXRyeWluZy5hZGQoZS5jb3JyZWxhdGlvbklkKTtcbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBpZCBvZiBwZW5kaW5nQ29ycmVsYXRpb25JZHMpIHtcbiAgICBpZiAoXG4gICAgICBpZCAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAhc2F3UmV0cnlpbmcuaGFzKGlkKSAmJlxuICAgICAgbGF0ZXN0T3duZXIuZ2V0KGlkKSA9PT0gbWVzc2FnZUlkXG4gICAgKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuIl19
@@ -0,0 +1,12 @@
1
+ import type { StepExecutionResult } from './step-executor.js';
2
+ /**
3
+ * Run `execute` unless an execution for the same run + step correlation ID is
4
+ * already in flight in this process. The winner's result is returned to the
5
+ * winner; a loser awaits the winner's settlement (success OR failure) and
6
+ * then returns `{ type: 'skipped' }` so its caller acks without running the
7
+ * body. A winner failure is not propagated to the loser — the winner's own
8
+ * queue message redelivers and drives the retry, so exactly one message
9
+ * keeps owning the outcome.
10
+ */
11
+ export declare function runStepSingleFlight(runId: string, correlationId: string, execute: () => Promise<StepExecutionResult>): Promise<StepExecutionResult>;
12
+ //# sourceMappingURL=step-single-flight.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step-single-flight.d.ts","sourceRoot":"","sources":["../../src/runtime/step-single-flight.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAgC9D;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,OAAO,CAAC,mBAAmB,CAAC,GAC1C,OAAO,CAAC,mBAAmB,CAAC,CA8B9B"}
@@ -0,0 +1,69 @@
1
+ import { runtimeLogger } from '../logger.js';
2
+ /**
3
+ * In-process single-flight for step body execution, keyed by
4
+ * `runId:correlationId`.
5
+ *
6
+ * This is a required companion to inline step ownership (see
7
+ * `isInlineOwnershipEnabled` in constants.ts): the ownership lease is a
8
+ * *death proof* only on platforms with a bounded invocation lifetime. On
9
+ * worlds without an invocation kill bound (world-local's single process,
10
+ * self-hosted deployments) a delayed backstop can fire while the owning
11
+ * execution is still mid-body — in the same process. This map absorbs that
12
+ * race: the loser awaits the winner's settlement and then acks WITHOUT
13
+ * executing. On Vercel Fluid compute it also absorbs same-instance races
14
+ * between an owner redelivery and a backstop.
15
+ *
16
+ * The loser must not ack-and-skip early (before the winner settles): a crash
17
+ * after an early ack would consume the loser's queue message while the
18
+ * winner's outcome is still unknown, potentially orphaning the step with no
19
+ * message left to drive it. Awaiting settlement first keeps the at-least-once
20
+ * envelope intact — if the loser's own invocation hits its deadline while
21
+ * waiting, its message redelivers and re-checks, degrading gracefully to
22
+ * polling.
23
+ *
24
+ * Cross-instance duplicates (two separate processes racing the same step)
25
+ * are out of scope here — that is what the ownership lease bounds on
26
+ * platforms where it is a death proof, and the documented residual risk on
27
+ * multi-instance self-hosted worlds (mitigate by raising
28
+ * `WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS`).
29
+ */
30
+ const inFlightSteps = new Map();
31
+ /**
32
+ * Run `execute` unless an execution for the same run + step correlation ID is
33
+ * already in flight in this process. The winner's result is returned to the
34
+ * winner; a loser awaits the winner's settlement (success OR failure) and
35
+ * then returns `{ type: 'skipped' }` so its caller acks without running the
36
+ * body. A winner failure is not propagated to the loser — the winner's own
37
+ * queue message redelivers and drives the retry, so exactly one message
38
+ * keeps owning the outcome.
39
+ */
40
+ export async function runStepSingleFlight(runId, correlationId, execute) {
41
+ const key = `${runId}:${correlationId}`;
42
+ const existing = inFlightSteps.get(key);
43
+ if (existing) {
44
+ // warn (always printed, unlike debug/info): the single-flight is
45
+ // absorbing what would have been a duplicate execution — typically a
46
+ // delayed backstop or retry message landing in the same process while
47
+ // the owner is still mid-body. Rare by design; a burst of these means
48
+ // leases are expiring under live executions (raise
49
+ // WORKFLOW_INLINE_OWNERSHIP_LEASE_SECONDS).
50
+ runtimeLogger.warn('Step execution already in flight in this process; awaiting its settlement instead of executing again', { workflowRunId: runId, stepId: correlationId });
51
+ try {
52
+ await existing;
53
+ }
54
+ catch {
55
+ // The winner failed (typically a transient world error). Its own queue
56
+ // message redelivers and retries; this loser still just skips.
57
+ }
58
+ return { type: 'skipped' };
59
+ }
60
+ const promise = execute();
61
+ inFlightSteps.set(key, promise);
62
+ try {
63
+ return await promise;
64
+ }
65
+ finally {
66
+ inFlightSteps.delete(key);
67
+ }
68
+ }
69
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC1zaW5nbGUtZmxpZ2h0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3J1bnRpbWUvc3RlcC1zaW5nbGUtZmxpZ2h0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFHN0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTJCRztBQUNILE1BQU0sYUFBYSxHQUFHLElBQUksR0FBRyxFQUF3QyxDQUFDO0FBRXRFOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxtQkFBbUIsQ0FDdkMsS0FBYSxFQUNiLGFBQXFCLEVBQ3JCLE9BQTJDO0lBRTNDLE1BQU0sR0FBRyxHQUFHLEdBQUcsS0FBSyxJQUFJLGFBQWEsRUFBRSxDQUFDO0lBQ3hDLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEMsSUFBSSxRQUFRLEVBQUUsQ0FBQztRQUNiLGlFQUFpRTtRQUNqRSxxRUFBcUU7UUFDckUsc0VBQXNFO1FBQ3RFLHNFQUFzRTtRQUN0RSxtREFBbUQ7UUFDbkQsNENBQTRDO1FBQzVDLGFBQWEsQ0FBQyxJQUFJLENBQ2hCLHNHQUFzRyxFQUN0RyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxDQUNoRCxDQUFDO1FBQ0YsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLENBQUM7UUFDakIsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLHVFQUF1RTtZQUN2RSwrREFBK0Q7UUFDakUsQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLENBQUM7SUFDN0IsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sRUFBRSxDQUFDO0lBQzFCLGFBQWEsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2hDLElBQUksQ0FBQztRQUNILE9BQU8sTUFBTSxPQUFPLENBQUM7SUFDdkIsQ0FBQztZQUFTLENBQUM7UUFDVCxhQUFhLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgcnVudGltZUxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlci5qcyc7XG5pbXBvcnQgdHlwZSB7IFN0ZXBFeGVjdXRpb25SZXN1bHQgfSBmcm9tICcuL3N0ZXAtZXhlY3V0b3IuanMnO1xuXG4vKipcbiAqIEluLXByb2Nlc3Mgc2luZ2xlLWZsaWdodCBmb3Igc3RlcCBib2R5IGV4ZWN1dGlvbiwga2V5ZWQgYnlcbiAqIGBydW5JZDpjb3JyZWxhdGlvbklkYC5cbiAqXG4gKiBUaGlzIGlzIGEgcmVxdWlyZWQgY29tcGFuaW9uIHRvIGlubGluZSBzdGVwIG93bmVyc2hpcCAoc2VlXG4gKiBgaXNJbmxpbmVPd25lcnNoaXBFbmFibGVkYCBpbiBjb25zdGFudHMudHMpOiB0aGUgb3duZXJzaGlwIGxlYXNlIGlzIGFcbiAqICpkZWF0aCBwcm9vZiogb25seSBvbiBwbGF0Zm9ybXMgd2l0aCBhIGJvdW5kZWQgaW52b2NhdGlvbiBsaWZldGltZS4gT25cbiAqIHdvcmxkcyB3aXRob3V0IGFuIGludm9jYXRpb24ga2lsbCBib3VuZCAod29ybGQtbG9jYWwncyBzaW5nbGUgcHJvY2VzcyxcbiAqIHNlbGYtaG9zdGVkIGRlcGxveW1lbnRzKSBhIGRlbGF5ZWQgYmFja3N0b3AgY2FuIGZpcmUgd2hpbGUgdGhlIG93bmluZ1xuICogZXhlY3V0aW9uIGlzIHN0aWxsIG1pZC1ib2R5IOKAlCBpbiB0aGUgc2FtZSBwcm9jZXNzLiBUaGlzIG1hcCBhYnNvcmJzIHRoYXRcbiAqIHJhY2U6IHRoZSBsb3NlciBhd2FpdHMgdGhlIHdpbm5lcidzIHNldHRsZW1lbnQgYW5kIHRoZW4gYWNrcyBXSVRIT1VUXG4gKiBleGVjdXRpbmcuIE9uIFZlcmNlbCBGbHVpZCBjb21wdXRlIGl0IGFsc28gYWJzb3JicyBzYW1lLWluc3RhbmNlIHJhY2VzXG4gKiBiZXR3ZWVuIGFuIG93bmVyIHJlZGVsaXZlcnkgYW5kIGEgYmFja3N0b3AuXG4gKlxuICogVGhlIGxvc2VyIG11c3Qgbm90IGFjay1hbmQtc2tpcCBlYXJseSAoYmVmb3JlIHRoZSB3aW5uZXIgc2V0dGxlcyk6IGEgY3Jhc2hcbiAqIGFmdGVyIGFuIGVhcmx5IGFjayB3b3VsZCBjb25zdW1lIHRoZSBsb3NlcidzIHF1ZXVlIG1lc3NhZ2Ugd2hpbGUgdGhlXG4gKiB3aW5uZXIncyBvdXRjb21lIGlzIHN0aWxsIHVua25vd24sIHBvdGVudGlhbGx5IG9ycGhhbmluZyB0aGUgc3RlcCB3aXRoIG5vXG4gKiBtZXNzYWdlIGxlZnQgdG8gZHJpdmUgaXQuIEF3YWl0aW5nIHNldHRsZW1lbnQgZmlyc3Qga2VlcHMgdGhlIGF0LWxlYXN0LW9uY2VcbiAqIGVudmVsb3BlIGludGFjdCDigJQgaWYgdGhlIGxvc2VyJ3Mgb3duIGludm9jYXRpb24gaGl0cyBpdHMgZGVhZGxpbmUgd2hpbGVcbiAqIHdhaXRpbmcsIGl0cyBtZXNzYWdlIHJlZGVsaXZlcnMgYW5kIHJlLWNoZWNrcywgZGVncmFkaW5nIGdyYWNlZnVsbHkgdG9cbiAqIHBvbGxpbmcuXG4gKlxuICogQ3Jvc3MtaW5zdGFuY2UgZHVwbGljYXRlcyAodHdvIHNlcGFyYXRlIHByb2Nlc3NlcyByYWNpbmcgdGhlIHNhbWUgc3RlcClcbiAqIGFyZSBvdXQgb2Ygc2NvcGUgaGVyZSDigJQgdGhhdCBpcyB3aGF0IHRoZSBvd25lcnNoaXAgbGVhc2UgYm91bmRzIG9uXG4gKiBwbGF0Zm9ybXMgd2hlcmUgaXQgaXMgYSBkZWF0aCBwcm9vZiwgYW5kIHRoZSBkb2N1bWVudGVkIHJlc2lkdWFsIHJpc2sgb25cbiAqIG11bHRpLWluc3RhbmNlIHNlbGYtaG9zdGVkIHdvcmxkcyAobWl0aWdhdGUgYnkgcmFpc2luZ1xuICogYFdPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EU2ApLlxuICovXG5jb25zdCBpbkZsaWdodFN0ZXBzID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8U3RlcEV4ZWN1dGlvblJlc3VsdD4+KCk7XG5cbi8qKlxuICogUnVuIGBleGVjdXRlYCB1bmxlc3MgYW4gZXhlY3V0aW9uIGZvciB0aGUgc2FtZSBydW4gKyBzdGVwIGNvcnJlbGF0aW9uIElEIGlzXG4gKiBhbHJlYWR5IGluIGZsaWdodCBpbiB0aGlzIHByb2Nlc3MuIFRoZSB3aW5uZXIncyByZXN1bHQgaXMgcmV0dXJuZWQgdG8gdGhlXG4gKiB3aW5uZXI7IGEgbG9zZXIgYXdhaXRzIHRoZSB3aW5uZXIncyBzZXR0bGVtZW50IChzdWNjZXNzIE9SIGZhaWx1cmUpIGFuZFxuICogdGhlbiByZXR1cm5zIGB7IHR5cGU6ICdza2lwcGVkJyB9YCBzbyBpdHMgY2FsbGVyIGFja3Mgd2l0aG91dCBydW5uaW5nIHRoZVxuICogYm9keS4gQSB3aW5uZXIgZmFpbHVyZSBpcyBub3QgcHJvcGFnYXRlZCB0byB0aGUgbG9zZXIg4oCUIHRoZSB3aW5uZXIncyBvd25cbiAqIHF1ZXVlIG1lc3NhZ2UgcmVkZWxpdmVycyBhbmQgZHJpdmVzIHRoZSByZXRyeSwgc28gZXhhY3RseSBvbmUgbWVzc2FnZVxuICoga2VlcHMgb3duaW5nIHRoZSBvdXRjb21lLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuU3RlcFNpbmdsZUZsaWdodChcbiAgcnVuSWQ6IHN0cmluZyxcbiAgY29ycmVsYXRpb25JZDogc3RyaW5nLFxuICBleGVjdXRlOiAoKSA9PiBQcm9taXNlPFN0ZXBFeGVjdXRpb25SZXN1bHQ+XG4pOiBQcm9taXNlPFN0ZXBFeGVjdXRpb25SZXN1bHQ+IHtcbiAgY29uc3Qga2V5ID0gYCR7cnVuSWR9OiR7Y29ycmVsYXRpb25JZH1gO1xuICBjb25zdCBleGlzdGluZyA9IGluRmxpZ2h0U3RlcHMuZ2V0KGtleSk7XG4gIGlmIChleGlzdGluZykge1xuICAgIC8vIHdhcm4gKGFsd2F5cyBwcmludGVkLCB1bmxpa2UgZGVidWcvaW5mbyk6IHRoZSBzaW5nbGUtZmxpZ2h0IGlzXG4gICAgLy8gYWJzb3JiaW5nIHdoYXQgd291bGQgaGF2ZSBiZWVuIGEgZHVwbGljYXRlIGV4ZWN1dGlvbiDigJQgdHlwaWNhbGx5IGFcbiAgICAvLyBkZWxheWVkIGJhY2tzdG9wIG9yIHJldHJ5IG1lc3NhZ2UgbGFuZGluZyBpbiB0aGUgc2FtZSBwcm9jZXNzIHdoaWxlXG4gICAgLy8gdGhlIG93bmVyIGlzIHN0aWxsIG1pZC1ib2R5LiBSYXJlIGJ5IGRlc2lnbjsgYSBidXJzdCBvZiB0aGVzZSBtZWFuc1xuICAgIC8vIGxlYXNlcyBhcmUgZXhwaXJpbmcgdW5kZXIgbGl2ZSBleGVjdXRpb25zIChyYWlzZVxuICAgIC8vIFdPUktGTE9XX0lOTElORV9PV05FUlNISVBfTEVBU0VfU0VDT05EUykuXG4gICAgcnVudGltZUxvZ2dlci53YXJuKFxuICAgICAgJ1N0ZXAgZXhlY3V0aW9uIGFscmVhZHkgaW4gZmxpZ2h0IGluIHRoaXMgcHJvY2VzczsgYXdhaXRpbmcgaXRzIHNldHRsZW1lbnQgaW5zdGVhZCBvZiBleGVjdXRpbmcgYWdhaW4nLFxuICAgICAgeyB3b3JrZmxvd1J1bklkOiBydW5JZCwgc3RlcElkOiBjb3JyZWxhdGlvbklkIH1cbiAgICApO1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBleGlzdGluZztcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8vIFRoZSB3aW5uZXIgZmFpbGVkICh0eXBpY2FsbHkgYSB0cmFuc2llbnQgd29ybGQgZXJyb3IpLiBJdHMgb3duIHF1ZXVlXG4gICAgICAvLyBtZXNzYWdlIHJlZGVsaXZlcnMgYW5kIHJldHJpZXM7IHRoaXMgbG9zZXIgc3RpbGwganVzdCBza2lwcy5cbiAgICB9XG4gICAgcmV0dXJuIHsgdHlwZTogJ3NraXBwZWQnIH07XG4gIH1cblxuICBjb25zdCBwcm9taXNlID0gZXhlY3V0ZSgpO1xuICBpbkZsaWdodFN0ZXBzLnNldChrZXksIHByb21pc2UpO1xuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBwcm9taXNlO1xuICB9IGZpbmFsbHkge1xuICAgIGluRmxpZ2h0U3RlcHMuZGVsZXRlKGtleSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,24 +1,126 @@
1
1
  import type { Span } from '@opentelemetry/api';
2
- import { type WorkflowRun, type World } from '@workflow/world';
3
- import type { WorkflowSuspension } from '../global.js';
2
+ import { type SerializedData, type WorkflowRun, type World } from '@workflow/world';
3
+ import type { StepInvocationQueueItem, WorkflowSuspension } from '../global.js';
4
+ import { type LoadedEventLog } from './helpers.js';
5
+ import { ReplayRecoveryReporter } from './replay-recovery-reporter.js';
4
6
  export interface SuspensionHandlerParams {
5
7
  suspension: WorkflowSuspension;
6
8
  world: World;
7
9
  run: WorkflowRun;
8
10
  span?: Span;
9
11
  requestId?: string;
12
+ /**
13
+ * The runtime's loaded event log. Every event creation this suspension makes
14
+ * is sent with the precondition snapshot derived from it, so a backend that
15
+ * has recorded an event the replay did not see rejects the write with a 412
16
+ * instead of accepting a divergent event. The rejection is not retried here:
17
+ * the event's correlation id was minted by *this* replay's seeded sequence,
18
+ * so re-committing it against a corrected log would persist an event no
19
+ * correct replay produces. The caller restarts the replay instead.
20
+ */
21
+ eventLog?: LoadedEventLog;
22
+ /**
23
+ * Turbo mode only: a promise that resolves once the backgrounded
24
+ * `run_started` has landed (the run exists). When present, every world write
25
+ * this suspension performs (`hook_created`, `wait_created`, eager overflow
26
+ * `step_created`, …) is gated on it so the write never races ahead of the
27
+ * run's creation. The pure inline hot path defers all of its steps and writes
28
+ * nothing here, so it never awaits this barrier. `undefined` outside turbo,
29
+ * where `run_started` was already awaited up front.
30
+ */
31
+ runReadyBarrier?: Promise<unknown>;
32
+ /** One-shot telemetry reporter, activated only after replay has recovered. */
33
+ replayRecoveryReporter?: ReplayRecoveryReporter;
10
34
  }
35
+ /**
36
+ * Result of handling a suspension. Returns pending step items so the caller
37
+ * can decide which to execute inline vs queue to background.
38
+ */
11
39
  export interface SuspensionHandlerResult {
12
- timeoutSeconds?: number;
40
+ /** Pending step items with events created but NOT queued */
41
+ pendingSteps: StepInvocationQueueItem[];
42
+ /**
43
+ * Correlation IDs for which this suspension call actually wrote the
44
+ * step_created event (as opposed to catching EntityConflictError because
45
+ * a concurrent handler wrote it first). Only the handler that wrote the
46
+ * step_created event should queue / inline-execute the step — this
47
+ * guarantees a single owner per step, even when multiple handlers race
48
+ * into the same batch boundary.
49
+ */
50
+ createdStepCorrelationIds: Set<string>;
51
+ /**
52
+ * How many events this phase's writes reported back as occupying slots they
53
+ * skipped over, already merged into the caller's `eventLog.events`. Nonzero
54
+ * means the array was reordered to restore slot order, so any index the
55
+ * caller cached into it (payload prewarm scan position) is stale.
56
+ */
57
+ reportedEventCount: number;
58
+ /**
59
+ * The steps whose `step_created` writes were intentionally deferred so the
60
+ * caller can run them inline via lazy `step_started` events (which create
61
+ * the step on the fly), saving one world round-trip per inline step. Up to
62
+ * `getMaxInlineSteps()` steps are deferred; the caller runs them inline in
63
+ * parallel and queues the rest. Empty when no step was deferred (nothing
64
+ * pending, or a `hook.getConflict()` awaiter is present so nothing is
65
+ * executed inline). The caller passes each `dehydratedInput` straight to
66
+ * `executeStep`, which sends it as the `step_started` payload. The atomic
67
+ * create-claim inside each `step_started` is the exactly-one-owner gate that
68
+ * the standalone `step_created` provided before: the loser of the race gets
69
+ * `EntityConflictError` → `skipped` and does not run the body.
70
+ */
71
+ lazyInlineSteps: Array<{
72
+ correlationId: string;
73
+ stepName: string;
74
+ dehydratedInput: SerializedData;
75
+ }>;
76
+ /**
77
+ * The soonest pending wait, if any: seconds until it elapses and the
78
+ * correlationId of the wait that produced that timeout. The
79
+ * correlationId seeds the idempotency key for the wait-continuation
80
+ * queue message so that repeated suspension passes over the same
81
+ * pending wait collapse into a single delayed continuation.
82
+ */
83
+ waitTimeout?: {
84
+ seconds: number;
85
+ correlationId: string;
86
+ };
87
+ /** Whether a hook conflict was detected (should re-invoke immediately) */
88
+ hasHookConflict: boolean;
89
+ /** Whether a `hook.getConflict()` awaiter needs the workflow to continue immediately */
90
+ hasAwaitedHookCreation: boolean;
91
+ /** Whether native workflow attribute events were written for replay. */
92
+ hasAttributeEvents: boolean;
93
+ /**
94
+ * Whether this suspension created any hook (`hook_created`) events. Unlike
95
+ * `hasHookConflict` / `hasAwaitedHookCreation`, this is true even for a plain
96
+ * fire-and-forget hook with no conflict and no awaiter. Turbo mode uses it to
97
+ * detect "a hook was created this suspension" and stop forcing optimistic
98
+ * inline start (a hook introduces later resume invocations that could race).
99
+ */
100
+ hasHookEvents: boolean;
101
+ /**
102
+ * Wall-clock ms spent committing this suspension's `hook_created` events
103
+ * (0 when it created none). The caller accumulates this across iterations
104
+ * and subtracts it from the TTFS latency measurement, so time spent
105
+ * durably creating the user's hooks doesn't count as runtime overhead.
106
+ */
107
+ hookCreationMs: number;
108
+ /**
109
+ * Whether serializing this suspension's new step inputs was passive (did
110
+ * not execute workflow-owned code such as getters, proxy traps, or custom
111
+ * serializers). `false` means the retained VM may have diverged from what
112
+ * a cold replay would compute, so the caller must demote to replay.
113
+ */
114
+ retainedStepInputsSafe: boolean;
13
115
  }
14
116
  /**
15
117
  * Handles a workflow suspension by processing all pending operations (hooks, steps, waits).
16
- * Uses an event-sourced architecture where entities (steps, hooks) are created atomically
17
- * with their corresponding events via events.create().
118
+ * Creates events for all operations but does NOT queue step messages — returns the pending
119
+ * steps so the caller can decide which to execute inline vs queue to background.
18
120
  *
19
121
  * Processing order:
20
122
  * 1. Hooks are processed first to prevent race conditions with webhook receivers
21
- * 2. Steps and waits are processed in parallel after hooks complete
123
+ * 2. Step events and wait events are created in parallel
22
124
  */
23
- export declare function handleSuspension({ suspension, world, run, span, requestId, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
125
+ export declare function handleSuspension({ suspension, world, run, span, requestId, eventLog, runReadyBarrier, replayRecoveryReporter, }: SuspensionHandlerParams): Promise<SuspensionHandlerResult>;
24
126
  //# sourceMappingURL=suspension-handler.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAO/C,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAwBtB,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,GACV,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAgS5D"}
1
+ {"version":3,"file":"suspension-handler.d.ts","sourceRoot":"","sources":["../../src/runtime/suspension-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAS/C,OAAO,EAKL,KAAK,cAAc,EAGnB,KAAK,WAAW,EAChB,KAAK,KAAK,EACX,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAGV,uBAAuB,EAEvB,kBAAkB,EACnB,MAAM,cAAc,CAAC;AAOtB,OAAO,EAEL,KAAK,cAAc,EAGpB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,WAAW,CAAC;IACjB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,8EAA8E;IAC9E,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,YAAY,EAAE,uBAAuB,EAAE,CAAC;IACxC;;;;;;;OAOG;IACH,yBAAyB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACvC;;;;;OAKG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;OAYG;IACH,eAAe,EAAE,KAAK,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,QAAQ,EAAE,MAAM,CAAC;QACjB,eAAe,EAAE,cAAc,CAAC;KACjC,CAAC,CAAC;IACH;;;;;;OAMG;IACH,WAAW,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0EAA0E;IAC1E,eAAe,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,sBAAsB,EAAE,OAAO,CAAC;IAChC,wEAAwE;IACxE,kBAAkB,EAAE,OAAO,CAAC;IAC5B;;;;;;OAMG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,sBAAsB,EAAE,OAAO,CAAC;CACjC;AA6ED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,EACrC,UAAU,EACV,KAAK,EACL,GAAG,EACH,IAAI,EACJ,SAAS,EACT,QAAQ,EACR,eAAe,EACf,sBAAsB,GACvB,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAgnB5D"}