@lostgradient/weft 0.2.1 → 0.4.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 (579) hide show
  1. package/README.md +123 -43
  2. package/dist/cli/conformance.js +7 -1
  3. package/dist/cli/generated/operation-client.generated.d.ts +55 -13
  4. package/dist/cli/generated/operation-client.generated.js +3 -0
  5. package/dist/cli/help-text.d.ts +1 -1
  6. package/dist/cli/help-text.js +1 -0
  7. package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
  8. package/dist/cli/operation-catalog-snapshot.js +11 -0
  9. package/dist/cli/parse-schedule-arguments.js +3 -1
  10. package/dist/cli/schedule.js +2 -1
  11. package/dist/cli/types.d.ts +1 -0
  12. package/dist/cli-main.js +80 -79
  13. package/dist/client/handle-delegation.d.ts +7 -2
  14. package/dist/client/handle-delegation.js +9 -1
  15. package/dist/client/http-client-requests.d.ts +4 -1
  16. package/dist/client/http-client-requests.js +10 -0
  17. package/dist/client/http-client.d.ts +10 -4
  18. package/dist/client/http-client.js +18 -1
  19. package/dist/client/http-request.d.ts +11 -1
  20. package/dist/client/http-request.js +17 -7
  21. package/dist/client/index.d.ts +1 -1
  22. package/dist/client/interface.d.ts +100 -4
  23. package/dist/client/local.d.ts +7 -1
  24. package/dist/client/local.js +17 -2
  25. package/dist/client/start-body.d.ts +9 -2
  26. package/dist/client/start-body.js +13 -4
  27. package/dist/core/byte-arrays.d.ts +5 -0
  28. package/dist/core/byte-arrays.js +5 -0
  29. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  30. package/dist/core/checkpoint/lifecycle.js +9 -4
  31. package/dist/core/checkpoint/serialization.js +12 -5
  32. package/dist/core/codec/extension-codec.d.ts +16 -0
  33. package/dist/core/codec/extension-codec.js +104 -8
  34. package/dist/core/codec/index.d.ts +1 -0
  35. package/dist/core/codec/index.js +1 -0
  36. package/dist/core/codec/serializer-registry.d.ts +122 -0
  37. package/dist/core/codec/serializer-registry.js +51 -0
  38. package/dist/core/context/activity-retry-state.d.ts +38 -0
  39. package/dist/core/context/activity-retry-state.js +89 -0
  40. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  41. package/dist/core/context/activity-schedule-to-close.js +69 -0
  42. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  43. package/dist/core/context/child-workflow-pipe.js +15 -2
  44. package/dist/core/context/context-presence.d.ts +19 -0
  45. package/dist/core/context/context-presence.js +13 -0
  46. package/dist/core/context/durable-operations.d.ts +25 -0
  47. package/dist/core/context/durable-operations.js +64 -0
  48. package/dist/core/context/index.d.ts +18 -5
  49. package/dist/core/context/index.js +17 -12
  50. package/dist/core/context/internals.d.ts +29 -0
  51. package/dist/core/context/internals.js +6 -1
  52. package/dist/core/context/operation-request.d.ts +35 -0
  53. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  54. package/dist/core/context/run-operation.d.ts +21 -3
  55. package/dist/core/context/run-operation.js +56 -93
  56. package/dist/core/context/session-state.js +7 -8
  57. package/dist/core/context/speculative-child.js +2 -0
  58. package/dist/core/context/types.d.ts +15 -0
  59. package/dist/core/context/version-patching.d.ts +8 -0
  60. package/dist/core/context/version-patching.js +40 -0
  61. package/dist/core/context/workflow-logger.d.ts +98 -0
  62. package/dist/core/context/workflow-logger.js +68 -0
  63. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  64. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  65. package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
  66. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  67. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  68. package/dist/core/engine/activity-reconciliation.js +12 -1
  69. package/dist/core/engine/activity-resolution.d.ts +23 -0
  70. package/dist/core/engine/activity-resolution.js +37 -0
  71. package/dist/core/engine/aggregate.js +66 -30
  72. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  73. package/dist/core/engine/async-activity-completion.js +53 -12
  74. package/dist/core/engine/attributes-tags.js +9 -4
  75. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  76. package/dist/core/engine/bulk-operations-purge.js +38 -3
  77. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  78. package/dist/core/engine/bulk-operations-shared.js +8 -2
  79. package/dist/core/engine/bulk-operations.d.ts +4 -1
  80. package/dist/core/engine/bulk-operations.js +235 -24
  81. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  82. package/dist/core/engine/callback-creators-bundles.js +30 -2
  83. package/dist/core/engine/callback-creators-core.js +6 -4
  84. package/dist/core/engine/callback-creators-router.js +10 -0
  85. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  86. package/dist/core/engine/callback-creators-schedule.js +12 -8
  87. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  88. package/dist/core/engine/candidate-read-batching.js +1 -0
  89. package/dist/core/engine/checkpoint-io.js +61 -25
  90. package/dist/core/engine/checkpoint-reads.js +3 -2
  91. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  92. package/dist/core/engine/checkpoint-replay.js +242 -0
  93. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  94. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  95. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  96. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  97. package/dist/core/engine/child-workflow.js +27 -4
  98. package/dist/core/engine/condition-waiters.d.ts +14 -0
  99. package/dist/core/engine/condition-waiters.js +5 -0
  100. package/dist/core/engine/construction.d.ts +3 -1
  101. package/dist/core/engine/construction.js +30 -8
  102. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  103. package/dist/core/engine/coordination-branch-executors.js +107 -0
  104. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  105. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  106. package/dist/core/engine/disposal.js +25 -0
  107. package/dist/core/engine/engine-create-types.d.ts +14 -18
  108. package/dist/core/engine/engine-internal-types.d.ts +38 -3
  109. package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
  110. package/dist/core/engine/engine-leak-warnings.js +4 -0
  111. package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
  112. package/dist/core/engine/engine-runtime-helpers.js +26 -5
  113. package/dist/core/engine/errors.d.ts +121 -0
  114. package/dist/core/engine/errors.js +45 -1
  115. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  116. package/dist/core/engine/event-log-compaction.js +20 -2
  117. package/dist/core/engine/fenced-write.d.ts +65 -0
  118. package/dist/core/engine/fenced-write.js +71 -0
  119. package/dist/core/engine/finalizer-state.d.ts +28 -0
  120. package/dist/core/engine/finalizer-state.js +16 -0
  121. package/dist/core/engine/handle-result.js +1 -1
  122. package/dist/core/engine/handles.d.ts +97 -40
  123. package/dist/core/engine/handles.js +25 -27
  124. package/dist/core/engine/index.d.ts +125 -15
  125. package/dist/core/engine/index.js +207 -11
  126. package/dist/core/engine/inline-launch-queue.d.ts +14 -0
  127. package/dist/core/engine/inline-launch-queue.js +32 -7
  128. package/dist/core/engine/inline-parking.js +3 -2
  129. package/dist/core/engine/internals.d.ts +125 -13
  130. package/dist/core/engine/lease-codec.d.ts +35 -0
  131. package/dist/core/engine/lease-codec.js +32 -0
  132. package/dist/core/engine/lease-deposition.d.ts +66 -0
  133. package/dist/core/engine/lease-deposition.js +10 -0
  134. package/dist/core/engine/lease-errors.d.ts +99 -0
  135. package/dist/core/engine/lease-errors.js +30 -0
  136. package/dist/core/engine/lease-manager.d.ts +114 -0
  137. package/dist/core/engine/lease-manager.js +135 -0
  138. package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
  139. package/dist/core/engine/lifecycle/persist.js +15 -52
  140. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  141. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  142. package/dist/core/engine/lifecycle/resume.js +39 -11
  143. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  144. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  145. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  146. package/dist/core/engine/lifecycle/start-commit.d.ts +56 -0
  147. package/dist/core/engine/lifecycle/start-commit.js +69 -0
  148. package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
  149. package/dist/core/engine/lifecycle/start-exec.js +38 -0
  150. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  151. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  152. package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
  153. package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
  154. package/dist/core/engine/lifecycle/start-or-signal.d.ts +46 -0
  155. package/dist/core/engine/lifecycle/start-or-signal.js +71 -0
  156. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  157. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  158. package/dist/core/engine/lifecycle/start.d.ts +6 -6
  159. package/dist/core/engine/lifecycle/start.js +47 -45
  160. package/dist/core/engine/lifecycle/transition.js +17 -5
  161. package/dist/core/engine/lifecycle.d.ts +3 -2
  162. package/dist/core/engine/lifecycle.js +9 -2
  163. package/dist/core/engine/list-candidate-resolution.js +2 -2
  164. package/dist/core/engine/listing.js +10 -6
  165. package/dist/core/engine/operations-activity.d.ts +4 -11
  166. package/dist/core/engine/operations-activity.js +22 -49
  167. package/dist/core/engine/operations-coordination.d.ts +10 -0
  168. package/dist/core/engine/operations-coordination.js +43 -8
  169. package/dist/core/engine/operations-router.d.ts +6 -0
  170. package/dist/core/engine/operations-router.js +2 -0
  171. package/dist/core/engine/operations-speculate.js +6 -2
  172. package/dist/core/engine/operations-stream.js +12 -2
  173. package/dist/core/engine/operations-time.d.ts +4 -2
  174. package/dist/core/engine/operations-time.js +14 -2
  175. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  176. package/dist/core/engine/operations-wait-condition.js +62 -0
  177. package/dist/core/engine/ownership-options.d.ts +23 -0
  178. package/dist/core/engine/ownership-options.js +26 -0
  179. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  180. package/dist/core/engine/payload-size-policy.js +4 -0
  181. package/dist/core/engine/pending-updates.d.ts +17 -0
  182. package/dist/core/engine/pending-updates.js +33 -11
  183. package/dist/core/engine/persisted-data-version.d.ts +5 -9
  184. package/dist/core/engine/persisted-data-version.js +4 -5
  185. package/dist/core/engine/queries.js +1 -1
  186. package/dist/core/engine/registration.d.ts +1 -0
  187. package/dist/core/engine/registration.js +18 -3
  188. package/dist/core/engine/schedule-handle.d.ts +45 -0
  189. package/dist/core/engine/schedule-handle.js +26 -0
  190. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  191. package/dist/core/engine/schedule-jitter.js +10 -0
  192. package/dist/core/engine/schedule-run.d.ts +17 -0
  193. package/dist/core/engine/schedule-run.js +38 -0
  194. package/dist/core/engine/schedule-timer.js +81 -17
  195. package/dist/core/engine/schedules.d.ts +8 -5
  196. package/dist/core/engine/schedules.js +44 -19
  197. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  198. package/dist/core/engine/search-attribute-records.js +17 -0
  199. package/dist/core/engine/second-instance-detector.d.ts +96 -0
  200. package/dist/core/engine/second-instance-detector.js +108 -0
  201. package/dist/core/engine/signals.d.ts +38 -0
  202. package/dist/core/engine/signals.js +55 -19
  203. package/dist/core/engine/state-utilities.d.ts +49 -2
  204. package/dist/core/engine/state-utilities.js +114 -3
  205. package/dist/core/engine/storage-io.d.ts +16 -2
  206. package/dist/core/engine/storage-io.js +26 -5
  207. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  208. package/dist/core/engine/stream-chunk-loading.js +24 -1
  209. package/dist/core/engine/sub-operation.js +22 -3
  210. package/dist/core/engine/termination/cleanup.d.ts +28 -1
  211. package/dist/core/engine/termination/cleanup.js +44 -2
  212. package/dist/core/engine/termination/complete.js +48 -9
  213. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  214. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  215. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  216. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  217. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  218. package/dist/core/engine/termination/finalizer.js +159 -0
  219. package/dist/core/engine/termination/suspend.d.ts +70 -0
  220. package/dist/core/engine/termination/suspend.js +41 -0
  221. package/dist/core/engine/termination.d.ts +5 -2
  222. package/dist/core/engine/termination.js +6 -0
  223. package/dist/core/engine/updates.js +5 -25
  224. package/dist/core/engine/validation/schedule.d.ts +2 -1
  225. package/dist/core/engine/validation/schedule.js +51 -2
  226. package/dist/core/engine/validation.js +54 -3
  227. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  228. package/dist/core/engine/waiting-update-response.js +22 -0
  229. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  230. package/dist/core/engine/workflow-concurrency.js +136 -0
  231. package/dist/core/engine/workflow-feed.d.ts +9 -8
  232. package/dist/core/engine/workflow-feed.js +4 -1
  233. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  234. package/dist/core/engine/workflow-indexes.js +10 -0
  235. package/dist/core/engine/workflow-state-stream.js +33 -13
  236. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  237. package/dist/core/engine-helpers.js +1 -0
  238. package/dist/core/events/activity-events.d.ts +43 -12
  239. package/dist/core/events/activity-events.js +28 -0
  240. package/dist/core/events/attribute-events.d.ts +2 -3
  241. package/dist/core/events/event-map.d.ts +19 -12
  242. package/dist/core/events/index.d.ts +1 -0
  243. package/dist/core/events/index.js +1 -0
  244. package/dist/core/events/schedule-events.d.ts +71 -0
  245. package/dist/core/events/schedule-events.js +29 -0
  246. package/dist/core/events/signal-events.d.ts +4 -6
  247. package/dist/core/events/system-events.d.ts +29 -19
  248. package/dist/core/events/system-events.js +26 -0
  249. package/dist/core/events/update-events.d.ts +6 -8
  250. package/dist/core/events/workflow-events.d.ts +108 -20
  251. package/dist/core/events/workflow-events.js +35 -0
  252. package/dist/core/failure-categories.js +5 -17
  253. package/dist/core/fault-code.d.ts +9 -3
  254. package/dist/core/fault-code.js +1 -0
  255. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  256. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  257. package/dist/core/inline-execution-strategy.d.ts +31 -36
  258. package/dist/core/inline-execution-strategy.js +16 -27
  259. package/dist/core/list-filter-validation.d.ts +1 -1
  260. package/dist/core/list-filter-validation.js +2 -1
  261. package/dist/core/payload-size.d.ts +1 -1
  262. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  263. package/dist/core/review/events.d.ts +6 -8
  264. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  265. package/dist/core/scheduler/scheduler-class.js +38 -11
  266. package/dist/core/scheduler/timer-batch.js +9 -1
  267. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  268. package/dist/core/scheduler/timer-sources.js +11 -5
  269. package/dist/core/session-state.d.ts +0 -1
  270. package/dist/core/session-state.js +2 -2
  271. package/dist/core/start-workflow-validation.d.ts +56 -0
  272. package/dist/core/start-workflow-validation.js +30 -1
  273. package/dist/core/step-context.d.ts +10 -6
  274. package/dist/core/step-context.js +7 -15
  275. package/dist/core/types/activity-verification.d.ts +67 -0
  276. package/dist/core/types/activity-verification.js +0 -0
  277. package/dist/core/types/activity.d.ts +86 -64
  278. package/dist/core/types/bulk.d.ts +50 -9
  279. package/dist/core/types/checkpoint.d.ts +44 -8
  280. package/dist/core/types/identity.d.ts +8 -1
  281. package/dist/core/types/launch-metadata.d.ts +33 -0
  282. package/dist/core/types/launch-metadata.js +0 -0
  283. package/dist/core/types/list-options.d.ts +146 -0
  284. package/dist/core/types/list-options.js +0 -0
  285. package/dist/core/types/message-handles.d.ts +25 -0
  286. package/dist/core/types/options.d.ts +165 -215
  287. package/dist/core/types/reviews.d.ts +2 -1
  288. package/dist/core/types/schedules.d.ts +39 -3
  289. package/dist/core/types/services-resolution.d.ts +47 -0
  290. package/dist/core/types/services-resolution.js +0 -0
  291. package/dist/core/types/state.d.ts +11 -11
  292. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  293. package/dist/core/types/workflow-builder-runtime.js +11 -2
  294. package/dist/core/types/workflow-builder.d.ts +47 -15
  295. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  296. package/dist/core/types/workflow-concurrency.js +0 -0
  297. package/dist/core/types/workflow-context.d.ts +157 -14
  298. package/dist/core/types/workflow-definition.d.ts +53 -10
  299. package/dist/core/types/workflow-function.d.ts +101 -9
  300. package/dist/core/types/workflow-log.d.ts +98 -0
  301. package/dist/core/types/workflow-log.js +0 -0
  302. package/dist/core/types/workflow-registries.d.ts +14 -3
  303. package/dist/core/types/workflow-registry.d.ts +3 -0
  304. package/dist/core/types/workflow-snapshot.d.ts +29 -0
  305. package/dist/core/types/workflow-snapshot.js +0 -0
  306. package/dist/core/types.d.ts +7 -0
  307. package/dist/core/types.js +7 -0
  308. package/dist/core/versioning.d.ts +9 -39
  309. package/dist/core/versioning.js +2 -12
  310. package/dist/core/weft-error.d.ts +44 -1
  311. package/dist/core/weft-error.js +19 -1
  312. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  313. package/dist/core/worker-execution-strategy.js +40 -36
  314. package/dist/core/worker-inbound-message.d.ts +38 -0
  315. package/dist/core/worker-inbound-message.js +37 -0
  316. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  317. package/dist/core/worker-log-abuse-counter.js +107 -0
  318. package/dist/core/worker-message-helpers.d.ts +47 -0
  319. package/dist/core/worker-message-helpers.js +26 -0
  320. package/dist/core/worker-protocol-guard.js +1 -1
  321. package/dist/core/worker-protocol-log.d.ts +56 -0
  322. package/dist/core/worker-protocol-log.js +18 -0
  323. package/dist/core/worker-protocol.d.ts +23 -0
  324. package/dist/core/worker-protocol.js +12 -2
  325. package/dist/core/workflow-version-tuple.d.ts +3 -9
  326. package/dist/core/workflow-version-tuple.js +2 -3
  327. package/dist/diagnostics/doctor.js +6 -3
  328. package/dist/diagnostics/format.js +3 -8
  329. package/dist/diagnostics/types.d.ts +5 -5
  330. package/dist/diagnostics/validate.d.ts +0 -1
  331. package/dist/diagnostics/version-check.d.ts +1 -1
  332. package/dist/diagnostics/version-check.js +10 -13
  333. package/dist/index.d.ts +13 -11
  334. package/dist/index.js +39 -4
  335. package/dist/json-schema.js +3 -3
  336. package/dist/mcp/cli.js +35 -35
  337. package/dist/mcp/dispatcher.js +1 -1
  338. package/dist/mcp/http.js +16 -6
  339. package/dist/mcp/list-filter.js +2 -1
  340. package/dist/mcp/protocol.d.ts +2 -0
  341. package/dist/mcp/protocol.js +1 -1
  342. package/dist/mcp/session.d.ts +16 -0
  343. package/dist/mcp/session.js +60 -6
  344. package/dist/mcp/tools.js +73 -6
  345. package/dist/observability/index.js +2 -2
  346. package/dist/server/asyncapi-channels.js +5 -2
  347. package/dist/server/attribute-filters.d.ts +8 -3
  348. package/dist/server/attribute-filters.js +6 -1
  349. package/dist/server/authentication/api-key.d.ts +2 -1
  350. package/dist/server/authentication/api-key.js +5 -2
  351. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  352. package/dist/server/authentication/constant-time-api-key.js +24 -0
  353. package/dist/server/authentication/index.d.ts +1 -1
  354. package/dist/server/authentication/index.js +7 -4
  355. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  356. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  357. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  358. package/dist/server/fault-to-http.js +8 -1
  359. package/dist/server/fault-to-json-rpc.js +1 -0
  360. package/dist/server/fleet-event-feed.d.ts +31 -0
  361. package/dist/server/fleet-event-feed.js +157 -0
  362. package/dist/server/handler/index.js +1 -1
  363. package/dist/server/handler/response-helpers.js +2 -1
  364. package/dist/server/handler/route-dispatch.d.ts +6 -3
  365. package/dist/server/handler/route-dispatch.js +2 -2
  366. package/dist/server/handler.js +31 -31
  367. package/dist/server/index.d.ts +32 -2
  368. package/dist/server/index.js +35 -35
  369. package/dist/server/interactive-operations.js +1 -0
  370. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  371. package/dist/server/json-rpc-transport-helpers.js +2 -1
  372. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  373. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  374. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  375. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  376. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  377. package/dist/server/json-rpc-websocket-types.js +0 -0
  378. package/dist/server/json-rpc-websocket-validation.js +20 -4
  379. package/dist/server/json-rpc-websocket.d.ts +2 -43
  380. package/dist/server/json-rpc-websocket.js +57 -74
  381. package/dist/server/openapi.d.ts +2 -1
  382. package/dist/server/openapi.js +1 -3
  383. package/dist/server/openrpc-document-schema.d.ts +78 -0
  384. package/dist/server/openrpc-document-schema.js +27 -1
  385. package/dist/server/openrpc-errors.d.ts +3 -0
  386. package/dist/server/openrpc-errors.js +2 -1
  387. package/dist/server/openrpc.js +32 -0
  388. package/dist/server/operation-catalog/index.d.ts +1 -1
  389. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  390. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  391. package/dist/server/operation-catalog/pipeline.js +8 -1
  392. package/dist/server/operation-catalog/registry.js +13 -0
  393. package/dist/server/operation-catalog/types.d.ts +20 -9
  394. package/dist/server/operation-fault.d.ts +10 -0
  395. package/dist/server/operation-fault.js +2 -0
  396. package/dist/server/operation-registry.d.ts +12 -11
  397. package/dist/server/operation-registry.js +12 -3
  398. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  399. package/dist/server/operations/async-activity.d.ts +2 -2
  400. package/dist/server/operations/async-activity.js +12 -7
  401. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  402. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  403. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  404. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  405. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  406. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  407. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  408. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  409. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  410. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  411. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  412. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  413. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  414. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  415. package/dist/server/operations/create-schedule.d.ts +3 -1
  416. package/dist/server/operations/create-schedule.js +29 -11
  417. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  418. package/dist/server/operations/fleet-events-subscription.js +99 -0
  419. package/dist/server/operations/fork-workflow.d.ts +1 -1
  420. package/dist/server/operations/fork-workflow.js +3 -2
  421. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  422. package/dist/server/operations/get-registry.d.ts +1 -1
  423. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  424. package/dist/server/operations/get-review.d.ts +1 -1
  425. package/dist/server/operations/get-schedule.d.ts +1 -1
  426. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  427. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  428. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  429. package/dist/server/operations/get-task-diagnostics.js +101 -7
  430. package/dist/server/operations/get-update-result.d.ts +1 -1
  431. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  432. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  433. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  434. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  435. package/dist/server/operations/get-workflow.d.ts +1 -1
  436. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  437. package/dist/server/operations/list-reviews.d.ts +1 -1
  438. package/dist/server/operations/list-schedules.d.ts +1 -1
  439. package/dist/server/operations/list-task-queues.d.ts +2 -2
  440. package/dist/server/operations/list-workers.d.ts +2 -2
  441. package/dist/server/operations/list-workflows.d.ts +1 -1
  442. package/dist/server/operations/operation-helpers.d.ts +16 -1
  443. package/dist/server/operations/operation-helpers.js +15 -3
  444. package/dist/server/operations/pause-schedule.d.ts +1 -1
  445. package/dist/server/operations/purge-workflows.d.ts +5 -5
  446. package/dist/server/operations/purge-workflows.js +2 -2
  447. package/dist/server/operations/query-workflow.d.ts +1 -1
  448. package/dist/server/operations/query-workflow.js +3 -2
  449. package/dist/server/operations/recover-all.d.ts +1 -1
  450. package/dist/server/operations/replay-workflow.d.ts +1 -1
  451. package/dist/server/operations/resume-schedule.d.ts +1 -1
  452. package/dist/server/operations/resume-workflow.js +2 -2
  453. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  454. package/dist/server/operations/set-workflow-attributes.js +6 -3
  455. package/dist/server/operations/signal-workflow.js +8 -3
  456. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  457. package/dist/server/operations/start-or-signal-workflow.d.ts +44 -0
  458. package/dist/server/operations/start-or-signal-workflow.js +130 -0
  459. package/dist/server/operations/start-workflow-options.d.ts +38 -0
  460. package/dist/server/operations/start-workflow-options.js +63 -0
  461. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  462. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  463. package/dist/server/operations/start-workflow.d.ts +1 -1
  464. package/dist/server/operations/start-workflow.js +15 -92
  465. package/dist/server/operations/storage.d.ts +6 -6
  466. package/dist/server/operations/storage.js +24 -14
  467. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  468. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  469. package/dist/server/operations/submit-review-decision.js +6 -3
  470. package/dist/server/operations/suspend-workflow.d.ts +13 -0
  471. package/dist/server/operations/suspend-workflow.js +36 -0
  472. package/dist/server/operations/update-schedule.d.ts +1 -1
  473. package/dist/server/operations/update-schedule.js +7 -4
  474. package/dist/server/operations/update-workflow.d.ts +1 -1
  475. package/dist/server/operations/update-workflow.js +7 -3
  476. package/dist/server/operations/worker-drain.d.ts +8 -8
  477. package/dist/server/operations/worker-drain.js +11 -8
  478. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  479. package/dist/server/operations/workflow-events-subscription.js +43 -8
  480. package/dist/server/rest-binding.d.ts +21 -8
  481. package/dist/server/rest-bindings.js +24 -0
  482. package/dist/server/rest-body.d.ts +10 -0
  483. package/dist/server/rest-body.js +80 -0
  484. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  485. package/dist/server/runtime/authentication-bridge.js +33 -6
  486. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  487. package/dist/server/runtime/client-visible-events.js +65 -0
  488. package/dist/server/runtime/context.d.ts +7 -0
  489. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  490. package/dist/server/runtime/event-broadcasting.js +72 -38
  491. package/dist/server/runtime/retry.d.ts +1 -0
  492. package/dist/server/runtime/retry.js +14 -0
  493. package/dist/server/runtime/shutdown.d.ts +7 -6
  494. package/dist/server/runtime/shutdown.js +6 -1
  495. package/dist/server/runtime/task-dispatch.js +5 -3
  496. package/dist/server/runtime/task-polling.d.ts +16 -2
  497. package/dist/server/runtime/task-polling.js +80 -24
  498. package/dist/server/runtime/task-reconciliation.js +9 -1
  499. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  500. package/dist/server/runtime/task-result-resolution.js +81 -0
  501. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  502. package/dist/server/runtime/websocket-stream.js +173 -7
  503. package/dist/server/runtime/websocket-upgrade.js +22 -3
  504. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  505. package/dist/server/runtime/websocket-worker.js +46 -30
  506. package/dist/server/serve-internals.d.ts +11 -1
  507. package/dist/server/serve-internals.js +20 -2
  508. package/dist/server/task-state.d.ts +38 -0
  509. package/dist/server/task-state.js +28 -0
  510. package/dist/server/workflow-event-feed.d.ts +36 -115
  511. package/dist/server/workflow-event-feed.js +92 -27
  512. package/dist/service-worker/index.js +31 -31
  513. package/dist/storage/auto.js +1 -1
  514. package/dist/storage/bun-sql.js +24 -0
  515. package/dist/storage/capabilities.d.ts +10 -2
  516. package/dist/storage/capabilities.js +2 -2
  517. package/dist/storage/compressed-storage.js +1 -1
  518. package/dist/storage/default-scope.d.ts +7 -4
  519. package/dist/storage/http.js +2 -2
  520. package/dist/storage/index.d.ts +81 -4
  521. package/dist/storage/indexeddb.js +1 -1
  522. package/dist/storage/interface.d.ts +189 -0
  523. package/dist/storage/interface.js +1 -1
  524. package/dist/storage/key-prefixes.d.ts +1 -1
  525. package/dist/storage/key-prefixes.js +12 -0
  526. package/dist/storage/lmdb.d.ts +4 -3
  527. package/dist/storage/lmdb.js +1 -1
  528. package/dist/storage/memory.js +1 -1
  529. package/dist/storage/neon-batch.d.ts +30 -0
  530. package/dist/storage/neon-batch.js +30 -0
  531. package/dist/storage/neon-value-mapping.d.ts +74 -0
  532. package/dist/storage/neon-value-mapping.js +23 -0
  533. package/dist/storage/neon.d.ts +124 -0
  534. package/dist/storage/neon.js +15 -0
  535. package/dist/storage/node-sqlite-loader.d.ts +71 -0
  536. package/dist/storage/node-sqlite-loader.js +41 -0
  537. package/dist/storage/node-sqlite.d.ts +1 -19
  538. package/dist/storage/node-sqlite.js +61 -32
  539. package/dist/storage/postgres-key-value-queries.d.ts +104 -0
  540. package/dist/storage/postgres-key-value-queries.js +101 -0
  541. package/dist/storage/resolve.d.ts +2 -165
  542. package/dist/storage/resolve.js +1 -1
  543. package/dist/storage/scoped-storage.js +1 -1
  544. package/dist/storage/storage-configuration.d.ts +209 -0
  545. package/dist/storage/storage-configuration.js +0 -0
  546. package/dist/storage/testing.d.ts +168 -0
  547. package/dist/storage/testing.js +2 -0
  548. package/dist/storage/text-value-store.d.ts +9 -9
  549. package/dist/storage/turso.d.ts +8 -0
  550. package/dist/storage/turso.js +2 -2
  551. package/dist/storage/typed-storage.js +1 -1
  552. package/dist/storage/web-extension.js +1 -1
  553. package/dist/testing/index.js +35 -35
  554. package/dist/version.d.ts +1 -1
  555. package/dist/version.js +1 -1
  556. package/dist/worker/index.js +9 -5
  557. package/dist/worker/long-poll.js +4 -0
  558. package/dist/worker/protocol-messages.d.ts +20 -0
  559. package/dist/worker/protocol-schemas.d.ts +32 -0
  560. package/dist/worker/protocol-schemas.js +8 -4
  561. package/dist/worker/protocol-task-result.d.ts +28 -0
  562. package/dist/worker/protocol-task-result.js +76 -0
  563. package/dist/worker/protocol.d.ts +4 -15
  564. package/dist/worker/protocol.js +1 -1
  565. package/dist/worker/registry/fair-share.d.ts +29 -0
  566. package/dist/worker/registry/fair-share.js +30 -0
  567. package/dist/worker/registry/routing.d.ts +18 -0
  568. package/dist/worker/registry/routing.js +14 -0
  569. package/dist/worker/registry/types.d.ts +7 -0
  570. package/dist/worker/registry.d.ts +16 -1
  571. package/dist/worker/registry.js +24 -36
  572. package/dist/workers/worker-replay-state.d.ts +32 -0
  573. package/dist/workers/worker-replay-state.js +35 -0
  574. package/dist/workers/worker-state-namespace.d.ts +21 -0
  575. package/dist/workers/worker-state-namespace.js +13 -0
  576. package/dist/workers/workflow-runner.d.ts +19 -15
  577. package/dist/workers/workflow-runner.js +72 -60
  578. package/dist/workers/workflow-worker-entry.js +5 -2
  579. package/package.json +21 -4
@@ -1,12 +1,24 @@
1
+ import { decode } from "../../core/codec.js";
2
+ import { loadStoredStreamTailSequence } from "../../core/engine/stream-chunk-loading.js";
1
3
  import { KEYS } from "../../storage/interface.js";
2
- const TOKEN_EVENT_TYPE = "stream:token";
4
+ const TOKEN_EVENT_TYPE = "stream:token", STREAM_CONNECTION_POLICY_CLOSE_CODE = 1008, MAX_WATCH_REPLAY_EVENTS = 1000, MAX_PENDING_WATCH_REPLAY_MESSAGES = 1000;
5
+ export const DEFAULT_MAX_STREAM_CONNECTIONS_PER_WORKFLOW = 100;
3
6
  export function sendStreamMessage(ws, sequence, message) {
4
- if (sequence <= (ws.data.lastDeliveredSequence ?? -1))
7
+ if (sequence <= (ws.data.streamLastDeliveredSequence ?? -1))
5
8
  return;
6
9
  ws.send(message);
7
- ws.data.lastDeliveredSequence = sequence;
10
+ ws.data.streamLastDeliveredSequence = sequence;
11
+ }
12
+ export function sendWatchMessage(ws, sequence, message) {
13
+ if (sequence <= (ws.data.watchLastDeliveredSequence ?? -1))
14
+ return;
15
+ ws.send(message);
16
+ ws.data.watchLastDeliveredSequence = sequence;
8
17
  }
9
18
  export async function getHighestStoredStreamSequence(engine, workflowId, key) {
19
+ const tailSequence = await loadStoredStreamTailSequence(engine.storage, workflowId, key);
20
+ if (tailSequence !== null)
21
+ return tailSequence;
10
22
  const prefix = KEYS.streamChunkPrefix(workflowId, key);
11
23
  for await (const [storageKey] of engine.storage.scan(prefix, { reverse: !0, limit: 1 })) {
12
24
  const sequenceText = storageKey.slice(prefix.length), sequence = Number.parseInt(sequenceText, 10);
@@ -15,13 +27,37 @@ export async function getHighestStoredStreamSequence(engine, workflowId, key) {
15
27
  }
16
28
  return -1;
17
29
  }
30
+ export async function getHighestStoredWatchSequence(engine, workflowId) {
31
+ const prefix = KEYS.eventPrefix(workflowId);
32
+ for await (const [storageKey] of engine.storage.scan(prefix, { reverse: !0, limit: 50 })) {
33
+ const sequence = parseSequenceFromEventKey(prefix, storageKey);
34
+ if (sequence === null)
35
+ continue;
36
+ return sequence;
37
+ }
38
+ return -1;
39
+ }
18
40
  export function addStreamSocket(context, workflowId, ws) {
41
+ if (!addWorkflowStreamConnection(context, workflowId, ws))
42
+ return !1;
19
43
  let sockets = context.streamSockets.get(workflowId);
20
44
  if (!sockets) {
21
45
  sockets = new Set;
22
46
  context.streamSockets.set(workflowId, sockets);
23
47
  }
24
48
  sockets.add(ws);
49
+ return !0;
50
+ }
51
+ export function addWatchSocket(context, workflowId, ws) {
52
+ if (!addWorkflowStreamConnection(context, workflowId, ws))
53
+ return !1;
54
+ let sockets = context.watchSockets.get(workflowId);
55
+ if (!sockets) {
56
+ sockets = new Set;
57
+ context.watchSockets.set(workflowId, sockets);
58
+ }
59
+ sockets.add(ws);
60
+ return !0;
25
61
  }
26
62
  export function removeStreamSocket(context, ws) {
27
63
  const workflowId = ws.data.workflowId;
@@ -34,6 +70,39 @@ export function removeStreamSocket(context, ws) {
34
70
  if (sockets.size === 0)
35
71
  context.streamSockets.delete(workflowId);
36
72
  }
73
+ export function removeWatchSocket(context, ws) {
74
+ const workflowId = ws.data.workflowId;
75
+ if (!workflowId)
76
+ return;
77
+ const sockets = context.watchSockets.get(workflowId);
78
+ if (!sockets)
79
+ return;
80
+ sockets.delete(ws);
81
+ if (sockets.size === 0)
82
+ context.watchSockets.delete(workflowId);
83
+ }
84
+ export function removeWorkflowStreamConnection(context, ws) {
85
+ const workflowId = ws.data.workflowId;
86
+ if (!workflowId || !ws.data.workflowStreamConnectionAccepted)
87
+ return;
88
+ ws.data.workflowStreamConnectionAccepted = !1;
89
+ const currentCount = context.workflowStreamConnectionCounts.get(workflowId);
90
+ if (currentCount === void 0 || currentCount <= 1) {
91
+ context.workflowStreamConnectionCounts.delete(workflowId);
92
+ return;
93
+ }
94
+ context.workflowStreamConnectionCounts.set(workflowId, currentCount - 1);
95
+ }
96
+ function addWorkflowStreamConnection(context, workflowId, ws) {
97
+ const currentCount = context.workflowStreamConnectionCounts.get(workflowId) ?? 0, maxConnections = context.maxStreamConnectionsPerWorkflow;
98
+ if (currentCount >= maxConnections) {
99
+ ws.close(STREAM_CONNECTION_POLICY_CLOSE_CODE, `maximum stream connections per workflow (${maxConnections}) exceeded`);
100
+ return !1;
101
+ }
102
+ context.workflowStreamConnectionCounts.set(workflowId, currentCount + 1);
103
+ ws.data.workflowStreamConnectionAccepted = !0;
104
+ return !0;
105
+ }
37
106
  export function flushPendingStreamMessages(_context, ws) {
38
107
  const pendingMessages = ws.data.pendingStreamMessages ?? [];
39
108
  pendingMessages.sort((left, right) => left.sequence - right.sequence);
@@ -41,12 +110,19 @@ export function flushPendingStreamMessages(_context, ws) {
41
110
  sendStreamMessage(ws, pending.sequence, pending.message);
42
111
  ws.data.pendingStreamMessages = [];
43
112
  }
113
+ export function flushPendingWatchMessages(_context, ws) {
114
+ const pendingMessages = ws.data.pendingWatchMessages ?? [];
115
+ pendingMessages.sort((left, right) => left.sequence - right.sequence);
116
+ for (const pending of pendingMessages)
117
+ sendWatchMessage(ws, pending.sequence, pending.message);
118
+ ws.data.pendingWatchMessages = [];
119
+ }
44
120
  export function publishTokenMessage(context, workflowId, sequence, message) {
45
121
  const sockets = context.streamSockets.get(workflowId);
46
122
  if (!sockets)
47
123
  return;
48
124
  for (const ws of sockets) {
49
- if (ws.data.replayInProgress) {
125
+ if (ws.data.streamReplayInProgress) {
50
126
  ws.data.pendingStreamMessages ??= [];
51
127
  ws.data.pendingStreamMessages.push({ sequence, message });
52
128
  continue;
@@ -54,11 +130,29 @@ export function publishTokenMessage(context, workflowId, sequence, message) {
54
130
  sendStreamMessage(ws, sequence, message);
55
131
  }
56
132
  }
133
+ export function publishWatchMessage(context, workflowId, sequence, message) {
134
+ const sockets = context.watchSockets.get(workflowId);
135
+ if (!sockets)
136
+ return;
137
+ for (const ws of sockets) {
138
+ if (ws.data.watchReplayInProgress) {
139
+ const pendingMessages = ws.data.pendingWatchMessages ?? [];
140
+ if (pendingMessages.length >= MAX_PENDING_WATCH_REPLAY_MESSAGES) {
141
+ closeWatchSocketForReplayLimit(context, ws, `watch replay buffer exceeded ${MAX_PENDING_WATCH_REPLAY_MESSAGES} pending messages`);
142
+ continue;
143
+ }
144
+ pendingMessages.push({ sequence, message });
145
+ ws.data.pendingWatchMessages = pendingMessages;
146
+ continue;
147
+ }
148
+ sendWatchMessage(ws, sequence, message);
149
+ }
150
+ }
57
151
  export async function replayTokenStream(context, engine, ws, workflowId) {
58
- ws.data.lastDeliveredSequence = -1;
152
+ ws.data.streamLastDeliveredSequence = -1;
59
153
  try {
60
154
  const requestedResumeFrom = ws.data.resumeFrom, after = requestedResumeFrom === void 0 ? -1 : Math.min(requestedResumeFrom, await getHighestStoredStreamSequence(engine, workflowId, "tokens"));
61
- ws.data.lastDeliveredSequence = after;
155
+ ws.data.streamLastDeliveredSequence = after;
62
156
  const chunks = after >= 0 ? await engine.getStreamChunks(workflowId, "tokens", { after }) : await engine.getStreamChunks(workflowId, "tokens");
63
157
  for (const chunk of chunks) {
64
158
  if (typeof chunk.value !== "object" || chunk.value === null)
@@ -73,7 +167,79 @@ export async function replayTokenStream(context, engine, ws, workflowId) {
73
167
  } catch (error) {
74
168
  console.error(`[weft] Failed to replay token stream for workflow "${workflowId}":`, error);
75
169
  } finally {
76
- ws.data.replayInProgress = !1;
170
+ ws.data.streamReplayInProgress = !1;
77
171
  flushPendingStreamMessages(context, ws);
78
172
  }
79
173
  }
174
+ export async function replayWatchEvents(context, engine, ws, workflowId) {
175
+ ws.data.watchLastDeliveredSequence = -1;
176
+ let shouldFlushPending = !0, replayedEvents = 0;
177
+ try {
178
+ const requestedResumeFrom = ws.data.resumeFrom, after = requestedResumeFrom === void 0 ? -1 : Math.min(requestedResumeFrom, await getHighestStoredWatchSequence(engine, workflowId));
179
+ ws.data.watchLastDeliveredSequence = after;
180
+ const prefix = KEYS.eventPrefix(workflowId), scanOptions = after >= 0 ? { gt: KEYS.event(workflowId, after) } : void 0;
181
+ for await (const [storageKey, value] of engine.storage.scan(prefix, scanOptions)) {
182
+ const sequence = parseSequenceFromEventKey(prefix, storageKey);
183
+ if (sequence === null || sequence <= after)
184
+ continue;
185
+ const decoded = decodeStoredWatchEvent(value);
186
+ if (!isStoredWatchEvent(decoded))
187
+ continue;
188
+ if (replayedEvents >= MAX_WATCH_REPLAY_EVENTS) {
189
+ shouldFlushPending = !1;
190
+ closeWatchSocketForReplayLimit(context, ws, `watch replay window exceeds ${MAX_WATCH_REPLAY_EVENTS} events; reconnect with a newer resumeFrom`);
191
+ return;
192
+ }
193
+ sendWatchMessage(ws, sequence, JSON.stringify({
194
+ type: decoded.type,
195
+ timestamp: decoded.timestamp,
196
+ data: decoded.data,
197
+ sequence,
198
+ cursor: String(sequence)
199
+ }));
200
+ replayedEvents += 1;
201
+ }
202
+ } catch (error) {
203
+ console.error(`[weft] Failed to replay watch events for workflow "${workflowId}":`, error);
204
+ shouldFlushPending = !1;
205
+ closeWatchSocketForReplayLimit(context, ws, "watch replay failed before catch-up completed; reconnect with a newer resumeFrom");
206
+ } finally {
207
+ ws.data.watchReplayInProgress = !1;
208
+ if (shouldFlushPending)
209
+ flushPendingWatchMessages(context, ws);
210
+ else
211
+ ws.data.pendingWatchMessages = [];
212
+ }
213
+ }
214
+ function closeWatchSocketForReplayLimit(context, ws, reason) {
215
+ ws.data.pendingWatchMessages = [];
216
+ ws.data.watchReplayInProgress = !1;
217
+ ws.close(STREAM_CONNECTION_POLICY_CLOSE_CODE, reason);
218
+ removeWatchSocket(context, ws);
219
+ removeWorkflowStreamConnection(context, ws);
220
+ }
221
+ function decodeStoredWatchEvent(value) {
222
+ try {
223
+ return decode(value);
224
+ } catch {
225
+ return null;
226
+ }
227
+ }
228
+ function parseSequenceFromEventKey(prefix, storageKey) {
229
+ if (!storageKey.startsWith(prefix))
230
+ return null;
231
+ const rawSequence = storageKey.slice(prefix.length);
232
+ if (!/^\d+$/.test(rawSequence))
233
+ return null;
234
+ const sequence = Number.parseInt(rawSequence, 10);
235
+ return Number.isSafeInteger(sequence) ? sequence : null;
236
+ }
237
+ function isStoredWatchEvent(value) {
238
+ if (typeof value !== "object" || value === null)
239
+ return !1;
240
+ const record = value;
241
+ return typeof record.type === "string" && typeof record.timestamp === "number" && Number.isFinite(record.timestamp) && isPlainRecord(record.data);
242
+ }
243
+ function isPlainRecord(value) {
244
+ return typeof value === "object" && value !== null && !Array.isArray(value);
245
+ }
@@ -37,7 +37,7 @@ function rejectsCrossOriginUpgrade(context, request) {
37
37
  return context.corsPolicy !== null && origin !== null && !isOriginAllowed(context.corsPolicy, origin);
38
38
  }
39
39
  function resolvePrincipalForUpgrade(connectionType, authContext) {
40
- if (connectionType !== "jsonrpc" && connectionType !== "worker")
40
+ if (connectionType !== "jsonrpc" && connectionType !== "worker" && connectionType !== "watch" && connectionType !== "stream")
41
41
  return { ok: !0, principal: void 0 };
42
42
  if (authContext === void 0)
43
43
  return { ok: !0, principal: void 0 };
@@ -48,10 +48,29 @@ function resolvePrincipalForUpgrade(connectionType, authContext) {
48
48
  console.error("[weft] WebSocket upgrade principal resolution failed", error);
49
49
  return { ok: !1, response: new Response("Authentication context invalid", { status: 401 }) };
50
50
  }
51
- if (connectionType === "worker" && isAuthenticated(principal) && !principal.hasScope("workers:write"))
52
- return { ok: !1, response: new Response("Insufficient scope", { status: 403 }) };
51
+ const requiredScope = upgradeScope(connectionType);
52
+ if (requiredScope !== null) {
53
+ if (!isAuthenticated(principal))
54
+ return { ok: !1, response: new Response("Authentication required", { status: 401 }) };
55
+ if (!principal.hasScope(requiredScope))
56
+ return { ok: !1, response: new Response("Insufficient scope", { status: 403 }) };
57
+ }
53
58
  return { ok: !0, principal };
54
59
  }
60
+ function upgradeScope(connectionType) {
61
+ switch (connectionType) {
62
+ case "worker":
63
+ return "workers:write";
64
+ case "watch":
65
+ return "events:read";
66
+ case "stream":
67
+ return "streams:read";
68
+ case "jsonrpc":
69
+ case "generic":
70
+ case void 0:
71
+ return null;
72
+ }
73
+ }
55
74
  export function handleWebSocketUpgrade(server, context, options, request, url, authContext) {
56
75
  if (request.headers.get("upgrade") !== "websocket")
57
76
  return null;
@@ -3,5 +3,5 @@ import type { ServeOptions } from '../index.ts';
3
3
  import type { WebSocketData } from '../json-rpc-websocket-runtime.ts';
4
4
  import type { ServerContext } from './context.ts';
5
5
  export { isInflightRecord } from '../task-state.ts';
6
- export declare function withRetry<T>(operation: () => Promise<T>, label: string, maxAttempts?: number): Promise<T>;
6
+ export { withRetry } from './retry.ts';
7
7
  export declare function handleWorkerWebSocketMessage(context: ServerContext, options: ServeOptions, ws: ServerWebSocket<WebSocketData>, rawMessage: string | Buffer, cleanupWorkflowIndex: (operationId: string) => void): void;
@@ -1,4 +1,5 @@
1
1
  import { decode, encode } from "../../core/codec.js";
2
+ import { WorkerConnectedEvent } from "../../core/events.js";
2
3
  import { KEYS } from "../../storage/interface.js";
3
4
  import {
4
5
  REMOTE_WORKER_PROTOCOL_VERSION,
@@ -7,35 +8,20 @@ import {
7
8
  } from "../../worker/protocol.js";
8
9
  import { workerProtocolIncompatibleMessage } from "../../worker/worker-protocol-incompatible-error.js";
9
10
  import { isAuthenticated } from "../principal.js";
11
+ import { isInflightRecord, readInflightRecord } from "../task-state.js";
12
+ import { withRetry } from "./retry.js";
13
+ import { recordWorkerCapacitySaturationMetric } from "./task-metrics.js";
10
14
  import {
11
- isInflightRecord,
12
- readInflightRecord,
13
- transitionInflightToResolved
14
- } from "../task-state.js";
15
- import {
16
- recordTaskExecutionLatencyMetric,
17
- recordWorkerCapacitySaturationMetric
18
- } from "./task-metrics.js";
15
+ taskResultPayloadSizeError,
16
+ transitionTaskResultToResolvedWithRetry
17
+ } from "./task-result-resolution.js";
19
18
  import { WORKER_STREAM_RE } from "./websocket-upgrade.js";
20
19
  const MAX_WORKER_CONCURRENCY = 1000, DEFAULT_WORKER_CONCURRENCY = 10, WORKER_PROTOCOL_CLOSE_CODE = 1002, WORKER_REGISTRATION_CLOSE_CODE = 1008;
21
20
  function isWorkerConnection(pathname) {
22
21
  return WORKER_STREAM_RE.test(pathname);
23
22
  }
24
23
  export { isInflightRecord } from "../task-state.js";
25
- export async function withRetry(operation, label, maxAttempts = 2) {
26
- let lastError;
27
- for (let attempt = 1;attempt <= maxAttempts; attempt++)
28
- try {
29
- return await operation();
30
- } catch (error) {
31
- lastError = error;
32
- if (attempt < maxAttempts) {
33
- console.warn(`[weft] Retrying "${label}" (attempt ${attempt + 1}/${maxAttempts})`);
34
- await Bun.sleep(100 * attempt);
35
- }
36
- }
37
- throw lastError;
38
- }
24
+ export { withRetry } from "./retry.js";
39
25
  function sendWorkerProtocolMessage(ws, message) {
40
26
  ws.send(JSON.stringify(message));
41
27
  }
@@ -83,7 +69,7 @@ function buildWorkerRegistrationInfo(message, queue, concurrency) {
83
69
  ...message.capabilities !== void 0 ? { capabilities: message.capabilities } : {}
84
70
  };
85
71
  }
86
- function registerWorker(context, ws, message) {
72
+ function registerWorker(context, options, ws, message) {
87
73
  if (!principalMayRegisterWorker(ws.data.principal)) {
88
74
  rejectRegistration(ws, "invalid_registration", "Worker registration requires the workers:write scope", message.protocolVersion);
89
75
  return;
@@ -106,6 +92,7 @@ function registerWorker(context, ws, message) {
106
92
  activities: [...message.activities],
107
93
  concurrency: clampedConcurrency
108
94
  });
95
+ options.engine.dispatchEvent(new WorkerConnectedEvent(message.workerId, queue, [...message.activities], clampedConcurrency));
109
96
  }
110
97
  function resolveTaskResultStatus(message) {
111
98
  return message.status === "completed" ? "completed" : "failed";
@@ -120,20 +107,49 @@ function onTaskResultMessage(context, options, ws, message, cleanupWorkflowIndex
120
107
  });
121
108
  return;
122
109
  }
110
+ if (!context.registry.isAssignedToAttempt(operationId, workerId, message.attemptToken)) {
111
+ sendWorkerProtocolMessage(ws, {
112
+ type: "protocolError",
113
+ code: "invalid_message",
114
+ message: `taskResult for operation "${operationId}" rejected \u2014 stale attempt token`
115
+ });
116
+ return;
117
+ }
118
+ const resolvedStatus = resolveTaskResultStatus(message), payloadError = taskResultPayloadSizeError({
119
+ operationId,
120
+ status: resolvedStatus,
121
+ resolutionReason: resolvedStatus,
122
+ ...message.status === "completed" ? { value: message.value } : { error: message.error }
123
+ }, context.payloadSizeMaxBytes);
123
124
  context.registry.completeTask(operationId);
124
125
  context.deadlineTracker.remove(operationId);
125
126
  cleanupWorkflowIndex(operationId);
126
127
  recordWorkerCapacitySaturationMetric(context.metricsCollector, context.registry);
127
128
  (async () => {
128
- const inflightRecord = await readInflightRecord(options.engine.storage, operationId), resolvedAt = Date.now(), resolvedStatus = resolveTaskResultStatus(message);
129
- await transitionInflightToResolved(options.engine.storage, operationId, resolvedStatus, {
130
- ...inflightRecord === null ? {} : { record: inflightRecord },
131
- resolvedAt,
129
+ const inflightRecord = await readInflightRecord(options.engine.storage, operationId);
130
+ if (payloadError !== null) {
131
+ sendWorkerProtocolMessage(ws, {
132
+ type: "protocolError",
133
+ code: "invalid_message",
134
+ message: payloadError.message
135
+ });
136
+ await transitionTaskResultToResolvedWithRetry(context, options, {
137
+ operationId,
138
+ status: "failed",
139
+ resolutionReason: "failed",
140
+ inflightRecord,
141
+ error: payloadError.message,
142
+ skipPayloadSizeCheck: !0
143
+ });
144
+ return;
145
+ }
146
+ await transitionTaskResultToResolvedWithRetry(context, options, {
147
+ operationId,
148
+ status: resolvedStatus,
132
149
  resolutionReason: resolvedStatus,
150
+ inflightRecord,
133
151
  ...message.status === "completed" ? { value: message.value } : { error: message.error }
134
152
  });
135
- if (inflightRecord !== null)
136
- recordTaskExecutionLatencyMetric(context.metricsCollector, inflightRecord, resolvedAt);
137
153
  })().catch((error) => {
138
154
  console.error(`[weft] Failed to transition task "${operationId}" to resolved \u2014 inflight record may leak:`, error);
139
155
  });
@@ -207,7 +223,7 @@ export function handleWorkerWebSocketMessage(context, options, ws, rawMessage, c
207
223
  }
208
224
  switch (message.type) {
209
225
  case "register": {
210
- registerWorker(context, ws, message);
226
+ registerWorker(context, options, ws, message);
211
227
  break;
212
228
  }
213
229
  case "taskResult": {
@@ -11,12 +11,22 @@ import type { WebSocketData } from './json-rpc-websocket-runtime.ts';
11
11
  import { createServerWebSocketHandlers } from './runtime/authentication-bridge.ts';
12
12
  import type { ServerContext } from './runtime/context.ts';
13
13
  import { type EventBroadcastingHandle } from './runtime/event-broadcasting.ts';
14
+ /**
15
+ * @internal
16
+ *
17
+ * Warning emitted when a server starts with no authentication and no explicit
18
+ * `unauthenticatedAccess` policy. Exported only for internal tests (see
19
+ * `tests/auth-warning-filter.test.ts`) and not part of the public API surface.
20
+ */
21
+ export declare const NO_AUTHENTICATION_WARNING = "[weft] WARNING: server started with NO authentication; all non-public operations are publicly accessible. Configure serve({ auth }) to lock down, or set unauthenticatedAccess: \"reject\" in production to fail closed.";
22
+ export declare const MCP_ORIGIN_CONFIGURATION_WARNING = "[weft] WARNING: MCP HTTP transport is enabled without publicOrigin or trustedHosts. Cross-origin /mcp requests are rejected, and discovery routes that emit absolute URLs return 503. Configure serve({ publicOrigin: \"https://api.example.com\" }) or serve({ trustedHosts: [\"api.example.com\"] }) before exposing the server through a browser or reverse proxy.";
14
23
  /**
15
24
  * Clamp a user-supplied `workerReconnectGracePeriodMs` into `[0, 5_000]`.
16
- * Returns the default when undefined or non-finite.
25
+ * Returns the 2000ms default when undefined or non-finite.
17
26
  */
18
27
  export declare function clampWorkerReconnectGracePeriod(value: number | undefined): number;
19
28
  export declare function assertAuthenticationPosture(options: ServeOptions, environmentRequirement?: string | undefined): void;
29
+ export declare function warnIfMcpOriginConfigurationMissing(options: ServeOptions): void;
20
30
  /**
21
31
  * A mutable holder for the Bun server instance. The `fetch` handler needs to
22
32
  * call back into the server (for WebSocket upgrades) but the server isn't
@@ -1,4 +1,5 @@
1
1
  import { decode } from "../core/codec.js";
2
+ import { getEnginePayloadSizeMaxBytes } from "../core/engine/payload-size-policy.js";
2
3
  import { createMcpSessionManager } from "../mcp/session.js";
3
4
  import { createMetricsCollectorExporter, MetricsCollector } from "../observability/metrics.js";
4
5
  import { WorkerRegistry } from "../worker/registry.js";
@@ -11,6 +12,7 @@ import {
11
12
  } from "./authentication.js";
12
13
  import { DeadlineTracker } from "./deadline-tracker.js";
13
14
  import { createEngineEventFeedBackend } from "./engine-event-feed-backend.js";
15
+ import { createFleetEventFeed } from "./fleet-event-feed.js";
14
16
  import { closeJsonRpcSessionsForShutdown } from "./json-rpc-websocket-runtime.js";
15
17
  import { createLiveOperationRegistry, createLiveRestBindings } from "./rest-bindings.js";
16
18
  import {
@@ -22,11 +24,15 @@ import { resolveCorsPolicy, validateCorsOptions } from "./runtime/cors.js";
22
24
  import {
23
25
  registerWorkflowEventLifecycle
24
26
  } from "./runtime/event-broadcasting.js";
27
+ import { shutdownAllWorkers } from "./runtime/shutdown.js";
25
28
  import { reconcileOrphanedRecords, scanExpiredTasks } from "./runtime/task-reconciliation.js";
29
+ import { DEFAULT_MAX_STREAM_CONNECTIONS_PER_WORKFLOW } from "./runtime/websocket-stream.js";
26
30
  import { isInflightRecord, withRetry } from "./runtime/websocket-worker.js";
27
31
  import { TaskQueue } from "./task-queue.js";
28
32
  import { createWorkflowEventFeed } from "./workflow-event-feed.js";
29
- const RECONCILIATION_MULTIPLIER = 12, DEFAULT_WORKER_RECONNECT_GRACE_PERIOD_MS = 100, MAX_WORKER_RECONNECT_GRACE_PERIOD_MS = 5000, AUTHENTICATION_REQUIRED_ENVIRONMENT_VARIABLE = "WEFT_SERVER_AUTHENTICATION_REQUIRED", NO_AUTHENTICATION_WARNING = '[weft] WARNING: server started with NO authentication; all non-public operations are publicly accessible. Configure serve({ auth }) to lock down, or set unauthenticatedAccess: "reject" in production to fail closed.', NO_AUTHENTICATION_REJECT_ERROR = '[weft] Refusing to start server with no authentication. Configure serve({ auth }) or set unauthenticatedAccess: "allow" only for trusted local development.', NO_AUTHENTICATION_ENVIRONMENT_ERROR = "[weft] Refusing to start server with no authentication because WEFT_SERVER_AUTHENTICATION_REQUIRED requires authentication. Configure serve({ auth }) or unset WEFT_SERVER_AUTHENTICATION_REQUIRED only for trusted local development.", TRUTHY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["1", "true", "yes", "on"]), FALSY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["0", "false", "no", "off"]);
33
+ const RECONCILIATION_MULTIPLIER = 12, DEFAULT_WORKER_RECONNECT_GRACE_PERIOD_MS = 2000, MAX_WORKER_RECONNECT_GRACE_PERIOD_MS = 5000, AUTHENTICATION_REQUIRED_ENVIRONMENT_VARIABLE = "WEFT_SERVER_AUTHENTICATION_REQUIRED";
34
+ export const NO_AUTHENTICATION_WARNING = '[weft] WARNING: server started with NO authentication; all non-public operations are publicly accessible. Configure serve({ auth }) to lock down, or set unauthenticatedAccess: "reject" in production to fail closed.', MCP_ORIGIN_CONFIGURATION_WARNING = '[weft] WARNING: MCP HTTP transport is enabled without publicOrigin or trustedHosts. Cross-origin /mcp requests are rejected, and discovery routes that emit absolute URLs return 503. Configure serve({ publicOrigin: "https://api.example.com" }) or serve({ trustedHosts: ["api.example.com"] }) before exposing the server through a browser or reverse proxy.';
35
+ const NO_AUTHENTICATION_REJECT_ERROR = '[weft] Refusing to start server with no authentication. Configure serve({ auth }) or set unauthenticatedAccess: "allow" only for trusted local development.', NO_AUTHENTICATION_ENVIRONMENT_ERROR = "[weft] Refusing to start server with no authentication because WEFT_SERVER_AUTHENTICATION_REQUIRED requires authentication. Configure serve({ auth }) or unset WEFT_SERVER_AUTHENTICATION_REQUIRED only for trusted local development.", TRUTHY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["1", "true", "yes", "on"]), FALSY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["0", "false", "no", "off"]);
30
36
  export function clampWorkerReconnectGracePeriod(value) {
31
37
  if (value === void 0 || !Number.isFinite(value))
32
38
  return DEFAULT_WORKER_RECONNECT_GRACE_PERIOD_MS;
@@ -59,6 +65,11 @@ export function assertAuthenticationPosture(options, environmentRequirement = Bu
59
65
  return;
60
66
  console.warn(NO_AUTHENTICATION_WARNING);
61
67
  }
68
+ export function warnIfMcpOriginConfigurationMissing(options) {
69
+ if (options.publicOrigin !== void 0 || options.trustedHosts !== void 0)
70
+ return;
71
+ console.warn(MCP_ORIGIN_CONFIGURATION_WARNING);
72
+ }
62
73
  export function resolveNetworkConfig(options) {
63
74
  if (options.auth)
64
75
  validateAuthConfig(options.auth);
@@ -67,6 +78,7 @@ export function resolveNetworkConfig(options) {
67
78
  if (options.cors)
68
79
  validateCorsOptions(options.cors, options.auth !== void 0);
69
80
  assertAuthenticationPosture(options);
81
+ warnIfMcpOriginConfigurationMissing(options);
70
82
  const port = options.port ?? 7233, hostname = options.hostname ?? "0.0.0.0", development = options.development ?? !1, serverMetricsCollector = new MetricsCollector, prometheusExporter = options.prometheusExporter ?? createMetricsCollectorExporter(serverMetricsCollector), serverOptions = { ...options, prometheusExporter }, tlsOptions = buildTLSOptions(options.auth);
71
83
  return { port, hostname, development, tlsOptions, serverOptions, serverMetricsCollector };
72
84
  }
@@ -77,6 +89,9 @@ export function buildServerContext(options, serverMetricsCollector) {
77
89
  taskQueue,
78
90
  workerSockets: new Map,
79
91
  streamSockets: new Map,
92
+ watchSockets: new Map,
93
+ workflowStreamConnectionCounts: new Map,
94
+ maxStreamConnectionsPerWorkflow: options.maxStreamConnectionsPerWorkflow ?? DEFAULT_MAX_STREAM_CONNECTIONS_PER_WORKFLOW,
80
95
  workerAffinity: new Map,
81
96
  workflowOperations: new Map,
82
97
  operationToWorkflow: new Map,
@@ -93,12 +108,14 @@ export function buildServerContext(options, serverMetricsCollector) {
93
108
  metricsCollector: serverMetricsCollector,
94
109
  eventFeedBackend,
95
110
  workflowEventFeed: createWorkflowEventFeed(eventFeedBackend),
111
+ fleetEventFeed: createFleetEventFeed(options.engine.storage),
96
112
  activeJsonRpcSessions: new Set,
97
113
  mcpSessionManager: createMcpSessionManager(options.engine),
98
114
  authenticatorPromise: options.auth ? createAuthenticator(options.auth) : null,
99
115
  rateLimiter: options.rateLimit ? createRateLimiter(options.rateLimit) : null,
100
116
  visibilityPollMs: options.visibilityPollIntervalMs ?? 5000,
101
117
  workerReconnectGracePeriodMs: clampWorkerReconnectGracePeriod(options.workerReconnectGracePeriodMs),
118
+ payloadSizeMaxBytes: getEnginePayloadSizeMaxBytes(options.engine),
102
119
  pendingWorkerRequeues: new Map,
103
120
  scanRunning: !1,
104
121
  processingOperations: new Set,
@@ -146,6 +163,7 @@ export function registerStackDisposers(stack, context, options, broadcastingHand
146
163
  });
147
164
  stack.defer(() => context.mcpSessionManager[Symbol.asyncDispose]());
148
165
  stack.defer(registerWorkflowEventLifecycle(options.engine, context, broadcastingHandle));
166
+ stack.defer(() => shutdownAllWorkers(context, options.workerShutdownTimeoutMs === void 0 ? void 0 : { timeoutMs: options.workerShutdownTimeoutMs, stopWaitingWhenIdle: !0 }));
149
167
  const visibilityPollHandle = setInterval(() => {
150
168
  scanExpiredTasks(context, options, onOperationCleanup);
151
169
  }, context.visibilityPollMs), reconciliationIntervalMs = context.visibilityPollMs * RECONCILIATION_MULTIPLIER, reconciliationHandle = setInterval(() => {
@@ -179,7 +197,7 @@ export function restoreInflightTasks(context, options) {
179
197
  continue;
180
198
  }
181
199
  const remaining = record.deadline - now;
182
- context.registry.assignTask(record.workerId, record.operationId, remaining);
200
+ context.registry.assignTask(record.workerId, record.operationId, remaining, void 0, record.attemptToken);
183
201
  context.deadlineTracker.add({ operationId: record.operationId, deadline: record.deadline });
184
202
  const tracked = context.registry.getWorkerTasks(record.workerId).find((t) => t.operationId === record.operationId);
185
203
  if (tracked)
@@ -20,6 +20,8 @@ export type TaskState = 'queued' | 'inflight' | 'resolved';
20
20
  export type TaskRequeueReason = 'visibility-timeout' | 'worker-disconnect';
21
21
  /** Final reason captured when a task reaches the resolved state. */
22
22
  export type TaskResolutionReason = 'completed' | 'failed' | 'cancelled' | 'max-attempts-exceeded';
23
+ /** Why a task-result transition was moved to the operator dead-letter guard. */
24
+ export type TaskDeadLetterReason = 'result-resolution-storage-exhausted';
23
25
  /** Lifecycle evidence persisted with task records for diagnostics. */
24
26
  export interface TaskLifecycleFields {
25
27
  /** First time this operation entered a task queue. */
@@ -67,6 +69,14 @@ export interface InflightRecord extends TaskLifecycleFields {
67
69
  retryPolicy?: RetryPolicy | undefined;
68
70
  /** Workflow that dispatched this activity. Present when the dispatch included a workflowId. */
69
71
  workflowId?: string | undefined;
72
+ /**
73
+ * Unique, unguessable token identifying this dispatch attempt. Rotated on every
74
+ * (re-)dispatch because each dispatch writes a fresh InflightRecord. The
75
+ * long-poll completion handler rejects a result whose echoed token does not
76
+ * match this value. Optional for back-compatible decoding of records written
77
+ * before this field existed; a missing token disables the check for that record.
78
+ */
79
+ attemptToken?: string | undefined;
70
80
  }
71
81
  /** Persisted record for a task in the resolved state. */
72
82
  export interface ResolvedRecord {
@@ -95,6 +105,24 @@ export interface ResolvedRecord {
95
105
  queueLatencyMs?: number | undefined;
96
106
  executionLatencyMs?: number | undefined;
97
107
  }
108
+ /** Durable operator guard for a task result whose resolved write exhausted retries. */
109
+ export interface DeadLetteredTaskRecord {
110
+ operationId: string;
111
+ reason: TaskDeadLetterReason;
112
+ deadLetteredAt: number;
113
+ errorMessage: string;
114
+ retryAttempts: number;
115
+ status: 'completed' | 'failed';
116
+ activityName?: string | undefined;
117
+ queue?: string | undefined;
118
+ workerId?: string | undefined;
119
+ attempt?: number | undefined;
120
+ visibilityTimeout?: number | undefined;
121
+ workflowId?: string | undefined;
122
+ retryCount?: number | undefined;
123
+ requeueCount?: number | undefined;
124
+ lastRequeueReason?: TaskRequeueReason | undefined;
125
+ }
98
126
  export interface TransitionInflightToResolvedOptions {
99
127
  resolutionReason?: TaskResolutionReason;
100
128
  resolvedAt?: number;
@@ -123,10 +151,20 @@ export declare function isQueuedRecord(value: unknown): value is QueuedRecord;
123
151
  export declare function isInflightRecord(value: unknown): value is InflightRecord;
124
152
  /** Type guard for decoded storage records in the resolved state. */
125
153
  export declare function isResolvedRecord(value: unknown): value is ResolvedRecord;
154
+ /** Type guard for decoded task-result dead-letter records. */
155
+ export declare function isDeadLetteredTaskRecord(value: unknown): value is DeadLetteredTaskRecord;
126
156
  /** Decode the queued record for an operation, returning null when absent or malformed. */
127
157
  export declare function readQueuedRecord(storage: Storage, operationId: string): Promise<QueuedRecord | null>;
128
158
  /** Decode the inflight record for an operation, returning null when absent or malformed. */
129
159
  export declare function readInflightRecord(storage: Storage, operationId: string): Promise<InflightRecord | null>;
160
+ /** Decode the task-result dead-letter record for an operation. */
161
+ export declare function readDeadLetteredTaskRecord(storage: Storage, operationId: string): Promise<DeadLetteredTaskRecord | null>;
162
+ /** True when reconciliation should not re-dispatch the operation. */
163
+ export declare function isTaskDeadLettered(storage: Storage, operationId: string): Promise<boolean>;
164
+ /** Persist a task-result dead-letter guard. */
165
+ export declare function writeDeadLetteredTaskRecord(storage: Storage, record: DeadLetteredTaskRecord): Promise<void>;
166
+ /** Clear a task-result dead-letter guard so reconciliation may handle the inflight record again. */
167
+ export declare function clearDeadLetteredTaskRecord(storage: Storage, operationId: string): Promise<void>;
130
168
  export declare function calculateQueueLatencyMs(record: TaskLifecycleFields): number | undefined;
131
169
  export declare function calculateExecutionLatencyMs(record: TaskLifecycleFields, completedAt: number): number | undefined;
132
170
  export declare function calculateHeartbeatAgeMs(record: TaskLifecycleFields & {
@@ -49,6 +49,12 @@ export function isResolvedRecord(value) {
49
49
  const record = value;
50
50
  return typeof record.operationId === "string" && (record.status === "completed" || record.status === "failed") && typeof record.resolvedAt === "number";
51
51
  }
52
+ export function isDeadLetteredTaskRecord(value) {
53
+ if (value === null || typeof value !== "object")
54
+ return !1;
55
+ const record = value;
56
+ return typeof record.operationId === "string" && record.reason === "result-resolution-storage-exhausted" && typeof record.deadLetteredAt === "number" && typeof record.errorMessage === "string" && typeof record.retryAttempts === "number" && (record.status === "completed" || record.status === "failed");
57
+ }
52
58
  export async function readQueuedRecord(storage, operationId) {
53
59
  const value = await storage.get(KEYS.operationQueued(operationId));
54
60
  if (value === null)
@@ -63,6 +69,28 @@ export async function readInflightRecord(storage, operationId) {
63
69
  const decoded = decode(value);
64
70
  return isInflightRecord(decoded) ? decoded : null;
65
71
  }
72
+ export async function readDeadLetteredTaskRecord(storage, operationId) {
73
+ const value = await storage.get(KEYS.operationDeadLetter(operationId));
74
+ if (value === null)
75
+ return null;
76
+ const decoded = decode(value);
77
+ return isDeadLetteredTaskRecord(decoded) ? decoded : null;
78
+ }
79
+ export async function isTaskDeadLettered(storage, operationId) {
80
+ return await readDeadLetteredTaskRecord(storage, operationId) !== null;
81
+ }
82
+ export async function writeDeadLetteredTaskRecord(storage, record) {
83
+ await storage.batch([
84
+ {
85
+ type: "put",
86
+ key: KEYS.operationDeadLetter(record.operationId),
87
+ value: encode(record)
88
+ }
89
+ ]);
90
+ }
91
+ export async function clearDeadLetteredTaskRecord(storage, operationId) {
92
+ await storage.delete(KEYS.operationDeadLetter(operationId));
93
+ }
66
94
  function normalizeQueuedRecordLifecycle(record, previous) {
67
95
  const normalized = {
68
96
  ...record,