@adonis-agora/durable 0.49.0 → 0.50.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 (324) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/README.md +53 -22
  3. package/dist/assets/spa/assets/index-DupjrK7N.js +16 -0
  4. package/dist/assets/spa/assets/index-DupjrK7N.js.map +1 -0
  5. package/dist/assets/spa/index.html +1 -1
  6. package/dist/commands/durable_worker.d.ts.map +1 -1
  7. package/dist/commands/durable_worker.js +9 -8
  8. package/dist/commands/durable_worker.js.map +1 -1
  9. package/dist/configure.d.ts.map +1 -1
  10. package/dist/configure.js +1 -0
  11. package/dist/configure.js.map +1 -1
  12. package/dist/providers/dashboard_provider.d.ts +2 -0
  13. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  14. package/dist/providers/dashboard_provider.js +50 -6
  15. package/dist/providers/dashboard_provider.js.map +1 -1
  16. package/dist/providers/durable_provider.d.ts.map +1 -1
  17. package/dist/providers/durable_provider.js +143 -34
  18. package/dist/providers/durable_provider.js.map +1 -1
  19. package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -1
  20. package/dist/src/admission-redis/redis-admission-backend.js +3 -1
  21. package/dist/src/admission-redis/redis-admission-backend.js.map +1 -1
  22. package/dist/src/ambient-step.d.ts +24 -0
  23. package/dist/src/ambient-step.d.ts.map +1 -0
  24. package/dist/src/ambient-step.js +42 -0
  25. package/dist/src/ambient-step.js.map +1 -0
  26. package/dist/src/base-workflow.d.ts +10 -1
  27. package/dist/src/base-workflow.d.ts.map +1 -1
  28. package/dist/src/base-workflow.js.map +1 -1
  29. package/dist/src/codec-state-store.d.ts +28 -2
  30. package/dist/src/codec-state-store.d.ts.map +1 -1
  31. package/dist/src/codec-state-store.js +61 -3
  32. package/dist/src/codec-state-store.js.map +1 -1
  33. package/dist/src/commands/worker.d.ts +4 -1
  34. package/dist/src/commands/worker.d.ts.map +1 -1
  35. package/dist/src/commands/worker.js +27 -3
  36. package/dist/src/commands/worker.js.map +1 -1
  37. package/dist/src/config_types.d.ts +6 -0
  38. package/dist/src/config_types.d.ts.map +1 -1
  39. package/dist/src/control-plane-redis/redis-control-plane.d.ts.map +1 -1
  40. package/dist/src/control-plane-redis/redis-control-plane.js +22 -6
  41. package/dist/src/control-plane-redis/redis-control-plane.js.map +1 -1
  42. package/dist/src/control-planes/factory.d.ts +6 -0
  43. package/dist/src/control-planes/factory.d.ts.map +1 -1
  44. package/dist/src/control-planes/factory.js +1 -0
  45. package/dist/src/control-planes/factory.js.map +1 -1
  46. package/dist/src/dashboard/gateway-adapter.d.ts +15 -5
  47. package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
  48. package/dist/src/dashboard/gateway-adapter.js +71 -7
  49. package/dist/src/dashboard/gateway-adapter.js.map +1 -1
  50. package/dist/src/dashboard/handlers.d.ts +53 -1
  51. package/dist/src/dashboard/handlers.d.ts.map +1 -1
  52. package/dist/src/dashboard/handlers.js +200 -20
  53. package/dist/src/dashboard/handlers.js.map +1 -1
  54. package/dist/src/dashboard/index.d.ts +2 -2
  55. package/dist/src/dashboard/index.d.ts.map +1 -1
  56. package/dist/src/dashboard/index.js +2 -2
  57. package/dist/src/dashboard/index.js.map +1 -1
  58. package/dist/src/dashboard/openapi.d.ts.map +1 -1
  59. package/dist/src/dashboard/openapi.js +71 -1
  60. package/dist/src/dashboard/openapi.js.map +1 -1
  61. package/dist/src/define_config.d.ts +122 -8
  62. package/dist/src/define_config.d.ts.map +1 -1
  63. package/dist/src/define_config.js.map +1 -1
  64. package/dist/src/diagnostics-bridge.d.ts +16 -3
  65. package/dist/src/diagnostics-bridge.d.ts.map +1 -1
  66. package/dist/src/diagnostics-bridge.js +9 -3
  67. package/dist/src/diagnostics-bridge.js.map +1 -1
  68. package/dist/src/discovery-roots.d.ts +92 -0
  69. package/dist/src/discovery-roots.d.ts.map +1 -0
  70. package/dist/src/discovery-roots.js +150 -0
  71. package/dist/src/discovery-roots.js.map +1 -0
  72. package/dist/src/engine.d.ts +418 -20
  73. package/dist/src/engine.d.ts.map +1 -1
  74. package/dist/src/engine.js +1523 -159
  75. package/dist/src/engine.js.map +1 -1
  76. package/dist/src/entities.d.ts +36 -1
  77. package/dist/src/entities.d.ts.map +1 -1
  78. package/dist/src/entities.js +65 -4
  79. package/dist/src/entities.js.map +1 -1
  80. package/dist/src/errors.d.ts +36 -0
  81. package/dist/src/errors.d.ts.map +1 -1
  82. package/dist/src/errors.js +44 -0
  83. package/dist/src/errors.js.map +1 -1
  84. package/dist/src/event-trigger-bridge.d.ts +8 -0
  85. package/dist/src/event-trigger-bridge.d.ts.map +1 -1
  86. package/dist/src/event-trigger-bridge.js +24 -3
  87. package/dist/src/event-trigger-bridge.js.map +1 -1
  88. package/dist/src/handshake/announced.d.ts +27 -0
  89. package/dist/src/handshake/announced.d.ts.map +1 -1
  90. package/dist/src/handshake/announced.js +62 -0
  91. package/dist/src/handshake/announced.js.map +1 -1
  92. package/dist/src/handshake/directory.d.ts +92 -0
  93. package/dist/src/handshake/directory.d.ts.map +1 -0
  94. package/dist/src/handshake/directory.js +139 -0
  95. package/dist/src/handshake/directory.js.map +1 -0
  96. package/dist/src/hooks/barrel-sources.d.ts +28 -0
  97. package/dist/src/hooks/barrel-sources.d.ts.map +1 -0
  98. package/dist/src/hooks/barrel-sources.js +92 -0
  99. package/dist/src/hooks/barrel-sources.js.map +1 -0
  100. package/dist/src/hooks/steps.d.ts +12 -3
  101. package/dist/src/hooks/steps.d.ts.map +1 -1
  102. package/dist/src/hooks/steps.js +7 -11
  103. package/dist/src/hooks/steps.js.map +1 -1
  104. package/dist/src/hooks/workflows.d.ts +12 -3
  105. package/dist/src/hooks/workflows.d.ts.map +1 -1
  106. package/dist/src/hooks/workflows.js +7 -13
  107. package/dist/src/hooks/workflows.js.map +1 -1
  108. package/dist/src/index.d.ts +12 -3
  109. package/dist/src/index.d.ts.map +1 -1
  110. package/dist/src/index.js +12 -3
  111. package/dist/src/index.js.map +1 -1
  112. package/dist/src/interfaces.d.ts +309 -21
  113. package/dist/src/interfaces.d.ts.map +1 -1
  114. package/dist/src/interfaces.js +10 -0
  115. package/dist/src/interfaces.js.map +1 -1
  116. package/dist/src/metrics.d.ts.map +1 -1
  117. package/dist/src/metrics.js +5 -0
  118. package/dist/src/metrics.js.map +1 -1
  119. package/dist/src/namespaces.d.ts +17 -0
  120. package/dist/src/namespaces.d.ts.map +1 -0
  121. package/dist/src/namespaces.js +24 -0
  122. package/dist/src/namespaces.js.map +1 -0
  123. package/dist/src/otel/durable-metrics.d.ts.map +1 -1
  124. package/dist/src/otel/durable-metrics.js +5 -0
  125. package/dist/src/otel/durable-metrics.js.map +1 -1
  126. package/dist/src/otel/durable-otel.d.ts.map +1 -1
  127. package/dist/src/otel/durable-otel.js +5 -0
  128. package/dist/src/otel/durable-otel.js.map +1 -1
  129. package/dist/src/pollers.d.ts +10 -1
  130. package/dist/src/pollers.d.ts.map +1 -1
  131. package/dist/src/pollers.js +15 -5
  132. package/dist/src/pollers.js.map +1 -1
  133. package/dist/src/protocol.d.ts +12 -0
  134. package/dist/src/protocol.d.ts.map +1 -1
  135. package/dist/src/protocol.js +27 -1
  136. package/dist/src/protocol.js.map +1 -1
  137. package/dist/src/remote-event.d.ts +6 -0
  138. package/dist/src/remote-event.d.ts.map +1 -0
  139. package/dist/src/remote-event.js +19 -0
  140. package/dist/src/remote-event.js.map +1 -0
  141. package/dist/src/remote-workflow-executor.d.ts +34 -12
  142. package/dist/src/remote-workflow-executor.d.ts.map +1 -1
  143. package/dist/src/remote-workflow-executor.js +42 -40
  144. package/dist/src/remote-workflow-executor.js.map +1 -1
  145. package/dist/src/run-detail-summary.d.ts +90 -3
  146. package/dist/src/run-detail-summary.d.ts.map +1 -1
  147. package/dist/src/run-detail-summary.js +360 -2
  148. package/dist/src/run-detail-summary.js.map +1 -1
  149. package/dist/src/run-facets.d.ts +48 -0
  150. package/dist/src/run-facets.d.ts.map +1 -0
  151. package/dist/src/run-facets.js +100 -0
  152. package/dist/src/run-facets.js.map +1 -0
  153. package/dist/src/run-gateway/interface.d.ts +27 -1
  154. package/dist/src/run-gateway/interface.d.ts.map +1 -1
  155. package/dist/src/run-gateway/proxy-run-gateway.d.ts +32 -4
  156. package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -1
  157. package/dist/src/run-gateway/proxy-run-gateway.js +101 -5
  158. package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -1
  159. package/dist/src/run-gateway/run-request-responder.d.ts +18 -5
  160. package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -1
  161. package/dist/src/run-gateway/run-request-responder.js +155 -32
  162. package/dist/src/run-gateway/run-request-responder.js.map +1 -1
  163. package/dist/src/run-gateway/store-run-gateway.d.ts +23 -1
  164. package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -1
  165. package/dist/src/run-gateway/store-run-gateway.js +38 -0
  166. package/dist/src/run-gateway/store-run-gateway.js.map +1 -1
  167. package/dist/src/search-attributes-schema.d.ts +44 -0
  168. package/dist/src/search-attributes-schema.d.ts.map +1 -0
  169. package/dist/src/search-attributes-schema.js +51 -0
  170. package/dist/src/search-attributes-schema.js.map +1 -0
  171. package/dist/src/singleton-admission.d.ts +75 -0
  172. package/dist/src/singleton-admission.d.ts.map +1 -0
  173. package/dist/src/singleton-admission.js +156 -0
  174. package/dist/src/singleton-admission.js.map +1 -0
  175. package/dist/src/singleton-gate.d.ts +23 -8
  176. package/dist/src/singleton-gate.d.ts.map +1 -1
  177. package/dist/src/singleton-gate.js +59 -12
  178. package/dist/src/singleton-gate.js.map +1 -1
  179. package/dist/src/standard-schema.d.ts +83 -0
  180. package/dist/src/standard-schema.d.ts.map +1 -0
  181. package/dist/src/standard-schema.js +31 -0
  182. package/dist/src/standard-schema.js.map +1 -0
  183. package/dist/src/step-discovery.d.ts +21 -11
  184. package/dist/src/step-discovery.d.ts.map +1 -1
  185. package/dist/src/step-discovery.js +86 -45
  186. package/dist/src/step-discovery.js.map +1 -1
  187. package/dist/src/step-ref.d.ts +38 -12
  188. package/dist/src/step-ref.d.ts.map +1 -1
  189. package/dist/src/step-ref.js +5 -13
  190. package/dist/src/step-ref.js.map +1 -1
  191. package/dist/src/stores/factory.d.ts +6 -0
  192. package/dist/src/stores/factory.d.ts.map +1 -1
  193. package/dist/src/stores/factory.js +4 -1
  194. package/dist/src/stores/factory.js.map +1 -1
  195. package/dist/src/stores/lucid-helpers.d.ts +2 -0
  196. package/dist/src/stores/lucid-helpers.d.ts.map +1 -1
  197. package/dist/src/stores/lucid-helpers.js +7 -0
  198. package/dist/src/stores/lucid-helpers.js.map +1 -1
  199. package/dist/src/stores/lucid-mappers.d.ts +25 -0
  200. package/dist/src/stores/lucid-mappers.d.ts.map +1 -1
  201. package/dist/src/stores/lucid-mappers.js +81 -18
  202. package/dist/src/stores/lucid-mappers.js.map +1 -1
  203. package/dist/src/stores/lucid-schema.d.ts +59 -1
  204. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  205. package/dist/src/stores/lucid-schema.js +271 -25
  206. package/dist/src/stores/lucid-schema.js.map +1 -1
  207. package/dist/src/stores/lucid.d.ts +61 -2
  208. package/dist/src/stores/lucid.d.ts.map +1 -1
  209. package/dist/src/stores/lucid.js +346 -41
  210. package/dist/src/stores/lucid.js.map +1 -1
  211. package/dist/src/telescope/dashboard.d.ts.map +1 -1
  212. package/dist/src/telescope/dashboard.js +30 -1
  213. package/dist/src/telescope/dashboard.js.map +1 -1
  214. package/dist/src/telescope/data-providers.d.ts +19 -1
  215. package/dist/src/telescope/data-providers.d.ts.map +1 -1
  216. package/dist/src/telescope/data-providers.js +119 -3
  217. package/dist/src/telescope/data-providers.js.map +1 -1
  218. package/dist/src/telescope/extension.d.ts.map +1 -1
  219. package/dist/src/telescope/extension.js +2 -1
  220. package/dist/src/telescope/extension.js.map +1 -1
  221. package/dist/src/telescope/index.d.ts +1 -1
  222. package/dist/src/telescope/index.d.ts.map +1 -1
  223. package/dist/src/telescope/index.js +1 -1
  224. package/dist/src/telescope/index.js.map +1 -1
  225. package/dist/src/testing/in-memory-state-store.d.ts +44 -15
  226. package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
  227. package/dist/src/testing/in-memory-state-store.js +204 -41
  228. package/dist/src/testing/in-memory-state-store.js.map +1 -1
  229. package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts +16 -0
  230. package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts.map +1 -0
  231. package/dist/src/testing-kit/checkpoint-aggregation-contract.js +228 -0
  232. package/dist/src/testing-kit/checkpoint-aggregation-contract.js.map +1 -0
  233. package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
  234. package/dist/src/testing-kit/state-store-conformance.js +355 -3
  235. package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
  236. package/dist/src/transport-pool.d.ts +15 -1
  237. package/dist/src/transport-pool.d.ts.map +1 -1
  238. package/dist/src/transport-pool.js +50 -4
  239. package/dist/src/transport-pool.js.map +1 -1
  240. package/dist/src/transports/adaptive-concurrency.d.ts +168 -0
  241. package/dist/src/transports/adaptive-concurrency.d.ts.map +1 -0
  242. package/dist/src/transports/adaptive-concurrency.js +353 -0
  243. package/dist/src/transports/adaptive-concurrency.js.map +1 -0
  244. package/dist/src/transports/bullmq/adaptive-concurrency.d.ts +1 -143
  245. package/dist/src/transports/bullmq/adaptive-concurrency.d.ts.map +1 -1
  246. package/dist/src/transports/bullmq/adaptive-concurrency.js +3 -311
  247. package/dist/src/transports/bullmq/adaptive-concurrency.js.map +1 -1
  248. package/dist/src/transports/bullmq/bullmq-transport.d.ts +49 -1
  249. package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
  250. package/dist/src/transports/bullmq/bullmq-transport.js +330 -38
  251. package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
  252. package/dist/src/transports/bullmq/deps.d.ts +18 -2
  253. package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
  254. package/dist/src/transports/bullmq/deps.js +44 -2
  255. package/dist/src/transports/bullmq/deps.js.map +1 -1
  256. package/dist/src/transports/db-helpers.d.ts +39 -0
  257. package/dist/src/transports/db-helpers.d.ts.map +1 -1
  258. package/dist/src/transports/db-helpers.js +73 -0
  259. package/dist/src/transports/db-helpers.js.map +1 -1
  260. package/dist/src/transports/db-remote.d.ts +53 -0
  261. package/dist/src/transports/db-remote.d.ts.map +1 -0
  262. package/dist/src/transports/db-remote.js +147 -0
  263. package/dist/src/transports/db-remote.js.map +1 -0
  264. package/dist/src/transports/db-schema.d.ts +44 -1
  265. package/dist/src/transports/db-schema.d.ts.map +1 -1
  266. package/dist/src/transports/db-schema.js +227 -88
  267. package/dist/src/transports/db-schema.js.map +1 -1
  268. package/dist/src/transports/db.d.ts +189 -6
  269. package/dist/src/transports/db.d.ts.map +1 -1
  270. package/dist/src/transports/db.js +1291 -137
  271. package/dist/src/transports/db.js.map +1 -1
  272. package/dist/src/transports/event-emitter.d.ts +8 -0
  273. package/dist/src/transports/event-emitter.d.ts.map +1 -1
  274. package/dist/src/transports/event-emitter.js +36 -3
  275. package/dist/src/transports/event-emitter.js.map +1 -1
  276. package/dist/src/transports/factory.d.ts +110 -5
  277. package/dist/src/transports/factory.d.ts.map +1 -1
  278. package/dist/src/transports/factory.js +56 -9
  279. package/dist/src/transports/factory.js.map +1 -1
  280. package/dist/src/transports/queue-mock-adapter.d.ts +7 -2
  281. package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
  282. package/dist/src/transports/queue-mock-adapter.js +18 -2
  283. package/dist/src/transports/queue-mock-adapter.js.map +1 -1
  284. package/dist/src/transports/queue-remote.d.ts +146 -0
  285. package/dist/src/transports/queue-remote.d.ts.map +1 -0
  286. package/dist/src/transports/queue-remote.js +398 -0
  287. package/dist/src/transports/queue-remote.js.map +1 -0
  288. package/dist/src/transports/queue.d.ts +159 -6
  289. package/dist/src/transports/queue.d.ts.map +1 -1
  290. package/dist/src/transports/queue.js +747 -37
  291. package/dist/src/transports/queue.js.map +1 -1
  292. package/dist/src/transports/task-failure.d.ts +31 -0
  293. package/dist/src/transports/task-failure.d.ts.map +1 -0
  294. package/dist/src/transports/task-failure.js +50 -0
  295. package/dist/src/transports/task-failure.js.map +1 -0
  296. package/dist/src/workflow-als.d.ts +1 -1
  297. package/dist/src/workflow-als.d.ts.map +1 -1
  298. package/dist/src/workflow-ctx.d.ts +10 -0
  299. package/dist/src/workflow-ctx.d.ts.map +1 -1
  300. package/dist/src/workflow-ctx.js +97 -15
  301. package/dist/src/workflow-ctx.js.map +1 -1
  302. package/dist/src/workflow-discovery.d.ts +32 -41
  303. package/dist/src/workflow-discovery.d.ts.map +1 -1
  304. package/dist/src/workflow-discovery.js +65 -88
  305. package/dist/src/workflow-discovery.js.map +1 -1
  306. package/dist/src/workflow-ref.d.ts +24 -0
  307. package/dist/src/workflow-ref.d.ts.map +1 -1
  308. package/dist/src/workflow-ref.js.map +1 -1
  309. package/dist/stubs/config/durable.stub +6 -0
  310. package/dist/stubs/config/durable_dashboard.stub +7 -3
  311. package/dist/stubs/database/migrations/create_durable_tables.stub +2 -1
  312. package/dist/stubs/database/migrations/create_durable_transport_messages.stub +43 -0
  313. package/dist/stubs/database/migrations/create_durable_transport_tables.stub +12 -9
  314. package/dist/stubs/database/migrations/create_durable_transport_worker_keys.stub +1 -1
  315. package/dist/stubs/make/workflow/main.stub +1 -1
  316. package/package.json +6 -4
  317. package/skills/durable-cluster/SKILL.md +80 -11
  318. package/skills/durable-determinism/SKILL.md +11 -5
  319. package/skills/durable-reliability/SKILL.md +77 -37
  320. package/skills/durable-setup/SKILL.md +51 -22
  321. package/skills/durable-transports-stores/SKILL.md +130 -19
  322. package/skills/durable-workflows/SKILL.md +71 -18
  323. package/dist/assets/spa/assets/index-DdB9zxuX.js +0 -16
  324. package/dist/assets/spa/assets/index-DdB9zxuX.js.map +0 -1
@@ -2,25 +2,47 @@ import type { HistoryEvent, Transport, WorkflowDecision, WorkflowExecutor, Workf
2
2
  import { type WorkflowBodyResolver } from './workflow-turn.js';
3
3
  /**
4
4
  * A {@link WorkflowExecutor} backed by a {@link Transport}: it advances a remote workflow by
5
- * dispatching a {@link WorkflowTask} over the broker and awaiting the matching {@link WorkflowDecision}
6
- * (correlated by `taskId`). Pass one to `engine.registerRemote(name, version, { group, executor })` so
7
- * a workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.
5
+ * DISPATCHING a {@link WorkflowTask} over the broker under the ENGINE-SUPPLIED `taskId`, WITHOUT
6
+ * awaiting the decision. Pass one to `engine.registerRemote(name, version, { group, executor })` so a
7
+ * workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.
8
8
  *
9
- * Recovery-safe: if the engine crashes awaiting a decision, the re-drive dispatches a fresh task with
10
- * the same history — the worker's replay is deterministic, so it returns the same decision; a late
11
- * decision for the old `taskId` simply finds no waiter and is dropped.
9
+ * Multi-instance safe by construction: the executor holds NO in-memory state correlating a turn to its
10
+ * decision. The engine records the `taskId` on the run as the awaited marker and releases the run lease
11
+ * BEFORE calling {@link dispatch}; the worker's {@link WorkflowDecision} comes back over the transport's
12
+ * `onDecision` and is applied durably (by run id) by whichever engine replica consumes it — even one
13
+ * that did not dispatch the turn. A point-to-point decisions queue can therefore hand the decision to
14
+ * any replica without it being dropped.
15
+ *
16
+ * Recovery-safe: when a decision is genuinely lost (the worker died mid-turn), the awaited turn's
17
+ * liveness window (`remoteAdvanceSilenceMs` on the engine, or `timeoutMs` here; run-scoped heartbeats
18
+ * rearm it) lapses and the timer poller re-dispatches a fresh turn with the same history — the
19
+ * worker's replay is deterministic, so it returns the same decision, and a late decision for the old
20
+ * `taskId` no longer matches the run's marker and is dropped.
12
21
  */
13
22
  export declare class RemoteWorkflowExecutor implements WorkflowExecutor {
23
+ #private;
14
24
  private readonly transport;
15
25
  private readonly group;
16
- private readonly opts;
17
- private readonly pending;
18
- private subscribed;
19
- constructor(transport: Transport, group: string, opts?: {
26
+ /**
27
+ * The executor's own liveness window for a dispatched turn, from `opts.timeoutMs`. It no longer fails
28
+ * the run: a lapsed window re-drives the turn (see the class doc).
29
+ */
30
+ readonly decisionTimeoutMs: number | undefined;
31
+ /**
32
+ * @param group The worker group the turns are dispatched to — or a function of the run, for a
33
+ * group that depends on it (the engine's convention routing sends each run to the group of its own
34
+ * namespace, `<workflow>@<tenant>`).
35
+ */
36
+ constructor(transport: Transport, group: string | ((run: WorkflowRun) => string), opts?: {
20
37
  timeoutMs?: number;
21
38
  });
22
- private ensureSubscribed;
23
- advance(run: WorkflowRun, history: HistoryEvent[]): Promise<WorkflowDecision>;
39
+ /** Subscribe the engine's (stable) decision handler to this executor's transport, once. */
40
+ subscribeDecisions(handler: (decision: WorkflowDecision) => Promise<void>): void;
41
+ /**
42
+ * Enqueue one workflow turn under the engine-supplied `taskId`. Does NOT await the decision — the
43
+ * engine has already suspended the run on `taskId` and applies the decision durably via `onDecision`.
44
+ */
45
+ dispatch(run: WorkflowRun, history: HistoryEvent[], taskId: string, pendingSignals?: WorkflowTask['pendingSignals']): Promise<void>;
24
46
  }
25
47
  /**
26
48
  * A {@link WorkflowExecutor} that advances a workflow turn IN-PROCESS through the shared, pure
@@ -1 +1 @@
1
- {"version":3,"file":"remote-workflow-executor.d.ts","sourceRoot":"","sources":["../../src/remote-workflow-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAIhF;;;;;;;;;GASG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB;IAK3D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,IAAI;IANvB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA2D;IACnF,OAAO,CAAC,UAAU,CAAS;IAE3B,YACmB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,EAChD;IAEJ,OAAO,CAAC,gBAAgB;IAelB,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA8BlF;CACF;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,yBAA0B,YAAW,gBAAgB;;IAI9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,MAAM,EAAE,oBAAoB,EAC5B,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,EAChE;IAEE,OAAO,CACX,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAiB3B;CACF"}
1
+ {"version":3,"file":"remote-workflow-executor.d.ts","sourceRoot":"","sources":["../../src/remote-workflow-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,YAAY,EACb,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEhF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,sBAAuB,YAAW,gBAAgB;;IAc3D,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAbxB;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,SAAS,CAAC;IAE/C;;;;OAIG;IACH,YACmB,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,WAAW,KAAK,MAAM,CAAC,EAC/D,IAAI,GAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,EAGlC;IAED,2FAA2F;IAC3F,kBAAkB,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,gBAAgB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAI/E;IAED;;;OAGG;IACG,QAAQ,CACZ,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,YAAY,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAoBf;CACF;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,yBAA0B,YAAW,gBAAgB;;IAI9D,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFvB,YACmB,MAAM,EAAE,oBAAoB,EAC5B,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAO,EAChE;IAEE,OAAO,CACX,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,CAAC,EAAE,YAAY,CAAC,gBAAgB,CAAC,GAC9C,OAAO,CAAC,gBAAgB,CAAC,CAiB3B;CACF"}
@@ -1,48 +1,60 @@
1
1
  import { runWorkflowTurn } from './workflow-turn.js';
2
- let taskCounter = 0;
3
2
  /**
4
3
  * A {@link WorkflowExecutor} backed by a {@link Transport}: it advances a remote workflow by
5
- * dispatching a {@link WorkflowTask} over the broker and awaiting the matching {@link WorkflowDecision}
6
- * (correlated by `taskId`). Pass one to `engine.registerRemote(name, version, { group, executor })` so
7
- * a workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.
4
+ * DISPATCHING a {@link WorkflowTask} over the broker under the ENGINE-SUPPLIED `taskId`, WITHOUT
5
+ * awaiting the decision. Pass one to `engine.registerRemote(name, version, { group, executor })` so a
6
+ * workflow authored in another SDK (e.g. the Python `durable-worker`) is driven over Redis/BullMQ.
8
7
  *
9
- * Recovery-safe: if the engine crashes awaiting a decision, the re-drive dispatches a fresh task with
10
- * the same history — the worker's replay is deterministic, so it returns the same decision; a late
11
- * decision for the old `taskId` simply finds no waiter and is dropped.
8
+ * Multi-instance safe by construction: the executor holds NO in-memory state correlating a turn to its
9
+ * decision. The engine records the `taskId` on the run as the awaited marker and releases the run lease
10
+ * BEFORE calling {@link dispatch}; the worker's {@link WorkflowDecision} comes back over the transport's
11
+ * `onDecision` and is applied durably (by run id) by whichever engine replica consumes it — even one
12
+ * that did not dispatch the turn. A point-to-point decisions queue can therefore hand the decision to
13
+ * any replica without it being dropped.
14
+ *
15
+ * Recovery-safe: when a decision is genuinely lost (the worker died mid-turn), the awaited turn's
16
+ * liveness window (`remoteAdvanceSilenceMs` on the engine, or `timeoutMs` here; run-scoped heartbeats
17
+ * rearm it) lapses and the timer poller re-dispatches a fresh turn with the same history — the
18
+ * worker's replay is deterministic, so it returns the same decision, and a late decision for the old
19
+ * `taskId` no longer matches the run's marker and is dropped.
12
20
  */
13
21
  export class RemoteWorkflowExecutor {
14
22
  transport;
15
23
  group;
16
- opts;
17
- pending = new Map();
18
- subscribed = false;
24
+ #subscribed = false;
25
+ /**
26
+ * The executor's own liveness window for a dispatched turn, from `opts.timeoutMs`. It no longer fails
27
+ * the run: a lapsed window re-drives the turn (see the class doc).
28
+ */
29
+ decisionTimeoutMs;
30
+ /**
31
+ * @param group The worker group the turns are dispatched to — or a function of the run, for a
32
+ * group that depends on it (the engine's convention routing sends each run to the group of its own
33
+ * namespace, `<workflow>@<tenant>`).
34
+ */
19
35
  constructor(transport, group, opts = {}) {
20
36
  this.transport = transport;
21
37
  this.group = group;
22
- this.opts = opts;
38
+ this.decisionTimeoutMs = opts.timeoutMs || undefined;
23
39
  }
24
- ensureSubscribed() {
25
- if (this.subscribed)
40
+ /** Subscribe the engine's (stable) decision handler to this executor's transport, once. */
41
+ subscribeDecisions(handler) {
42
+ if (this.#subscribed || !this.transport.onDecision)
26
43
  return;
27
- if (!this.transport.onDecision) {
28
- throw new Error('transport does not support workflow decisions (onDecision)');
29
- }
30
- this.subscribed = true;
31
- this.transport.onDecision(async (decision) => {
32
- const resolve = this.pending.get(decision.taskId);
33
- if (resolve) {
34
- this.pending.delete(decision.taskId);
35
- resolve(decision);
36
- }
37
- });
44
+ this.#subscribed = true;
45
+ this.transport.onDecision(handler);
38
46
  }
39
- async advance(run, history) {
47
+ /**
48
+ * Enqueue one workflow turn under the engine-supplied `taskId`. Does NOT await the decision — the
49
+ * engine has already suspended the run on `taskId` and applies the decision durably via `onDecision`.
50
+ */
51
+ async dispatch(run, history, taskId, pendingSignals) {
40
52
  if (!this.transport.dispatchWorkflowTask) {
41
53
  throw new Error('transport does not support workflow tasks (dispatchWorkflowTask)');
42
54
  }
43
- this.ensureSubscribed();
44
- taskCounter += 1;
45
- const taskId = `${run.id}:wf:${taskCounter}`;
55
+ if (!this.transport.onDecision) {
56
+ throw new Error('transport does not support workflow decisions (onDecision)');
57
+ }
46
58
  const task = {
47
59
  taskId,
48
60
  runId: run.id,
@@ -50,22 +62,12 @@ export class RemoteWorkflowExecutor {
50
62
  workflowVersion: run.workflowVersion,
51
63
  input: run.input,
52
64
  history,
53
- group: this.group,
65
+ ...(pendingSignals ? { pendingSignals } : {}),
66
+ group: typeof this.group === 'function' ? this.group(run) : this.group,
54
67
  priority: run.priority,
55
68
  attempt: 1,
56
69
  };
57
- const decision = new Promise((resolve, reject) => {
58
- this.pending.set(taskId, resolve);
59
- if (this.opts.timeoutMs) {
60
- const timer = setTimeout(() => {
61
- this.pending.delete(taskId);
62
- reject(new Error(`workflow task ${taskId} timed out after ${this.opts.timeoutMs}ms`));
63
- }, this.opts.timeoutMs);
64
- timer.unref?.();
65
- }
66
- });
67
70
  await this.transport.dispatchWorkflowTask(task);
68
- return decision;
69
71
  }
70
72
  }
71
73
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"remote-workflow-executor.js","sourceRoot":"","sources":["../../src/remote-workflow-executor.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,eAAe,EAA6B,MAAM,oBAAoB,CAAC;AAEhF,IAAI,WAAW,GAAG,CAAC,CAAC;AAEpB;;;;;;;;;GASG;AACH,MAAM,OAAO,sBAAsB;IAKd,SAAS;IACT,KAAK;IACL,IAAI;IANN,OAAO,GAAG,IAAI,GAAG,EAAgD,CAAC;IAC3E,UAAU,GAAG,KAAK,CAAC;IAE3B,YACmB,SAAoB,EACpB,KAAa,EACb,IAAI,GAA2B,EAAE;yBAFjC,SAAS;qBACT,KAAK;oBACL,IAAI;IACpB,CAAC;IAEI,gBAAgB;QACtB,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;QAChF,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAClD,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBACrC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAgB,EAAE,OAAuB;QACrD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,oBAAoB,EAAE,CAAC;YACzC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,WAAW,IAAI,CAAC,CAAC;QACjB,MAAM,MAAM,GAAG,GAAG,GAAG,CAAC,EAAE,OAAO,WAAW,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAiB;YACzB,MAAM;YACN,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO;YACP,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,OAAO,EAAE,CAAC;SACX,CAAC;QACF,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACjE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;oBAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,MAAM,oBAAoB,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC;gBACxF,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,KAAgC,CAAC,KAAK,EAAE,EAAE,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC;QAChD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,yBAAyB;IAIjB,MAAM;IACN,IAAI;IAJvB,QAAQ,GAAG,CAAC,CAAC;IAEb,YACmB,MAA4B,EAC5B,IAAI,GAA2C,EAAE;sBADjD,MAAM;oBACN,IAAI;IACpB,CAAC;IAEJ,KAAK,CAAC,OAAO,CACX,GAAgB,EAChB,OAAuB,EACvB,cAA+C;QAE/C,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QACnB,MAAM,IAAI,GAAiB;YACzB,MAAM,EAAE,GAAG,GAAG,CAAC,EAAE,OAAO,IAAI,CAAC,QAAQ,EAAE;YACvC,KAAK,EAAE,GAAG,CAAC,EAAE;YACb,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,OAAO;YACP,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE;YAC5B,GAAG,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjE,OAAO,EAAE,CAAC;SACX,CAAC;QACF,OAAO,eAAe,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;YACxC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjF,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"remote-workflow-executor.js","sourceRoot":"","sources":["../../src/remote-workflow-executor.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import type { StepCheckpoint, WorkflowRun } from './interfaces.js';
1
+ import { type CheckpointQuery, type CheckpointStat, type StateStore, type StepCheckpoint, type WorkflowRun } from './interfaces.js';
2
2
  /**
3
3
  * A parallel fan (a `ctx.all`, a step fan, a polyglot `gather`) reduced to what a detail view needs
4
4
  * to draw it: one node, its progress and its failures. A run detail with a 40,000-item fan otherwise
@@ -34,16 +34,28 @@ export interface FanPage {
34
34
  items: StepCheckpoint[];
35
35
  /** Members matching the query, across all pages. */
36
36
  total: number;
37
+ /** A validator for this page, when the source can compute one without reading the members. */
38
+ etag?: string | undefined;
39
+ /**
40
+ * Set when the query's `ifNoneMatch` matched {@link etag}: the page has not changed, so nothing
41
+ * was read. `items` is empty and `total` is 0 as placeholders, not the fan's; keep the page the
42
+ * caller already holds.
43
+ */
44
+ notModified?: true | undefined;
37
45
  }
38
46
  export interface FanPageQuery {
39
47
  offset?: number | undefined;
40
48
  limit?: number | undefined;
41
49
  /** Only failed members (a failed step, or a child that failed). */
42
50
  failedOnly?: boolean | undefined;
51
+ /** An HTTP `If-None-Match` value: a page whose `etag` it names comes back `notModified`. */
52
+ ifNoneMatch?: string | undefined;
43
53
  }
44
54
  export declare const FAN_SUMMARY_FAILURES = 20;
45
55
  /** The most children a summarized detail lists by id; `childCount` carries the rest. */
46
56
  export declare const SUMMARY_CHILD_LIMIT = 200;
57
+ /** How many children a folded `fan:` checkpoint stands for; undefined for any other checkpoint. */
58
+ export declare function foldedCount(cp: StepCheckpoint): number | undefined;
47
59
  /** A failed member: a failed step, or a child whose completion reports `ok: false`. */
48
60
  export declare function isFailedMember(cp: StepCheckpoint): boolean;
49
61
  /** Summarize one fan's members (in seq order). */
@@ -60,6 +72,11 @@ export declare function summarizeTimeline(timeline: StepCheckpoint[], over: numb
60
72
  };
61
73
  /** One page of a fan's members out of a run's timeline. */
62
74
  export declare function pageFan(timeline: StepCheckpoint[], group: string, query: FanPageQuery): FanPage;
75
+ /** A {@link FanPageQuery}'s offset and limit, clamped to sane bounds. */
76
+ export declare function fanPageBounds(query: FanPageQuery): {
77
+ offset: number;
78
+ limit: number;
79
+ };
63
80
  /**
64
81
  * A run's detail: the run, its step timeline, and the runs it spawned. With
65
82
  * {@link RunDetailOptions.summarizeFansOver}, the members of a wide fan are left out of `timeline`
@@ -75,6 +92,16 @@ export interface RunDetail {
75
92
  fans?: FanSummary[] | undefined;
76
93
  /** How many children the run has, when `children` lists only the first of them. */
77
94
  childCount?: number | undefined;
95
+ /**
96
+ * A validator for this detail, when the source can compute one without reading the timeline (a
97
+ * store with `checkpointStats`): it changes whenever the run or any of its checkpoints does.
98
+ */
99
+ etag?: string | undefined;
100
+ /**
101
+ * Set when {@link RunDetailOptions.ifNoneMatch} matched {@link etag}: nothing changed, so only
102
+ * `run` was read — `timeline` and `children` are empty, not the run's.
103
+ */
104
+ notModified?: true | undefined;
78
105
  }
79
106
  /** How to shape a {@link RunDetail}. */
80
107
  export interface RunDetailOptions {
@@ -84,15 +111,75 @@ export interface RunDetailOptions {
84
111
  * fan should set it: the full detail of a 40k-member fan is megabytes.
85
112
  */
86
113
  summarizeFansOver?: number | undefined;
114
+ /**
115
+ * An HTTP `If-None-Match` value. When it names the detail's current {@link RunDetail.etag}, the
116
+ * detail comes back `notModified` without the timeline being read. Ignored when no etag can be
117
+ * computed (no `summarizeFansOver`, or a store without the checkpoint aggregates).
118
+ */
119
+ ifNoneMatch?: string | undefined;
87
120
  }
88
- /** The reads a {@link RunDetail} is built from — an engine, a dashboard port, or a gateway. */
121
+ /**
122
+ * The reads a {@link RunDetail} is built from — an engine, a dashboard port, or a gateway. With both
123
+ * of the optional aggregate reads (a store's `checkpointStats` + `queryCheckpoints`), a summarized
124
+ * detail and a fan page are built from the aggregates instead of the whole checkpoint list, and come
125
+ * back with an `etag`.
126
+ */
89
127
  export interface RunDetailSource {
90
128
  getRun(runId: string): Promise<WorkflowRun | null>;
91
129
  listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
92
130
  getRunChildren(runId: string): Promise<string[]>;
131
+ checkpointStats?: StateStore['checkpointStats'] | undefined;
132
+ queryCheckpoints?: StateStore['queryCheckpoints'] | undefined;
93
133
  }
94
134
  /** Read `runId`'s {@link RunDetail}, summarized per `options`, or null for an unknown run. */
95
135
  export declare function loadRunDetail(source: RunDetailSource, runId: string, options?: RunDetailOptions): Promise<RunDetail | null>;
96
136
  /** One page of `runId`'s fan `group`, or null for an unknown run. */
97
- export declare function loadFanMembers(source: Pick<RunDetailSource, 'getRun' | 'listCheckpoints'>, runId: string, group: string, query: FanPageQuery): Promise<FanPage | null>;
137
+ export declare function loadFanMembers(source: Pick<RunDetailSource, 'getRun' | 'listCheckpoints' | 'checkpointStats' | 'queryCheckpoints'>, runId: string, group: string, query: FanPageQuery): Promise<FanPage | null>;
138
+ /** A source that aggregates checkpoints itself: both halves of the pair are present. */
139
+ export type CheckpointAggregatingStore = Required<Pick<StateStore, 'checkpointStats' | 'queryCheckpoints'>>;
140
+ /** Whether `source` has both aggregate reads ({@link StateStore.checkpointStats} + `queryCheckpoints`). */
141
+ export declare function aggregatesCheckpoints<T extends {
142
+ checkpointStats?: StateStore['checkpointStats'] | undefined;
143
+ queryCheckpoints?: StateStore['queryCheckpoints'] | undefined;
144
+ }>(source: T): source is T & CheckpointAggregatingStore;
145
+ /**
146
+ * {@link StateStore.checkpointStats} over checkpoints already in memory — the reference a store's
147
+ * `GROUP BY` must agree with, and the in-memory store's implementation.
148
+ */
149
+ export declare function checkpointStatsOf(checkpoints: StepCheckpoint[], opts?: {
150
+ group?: string | undefined;
151
+ }): CheckpointStat[];
152
+ /** {@link StateStore.queryCheckpoints} over checkpoints already in memory, sorted by `seq` here. */
153
+ export declare function queryCheckpointsOf(checkpoints: StepCheckpoint[], query: CheckpointQuery): StepCheckpoint[];
154
+ /**
155
+ * What `summarizeTimeline` plus `childIdsOf` make of a run's whole checkpoint list, read through the
156
+ * store's aggregates instead: the checkpoints outside wide fans, one {@link FanSummary} per wide fan,
157
+ * and the run's children capped at {@link SUMMARY_CHILD_LIMIT} with their count.
158
+ *
159
+ * What it reads besides the aggregates: the rows outside wide fans, every folded `fan:` checkpoint
160
+ * (one per settled wave), up to {@link FAN_SUMMARY_FAILURES} failed rows per wide fan, the first
161
+ * child-edge rows, and — while a wide child fan is in flight — that fan's completed `signal:child:`
162
+ * rows, whose `ok: false` payload is what marks a failed child.
163
+ *
164
+ * `childCount` is exact (distinct ids, as `loadRunDetail` counts them) while the run has few enough
165
+ * child edges to read them all. Past that it adds up the edge rows and the folded ids without
166
+ * de-duplicating, so a child both spawned and awaited counts twice.
167
+ */
168
+ export declare function summarizeRunFromStore(store: CheckpointAggregatingStore, runId: string, over: number, stats?: CheckpointStat[]): Promise<{
169
+ timeline: StepCheckpoint[];
170
+ fans: FanSummary[];
171
+ children: string[];
172
+ childCount: number;
173
+ }>;
174
+ /** What `pageFan` makes of a run's whole checkpoint list, read one page at a time from the store. */
175
+ export declare function pageFanFromStore(store: CheckpointAggregatingStore, runId: string, group: string, query: FanPageQuery, stats?: CheckpointStat[]): Promise<FanPage>;
176
+ /**
177
+ * The ETag of a summarized run detail: the run row as read (so any run field that changes shows)
178
+ * plus its checkpoint buckets, and the threshold it was summarized with.
179
+ */
180
+ export declare function runDetailEtag(run: WorkflowRun, stats: CheckpointStat[], over: number): string;
181
+ /** The ETag of one page of a fan: its group's buckets and the page asked for. */
182
+ export declare function fanPageEtag(group: string, stats: CheckpointStat[], query: FanPageQuery): string;
183
+ /** Whether an `If-None-Match` header value names `etag` (weak comparison, as RFC 9110 asks for). */
184
+ export declare function etagMatches(ifNoneMatch: string | undefined, etag: string): boolean;
98
185
  //# sourceMappingURL=run-detail-summary.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-detail-summary.d.ts","sourceRoot":"","sources":["../../src/run-detail-summary.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-detail-summary.d.ts","sourceRoot":"","sources":["../../src/run-detail-summary.ts"],"names":[],"mappings":"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"}