@adonis-agora/durable 0.1.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 (316) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/assets/dashboard.html +446 -0
  4. package/dist/commands/main.d.ts +15 -0
  5. package/dist/commands/main.d.ts.map +1 -0
  6. package/dist/commands/main.js +15 -0
  7. package/dist/commands/main.js.map +1 -0
  8. package/dist/commands/retry.d.ts +16 -0
  9. package/dist/commands/retry.d.ts.map +1 -0
  10. package/dist/commands/retry.js +34 -0
  11. package/dist/commands/retry.js.map +1 -0
  12. package/dist/commands/runs.d.ts +17 -0
  13. package/dist/commands/runs.d.ts.map +1 -0
  14. package/dist/commands/runs.js +40 -0
  15. package/dist/commands/runs.js.map +1 -0
  16. package/dist/commands/work.d.ts +18 -0
  17. package/dist/commands/work.d.ts.map +1 -0
  18. package/dist/commands/work.js +58 -0
  19. package/dist/commands/work.js.map +1 -0
  20. package/dist/configure.d.ts +15 -0
  21. package/dist/configure.d.ts.map +1 -0
  22. package/dist/configure.js +26 -0
  23. package/dist/configure.js.map +1 -0
  24. package/dist/providers/dashboard_provider.d.ts +27 -0
  25. package/dist/providers/dashboard_provider.d.ts.map +1 -0
  26. package/dist/providers/dashboard_provider.js +94 -0
  27. package/dist/providers/dashboard_provider.js.map +1 -0
  28. package/dist/providers/durable_provider.d.ts +36 -0
  29. package/dist/providers/durable_provider.d.ts.map +1 -0
  30. package/dist/providers/durable_provider.js +113 -0
  31. package/dist/providers/durable_provider.js.map +1 -0
  32. package/dist/src/admission-redis/index.d.ts +2 -0
  33. package/dist/src/admission-redis/index.d.ts.map +1 -0
  34. package/dist/src/admission-redis/index.js +2 -0
  35. package/dist/src/admission-redis/index.js.map +1 -0
  36. package/dist/src/admission-redis/redis-admission-backend.d.ts +83 -0
  37. package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -0
  38. package/dist/src/admission-redis/redis-admission-backend.js +200 -0
  39. package/dist/src/admission-redis/redis-admission-backend.js.map +1 -0
  40. package/dist/src/admission.d.ts +49 -0
  41. package/dist/src/admission.d.ts.map +1 -0
  42. package/dist/src/admission.js +30 -0
  43. package/dist/src/admission.js.map +1 -0
  44. package/dist/src/backoff.d.ts +5 -0
  45. package/dist/src/backoff.d.ts.map +1 -0
  46. package/dist/src/backoff.js +11 -0
  47. package/dist/src/backoff.js.map +1 -0
  48. package/dist/src/checkpoints.d.ts +42 -0
  49. package/dist/src/checkpoints.d.ts.map +1 -0
  50. package/dist/src/checkpoints.js +57 -0
  51. package/dist/src/checkpoints.js.map +1 -0
  52. package/dist/src/codec-state-store.d.ts +60 -0
  53. package/dist/src/codec-state-store.d.ts.map +1 -0
  54. package/dist/src/codec-state-store.js +129 -0
  55. package/dist/src/codec-state-store.js.map +1 -0
  56. package/dist/src/commands/index.d.ts +3 -0
  57. package/dist/src/commands/index.d.ts.map +1 -0
  58. package/dist/src/commands/index.js +3 -0
  59. package/dist/src/commands/index.js.map +1 -0
  60. package/dist/src/commands/runs.d.ts +24 -0
  61. package/dist/src/commands/runs.d.ts.map +1 -0
  62. package/dist/src/commands/runs.js +39 -0
  63. package/dist/src/commands/runs.js.map +1 -0
  64. package/dist/src/commands/worker.d.ts +61 -0
  65. package/dist/src/commands/worker.d.ts.map +1 -0
  66. package/dist/src/commands/worker.js +74 -0
  67. package/dist/src/commands/worker.js.map +1 -0
  68. package/dist/src/completion.d.ts +15 -0
  69. package/dist/src/completion.d.ts.map +1 -0
  70. package/dist/src/completion.js +10 -0
  71. package/dist/src/completion.js.map +1 -0
  72. package/dist/src/dashboard/define_config.d.ts +48 -0
  73. package/dist/src/dashboard/define_config.d.ts.map +1 -0
  74. package/dist/src/dashboard/define_config.js +57 -0
  75. package/dist/src/dashboard/define_config.js.map +1 -0
  76. package/dist/src/dashboard/handlers.d.ts +47 -0
  77. package/dist/src/dashboard/handlers.d.ts.map +1 -0
  78. package/dist/src/dashboard/handlers.js +163 -0
  79. package/dist/src/dashboard/handlers.js.map +1 -0
  80. package/dist/src/dashboard/html.d.ts +7 -0
  81. package/dist/src/dashboard/html.d.ts.map +1 -0
  82. package/dist/src/dashboard/html.js +24 -0
  83. package/dist/src/dashboard/html.js.map +1 -0
  84. package/dist/src/dashboard/index.d.ts +8 -0
  85. package/dist/src/dashboard/index.d.ts.map +1 -0
  86. package/dist/src/dashboard/index.js +6 -0
  87. package/dist/src/dashboard/index.js.map +1 -0
  88. package/dist/src/define_config.d.ts +72 -0
  89. package/dist/src/define_config.d.ts.map +1 -0
  90. package/dist/src/define_config.js +8 -0
  91. package/dist/src/define_config.js.map +1 -0
  92. package/dist/src/diagnostics-bridge.d.ts +22 -0
  93. package/dist/src/diagnostics-bridge.d.ts.map +1 -0
  94. package/dist/src/diagnostics-bridge.js +25 -0
  95. package/dist/src/diagnostics-bridge.js.map +1 -0
  96. package/dist/src/duration.d.ts +6 -0
  97. package/dist/src/duration.d.ts.map +1 -0
  98. package/dist/src/duration.js +39 -0
  99. package/dist/src/duration.js.map +1 -0
  100. package/dist/src/engine.d.ts +583 -0
  101. package/dist/src/engine.d.ts.map +1 -0
  102. package/dist/src/engine.js +1894 -0
  103. package/dist/src/engine.js.map +1 -0
  104. package/dist/src/entities.d.ts +44 -0
  105. package/dist/src/entities.d.ts.map +1 -0
  106. package/dist/src/entities.js +64 -0
  107. package/dist/src/entities.js.map +1 -0
  108. package/dist/src/errors.d.ts +68 -0
  109. package/dist/src/errors.d.ts.map +1 -0
  110. package/dist/src/errors.js +102 -0
  111. package/dist/src/errors.js.map +1 -0
  112. package/dist/src/event-accumulators.d.ts +39 -0
  113. package/dist/src/event-accumulators.d.ts.map +1 -0
  114. package/dist/src/event-accumulators.js +70 -0
  115. package/dist/src/event-accumulators.js.map +1 -0
  116. package/dist/src/events.d.ts +9 -0
  117. package/dist/src/events.d.ts.map +1 -0
  118. package/dist/src/events.js +35 -0
  119. package/dist/src/events.js.map +1 -0
  120. package/dist/src/index.d.ts +36 -0
  121. package/dist/src/index.d.ts.map +1 -0
  122. package/dist/src/index.js +37 -0
  123. package/dist/src/index.js.map +1 -0
  124. package/dist/src/interfaces.d.ts +909 -0
  125. package/dist/src/interfaces.d.ts.map +1 -0
  126. package/dist/src/interfaces.js +2 -0
  127. package/dist/src/interfaces.js.map +1 -0
  128. package/dist/src/metrics.d.ts +44 -0
  129. package/dist/src/metrics.d.ts.map +1 -0
  130. package/dist/src/metrics.js +78 -0
  131. package/dist/src/metrics.js.map +1 -0
  132. package/dist/src/otel/durable-metrics.d.ts +42 -0
  133. package/dist/src/otel/durable-metrics.d.ts.map +1 -0
  134. package/dist/src/otel/durable-metrics.js +75 -0
  135. package/dist/src/otel/durable-metrics.js.map +1 -0
  136. package/dist/src/otel/durable-otel.d.ts +20 -0
  137. package/dist/src/otel/durable-otel.d.ts.map +1 -0
  138. package/dist/src/otel/durable-otel.js +74 -0
  139. package/dist/src/otel/durable-otel.js.map +1 -0
  140. package/dist/src/otel/index.d.ts +4 -0
  141. package/dist/src/otel/index.d.ts.map +1 -0
  142. package/dist/src/otel/index.js +4 -0
  143. package/dist/src/otel/index.js.map +1 -0
  144. package/dist/src/otel/traceparent.d.ts +17 -0
  145. package/dist/src/otel/traceparent.d.ts.map +1 -0
  146. package/dist/src/otel/traceparent.js +21 -0
  147. package/dist/src/otel/traceparent.js.map +1 -0
  148. package/dist/src/pollers.d.ts +33 -0
  149. package/dist/src/pollers.d.ts.map +1 -0
  150. package/dist/src/pollers.js +76 -0
  151. package/dist/src/pollers.js.map +1 -0
  152. package/dist/src/protocol.d.ts +17 -0
  153. package/dist/src/protocol.d.ts.map +1 -0
  154. package/dist/src/protocol.js +47 -0
  155. package/dist/src/protocol.js.map +1 -0
  156. package/dist/src/queue.d.ts +113 -0
  157. package/dist/src/queue.d.ts.map +1 -0
  158. package/dist/src/queue.js +128 -0
  159. package/dist/src/queue.js.map +1 -0
  160. package/dist/src/remote-step-factory.d.ts +15 -0
  161. package/dist/src/remote-step-factory.d.ts.map +1 -0
  162. package/dist/src/remote-step-factory.js +12 -0
  163. package/dist/src/remote-step-factory.js.map +1 -0
  164. package/dist/src/remote-workflow-executor.d.ts +24 -0
  165. package/dist/src/remote-workflow-executor.d.ts.map +1 -0
  166. package/dist/src/remote-workflow-executor.js +70 -0
  167. package/dist/src/remote-workflow-executor.js.map +1 -0
  168. package/dist/src/scheduler.d.ts +67 -0
  169. package/dist/src/scheduler.d.ts.map +1 -0
  170. package/dist/src/scheduler.js +111 -0
  171. package/dist/src/scheduler.js.map +1 -0
  172. package/dist/src/search-attributes.d.ts +48 -0
  173. package/dist/src/search-attributes.d.ts.map +1 -0
  174. package/dist/src/search-attributes.js +98 -0
  175. package/dist/src/search-attributes.js.map +1 -0
  176. package/dist/src/singleton-gate.d.ts +44 -0
  177. package/dist/src/singleton-gate.d.ts.map +1 -0
  178. package/dist/src/singleton-gate.js +90 -0
  179. package/dist/src/singleton-gate.js.map +1 -0
  180. package/dist/src/step-logger.d.ts +9 -0
  181. package/dist/src/step-logger.d.ts.map +1 -0
  182. package/dist/src/step-logger.js +89 -0
  183. package/dist/src/step-logger.js.map +1 -0
  184. package/dist/src/stores/factory.d.ts +42 -0
  185. package/dist/src/stores/factory.d.ts.map +1 -0
  186. package/dist/src/stores/factory.js +29 -0
  187. package/dist/src/stores/factory.js.map +1 -0
  188. package/dist/src/stores/lucid-helpers.d.ts +11 -0
  189. package/dist/src/stores/lucid-helpers.d.ts.map +1 -0
  190. package/dist/src/stores/lucid-helpers.js +38 -0
  191. package/dist/src/stores/lucid-helpers.js.map +1 -0
  192. package/dist/src/stores/lucid-mappers.d.ts +58 -0
  193. package/dist/src/stores/lucid-mappers.d.ts.map +1 -0
  194. package/dist/src/stores/lucid-mappers.js +174 -0
  195. package/dist/src/stores/lucid-mappers.js.map +1 -0
  196. package/dist/src/stores/lucid-schema.d.ts +28 -0
  197. package/dist/src/stores/lucid-schema.d.ts.map +1 -0
  198. package/dist/src/stores/lucid-schema.js +115 -0
  199. package/dist/src/stores/lucid-schema.js.map +1 -0
  200. package/dist/src/stores/lucid.d.ts +69 -0
  201. package/dist/src/stores/lucid.d.ts.map +1 -0
  202. package/dist/src/stores/lucid.js +342 -0
  203. package/dist/src/stores/lucid.js.map +1 -0
  204. package/dist/src/telescope/dashboard.d.ts +15 -0
  205. package/dist/src/telescope/dashboard.d.ts.map +1 -0
  206. package/dist/src/telescope/dashboard.js +113 -0
  207. package/dist/src/telescope/dashboard.js.map +1 -0
  208. package/dist/src/telescope/data-providers.d.ts +20 -0
  209. package/dist/src/telescope/data-providers.d.ts.map +1 -0
  210. package/dist/src/telescope/data-providers.js +322 -0
  211. package/dist/src/telescope/data-providers.js.map +1 -0
  212. package/dist/src/telescope/extension.d.ts +22 -0
  213. package/dist/src/telescope/extension.d.ts.map +1 -0
  214. package/dist/src/telescope/extension.js +38 -0
  215. package/dist/src/telescope/extension.js.map +1 -0
  216. package/dist/src/telescope/index.d.ts +5 -0
  217. package/dist/src/telescope/index.d.ts.map +1 -0
  218. package/dist/src/telescope/index.js +4 -0
  219. package/dist/src/telescope/index.js.map +1 -0
  220. package/dist/src/telescope/telescope-sdk.d.ts +123 -0
  221. package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
  222. package/dist/src/telescope/telescope-sdk.js +12 -0
  223. package/dist/src/telescope/telescope-sdk.js.map +1 -0
  224. package/dist/src/test-helpers.d.ts +11 -0
  225. package/dist/src/test-helpers.d.ts.map +1 -0
  226. package/dist/src/test-helpers.js +12 -0
  227. package/dist/src/test-helpers.js.map +1 -0
  228. package/dist/src/testing/in-memory-state-store.d.ts +64 -0
  229. package/dist/src/testing/in-memory-state-store.d.ts.map +1 -0
  230. package/dist/src/testing/in-memory-state-store.js +259 -0
  231. package/dist/src/testing/in-memory-state-store.js.map +1 -0
  232. package/dist/src/testing/in-memory-transport.d.ts +25 -0
  233. package/dist/src/testing/in-memory-transport.d.ts.map +1 -0
  234. package/dist/src/testing/in-memory-transport.js +49 -0
  235. package/dist/src/testing/in-memory-transport.js.map +1 -0
  236. package/dist/src/testing-kit/admission-backend-conformance.d.ts +18 -0
  237. package/dist/src/testing-kit/admission-backend-conformance.d.ts.map +1 -0
  238. package/dist/src/testing-kit/admission-backend-conformance.js +81 -0
  239. package/dist/src/testing-kit/admission-backend-conformance.js.map +1 -0
  240. package/dist/src/testing-kit/assertions.d.ts +10 -0
  241. package/dist/src/testing-kit/assertions.d.ts.map +1 -0
  242. package/dist/src/testing-kit/assertions.js +41 -0
  243. package/dist/src/testing-kit/assertions.js.map +1 -0
  244. package/dist/src/testing-kit/harness.d.ts +28 -0
  245. package/dist/src/testing-kit/harness.d.ts.map +1 -0
  246. package/dist/src/testing-kit/harness.js +42 -0
  247. package/dist/src/testing-kit/harness.js.map +1 -0
  248. package/dist/src/testing-kit/index.d.ts +8 -0
  249. package/dist/src/testing-kit/index.d.ts.map +1 -0
  250. package/dist/src/testing-kit/index.js +8 -0
  251. package/dist/src/testing-kit/index.js.map +1 -0
  252. package/dist/src/testing-kit/replay.d.ts +22 -0
  253. package/dist/src/testing-kit/replay.d.ts.map +1 -0
  254. package/dist/src/testing-kit/replay.js +38 -0
  255. package/dist/src/testing-kit/replay.js.map +1 -0
  256. package/dist/src/testing-kit/state-store-conformance.d.ts +51 -0
  257. package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -0
  258. package/dist/src/testing-kit/state-store-conformance.js +430 -0
  259. package/dist/src/testing-kit/state-store-conformance.js.map +1 -0
  260. package/dist/src/testing-kit/steps.d.ts +5 -0
  261. package/dist/src/testing-kit/steps.d.ts.map +1 -0
  262. package/dist/src/testing-kit/steps.js +15 -0
  263. package/dist/src/testing-kit/steps.js.map +1 -0
  264. package/dist/src/testing-kit/transport-conformance.d.ts +16 -0
  265. package/dist/src/testing-kit/transport-conformance.d.ts.map +1 -0
  266. package/dist/src/testing-kit/transport-conformance.js +64 -0
  267. package/dist/src/testing-kit/transport-conformance.js.map +1 -0
  268. package/dist/src/tokens.d.ts +18 -0
  269. package/dist/src/tokens.d.ts.map +1 -0
  270. package/dist/src/tokens.js +18 -0
  271. package/dist/src/tokens.js.map +1 -0
  272. package/dist/src/transport-pool.d.ts +30 -0
  273. package/dist/src/transport-pool.d.ts.map +1 -0
  274. package/dist/src/transport-pool.js +82 -0
  275. package/dist/src/transport-pool.js.map +1 -0
  276. package/dist/src/transports/db-helpers.d.ts +10 -0
  277. package/dist/src/transports/db-helpers.d.ts.map +1 -0
  278. package/dist/src/transports/db-helpers.js +33 -0
  279. package/dist/src/transports/db-helpers.js.map +1 -0
  280. package/dist/src/transports/db-schema.d.ts +28 -0
  281. package/dist/src/transports/db-schema.d.ts.map +1 -0
  282. package/dist/src/transports/db-schema.js +98 -0
  283. package/dist/src/transports/db-schema.js.map +1 -0
  284. package/dist/src/transports/db.d.ts +81 -0
  285. package/dist/src/transports/db.d.ts.map +1 -0
  286. package/dist/src/transports/db.js +340 -0
  287. package/dist/src/transports/db.js.map +1 -0
  288. package/dist/src/transports/factory.d.ts +79 -0
  289. package/dist/src/transports/factory.d.ts.map +1 -0
  290. package/dist/src/transports/factory.js +57 -0
  291. package/dist/src/transports/factory.js.map +1 -0
  292. package/dist/src/transports/queue-mock-adapter.d.ts +39 -0
  293. package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -0
  294. package/dist/src/transports/queue-mock-adapter.js +86 -0
  295. package/dist/src/transports/queue-mock-adapter.js.map +1 -0
  296. package/dist/src/transports/queue.d.ts +84 -0
  297. package/dist/src/transports/queue.d.ts.map +1 -0
  298. package/dist/src/transports/queue.js +210 -0
  299. package/dist/src/transports/queue.js.map +1 -0
  300. package/dist/src/workflow-ctx.d.ts +64 -0
  301. package/dist/src/workflow-ctx.d.ts.map +1 -0
  302. package/dist/src/workflow-ctx.js +457 -0
  303. package/dist/src/workflow-ctx.js.map +1 -0
  304. package/dist/src/workflow-ref.d.ts +34 -0
  305. package/dist/src/workflow-ref.d.ts.map +1 -0
  306. package/dist/src/workflow-ref.js +28 -0
  307. package/dist/src/workflow-ref.js.map +1 -0
  308. package/dist/stubs/config/durable.stub +49 -0
  309. package/dist/stubs/config/durable_dashboard.stub +17 -0
  310. package/dist/stubs/database/migrations/create_durable_tables.stub +87 -0
  311. package/dist/stubs/database/migrations/create_durable_transport_tables.stub +75 -0
  312. package/dist/stubs/main.d.ts +3 -0
  313. package/dist/stubs/main.d.ts.map +1 -0
  314. package/dist/stubs/main.js +4 -0
  315. package/dist/stubs/main.js.map +1 -0
  316. package/package.json +154 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Dependency-injection tokens. Adapters bind their implementations to these so `core` and
3
+ * `@dudousxd/nestjs-durable` depend only on the interfaces in `./interfaces`.
4
+ *
5
+ * These use `Symbol.for(key)` (the global symbol registry), NOT `Symbol(key)`, so the token is the
6
+ * SAME instance no matter how many times `core` is evaluated in a process. A consumer can hold more
7
+ * than one physical copy of `core` at runtime — pnpm peer-dependency multiplexing installs a
8
+ * separate virtual copy per distinct peer set, and the dual ESM/CJS build can be loaded once as
9
+ * `import` (`index.js`) and once as `require` (`index.cjs`). A plain `Symbol()` would mint a
10
+ * DISTINCT token per copy, so `DurableModule` (provider) and `DashboardService` / a store adapter
11
+ * (injector) could resolve different symbols → Nest can't satisfy the dependency
12
+ * (`STATE_STORE is not available in the DurableApiModule context`). A registered symbol collapses
13
+ * them to one. Mirrors the `CONTEXT_ACCESSOR` token in `@dudousxd/nestjs-durable`'s `tokens.ts`.
14
+ */
15
+ export const STATE_STORE = Symbol.for('@agora/durable:STATE_STORE');
16
+ export const TRANSPORT = Symbol.for('@agora/durable:TRANSPORT');
17
+ export const DURABLE_OPTIONS = Symbol.for('@agora/durable:DURABLE_OPTIONS');
18
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;AACpE,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;AAChE,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { GroupHealth, Heartbeat, NamedTransport, RemoteTask, StepResult, WorkflowStepEvent } from './interfaces.js';
2
+ /**
3
+ * An ordered pool of named transports. The engine dispatches on the first and fails over to the
4
+ * next on a dispatch error; a step can pin one by id. Pure transport plumbing — no run lifecycle —
5
+ * so it lives apart from the engine.
6
+ */
7
+ export declare class TransportPool {
8
+ private readonly transports;
9
+ constructor(transports: NamedTransport[]);
10
+ get size(): number;
11
+ /** Register the engine's result/heartbeat/step-event handlers on EVERY transport — a result can come
12
+ * back on whichever one delivered the task, so failover stays symmetric. `onStepEvent` is wired only
13
+ * on transports that carry streamed workflow step lifecycle (BullMQ); others simply skip it. */
14
+ bind(onResult: (result: StepResult) => Promise<void>, onHeartbeat: (beat: Heartbeat) => Promise<void>, onStepEvent?: (event: WorkflowStepEvent) => Promise<void>): void;
15
+ /**
16
+ * Dispatch `task` over the pool: try the preferred (or first) transport, fail over to the next on
17
+ * a dispatch error, and stamp the task with the id of the transport that accepted it (so a worker
18
+ * replies on the matching one). Throws if every transport fails.
19
+ */
20
+ dispatch(task: Omit<RemoteTask, 'transport'>, preferId?: string): Promise<void>;
21
+ /** Worker-health for `group`, merged across every transport that can report it (a group's queue
22
+ * and its workers may live on any pinned transport). Undefined when no transport implements
23
+ * `groupHealth` (e.g. a pure in-process transport — nothing to introspect). */
24
+ groupHealth(group: string): Promise<GroupHealth | undefined>;
25
+ /** Distinct worker groups with a live heartbeat, merged across every transport that can report it. */
26
+ listWorkerGroups(): Promise<string[]>;
27
+ /** Pinned `preferId` first, then the rest (failover order). */
28
+ private ordered;
29
+ }
30
+ //# sourceMappingURL=transport-pool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-pool.d.ts","sourceRoot":"","sources":["../../src/transport-pool.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,UAAU,EACV,UAAU,EACV,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB;;;;GAIG;AACH,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAAV,UAAU,EAAE,cAAc,EAAE;IAEzD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;qGAEiG;IACjG,IAAI,CACF,QAAQ,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/C,WAAW,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,EAC/C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,OAAO,CAAC,IAAI,CAAC,GACxD,IAAI;IAUP;;;;OAIG;IACG,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAarF;;oFAEgF;IAC1E,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAalE,sGAAsG;IAChG,gBAAgB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAU3C,+DAA+D;IAC/D,OAAO,CAAC,OAAO;CAMhB"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * An ordered pool of named transports. The engine dispatches on the first and fails over to the
3
+ * next on a dispatch error; a step can pin one by id. Pure transport plumbing — no run lifecycle —
4
+ * so it lives apart from the engine.
5
+ */
6
+ export class TransportPool {
7
+ transports;
8
+ constructor(transports) {
9
+ this.transports = transports;
10
+ }
11
+ get size() {
12
+ return this.transports.length;
13
+ }
14
+ /** Register the engine's result/heartbeat/step-event handlers on EVERY transport — a result can come
15
+ * back on whichever one delivered the task, so failover stays symmetric. `onStepEvent` is wired only
16
+ * on transports that carry streamed workflow step lifecycle (BullMQ); others simply skip it. */
17
+ bind(onResult, onHeartbeat, onStepEvent) {
18
+ for (const { transport } of this.transports) {
19
+ transport.onResult(onResult);
20
+ transport.onHeartbeat(onHeartbeat);
21
+ if (onStepEvent && transport.onStepEvent) {
22
+ transport.onStepEvent(onStepEvent);
23
+ }
24
+ }
25
+ }
26
+ /**
27
+ * Dispatch `task` over the pool: try the preferred (or first) transport, fail over to the next on
28
+ * a dispatch error, and stamp the task with the id of the transport that accepted it (so a worker
29
+ * replies on the matching one). Throws if every transport fails.
30
+ */
31
+ async dispatch(task, preferId) {
32
+ let lastErr;
33
+ for (const { id, transport } of this.ordered(preferId)) {
34
+ try {
35
+ await transport.dispatch({ ...task, transport: id });
36
+ return;
37
+ }
38
+ catch (err) {
39
+ lastErr = err;
40
+ }
41
+ }
42
+ throw lastErr ?? new Error('no transport accepted the dispatch');
43
+ }
44
+ /** Worker-health for `group`, merged across every transport that can report it (a group's queue
45
+ * and its workers may live on any pinned transport). Undefined when no transport implements
46
+ * `groupHealth` (e.g. a pure in-process transport — nothing to introspect). */
47
+ async groupHealth(group) {
48
+ const reports = [];
49
+ for (const { transport } of this.transports) {
50
+ if (transport.groupHealth)
51
+ reports.push(await transport.groupHealth(group));
52
+ }
53
+ if (reports.length === 0)
54
+ return undefined;
55
+ return {
56
+ group,
57
+ depth: reports.reduce((sum, r) => sum + r.depth, 0),
58
+ liveWorkers: reports.flatMap((r) => r.liveWorkers),
59
+ };
60
+ }
61
+ /** Distinct worker groups with a live heartbeat, merged across every transport that can report it. */
62
+ async listWorkerGroups() {
63
+ const groups = new Set();
64
+ for (const { transport } of this.transports) {
65
+ if (transport.listWorkerGroups) {
66
+ for (const g of await transport.listWorkerGroups())
67
+ groups.add(g);
68
+ }
69
+ }
70
+ return [...groups];
71
+ }
72
+ /** Pinned `preferId` first, then the rest (failover order). */
73
+ ordered(preferId) {
74
+ if (!preferId)
75
+ return this.transports;
76
+ const pref = this.transports.filter((t) => t.id === preferId);
77
+ if (pref.length === 0)
78
+ throw new Error(`transport "${preferId}" is not registered`);
79
+ return [...pref, ...this.transports.filter((t) => t.id !== preferId)];
80
+ }
81
+ }
82
+ //# sourceMappingURL=transport-pool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-pool.js","sourceRoot":"","sources":["../../src/transport-pool.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,OAAO,aAAa;IACK;IAA7B,YAA6B,UAA4B;QAA5B,eAAU,GAAV,UAAU,CAAkB;IAAG,CAAC;IAE7D,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;IAChC,CAAC;IAED;;qGAEiG;IACjG,IAAI,CACF,QAA+C,EAC/C,WAA+C,EAC/C,WAAyD;QAEzD,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC7B,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;YACnC,IAAI,WAAW,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;gBACzC,SAAS,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,IAAmC,EAAE,QAAiB;QACnE,IAAI,OAAgB,CAAC;QACrB,KAAK,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,MAAM,SAAS,CAAC,QAAQ,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;gBACrD,OAAO;YACT,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,GAAG,GAAG,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,OAAO,IAAI,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACnE,CAAC;IAED;;oFAEgF;IAChF,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,SAAS,CAAC,WAAW;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;QAC9E,CAAC;QACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO;YACL,KAAK;YACL,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACnD,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;SACnD,CAAC;IACJ,CAAC;IAED,sGAAsG;IACtG,KAAK,CAAC,gBAAgB;QACpB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;QACjC,KAAK,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,SAAS,CAAC,gBAAgB,EAAE,CAAC;gBAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,SAAS,CAAC,gBAAgB,EAAE;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;IACrB,CAAC;IAED,+DAA+D;IACvD,OAAO,CAAC,QAAiB;QAC/B,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC,UAAU,CAAC;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC;QAC9D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,cAAc,QAAQ,qBAAqB,CAAC,CAAC;QACpF,OAAO,CAAC,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC;IACxE,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { Database } from '@adonisjs/lucid/database';
2
+ /**
3
+ * Build a standalone Lucid `Database` over an in-memory SQLite (`better-sqlite3`) — the "using Lucid
4
+ * outside an app" pattern. We construct `Database(config, logger, emitter)` directly (the three args
5
+ * Lucid's provider passes) so the transport runs against real SQL with no AdonisJS app boot.
6
+ */
7
+ export declare function makeMemoryDb(): Database;
8
+ /** A fresh in-memory db with the transport tables already created. */
9
+ export declare function makeTransportDb(): Promise<Database>;
10
+ //# sourceMappingURL=db-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-helpers.d.ts","sourceRoot":"","sources":["../../../src/transports/db-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAGpD;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,QAAQ,CAoBvC;AAED,sEAAsE;AACtE,wBAAsB,eAAe,IAAI,OAAO,CAAC,QAAQ,CAAC,CAIzD"}
@@ -0,0 +1,33 @@
1
+ import { Emitter } from '@adonisjs/core/events';
2
+ import { Logger } from '@adonisjs/core/logger';
3
+ import { Database } from '@adonisjs/lucid/database';
4
+ import { createDurableTransportTables } from './db-schema.js';
5
+ /**
6
+ * Build a standalone Lucid `Database` over an in-memory SQLite (`better-sqlite3`) — the "using Lucid
7
+ * outside an app" pattern. We construct `Database(config, logger, emitter)` directly (the three args
8
+ * Lucid's provider passes) so the transport runs against real SQL with no AdonisJS app boot.
9
+ */
10
+ export function makeMemoryDb() {
11
+ const logger = new Logger({ enabled: false });
12
+ const emitter = new Emitter(undefined);
13
+ return new Database({
14
+ connection: 'sqlite',
15
+ connections: {
16
+ sqlite: {
17
+ client: 'better-sqlite3',
18
+ connection: { filename: ':memory:' },
19
+ useNullAsDefault: true,
20
+ // A `:memory:` SQLite db is per-connection: pin the pool to ONE connection so every query
21
+ // (and the schema) hits the same in-memory database.
22
+ pool: { min: 1, max: 1 },
23
+ },
24
+ },
25
+ }, logger, emitter);
26
+ }
27
+ /** A fresh in-memory db with the transport tables already created. */
28
+ export async function makeTransportDb() {
29
+ const db = makeMemoryDb();
30
+ await createDurableTransportTables(db);
31
+ return db;
32
+ }
33
+ //# sourceMappingURL=db-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-helpers.js","sourceRoot":"","sources":["../../../src/transports/db-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,SAAkB,CAAC,CAAC;IAChD,OAAO,IAAI,QAAQ,CACjB;QACE,UAAU,EAAE,QAAQ;QACpB,WAAW,EAAE;YACX,MAAM,EAAE;gBACN,MAAM,EAAE,gBAAgB;gBACxB,UAAU,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE;gBACpC,gBAAgB,EAAE,IAAI;gBACtB,0FAA0F;gBAC1F,qDAAqD;gBACrD,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE;aACzB;SACF;KACF,EACD,MAAM,EACN,OAAO,CACR,CAAC;AACJ,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,EAAE,GAAG,YAAY,EAAE,CAAC;IAC1B,MAAM,4BAA4B,CAAC,EAAE,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { Database } from '@adonisjs/lucid/database';
2
+ /**
3
+ * The DB transport's table names. Distinct from the durable *store* tables (`durable_workflow_runs`
4
+ * etc.) — these carry the point-to-point work channels (tasks / results / heartbeats / control), so
5
+ * the transport can share one database with the store without colliding.
6
+ */
7
+ export declare const TRANSPORT_TABLES: {
8
+ readonly tasks: "durable_transport_tasks";
9
+ readonly results: "durable_transport_results";
10
+ readonly heartbeats: "durable_transport_heartbeats";
11
+ readonly control: "durable_transport_control";
12
+ };
13
+ /**
14
+ * Idempotent DDL for the four transport tables, via Lucid's schema builder (Knex). Portable across
15
+ * SQLite / Postgres / MySQL: JSON payloads (`input`/`output`/`error`/`payload`) are stored as TEXT
16
+ * and (de)serialized by the transport, and every timestamp is an epoch-ms `bigInteger`, so there's
17
+ * no dependency on a dialect's native JSON/date type.
18
+ *
19
+ * Each row is a one-shot message claimed by exactly one consumer (atomic conditional UPDATE on
20
+ * `claimed_by`) and then deleted once handled — the DB is the queue.
21
+ *
22
+ * Call this on boot or once at deploy time. For an AdonisJS app prefer the published migration
23
+ * (`node ace configure @adonis-agora/durable`); this helper is for standalone use and tests.
24
+ */
25
+ export declare function createDurableTransportTables(db: Database): Promise<void>;
26
+ /** Drop every transport table. Used by tests and the migration `down`. */
27
+ export declare function dropDurableTransportTables(db: Database): Promise<void>;
28
+ //# sourceMappingURL=db-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schema.d.ts","sourceRoot":"","sources":["../../../src/transports/db-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;CAKnB,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAsB,4BAA4B,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqE9E;AAED,0EAA0E;AAC1E,wBAAsB,0BAA0B,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5E"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * The DB transport's table names. Distinct from the durable *store* tables (`durable_workflow_runs`
3
+ * etc.) — these carry the point-to-point work channels (tasks / results / heartbeats / control), so
4
+ * the transport can share one database with the store without colliding.
5
+ */
6
+ export const TRANSPORT_TABLES = {
7
+ tasks: 'durable_transport_tasks',
8
+ results: 'durable_transport_results',
9
+ heartbeats: 'durable_transport_heartbeats',
10
+ control: 'durable_transport_control',
11
+ };
12
+ /**
13
+ * Idempotent DDL for the four transport tables, via Lucid's schema builder (Knex). Portable across
14
+ * SQLite / Postgres / MySQL: JSON payloads (`input`/`output`/`error`/`payload`) are stored as TEXT
15
+ * and (de)serialized by the transport, and every timestamp is an epoch-ms `bigInteger`, so there's
16
+ * no dependency on a dialect's native JSON/date type.
17
+ *
18
+ * Each row is a one-shot message claimed by exactly one consumer (atomic conditional UPDATE on
19
+ * `claimed_by`) and then deleted once handled — the DB is the queue.
20
+ *
21
+ * Call this on boot or once at deploy time. For an AdonisJS app prefer the published migration
22
+ * (`node ace configure @adonis-agora/durable`); this helper is for standalone use and tests.
23
+ */
24
+ export async function createDurableTransportTables(db) {
25
+ // Knex's schema builder is stateful — take a FRESH `db.connection().schema` per hasTable/createTable
26
+ // so each DDL statement executes exactly once.
27
+ const conn = () => db.connection().schema;
28
+ // ── tasks: engine → worker (a RemoteTask) ──────────────────────────────────
29
+ if (!(await conn().hasTable(TRANSPORT_TABLES.tasks))) {
30
+ await conn().createTable(TRANSPORT_TABLES.tasks, (table) => {
31
+ table.string('step_id').primary();
32
+ table.string('run_id').notNullable();
33
+ table.integer('seq').notNullable();
34
+ table.string('name').notNullable();
35
+ table.string('grp').notNullable();
36
+ table.text('input');
37
+ table.string('traceparent');
38
+ table.text('context');
39
+ table.string('transport');
40
+ table.integer('attempt').notNullable();
41
+ table.string('claimed_by');
42
+ table.bigInteger('claimed_at');
43
+ table.bigInteger('created_at').notNullable();
44
+ table.index(['grp', 'claimed_at', 'created_at'], 'durable_transport_tasks_grp_idx');
45
+ });
46
+ }
47
+ // ── results: worker → engine (a StepResult) ────────────────────────────────
48
+ if (!(await conn().hasTable(TRANSPORT_TABLES.results))) {
49
+ await conn().createTable(TRANSPORT_TABLES.results, (table) => {
50
+ table.string('step_id').primary();
51
+ table.string('run_id').notNullable();
52
+ table.integer('seq').notNullable();
53
+ table.string('status').notNullable();
54
+ table.text('output');
55
+ table.text('error');
56
+ table.bigInteger('started_at');
57
+ table.text('events');
58
+ table.string('claimed_by');
59
+ table.bigInteger('claimed_at');
60
+ table.bigInteger('created_at').notNullable();
61
+ table.index(['claimed_at', 'created_at'], 'durable_transport_results_idx');
62
+ });
63
+ }
64
+ // ── heartbeats: worker → engine (liveness for a long step) ─────────────────
65
+ if (!(await conn().hasTable(TRANSPORT_TABLES.heartbeats))) {
66
+ await conn().createTable(TRANSPORT_TABLES.heartbeats, (table) => {
67
+ table.increments('id').primary();
68
+ table.string('run_id').notNullable();
69
+ table.integer('seq').notNullable();
70
+ table.string('step_id').notNullable();
71
+ table.string('grp').notNullable();
72
+ table.string('claimed_by');
73
+ table.bigInteger('claimed_at');
74
+ table.bigInteger('created_at').notNullable();
75
+ table.index(['claimed_at', 'created_at'], 'durable_transport_heartbeats_idx');
76
+ });
77
+ }
78
+ // ── control: best-effort control-plane messages (single-consumer) ──────────
79
+ if (!(await conn().hasTable(TRANSPORT_TABLES.control))) {
80
+ await conn().createTable(TRANSPORT_TABLES.control, (table) => {
81
+ table.increments('id').primary();
82
+ table.text('payload').notNullable();
83
+ table.string('claimed_by');
84
+ table.bigInteger('claimed_at');
85
+ table.bigInteger('created_at').notNullable();
86
+ table.index(['claimed_at', 'created_at'], 'durable_transport_control_idx');
87
+ });
88
+ }
89
+ }
90
+ /** Drop every transport table. Used by tests and the migration `down`. */
91
+ export async function dropDurableTransportTables(db) {
92
+ const conn = () => db.connection().schema;
93
+ await conn().dropTableIfExists(TRANSPORT_TABLES.control);
94
+ await conn().dropTableIfExists(TRANSPORT_TABLES.heartbeats);
95
+ await conn().dropTableIfExists(TRANSPORT_TABLES.results);
96
+ await conn().dropTableIfExists(TRANSPORT_TABLES.tasks);
97
+ }
98
+ //# sourceMappingURL=db-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db-schema.js","sourceRoot":"","sources":["../../../src/transports/db-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ import type { Database } from '@adonisjs/lucid/database';
2
+ import { type ControlMessage, type ControlPlane, type Heartbeat, type RemoteTask, type StepResult, type Transport } from '../interfaces.js';
3
+ import { type StepHandler } from '../protocol.js';
4
+ export interface DbTransportOptions {
5
+ /**
6
+ * The Lucid `Database` to read/write. Use the app's own `db` service (no broker, no extra
7
+ * connection) — the database you already have IS the queue.
8
+ */
9
+ db: Database;
10
+ /**
11
+ * The worker group this instance serves. Required to register {@link DbTransport.handle} consumers
12
+ * — the task poll loop claims rows for this group. Omit on an engine-only instance that just
13
+ * dispatches + consumes results/heartbeats.
14
+ */
15
+ group?: string;
16
+ /** Lucid connection name to use. Defaults to the `Database` default connection. */
17
+ connectionName?: string;
18
+ /** Poll interval (ms) for the result/task/heartbeat/control loops. Default 200ms. */
19
+ pollIntervalMs?: number;
20
+ /** How long a claimed-but-unfinished row is owned before it's reclaimable (crash recovery). Default 30s. */
21
+ leaseMs?: number;
22
+ /** Max rows claimed per poll. Default 20. */
23
+ batchSize?: number;
24
+ /** Create the transport tables on first use if missing. Default true. */
25
+ autoCreate?: boolean;
26
+ /** Stable id for this process (stamped on heartbeats / control `from` / `claimed_by`). Default random. */
27
+ instanceId?: string;
28
+ }
29
+ /**
30
+ * A poll-based, DB-table-backed {@link Transport} (and best-effort {@link ControlPlane}) over
31
+ * AdonisJS **Lucid** — DBOS-style. Instead of a broker (Redis/SQS), remote steps are **rows** in the
32
+ * same database the durable store already uses: `dispatch` inserts a task row; a worker poller claims
33
+ * unclaimed task rows (atomic conditional `UPDATE … SET claimed_by`), runs the handler via
34
+ * {@link runStepHandler}, and writes a result row the engine polls. Heartbeats and control messages
35
+ * ride their own tables. Zero new infrastructure — often the simplest production transport.
36
+ *
37
+ * Claiming is portable across SQLite / Postgres / MySQL: it uses a compare-and-set UPDATE on
38
+ * `claimed_by`/`claimed_at` (no `FOR UPDATE SKIP LOCKED`), so multiple workers never double-process a
39
+ * row, and a crashed worker's claim is reclaimed once its lease (`leaseMs`) expires.
40
+ *
41
+ * Trade-off vs a real broker: throughput is bounded by polling + row contention — great for
42
+ * workflow/pipeline scale (modest rate, long steps), not for high-fanout firehoses. The
43
+ * {@link ControlPlane} here is single-consumer (one row → one poller), correct for a single engine
44
+ * instance but NOT a true broadcast.
45
+ *
46
+ * Run one instance engine-side (`onResult` + `dispatch`) and one per worker process (`handle()` for
47
+ * its group). Call {@link start} to begin the engine-side pollers; `handle()` auto-starts the task
48
+ * loop. The wire payloads are the documented `RemoteTask`/`StepResult` JSON.
49
+ *
50
+ * Usually you don't construct this directly: `config/durable.ts` selects it via
51
+ * `transports.db({ ... })` and the provider builds it for you.
52
+ */
53
+ export declare class DbTransport implements Transport, ControlPlane {
54
+ #private;
55
+ constructor(options: DbTransportOptions);
56
+ /** Stable id stamped on heartbeats, control `from`, and `claimed_by`. */
57
+ get instanceId(): string;
58
+ dispatch(task: RemoteTask): Promise<void>;
59
+ /**
60
+ * Register a step handler (worker side). Starts this group's task poll loop on the first call —
61
+ * each claimed task runs through {@link runStepHandler} and its result is written for the engine.
62
+ */
63
+ handle(name: string, fn: StepHandler): void;
64
+ /** Worker side: publish a liveness heartbeat for an in-flight long step. */
65
+ heartbeat(beat: Heartbeat): Promise<void>;
66
+ onResult(handler: (result: StepResult) => Promise<void>): void;
67
+ onHeartbeat(handler: (beat: Heartbeat) => Promise<void>): void;
68
+ publishControl(msg: ControlMessage): Promise<void>;
69
+ onControl(handler: (msg: ControlMessage) => void): void;
70
+ /**
71
+ * No-op convenience: the loops auto-start when `onResult`/`onHeartbeat`/`onControl`/`handle` are
72
+ * registered. Exposed for symmetry and to mirror broker transports — call it after wiring handlers
73
+ * if you prefer an explicit start. Returns once the schema is ready.
74
+ */
75
+ start(): Promise<void>;
76
+ /** Stop every poll loop. Does not close the shared `Database`. */
77
+ stop(): Promise<void>;
78
+ /** Stop the pollers (alias of {@link stop} for the `Transport.close` contract). */
79
+ close(): Promise<void>;
80
+ }
81
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/transports/db.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAKzD,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAqElE,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,EAAE,EAAE,QAAQ,CAAC;IACb;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mFAAmF;IACnF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4GAA4G;IAC5G,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yEAAyE;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0GAA0G;IAC1G,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,qBAAa,WAAY,YAAW,SAAS,EAAE,YAAY;;gBAc7C,OAAO,EAAE,kBAAkB;IAYvC,yEAAyE;IACzE,IAAI,UAAU,IAAI,MAAM,CAEvB;IAoBK,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B/C;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAW3C,4EAA4E;IACtE,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IA4D/C,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAI9D,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAyCxD,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAaxD,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAkFvD;;;;OAIG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,kEAAkE;IAC5D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAK3B,mFAAmF;IAC7E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B"}