@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
@@ -39,7 +39,7 @@ import type { WorkflowDefinition, WorkflowOperation } from './workflow-function.
39
39
  * void job;
40
40
  * ```
41
41
  */
42
- export type WorkflowGenerator<TInput, TOutput, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema> = (context: WorkflowContextOf<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes>, input: TInput) => AsyncGenerator<unknown, TOutput, unknown>;
42
+ export type WorkflowGenerator<TInput, TOutput, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema, TServices = unknown> = (context: WorkflowContextOf<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, TServices>, input: TInput) => AsyncGenerator<unknown, TOutput, unknown>;
43
43
  /**
44
44
  * Convenience alias for the workflow-scoped `WorkflowContext` projection. The
45
45
  * underlying `WorkflowContext` interface accepts the same five generic
@@ -53,7 +53,7 @@ export type WorkflowGenerator<TInput, TOutput, TActivities extends ActivityMap,
53
53
  * callable overloads match instead. This permissive path is current API — it is
54
54
  * how untyped, ad-hoc-name authoring is supported, not a compatibility shim.
55
55
  */
56
- export type WorkflowContextOf<TActivities extends ActivityMap = ActivityMap, TSignals extends SignalMap = SignalMap, TUpdates extends UpdateMap = UpdateMap, TQueries extends QueryMap = QueryMap, TSearchAttributes extends SearchAttributeSchema = SearchAttributeSchema> = WorkflowContext<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes>;
56
+ export type WorkflowContextOf<TActivities extends ActivityMap = ActivityMap, TSignals extends SignalMap = SignalMap, TUpdates extends UpdateMap = UpdateMap, TQueries extends QueryMap = QueryMap, TSearchAttributes extends SearchAttributeSchema = SearchAttributeSchema, TServices = unknown> = WorkflowContext<TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, TServices>;
57
57
  /**
58
58
  * Tracks which `WorkflowBuilder` chain methods have already been called. Each
59
59
  * call flips its flag from `false` to `true`; the method's type becomes `never`
@@ -82,6 +82,7 @@ export interface BuilderState {
82
82
  readonly updates: boolean;
83
83
  readonly queries: boolean;
84
84
  readonly searchAttributes: boolean;
85
+ readonly services?: boolean | undefined;
85
86
  }
86
87
  /**
87
88
  * Initial builder state — every chain method is still available. A fresh
@@ -102,6 +103,7 @@ export interface InitialBuilderState {
102
103
  readonly updates: false;
103
104
  readonly queries: false;
104
105
  readonly searchAttributes: false;
106
+ readonly services?: false | undefined;
105
107
  }
106
108
  /**
107
109
  * Flip one builder-state flag from `false` to `true`. Each chain method on
@@ -118,7 +120,9 @@ export interface InitialBuilderState {
118
120
  * void _check;
119
121
  * ```
120
122
  */
121
- export type MarkBuilderState<S extends BuilderState, K extends keyof BuilderState> = {
123
+ export type MarkBuilderState<S extends BuilderState, K extends keyof BuilderState> = K extends 'services' ? Omit<S, 'services'> & {
124
+ readonly services: true;
125
+ } : {
122
126
  readonly [P in keyof S]: P extends K ? true : S[P];
123
127
  };
124
128
  declare const workflowAlreadyRegisteredBrand: unique symbol;
@@ -176,7 +180,7 @@ export interface WorkflowAlreadyRegistered<TName extends string> {
176
180
  * void welcome;
177
181
  * ```
178
182
  */
179
- export interface WorkflowBuilder<TName extends string, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema, TState extends BuilderState> {
183
+ export interface WorkflowBuilder<TName extends string, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema, TState extends BuilderState, TServices = unknown> {
180
184
  /**
181
185
  * Declare the activity table this workflow can dispatch with
182
186
  * `ctx.run('name', input)`. The outer object key is the canonical activity
@@ -196,7 +200,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
196
200
  * void welcome;
197
201
  * ```
198
202
  */
199
- activities: TState['activities'] extends true ? never : <TInput extends ActivityMapInput>(map: TInput) => WorkflowBuilder<TName, NormalizeActivities<TInput>, TSignals, TUpdates, TQueries, TSearchAttributes, MarkBuilderState<TState, 'activities'>>;
203
+ activities: TState['activities'] extends true ? never : <TInput extends ActivityMapInput>(map: TInput) => WorkflowBuilder<TName, NormalizeActivities<TInput>, TSignals, TUpdates, TQueries, TSearchAttributes, MarkBuilderState<TState, 'activities'>, TServices>;
200
204
  /**
201
205
  * Declare the signals this workflow accepts so `ctx.waitForSignal('name')`
202
206
  * autocompletes and types the payload. Type-safety and introspection
@@ -215,7 +219,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
215
219
  * void approval;
216
220
  * ```
217
221
  */
218
- signals: TState['signals'] extends true ? never : <TInput extends SignalMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TInput, TUpdates, TQueries, TSearchAttributes, MarkBuilderState<TState, 'signals'>>;
222
+ signals: TState['signals'] extends true ? never : <TInput extends SignalMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TInput, TUpdates, TQueries, TSearchAttributes, MarkBuilderState<TState, 'signals'>, TServices>;
219
223
  /**
220
224
  * Declare the request-response update handlers this workflow accepts.
221
225
  * Type-safety and introspection metadata only — the update-dispatch path
@@ -231,7 +235,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
231
235
  * void order;
232
236
  * ```
233
237
  */
234
- updates: TState['updates'] extends true ? never : <TInput extends UpdateMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TInput, TQueries, TSearchAttributes, MarkBuilderState<TState, 'updates'>>;
238
+ updates: TState['updates'] extends true ? never : <TInput extends UpdateMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TInput, TQueries, TSearchAttributes, MarkBuilderState<TState, 'updates'>, TServices>;
235
239
  /**
236
240
  * Declare the read-only query handlers this workflow accepts. Type-safety
237
241
  * and introspection metadata only — `.queries` does not introduce new
@@ -247,7 +251,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
247
251
  * void job;
248
252
  * ```
249
253
  */
250
- queries: TState['queries'] extends true ? never : <TInput extends QueryMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TUpdates, TInput, TSearchAttributes, MarkBuilderState<TState, 'queries'>>;
254
+ queries: TState['queries'] extends true ? never : <TInput extends QueryMap>(map: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TUpdates, TInput, TSearchAttributes, MarkBuilderState<TState, 'queries'>, TServices>;
251
255
  /**
252
256
  * Declare the search-attribute schema this workflow populates via
253
257
  * `ctx.setAttribute('key', value)`. Each entry pins the attribute's value
@@ -267,7 +271,32 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
267
271
  * void order;
268
272
  * ```
269
273
  */
270
- searchAttributes: TState['searchAttributes'] extends true ? never : <TInput extends SearchAttributeSchema>(schema: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TUpdates, TQueries, TInput, MarkBuilderState<TState, 'searchAttributes'>>;
274
+ searchAttributes: TState['searchAttributes'] extends true ? never : <TInput extends SearchAttributeSchema>(schema: TInput) => WorkflowBuilder<TName, TActivities, TSignals, TUpdates, TQueries, TInput, MarkBuilderState<TState, 'searchAttributes'>, TServices>;
275
+ /**
276
+ * Declare the per-run services type exposed at `ctx.services`. This is a
277
+ * type-only marker: services remain supplied at launch through
278
+ * `engine.start(type, input, { services })` and re-provided on recovery by
279
+ * `EngineOptions.resolveWorkflowServices`. Calling `.services` twice before
280
+ * `.execute()` is a type error and throws `WorkflowBuilderError` at runtime.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * import { workflow } from '@lostgradient/weft';
285
+ *
286
+ * interface Services {
287
+ * repository: { load(id: string): Promise<string> };
288
+ * }
289
+ *
290
+ * const job = workflow({ name: 'job' })
291
+ * .services<Services>()
292
+ * .execute(async function* (ctx, id: string) {
293
+ * const services = ctx.services;
294
+ * return services === undefined ? id : yield* ctx.run(() => services.repository.load(id));
295
+ * });
296
+ * void job;
297
+ * ```
298
+ */
299
+ services: TState['services'] extends true ? never : <TInput>() => WorkflowBuilder<TName, TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, MarkBuilderState<TState, 'services'>, TInput>;
271
300
  /**
272
301
  * Seal the builder and produce a `BuiltWorkflowDefinition`. The generator's
273
302
  * `input` and `output` types are re-inferred from `fn`'s signature, so the
@@ -288,7 +317,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
288
317
  * void welcome;
289
318
  * ```
290
319
  */
291
- execute<TInput, TOutput>(fn: WorkflowGenerator<TInput, TOutput, TActivities, TSignals, TUpdates, TQueries, TSearchAttributes>): BuiltWorkflowDefinition<TInput, Awaited<TOutput>, TName, TActivities, TSignals, TUpdates, TQueries, TSearchAttributes>;
320
+ execute<TInput, TOutput>(fn: WorkflowGenerator<TInput, TOutput, TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, TServices>): BuiltWorkflowDefinition<TInput, Awaited<TOutput>, TName, TActivities, TSignals, TUpdates, TQueries, TSearchAttributes, TServices>;
292
321
  }
293
322
  /**
294
323
  * The `WorkflowDefinition` returned by `.execute(fn)`. Carries the normalised
@@ -319,7 +348,7 @@ export interface WorkflowBuilder<TName extends string, TActivities extends Activ
319
348
  * void built;
320
349
  * ```
321
350
  */
322
- export interface BuiltWorkflowDefinition<TInput, TOutput, TName extends string, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema> extends WorkflowDefinition<TInput, TOutput, TName> {
351
+ export interface BuiltWorkflowDefinition<TInput, TOutput, TName extends string, TActivities extends ActivityMap, TSignals extends SignalMap, TUpdates extends UpdateMap, TQueries extends QueryMap, TSearchAttributes extends SearchAttributeSchema, TServices = unknown> extends WorkflowDefinition<TInput, TOutput, TName, TServices> {
323
352
  readonly activities: Readonly<Record<string, Readonly<ActivityDefinition>>>;
324
353
  readonly signals: Readonly<Record<string, Readonly<SignalDefinition<unknown>>>>;
325
354
  readonly updates: Readonly<Record<string, Readonly<UpdateDefinition>>>;
@@ -335,6 +364,8 @@ export interface BuiltWorkflowDefinition<TInput, TOutput, TName extends string,
335
364
  readonly _queries?: TQueries;
336
365
  /** Phantom marker for the search-attribute schema. Not present at runtime. */
337
366
  readonly _searchAttributes?: TSearchAttributes;
367
+ /** Phantom marker for the per-run services type. Not present at runtime. */
368
+ readonly _services?: TServices;
338
369
  }
339
370
  /**
340
371
  * Re-exported so Phase 2 (`workflow()` runtime rewrite) and Phase 3 (engine
@@ -0,0 +1,39 @@
1
+ type WorkflowConcurrencyKeyResolver<TInput> = {
2
+ resolve(input: TInput): string;
3
+ }['resolve'];
4
+ /**
5
+ * Workflow-level start admission policy. When present on a workflow definition,
6
+ * the engine admits at most `max` non-terminal runs for the same partition.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { workflow, type WorkflowConcurrencyOptions } from '@lostgradient/weft';
11
+ *
12
+ * type OrderInput = { customerId: string };
13
+ *
14
+ * const concurrency: WorkflowConcurrencyOptions<OrderInput> = {
15
+ * max: 3,
16
+ * key: (input) => input.customerId,
17
+ * };
18
+ *
19
+ * const processOrder = workflow({ name: 'process-order', concurrency }).execute(
20
+ * async function* () {
21
+ * return 'done';
22
+ * },
23
+ * );
24
+ * void processOrder;
25
+ * ```
26
+ */
27
+ export interface WorkflowConcurrencyOptions<TInput = unknown> {
28
+ /**
29
+ * Maximum number of non-terminal runs admitted for the workflow type or
30
+ * partition key. Excess starts are rejected immediately.
31
+ */
32
+ max: number;
33
+ /**
34
+ * Optional partition key resolver. When omitted, the limit applies to the
35
+ * workflow type as a whole.
36
+ */
37
+ key?: WorkflowConcurrencyKeyResolver<TInput>;
38
+ }
39
+ export {};
File without changes
@@ -9,7 +9,8 @@ import type { Duration } from './retry-retention.ts';
9
9
  import type { SearchAttributeHandle, SearchAttributeSchema, SearchAttributeValue, SearchAttributeValueForDefinition } from './search-attributes.ts';
10
10
  import type { WorkflowStateNamespace } from './state.ts';
11
11
  import type { ActivityArgsFor, ActivityMap, ActivityResultFor, QueryMap, QueryShape, SignalMap, SignalPayload, UpdateMap, UpdatePayload } from './workflow-builder-helpers.ts';
12
- import type { ChildWorkflowOptions, ChildWorkflowTarget, WorkflowMapOptions, WorkflowOperation, WorkflowPipeStage, WorkflowPipeStageDefinition, WorkflowReduceInput, WorkflowReduceOptions } from './workflow-function.ts';
12
+ import type { AwaitChildWorkflowOptions, ChildWorkflowHandle, ChildWorkflowOptions, ChildWorkflowTarget, DetachedChildWorkflowOptions, WorkflowMapOptions, WorkflowOperation, WorkflowPipeStage, WorkflowPipeStageDefinition, WorkflowReduceInput, WorkflowReduceOptions } from './workflow-function.ts';
13
+ import type { WorkflowLogger } from './workflow-log.ts';
13
14
  export type WorkflowOperationResult<TOperation> = TOperation extends Generator<unknown, infer TResult, unknown> ? TResult : never;
14
15
  export type WorkflowOperationTupleResult<TOperations extends readonly WorkflowOperation<unknown>[]> = {
15
16
  -readonly [TIndex in keyof TOperations]: WorkflowOperationResult<TOperations[TIndex]>;
@@ -51,8 +52,14 @@ export type RunAllResult<TBranches extends Record<string, WorkflowRunAllBranch>>
51
52
  * void engine;
52
53
  * ```
53
54
  */
54
- export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals extends SignalMap = {}, TUpdates extends UpdateMap = {}, TQueries extends QueryMap = {}, TSearchAttributes extends SearchAttributeSchema = {}> {
55
+ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals extends SignalMap = {}, TUpdates extends UpdateMap = {}, TQueries extends QueryMap = {}, TSearchAttributes extends SearchAttributeSchema = {}, TServices = unknown> {
55
56
  readonly workflowId: WorkflowId;
57
+ /**
58
+ * The registered workflow type name for this run (the `name` field from
59
+ * `workflow({ name: '...' })`). Useful for logging and self-inspection
60
+ * without capturing the name at the workflow definition site.
61
+ */
62
+ readonly workflowType: string;
56
63
  readonly signal: AbortSignal;
57
64
  readonly executionTimeRemaining: number;
58
65
  readonly startedAt: number;
@@ -63,15 +70,16 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
63
70
  * clients, tool registries). The value is **never checkpointed**: it is held
64
71
  * only in engine memory for this run, and on a fresh-process recovery it is
65
72
  * re-provided by the engine's `resolveWorkflowServices` resolver before the
66
- * generator advances. `undefined` when no services were supplied (and not yet
67
- * re-provided on recovery). Inline execution mode only passing `services`
68
- * under `workflowExecutionMode: 'worker'` throws at `engine.start()`, since a
73
+ * generator advances. `undefined` only when no services were supplied; a
74
+ * services-marked run fails before resume if the fresh engine cannot
75
+ * re-provide them. Inline execution mode only — passing `services` under
76
+ * `workflowExecutionMode: 'worker'` throws at `engine.start()`, since a
69
77
  * non-serializable value cannot cross to a Worker.
70
78
  *
71
- * Typed `unknown`: narrow or cast at the call site
72
- * (`const { db } = ctx.services as MyServices`). A threaded generic is a
73
- * deliberate follow-on, not part of this surface yet. Optional so existing
74
- * structural `WorkflowContext` implementors are not source-broken.
79
+ * Typed by the workflow definition when the builder declares
80
+ * `.services<MyServices>()`, and `unknown` otherwise. Optional so existing
81
+ * structural `WorkflowContext` implementors are not source-broken and so
82
+ * workflows still handle no-services launches explicitly.
75
83
  *
76
84
  * Separate child *workflows* started from within a workflow (`ctx.startChild()`)
77
85
  * do **not** inherit the parent's `services` — each run is its own workflow with
@@ -81,7 +89,21 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
81
89
  * replay (same `workflowId`) and therefore does carry the run's `services`
82
90
  * across.
83
91
  */
84
- readonly services?: unknown;
92
+ readonly services?: TServices;
93
+ /**
94
+ * Structured logger scoped to this run, auto-carrying `workflowId` and
95
+ * `workflowType`. Replay-safe in both inline and worker execution modes: log
96
+ * calls in the already-committed replay window are suppressed so a recovered
97
+ * run does not re-emit logs. See {@link WorkflowLogger} for the full contract
98
+ * (method set, the after-last-step caveat, and parallel-branch semantics).
99
+ *
100
+ * Optional on the interface so existing structural `WorkflowContext`
101
+ * implementors (test stubs and the like) are not source-broken — the same
102
+ * precedent as {@link WorkflowContext.services}. The engine always populates it
103
+ * at runtime, so within a real workflow body `ctx.log` is always present; the
104
+ * `?` only affects callers typed against the bare interface (use `ctx.log?.`).
105
+ */
106
+ readonly log?: WorkflowLogger;
85
107
  run<TName extends keyof TActivities & string>(name: TName, ...rest: ActivityArgsFor<TActivities[TName]>): WorkflowOperation<ActivityResultFor<TActivities[TName]>>;
86
108
  run<TName extends keyof TActivities & string>(name: TName, ...rest: [...ActivityArgsFor<TActivities[TName]>, ActivityCallOptions]): WorkflowOperation<ActivityResultFor<TActivities[TName]>>;
87
109
  run<TName extends string>(name: UnknownNameWhenRegistryHasNoKnownNames<TName, keyof TActivities & string>, input?: unknown, options?: ActivityCallOptions): WorkflowOperation<unknown>;
@@ -107,6 +129,47 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
107
129
  payload: T;
108
130
  respond: (result: unknown) => void;
109
131
  }>;
132
+ /**
133
+ * Wait until `predicate` returns `true`, re-evaluated by the engine each time
134
+ * the workflow is driven forward — when an `onUpdate` handler mutates
135
+ * workflow-local state, or when the optional `timeout` elapses. This is the
136
+ * condition-variable primitive (Temporal's `condition()`): a `waitUntil` whose
137
+ * predicate reads state mutated by `onUpdate` handlers re-checks in-process
138
+ * without polling. (Weft signals are pull-only via `ctx.waitForSignal`; they
139
+ * run no state-mutating handler, so signal delivery does not re-drive a
140
+ * `waitUntil` — use `onUpdate` to push state a predicate observes.)
141
+ *
142
+ * The predicate must be PURE — it may read only checkpoint-restored
143
+ * workflow-local state (`ctx.state`, locals, search attributes) and must not
144
+ * perform I/O, generate randomness, or read wall-clock time. It is a
145
+ * non-serializable closure (like `ctx.memo`'s function), held in-process and
146
+ * never checkpointed. Once the wait outcome has been checkpointed, replay
147
+ * returns the cached outcome and does not re-invoke the predicate. A predicate
148
+ * that throws fails the workflow at the `yield* ctx.waitUntil` call site (like
149
+ * a throwing activity), so the workflow body can `try`/`catch` it.
150
+ *
151
+ * Inline execution only — worker execution does not expose this operation (it
152
+ * is omitted from the worker context type), because the predicate closure
153
+ * cannot cross to a worker process. It also cannot be a branch of `ctx.race`,
154
+ * `ctx.all`, or `ctx.speculate`; used there it throws an actionable error.
155
+ *
156
+ * Without `timeout` it resolves `void` once the predicate is met (waits
157
+ * forever). With `timeout` it resolves `true` when the predicate was met or
158
+ * `false` when the deadline elapsed first; if both happen on the same tick the
159
+ * predicate wins (resolves `true`). `timeout` is milliseconds (`number`) or a
160
+ * duration string (`'30s'`, `'5m'` — see {@link Duration}).
161
+ */
162
+ waitUntil(predicate: () => boolean): WorkflowOperation<void>;
163
+ waitUntil(predicate: () => boolean, timeout: Duration): WorkflowOperation<boolean>;
164
+ /**
165
+ * Pin a named workflow patch to a deterministic numeric version. The first
166
+ * execution stores `maxSupported` under `version:${changeId}` in checkpoint
167
+ * locals; replay and recovery return that stored value so in-flight workflows
168
+ * can keep taking their original branch while new runs pin the newer version.
169
+ * Raise `minSupported` only after every in-flight run pinned below that version
170
+ * has completed.
171
+ */
172
+ getVersion(changeId: string, minSupported: number, maxSupported: number): WorkflowOperation<number>;
110
173
  review(options: HumanReviewOptions): WorkflowOperation<HumanReviewResult>;
111
174
  all<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): WorkflowOperation<WorkflowOperationTupleResult<TOperations>>;
112
175
  race<const TOperations extends readonly WorkflowOperation<unknown>[]>(operations: TOperations): WorkflowOperation<WorkflowOperationTupleResult<TOperations>[number]>;
@@ -123,7 +186,9 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
123
186
  * durable activity pipeline and is not replayed after engine restart.
124
187
  */
125
188
  saga<TFinalOutput = unknown>(steps: ErasedSagaStep[]): WorkflowOperation<TFinalOutput>;
126
- startChild<TResult = unknown>(workflowType: string, input: unknown, options?: ChildWorkflowOptions): WorkflowOperation<TResult>;
189
+ startChild<TResult = unknown>(workflowType: string, input: unknown, options: DetachedChildWorkflowOptions): WorkflowOperation<ChildWorkflowHandle<TResult>>;
190
+ startChild<TResult = unknown>(workflowType: string, input: unknown, options?: AwaitChildWorkflowOptions): WorkflowOperation<TResult>;
191
+ startChild<TResult = unknown>(workflowType: string, input: unknown, options?: ChildWorkflowOptions): WorkflowOperation<TResult | ChildWorkflowHandle<TResult>>;
127
192
  pipe<TInput, TOutput>(stages: [WorkflowPipeStageDefinition<TInput, TOutput>], input: TInput): WorkflowOperation<TOutput>;
128
193
  pipe<TInput, TIntermediate, TOutput>(stages: [
129
194
  WorkflowPipeStageDefinition<TInput, TIntermediate>,
@@ -170,10 +235,27 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
170
235
  *
171
236
  * **Best-effort only**: handlers run outside the durable effect log and are
172
237
  * not retried. Side effects in handlers are not replay-safe, and registered
173
- * handlers are not restored after an engine restart.
238
+ * handlers are not restored after an engine restart. A hard cancel or an
239
+ * engine crash that evicts the workflow before the handler runs loses it.
240
+ *
241
+ * **Prefer a durable `finalizer` for resource teardown.** To tear down a paid
242
+ * external resource (a sandbox, a leased VM) so it is destroyed even across a
243
+ * hard cancel or a crash, record the resource with
244
+ * {@link WorkflowContext.setFinalizerState} and declare a definition-level
245
+ * `finalizer` activity — the engine drives it durably post-terminal. `onCancel`
246
+ * remains the right tool for in-process, best-effort cleanup (releasing an
247
+ * in-memory lock, flushing a buffer) where durability is not required.
248
+ * Registering a `finalizer` works in both inline and worker mode; only the
249
+ * in-generator `ctx.setFinalizerState` call requires inline execution (see
250
+ * `setFinalizerState`).
174
251
  *
175
- * **Worker-pool mode**: this method throws when the engine uses a remote
176
- * worker pool so teardown does not silently drop.
252
+ * **Inline-only**: `onCancel` is in-process host wiring available only under
253
+ * inline execution. A handler annotated `(ctx: WorkflowContext)` type-checks the
254
+ * call (the static type declares it), but at runtime in worker mode the
255
+ * generator's `ctx` is a reduced worker-side context that does not carry
256
+ * `onCancel`, so the call fails with a `TypeError` rather than silently dropping
257
+ * teardown. (Inside a `ctx.speculate()` branch the method is present but its
258
+ * engine callback is unset, so it throws a descriptive guard error instead.)
177
259
  *
178
260
  * @example
179
261
  * ```ts
@@ -189,5 +271,66 @@ export interface WorkflowContext<TActivities extends ActivityMap = {}, TSignals
189
271
  * ```
190
272
  */
191
273
  onCancel(handler: () => Promise<void> | void): void;
274
+ /**
275
+ * Durably record the payload the engine passes to this workflow's
276
+ * definition-level `finalizer` activity when it drives teardown after a
277
+ * `cancelled` or `timed-out` terminal (issue #446).
278
+ *
279
+ * Call this immediately after acquiring a paid external resource, passing
280
+ * whatever the finalizer needs to destroy it (e.g. a sandbox id). The value is
281
+ * durably staged — as a pending atomic side-effect committed with the next
282
+ * checkpoint or the terminal transition, fenced under lease ownership — so the
283
+ * finalizer can run even across a hard cancel or an engine crash. Recording is
284
+ * the engine's signal that there is something to tear down: if the workflow
285
+ * never calls this, the engine skips the finalizer entirely. Recording `null`
286
+ * is different — it still counts as recorded, so the finalizer runs with a
287
+ * `null` payload. The value is last-write-wins, so a later call replaces the
288
+ * earlier one — record the id of the resource that is currently live.
289
+ *
290
+ * **The finalizer runs at least once and must be idempotent.** The engine
291
+ * drives it with bounded retries and re-drives a stale claim after a crash, so
292
+ * the same payload can reach the finalizer more than once (the same contract as
293
+ * keying a destroy by `sandboxId`). Make the teardown safe to repeat —
294
+ * destroying an already-destroyed resource must succeed (or no-op), not throw.
295
+ *
296
+ * Calling this after the workflow is already terminalizing is a no-op (a
297
+ * development warning is logged); finalizer state is recordable only while the
298
+ * workflow is live.
299
+ *
300
+ * **Inline-only caveat**: this method is durable host wiring, available only
301
+ * under inline execution — but its absence surfaces differently per path:
302
+ *
303
+ * - *Inline, top level*: the engine wires up the callback this method delegates
304
+ * to, so it records state.
305
+ * - *Inside a `ctx.speculate()` branch*: the branch reuses the same
306
+ * {@link WorkflowContext}, so `setFinalizerState` exists, but the engine
307
+ * leaves its callback unset for speculation, so the call throws a descriptive
308
+ * guard error rather than recording state.
309
+ * - *Worker execution mode*: the generator's runtime `ctx` is a reduced
310
+ * worker-side context that does not carry `setFinalizerState` at all. A
311
+ * handler annotated `(ctx: WorkflowContext)` still type-checks the call (the
312
+ * static type declares the method), but at runtime the method is absent on the
313
+ * worker context value, so the call fails with a `TypeError`.
314
+ *
315
+ * A workflow that must record finalizer state therefore has to run in inline
316
+ * execution mode. Durable finalizer *registration* works in worker mode since
317
+ * #564; only the in-generator `setFinalizerState` call requires inline execution.
318
+ * For in-process, best-effort cleanup that does not need to survive a crash, use
319
+ * {@link WorkflowContext.onCancel}.
320
+ *
321
+ * @example
322
+ * ```ts
323
+ * import { workflow, type WorkflowContext } from '@lostgradient/weft';
324
+ *
325
+ * const provision = workflow({ name: 'provision' })
326
+ * .execute(async function* (ctx: WorkflowContext) {
327
+ * const sandbox = yield* ctx.run(createSandbox);
328
+ * ctx.setFinalizerState({ sandboxId: sandbox.id });
329
+ * yield* ctx.run(doWork, sandbox.id);
330
+ * });
331
+ * void provision;
332
+ * ```
333
+ */
334
+ setFinalizerState(value: unknown): void;
192
335
  }
193
336
  export {};
@@ -2,20 +2,21 @@
2
2
  * The `WorkflowDefinition` type — the runtime shape produced by
3
3
  * `workflow({ name }).execute(fn)`. Carries the workflow name, the generator
4
4
  * handler, and the colocated metadata the engine reads at registration time
5
- * (version, schemas, retention, search attributes, migration, domain
6
- * constraints, tags, description).
5
+ * (version, schemas, retention, search attributes, domain constraints, tags,
6
+ * description).
7
7
  */
8
8
  import type { ConstraintDefinition } from '../constraint.ts';
9
9
  import type { DefinitionSchema } from './definition-schema.ts';
10
10
  import type { RetentionPolicy } from './retry-retention.ts';
11
11
  import type { SearchAttributeSchema } from './search-attributes.ts';
12
+ import type { WorkflowConcurrencyOptions } from './workflow-concurrency.ts';
12
13
  import type { WorkflowFunction } from './workflow-function.ts';
14
+ import type { AnyActivityDefinition } from './workflow-registries.ts';
13
15
  /**
14
16
  * Named workflow definition returned by {@link workflow}. The runtime object
15
17
  * carries the workflow name, the generator handler, and optional metadata
16
- * (version, schemas, retention policy, search-attribute schema, checkpoint
17
- * migration, and domain constraints) that the engine reads at registration
18
- * time.
18
+ * (version, schemas, retention policy, workflow concurrency, search-attribute
19
+ * schema, and domain constraints) that the engine reads at registration time.
19
20
  *
20
21
  * @example
21
22
  * ```ts
@@ -27,12 +28,12 @@ import type { WorkflowFunction } from './workflow-function.ts';
27
28
  * });
28
29
  * ```
29
30
  */
30
- export interface WorkflowDefinition<TInput = unknown, TOutput = unknown, TName extends string = string> {
31
+ export interface WorkflowDefinition<TInput = unknown, TOutput = unknown, TName extends string = string, TServices = unknown> {
31
32
  /** Wire-safe workflow name; the registry key. */
32
33
  name: TName;
33
34
  /** Workflow generator function executed by the engine. */
34
- handler: WorkflowFunction<TInput, TOutput>;
35
- /** Version recorded with workflow state and used for checkpoint migration. */
35
+ handler: WorkflowFunction<TInput, TOutput, TServices>;
36
+ /** Version recorded with workflow state and checked during recovery. */
36
37
  version?: string;
37
38
  /** User-facing description for catalog, code generation, and tool surfaces. */
38
39
  description?: string;
@@ -42,12 +43,12 @@ export interface WorkflowDefinition<TInput = unknown, TOutput = unknown, TName e
42
43
  inputSchema?: DefinitionSchema<unknown, TInput>;
43
44
  /** Optional output schema metadata for introspection; registration validates metadata shape only. */
44
45
  outputSchema?: DefinitionSchema<unknown, TOutput>;
45
- /** Optional checkpoint migration from a prior workflow version. */
46
- migrate?: (checkpoint: unknown, fromVersion: string) => unknown;
47
46
  /** Search-attribute schema used to validate indexed workflow metadata. */
48
47
  searchAttributes?: SearchAttributeSchema;
49
48
  /** Retention policy for terminal workflow records. */
50
49
  retention?: RetentionPolicy;
50
+ /** Start admission policy for this workflow type. */
51
+ concurrency?: WorkflowConcurrencyOptions<TInput>;
51
52
  /**
52
53
  * Domain constraints evaluated at every checkpoint commit. When a constraint's
53
54
  * `check` returns false, the engine dispatches a `ConstraintViolatedEvent`
@@ -58,4 +59,46 @@ export interface WorkflowDefinition<TInput = unknown, TOutput = unknown, TName e
58
59
  * (`workerExecution` option) will silently skip constraint evaluation.
59
60
  */
60
61
  constraints?: ConstraintDefinition[];
62
+ /**
63
+ * Declares a definition-level teardown activity for durable, replay-safe
64
+ * cancellation cleanup (issue #446) — for example destroying a paid sandbox
65
+ * when a workflow is cancelled or times out.
66
+ *
67
+ * After a `cancelled` or `timed-out` terminal, the engine drives this finalizer
68
+ * to durable completion, passing the value recorded by
69
+ * {@link WorkflowContext.setFinalizerState} as its input. That teardown survives
70
+ * a hard cancel and an engine crash: the engine schedules it durably, claims it
71
+ * before running, retries failures with backoff, re-drives a stale claim after
72
+ * recovery, and records a durable dead-letter once the attempt budget is
73
+ * exhausted. The engine skips the finalizer entirely when the workflow never
74
+ * recorded any finalizer state, and `completed`/`failed` workflows never run it
75
+ * (only `cancelled`/`timed-out`).
76
+ *
77
+ * **The finalizer runs at least once and must be idempotent.** Bounded retries
78
+ * and crash-recovery re-drive mean the same payload can reach it more than once,
79
+ * so destroying an already-destroyed resource must succeed (or no-op) rather
80
+ * than throw — the same contract as keying a destroy by `sandboxId`.
81
+ *
82
+ * A `finalizer` is trusted host code. **Registration** works in both inline and
83
+ * worker execution modes, and the teardown **runs on the engine host** regardless
84
+ * of execution mode (and regardless of whether `activityExecution` is configured):
85
+ * worker execution mode isolates only the workflow generator in a Web Worker.
86
+ *
87
+ * Durable teardown, however, only fires when the workflow staged finalizer state
88
+ * via {@link WorkflowContext.setFinalizerState} before terminating — and that
89
+ * call works only under inline execution. A handler annotated
90
+ * `(ctx: WorkflowContext)` type-checks the call in any generator (the static type
91
+ * declares the method), but at runtime in worker mode the generator's `ctx` is a
92
+ * reduced worker-side context that does not carry `setFinalizerState` at all, so
93
+ * the call fails with a `TypeError`; and there is no host-side API to stage the
94
+ * state on the workflow's behalf. So a worker-mode workflow that needs durable
95
+ * finalizer teardown must run **inline** to record its state; registering a
96
+ * `finalizer` on a worker-mode engine no longer throws, but a worker generator
97
+ * cannot drive it. The inline-only alternatives are `ctx.onCancel`
98
+ * (in-process, best-effort cleanup that need not survive a crash) and `ctx.saga`
99
+ * (multi-step ordered rollback) — both are unavailable in worker mode, where
100
+ * teardown must happen in the workflow body (a `ctx.run` destroy step in a
101
+ * `try/finally`).
102
+ */
103
+ finalizer?: AnyActivityDefinition;
61
104
  }
@@ -28,7 +28,7 @@ export type { WorkflowDefinition } from './workflow-definition.ts';
28
28
  * void engine;
29
29
  * ```
30
30
  */
31
- export type WorkflowFunction<TInput = unknown, TOutput = unknown> = (context: WorkflowContext, input: TInput) => AsyncGenerator<unknown, TOutput, unknown>;
31
+ export type WorkflowFunction<TInput = unknown, TOutput = unknown, TServices = unknown> = (context: WorkflowContext<{}, {}, {}, {}, {}, TServices>, input: TInput) => AsyncGenerator<unknown, TOutput, unknown>;
32
32
  /**
33
33
  * Simplified context for step-based ("progressive disclosure") workflows.
34
34
  * Instead of yielding operations via a generator, write a plain `async`
@@ -158,17 +158,92 @@ export type WorkflowOperation<TResult> = Generator<unknown, TResult, unknown>;
158
158
  */
159
159
  export type ChildWorkflowTarget<TInput = unknown, TOutput = unknown> = string | WorkflowFunction<TInput, TOutput> | StepWorkflowFunction<TInput, TOutput>;
160
160
  /**
161
- * Options passed to child workflow invocations within `ctx.pipe`, `ctx.map`,
162
- * or `ctx.reduce`. Currently accepts an optional `id` to control the child
163
- * workflow ID.
161
+ * How a direct `ctx.startChild()` call relates the child workflow to the parent.
162
+ *
163
+ * - `'await'` is the default and preserves the original behavior: the parent
164
+ * waits for the child result.
165
+ * - `'abandon'` starts the child and returns a serializable child handle
166
+ * reference immediately. The child does not inherit the parent's execution
167
+ * state owner.
168
+ * - `'request-cancel'` starts the child and returns a serializable child handle
169
+ * reference immediately. If the parent is cancelled in the same engine
170
+ * process, Weft requests cancellation of the child.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * import type { ChildWorkflowParentClosePolicy } from '@lostgradient/weft';
175
+ *
176
+ * const policy: ChildWorkflowParentClosePolicy = 'abandon';
177
+ * void policy;
178
+ * ```
179
+ */
180
+ export type ChildWorkflowParentClosePolicy = 'await' | 'abandon' | 'request-cancel';
181
+ declare const childWorkflowResultType: unique symbol;
182
+ /**
183
+ * Serializable reference returned by detached `ctx.startChild()` policies.
184
+ * It intentionally contains only durable data that can be checkpointed. Use
185
+ * `engine.getHandle(reference.id)` outside the workflow body to observe status,
186
+ * signal the child, or await its result.
187
+ *
188
+ * @example
189
+ * ```ts
190
+ * import type { ChildWorkflowHandle } from '@lostgradient/weft';
191
+ *
192
+ * const child: ChildWorkflowHandle<{ receiptId: string }> = { id: 'payment-child' };
193
+ * const workflowId: string = child.id;
194
+ * void workflowId;
195
+ * ```
196
+ */
197
+ export type ChildWorkflowHandle<TResult = unknown> = {
198
+ readonly id: string;
199
+ readonly [childWorkflowResultType]?: TResult;
200
+ };
201
+ /**
202
+ * Options for child workflow calls that wait for the child result.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * import type { AwaitChildWorkflowOptions } from '@lostgradient/weft';
207
+ *
208
+ * const options: AwaitChildWorkflowOptions = {
209
+ * id: 'payment-child',
210
+ * parentClosePolicy: 'await',
211
+ * };
212
+ * void options;
213
+ * ```
164
214
  */
165
- export type ChildWorkflowOptions = {
215
+ export type AwaitChildWorkflowOptions = {
166
216
  id?: string;
217
+ parentClosePolicy?: 'await';
167
218
  };
219
+ /**
220
+ * Options for direct child workflow calls that return a child handle reference.
221
+ *
222
+ * @example
223
+ * ```ts
224
+ * import type { DetachedChildWorkflowOptions } from '@lostgradient/weft';
225
+ *
226
+ * const options: DetachedChildWorkflowOptions = {
227
+ * id: 'background-payment',
228
+ * parentClosePolicy: 'request-cancel',
229
+ * };
230
+ * void options;
231
+ * ```
232
+ */
233
+ export type DetachedChildWorkflowOptions = {
234
+ id?: string;
235
+ parentClosePolicy: Exclude<ChildWorkflowParentClosePolicy, 'await'>;
236
+ };
237
+ /**
238
+ * Options passed to direct child workflow invocations via `ctx.startChild()`.
239
+ * Composition operators (`ctx.pipe`, `ctx.map`, and `ctx.reduce`) are await-only
240
+ * and accept only {@link AwaitChildWorkflowOptions}.
241
+ */
242
+ export type ChildWorkflowOptions = AwaitChildWorkflowOptions | DetachedChildWorkflowOptions;
168
243
  /**
169
244
  * A single stage in a `ctx.pipe(stages, input)` composition chain. Pairs a
170
- * {@link ChildWorkflowTarget} with optional {@link ChildWorkflowOptions} such
171
- * as a custom child workflow ID. Use the object form when you need to pass
245
+ * {@link ChildWorkflowTarget} with optional {@link AwaitChildWorkflowOptions}
246
+ * such as a custom child workflow ID. Use the object form when you need to pass
172
247
  * per-stage options; otherwise a bare {@link ChildWorkflowTarget} also works.
173
248
  *
174
249
  * @example
@@ -193,7 +268,7 @@ export type ChildWorkflowOptions = {
193
268
  */
194
269
  export interface WorkflowPipeStage<TInput = unknown, TOutput = unknown> {
195
270
  type: ChildWorkflowTarget<TInput, TOutput>;
196
- options?: ChildWorkflowOptions;
271
+ options?: AwaitChildWorkflowOptions;
197
272
  }
198
273
  /**
199
274
  * Union of the two accepted formats for each stage passed to `ctx.pipe`:
@@ -321,7 +396,7 @@ export interface WorkflowReduceInput<TAccumulator, TItem> {
321
396
  * void engine;
322
397
  * ```
323
398
  */
324
- export interface WorkflowReduceOptions extends Record<string, unknown> {
399
+ export interface WorkflowReduceOptions extends AwaitChildWorkflowOptions {
325
400
  idPrefix?: string;
326
401
  }
327
402
  /**