@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,146 @@
1
+ import type { FailureCategory, WorkflowStatus } from './identity.ts';
2
+ import type { SearchAttributeHandle, SearchAttributeValue } from './search-attributes.ts';
3
+ /**
4
+ * Numeric half-open range bound, used by visibility filters that match a
5
+ * stored numeric field (timestamps, deadlines). Provide at least one of the
6
+ * four bounds. `gt`/`gte` are mutually exclusive on the lower side; `lt`/`lte`
7
+ * are mutually exclusive on the upper side.
8
+ */
9
+ export interface TimeRange {
10
+ gte?: number;
11
+ lte?: number;
12
+ gt?: number;
13
+ lt?: number;
14
+ }
15
+ /**
16
+ * Filter passed to {@link Engine.list} (and equivalent visibility transports)
17
+ * to narrow which {@link WorkflowSummary} entries are returned. Every field
18
+ * is optional; combining fields applies them as AND.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { Engine, type ListFilter } from '@lostgradient/weft';
23
+ *
24
+ * const engine = new Engine();
25
+ * const filter: ListFilter = {
26
+ * status: ['running', 'failed'],
27
+ * createdAt: { gte: Date.now() - 60_000 },
28
+ * };
29
+ *
30
+ * const page = await engine.list(filter);
31
+ * ```
32
+ */
33
+ export interface ListFilter {
34
+ /** Match workflows whose {@link WorkflowState.status} is one of the listed values. */
35
+ status?: WorkflowStatus | WorkflowStatus[];
36
+ /**
37
+ * Match workflows by registered workflow type (e.g. `'order-fulfillment'`).
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * import type { ListFilter } from '@lostgradient/weft';
42
+ * const filter: ListFilter = { type: 'order-fulfillment' };
43
+ * ```
44
+ */
45
+ type?: string;
46
+ /** Match workflows that carry every listed tag. */
47
+ tags?: string[];
48
+ /** Filter on indexed search attributes (equality, string any-of, or range). */
49
+ attributes?: readonly AttributeFilter[];
50
+ /** Maximum number of summaries to return. Server enforces an upper bound. */
51
+ limit?: number;
52
+ /** Number of summaries to skip before returning results. */
53
+ offset?: number;
54
+ /**
55
+ * Workflow id prefix. Restricted to `[A-Za-z0-9_-]+`; values containing
56
+ * other characters are rejected during validation. Matches by raw
57
+ * `state.id.startsWith(idPrefix)` after candidate enumeration.
58
+ */
59
+ idPrefix?: string;
60
+ /** Range filter on `WorkflowState.createdAt` (ms epoch). */
61
+ createdAt?: TimeRange;
62
+ /** Range filter on `WorkflowState.updatedAt` (ms epoch). */
63
+ updatedAt?: TimeRange;
64
+ /** Range filter on `WorkflowState.executionDeadline` (ms epoch). */
65
+ executionDeadline?: TimeRange;
66
+ /**
67
+ * Match by the workflow's `failureCategory`. The engine uses the
68
+ * `failureCategory` search-attribute index to narrow candidate workflow IDs,
69
+ * then still verifies the loaded `WorkflowState.failureCategory` so state
70
+ * remains authoritative when index entries are stale.
71
+ */
72
+ failureCategory?: FailureCategory | FailureCategory[];
73
+ }
74
+ /**
75
+ * Projection options for {@link Engine.list}. These options do not change
76
+ * which workflows match the list filter; they only control optional summary
77
+ * fields that may require additional storage reads.
78
+ *
79
+ * @example Include failure categories projected from search attributes
80
+ * ```ts
81
+ * import { Engine, type ListOptions } from '@lostgradient/weft';
82
+ *
83
+ * const engine = new Engine();
84
+ * const options: ListOptions = { includeFailureCategory: true };
85
+ * const page = await engine.list({ status: 'failed' }, options);
86
+ * void page;
87
+ * ```
88
+ */
89
+ export interface ListOptions {
90
+ /**
91
+ * Populate `WorkflowSummary.failureCategory` for failed workflows from the
92
+ * stored `failureCategory` search attribute when the workflow state itself
93
+ * does not carry a category. Defaults to `false`.
94
+ */
95
+ includeFailureCategory?: boolean;
96
+ }
97
+ export type AttributeFilterKey = string | SearchAttributeHandle;
98
+ export type AttributeFilterScalarValue = Exclude<SearchAttributeValue, string[]>;
99
+ export type AttributeFilterValue<TKey extends AttributeFilterKey> = TKey extends SearchAttributeHandle<infer TValue> ? TValue extends string[] ? string : TValue : AttributeFilterScalarValue;
100
+ export type AttributeFilterAnyOfValue<TKey extends AttributeFilterKey> = TKey extends SearchAttributeHandle<infer TValue> ? TValue extends string[] ? string[] : TValue extends AttributeFilterScalarValue ? TValue[] : never : AttributeFilterScalarValue[];
101
+ export type AttributeRangeValue<TKey extends AttributeFilterKey> = TKey extends SearchAttributeHandle<infer TValue> ? Extract<TValue, Date | number> : AttributeFilterScalarValue;
102
+ export type AttributeFilter<TKey extends AttributeFilterKey = AttributeFilterKey> = TKey extends SearchAttributeHandle ? {
103
+ key: TKey;
104
+ value?: AttributeFilterValue<TKey> | AttributeFilterAnyOfValue<TKey>;
105
+ gt?: never;
106
+ lt?: never;
107
+ gte?: never;
108
+ lte?: never;
109
+ } | {
110
+ key: TKey;
111
+ value?: never;
112
+ gt?: AttributeRangeValue<TKey>;
113
+ lt?: AttributeRangeValue<TKey>;
114
+ gte?: AttributeRangeValue<TKey>;
115
+ lte?: AttributeRangeValue<TKey>;
116
+ } : {
117
+ key: TKey;
118
+ /**
119
+ * Match a single indexed scalar value, or provide a scalar array to match
120
+ * any listed value for the same attribute.
121
+ */
122
+ value?: AttributeFilterScalarValue | AttributeFilterScalarValue[];
123
+ gt?: AttributeRangeValue<TKey>;
124
+ lt?: AttributeRangeValue<TKey>;
125
+ gte?: AttributeRangeValue<TKey>;
126
+ lte?: AttributeRangeValue<TKey>;
127
+ };
128
+ export type AttributeFilterList<TAttributeKeys extends readonly AttributeFilterKey[]> = {
129
+ readonly [TIndex in keyof TAttributeKeys]: AttributeFilter<TAttributeKeys[TIndex]>;
130
+ };
131
+ export type TypedListFilter<TAttributeKeys extends readonly AttributeFilterKey[]> = Omit<ListFilter, 'attributes'> & {
132
+ attributes?: AttributeFilterList<TAttributeKeys>;
133
+ };
134
+ /**
135
+ * Generic paginated response envelope returned by list operations such as
136
+ * {@link Engine.list} and `engine.listSchedules`. `total` is the full count
137
+ * matching the filter; `items` is the current page slice. `items.length` is
138
+ * bounded by `limit`; the consumer reaches the end of the result set when
139
+ * `offset + items.length >= total`.
140
+ */
141
+ export interface PaginatedResult<T> {
142
+ items: T[];
143
+ total: number;
144
+ offset: number;
145
+ limit: number;
146
+ }
File without changes
@@ -111,6 +111,31 @@ export interface SignalOptions<TInput = void> {
111
111
  export interface SignalDeliveryOptions {
112
112
  readonly signalId?: string;
113
113
  }
114
+ /**
115
+ * The signal half of `startOrSignal` (signal-with-start): a signal `name`, an
116
+ * optional `payload`, and an optional `signalId`. When `signalId` is omitted it
117
+ * is derived from `options.idempotencyKey`. The id is load-bearing for
118
+ * convergence — concurrent callers deliver one signal only when they share it,
119
+ * and independent webhook retries share only the idempotency key — so a
120
+ * caller-supplied `signalId` covers the single-caller case while idempotent
121
+ * convergence relies on the derived-from-key value.
122
+ *
123
+ * @example
124
+ * ```ts
125
+ * import type { StartOrSignalSignal } from '@lostgradient/weft';
126
+ *
127
+ * const signal: StartOrSignalSignal = {
128
+ * name: 'webhook',
129
+ * payload: { event: 'payment.succeeded' },
130
+ * };
131
+ * void signal;
132
+ * ```
133
+ */
134
+ export interface StartOrSignalSignal {
135
+ readonly name: string;
136
+ readonly payload?: unknown;
137
+ readonly signalId?: string;
138
+ }
114
139
  /**
115
140
  * Create a typed workflow signal handle. When an `inputSchema` is supplied
116
141
  * via options, the payload type is inferred from the schema's
@@ -4,24 +4,40 @@ import type { CompressionOptions } from '../compression.ts';
4
4
  import type { Interceptor } from '../interceptor.ts';
5
5
  import type { ArchiveAdapter } from './archive-adapter.ts';
6
6
  import type { HistoryPolicy } from './history-policy.ts';
7
- import type { FailureCategory, WorkflowStatus } from './identity.ts';
8
7
  import type { PayloadSizePolicy } from './payload-size-policy.ts';
9
8
  import type { Duration, RetentionPolicy } from './retry-retention.ts';
10
- import type { SearchAttributeHandle, SearchAttributeValue } from './search-attributes.ts';
9
+ import type { SearchAttributeValue } from './search-attributes.ts';
11
10
  import type { Serializer } from './serializer.ts';
11
+ import type { WorkflowServicesResolution, WorkflowServicesResolverInfo } from './services-resolution.ts';
12
+ import type { WorkflowLogRecord } from './workflow-log.ts';
12
13
  /**
13
14
  * Options accepted by `engine.start(type, input, options?)`.
14
15
  *
15
16
  * Every field is optional. `id` lets you specify your own workflow ID;
16
- * `idempotencyKey` enforces single-execution semantics within a window;
17
- * `executionTimeout` caps wall-clock time; `startAt`/`startAfter` defer
17
+ * `idempotencyKey` enforces at-most-once starts (a repeated key returns the
18
+ * existing run instead of starting a second, even after it reaches a terminal
19
+ * state); `executionTimeout` caps wall-clock time; `startAt`/`startAfter` defer
18
20
  * execution; `tags` and `searchAttributes` make the workflow discoverable
19
- * via filters.
21
+ * via filters. `id` and `idempotencyKey` are mutually exclusive — idempotency
22
+ * assigns its own generated id and dedups through the key.
20
23
  *
21
- * `HttpClient.start` forwards `searchAttributes` to the server. It rejects
22
- * `idempotencyKey` until the HTTP start protocol exposes matching
23
- * single-execution semantics, so callers do not accidentally rely on a
24
- * silently dropped option.
24
+ * This is the shared base accepted by every start-like surface
25
+ * (`engine.start`, `engine.startOrSignal`, and the clients). `engine.start`
26
+ * specifically accepts the wider {@link StartWorkflowOptions}, which adds
27
+ * `onTerminalConflict`; that policy is intentionally absent here so it cannot be
28
+ * passed to `startOrSignal` (whose at-most-once identity is the permanent
29
+ * idempotency mapping).
30
+ *
31
+ * The `idempotencyKey` mapping is durable and permanent: it survives the run
32
+ * reaching a terminal state, so repeat calls keep returning the same handle. When
33
+ * the workflow record is purged or swept by retention the mapping itself survives
34
+ * (purge does not touch the `start-idem:` keyspace) but now points at a gone run;
35
+ * a call with that spent key throws {@link IdempotencyKeyPurgedError} (mapped to
36
+ * HTTP 409 over REST/JSON-RPC) rather than silently starting a new run.
37
+ *
38
+ * Both `LocalClient.start` and `HttpClient.start` forward `idempotencyKey` and
39
+ * `searchAttributes` to the server, so single-execution semantics hold across
40
+ * transports. Idempotent start requires a storage backend with `conditionalBatch`.
25
41
  *
26
42
  * @example Start a delayed workflow with tags and search attributes
27
43
  * ```ts
@@ -44,7 +60,7 @@ import type { Serializer } from './serializer.ts';
44
60
  * void handle;
45
61
  * ```
46
62
  */
47
- export interface StartOptions {
63
+ export interface StartOptions<TServices = unknown> {
48
64
  id?: string;
49
65
  idempotencyKey?: string;
50
66
  executionTimeout?: Duration;
@@ -63,54 +79,61 @@ export interface StartOptions {
63
79
  * `workflowExecutionMode: 'worker'` throws at `engine.start()`, because a
64
80
  * non-serializable value cannot cross to a Worker.
65
81
  */
66
- services?: unknown;
82
+ services?: TServices;
83
+ /**
84
+ * When `false`, `engine.start()` resolves only after the workflow has begun
85
+ * executing (its generator has been driven its first turn), not merely after
86
+ * the initial state is persisted. The default (`true`) returns a handle as
87
+ * soon as state is written and queues execution onto a macrotask, so a caller
88
+ * cannot assume the run is live without a round-trip. Use `defer: false` when a
89
+ * caller — or a test — must rely on the run being live immediately after
90
+ * `await engine.start(...)`. If the body throws on its first turn, `start()`
91
+ * still resolves; observe the failure via `handle.result()`. Inline mode only;
92
+ * throws at `engine.start()` under `workflowExecutionMode: 'worker'` or with a
93
+ * delayed start (`startAt`/`startAfter`), neither of which has liveness to await.
94
+ */
95
+ defer?: boolean;
67
96
  }
68
97
  /**
69
- * Result of {@link EngineOptions.resolveWorkflowServices}. An explicit union
70
- * rather than a nullable return: `'unavailable'` is a deliberate, named outcome
71
- * (the run's dependencies cannot be rebuilt in this process) that fails just
72
- * that recovered run — it does not overload the resolved value with a lifecycle
73
- * signal.
74
- *
75
- * @example
76
- * ```ts
77
- * import { type WorkflowServicesResolution } from '@lostgradient/weft';
78
- *
79
- * const ok: WorkflowServicesResolution = {
80
- * status: 'available',
81
- * services: { db: { query: () => [] } },
82
- * };
83
- * const no: WorkflowServicesResolution = { status: 'unavailable', reason: 'no config' };
84
- * void ok;
85
- * void no;
86
- * ```
87
- */
88
- export type WorkflowServicesResolution = {
89
- status: 'available';
90
- services: unknown;
91
- } | {
92
- status: 'unavailable';
93
- reason: string;
94
- };
95
- /**
96
- * Information passed to {@link EngineOptions.resolveWorkflowServices} for each
97
- * recovered workflow. `input` is the original durable launch input, available
98
- * at resume time — typically enough to rebuild the run's dependencies (tenant,
99
- * model, tool registry) without a side table.
100
- *
101
- * @example
102
- * ```ts
103
- * import { type WorkflowServicesResolverInfo } from '@lostgradient/weft';
98
+ * Options accepted by `engine.start(type, input, options?)` — the shared
99
+ * {@link StartOptions} plus the start-only `onTerminalConflict` policy.
104
100
  *
105
- * function describe(info: WorkflowServicesResolverInfo): string {
106
- * return `${info.workflowType}/${info.workflowId}`;
107
- * }
108
- * ```
101
+ * `onTerminalConflict` lives here, not on {@link StartOptions}, so it is
102
+ * structurally rejected on every other start-like surface: `engine.startOrSignal`
103
+ * (whose identity is the permanent at-most-once idempotency mapping),
104
+ * `ctx.startChild` (which re-attaches to an existing run by id on replay), and the
105
+ * REST/JSON-RPC transport (which keeps `weft.workflows.start` honestly
106
+ * `destructive: false`). It is therefore an in-process `engine.start`-only policy.
109
107
  */
110
- export interface WorkflowServicesResolverInfo {
111
- workflowId: string;
112
- workflowType: string;
113
- input: unknown;
108
+ export interface StartWorkflowOptions<TServices = unknown> extends StartOptions<TServices> {
109
+ /**
110
+ * What `engine.start()` does when the supplied `id` already belongs to a run
111
+ * that has reached a **terminal** state (`completed` | `failed` | `cancelled`
112
+ * | `timed-out`). This is Weft's equivalent of Temporal's
113
+ * `WorkflowIdReusePolicy.ALLOW_DUPLICATE`, for the common case of a periodic
114
+ * job keyed by a stable id (e.g. `reconcile:installation-42`) whose previous
115
+ * run has already finished.
116
+ *
117
+ * - `'error'` (default): preserve the existing contract — a duplicate id always
118
+ * throws {@link WorkflowAlreadyExistsError}, terminal or not.
119
+ * - `'start-new'`: if the prior run under this id is terminal, purge it (while
120
+ * holding the in-process start reservation, the same teardown as
121
+ * `engine.purge`, sweeping every key the run owns) and start a fresh run in
122
+ * its place; if the prior run is still **non-terminal** (running/pending),
123
+ * throw {@link WorkflowAlreadyExistsError} unchanged — `'start-new'` never
124
+ * displaces a live run.
125
+ *
126
+ * Requires an explicit `id` (the policy only makes sense for a caller-chosen,
127
+ * reusable id) and is mutually exclusive with `idempotencyKey` (whose mapping
128
+ * is permanent and at-most-once — restarting under it would violate that
129
+ * contract). The previous run's durable record is gone after a `'start-new'`
130
+ * restart, so a {@link WorkflowHandle} held against the old id resolves to the
131
+ * fresh run for every method (`result()`, `snapshot()`, status), because handles
132
+ * are id-scoped, not run-attempt-scoped. The restart holds the same in-process
133
+ * start reservation as a normal start, so two concurrent `'start-new'` calls for
134
+ * one id cannot both win — the loser sees {@link WorkflowAlreadyExistsError}.
135
+ */
136
+ onTerminalConflict?: 'error' | 'start-new';
114
137
  }
115
138
  /**
116
139
  * Options for {@link Engine.fork}. Controls which checkpoint step to fork
@@ -155,13 +178,87 @@ export interface ForkOptions {
155
178
  * void engine;
156
179
  * ```
157
180
  */
158
- export interface EngineOptions {
181
+ export interface EngineOptions<TServices = unknown> {
159
182
  storage?: WeftStorage;
160
183
  development?: boolean;
161
184
  serializer?: Serializer;
162
185
  retention?: RetentionPolicy;
163
186
  retentionSweepInterval?: Duration;
164
187
  retentionSweepBatchSize?: number;
188
+ /**
189
+ * Enable a best-effort, warn-only detector for a SECOND engine instance writing
190
+ * to the same durable store — a smoke alarm for singleton misconfiguration (an
191
+ * autoscaler above one replica, or overlapping rolling deploys). Default `false`.
192
+ * This is **liveness, not fencing**: it never blocks boot, gates recovery, or
193
+ * prevents duplicate execution — enforce one instance at the infrastructure layer
194
+ * (one replica + a `Recreate` deploy, or a single systemd unit). When enabled,
195
+ * each engine writes a periodic heartbeat and warns (`process.emitWarning`) when
196
+ * it sees another instance's heartbeat advancing while it runs. The periodic
197
+ * writes are an ongoing cost, so leave it off unless you want the backstop.
198
+ */
199
+ detectSecondInstance?: boolean;
200
+ /**
201
+ * Heartbeat interval for {@link EngineOptions.detectSecondInstance} (default
202
+ * `15s`). A foreign heartbeat must advance across two intervals before warning,
203
+ * so this also sets how long a deploy overlap must last before it warns — keep it
204
+ * well above your deploy drain window. Ignored when detection is disabled.
205
+ */
206
+ secondInstanceHeartbeatInterval?: Duration;
207
+ /**
208
+ * Single-writer ownership posture over the shared durable store. Default
209
+ * `'none'` — the engine recovers immediately at boot and relies on
210
+ * infrastructure (one replica + a `Recreate` deploy) for mutual exclusion.
211
+ *
212
+ * `'lease'` opts into a storage-keyed ownership lease: at boot the engine
213
+ * acquires the lease (waiting, up to {@link EngineOptions.leaseWaitTimeout}, if
214
+ * another instance still holds it) **before** recovering, renews it on a
215
+ * heartbeat, and releases it on dispose. This turns a rolling deploy into a
216
+ * clean handoff — the incoming instance parks until the outgoing one releases
217
+ * (or its lease expires), so the two never recover concurrently.
218
+ *
219
+ * Requires a storage backend with the `conditionalBatch` capability (every
220
+ * durable recovery backend already provides it).
221
+ *
222
+ * **Step-1 acquisition boundary.** The lease is acquired on the standard boot
223
+ * paths — `Engine.create()` and `Engine.recoverAll()` (so `new Engine({ ownership:
224
+ * 'lease' })` followed by `recoverAll()` acquires it too). It is **not** yet
225
+ * acquired on a first durable write, so a `new Engine({ ownership: 'lease' })`
226
+ * that calls `engine.start(...)` *without* ever calling `recoverAll()` will write
227
+ * without holding the lease. Use `Engine.create()` (or call `recoverAll()` before
228
+ * accepting traffic) so acquisition runs before any write.
229
+ *
230
+ * **Lease alone is deploy ergonomics, not a correctness guarantee.** It
231
+ * prevents the *new* instance from recovering early; it does not by itself stop
232
+ * a stalled *old* instance (e.g. a long GC pause past the lease TTL) from
233
+ * writing after its lease expired. Epoch fencing of durable writes is what
234
+ * closes that gap. Keep infrastructure-level single-instance enforcement as the
235
+ * real control.
236
+ */
237
+ ownership?: 'none' | 'lease';
238
+ /**
239
+ * Lease time-to-live for `ownership: 'lease'` (default `30s`). A holder renews
240
+ * well within this window; once it lapses without renewal, a waiting instance
241
+ * may steal the lease. Must comfortably exceed the renewal interval plus the
242
+ * worst-case GC pause, clock skew, and storage round-trip. Ignored when
243
+ * `ownership` is not `'lease'`.
244
+ */
245
+ leaseTtl?: Duration;
246
+ /**
247
+ * Lease renewal interval for `ownership: 'lease'` (default `5s`). The holder
248
+ * re-asserts the lease this often; keep it well below {@link EngineOptions.leaseTtl}
249
+ * so a single slow renewal cannot let the lease lapse. Ignored when `ownership`
250
+ * is not `'lease'`.
251
+ */
252
+ leaseRenewInterval?: Duration;
253
+ /**
254
+ * How long a booting `ownership: 'lease'` instance waits to acquire the lease
255
+ * when another instance still holds it, before throwing
256
+ * {@link EngineLeaseAcquisitionTimeoutError} (default `60s`). Size this above
257
+ * both the outgoing instance's drain time and the lease TTL, so a graceful
258
+ * handoff and a crash (no clean release, lease expires after TTL) both resolve.
259
+ * Ignored when `ownership` is not `'lease'`.
260
+ */
261
+ leaseWaitTimeout?: Duration;
165
262
  /**
166
263
  * History circuit-breaker thresholds. When `history.maxEvents` is set, a
167
264
  * workflow whose event-log record count would exceed it is forced to a
@@ -267,8 +364,9 @@ export interface EngineOptions {
267
364
  * Return `{ status: 'available', services }` to supply the rebuilt
268
365
  * capabilities, or `{ status: 'unavailable', reason }` to fail just that one
269
366
  * recovered run — the engine and every other recovered run are unaffected.
270
- * Without a resolver, a recovered inline workflow that reads `ctx.services`
271
- * sees `undefined`.
367
+ * Without a resolver, a recovered run that carries the durable "expects
368
+ * services" marker fails before the generator advances and emits a diagnostic
369
+ * warning naming this option.
272
370
  *
273
371
  * Contract a fresh integrator must know:
274
372
  * - Fires only for recovered inline runs that were launched WITH `services`
@@ -285,165 +383,17 @@ export interface EngineOptions {
285
383
  * Engine-scoped: each engine instance carries its own resolver, so two engines
286
384
  * in one process never collide on per-run dependency reconstruction.
287
385
  */
288
- resolveWorkflowServices?: (info: WorkflowServicesResolverInfo) => WorkflowServicesResolution | Promise<WorkflowServicesResolution>;
289
- }
290
- /**
291
- * Filter criteria for {@link Engine.list}. All fields are optional and
292
- * combine with AND semantics. `status` accepts a single value or an array;
293
- * `attributes` is a list of attribute predicates evaluated on indexed search
294
- * attributes. Pairs with `limit`/`offset` for pagination.
295
- *
296
- * @example
297
- * ```ts
298
- * import { Engine, type ListFilter } from '@lostgradient/weft';
299
- *
300
- * const engine = new Engine();
301
- * const filter: ListFilter = {
302
- * status: ['running', 'pending'],
303
- * tags: ['nightly'],
304
- * attributes: [{ key: 'customerId', value: 'acme' }],
305
- * limit: 20,
306
- * offset: 0,
307
- * };
308
- * const result = await engine.list(filter);
309
- * console.log(result.items.length);
310
- * ```
311
- */
312
- /**
313
- * Numeric half-open range bound, used by visibility filters that match a
314
- * stored numeric field (timestamps, deadlines). Provide at least one of the
315
- * four bounds. `gt`/`gte` are mutually exclusive on the lower side; `lt`/`lte`
316
- * are mutually exclusive on the upper side.
317
- */
318
- export interface TimeRange {
319
- gte?: number;
320
- lte?: number;
321
- gt?: number;
322
- lt?: number;
323
- }
324
- /**
325
- * Filter passed to {@link Engine.list} (and equivalent visibility transports)
326
- * to narrow which {@link WorkflowSummary} entries are returned. Every field
327
- * is optional; combining fields applies them as AND.
328
- *
329
- * @example
330
- * ```ts
331
- * import { Engine, type ListFilter } from '@lostgradient/weft';
332
- *
333
- * const engine = new Engine();
334
- * const filter: ListFilter = {
335
- * status: ['running', 'failed'],
336
- * createdAt: { gte: Date.now() - 60_000 },
337
- * };
338
- *
339
- * const page = await engine.list(filter);
340
- * ```
341
- */
342
- export interface ListFilter {
343
- /** Match workflows whose {@link WorkflowState.status} is one of the listed values. */
344
- status?: WorkflowStatus | WorkflowStatus[];
386
+ resolveWorkflowServices?: (info: WorkflowServicesResolverInfo) => WorkflowServicesResolution<TServices> | Promise<WorkflowServicesResolution<TServices>>;
345
387
  /**
346
- * Match workflows by registered workflow type (e.g. `'order-fulfillment'`).
388
+ * Optional host sink for `ctx.log` records. When provided, every non-replayed
389
+ * record from inline workflow execution is routed here (into your pino / winston
390
+ * / OpenTelemetry stack, etc.) **instead of** the console; when omitted, records
391
+ * fall back to the matching `console` method, preserving the default behavior.
347
392
  *
348
- * @example
349
- * ```ts
350
- * import type { ListFilter } from '@lostgradient/weft';
351
- * const filter: ListFilter = { type: 'order-fulfillment' };
352
- * ```
353
- */
354
- type?: string;
355
- /** Match workflows that carry every listed tag. */
356
- tags?: string[];
357
- /** Filter on indexed search attributes (equality or range). */
358
- attributes?: readonly AttributeFilter[];
359
- /** Maximum number of summaries to return. Server enforces an upper bound. */
360
- limit?: number;
361
- /** Number of summaries to skip before returning results. */
362
- offset?: number;
363
- /**
364
- * Workflow id prefix. Restricted to `[A-Za-z0-9_-]+`; values containing
365
- * other characters are rejected during validation. Matches by raw
366
- * `state.id.startsWith(idPrefix)` after candidate enumeration.
367
- */
368
- idPrefix?: string;
369
- /** Range filter on `WorkflowState.createdAt` (ms epoch). */
370
- createdAt?: TimeRange;
371
- /** Range filter on `WorkflowState.updatedAt` (ms epoch). */
372
- updatedAt?: TimeRange;
373
- /** Range filter on `WorkflowState.executionDeadline` (ms epoch). */
374
- executionDeadline?: TimeRange;
375
- /**
376
- * Match by the workflow's `failureCategory`. The engine uses the
377
- * `failureCategory` search-attribute index to narrow candidate workflow IDs,
378
- * then still verifies the loaded `WorkflowState.failureCategory` so state
379
- * remains authoritative when index entries are stale.
393
+ * Engine-scoped infrastructure: set once at construction, never per run. The sink
394
+ * is not invoked for records suppressed during replay, so a recovered run does
395
+ * not re-emit its replayed prefix. Worker-mode records still log to the worker
396
+ * process's console routing them back to the host is tracked separately.
380
397
  */
381
- failureCategory?: FailureCategory | FailureCategory[];
382
- }
383
- /**
384
- * Projection options for {@link Engine.list}. These options do not change
385
- * which workflows match the list filter; they only control optional summary
386
- * fields that may require additional storage reads.
387
- *
388
- * @example Include failure categories projected from search attributes
389
- * ```ts
390
- * import { Engine, type ListOptions } from '@lostgradient/weft';
391
- *
392
- * const engine = new Engine();
393
- * const options: ListOptions = { includeFailureCategory: true };
394
- * const page = await engine.list({ status: 'failed' }, options);
395
- * void page;
396
- * ```
397
- */
398
- export interface ListOptions {
399
- /**
400
- * Populate `WorkflowSummary.failureCategory` for failed workflows from the
401
- * stored `failureCategory` search attribute when the workflow state itself
402
- * does not carry a category. Defaults to `false`.
403
- */
404
- includeFailureCategory?: boolean;
405
- }
406
- export type AttributeFilterKey = string | SearchAttributeHandle;
407
- export type AttributeFilterValue<TKey extends AttributeFilterKey> = TKey extends SearchAttributeHandle<infer TValue> ? TValue extends string[] ? string : TValue : SearchAttributeValue;
408
- export type AttributeRangeValue<TKey extends AttributeFilterKey> = TKey extends SearchAttributeHandle<infer TValue> ? Extract<TValue, Date | number> : SearchAttributeValue;
409
- export type AttributeFilter<TKey extends AttributeFilterKey = AttributeFilterKey> = TKey extends SearchAttributeHandle ? {
410
- key: TKey;
411
- value?: AttributeFilterValue<TKey>;
412
- gt?: never;
413
- lt?: never;
414
- gte?: never;
415
- lte?: never;
416
- } | {
417
- key: TKey;
418
- value?: never;
419
- gt?: AttributeRangeValue<TKey>;
420
- lt?: AttributeRangeValue<TKey>;
421
- gte?: AttributeRangeValue<TKey>;
422
- lte?: AttributeRangeValue<TKey>;
423
- } : {
424
- key: TKey;
425
- value?: SearchAttributeValue;
426
- gt?: SearchAttributeValue;
427
- lt?: SearchAttributeValue;
428
- gte?: SearchAttributeValue;
429
- lte?: SearchAttributeValue;
430
- };
431
- export type AttributeFilterList<TAttributeKeys extends readonly AttributeFilterKey[]> = {
432
- readonly [TIndex in keyof TAttributeKeys]: AttributeFilter<TAttributeKeys[TIndex]>;
433
- };
434
- export type TypedListFilter<TAttributeKeys extends readonly AttributeFilterKey[]> = Omit<ListFilter, 'attributes'> & {
435
- attributes?: AttributeFilterList<TAttributeKeys>;
436
- };
437
- /**
438
- * Generic paginated response envelope returned by list operations such as
439
- * {@link Engine.list} and `engine.listSchedules`. `total` is the full count
440
- * matching the filter; `items` is the current page slice. `items.length` is
441
- * bounded by `limit`; the consumer reaches the end of the result set when
442
- * `offset + items.length >= total`.
443
- */
444
- export interface PaginatedResult<T> {
445
- items: T[];
446
- total: number;
447
- offset: number;
448
- limit: number;
398
+ onLog?: (record: WorkflowLogRecord) => void;
449
399
  }
@@ -54,7 +54,8 @@ export type ReviewStatus = 'pending' | 'completed';
54
54
  * Filter accepted by `engine.listReviews(filter?)` and the `/v1/reviews`
55
55
  * transport surfaces.
56
56
  *
57
- * Omitting `status` preserves the legacy pending-only behavior.
57
+ * Omitting `status` lists pending reviews; pass `status: 'completed'` to list
58
+ * completed reviews instead.
58
59
  *
59
60
  * @example
60
61
  * ```ts