@lostgradient/weft 0.2.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (579) hide show
  1. package/README.md +123 -43
  2. package/dist/cli/conformance.js +7 -1
  3. package/dist/cli/generated/operation-client.generated.d.ts +55 -13
  4. package/dist/cli/generated/operation-client.generated.js +3 -0
  5. package/dist/cli/help-text.d.ts +1 -1
  6. package/dist/cli/help-text.js +1 -0
  7. package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
  8. package/dist/cli/operation-catalog-snapshot.js +11 -0
  9. package/dist/cli/parse-schedule-arguments.js +3 -1
  10. package/dist/cli/schedule.js +2 -1
  11. package/dist/cli/types.d.ts +1 -0
  12. package/dist/cli-main.js +80 -79
  13. package/dist/client/handle-delegation.d.ts +7 -2
  14. package/dist/client/handle-delegation.js +9 -1
  15. package/dist/client/http-client-requests.d.ts +4 -1
  16. package/dist/client/http-client-requests.js +10 -0
  17. package/dist/client/http-client.d.ts +10 -4
  18. package/dist/client/http-client.js +18 -1
  19. package/dist/client/http-request.d.ts +11 -1
  20. package/dist/client/http-request.js +17 -7
  21. package/dist/client/index.d.ts +1 -1
  22. package/dist/client/interface.d.ts +100 -4
  23. package/dist/client/local.d.ts +7 -1
  24. package/dist/client/local.js +17 -2
  25. package/dist/client/start-body.d.ts +9 -2
  26. package/dist/client/start-body.js +13 -4
  27. package/dist/core/byte-arrays.d.ts +5 -0
  28. package/dist/core/byte-arrays.js +5 -0
  29. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  30. package/dist/core/checkpoint/lifecycle.js +9 -4
  31. package/dist/core/checkpoint/serialization.js +12 -5
  32. package/dist/core/codec/extension-codec.d.ts +16 -0
  33. package/dist/core/codec/extension-codec.js +104 -8
  34. package/dist/core/codec/index.d.ts +1 -0
  35. package/dist/core/codec/index.js +1 -0
  36. package/dist/core/codec/serializer-registry.d.ts +122 -0
  37. package/dist/core/codec/serializer-registry.js +51 -0
  38. package/dist/core/context/activity-retry-state.d.ts +38 -0
  39. package/dist/core/context/activity-retry-state.js +89 -0
  40. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  41. package/dist/core/context/activity-schedule-to-close.js +69 -0
  42. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  43. package/dist/core/context/child-workflow-pipe.js +15 -2
  44. package/dist/core/context/context-presence.d.ts +19 -0
  45. package/dist/core/context/context-presence.js +13 -0
  46. package/dist/core/context/durable-operations.d.ts +25 -0
  47. package/dist/core/context/durable-operations.js +64 -0
  48. package/dist/core/context/index.d.ts +18 -5
  49. package/dist/core/context/index.js +17 -12
  50. package/dist/core/context/internals.d.ts +29 -0
  51. package/dist/core/context/internals.js +6 -1
  52. package/dist/core/context/operation-request.d.ts +35 -0
  53. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  54. package/dist/core/context/run-operation.d.ts +21 -3
  55. package/dist/core/context/run-operation.js +56 -93
  56. package/dist/core/context/session-state.js +7 -8
  57. package/dist/core/context/speculative-child.js +2 -0
  58. package/dist/core/context/types.d.ts +15 -0
  59. package/dist/core/context/version-patching.d.ts +8 -0
  60. package/dist/core/context/version-patching.js +40 -0
  61. package/dist/core/context/workflow-logger.d.ts +98 -0
  62. package/dist/core/context/workflow-logger.js +68 -0
  63. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  64. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  65. package/dist/core/engine/activity-per-attempt-timeout.d.ts +41 -0
  66. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  67. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  68. package/dist/core/engine/activity-reconciliation.js +12 -1
  69. package/dist/core/engine/activity-resolution.d.ts +23 -0
  70. package/dist/core/engine/activity-resolution.js +37 -0
  71. package/dist/core/engine/aggregate.js +66 -30
  72. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  73. package/dist/core/engine/async-activity-completion.js +53 -12
  74. package/dist/core/engine/attributes-tags.js +9 -4
  75. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  76. package/dist/core/engine/bulk-operations-purge.js +38 -3
  77. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  78. package/dist/core/engine/bulk-operations-shared.js +8 -2
  79. package/dist/core/engine/bulk-operations.d.ts +4 -1
  80. package/dist/core/engine/bulk-operations.js +235 -24
  81. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  82. package/dist/core/engine/callback-creators-bundles.js +30 -2
  83. package/dist/core/engine/callback-creators-core.js +6 -4
  84. package/dist/core/engine/callback-creators-router.js +10 -0
  85. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  86. package/dist/core/engine/callback-creators-schedule.js +12 -8
  87. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  88. package/dist/core/engine/candidate-read-batching.js +1 -0
  89. package/dist/core/engine/checkpoint-io.js +61 -25
  90. package/dist/core/engine/checkpoint-reads.js +3 -2
  91. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  92. package/dist/core/engine/checkpoint-replay.js +242 -0
  93. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  94. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  95. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  96. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  97. package/dist/core/engine/child-workflow.js +27 -4
  98. package/dist/core/engine/condition-waiters.d.ts +14 -0
  99. package/dist/core/engine/condition-waiters.js +5 -0
  100. package/dist/core/engine/construction.d.ts +3 -1
  101. package/dist/core/engine/construction.js +30 -8
  102. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  103. package/dist/core/engine/coordination-branch-executors.js +107 -0
  104. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  105. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  106. package/dist/core/engine/disposal.js +25 -0
  107. package/dist/core/engine/engine-create-types.d.ts +14 -18
  108. package/dist/core/engine/engine-internal-types.d.ts +38 -3
  109. package/dist/core/engine/engine-leak-warnings.d.ts +6 -0
  110. package/dist/core/engine/engine-leak-warnings.js +4 -0
  111. package/dist/core/engine/engine-runtime-helpers.d.ts +17 -0
  112. package/dist/core/engine/engine-runtime-helpers.js +26 -5
  113. package/dist/core/engine/errors.d.ts +121 -0
  114. package/dist/core/engine/errors.js +45 -1
  115. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  116. package/dist/core/engine/event-log-compaction.js +20 -2
  117. package/dist/core/engine/fenced-write.d.ts +65 -0
  118. package/dist/core/engine/fenced-write.js +71 -0
  119. package/dist/core/engine/finalizer-state.d.ts +28 -0
  120. package/dist/core/engine/finalizer-state.js +16 -0
  121. package/dist/core/engine/handle-result.js +1 -1
  122. package/dist/core/engine/handles.d.ts +97 -40
  123. package/dist/core/engine/handles.js +25 -27
  124. package/dist/core/engine/index.d.ts +125 -15
  125. package/dist/core/engine/index.js +207 -11
  126. package/dist/core/engine/inline-launch-queue.d.ts +14 -0
  127. package/dist/core/engine/inline-launch-queue.js +32 -7
  128. package/dist/core/engine/inline-parking.js +3 -2
  129. package/dist/core/engine/internals.d.ts +125 -13
  130. package/dist/core/engine/lease-codec.d.ts +35 -0
  131. package/dist/core/engine/lease-codec.js +32 -0
  132. package/dist/core/engine/lease-deposition.d.ts +66 -0
  133. package/dist/core/engine/lease-deposition.js +10 -0
  134. package/dist/core/engine/lease-errors.d.ts +99 -0
  135. package/dist/core/engine/lease-errors.js +30 -0
  136. package/dist/core/engine/lease-manager.d.ts +114 -0
  137. package/dist/core/engine/lease-manager.js +135 -0
  138. package/dist/core/engine/lifecycle/fork-helpers.js +1 -7
  139. package/dist/core/engine/lifecycle/persist.js +15 -52
  140. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  141. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  142. package/dist/core/engine/lifecycle/resume.js +39 -11
  143. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  144. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  145. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  146. package/dist/core/engine/lifecycle/start-commit.d.ts +56 -0
  147. package/dist/core/engine/lifecycle/start-commit.js +69 -0
  148. package/dist/core/engine/lifecycle/start-exec.d.ts +30 -2
  149. package/dist/core/engine/lifecycle/start-exec.js +38 -0
  150. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  151. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  152. package/dist/core/engine/lifecycle/start-or-signal-resolution.d.ts +79 -0
  153. package/dist/core/engine/lifecycle/start-or-signal-resolution.js +60 -0
  154. package/dist/core/engine/lifecycle/start-or-signal.d.ts +46 -0
  155. package/dist/core/engine/lifecycle/start-or-signal.js +71 -0
  156. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  157. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  158. package/dist/core/engine/lifecycle/start.d.ts +6 -6
  159. package/dist/core/engine/lifecycle/start.js +47 -45
  160. package/dist/core/engine/lifecycle/transition.js +17 -5
  161. package/dist/core/engine/lifecycle.d.ts +3 -2
  162. package/dist/core/engine/lifecycle.js +9 -2
  163. package/dist/core/engine/list-candidate-resolution.js +2 -2
  164. package/dist/core/engine/listing.js +10 -6
  165. package/dist/core/engine/operations-activity.d.ts +4 -11
  166. package/dist/core/engine/operations-activity.js +22 -49
  167. package/dist/core/engine/operations-coordination.d.ts +10 -0
  168. package/dist/core/engine/operations-coordination.js +43 -8
  169. package/dist/core/engine/operations-router.d.ts +6 -0
  170. package/dist/core/engine/operations-router.js +2 -0
  171. package/dist/core/engine/operations-speculate.js +6 -2
  172. package/dist/core/engine/operations-stream.js +12 -2
  173. package/dist/core/engine/operations-time.d.ts +4 -2
  174. package/dist/core/engine/operations-time.js +14 -2
  175. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  176. package/dist/core/engine/operations-wait-condition.js +62 -0
  177. package/dist/core/engine/ownership-options.d.ts +23 -0
  178. package/dist/core/engine/ownership-options.js +26 -0
  179. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  180. package/dist/core/engine/payload-size-policy.js +4 -0
  181. package/dist/core/engine/pending-updates.d.ts +17 -0
  182. package/dist/core/engine/pending-updates.js +33 -11
  183. package/dist/core/engine/persisted-data-version.d.ts +5 -9
  184. package/dist/core/engine/persisted-data-version.js +4 -5
  185. package/dist/core/engine/queries.js +1 -1
  186. package/dist/core/engine/registration.d.ts +1 -0
  187. package/dist/core/engine/registration.js +18 -3
  188. package/dist/core/engine/schedule-handle.d.ts +45 -0
  189. package/dist/core/engine/schedule-handle.js +26 -0
  190. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  191. package/dist/core/engine/schedule-jitter.js +10 -0
  192. package/dist/core/engine/schedule-run.d.ts +17 -0
  193. package/dist/core/engine/schedule-run.js +38 -0
  194. package/dist/core/engine/schedule-timer.js +81 -17
  195. package/dist/core/engine/schedules.d.ts +8 -5
  196. package/dist/core/engine/schedules.js +44 -19
  197. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  198. package/dist/core/engine/search-attribute-records.js +17 -0
  199. package/dist/core/engine/second-instance-detector.d.ts +96 -0
  200. package/dist/core/engine/second-instance-detector.js +108 -0
  201. package/dist/core/engine/signals.d.ts +38 -0
  202. package/dist/core/engine/signals.js +55 -19
  203. package/dist/core/engine/state-utilities.d.ts +49 -2
  204. package/dist/core/engine/state-utilities.js +114 -3
  205. package/dist/core/engine/storage-io.d.ts +16 -2
  206. package/dist/core/engine/storage-io.js +26 -5
  207. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  208. package/dist/core/engine/stream-chunk-loading.js +24 -1
  209. package/dist/core/engine/sub-operation.js +22 -3
  210. package/dist/core/engine/termination/cleanup.d.ts +28 -1
  211. package/dist/core/engine/termination/cleanup.js +44 -2
  212. package/dist/core/engine/termination/complete.js +48 -9
  213. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  214. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  215. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  216. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  217. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  218. package/dist/core/engine/termination/finalizer.js +159 -0
  219. package/dist/core/engine/termination/suspend.d.ts +70 -0
  220. package/dist/core/engine/termination/suspend.js +41 -0
  221. package/dist/core/engine/termination.d.ts +5 -2
  222. package/dist/core/engine/termination.js +6 -0
  223. package/dist/core/engine/updates.js +5 -25
  224. package/dist/core/engine/validation/schedule.d.ts +2 -1
  225. package/dist/core/engine/validation/schedule.js +51 -2
  226. package/dist/core/engine/validation.js +54 -3
  227. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  228. package/dist/core/engine/waiting-update-response.js +22 -0
  229. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  230. package/dist/core/engine/workflow-concurrency.js +136 -0
  231. package/dist/core/engine/workflow-feed.d.ts +9 -8
  232. package/dist/core/engine/workflow-feed.js +4 -1
  233. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  234. package/dist/core/engine/workflow-indexes.js +10 -0
  235. package/dist/core/engine/workflow-state-stream.js +33 -13
  236. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  237. package/dist/core/engine-helpers.js +1 -0
  238. package/dist/core/events/activity-events.d.ts +43 -12
  239. package/dist/core/events/activity-events.js +28 -0
  240. package/dist/core/events/attribute-events.d.ts +2 -3
  241. package/dist/core/events/event-map.d.ts +19 -12
  242. package/dist/core/events/index.d.ts +1 -0
  243. package/dist/core/events/index.js +1 -0
  244. package/dist/core/events/schedule-events.d.ts +71 -0
  245. package/dist/core/events/schedule-events.js +29 -0
  246. package/dist/core/events/signal-events.d.ts +4 -6
  247. package/dist/core/events/system-events.d.ts +29 -19
  248. package/dist/core/events/system-events.js +26 -0
  249. package/dist/core/events/update-events.d.ts +6 -8
  250. package/dist/core/events/workflow-events.d.ts +108 -20
  251. package/dist/core/events/workflow-events.js +35 -0
  252. package/dist/core/failure-categories.js +5 -17
  253. package/dist/core/fault-code.d.ts +9 -3
  254. package/dist/core/fault-code.js +1 -0
  255. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  256. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  257. package/dist/core/inline-execution-strategy.d.ts +31 -36
  258. package/dist/core/inline-execution-strategy.js +16 -27
  259. package/dist/core/list-filter-validation.d.ts +1 -1
  260. package/dist/core/list-filter-validation.js +2 -1
  261. package/dist/core/payload-size.d.ts +1 -1
  262. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  263. package/dist/core/review/events.d.ts +6 -8
  264. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  265. package/dist/core/scheduler/scheduler-class.js +38 -11
  266. package/dist/core/scheduler/timer-batch.js +9 -1
  267. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  268. package/dist/core/scheduler/timer-sources.js +11 -5
  269. package/dist/core/session-state.d.ts +0 -1
  270. package/dist/core/session-state.js +2 -2
  271. package/dist/core/start-workflow-validation.d.ts +56 -0
  272. package/dist/core/start-workflow-validation.js +30 -1
  273. package/dist/core/step-context.d.ts +10 -6
  274. package/dist/core/step-context.js +7 -15
  275. package/dist/core/types/activity-verification.d.ts +67 -0
  276. package/dist/core/types/activity-verification.js +0 -0
  277. package/dist/core/types/activity.d.ts +86 -64
  278. package/dist/core/types/bulk.d.ts +50 -9
  279. package/dist/core/types/checkpoint.d.ts +44 -8
  280. package/dist/core/types/identity.d.ts +8 -1
  281. package/dist/core/types/launch-metadata.d.ts +33 -0
  282. package/dist/core/types/launch-metadata.js +0 -0
  283. package/dist/core/types/list-options.d.ts +146 -0
  284. package/dist/core/types/list-options.js +0 -0
  285. package/dist/core/types/message-handles.d.ts +25 -0
  286. package/dist/core/types/options.d.ts +165 -215
  287. package/dist/core/types/reviews.d.ts +2 -1
  288. package/dist/core/types/schedules.d.ts +39 -3
  289. package/dist/core/types/services-resolution.d.ts +47 -0
  290. package/dist/core/types/services-resolution.js +0 -0
  291. package/dist/core/types/state.d.ts +11 -11
  292. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  293. package/dist/core/types/workflow-builder-runtime.js +11 -2
  294. package/dist/core/types/workflow-builder.d.ts +47 -15
  295. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  296. package/dist/core/types/workflow-concurrency.js +0 -0
  297. package/dist/core/types/workflow-context.d.ts +157 -14
  298. package/dist/core/types/workflow-definition.d.ts +53 -10
  299. package/dist/core/types/workflow-function.d.ts +101 -9
  300. package/dist/core/types/workflow-log.d.ts +98 -0
  301. package/dist/core/types/workflow-log.js +0 -0
  302. package/dist/core/types/workflow-registries.d.ts +14 -3
  303. package/dist/core/types/workflow-registry.d.ts +3 -0
  304. package/dist/core/types/workflow-snapshot.d.ts +29 -0
  305. package/dist/core/types/workflow-snapshot.js +0 -0
  306. package/dist/core/types.d.ts +7 -0
  307. package/dist/core/types.js +7 -0
  308. package/dist/core/versioning.d.ts +9 -39
  309. package/dist/core/versioning.js +2 -12
  310. package/dist/core/weft-error.d.ts +44 -1
  311. package/dist/core/weft-error.js +19 -1
  312. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  313. package/dist/core/worker-execution-strategy.js +40 -36
  314. package/dist/core/worker-inbound-message.d.ts +38 -0
  315. package/dist/core/worker-inbound-message.js +37 -0
  316. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  317. package/dist/core/worker-log-abuse-counter.js +107 -0
  318. package/dist/core/worker-message-helpers.d.ts +47 -0
  319. package/dist/core/worker-message-helpers.js +26 -0
  320. package/dist/core/worker-protocol-guard.js +1 -1
  321. package/dist/core/worker-protocol-log.d.ts +56 -0
  322. package/dist/core/worker-protocol-log.js +18 -0
  323. package/dist/core/worker-protocol.d.ts +23 -0
  324. package/dist/core/worker-protocol.js +12 -2
  325. package/dist/core/workflow-version-tuple.d.ts +3 -9
  326. package/dist/core/workflow-version-tuple.js +2 -3
  327. package/dist/diagnostics/doctor.js +6 -3
  328. package/dist/diagnostics/format.js +3 -8
  329. package/dist/diagnostics/types.d.ts +5 -5
  330. package/dist/diagnostics/validate.d.ts +0 -1
  331. package/dist/diagnostics/version-check.d.ts +1 -1
  332. package/dist/diagnostics/version-check.js +10 -13
  333. package/dist/index.d.ts +13 -11
  334. package/dist/index.js +39 -4
  335. package/dist/json-schema.js +3 -3
  336. package/dist/mcp/cli.js +35 -35
  337. package/dist/mcp/dispatcher.js +1 -1
  338. package/dist/mcp/http.js +16 -6
  339. package/dist/mcp/list-filter.js +2 -1
  340. package/dist/mcp/protocol.d.ts +2 -0
  341. package/dist/mcp/protocol.js +1 -1
  342. package/dist/mcp/session.d.ts +16 -0
  343. package/dist/mcp/session.js +60 -6
  344. package/dist/mcp/tools.js +73 -6
  345. package/dist/observability/index.js +2 -2
  346. package/dist/server/asyncapi-channels.js +5 -2
  347. package/dist/server/attribute-filters.d.ts +8 -3
  348. package/dist/server/attribute-filters.js +6 -1
  349. package/dist/server/authentication/api-key.d.ts +2 -1
  350. package/dist/server/authentication/api-key.js +5 -2
  351. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  352. package/dist/server/authentication/constant-time-api-key.js +24 -0
  353. package/dist/server/authentication/index.d.ts +1 -1
  354. package/dist/server/authentication/index.js +7 -4
  355. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  356. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  357. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  358. package/dist/server/fault-to-http.js +8 -1
  359. package/dist/server/fault-to-json-rpc.js +1 -0
  360. package/dist/server/fleet-event-feed.d.ts +31 -0
  361. package/dist/server/fleet-event-feed.js +157 -0
  362. package/dist/server/handler/index.js +1 -1
  363. package/dist/server/handler/response-helpers.js +2 -1
  364. package/dist/server/handler/route-dispatch.d.ts +6 -3
  365. package/dist/server/handler/route-dispatch.js +2 -2
  366. package/dist/server/handler.js +31 -31
  367. package/dist/server/index.d.ts +32 -2
  368. package/dist/server/index.js +35 -35
  369. package/dist/server/interactive-operations.js +1 -0
  370. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  371. package/dist/server/json-rpc-transport-helpers.js +2 -1
  372. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  373. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  374. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  375. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  376. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  377. package/dist/server/json-rpc-websocket-types.js +0 -0
  378. package/dist/server/json-rpc-websocket-validation.js +20 -4
  379. package/dist/server/json-rpc-websocket.d.ts +2 -43
  380. package/dist/server/json-rpc-websocket.js +57 -74
  381. package/dist/server/openapi.d.ts +2 -1
  382. package/dist/server/openapi.js +1 -3
  383. package/dist/server/openrpc-document-schema.d.ts +78 -0
  384. package/dist/server/openrpc-document-schema.js +27 -1
  385. package/dist/server/openrpc-errors.d.ts +3 -0
  386. package/dist/server/openrpc-errors.js +2 -1
  387. package/dist/server/openrpc.js +32 -0
  388. package/dist/server/operation-catalog/index.d.ts +1 -1
  389. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  390. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  391. package/dist/server/operation-catalog/pipeline.js +8 -1
  392. package/dist/server/operation-catalog/registry.js +13 -0
  393. package/dist/server/operation-catalog/types.d.ts +20 -9
  394. package/dist/server/operation-fault.d.ts +10 -0
  395. package/dist/server/operation-fault.js +2 -0
  396. package/dist/server/operation-registry.d.ts +12 -11
  397. package/dist/server/operation-registry.js +12 -3
  398. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  399. package/dist/server/operations/async-activity.d.ts +2 -2
  400. package/dist/server/operations/async-activity.js +12 -7
  401. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  402. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  403. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  404. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  405. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  406. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  407. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  408. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  409. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  410. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  411. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  412. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  413. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  414. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  415. package/dist/server/operations/create-schedule.d.ts +3 -1
  416. package/dist/server/operations/create-schedule.js +29 -11
  417. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  418. package/dist/server/operations/fleet-events-subscription.js +99 -0
  419. package/dist/server/operations/fork-workflow.d.ts +1 -1
  420. package/dist/server/operations/fork-workflow.js +3 -2
  421. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  422. package/dist/server/operations/get-registry.d.ts +1 -1
  423. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  424. package/dist/server/operations/get-review.d.ts +1 -1
  425. package/dist/server/operations/get-schedule.d.ts +1 -1
  426. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  427. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  428. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  429. package/dist/server/operations/get-task-diagnostics.js +101 -7
  430. package/dist/server/operations/get-update-result.d.ts +1 -1
  431. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  432. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  433. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  434. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  435. package/dist/server/operations/get-workflow.d.ts +1 -1
  436. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  437. package/dist/server/operations/list-reviews.d.ts +1 -1
  438. package/dist/server/operations/list-schedules.d.ts +1 -1
  439. package/dist/server/operations/list-task-queues.d.ts +2 -2
  440. package/dist/server/operations/list-workers.d.ts +2 -2
  441. package/dist/server/operations/list-workflows.d.ts +1 -1
  442. package/dist/server/operations/operation-helpers.d.ts +16 -1
  443. package/dist/server/operations/operation-helpers.js +15 -3
  444. package/dist/server/operations/pause-schedule.d.ts +1 -1
  445. package/dist/server/operations/purge-workflows.d.ts +5 -5
  446. package/dist/server/operations/purge-workflows.js +2 -2
  447. package/dist/server/operations/query-workflow.d.ts +1 -1
  448. package/dist/server/operations/query-workflow.js +3 -2
  449. package/dist/server/operations/recover-all.d.ts +1 -1
  450. package/dist/server/operations/replay-workflow.d.ts +1 -1
  451. package/dist/server/operations/resume-schedule.d.ts +1 -1
  452. package/dist/server/operations/resume-workflow.js +2 -2
  453. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  454. package/dist/server/operations/set-workflow-attributes.js +6 -3
  455. package/dist/server/operations/signal-workflow.js +8 -3
  456. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  457. package/dist/server/operations/start-or-signal-workflow.d.ts +44 -0
  458. package/dist/server/operations/start-or-signal-workflow.js +130 -0
  459. package/dist/server/operations/start-workflow-options.d.ts +38 -0
  460. package/dist/server/operations/start-workflow-options.js +63 -0
  461. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  462. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  463. package/dist/server/operations/start-workflow.d.ts +1 -1
  464. package/dist/server/operations/start-workflow.js +15 -92
  465. package/dist/server/operations/storage.d.ts +6 -6
  466. package/dist/server/operations/storage.js +24 -14
  467. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  468. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  469. package/dist/server/operations/submit-review-decision.js +6 -3
  470. package/dist/server/operations/suspend-workflow.d.ts +13 -0
  471. package/dist/server/operations/suspend-workflow.js +36 -0
  472. package/dist/server/operations/update-schedule.d.ts +1 -1
  473. package/dist/server/operations/update-schedule.js +7 -4
  474. package/dist/server/operations/update-workflow.d.ts +1 -1
  475. package/dist/server/operations/update-workflow.js +7 -3
  476. package/dist/server/operations/worker-drain.d.ts +8 -8
  477. package/dist/server/operations/worker-drain.js +11 -8
  478. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  479. package/dist/server/operations/workflow-events-subscription.js +43 -8
  480. package/dist/server/rest-binding.d.ts +21 -8
  481. package/dist/server/rest-bindings.js +24 -0
  482. package/dist/server/rest-body.d.ts +10 -0
  483. package/dist/server/rest-body.js +80 -0
  484. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  485. package/dist/server/runtime/authentication-bridge.js +33 -6
  486. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  487. package/dist/server/runtime/client-visible-events.js +65 -0
  488. package/dist/server/runtime/context.d.ts +7 -0
  489. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  490. package/dist/server/runtime/event-broadcasting.js +72 -38
  491. package/dist/server/runtime/retry.d.ts +1 -0
  492. package/dist/server/runtime/retry.js +14 -0
  493. package/dist/server/runtime/shutdown.d.ts +7 -6
  494. package/dist/server/runtime/shutdown.js +6 -1
  495. package/dist/server/runtime/task-dispatch.js +5 -3
  496. package/dist/server/runtime/task-polling.d.ts +16 -2
  497. package/dist/server/runtime/task-polling.js +80 -24
  498. package/dist/server/runtime/task-reconciliation.js +9 -1
  499. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  500. package/dist/server/runtime/task-result-resolution.js +81 -0
  501. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  502. package/dist/server/runtime/websocket-stream.js +173 -7
  503. package/dist/server/runtime/websocket-upgrade.js +22 -3
  504. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  505. package/dist/server/runtime/websocket-worker.js +46 -30
  506. package/dist/server/serve-internals.d.ts +11 -1
  507. package/dist/server/serve-internals.js +20 -2
  508. package/dist/server/task-state.d.ts +38 -0
  509. package/dist/server/task-state.js +28 -0
  510. package/dist/server/workflow-event-feed.d.ts +36 -115
  511. package/dist/server/workflow-event-feed.js +92 -27
  512. package/dist/service-worker/index.js +31 -31
  513. package/dist/storage/auto.js +1 -1
  514. package/dist/storage/bun-sql.js +24 -0
  515. package/dist/storage/capabilities.d.ts +10 -2
  516. package/dist/storage/capabilities.js +2 -2
  517. package/dist/storage/compressed-storage.js +1 -1
  518. package/dist/storage/default-scope.d.ts +7 -4
  519. package/dist/storage/http.js +2 -2
  520. package/dist/storage/index.d.ts +81 -4
  521. package/dist/storage/indexeddb.js +1 -1
  522. package/dist/storage/interface.d.ts +189 -0
  523. package/dist/storage/interface.js +1 -1
  524. package/dist/storage/key-prefixes.d.ts +1 -1
  525. package/dist/storage/key-prefixes.js +12 -0
  526. package/dist/storage/lmdb.d.ts +4 -3
  527. package/dist/storage/lmdb.js +1 -1
  528. package/dist/storage/memory.js +1 -1
  529. package/dist/storage/neon-batch.d.ts +30 -0
  530. package/dist/storage/neon-batch.js +30 -0
  531. package/dist/storage/neon-value-mapping.d.ts +74 -0
  532. package/dist/storage/neon-value-mapping.js +23 -0
  533. package/dist/storage/neon.d.ts +124 -0
  534. package/dist/storage/neon.js +15 -0
  535. package/dist/storage/node-sqlite-loader.d.ts +71 -0
  536. package/dist/storage/node-sqlite-loader.js +41 -0
  537. package/dist/storage/node-sqlite.d.ts +1 -19
  538. package/dist/storage/node-sqlite.js +61 -32
  539. package/dist/storage/postgres-key-value-queries.d.ts +104 -0
  540. package/dist/storage/postgres-key-value-queries.js +101 -0
  541. package/dist/storage/resolve.d.ts +2 -165
  542. package/dist/storage/resolve.js +1 -1
  543. package/dist/storage/scoped-storage.js +1 -1
  544. package/dist/storage/storage-configuration.d.ts +209 -0
  545. package/dist/storage/storage-configuration.js +0 -0
  546. package/dist/storage/testing.d.ts +168 -0
  547. package/dist/storage/testing.js +2 -0
  548. package/dist/storage/text-value-store.d.ts +9 -9
  549. package/dist/storage/turso.d.ts +8 -0
  550. package/dist/storage/turso.js +2 -2
  551. package/dist/storage/typed-storage.js +1 -1
  552. package/dist/storage/web-extension.js +1 -1
  553. package/dist/testing/index.js +35 -35
  554. package/dist/version.d.ts +1 -1
  555. package/dist/version.js +1 -1
  556. package/dist/worker/index.js +9 -5
  557. package/dist/worker/long-poll.js +4 -0
  558. package/dist/worker/protocol-messages.d.ts +20 -0
  559. package/dist/worker/protocol-schemas.d.ts +32 -0
  560. package/dist/worker/protocol-schemas.js +8 -4
  561. package/dist/worker/protocol-task-result.d.ts +28 -0
  562. package/dist/worker/protocol-task-result.js +76 -0
  563. package/dist/worker/protocol.d.ts +4 -15
  564. package/dist/worker/protocol.js +1 -1
  565. package/dist/worker/registry/fair-share.d.ts +29 -0
  566. package/dist/worker/registry/fair-share.js +30 -0
  567. package/dist/worker/registry/routing.d.ts +18 -0
  568. package/dist/worker/registry/routing.js +14 -0
  569. package/dist/worker/registry/types.d.ts +7 -0
  570. package/dist/worker/registry.d.ts +16 -1
  571. package/dist/worker/registry.js +24 -36
  572. package/dist/workers/worker-replay-state.d.ts +32 -0
  573. package/dist/workers/worker-replay-state.js +35 -0
  574. package/dist/workers/worker-state-namespace.d.ts +21 -0
  575. package/dist/workers/worker-state-namespace.js +13 -0
  576. package/dist/workers/workflow-runner.d.ts +19 -15
  577. package/dist/workers/workflow-runner.js +72 -60
  578. package/dist/workers/workflow-worker-entry.js +5 -2
  579. package/package.json +21 -4
@@ -0,0 +1,64 @@
1
+ import type { ActivityContext } from '../types.ts';
2
+ import type { EngineInternals } from './internals.ts';
3
+ /**
4
+ * Per-step heartbeat tracking for {@link ActivityContext.lastHeartbeatDetails}.
5
+ *
6
+ * The store is keyed `workflowId -> step` (not `workflowId` alone) so a retry of
7
+ * an activity step reads the heartbeat ITS prior attempt recorded — and so a
8
+ * later step's first attempt never inherits an earlier step's heartbeat, and
9
+ * concurrent `ctx.all` activities never clobber one another. The step is stable
10
+ * across retry attempts (assigned once at `stepIndex++`). Held only in engine
11
+ * memory and cleared by workflowId (the outer key) on terminal cleanup and purge.
12
+ */
13
+ /** Record the heartbeat the current attempt of a step sent. */
14
+ export declare function recordLastHeartbeatForStep(internals: EngineInternals, workflowId: string, step: number, details: unknown): void;
15
+ /** Read the heartbeat a prior attempt of this step recorded, or `undefined`. */
16
+ export declare function readLastHeartbeatForStep(internals: EngineInternals, workflowId: string, step: number): unknown;
17
+ /**
18
+ * Drop the heartbeat tracked for a single step once that step has completed
19
+ * successfully — after inline verify, and (on the idempotency path) after the
20
+ * reconciliation write, so a verify-rejection retry still reads its prior
21
+ * attempt's heartbeat. The plain path has no reconciliation write; both paths
22
+ * call this only at their successful return. Removes the inner-map entry and
23
+ * drops the outer workflow entry when its last step clears, so a long-lived
24
+ * workflow doesn't accumulate stale per-step heartbeats. Clearing late is
25
+ * harmless (bounded by terminal cleanup); clearing early would strip the
26
+ * resumable-batch heartbeat a retry depends on, so this is only ever called from
27
+ * the non-speculative success path.
28
+ */
29
+ export declare function clearLastHeartbeatForStep(internals: EngineInternals, workflowId: string, step: number): void;
30
+ /**
31
+ * #493: in development mode, emit a COARSE warning when an inline activity RETRY
32
+ * (`attempt > 1`) starts with no `lastHeartbeatDetails` — the closest runtime
33
+ * proxy for the resumable-batch footgun. We cannot distinguish "the prior attempt
34
+ * never heartbeated" (benign) from "the heartbeat was discarded by a process
35
+ * restart" (the dangerous case): the distinguishing fact is the wiped in-memory
36
+ * state, gone by definition. So the message names BOTH possibilities and never
37
+ * claims a restart happened. The gates (development, inline, attempt, missing
38
+ * heartbeat) are read straight off the code below; two facts are NOT derivable
39
+ * from it:
40
+ *
41
+ * - It fires on the speculative path too. A speculative `attempt > 1` that later
42
+ * rolls back still ran twice and still lost any resume payload, so the footgun
43
+ * is real regardless — letting it warn is the deliberate, honest choice.
44
+ * - It pairs with {@link clearLastHeartbeatForStep} without interference: the
45
+ * clear fires only on SUCCESS (a step that never retries) and this reads
46
+ * `undefined` only on a RETRY, and a cleared step is a completed step that by
47
+ * definition will not be retried.
48
+ *
49
+ * The inline gate keys on `!activityWorkerDispatcher` because dispatch is
50
+ * engine-wide today; the heartbeat cache is only ever written on the inline path,
51
+ * so whenever a dispatcher exists the cache is structurally empty and the gate is
52
+ * required to suppress a false warning on every worker retry. A future per-activity
53
+ * routing model would need this gate to key on the resolved per-dispatch mode
54
+ * instead.
55
+ */
56
+ export declare function warnIfRetryMissingHeartbeat(internals: EngineInternals, workflowId: string, step: number, attempt: number): void;
57
+ /**
58
+ * Build the {@link ActivityContext} handed to an inline activity function. The
59
+ * signal comes from the per-workflow AbortController (so workflow cancellation
60
+ * aborts it); `lastHeartbeatDetails` and `heartbeat` are wired to the per-step
61
+ * tracking above; `completeAsync` is supplied by the caller (it owns the
62
+ * async-completion token machinery).
63
+ */
64
+ export declare function buildActivityContext(internals: EngineInternals, workflowId: string, step: number, signal: AbortSignal, completeAsync: () => never): ActivityContext;
@@ -0,0 +1,42 @@
1
+ import { DevelopmentWarningEvent } from "../events.js";
2
+ export function recordLastHeartbeatForStep(internals, workflowId, step, details) {
3
+ let byStep = internals.lastHeartbeatDetailsByStep.get(workflowId);
4
+ if (byStep === void 0) {
5
+ byStep = new Map;
6
+ internals.lastHeartbeatDetailsByStep.set(workflowId, byStep);
7
+ }
8
+ byStep.set(step, details);
9
+ }
10
+ export function readLastHeartbeatForStep(internals, workflowId, step) {
11
+ return internals.lastHeartbeatDetailsByStep.get(workflowId)?.get(step);
12
+ }
13
+ export function clearLastHeartbeatForStep(internals, workflowId, step) {
14
+ const byStep = internals.lastHeartbeatDetailsByStep.get(workflowId);
15
+ if (byStep === void 0)
16
+ return;
17
+ byStep.delete(step);
18
+ if (byStep.size === 0)
19
+ internals.lastHeartbeatDetailsByStep.delete(workflowId);
20
+ }
21
+ export function warnIfRetryMissingHeartbeat(internals, workflowId, step, attempt) {
22
+ if (!internals.options.development)
23
+ return;
24
+ if (internals.activityWorkerDispatcher)
25
+ return;
26
+ if (attempt <= 1)
27
+ return;
28
+ if (readLastHeartbeatForStep(internals, workflowId, step) !== void 0)
29
+ return;
30
+ internals.engine.dispatchEvent(new DevelopmentWarningEvent(workflowId, `Activity retry (attempt ${attempt}) at step ${step} has no lastHeartbeatDetails. Either the previous attempt never recorded heartbeat details (it never called heartbeat(), or called it with no details), or the engine process restarted and discarded the in-memory heartbeat (it is not durable). The resumable-batch pattern only resumes across in-process retries; design the activity to restart cleanly when lastHeartbeatDetails is undefined.`, [`step.${step}.lastHeartbeatDetails`]));
31
+ }
32
+ export function buildActivityContext(internals, workflowId, step, signal, completeAsync) {
33
+ return {
34
+ signal,
35
+ lastHeartbeatDetails: readLastHeartbeatForStep(internals, workflowId, step),
36
+ heartbeat: (details) => {
37
+ internals.heartbeatDetails.set(workflowId, details);
38
+ recordLastHeartbeatForStep(internals, workflowId, step, details);
39
+ },
40
+ completeAsync
41
+ };
42
+ }
@@ -0,0 +1,41 @@
1
+ import type { ContextOperationRequest } from '../context.ts';
2
+ import type { EngineInternals } from './internals.ts';
3
+ type ActivityOperation = Extract<ContextOperationRequest, {
4
+ type: 'activity';
5
+ }>;
6
+ /**
7
+ * Resolve the per-attempt `timeout` setup for an activity attempt (#494).
8
+ *
9
+ * The cap is INLINE-only: worker-mode per-attempt bounds are governed by
10
+ * `visibilityTimeout`, and racing the engine's await against a deadline while a
11
+ * remote worker keeps running would orphan its result and risk double-execution on
12
+ * the next visibility-timeout re-dispatch. When a cap is configured, a fresh
13
+ * per-attempt `AbortController` drives cooperative cancellation; its signal is
14
+ * composited with the workflow-wide signal so the activity's `ctx.signal` aborts on
15
+ * EITHER workflow cancellation OR a per-attempt timeout — without the timeout
16
+ * reaching back to cancel the whole workflow (which would also poison the next
17
+ * retry's signal).
18
+ */
19
+ export declare function resolvePerAttemptTimeout(internals: EngineInternals, workflowId: string, operation: ActivityOperation): {
20
+ perAttemptTimeoutMs: number | undefined;
21
+ attemptAbortController: AbortController | undefined;
22
+ activitySignal: AbortSignal;
23
+ };
24
+ /**
25
+ * Bound a single inline activity attempt by its per-attempt `timeout` (#494).
26
+ *
27
+ * When `timeoutMs` is set and the attempt does not settle first, the returned
28
+ * promise rejects with {@link ActivityPerAttemptTimeoutError} and the per-attempt
29
+ * `AbortController` is aborted with that same error — so the activity's composite
30
+ * `ctx.signal` flips, letting a cooperating activity stop promptly. Weft cannot
31
+ * forcibly preempt the activity function: a non-cooperating activity keeps running
32
+ * in the background until it returns; only the workflow stops awaiting it. The
33
+ * abandoned invocation's eventual settlement is swallowed so it never surfaces as
34
+ * an unhandled rejection after the race has moved on. The timed-out rejection
35
+ * flows through the normal retry path, so a retry policy gets a fresh attempt with
36
+ * a fresh cap (and a fresh per-attempt controller).
37
+ *
38
+ * Returns the invocation unchanged (no timer armed) when no cap is configured.
39
+ */
40
+ export declare function withPerAttemptTimeout(invocation: unknown, timeoutMs: number | undefined, activityName: string, attempt: number, attemptAbortController: AbortController | undefined): Promise<unknown>;
41
+ export {};
@@ -0,0 +1,36 @@
1
+ import {
2
+ ActivityPerAttemptTimeoutError,
3
+ parsePerAttemptTimeoutMs
4
+ } from "../context/activity-schedule-to-close.js";
5
+ export function resolvePerAttemptTimeout(internals, workflowId, operation) {
6
+ const workflowAbortController = internals.inlineStrategy?.getAbortController(workflowId), perAttemptTimeoutMs = internals.activityWorkerDispatcher ? void 0 : parsePerAttemptTimeoutMs(operation.options?.timeout), attemptAbortController = perAttemptTimeoutMs === void 0 ? void 0 : new AbortController, activitySignal = composeActivitySignal(workflowAbortController?.signal, attemptAbortController?.signal);
7
+ return { perAttemptTimeoutMs, attemptAbortController, activitySignal };
8
+ }
9
+ function composeActivitySignal(workflowSignal, attemptSignal) {
10
+ const signals = [workflowSignal, attemptSignal].filter((signal) => signal !== void 0), [first] = signals;
11
+ if (first === void 0)
12
+ return new AbortController().signal;
13
+ if (signals.length === 1)
14
+ return first;
15
+ return AbortSignal.any(signals);
16
+ }
17
+ export async function withPerAttemptTimeout(invocation, timeoutMs, activityName, attempt, attemptAbortController) {
18
+ if (timeoutMs === void 0)
19
+ return invocation;
20
+ const activityPromise = Promise.resolve(invocation);
21
+ activityPromise.catch(() => {});
22
+ let timer;
23
+ const deadline = new Promise((_resolve, reject) => {
24
+ timer = setTimeout(() => {
25
+ const error = new ActivityPerAttemptTimeoutError(activityName, attempt, timeoutMs);
26
+ reject(error);
27
+ attemptAbortController?.abort(error);
28
+ }, timeoutMs);
29
+ });
30
+ try {
31
+ return await Promise.race([activityPromise, deadline]);
32
+ } finally {
33
+ if (timer !== void 0)
34
+ clearTimeout(timer);
35
+ }
36
+ }
@@ -101,6 +101,7 @@ export declare function resolveStartedActivityReconciliationRecord(internals: En
101
101
  completedResult: unknown;
102
102
  }>;
103
103
  export declare function writeActivityReconciliationTransition(storage: Storage, reference: ActivityReconciliationReference, expectedRecord: ActivityReconciliationRecord, nextRecord: ActivityReconciliationRecord): Promise<void>;
104
+ export declare function stageActivityReconciliationTransitionWithAtomicWorkflowCommit(internals: EngineInternals, workflowId: string, reference: ActivityReconciliationReference, expectedRecord: ActivityReconciliationRecord, nextRecord: ActivityReconciliationRecord): void;
104
105
  export declare function normalizePreDispatchVerificationResult(result: ActivityVerificationResult): 'not-completed' | 'completed-result-unavailable' | 'indeterminate' | {
105
106
  result: unknown;
106
107
  };
@@ -6,6 +6,7 @@ import {
6
6
  import { decode, encode } from "../codec.js";
7
7
  import { assertPayloadWithinLimit } from "../payload-size.js";
8
8
  import { WeftError } from "../weft-error.js";
9
+ import { stageAtomicWorkflowCommitSideEffects } from "./checkpoint-side-effects.js";
9
10
 
10
11
  export class ActivityReconciliationCapabilityError extends WeftError {
11
12
  constructor() {
@@ -95,9 +96,19 @@ export async function resolveStartedActivityReconciliationRecord(internals, work
95
96
  return { completedResult: normalized.result };
96
97
  }
97
98
  export async function writeActivityReconciliationTransition(storage, reference, expectedRecord, nextRecord) {
98
- if (!await storageConditionalBatch(storage, [{ key: reference.key, expectedValue: encode(expectedRecord) }], [{ type: "put", key: reference.key, value: encode(nextRecord) }]))
99
+ const sideEffects = buildActivityReconciliationTransitionSideEffects(reference, expectedRecord, nextRecord);
100
+ if (!await storageConditionalBatch(storage, sideEffects.conditions, sideEffects.operations))
99
101
  throw new ActivityReconciliationConflictError("Activity reconciliation completion lost compare-and-set ownership.");
100
102
  }
103
+ export function stageActivityReconciliationTransitionWithAtomicWorkflowCommit(internals, workflowId, reference, expectedRecord, nextRecord) {
104
+ stageAtomicWorkflowCommitSideEffects(internals, workflowId, buildActivityReconciliationTransitionSideEffects(reference, expectedRecord, nextRecord));
105
+ }
106
+ function buildActivityReconciliationTransitionSideEffects(reference, expectedRecord, nextRecord) {
107
+ return {
108
+ conditions: [{ key: reference.key, expectedValue: encode(expectedRecord) }],
109
+ operations: [{ type: "put", key: reference.key, value: encode(nextRecord) }]
110
+ };
111
+ }
101
112
  export function normalizePreDispatchVerificationResult(result) {
102
113
  if (result === "not-completed")
103
114
  return "not-completed";
@@ -0,0 +1,23 @@
1
+ import type { ContextOperationRequest } from '../context.ts';
2
+ import type { EngineInternals } from './internals.ts';
3
+ import type { ActivityFunctionWithMetadata } from './operations-activity.ts';
4
+ type ActivityOperation = Extract<ContextOperationRequest, {
5
+ type: 'activity';
6
+ }>;
7
+ /**
8
+ * Resolve the activity callable along with its attached metadata (compensation,
9
+ * verification). Returns `undefined` when no registry and no `operation.fn`
10
+ * resolve the name — the metadata path treats a miss as advisory rather than
11
+ * fatal.
12
+ */
13
+ export declare function getActivityFunctionWithMetadata(internals: EngineInternals, workflowId: string, operation: ActivityOperation): ActivityFunctionWithMetadata | undefined;
14
+ /**
15
+ * Resolve the activity function for a given operation. Uses the same
16
+ * per-workflow-first-then-global ordering as `getActivityFunctionWithMetadata`.
17
+ * For inline-mode callers that pass an `operation.fn` directly, the registries
18
+ * are still consulted first so a workflow's locally-scoped activity wins over
19
+ * the bare callable. Throws `ActivityResolutionError` when neither path
20
+ * resolves.
21
+ */
22
+ export declare function resolveActivityFunction(internals: EngineInternals, workflowId: string, operation: ActivityOperation): (...arguments_: unknown[]) => unknown;
23
+ export {};
@@ -0,0 +1,37 @@
1
+ import { ActivityResolutionError } from "./errors.js";
2
+ function resolveActivityViaRegistries(internals, workflowId, activityName) {
3
+ const workflowType = internals.workflowTypeByWorkflowId.get(workflowId);
4
+ if (workflowType !== void 0) {
5
+ const perWorkflow = internals.activityRegistriesByWorkflow.get(workflowType);
6
+ if (perWorkflow !== void 0) {
7
+ const perWorkflowFn = perWorkflow.resolve(activityName);
8
+ if (perWorkflowFn)
9
+ return { fn: perWorkflowFn, workflowType };
10
+ }
11
+ const globalFn = internals.activityRegistry.resolve(activityName);
12
+ if (globalFn)
13
+ return { fn: globalFn, workflowType };
14
+ return;
15
+ }
16
+ const globalFn = internals.activityRegistry.resolve(activityName);
17
+ if (globalFn)
18
+ return { fn: globalFn, workflowType: "<unknown>" };
19
+ return;
20
+ }
21
+ export function getActivityFunctionWithMetadata(internals, workflowId, operation) {
22
+ const resolved = resolveActivityViaRegistries(internals, workflowId, operation.activityName);
23
+ if (resolved)
24
+ return resolved.fn;
25
+ if (typeof operation.fn === "function")
26
+ return operation.fn;
27
+ return;
28
+ }
29
+ export function resolveActivityFunction(internals, workflowId, operation) {
30
+ const resolved = resolveActivityViaRegistries(internals, workflowId, operation.activityName);
31
+ if (resolved)
32
+ return resolved.fn;
33
+ if (operation.fn)
34
+ return operation.fn;
35
+ const workflowType = internals.workflowTypeByWorkflowId.get(workflowId) ?? "<unknown>";
36
+ throw new ActivityResolutionError(workflowType, operation.activityName);
37
+ }
@@ -5,12 +5,16 @@ import {
5
5
  MAX_AGGREGATE_DISTINCT_KEYS,
6
6
  normalizeAggregateOptions
7
7
  } from "../aggregate-validation.js";
8
- import { decode } from "../codec.js";
9
8
  import { normalizeListFilter } from "../list-filter-validation.js";
10
9
  import { WeftError } from "../weft-error.js";
11
10
  import { normalizeWorkflowTags } from "../workflow-tags.js";
11
+ import { CONSTRAINED_ID_CHUNK_SIZE } from "./candidate-read-batching.js";
12
12
  import { resolveListCandidateIds } from "./list-candidate-resolution.js";
13
- import { matchesListFilter } from "./state-utilities.js";
13
+ import {
14
+ readSearchAttributesForFilter,
15
+ readSearchAttributesForStates
16
+ } from "./search-attribute-records.js";
17
+ import { decodeSearchAttributeRecord, matchesListFilter } from "./state-utilities.js";
14
18
  import { decodeWorkflowState } from "./validation.js";
15
19
  import { MAX_LIST_SCAN_ROWS, WorkflowListScanCapExceededError } from "./workflow-indexes.js";
16
20
  import { isTopLevelWorkflowStateKey } from "./workflow-state-stream.js";
@@ -27,19 +31,6 @@ const ATTRIBUTE_VALUE_TO_KEY = (value) => {
27
31
  return value.join(",");
28
32
  return String(value);
29
33
  };
30
- async function resolveDimensionKey(internals, state, groupBy) {
31
- if (groupBy === "status")
32
- return state.status;
33
- if (groupBy === "type")
34
- return state.type;
35
- if (groupBy === "failureCategory")
36
- return state.failureCategory ?? null;
37
- const attributeBytes = await internals.storage.get(KEYS.attribute(state.id));
38
- if (!attributeBytes)
39
- return null;
40
- const attributes = decode(attributeBytes);
41
- return ATTRIBUTE_VALUE_TO_KEY(attributes[groupBy.attribute]);
42
- }
43
34
 
44
35
  export class UnknownAggregateAttributeError extends WeftError {
45
36
  attribute;
@@ -72,8 +63,8 @@ function validateAggregateInputs(internals, filter, options, executionOptions) {
72
63
  distinctKeyCap: executionOptions.distinctKeyCap ?? MAX_AGGREGATE_DISTINCT_KEYS
73
64
  };
74
65
  }
75
- async function accumulateAggregateState(internals, state, groupBy, distinctKeyCap, accumulator) {
76
- const key = await resolveDimensionKey(internals, state, groupBy), current = accumulator.counts.get(key);
66
+ function accumulateAggregateKey(key, distinctKeyCap, accumulator) {
67
+ const current = accumulator.counts.get(key);
77
68
  if (current === void 0) {
78
69
  if (accumulator.counts.size >= distinctKeyCap)
79
70
  throw new AggregateDistinctKeyCapExceededError(distinctKeyCap);
@@ -82,32 +73,77 @@ async function accumulateAggregateState(internals, state, groupBy, distinctKeyCa
82
73
  accumulator.counts.set(key, current + 1);
83
74
  accumulator.total += 1;
84
75
  }
76
+ async function resolveDimensionKeys(internals, states, groupBy, searchAttributesByWorkflowId = new Map) {
77
+ if (groupBy === "status")
78
+ return states.map((state) => state.status);
79
+ if (groupBy === "type")
80
+ return states.map((state) => state.type);
81
+ if (groupBy === "failureCategory")
82
+ return states.map((state) => state.failureCategory ?? null);
83
+ return resolveAttributeDimensionKeys(internals, states, groupBy, searchAttributesByWorkflowId);
84
+ }
85
+ async function resolveAttributeDimensionKeys(internals, states, groupBy, searchAttributesByWorkflowId) {
86
+ const keys = [];
87
+ for (let start = 0;start < states.length; start += CONSTRAINED_ID_CHUNK_SIZE) {
88
+ const stateChunk = states.slice(start, start + CONSTRAINED_ID_CHUNK_SIZE), statesNeedingReads = stateChunk.filter((state) => !searchAttributesByWorkflowId.has(state.id)), attributeBytesByWorkflowId = new Map;
89
+ await Promise.all(statesNeedingReads.map(async (state) => {
90
+ attributeBytesByWorkflowId.set(state.id, await internals.storage.get(KEYS.attribute(state.id)));
91
+ }));
92
+ for (const state of stateChunk) {
93
+ const attributes = searchAttributesByWorkflowId.has(state.id) ? searchAttributesByWorkflowId.get(state.id) ?? null : decodeSearchAttributeRecord(attributeBytesByWorkflowId.get(state.id) ?? null);
94
+ if (attributes === null) {
95
+ keys.push(null);
96
+ continue;
97
+ }
98
+ keys.push(ATTRIBUTE_VALUE_TO_KEY(attributes[groupBy.attribute]));
99
+ }
100
+ }
101
+ return keys;
102
+ }
103
+ async function accumulateAggregateStates(internals, states, groupBy, distinctKeyCap, accumulator, searchAttributesByWorkflowId) {
104
+ const dimensionKeys = await resolveDimensionKeys(internals, states, groupBy, searchAttributesByWorkflowId);
105
+ for (const key of dimensionKeys)
106
+ accumulateAggregateKey(key, distinctKeyCap, accumulator);
107
+ }
85
108
  async function accumulateFromConstrainedIds(internals, constrainedIds, normalizedFilter, normalizedTagFilters, groupBy, distinctKeyCap, accumulator) {
86
- if (constrainedIds.size > MAX_LIST_SCAN_ROWS)
109
+ const orderedIds = [...constrainedIds];
110
+ if (orderedIds.length > MAX_LIST_SCAN_ROWS)
87
111
  throw new WorkflowListScanCapExceededError(MAX_LIST_SCAN_ROWS);
88
- for (const workflowId of constrainedIds) {
89
- const stateBytes = await internals.storage.get(KEYS.workflow(workflowId));
90
- if (!stateBytes)
91
- continue;
92
- const state = decodeWorkflowState(stateBytes);
93
- if (!matchesListFilter(state, normalizedFilter, constrainedIds, normalizedTagFilters))
94
- continue;
95
- await accumulateAggregateState(internals, state, groupBy, distinctKeyCap, accumulator);
112
+ for (let start = 0;start < orderedIds.length; start += CONSTRAINED_ID_CHUNK_SIZE) {
113
+ const idChunk = orderedIds.slice(start, start + CONSTRAINED_ID_CHUNK_SIZE), stateBytesChunk = await Promise.all(idChunk.map((workflowId) => internals.storage.get(KEYS.workflow(workflowId)))), searchAttributesByWorkflowId = await readSearchAttributesForStates(internals, stateBytesChunk, normalizedFilter), matchingStates = [];
114
+ for (const stateBytes of stateBytesChunk) {
115
+ if (!stateBytes)
116
+ continue;
117
+ const state = decodeWorkflowState(stateBytes);
118
+ if (!matchesListFilter(state, normalizedFilter, constrainedIds, normalizedTagFilters, searchAttributesByWorkflowId.get(state.id) ?? null))
119
+ continue;
120
+ matchingStates.push(state);
121
+ }
122
+ await accumulateAggregateStates(internals, matchingStates, groupBy, distinctKeyCap, accumulator, searchAttributesByWorkflowId);
96
123
  }
97
124
  }
98
125
  async function accumulateFromFullScan(internals, normalizedFilter, normalizedTagFilters, groupBy, distinctKeyCap, accumulator) {
99
- let scanned = 0;
126
+ let scanned = 0, matchingStates = [], matchingSearchAttributesByWorkflowId = new Map;
100
127
  for await (const [storageKey, value] of internals.storage.scan("wf:")) {
101
128
  if (!isTopLevelWorkflowStateKey(storageKey))
102
129
  continue;
103
130
  scanned += 1;
104
131
  if (scanned > MAX_LIST_SCAN_ROWS)
105
132
  throw new WorkflowListScanCapExceededError(MAX_LIST_SCAN_ROWS);
106
- const state = decodeWorkflowState(value);
107
- if (!matchesListFilter(state, normalizedFilter, null, normalizedTagFilters))
133
+ const state = decodeWorkflowState(value), searchAttributes = await readSearchAttributesForFilter(internals, state.id, normalizedFilter);
134
+ if (!matchesListFilter(state, normalizedFilter, null, normalizedTagFilters, searchAttributes))
108
135
  continue;
109
- await accumulateAggregateState(internals, state, groupBy, distinctKeyCap, accumulator);
136
+ matchingStates.push(state);
137
+ if (searchAttributes !== null)
138
+ matchingSearchAttributesByWorkflowId.set(state.id, searchAttributes);
139
+ if (matchingStates.length === CONSTRAINED_ID_CHUNK_SIZE) {
140
+ await accumulateAggregateStates(internals, matchingStates, groupBy, distinctKeyCap, accumulator, matchingSearchAttributesByWorkflowId);
141
+ matchingStates = [];
142
+ matchingSearchAttributesByWorkflowId = new Map;
143
+ }
110
144
  }
145
+ if (matchingStates.length > 0)
146
+ await accumulateAggregateStates(internals, matchingStates, groupBy, distinctKeyCap, accumulator, matchingSearchAttributesByWorkflowId);
111
147
  }
112
148
  function finalizeAggregateResult(accumulator, requestedLimit) {
113
149
  const sortedGroups = [...accumulator.counts.entries()].map(([groupKey, count]) => ({ key: groupKey, count })).toSorted((left, right) => {
@@ -22,7 +22,10 @@
22
22
  * across replay. After an engine restart, `recoverAll()` replays the workflow
23
23
  * from its checkpoint; the deferred activity re-runs, re-defers, and produces
24
24
  * the *same* token. A callback that arrives after the crash therefore still
25
- * resolves the correct activity.
25
+ * resolves the correct activity. If that callback races `recoverAll()` and
26
+ * arrives after token recovery but before replay has adopted the workflow
27
+ * generator, the engine buffers the completion or failure outcome and drains it
28
+ * when replay reaches the same deterministic token.
26
29
  *
27
30
  * Internal-only. Imported from `src/core/engine/**` and the `ActivityContext`
28
31
  * construction path.
@@ -30,6 +33,12 @@
30
33
  import type { OperationOutcome } from '../types.ts';
31
34
  import { WeftError } from '../weft-error.ts';
32
35
  import type { EngineInternals } from './internals.ts';
36
+ type AsyncActivityResolutionCallbacks = {
37
+ feedOperationResult: (workflowId: string, outcome: OperationOutcome, originalReason?: {
38
+ value: unknown;
39
+ }) => void;
40
+ finalizeTimeline: (workflowId: string, status: 'completed' | 'failed', output: unknown) => void;
41
+ };
33
42
  /**
34
43
  * Per-workflow prefix for all async-activity storage keys. Used by cleanup and
35
44
  * purge paths that need to sweep every async-activity record for a workflow
@@ -80,6 +89,15 @@ export type PendingAsyncActivity = {
80
89
  readonly attempt: number;
81
90
  readonly createdAt: number;
82
91
  };
92
+ export type PendingAsyncActivityResolution = {
93
+ readonly token: string;
94
+ readonly outcome: OperationOutcome;
95
+ readonly originalReason?: {
96
+ value: unknown;
97
+ };
98
+ readonly timelineStatus: 'completed' | 'failed';
99
+ readonly timelineOutput: unknown;
100
+ };
83
101
  /**
84
102
  * Derive the durable, deterministic task token for an async activity.
85
103
  *
@@ -106,7 +124,7 @@ export declare function registerPendingAsyncActivity(internals: EngineInternals,
106
124
  * out-of-band completion resumes it. Keeps the operation-pipeline catch site a
107
125
  * one-liner.
108
126
  */
109
- export declare function parkDeferredAsyncActivity(internals: EngineInternals, deferral: AsyncActivityDeferral, details: Omit<PendingAsyncActivity, 'token' | 'createdAt'>): Promise<never>;
127
+ export declare function parkDeferredAsyncActivity(internals: EngineInternals, deferral: AsyncActivityDeferral, details: Omit<PendingAsyncActivity, 'token' | 'createdAt'>, callbacks: AsyncActivityResolutionCallbacks): Promise<never>;
110
128
  /**
111
129
  * Reload pending async-activity records from storage into memory. Called by
112
130
  * `recoverAll()` so a token minted before a crash is resolvable again — even
@@ -117,7 +135,7 @@ export declare function recoverPendingAsyncActivities(internals: EngineInternals
117
135
  * Complete a deferred activity out-of-band with `result`, resuming the parked
118
136
  * workflow as though the activity had returned `result` inline.
119
137
  */
120
- export declare function completeAsyncActivity(internals: EngineInternals, token: string, result: unknown, feedOperationResult: (workflowId: string, outcome: OperationOutcome) => void, finalizeTimeline: (workflowId: string, status: 'completed' | 'failed', output: unknown) => void): Promise<void>;
138
+ export declare function completeAsyncActivity(internals: EngineInternals, token: string, result: unknown, callbacks: AsyncActivityResolutionCallbacks): Promise<void>;
121
139
  /**
122
140
  * Drive a generator that may yield promises — the workflow interceptor's
123
141
  * `activity` hook returns such a generator. Forwards rejections into the
@@ -136,6 +154,5 @@ export declare function driveWorkflowInterceptorGenerator(generator: Generator<u
136
154
  * that threw — so the workflow's own try/catch and any configured retry policy
137
155
  * apply unchanged.
138
156
  */
139
- export declare function failAsyncActivity(internals: EngineInternals, token: string, error: unknown, feedOperationResult: (workflowId: string, outcome: OperationOutcome, originalReason?: {
140
- value: unknown;
141
- }) => void, finalizeTimeline: (workflowId: string, status: 'completed' | 'failed', output: unknown) => void): Promise<void>;
157
+ export declare function failAsyncActivity(internals: EngineInternals, token: string, error: unknown, callbacks: AsyncActivityResolutionCallbacks): Promise<void>;
158
+ export {};
@@ -53,7 +53,12 @@ export async function registerPendingAsyncActivity(internals, pending) {
53
53
  if (!alreadyRegistered)
54
54
  internals.engine.dispatchEvent(new ActivityAsyncPendingEvent(pending.token, pending.operationId, pending.workflowId, pending.activityName, pending.attempt));
55
55
  }
56
- export async function parkDeferredAsyncActivity(internals, deferral, details) {
56
+ export async function parkDeferredAsyncActivity(internals, deferral, details, callbacks) {
57
+ const queuedResolution = takePendingAsyncActivityResolution(internals, details.workflowId, deferral.token);
58
+ if (queuedResolution !== void 0) {
59
+ deliverPendingAsyncActivityResolution(details.workflowId, queuedResolution, callbacks);
60
+ return new Promise(() => {});
61
+ }
57
62
  await registerPendingAsyncActivity(internals, {
58
63
  token: deferral.token,
59
64
  createdAt: internals.options.getNow(),
@@ -90,14 +95,52 @@ async function consumePendingAsyncActivity(internals, token) {
90
95
  }
91
96
  return pending;
92
97
  }
93
- async function resolvePendingAsyncActivity(internals, token, outcome, feedOperationResult, finalizeTimeline) {
94
- const pending = await consumePendingAsyncActivity(internals, token), timelineOutput = outcome.status === "completed" ? outcome.value : outcome.error;
95
- finalizeTimeline(pending.workflowId, outcome.status, timelineOutput);
96
- feedOperationResult(pending.workflowId, outcome);
98
+ function shouldBufferPendingAsyncActivityResolution(internals, workflowId) {
99
+ return internals.inlineStrategy !== null && !internals.inlineStrategy.hasGenerator(workflowId);
100
+ }
101
+ function queuePendingAsyncActivityResolution(internals, workflowId, resolution) {
102
+ internals.pendingAsyncActivityResolutions ??= new Map;
103
+ const queued = internals.pendingAsyncActivityResolutions.get(workflowId) ?? [];
104
+ queued.push(resolution);
105
+ internals.pendingAsyncActivityResolutions.set(workflowId, queued);
106
+ }
107
+ function takePendingAsyncActivityResolution(internals, workflowId, token) {
108
+ internals.pendingAsyncActivityResolutions ??= new Map;
109
+ const queued = internals.pendingAsyncActivityResolutions.get(workflowId);
110
+ if (queued === void 0)
111
+ return;
112
+ const index = queued.findIndex((resolution) => resolution.token === token);
113
+ if (index === -1)
114
+ return;
115
+ const resolution = queued[index];
116
+ if (resolution === void 0)
117
+ return;
118
+ queued.splice(index, 1);
119
+ if (queued.length === 0)
120
+ internals.pendingAsyncActivityResolutions.delete(workflowId);
121
+ return resolution;
122
+ }
123
+ function deliverPendingAsyncActivityResolution(workflowId, resolution, callbacks) {
124
+ callbacks.finalizeTimeline(workflowId, resolution.timelineStatus, resolution.timelineOutput);
125
+ callbacks.feedOperationResult(workflowId, resolution.outcome, resolution.originalReason);
126
+ }
127
+ async function resolvePendingAsyncActivity(internals, token, outcome, callbacks, originalReason) {
128
+ const pending = await consumePendingAsyncActivity(internals, token), timelineOutput = outcome.status === "completed" ? outcome.value : outcome.error, resolution = {
129
+ token,
130
+ outcome,
131
+ timelineStatus: outcome.status,
132
+ timelineOutput,
133
+ ...originalReason !== void 0 ? { originalReason } : {}
134
+ };
135
+ if (shouldBufferPendingAsyncActivityResolution(internals, pending.workflowId)) {
136
+ queuePendingAsyncActivityResolution(internals, pending.workflowId, resolution);
137
+ return;
138
+ }
139
+ deliverPendingAsyncActivityResolution(pending.workflowId, resolution, callbacks);
97
140
  }
98
- export async function completeAsyncActivity(internals, token, result, feedOperationResult, finalizeTimeline) {
141
+ export async function completeAsyncActivity(internals, token, result, callbacks) {
99
142
  assertPayloadWithinLimit(result, internals.options.payloadSizePolicy.maxBytes, "activity result");
100
- await resolvePendingAsyncActivity(internals, token, { status: "completed", value: result }, feedOperationResult, finalizeTimeline);
143
+ await resolvePendingAsyncActivity(internals, token, { status: "completed", value: result }, callbacks);
101
144
  }
102
145
  export async function driveWorkflowInterceptorGenerator(generator) {
103
146
  let current = generator.next();
@@ -117,15 +160,13 @@ export async function driveWorkflowInterceptorGenerator(generator) {
117
160
  }
118
161
  return current.value;
119
162
  }
120
- export async function failAsyncActivity(internals, token, error, feedOperationResult, finalizeTimeline) {
163
+ export async function failAsyncActivity(internals, token, error, callbacks) {
121
164
  const message = error instanceof Error ? error.message : String(error), errorName = error instanceof Error ? error.name : void 0;
122
165
  assertPayloadWithinLimit({ message, name: errorName }, internals.options.payloadSizePolicy.maxBytes, "activity result");
123
- const pending = await consumePendingAsyncActivity(internals, token);
124
- finalizeTimeline(pending.workflowId, "failed", message);
125
- feedOperationResult(pending.workflowId, {
166
+ await resolvePendingAsyncActivity(internals, token, {
126
167
  status: "failed",
127
168
  error: message,
128
169
  ...error instanceof Error ? { errorName: error.name } : {},
129
170
  failureCategory: "application"
130
- }, { value: error });
171
+ }, callbacks, { value: error });
131
172
  }
@@ -9,7 +9,10 @@ import {
9
9
  import { assertWorkflowTagCount, coerceStartWorkflowTags } from "../start-workflow-validation.js";
10
10
  import { buildWorkflowTagIndexOperations, normalizeWorkflowTags } from "../workflow-tags.js";
11
11
  import { WorkflowNotFoundError } from "./errors.js";
12
- import { commitWorkflowStateOperations, runSerializedWorkflowStateWrite } from "./storage-io.js";
12
+ import {
13
+ commitFencedWorkflowStateOperations,
14
+ runSerializedWorkflowStateWrite
15
+ } from "./storage-io.js";
13
16
  import {
14
17
  decodeWorkflowState,
15
18
  isTerminalWorkflowStatus,
@@ -73,12 +76,14 @@ export async function updateWorkflowState(internals, workflowId, updates, option
73
76
  ...updates,
74
77
  updatedAt
75
78
  }, additionalOperations = options.buildAdditionalOperations?.(state, updatedAt) ?? [];
76
- await commitWorkflowStateOperations(internals, state, [
79
+ await commitFencedWorkflowStateOperations(internals, state, [
77
80
  ...buildTerminalWorkflowIndexOperations(state, updated),
78
81
  { type: "put", key: KEYS.workflow(workflowId), value: encode(updated) },
79
82
  ...buildWorkflowVisibilityIndexTransition(workflowId, state, updated).batchOps,
80
83
  ...additionalOperations
81
- ]);
84
+ ], {
85
+ includePendingAtomicSideEffects: isTerminalWorkflowStatus(updated.status)
86
+ });
82
87
  return {
83
88
  previousState: state,
84
89
  updatedAt
@@ -172,7 +177,7 @@ async function snapshotMatchingWorkflowIds(internals, filter) {
172
177
  if (remainingLimit !== void 0)
173
178
  remainingLimit -= 1;
174
179
  if (remainingLimit === 0)
175
- break;
180
+ return workflowIds;
176
181
  }
177
182
  return workflowIds;
178
183
  }