@lostgradient/weft 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (510) hide show
  1. package/README.md +79 -24
  2. package/dist/cli/conformance.js +7 -1
  3. package/dist/cli/generated/operation-client.generated.d.ts +28 -13
  4. package/dist/cli/generated/operation-client.generated.js +1 -0
  5. package/dist/cli/help-text.d.ts +1 -1
  6. package/dist/cli/help-text.js +1 -0
  7. package/dist/cli/operation-catalog-snapshot.d.ts +8 -0
  8. package/dist/cli/operation-catalog-snapshot.js +11 -0
  9. package/dist/cli/parse-schedule-arguments.js +3 -1
  10. package/dist/cli/schedule.js +2 -1
  11. package/dist/cli/types.d.ts +1 -0
  12. package/dist/cli-main.js +79 -78
  13. package/dist/client/handle-delegation.d.ts +3 -2
  14. package/dist/client/handle-delegation.js +3 -1
  15. package/dist/client/http-client-requests.d.ts +2 -1
  16. package/dist/client/http-client-requests.js +7 -0
  17. package/dist/client/http-client.d.ts +9 -6
  18. package/dist/client/http-client.js +10 -1
  19. package/dist/client/http-request.d.ts +11 -1
  20. package/dist/client/http-request.js +17 -7
  21. package/dist/client/index.d.ts +1 -1
  22. package/dist/client/interface.d.ts +61 -5
  23. package/dist/client/local-handles.d.ts +22 -0
  24. package/dist/client/local-handles.js +23 -0
  25. package/dist/client/local.d.ts +6 -3
  26. package/dist/client/local.js +12 -26
  27. package/dist/client/start-body.d.ts +4 -3
  28. package/dist/core/byte-arrays.d.ts +5 -0
  29. package/dist/core/byte-arrays.js +5 -0
  30. package/dist/core/checkpoint/lifecycle.d.ts +3 -0
  31. package/dist/core/checkpoint/lifecycle.js +9 -4
  32. package/dist/core/checkpoint/serialization.js +12 -5
  33. package/dist/core/codec/extension-codec.d.ts +16 -0
  34. package/dist/core/codec/extension-codec.js +100 -6
  35. package/dist/core/context/activity-retry-state.d.ts +38 -0
  36. package/dist/core/context/activity-retry-state.js +89 -0
  37. package/dist/core/context/activity-schedule-to-close.d.ts +159 -0
  38. package/dist/core/context/activity-schedule-to-close.js +69 -0
  39. package/dist/core/context/child-workflow-pipe.d.ts +5 -5
  40. package/dist/core/context/child-workflow-pipe.js +15 -2
  41. package/dist/core/context/context-presence.d.ts +19 -0
  42. package/dist/core/context/context-presence.js +13 -0
  43. package/dist/core/context/durable-operations.d.ts +25 -0
  44. package/dist/core/context/durable-operations.js +64 -0
  45. package/dist/core/context/index.d.ts +9 -5
  46. package/dist/core/context/index.js +17 -12
  47. package/dist/core/context/internals.d.ts +20 -0
  48. package/dist/core/context/internals.js +3 -1
  49. package/dist/core/context/operation-request.d.ts +35 -0
  50. package/dist/core/context/parallel-cache-entry.d.ts +14 -5
  51. package/dist/core/context/run-operation.d.ts +6 -1
  52. package/dist/core/context/run-operation.js +41 -87
  53. package/dist/core/context/session-state.js +7 -8
  54. package/dist/core/context/speculative-child.js +2 -0
  55. package/dist/core/context/types.d.ts +15 -0
  56. package/dist/core/context/version-patching.d.ts +8 -0
  57. package/dist/core/context/version-patching.js +40 -0
  58. package/dist/core/context/workflow-logger.d.ts +98 -0
  59. package/dist/core/context/workflow-logger.js +68 -0
  60. package/dist/core/engine/activity-heartbeat-tracking.d.ts +64 -0
  61. package/dist/core/engine/activity-heartbeat-tracking.js +42 -0
  62. package/dist/core/engine/activity-per-attempt-timeout.d.ts +46 -0
  63. package/dist/core/engine/activity-per-attempt-timeout.js +36 -0
  64. package/dist/core/engine/activity-reconciliation.d.ts +1 -0
  65. package/dist/core/engine/activity-reconciliation.js +12 -1
  66. package/dist/core/engine/activity-resolution.d.ts +23 -0
  67. package/dist/core/engine/activity-resolution.js +37 -0
  68. package/dist/core/engine/aggregate.js +66 -30
  69. package/dist/core/engine/async-activity-completion.d.ts +23 -6
  70. package/dist/core/engine/async-activity-completion.js +53 -12
  71. package/dist/core/engine/attributes-tags.js +9 -4
  72. package/dist/core/engine/bulk-operations-purge.d.ts +26 -0
  73. package/dist/core/engine/bulk-operations-purge.js +38 -3
  74. package/dist/core/engine/bulk-operations-shared.d.ts +2 -0
  75. package/dist/core/engine/bulk-operations-shared.js +8 -2
  76. package/dist/core/engine/bulk-operations.d.ts +4 -1
  77. package/dist/core/engine/bulk-operations.js +235 -24
  78. package/dist/core/engine/callback-creators-bundles.d.ts +9 -0
  79. package/dist/core/engine/callback-creators-bundles.js +30 -2
  80. package/dist/core/engine/callback-creators-core.js +6 -4
  81. package/dist/core/engine/callback-creators-router.js +10 -0
  82. package/dist/core/engine/callback-creators-schedule.d.ts +2 -2
  83. package/dist/core/engine/callback-creators-schedule.js +12 -8
  84. package/dist/core/engine/candidate-read-batching.d.ts +6 -0
  85. package/dist/core/engine/candidate-read-batching.js +1 -0
  86. package/dist/core/engine/checkpoint-io.js +61 -25
  87. package/dist/core/engine/checkpoint-reads.js +3 -2
  88. package/dist/core/engine/checkpoint-replay.d.ts +20 -0
  89. package/dist/core/engine/checkpoint-replay.js +242 -0
  90. package/dist/core/engine/checkpoint-side-effects.d.ts +23 -0
  91. package/dist/core/engine/checkpoint-side-effects.js +35 -0
  92. package/dist/core/engine/child-workflow-cancellation.d.ts +10 -0
  93. package/dist/core/engine/child-workflow-cancellation.js +40 -0
  94. package/dist/core/engine/child-workflow.js +27 -4
  95. package/dist/core/engine/condition-waiters.d.ts +14 -0
  96. package/dist/core/engine/condition-waiters.js +5 -0
  97. package/dist/core/engine/construction.d.ts +3 -0
  98. package/dist/core/engine/construction.js +21 -8
  99. package/dist/core/engine/coordination-branch-executors.d.ts +70 -0
  100. package/dist/core/engine/coordination-branch-executors.js +107 -0
  101. package/dist/core/engine/deferred-consume-envelope.d.ts +59 -0
  102. package/dist/core/engine/deferred-consume-envelope.js +14 -0
  103. package/dist/core/engine/disposal.js +13 -0
  104. package/dist/core/engine/engine-create-types.d.ts +14 -4
  105. package/dist/core/engine/engine-internal-types.d.ts +26 -3
  106. package/dist/core/engine/errors.d.ts +47 -0
  107. package/dist/core/engine/errors.js +20 -0
  108. package/dist/core/engine/event-log-compaction.d.ts +8 -0
  109. package/dist/core/engine/event-log-compaction.js +20 -2
  110. package/dist/core/engine/fenced-write.d.ts +65 -0
  111. package/dist/core/engine/fenced-write.js +71 -0
  112. package/dist/core/engine/finalizer-state.d.ts +28 -0
  113. package/dist/core/engine/finalizer-state.js +16 -0
  114. package/dist/core/engine/handles.d.ts +8 -0
  115. package/dist/core/engine/index.d.ts +34 -16
  116. package/dist/core/engine/index.js +136 -9
  117. package/dist/core/engine/inline-parking.js +3 -2
  118. package/dist/core/engine/internals.d.ts +107 -3
  119. package/dist/core/engine/lease-codec.d.ts +35 -0
  120. package/dist/core/engine/lease-codec.js +32 -0
  121. package/dist/core/engine/lease-deposition.d.ts +66 -0
  122. package/dist/core/engine/lease-deposition.js +10 -0
  123. package/dist/core/engine/lease-errors.d.ts +99 -0
  124. package/dist/core/engine/lease-errors.js +30 -0
  125. package/dist/core/engine/lease-manager.d.ts +114 -0
  126. package/dist/core/engine/lease-manager.js +135 -0
  127. package/dist/core/engine/lifecycle/persist.js +10 -32
  128. package/dist/core/engine/lifecycle/recovered-services.d.ts +8 -6
  129. package/dist/core/engine/lifecycle/recovered-services.js +18 -3
  130. package/dist/core/engine/lifecycle/resume.js +16 -9
  131. package/dist/core/engine/lifecycle/shared.d.ts +8 -1
  132. package/dist/core/engine/lifecycle/start-batch.d.ts +1 -1
  133. package/dist/core/engine/lifecycle/start-batch.js +2 -1
  134. package/dist/core/engine/lifecycle/start-commit.d.ts +9 -0
  135. package/dist/core/engine/lifecycle/start-commit.js +50 -8
  136. package/dist/core/engine/lifecycle/start-or-signal-create.d.ts +58 -0
  137. package/dist/core/engine/lifecycle/start-or-signal-create.js +95 -0
  138. package/dist/core/engine/lifecycle/start-or-signal.d.ts +3 -2
  139. package/dist/core/engine/lifecycle/start-or-signal.js +11 -81
  140. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.d.ts +39 -0
  141. package/dist/core/engine/lifecycle/start-terminal-conflict-purge.js +28 -0
  142. package/dist/core/engine/lifecycle/start.d.ts +4 -4
  143. package/dist/core/engine/lifecycle/start.js +17 -9
  144. package/dist/core/engine/lifecycle/transition.js +17 -5
  145. package/dist/core/engine/lifecycle.d.ts +1 -1
  146. package/dist/core/engine/list-candidate-resolution.js +2 -2
  147. package/dist/core/engine/listing.js +9 -5
  148. package/dist/core/engine/operations-activity.d.ts +6 -13
  149. package/dist/core/engine/operations-activity.js +26 -53
  150. package/dist/core/engine/operations-coordination.d.ts +10 -0
  151. package/dist/core/engine/operations-coordination.js +44 -9
  152. package/dist/core/engine/operations-router.d.ts +6 -0
  153. package/dist/core/engine/operations-router.js +2 -0
  154. package/dist/core/engine/operations-speculate.js +6 -2
  155. package/dist/core/engine/operations-stream.js +12 -2
  156. package/dist/core/engine/operations-time.d.ts +4 -2
  157. package/dist/core/engine/operations-time.js +14 -2
  158. package/dist/core/engine/operations-wait-condition.d.ts +23 -0
  159. package/dist/core/engine/operations-wait-condition.js +62 -0
  160. package/dist/core/engine/ownership-options.d.ts +23 -0
  161. package/dist/core/engine/ownership-options.js +26 -0
  162. package/dist/core/engine/payload-size-policy.d.ts +3 -0
  163. package/dist/core/engine/payload-size-policy.js +4 -0
  164. package/dist/core/engine/pending-updates.d.ts +17 -0
  165. package/dist/core/engine/pending-updates.js +33 -11
  166. package/dist/core/engine/queries.js +1 -1
  167. package/dist/core/engine/registration.d.ts +1 -0
  168. package/dist/core/engine/registration.js +18 -3
  169. package/dist/core/engine/schedule-jitter.d.ts +5 -0
  170. package/dist/core/engine/schedule-jitter.js +10 -0
  171. package/dist/core/engine/schedule-run.d.ts +17 -0
  172. package/dist/core/engine/schedule-run.js +38 -0
  173. package/dist/core/engine/schedule-timer.js +81 -17
  174. package/dist/core/engine/schedules.d.ts +7 -4
  175. package/dist/core/engine/schedules.js +37 -16
  176. package/dist/core/engine/search-attribute-records.d.ts +4 -0
  177. package/dist/core/engine/search-attribute-records.js +17 -0
  178. package/dist/core/engine/signals.d.ts +18 -2
  179. package/dist/core/engine/signals.js +42 -21
  180. package/dist/core/engine/state-utilities.d.ts +49 -2
  181. package/dist/core/engine/state-utilities.js +114 -3
  182. package/dist/core/engine/storage-io.d.ts +16 -2
  183. package/dist/core/engine/storage-io.js +26 -5
  184. package/dist/core/engine/stream-chunk-loading.d.ts +2 -0
  185. package/dist/core/engine/stream-chunk-loading.js +24 -1
  186. package/dist/core/engine/sub-operation.js +25 -6
  187. package/dist/core/engine/termination/cleanup.d.ts +3 -1
  188. package/dist/core/engine/termination/cleanup.js +25 -1
  189. package/dist/core/engine/termination/complete.js +44 -6
  190. package/dist/core/engine/termination/finalizer-activity.d.ts +53 -0
  191. package/dist/core/engine/termination/finalizer-activity.js +30 -0
  192. package/dist/core/engine/termination/finalizer-claim.d.ts +110 -0
  193. package/dist/core/engine/termination/finalizer-claim.js +80 -0
  194. package/dist/core/engine/termination/finalizer.d.ts +48 -0
  195. package/dist/core/engine/termination/finalizer.js +159 -0
  196. package/dist/core/engine/termination/suspend.d.ts +3 -1
  197. package/dist/core/engine/termination.d.ts +1 -0
  198. package/dist/core/engine/termination.js +4 -0
  199. package/dist/core/engine/updates.js +5 -25
  200. package/dist/core/engine/validation/schedule.d.ts +2 -1
  201. package/dist/core/engine/validation/schedule.js +51 -2
  202. package/dist/core/engine/validation.js +32 -5
  203. package/dist/core/engine/waiting-update-response.d.ts +8 -0
  204. package/dist/core/engine/waiting-update-response.js +22 -0
  205. package/dist/core/engine/workflow-concurrency.d.ts +10 -0
  206. package/dist/core/engine/workflow-concurrency.js +136 -0
  207. package/dist/core/engine/workflow-feed.d.ts +4 -5
  208. package/dist/core/engine/workflow-feed.js +4 -1
  209. package/dist/core/engine/workflow-indexes.d.ts +9 -0
  210. package/dist/core/engine/workflow-indexes.js +10 -0
  211. package/dist/core/engine/workflow-state-stream.js +33 -13
  212. package/dist/core/engine/workflow-visibility-queries.d.ts +2 -2
  213. package/dist/core/engine-helpers.js +1 -0
  214. package/dist/core/events/activity-events.d.ts +43 -12
  215. package/dist/core/events/activity-events.js +28 -0
  216. package/dist/core/events/attribute-events.d.ts +2 -3
  217. package/dist/core/events/event-map.d.ts +18 -12
  218. package/dist/core/events/index.d.ts +1 -0
  219. package/dist/core/events/index.js +1 -0
  220. package/dist/core/events/schedule-events.d.ts +71 -0
  221. package/dist/core/events/schedule-events.js +29 -0
  222. package/dist/core/events/signal-events.d.ts +4 -6
  223. package/dist/core/events/system-events.d.ts +29 -19
  224. package/dist/core/events/system-events.js +26 -0
  225. package/dist/core/events/update-events.d.ts +6 -8
  226. package/dist/core/events/workflow-events.d.ts +88 -23
  227. package/dist/core/events/workflow-events.js +26 -0
  228. package/dist/core/failure-categories.js +5 -17
  229. package/dist/core/fault-code.d.ts +9 -3
  230. package/dist/core/fault-code.js +1 -0
  231. package/dist/core/inline-execution-strategy.context-options.d.ts +69 -0
  232. package/dist/core/inline-execution-strategy.context-options.js +56 -0
  233. package/dist/core/inline-execution-strategy.d.ts +31 -36
  234. package/dist/core/inline-execution-strategy.js +16 -27
  235. package/dist/core/list-filter-validation.d.ts +1 -1
  236. package/dist/core/payload-size.d.ts +1 -1
  237. package/dist/core/persisted-data-incompatible-error.d.ts +9 -7
  238. package/dist/core/review/events.d.ts +6 -8
  239. package/dist/core/scheduler/scheduler-class.d.ts +10 -1
  240. package/dist/core/scheduler/scheduler-class.js +38 -11
  241. package/dist/core/scheduler/timer-batch.js +9 -1
  242. package/dist/core/scheduler/timer-sources.d.ts +1 -0
  243. package/dist/core/scheduler/timer-sources.js +11 -5
  244. package/dist/core/session-state.d.ts +0 -1
  245. package/dist/core/session-state.js +2 -2
  246. package/dist/core/start-workflow-validation.d.ts +34 -0
  247. package/dist/core/start-workflow-validation.js +19 -0
  248. package/dist/core/types/activity-verification.d.ts +67 -0
  249. package/dist/core/types/activity-verification.js +0 -0
  250. package/dist/core/types/activity.d.ts +80 -61
  251. package/dist/core/types/bulk.d.ts +50 -9
  252. package/dist/core/types/checkpoint.d.ts +44 -8
  253. package/dist/core/types/list-options.d.ts +146 -0
  254. package/dist/core/types/list-options.js +0 -0
  255. package/dist/core/types/options.d.ts +121 -165
  256. package/dist/core/types/schedules.d.ts +39 -3
  257. package/dist/core/types/services-resolution.d.ts +2 -2
  258. package/dist/core/types/workflow-builder-runtime.d.ts +12 -3
  259. package/dist/core/types/workflow-builder-runtime.js +11 -2
  260. package/dist/core/types/workflow-builder.d.ts +42 -11
  261. package/dist/core/types/workflow-concurrency.d.ts +39 -0
  262. package/dist/core/types/workflow-concurrency.js +0 -0
  263. package/dist/core/types/workflow-context.d.ts +157 -14
  264. package/dist/core/types/workflow-definition.d.ts +53 -10
  265. package/dist/core/types/workflow-function.d.ts +84 -9
  266. package/dist/core/types/workflow-log.d.ts +98 -0
  267. package/dist/core/types/workflow-log.js +0 -0
  268. package/dist/core/types/workflow-registries.d.ts +14 -3
  269. package/dist/core/types/workflow-registry.d.ts +3 -0
  270. package/dist/core/types.d.ts +4 -0
  271. package/dist/core/types.js +4 -0
  272. package/dist/core/versioning.d.ts +9 -39
  273. package/dist/core/versioning.js +2 -12
  274. package/dist/core/weft-error.d.ts +44 -1
  275. package/dist/core/weft-error.js +16 -0
  276. package/dist/core/worker-execution-strategy-options.d.ts +26 -0
  277. package/dist/core/worker-execution-strategy.js +40 -36
  278. package/dist/core/worker-inbound-message.d.ts +38 -0
  279. package/dist/core/worker-inbound-message.js +37 -0
  280. package/dist/core/worker-log-abuse-counter.d.ts +175 -0
  281. package/dist/core/worker-log-abuse-counter.js +107 -0
  282. package/dist/core/worker-message-helpers.d.ts +47 -0
  283. package/dist/core/worker-message-helpers.js +26 -0
  284. package/dist/core/worker-protocol-guard.js +1 -1
  285. package/dist/core/worker-protocol-log.d.ts +56 -0
  286. package/dist/core/worker-protocol-log.js +18 -0
  287. package/dist/core/worker-protocol.d.ts +23 -0
  288. package/dist/core/worker-protocol.js +12 -2
  289. package/dist/core/workflow-version-tuple.d.ts +3 -9
  290. package/dist/core/workflow-version-tuple.js +2 -3
  291. package/dist/diagnostics/format.js +1 -6
  292. package/dist/diagnostics/types.d.ts +4 -5
  293. package/dist/diagnostics/validate.d.ts +0 -1
  294. package/dist/diagnostics/version-check.d.ts +1 -1
  295. package/dist/diagnostics/version-check.js +4 -9
  296. package/dist/index.d.ts +12 -10
  297. package/dist/index.js +29 -3
  298. package/dist/json-schema.js +3 -3
  299. package/dist/mcp/cli.js +19 -19
  300. package/dist/mcp/dispatcher.js +1 -1
  301. package/dist/mcp/http.js +16 -6
  302. package/dist/mcp/protocol.d.ts +2 -0
  303. package/dist/mcp/protocol.js +1 -1
  304. package/dist/mcp/session.d.ts +16 -0
  305. package/dist/mcp/session.js +59 -6
  306. package/dist/mcp/tools.js +73 -6
  307. package/dist/observability/index.js +2 -2
  308. package/dist/server/asyncapi-channels.js +5 -2
  309. package/dist/server/attribute-filters.d.ts +8 -3
  310. package/dist/server/attribute-filters.js +6 -1
  311. package/dist/server/authentication/api-key.d.ts +2 -1
  312. package/dist/server/authentication/api-key.js +5 -2
  313. package/dist/server/authentication/constant-time-api-key.d.ts +15 -0
  314. package/dist/server/authentication/constant-time-api-key.js +24 -0
  315. package/dist/server/authentication/index.d.ts +1 -1
  316. package/dist/server/authentication/index.js +7 -4
  317. package/dist/server/authentication/rotating-api-key-store.d.ts +5 -3
  318. package/dist/server/authentication/rotating-api-key-store.js +19 -11
  319. package/dist/server/engine-event-feed-backend.d.ts +4 -5
  320. package/dist/server/fault-to-http.js +8 -1
  321. package/dist/server/fault-to-json-rpc.js +1 -0
  322. package/dist/server/fleet-event-feed.d.ts +31 -0
  323. package/dist/server/fleet-event-feed.js +157 -0
  324. package/dist/server/handler/index.js +1 -1
  325. package/dist/server/handler/response-helpers.js +2 -1
  326. package/dist/server/handler/route-dispatch.d.ts +6 -3
  327. package/dist/server/handler/route-dispatch.js +2 -2
  328. package/dist/server/handler.js +23 -23
  329. package/dist/server/index.d.ts +32 -2
  330. package/dist/server/index.js +32 -32
  331. package/dist/server/json-rpc-transport-helpers.d.ts +1 -0
  332. package/dist/server/json-rpc-transport-helpers.js +2 -1
  333. package/dist/server/json-rpc-websocket-runtime.d.ts +11 -2
  334. package/dist/server/json-rpc-websocket-runtime.js +1 -0
  335. package/dist/server/json-rpc-websocket-subscriptions.d.ts +10 -0
  336. package/dist/server/json-rpc-websocket-subscriptions.js +29 -0
  337. package/dist/server/json-rpc-websocket-types.d.ts +22 -0
  338. package/dist/server/json-rpc-websocket-types.js +0 -0
  339. package/dist/server/json-rpc-websocket-validation.js +20 -4
  340. package/dist/server/json-rpc-websocket.d.ts +2 -43
  341. package/dist/server/json-rpc-websocket.js +57 -74
  342. package/dist/server/openapi.d.ts +2 -1
  343. package/dist/server/openapi.js +1 -3
  344. package/dist/server/openrpc-document-schema.d.ts +78 -0
  345. package/dist/server/openrpc-document-schema.js +27 -1
  346. package/dist/server/openrpc-errors.d.ts +3 -0
  347. package/dist/server/openrpc-errors.js +2 -1
  348. package/dist/server/openrpc.js +32 -0
  349. package/dist/server/operation-catalog/index.d.ts +1 -1
  350. package/dist/server/operation-catalog/pipeline-helpers.js +1 -0
  351. package/dist/server/operation-catalog/pipeline-stages.js +26 -12
  352. package/dist/server/operation-catalog/pipeline.js +8 -1
  353. package/dist/server/operation-catalog/registry.js +13 -0
  354. package/dist/server/operation-catalog/types.d.ts +20 -9
  355. package/dist/server/operation-fault.d.ts +10 -0
  356. package/dist/server/operation-fault.js +2 -0
  357. package/dist/server/operation-registry.d.ts +12 -11
  358. package/dist/server/operation-registry.js +12 -3
  359. package/dist/server/operations/aggregate-workflows.d.ts +15 -15
  360. package/dist/server/operations/async-activity.d.ts +2 -2
  361. package/dist/server/operations/async-activity.js +12 -7
  362. package/dist/server/operations/bulk-cancel-workflows.d.ts +1 -1
  363. package/dist/server/operations/bulk-cancel-workflows.js +2 -2
  364. package/dist/server/operations/bulk-delete-workflows.d.ts +1 -1
  365. package/dist/server/operations/bulk-delete-workflows.js +2 -2
  366. package/dist/server/operations/bulk-filter-helpers.d.ts +8 -6
  367. package/dist/server/operations/bulk-filter-helpers.js +54 -24
  368. package/dist/server/operations/bulk-mutate-workflow-tags.d.ts +11 -9
  369. package/dist/server/operations/bulk-mutate-workflow-tags.js +2 -2
  370. package/dist/server/operations/bulk-operation-helpers.d.ts +2 -2
  371. package/dist/server/operations/bulk-retry-failed-workflows.d.ts +7 -0
  372. package/dist/server/operations/bulk-retry-failed-workflows.js +64 -0
  373. package/dist/server/operations/bulk-signal-workflows.d.ts +11 -9
  374. package/dist/server/operations/bulk-signal-workflows.js +2 -2
  375. package/dist/server/operations/cancel-schedule.d.ts +1 -1
  376. package/dist/server/operations/create-schedule.d.ts +3 -1
  377. package/dist/server/operations/create-schedule.js +29 -11
  378. package/dist/server/operations/fleet-events-subscription.d.ts +54 -0
  379. package/dist/server/operations/fleet-events-subscription.js +99 -0
  380. package/dist/server/operations/fork-workflow.d.ts +1 -1
  381. package/dist/server/operations/fork-workflow.js +3 -2
  382. package/dist/server/operations/get-checkpoint-at.d.ts +1 -1
  383. package/dist/server/operations/get-registry.d.ts +1 -1
  384. package/dist/server/operations/get-retention-overview.d.ts +1 -1
  385. package/dist/server/operations/get-review.d.ts +1 -1
  386. package/dist/server/operations/get-schedule.d.ts +1 -1
  387. package/dist/server/operations/get-stream-chunks.d.ts +1 -1
  388. package/dist/server/operations/get-system-metrics.d.ts +2 -2
  389. package/dist/server/operations/get-task-diagnostics.d.ts +45 -6
  390. package/dist/server/operations/get-task-diagnostics.js +101 -7
  391. package/dist/server/operations/get-update-result.d.ts +1 -1
  392. package/dist/server/operations/get-workflow-attributes.d.ts +1 -1
  393. package/dist/server/operations/get-workflow-events.d.ts +1 -1
  394. package/dist/server/operations/get-workflow-result.d.ts +1 -1
  395. package/dist/server/operations/get-workflow-timeline.d.ts +1 -1
  396. package/dist/server/operations/get-workflow.d.ts +1 -1
  397. package/dist/server/operations/list-checkpoints.d.ts +1 -1
  398. package/dist/server/operations/list-reviews.d.ts +1 -1
  399. package/dist/server/operations/list-schedules.d.ts +1 -1
  400. package/dist/server/operations/list-task-queues.d.ts +2 -2
  401. package/dist/server/operations/list-workers.d.ts +2 -2
  402. package/dist/server/operations/list-workflows.d.ts +1 -1
  403. package/dist/server/operations/operation-helpers.d.ts +16 -1
  404. package/dist/server/operations/operation-helpers.js +15 -3
  405. package/dist/server/operations/pause-schedule.d.ts +1 -1
  406. package/dist/server/operations/purge-workflows.d.ts +5 -5
  407. package/dist/server/operations/purge-workflows.js +2 -2
  408. package/dist/server/operations/query-workflow.d.ts +1 -1
  409. package/dist/server/operations/query-workflow.js +3 -2
  410. package/dist/server/operations/recover-all.d.ts +1 -1
  411. package/dist/server/operations/replay-workflow.d.ts +1 -1
  412. package/dist/server/operations/resume-schedule.d.ts +1 -1
  413. package/dist/server/operations/set-workflow-attributes.d.ts +1 -1
  414. package/dist/server/operations/set-workflow-attributes.js +6 -3
  415. package/dist/server/operations/signal-workflow.js +8 -3
  416. package/dist/server/operations/single-workflow-tag-mutation.js +13 -3
  417. package/dist/server/operations/start-or-signal-workflow.d.ts +6 -1
  418. package/dist/server/operations/start-or-signal-workflow.js +14 -24
  419. package/dist/server/operations/start-workflow-options.d.ts +6 -0
  420. package/dist/server/operations/start-workflow-rest-input.d.ts +14 -0
  421. package/dist/server/operations/start-workflow-rest-input.js +31 -0
  422. package/dist/server/operations/start-workflow.d.ts +1 -1
  423. package/dist/server/operations/start-workflow.js +8 -23
  424. package/dist/server/operations/storage.d.ts +6 -6
  425. package/dist/server/operations/storage.js +24 -14
  426. package/dist/server/operations/stream-workflow-sse.d.ts +1 -1
  427. package/dist/server/operations/submit-review-decision.d.ts +1 -1
  428. package/dist/server/operations/submit-review-decision.js +6 -3
  429. package/dist/server/operations/update-schedule.d.ts +1 -1
  430. package/dist/server/operations/update-schedule.js +7 -4
  431. package/dist/server/operations/update-workflow.d.ts +1 -1
  432. package/dist/server/operations/update-workflow.js +7 -3
  433. package/dist/server/operations/worker-drain.d.ts +8 -8
  434. package/dist/server/operations/worker-drain.js +11 -8
  435. package/dist/server/operations/workflow-events-subscription.d.ts +7 -8
  436. package/dist/server/operations/workflow-events-subscription.js +43 -8
  437. package/dist/server/rest-binding.d.ts +3 -1
  438. package/dist/server/rest-bindings.js +12 -0
  439. package/dist/server/rest-body.d.ts +10 -0
  440. package/dist/server/rest-body.js +80 -0
  441. package/dist/server/runtime/authentication-bridge.d.ts +1 -0
  442. package/dist/server/runtime/authentication-bridge.js +33 -6
  443. package/dist/server/runtime/client-visible-events.d.ts +3 -0
  444. package/dist/server/runtime/client-visible-events.js +65 -0
  445. package/dist/server/runtime/context.d.ts +7 -0
  446. package/dist/server/runtime/event-broadcasting.d.ts +6 -0
  447. package/dist/server/runtime/event-broadcasting.js +72 -38
  448. package/dist/server/runtime/retry.d.ts +1 -0
  449. package/dist/server/runtime/retry.js +14 -0
  450. package/dist/server/runtime/shutdown.d.ts +7 -6
  451. package/dist/server/runtime/shutdown.js +6 -1
  452. package/dist/server/runtime/task-polling.js +61 -20
  453. package/dist/server/runtime/task-reconciliation.js +9 -1
  454. package/dist/server/runtime/task-result-resolution.d.ts +15 -0
  455. package/dist/server/runtime/task-result-resolution.js +81 -0
  456. package/dist/server/runtime/websocket-stream.d.ts +20 -1
  457. package/dist/server/runtime/websocket-stream.js +173 -7
  458. package/dist/server/runtime/websocket-upgrade.js +22 -3
  459. package/dist/server/runtime/websocket-worker.d.ts +1 -1
  460. package/dist/server/runtime/websocket-worker.js +38 -30
  461. package/dist/server/serve-internals.d.ts +3 -1
  462. package/dist/server/serve-internals.js +18 -2
  463. package/dist/server/task-state.d.ts +30 -0
  464. package/dist/server/task-state.js +28 -0
  465. package/dist/server/workflow-event-feed.d.ts +36 -115
  466. package/dist/server/workflow-event-feed.js +92 -27
  467. package/dist/service-worker/index.js +30 -30
  468. package/dist/storage/auto.js +1 -1
  469. package/dist/storage/bun-sql.js +24 -0
  470. package/dist/storage/compressed-storage.js +1 -1
  471. package/dist/storage/default-scope.d.ts +7 -4
  472. package/dist/storage/http.js +2 -2
  473. package/dist/storage/index.d.ts +76 -4
  474. package/dist/storage/indexeddb.js +1 -1
  475. package/dist/storage/interface.d.ts +163 -0
  476. package/dist/storage/interface.js +1 -1
  477. package/dist/storage/key-prefixes.d.ts +1 -1
  478. package/dist/storage/key-prefixes.js +10 -0
  479. package/dist/storage/lmdb.d.ts +4 -3
  480. package/dist/storage/lmdb.js +1 -1
  481. package/dist/storage/memory.js +1 -1
  482. package/dist/storage/neon-batch.d.ts +30 -0
  483. package/dist/storage/neon-batch.js +30 -0
  484. package/dist/storage/neon-value-mapping.d.ts +30 -3
  485. package/dist/storage/neon-value-mapping.js +12 -0
  486. package/dist/storage/neon.d.ts +16 -0
  487. package/dist/storage/neon.js +9 -4
  488. package/dist/storage/node-sqlite.js +23 -0
  489. package/dist/storage/postgres-key-value-queries.d.ts +69 -44
  490. package/dist/storage/postgres-key-value-queries.js +62 -24
  491. package/dist/storage/resolve.js +1 -1
  492. package/dist/storage/scoped-storage.js +1 -1
  493. package/dist/storage/testing.d.ts +168 -0
  494. package/dist/storage/testing.js +2 -0
  495. package/dist/storage/turso.d.ts +8 -0
  496. package/dist/storage/turso.js +2 -2
  497. package/dist/storage/typed-storage.js +1 -1
  498. package/dist/storage/web-extension.js +1 -1
  499. package/dist/testing/index.js +20 -20
  500. package/dist/version.d.ts +1 -1
  501. package/dist/version.js +1 -1
  502. package/dist/worker/protocol.js +1 -1
  503. package/dist/workers/worker-replay-state.d.ts +32 -0
  504. package/dist/workers/worker-replay-state.js +35 -0
  505. package/dist/workers/worker-state-namespace.d.ts +21 -0
  506. package/dist/workers/worker-state-namespace.js +13 -0
  507. package/dist/workers/workflow-runner.d.ts +19 -15
  508. package/dist/workers/workflow-runner.js +72 -60
  509. package/dist/workers/workflow-worker-entry.js +5 -2
  510. package/package.json +5 -1
@@ -1,4 +1,7 @@
1
- import { KEYS } from "../../storage/interface.js";
1
+ import {
2
+ KEYS,
3
+ requireStorageCapability
4
+ } from "../../storage/interface.js";
2
5
  import {
3
6
  ActivityRegistry
4
7
  } from "../activity-registry.js";
@@ -24,6 +27,7 @@ import {
24
27
  cancelAll as cancelAllWorkflows,
25
28
  deleteAll as deleteAllWorkflows,
26
29
  purge as purgeWorkflows,
30
+ retryFailedAll as retryFailedAllWorkflows,
27
31
  signalAll as signalAllWorkflows,
28
32
  tagAll as tagAllWorkflows,
29
33
  untagAll as untagAllWorkflows
@@ -68,7 +72,9 @@ import {
68
72
  drainQueuedInlineWorkflowStartsForEngine,
69
73
  isActivityDefinition
70
74
  } from "./engine-runtime-helpers.js";
71
- import { EngineCreateNameMismatchError } from "./errors.js";
75
+ import { EngineCreateNameMismatchError, EngineDisposedError } from "./errors.js";
76
+ import { assertLeaseHeldForEngineWork, commitFencedEngineWrite } from "./fenced-write.js";
77
+ import { recordFinalizerState } from "./finalizer-state.js";
72
78
  import {
73
79
  createWorkflowHandleWithResultPromise as createWorkflowHandleWithResultPromiseFromInternals,
74
80
  getWorkflowResultPromise as getWorkflowResultPromiseFromInternals
@@ -80,6 +86,8 @@ import {
80
86
  resumeParkedInlineWorkflow as resumeParkedInlineWorkflowFromInternals
81
87
  } from "./inline-parking.js";
82
88
  import { getInternals, initializeInternals } from "./internals.js";
89
+ import { ENGINE_LEASE_LOST_WARNING_NAME, handleDeposition } from "./lease-deposition.js";
90
+ import { createLeaseManager } from "./lease-manager.js";
83
91
  import {
84
92
  fork as forkFromLifecycle,
85
93
  recoverAll as recoverAllFromLifecycle,
@@ -124,6 +132,7 @@ import {
124
132
  cancelSchedule as cancelScheduleFromInternals,
125
133
  listSchedules as listSchedulesFromInternals,
126
134
  pauseSchedule as pauseScheduleFromInternals,
135
+ recoverOrphanedScheduleTimers,
127
136
  resumeSchedule as resumeScheduleFromInternals,
128
137
  schedule as scheduleFromInternals,
129
138
  toScheduleSummary,
@@ -174,12 +183,19 @@ export {
174
183
  PersistedDataIncompatibleError,
175
184
  StartOrSignalConflictError,
176
185
  WorkflowAlreadyExistsError,
186
+ WorkflowConcurrencyLimitExceededError,
177
187
  WorkflowNotFoundError,
178
188
  WorkflowNotRegisteredError,
179
189
  WorkflowSuspendNotSupportedError,
190
+ WorkflowTeardownPendingError,
180
191
  WorkflowTypeNotRegisteredForRecoveryError
181
192
  } from "./errors.js";
182
193
  export { HANDLE_RESULT_PROMISE, WorkflowHandle } from "./handles.js";
194
+ export {
195
+ EngineLeaseAcquisitionTimeoutError,
196
+ EngineLeaseCorruptedError,
197
+ EngineLeaseNotHeldError
198
+ } from "./lease-errors.js";
183
199
  export { ScheduleHandle } from "./schedule-handle.js";
184
200
  export {
185
201
  clearEngineLeakWarningTokenForTesting,
@@ -192,6 +208,8 @@ export {
192
208
  export { assertCompatiblePersistedDataVersion };
193
209
  export const ENGINE_PARKED_WORKFLOW_COUNT_FOR_TESTING = Symbol("engineParkedWorkflowCountForTesting"), ENGINE_SIGNAL_WAITER_COUNT_FOR_TESTING = Symbol("engineSignalWaiterCountForTesting"), ENGINE_SLEEP_RESOLVER_COUNT_FOR_TESTING = Symbol("engineSleepResolverCountForTesting");
194
210
 
211
+ export { ENGINE_LEASE_LOST_WARNING_NAME };
212
+
195
213
  export class Engine extends EventTarget {
196
214
  static async create(options) {
197
215
  const engine = new Engine(options);
@@ -207,8 +225,11 @@ export class Engine extends EventTarget {
207
225
  throw new EngineCreateNameMismatchError("workflow", name, definition.name);
208
226
  engine.register(definition);
209
227
  }
210
- if (options.recover !== !1)
228
+ await engine.#acquireLeaseIfConfigured();
229
+ if (options.recover !== !1) {
211
230
  await engine.recoverAll(options.acknowledgeUnknownWorkflowTypes !== void 0 ? { acknowledgeUnknownWorkflowTypes: options.acknowledgeUnknownWorkflowTypes } : {});
231
+ getInternals(engine).scheduler.start();
232
+ }
212
233
  } catch (error) {
213
234
  await engine[Symbol.asyncDispose]();
214
235
  throw error;
@@ -230,7 +251,9 @@ export class Engine extends EventTarget {
230
251
  getComposedWorkflowInterceptor: () => getComposedWorkflowInterceptor(getInternals(this)),
231
252
  resolveWorkflowType: this.#resolveWorkflowTypeTarget.bind(this),
232
253
  registerCancelHandler: (workflowId, handler) => registerCancelHandler(getInternals(this), workflowId, handler),
233
- getWorkflowServices: (workflowId) => getInternals(this).workflowServices.get(workflowId)
254
+ recordFinalizerState: (workflowId, value) => recordFinalizerState(getInternals(this), workflowId, value),
255
+ getWorkflowServices: (workflowId) => getInternals(this).workflowServices.get(workflowId),
256
+ getLogSink: () => resolvedOptions.onLog ?? void 0
234
257
  });
235
258
  getInternals(this).storage = storage;
236
259
  getInternals(this).abortController = new AbortController;
@@ -239,6 +262,7 @@ export class Engine extends EventTarget {
239
262
  getInternals(this).resultResolvers = new Map;
240
263
  getInternals(this).signalWaiters = new Map;
241
264
  getInternals(this).signalWaitersByWorkflow = new Map;
265
+ getInternals(this).conditionWaiters = new Map;
242
266
  getInternals(this).updateWaiters = new Map;
243
267
  getInternals(this).updateWaitersByWorkflow = new Map;
244
268
  getInternals(this).sleepResolvers = new Map;
@@ -265,7 +289,8 @@ export class Engine extends EventTarget {
265
289
  getInternals(this).scheduler = new Scheduler({
266
290
  storage,
267
291
  onTimerFired: (entry) => handleTimerFiredFromInternals(getInternals(this), entry, this.#createTimeOperationCallbacks()),
268
- getNow
292
+ getNow,
293
+ commitTimerCleanup: (operations) => commitFencedEngineWrite(getInternals(this), operations, [], () => Error("Timer cleanup lost its fenced CAS race"))
269
294
  });
270
295
  getInternals(this).strategy = strategyBundle.strategy;
271
296
  getInternals(this).inlineStrategy = strategyBundle.inlineStrategy;
@@ -278,8 +303,10 @@ export class Engine extends EventTarget {
278
303
  if (queuedInlineWorkflowStartChannel !== null)
279
304
  queuedInlineWorkflowStartChannel.port1.onmessage = createQueuedInlineWorkflowStartHandler(weakEngine, queuedInlineWorkflowStartChannel);
280
305
  getInternals(this).heartbeatDetails = new Map;
306
+ getInternals(this).lastHeartbeatDetailsByStep = new Map;
281
307
  getInternals(this).workflowServices = new Map;
282
308
  getInternals(this).pendingAsyncActivities = new Map;
309
+ getInternals(this).pendingAsyncActivityResolutions = new Map;
283
310
  getInternals(this).pendingStarts = new Set;
284
311
  getInternals(this).pendingScheduleCreations = new Set;
285
312
  getInternals(this).workflowsNeedingTerminalCleanup = new Set;
@@ -290,10 +317,12 @@ export class Engine extends EventTarget {
290
317
  getInternals(this).workflowReviewIds = new Map;
291
318
  getInternals(this).parkedInlineWorkflows = new Set;
292
319
  getInternals(this).terminalizingWorkflows = new Set;
320
+ getInternals(this).deliveredPendingUpdateIds = new Map;
293
321
  getInternals(this).cancelHandlersByWorkflow = new Map;
294
322
  getInternals(this).reviewTimerIds = new Map;
295
323
  getInternals(this).pendingWebhooks = new Set;
296
324
  getInternals(this).pendingTimelineEntries = new Map;
325
+ getInternals(this).pendingAtomicWorkflowCommitSideEffects = new Map;
297
326
  getInternals(this).cleanupIntervalDisposalTracker = null;
298
327
  const cleanupIntervalDisposalTracker = {
299
328
  disposed: !1,
@@ -310,15 +339,90 @@ export class Engine extends EventTarget {
310
339
  getInternals(this).nextRetentionSweepAt = null;
311
340
  getInternals(this).secondInstanceDetectionInterval = null;
312
341
  getInternals(this).secondInstanceDetector = null;
342
+ getInternals(this).leaseManager = null;
343
+ getInternals(this).inFlightLeaseAcquire = null;
344
+ getInternals(this).deposed = !1;
345
+ getInternals(this).tearDownAfterDeposition = () => {
346
+ this.#disposeAfterDeposition();
347
+ };
313
348
  getInternals(this).eventLogHeads = new Map;
314
349
  getInternals(this).workflowFeedListeners = new Map;
315
350
  getInternals(this).workflowVersionTuples = new Map;
351
+ getInternals(this).workflowVisibilityWatermark = void 0;
352
+ getInternals(this).workflowVisibilityWatermarkExpiresAt = void 0;
316
353
  getInternals(this).activityWorkerDispatcher = createActivityWorkerDispatcher(options?.activityExecution);
317
354
  getInternals(this).strategy.onMessage(this.#handleStrategyMessage.bind(this));
318
355
  getInternals(this).alertManager = createAlertManagerForEngine(this, options?.alerts, getNow);
319
356
  this.#ensureRetentionSweepInterval();
320
357
  this.#startSecondInstanceDetection();
321
358
  }
359
+ addEventListener(type, listener, options) {
360
+ super.addEventListener(type, listener, options);
361
+ }
362
+ removeEventListener(type, listener, options) {
363
+ super.removeEventListener(type, listener, options);
364
+ }
365
+ async#acquireLeaseIfConfigured() {
366
+ const internals = getInternals(this);
367
+ if (internals.options.ownershipMode !== "lease")
368
+ return;
369
+ if (internals.disposed)
370
+ throw new EngineDisposedError;
371
+ if (internals.inFlightLeaseAcquire !== null) {
372
+ await internals.inFlightLeaseAcquire;
373
+ return;
374
+ }
375
+ if (internals.leaseManager !== null)
376
+ return;
377
+ requireStorageCapability(internals.storage, "conditionalBatch", "ownership: 'lease'");
378
+ const manager = createLeaseManager({
379
+ storage: internals.storage,
380
+ holderId: crypto.randomUUID(),
381
+ getNow: internals.options.getNow,
382
+ ttlMs: internals.options.leaseTtlMs,
383
+ renewIntervalMs: internals.options.leaseRenewIntervalMs,
384
+ waitTimeoutMs: internals.options.leaseWaitTimeoutMs,
385
+ onLeaseLost: (reason) => {
386
+ if (reason === "deposed") {
387
+ handleDeposition(internals);
388
+ return;
389
+ }
390
+ process.emitWarning("engine ownership lease renewal could not be confirmed (transient storage error); another instance may take over if this persists. Weft supports one engine process " + "per store \u2014 keep infrastructure-level single-instance enforcement in place.", ENGINE_LEASE_LOST_WARNING_NAME);
391
+ }
392
+ });
393
+ internals.leaseManager = manager;
394
+ const acquisition = (async () => {
395
+ try {
396
+ await manager.acquire();
397
+ } catch (error) {
398
+ if (internals.leaseManager === manager)
399
+ internals.leaseManager = null;
400
+ throw error;
401
+ }
402
+ if (internals.disposed) {
403
+ await manager.release();
404
+ if (internals.leaseManager === manager)
405
+ internals.leaseManager = null;
406
+ throw new EngineDisposedError;
407
+ }
408
+ manager.startRenewal();
409
+ })();
410
+ internals.inFlightLeaseAcquire = acquisition;
411
+ try {
412
+ await acquisition;
413
+ } finally {
414
+ if (internals.inFlightLeaseAcquire === acquisition)
415
+ internals.inFlightLeaseAcquire = null;
416
+ }
417
+ }
418
+ #disposeAfterDeposition() {
419
+ const internals = getInternals(this);
420
+ if (internals.disposed)
421
+ return;
422
+ const leaseManager = internals.leaseManager;
423
+ disposeEngine(internals);
424
+ leaseManager?.release().catch(() => {});
425
+ }
322
426
  #startSecondInstanceDetection() {
323
427
  const internals = getInternals(this);
324
428
  if (!internals.options.secondInstanceDetectionEnabled)
@@ -437,11 +541,13 @@ export class Engine extends EventTarget {
437
541
  return getInternals(this).activityRegistry.listDefinitions();
438
542
  }
439
543
  async start(type, input, options) {
544
+ assertLeaseHeldForEngineWork(getInternals(this));
440
545
  if (options?.idempotencyKey !== void 0)
441
546
  return startWithIdempotencyFromLifecycle(getInternals(this), type, input, options, this.#createLifecycleCallbacks());
442
547
  return startWorkflowFromLifecycle(getInternals(this), type, input, options, void 0, this.#createLifecycleCallbacks());
443
548
  }
444
549
  async startOrSignal(type, input, signal, options) {
550
+ assertLeaseHeldForEngineWork(getInternals(this));
445
551
  return startOrSignalFromLifecycle(getInternals(this), type, input, signal, options, this.#createStartOrSignalCallbacks());
446
552
  }
447
553
  #createStartOrSignalCallbacks() {
@@ -474,6 +580,9 @@ export class Engine extends EventTarget {
474
580
  async cancelAll(filter, options) {
475
581
  return cancelAllWorkflows(getInternals(this), filter, options);
476
582
  }
583
+ async retryFailedAll(filter, options) {
584
+ return retryFailedAllWorkflows(getInternals(this), filter, options);
585
+ }
477
586
  async signalAll(filter, name, payloadOrOptions, options) {
478
587
  if (options === void 0)
479
588
  return signalAllWorkflows(getInternals(this), filter, name, payloadOrOptions);
@@ -494,7 +603,8 @@ export class Engine extends EventTarget {
494
603
  return scheduleFromInternals(getInternals(this), workflowType, definition.input, definitionSpec, {
495
604
  ...definition.id !== void 0 && { id: definition.id },
496
605
  ...definition.overlapPolicy !== void 0 && { overlap: definition.overlapPolicy },
497
- ...definition.backfill !== void 0 && { backfill: definition.backfill }
606
+ ...definition.backfill !== void 0 && { backfill: definition.backfill },
607
+ ...definition.jitter !== void 0 && { jitter: definition.jitter }
498
608
  });
499
609
  }
500
610
  if (spec === void 0)
@@ -554,20 +664,32 @@ export class Engine extends EventTarget {
554
664
  return getOffloadFromInternals(getInternals(this), workflowId, key);
555
665
  }
556
666
  async fork(sourceWorkflowId, options) {
667
+ assertLeaseHeldForEngineWork(getInternals(this));
557
668
  return forkFromLifecycle(getInternals(this), sourceWorkflowId, options, this.#createLifecycleCallbacks());
558
669
  }
559
670
  async resume(workflowId) {
671
+ assertLeaseHeldForEngineWork(getInternals(this));
560
672
  return resumeFromLifecycle(getInternals(this), workflowId, this.#createLifecycleCallbacks());
561
673
  }
562
674
  async recoverAll(options) {
675
+ await this.#acquireLeaseIfConfigured();
676
+ if (getInternals(this).disposed)
677
+ throw new EngineDisposedError;
563
678
  await recoverPendingAsyncActivities(getInternals(this));
679
+ await recoverOrphanedScheduleTimers(getInternals(this));
564
680
  return recoverAllFromLifecycle(getInternals(this), this.#createLifecycleCallbacks(), options);
565
681
  }
566
682
  async completeAsyncActivity(token, result) {
567
- await completeAsyncActivityFromInternals(getInternals(this), token, result, (workflowId, outcome) => feedOperationResult(getInternals(this), workflowId, outcome), (workflowId, status, output) => finalizePendingTimelineEntry(getInternals(this), workflowId, status, output));
683
+ await completeAsyncActivityFromInternals(getInternals(this), token, result, {
684
+ feedOperationResult: (workflowId, outcome) => feedOperationResult(getInternals(this), workflowId, outcome),
685
+ finalizeTimeline: (workflowId, status, output) => finalizePendingTimelineEntry(getInternals(this), workflowId, status, output)
686
+ });
568
687
  }
569
688
  async failAsyncActivity(token, error) {
570
- await failAsyncActivityFromInternals(getInternals(this), token, error, (workflowId, outcome, originalReason) => feedOperationResult(getInternals(this), workflowId, outcome, originalReason), (workflowId, status, output) => finalizePendingTimelineEntry(getInternals(this), workflowId, status, output));
689
+ await failAsyncActivityFromInternals(getInternals(this), token, error, {
690
+ feedOperationResult: (workflowId, outcome, originalReason) => feedOperationResult(getInternals(this), workflowId, outcome, originalReason),
691
+ finalizeTimeline: (workflowId, status, output) => finalizePendingTimelineEntry(getInternals(this), workflowId, status, output)
692
+ });
571
693
  }
572
694
  async cancel(workflowId) {
573
695
  await cancelWorkflowFromTermination(getInternals(this), workflowId, this.#createTerminationCallbacks());
@@ -647,14 +769,19 @@ export class Engine extends EventTarget {
647
769
  return submitCoordinatedUpdateFromInternals(getInternals(this), workflowId, name, payload, options, this.#createUpdateCallbacks());
648
770
  }
649
771
  [Symbol.dispose]() {
772
+ const leaseManager = getInternals(this).leaseManager;
650
773
  disposeEngine(getInternals(this));
774
+ leaseManager?.release();
651
775
  }
652
776
  async[Symbol.asyncDispose]() {
653
777
  if (!getInternals(this).disposed) {
778
+ const leaseManager = getInternals(this).leaseManager;
654
779
  try {
655
780
  await drainQueuedInlineWorkflowStartsForEngine(this);
656
781
  } finally {
657
- this[Symbol.dispose]();
782
+ disposeEngine(getInternals(this));
783
+ await getInternals(this).inFlightLeaseAcquire?.catch(() => {});
784
+ await leaseManager?.release();
658
785
  }
659
786
  return;
660
787
  }
@@ -1,3 +1,4 @@
1
+ import { hasExposedAccessors, hasUpdateHandlers } from "../context/context-presence.js";
1
2
  import {
2
3
  resumeWorkflowFromStorage as resumeWorkflowFromStorageFromLifecycle
3
4
  } from "./lifecycle.js";
@@ -9,7 +10,7 @@ export async function parkInlineWorkflowAfterCheckpoint(internals, workflowId, o
9
10
  if (operation.type !== "wait-signal" || internals.inlineStrategy === null)
10
11
  return !1;
11
12
  const inlineStrategy = internals.inlineStrategy, context = inlineStrategy.getContext(workflowId);
12
- if (context?.hasUpdateHandlers || context?.hasExposedAccessors)
13
+ if (context && (hasUpdateHandlers(context) || hasExposedAccessors(context)))
13
14
  return !1;
14
15
  if (await callbacks.hasBufferedSignal(workflowId, operation.signalName))
15
16
  return !1;
@@ -17,7 +18,7 @@ export async function parkInlineWorkflowAfterCheckpoint(internals, workflowId, o
17
18
  const latestState = await callbacks.loadWorkflowState(workflowId);
18
19
  if (internals.terminalizingWorkflows.has(workflowId) || !latestState || latestState.status !== "running")
19
20
  return !1;
20
- inlineStrategy.parkWorkflow(workflowId);
21
+ inlineStrategy.parkWorkflow(workflowId, { retainContext: !0 });
21
22
  internals.parkedInlineWorkflows.add(workflowId);
22
23
  return !0;
23
24
  }))
@@ -28,16 +28,19 @@ import type { InlineExecutionStrategy } from '../inline-execution-strategy.ts';
28
28
  import type { ComposedActivityInterceptor, ComposedWorkflowInterceptor, Interceptor } from '../interceptor.ts';
29
29
  import type { HumanReviewResult, ReviewCoordinator } from '../review/index.ts';
30
30
  import type { Scheduler } from '../scheduler.ts';
31
- import type { Checkpoint } from '../types.ts';
31
+ import type { Checkpoint, StartWorkflowOptions } from '../types.ts';
32
32
  import type { UpdateCoordinator } from '../updates.ts';
33
33
  import type { WorkflowVersionTuple } from '../workflow-version-tuple.ts';
34
34
  import type { PendingTimelineEntry, QueuedInlineWorkflowExecutionStart, RegistrationEntry, ResolvedOptions, TrackedWaiterKeys, WorkflowResultWaiter } from './engine-internal-types.ts';
35
35
  import type { EngineCleanupIntervalDisposalTracker } from './engine-leak-warnings.ts';
36
36
  import type { WorkflowHandle, WorkflowHandleEngine } from './handles.ts';
37
37
  import type { WorkflowFeedListener } from './index.ts';
38
+ import type { LeaseManager } from './lease-manager.ts';
38
39
  import type { ScheduleHandleEngine } from './schedule-handle.ts';
39
40
  import type { SecondInstanceDetector } from './second-instance-detector.ts';
40
- type EngineRuntime = WorkflowHandleEngine & ScheduleHandleEngine;
41
+ type EngineRuntime = WorkflowHandleEngine & ScheduleHandleEngine & {
42
+ start(type: string, input: unknown, options?: StartWorkflowOptions): Promise<WorkflowHandle>;
43
+ };
41
44
  export interface EngineInternals {
42
45
  engine: EngineRuntime;
43
46
  storage: WeftStorage;
@@ -67,6 +70,23 @@ export interface EngineInternals {
67
70
  resultResolvers: Map<string, WorkflowResultWaiter>;
68
71
  signalWaiters: Map<string, () => void>;
69
72
  signalWaitersByWorkflow: Map<string, TrackedWaiterKeys>;
73
+ /**
74
+ * In-process resolvers for inline `ctx.waitUntil` waits, keyed by `workflowId`
75
+ * ALONE — a workflow has at most one active wait-condition because its inline
76
+ * generator is suspended at exactly one yield, and the top-level-only guard in
77
+ * `executeSubOperation` rejects `waitUntil` as a `race`/`all`/`speculate`
78
+ * branch. So unlike `signalWaiters` (which need a per-workflow string-or-Set
79
+ * index because they CAN be concurrent sub-operations), this is a flat map with
80
+ * no secondary index. Calling the resolver wakes `processWaitConditionOperation`
81
+ * to re-evaluate its predicate. Never checkpointed — engine-memory state cleared
82
+ * on terminal cleanup.
83
+ *
84
+ * Note: the deadline TIMER is still keyed `cond:${workflowId}:${step}` (step is
85
+ * stable across replay, so recovery does not double-arm). Only this waiter map
86
+ * keys by `workflowId`. If `waitUntil`-in-`race`/`all`/`speculate` is ever
87
+ * supported, this keying must revert to `${workflowId}:${step}` + a Set index.
88
+ */
89
+ conditionWaiters: Map<string, () => void>;
70
90
  updateWaiters: Map<string, (payload: unknown) => void>;
71
91
  updateWaitersByWorkflow: Map<string, TrackedWaiterKeys>;
72
92
  sleepResolvers: Map<string, () => void>;
@@ -110,11 +130,25 @@ export interface EngineInternals {
110
130
  broadcastChannel: BroadcastChannel | null;
111
131
  pendingNestingDepth: number | undefined;
112
132
  pendingParentHeaders: Map<string, string> | undefined;
113
- pendingExecutionStateOwnerId: string | undefined;
133
+ pendingExecutionStateOwnerId: string | null | undefined;
114
134
  workflowNestingDepths: Map<string, number>;
115
135
  workflowHeaders: Map<string, Map<string, string>>;
116
136
  workflowStateWriteChains: Map<string, Promise<void>>;
117
137
  heartbeatDetails: Map<string, unknown>;
138
+ /**
139
+ * Last heartbeat payload PER ACTIVITY STEP, so a retry of a step can read the
140
+ * heartbeat its previous attempt recorded (the resumable-batch pattern). Keyed
141
+ * `workflowId -> step -> details`. This is separate from {@link heartbeatDetails}
142
+ * (which is keyed by `workflowId` alone and powers the `activityProgress` query):
143
+ * concurrent activities inside one `ctx.all` would clobber a workflow-keyed map,
144
+ * so a retry could read a sibling's heartbeat. The step is stable across attempts
145
+ * (assigned once at `stepIndex++`), so a retry reads its OWN prior heartbeat.
146
+ * Never checkpointed — held only in engine memory and cleared (by workflowId, the
147
+ * outer key) on terminal cleanup and purge, the same lifecycle as
148
+ * {@link heartbeatDetails}. Inline-execution only; worker-executed activities run
149
+ * their function out of process and never observe this.
150
+ */
151
+ lastHeartbeatDetailsByStep: Map<string, Map<number, unknown>>;
118
152
  /**
119
153
  * Per-run, non-serialized `services` value exposed to the workflow body as
120
154
  * `ctx.services`. Set at `engine.start({ services })` and re-provided on
@@ -130,6 +164,12 @@ export interface EngineInternals {
130
164
  * reloaded by `recoverAll()`. See `async-activity-completion.ts`.
131
165
  */
132
166
  pendingAsyncActivities: Map<string, import('./async-activity-completion.ts').PendingAsyncActivity>;
167
+ /**
168
+ * Completed or failed async-activity tokens that were consumed before inline
169
+ * recovery adopted the workflow generator. Replay drains these by workflow id
170
+ * when it reaches the same deterministic async-activity token again.
171
+ */
172
+ pendingAsyncActivityResolutions: Map<string, import('./async-activity-completion.ts').PendingAsyncActivityResolution[]>;
133
173
  pendingStarts: Set<string>;
134
174
  pendingScheduleCreations: Set<string>;
135
175
  workflowsNeedingTerminalCleanup: Set<string>;
@@ -142,6 +182,45 @@ export interface EngineInternals {
142
182
  secondInstanceDetectionInterval: ReturnType<typeof setInterval> | null;
143
183
  /** The active second-instance detector; `null` when detection is disabled. */
144
184
  secondInstanceDetector: SecondInstanceDetector | null;
185
+ /**
186
+ * The active lease manager for `ownership: 'lease'`; `null` when ownership is
187
+ * `'none'`. Acquired before recovery, renewed on a heartbeat, released on
188
+ * dispose. Unlike the second-instance detector its acquire/renew errors are real
189
+ * (a failed acquire blocks recovery). Renewal loss is surfaced as a warning in
190
+ * Step 1; epoch fencing of durable writes (Step 2) is what makes it enforceable.
191
+ */
192
+ leaseManager: LeaseManager | null;
193
+ /**
194
+ * The in-flight lease acquisition, or `null` when none is running. Set while
195
+ * `#acquireLeaseIfConfigured` awaits `acquire()` (which can park for the whole
196
+ * `leaseWaitTimeout` waiting for a handoff) and cleared when it settles. Disposal
197
+ * awaits this so a dispose that races a parked acquire is a clean handoff — the
198
+ * holder this engine may take is released before `asyncDispose` resolves, rather
199
+ * than leaking until TTL on an already-disposed engine.
200
+ */
201
+ inFlightLeaseAcquire: Promise<void> | null;
202
+ /**
203
+ * Set to `true` the instant this engine is detected as deposed under
204
+ * `ownership: 'lease'` — either a fenced durable write's CAS failed against a
205
+ * newer epoch ({@link commitFencedEngineWrite}) or the lease manager reported
206
+ * `onLeaseLost('deposed')`. It is the synchronous half of the deposition halt:
207
+ * {@link commitFencedEngineWrite} short-circuits at its top on this flag, so a
208
+ * write that *starts* after detection is rejected before reaching storage,
209
+ * while writes already in flight are caught by the epoch CAS itself. Set once
210
+ * by {@link handleDeposition}, which also warns the operator and schedules a
211
+ * deferred engine teardown. Always `false` under `ownership: 'none'`.
212
+ */
213
+ deposed: boolean;
214
+ /**
215
+ * Teardown callback invoked (deferred to a later tick) when this engine is
216
+ * deposed. Set once during engine construction to the engine's own
217
+ * `disposeAfterDeposition` method. It exists as an injected field rather than a
218
+ * direct import so {@link handleDeposition} (reached from the durable-write
219
+ * helper) does not statically import `disposal.ts`, which would close an import
220
+ * cycle (`storage-io → fenced-write → lease-deposition → disposal → … →
221
+ * storage-io`). `null` until the constructor wires it.
222
+ */
223
+ tearDownAfterDeposition: (() => void) | null;
145
224
  reviewCoordinator: ReviewCoordinator;
146
225
  reviewWaiters: Map<string, (decision: HumanReviewResult) => void>;
147
226
  reviewWaitersByWorkflow: Map<string, TrackedWaiterKeys>;
@@ -152,6 +231,22 @@ export interface EngineInternals {
152
231
  workflowReviewIds: Map<string, Set<string>>;
153
232
  parkedInlineWorkflows: Set<string>;
154
233
  terminalizingWorkflows: Set<string>;
234
+ /**
235
+ * Coordinated update IDs already claimed for delivery by a pending-update
236
+ * drain, keyed by workflow. Several drain triggers (each `update()` schedules a
237
+ * `setTimeout(0)` drain; the post-advance path drains too) can fire
238
+ * near-simultaneously, and the durable consume-delete (`buildResponseOperations`
239
+ * deletes the pending key via async `storage.batch`) lags the in-memory
240
+ * `getPendingUpdates` scan — so overlapping drains would re-read and re-deliver
241
+ * the same buffered update. Each drain claims an update's id SYNCHRONOUSLY (no
242
+ * `await` between the membership check and the add) before delivering it, so a
243
+ * racing drain that scans the same id skips it. The claim persists across
244
+ * drains (unlike a per-drain guard), which is what makes delivery idempotent
245
+ * against the cross-drain race. Cleared per workflow on terminal cleanup; empty
246
+ * after a crash, which matches durable state (recovery re-delivers exactly the
247
+ * updates whose delete never committed).
248
+ */
249
+ deliveredPendingUpdateIds: Map<string, Set<string>>;
155
250
  cancelHandlersByWorkflow: Map<string, Array<() => Promise<void> | void>>;
156
251
  reviewTimerIds: Map<string, string[]>;
157
252
  pendingWebhooks: Set<AbortController>;
@@ -159,7 +254,16 @@ export interface EngineInternals {
159
254
  eventLogHeads: Map<string, Readonly<EventHeadRecord>>;
160
255
  workflowFeedListeners: Map<string, Set<WorkflowFeedListener>>;
161
256
  workflowVersionTuples: Map<string, WorkflowVersionTuple>;
257
+ /**
258
+ * Cached visibility-index watermark for query planning. `undefined` means the
259
+ * watermark has not been read yet or an in-process caller invalidated it.
260
+ * `workflowVisibilityWatermarkExpiresAt` bounds how long external maintenance
261
+ * commands can leave this process planning against a stale watermark.
262
+ */
263
+ workflowVisibilityWatermark: 'current' | 'stale' | undefined;
264
+ workflowVisibilityWatermarkExpiresAt: number | undefined;
162
265
  pendingTimelineEntries: Map<string, PendingTimelineEntry>;
266
+ pendingAtomicWorkflowCommitSideEffects: Map<string, import('./checkpoint-side-effects.ts').AtomicWorkflowCommitSideEffects>;
163
267
  }
164
268
  /**
165
269
  * Set up an empty `EngineInternals` skeleton in the WeakMap. The Engine
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Pure codecs for the two lease ownership keys (`lease:epoch` and `lease:holder`).
3
+ * Extracted from `lease-manager.ts` to keep that file under the `max-lines` ceiling;
4
+ * these functions have no engine state, so they live and test cleanly on their own.
5
+ *
6
+ * @module core/engine/lease-codec
7
+ */
8
+ /** The decoded `lease:holder` record. */
9
+ export type LeaseHolderRecord = {
10
+ holderId: string;
11
+ /** Wall-clock ms (from the engine's `getNow`) after which the lease may be stolen. */
12
+ expiresAt: number;
13
+ /** The ownership epoch this holder acquired. Mirrors `lease:epoch`. */
14
+ epoch: number;
15
+ };
16
+ /**
17
+ * Encode an 8-byte big-endian uint64 epoch. `DataView.setBigUint64` is the
18
+ * standard, overflow-safe encoder — preferred over a hand-rolled byte loop.
19
+ */
20
+ export declare function encodeEpoch(epoch: number): Uint8Array;
21
+ /**
22
+ * Decode an 8-byte big-endian uint64 epoch, or `null` when the stored value is
23
+ * not a usable epoch — not exactly 8 bytes, or outside `[1, MAX_SAFE_INTEGER)`.
24
+ * The epoch is the monotonic fencing high-water mark, so it must stay exactly
25
+ * comparable AND have room to increment: acquisition always mints `epoch + 1`, so
26
+ * `Number.MAX_SAFE_INTEGER` itself is rejected too — minting `2^53` would fail
27
+ * `Number.isSafeInteger` on the next boot and brick the lease. A value at or above
28
+ * the safe-integer ceiling (or below `1`) routes to the corruption path
29
+ * (fail-closed at boot) rather than silently re-minting an imprecise generation.
30
+ */
31
+ export declare function decodeEpoch(raw: Uint8Array): number | null;
32
+ /** Encode a holder record to its stored JSON bytes. */
33
+ export declare function encodeHolder(record: LeaseHolderRecord): Uint8Array;
34
+ /** Decode a stored holder record, tolerating any malformed/foreign value as `null`. */
35
+ export declare function decodeHolder(raw: Uint8Array): LeaseHolderRecord | null;
@@ -0,0 +1,32 @@
1
+ const textEncoder = new TextEncoder, textDecoder = new TextDecoder;
2
+ export function encodeEpoch(epoch) {
3
+ const bytes = new Uint8Array(8);
4
+ new DataView(bytes.buffer).setBigUint64(0, BigInt(epoch), !1);
5
+ return bytes;
6
+ }
7
+ export function decodeEpoch(raw) {
8
+ if (raw.byteLength !== 8)
9
+ return null;
10
+ const value = new DataView(raw.buffer, raw.byteOffset, raw.byteLength).getBigUint64(0, !1), numberValue = Number(value);
11
+ return Number.isSafeInteger(numberValue) && numberValue >= 1 && numberValue < Number.MAX_SAFE_INTEGER ? numberValue : null;
12
+ }
13
+ export function encodeHolder(record) {
14
+ return textEncoder.encode(JSON.stringify(record));
15
+ }
16
+ function isRecord(value) {
17
+ return typeof value === "object" && value !== null;
18
+ }
19
+ export function decodeHolder(raw) {
20
+ let parsed;
21
+ try {
22
+ parsed = JSON.parse(textDecoder.decode(raw));
23
+ } catch {
24
+ return null;
25
+ }
26
+ if (!isRecord(parsed))
27
+ return null;
28
+ const { holderId, expiresAt, epoch } = parsed;
29
+ if (typeof holderId !== "string" || typeof expiresAt !== "number" || !Number.isSafeInteger(expiresAt) || expiresAt < 0 || typeof epoch !== "number" || !Number.isSafeInteger(epoch) || epoch < 1)
30
+ return null;
31
+ return { holderId, expiresAt, epoch };
32
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Deposition handling for `ownership: 'lease'` Step-2 fencing (issue #470).
3
+ *
4
+ * "Deposed" means another instance now holds the ownership lease at a strictly
5
+ * newer epoch, so this instance has lost the store. Deposition is detected at two
6
+ * sites and both funnel here:
7
+ *
8
+ * - A fenced durable write's CAS fails against a newer epoch
9
+ * ({@link commitFencedEngineWrite} re-reads `lease:epoch` to disambiguate).
10
+ * - The lease manager's renewal reports `onLeaseLost('deposed')` (a successor
11
+ * stole the holder out from under an otherwise-idle engine).
12
+ *
13
+ * The renewal-loss reason `'renewal-unconfirmable'` is deliberately NOT routed
14
+ * here: it is a transient storage blip (the holder could not prove it still
15
+ * holds), and halting a healthy holder on a momentary storage hiccup would be a
16
+ * self-inflicted outage. Only a confirmed `'deposed'` triggers the halt.
17
+ *
18
+ * {@link handleDeposition} is idempotent (guarded on {@link EngineInternals.deposed})
19
+ * and does the minimum synchronously — set the flag, warn the operator — then
20
+ * schedules engine teardown on a later tick. Teardown is never run inline:
21
+ * detection happens mid-commit while a workflow generator is advancing, and
22
+ * synchronous {@link disposeEngine} clears maps that the unwinding commit and
23
+ * other in-flight workflows still touch. The flag (plus the
24
+ * {@link commitFencedEngineWrite} top short-circuit) carries the halt guarantee;
25
+ * deferring the actual dispose by a tick is safe because every write in that
26
+ * window is still fenced on the now-stale epoch and loses its CAS.
27
+ *
28
+ * This module is allow-listed for import only from `src/core/engine/**`.
29
+ */
30
+ import type { EngineInternals } from './internals.ts';
31
+ /**
32
+ * The `name` of the `process` warning emitted when an engine configured with
33
+ * `ownership: 'lease'` can no longer be sure it owns the store. The same name
34
+ * covers all three signals, so a single `process.on('warning')` handler catches
35
+ * every "this engine may no longer own the store" event:
36
+ *
37
+ * - **deposed (confirmed)** — a renewal's CAS failed (a successor stole the lease),
38
+ * or a fenced durable write was rejected because a newer epoch holds the store
39
+ * (Step 2). The engine halts.
40
+ * - **renewal-unconfirmable (transient)** — a storage error left the holder unable
41
+ * to prove it still holds within the lease window. This is NOT a confirmed
42
+ * deposition; the engine keeps running, and a later renewal or fenced write
43
+ * resolves the truth. The warning is informational so operators can investigate.
44
+ *
45
+ * Filter on this name to react to ownership-loss signals (alert, drain, restart).
46
+ *
47
+ * @example
48
+ * ```ts
49
+ * import { ENGINE_LEASE_LOST_WARNING_NAME } from '@lostgradient/weft';
50
+ *
51
+ * process.on('warning', (warning) => {
52
+ * if (warning.name === ENGINE_LEASE_LOST_WARNING_NAME) {
53
+ * // This engine may no longer own the store — investigate / drain / restart.
54
+ * }
55
+ * });
56
+ * ```
57
+ */
58
+ export declare const ENGINE_LEASE_LOST_WARNING_NAME = "WeftEngineLeaseLostWarning";
59
+ /**
60
+ * React to a confirmed deposition. Idempotent: the first call sets the deposed
61
+ * flag, emits the operator warning, and schedules a deferred engine teardown;
62
+ * subsequent calls are no-ops. Returns immediately — the caller is expected to
63
+ * then throw {@link EngineDeposedError} to unwind the current commit so it does
64
+ * not advance in-memory state past a durable write that did not land.
65
+ */
66
+ export declare function handleDeposition(internals: EngineInternals): void;
@@ -0,0 +1,10 @@
1
+ export const ENGINE_LEASE_LOST_WARNING_NAME = "WeftEngineLeaseLostWarning";
2
+ export function handleDeposition(internals) {
3
+ if (internals.deposed)
4
+ return;
5
+ internals.deposed = !0;
6
+ process.emitWarning("engine deposed: a durable write was fenced out because another instance now holds this store's ownership lease at a newer epoch. This engine is halting to avoid split-brain writes. Weft supports one engine process per store; ensure your deploy hands off cleanly (graceful shutdown releases the lease) and keep infrastructure-level single-instance enforcement in place.", ENGINE_LEASE_LOST_WARNING_NAME);
7
+ const tearDown = internals.tearDownAfterDeposition;
8
+ if (tearDown !== null)
9
+ Promise.resolve().then(tearDown).catch(() => {});
10
+ }