@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,84 @@
1
+ import type { AdapterFactory } from '@adonisjs/queue/types';
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
+ /**
5
+ * The wire payloads carried as a queue job's `payload`. Everything that crosses the queue is plain
6
+ * JSON — a `RemoteTask` (engine → worker), a `StepResult` / `Heartbeat` (worker → engine) and a
7
+ * `ControlMessage` (best-effort). The adapter stores `payload: any`, so these helpers round-trip
8
+ * through `JSON.stringify`/`JSON.parse` to guarantee that only JSON-safe values survive (functions,
9
+ * symbols, `undefined` members are dropped exactly as a real broker would drop them).
10
+ */
11
+ /** Serialize a value to a JSON-safe clone. Throws on a non-serializable value (e.g. a cycle). */
12
+ export declare function toJson<T>(value: T): T;
13
+ /** Parse a job payload that we previously wrote with {@link toJson}. */
14
+ export declare function fromJson<T>(value: unknown): T;
15
+ export type TaskPayload = RemoteTask;
16
+ export type ResultPayload = StepResult;
17
+ export type HeartbeatPayload = Heartbeat;
18
+ export type ControlPayload = ControlMessage;
19
+ /**
20
+ * Map the engine's per-call `priority` (higher = more urgent, default/absent = unprioritised) onto an
21
+ * `@adonisjs/queue` job `priority` (lower = more urgent). Returns `undefined` for an absent priority so
22
+ * the default FIFO path is untouched.
23
+ */
24
+ export declare function toBrokerPriority(priority?: number): number | undefined;
25
+ export interface QueueTransportOptions {
26
+ /**
27
+ * Factory for the `@adonisjs/queue` adapter this transport reads/writes. The same kind of factory
28
+ * you hand `@adonisjs/queue`'s `defineConfig` (e.g. `redis(...)`, `knex(...)`, or `FakeAdapter`).
29
+ * One adapter instance is created per transport and reused for every queue.
30
+ */
31
+ adapter: AdapterFactory;
32
+ /**
33
+ * The worker group this instance serves. Required to register {@link QueueTransport.handle}
34
+ * consumers — the task poll loop pulls from this group's task queue. Omit on an engine-only
35
+ * instance that just dispatches + consumes results.
36
+ */
37
+ group?: string;
38
+ /** Queue-name prefix so several apps can share one backend without colliding. Default `durable`. */
39
+ prefix?: string;
40
+ /** Poll interval (ms) for the result/task/heartbeat/control loops. Default 200ms. */
41
+ pollIntervalMs?: number;
42
+ /** Stable id for this process (stamped on heartbeats / control `from`). Default a random id. */
43
+ instanceId?: string;
44
+ }
45
+ /**
46
+ * A `@adonisjs/queue`-backed {@link Transport}. Remote steps are dispatched to a per-group task
47
+ * queue; the worker side runs the registered handler via {@link runStepHandler} and pushes the
48
+ * {@link StepResult} onto a results queue the engine consumes. Heartbeats ride their own queue.
49
+ *
50
+ * `@adonisjs/queue` v0.6 is a one-directional job queue (dispatch → a separate `Worker` process
51
+ * runs `job.execute()`), with no built-in way to await a job's result. This transport instead
52
+ * drives the underlying queue **adapter** directly (`pushOn` / `popFrom` / `completeJob`), so both
53
+ * directions are plain point-to-point queues we fully control. Notably the {@link ControlPlane} here
54
+ * is single-consumer (point-to-point), so it is correct for a single engine instance but does NOT
55
+ * fan out to every pod the way a real pub/sub does.
56
+ *
57
+ * Run one instance engine-side (`onResult` + `dispatch`) and one per worker process (`handle()`).
58
+ * The wire payloads are the documented `RemoteTask`/`StepResult` JSON, so non-Node workers on the
59
+ * same queues interoperate.
60
+ *
61
+ * Usually you don't construct this directly: `config/durable.ts` selects it via
62
+ * `transports.queue({ ... })` and the provider builds it for you.
63
+ */
64
+ export declare class QueueTransport implements Transport, ControlPlane {
65
+ #private;
66
+ constructor(options: QueueTransportOptions);
67
+ /** Stable id stamped on heartbeats and control `from`. */
68
+ get instanceId(): string;
69
+ dispatch(task: RemoteTask): Promise<void>;
70
+ /**
71
+ * Register a step handler (worker side). Starts this group's task poll loop on the first call —
72
+ * each task it pops runs through {@link runStepHandler} and its result is pushed to the engine.
73
+ */
74
+ handle(name: string, fn: StepHandler): void;
75
+ /** Worker side: publish a liveness heartbeat for an in-flight long step. */
76
+ heartbeat(beat: Heartbeat): Promise<void>;
77
+ onResult(handler: (result: StepResult) => Promise<void>): void;
78
+ onHeartbeat(handler: (beat: Heartbeat) => Promise<void>): void;
79
+ publishControl(msg: ControlMessage): Promise<void>;
80
+ onControl(handler: (msg: ControlMessage) => void): void;
81
+ /** Stop every poll loop and destroy the adapter so the process can exit. */
82
+ close(): Promise<void>;
83
+ }
84
+ //# sourceMappingURL=queue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/transports/queue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAwB,cAAc,EAAW,MAAM,uBAAuB,CAAC;AAC3F,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;AAElE;;;;;;GAMG;AAEH,iGAAiG;AACjG,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAErC;AAED,wEAAwE;AACxE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,CAAC,CAO7C;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC;AACrC,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC;AACvC,MAAM,MAAM,gBAAgB,GAAG,SAAS,CAAC;AACzC,MAAM,MAAM,cAAc,GAAG,cAAc,CAAC;AAc5C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAItE;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,EAAE,cAAc,CAAC;IACxB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oGAAoG;IACpG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qFAAqF;IACrF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,cAAe,YAAW,SAAS,EAAE,YAAY;;gBAUhD,OAAO,EAAE,qBAAqB;IAW1C,0DAA0D;IAC1D,IAAI,UAAU,IAAI,MAAM,CAEvB;IAmCK,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/C;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,WAAW,GAAG,IAAI;IAe3C,4EAA4E;IACtE,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ/C,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAM9D,WAAW,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAUxD,cAAc,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxD,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI;IAsCvD,4EAA4E;IACtE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
@@ -0,0 +1,210 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { Pollers } from '../pollers.js';
3
+ import { runStepHandler } from '../protocol.js';
4
+ /**
5
+ * The wire payloads carried as a queue job's `payload`. Everything that crosses the queue is plain
6
+ * JSON — a `RemoteTask` (engine → worker), a `StepResult` / `Heartbeat` (worker → engine) and a
7
+ * `ControlMessage` (best-effort). The adapter stores `payload: any`, so these helpers round-trip
8
+ * through `JSON.stringify`/`JSON.parse` to guarantee that only JSON-safe values survive (functions,
9
+ * symbols, `undefined` members are dropped exactly as a real broker would drop them).
10
+ */
11
+ /** Serialize a value to a JSON-safe clone. Throws on a non-serializable value (e.g. a cycle). */
12
+ export function toJson(value) {
13
+ return JSON.parse(JSON.stringify(value));
14
+ }
15
+ /** Parse a job payload that we previously wrote with {@link toJson}. */
16
+ export function fromJson(value) {
17
+ // The adapter already gives us a structured value; if a driver hands back a raw string
18
+ // (some persist `payload` as text), decode it. Otherwise pass it straight through.
19
+ if (typeof value === 'string') {
20
+ return JSON.parse(value);
21
+ }
22
+ return value;
23
+ }
24
+ /** How often the engine-side / worker-side poll loops ask the adapter for the next job. */
25
+ const DEFAULT_POLL_INTERVAL_MS = 200;
26
+ // `@adonisjs/queue` job priority is the INVERSE of the durable engine's: a queue job runs the LOWEST
27
+ // number first (1..10, default 5), while the engine's admission `priority` is "higher wins". We map
28
+ // so one convention ("higher = more urgent") holds end-to-end. `BASELINE - p` keeps relative order (a
29
+ // higher `p` yields a lower — more urgent — broker number), clamped into the adapter's valid range.
30
+ // Centred on the default so callers have headroom both above and below it.
31
+ const BROKER_PRIORITY_MIN = 1;
32
+ const BROKER_PRIORITY_MAX = 10;
33
+ const BROKER_PRIORITY_BASELINE = 5;
34
+ /**
35
+ * Map the engine's per-call `priority` (higher = more urgent, default/absent = unprioritised) onto an
36
+ * `@adonisjs/queue` job `priority` (lower = more urgent). Returns `undefined` for an absent priority so
37
+ * the default FIFO path is untouched.
38
+ */
39
+ export function toBrokerPriority(priority) {
40
+ if (priority == null)
41
+ return undefined;
42
+ const mapped = Math.round(BROKER_PRIORITY_BASELINE - priority);
43
+ return Math.min(BROKER_PRIORITY_MAX, Math.max(BROKER_PRIORITY_MIN, mapped));
44
+ }
45
+ /**
46
+ * A `@adonisjs/queue`-backed {@link Transport}. Remote steps are dispatched to a per-group task
47
+ * queue; the worker side runs the registered handler via {@link runStepHandler} and pushes the
48
+ * {@link StepResult} onto a results queue the engine consumes. Heartbeats ride their own queue.
49
+ *
50
+ * `@adonisjs/queue` v0.6 is a one-directional job queue (dispatch → a separate `Worker` process
51
+ * runs `job.execute()`), with no built-in way to await a job's result. This transport instead
52
+ * drives the underlying queue **adapter** directly (`pushOn` / `popFrom` / `completeJob`), so both
53
+ * directions are plain point-to-point queues we fully control. Notably the {@link ControlPlane} here
54
+ * is single-consumer (point-to-point), so it is correct for a single engine instance but does NOT
55
+ * fan out to every pod the way a real pub/sub does.
56
+ *
57
+ * Run one instance engine-side (`onResult` + `dispatch`) and one per worker process (`handle()`).
58
+ * The wire payloads are the documented `RemoteTask`/`StepResult` JSON, so non-Node workers on the
59
+ * same queues interoperate.
60
+ *
61
+ * Usually you don't construct this directly: `config/durable.ts` selects it via
62
+ * `transports.queue({ ... })` and the provider builds it for you.
63
+ */
64
+ export class QueueTransport {
65
+ #adapter;
66
+ #group;
67
+ #prefix;
68
+ #pollIntervalMs;
69
+ #instanceId;
70
+ #handlers = new Map();
71
+ #pollers;
72
+ #taskLoop;
73
+ constructor(options) {
74
+ this.#adapter = options.adapter();
75
+ this.#group = options.group;
76
+ this.#prefix = options.prefix ?? 'durable';
77
+ this.#pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
78
+ this.#instanceId = options.instanceId ?? randomUUID();
79
+ // pop()/popFrom() require a worker id be set on the adapter before consuming.
80
+ this.#adapter.setWorkerId(this.#instanceId);
81
+ this.#pollers = new Pollers(this.#pollIntervalMs);
82
+ }
83
+ /** Stable id stamped on heartbeats and control `from`. */
84
+ get instanceId() {
85
+ return this.#instanceId;
86
+ }
87
+ #tasksQueue(group) {
88
+ return `${this.#prefix}:tasks:${group}`;
89
+ }
90
+ #resultsQueue() {
91
+ return `${this.#prefix}:results`;
92
+ }
93
+ #heartbeatsQueue() {
94
+ return `${this.#prefix}:heartbeats`;
95
+ }
96
+ #controlQueue() {
97
+ return `${this.#prefix}:control`;
98
+ }
99
+ /**
100
+ * Build the adapter `JobData` envelope for a JSON-safe payload. A translated `priority` is added
101
+ * only when set, so the default FIFO path is untouched for unprioritised dispatches.
102
+ */
103
+ #job(name, payload, priority) {
104
+ const brokerPriority = toBrokerPriority(priority);
105
+ return {
106
+ id: randomUUID(),
107
+ name,
108
+ payload: toJson(payload),
109
+ attempts: 0,
110
+ createdAt: Date.now(),
111
+ ...(brokerPriority != null ? { priority: brokerPriority } : {}),
112
+ };
113
+ }
114
+ // ---------------------------------------------------------------------------
115
+ // engine → worker
116
+ // ---------------------------------------------------------------------------
117
+ async dispatch(task) {
118
+ await this.#adapter.pushOn(this.#tasksQueue(task.group), this.#job('task', task, task.priority));
119
+ }
120
+ // ---------------------------------------------------------------------------
121
+ // worker side — register a step handler, run it, push the result back
122
+ // ---------------------------------------------------------------------------
123
+ /**
124
+ * Register a step handler (worker side). Starts this group's task poll loop on the first call —
125
+ * each task it pops runs through {@link runStepHandler} and its result is pushed to the engine.
126
+ */
127
+ handle(name, fn) {
128
+ if (!this.#group) {
129
+ throw new Error('QueueTransport needs a `group` option to register handlers');
130
+ }
131
+ this.#handlers.set(name, fn);
132
+ if (!this.#taskLoop) {
133
+ const group = this.#group;
134
+ this.#taskLoop = this.#startLoop(this.#tasksQueue(group), async (job) => {
135
+ const task = fromJson(job.payload);
136
+ const result = await runStepHandler(task, this.#handlers.get(task.name));
137
+ await this.#adapter.pushOn(this.#resultsQueue(), this.#job('result', result));
138
+ });
139
+ }
140
+ }
141
+ /** Worker side: publish a liveness heartbeat for an in-flight long step. */
142
+ async heartbeat(beat) {
143
+ await this.#adapter.pushOn(this.#heartbeatsQueue(), this.#job('heartbeat', beat));
144
+ }
145
+ // ---------------------------------------------------------------------------
146
+ // worker → engine — the engine consumes results + heartbeats
147
+ // ---------------------------------------------------------------------------
148
+ onResult(handler) {
149
+ this.#startLoop(this.#resultsQueue(), async (job) => {
150
+ await handler(fromJson(job.payload));
151
+ });
152
+ }
153
+ onHeartbeat(handler) {
154
+ this.#startLoop(this.#heartbeatsQueue(), async (job) => {
155
+ await handler(fromJson(job.payload));
156
+ });
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // control plane (best-effort, point-to-point)
160
+ // ---------------------------------------------------------------------------
161
+ async publishControl(msg) {
162
+ const stamped = msg.from ? msg : { ...msg, from: this.#instanceId };
163
+ await this.#adapter.pushOn(this.#controlQueue(), this.#job('control', stamped));
164
+ }
165
+ onControl(handler) {
166
+ this.#startLoop(this.#controlQueue(), async (job) => {
167
+ handler(fromJson(job.payload));
168
+ });
169
+ }
170
+ // ---------------------------------------------------------------------------
171
+ // poll loop
172
+ // ---------------------------------------------------------------------------
173
+ /**
174
+ * Poll `queue`, handing each popped job to `onJob` then marking it complete. A throwing `onJob`
175
+ * fails the job (so it is not silently lost) and polling continues. One job is popped per tick;
176
+ * core's {@link Pollers} drains a burst (re-ticking while a job was found) before sleeping, and
177
+ * owns the stop-all bookkeeping. Returns a handle that stops just this loop.
178
+ */
179
+ #startLoop(queue, onJob) {
180
+ return this.#pollers.start(async () => {
181
+ let job;
182
+ try {
183
+ job = await this.#adapter.popFrom(queue);
184
+ }
185
+ catch {
186
+ // A transient adapter error: treat as "no work", retry on the next tick.
187
+ return false;
188
+ }
189
+ if (!job)
190
+ return false;
191
+ try {
192
+ await onJob(job);
193
+ await this.#adapter.completeJob(job.id, queue);
194
+ }
195
+ catch (err) {
196
+ await this.#adapter
197
+ .failJob(job.id, queue, err instanceof Error ? err : new Error(String(err)))
198
+ .catch(() => { });
199
+ }
200
+ return true;
201
+ });
202
+ }
203
+ /** Stop every poll loop and destroy the adapter so the process can exit. */
204
+ async close() {
205
+ this.#pollers.stopAll();
206
+ this.#taskLoop = undefined;
207
+ await this.#adapter.destroy();
208
+ }
209
+ }
210
+ //# sourceMappingURL=queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.js","sourceRoot":"","sources":["../../../src/transports/queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { RemoteStepDef, StateStore, StepCheckpoint, StepError, StepEvent, StepInvocation, StepKind, WorkflowCtx } from './interfaces.js';
2
+ /** A saga undo registered by a completed step, kept with its step name for visibility on failure. */
3
+ export interface Compensation {
4
+ name: string;
5
+ fn: () => Promise<void>;
6
+ }
7
+ /** A finished local step the host should checkpoint and announce (completed or failed). */
8
+ export interface StepRecord {
9
+ runId: string;
10
+ seq: number;
11
+ name: string;
12
+ kind: StepKind;
13
+ input?: unknown;
14
+ events?: StepEvent[] | undefined;
15
+ attempts: number;
16
+ enqueuedAt: Date;
17
+ startedAt: Date;
18
+ workerGroup?: string | undefined;
19
+ }
20
+ /**
21
+ * The narrow surface {@link createWorkflowCtx} needs from the engine — the seam between the
22
+ * authoring API (this module) and the orchestrator (the engine owns lifecycle: emitting events,
23
+ * suspending/resuming runs, dispatching remote steps).
24
+ */
25
+ export interface CtxHost {
26
+ readonly store: StateStore;
27
+ /**
28
+ * Per-execution checkpoint snapshot, loaded ONCE at execution start (the completed prefix this
29
+ * replay walks). Lets each primitive read the prefix from memory instead of a per-call DB SELECT
30
+ * (the O(N²) replay-reads fix). A seq ABSENT from the map is NOT cached — the primitive falls back
31
+ * to the live store, so the checkpoint this resume is waking on (signal/timer/child, written after
32
+ * the snapshot) is always read fresh. New checkpoints written during this execution are inserted
33
+ * into the map so any later same-execution read sees them. Undefined ⇒ always hit the store.
34
+ */
35
+ readonly replay?: Map<number, StepCheckpoint> | undefined;
36
+ clock(): number;
37
+ webhookUrl?: ((token: string) => string) | undefined;
38
+ /** Mark a local step's body as started — emits `step.started` and (optionally) a `running` checkpoint. */
39
+ startStep(step: StepRecord): Promise<void>;
40
+ completeStep(step: StepRecord & {
41
+ output: unknown;
42
+ }): Promise<void>;
43
+ failStep(step: StepRecord & {
44
+ error: StepError;
45
+ }): Promise<void>;
46
+ callRemote<TInput, TOutput>(runId: string, seq: number, step: RemoteStepDef<TInput, TOutput>, input: TInput, queue?: string, transport?: string, admission?: {
47
+ priority?: number | undefined;
48
+ fairnessKey?: string | undefined;
49
+ }): Promise<TOutput>;
50
+ /** Start a child run once, deferred so it can't reentrantly resume a still-running parent. */
51
+ startChild(workflow: string, input: unknown, id: string, priority?: number): void;
52
+ /** Deliver an op to a durable entity (deferred), optionally with a `reply` token for the result. */
53
+ signalEntity?(name: string, key: string, op: string, arg: unknown, reply?: string): void;
54
+ /** Run a local step body through the registered step interceptors (identity if none). */
55
+ interceptStep?<T>(invocation: StepInvocation, body: () => Promise<T>): Promise<T>;
56
+ }
57
+ /**
58
+ * Build the {@link WorkflowCtx} handed to a workflow body. Every primitive is a closure over the
59
+ * position counter (the per-run logical position) and the saga `compensations` stack, so `task`/
60
+ * `child` compose `step`/`waitForSignal` directly. All durability goes through {@link CtxHost}, so
61
+ * the workflow body stays deterministic.
62
+ */
63
+ export declare function createWorkflowCtx(host: CtxHost, runId: string, compensations: Compensation[], workflow?: string): WorkflowCtx;
64
+ //# sourceMappingURL=workflow-ctx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow-ctx.d.ts","sourceRoot":"","sources":["../../src/workflow-ctx.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAGV,aAAa,EACb,UAAU,EACV,cAAc,EACd,SAAS,EACT,SAAS,EACT,cAAc,EACd,QAAQ,EAGR,WAAW,EACZ,MAAM,iBAAiB,CAAC;AAUzB,qGAAqG;AACrG,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,IAAI,CAAC;IACjB,SAAS,EAAE,IAAI,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;;;;;OAOG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,SAAS,CAAC;IAC1D,KAAK,IAAI,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,GAAG,SAAS,CAAC;IACrD,0GAA0G;IAC1G,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,UAAU,CAAC,MAAM,EAAE,OAAO,EACxB,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,EACpC,KAAK,EAAE,MAAM,EACb,KAAK,CAAC,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAC9E,OAAO,CAAC,OAAO,CAAC,CAAC;IACpB,8FAA8F;IAC9F,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClF,oGAAoG;IACpG,YAAY,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzF,yFAAyF;IACzF,aAAa,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnF;AAcD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,YAAY,EAAE,EAC7B,QAAQ,SAAK,GACZ,WAAW,CAgeb"}