@lostgradient/weft 0.3.0 → 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 (508) hide show
  1. package/README.md +79 -24
  2. package/dist/cli/conformance.js +7 -1
  3. package/dist/cli/generated/operation-client.generated.d.ts +28 -13
  4. package/dist/cli/generated/operation-client.generated.js +1 -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 +79 -78
  13. package/dist/client/handle-delegation.d.ts +3 -2
  14. package/dist/client/handle-delegation.js +3 -1
  15. package/dist/client/http-client-requests.d.ts +2 -1
  16. package/dist/client/http-client-requests.js +7 -0
  17. package/dist/client/http-client.d.ts +9 -6
  18. package/dist/client/http-client.js +10 -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 +46 -5
  23. package/dist/client/local.d.ts +4 -1
  24. package/dist/client/local.js +12 -4
  25. package/dist/client/start-body.d.ts +4 -3
  26. package/dist/core/byte-arrays.d.ts +5 -0
  27. package/dist/core/byte-arrays.js +5 -0
  28. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  29. package/dist/core/checkpoint/lifecycle.js +9 -4
  30. package/dist/core/checkpoint/serialization.js +12 -5
  31. package/dist/core/codec/extension-codec.d.ts +16 -0
  32. package/dist/core/codec/extension-codec.js +100 -6
  33. package/dist/core/context/activity-retry-state.d.ts +38 -0
  34. package/dist/core/context/activity-retry-state.js +89 -0
  35. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  36. package/dist/core/context/activity-schedule-to-close.js +69 -0
  37. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  38. package/dist/core/context/child-workflow-pipe.js +15 -2
  39. package/dist/core/context/context-presence.d.ts +19 -0
  40. package/dist/core/context/context-presence.js +13 -0
  41. package/dist/core/context/durable-operations.d.ts +25 -0
  42. package/dist/core/context/durable-operations.js +64 -0
  43. package/dist/core/context/index.d.ts +9 -5
  44. package/dist/core/context/index.js +17 -12
  45. package/dist/core/context/internals.d.ts +20 -0
  46. package/dist/core/context/internals.js +3 -1
  47. package/dist/core/context/operation-request.d.ts +35 -0
  48. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  49. package/dist/core/context/run-operation.d.ts +6 -1
  50. package/dist/core/context/run-operation.js +41 -87
  51. package/dist/core/context/session-state.js +7 -8
  52. package/dist/core/context/speculative-child.js +2 -0
  53. package/dist/core/context/types.d.ts +15 -0
  54. package/dist/core/context/version-patching.d.ts +8 -0
  55. package/dist/core/context/version-patching.js +40 -0
  56. package/dist/core/context/workflow-logger.d.ts +98 -0
  57. package/dist/core/context/workflow-logger.js +68 -0
  58. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  59. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  60. package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
  61. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  62. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  63. package/dist/core/engine/activity-reconciliation.js +12 -1
  64. package/dist/core/engine/activity-resolution.d.ts +23 -0
  65. package/dist/core/engine/activity-resolution.js +37 -0
  66. package/dist/core/engine/aggregate.js +66 -30
  67. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  68. package/dist/core/engine/async-activity-completion.js +53 -12
  69. package/dist/core/engine/attributes-tags.js +9 -4
  70. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  71. package/dist/core/engine/bulk-operations-purge.js +38 -3
  72. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  73. package/dist/core/engine/bulk-operations-shared.js +8 -2
  74. package/dist/core/engine/bulk-operations.d.ts +4 -1
  75. package/dist/core/engine/bulk-operations.js +235 -24
  76. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  77. package/dist/core/engine/callback-creators-bundles.js +30 -2
  78. package/dist/core/engine/callback-creators-core.js +6 -4
  79. package/dist/core/engine/callback-creators-router.js +10 -0
  80. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  81. package/dist/core/engine/callback-creators-schedule.js +12 -8
  82. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  83. package/dist/core/engine/candidate-read-batching.js +1 -0
  84. package/dist/core/engine/checkpoint-io.js +61 -25
  85. package/dist/core/engine/checkpoint-reads.js +3 -2
  86. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  87. package/dist/core/engine/checkpoint-replay.js +242 -0
  88. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  89. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  90. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  91. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  92. package/dist/core/engine/child-workflow.js +27 -4
  93. package/dist/core/engine/condition-waiters.d.ts +14 -0
  94. package/dist/core/engine/condition-waiters.js +5 -0
  95. package/dist/core/engine/construction.d.ts +3 -0
  96. package/dist/core/engine/construction.js +21 -8
  97. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  98. package/dist/core/engine/coordination-branch-executors.js +107 -0
  99. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  100. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  101. package/dist/core/engine/disposal.js +13 -0
  102. package/dist/core/engine/engine-create-types.d.ts +14 -4
  103. package/dist/core/engine/engine-internal-types.d.ts +26 -3
  104. package/dist/core/engine/errors.d.ts +47 -0
  105. package/dist/core/engine/errors.js +20 -0
  106. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  107. package/dist/core/engine/event-log-compaction.js +20 -2
  108. package/dist/core/engine/fenced-write.d.ts +65 -0
  109. package/dist/core/engine/fenced-write.js +71 -0
  110. package/dist/core/engine/finalizer-state.d.ts +28 -0
  111. package/dist/core/engine/finalizer-state.js +16 -0
  112. package/dist/core/engine/handles.d.ts +8 -0
  113. package/dist/core/engine/index.d.ts +34 -16
  114. package/dist/core/engine/index.js +133 -8
  115. package/dist/core/engine/inline-parking.js +3 -2
  116. package/dist/core/engine/internals.d.ts +107 -3
  117. package/dist/core/engine/lease-codec.d.ts +35 -0
  118. package/dist/core/engine/lease-codec.js +32 -0
  119. package/dist/core/engine/lease-deposition.d.ts +66 -0
  120. package/dist/core/engine/lease-deposition.js +10 -0
  121. package/dist/core/engine/lease-errors.d.ts +99 -0
  122. package/dist/core/engine/lease-errors.js +30 -0
  123. package/dist/core/engine/lease-manager.d.ts +114 -0
  124. package/dist/core/engine/lease-manager.js +135 -0
  125. package/dist/core/engine/lifecycle/persist.js +10 -32
  126. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  127. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  128. package/dist/core/engine/lifecycle/resume.js +16 -9
  129. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  130. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  131. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  132. package/dist/core/engine/lifecycle/start-commit.d.ts +9 -0
  133. package/dist/core/engine/lifecycle/start-commit.js +50 -8
  134. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  135. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  136. package/dist/core/engine/lifecycle/start-or-signal.d.ts +3 -2
  137. package/dist/core/engine/lifecycle/start-or-signal.js +11 -81
  138. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  139. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  140. package/dist/core/engine/lifecycle/start.d.ts +4 -4
  141. package/dist/core/engine/lifecycle/start.js +17 -9
  142. package/dist/core/engine/lifecycle/transition.js +17 -5
  143. package/dist/core/engine/lifecycle.d.ts +1 -1
  144. package/dist/core/engine/list-candidate-resolution.js +2 -2
  145. package/dist/core/engine/listing.js +9 -5
  146. package/dist/core/engine/operations-activity.d.ts +4 -11
  147. package/dist/core/engine/operations-activity.js +22 -49
  148. package/dist/core/engine/operations-coordination.d.ts +10 -0
  149. package/dist/core/engine/operations-coordination.js +43 -8
  150. package/dist/core/engine/operations-router.d.ts +6 -0
  151. package/dist/core/engine/operations-router.js +2 -0
  152. package/dist/core/engine/operations-speculate.js +6 -2
  153. package/dist/core/engine/operations-stream.js +12 -2
  154. package/dist/core/engine/operations-time.d.ts +4 -2
  155. package/dist/core/engine/operations-time.js +14 -2
  156. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  157. package/dist/core/engine/operations-wait-condition.js +62 -0
  158. package/dist/core/engine/ownership-options.d.ts +23 -0
  159. package/dist/core/engine/ownership-options.js +26 -0
  160. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  161. package/dist/core/engine/payload-size-policy.js +4 -0
  162. package/dist/core/engine/pending-updates.d.ts +17 -0
  163. package/dist/core/engine/pending-updates.js +33 -11
  164. package/dist/core/engine/queries.js +1 -1
  165. package/dist/core/engine/registration.d.ts +1 -0
  166. package/dist/core/engine/registration.js +18 -3
  167. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  168. package/dist/core/engine/schedule-jitter.js +10 -0
  169. package/dist/core/engine/schedule-run.d.ts +17 -0
  170. package/dist/core/engine/schedule-run.js +38 -0
  171. package/dist/core/engine/schedule-timer.js +81 -17
  172. package/dist/core/engine/schedules.d.ts +7 -4
  173. package/dist/core/engine/schedules.js +37 -16
  174. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  175. package/dist/core/engine/search-attribute-records.js +17 -0
  176. package/dist/core/engine/signals.d.ts +18 -2
  177. package/dist/core/engine/signals.js +42 -21
  178. package/dist/core/engine/state-utilities.d.ts +49 -2
  179. package/dist/core/engine/state-utilities.js +114 -3
  180. package/dist/core/engine/storage-io.d.ts +16 -2
  181. package/dist/core/engine/storage-io.js +26 -5
  182. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  183. package/dist/core/engine/stream-chunk-loading.js +24 -1
  184. package/dist/core/engine/sub-operation.js +22 -3
  185. package/dist/core/engine/termination/cleanup.d.ts +3 -1
  186. package/dist/core/engine/termination/cleanup.js +25 -1
  187. package/dist/core/engine/termination/complete.js +44 -6
  188. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  189. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  190. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  191. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  192. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  193. package/dist/core/engine/termination/finalizer.js +159 -0
  194. package/dist/core/engine/termination/suspend.d.ts +3 -1
  195. package/dist/core/engine/termination.d.ts +1 -0
  196. package/dist/core/engine/termination.js +4 -0
  197. package/dist/core/engine/updates.js +5 -25
  198. package/dist/core/engine/validation/schedule.d.ts +2 -1
  199. package/dist/core/engine/validation/schedule.js +51 -2
  200. package/dist/core/engine/validation.js +32 -5
  201. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  202. package/dist/core/engine/waiting-update-response.js +22 -0
  203. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  204. package/dist/core/engine/workflow-concurrency.js +136 -0
  205. package/dist/core/engine/workflow-feed.d.ts +4 -5
  206. package/dist/core/engine/workflow-feed.js +4 -1
  207. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  208. package/dist/core/engine/workflow-indexes.js +10 -0
  209. package/dist/core/engine/workflow-state-stream.js +33 -13
  210. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  211. package/dist/core/engine-helpers.js +1 -0
  212. package/dist/core/events/activity-events.d.ts +43 -12
  213. package/dist/core/events/activity-events.js +28 -0
  214. package/dist/core/events/attribute-events.d.ts +2 -3
  215. package/dist/core/events/event-map.d.ts +18 -12
  216. package/dist/core/events/index.d.ts +1 -0
  217. package/dist/core/events/index.js +1 -0
  218. package/dist/core/events/schedule-events.d.ts +71 -0
  219. package/dist/core/events/schedule-events.js +29 -0
  220. package/dist/core/events/signal-events.d.ts +4 -6
  221. package/dist/core/events/system-events.d.ts +29 -19
  222. package/dist/core/events/system-events.js +26 -0
  223. package/dist/core/events/update-events.d.ts +6 -8
  224. package/dist/core/events/workflow-events.d.ts +88 -23
  225. package/dist/core/events/workflow-events.js +26 -0
  226. package/dist/core/failure-categories.js +5 -17
  227. package/dist/core/fault-code.d.ts +9 -3
  228. package/dist/core/fault-code.js +1 -0
  229. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  230. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  231. package/dist/core/inline-execution-strategy.d.ts +31 -36
  232. package/dist/core/inline-execution-strategy.js +16 -27
  233. package/dist/core/list-filter-validation.d.ts +1 -1
  234. package/dist/core/payload-size.d.ts +1 -1
  235. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  236. package/dist/core/review/events.d.ts +6 -8
  237. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  238. package/dist/core/scheduler/scheduler-class.js +38 -11
  239. package/dist/core/scheduler/timer-batch.js +9 -1
  240. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  241. package/dist/core/scheduler/timer-sources.js +11 -5
  242. package/dist/core/session-state.d.ts +0 -1
  243. package/dist/core/session-state.js +2 -2
  244. package/dist/core/start-workflow-validation.d.ts +34 -0
  245. package/dist/core/start-workflow-validation.js +19 -0
  246. package/dist/core/types/activity-verification.d.ts +67 -0
  247. package/dist/core/types/activity-verification.js +0 -0
  248. package/dist/core/types/activity.d.ts +80 -61
  249. package/dist/core/types/bulk.d.ts +50 -9
  250. package/dist/core/types/checkpoint.d.ts +44 -8
  251. package/dist/core/types/list-options.d.ts +146 -0
  252. package/dist/core/types/list-options.js +0 -0
  253. package/dist/core/types/options.d.ts +121 -165
  254. package/dist/core/types/schedules.d.ts +39 -3
  255. package/dist/core/types/services-resolution.d.ts +2 -2
  256. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  257. package/dist/core/types/workflow-builder-runtime.js +11 -2
  258. package/dist/core/types/workflow-builder.d.ts +42 -11
  259. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  260. package/dist/core/types/workflow-concurrency.js +0 -0
  261. package/dist/core/types/workflow-context.d.ts +157 -14
  262. package/dist/core/types/workflow-definition.d.ts +53 -10
  263. package/dist/core/types/workflow-function.d.ts +84 -9
  264. package/dist/core/types/workflow-log.d.ts +98 -0
  265. package/dist/core/types/workflow-log.js +0 -0
  266. package/dist/core/types/workflow-registries.d.ts +14 -3
  267. package/dist/core/types/workflow-registry.d.ts +3 -0
  268. package/dist/core/types.d.ts +4 -0
  269. package/dist/core/types.js +4 -0
  270. package/dist/core/versioning.d.ts +9 -39
  271. package/dist/core/versioning.js +2 -12
  272. package/dist/core/weft-error.d.ts +44 -1
  273. package/dist/core/weft-error.js +16 -0
  274. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  275. package/dist/core/worker-execution-strategy.js +40 -36
  276. package/dist/core/worker-inbound-message.d.ts +38 -0
  277. package/dist/core/worker-inbound-message.js +37 -0
  278. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  279. package/dist/core/worker-log-abuse-counter.js +107 -0
  280. package/dist/core/worker-message-helpers.d.ts +47 -0
  281. package/dist/core/worker-message-helpers.js +26 -0
  282. package/dist/core/worker-protocol-guard.js +1 -1
  283. package/dist/core/worker-protocol-log.d.ts +56 -0
  284. package/dist/core/worker-protocol-log.js +18 -0
  285. package/dist/core/worker-protocol.d.ts +23 -0
  286. package/dist/core/worker-protocol.js +12 -2
  287. package/dist/core/workflow-version-tuple.d.ts +3 -9
  288. package/dist/core/workflow-version-tuple.js +2 -3
  289. package/dist/diagnostics/format.js +1 -6
  290. package/dist/diagnostics/types.d.ts +4 -5
  291. package/dist/diagnostics/validate.d.ts +0 -1
  292. package/dist/diagnostics/version-check.d.ts +1 -1
  293. package/dist/diagnostics/version-check.js +4 -9
  294. package/dist/index.d.ts +12 -10
  295. package/dist/index.js +29 -3
  296. package/dist/json-schema.js +3 -3
  297. package/dist/mcp/cli.js +27 -27
  298. package/dist/mcp/dispatcher.js +1 -1
  299. package/dist/mcp/http.js +16 -6
  300. package/dist/mcp/protocol.d.ts +2 -0
  301. package/dist/mcp/protocol.js +1 -1
  302. package/dist/mcp/session.d.ts +16 -0
  303. package/dist/mcp/session.js +59 -6
  304. package/dist/mcp/tools.js +73 -6
  305. package/dist/observability/index.js +2 -2
  306. package/dist/server/asyncapi-channels.js +5 -2
  307. package/dist/server/attribute-filters.d.ts +8 -3
  308. package/dist/server/attribute-filters.js +6 -1
  309. package/dist/server/authentication/api-key.d.ts +2 -1
  310. package/dist/server/authentication/api-key.js +5 -2
  311. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  312. package/dist/server/authentication/constant-time-api-key.js +24 -0
  313. package/dist/server/authentication/index.d.ts +1 -1
  314. package/dist/server/authentication/index.js +7 -4
  315. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  316. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  317. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  318. package/dist/server/fault-to-http.js +8 -1
  319. package/dist/server/fault-to-json-rpc.js +1 -0
  320. package/dist/server/fleet-event-feed.d.ts +31 -0
  321. package/dist/server/fleet-event-feed.js +157 -0
  322. package/dist/server/handler/index.js +1 -1
  323. package/dist/server/handler/response-helpers.js +2 -1
  324. package/dist/server/handler/route-dispatch.d.ts +6 -3
  325. package/dist/server/handler/route-dispatch.js +2 -2
  326. package/dist/server/handler.js +23 -23
  327. package/dist/server/index.d.ts +32 -2
  328. package/dist/server/index.js +26 -26
  329. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  330. package/dist/server/json-rpc-transport-helpers.js +2 -1
  331. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  332. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  333. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  334. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  335. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  336. package/dist/server/json-rpc-websocket-types.js +0 -0
  337. package/dist/server/json-rpc-websocket-validation.js +20 -4
  338. package/dist/server/json-rpc-websocket.d.ts +2 -43
  339. package/dist/server/json-rpc-websocket.js +57 -74
  340. package/dist/server/openapi.d.ts +2 -1
  341. package/dist/server/openapi.js +1 -3
  342. package/dist/server/openrpc-document-schema.d.ts +78 -0
  343. package/dist/server/openrpc-document-schema.js +27 -1
  344. package/dist/server/openrpc-errors.d.ts +3 -0
  345. package/dist/server/openrpc-errors.js +2 -1
  346. package/dist/server/openrpc.js +32 -0
  347. package/dist/server/operation-catalog/index.d.ts +1 -1
  348. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  349. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  350. package/dist/server/operation-catalog/pipeline.js +8 -1
  351. package/dist/server/operation-catalog/registry.js +13 -0
  352. package/dist/server/operation-catalog/types.d.ts +20 -9
  353. package/dist/server/operation-fault.d.ts +10 -0
  354. package/dist/server/operation-fault.js +2 -0
  355. package/dist/server/operation-registry.d.ts +12 -11
  356. package/dist/server/operation-registry.js +12 -3
  357. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  358. package/dist/server/operations/async-activity.d.ts +2 -2
  359. package/dist/server/operations/async-activity.js +12 -7
  360. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  361. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  362. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  363. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  364. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  365. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  366. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  367. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  368. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  369. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  370. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  371. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  372. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  373. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  374. package/dist/server/operations/create-schedule.d.ts +3 -1
  375. package/dist/server/operations/create-schedule.js +29 -11
  376. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  377. package/dist/server/operations/fleet-events-subscription.js +99 -0
  378. package/dist/server/operations/fork-workflow.d.ts +1 -1
  379. package/dist/server/operations/fork-workflow.js +3 -2
  380. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  381. package/dist/server/operations/get-registry.d.ts +1 -1
  382. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  383. package/dist/server/operations/get-review.d.ts +1 -1
  384. package/dist/server/operations/get-schedule.d.ts +1 -1
  385. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  386. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  387. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  388. package/dist/server/operations/get-task-diagnostics.js +101 -7
  389. package/dist/server/operations/get-update-result.d.ts +1 -1
  390. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  391. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  392. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  393. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  394. package/dist/server/operations/get-workflow.d.ts +1 -1
  395. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  396. package/dist/server/operations/list-reviews.d.ts +1 -1
  397. package/dist/server/operations/list-schedules.d.ts +1 -1
  398. package/dist/server/operations/list-task-queues.d.ts +2 -2
  399. package/dist/server/operations/list-workers.d.ts +2 -2
  400. package/dist/server/operations/list-workflows.d.ts +1 -1
  401. package/dist/server/operations/operation-helpers.d.ts +16 -1
  402. package/dist/server/operations/operation-helpers.js +15 -3
  403. package/dist/server/operations/pause-schedule.d.ts +1 -1
  404. package/dist/server/operations/purge-workflows.d.ts +5 -5
  405. package/dist/server/operations/purge-workflows.js +2 -2
  406. package/dist/server/operations/query-workflow.d.ts +1 -1
  407. package/dist/server/operations/query-workflow.js +3 -2
  408. package/dist/server/operations/recover-all.d.ts +1 -1
  409. package/dist/server/operations/replay-workflow.d.ts +1 -1
  410. package/dist/server/operations/resume-schedule.d.ts +1 -1
  411. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  412. package/dist/server/operations/set-workflow-attributes.js +6 -3
  413. package/dist/server/operations/signal-workflow.js +8 -3
  414. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  415. package/dist/server/operations/start-or-signal-workflow.d.ts +6 -1
  416. package/dist/server/operations/start-or-signal-workflow.js +14 -24
  417. package/dist/server/operations/start-workflow-options.d.ts +6 -0
  418. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  419. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  420. package/dist/server/operations/start-workflow.d.ts +1 -1
  421. package/dist/server/operations/start-workflow.js +8 -23
  422. package/dist/server/operations/storage.d.ts +6 -6
  423. package/dist/server/operations/storage.js +24 -14
  424. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  425. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  426. package/dist/server/operations/submit-review-decision.js +6 -3
  427. package/dist/server/operations/update-schedule.d.ts +1 -1
  428. package/dist/server/operations/update-schedule.js +7 -4
  429. package/dist/server/operations/update-workflow.d.ts +1 -1
  430. package/dist/server/operations/update-workflow.js +7 -3
  431. package/dist/server/operations/worker-drain.d.ts +8 -8
  432. package/dist/server/operations/worker-drain.js +11 -8
  433. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  434. package/dist/server/operations/workflow-events-subscription.js +43 -8
  435. package/dist/server/rest-binding.d.ts +3 -1
  436. package/dist/server/rest-bindings.js +12 -0
  437. package/dist/server/rest-body.d.ts +10 -0
  438. package/dist/server/rest-body.js +80 -0
  439. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  440. package/dist/server/runtime/authentication-bridge.js +33 -6
  441. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  442. package/dist/server/runtime/client-visible-events.js +65 -0
  443. package/dist/server/runtime/context.d.ts +7 -0
  444. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  445. package/dist/server/runtime/event-broadcasting.js +72 -38
  446. package/dist/server/runtime/retry.d.ts +1 -0
  447. package/dist/server/runtime/retry.js +14 -0
  448. package/dist/server/runtime/shutdown.d.ts +7 -6
  449. package/dist/server/runtime/shutdown.js +6 -1
  450. package/dist/server/runtime/task-polling.js +61 -20
  451. package/dist/server/runtime/task-reconciliation.js +9 -1
  452. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  453. package/dist/server/runtime/task-result-resolution.js +81 -0
  454. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  455. package/dist/server/runtime/websocket-stream.js +173 -7
  456. package/dist/server/runtime/websocket-upgrade.js +22 -3
  457. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  458. package/dist/server/runtime/websocket-worker.js +38 -30
  459. package/dist/server/serve-internals.d.ts +3 -1
  460. package/dist/server/serve-internals.js +18 -2
  461. package/dist/server/task-state.d.ts +30 -0
  462. package/dist/server/task-state.js +28 -0
  463. package/dist/server/workflow-event-feed.d.ts +36 -115
  464. package/dist/server/workflow-event-feed.js +92 -27
  465. package/dist/service-worker/index.js +30 -30
  466. package/dist/storage/auto.js +1 -1
  467. package/dist/storage/bun-sql.js +24 -0
  468. package/dist/storage/compressed-storage.js +1 -1
  469. package/dist/storage/default-scope.d.ts +7 -4
  470. package/dist/storage/http.js +2 -2
  471. package/dist/storage/index.d.ts +76 -4
  472. package/dist/storage/indexeddb.js +1 -1
  473. package/dist/storage/interface.d.ts +163 -0
  474. package/dist/storage/interface.js +1 -1
  475. package/dist/storage/key-prefixes.d.ts +1 -1
  476. package/dist/storage/key-prefixes.js +10 -0
  477. package/dist/storage/lmdb.d.ts +4 -3
  478. package/dist/storage/lmdb.js +1 -1
  479. package/dist/storage/memory.js +1 -1
  480. package/dist/storage/neon-batch.d.ts +30 -0
  481. package/dist/storage/neon-batch.js +30 -0
  482. package/dist/storage/neon-value-mapping.d.ts +30 -3
  483. package/dist/storage/neon-value-mapping.js +12 -0
  484. package/dist/storage/neon.d.ts +16 -0
  485. package/dist/storage/neon.js +9 -4
  486. package/dist/storage/node-sqlite.js +23 -0
  487. package/dist/storage/postgres-key-value-queries.d.ts +69 -44
  488. package/dist/storage/postgres-key-value-queries.js +62 -24
  489. package/dist/storage/resolve.js +1 -1
  490. package/dist/storage/scoped-storage.js +1 -1
  491. package/dist/storage/testing.d.ts +168 -0
  492. package/dist/storage/testing.js +2 -0
  493. package/dist/storage/turso.d.ts +8 -0
  494. package/dist/storage/turso.js +2 -2
  495. package/dist/storage/typed-storage.js +1 -1
  496. package/dist/storage/web-extension.js +1 -1
  497. package/dist/testing/index.js +28 -28
  498. package/dist/version.d.ts +1 -1
  499. package/dist/version.js +1 -1
  500. package/dist/worker/protocol.js +1 -1
  501. package/dist/workers/worker-replay-state.d.ts +32 -0
  502. package/dist/workers/worker-replay-state.js +35 -0
  503. package/dist/workers/worker-state-namespace.d.ts +21 -0
  504. package/dist/workers/worker-state-namespace.js +13 -0
  505. package/dist/workers/workflow-runner.d.ts +19 -15
  506. package/dist/workers/workflow-runner.js +72 -60
  507. package/dist/workers/workflow-worker-entry.js +5 -2
  508. package/package.json +5 -1
@@ -0,0 +1,159 @@
1
+ import { KEYS } from "../../../storage/interface.js";
2
+ import { decode } from "../../codec.js";
3
+ import { WorkflowTeardownEvent } from "../../events.js";
4
+ import { isTeardownClaim, parseTeardownTimerId } from "../state-utilities.js";
5
+ import { runFinalizerActivity } from "./finalizer-activity.js";
6
+ import {
7
+ claimTeardownMarker,
8
+ clearTeardownMarker,
9
+ deadLetterTeardown,
10
+ encodeOwedClaim,
11
+ MAX_TEARDOWN_ATTEMPTS,
12
+ rearmTeardownTimer,
13
+ runningClaimIsStale,
14
+ settleOnRunningClaim,
15
+ TEARDOWN_SELF_HEAL_DELAY_MS,
16
+ teardownBackoffMs,
17
+ teardownStaleThresholdMs,
18
+ teardownTimerOperations
19
+ } from "./finalizer-claim.js";
20
+ export { teardownStaleThresholdMs } from "./finalizer-claim.js";
21
+ const TERMINAL_STATUSES_OWED_TEARDOWN = new Set([
22
+ "cancelled",
23
+ "timed-out"
24
+ ]);
25
+ function errorMessage(error) {
26
+ return error instanceof Error ? error.message : String(error);
27
+ }
28
+ async function rearmOnLostSettle(internals, workflowId, token) {
29
+ await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
30
+ }
31
+ async function clearOrRearm(internals, workflowId, token, markerBytes) {
32
+ return await clearTeardownMarker(internals, workflowId, markerBytes) ? { kind: "cleared" } : { kind: "rearm", token };
33
+ }
34
+ async function readDriveableClaim(internals, workflowId, token, markerBytes) {
35
+ let decoded;
36
+ try {
37
+ decoded = decode(markerBytes);
38
+ } catch {
39
+ return clearOrRearm(internals, workflowId, token, markerBytes);
40
+ }
41
+ if (!isTeardownClaim(decoded))
42
+ return clearOrRearm(internals, workflowId, token, markerBytes);
43
+ return { kind: "claim", claim: decoded };
44
+ }
45
+ async function resolveTeardownDrive(internals, workflowId, token, callbacks) {
46
+ const markerBytes = await internals.storage.get(KEYS.teardownOwed(workflowId));
47
+ if (markerBytes === null)
48
+ return { kind: "cleared" };
49
+ const resolution = await readDriveableClaim(internals, workflowId, token, markerBytes);
50
+ if (resolution.kind !== "claim")
51
+ return resolution;
52
+ const claim = resolution.claim;
53
+ if (claim.token !== token)
54
+ return { kind: "cleared" };
55
+ const state = await callbacks.loadWorkflowState(workflowId);
56
+ if (state === null || !TERMINAL_STATUSES_OWED_TEARDOWN.has(state.status))
57
+ return clearOrRearm(internals, workflowId, token, markerBytes);
58
+ const registeredFinalizer = internals.registrations.get(state.type)?.finalizer;
59
+ if (registeredFinalizer === void 0)
60
+ return { kind: "rearm", token };
61
+ const finalizer = registeredFinalizer;
62
+ if (!runningClaimIsStale(internals, claim, finalizer))
63
+ return { kind: "rearm", token };
64
+ const finalizerStateBytes = await internals.storage.get(KEYS.finalizerState(workflowId));
65
+ if (finalizerStateBytes === null) {
66
+ await deadLetterMissingState(internals, workflowId, state.type, claim.attempts, markerBytes, callbacks);
67
+ return { kind: "cleared" };
68
+ }
69
+ return {
70
+ kind: "run",
71
+ drive: { state, claim, markerBytes, finalizer, finalizerInput: decode(finalizerStateBytes) }
72
+ };
73
+ }
74
+ async function deadLetterMissingState(internals, workflowId, workflowType, attempts, expectedBytes, callbacks) {
75
+ const lastError = "finalizer state missing \u2014 recorded resource cannot be torn down";
76
+ if (await deadLetterTeardown(internals, workflowId, workflowType, attempts, expectedBytes, {
77
+ lastError,
78
+ finalizerInput: void 0
79
+ }))
80
+ callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, workflowType, "dead-lettered", attempts, lastError));
81
+ }
82
+ export async function runWorkflowFinalizer(internals, workflowId, timerId, callbacks) {
83
+ const token = parseTeardownTimerId(timerId);
84
+ if (token === null)
85
+ return;
86
+ try {
87
+ const resolution = await resolveTeardownDrive(internals, workflowId, token, callbacks);
88
+ if (resolution.kind === "cleared")
89
+ return;
90
+ if (resolution.kind === "rearm") {
91
+ await rearmTeardownTimer(internals, workflowId, resolution.token, TEARDOWN_SELF_HEAL_DELAY_MS);
92
+ return;
93
+ }
94
+ await driveResolvedTeardown(internals, workflowId, token, resolution.drive, callbacks);
95
+ } catch (error) {
96
+ await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
97
+ callbacks.handleCleanupError("runWorkflowFinalizer", error, workflowId);
98
+ }
99
+ }
100
+ async function driveResolvedTeardown(internals, workflowId, token, drive, callbacks) {
101
+ const { state, claim, markerBytes, finalizer, finalizerInput } = drive, attempt = claim.attempts + 1, runningBytes = await claimTeardownMarker(internals, workflowId, markerBytes, claim.attempts, token);
102
+ if (runningBytes === null) {
103
+ await rearmTeardownTimer(internals, workflowId, token, TEARDOWN_SELF_HEAL_DELAY_MS);
104
+ return;
105
+ }
106
+ const result = await runFinalizerActivity(finalizer, finalizerInput, attempt, internals.abortController.signal);
107
+ if (result.ok) {
108
+ await settleTeardownSuccess(internals, workflowId, state.type, token, attempt, runningBytes, callbacks);
109
+ return;
110
+ }
111
+ if (result.abortedByShutdown) {
112
+ const fireAt = internals.options.getNow() + TEARDOWN_SELF_HEAL_DELAY_MS;
113
+ if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
114
+ {
115
+ type: "put",
116
+ key: KEYS.teardownOwed(workflowId),
117
+ value: encodeOwedClaim(claim.attempts, token)
118
+ },
119
+ ...teardownTimerOperations(token, workflowId, fireAt)
120
+ ]))
121
+ await rearmOnLostSettle(internals, workflowId, token);
122
+ return;
123
+ }
124
+ await settleTeardownFailure(internals, workflowId, state, attempt, token, runningBytes, result.error, callbacks);
125
+ }
126
+ async function settleTeardownSuccess(internals, workflowId, workflowType, token, attempt, runningBytes, callbacks) {
127
+ if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
128
+ { type: "delete", key: KEYS.teardownOwed(workflowId) },
129
+ { type: "delete", key: KEYS.finalizerState(workflowId) }
130
+ ])) {
131
+ await rearmOnLostSettle(internals, workflowId, token);
132
+ return;
133
+ }
134
+ callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, workflowType, "completed", attempt));
135
+ }
136
+ async function settleTeardownFailure(internals, workflowId, state, attempt, token, runningBytes, error, callbacks) {
137
+ const message = errorMessage(error);
138
+ if (attempt >= MAX_TEARDOWN_ATTEMPTS) {
139
+ const finalizerStateBytes = await internals.storage.get(KEYS.finalizerState(workflowId));
140
+ if (!await deadLetterTeardown(internals, workflowId, state.type, attempt, runningBytes, {
141
+ lastError: message,
142
+ finalizerInput: finalizerStateBytes === null ? void 0 : decode(finalizerStateBytes)
143
+ })) {
144
+ await rearmOnLostSettle(internals, workflowId, token);
145
+ return;
146
+ }
147
+ callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, state.type, "dead-lettered", attempt, message));
148
+ return;
149
+ }
150
+ const fireAt = internals.options.getNow() + teardownBackoffMs(attempt);
151
+ if (!await settleOnRunningClaim(internals, workflowId, runningBytes, [
152
+ { type: "put", key: KEYS.teardownOwed(workflowId), value: encodeOwedClaim(attempt, token) },
153
+ ...teardownTimerOperations(token, workflowId, fireAt)
154
+ ])) {
155
+ await rearmOnLostSettle(internals, workflowId, token);
156
+ return;
157
+ }
158
+ callbacks.dispatchEvent(new WorkflowTeardownEvent(workflowId, state.type, "failed", attempt, message));
159
+ }
@@ -13,7 +13,9 @@ import { type TerminationCallbacks } from './cleanup.ts';
13
13
  * cancellation, so user code observing `ctx.signal.aborted` or registered
14
14
  * abort listeners must not fire. The live inline run is *parked*
15
15
  * (`parkWorkflow`: evict execution state without aborting), the same primitive
16
- * the engine uses for signal-parking,
16
+ * the engine uses for signal-parking — but with the default eviction, not the
17
+ * `retainContext` form signal-parking uses, so suspend leaves no queryable
18
+ * Context behind,
17
19
  * - does NOT run cancel handlers,
18
20
  * - does NOT settle the result promise (`handle.result()` stays pending until a
19
21
  * later `resume()` drives the run to completion, or a `cancel()` terminates it),
@@ -6,4 +6,5 @@
6
6
  */
7
7
  export { TERMINAL_WORKFLOW_STATUSES, cleanupTerminalWorkflowDurableState, cleanupTerminalWorkflowImmediately, cleanupTerminalWorkflowMemory, cleanupTerminalWorkflowSynchronously, cleanupWaiters, cleanupWorkflowStorage, evictSuspendedWorkflowWaiters, finalizeScheduledWorkflowTerminal, handleCleanupError, runDeferredTerminalCleanup, type TerminationCallbacks, } from './termination/cleanup.ts';
8
8
  export { buildPendingTimelineOperation, buildTerminalCleanupTimerOperations, cancelWorkflow, completeWorkflow, ensureTerminalCleanupTracked, failWorkflow, finalizePendingTimelineEntry, terminateWorkflow, timeoutWorkflow, } from './termination/complete.ts';
9
+ export { runWorkflowFinalizer, teardownStaleThresholdMs, type FinalizerDriveCallbacks, type TeardownDeadLetterRecord, } from './termination/finalizer.ts';
9
10
  export { suspendWorkflow } from './termination/suspend.ts';
@@ -22,4 +22,8 @@ export {
22
22
  terminateWorkflow,
23
23
  timeoutWorkflow
24
24
  } from "./termination/complete.js";
25
+ export {
26
+ runWorkflowFinalizer,
27
+ teardownStaleThresholdMs
28
+ } from "./termination/finalizer.js";
25
29
  export { suspendWorkflow } from "./termination/suspend.js";
@@ -1,10 +1,9 @@
1
1
  import { UpdateCompletedEvent, UpdateReceivedEvent } from "../events.js";
2
2
  import { isGeneratorResult } from "../step-context.js";
3
- import {
4
- UpdateTimeoutError,
5
- UpdateValidationError
6
- } from "../updates.js";
3
+ import { UpdateValidationError } from "../updates.js";
4
+ import { notifyConditionWaiters } from "./condition-waiters.js";
7
5
  import { trackWaiterKey, untrackWaiterKey } from "./signals.js";
6
+ import { waitForUpdateResponse } from "./waiting-update-response.js";
8
7
  export async function update(internals, workflowId, name, payload, options, callbacks) {
9
8
  const timeout = options?.timeout ?? 30000;
10
9
  await runUpdateValidator(internals, workflowId, name, payload);
@@ -27,11 +26,13 @@ async function tryInlineUpdateHandler(internals, workflowId, name, payload, call
27
26
  const result = await invokeUpdateHandler(internals, name, handler, payload);
28
27
  callbacks.dispatchEvent(new UpdateCompletedEvent(updateId, workflowId, name, result));
29
28
  callbacks.broadcast({ type: "update:completed", workflowId, updateId });
29
+ notifyConditionWaiters(internals, workflowId);
30
30
  return { handled: !0, value: result };
31
31
  } catch (error) {
32
32
  const errorMessage = error instanceof Error ? error.message : String(error);
33
33
  callbacks.dispatchEvent(new UpdateCompletedEvent(updateId, workflowId, name, void 0, errorMessage));
34
34
  callbacks.broadcast({ type: "update:completed", workflowId, updateId });
35
+ notifyConditionWaiters(internals, workflowId);
35
36
  throw error;
36
37
  }
37
38
  }
@@ -51,27 +52,6 @@ async function tryWaitingUpdateHandler(internals, workflowId, name, payload, tim
51
52
  callbacks.broadcast({ type: "update:completed", workflowId, updateId });
52
53
  return { handled: !0, value: result };
53
54
  }
54
- async function waitForUpdateResponse(updateId, payload, timeout, updateWaiter) {
55
- const { promise: respondPromise, resolve: resolveRespond } = Promise.withResolvers();
56
- let responded = !1;
57
- updateWaiter({ payload, respond: (value) => {
58
- if (responded)
59
- return;
60
- responded = !0;
61
- resolveRespond(value);
62
- } });
63
- let timeoutId;
64
- try {
65
- return await Promise.race([
66
- respondPromise,
67
- new Promise((_resolve, reject) => {
68
- timeoutId = setTimeout(() => reject(new UpdateTimeoutError(updateId, timeout)), timeout);
69
- })
70
- ]);
71
- } finally {
72
- clearTimeout(timeoutId);
73
- }
74
- }
75
55
  async function runCoordinatedUpdate(internals, workflowId, name, payload, timeout, callbacks) {
76
56
  const updateId = await internals.updateCoordinator.createRequest(workflowId, name, payload);
77
57
  callbacks.schedulePendingInlineUpdateDrain(workflowId);
@@ -8,6 +8,7 @@ export declare function isValidScheduleIdentifier(value: unknown): value is stri
8
8
  export declare function coerceScheduleId(scheduleId: string, fieldName: string): string;
9
9
  export declare function normalizeScheduleOptions(options: ScheduleOptions | undefined): Required<Pick<ScheduleOptions, 'overlap' | 'backfill'>> & {
10
10
  id?: string;
11
+ jitterMs?: number;
11
12
  };
12
13
  /**
13
14
  * A recurrence specification normalized into the discriminated cadence the
@@ -32,7 +33,7 @@ export declare function decodeScheduleIdentityFields(decoded: Record<string, unk
32
33
  cronExpression?: string;
33
34
  intervalMs?: number;
34
35
  }) | null;
35
- type ScheduleRuntimeFields = Pick<ScheduleState, 'backfill' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'queuedRuns'>;
36
+ type ScheduleRuntimeFields = Pick<ScheduleState, 'backfill' | 'jitterMs' | 'createdAt' | 'updatedAt' | 'lastFireAt' | 'lastMissedFireAt' | 'nextFireAt' | 'currentWorkflowId' | 'missedFireCount' | 'queuedRuns'>;
36
37
  export declare function decodeScheduleRuntimeFields(decoded: Record<string, unknown>, scheduleId: string): ScheduleRuntimeFields | null;
37
38
  export declare function decodeScheduleState(bytes: Uint8Array): ScheduleState | null;
38
39
  export {};
@@ -36,7 +36,7 @@ export function normalizeScheduleOptions(options) {
36
36
  return { overlap: "skip", backfill: !1 };
37
37
  if (typeof options !== "object" || options === null)
38
38
  throw Error("options must be an object when provided");
39
- const { id, overlap, backfill } = options, normalizedOptions = {
39
+ const { id, overlap, backfill, jitter } = options, normalizedOptions = {
40
40
  overlap: "skip",
41
41
  backfill: !1
42
42
  };
@@ -52,8 +52,25 @@ export function normalizeScheduleOptions(options) {
52
52
  throw Error("options.backfill must be a boolean when provided");
53
53
  normalizedOptions.backfill = backfill;
54
54
  }
55
+ if (jitter !== void 0)
56
+ normalizedOptions.jitterMs = normalizeScheduleJitter(jitter, "options.jitter");
55
57
  return normalizedOptions;
56
58
  }
59
+ function normalizeScheduleJitter(value, fieldName) {
60
+ if (typeof value !== "string" && typeof value !== "number")
61
+ throw Error(`${fieldName} must be a duration string or a number of milliseconds`);
62
+ let milliseconds;
63
+ try {
64
+ milliseconds = parseDuration(value);
65
+ } catch (error) {
66
+ const message = error instanceof Error ? error.message : String(error);
67
+ throw Error(`Invalid ${fieldName}: ${message}`, { cause: error });
68
+ }
69
+ const jitterMs = Math.ceil(milliseconds);
70
+ if (!Number.isSafeInteger(jitterMs) || jitterMs <= 0)
71
+ throw Error(`${fieldName} must resolve to a positive number of milliseconds`);
72
+ return jitterMs;
73
+ }
57
74
  function normalizeIntervalEvery(every) {
58
75
  if (typeof every !== "string" && typeof every !== "number")
59
76
  throw Error('Schedule interval "every" must be a duration string or a number of milliseconds');
@@ -171,6 +188,16 @@ function decodeScheduleBackfill(decoded, scheduleId) {
171
188
  }
172
189
  return backfill;
173
190
  }
191
+ function decodeScheduleJitterMs(decoded, scheduleId) {
192
+ const jitterMs = decoded.jitterMs;
193
+ if (jitterMs === void 0)
194
+ return;
195
+ if (typeof jitterMs !== "number" || !Number.isSafeInteger(jitterMs) || jitterMs <= 0) {
196
+ rejectInvalidScheduleRecord(scheduleId, "with invalid jitterMs");
197
+ return null;
198
+ }
199
+ return jitterMs;
200
+ }
174
201
  function decodeScheduleTimestamps(decoded, scheduleId) {
175
202
  const { createdAt, updatedAt } = decoded;
176
203
  if (!isValidScheduleTimestamp(createdAt) || !isValidScheduleTimestamp(updatedAt))
@@ -178,10 +205,14 @@ function decodeScheduleTimestamps(decoded, scheduleId) {
178
205
  const lastFireAt = decoded.lastFireAt;
179
206
  if (lastFireAt !== void 0 && !isValidScheduleTimestamp(lastFireAt))
180
207
  return rejectInvalidScheduleRecord(scheduleId, "with invalid lastFireAt");
208
+ const lastMissedFireAt = decoded.lastMissedFireAt;
209
+ if (lastMissedFireAt !== void 0 && !isValidScheduleTimestamp(lastMissedFireAt))
210
+ return rejectInvalidScheduleRecord(scheduleId, "with invalid lastMissedFireAt");
181
211
  return {
182
212
  createdAt,
183
213
  updatedAt,
184
- ...lastFireAt !== void 0 && { lastFireAt }
214
+ ...lastFireAt !== void 0 && { lastFireAt },
215
+ ...lastMissedFireAt !== void 0 && { lastMissedFireAt }
185
216
  };
186
217
  }
187
218
  function decodeScheduleNextFireAt(decoded, scheduleId) {
@@ -214,10 +245,23 @@ function decodeScheduleQueuedRuns(decoded, scheduleId) {
214
245
  }
215
246
  return queuedRuns;
216
247
  }
248
+ function decodeScheduleMissedFireCount(decoded, scheduleId) {
249
+ const missedFireCount = decoded.missedFireCount;
250
+ if (missedFireCount === void 0)
251
+ return 0;
252
+ if (typeof missedFireCount !== "number" || !Number.isSafeInteger(missedFireCount) || missedFireCount < 0) {
253
+ rejectInvalidScheduleRecord(scheduleId, "with invalid missedFireCount");
254
+ return null;
255
+ }
256
+ return missedFireCount;
257
+ }
217
258
  export function decodeScheduleRuntimeFields(decoded, scheduleId) {
218
259
  const backfill = decodeScheduleBackfill(decoded, scheduleId);
219
260
  if (backfill === null)
220
261
  return null;
262
+ const jitterMs = decodeScheduleJitterMs(decoded, scheduleId);
263
+ if (jitterMs === null)
264
+ return null;
221
265
  const timestamps = decodeScheduleTimestamps(decoded, scheduleId);
222
266
  if (timestamps === null)
223
267
  return null;
@@ -230,11 +274,16 @@ export function decodeScheduleRuntimeFields(decoded, scheduleId) {
230
274
  const queuedRuns = decodeScheduleQueuedRuns(decoded, scheduleId);
231
275
  if (queuedRuns === null)
232
276
  return null;
277
+ const missedFireCount = decodeScheduleMissedFireCount(decoded, scheduleId);
278
+ if (missedFireCount === null)
279
+ return null;
233
280
  return {
234
281
  backfill,
282
+ ...jitterMs !== void 0 && { jitterMs },
235
283
  ...timestamps,
236
284
  nextFireAt: nextFireAt.value,
237
285
  ...currentWorkflow.value !== void 0 && { currentWorkflowId: currentWorkflow.value },
286
+ missedFireCount,
238
287
  queuedRuns
239
288
  };
240
289
  }
@@ -11,6 +11,29 @@ const WORKFLOW_TIMELINE_STATUSES = new Set([
11
11
  "cancelled",
12
12
  "timed-out"
13
13
  ]);
14
+ function defineCompleteWorkflowStateFieldNames(fieldNames) {
15
+ return fieldNames;
16
+ }
17
+ const WORKFLOW_STATE_FIELD_NAMES = new Set(defineCompleteWorkflowStateFieldNames([
18
+ "id",
19
+ "type",
20
+ "status",
21
+ "tags",
22
+ "input",
23
+ "result",
24
+ "error",
25
+ "errorStack",
26
+ "failureCategory",
27
+ "terminationReason",
28
+ "versionTuple",
29
+ "executionStateOwnerId",
30
+ "createdAt",
31
+ "startedAt",
32
+ "updatedAt",
33
+ "terminalCleanupToken",
34
+ "executionDeadline",
35
+ "forkedFrom"
36
+ ]));
14
37
  export function isSanitizedSearchAttributeValue(value) {
15
38
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
16
39
  return !0;
@@ -56,12 +79,10 @@ export function isValidDecodedTags(value) {
56
79
  return value === void 0 || isWorkflowTagArray(value);
57
80
  }
58
81
  export function decodeWorkflowState(bytes) {
59
- const decoded = decode(bytes);
60
- if (isRecord(decoded))
61
- liftFlatVersionTuple(decoded);
82
+ const decoded = decode(bytes), decodedRecord = isRecord(decoded) ? decoded : void 0;
83
+ if (decodedRecord !== void 0)
84
+ liftFlatVersionTuple(decodedRecord);
62
85
  const state = decoded;
63
- if ("tenant" in state)
64
- delete state.tenant;
65
86
  if (!isValidDecodedTags(state.tags)) {
66
87
  console.warn(`[weft] Decoded workflow state for "${String(state.id)}" has invalid tags; dropping the malformed tag list from the decoded state.`);
67
88
  delete state.tags;
@@ -80,6 +101,12 @@ export function decodeWorkflowState(bytes) {
80
101
  console.warn(`[weft] Decoded workflow state for "${String(state.id)}" has an invalid executionStateOwnerId field; falling back to the workflow id as the execution owner. This usually indicates corruption or tampering of the storage record.`);
81
102
  delete state.executionStateOwnerId;
82
103
  }
104
+ return decodedRecord === void 0 ? state : stripUnknownWorkflowStateFields(state, decodedRecord);
105
+ }
106
+ function stripUnknownWorkflowStateFields(state, stateFields) {
107
+ for (const fieldName of Object.keys(stateFields))
108
+ if (!WORKFLOW_STATE_FIELD_NAMES.has(fieldName))
109
+ delete stateFields[fieldName];
83
110
  return state;
84
111
  }
85
112
  function liftFlatVersionTuple(record) {
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Park until a waiting `ctx.waitForUpdate` handler responds (via the resolver it
3
+ * registered in `updateWaiters`) or the update times out. Resolves with the
4
+ * handler's response value; rejects with {@link UpdateTimeoutError} when the
5
+ * timeout elapses first. The `respond` callback is single-shot — a late second
6
+ * response is ignored.
7
+ */
8
+ export declare function waitForUpdateResponse(updateId: string, payload: unknown, timeout: number, updateWaiter: (request: unknown) => void): Promise<unknown>;
@@ -0,0 +1,22 @@
1
+ import { UpdateTimeoutError } from "../updates.js";
2
+ export async function waitForUpdateResponse(updateId, payload, timeout, updateWaiter) {
3
+ const { promise: respondPromise, resolve: resolveRespond } = Promise.withResolvers();
4
+ let responded = !1;
5
+ updateWaiter({ payload, respond: (value) => {
6
+ if (responded)
7
+ return;
8
+ responded = !0;
9
+ resolveRespond(value);
10
+ } });
11
+ let timeoutId;
12
+ try {
13
+ return await Promise.race([
14
+ respondPromise,
15
+ new Promise((_resolve, reject) => {
16
+ timeoutId = setTimeout(() => reject(new UpdateTimeoutError(updateId, timeout)), timeout);
17
+ })
18
+ ]);
19
+ } finally {
20
+ clearTimeout(timeoutId);
21
+ }
22
+ }
@@ -0,0 +1,10 @@
1
+ import type { BatchOperation, ConditionalBatchCondition } from '../../storage/interface.ts';
2
+ import type { WorkflowConcurrencyOptions } from '../types.ts';
3
+ import type { EngineInternals } from './internals.ts';
4
+ export type WorkflowConcurrencyStartOperations = {
5
+ stateKey: string;
6
+ operations: BatchOperation[];
7
+ conditions: ConditionalBatchCondition[];
8
+ };
9
+ export declare function buildWorkflowConcurrencyStartOperations(internals: EngineInternals, workflowType: string, workflowId: string, input: unknown, concurrency: WorkflowConcurrencyOptions): Promise<WorkflowConcurrencyStartOperations>;
10
+ export declare function releaseWorkflowConcurrencySlot(internals: EngineInternals, workflowId: string): Promise<void>;
@@ -0,0 +1,136 @@
1
+ import { KEYS } from "../../storage/interface.js";
2
+ import { AtomicState, atomicStateVersionKey, readAtomicStateSnapshot } from "../atomic-state.js";
3
+ import { decode, encode } from "../codec.js";
4
+ import {
5
+ initialLockRecord,
6
+ reduceRelease
7
+ } from "../concurrency.js";
8
+ import { WorkflowConcurrencyLimitExceededError } from "./errors.js";
9
+ const WORKFLOW_CONCURRENCY_HOLDER_VERSION = 1, NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE = Number.MAX_SAFE_INTEGER;
10
+ function encodeVersionCondition(dataKey, version) {
11
+ return {
12
+ key: atomicStateVersionKey(dataKey),
13
+ expectedValue: version === 0 ? null : encode(version)
14
+ };
15
+ }
16
+ function normalizeLockRecord(record) {
17
+ if (record === void 0)
18
+ return initialLockRecord();
19
+ return {
20
+ holders: Array.isArray(record.holders) ? record.holders : [],
21
+ waiters: Array.isArray(record.waiters) ? record.waiters : []
22
+ };
23
+ }
24
+ function liveWorkflowConcurrencyHolders(holders, now) {
25
+ return holders.filter((holder) => holder.leaseExpiresAt > now);
26
+ }
27
+ function acquireWorkflowConcurrencySlot(current, options) {
28
+ const record = normalizeLockRecord(current), holders = liveWorkflowConcurrencyHolders(record.holders, options.now);
29
+ if (holders.some((holder) => holder.holderId === options.workflowId))
30
+ return {
31
+ acquired: !0,
32
+ record: {
33
+ holders: holders.map((holder) => holder.holderId === options.workflowId ? {
34
+ holderId: options.workflowId,
35
+ leaseExpiresAt: NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE
36
+ } : holder),
37
+ waiters: []
38
+ }
39
+ };
40
+ if (holders.length >= options.limit)
41
+ return { acquired: !1, record: { holders, waiters: [] } };
42
+ return {
43
+ acquired: !0,
44
+ record: {
45
+ holders: [
46
+ ...holders,
47
+ {
48
+ holderId: options.workflowId,
49
+ leaseExpiresAt: NON_EXPIRING_WORKFLOW_CONCURRENCY_LEASE
50
+ }
51
+ ],
52
+ waiters: []
53
+ }
54
+ };
55
+ }
56
+ function resolveWorkflowConcurrencyPartitionKey(workflowType, input, concurrency) {
57
+ if (concurrency.key === void 0)
58
+ return workflowType;
59
+ let partitionKey;
60
+ try {
61
+ partitionKey = concurrency.key(input);
62
+ } catch (error) {
63
+ throw Error(`workflow("${workflowType}").concurrency.key threw while resolving the partition key: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
64
+ }
65
+ if (typeof partitionKey !== "string")
66
+ throw TypeError(`workflow("${workflowType}").concurrency.key must return a string partition key`);
67
+ return partitionKey;
68
+ }
69
+ function encodeHolderRecord(workflowType, partitionKey) {
70
+ return {
71
+ version: WORKFLOW_CONCURRENCY_HOLDER_VERSION,
72
+ workflowType,
73
+ partitionKey
74
+ };
75
+ }
76
+ function decodeHolderRecord(bytes) {
77
+ const decoded = decode(bytes);
78
+ if (typeof decoded !== "object" || decoded === null)
79
+ return null;
80
+ const record = decoded;
81
+ if (record.version !== WORKFLOW_CONCURRENCY_HOLDER_VERSION || typeof record.workflowType !== "string" || typeof record.partitionKey !== "string")
82
+ return null;
83
+ return {
84
+ version: WORKFLOW_CONCURRENCY_HOLDER_VERSION,
85
+ workflowType: record.workflowType,
86
+ partitionKey: record.partitionKey
87
+ };
88
+ }
89
+ export async function buildWorkflowConcurrencyStartOperations(internals, workflowType, workflowId, input, concurrency) {
90
+ const partitionKey = resolveWorkflowConcurrencyPartitionKey(workflowType, input, concurrency), stateKey = KEYS.workflowConcurrency(workflowType, partitionKey), snapshot = await readAtomicStateSnapshot(internals.storage, stateKey, {
91
+ initial: initialLockRecord()
92
+ }), acquired = acquireWorkflowConcurrencySlot(snapshot.value, {
93
+ workflowId,
94
+ now: internals.options.getNow(),
95
+ limit: concurrency.max
96
+ });
97
+ if (!acquired.acquired)
98
+ throw new WorkflowConcurrencyLimitExceededError({
99
+ workflowType,
100
+ limit: concurrency.max,
101
+ partitionKey
102
+ });
103
+ return {
104
+ stateKey,
105
+ conditions: [encodeVersionCondition(stateKey, snapshot.version)],
106
+ operations: [
107
+ { type: "put", key: stateKey, value: encode(acquired.record) },
108
+ { type: "put", key: atomicStateVersionKey(stateKey), value: encode(snapshot.version + 1) },
109
+ {
110
+ type: "put",
111
+ key: KEYS.workflowConcurrencyHolder(workflowId),
112
+ value: encode(encodeHolderRecord(workflowType, partitionKey))
113
+ },
114
+ {
115
+ type: "put",
116
+ key: KEYS.terminalCleanupNeeded(workflowId),
117
+ value: new Uint8Array(0)
118
+ }
119
+ ]
120
+ };
121
+ }
122
+ export async function releaseWorkflowConcurrencySlot(internals, workflowId) {
123
+ const holderKey = KEYS.workflowConcurrencyHolder(workflowId), markerBytes = await internals.storage.get(holderKey);
124
+ if (markerBytes === null)
125
+ return;
126
+ const marker = decodeHolderRecord(markerBytes);
127
+ if (marker === null) {
128
+ await internals.storage.delete(holderKey);
129
+ return;
130
+ }
131
+ const stateKey = KEYS.workflowConcurrency(marker.workflowType, marker.partitionKey);
132
+ await new AtomicState(internals.storage, stateKey, {
133
+ initial: initialLockRecord()
134
+ }).update((current) => reduceRelease(current, { holderId: workflowId, now: internals.options.getNow() }));
135
+ await internals.storage.delete(holderKey);
136
+ }
@@ -26,11 +26,10 @@ export declare const STREAM_CHUNK_KIND = "stream:chunk";
26
26
  export declare const COMPACTION_BOUNDARY_KIND = "workflow:compaction-boundary";
27
27
  /**
28
28
  * A committed workflow-feed record surfaced to subscribers of
29
- * `subscribeWorkflowFeedCommits()`. Fires after `storage.batch()`
30
- * (events) or `storage.put()` (tokens) resolves, so replay and live
31
- * delivery share the same committed sequence authority. The same
32
- * shape covers both selectors — consumers filter on `selector`
33
- * before interpreting `payload`.
29
+ * `subscribeWorkflowFeedCommits()`. Fires after the storage commit resolves, so
30
+ * replay and live delivery share the same committed sequence authority. The
31
+ * same shape covers both selectors consumers filter on `selector` before
32
+ * interpreting `payload`.
34
33
  *
35
34
  * - `events` selector: `kind` is the durable log entry type
36
35
  * (e.g. `'workflow:checkpoint'`). `sequence` / `timestamp` come
@@ -1,7 +1,7 @@
1
1
  import { EventLog } from "../event-log.js";
2
2
  import { readEventLogWatermark } from "./event-log-compaction.js";
3
3
  import { workflowFeedListenerKey } from "./state-utilities.js";
4
- import { loadStoredStreamChunks } from "./stream-chunk-loading.js";
4
+ import { loadStoredStreamChunks, loadStoredStreamTailSequence } from "./stream-chunk-loading.js";
5
5
  export const TOKENS_STREAM_KEY = "tokens", STREAM_CHUNK_KIND = "stream:chunk", COMPACTION_BOUNDARY_KIND = "workflow:compaction-boundary";
6
6
  export async function* replayWorkflowFeed(internals, workflowId, selector, afterSequence) {
7
7
  if (selector === "events") {
@@ -17,6 +17,9 @@ export async function snapshotWorkflowFeedTail(internals, workflowId, selector)
17
17
  return head.sequence;
18
18
  return (await new EventLog(internals.storage, workflowId).loadHead()).sequence;
19
19
  }
20
+ const tail = await loadStoredStreamTailSequence(internals.storage, workflowId, TOKENS_STREAM_KEY);
21
+ if (tail !== null)
22
+ return tail;
20
23
  const chunks = await loadStoredStreamChunks(internals.storage, workflowId, TOKENS_STREAM_KEY);
21
24
  if (chunks.length === 0)
22
25
  return -1;