@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
@@ -25,7 +25,9 @@ export function initializeInternals(context, options, initialSessionState) {
25
25
  executionStateOwnerId: options.executionStateOwnerId ?? options.workflowId,
26
26
  resolveWorkflowType: options.resolveWorkflowType,
27
27
  registerCancelHandler: options.registerCancelHandler,
28
- services: options.services
28
+ services: options.services,
29
+ logSink: options.logSink,
30
+ recordFinalizerState: options.recordFinalizerState
29
31
  };
30
32
  INTERNALS.set(context, internals);
31
33
  }
@@ -35,3 +37,6 @@ export function getInternals(context) {
35
37
  throw Error("Context internals not initialized");
36
38
  return internals;
37
39
  }
40
+ export function hasContextInternals(value) {
41
+ return INTERNALS.has(value);
42
+ }
@@ -58,6 +58,41 @@ export type ContextOperationRequest = {
58
58
  operationId: string;
59
59
  updateName: string;
60
60
  callerStack?: string;
61
+ } | {
62
+ type: 'wait-condition';
63
+ operationId: string;
64
+ /**
65
+ * Deterministic workflow step index for this `ctx.waitUntil` call. Stable
66
+ * across replay (unlike `operationId`, which is regenerated each yield), so
67
+ * it anchors both the deterministic deadline timer key
68
+ * (`cond:${workflowId}:${step}`) and the in-process condition waiter to a
69
+ * fixed step. Re-using a regenerated `operationId` would arm duplicate
70
+ * durable timers on recovery.
71
+ */
72
+ step: number;
73
+ /**
74
+ * The condition predicate. A non-serializable closure (like `memo.fn`) held
75
+ * in-process by the engine processor and re-evaluated on every wake; it is
76
+ * never checkpointed. The workflow re-yields a fresh request after each
77
+ * replay, so the engine always has a live closure to call. Must be pure and
78
+ * read only checkpoint-restored workflow-local state.
79
+ */
80
+ predicate: () => boolean;
81
+ /**
82
+ * Absolute deadline (epoch millis) after which the wait completes with
83
+ * `false`. Anchored once via `readOrInitConditionDeadline` so crash/replay
84
+ * never resets the window. Absent means "wait forever".
85
+ */
86
+ deadline?: number;
87
+ callerStack?: string;
88
+ } | {
89
+ type: 'get-version';
90
+ operationId: string;
91
+ changeId: string;
92
+ minSupported: number;
93
+ maxSupported: number;
94
+ version: number;
95
+ callerStack?: string;
61
96
  } | {
62
97
  type: 'parallel';
63
98
  operationId: string;
@@ -66,6 +66,15 @@ export type ParallelOperationCacheEntry = {
66
66
  * key list for `ctx.runAll`) differs from the cached entry on retry.
67
67
  * Indicates non-deterministic workflow code — branches must be stable
68
68
  * across retries.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * import { BranchTopologyChangedError } from '@lostgradient/weft';
73
+ *
74
+ * function isBranchTopologyChange(error: unknown): boolean {
75
+ * return error instanceof BranchTopologyChangedError;
76
+ * }
77
+ * ```
69
78
  */
70
79
  export declare class BranchTopologyChangedError extends WeftError<'BranchTopologyChangedError'> {
71
80
  constructor(message: string);
@@ -80,11 +89,11 @@ export declare function isParallelOperationCacheEntry(value: unknown): value is
80
89
  * replay behavior.
81
90
  *
82
91
  * NOT an `asserts` predicate: a value without the marker is also a
83
- * valid input here (it just means the cache slot held a non-parallel
84
- * legacy value). Callers still narrow via `isParallelOperationCacheEntry`
85
- * after calling this using `asserts` would over-narrow plain
86
- * non-parallel cached values and mark the legacy fallback paths
87
- * (`return cached as unknown[]`) as dead code in TypeScript.
92
+ * valid input here (it means the cache slot held a plain cached value).
93
+ * Callers still narrow via `isParallelOperationCacheEntry` after calling
94
+ * this. Using `asserts` would over-narrow plain non-parallel cached
95
+ * values and mark the current plain-value return path as dead code in
96
+ * TypeScript.
88
97
  */
89
98
  export declare function assertValidParallelOperationCacheEntry(value: unknown): void;
90
99
  /** Build a fresh v2 cache entry with the given branch slots. */
@@ -1,6 +1,20 @@
1
- import { type RetryPolicy } from '../types.ts';
1
+ import { type Duration, type RetryPolicy, type WorkflowContext } from '../types.ts';
2
+ import { completeActivityRetryAttempt, readActivityRetryAttempt, readCompletedRetrySleepCount } from './activity-retry-state.ts';
2
3
  import type { Context } from './index.ts';
3
4
  import type { ContextOperationRequest } from './operation-request.ts';
5
+ /**
6
+ * Recover the concrete {@link Context} from the public {@link WorkflowContext}
7
+ * the engine passes to a workflow handler. Under the inline execution strategy
8
+ * the engine invokes a handler with the concrete `Context` instance (carrying
9
+ * the `stepIndex`/`accumulatedResults` replay machinery). Worker execution mode
10
+ * instead drives the handler with a minimal `WorkerWorkflowContext`, which has
11
+ * no replay internals — so infrastructure such as `compileStepWorkflow` cannot
12
+ * drive the durable activity machinery there. This probes for the inline
13
+ * internals (via the `hasContextInternals` type guard, which narrows without a
14
+ * cast) and throws an actionable error rather than the cryptic
15
+ * "Context internals not initialized" from a downstream `getInternals` call.
16
+ */
17
+ export declare function asConcreteContext(context: WorkflowContext): Context;
4
18
  type ActivityInput = string | (Function & {
5
19
  retry?: RetryPolicy;
6
20
  });
@@ -14,8 +28,12 @@ interface RunActivityRequest<TResult> {
14
28
  cachedResult?: TResult;
15
29
  retryAttempt: number;
16
30
  retryPolicy?: RetryPolicy;
31
+ scheduleToCloseTimeout?: Duration;
17
32
  }
33
+ export declare const readActivityRetryAttemptForTesting: typeof readActivityRetryAttempt;
34
+ export declare const readCompletedRetrySleepCountForTesting: typeof readCompletedRetrySleepCount;
35
+ export declare const completeActivityRetryAttemptForTesting: typeof completeActivityRetryAttempt;
18
36
  export declare function shouldRetryActivityError(error: unknown, policy: RetryPolicy | undefined, attempt: number): policy is RetryPolicy;
19
- export declare function createRunActivityRequest<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[]): RunActivityRequest<TResult>;
20
- export declare function runActivityWithRetry<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[]): Generator<ContextOperationRequest, TResult, unknown>;
37
+ export declare function createRunActivityRequest<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[], explicitName?: string): RunActivityRequest<TResult>;
38
+ export declare function runActivityWithRetry<TResult>(context: Context, activity: ActivityInput, rest: readonly unknown[], explicitName?: string): Generator<ContextOperationRequest, TResult, unknown>;
21
39
  export {};
@@ -1,9 +1,28 @@
1
1
  import { calculateBackoff } from "../scheduler.js";
2
- import { DEFAULT_RETRY_POLICY } from "../types.js";
3
- import { getInternals } from "./internals.js";
2
+ import {
3
+ DEFAULT_RETRY_POLICY
4
+ } from "../types.js";
5
+ import {
6
+ completeActivityRetryAttempt,
7
+ readActivityRetryAttempt,
8
+ readCompletedRetrySleepCount,
9
+ readOrInitActivityDispatchedAt,
10
+ writeActivityRetryAttempt
11
+ } from "./activity-retry-state.js";
12
+ import {
13
+ assertScheduleToCloseBudgetNotExhausted,
14
+ parseScheduleToCloseBudgetMs,
15
+ resolveActivityScheduleToCloseTimeout,
16
+ resolveActivityTimeout
17
+ } from "./activity-schedule-to-close.js";
18
+ import { getInternals, hasContextInternals } from "./internals.js";
4
19
  import { isActivityCallOptions } from "./session-state.js";
5
20
  import { captureCallerStack } from "./validation.js";
6
- const ACTIVITY_RETRY_STATE_LOCAL_KEY = "__weftActivityRetryState", ACTIVITY_RETRY_STATE_VERSION = 1, MAX_CHECKPOINTED_RETRY_ATTEMPT = 1e4;
21
+ export function asConcreteContext(context) {
22
+ if (!hasContextInternals(context))
23
+ throw Error("Step-based workflows (compileStepWorkflow / ctx.step) require workflowExecutionMode: 'inline'. The worker execution strategy runs workflows with a different context that has no durable step machinery. Use the generator workflow API for worker execution mode.");
24
+ return context;
25
+ }
7
26
  function acceptsNoActivityInput(fn) {
8
27
  if (typeof fn !== "function")
9
28
  return !1;
@@ -22,89 +41,19 @@ function parseRunArguments(activity, rest) {
22
41
  throw Error("ctx.run() accepts one activity input value plus optional ActivityCallOptions.");
23
42
  return { input: values[0], options };
24
43
  }
25
- function isRecord(value) {
26
- return typeof value === "object" && value !== null && !Array.isArray(value);
27
- }
28
- function isActivityRetryState(value) {
29
- return isRecord(value) && value.version === ACTIVITY_RETRY_STATE_VERSION && isRecord(value.attempts) && (value.completedRetrySleeps === void 0 || isRecord(value.completedRetrySleeps));
30
- }
31
- function assertValidRetryAttempt(attempt, step) {
32
- if (!Number.isInteger(attempt) || attempt <= 1 || attempt > MAX_CHECKPOINTED_RETRY_ATTEMPT)
33
- throw Error(`Invalid checkpointed activity retry attempt ${String(attempt)} for step ${String(step)}`);
34
- }
35
- function readActivityRetryAttempt(internals, step) {
36
- const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
37
- if (!isActivityRetryState(state))
38
- return;
39
- const attempt = state.attempts[String(step)];
40
- if (attempt === void 0)
41
- return;
42
- assertValidRetryAttempt(attempt, step);
43
- return attempt;
44
- }
45
- function readCompletedRetrySleepCount(internals, step) {
46
- const state = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
47
- if (!isActivityRetryState(state))
48
- return 0;
49
- const count = state.completedRetrySleeps?.[String(step)];
50
- if (count === void 0)
51
- return 0;
52
- if (!Number.isInteger(count) || count < 0 || count > MAX_CHECKPOINTED_RETRY_ATTEMPT)
53
- throw Error(`Invalid checkpointed activity retry sleep count ${String(count)} for step ${String(step)}`);
54
- return count;
55
- }
56
- function writeActivityRetryAttempt(internals, step, attempt) {
57
- assertValidRetryAttempt(attempt, step);
58
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY], attempts = isActivityRetryState(current) ? { ...current.attempts } : {};
59
- attempts[String(step)] = attempt;
60
- const completedRetrySleeps = isActivityRetryState(current) ? current.completedRetrySleeps : void 0;
61
- internals.checkpointLocals = {
62
- ...internals.checkpointLocals,
63
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
64
- version: ACTIVITY_RETRY_STATE_VERSION,
65
- attempts,
66
- ...completedRetrySleeps === void 0 ? {} : { completedRetrySleeps }
67
- }
68
- };
69
- }
70
- function clearActivityRetryAttempt(internals, step) {
71
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY];
72
- if (!isActivityRetryState(current))
44
+ export const readActivityRetryAttemptForTesting = readActivityRetryAttempt, readCompletedRetrySleepCountForTesting = readCompletedRetrySleepCount, completeActivityRetryAttemptForTesting = completeActivityRetryAttempt;
45
+ function resolveScheduleToCloseBudget(internals, step, scheduleToCloseTimeout) {
46
+ const budgetMs = parseScheduleToCloseBudgetMs(scheduleToCloseTimeout);
47
+ if (budgetMs === void 0)
73
48
  return;
74
- const attempts = { ...current.attempts };
75
- delete attempts[String(step)];
76
- const completedRetrySleeps = current.completedRetrySleeps, { [ACTIVITY_RETRY_STATE_LOCAL_KEY]: _removed, ...remainingLocals } = internals.checkpointLocals;
77
- if (Object.keys(attempts).length === 0 && completedRetrySleeps === void 0) {
78
- internals.checkpointLocals = remainingLocals;
79
- return;
80
- }
81
- internals.checkpointLocals = {
82
- ...remainingLocals,
83
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
84
- version: ACTIVITY_RETRY_STATE_VERSION,
85
- attempts,
86
- ...completedRetrySleeps === void 0 ? {} : { completedRetrySleeps }
87
- }
88
- };
89
- }
90
- function completeActivityRetryAttempt(internals, step, completedRetrySleepCount) {
91
- if (!Number.isInteger(completedRetrySleepCount) || completedRetrySleepCount < 0 || completedRetrySleepCount > MAX_CHECKPOINTED_RETRY_ATTEMPT)
92
- throw Error(`Invalid completed activity retry sleep count ${String(completedRetrySleepCount)} for step ${String(step)}`);
93
- clearActivityRetryAttempt(internals, step);
94
- if (completedRetrySleepCount === 0)
95
- return;
96
- const current = internals.checkpointLocals[ACTIVITY_RETRY_STATE_LOCAL_KEY], attempts = isActivityRetryState(current) ? { ...current.attempts } : {}, completedRetrySleeps = isActivityRetryState(current) ? { ...current.completedRetrySleeps } : {};
97
- completedRetrySleeps[String(step)] = completedRetrySleepCount;
98
- internals.checkpointLocals = {
99
- ...internals.checkpointLocals,
100
- [ACTIVITY_RETRY_STATE_LOCAL_KEY]: {
101
- version: ACTIVITY_RETRY_STATE_VERSION,
102
- attempts,
103
- completedRetrySleeps
104
- }
49
+ return {
50
+ budgetMs,
51
+ dispatchedAt: readOrInitActivityDispatchedAt(internals, step, internals.getNow())
105
52
  };
106
53
  }
107
- function getActivityName(activity) {
54
+ function getActivityName(activity, explicitName) {
55
+ if (explicitName !== void 0)
56
+ return explicitName;
108
57
  return typeof activity === "string" ? activity : activity.name || "anonymous";
109
58
  }
110
59
  function getActivityFunction(activity) {
@@ -190,31 +139,42 @@ function prepareActivityRetryRequest(request, attempt) {
190
139
  attempt
191
140
  };
192
141
  }
193
- export function createRunActivityRequest(context, activity, rest) {
194
- const { input, options } = parseRunArguments(activity, rest), activityName = getActivityName(activity), activityFunction = getActivityFunction(activity), internals = getInternals(context), step = internals.stepIndex++, cachedRequest = getCachedRunActivityRequest(internals, step, activityName, input);
142
+ export function createRunActivityRequest(context, activity, rest, explicitName) {
143
+ const { input, options } = parseRunArguments(activity, rest), activityName = getActivityName(activity, explicitName), activityFunction = getActivityFunction(activity), internals = getInternals(context), step = internals.stepIndex++, cachedRequest = getCachedRunActivityRequest(internals, step, activityName, input);
195
144
  if (cachedRequest.hasCachedResult)
196
145
  return cachedRequest;
197
- const retryPolicy = resolveActivityRetryPolicy(activity, options);
146
+ const retryPolicy = resolveActivityRetryPolicy(activity, options), scheduleToCloseTimeout = resolveActivityScheduleToCloseTimeout(activity, options), effectiveTimeout = resolveActivityTimeout(activity, options), dispatchedOptions = effectiveTimeout === void 0 ? options : { ...options, timeout: effectiveTimeout };
198
147
  return {
199
- request: createFreshRunActivityRequest(internals, step, activityName, activityFunction, input, options),
148
+ request: createFreshRunActivityRequest(internals, step, activityName, activityFunction, input, dispatchedOptions),
200
149
  step,
201
150
  hasCachedResult: !1,
202
151
  retryAttempt: cachedRequest.retryAttempt,
203
- ...retryPolicy === void 0 ? {} : { retryPolicy }
152
+ ...retryPolicy === void 0 ? {} : { retryPolicy },
153
+ ...scheduleToCloseTimeout === void 0 ? {} : { scheduleToCloseTimeout }
204
154
  };
205
155
  }
206
- export function* runActivityWithRetry(context, activity, rest) {
207
- const { request, step, hasCachedResult, cachedResult, retryAttempt, retryPolicy } = createRunActivityRequest(context, activity, rest);
156
+ export function* runActivityWithRetry(context, activity, rest, explicitName) {
157
+ const {
158
+ request,
159
+ step,
160
+ hasCachedResult,
161
+ cachedResult,
162
+ retryAttempt,
163
+ retryPolicy,
164
+ scheduleToCloseTimeout
165
+ } = createRunActivityRequest(context, activity, rest, explicitName);
208
166
  if (hasCachedResult)
209
167
  return cachedResult;
210
- const internals = getInternals(context);
168
+ const internals = getInternals(context), budget = retryPolicy === void 0 ? void 0 : resolveScheduleToCloseBudget(internals, step, scheduleToCloseTimeout);
211
169
  let attempt = retryAttempt;
212
170
  if (attempt > 1) {
213
171
  if (retryPolicy === void 0)
214
172
  throw Error(`Missing activity retry policy for checkpointed retry attempt ${attempt}`);
215
173
  yield* context.sleep(calculateBackoff(attempt - 1, retryPolicy));
216
174
  }
217
- while (!0)
175
+ while (!0) {
176
+ if (attempt > 1)
177
+ assertScheduleToCloseBudgetNotExhausted(budget, request.activityName, internals.getNow());
218
178
  try {
219
179
  const result = yield prepareActivityRetryRequest(request, attempt);
220
180
  context.accumulatedResults.set(step, result);
@@ -223,9 +183,12 @@ export function* runActivityWithRetry(context, activity, rest) {
223
183
  } catch (error) {
224
184
  if (!shouldRetryActivityError(error, retryPolicy, attempt))
225
185
  throw error;
186
+ const backoff = calculateBackoff(attempt, retryPolicy), now = internals.getNow();
187
+ assertScheduleToCloseBudgetNotExhausted(budget, request.activityName, now, now + backoff);
226
188
  const nextAttempt = attempt + 1;
227
189
  writeActivityRetryAttempt(internals, step, nextAttempt);
228
- yield* context.sleep(calculateBackoff(attempt, retryPolicy));
190
+ yield* context.sleep(backoff);
229
191
  attempt = nextAttempt;
230
192
  }
193
+ }
231
194
  }
@@ -4,23 +4,24 @@ import {
4
4
  cloneSessionStateValue,
5
5
  createSessionStateStore,
6
6
  hasSessionStateKey,
7
- LEGACY_SESSION_STATE_LOCAL_KEY,
8
7
  SESSION_STATE_LOCAL_KEY,
9
8
  validateSessionStateStore
10
9
  } from "../session-state.js";
11
- const EMPTY_CHECKPOINT_LOCALS = Object.freeze({}), ACTIVITY_CALL_OPTION_KEYS = new Set([
10
+ const EMPTY_CHECKPOINT_LOCALS = Object.freeze({}), RETIRED_SESSION_STATE_LOCAL_KEY = "sessionState", ACTIVITY_CALL_OPTION_KEYS = new Set([
12
11
  "timeout",
13
12
  "queue",
14
13
  "retry",
15
14
  "idempotencyKey",
16
15
  "sticky",
17
- "visibilityTimeout"
16
+ "visibilityTimeout",
17
+ "scheduleToCloseTimeout"
18
18
  ]), DISCRIMINATOR_KEYS = new Set([
19
19
  "queue",
20
20
  "retry",
21
21
  "idempotencyKey",
22
22
  "sticky",
23
- "visibilityTimeout"
23
+ "visibilityTimeout",
24
+ "scheduleToCloseTimeout"
24
25
  ]);
25
26
  export function isActivityCallOptions(value) {
26
27
  if (value === null || typeof value !== "object" || Array.isArray(value))
@@ -37,7 +38,7 @@ export function isActivityCallOptions(value) {
37
38
  return !1;
38
39
  }
39
40
  export function createCheckpointLocals(stateSessionStore, existingLocals) {
40
- const localEntries = existingLocals === void 0 ? [] : Object.entries(existingLocals).filter(([key]) => key !== SESSION_STATE_LOCAL_KEY && key !== LEGACY_SESSION_STATE_LOCAL_KEY);
41
+ const localEntries = existingLocals === void 0 ? [] : Object.entries(existingLocals).filter(([key]) => key !== SESSION_STATE_LOCAL_KEY && key !== RETIRED_SESSION_STATE_LOCAL_KEY);
41
42
  if (stateSessionStore === void 0) {
42
43
  if (localEntries.length === 0)
43
44
  return EMPTY_CHECKPOINT_LOCALS;
@@ -73,9 +74,7 @@ export function clearSessionStateValue(internals, key) {
73
74
  assertValidSessionStateKey(key);
74
75
  if (!internals.stateSession || !hasSessionStateKey(internals.stateSession, key))
75
76
  return;
76
- const candidate = cloneSessionStateStore(internals.stateSession);
77
- if (!candidate)
78
- return;
77
+ const candidate = cloneSessionStateStore(internals.stateSession) ?? createSessionStateStore();
79
78
  delete candidate[key];
80
79
  commitSessionStateStore(internals, Object.keys(candidate).length === 0 ? void 0 : candidate);
81
80
  }
@@ -18,6 +18,8 @@ function assignOptionalContextOptions(options, internals) {
18
18
  options.resolveWorkflowType = internals.resolveWorkflowType;
19
19
  if (internals.services !== void 0)
20
20
  options.services = internals.services;
21
+ if (internals.logSink !== void 0)
22
+ options.logSink = internals.logSink;
21
23
  }
22
24
  function createSpeculativeChildOptions(parent, internals) {
23
25
  const options = {
@@ -1,4 +1,5 @@
1
1
  import type { ActivityDefinition, SearchAttributeSchema, SearchAttributeValue } from '../types.ts';
2
+ import type { WorkflowLogRecord } from '../types/workflow-log.ts';
2
3
  /**
3
4
  * A single step in a saga: an activity definition and the input to pass to it.
4
5
  *
@@ -184,4 +185,18 @@ export interface ContextOptions {
184
185
  * engine's `resolveWorkflowServices` resolver.
185
186
  */
186
187
  services?: unknown;
188
+ /**
189
+ * Host sink for `ctx.log` records (`EngineOptions.onLog`). When set, non-replayed
190
+ * records route here instead of the console; when absent, the default console
191
+ * behavior is preserved. Never checkpointed.
192
+ */
193
+ logSink?: (record: WorkflowLogRecord) => void;
194
+ /**
195
+ * Called by `ctx.setFinalizerState(value)` (#446) to durably record the payload
196
+ * the engine passes to the workflow's `finalizer` activity on cancel/timeout
197
+ * teardown. The engine stages it as a pending atomic side-effect so it commits
198
+ * with the next checkpoint or the terminal batch. Absent for worker-mode and
199
+ * speculative contexts, where `ctx.setFinalizerState` is unsupported.
200
+ */
201
+ recordFinalizerState?: (value: unknown) => void;
187
202
  }
@@ -0,0 +1,8 @@
1
+ export declare const WORKFLOW_VERSION_LOCAL_PREFIX = "version:";
2
+ export type WorkflowVersionPatchResolution = {
3
+ localKey: string;
4
+ version: number;
5
+ newlyPinned: boolean;
6
+ checkpointLocals: Record<string, unknown>;
7
+ };
8
+ export declare function resolveWorkflowVersionPatch(checkpointLocals: Record<string, unknown>, changeId: string, minSupported: number, maxSupported: number): WorkflowVersionPatchResolution;
@@ -0,0 +1,40 @@
1
+ export const WORKFLOW_VERSION_LOCAL_PREFIX = "version:";
2
+ export function resolveWorkflowVersionPatch(checkpointLocals, changeId, minSupported, maxSupported) {
3
+ validateWorkflowVersionPatchArguments(changeId, minSupported, maxSupported);
4
+ const localKey = `${WORKFLOW_VERSION_LOCAL_PREFIX}${changeId}`, existing = checkpointLocals[localKey];
5
+ if (existing === void 0)
6
+ return {
7
+ localKey,
8
+ version: maxSupported,
9
+ newlyPinned: !0,
10
+ checkpointLocals: { ...checkpointLocals, [localKey]: maxSupported }
11
+ };
12
+ if (typeof existing !== "number" || !Number.isSafeInteger(existing))
13
+ throw Error(`Invalid checkpointed workflow version patch "${changeId}" value ${JSON.stringify(existing)}`);
14
+ const version = existing;
15
+ assertPinnedVersionSupported(changeId, version, minSupported, maxSupported);
16
+ return {
17
+ localKey,
18
+ version,
19
+ newlyPinned: !1,
20
+ checkpointLocals
21
+ };
22
+ }
23
+ function validateWorkflowVersionPatchArguments(changeId, minSupported, maxSupported) {
24
+ if (typeof changeId !== "string" || changeId.length === 0)
25
+ throw Error("ctx.getVersion() requires a non-empty changeId");
26
+ assertVersionBoundary("minSupported", minSupported);
27
+ assertVersionBoundary("maxSupported", maxSupported);
28
+ if (minSupported > maxSupported)
29
+ throw Error("ctx.getVersion() minSupported must be less than or equal to maxSupported");
30
+ }
31
+ function assertVersionBoundary(name, value) {
32
+ if (!Number.isSafeInteger(value))
33
+ throw Error(`ctx.getVersion() ${name} must be a safe integer`);
34
+ }
35
+ function assertPinnedVersionSupported(changeId, version, minSupported, maxSupported) {
36
+ if (version < minSupported)
37
+ throw Error(`Workflow version patch "${changeId}" is pinned to version ${version}, below the minimum supported version ${minSupported}`);
38
+ if (version > maxSupported)
39
+ throw Error(`Workflow version patch "${changeId}" is pinned to version ${version}, above the maximum supported version ${maxSupported}`);
40
+ }
@@ -0,0 +1,98 @@
1
+ import type { WorkflowLogger, WorkflowLogRecord } from '../types/workflow-log.ts';
2
+ import type { ContextInternals } from './internals.ts';
3
+ /**
4
+ * Dispatch one record to the matching `console` method (`debug`/`info`/`warn`/`error`).
5
+ * The single console-fallback primitive: the logger factory uses it when no sink is
6
+ * installed or a sink throws, and the worker-log host-delivery path (#529) uses it when
7
+ * the host `onLog` sink throws — so console-fallback behavior cannot drift between the
8
+ * inline and worker-forwarded paths.
9
+ */
10
+ export declare function logRecordToConsole(record: WorkflowLogRecord): void;
11
+ /**
12
+ * Inputs the logger needs at construction. The replay/clock probes (`isReplaying`,
13
+ * `now`) are evaluated fresh per emit so they track the live frontier; the identity
14
+ * fields (`workflowId`, `workflowType`) and the `sink` are fixed values.
15
+ */
16
+ export interface WorkflowLoggerBindings {
17
+ readonly workflowId: string;
18
+ readonly workflowType: string;
19
+ /**
20
+ * Whether the current execution position is a replay of an already-committed
21
+ * step. Evaluated lazily at each emit call so it reflects the live frontier.
22
+ */
23
+ isReplaying(): boolean;
24
+ /** Wall-clock millisecond timestamp for the record (never checkpointed). */
25
+ now(): number;
26
+ /**
27
+ * Optional host sink (`EngineOptions.onLog`). When provided, each non-replayed
28
+ * record is routed here INSTEAD of the console — the host owns where logs go
29
+ * (pino / winston / OpenTelemetry / etc.). When absent, records fall back to the
30
+ * matching `console` method, preserving the default behavior. `onLog` is fixed at
31
+ * engine construction (it has no public setter), so this is a captured value, not
32
+ * a per-emit resolver.
33
+ */
34
+ readonly sink?: (record: WorkflowLogRecord) => void;
35
+ }
36
+ /**
37
+ * Create a {@link WorkflowLogger} from the given bindings. Each method suppresses
38
+ * emission when `bindings.isReplaying()` is true (so a recovered run does not
39
+ * re-emit logs from the replayed prefix). A non-replayed record is routed to the
40
+ * host sink (`bindings.sink`) when one is installed, and otherwise to the matching
41
+ * `console` method — so a host that wires `EngineOptions.onLog` takes full control
42
+ * of log routing without duplicate console noise, while the default stays console.
43
+ *
44
+ * A logger must never be able to crash the thing it is logging: if the host sink
45
+ * throws (a serialization error, a transport failure, a bug in the callback — all
46
+ * realistic for the pino / winston / OpenTelemetry integrations this targets), the
47
+ * throw is swallowed and the record falls back to `console` so the workflow run is
48
+ * not marked failed by a logging error.
49
+ */
50
+ export declare function createWorkflowLogger(bindings: WorkflowLoggerBindings): WorkflowLogger;
51
+ /**
52
+ * Build the inline `ctx.log` logger for a {@link Context}. The replay probe reads
53
+ * the RAW nullable `internals.accumulatedResults` field (not the allocating
54
+ * `ctx.accumulatedResults` getter) and the live `internals.stepIndex` without
55
+ * incrementing it — `ctx.log` consumes no durable position, the same step-neutral
56
+ * peek `waitForSignal` makes. `getInternals` is read per emit so the probe tracks
57
+ * the frontier as durable ops advance `stepIndex`. The `sink` is captured by value:
58
+ * `EngineOptions.onLog` is fixed at engine construction, so it never changes for the
59
+ * life of the context.
60
+ */
61
+ export declare function createInlineWorkflowLogger(workflowId: string, workflowType: string, getInternals: () => Pick<ContextInternals, 'accumulatedResults' | 'stepIndex' | 'getNow'>, sink?: (record: WorkflowLogRecord) => void): WorkflowLogger;
62
+ /**
63
+ * The slice of worker replay state the worker logger's replay probe reads. A step
64
+ * being replayed is cached in `accumulatedResults` (it succeeded) OR in
65
+ * `failedOutcomes` (it failed and the failure is replayed) — the logger must check
66
+ * both, mirroring the runner's own `hasCachedWorkerOutcome`, or a log at a
67
+ * replayed *failure* position would re-emit on recovery.
68
+ */
69
+ export interface WorkerLoggerReplayState {
70
+ readonly accumulatedResults: ReadonlyMap<number, unknown>;
71
+ readonly failedOutcomes: ReadonlyMap<number, unknown>;
72
+ readonly nextStepIndex: number;
73
+ }
74
+ /**
75
+ * Build the worker-side `ctx.log` logger. Mirrors {@link createInlineWorkflowLogger}
76
+ * through the shared factory; only the replay probe differs. `nextStepIndex` points
77
+ * at the step the worker generator is about to run, so a cached outcome at that
78
+ * index (success in `accumulatedResults` or failure in `failedOutcomes`) means the
79
+ * step is replaying and its preceding log is suppressed; an uncached index is the
80
+ * live frontier — the same per-position check the inline path makes (and the same
81
+ * union the runner's own replay short-circuit uses). The state is read through
82
+ * `getReplayState` (not captured by value) because the worker registers its replay
83
+ * state *after* the context is built, so the closure must observe the live state at
84
+ * emit time. Worker records use wall-clock `Date.now()` (the worker has no engine
85
+ * clock); the timestamp is observability metadata only, never checkpointed.
86
+ *
87
+ * When the engine host installs an `EngineOptions.onLog` sink, the run/resume message
88
+ * reports `hostHasLogSink: true` and the worker supplies a `forwardToHost` callback
89
+ * here (#529): each non-replayed record is posted back to the host as a `log`
90
+ * protocol message INSTEAD of the worker console, mirroring the inline sink. The
91
+ * callback runs through the shared factory's `sink` slot, so its existing
92
+ * throw-then-console fallback applies — if forwarding is impossible (an oversized or
93
+ * non-cloneable record makes `postMessage` throw), the record falls back to the
94
+ * worker console rather than failing the run. When no host sink exists, `forwardToHost`
95
+ * is omitted and the worker logs to its own console, preserving the default and never
96
+ * losing a log to a no-op host callback.
97
+ */
98
+ export declare function createWorkerWorkflowLogger(workflowId: string, workflowType: string, getReplayState: () => WorkerLoggerReplayState | undefined, forwardToHost?: (record: WorkflowLogRecord) => void): WorkflowLogger;
@@ -0,0 +1,68 @@
1
+ const CONSOLE_METHOD = {
2
+ debug: "debug",
3
+ info: "info",
4
+ warn: "warn",
5
+ error: "error"
6
+ };
7
+ export function logRecordToConsole(record) {
8
+ console[CONSOLE_METHOD[record.level]](record);
9
+ }
10
+ function buildLogRecord(bindings, level, message, attributes) {
11
+ return {
12
+ level,
13
+ message,
14
+ workflowId: bindings.workflowId,
15
+ workflowType: bindings.workflowType,
16
+ timestamp: bindings.now(),
17
+ ...attributes !== void 0 && { attributes }
18
+ };
19
+ }
20
+ export function createWorkflowLogger(bindings) {
21
+ const emit = (level, message, attributes) => {
22
+ if (bindings.isReplaying())
23
+ return;
24
+ const record = buildLogRecord(bindings, level, message, attributes);
25
+ if (bindings.sink !== void 0) {
26
+ try {
27
+ bindings.sink(record);
28
+ } catch {
29
+ logRecordToConsole(record);
30
+ }
31
+ return;
32
+ }
33
+ logRecordToConsole(record);
34
+ };
35
+ return {
36
+ debug: (message, attributes) => emit("debug", message, attributes),
37
+ info: (message, attributes) => emit("info", message, attributes),
38
+ warn: (message, attributes) => emit("warn", message, attributes),
39
+ error: (message, attributes) => emit("error", message, attributes)
40
+ };
41
+ }
42
+ export function createInlineWorkflowLogger(workflowId, workflowType, getInternals, sink) {
43
+ return createWorkflowLogger({
44
+ workflowId,
45
+ workflowType,
46
+ isReplaying: () => {
47
+ const internals = getInternals();
48
+ return internals.accumulatedResults?.has(internals.stepIndex) ?? !1;
49
+ },
50
+ now: () => getInternals().getNow(),
51
+ ...sink !== void 0 && { sink }
52
+ });
53
+ }
54
+ export function createWorkerWorkflowLogger(workflowId, workflowType, getReplayState, forwardToHost) {
55
+ return createWorkflowLogger({
56
+ workflowId,
57
+ workflowType,
58
+ isReplaying: () => {
59
+ const replayState = getReplayState();
60
+ if (replayState === void 0)
61
+ return !1;
62
+ const step = replayState.nextStepIndex;
63
+ return replayState.accumulatedResults.has(step) || replayState.failedOutcomes.has(step);
64
+ },
65
+ now: () => Date.now(),
66
+ ...forwardToHost !== void 0 && { sink: forwardToHost }
67
+ });
68
+ }