@lostgradient/weft 0.3.0 → 0.5.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 (510) 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 +61 -5
  23. package/dist/client/local-handles.d.ts +22 -0
  24. package/dist/client/local-handles.js +23 -0
  25. package/dist/client/local.d.ts +6 -3
  26. package/dist/client/local.js +12 -26
  27. package/dist/client/start-body.d.ts +4 -3
  28. package/dist/core/byte-arrays.d.ts +5 -0
  29. package/dist/core/byte-arrays.js +5 -0
  30. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  31. package/dist/core/checkpoint/lifecycle.js +9 -4
  32. package/dist/core/checkpoint/serialization.js +12 -5
  33. package/dist/core/codec/extension-codec.d.ts +16 -0
  34. package/dist/core/codec/extension-codec.js +100 -6
  35. package/dist/core/context/activity-retry-state.d.ts +38 -0
  36. package/dist/core/context/activity-retry-state.js +89 -0
  37. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  38. package/dist/core/context/activity-schedule-to-close.js +69 -0
  39. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  40. package/dist/core/context/child-workflow-pipe.js +15 -2
  41. package/dist/core/context/context-presence.d.ts +19 -0
  42. package/dist/core/context/context-presence.js +13 -0
  43. package/dist/core/context/durable-operations.d.ts +25 -0
  44. package/dist/core/context/durable-operations.js +64 -0
  45. package/dist/core/context/index.d.ts +9 -5
  46. package/dist/core/context/index.js +17 -12
  47. package/dist/core/context/internals.d.ts +20 -0
  48. package/dist/core/context/internals.js +3 -1
  49. package/dist/core/context/operation-request.d.ts +35 -0
  50. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  51. package/dist/core/context/run-operation.d.ts +6 -1
  52. package/dist/core/context/run-operation.js +41 -87
  53. package/dist/core/context/session-state.js +7 -8
  54. package/dist/core/context/speculative-child.js +2 -0
  55. package/dist/core/context/types.d.ts +15 -0
  56. package/dist/core/context/version-patching.d.ts +8 -0
  57. package/dist/core/context/version-patching.js +40 -0
  58. package/dist/core/context/workflow-logger.d.ts +98 -0
  59. package/dist/core/context/workflow-logger.js +68 -0
  60. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  61. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  62. package/dist/core/engine/activity-per-attempt-timeout.d.ts +46 -0
  63. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  64. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  65. package/dist/core/engine/activity-reconciliation.js +12 -1
  66. package/dist/core/engine/activity-resolution.d.ts +23 -0
  67. package/dist/core/engine/activity-resolution.js +37 -0
  68. package/dist/core/engine/aggregate.js +66 -30
  69. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  70. package/dist/core/engine/async-activity-completion.js +53 -12
  71. package/dist/core/engine/attributes-tags.js +9 -4
  72. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  73. package/dist/core/engine/bulk-operations-purge.js +38 -3
  74. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  75. package/dist/core/engine/bulk-operations-shared.js +8 -2
  76. package/dist/core/engine/bulk-operations.d.ts +4 -1
  77. package/dist/core/engine/bulk-operations.js +235 -24
  78. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  79. package/dist/core/engine/callback-creators-bundles.js +30 -2
  80. package/dist/core/engine/callback-creators-core.js +6 -4
  81. package/dist/core/engine/callback-creators-router.js +10 -0
  82. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  83. package/dist/core/engine/callback-creators-schedule.js +12 -8
  84. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  85. package/dist/core/engine/candidate-read-batching.js +1 -0
  86. package/dist/core/engine/checkpoint-io.js +61 -25
  87. package/dist/core/engine/checkpoint-reads.js +3 -2
  88. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  89. package/dist/core/engine/checkpoint-replay.js +242 -0
  90. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  91. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  92. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  93. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  94. package/dist/core/engine/child-workflow.js +27 -4
  95. package/dist/core/engine/condition-waiters.d.ts +14 -0
  96. package/dist/core/engine/condition-waiters.js +5 -0
  97. package/dist/core/engine/construction.d.ts +3 -0
  98. package/dist/core/engine/construction.js +21 -8
  99. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  100. package/dist/core/engine/coordination-branch-executors.js +107 -0
  101. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  102. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  103. package/dist/core/engine/disposal.js +13 -0
  104. package/dist/core/engine/engine-create-types.d.ts +14 -4
  105. package/dist/core/engine/engine-internal-types.d.ts +26 -3
  106. package/dist/core/engine/errors.d.ts +47 -0
  107. package/dist/core/engine/errors.js +20 -0
  108. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  109. package/dist/core/engine/event-log-compaction.js +20 -2
  110. package/dist/core/engine/fenced-write.d.ts +65 -0
  111. package/dist/core/engine/fenced-write.js +71 -0
  112. package/dist/core/engine/finalizer-state.d.ts +28 -0
  113. package/dist/core/engine/finalizer-state.js +16 -0
  114. package/dist/core/engine/handles.d.ts +8 -0
  115. package/dist/core/engine/index.d.ts +34 -16
  116. package/dist/core/engine/index.js +136 -9
  117. package/dist/core/engine/inline-parking.js +3 -2
  118. package/dist/core/engine/internals.d.ts +107 -3
  119. package/dist/core/engine/lease-codec.d.ts +35 -0
  120. package/dist/core/engine/lease-codec.js +32 -0
  121. package/dist/core/engine/lease-deposition.d.ts +66 -0
  122. package/dist/core/engine/lease-deposition.js +10 -0
  123. package/dist/core/engine/lease-errors.d.ts +99 -0
  124. package/dist/core/engine/lease-errors.js +30 -0
  125. package/dist/core/engine/lease-manager.d.ts +114 -0
  126. package/dist/core/engine/lease-manager.js +135 -0
  127. package/dist/core/engine/lifecycle/persist.js +10 -32
  128. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  129. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  130. package/dist/core/engine/lifecycle/resume.js +16 -9
  131. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  132. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  133. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  134. package/dist/core/engine/lifecycle/start-commit.d.ts +9 -0
  135. package/dist/core/engine/lifecycle/start-commit.js +50 -8
  136. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  137. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  138. package/dist/core/engine/lifecycle/start-or-signal.d.ts +3 -2
  139. package/dist/core/engine/lifecycle/start-or-signal.js +11 -81
  140. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  141. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  142. package/dist/core/engine/lifecycle/start.d.ts +4 -4
  143. package/dist/core/engine/lifecycle/start.js +17 -9
  144. package/dist/core/engine/lifecycle/transition.js +17 -5
  145. package/dist/core/engine/lifecycle.d.ts +1 -1
  146. package/dist/core/engine/list-candidate-resolution.js +2 -2
  147. package/dist/core/engine/listing.js +9 -5
  148. package/dist/core/engine/operations-activity.d.ts +6 -13
  149. package/dist/core/engine/operations-activity.js +26 -53
  150. package/dist/core/engine/operations-coordination.d.ts +10 -0
  151. package/dist/core/engine/operations-coordination.js +44 -9
  152. package/dist/core/engine/operations-router.d.ts +6 -0
  153. package/dist/core/engine/operations-router.js +2 -0
  154. package/dist/core/engine/operations-speculate.js +6 -2
  155. package/dist/core/engine/operations-stream.js +12 -2
  156. package/dist/core/engine/operations-time.d.ts +4 -2
  157. package/dist/core/engine/operations-time.js +14 -2
  158. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  159. package/dist/core/engine/operations-wait-condition.js +62 -0
  160. package/dist/core/engine/ownership-options.d.ts +23 -0
  161. package/dist/core/engine/ownership-options.js +26 -0
  162. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  163. package/dist/core/engine/payload-size-policy.js +4 -0
  164. package/dist/core/engine/pending-updates.d.ts +17 -0
  165. package/dist/core/engine/pending-updates.js +33 -11
  166. package/dist/core/engine/queries.js +1 -1
  167. package/dist/core/engine/registration.d.ts +1 -0
  168. package/dist/core/engine/registration.js +18 -3
  169. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  170. package/dist/core/engine/schedule-jitter.js +10 -0
  171. package/dist/core/engine/schedule-run.d.ts +17 -0
  172. package/dist/core/engine/schedule-run.js +38 -0
  173. package/dist/core/engine/schedule-timer.js +81 -17
  174. package/dist/core/engine/schedules.d.ts +7 -4
  175. package/dist/core/engine/schedules.js +37 -16
  176. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  177. package/dist/core/engine/search-attribute-records.js +17 -0
  178. package/dist/core/engine/signals.d.ts +18 -2
  179. package/dist/core/engine/signals.js +42 -21
  180. package/dist/core/engine/state-utilities.d.ts +49 -2
  181. package/dist/core/engine/state-utilities.js +114 -3
  182. package/dist/core/engine/storage-io.d.ts +16 -2
  183. package/dist/core/engine/storage-io.js +26 -5
  184. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  185. package/dist/core/engine/stream-chunk-loading.js +24 -1
  186. package/dist/core/engine/sub-operation.js +25 -6
  187. package/dist/core/engine/termination/cleanup.d.ts +3 -1
  188. package/dist/core/engine/termination/cleanup.js +25 -1
  189. package/dist/core/engine/termination/complete.js +44 -6
  190. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  191. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  192. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  193. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  194. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  195. package/dist/core/engine/termination/finalizer.js +159 -0
  196. package/dist/core/engine/termination/suspend.d.ts +3 -1
  197. package/dist/core/engine/termination.d.ts +1 -0
  198. package/dist/core/engine/termination.js +4 -0
  199. package/dist/core/engine/updates.js +5 -25
  200. package/dist/core/engine/validation/schedule.d.ts +2 -1
  201. package/dist/core/engine/validation/schedule.js +51 -2
  202. package/dist/core/engine/validation.js +32 -5
  203. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  204. package/dist/core/engine/waiting-update-response.js +22 -0
  205. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  206. package/dist/core/engine/workflow-concurrency.js +136 -0
  207. package/dist/core/engine/workflow-feed.d.ts +4 -5
  208. package/dist/core/engine/workflow-feed.js +4 -1
  209. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  210. package/dist/core/engine/workflow-indexes.js +10 -0
  211. package/dist/core/engine/workflow-state-stream.js +33 -13
  212. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  213. package/dist/core/engine-helpers.js +1 -0
  214. package/dist/core/events/activity-events.d.ts +43 -12
  215. package/dist/core/events/activity-events.js +28 -0
  216. package/dist/core/events/attribute-events.d.ts +2 -3
  217. package/dist/core/events/event-map.d.ts +18 -12
  218. package/dist/core/events/index.d.ts +1 -0
  219. package/dist/core/events/index.js +1 -0
  220. package/dist/core/events/schedule-events.d.ts +71 -0
  221. package/dist/core/events/schedule-events.js +29 -0
  222. package/dist/core/events/signal-events.d.ts +4 -6
  223. package/dist/core/events/system-events.d.ts +29 -19
  224. package/dist/core/events/system-events.js +26 -0
  225. package/dist/core/events/update-events.d.ts +6 -8
  226. package/dist/core/events/workflow-events.d.ts +88 -23
  227. package/dist/core/events/workflow-events.js +26 -0
  228. package/dist/core/failure-categories.js +5 -17
  229. package/dist/core/fault-code.d.ts +9 -3
  230. package/dist/core/fault-code.js +1 -0
  231. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  232. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  233. package/dist/core/inline-execution-strategy.d.ts +31 -36
  234. package/dist/core/inline-execution-strategy.js +16 -27
  235. package/dist/core/list-filter-validation.d.ts +1 -1
  236. package/dist/core/payload-size.d.ts +1 -1
  237. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  238. package/dist/core/review/events.d.ts +6 -8
  239. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  240. package/dist/core/scheduler/scheduler-class.js +38 -11
  241. package/dist/core/scheduler/timer-batch.js +9 -1
  242. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  243. package/dist/core/scheduler/timer-sources.js +11 -5
  244. package/dist/core/session-state.d.ts +0 -1
  245. package/dist/core/session-state.js +2 -2
  246. package/dist/core/start-workflow-validation.d.ts +34 -0
  247. package/dist/core/start-workflow-validation.js +19 -0
  248. package/dist/core/types/activity-verification.d.ts +67 -0
  249. package/dist/core/types/activity-verification.js +0 -0
  250. package/dist/core/types/activity.d.ts +80 -61
  251. package/dist/core/types/bulk.d.ts +50 -9
  252. package/dist/core/types/checkpoint.d.ts +44 -8
  253. package/dist/core/types/list-options.d.ts +146 -0
  254. package/dist/core/types/list-options.js +0 -0
  255. package/dist/core/types/options.d.ts +121 -165
  256. package/dist/core/types/schedules.d.ts +39 -3
  257. package/dist/core/types/services-resolution.d.ts +2 -2
  258. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  259. package/dist/core/types/workflow-builder-runtime.js +11 -2
  260. package/dist/core/types/workflow-builder.d.ts +42 -11
  261. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  262. package/dist/core/types/workflow-concurrency.js +0 -0
  263. package/dist/core/types/workflow-context.d.ts +157 -14
  264. package/dist/core/types/workflow-definition.d.ts +53 -10
  265. package/dist/core/types/workflow-function.d.ts +84 -9
  266. package/dist/core/types/workflow-log.d.ts +98 -0
  267. package/dist/core/types/workflow-log.js +0 -0
  268. package/dist/core/types/workflow-registries.d.ts +14 -3
  269. package/dist/core/types/workflow-registry.d.ts +3 -0
  270. package/dist/core/types.d.ts +4 -0
  271. package/dist/core/types.js +4 -0
  272. package/dist/core/versioning.d.ts +9 -39
  273. package/dist/core/versioning.js +2 -12
  274. package/dist/core/weft-error.d.ts +44 -1
  275. package/dist/core/weft-error.js +16 -0
  276. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  277. package/dist/core/worker-execution-strategy.js +40 -36
  278. package/dist/core/worker-inbound-message.d.ts +38 -0
  279. package/dist/core/worker-inbound-message.js +37 -0
  280. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  281. package/dist/core/worker-log-abuse-counter.js +107 -0
  282. package/dist/core/worker-message-helpers.d.ts +47 -0
  283. package/dist/core/worker-message-helpers.js +26 -0
  284. package/dist/core/worker-protocol-guard.js +1 -1
  285. package/dist/core/worker-protocol-log.d.ts +56 -0
  286. package/dist/core/worker-protocol-log.js +18 -0
  287. package/dist/core/worker-protocol.d.ts +23 -0
  288. package/dist/core/worker-protocol.js +12 -2
  289. package/dist/core/workflow-version-tuple.d.ts +3 -9
  290. package/dist/core/workflow-version-tuple.js +2 -3
  291. package/dist/diagnostics/format.js +1 -6
  292. package/dist/diagnostics/types.d.ts +4 -5
  293. package/dist/diagnostics/validate.d.ts +0 -1
  294. package/dist/diagnostics/version-check.d.ts +1 -1
  295. package/dist/diagnostics/version-check.js +4 -9
  296. package/dist/index.d.ts +12 -10
  297. package/dist/index.js +29 -3
  298. package/dist/json-schema.js +3 -3
  299. package/dist/mcp/cli.js +19 -19
  300. package/dist/mcp/dispatcher.js +1 -1
  301. package/dist/mcp/http.js +16 -6
  302. package/dist/mcp/protocol.d.ts +2 -0
  303. package/dist/mcp/protocol.js +1 -1
  304. package/dist/mcp/session.d.ts +16 -0
  305. package/dist/mcp/session.js +59 -6
  306. package/dist/mcp/tools.js +73 -6
  307. package/dist/observability/index.js +2 -2
  308. package/dist/server/asyncapi-channels.js +5 -2
  309. package/dist/server/attribute-filters.d.ts +8 -3
  310. package/dist/server/attribute-filters.js +6 -1
  311. package/dist/server/authentication/api-key.d.ts +2 -1
  312. package/dist/server/authentication/api-key.js +5 -2
  313. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  314. package/dist/server/authentication/constant-time-api-key.js +24 -0
  315. package/dist/server/authentication/index.d.ts +1 -1
  316. package/dist/server/authentication/index.js +7 -4
  317. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  318. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  319. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  320. package/dist/server/fault-to-http.js +8 -1
  321. package/dist/server/fault-to-json-rpc.js +1 -0
  322. package/dist/server/fleet-event-feed.d.ts +31 -0
  323. package/dist/server/fleet-event-feed.js +157 -0
  324. package/dist/server/handler/index.js +1 -1
  325. package/dist/server/handler/response-helpers.js +2 -1
  326. package/dist/server/handler/route-dispatch.d.ts +6 -3
  327. package/dist/server/handler/route-dispatch.js +2 -2
  328. package/dist/server/handler.js +23 -23
  329. package/dist/server/index.d.ts +32 -2
  330. package/dist/server/index.js +32 -32
  331. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  332. package/dist/server/json-rpc-transport-helpers.js +2 -1
  333. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  334. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  335. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  336. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  337. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  338. package/dist/server/json-rpc-websocket-types.js +0 -0
  339. package/dist/server/json-rpc-websocket-validation.js +20 -4
  340. package/dist/server/json-rpc-websocket.d.ts +2 -43
  341. package/dist/server/json-rpc-websocket.js +57 -74
  342. package/dist/server/openapi.d.ts +2 -1
  343. package/dist/server/openapi.js +1 -3
  344. package/dist/server/openrpc-document-schema.d.ts +78 -0
  345. package/dist/server/openrpc-document-schema.js +27 -1
  346. package/dist/server/openrpc-errors.d.ts +3 -0
  347. package/dist/server/openrpc-errors.js +2 -1
  348. package/dist/server/openrpc.js +32 -0
  349. package/dist/server/operation-catalog/index.d.ts +1 -1
  350. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  351. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  352. package/dist/server/operation-catalog/pipeline.js +8 -1
  353. package/dist/server/operation-catalog/registry.js +13 -0
  354. package/dist/server/operation-catalog/types.d.ts +20 -9
  355. package/dist/server/operation-fault.d.ts +10 -0
  356. package/dist/server/operation-fault.js +2 -0
  357. package/dist/server/operation-registry.d.ts +12 -11
  358. package/dist/server/operation-registry.js +12 -3
  359. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  360. package/dist/server/operations/async-activity.d.ts +2 -2
  361. package/dist/server/operations/async-activity.js +12 -7
  362. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  363. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  364. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  365. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  366. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  367. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  368. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  369. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  370. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  371. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  372. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  373. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  374. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  375. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  376. package/dist/server/operations/create-schedule.d.ts +3 -1
  377. package/dist/server/operations/create-schedule.js +29 -11
  378. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  379. package/dist/server/operations/fleet-events-subscription.js +99 -0
  380. package/dist/server/operations/fork-workflow.d.ts +1 -1
  381. package/dist/server/operations/fork-workflow.js +3 -2
  382. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  383. package/dist/server/operations/get-registry.d.ts +1 -1
  384. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  385. package/dist/server/operations/get-review.d.ts +1 -1
  386. package/dist/server/operations/get-schedule.d.ts +1 -1
  387. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  388. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  389. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  390. package/dist/server/operations/get-task-diagnostics.js +101 -7
  391. package/dist/server/operations/get-update-result.d.ts +1 -1
  392. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  393. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  394. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  395. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  396. package/dist/server/operations/get-workflow.d.ts +1 -1
  397. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  398. package/dist/server/operations/list-reviews.d.ts +1 -1
  399. package/dist/server/operations/list-schedules.d.ts +1 -1
  400. package/dist/server/operations/list-task-queues.d.ts +2 -2
  401. package/dist/server/operations/list-workers.d.ts +2 -2
  402. package/dist/server/operations/list-workflows.d.ts +1 -1
  403. package/dist/server/operations/operation-helpers.d.ts +16 -1
  404. package/dist/server/operations/operation-helpers.js +15 -3
  405. package/dist/server/operations/pause-schedule.d.ts +1 -1
  406. package/dist/server/operations/purge-workflows.d.ts +5 -5
  407. package/dist/server/operations/purge-workflows.js +2 -2
  408. package/dist/server/operations/query-workflow.d.ts +1 -1
  409. package/dist/server/operations/query-workflow.js +3 -2
  410. package/dist/server/operations/recover-all.d.ts +1 -1
  411. package/dist/server/operations/replay-workflow.d.ts +1 -1
  412. package/dist/server/operations/resume-schedule.d.ts +1 -1
  413. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  414. package/dist/server/operations/set-workflow-attributes.js +6 -3
  415. package/dist/server/operations/signal-workflow.js +8 -3
  416. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  417. package/dist/server/operations/start-or-signal-workflow.d.ts +6 -1
  418. package/dist/server/operations/start-or-signal-workflow.js +14 -24
  419. package/dist/server/operations/start-workflow-options.d.ts +6 -0
  420. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  421. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  422. package/dist/server/operations/start-workflow.d.ts +1 -1
  423. package/dist/server/operations/start-workflow.js +8 -23
  424. package/dist/server/operations/storage.d.ts +6 -6
  425. package/dist/server/operations/storage.js +24 -14
  426. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  427. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  428. package/dist/server/operations/submit-review-decision.js +6 -3
  429. package/dist/server/operations/update-schedule.d.ts +1 -1
  430. package/dist/server/operations/update-schedule.js +7 -4
  431. package/dist/server/operations/update-workflow.d.ts +1 -1
  432. package/dist/server/operations/update-workflow.js +7 -3
  433. package/dist/server/operations/worker-drain.d.ts +8 -8
  434. package/dist/server/operations/worker-drain.js +11 -8
  435. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  436. package/dist/server/operations/workflow-events-subscription.js +43 -8
  437. package/dist/server/rest-binding.d.ts +3 -1
  438. package/dist/server/rest-bindings.js +12 -0
  439. package/dist/server/rest-body.d.ts +10 -0
  440. package/dist/server/rest-body.js +80 -0
  441. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  442. package/dist/server/runtime/authentication-bridge.js +33 -6
  443. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  444. package/dist/server/runtime/client-visible-events.js +65 -0
  445. package/dist/server/runtime/context.d.ts +7 -0
  446. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  447. package/dist/server/runtime/event-broadcasting.js +72 -38
  448. package/dist/server/runtime/retry.d.ts +1 -0
  449. package/dist/server/runtime/retry.js +14 -0
  450. package/dist/server/runtime/shutdown.d.ts +7 -6
  451. package/dist/server/runtime/shutdown.js +6 -1
  452. package/dist/server/runtime/task-polling.js +61 -20
  453. package/dist/server/runtime/task-reconciliation.js +9 -1
  454. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  455. package/dist/server/runtime/task-result-resolution.js +81 -0
  456. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  457. package/dist/server/runtime/websocket-stream.js +173 -7
  458. package/dist/server/runtime/websocket-upgrade.js +22 -3
  459. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  460. package/dist/server/runtime/websocket-worker.js +38 -30
  461. package/dist/server/serve-internals.d.ts +3 -1
  462. package/dist/server/serve-internals.js +18 -2
  463. package/dist/server/task-state.d.ts +30 -0
  464. package/dist/server/task-state.js +28 -0
  465. package/dist/server/workflow-event-feed.d.ts +36 -115
  466. package/dist/server/workflow-event-feed.js +92 -27
  467. package/dist/service-worker/index.js +30 -30
  468. package/dist/storage/auto.js +1 -1
  469. package/dist/storage/bun-sql.js +24 -0
  470. package/dist/storage/compressed-storage.js +1 -1
  471. package/dist/storage/default-scope.d.ts +7 -4
  472. package/dist/storage/http.js +2 -2
  473. package/dist/storage/index.d.ts +76 -4
  474. package/dist/storage/indexeddb.js +1 -1
  475. package/dist/storage/interface.d.ts +163 -0
  476. package/dist/storage/interface.js +1 -1
  477. package/dist/storage/key-prefixes.d.ts +1 -1
  478. package/dist/storage/key-prefixes.js +10 -0
  479. package/dist/storage/lmdb.d.ts +4 -3
  480. package/dist/storage/lmdb.js +1 -1
  481. package/dist/storage/memory.js +1 -1
  482. package/dist/storage/neon-batch.d.ts +30 -0
  483. package/dist/storage/neon-batch.js +30 -0
  484. package/dist/storage/neon-value-mapping.d.ts +30 -3
  485. package/dist/storage/neon-value-mapping.js +12 -0
  486. package/dist/storage/neon.d.ts +16 -0
  487. package/dist/storage/neon.js +9 -4
  488. package/dist/storage/node-sqlite.js +23 -0
  489. package/dist/storage/postgres-key-value-queries.d.ts +69 -44
  490. package/dist/storage/postgres-key-value-queries.js +62 -24
  491. package/dist/storage/resolve.js +1 -1
  492. package/dist/storage/scoped-storage.js +1 -1
  493. package/dist/storage/testing.d.ts +168 -0
  494. package/dist/storage/testing.js +2 -0
  495. package/dist/storage/turso.d.ts +8 -0
  496. package/dist/storage/turso.js +2 -2
  497. package/dist/storage/typed-storage.js +1 -1
  498. package/dist/storage/web-extension.js +1 -1
  499. package/dist/testing/index.js +20 -20
  500. package/dist/version.d.ts +1 -1
  501. package/dist/version.js +1 -1
  502. package/dist/worker/protocol.js +1 -1
  503. package/dist/workers/worker-replay-state.d.ts +32 -0
  504. package/dist/workers/worker-replay-state.js +35 -0
  505. package/dist/workers/worker-state-namespace.d.ts +21 -0
  506. package/dist/workers/worker-state-namespace.js +13 -0
  507. package/dist/workers/workflow-runner.d.ts +19 -15
  508. package/dist/workers/workflow-runner.js +72 -60
  509. package/dist/workers/workflow-worker-entry.js +5 -2
  510. package/package.json +5 -1
@@ -18,6 +18,31 @@ export declare function completePreparedSleepOperation(context: Context, prepare
18
18
  }>): Generator<ContextOperationRequest, void, unknown>;
19
19
  export declare function sleep(context: Context, internals: ContextInternals, duration: Duration): Generator<ContextOperationRequest, void, unknown>;
20
20
  export declare function waitForSignal<T = unknown>(context: Context, internals: ContextInternals, name: string): Generator<ContextOperationRequest, T, unknown>;
21
+ /**
22
+ * Read the absolute deadline anchor for a `ctx.waitUntil` step, writing it on the
23
+ * first evaluation. Read-first so a crash/replay never resets the window: the
24
+ * timeout is measured from the original first yield, and the anchor lands in the
25
+ * checkpoint committed at that yield — the same atomicity the activity
26
+ * schedule-to-close anchor (`readOrInitActivityDispatchedAt`) relies on.
27
+ *
28
+ * Returns `undefined` when no timeout was supplied (wait forever).
29
+ */
30
+ export declare function readOrInitConditionDeadline(internals: ContextInternals, step: number, timeout: Duration | undefined): number | undefined;
31
+ /**
32
+ * Wait until `predicate` returns `true`, re-evaluated by the engine each time the
33
+ * workflow is driven forward (an `onUpdate` handler mutating state, or the
34
+ * optional timeout). The predicate is a non-serializable closure held in-process,
35
+ * never checkpointed. Once the wait outcome has been checkpointed, replay returns
36
+ * the cached outcome and does not re-invoke the predicate. A predicate that
37
+ * throws fails the workflow at the `yield*` call site (like a throwing activity).
38
+ * Inline execution only.
39
+ *
40
+ * With no `timeout` the generator yields `void` (waits forever). With a `timeout`
41
+ * it yields `true` when the predicate was met or `false` when the deadline
42
+ * elapsed first.
43
+ */
44
+ export declare function waitUntil(context: Context, internals: ContextInternals, predicate: () => boolean, timeout?: Duration): Generator<ContextOperationRequest, boolean | void, unknown>;
45
+ export declare function getVersion(_context: Context, internals: ContextInternals, changeId: string, minSupported: number, maxSupported: number): Generator<ContextOperationRequest, number, unknown>;
21
46
  export declare function waitForUpdate<T = unknown>(context: Context, internals: ContextInternals, name: string): Generator<ContextOperationRequest, {
22
47
  payload: T;
23
48
  respond: (result: unknown) => void;
@@ -1,5 +1,6 @@
1
1
  import { parseDuration } from "../scheduler.js";
2
2
  import { captureCallerStack } from "./validation.js";
3
+ import { resolveWorkflowVersionPatch } from "./version-patching.js";
3
4
  export function prepareSleepOperation(internals, duration) {
4
5
  const step = internals.stepIndex++;
5
6
  if (internals.accumulatedResults?.has(step))
@@ -53,6 +54,69 @@ export function* waitForSignal(context, internals, name) {
53
54
  context.accumulatedResults.set(step, result);
54
55
  return result;
55
56
  }
57
+ const CONDITION_DEADLINE_LOCAL_PREFIX = "__weftConditionDeadline:";
58
+ export function readOrInitConditionDeadline(internals, step, timeout) {
59
+ if (timeout === void 0)
60
+ return;
61
+ const localKey = `${CONDITION_DEADLINE_LOCAL_PREFIX}${step}`, existing = internals.checkpointLocals[localKey];
62
+ if (typeof existing === "number" && Number.isFinite(existing))
63
+ return existing;
64
+ if (existing !== void 0)
65
+ throw Error(`Invalid checkpointed wait-condition deadline ${JSON.stringify(existing)} for step ${step}`);
66
+ const milliseconds = parseDuration(timeout), referenceTime = internals.sleepReferenceTime ?? internals.getNow();
67
+ internals.sleepReferenceTime = void 0;
68
+ const deadline = referenceTime + milliseconds;
69
+ internals.checkpointLocals = { ...internals.checkpointLocals, [localKey]: deadline };
70
+ return deadline;
71
+ }
72
+ export function* waitUntil(context, internals, predicate, timeout) {
73
+ const step = internals.stepIndex++;
74
+ if (internals.accumulatedResults?.has(step))
75
+ return internals.accumulatedResults.get(step);
76
+ const deadline = readOrInitConditionDeadline(internals, step, timeout);
77
+ if (internals.explainMode) {
78
+ console.log("[weft] ctx.waitUntil(predicate)");
79
+ console.log(` \u2192 Creating checkpoint at step ${step}`);
80
+ console.log(deadline === void 0 ? " \u2192 Waiting indefinitely" : ` \u2192 Deadline at ${deadline}`);
81
+ }
82
+ const operationId = crypto.randomUUID(), callerStack = captureCallerStack(), result = yield {
83
+ type: "wait-condition",
84
+ operationId,
85
+ step,
86
+ predicate,
87
+ ...deadline !== void 0 && { deadline },
88
+ callerStack
89
+ };
90
+ context.accumulatedResults.set(step, result);
91
+ return result;
92
+ }
93
+ export function* getVersion(_context, internals, changeId, minSupported, maxSupported) {
94
+ const step = internals.stepIndex++, resolution = resolveWorkflowVersionPatch(internals.checkpointLocals, changeId, minSupported, maxSupported);
95
+ internals.checkpointLocals = resolution.checkpointLocals;
96
+ if (!resolution.newlyPinned)
97
+ return resolution.version;
98
+ if (internals.accumulatedResults?.has(step)) {
99
+ const cachedVersion = internals.accumulatedResults.get(step);
100
+ if (cachedVersion !== resolution.version)
101
+ throw Error(`ctx.getVersion("${changeId}") replay result ${String(cachedVersion)} does not match pinned version ${String(resolution.version)}`);
102
+ return resolution.version;
103
+ }
104
+ if (internals.explainMode) {
105
+ console.log(`[weft] ctx.getVersion("${changeId}", ${minSupported}, ${maxSupported})`);
106
+ console.log(` \u2192 Creating checkpoint at step ${step}`);
107
+ console.log(` \u2192 Pinning workflow patch "${changeId}" to version ${resolution.version}`);
108
+ }
109
+ const operationId = crypto.randomUUID(), callerStack = captureCallerStack();
110
+ return yield {
111
+ type: "get-version",
112
+ operationId,
113
+ changeId,
114
+ minSupported,
115
+ maxSupported,
116
+ version: resolution.version,
117
+ callerStack
118
+ };
119
+ }
56
120
  export function* waitForUpdate(context, internals, name) {
57
121
  const step = internals.stepIndex++;
58
122
  if (internals.accumulatedResults?.has(step))
@@ -1,6 +1,6 @@
1
1
  import type { ComposedWorkflowInterceptor } from '../interceptor.ts';
2
2
  import type { HumanReviewOptions, HumanReviewResult } from '../review/index.ts';
3
- import type { ActivityCallable, ActivityCallOptions, ChildWorkflowOptions, ChildWorkflowTarget, Duration, QueryDefinition, RunAllResult, SearchAttributeHandle, SearchAttributeValue, SignalDefinition, UpdateDefinition, WorkflowContext, WorkflowMapOptions, WorkflowOperation, WorkflowOperationTupleResult, WorkflowPipeStageDefinition, WorkflowReduceInput, WorkflowReduceOptions, WorkflowRunAllBranch, WorkflowStateNamespace } from '../types.ts';
3
+ import type { ActivityCallable, ActivityCallOptions, AwaitChildWorkflowOptions, ChildWorkflowHandle, ChildWorkflowTarget, DetachedChildWorkflowOptions, Duration, QueryDefinition, RunAllResult, SearchAttributeHandle, SearchAttributeValue, SignalDefinition, UpdateDefinition, WorkflowContext, WorkflowLogger, WorkflowMapOptions, WorkflowOperation, WorkflowOperationTupleResult, WorkflowPipeStageDefinition, WorkflowReduceInput, WorkflowReduceOptions, WorkflowRunAllBranch, WorkflowStateNamespace } from '../types.ts';
4
4
  import type { ContextOperationRequest } from './operation-request.ts';
5
5
  import type { ContextOptions, ErasedSagaStep, OffloadReference, StreamReference, StreamSink } from './types.ts';
6
6
  import * as contextUpdates from './updates.ts';
@@ -21,6 +21,7 @@ export declare function setContextWorkflowInterceptor(context: Context, workflow
21
21
  * ```
22
22
  */
23
23
  export declare class Context implements WorkflowContext {
24
+ #private;
24
25
  readonly workflowId: string;
25
26
  readonly workflowType: string;
26
27
  readonly startedAt: number;
@@ -28,6 +29,7 @@ export declare class Context implements WorkflowContext {
28
29
  constructor(options: ContextOptions);
29
30
  get executionTimeRemaining(): number;
30
31
  get services(): unknown;
32
+ get log(): WorkflowLogger;
31
33
  get stepIndex(): number;
32
34
  get nestingDepth(): number;
33
35
  get accumulatedResults(): Map<number, unknown>;
@@ -40,9 +42,6 @@ export declare class Context implements WorkflowContext {
40
42
  get explainEnabled(): boolean;
41
43
  get checkpointAccumulatedResults(): Array<[number, unknown]>;
42
44
  get checkpointPendingAttributeChanges(): Record<string, SearchAttributeValue> | undefined;
43
- get hasPendingAttributeChanges(): boolean;
44
- get hasUpdateHandlers(): boolean;
45
- get hasExposedAccessors(): boolean;
46
45
  createSpeculativeChild(): Context;
47
46
  commitSpeculativeChild(child: Context): void;
48
47
  get state(): WorkflowStateNamespace;
@@ -76,6 +75,9 @@ export declare class Context implements WorkflowContext {
76
75
  payload: T;
77
76
  respond: (result: unknown) => void;
78
77
  }, unknown>;
78
+ waitUntil(predicate: () => boolean): Generator<ContextOperationRequest, void, unknown>;
79
+ waitUntil(p: () => boolean, t: Duration): Generator<ContextOperationRequest, boolean, unknown>;
80
+ getVersion(changeId: string, minSupported: number, maxSupported: number): Generator<ContextOperationRequest, number, unknown>;
79
81
  review(options: HumanReviewOptions): Generator<ContextOperationRequest, HumanReviewResult, unknown>;
80
82
  all<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): Generator<ContextOperationRequest, WorkflowOperationTupleResult<TOperations>, unknown>;
81
83
  race<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): Generator<ContextOperationRequest, WorkflowOperationTupleResult<TOperations>[number], unknown>;
@@ -86,7 +88,8 @@ export declare class Context implements WorkflowContext {
86
88
  archive(key: string, data: unknown): Generator<ContextOperationRequest, void, unknown>;
87
89
  runAll<const TBranches extends Record<string, WorkflowRunAllBranch>>(branches: TBranches): Generator<ContextOperationRequest, RunAllResult<TBranches>, unknown>;
88
90
  saga<TFinalOutput = unknown>(steps: ErasedSagaStep[]): Generator<ContextOperationRequest, TFinalOutput, unknown>;
89
- startChild<TResult = unknown>(workflowType: string, input: unknown, options?: ChildWorkflowOptions): Generator<ContextOperationRequest, TResult, unknown>;
91
+ startChild<TResult = unknown>(workflowType: string, input: unknown, options: DetachedChildWorkflowOptions): Generator<ContextOperationRequest, ChildWorkflowHandle<TResult>, unknown>;
92
+ startChild<TResult = unknown>(workflowType: string, input: unknown, options?: AwaitChildWorkflowOptions): Generator<ContextOperationRequest, TResult, unknown>;
90
93
  pipe<TInput, TOutput>(stages: [WorkflowPipeStageDefinition<TInput, TOutput>], input: TInput): Generator<ContextOperationRequest, TOutput, unknown>;
91
94
  pipe<TInput, TIntermediate, TOutput>(stages: [
92
95
  WorkflowPipeStageDefinition<TInput, TIntermediate>,
@@ -120,5 +123,6 @@ export declare class Context implements WorkflowContext {
120
123
  onQuery(name: string, handler: (input: unknown) => unknown): void;
121
124
  expose(accessors: Record<string, () => unknown>): void;
122
125
  onCancel(handler: () => Promise<void> | void): void;
126
+ setFinalizerState(value: unknown): void;
123
127
  streamUrl(reference: StreamReference): string;
124
128
  }
@@ -14,6 +14,7 @@ import {
14
14
  } from "./speculative-child.js";
15
15
  import * as stateNamespaceHelpers from "./state-namespace.js";
16
16
  import * as contextUpdates from "./updates.js";
17
+ import { createInlineWorkflowLogger } from "./workflow-logger.js";
17
18
  export function setContextWorkflowInterceptor(context, workflowInterceptor) {
18
19
  getInternals(context).workflowInterceptor = workflowInterceptor;
19
20
  }
@@ -23,6 +24,7 @@ export class Context {
23
24
  workflowType;
24
25
  startedAt;
25
26
  signal;
27
+ #log;
26
28
  constructor(options) {
27
29
  this.workflowId = options.workflowId;
28
30
  this.workflowType = options.workflowType;
@@ -40,6 +42,9 @@ export class Context {
40
42
  get services() {
41
43
  return getInternals(this).services;
42
44
  }
45
+ get log() {
46
+ return this.#log ??= createInlineWorkflowLogger(this.workflowId, this.workflowType, () => getInternals(this), getInternals(this).logSink);
47
+ }
43
48
  get stepIndex() {
44
49
  return getInternals(this).stepIndex;
45
50
  }
@@ -90,18 +95,6 @@ export class Context {
90
95
  const pendingAttributeChanges = getInternals(this).pendingAttributeChanges;
91
96
  return pendingAttributeChanges ? { ...pendingAttributeChanges } : void 0;
92
97
  }
93
- get hasPendingAttributeChanges() {
94
- const pendingAttributeChanges = getInternals(this).pendingAttributeChanges;
95
- return pendingAttributeChanges !== void 0 && Object.keys(pendingAttributeChanges).length > 0;
96
- }
97
- get hasUpdateHandlers() {
98
- const updateHandlers = getInternals(this).updateHandlers;
99
- return updateHandlers !== void 0 && updateHandlers.size > 0;
100
- }
101
- get hasExposedAccessors() {
102
- const exposedValues = getInternals(this).exposedValues;
103
- return exposedValues !== void 0 && exposedValues.size > 0;
104
- }
105
98
  createSpeculativeChild() {
106
99
  return createSpeculativeChildState(this, (options) => new Context(options));
107
100
  }
@@ -146,6 +139,12 @@ export class Context {
146
139
  *waitForUpdate(nameOrDefinition) {
147
140
  return yield* durableOperations.waitForUpdate(this, getInternals(this), messageName(nameOrDefinition));
148
141
  }
142
+ *waitUntil(predicate, timeout) {
143
+ return yield* durableOperations.waitUntil(this, getInternals(this), predicate, timeout);
144
+ }
145
+ *getVersion(changeId, minSupported, maxSupported) {
146
+ return yield* durableOperations.getVersion(this, getInternals(this), changeId, minSupported, maxSupported);
147
+ }
149
148
  *review(options) {
150
149
  return yield* durableOperations.review(this, getInternals(this), options);
151
150
  }
@@ -221,6 +220,12 @@ export class Context {
221
220
  throw Error("ctx.onCancel() is only supported for inline workflow execution");
222
221
  internals.registerCancelHandler(handler);
223
222
  }
223
+ setFinalizerState(value) {
224
+ const internals = getInternals(this);
225
+ if (internals.recordFinalizerState === void 0)
226
+ throw Error("ctx.setFinalizerState() is only supported for inline workflow execution; it is unavailable in worker execution mode and inside ctx.speculate() branches.");
227
+ internals.recordFinalizerState(value);
228
+ }
224
229
  streamUrl(reference) {
225
230
  return `/v1/workflows/${encodeURIComponent(reference.workflowId)}/streams/${encodeURIComponent(reference.key)}`;
226
231
  }
@@ -1,5 +1,6 @@
1
1
  import type { ComposedWorkflowInterceptor } from '../interceptor.ts';
2
2
  import type { SearchAttributeSchema, SearchAttributeValue } from '../types.ts';
3
+ import type { WorkflowLogRecord } from '../types/workflow-log.ts';
3
4
  import type { Context, ContextOptions } from './index.ts';
4
5
  export interface ContextInternals {
5
6
  context: Context;
@@ -26,6 +27,25 @@ export interface ContextInternals {
26
27
  resolveWorkflowType: ((target: string | Function) => string) | undefined;
27
28
  registerCancelHandler: ((handler: () => Promise<void> | void) => () => void) | undefined;
28
29
  services: unknown;
30
+ /**
31
+ * Host sink for `ctx.log` records (`EngineOptions.onLog`), or `undefined` for the
32
+ * default console behavior. Captured by value when the `ctx.log` getter first
33
+ * builds its logger; `onLog` is fixed at engine construction, so there is nothing
34
+ * to re-read per emit.
35
+ */
36
+ logSink: ((record: WorkflowLogRecord) => void) | undefined;
37
+ /**
38
+ * Engine callback that durably records `ctx.setFinalizerState(value)` payloads
39
+ * (#446); `undefined` in speculative branches, where the branch reuses this
40
+ * inline {@link Context} but the engine leaves the callback unset, so
41
+ * `ctx.setFinalizerState` throws a descriptive guard error. (Worker-mode
42
+ * generators never reach this field at all — they receive a reduced worker-side
43
+ * context that does not carry `setFinalizerState`, so the call fails there with a
44
+ * `TypeError`.) Finalizer *registration* and teardown are unaffected — those run
45
+ * on the engine host in every mode (#564). Injected at context construction,
46
+ * mirroring {@link registerCancelHandler}.
47
+ */
48
+ recordFinalizerState: ((value: unknown) => void) | undefined;
29
49
  }
30
50
  export declare function initializeInternals(context: Context, options: ContextOptions, initialSessionState: Record<string, unknown> | undefined): void;
31
51
  export declare function getInternals(context: Context): ContextInternals;
@@ -25,7 +25,9 @@ export function initializeInternals(context, options, initialSessionState) {
25
25
  executionStateOwnerId: options.executionStateOwnerId ?? options.workflowId,
26
26
  resolveWorkflowType: options.resolveWorkflowType,
27
27
  registerCancelHandler: options.registerCancelHandler,
28
- services: options.services
28
+ services: options.services,
29
+ logSink: options.logSink,
30
+ recordFinalizerState: options.recordFinalizerState
29
31
  };
30
32
  INTERNALS.set(context, internals);
31
33
  }
@@ -58,6 +58,41 @@ export type ContextOperationRequest = {
58
58
  operationId: string;
59
59
  updateName: string;
60
60
  callerStack?: string;
61
+ } | {
62
+ type: 'wait-condition';
63
+ operationId: string;
64
+ /**
65
+ * Deterministic workflow step index for this `ctx.waitUntil` call. Stable
66
+ * across replay (unlike `operationId`, which is regenerated each yield), so
67
+ * it anchors both the deterministic deadline timer key
68
+ * (`cond:${workflowId}:${step}`) and the in-process condition waiter to a
69
+ * fixed step. Re-using a regenerated `operationId` would arm duplicate
70
+ * durable timers on recovery.
71
+ */
72
+ step: number;
73
+ /**
74
+ * The condition predicate. A non-serializable closure (like `memo.fn`) held
75
+ * in-process by the engine processor and re-evaluated on every wake; it is
76
+ * never checkpointed. The workflow re-yields a fresh request after each
77
+ * replay, so the engine always has a live closure to call. Must be pure and
78
+ * read only checkpoint-restored workflow-local state.
79
+ */
80
+ predicate: () => boolean;
81
+ /**
82
+ * Absolute deadline (epoch millis) after which the wait completes with
83
+ * `false`. Anchored once via `readOrInitConditionDeadline` so crash/replay
84
+ * never resets the window. Absent means "wait forever".
85
+ */
86
+ deadline?: number;
87
+ callerStack?: string;
88
+ } | {
89
+ type: 'get-version';
90
+ operationId: string;
91
+ changeId: string;
92
+ minSupported: number;
93
+ maxSupported: number;
94
+ version: number;
95
+ callerStack?: string;
61
96
  } | {
62
97
  type: 'parallel';
63
98
  operationId: string;
@@ -66,6 +66,15 @@ export type ParallelOperationCacheEntry = {
66
66
  * key list for `ctx.runAll`) differs from the cached entry on retry.
67
67
  * Indicates non-deterministic workflow code — branches must be stable
68
68
  * across retries.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * import { BranchTopologyChangedError } from '@lostgradient/weft';
73
+ *
74
+ * function isBranchTopologyChange(error: unknown): boolean {
75
+ * return error instanceof BranchTopologyChangedError;
76
+ * }
77
+ * ```
69
78
  */
70
79
  export declare class BranchTopologyChangedError extends WeftError<'BranchTopologyChangedError'> {
71
80
  constructor(message: string);
@@ -80,11 +89,11 @@ export declare function isParallelOperationCacheEntry(value: unknown): value is
80
89
  * replay behavior.
81
90
  *
82
91
  * NOT an `asserts` predicate: a value without the marker is also a
83
- * valid input here (it just means the cache slot held a non-parallel
84
- * legacy value). Callers still narrow via `isParallelOperationCacheEntry`
85
- * after calling this using `asserts` would over-narrow plain
86
- * non-parallel cached values and mark the legacy fallback paths
87
- * (`return cached as unknown[]`) as dead code in TypeScript.
92
+ * valid input here (it means the cache slot held a plain cached value).
93
+ * Callers still narrow via `isParallelOperationCacheEntry` after calling
94
+ * this. Using `asserts` would over-narrow plain non-parallel cached
95
+ * values and mark the current plain-value return path as dead code in
96
+ * TypeScript.
88
97
  */
89
98
  export declare function assertValidParallelOperationCacheEntry(value: unknown): void;
90
99
  /** Build a fresh v2 cache entry with the given branch slots. */
@@ -1,4 +1,5 @@
1
- import { type RetryPolicy, type WorkflowContext } from '../types.ts';
1
+ import { type Duration, type RetryPolicy, type WorkflowContext } from '../types.ts';
2
+ import { completeActivityRetryAttempt, readActivityRetryAttempt, readCompletedRetrySleepCount } from './activity-retry-state.ts';
2
3
  import type { Context } from './index.ts';
3
4
  import type { ContextOperationRequest } from './operation-request.ts';
4
5
  /**
@@ -27,7 +28,11 @@ interface RunActivityRequest<TResult> {
27
28
  cachedResult?: TResult;
28
29
  retryAttempt: number;
29
30
  retryPolicy?: RetryPolicy;
31
+ scheduleToCloseTimeout?: Duration;
30
32
  }
33
+ export declare const readActivityRetryAttemptForTesting: typeof readActivityRetryAttempt;
34
+ export declare const readCompletedRetrySleepCountForTesting: typeof readCompletedRetrySleepCount;
35
+ export declare const completeActivityRetryAttemptForTesting: typeof completeActivityRetryAttempt;
31
36
  export declare function shouldRetryActivityError(error: unknown, policy: RetryPolicy | undefined, attempt: number): policy is RetryPolicy;
32
37
  export declare function createRunActivityRequest<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[], explicitName?: string): RunActivityRequest<TResult>;
33
38
  export declare function runActivityWithRetry<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[], explicitName?: string): Generator<ContextOperationRequest, TResult, unknown>;
@@ -2,6 +2,19 @@ import { calculateBackoff } from "../scheduler.js";
2
2
  import {
3
3
  DEFAULT_RETRY_POLICY
4
4
  } from "../types.js";
5
+ import {
6
+ completeActivityRetryAttempt,
7
+ readActivityRetryAttempt,
8
+ readCompletedRetrySleepCount,
9
+ readOrInitActivityDispatchedAt,
10
+ writeActivityRetryAttempt
11
+ } from "./activity-retry-state.js";
12
+ import {
13
+ assertScheduleToCloseBudgetNotExhausted,
14
+ parseScheduleToCloseBudgetMs,
15
+ resolveActivityScheduleToCloseTimeout,
16
+ resolveActivityTimeout
17
+ } from "./activity-schedule-to-close.js";
5
18
  import { getInternals, hasContextInternals } from "./internals.js";
6
19
  import { isActivityCallOptions } from "./session-state.js";
7
20
  import { captureCallerStack } from "./validation.js";
@@ -10,7 +23,6 @@ export function asConcreteContext(context) {
10
23
  throw Error("Step-based workflows (compileStepWorkflow / ctx.step) require workflowExecutionMode: 'inline'. The worker execution strategy runs workflows with a different context that has no durable step machinery. Use the generator workflow API for worker execution mode.");
11
24
  return context;
12
25
  }
13
- const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState", ACTIVITY_RETRY_STATE_VERSION = 1, MAX_CHECKPOINTED_RETRY_ATTEMPT = 1e4;
14
26
  function acceptsNoActivityInput(fn) {
15
27
  if (typeof fn !== "function")
16
28
  return !1;
@@ -29,86 +41,14 @@ function parseRunArguments(activity, rest) {
29
41
  throw Error("ctx.run() accepts one activity input value plus optional ActivityCallOptions.");
30
42
  return { input: values[0], options };
31
43
  }
32
- function isRecord(value) {
33
- return typeof value === "object" && value !== null && !Array.isArray(value);
34
- }
35
- function isActivityRetryState(value) {
36
- return isRecord(value) && value.version === ACTIVITY_RETRY_STATE_VERSION && isRecord(value.attempts) && (value.completedRetrySleeps === void 0 || isRecord(value.completedRetrySleeps));
37
- }
38
- function assertValidRetryAttempt(attempt, step) {
39
- if (!Number.isInteger(attempt) || attempt <= 1 || attempt > MAX_CHECKPOINTED_RETRY_ATTEMPT)
40
- throw Error(`Invalid checkpointed activity retry attempt ${String(attempt)} for step ${String(step)}`);
41
- }
42
- function readActivityRetryAttempt(internals, step) {
43
- const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
44
- if (!isActivityRetryState(state))
45
- return;
46
- const attempt = state.attempts[String(step)];
47
- if (attempt === void 0)
48
- return;
49
- assertValidRetryAttempt(attempt, step);
50
- return attempt;
51
- }
52
- function readCompletedRetrySleepCount(internals, step) {
53
- const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
54
- if (!isActivityRetryState(state))
55
- return 0;
56
- const count = state.completedRetrySleeps?.[String(step)];
57
- if (count === void 0)
58
- return 0;
59
- if (!Number.isInteger(count) || count < 0 || count > MAX_CHECKPOINTED_RETRY_ATTEMPT)
60
- throw Error(`Invalid checkpointed activity retry sleep count ${String(count)} for step ${String(step)}`);
61
- return count;
62
- }
63
- function writeActivityRetryAttempt(internals, step, attempt) {
64
- assertValidRetryAttempt(attempt, step);
65
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY], attempts = isActivityRetryState(current) ? { ...current.attempts } : {};
66
- attempts[String(step)] = attempt;
67
- const completedRetrySleeps = isActivityRetryState(current) ? current.completedRetrySleeps : void 0;
68
- internals.checkpointLocals = {
69
- ...internals.checkpointLocals,
70
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
71
- version: ACTIVITY_RETRY_STATE_VERSION,
72
- attempts,
73
- ...completedRetrySleeps === void 0 ? {} : { completedRetrySleeps }
74
- }
75
- };
76
- }
77
- function clearActivityRetryAttempt(internals, step) {
78
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
79
- if (!isActivityRetryState(current))
44
+ export const readActivityRetryAttemptForTesting = readActivityRetryAttempt, readCompletedRetrySleepCountForTesting = readCompletedRetrySleepCount, completeActivityRetryAttemptForTesting = completeActivityRetryAttempt;
45
+ function resolveScheduleToCloseBudget(internals, step, scheduleToCloseTimeout) {
46
+ const budgetMs = parseScheduleToCloseBudgetMs(scheduleToCloseTimeout);
47
+ if (budgetMs === void 0)
80
48
  return;
81
- const attempts = { ...current.attempts };
82
- delete attempts[String(step)];
83
- const completedRetrySleeps = current.completedRetrySleeps, { [ACTIVITY_RETRY_STATE_LOCAL_KEY]: _removed, ...remainingLocals } = internals.checkpointLocals;
84
- if (Object.keys(attempts).length === 0 && completedRetrySleeps === void 0) {
85
- internals.checkpointLocals = remainingLocals;
86
- return;
87
- }
88
- internals.checkpointLocals = {
89
- ...remainingLocals,
90
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
91
- version: ACTIVITY_RETRY_STATE_VERSION,
92
- attempts,
93
- ...completedRetrySleeps === void 0 ? {} : { completedRetrySleeps }
94
- }
95
- };
96
- }
97
- function completeActivityRetryAttempt(internals, step, completedRetrySleepCount) {
98
- if (!Number.isInteger(completedRetrySleepCount) || completedRetrySleepCount < 0 || completedRetrySleepCount > MAX_CHECKPOINTED_RETRY_ATTEMPT)
99
- throw Error(`Invalid completed activity retry sleep count ${String(completedRetrySleepCount)} for step ${String(step)}`);
100
- clearActivityRetryAttempt(internals, step);
101
- if (completedRetrySleepCount === 0)
102
- return;
103
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY], attempts = isActivityRetryState(current) ? { ...current.attempts } : {}, completedRetrySleeps = isActivityRetryState(current) ? { ...current.completedRetrySleeps } : {};
104
- completedRetrySleeps[String(step)] = completedRetrySleepCount;
105
- internals.checkpointLocals = {
106
- ...internals.checkpointLocals,
107
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
108
- version: ACTIVITY_RETRY_STATE_VERSION,
109
- attempts,
110
- completedRetrySleeps
111
- }
49
+ return {
50
+ budgetMs,
51
+ dispatchedAt: readOrInitActivityDispatchedAt(internals, step, internals.getNow())
112
52
  };
113
53
  }
114
54
  function getActivityName(activity, explicitName) {
@@ -203,27 +143,38 @@ export function createRunActivityRequest(context, activity, rest, explicitName)
203
143
  const { input, options } = parseRunArguments(activity, rest), activityName = getActivityName(activity, explicitName), activityFunction = getActivityFunction(activity), internals = getInternals(context), step = internals.stepIndex++, cachedRequest = getCachedRunActivityRequest(internals, step, activityName, input);
204
144
  if (cachedRequest.hasCachedResult)
205
145
  return cachedRequest;
206
- const retryPolicy = resolveActivityRetryPolicy(activity, options);
146
+ const retryPolicy = resolveActivityRetryPolicy(activity, options), scheduleToCloseTimeout = resolveActivityScheduleToCloseTimeout(activity, options), effectiveTimeout = resolveActivityTimeout(activity, options), dispatchedOptions = effectiveTimeout === void 0 ? options : { ...options, timeout: effectiveTimeout };
207
147
  return {
208
- request: createFreshRunActivityRequest(internals, step, activityName, activityFunction, input, options),
148
+ request: createFreshRunActivityRequest(internals, step, activityName, activityFunction, input, dispatchedOptions),
209
149
  step,
210
150
  hasCachedResult: !1,
211
151
  retryAttempt: cachedRequest.retryAttempt,
212
- ...retryPolicy === void 0 ? {} : { retryPolicy }
152
+ ...retryPolicy === void 0 ? {} : { retryPolicy },
153
+ ...scheduleToCloseTimeout === void 0 ? {} : { scheduleToCloseTimeout }
213
154
  };
214
155
  }
215
156
  export function* runActivityWithRetry(context, activity, rest, explicitName) {
216
- const { request, step, hasCachedResult, cachedResult, retryAttempt, retryPolicy } = createRunActivityRequest(context, activity, rest, explicitName);
157
+ const {
158
+ request,
159
+ step,
160
+ hasCachedResult,
161
+ cachedResult,
162
+ retryAttempt,
163
+ retryPolicy,
164
+ scheduleToCloseTimeout
165
+ } = createRunActivityRequest(context, activity, rest, explicitName);
217
166
  if (hasCachedResult)
218
167
  return cachedResult;
219
- const internals = getInternals(context);
168
+ const internals = getInternals(context), budget = retryPolicy === void 0 ? void 0 : resolveScheduleToCloseBudget(internals, step, scheduleToCloseTimeout);
220
169
  let attempt = retryAttempt;
221
170
  if (attempt > 1) {
222
171
  if (retryPolicy === void 0)
223
172
  throw Error(`Missing activity retry policy for checkpointed retry attempt ${attempt}`);
224
173
  yield* context.sleep(calculateBackoff(attempt - 1, retryPolicy));
225
174
  }
226
- while (!0)
175
+ while (!0) {
176
+ if (attempt > 1)
177
+ assertScheduleToCloseBudgetNotExhausted(budget, request.activityName, internals.getNow());
227
178
  try {
228
179
  const result = yield prepareActivityRetryRequest(request, attempt);
229
180
  context.accumulatedResults.set(step, result);
@@ -232,9 +183,12 @@ export function* runActivityWithRetry(context, activity, rest, explicitName) {
232
183
  } catch (error) {
233
184
  if (!shouldRetryActivityError(error, retryPolicy, attempt))
234
185
  throw error;
186
+ const backoff = calculateBackoff(attempt, retryPolicy), now = internals.getNow();
187
+ assertScheduleToCloseBudgetNotExhausted(budget, request.activityName, now, now + backoff);
235
188
  const nextAttempt = attempt + 1;
236
189
  writeActivityRetryAttempt(internals, step, nextAttempt);
237
- yield* context.sleep(calculateBackoff(attempt, retryPolicy));
190
+ yield* context.sleep(backoff);
238
191
  attempt = nextAttempt;
239
192
  }
193
+ }
240
194
  }
@@ -4,23 +4,24 @@ import {
4
4
  cloneSessionStateValue,
5
5
  createSessionStateStore,
6
6
  hasSessionStateKey,
7
- LEGACY_SESSION_STATE_LOCAL_KEY,
8
7
  SESSION_STATE_LOCAL_KEY,
9
8
  validateSessionStateStore
10
9
  } from "../session-state.js";
11
- const EMPTY_CHECKPOINT_LOCALS = Object.freeze({}), ACTIVITY_CALL_OPTION_KEYS = new Set([
10
+ const EMPTY_CHECKPOINT_LOCALS = Object.freeze({}), RETIRED_SESSION_STATE_LOCAL_KEY = "sessionState", ACTIVITY_CALL_OPTION_KEYS = new Set([
12
11
  "timeout",
13
12
  "queue",
14
13
  "retry",
15
14
  "idempotencyKey",
16
15
  "sticky",
17
- "visibilityTimeout"
16
+ "visibilityTimeout",
17
+ "scheduleToCloseTimeout"
18
18
  ]), DISCRIMINATOR_KEYS = new Set([
19
19
  "queue",
20
20
  "retry",
21
21
  "idempotencyKey",
22
22
  "sticky",
23
- "visibilityTimeout"
23
+ "visibilityTimeout",
24
+ "scheduleToCloseTimeout"
24
25
  ]);
25
26
  export function isActivityCallOptions(value) {
26
27
  if (value === null || typeof value !== "object" || Array.isArray(value))
@@ -37,7 +38,7 @@ export function isActivityCallOptions(value) {
37
38
  return !1;
38
39
  }
39
40
  export function createCheckpointLocals(stateSessionStore, existingLocals) {
40
- const localEntries = existingLocals === void 0 ? [] : Object.entries(existingLocals).filter(([key]) => key !== SESSION_STATE_LOCAL_KEY && key !== LEGACY_SESSION_STATE_LOCAL_KEY);
41
+ const localEntries = existingLocals === void 0 ? [] : Object.entries(existingLocals).filter(([key]) => key !== SESSION_STATE_LOCAL_KEY && key !== RETIRED_SESSION_STATE_LOCAL_KEY);
41
42
  if (stateSessionStore === void 0) {
42
43
  if (localEntries.length === 0)
43
44
  return EMPTY_CHECKPOINT_LOCALS;
@@ -73,9 +74,7 @@ export function clearSessionStateValue(internals, key) {
73
74
  assertValidSessionStateKey(key);
74
75
  if (!internals.stateSession || !hasSessionStateKey(internals.stateSession, key))
75
76
  return;
76
- const candidate = cloneSessionStateStore(internals.stateSession);
77
- if (!candidate)
78
- return;
77
+ const candidate = cloneSessionStateStore(internals.stateSession) ?? createSessionStateStore();
79
78
  delete candidate[key];
80
79
  commitSessionStateStore(internals, Object.keys(candidate).length === 0 ? void 0 : candidate);
81
80
  }
@@ -18,6 +18,8 @@ function assignOptionalContextOptions(options, internals) {
18
18
  options.resolveWorkflowType = internals.resolveWorkflowType;
19
19
  if (internals.services !== void 0)
20
20
  options.services = internals.services;
21
+ if (internals.logSink !== void 0)
22
+ options.logSink = internals.logSink;
21
23
  }
22
24
  function createSpeculativeChildOptions(parent, internals) {
23
25
  const options = {
@@ -1,4 +1,5 @@
1
1
  import type { ActivityDefinition, SearchAttributeSchema, SearchAttributeValue } from '../types.ts';
2
+ import type { WorkflowLogRecord } from '../types/workflow-log.ts';
2
3
  /**
3
4
  * A single step in a saga: an activity definition and the input to pass to it.
4
5
  *
@@ -184,4 +185,18 @@ export interface ContextOptions {
184
185
  * engine's `resolveWorkflowServices` resolver.
185
186
  */
186
187
  services?: unknown;
188
+ /**
189
+ * Host sink for `ctx.log` records (`EngineOptions.onLog`). When set, non-replayed
190
+ * records route here instead of the console; when absent, the default console
191
+ * behavior is preserved. Never checkpointed.
192
+ */
193
+ logSink?: (record: WorkflowLogRecord) => void;
194
+ /**
195
+ * Called by `ctx.setFinalizerState(value)` (#446) to durably record the payload
196
+ * the engine passes to the workflow's `finalizer` activity on cancel/timeout
197
+ * teardown. The engine stages it as a pending atomic side-effect so it commits
198
+ * with the next checkpoint or the terminal batch. Absent for worker-mode and
199
+ * speculative contexts, where `ctx.setFinalizerState` is unsupported.
200
+ */
201
+ recordFinalizerState?: (value: unknown) => void;
187
202
  }
@@ -0,0 +1,8 @@
1
+ export declare const WORKFLOW_VERSION_LOCAL_PREFIX = "version:";
2
+ export type WorkflowVersionPatchResolution = {
3
+ localKey: string;
4
+ version: number;
5
+ newlyPinned: boolean;
6
+ checkpointLocals: Record<string, unknown>;
7
+ };
8
+ export declare function resolveWorkflowVersionPatch(checkpointLocals: Record<string, unknown>, changeId: string, minSupported: number, maxSupported: number): WorkflowVersionPatchResolution;