@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,430 @@
1
+ import { beforeEach, describe, expect, it } from 'vitest';
2
+ import { WorkflowEngine, } from '../index.js';
3
+ /**
4
+ * Thrown by a {@link StateStoreFactory} to SKIP the contract for an unavailable backend instead of
5
+ * failing it — e.g. a testcontainers DB spec when Docker isn't running. Every contract case catches
6
+ * it, logs once, and returns (a no-op pass), so `pnpm test:db` is green-with-skips off a dev box
7
+ * without Docker rather than red.
8
+ */
9
+ export class StateStoreUnavailableError extends Error {
10
+ isStateStoreUnavailable = true;
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = 'StateStoreUnavailableError';
14
+ }
15
+ }
16
+ function isUnavailable(err) {
17
+ return !!err && typeof err === 'object' && 'isStateStoreUnavailable' in err;
18
+ }
19
+ const at = new Date('2026-06-11T00:00:00.000Z');
20
+ const run = (over = {}) => ({
21
+ id: 'r1',
22
+ workflow: 'checkout',
23
+ workflowVersion: '1',
24
+ status: 'running',
25
+ input: { orderId: 'o1' },
26
+ createdAt: at,
27
+ updatedAt: at,
28
+ ...over,
29
+ });
30
+ const checkpoint = (over = {}) => ({
31
+ runId: 'r1',
32
+ seq: 0,
33
+ name: 'reserve',
34
+ kind: 'local',
35
+ stepId: 'r1:0',
36
+ status: 'completed',
37
+ output: { ok: true },
38
+ attempts: 1,
39
+ enqueuedAt: at,
40
+ startedAt: at,
41
+ finishedAt: at,
42
+ ...over,
43
+ });
44
+ /**
45
+ * The SHARED behavioral contract every `StateStore` must satisfy — in-memory and each ORM adapter
46
+ * alike. Registered as a vitest `describe`; pass a `name` and a {@link StateStoreFactory} that builds
47
+ * a fresh, empty store. The same assertions run against SQLite/in-memory under `pnpm test` and
48
+ * against real Postgres/MySQL (via testcontainers) under `pnpm test:db`, so any drift between an
49
+ * adapter and the canonical (in-memory) semantics — especially the search-attribute side-table
50
+ * pushdown, which is implemented per-store — fails here instead of silently in production.
51
+ *
52
+ * Each adapter's own spec keeps its dialect-specific tests (DDL/longtext/EXISTS-SQL/JSON-tolerance);
53
+ * this suite owns the cross-store behavior so those never drift apart.
54
+ */
55
+ export function runStateStoreContract(name, makeStore) {
56
+ describe(`StateStore contract: ${name}`, () => {
57
+ let store;
58
+ let cleanup;
59
+ let supportsAsyncTransaction = true;
60
+ let supportsTagFilter = true;
61
+ let skipReason;
62
+ let loggedSkip = false;
63
+ beforeEach(async () => {
64
+ try {
65
+ const ctx = await makeStore();
66
+ store = ctx.store;
67
+ cleanup = ctx.cleanup;
68
+ supportsAsyncTransaction = ctx.supportsAsyncTransaction ?? true;
69
+ supportsTagFilter = ctx.supportsTagFilter ?? true;
70
+ skipReason = undefined;
71
+ }
72
+ catch (err) {
73
+ if (isUnavailable(err)) {
74
+ // Backend unavailable (e.g. no Docker for a testcontainers spec): skip — don't fail.
75
+ skipReason = err.message;
76
+ if (!loggedSkip) {
77
+ console.warn(`[state-store-contract] SKIPPING "${name}": ${skipReason}`);
78
+ loggedSkip = true;
79
+ }
80
+ return;
81
+ }
82
+ throw err;
83
+ }
84
+ return async () => {
85
+ await cleanup?.();
86
+ };
87
+ });
88
+ /** Register a contract case that no-ops (passes) when the backend was reported unavailable. */
89
+ const t = (label, fn) => {
90
+ it(label, async () => {
91
+ if (skipReason)
92
+ return;
93
+ await fn();
94
+ });
95
+ };
96
+ // ---- create / get / update --------------------------------------------------------------
97
+ t('creates a run and reads it back with its JSON input', async () => {
98
+ await store.createRun(run());
99
+ const loaded = await store.getRun('r1');
100
+ expect(loaded?.workflow).toBe('checkout');
101
+ expect(loaded?.input).toEqual({ orderId: 'o1' });
102
+ });
103
+ t('returns null for a missing run', async () => {
104
+ expect(await store.getRun('nope')).toBeNull();
105
+ });
106
+ t('updates a run (status/output) and round-trips recoveryAttempts + dead status', async () => {
107
+ await store.createRun(run({ recoveryAttempts: 3 }));
108
+ await store.updateRun('r1', {
109
+ status: 'completed',
110
+ output: { total: 42 },
111
+ updatedAt: at,
112
+ });
113
+ const done = await store.getRun('r1');
114
+ expect(done?.status).toBe('completed');
115
+ expect(done?.output).toEqual({ total: 42 });
116
+ expect(done?.recoveryAttempts).toBe(3);
117
+ await store.updateRun('r1', { status: 'dead', recoveryAttempts: 4 });
118
+ const dead = await store.getRun('r1');
119
+ expect(dead?.status).toBe('dead');
120
+ expect(dead?.recoveryAttempts).toBe(4);
121
+ });
122
+ t('deleteRun removes the run and all its rows (checkpoints, waiters, attributes)', async () => {
123
+ await store.createRun(run({ searchAttributes: { tier: 'pro' } }));
124
+ await store.saveCheckpoint(checkpoint());
125
+ await store.putSignalWaiter({ token: 'approve-r1', runId: 'r1', seq: 0 });
126
+ await store.deleteRun('r1');
127
+ // The run and every child row are gone — not merely marked terminal.
128
+ expect(await store.getRun('r1')).toBeNull();
129
+ expect(await store.listCheckpoints('r1')).toEqual([]);
130
+ expect(await store.listSignalWaiters('approve-')).toEqual([]);
131
+ // The normalized attribute side-table no longer matches it.
132
+ expect(await store.listRuns({
133
+ attributes: [{ key: 'tier', op: 'eq', value: 'pro' }],
134
+ })).toEqual([]);
135
+ });
136
+ t('deleteRun is a no-op for a missing run', async () => {
137
+ await expect(store.deleteRun('nope')).resolves.toBeUndefined();
138
+ });
139
+ t('updateRun maps every patchable field — clears error and patches tags/lockedBy/input/timers', async () => {
140
+ // Guards against per-adapter patch-whitelist drift: a store that maps only a subset of fields
141
+ // (or ignores `undefined` instead of clearing) would silently no-op these and fail here.
142
+ await store.createRun(run({ status: 'failed', error: { message: 'boom' }, tags: ['old'], lockedBy: 'owner-1' }));
143
+ await store.updateRun('r1', {
144
+ status: 'completed',
145
+ output: { ok: true },
146
+ error: undefined, // completion CLEARS the prior error
147
+ input: { orderId: 'o2' },
148
+ tags: ['x', 'y'],
149
+ lockedBy: 'owner-2',
150
+ wakeAt: 123_456,
151
+ lockedUntil: 222_222,
152
+ updatedAt: at,
153
+ });
154
+ const r = await store.getRun('r1');
155
+ expect(r?.status).toBe('completed');
156
+ expect(r?.output).toEqual({ ok: true });
157
+ expect(r?.error).toBeUndefined();
158
+ expect(r?.input).toEqual({ orderId: 'o2' });
159
+ expect(r?.tags).toEqual(['x', 'y']);
160
+ expect(r?.lockedBy).toBe('owner-2');
161
+ expect(r?.wakeAt).toBe(123_456);
162
+ expect(r?.lockedUntil).toBe(222_222);
163
+ });
164
+ // ---- checkpoints ------------------------------------------------------------------------
165
+ t('upserts checkpoints, reads them by (runId, seq), and lists them ordered by seq', async () => {
166
+ await store.createRun(run());
167
+ await store.saveCheckpoint(checkpoint());
168
+ await store.saveCheckpoint(checkpoint({ seq: 1, name: 'charge', output: { chargeId: 'ch_1' } }));
169
+ // Re-save seq 0 with a new output — upsert, not a duplicate row.
170
+ await store.saveCheckpoint(checkpoint({ output: { ok: true, again: true } }));
171
+ expect((await store.getCheckpoint('r1', 0))?.output).toEqual({ ok: true, again: true });
172
+ expect((await store.getCheckpoint('r1', 1))?.name).toBe('charge');
173
+ const list = await store.listCheckpoints('r1');
174
+ expect(list.map((c) => c.seq)).toEqual([0, 1]);
175
+ });
176
+ t('getLatestCheckpointByName returns the highest-seq match (and undefined for none)', async () => {
177
+ await store.createRun(run());
178
+ await store.saveCheckpoint(checkpoint({ seq: 0, name: 'event:progress', output: { pct: 10 } }));
179
+ await store.saveCheckpoint(checkpoint({ seq: 1, name: 'charge', output: { id: 'c1' } }));
180
+ await store.saveCheckpoint(checkpoint({ seq: 2, name: 'event:progress', output: { pct: 50 } }));
181
+ await store.saveCheckpoint(checkpoint({ seq: 3, name: 'event:progress', output: { pct: 90 } }));
182
+ // Optional on the interface (the engine has a fallback), but a conformant store MUST provide
183
+ // it — assert presence, then exercise the fast path.
184
+ const getLatestCheckpointByName = store.getLatestCheckpointByName;
185
+ expect(getLatestCheckpointByName).toBeDefined();
186
+ if (!getLatestCheckpointByName)
187
+ return;
188
+ const latest = await getLatestCheckpointByName.call(store, 'r1', 'event:progress');
189
+ expect(latest?.seq).toBe(3);
190
+ expect(latest?.output).toEqual({ pct: 90 });
191
+ expect(await getLatestCheckpointByName.call(store, 'r1', 'event:missing')).toBeUndefined();
192
+ });
193
+ t('listCheckpointsByNamePrefix returns prefix matches ordered by seq (empty => none)', async () => {
194
+ await store.createRun(run());
195
+ await store.saveCheckpoint(checkpoint({ seq: 0, name: 'reserve' }));
196
+ await store.saveCheckpoint(checkpoint({ seq: 1, name: 'spawn:0', output: 'child-a' }));
197
+ await store.saveCheckpoint(checkpoint({ seq: 2, name: 'signal:child:c2' }));
198
+ await store.saveCheckpoint(checkpoint({ seq: 3, name: 'event:progress' }));
199
+ await store.saveCheckpoint(checkpoint({ seq: 4, name: 'spawn:1', output: 'child-b' }));
200
+ // Optional on the interface (the engine has a fallback), but a conformant store MUST provide
201
+ // it — assert presence, then exercise the fast path.
202
+ const listCheckpointsByNamePrefix = store.listCheckpointsByNamePrefix;
203
+ expect(listCheckpointsByNamePrefix).toBeDefined();
204
+ if (!listCheckpointsByNamePrefix)
205
+ return;
206
+ const matches = await listCheckpointsByNamePrefix.call(store, 'r1', [
207
+ 'signal:child:',
208
+ 'spawn:',
209
+ ]);
210
+ expect(matches.map((c) => c.name)).toEqual(['spawn:0', 'signal:child:c2', 'spawn:1']);
211
+ expect(await listCheckpointsByNamePrefix.call(store, 'r1', [])).toEqual([]);
212
+ });
213
+ t('round-trips checkpoint events and reads back a missing checkpoint as null', async () => {
214
+ await store.createRun(run());
215
+ await store.saveCheckpoint(checkpoint({
216
+ events: [{ at: 1, level: 'error', message: 'p-3 failed', name: 'p-3', status: 'failed' }],
217
+ }));
218
+ expect((await store.getCheckpoint('r1', 0))?.events).toEqual([
219
+ { at: 1, level: 'error', message: 'p-3 failed', name: 'p-3', status: 'failed' },
220
+ ]);
221
+ expect(await store.getCheckpoint('r1', 99)).toBeNull();
222
+ });
223
+ // ---- recovery / dispatch / timer scans --------------------------------------------------
224
+ t('lists incomplete runs, pending runs (FIFO), and due timers', async () => {
225
+ await store.createRun(run({ id: 'running1', status: 'running' }));
226
+ await store.createRun(run({ id: 'suspended1', status: 'suspended', wakeAt: 5_000 }));
227
+ await store.createRun(run({ id: 'done1', status: 'completed' }));
228
+ await store.createRun(run({ id: 'pending2', status: 'pending', createdAt: new Date('2026-06-11T00:00:02.000Z') }));
229
+ await store.createRun(run({ id: 'pending1', status: 'pending', createdAt: new Date('2026-06-11T00:00:01.000Z') }));
230
+ expect((await store.listIncompleteRuns()).map((r) => r.id)).toEqual(['running1']);
231
+ // FIFO by createdAt.
232
+ expect((await store.listPendingRuns(10)).map((r) => r.id)).toEqual(['pending1', 'pending2']);
233
+ expect((await store.listPendingRuns(1)).map((r) => r.id)).toEqual(['pending1']);
234
+ expect((await store.listDueTimers(10_000)).map((r) => r.id)).toEqual(['suspended1']);
235
+ expect(await store.listDueTimers(1_000)).toHaveLength(0);
236
+ });
237
+ // ---- lease / lock -----------------------------------------------------------------------
238
+ t('tryLockRun is atomic and respects lease expiry', async () => {
239
+ await store.createRun(run({ id: 'r1' }));
240
+ expect(await store.tryLockRun('r1', 'A', 2_000, 1_000)).toBe(true);
241
+ // B can't take it while A's lease is live.
242
+ expect(await store.tryLockRun('r1', 'B', 3_000, 1_500)).toBe(false);
243
+ // Once A's lease (2_000) has passed, B reclaims it.
244
+ expect(await store.tryLockRun('r1', 'B', 4_000, 2_500)).toBe(true);
245
+ // Release lets anyone re-acquire immediately.
246
+ await store.releaseRunLock('r1');
247
+ expect(await store.tryLockRun('r1', 'C', 9_000, 2_600)).toBe(true);
248
+ });
249
+ t('renewRunLock only succeeds for the current owner', async () => {
250
+ await store.createRun(run({ id: 'r1' }));
251
+ expect(await store.tryLockRun('r1', 'A', 2_000, 1_000)).toBe(true);
252
+ // The holder heartbeats and keeps the lease.
253
+ expect(await store.renewRunLock('r1', 'A', 5_000)).toBe(true);
254
+ // A different instance can't renew a lease it doesn't hold.
255
+ expect(await store.renewRunLock('r1', 'B', 9_000)).toBe(false);
256
+ // And the renewed lease is honored: B still can't steal it before it expires.
257
+ expect(await store.tryLockRun('r1', 'B', 6_000, 4_000)).toBe(false);
258
+ });
259
+ // ---- list filters: status / statuses / tag ----------------------------------------------
260
+ t('filters listRuns by workflow and by status', async () => {
261
+ await store.createRun(run({ id: 'a', workflow: 'checkout', status: 'running' }));
262
+ await store.createRun(run({ id: 'b', workflow: 'refund', status: 'running' }));
263
+ await store.createRun(run({ id: 'c', workflow: 'checkout', status: 'completed' }));
264
+ expect((await store.listRuns({ workflow: 'checkout' })).map((r) => r.id).sort()).toEqual([
265
+ 'a',
266
+ 'c',
267
+ ]);
268
+ expect((await store.listRuns({ status: 'running' })).map((r) => r.id).sort()).toEqual([
269
+ 'a',
270
+ 'b',
271
+ ]);
272
+ expect((await store.listRuns({ workflow: 'checkout', status: 'running' })).map((r) => r.id)).toEqual(['a']);
273
+ });
274
+ t('filters listRuns by a status set (status IN ...) for singleton admission', async () => {
275
+ await store.createRun(run({ id: 'a', status: 'running' }));
276
+ await store.createRun(run({ id: 'b', status: 'suspended' }));
277
+ await store.createRun(run({ id: 'c', status: 'completed' }));
278
+ await store.createRun(run({ id: 'd', status: 'pending' }));
279
+ expect((await store.listRuns({ statuses: ['running', 'suspended'] })).map((r) => r.id).sort()).toEqual(['a', 'b']);
280
+ // Single + set are ANDed (the narrower set wins).
281
+ expect((await store.listRuns({ status: 'running', statuses: ['running', 'suspended'] })).map((r) => r.id)).toEqual(['a']);
282
+ // Empty set matches nothing.
283
+ expect(await store.listRuns({ statuses: [] })).toHaveLength(0);
284
+ });
285
+ t('filters listRuns by an exact tag (no substring match)', async () => {
286
+ if (!supportsTagFilter)
287
+ return; // Prisma + SQLite: array_contains is unsupported there (see flag doc)
288
+ await store.createRun(run({ id: 'a', tags: ['etl', 'critical'] }));
289
+ await store.createRun(run({ id: 'b', tags: ['etl-foo'] }));
290
+ await store.createRun(run({ id: 'c' })); // no tags
291
+ expect((await store.getRun('a'))?.tags).toEqual(['etl', 'critical']);
292
+ expect((await store.listRuns({ tag: 'etl' })).map((r) => r.id)).toEqual(['a']);
293
+ expect((await store.listRuns({ tag: 'etl-foo' })).map((r) => r.id)).toEqual(['b']);
294
+ expect(await store.listRuns({ tag: 'nope' })).toHaveLength(0);
295
+ });
296
+ t('orders listRuns newest-first and paginates with limit/offset', async () => {
297
+ await store.createRun(run({ id: 'old', createdAt: new Date('2026-06-11T00:00:00.000Z') }));
298
+ await store.createRun(run({ id: 'mid', createdAt: new Date('2026-06-11T00:00:01.000Z') }));
299
+ await store.createRun(run({ id: 'new', createdAt: new Date('2026-06-11T00:00:02.000Z') }));
300
+ expect((await store.listRuns({})).map((r) => r.id)).toEqual(['new', 'mid', 'old']);
301
+ expect((await store.listRuns({ limit: 2 })).map((r) => r.id)).toEqual(['new', 'mid']);
302
+ expect((await store.listRuns({ limit: 2, offset: 1 })).map((r) => r.id)).toEqual([
303
+ 'mid',
304
+ 'old',
305
+ ]);
306
+ });
307
+ // ---- search-attribute pushdown (range + equality + the missing-key contract) ------------
308
+ t('round-trips searchAttributes and answers equality + range attribute queries', async () => {
309
+ await store.createRun(run({ id: 'a', searchAttributes: { amount: 30, tier: 'free' } }));
310
+ await store.createRun(run({ id: 'b', searchAttributes: { amount: 200, tier: 'pro' } }));
311
+ await store.createRun(run({ id: 'c', searchAttributes: { amount: 500, tier: 'pro' } }));
312
+ expect((await store.getRun('b'))?.searchAttributes).toEqual({ amount: 200, tier: 'pro' });
313
+ // Range (numeric).
314
+ expect((await store.listRuns({ attributes: [{ key: 'amount', op: 'gte', value: 200 }] }))
315
+ .map((r) => r.id)
316
+ .sort()).toEqual(['b', 'c']);
317
+ // Two ANDed predicates (string eq + numeric range).
318
+ expect((await store.listRuns({
319
+ attributes: [
320
+ { key: 'tier', op: 'eq', value: 'pro' },
321
+ { key: 'amount', op: 'lt', value: 300 },
322
+ ],
323
+ })).map((r) => r.id)).toEqual(['b']);
324
+ // `ne` excludes the matching value AND absent keys (missing-key-never-matches contract).
325
+ expect((await store.listRuns({ attributes: [{ key: 'tier', op: 'ne', value: 'free' }] }))
326
+ .map((r) => r.id)
327
+ .sort()).toEqual(['b', 'c']);
328
+ });
329
+ t('matches a boolean search attribute by eq/ne', async () => {
330
+ await store.createRun(run({ id: 'a', searchAttributes: { vip: true } }));
331
+ await store.createRun(run({ id: 'b', searchAttributes: { vip: false } }));
332
+ await store.createRun(run({ id: 'c', searchAttributes: { other: 1 } })); // no `vip`
333
+ expect((await store.listRuns({ attributes: [{ key: 'vip', op: 'eq', value: true }] })).map((r) => r.id)).toEqual(['a']);
334
+ // ne=true matches the explicit false but NOT the run missing `vip` (missing-key contract).
335
+ expect((await store.listRuns({ attributes: [{ key: 'vip', op: 'ne', value: true }] })).map((r) => r.id)).toEqual(['b']);
336
+ });
337
+ t('a predicate on an absent key matches nothing (every op)', async () => {
338
+ await store.createRun(run({ id: 'a', searchAttributes: { amount: 100 } }));
339
+ for (const op of ['eq', 'ne', 'gt', 'gte', 'lt', 'lte']) {
340
+ expect(await store.listRuns({ attributes: [{ key: 'missing', op, value: 1 }] })).toHaveLength(0);
341
+ }
342
+ });
343
+ t('re-indexes the search-attribute side-table on update (old values stop matching)', async () => {
344
+ await store.createRun(run({ id: 'a', searchAttributes: { tier: 'free', amount: 10 } }));
345
+ expect((await store.listRuns({ attributes: [{ key: 'tier', op: 'eq', value: 'free' }] })).map((r) => r.id)).toEqual(['a']);
346
+ await store.updateRun('a', { searchAttributes: { tier: 'pro' } });
347
+ expect((await store.listRuns({ attributes: [{ key: 'tier', op: 'eq', value: 'pro' }] })).map((r) => r.id)).toEqual(['a']);
348
+ // Old key/value pairs are gone.
349
+ expect(await store.listRuns({ attributes: [{ key: 'tier', op: 'eq', value: 'free' }] })).toHaveLength(0);
350
+ expect(await store.listRuns({ attributes: [{ key: 'amount', op: 'eq', value: 10 }] })).toHaveLength(0);
351
+ });
352
+ t('combines an attribute predicate with a coarse status filter and paginates', async () => {
353
+ await store.createRun(run({ id: 'a', status: 'running', searchAttributes: { amount: 300 } }));
354
+ await store.createRun(run({ id: 'b', status: 'completed', searchAttributes: { amount: 400 } }));
355
+ await store.createRun(run({ id: 'c', status: 'running', searchAttributes: { amount: 50 } }));
356
+ const res = await store.listRuns({
357
+ status: 'running',
358
+ attributes: [{ key: 'amount', op: 'gte', value: 100 }],
359
+ limit: 10,
360
+ });
361
+ expect(res.map((r) => r.id)).toEqual(['a']);
362
+ });
363
+ // ---- signal waiters & buffered signals --------------------------------------------------
364
+ t('stores, lists by prefix, and atomically takes a signal waiter', async () => {
365
+ await store.putSignalWaiter({ token: 'approve-1', runId: 'r1', seq: 3 });
366
+ await store.putSignalWaiter({ token: 'approve-2', runId: 'r2', seq: 4 });
367
+ await store.putSignalWaiter({ token: 'other-1', runId: 'r3', seq: 5 });
368
+ expect((await store.listSignalWaiters('approve-')).map((w) => w.token).sort()).toEqual([
369
+ 'approve-1',
370
+ 'approve-2',
371
+ ]);
372
+ expect((await store.takeSignalWaiter('approve-1'))?.seq).toBe(3);
373
+ // Taken exactly once.
374
+ expect(await store.takeSignalWaiter('approve-1')).toBeNull();
375
+ });
376
+ t('buffers signals and takes them FIFO per token', async () => {
377
+ await store.bufferSignal('sig', { n: 1 });
378
+ await store.bufferSignal('sig', { n: 2 });
379
+ await store.bufferSignal('other', { n: 9 });
380
+ expect(await store.takeBufferedSignal('sig')).toEqual({ payload: { n: 1 } });
381
+ expect(await store.takeBufferedSignal('sig')).toEqual({ payload: { n: 2 } });
382
+ expect(await store.takeBufferedSignal('sig')).toBeNull();
383
+ expect(await store.takeBufferedSignal('other')).toEqual({ payload: { n: 9 } });
384
+ });
385
+ // ---- transaction (optional) -------------------------------------------------------------
386
+ t('transaction commits the checkpoint atomically and returns the work result', async () => {
387
+ if (!store.transaction)
388
+ return; // store without transactions (rare); skip
389
+ if (!supportsAsyncTransaction)
390
+ return; // sync driver (Drizzle + better-sqlite3); skip — see flag doc
391
+ await store.createRun(run());
392
+ const result = await store.transaction(async (tx) => {
393
+ await tx.saveCheckpoint(checkpoint({ seq: 7, name: 'tx-step', output: { paid: true } }));
394
+ return 'ok';
395
+ });
396
+ expect(result).toBe('ok');
397
+ const cp = await store.getCheckpoint('r1', 7);
398
+ expect(cp?.name).toBe('tx-step');
399
+ expect(cp?.output).toEqual({ paid: true });
400
+ });
401
+ // ---- engine end-to-end durability -------------------------------------------------------
402
+ t('runs the engine end-to-end durably, resuming without re-running completed steps', async () => {
403
+ const engine = new WorkflowEngine({ store });
404
+ let aRuns = 0;
405
+ let failOnce = true;
406
+ engine.register('wf', '1', async (ctx) => {
407
+ const a = await ctx.step('a', async () => {
408
+ aRuns += 1;
409
+ return 10;
410
+ });
411
+ const b = await ctx.step('b', async () => {
412
+ if (failOnce) {
413
+ failOnce = false;
414
+ throw new Error('boom');
415
+ }
416
+ return a + 5;
417
+ });
418
+ return b;
419
+ });
420
+ await engine.start('wf', { x: 1 }, 'run1');
421
+ expect((await engine.waitForRun('run1')).status).toBe('failed');
422
+ const resumed = await engine.resume('run1');
423
+ expect(resumed.status).toBe('completed');
424
+ expect(resumed.output).toBe(15);
425
+ // Step `a` checkpointed `completed` the first turn, so replay returns it instead of re-running.
426
+ expect(aRuns).toBe(1);
427
+ });
428
+ });
429
+ }
430
+ //# sourceMappingURL=state-store-conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store-conformance.js","sourceRoot":"","sources":["../../../src/testing-kit/state-store-conformance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** A step body that throws once, then returns `value` — drives a retry, or a crash-then-resume. */
2
+ export declare function failOnce<T>(value: T, error?: Error): () => Promise<T>;
3
+ /** A step body that throws the first `n` times, then returns `value`. */
4
+ export declare function failTimes<T>(n: number, value: T, error?: Error): () => Promise<T>;
5
+ //# sourceMappingURL=steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../../src/testing-kit/steps.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,wBAAgB,QAAQ,CAAC,CAAC,EACxB,KAAK,EAAE,CAAC,EACR,KAAK,GAAE,KAAqC,GAC3C,MAAM,OAAO,CAAC,CAAC,CAAC,CAElB;AAED,yEAAyE;AACzE,wBAAgB,SAAS,CAAC,CAAC,EACzB,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,CAAC,EACR,KAAK,GAAE,KAAqC,GAC3C,MAAM,OAAO,CAAC,CAAC,CAAC,CAOlB"}
@@ -0,0 +1,15 @@
1
+ /** A step body that throws once, then returns `value` — drives a retry, or a crash-then-resume. */
2
+ export function failOnce(value, error = new Error('injected failure')) {
3
+ return failTimes(1, value, error);
4
+ }
5
+ /** A step body that throws the first `n` times, then returns `value`. */
6
+ export function failTimes(n, value, error = new Error('injected failure')) {
7
+ let calls = 0;
8
+ return async () => {
9
+ calls += 1;
10
+ if (calls <= n)
11
+ throw error;
12
+ return value;
13
+ };
14
+ }
15
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../../src/testing-kit/steps.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,MAAM,UAAU,QAAQ,CACtB,KAAQ,EACR,QAAe,IAAI,KAAK,CAAC,kBAAkB,CAAC;IAE5C,OAAO,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,SAAS,CACvB,CAAS,EACT,KAAQ,EACR,QAAe,IAAI,KAAK,CAAC,kBAAkB,CAAC;IAE5C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,OAAO,KAAK,IAAI,EAAE;QAChB,KAAK,IAAI,CAAC,CAAC;QACX,IAAI,KAAK,IAAI,CAAC;YAAE,MAAM,KAAK,CAAC;QAC5B,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type Transport } from '../index.js';
2
+ /** A transport that can register worker handlers (every shipped transport does). */
3
+ export type HandleableTransport = Transport & {
4
+ handle(name: string, fn: (input: unknown) => Promise<unknown>): void;
5
+ close?(): Promise<void>;
6
+ };
7
+ /**
8
+ * The contract every `Transport` must satisfy: a remote step dispatched through it round-trips to a
9
+ * worker and back (success), and a throwing handler surfaces as a failed run (failure). Point it at
10
+ * a freshly constructed transport (engine-side + worker `group` in one instance) to prove parity —
11
+ * useful when adding a new transport. Throws on any mismatch; closes the transport when done.
12
+ *
13
+ * `idPrefix` keeps run ids unique across invocations against real, shared infra (queues/tables).
14
+ */
15
+ export declare function assertTransportConformance(transport: HandleableTransport, idPrefix?: string): Promise<void>;
16
+ //# sourceMappingURL=transport-conformance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-conformance.d.ts","sourceRoot":"","sources":["../../../src/testing-kit/transport-conformance.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,aAAa,CAAC;AAErB,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG;IAC5C,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC;IACrE,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB,CAAC;AA0BF;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAC9C,SAAS,EAAE,mBAAmB,EAC9B,QAAQ,SAAS,GAChB,OAAO,CAAC,IAAI,CAAC,CA+Bf"}
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+ import { InMemoryStateStore, WorkflowEngine, } from '../index.js';
3
+ const echo = {
4
+ name: 'conformance.echo',
5
+ group: 'conformance',
6
+ input: z.object({ n: z.number() }),
7
+ output: z.object({ doubled: z.number() }),
8
+ __remote: true,
9
+ };
10
+ /**
11
+ * A durable `ctx.call` suspends the run; the worker result resumes it asynchronously (on whatever
12
+ * tick/poll the transport delivers on). Poll the store until the run reaches a terminal state —
13
+ * with a generous budget so a poll-based transport (DB/SQS) has time to round-trip.
14
+ */
15
+ async function settle(store, runId, timeoutMs = 15_000) {
16
+ const deadline = Date.now() + timeoutMs;
17
+ while (Date.now() < deadline) {
18
+ const run = await store.getRun(runId);
19
+ if (run && run.status !== 'pending' && run.status !== 'running' && run.status !== 'suspended')
20
+ return run;
21
+ await new Promise((r) => setTimeout(r, 25));
22
+ }
23
+ throw new Error(`run ${runId} did not settle within ${timeoutMs}ms`);
24
+ }
25
+ /**
26
+ * The contract every `Transport` must satisfy: a remote step dispatched through it round-trips to a
27
+ * worker and back (success), and a throwing handler surfaces as a failed run (failure). Point it at
28
+ * a freshly constructed transport (engine-side + worker `group` in one instance) to prove parity —
29
+ * useful when adding a new transport. Throws on any mismatch; closes the transport when done.
30
+ *
31
+ * `idPrefix` keeps run ids unique across invocations against real, shared infra (queues/tables).
32
+ */
33
+ export async function assertTransportConformance(transport, idPrefix = 'conf') {
34
+ try {
35
+ // One engine/store/transport — a durable remote step routes its result back to this engine,
36
+ // which resumes the run. (Two engines on one transport would fight over the result stream.)
37
+ const store = new InMemoryStateStore();
38
+ const engine = new WorkflowEngine({ store, transport });
39
+ engine.register('conf-ok', '1', async (ctx) => (await ctx.call(echo, { n: 21 })).doubled);
40
+ engine.register('conf-fail', '1', async (ctx) => ctx.call(echo, { n: 1 }));
41
+ // success: the worker doubles the input
42
+ transport.handle('conformance.echo', async (input) => ({
43
+ doubled: input.n * 2,
44
+ }));
45
+ await engine.start('conf-ok', {}, `${idPrefix}-ok`);
46
+ const ok = await settle(store, `${idPrefix}-ok`);
47
+ if (ok.status !== 'completed' || ok.output !== 42) {
48
+ throw new Error(`expected completed/42, got ${JSON.stringify(ok)}`);
49
+ }
50
+ // failure: a throwing handler surfaces as a failed run (re-register the same step to throw)
51
+ transport.handle('conformance.echo', async () => {
52
+ throw new Error('handler boom');
53
+ });
54
+ await engine.start('conf-fail', {}, `${idPrefix}-fail`);
55
+ const failed = await settle(store, `${idPrefix}-fail`);
56
+ if (failed.status !== 'failed') {
57
+ throw new Error(`expected failed, got ${JSON.stringify(failed)}`);
58
+ }
59
+ }
60
+ finally {
61
+ await transport.close?.();
62
+ }
63
+ }
64
+ //# sourceMappingURL=transport-conformance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport-conformance.js","sourceRoot":"","sources":["../../../src/testing-kit/transport-conformance.ts"],"names":[],"mappings":"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"}
@@ -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 declare const STATE_STORE: unique symbol;
16
+ export declare const TRANSPORT: unique symbol;
17
+ export declare const DURABLE_OPTIONS: unique symbol;
18
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,WAAW,eAA2C,CAAC;AACpE,eAAO,MAAM,SAAS,eAAyC,CAAC;AAChE,eAAO,MAAM,eAAe,eAA+C,CAAC"}