@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
@@ -1,7 +1,23 @@
1
1
  import { ExtensionCodec } from '@msgpack/msgpack';
2
+ import { WeftError } from '../weft-error.ts';
3
+ declare const EXTENSION_TYPE_REGEXP = 2;
4
+ export declare class RegExpExtensionDecodeError extends WeftError<'RegExpExtensionDecodeError'> {
5
+ readonly extensionType: typeof EXTENSION_TYPE_REGEXP;
6
+ readonly source: string;
7
+ readonly flags: string;
8
+ readonly sourceByteLength: number;
9
+ constructor(parameters: {
10
+ source: string;
11
+ flags: string;
12
+ sourceByteLength: number;
13
+ reason: string;
14
+ cause?: unknown;
15
+ });
16
+ }
2
17
  export declare const extensionCodec: ExtensionCodec<undefined>;
3
18
  /**
4
19
  * Recursively replace `undefined` with the sentinel so msgpack's encoder
5
20
  * routes it through the extension codec instead of encoding it as null.
6
21
  */
7
22
  export declare function replaceUndefined(value: unknown, visited: Set<object>): unknown;
23
+ export {};
@@ -5,8 +5,50 @@ import {
5
5
  decodeCodecDate,
6
6
  encodeCodecDate
7
7
  } from "../codec-helpers.js";
8
+ import { WeftError } from "../weft-error.js";
8
9
  import { bindSerializerRegistryToCodec, hasRegisteredSerializer } from "./serializer-registry.js";
9
- const EXTENSION_TYPE_DATE = 1, EXTENSION_TYPE_REGEXP = 2, EXTENSION_TYPE_MAP = 3, EXTENSION_TYPE_SET = 4, EXTENSION_TYPE_UNDEFINED = 5, EXTENSION_TYPE_ERROR = 6;
10
+ const EXTENSION_TYPE_DATE = 1, EXTENSION_TYPE_REGEXP = 2, EXTENSION_TYPE_MAP = 3, EXTENSION_TYPE_SET = 4, EXTENSION_TYPE_UNDEFINED = 5, EXTENSION_TYPE_ERROR = 6, REGEXP_SOURCE_MAX_BYTES = 65535, regexpSourceTextEncoder = new TextEncoder;
11
+
12
+ export class RegExpExtensionDecodeError extends WeftError {
13
+ extensionType;
14
+ source;
15
+ flags;
16
+ sourceByteLength;
17
+ constructor(parameters) {
18
+ super("RegExpExtensionDecodeError", `RegExp extension type ${EXTENSION_TYPE_REGEXP} could not be decoded: source=${formatRegExpSourceForMessage(parameters.source, parameters.sourceByteLength)} flags=${JSON.stringify(parameters.flags)} ${parameters.reason}`, parameters.cause === void 0 ? void 0 : { cause: parameters.cause });
19
+ this.extensionType = EXTENSION_TYPE_REGEXP;
20
+ this.source = parameters.source;
21
+ this.flags = parameters.flags;
22
+ this.sourceByteLength = parameters.sourceByteLength;
23
+ }
24
+ }
25
+ function formatRegExpSourceForMessage(source, sourceByteLength) {
26
+ if (sourceByteLength <= 200)
27
+ return JSON.stringify(source);
28
+ return `${sourceByteLength}-byte string starting ${JSON.stringify(source.slice(0, 120))}`;
29
+ }
30
+ function decodeRegExpExtension(source, flags) {
31
+ const sourceByteLength = regexpSourceTextEncoder.encode(source).byteLength;
32
+ if (sourceByteLength > REGEXP_SOURCE_MAX_BYTES)
33
+ throw new RegExpExtensionDecodeError({
34
+ source,
35
+ flags,
36
+ sourceByteLength,
37
+ reason: `because source exceeds the ${REGEXP_SOURCE_MAX_BYTES}-byte limit.`
38
+ });
39
+ try {
40
+ return new RegExp(source, flags);
41
+ } catch (cause) {
42
+ const reason = cause instanceof Error ? cause.message : String(cause);
43
+ throw new RegExpExtensionDecodeError({
44
+ source,
45
+ flags,
46
+ sourceByteLength,
47
+ reason: `because ${reason}`,
48
+ cause
49
+ });
50
+ }
51
+ }
10
52
  export const extensionCodec = new ExtensionCodec;
11
53
  bindSerializerRegistryToCodec(extensionCodec, replaceUndefined);
12
54
  extensionCodec.register({
@@ -23,7 +65,7 @@ extensionCodec.register({
23
65
  },
24
66
  decode(data) {
25
67
  const decoded = coerceCodecRecord(msgpackDecode(data)), source = typeof decoded.source === "string" ? decoded.source : "", flags = typeof decoded.flags === "string" ? decoded.flags : "";
26
- return new RegExp(source, flags);
68
+ return decodeRegExpExtension(source, flags);
27
69
  }
28
70
  });
29
71
  extensionCodec.register({
@@ -94,6 +136,11 @@ extensionCodec.register({
94
136
  }
95
137
  });
96
138
  export function replaceUndefined(value, visited) {
139
+ if (!containsUndefined(value, visited))
140
+ return value;
141
+ return replaceUndefinedDeep(value, new Set);
142
+ }
143
+ function replaceUndefinedDeep(value, visited) {
97
144
  if (value === void 0)
98
145
  return undefinedSentinel;
99
146
  if (value === null || typeof value !== "object")
@@ -121,19 +168,19 @@ function replaceObjectUndefined(value, visited) {
121
168
  function replaceArrayUndefined(value, visited) {
122
169
  const result = Array.from({ length: value.length });
123
170
  for (let index = 0;index < value.length; index++)
124
- result[index] = replaceUndefined(value[index], visited);
171
+ result[index] = replaceUndefinedDeep(value[index], visited);
125
172
  return result;
126
173
  }
127
174
  function replaceMapUndefined(value, visited) {
128
175
  const result = new Map;
129
176
  for (const [key, mapValue] of value)
130
- result.set(replaceUndefined(key, visited), replaceUndefined(mapValue, visited));
177
+ result.set(replaceUndefinedDeep(key, visited), replaceUndefinedDeep(mapValue, visited));
131
178
  return result;
132
179
  }
133
180
  function replaceSetUndefined(value, visited) {
134
181
  const result = new Set;
135
182
  for (const setValue of value)
136
- result.add(replaceUndefined(setValue, visited));
183
+ result.add(replaceUndefinedDeep(setValue, visited));
137
184
  return result;
138
185
  }
139
186
  function isNestedValueFree(value) {
@@ -142,6 +189,53 @@ function isNestedValueFree(value) {
142
189
  function replaceRecordUndefined(value, visited) {
143
190
  const record = value, result = {};
144
191
  for (const key of Object.keys(record))
145
- result[key] = replaceUndefined(record[key], visited);
192
+ result[key] = replaceUndefinedDeep(record[key], visited);
146
193
  return result;
147
194
  }
195
+ function containsUndefined(value, visited) {
196
+ if (value === void 0)
197
+ return !0;
198
+ if (value === null || typeof value !== "object")
199
+ return !1;
200
+ if (visited.has(value))
201
+ return !1;
202
+ if (isNestedValueFree(value))
203
+ return !1;
204
+ visited.add(value);
205
+ try {
206
+ if (Array.isArray(value))
207
+ return arrayContainsUndefined(value, visited);
208
+ if (value instanceof Map)
209
+ return mapContainsUndefined(value, visited);
210
+ if (value instanceof Set)
211
+ return setContainsUndefined(value, visited);
212
+ return recordContainsUndefined(value, visited);
213
+ } finally {
214
+ visited.delete(value);
215
+ }
216
+ }
217
+ function arrayContainsUndefined(value, visited) {
218
+ for (let index = 0;index < value.length; index++)
219
+ if (containsUndefined(value[index], visited))
220
+ return !0;
221
+ return !1;
222
+ }
223
+ function mapContainsUndefined(value, visited) {
224
+ for (const [key, mapValue] of value)
225
+ if (containsUndefined(key, visited) || containsUndefined(mapValue, visited))
226
+ return !0;
227
+ return !1;
228
+ }
229
+ function setContainsUndefined(value, visited) {
230
+ for (const setValue of value)
231
+ if (containsUndefined(setValue, visited))
232
+ return !0;
233
+ return !1;
234
+ }
235
+ function recordContainsUndefined(value, visited) {
236
+ const record = value;
237
+ for (const key of Object.keys(record))
238
+ if (containsUndefined(record[key], visited))
239
+ return !0;
240
+ return !1;
241
+ }
@@ -0,0 +1,38 @@
1
+ import type { ContextInternals } from './internals.ts';
2
+ /**
3
+ * Durable per-step retry bookkeeping for `ctx.run`, stored in the workflow's
4
+ * `checkpointLocals` so it survives crash/replay. One slot holds, per step: the
5
+ * current attempt number, how many backoff sleeps already completed, and the
6
+ * first-dispatch timestamp anchoring `scheduleToCloseTimeout`. Every mutator
7
+ * rebuilds the slot through {@link writeRetryStateSlot} so no sub-map is silently
8
+ * erased when another is updated.
9
+ */
10
+ export declare const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState";
11
+ declare const ACTIVITY_RETRY_STATE_VERSION = 1;
12
+ export declare const MAX_CHECKPOINTED_RETRY_ATTEMPT = 10000;
13
+ export interface ActivityRetryState {
14
+ version: typeof ACTIVITY_RETRY_STATE_VERSION;
15
+ attempts: Record<string, number>;
16
+ completedRetrySleeps?: Record<string, number>;
17
+ /**
18
+ * First-dispatch engine-clock timestamp per step, the anchor for
19
+ * `scheduleToCloseTimeout`. Written ONCE on the first dispatch of a step and
20
+ * never overwritten, so the wall-clock budget is measured from the original
21
+ * dispatch even across crash/replay. Like `completedRetrySleeps`, it must be
22
+ * preserved whenever the retry-state slot is rebuilt.
23
+ */
24
+ dispatchedAt?: Record<string, number>;
25
+ }
26
+ export declare function isActivityRetryState(value: unknown): value is ActivityRetryState;
27
+ export declare function readActivityRetryAttempt(internals: ContextInternals, step: number): number | undefined;
28
+ export declare function readCompletedRetrySleepCount(internals: ContextInternals, step: number): number;
29
+ export declare function writeActivityRetryAttempt(internals: ContextInternals, step: number, attempt: number): void;
30
+ export declare function completeActivityRetryAttempt(internals: ContextInternals, step: number, completedRetrySleepCount: number): void;
31
+ /**
32
+ * Read the first-dispatch anchor for a step's `scheduleToCloseTimeout`, writing
33
+ * `now` on the first dispatch. Read-first so a crash/replay never resets the
34
+ * window: the budget is measured from the original dispatch, and the anchor
35
+ * lands in the checkpoint committed at the dispatch `yield` that follows.
36
+ */
37
+ export declare function readOrInitActivityDispatchedAt(internals: ContextInternals, step: number, now: number): number;
38
+ export {};
@@ -0,0 +1,89 @@
1
+ export const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState";
2
+ const ACTIVITY_RETRY_STATE_VERSION = 1;
3
+ export const MAX_CHECKPOINTED_RETRY_ATTEMPT = 1e4;
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ export function isActivityRetryState(value) {
8
+ return isRecord(value) && value.version === ACTIVITY_RETRY_STATE_VERSION && isRecord(value.attempts) && (value.completedRetrySleeps === void 0 || isRecord(value.completedRetrySleeps)) && (value.dispatchedAt === void 0 || isRecord(value.dispatchedAt));
9
+ }
10
+ function assertValidRetryAttempt(attempt, step) {
11
+ if (!Number.isInteger(attempt) || attempt <= 1 || attempt > MAX_CHECKPOINTED_RETRY_ATTEMPT)
12
+ throw Error(`Invalid checkpointed activity retry attempt ${String(attempt)} for step ${String(step)}`);
13
+ }
14
+ export function readActivityRetryAttempt(internals, step) {
15
+ const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
16
+ if (!isActivityRetryState(state))
17
+ return;
18
+ const attempt = state.attempts[String(step)];
19
+ if (attempt === void 0)
20
+ return;
21
+ assertValidRetryAttempt(attempt, step);
22
+ return attempt;
23
+ }
24
+ export function readCompletedRetrySleepCount(internals, step) {
25
+ const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
26
+ if (!isActivityRetryState(state))
27
+ return 0;
28
+ const count = state.completedRetrySleeps?.[String(step)];
29
+ if (count === void 0)
30
+ return 0;
31
+ if (!Number.isInteger(count) || count < 0 || count > MAX_CHECKPOINTED_RETRY_ATTEMPT)
32
+ throw Error(`Invalid checkpointed activity retry sleep count ${String(count)} for step ${String(step)}`);
33
+ return count;
34
+ }
35
+ function currentRetryState(internals) {
36
+ const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
37
+ return isActivityRetryState(current) ? current : void 0;
38
+ }
39
+ function writeRetryStateSlot(internals, attempts, completedRetrySleeps, dispatchedAt) {
40
+ const { [ACTIVITY_RETRY_STATE_LOCAL_KEY]: _removed, ...remainingLocals } = internals.checkpointLocals, hasAttempts = Object.keys(attempts).length > 0, hasSleeps = completedRetrySleeps !== void 0 && Object.keys(completedRetrySleeps).length > 0, hasDispatched = dispatchedAt !== void 0 && Object.keys(dispatchedAt).length > 0;
41
+ if (!hasAttempts && !hasSleeps && !hasDispatched) {
42
+ internals.checkpointLocals = remainingLocals;
43
+ return;
44
+ }
45
+ internals.checkpointLocals = {
46
+ ...remainingLocals,
47
+ [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
48
+ version: ACTIVITY_RETRY_STATE_VERSION,
49
+ attempts,
50
+ ...hasSleeps ? { completedRetrySleeps } : {},
51
+ ...hasDispatched ? { dispatchedAt } : {}
52
+ }
53
+ };
54
+ }
55
+ export function writeActivityRetryAttempt(internals, step, attempt) {
56
+ assertValidRetryAttempt(attempt, step);
57
+ const current = currentRetryState(internals), attempts = current ? { ...current.attempts } : {};
58
+ attempts[String(step)] = attempt;
59
+ writeRetryStateSlot(internals, attempts, current?.completedRetrySleeps, current?.dispatchedAt);
60
+ }
61
+ function clearActivityRetryAttempt(internals, step) {
62
+ const current = currentRetryState(internals);
63
+ if (!current)
64
+ return;
65
+ const attempts = { ...current.attempts };
66
+ delete attempts[String(step)];
67
+ writeRetryStateSlot(internals, attempts, current.completedRetrySleeps, current.dispatchedAt);
68
+ }
69
+ export function completeActivityRetryAttempt(internals, step, completedRetrySleepCount) {
70
+ if (!Number.isInteger(completedRetrySleepCount) || completedRetrySleepCount < 0 || completedRetrySleepCount > MAX_CHECKPOINTED_RETRY_ATTEMPT)
71
+ throw Error(`Invalid completed activity retry sleep count ${String(completedRetrySleepCount)} for step ${String(step)}`);
72
+ clearActivityRetryAttempt(internals, step);
73
+ if (completedRetrySleepCount === 0)
74
+ return;
75
+ const current = currentRetryState(internals), attempts = current ? { ...current.attempts } : {}, completedRetrySleeps = current ? { ...current.completedRetrySleeps } : {};
76
+ completedRetrySleeps[String(step)] = completedRetrySleepCount;
77
+ writeRetryStateSlot(internals, attempts, completedRetrySleeps, current?.dispatchedAt);
78
+ }
79
+ export function readOrInitActivityDispatchedAt(internals, step, now) {
80
+ const current = currentRetryState(internals), existing = current?.dispatchedAt?.[String(step)];
81
+ if (typeof existing === "number" && Number.isFinite(existing))
82
+ return existing;
83
+ if (existing !== void 0)
84
+ throw Error(`Invalid checkpointed activity dispatch anchor ${String(existing)} for step ${String(step)}`);
85
+ const attempts = current ? { ...current.attempts } : {}, dispatchedAt = current?.dispatchedAt ? { ...current.dispatchedAt } : {};
86
+ dispatchedAt[String(step)] = now;
87
+ writeRetryStateSlot(internals, attempts, current?.completedRetrySleeps, dispatchedAt);
88
+ return now;
89
+ }
@@ -0,0 +1,159 @@
1
+ import type { ActivityCallOptions, Duration } from '../types.ts';
2
+ import { WeftError } from '../weft-error.ts';
3
+ /**
4
+ * Thrown when an activity's {@link ActivityCallOptions.scheduleToCloseTimeout}
5
+ * is enforced at the retry boundary. This fires in two situations, both reported
6
+ * with the **actual** wall-clock {@link elapsed} at the moment of the throw:
7
+ *
8
+ * - The budget has genuinely elapsed (`elapsed >= budget`) — an attempt overran,
9
+ * or downtime during a backoff sleep pushed wall time past the deadline.
10
+ * - The budget has NOT yet elapsed, but the next retry's backoff would start it at
11
+ * or after the deadline — so Weft refuses to schedule a doomed sleep and fails at
12
+ * the retry decision point. In this case {@link projectedNextDispatchElapsed} is
13
+ * set to the elapsed milliseconds after first dispatch at which the skipped retry
14
+ * would have started.
15
+ *
16
+ * The name is registered as a `timeout` failure category, so it classifies and is
17
+ * searchable the same way the other timeout errors are.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { ActivityScheduleToCloseTimeoutError } from '@lostgradient/weft';
22
+ *
23
+ * function exceededRetryBudget(error: unknown): boolean {
24
+ * return error instanceof ActivityScheduleToCloseTimeoutError;
25
+ * }
26
+ * ```
27
+ */
28
+ export declare class ActivityScheduleToCloseTimeoutError extends WeftError<'ActivityScheduleToCloseTimeoutError'> {
29
+ readonly activityName: string;
30
+ /** Actual wall-clock milliseconds elapsed since first dispatch, at the throw. */
31
+ readonly elapsed: number;
32
+ readonly budget: number;
33
+ /**
34
+ * When the failure is the early retry-decision case (the budget has not yet
35
+ * elapsed but the next backoff would start the retry at or after the deadline),
36
+ * the elapsed milliseconds after first dispatch at which that skipped retry would
37
+ * have started. `undefined` when the budget had genuinely elapsed at the throw.
38
+ */
39
+ readonly projectedNextDispatchElapsed?: number;
40
+ constructor(activityName: string, elapsed: number, budget: number, projectedNextDispatchElapsed?: number);
41
+ }
42
+ /**
43
+ * Thrown when an inline activity attempt overruns its per-attempt
44
+ * {@link ActivityCallOptions.timeout} wall-clock cap. The cap is measured fresh
45
+ * on every attempt (unlike {@link ActivityScheduleToCloseTimeoutError}, which is a
46
+ * single budget across all attempts), so the {@link attempt} number is reported.
47
+ *
48
+ * When this fires, the workflow stops awaiting the attempt and the activity's
49
+ * `AbortSignal` is aborted so a cooperating activity can stop promptly — but Weft
50
+ * cannot forcibly preempt a running activity function, so a non-cooperating
51
+ * activity keeps executing in the background until it returns. The timed-out
52
+ * attempt is retried (with a fresh cap) when a retry policy permits.
53
+ *
54
+ * The name is registered as a `timeout` failure category, so it classifies and is
55
+ * searchable the same way the other timeout errors are. `timeout` is enforced for
56
+ * **inline** execution only; worker-mode per-attempt bounds are governed by
57
+ * `visibilityTimeout`.
58
+ *
59
+ * @example
60
+ * ```ts
61
+ * import { ActivityPerAttemptTimeoutError } from '@lostgradient/weft';
62
+ *
63
+ * function overranAttempt(error: unknown): boolean {
64
+ * return error instanceof ActivityPerAttemptTimeoutError;
65
+ * }
66
+ * ```
67
+ */
68
+ export declare class ActivityPerAttemptTimeoutError extends WeftError<'ActivityPerAttemptTimeoutError'> {
69
+ readonly activityName: string;
70
+ /** The 1-based attempt number that overran its per-attempt cap. */
71
+ readonly attempt: number;
72
+ /** The per-attempt wall-clock cap, in milliseconds. */
73
+ readonly timeoutMs: number;
74
+ constructor(activityName: string, attempt: number, timeoutMs: number);
75
+ }
76
+ /**
77
+ * The largest delay a single `setTimeout` can represent without 32-bit overflow.
78
+ * A delay above this silently wraps and fires almost immediately, so a per-attempt
79
+ * `timeout` larger than this is rejected rather than misbehaving. (~24.8 days.)
80
+ */
81
+ export declare const MAX_PER_ATTEMPT_TIMEOUT_MS = 2147483647;
82
+ /**
83
+ * Parse a per-attempt `timeout` duration to milliseconds, or `undefined` when
84
+ * unset. The value is read off the serialized activity operation, so it is typed
85
+ * `unknown` and validated here as hostile input: only a `number`/`string`
86
+ * {@link Duration} is accepted, and `parseDuration` enforces finite/non-negative
87
+ * so the cap can never silently become `NaN`/`Infinity`/negative. A `0`ms cap is
88
+ * rejected as meaningless (it would expire an attempt before it could run) —
89
+ * callers must omit `timeout` to disable the cap rather than passing `0` — and a
90
+ * value above {@link MAX_PER_ATTEMPT_TIMEOUT_MS} is rejected because it would
91
+ * overflow the underlying `setTimeout` and fire almost immediately.
92
+ */
93
+ export declare function parsePerAttemptTimeoutMs(timeout: unknown): number | undefined;
94
+ /**
95
+ * The first-dispatch anchor and parsed budget for a `ctx.run` call's
96
+ * `scheduleToCloseTimeout`, or `undefined` when no budget is configured.
97
+ */
98
+ export type ScheduleToCloseBudget = {
99
+ budgetMs: number;
100
+ dispatchedAt: number;
101
+ };
102
+ /**
103
+ * Parse a `scheduleToCloseTimeout` duration to milliseconds, or `undefined` when
104
+ * unset. `parseDuration` validates the result is finite and non-negative on every
105
+ * input path (numeric and string, via `assertValidDurationMilliseconds`) and
106
+ * throws otherwise — so the budget can never silently become `NaN`/`Infinity`
107
+ * (which would make `elapsed >= budgetMs` always-false) or negative. `0` is valid
108
+ * (it permits exactly one attempt).
109
+ */
110
+ export declare function parseScheduleToCloseBudgetMs(scheduleToCloseTimeout: Duration | undefined): number | undefined;
111
+ /**
112
+ * Resolve the cross-attempt wall-clock budget for a `ctx.run` call: a per-call
113
+ * `scheduleToCloseTimeout` overrides the activity definition's default. String
114
+ * activities have no definition fields, so only the per-call option applies. The
115
+ * by-reference arm is `Function & { scheduleToCloseTimeout?: Duration }` to match
116
+ * the caller's `ActivityInput` (a callable carrying the activity definition); this
117
+ * resolver reads only the single `scheduleToCloseTimeout` field off it.
118
+ */
119
+ export declare function resolveActivityScheduleToCloseTimeout(activity: string | (Function & {
120
+ scheduleToCloseTimeout?: Duration;
121
+ }), options: ActivityCallOptions | undefined): Duration | undefined;
122
+ /**
123
+ * Resolve the per-attempt `timeout` for a `ctx.run` call: a per-call `timeout`
124
+ * overrides the activity definition's default. String activities have no
125
+ * definition fields, so only the per-call option applies. Mirrors
126
+ * {@link resolveActivityScheduleToCloseTimeout} so the per-attempt cap honors a
127
+ * `timeout` declared on the activity definition, not just at the call site.
128
+ */
129
+ export declare function resolveActivityTimeout(activity: string | (Function & {
130
+ timeout?: Duration;
131
+ }), options: ActivityCallOptions | undefined): Duration | undefined;
132
+ /**
133
+ * Whether the schedule-to-close budget is exhausted at the given clock value.
134
+ * The comparison is `>=` so an exact-deadline or zero-budget retry is treated as
135
+ * exhausted — a `0`ms budget allows exactly one attempt, then throws.
136
+ */
137
+ export declare function isScheduleToCloseBudgetExhausted(budget: ScheduleToCloseBudget, now: number): boolean;
138
+ /**
139
+ * Throw {@link ActivityScheduleToCloseTimeoutError} when the schedule-to-close
140
+ * budget bars the next attempt, otherwise return. Called two ways at the retry
141
+ * boundary, both routing through this single check; the thrown error always
142
+ * reports the ACTUAL elapsed time at `now`, never a projected one:
143
+ *
144
+ * - **Top of the retry loop** (`now = getNow()`, no `projectedNextDispatchClock`):
145
+ * the live clock has reached or passed the deadline — an attempt overran, or
146
+ * downtime during a backoff replay pushed wall time past it. Exhaustion is
147
+ * checked at `now`; the error reports `now - dispatchedAt` and no projection.
148
+ * - **Catch branch** (`now = getNow()`, `projectedNextDispatchClock = now +
149
+ * nextBackoff`, both from a single clock read): the budget may not have elapsed
150
+ * yet, but the next backoff would start the retry at or after the deadline, so we
151
+ * refuse to schedule that doomed sleep and fail at the retry decision point.
152
+ * Exhaustion is checked at the PROJECTED dispatch clock; the error still reports
153
+ * the actual `now - dispatchedAt` elapsed plus the projected next-dispatch
154
+ * (as elapsed-since-first-dispatch ms) as the deciding reason.
155
+ *
156
+ * `budget` is `undefined` when no `scheduleToCloseTimeout` is configured, in which
157
+ * case this is a no-op.
158
+ */
159
+ export declare function assertScheduleToCloseBudgetNotExhausted(budget: ScheduleToCloseBudget | undefined, activityName: string, now: number, projectedNextDispatchClock?: number): void;
@@ -0,0 +1,69 @@
1
+ import { parseDuration } from "../scheduler.js";
2
+ import { WeftError } from "../weft-error.js";
3
+
4
+ export class ActivityScheduleToCloseTimeoutError extends WeftError {
5
+ activityName;
6
+ elapsed;
7
+ budget;
8
+ projectedNextDispatchElapsed;
9
+ constructor(activityName, elapsed, budget, projectedNextDispatchElapsed) {
10
+ super("ActivityScheduleToCloseTimeoutError", projectedNextDispatchElapsed === void 0 ? `Activity "${activityName}" exceeded its scheduleToCloseTimeout budget of ${budget}ms (elapsed ${elapsed}ms across retries)` : `Activity "${activityName}" will not retry within its scheduleToCloseTimeout budget of ${budget}ms (elapsed ${elapsed}ms; next retry would start at ${projectedNextDispatchElapsed}ms after first dispatch, at or beyond the deadline)`);
11
+ this.activityName = activityName;
12
+ this.elapsed = elapsed;
13
+ this.budget = budget;
14
+ if (projectedNextDispatchElapsed !== void 0)
15
+ this.projectedNextDispatchElapsed = projectedNextDispatchElapsed;
16
+ }
17
+ }
18
+
19
+ export class ActivityPerAttemptTimeoutError extends WeftError {
20
+ activityName;
21
+ attempt;
22
+ timeoutMs;
23
+ constructor(activityName, attempt, timeoutMs) {
24
+ super("ActivityPerAttemptTimeoutError", `Activity "${activityName}" attempt ${attempt} exceeded its per-attempt timeout of ${timeoutMs}ms`);
25
+ this.activityName = activityName;
26
+ this.attempt = attempt;
27
+ this.timeoutMs = timeoutMs;
28
+ }
29
+ }
30
+ export const MAX_PER_ATTEMPT_TIMEOUT_MS = 2147483647;
31
+ export function parsePerAttemptTimeoutMs(timeout) {
32
+ if (timeout === void 0)
33
+ return;
34
+ if (typeof timeout !== "number" && typeof timeout !== "string")
35
+ throw Error(`Activity timeout must be a number or duration string when set (got ${typeof timeout}).`);
36
+ const ms = parseDuration(timeout);
37
+ if (ms <= 0)
38
+ throw Error(`Activity timeout must be greater than 0ms when set (got ${ms}ms); omit it to disable the per-attempt cap.`);
39
+ if (ms > MAX_PER_ATTEMPT_TIMEOUT_MS)
40
+ throw Error(`Activity timeout of ${ms}ms exceeds the maximum supported per-attempt cap of ${MAX_PER_ATTEMPT_TIMEOUT_MS}ms (~24.8 days).`);
41
+ return ms;
42
+ }
43
+ export function parseScheduleToCloseBudgetMs(scheduleToCloseTimeout) {
44
+ return scheduleToCloseTimeout === void 0 ? void 0 : parseDuration(scheduleToCloseTimeout);
45
+ }
46
+ export function resolveActivityScheduleToCloseTimeout(activity, options) {
47
+ if (options?.scheduleToCloseTimeout !== void 0)
48
+ return options.scheduleToCloseTimeout;
49
+ if (typeof activity === "string")
50
+ return;
51
+ return activity.scheduleToCloseTimeout;
52
+ }
53
+ export function resolveActivityTimeout(activity, options) {
54
+ if (options?.timeout !== void 0)
55
+ return options.timeout;
56
+ if (typeof activity === "string")
57
+ return;
58
+ return activity.timeout;
59
+ }
60
+ export function isScheduleToCloseBudgetExhausted(budget, now) {
61
+ return now - budget.dispatchedAt >= budget.budgetMs;
62
+ }
63
+ export function assertScheduleToCloseBudgetNotExhausted(budget, activityName, now, projectedNextDispatchClock) {
64
+ if (budget === void 0)
65
+ return;
66
+ if (!isScheduleToCloseBudgetExhausted(budget, projectedNextDispatchClock ?? now))
67
+ return;
68
+ throw new ActivityScheduleToCloseTimeoutError(activityName, now - budget.dispatchedAt, budget.budgetMs, projectedNextDispatchClock !== void 0 && now - budget.dispatchedAt < budget.budgetMs ? projectedNextDispatchClock - budget.dispatchedAt : void 0);
69
+ }
@@ -1,18 +1,18 @@
1
- import type { ChildWorkflowOptions, ChildWorkflowTarget, WorkflowMapOptions, WorkflowPipeStage, WorkflowReduceInput, WorkflowReduceOptions } from '../types.ts';
1
+ import type { AwaitChildWorkflowOptions, ChildWorkflowHandle, ChildWorkflowOptions, ChildWorkflowTarget, WorkflowMapOptions, WorkflowPipeStage, WorkflowReduceInput, WorkflowReduceOptions } from '../types.ts';
2
2
  import type { Context } from './index.ts';
3
3
  import type { ContextInternals } from './internals.ts';
4
4
  import type { ContextOperationRequest } from './operation-request.ts';
5
5
  export declare function normalizePipeStage(internals: ContextInternals, stage: WorkflowPipeStage | ChildWorkflowTarget): {
6
6
  workflowType: string;
7
- options: ChildWorkflowOptions | undefined;
7
+ options: AwaitChildWorkflowOptions | undefined;
8
8
  };
9
9
  export declare function resolveChildWorkflowTarget<TInput = unknown, TOutput = unknown>(internals: ContextInternals, target: ChildWorkflowTarget<TInput, TOutput>): string;
10
10
  export declare function resolveMapConcurrency(totalItems: number, requestedConcurrency: number | undefined): number;
11
11
  export declare function createCompositionToken(internals: ContextInternals, kind: 'map' | 'pipe' | 'reduce'): string;
12
- export declare function createCompositionChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options?: ChildWorkflowOptions | undefined): ChildWorkflowOptions;
13
- export declare function createReduceChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options: WorkflowReduceOptions | undefined): ChildWorkflowOptions;
12
+ export declare function createCompositionChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options?: AwaitChildWorkflowOptions | undefined): AwaitChildWorkflowOptions;
13
+ export declare function createReduceChildWorkflowOptions(internals: ContextInternals, token: string, index: number, options: WorkflowReduceOptions | undefined): AwaitChildWorkflowOptions;
14
14
  export declare function primeParallelOperations(operations: Generator<ContextOperationRequest, unknown, unknown>[]): ContextOperationRequest[];
15
- export declare function startChild<TResult = unknown>(context: Context, internals: ContextInternals, workflowType: string, input: unknown, options?: ChildWorkflowOptions): Generator<ContextOperationRequest, TResult, unknown>;
15
+ export declare function startChild<TResult = unknown>(context: Context, internals: ContextInternals, workflowType: string, input: unknown, options?: ChildWorkflowOptions): Generator<ContextOperationRequest, TResult | ChildWorkflowHandle<TResult>, unknown>;
16
16
  export declare function pipe<TResult = unknown>(context: Context, internals: ContextInternals, stages: Array<WorkflowPipeStage | ChildWorkflowTarget>, input: unknown): Generator<ContextOperationRequest, TResult, unknown>;
17
17
  export declare function map<TItem, TResult>(context: Context, internals: ContextInternals, items: readonly TItem[], workflowType: ChildWorkflowTarget<TItem, TResult>, options?: WorkflowMapOptions): Generator<ContextOperationRequest, TResult[], unknown>;
18
18
  export declare function reduce<TItem, TAccumulator>(context: Context, internals: ContextInternals, items: readonly TItem[], workflowType: ChildWorkflowTarget<WorkflowReduceInput<TAccumulator, TItem>, TAccumulator>, initialValue: TAccumulator, options?: WorkflowReduceOptions): Generator<ContextOperationRequest, TAccumulator, unknown>;
@@ -28,6 +28,7 @@ export function createCompositionToken(internals, kind) {
28
28
  return `${kind}:${internals.stepIndex}`;
29
29
  }
30
30
  export function createCompositionChildWorkflowOptions(internals, token, index, options = void 0) {
31
+ assertCompositionAwaitsChildWorkflow(options);
31
32
  if (options?.id !== void 0)
32
33
  return options;
33
34
  return {
@@ -39,11 +40,20 @@ export function createReduceChildWorkflowOptions(internals, token, index, option
39
40
  if (options === void 0)
40
41
  return createCompositionChildWorkflowOptions(internals, token, index);
41
42
  const { idPrefix, ...childWorkflowOptions } = options;
43
+ assertCompositionAwaitsChildWorkflow(childWorkflowOptions);
42
44
  return createCompositionChildWorkflowOptions(internals, token, index, idPrefix !== void 0 ? {
43
45
  ...childWorkflowOptions,
44
46
  id: `${idPrefix}:${index}`
45
47
  } : childWorkflowOptions);
46
48
  }
49
+ function assertCompositionAwaitsChildWorkflow(options) {
50
+ if (typeof options !== "object" || options === null || !("parentClosePolicy" in options))
51
+ return;
52
+ const parentClosePolicy = options.parentClosePolicy;
53
+ if (parentClosePolicy === void 0 || parentClosePolicy === "await")
54
+ return;
55
+ throw Error('ctx.pipe, ctx.map, and ctx.reduce always await child workflow results. Use ctx.startChild() directly for parentClosePolicy: "abandon" or "request-cancel".');
56
+ }
47
57
  export function primeParallelOperations(operations) {
48
58
  const subOperations = [];
49
59
  for (const generator of operations) {
@@ -58,7 +68,7 @@ export function* startChild(context, internals, workflowType, input, options) {
58
68
  if (internals.accumulatedResults?.has(step)) {
59
69
  if (internals.explainMode)
60
70
  console.log(`[weft] ctx.startChild("${workflowType}") \u2192 Returning cached result from step ${step}`);
61
- return internals.accumulatedResults.get(step);
71
+ return resolveCachedStartChildResult(internals.accumulatedResults.get(step), options);
62
72
  }
63
73
  if (internals.explainMode) {
64
74
  console.log(`[weft] ctx.startChild("${workflowType}", ${JSON.stringify(input)})`);
@@ -74,7 +84,10 @@ export function* startChild(context, internals, workflowType, input, options) {
74
84
  ...options !== void 0 ? { options } : {}
75
85
  };
76
86
  context.accumulatedResults.set(step, result);
77
- return result;
87
+ return resolveCachedStartChildResult(result, options);
88
+ }
89
+ function resolveCachedStartChildResult(result, options) {
90
+ return (options?.parentClosePolicy ?? "await") === "await" ? result : result;
78
91
  }
79
92
  export function* pipe(context, internals, stages, input) {
80
93
  const pipelineToken = createCompositionToken(internals, "pipe");
@@ -0,0 +1,19 @@
1
+ import type { Context } from './index.ts';
2
+ /**
3
+ * Presence checks over a {@link Context}'s lazily-allocated internal maps. Each
4
+ * returns `true` only when the backing structure exists *and* is non-empty, so
5
+ * the checkpoint-commit and inline-parking paths can decide whether a context
6
+ * carries pending attribute changes, registered update handlers, or exposed
7
+ * accessors without forcing allocation through the public getters.
8
+ *
9
+ * Extracted from the `Context` class (which sits at the module line ceiling) as
10
+ * free functions; behavior is identical to the former `ctx.has*` getters.
11
+ *
12
+ * @module core/context/context-presence
13
+ */
14
+ /** True when the context has at least one pending search-attribute change. */
15
+ export declare function hasPendingAttributeChanges(context: Context): boolean;
16
+ /** True when the context has at least one registered update handler. */
17
+ export declare function hasUpdateHandlers(context: Context): boolean;
18
+ /** True when the context has at least one exposed accessor. */
19
+ export declare function hasExposedAccessors(context: Context): boolean;
@@ -0,0 +1,13 @@
1
+ import { getInternals } from "./internals.js";
2
+ export function hasPendingAttributeChanges(context) {
3
+ const pendingAttributeChanges = getInternals(context).pendingAttributeChanges;
4
+ return pendingAttributeChanges !== void 0 && Object.keys(pendingAttributeChanges).length > 0;
5
+ }
6
+ export function hasUpdateHandlers(context) {
7
+ const updateHandlers = getInternals(context).updateHandlers;
8
+ return updateHandlers !== void 0 && updateHandlers.size > 0;
9
+ }
10
+ export function hasExposedAccessors(context) {
11
+ const exposedValues = getInternals(context).exposedValues;
12
+ return exposedValues !== void 0 && exposedValues.size > 0;
13
+ }