@workflow/core 5.0.0-beta.5 → 5.0.0-beta.51

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 (317) hide show
  1. package/README.md +5 -0
  2. package/dist/attribute-changes.d.ts +5 -0
  3. package/dist/attribute-changes.d.ts.map +1 -0
  4. package/dist/attribute-changes.js +25 -0
  5. package/dist/capabilities.d.ts +35 -2
  6. package/dist/capabilities.d.ts.map +1 -1
  7. package/dist/capabilities.js +74 -5
  8. package/dist/capture-stack.d.ts +1 -1
  9. package/dist/capture-stack.js +2 -2
  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 +19 -3
  14. package/dist/classify-error.d.ts.map +1 -1
  15. package/dist/classify-error.js +98 -6
  16. package/dist/context-violation-error.d.ts +5 -5
  17. package/dist/context-violation-error.d.ts.map +1 -1
  18. package/dist/context-violation-error.js +8 -6
  19. package/dist/create-hook.d.ts +72 -7
  20. package/dist/create-hook.d.ts.map +1 -1
  21. package/dist/create-hook.js +1 -1
  22. package/dist/define-hook.js +2 -2
  23. package/dist/describe-error.d.ts +7 -7
  24. package/dist/describe-error.d.ts.map +1 -1
  25. package/dist/describe-error.js +97 -12
  26. package/dist/encryption.d.ts +38 -4
  27. package/dist/encryption.d.ts.map +1 -1
  28. package/dist/encryption.js +96 -14
  29. package/dist/events-consumer.d.ts +297 -0
  30. package/dist/events-consumer.d.ts.map +1 -1
  31. package/dist/events-consumer.js +673 -42
  32. package/dist/flushable-stream.d.ts +97 -1
  33. package/dist/flushable-stream.d.ts.map +1 -1
  34. package/dist/flushable-stream.js +291 -11
  35. package/dist/global.d.ts +36 -2
  36. package/dist/global.d.ts.map +1 -1
  37. package/dist/global.js +21 -6
  38. package/dist/index.d.ts +2 -1
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +3 -2
  41. package/dist/log-format.d.ts +2 -2
  42. package/dist/log-format.js +19 -12
  43. package/dist/logger.d.ts +1 -0
  44. package/dist/logger.d.ts.map +1 -1
  45. package/dist/logger.js +10 -6
  46. package/dist/private.d.ts +226 -9
  47. package/dist/private.d.ts.map +1 -1
  48. package/dist/private.js +626 -7
  49. package/dist/replay-divergence.d.ts +25 -0
  50. package/dist/replay-divergence.d.ts.map +1 -0
  51. package/dist/replay-divergence.js +61 -0
  52. package/dist/replay-payload-cache.d.ts +64 -0
  53. package/dist/replay-payload-cache.d.ts.map +1 -0
  54. package/dist/replay-payload-cache.js +158 -0
  55. package/dist/runtime/compute-instance.d.ts +13 -0
  56. package/dist/runtime/compute-instance.d.ts.map +1 -0
  57. package/dist/runtime/compute-instance.js +14 -0
  58. package/dist/runtime/constants.d.ts +315 -0
  59. package/dist/runtime/constants.d.ts.map +1 -1
  60. package/dist/runtime/constants.js +502 -16
  61. package/dist/runtime/count-step-started-events.d.ts +52 -0
  62. package/dist/runtime/count-step-started-events.d.ts.map +1 -0
  63. package/dist/runtime/count-step-started-events.js +72 -0
  64. package/dist/runtime/deployment-guard.d.ts +99 -0
  65. package/dist/runtime/deployment-guard.d.ts.map +1 -0
  66. package/dist/runtime/deployment-guard.js +154 -0
  67. package/dist/runtime/get-port-lazy.d.ts +15 -0
  68. package/dist/runtime/get-port-lazy.d.ts.map +1 -1
  69. package/dist/runtime/get-port-lazy.js +75 -6
  70. package/dist/runtime/get-world-lazy.d.ts +5 -14
  71. package/dist/runtime/get-world-lazy.d.ts.map +1 -1
  72. package/dist/runtime/get-world-lazy.js +19 -29
  73. package/dist/runtime/helpers.d.ts +415 -29
  74. package/dist/runtime/helpers.d.ts.map +1 -1
  75. package/dist/runtime/helpers.js +686 -57
  76. package/dist/runtime/quickjs-assets.generated.d.ts +14 -0
  77. package/dist/runtime/quickjs-assets.generated.d.ts.map +1 -0
  78. package/dist/runtime/quickjs-assets.generated.js +30 -0
  79. package/dist/runtime/quickjs-entrypoint.d.ts +158 -0
  80. package/dist/runtime/quickjs-entrypoint.d.ts.map +1 -0
  81. package/dist/runtime/quickjs-entrypoint.js +1863 -0
  82. package/dist/runtime/quickjs-log-view.d.ts +129 -0
  83. package/dist/runtime/quickjs-log-view.d.ts.map +1 -0
  84. package/dist/runtime/quickjs-log-view.js +229 -0
  85. package/dist/runtime/quickjs-runtime.d.ts +244 -0
  86. package/dist/runtime/quickjs-runtime.d.ts.map +1 -0
  87. package/dist/runtime/quickjs-runtime.js +2427 -0
  88. package/dist/runtime/quickjs-serde.d.ts +107 -0
  89. package/dist/runtime/quickjs-serde.d.ts.map +1 -0
  90. package/dist/runtime/quickjs-serde.js +2159 -0
  91. package/dist/runtime/replay-budget.d.ts +97 -0
  92. package/dist/runtime/replay-budget.d.ts.map +1 -0
  93. package/dist/runtime/replay-budget.js +139 -0
  94. package/dist/runtime/replay-recovery-reporter.d.ts +36 -0
  95. package/dist/runtime/replay-recovery-reporter.d.ts.map +1 -0
  96. package/dist/runtime/replay-recovery-reporter.js +64 -0
  97. package/dist/runtime/resume-hook.d.ts +91 -8
  98. package/dist/runtime/resume-hook.d.ts.map +1 -1
  99. package/dist/runtime/resume-hook.js +512 -89
  100. package/dist/runtime/resume-latency.d.ts +150 -0
  101. package/dist/runtime/resume-latency.d.ts.map +1 -0
  102. package/dist/runtime/resume-latency.js +155 -0
  103. package/dist/runtime/run-id-time.d.ts +19 -0
  104. package/dist/runtime/run-id-time.d.ts.map +1 -0
  105. package/dist/runtime/run-id-time.js +42 -0
  106. package/dist/runtime/run.d.ts +72 -7
  107. package/dist/runtime/run.d.ts.map +1 -1
  108. package/dist/runtime/run.js +280 -53
  109. package/dist/runtime/runs.d.ts +54 -3
  110. package/dist/runtime/runs.d.ts.map +1 -1
  111. package/dist/runtime/runs.js +126 -16
  112. package/dist/runtime/start.d.ts +101 -2
  113. package/dist/runtime/start.d.ts.map +1 -1
  114. package/dist/runtime/start.js +352 -61
  115. package/dist/runtime/step-executor.d.ts +186 -5
  116. package/dist/runtime/step-executor.d.ts.map +1 -1
  117. package/dist/runtime/step-executor.js +768 -130
  118. package/dist/runtime/step-latency.d.ts +220 -0
  119. package/dist/runtime/step-latency.d.ts.map +1 -0
  120. package/dist/runtime/step-latency.js +215 -0
  121. package/dist/runtime/step-ownership.d.ts +72 -0
  122. package/dist/runtime/step-ownership.d.ts.map +1 -0
  123. package/dist/runtime/step-ownership.js +114 -0
  124. package/dist/runtime/step-single-flight.d.ts +12 -0
  125. package/dist/runtime/step-single-flight.d.ts.map +1 -0
  126. package/dist/runtime/step-single-flight.js +75 -0
  127. package/dist/runtime/suspension-handler.d.ts +247 -7
  128. package/dist/runtime/suspension-handler.d.ts.map +1 -1
  129. package/dist/runtime/suspension-handler.js +1304 -125
  130. package/dist/runtime/unserializable-step.d.ts +34 -0
  131. package/dist/runtime/unserializable-step.d.ts.map +1 -0
  132. package/dist/runtime/unserializable-step.js +52 -0
  133. package/dist/runtime/vm-mode.d.ts +44 -0
  134. package/dist/runtime/vm-mode.d.ts.map +1 -0
  135. package/dist/runtime/vm-mode.js +62 -0
  136. package/dist/runtime/vm-serde-bundle.generated.d.ts +14 -0
  137. package/dist/runtime/vm-serde-bundle.generated.d.ts.map +1 -0
  138. package/dist/runtime/vm-serde-bundle.generated.js +16 -0
  139. package/dist/runtime/wait-continuation.d.ts +106 -0
  140. package/dist/runtime/wait-continuation.d.ts.map +1 -0
  141. package/dist/runtime/wait-continuation.js +136 -0
  142. package/dist/runtime/wait-until.d.ts +18 -0
  143. package/dist/runtime/wait-until.d.ts.map +1 -0
  144. package/dist/runtime/wait-until.js +42 -0
  145. package/dist/runtime/world-compatibility.d.ts +32 -0
  146. package/dist/runtime/world-compatibility.d.ts.map +1 -0
  147. package/dist/runtime/world-compatibility.js +44 -0
  148. package/dist/runtime/world-init.d.ts +17 -42
  149. package/dist/runtime/world-init.d.ts.map +1 -1
  150. package/dist/runtime/world-init.js +18 -43
  151. package/dist/runtime/world.d.ts +14 -2
  152. package/dist/runtime/world.d.ts.map +1 -1
  153. package/dist/runtime/world.js +75 -19
  154. package/dist/runtime.d.ts +10 -6
  155. package/dist/runtime.d.ts.map +1 -1
  156. package/dist/runtime.js +3911 -489
  157. package/dist/sealed-box.d.ts +167 -0
  158. package/dist/sealed-box.d.ts.map +1 -0
  159. package/dist/sealed-box.js +571 -0
  160. package/dist/serialization/client.d.ts +3 -3
  161. package/dist/serialization/client.d.ts.map +1 -1
  162. package/dist/serialization/client.js +8 -4
  163. package/dist/serialization/codec-devalue-vm.d.ts +16 -0
  164. package/dist/serialization/codec-devalue-vm.d.ts.map +1 -0
  165. package/dist/serialization/codec-devalue-vm.js +148 -0
  166. package/dist/serialization/codec-devalue.d.ts +1 -1
  167. package/dist/serialization/codec-devalue.d.ts.map +1 -1
  168. package/dist/serialization/codec-devalue.js +24 -6
  169. package/dist/serialization/codec.d.ts +37 -2
  170. package/dist/serialization/codec.d.ts.map +1 -1
  171. package/dist/serialization/codec.js +2 -2
  172. package/dist/serialization/compression.d.ts +105 -0
  173. package/dist/serialization/compression.d.ts.map +1 -0
  174. package/dist/serialization/compression.js +261 -0
  175. package/dist/serialization/encryption.d.ts +119 -17
  176. package/dist/serialization/encryption.d.ts.map +1 -1
  177. package/dist/serialization/encryption.js +152 -17
  178. package/dist/serialization/errors.d.ts +13 -0
  179. package/dist/serialization/errors.d.ts.map +1 -1
  180. package/dist/serialization/errors.js +20 -2
  181. package/dist/serialization/format.d.ts +6 -6
  182. package/dist/serialization/format.js +7 -7
  183. package/dist/serialization/hardened.d.ts +156 -0
  184. package/dist/serialization/hardened.d.ts.map +1 -0
  185. package/dist/serialization/hardened.js +538 -0
  186. package/dist/serialization/index.d.ts +10 -8
  187. package/dist/serialization/index.d.ts.map +1 -1
  188. package/dist/serialization/index.js +10 -8
  189. package/dist/serialization/reducers/class-vm.d.ts +20 -0
  190. package/dist/serialization/reducers/class-vm.d.ts.map +1 -0
  191. package/dist/serialization/reducers/class-vm.js +77 -0
  192. package/dist/serialization/reducers/class.d.ts.map +1 -1
  193. package/dist/serialization/reducers/class.js +11 -6
  194. package/dist/serialization/reducers/common-vm.d.ts +15 -0
  195. package/dist/serialization/reducers/common-vm.d.ts.map +1 -0
  196. package/dist/serialization/reducers/common-vm.js +616 -0
  197. package/dist/serialization/reducers/common.d.ts +1 -1
  198. package/dist/serialization/reducers/common.d.ts.map +1 -1
  199. package/dist/serialization/reducers/common.js +202 -62
  200. package/dist/serialization/reducers/step-function-vm.d.ts +44 -0
  201. package/dist/serialization/reducers/step-function-vm.d.ts.map +1 -0
  202. package/dist/serialization/reducers/step-function-vm.js +97 -0
  203. package/dist/serialization/reducers/step-function.d.ts.map +1 -1
  204. package/dist/serialization/reducers/step-function.js +25 -9
  205. package/dist/serialization/step.d.ts +4 -4
  206. package/dist/serialization/step.d.ts.map +1 -1
  207. package/dist/serialization/step.js +9 -5
  208. package/dist/serialization/types.d.ts +80 -1
  209. package/dist/serialization/types.d.ts.map +1 -1
  210. package/dist/serialization/types.js +15 -1
  211. package/dist/serialization/workflow-vm.d.ts +29 -0
  212. package/dist/serialization/workflow-vm.d.ts.map +1 -0
  213. package/dist/serialization/workflow-vm.js +74 -0
  214. package/dist/serialization-format.d.ts +64 -8
  215. package/dist/serialization-format.d.ts.map +1 -1
  216. package/dist/serialization-format.js +225 -73
  217. package/dist/serialization.d.ts +262 -34
  218. package/dist/serialization.d.ts.map +1 -1
  219. package/dist/serialization.js +1885 -277
  220. package/dist/set-attributes.d.ts +13 -0
  221. package/dist/set-attributes.d.ts.map +1 -0
  222. package/dist/set-attributes.js +60 -0
  223. package/dist/source-map.d.ts +25 -0
  224. package/dist/source-map.d.ts.map +1 -1
  225. package/dist/source-map.js +154 -10
  226. package/dist/step/context-storage.d.ts +63 -2
  227. package/dist/step/context-storage.d.ts.map +1 -1
  228. package/dist/step/context-storage.js +7 -5
  229. package/dist/step/writable-stream.d.ts +3 -3
  230. package/dist/step/writable-stream.d.ts.map +1 -1
  231. package/dist/step/writable-stream.js +80 -13
  232. package/dist/step.d.ts.map +1 -1
  233. package/dist/step.js +148 -27
  234. package/dist/symbols.d.ts +50 -0
  235. package/dist/symbols.d.ts.map +1 -1
  236. package/dist/symbols.js +51 -1
  237. package/dist/telemetry/semantic-conventions.d.ts +433 -2
  238. package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
  239. package/dist/telemetry/semantic-conventions.js +319 -3
  240. package/dist/telemetry.d.ts +91 -0
  241. package/dist/telemetry.d.ts.map +1 -1
  242. package/dist/telemetry.js +244 -17
  243. package/dist/test-support/orchestrator-context.d.ts +25 -0
  244. package/dist/test-support/orchestrator-context.d.ts.map +1 -0
  245. package/dist/test-support/orchestrator-context.js +107 -0
  246. package/dist/types.d.ts +6 -0
  247. package/dist/types.d.ts.map +1 -1
  248. package/dist/types.js +23 -1
  249. package/dist/util.d.ts +0 -5
  250. package/dist/util.d.ts.map +1 -1
  251. package/dist/util.js +1 -15
  252. package/dist/version.d.ts +1 -1
  253. package/dist/version.d.ts.map +1 -1
  254. package/dist/version.js +2 -2
  255. package/dist/vm/index.d.ts.map +1 -1
  256. package/dist/vm/index.js +84 -14
  257. package/dist/vm/script-cache.d.ts +26 -0
  258. package/dist/vm/script-cache.d.ts.map +1 -0
  259. package/dist/vm/script-cache.js +131 -0
  260. package/dist/vm/uint8array-base64.js +1 -1
  261. package/dist/workflow/abort-controller.d.ts +2 -2
  262. package/dist/workflow/abort-controller.d.ts.map +1 -1
  263. package/dist/workflow/abort-controller.js +88 -21
  264. package/dist/workflow/attribute-dispatcher.d.ts +6 -0
  265. package/dist/workflow/attribute-dispatcher.d.ts.map +1 -0
  266. package/dist/workflow/attribute-dispatcher.js +45 -0
  267. package/dist/workflow/create-hook.d.ts.map +1 -1
  268. package/dist/workflow/create-hook.js +24 -3
  269. package/dist/workflow/get-workflow-metadata.js +2 -2
  270. package/dist/workflow/hook.d.ts.map +1 -1
  271. package/dist/workflow/hook.js +304 -47
  272. package/dist/workflow/index.d.ts +1 -0
  273. package/dist/workflow/index.d.ts.map +1 -1
  274. package/dist/workflow/index.js +2 -1
  275. package/dist/workflow/set-attributes.d.ts +68 -0
  276. package/dist/workflow/set-attributes.d.ts.map +1 -0
  277. package/dist/workflow/set-attributes.js +60 -0
  278. package/dist/workflow/sleep.d.ts.map +1 -1
  279. package/dist/workflow/sleep.js +58 -12
  280. package/dist/workflow/world-init-stub.d.ts +3 -3
  281. package/dist/workflow/world-init-stub.js +4 -4
  282. package/dist/workflow.d.ts +95 -3
  283. package/dist/workflow.d.ts.map +1 -1
  284. package/dist/workflow.js +900 -561
  285. package/docs/api-reference/create-hook.mdx +89 -10
  286. package/docs/api-reference/create-webhook.mdx +16 -15
  287. package/docs/api-reference/define-hook.mdx +35 -33
  288. package/docs/api-reference/fatal-error.mdx +30 -8
  289. package/docs/api-reference/fetch.mdx +14 -10
  290. package/docs/api-reference/get-step-metadata.mdx +2 -2
  291. package/docs/api-reference/get-workflow-metadata.mdx +3 -3
  292. package/docs/api-reference/get-writable.mdx +7 -7
  293. package/docs/api-reference/index.mdx +4 -1
  294. package/docs/api-reference/retryable-error.mdx +1 -1
  295. package/docs/api-reference/set-attributes.mdx +61 -0
  296. package/docs/api-reference/sleep.mdx +4 -4
  297. package/docs/foundations/cancellation.mdx +31 -32
  298. package/docs/foundations/errors-and-retries.mdx +42 -11
  299. package/docs/foundations/hooks.mdx +64 -35
  300. package/docs/foundations/idempotency.mdx +244 -12
  301. package/docs/foundations/index.mdx +1 -23
  302. package/docs/foundations/meta.json +2 -1
  303. package/docs/foundations/serialization.mdx +21 -22
  304. package/docs/foundations/starting-workflows.mdx +106 -30
  305. package/docs/foundations/streaming.mdx +108 -60
  306. package/docs/foundations/versioning.mdx +263 -0
  307. package/docs/foundations/workflows-and-steps.mdx +9 -9
  308. package/docs/how-it-works/cancellation.mdx +63 -63
  309. package/docs/how-it-works/code-transform.mdx +83 -67
  310. package/docs/how-it-works/encryption.mdx +30 -26
  311. package/docs/how-it-works/event-sourcing.mdx +125 -34
  312. package/docs/how-it-works/framework-integrations.mdx +96 -337
  313. package/docs/how-it-works/understanding-directives.mdx +22 -22
  314. package/package.json +24 -15
  315. package/dist/runtime/step-handler.d.ts +0 -2
  316. package/dist/runtime/step-handler.d.ts.map +0 -1
  317. package/dist/runtime/step-handler.js +0 -776
@@ -6,6 +6,15 @@ import type { Event } from '@workflow/world';
6
6
  * in host). Any subscribe() arriving during this window cancels the check.
7
7
  */
8
8
  export declare const DEFERRED_CHECK_DELAY_MS = 100;
9
+ /**
10
+ * Floor for the deferred-check delay, so a too-low override can't manufacture
11
+ * spurious divergence (each false positive burns a divergence-recovery retry
12
+ * and can escalate to a terminal `CorruptedEventLogError`).
13
+ *
14
+ * Exported so tests needing the shortest legal delay can ask for it instead of
15
+ * hardcoding a number this floor would silently clamp up.
16
+ */
17
+ export declare const MIN_DEFERRED_CHECK_DELAY_MS = 10;
9
18
  export declare enum EventConsumerResult {
10
19
  /**
11
20
  * Callback consumed the event, but should not be removed from the callbacks list
@@ -22,6 +31,12 @@ export declare enum EventConsumerResult {
22
31
  }
23
32
  type EventConsumerCallback = (event: Event | null) => EventConsumerResult;
24
33
  export interface EventsConsumerOptions {
34
+ /**
35
+ * Callback invoked after an event has been consumed. Consumers such as the
36
+ * deterministic workflow clock must not observe events that are merely
37
+ * inspected while waiting for user code to subscribe to the next operation.
38
+ */
39
+ onConsumedEvent?: (event: Event) => void;
25
40
  /**
26
41
  * Callback invoked when a non-null event cannot be consumed by any registered
27
42
  * callback, indicating an orphaned or invalid event in the event log. The
@@ -30,6 +45,16 @@ export interface EventsConsumerOptions {
30
45
  * downstream subscribe() calls have a chance to cancel the check first.
31
46
  */
32
47
  onUnconsumedEvent: (event: Event) => void;
48
+ /**
49
+ * Callback invoked when an event is skipped because it repeats an event
50
+ * class the walk already consumed for the same entity. `firstEventType` is
51
+ * the type that recorded the class, which is the one the workflow observed.
52
+ * Diagnostics only: skipping is a normal outcome, not an error, though a
53
+ * `firstEventType` differing from `event.eventType` says the two writers
54
+ * decided the entity's outcome differently, which is worth more than an
55
+ * info log.
56
+ */
57
+ onDuplicateEvent?: (event: Event, firstEventType: Event['eventType']) => void;
33
58
  /**
34
59
  * Returns the current promise queue. The unconsumed event check is chained
35
60
  * onto this queue so it only fires after all pending async work (e.g.,
@@ -37,17 +62,108 @@ export interface EventsConsumerOptions {
37
62
  * deserialization delays the resolve() that triggers the next subscribe().
38
63
  */
39
64
  getPromiseQueue: () => Promise<void>;
65
+ /**
66
+ * Whether no data delivery is in flight (`isDeliveryIdle` in private.ts).
67
+ * The unconsumed-event check waits for this before it fires: a delivery in
68
+ * flight means the workflow VM is mid-reaction, and an event it has not
69
+ * claimed yet is an event it has not reached yet.
70
+ *
71
+ * Required rather than defaulting to always-idle: always-idle is exactly the
72
+ * pre-gate behavior, so a defaulted option would let a construction site opt
73
+ * a whole replay path back out without saying so. Tests that drive a consumer
74
+ * with no orchestrator context pass `() => true` to keep the pre-existing
75
+ * timing, and say so at the call site.
76
+ */
77
+ isDeliveryIdle: () => boolean;
78
+ }
79
+ /** See {@link EventsConsumer.describe}. */
80
+ export interface EventsConsumerSnapshot {
81
+ index: number;
82
+ length: number;
83
+ parked: number;
84
+ lastConsumedEventId: string | undefined;
40
85
  }
41
86
  export declare class EventsConsumer {
42
87
  eventIndex: number;
43
88
  readonly events: Event[];
44
89
  readonly callbacks: EventConsumerCallback[];
90
+ /**
91
+ * Events the ordered walk stepped over because nobody claimed them and their
92
+ * type carries no ordering claim. Each keeps the index it held in the log:
93
+ * consumers read {@link eventIndex} at consumption time to order their
94
+ * delivery against the rest of the log, and a late delivery must still make
95
+ * the claim its position gave it.
96
+ *
97
+ * Held in log order, drained in log order, and drained before every offer so
98
+ * a consumer registered after the walk passed the event still receives it.
99
+ */
100
+ private readonly parked;
101
+ /**
102
+ * Correlation ids of the {@link ONE_SHOT_EVENT_TYPES} events consumed so
103
+ * far, so a second resolution for one of them is recognized as unclaimable
104
+ * rather than parked for a consumer that cannot exist.
105
+ */
106
+ private readonly resolved;
107
+ /**
108
+ * `<class>:<correlationId>` for every event class the walk has already
109
+ * consumed, mapped to the event type that recorded it. The type is kept so a
110
+ * repeat that decided the same class *differently* (a `step_failed` behind a
111
+ * `step_completed`) can be reported as more than a re-commit. See
112
+ * {@link EventsConsumer.firstEventTypeOfClass}.
113
+ */
114
+ private readonly seenEventClasses;
115
+ private onConsumedEvent?;
45
116
  private onUnconsumedEvent;
117
+ private onDuplicateEvent?;
46
118
  private getPromiseQueue;
119
+ private isDeliveryIdle;
47
120
  private pendingUnconsumedCheck;
48
121
  private pendingUnconsumedTimeout;
49
122
  private unconsumedCheckVersion;
123
+ /**
124
+ * The event a callback most recently claimed, for {@link describe}. Tracked
125
+ * separately from {@link eventIndex} because the walk also steps over events
126
+ * (parked, sealed no-ops, duplicates) without anyone consuming them, so
127
+ * `events[eventIndex - 1]` does not say what replay last acted on.
128
+ */
129
+ private lastConsumed;
50
130
  constructor(events: Event[], options: EventsConsumerOptions);
131
+ /**
132
+ * The oldest event the walk stepped over that no consumer has claimed yet,
133
+ * if any. Parking is a bet that a consumer will be registered later, so at
134
+ * any point where no consumer ever will be again (the replay finishing is
135
+ * the definitive one), this answers which event the bet lost on.
136
+ */
137
+ get strandedEvent(): Event | undefined;
138
+ /**
139
+ * What the walk is still holding, or `undefined` when it holds nothing.
140
+ *
141
+ * Read at every point a replay stops, including the suspensions that are not
142
+ * settling points, so the held state reaches telemetry. A replay cannot tell
143
+ * a delivery awaiting a later consumer from one no consumer will ever
144
+ * register, so it reports rather than decides: the same `eventId` reported on
145
+ * suspension after suspension of one run is the shape that says the bet
146
+ * parking made is not going to pay off, and that shape is only visible across
147
+ * replays.
148
+ */
149
+ get parkedSummary(): {
150
+ count: number;
151
+ eventId: string;
152
+ eventType: Event['eventType'];
153
+ } | undefined;
154
+ /**
155
+ * Where the walk stands, for a divergence message. Everything here is
156
+ * already known to the consumer; the point of the method is that the
157
+ * orchestrator can print it without reaching into private state.
158
+ *
159
+ * `index` is the ordered walk's position (the offset of the event it is
160
+ * stuck on, when it is stuck), `length` the log as this consumer holds it,
161
+ * `parked` how many events the walk stepped over and still holds, and
162
+ * `lastConsumedEventId` the id of the event a callback most recently
163
+ * claimed, `undefined` before the first claim.
164
+ */
165
+ describe(): EventsConsumerSnapshot;
166
+ append(events: Event[]): void;
51
167
  /**
52
168
  * Registers a callback function to be called after an event has been consumed
53
169
  * by a different callback. The callback can return:
@@ -58,7 +174,188 @@ export declare class EventsConsumer {
58
174
  * @param fn - The callback function to register.
59
175
  */
60
176
  subscribe(fn: EventConsumerCallback): void;
177
+ private notifyConsumedEvent;
61
178
  private consume;
179
+ /**
180
+ * Offer `currentEvent` to each registered callback in turn. Returns true
181
+ * when a callback consumed it. Does not move {@link eventIndex}: the ordered
182
+ * walk and the parked drain advance differently, so each does its own.
183
+ */
184
+ private offer;
185
+ /**
186
+ * Offer everything parked, oldest first, until a pass claims nothing.
187
+ *
188
+ * Each offer runs with {@link eventIndex} moved back to the position the
189
+ * parked event held in the log, because that is the position its consumer
190
+ * will register a delivery barrier under. Restoring the walk pointer
191
+ * afterwards is what keeps the two pointers from interfering.
192
+ */
193
+ private drainParked;
194
+ /**
195
+ * Release anything parked whose class a consumption has since recorded for
196
+ * the same entity, on the same terms as {@link skipDuplicateEvent}.
197
+ *
198
+ * The ordered walk decides a straggler at the event, but only for one of the
199
+ * two orders the copies can arrive in. When neither copy has a consumer yet,
200
+ * both park — the walk steps over the first and re-enters immediately, so
201
+ * the second is offered in the same tick, with no class recorded because
202
+ * nothing has been *consumed*. The drain then claims the first and the
203
+ * second is left held by a consumer list that will never grow the callback
204
+ * it needs, which the workflow function returning reports through
205
+ * {@link strandedEvent} as a replay divergence.
206
+ *
207
+ * Run before each offer pass rather than once, because the consumption that
208
+ * records the class happens inside the drain itself.
209
+ *
210
+ * Not specific to `attr_set`: `wait_completed` reaches the same state, and
211
+ * {@link ONE_SHOT_EVENT_TYPES} only covers it in the order where the
212
+ * consumption came first.
213
+ */
214
+ private dropParkedDuplicates;
215
+ /**
216
+ * Step the ordered walk over an event nobody claimed, holding on to it for a
217
+ * later consumer. Returns false when the event's type makes its position a
218
+ * decision record, which is the one case where nobody claiming it means the
219
+ * replay diverged.
220
+ */
221
+ private park;
222
+ /**
223
+ * The key `event`'s class is tracked under, or `undefined` for the events
224
+ * that belong to no class and are therefore never skipped: the types with no
225
+ * entry at all (`hook_received`, `hook_conflict`, `run_created`), and a
226
+ * classed type carrying no entity to track it under.
227
+ *
228
+ * {@link classifyEntityEvent} owns that rule, because the observability UI
229
+ * decides the same question about the same log and the two must not drift.
230
+ */
231
+ private eventClassKey;
232
+ /**
233
+ * Remembers that `event`'s class is now decided for its entity, if the type
234
+ * belongs to a class. First writer wins: the recorded type is the one the
235
+ * workflow observed, and a later repeat is measured against it.
236
+ */
237
+ private recordEventClass;
238
+ /**
239
+ * The type that already decided `event`'s class for the same entity, or
240
+ * `undefined` when nothing has: a second `step_created` for one step, a
241
+ * second terminal outcome, a second `step_started` after the step's result is
242
+ * already in the log.
243
+ *
244
+ * Such an event is committed but inert. Concurrent replays write into one
245
+ * log without a currency guard, so a replay working from a prefix that
246
+ * predates another replay's write can commit its own copy of work the log
247
+ * already records. That copy cannot change what the workflow observed: the
248
+ * outcome was decided by the first event of the class and every later replay
249
+ * reads that same event at the same log position, so ignoring the straggler
250
+ * is deterministic across replays.
251
+ *
252
+ * Classes are tracked separately, so passing one does not suppress another.
253
+ * A step whose result is in the log still reaches its `step_created` and
254
+ * `step_started` consumers if it has yet to see those classes.
255
+ *
256
+ * Consulted only after every registered callback has declined the event, so
257
+ * it can never take an event a consumer wanted. A retry's `step_started` is
258
+ * claimed by the step's live consumer and counts as an attempt exactly as
259
+ * before, and a second `step_created` reaching a step that has not finished
260
+ * is likewise consumed rather than skipped; only the copies nobody claims are
261
+ * skipped.
262
+ *
263
+ * Unlike the divergence report, this does *not* wait out the deferred window
264
+ * first, and it does not need to. The window buys time for a consumer that
265
+ * has yet to register, and no such consumer can want this event: the class
266
+ * was recorded by a consumption in this same replay, which means the entity's
267
+ * consumer was registered and took an event of this class, and correlation
268
+ * ids are minted from a monotonic ULID per body position, so nothing later in
269
+ * the body registers a second consumer under this id. Waiting would cost
270
+ * `getDeferredCheckDelayMs()` per straggler per replay for information that
271
+ * cannot arrive: 0.75% of production runs carry at least one straggler, and
272
+ * the p99 among those carries 155.
273
+ *
274
+ * The invariant to preserve if hook identity ever becomes caller-supplied
275
+ * (an idempotency key rather than a minted id): two `createHook` calls in one
276
+ * body could then share a correlation id, and the second consumer's
277
+ * `hook_created` would be a repeat of a class this replay already recorded.
278
+ * That would make skipping wrong for `hook_created`, and is the reason the
279
+ * class map lives next to the event types rather than being inferred.
280
+ */
281
+ private firstEventTypeOfClass;
282
+ /**
283
+ * Steps the walk over a sealed-log `noop` (specVersion >= 7): the World's
284
+ * backend wrote it to occupy a slot whose writer allocated the position and
285
+ * died, so the log's density arithmetic holds. It is invisible to the
286
+ * workflow: no consumer is offered it, no event class is recorded, and the
287
+ * deterministic clock does not advance, exactly as with
288
+ * {@link skipDuplicateEvent}, so a log that happens to contain one produces the same
289
+ * timestamps as a log that does not. (Its `createdAt` is the seal time,
290
+ * which can even postdate later slots' events; letting it touch the clock
291
+ * would leak the sealer's wall clock into replay.)
292
+ */
293
+ private skipSealedNoop;
294
+ /** Steps the walk over a repeat of an already-consumed class. */
295
+ private skipDuplicateEvent;
296
+ private handleEndOfLog;
297
+ private scheduleUnconsumedCheck;
298
+ /**
299
+ * Decide what a still-unconsumed event is, now that the promise queue has
300
+ * drained and the delivery gate says the VM is not mid-reaction.
301
+ *
302
+ * `mayPark` is false only for the end-of-log recheck of an event {@link park}
303
+ * already holds. Nothing in the first branch applies to one of those: it is
304
+ * not the event at the cursor, so the identity guard is not meaningful, and
305
+ * it is parked already.
306
+ *
307
+ * A duplicate class never arrives here. {@link consume} steps over one in the
308
+ * pass that offered it, before this check is ever scheduled, and a class
309
+ * recorded while the check was in flight can only have been recorded by a
310
+ * consumption inside {@link consume}, whose next pass re-offers this event
311
+ * and steps over it there, leaving the identity guard above to drop the
312
+ * in-flight check. One that parks before any consumption records its class
313
+ * is released later by {@link dropParkedDuplicates} instead.
314
+ */
315
+ private resolveUnconsumedEvent;
316
+ /**
317
+ * Run `fn` once no data delivery is in flight, polling the way
318
+ * `scheduleWhenIdle` does: let the promise queue drain, re-check a timer
319
+ * tick later, repeat.
320
+ *
321
+ * Without this the check is a bet that every delivery the walk is running
322
+ * ahead of lands inside a fixed window. Consumption is synchronous while the
323
+ * resolution it triggers is not: a step result hydrates in the host, resolves
324
+ * from a detached continuation behind `awaitEarlierDeliveries`, and only then
325
+ * does VM code run far enough to subscribe the next consumer. Replaying a
326
+ * batch of N parallel step results leaves N-1 of them on that detached path
327
+ * with the queue already drained, so the walk sits on the ordered event the
328
+ * VM is about to draw and the window is the only thing standing between a
329
+ * healthy run and `ReplayDivergenceError`.
330
+ *
331
+ * Shortening the window shows that mechanism directly: on identical event logs
332
+ * the local race repro corrupts 34 of 42 runs at a 10ms window and 0 of 114 at
333
+ * the 100ms default. That measures how the bet loses, not that the default
334
+ * loses it, and no measurement of a delivery outrunning 100ms exists either
335
+ * way. So read this as retiring the bet rather than as repairing an observed
336
+ * failure of that number: the delay is a user-settable env override, which
337
+ * leaves the old behavior one configuration away from losing on any backend.
338
+ *
339
+ * Termination is `hasParkedCommittedDelivery`'s: it counts only deliveries
340
+ * that resolve on their own, so nothing here can gate its own retirement. A
341
+ * genuinely orphaned event has no delivery to wait on and reaches `fn` on the
342
+ * first poll.
343
+ *
344
+ * What the gate gives up: for the ordered events that still reach
345
+ * `onUnconsumedEvent` rather than {@link park}, this stops being the thing
346
+ * that catches a diverged log while a delivery is in flight. The suspension
347
+ * and this check now wake from the same `isDeliveryIdle` edge, and
348
+ * `scheduleWhenIdle` fires on the first timer tick after idle while this waits
349
+ * a further `getDeferredCheckDelayMs()`. So a run with a pending `sleep()`
350
+ * suspends first, and `onWorkflowError` drops the divergence arriving second
351
+ * (its `'suspended'` branch demotes to `'replay'` and surfaces nothing),
352
+ * leaving a later `resume()` to decline into a cold replay. Pre-gate the
353
+ * suspension already won that race whenever the delivery landed inside the
354
+ * fixed window, so what changed is that the outcome stopped depending on
355
+ * timing. Nothing should treat this check as the mechanism that reports
356
+ * divergence on a log the run is still delivering into.
357
+ */
358
+ private whenDeliveryIdle;
62
359
  }
63
360
  export {};
64
361
  //# sourceMappingURL=events-consumer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"events-consumer.d.ts","sourceRoot":"","sources":["../src/events-consumer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAG7C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,oBAAY,mBAAmB;IAC7B;;OAEG;IACH,QAAQ,IAAA;IACR;;OAEG;IACH,WAAW,IAAA;IACX;;OAEG;IACH,QAAQ,IAAA;CACT;AAED,KAAK,qBAAqB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,KAAK,mBAAmB,CAAC;AAE1E,MAAM,WAAW,qBAAqB;IACpC;;;;;;OAMG;IACH,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAC1C;;;;;OAKG;IACH,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED,qBAAa,cAAc;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,CAAM;IAC9B,QAAQ,CAAC,SAAS,EAAE,qBAAqB,EAAE,CAAM;IACjD,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,eAAe,CAAsB;IAC7C,OAAO,CAAC,sBAAsB,CAA8B;IAC5D,OAAO,CAAC,wBAAwB,CAA8C;IAC9E,OAAO,CAAC,sBAAsB,CAAK;gBAEvB,MAAM,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,qBAAqB;IAO3D;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,EAAE,qBAAqB;IAgBnC,OAAO,CAAC,OAAO,CA+Db;CACH"}
1
+ {"version":3,"file":"events-consumer.d.ts","sourceRoot":"","sources":["../src/events-consumer.ts"],"names":[],"mappings":"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"}