@adonis-agora/durable 0.49.0 → 0.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (324) hide show
  1. package/CHANGELOG.md +261 -0
  2. package/README.md +53 -22
  3. package/dist/assets/spa/assets/index-DupjrK7N.js +16 -0
  4. package/dist/assets/spa/assets/index-DupjrK7N.js.map +1 -0
  5. package/dist/assets/spa/index.html +1 -1
  6. package/dist/commands/durable_worker.d.ts.map +1 -1
  7. package/dist/commands/durable_worker.js +9 -8
  8. package/dist/commands/durable_worker.js.map +1 -1
  9. package/dist/configure.d.ts.map +1 -1
  10. package/dist/configure.js +1 -0
  11. package/dist/configure.js.map +1 -1
  12. package/dist/providers/dashboard_provider.d.ts +2 -0
  13. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  14. package/dist/providers/dashboard_provider.js +50 -6
  15. package/dist/providers/dashboard_provider.js.map +1 -1
  16. package/dist/providers/durable_provider.d.ts.map +1 -1
  17. package/dist/providers/durable_provider.js +143 -34
  18. package/dist/providers/durable_provider.js.map +1 -1
  19. package/dist/src/admission-redis/redis-admission-backend.d.ts.map +1 -1
  20. package/dist/src/admission-redis/redis-admission-backend.js +3 -1
  21. package/dist/src/admission-redis/redis-admission-backend.js.map +1 -1
  22. package/dist/src/ambient-step.d.ts +24 -0
  23. package/dist/src/ambient-step.d.ts.map +1 -0
  24. package/dist/src/ambient-step.js +42 -0
  25. package/dist/src/ambient-step.js.map +1 -0
  26. package/dist/src/base-workflow.d.ts +10 -1
  27. package/dist/src/base-workflow.d.ts.map +1 -1
  28. package/dist/src/base-workflow.js.map +1 -1
  29. package/dist/src/codec-state-store.d.ts +28 -2
  30. package/dist/src/codec-state-store.d.ts.map +1 -1
  31. package/dist/src/codec-state-store.js +61 -3
  32. package/dist/src/codec-state-store.js.map +1 -1
  33. package/dist/src/commands/worker.d.ts +4 -1
  34. package/dist/src/commands/worker.d.ts.map +1 -1
  35. package/dist/src/commands/worker.js +27 -3
  36. package/dist/src/commands/worker.js.map +1 -1
  37. package/dist/src/config_types.d.ts +6 -0
  38. package/dist/src/config_types.d.ts.map +1 -1
  39. package/dist/src/control-plane-redis/redis-control-plane.d.ts.map +1 -1
  40. package/dist/src/control-plane-redis/redis-control-plane.js +22 -6
  41. package/dist/src/control-plane-redis/redis-control-plane.js.map +1 -1
  42. package/dist/src/control-planes/factory.d.ts +6 -0
  43. package/dist/src/control-planes/factory.d.ts.map +1 -1
  44. package/dist/src/control-planes/factory.js +1 -0
  45. package/dist/src/control-planes/factory.js.map +1 -1
  46. package/dist/src/dashboard/gateway-adapter.d.ts +15 -5
  47. package/dist/src/dashboard/gateway-adapter.d.ts.map +1 -1
  48. package/dist/src/dashboard/gateway-adapter.js +71 -7
  49. package/dist/src/dashboard/gateway-adapter.js.map +1 -1
  50. package/dist/src/dashboard/handlers.d.ts +53 -1
  51. package/dist/src/dashboard/handlers.d.ts.map +1 -1
  52. package/dist/src/dashboard/handlers.js +200 -20
  53. package/dist/src/dashboard/handlers.js.map +1 -1
  54. package/dist/src/dashboard/index.d.ts +2 -2
  55. package/dist/src/dashboard/index.d.ts.map +1 -1
  56. package/dist/src/dashboard/index.js +2 -2
  57. package/dist/src/dashboard/index.js.map +1 -1
  58. package/dist/src/dashboard/openapi.d.ts.map +1 -1
  59. package/dist/src/dashboard/openapi.js +71 -1
  60. package/dist/src/dashboard/openapi.js.map +1 -1
  61. package/dist/src/define_config.d.ts +122 -8
  62. package/dist/src/define_config.d.ts.map +1 -1
  63. package/dist/src/define_config.js.map +1 -1
  64. package/dist/src/diagnostics-bridge.d.ts +16 -3
  65. package/dist/src/diagnostics-bridge.d.ts.map +1 -1
  66. package/dist/src/diagnostics-bridge.js +9 -3
  67. package/dist/src/diagnostics-bridge.js.map +1 -1
  68. package/dist/src/discovery-roots.d.ts +92 -0
  69. package/dist/src/discovery-roots.d.ts.map +1 -0
  70. package/dist/src/discovery-roots.js +150 -0
  71. package/dist/src/discovery-roots.js.map +1 -0
  72. package/dist/src/engine.d.ts +418 -20
  73. package/dist/src/engine.d.ts.map +1 -1
  74. package/dist/src/engine.js +1523 -159
  75. package/dist/src/engine.js.map +1 -1
  76. package/dist/src/entities.d.ts +36 -1
  77. package/dist/src/entities.d.ts.map +1 -1
  78. package/dist/src/entities.js +65 -4
  79. package/dist/src/entities.js.map +1 -1
  80. package/dist/src/errors.d.ts +36 -0
  81. package/dist/src/errors.d.ts.map +1 -1
  82. package/dist/src/errors.js +44 -0
  83. package/dist/src/errors.js.map +1 -1
  84. package/dist/src/event-trigger-bridge.d.ts +8 -0
  85. package/dist/src/event-trigger-bridge.d.ts.map +1 -1
  86. package/dist/src/event-trigger-bridge.js +24 -3
  87. package/dist/src/event-trigger-bridge.js.map +1 -1
  88. package/dist/src/handshake/announced.d.ts +27 -0
  89. package/dist/src/handshake/announced.d.ts.map +1 -1
  90. package/dist/src/handshake/announced.js +62 -0
  91. package/dist/src/handshake/announced.js.map +1 -1
  92. package/dist/src/handshake/directory.d.ts +92 -0
  93. package/dist/src/handshake/directory.d.ts.map +1 -0
  94. package/dist/src/handshake/directory.js +139 -0
  95. package/dist/src/handshake/directory.js.map +1 -0
  96. package/dist/src/hooks/barrel-sources.d.ts +28 -0
  97. package/dist/src/hooks/barrel-sources.d.ts.map +1 -0
  98. package/dist/src/hooks/barrel-sources.js +92 -0
  99. package/dist/src/hooks/barrel-sources.js.map +1 -0
  100. package/dist/src/hooks/steps.d.ts +12 -3
  101. package/dist/src/hooks/steps.d.ts.map +1 -1
  102. package/dist/src/hooks/steps.js +7 -11
  103. package/dist/src/hooks/steps.js.map +1 -1
  104. package/dist/src/hooks/workflows.d.ts +12 -3
  105. package/dist/src/hooks/workflows.d.ts.map +1 -1
  106. package/dist/src/hooks/workflows.js +7 -13
  107. package/dist/src/hooks/workflows.js.map +1 -1
  108. package/dist/src/index.d.ts +12 -3
  109. package/dist/src/index.d.ts.map +1 -1
  110. package/dist/src/index.js +12 -3
  111. package/dist/src/index.js.map +1 -1
  112. package/dist/src/interfaces.d.ts +309 -21
  113. package/dist/src/interfaces.d.ts.map +1 -1
  114. package/dist/src/interfaces.js +10 -0
  115. package/dist/src/interfaces.js.map +1 -1
  116. package/dist/src/metrics.d.ts.map +1 -1
  117. package/dist/src/metrics.js +5 -0
  118. package/dist/src/metrics.js.map +1 -1
  119. package/dist/src/namespaces.d.ts +17 -0
  120. package/dist/src/namespaces.d.ts.map +1 -0
  121. package/dist/src/namespaces.js +24 -0
  122. package/dist/src/namespaces.js.map +1 -0
  123. package/dist/src/otel/durable-metrics.d.ts.map +1 -1
  124. package/dist/src/otel/durable-metrics.js +5 -0
  125. package/dist/src/otel/durable-metrics.js.map +1 -1
  126. package/dist/src/otel/durable-otel.d.ts.map +1 -1
  127. package/dist/src/otel/durable-otel.js +5 -0
  128. package/dist/src/otel/durable-otel.js.map +1 -1
  129. package/dist/src/pollers.d.ts +10 -1
  130. package/dist/src/pollers.d.ts.map +1 -1
  131. package/dist/src/pollers.js +15 -5
  132. package/dist/src/pollers.js.map +1 -1
  133. package/dist/src/protocol.d.ts +12 -0
  134. package/dist/src/protocol.d.ts.map +1 -1
  135. package/dist/src/protocol.js +27 -1
  136. package/dist/src/protocol.js.map +1 -1
  137. package/dist/src/remote-event.d.ts +6 -0
  138. package/dist/src/remote-event.d.ts.map +1 -0
  139. package/dist/src/remote-event.js +19 -0
  140. package/dist/src/remote-event.js.map +1 -0
  141. package/dist/src/remote-workflow-executor.d.ts +34 -12
  142. package/dist/src/remote-workflow-executor.d.ts.map +1 -1
  143. package/dist/src/remote-workflow-executor.js +42 -40
  144. package/dist/src/remote-workflow-executor.js.map +1 -1
  145. package/dist/src/run-detail-summary.d.ts +90 -3
  146. package/dist/src/run-detail-summary.d.ts.map +1 -1
  147. package/dist/src/run-detail-summary.js +360 -2
  148. package/dist/src/run-detail-summary.js.map +1 -1
  149. package/dist/src/run-facets.d.ts +48 -0
  150. package/dist/src/run-facets.d.ts.map +1 -0
  151. package/dist/src/run-facets.js +100 -0
  152. package/dist/src/run-facets.js.map +1 -0
  153. package/dist/src/run-gateway/interface.d.ts +27 -1
  154. package/dist/src/run-gateway/interface.d.ts.map +1 -1
  155. package/dist/src/run-gateway/proxy-run-gateway.d.ts +32 -4
  156. package/dist/src/run-gateway/proxy-run-gateway.d.ts.map +1 -1
  157. package/dist/src/run-gateway/proxy-run-gateway.js +101 -5
  158. package/dist/src/run-gateway/proxy-run-gateway.js.map +1 -1
  159. package/dist/src/run-gateway/run-request-responder.d.ts +18 -5
  160. package/dist/src/run-gateway/run-request-responder.d.ts.map +1 -1
  161. package/dist/src/run-gateway/run-request-responder.js +155 -32
  162. package/dist/src/run-gateway/run-request-responder.js.map +1 -1
  163. package/dist/src/run-gateway/store-run-gateway.d.ts +23 -1
  164. package/dist/src/run-gateway/store-run-gateway.d.ts.map +1 -1
  165. package/dist/src/run-gateway/store-run-gateway.js +38 -0
  166. package/dist/src/run-gateway/store-run-gateway.js.map +1 -1
  167. package/dist/src/search-attributes-schema.d.ts +44 -0
  168. package/dist/src/search-attributes-schema.d.ts.map +1 -0
  169. package/dist/src/search-attributes-schema.js +51 -0
  170. package/dist/src/search-attributes-schema.js.map +1 -0
  171. package/dist/src/singleton-admission.d.ts +75 -0
  172. package/dist/src/singleton-admission.d.ts.map +1 -0
  173. package/dist/src/singleton-admission.js +156 -0
  174. package/dist/src/singleton-admission.js.map +1 -0
  175. package/dist/src/singleton-gate.d.ts +23 -8
  176. package/dist/src/singleton-gate.d.ts.map +1 -1
  177. package/dist/src/singleton-gate.js +59 -12
  178. package/dist/src/singleton-gate.js.map +1 -1
  179. package/dist/src/standard-schema.d.ts +83 -0
  180. package/dist/src/standard-schema.d.ts.map +1 -0
  181. package/dist/src/standard-schema.js +31 -0
  182. package/dist/src/standard-schema.js.map +1 -0
  183. package/dist/src/step-discovery.d.ts +21 -11
  184. package/dist/src/step-discovery.d.ts.map +1 -1
  185. package/dist/src/step-discovery.js +86 -45
  186. package/dist/src/step-discovery.js.map +1 -1
  187. package/dist/src/step-ref.d.ts +38 -12
  188. package/dist/src/step-ref.d.ts.map +1 -1
  189. package/dist/src/step-ref.js +5 -13
  190. package/dist/src/step-ref.js.map +1 -1
  191. package/dist/src/stores/factory.d.ts +6 -0
  192. package/dist/src/stores/factory.d.ts.map +1 -1
  193. package/dist/src/stores/factory.js +4 -1
  194. package/dist/src/stores/factory.js.map +1 -1
  195. package/dist/src/stores/lucid-helpers.d.ts +2 -0
  196. package/dist/src/stores/lucid-helpers.d.ts.map +1 -1
  197. package/dist/src/stores/lucid-helpers.js +7 -0
  198. package/dist/src/stores/lucid-helpers.js.map +1 -1
  199. package/dist/src/stores/lucid-mappers.d.ts +25 -0
  200. package/dist/src/stores/lucid-mappers.d.ts.map +1 -1
  201. package/dist/src/stores/lucid-mappers.js +81 -18
  202. package/dist/src/stores/lucid-mappers.js.map +1 -1
  203. package/dist/src/stores/lucid-schema.d.ts +59 -1
  204. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  205. package/dist/src/stores/lucid-schema.js +271 -25
  206. package/dist/src/stores/lucid-schema.js.map +1 -1
  207. package/dist/src/stores/lucid.d.ts +61 -2
  208. package/dist/src/stores/lucid.d.ts.map +1 -1
  209. package/dist/src/stores/lucid.js +346 -41
  210. package/dist/src/stores/lucid.js.map +1 -1
  211. package/dist/src/telescope/dashboard.d.ts.map +1 -1
  212. package/dist/src/telescope/dashboard.js +30 -1
  213. package/dist/src/telescope/dashboard.js.map +1 -1
  214. package/dist/src/telescope/data-providers.d.ts +19 -1
  215. package/dist/src/telescope/data-providers.d.ts.map +1 -1
  216. package/dist/src/telescope/data-providers.js +119 -3
  217. package/dist/src/telescope/data-providers.js.map +1 -1
  218. package/dist/src/telescope/extension.d.ts.map +1 -1
  219. package/dist/src/telescope/extension.js +2 -1
  220. package/dist/src/telescope/extension.js.map +1 -1
  221. package/dist/src/telescope/index.d.ts +1 -1
  222. package/dist/src/telescope/index.d.ts.map +1 -1
  223. package/dist/src/telescope/index.js +1 -1
  224. package/dist/src/telescope/index.js.map +1 -1
  225. package/dist/src/testing/in-memory-state-store.d.ts +44 -15
  226. package/dist/src/testing/in-memory-state-store.d.ts.map +1 -1
  227. package/dist/src/testing/in-memory-state-store.js +204 -41
  228. package/dist/src/testing/in-memory-state-store.js.map +1 -1
  229. package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts +16 -0
  230. package/dist/src/testing-kit/checkpoint-aggregation-contract.d.ts.map +1 -0
  231. package/dist/src/testing-kit/checkpoint-aggregation-contract.js +228 -0
  232. package/dist/src/testing-kit/checkpoint-aggregation-contract.js.map +1 -0
  233. package/dist/src/testing-kit/state-store-conformance.d.ts.map +1 -1
  234. package/dist/src/testing-kit/state-store-conformance.js +355 -3
  235. package/dist/src/testing-kit/state-store-conformance.js.map +1 -1
  236. package/dist/src/transport-pool.d.ts +15 -1
  237. package/dist/src/transport-pool.d.ts.map +1 -1
  238. package/dist/src/transport-pool.js +50 -4
  239. package/dist/src/transport-pool.js.map +1 -1
  240. package/dist/src/transports/adaptive-concurrency.d.ts +168 -0
  241. package/dist/src/transports/adaptive-concurrency.d.ts.map +1 -0
  242. package/dist/src/transports/adaptive-concurrency.js +353 -0
  243. package/dist/src/transports/adaptive-concurrency.js.map +1 -0
  244. package/dist/src/transports/bullmq/adaptive-concurrency.d.ts +1 -143
  245. package/dist/src/transports/bullmq/adaptive-concurrency.d.ts.map +1 -1
  246. package/dist/src/transports/bullmq/adaptive-concurrency.js +3 -311
  247. package/dist/src/transports/bullmq/adaptive-concurrency.js.map +1 -1
  248. package/dist/src/transports/bullmq/bullmq-transport.d.ts +49 -1
  249. package/dist/src/transports/bullmq/bullmq-transport.d.ts.map +1 -1
  250. package/dist/src/transports/bullmq/bullmq-transport.js +330 -38
  251. package/dist/src/transports/bullmq/bullmq-transport.js.map +1 -1
  252. package/dist/src/transports/bullmq/deps.d.ts +18 -2
  253. package/dist/src/transports/bullmq/deps.d.ts.map +1 -1
  254. package/dist/src/transports/bullmq/deps.js +44 -2
  255. package/dist/src/transports/bullmq/deps.js.map +1 -1
  256. package/dist/src/transports/db-helpers.d.ts +39 -0
  257. package/dist/src/transports/db-helpers.d.ts.map +1 -1
  258. package/dist/src/transports/db-helpers.js +73 -0
  259. package/dist/src/transports/db-helpers.js.map +1 -1
  260. package/dist/src/transports/db-remote.d.ts +53 -0
  261. package/dist/src/transports/db-remote.d.ts.map +1 -0
  262. package/dist/src/transports/db-remote.js +147 -0
  263. package/dist/src/transports/db-remote.js.map +1 -0
  264. package/dist/src/transports/db-schema.d.ts +44 -1
  265. package/dist/src/transports/db-schema.d.ts.map +1 -1
  266. package/dist/src/transports/db-schema.js +227 -88
  267. package/dist/src/transports/db-schema.js.map +1 -1
  268. package/dist/src/transports/db.d.ts +189 -6
  269. package/dist/src/transports/db.d.ts.map +1 -1
  270. package/dist/src/transports/db.js +1291 -137
  271. package/dist/src/transports/db.js.map +1 -1
  272. package/dist/src/transports/event-emitter.d.ts +8 -0
  273. package/dist/src/transports/event-emitter.d.ts.map +1 -1
  274. package/dist/src/transports/event-emitter.js +36 -3
  275. package/dist/src/transports/event-emitter.js.map +1 -1
  276. package/dist/src/transports/factory.d.ts +110 -5
  277. package/dist/src/transports/factory.d.ts.map +1 -1
  278. package/dist/src/transports/factory.js +56 -9
  279. package/dist/src/transports/factory.js.map +1 -1
  280. package/dist/src/transports/queue-mock-adapter.d.ts +7 -2
  281. package/dist/src/transports/queue-mock-adapter.d.ts.map +1 -1
  282. package/dist/src/transports/queue-mock-adapter.js +18 -2
  283. package/dist/src/transports/queue-mock-adapter.js.map +1 -1
  284. package/dist/src/transports/queue-remote.d.ts +146 -0
  285. package/dist/src/transports/queue-remote.d.ts.map +1 -0
  286. package/dist/src/transports/queue-remote.js +398 -0
  287. package/dist/src/transports/queue-remote.js.map +1 -0
  288. package/dist/src/transports/queue.d.ts +159 -6
  289. package/dist/src/transports/queue.d.ts.map +1 -1
  290. package/dist/src/transports/queue.js +747 -37
  291. package/dist/src/transports/queue.js.map +1 -1
  292. package/dist/src/transports/task-failure.d.ts +31 -0
  293. package/dist/src/transports/task-failure.d.ts.map +1 -0
  294. package/dist/src/transports/task-failure.js +50 -0
  295. package/dist/src/transports/task-failure.js.map +1 -0
  296. package/dist/src/workflow-als.d.ts +1 -1
  297. package/dist/src/workflow-als.d.ts.map +1 -1
  298. package/dist/src/workflow-ctx.d.ts +10 -0
  299. package/dist/src/workflow-ctx.d.ts.map +1 -1
  300. package/dist/src/workflow-ctx.js +97 -15
  301. package/dist/src/workflow-ctx.js.map +1 -1
  302. package/dist/src/workflow-discovery.d.ts +32 -41
  303. package/dist/src/workflow-discovery.d.ts.map +1 -1
  304. package/dist/src/workflow-discovery.js +65 -88
  305. package/dist/src/workflow-discovery.js.map +1 -1
  306. package/dist/src/workflow-ref.d.ts +24 -0
  307. package/dist/src/workflow-ref.d.ts.map +1 -1
  308. package/dist/src/workflow-ref.js.map +1 -1
  309. package/dist/stubs/config/durable.stub +6 -0
  310. package/dist/stubs/config/durable_dashboard.stub +7 -3
  311. package/dist/stubs/database/migrations/create_durable_tables.stub +2 -1
  312. package/dist/stubs/database/migrations/create_durable_transport_messages.stub +43 -0
  313. package/dist/stubs/database/migrations/create_durable_transport_tables.stub +12 -9
  314. package/dist/stubs/database/migrations/create_durable_transport_worker_keys.stub +1 -1
  315. package/dist/stubs/make/workflow/main.stub +1 -1
  316. package/package.json +6 -4
  317. package/skills/durable-cluster/SKILL.md +80 -11
  318. package/skills/durable-determinism/SKILL.md +11 -5
  319. package/skills/durable-reliability/SKILL.md +77 -37
  320. package/skills/durable-setup/SKILL.md +51 -22
  321. package/skills/durable-transports-stores/SKILL.md +130 -19
  322. package/skills/durable-workflows/SKILL.md +71 -18
  323. package/dist/assets/spa/assets/index-DdB9zxuX.js +0 -16
  324. package/dist/assets/spa/assets/index-DdB9zxuX.js.map +0 -1
@@ -1,45 +1,66 @@
1
- import type { ChildWait, RunFacetQuery, RunQuery, RunStatus, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleQuery, ScheduleRecord, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from '../interfaces.js';
2
- /**
3
- * A non-durable, in-process `StateStore` for tests and local development.
4
- * The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
5
- */
1
+ import type { CheckpointQuery, CheckpointStat, ChildWait, RunFacetQuery, RunFacetRow, RunQuery, RunStatus, RunValueAxis, RunValueFacetOptions, RunValueFacetRow, ScheduleQuery, ScheduleRecord, SignalWaiter, StateStore, StepCheckpoint, WorkflowRun } from '../interfaces.js';
6
2
  export declare class InMemoryStateStore implements StateStore {
7
- private readonly runs;
8
- private readonly checkpoints;
9
- private readonly signalWaiters;
3
+ /** All of this store's data; shared by reference with every {@link withScope} view. */
4
+ private state;
5
+ private get runs();
6
+ private get checkpoints();
7
+ private get signalWaiters();
10
8
  /**
11
9
  * Normalized search-attribute side-table, the in-memory analog of the SQL stores'
12
10
  * `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an
13
11
  * attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run
14
12
  * and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.
15
13
  */
16
- private readonly attributeIndex;
14
+ private get attributeIndex();
17
15
  /** Test/observability hook: how many candidate runs the last attribute query's index produced. */
18
- lastAttributeCandidates: number;
16
+ get lastAttributeCandidates(): number;
17
+ set lastAttributeCandidates(value: number);
19
18
  /**
20
19
  * Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows
21
20
  * actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted
22
21
  * {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —
23
22
  * so this lets the benchmark contrast "fetch N, scan in JS" against "fetch the k that match".
24
23
  */
25
- lastCheckpointRowsRead: number;
24
+ get lastCheckpointRowsRead(): number;
25
+ set lastCheckpointRowsRead(value: number);
26
+ /**
27
+ * Test/observability hook: checkpoint rows materialized since construction, across every
28
+ * checkpoint read that returns rows — what a run-detail test compares between paths.
29
+ */
30
+ get checkpointRowsRead(): number;
31
+ set checkpointRowsRead(value: number);
32
+ /** The namespace run reads are fenced to (see {@link withScope}); undefined sees every run. */
33
+ private scopeNamespace;
34
+ /**
35
+ * A view of THIS store (same data) whose run reads — `getRun`, `listRuns`, the counts and the
36
+ * recovery/dispatch/timer scans — only see `scope.namespace`. Writes stay unscoped. Mirrors
37
+ * `LucidStateStore.withScope`; `{ namespace: undefined }` is the operator view.
38
+ */
39
+ withScope(scope: {
40
+ namespace?: string | undefined;
41
+ }): InMemoryStateStore;
42
+ private inScope;
43
+ private visibleRuns;
26
44
  private key;
27
45
  /** Drop then re-add a run's normalized attribute rows so the index tracks its current attributes. */
28
46
  private reindexAttributes;
29
47
  createRun(run: WorkflowRun): Promise<void>;
30
48
  updateRun(runId: string, patch: Partial<WorkflowRun>): Promise<void>;
31
49
  updateRunIf(runId: string, expectedStatuses: RunStatus[], patch: Partial<WorkflowRun>): Promise<boolean>;
50
+ tryAdmitSingleton(runId: string, tag: string, workflow: string, limit: number, retryWakeAt?: number): Promise<boolean>;
32
51
  getRun(runId: string): Promise<WorkflowRun | null>;
33
52
  deleteRun(runId: string): Promise<void>;
53
+ deleteRuns(runIds: string[]): Promise<void>;
34
54
  getCheckpoint(runId: string, seq: number): Promise<StepCheckpoint | null>;
35
55
  saveCheckpoint(checkpoint: StepCheckpoint): Promise<void>;
36
56
  saveCheckpointIfPending(checkpoint: StepCheckpoint): Promise<boolean>;
57
+ saveCheckpointsIfPending(checkpoints: StepCheckpoint[]): Promise<boolean[]>;
37
58
  /** Mirror of `LucidStateStore.recordStepHeartbeat`: mutate in place, no-op when absent. */
38
59
  recordStepHeartbeat(runId: string, seq: number, at: Date, progress?: unknown): Promise<void>;
39
60
  listIncompleteRuns(namespace?: string): Promise<WorkflowRun[]>;
40
61
  listPendingRuns(limit: number, namespace?: string): Promise<WorkflowRun[]>;
41
62
  listDueTimers(nowMs: number, namespace?: string, limit?: number): Promise<WorkflowRun[]>;
42
- listOrphanedRuns(nowMs: number, limit: number, namespace?: string): Promise<WorkflowRun[]>;
63
+ listOrphanedRuns(nowMs: number, limit: number, namespace?: string, owner?: string): Promise<WorkflowRun[]>;
43
64
  tryLockRun(runId: string, owner: string, leaseUntilMs: number, nowMs: number): Promise<boolean>;
44
65
  releaseRunLock(runId: string, owner?: string): Promise<void>;
45
66
  renewRunLock(runId: string, owner: string, leaseUntilMs: number): Promise<boolean>;
@@ -55,14 +76,15 @@ export declare class InMemoryStateStore implements StateStore {
55
76
  raw: unknown;
56
77
  saveCheckpoint: (cp: StepCheckpoint) => Promise<void>;
57
78
  }) => Promise<T>): Promise<T>;
58
- private readonly bufferedSignals;
79
+ private get bufferedSignals();
59
80
  bufferSignal(token: string, payload: unknown): Promise<void>;
81
+ listBufferedSignalTokens(prefix: string, limit: number): Promise<string[]>;
60
82
  takeBufferedSignal(token: string): Promise<{
61
83
  payload: unknown;
62
84
  } | null>;
63
85
  /** `id -> row`, so {@link removeBufferedEvent} can delete an exact row regardless of iteration
64
86
  * order — mirrors the SQL store's PK-by-id delete. */
65
- private readonly bufferedEvents;
87
+ private get bufferedEvents();
66
88
  bufferEvent(input: {
67
89
  name: string;
68
90
  payload: unknown;
@@ -75,6 +97,7 @@ export declare class InMemoryStateStore implements StateStore {
75
97
  publishedAt: number;
76
98
  }>>;
77
99
  removeBufferedEvent(id: string): Promise<boolean>;
100
+ pruneBufferedEvents(publishedBefore: number, limit: number): Promise<number>;
78
101
  /**
79
102
  * Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the
80
103
  * pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones
@@ -82,7 +105,8 @@ export declare class InMemoryStateStore implements StateStore {
82
105
  */
83
106
  private candidatesForFilter;
84
107
  countRuns(query: Omit<RunQuery, 'page' | 'size'>): Promise<number>;
85
- private readonly schedules;
108
+ runFacets(query: RunFacetQuery): Promise<RunFacetRow[]>;
109
+ private get schedules();
86
110
  saveSchedule(record: ScheduleRecord): Promise<void>;
87
111
  getSchedule(id: string): Promise<ScheduleRecord | null>;
88
112
  updateSchedule(id: string, patch: Partial<Omit<ScheduleRecord, 'id' | 'createdAt'>>, expectedNextFireAt?: number | null): Promise<boolean>;
@@ -97,6 +121,11 @@ export declare class InMemoryStateStore implements StateStore {
97
121
  */
98
122
  runValueFacets(axis: RunValueAxis, query: RunFacetQuery, opts?: RunValueFacetOptions): Promise<RunValueFacetRow[]>;
99
123
  listCheckpoints(runId: string): Promise<StepCheckpoint[]>;
124
+ checkpointStats(runId: string, opts?: {
125
+ group?: string | undefined;
126
+ }): Promise<CheckpointStat[]>;
127
+ queryCheckpoints(runId: string, query: CheckpointQuery): Promise<StepCheckpoint[]>;
128
+ private runCheckpoints;
100
129
  getLatestCheckpointByName(runId: string, name: string): Promise<StepCheckpoint | undefined>;
101
130
  countCheckpoints(runId: string, fromSeq: number, toSeq: number, statuses: StepCheckpoint['status'][]): Promise<number>;
102
131
  listCheckpointsByNamePrefix(runId: string, prefixes: string[]): Promise<StepCheckpoint[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-state-store.d.ts","sourceRoot":"","sources":["../../../src/testing/in-memory-state-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"in-memory-state-store.d.ts","sourceRoot":"","sources":["../../../src/testing/in-memory-state-store.ts"],"names":[],"mappings":"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"}
@@ -1,30 +1,100 @@
1
+ import { namespaceMatches, normalizeNamespace } from '../namespaces.js';
2
+ import { checkpointStatsOf, queryCheckpointsOf } from '../run-detail-summary.js';
3
+ import { mergeRunFacetRows } from '../run-facets.js';
1
4
  import { runPageWindow } from '../run-pagination.js';
2
5
  import { scanRunValueFacets } from '../run-value-facets.js';
3
6
  import { normalizeAttributeRows } from '../search-attributes.js';
4
- /**
5
- * A non-durable, in-process `StateStore` for tests and local development.
6
- * The shipped `@dudousxd/nestjs-durable-store` package re-exports an equivalent.
7
- */
7
+ import { settlesTerminally, singletonAdmissionDenialPatch, singletonAdmissionTags, withoutAdmission, } from '../singleton-admission.js';
8
+ /** A caller's copy of a stored run, with a legacy `''`/absent namespace read as `'default'`. */
9
+ const copyRun = (run) => ({
10
+ ...run,
11
+ namespace: normalizeNamespace(run.namespace),
12
+ });
13
+ /** A run about to be stored, its namespace normalized (`''` is the default pool). */
14
+ const withNormalizedNamespace = (run) => run.namespace === undefined || run.namespace === '' ? copyRun(run) : run;
15
+ const freshState = () => ({
16
+ runs: new Map(),
17
+ checkpoints: new Map(),
18
+ signalWaiters: new Map(),
19
+ attributeIndex: new Map(),
20
+ bufferedSignals: new Map(),
21
+ bufferedEvents: new Map(),
22
+ schedules: new Map(),
23
+ stats: { lastAttributeCandidates: 0, lastCheckpointRowsRead: 0, checkpointRowsRead: 0 },
24
+ });
8
25
  export class InMemoryStateStore {
9
- runs = new Map();
10
- checkpoints = new Map();
11
- signalWaiters = new Map();
26
+ /** All of this store's data; shared by reference with every {@link withScope} view. */
27
+ state = freshState();
28
+ get runs() {
29
+ return this.state.runs;
30
+ }
31
+ get checkpoints() {
32
+ return this.state.checkpoints;
33
+ }
34
+ get signalWaiters() {
35
+ return this.state.signalWaiters;
36
+ }
12
37
  /**
13
38
  * Normalized search-attribute side-table, the in-memory analog of the SQL stores'
14
39
  * `durable_run_attributes`: `key -> (runId -> row)`. Maintained on every create/update so an
15
40
  * attribute query can be pushed DOWN to a key-indexed candidate set instead of scanning every run
16
41
  * and comparing in-process. Mirrors {@link normalizeAttributeRows} so behavior matches the SQL path.
17
42
  */
18
- attributeIndex = new Map();
43
+ get attributeIndex() {
44
+ return this.state.attributeIndex;
45
+ }
19
46
  /** Test/observability hook: how many candidate runs the last attribute query's index produced. */
20
- lastAttributeCandidates = 0;
47
+ get lastAttributeCandidates() {
48
+ return this.state.stats.lastAttributeCandidates;
49
+ }
50
+ set lastAttributeCandidates(value) {
51
+ this.state.stats.lastAttributeCandidates = value;
52
+ }
21
53
  /**
22
54
  * Test/observability hook: how many checkpoint rows the LAST checkpoint read materialized (the rows
23
55
  * actually returned to the caller). `listCheckpoints` returns all rows for the run; the targeted
24
56
  * {@link getLatestCheckpointByName} / {@link listCheckpointsByNamePrefix} return only the matches —
25
57
  * so this lets the benchmark contrast "fetch N, scan in JS" against "fetch the k that match".
26
58
  */
27
- lastCheckpointRowsRead = 0;
59
+ get lastCheckpointRowsRead() {
60
+ return this.state.stats.lastCheckpointRowsRead;
61
+ }
62
+ set lastCheckpointRowsRead(value) {
63
+ this.state.stats.lastCheckpointRowsRead = value;
64
+ }
65
+ /**
66
+ * Test/observability hook: checkpoint rows materialized since construction, across every
67
+ * checkpoint read that returns rows — what a run-detail test compares between paths.
68
+ */
69
+ get checkpointRowsRead() {
70
+ return this.state.stats.checkpointRowsRead;
71
+ }
72
+ set checkpointRowsRead(value) {
73
+ this.state.stats.checkpointRowsRead = value;
74
+ }
75
+ /** The namespace run reads are fenced to (see {@link withScope}); undefined sees every run. */
76
+ scopeNamespace;
77
+ /**
78
+ * A view of THIS store (same data) whose run reads — `getRun`, `listRuns`, the counts and the
79
+ * recovery/dispatch/timer scans — only see `scope.namespace`. Writes stay unscoped. Mirrors
80
+ * `LucidStateStore.withScope`; `{ namespace: undefined }` is the operator view.
81
+ */
82
+ withScope(scope) {
83
+ // A plain store holding the SAME state object by reference (not an `Object.create(this)` child,
84
+ // whose own-property writes — a counter bump — would shadow the base's, and which would break on
85
+ // any `#private` field). Overrides of a subclass are not carried over to the view.
86
+ const view = new InMemoryStateStore();
87
+ view.state = this.state;
88
+ view.scopeNamespace = scope.namespace;
89
+ return view;
90
+ }
91
+ inScope(run) {
92
+ return (this.scopeNamespace === undefined || namespaceMatches(run.namespace, this.scopeNamespace));
93
+ }
94
+ visibleRuns() {
95
+ const runs = [...this.runs.values()];
96
+ return this.scopeNamespace === undefined ? runs : runs.filter((r) => this.inScope(r));
97
+ }
28
98
  key(runId, seq) {
29
99
  return `${runId}:${seq}`;
30
100
  }
@@ -50,14 +120,18 @@ export class InMemoryStateStore {
50
120
  // Normalize an undefined namespace to 'default', matching the SQL stores' column DEFAULT 'default'
51
121
  // — so a run created directly against this store (bypassing the engine, e.g. in tests) is still
52
122
  // reachable via a namespace='default' filter and partitions consistently.
53
- this.runs.set(run.id, { ...run, namespace: run.namespace ?? 'default' });
123
+ this.runs.set(run.id, { ...run, namespace: normalizeNamespace(run.namespace) });
54
124
  this.reindexAttributes(run.id, run.searchAttributes);
55
125
  }
56
126
  async updateRun(runId, patch) {
57
127
  const existing = this.runs.get(runId);
58
128
  if (!existing)
59
129
  throw new Error(`run ${runId} not found`);
60
- const next = { ...existing, ...patch };
130
+ const next = withNormalizedNamespace({
131
+ ...existing,
132
+ ...patch,
133
+ ...releasedSlot(existing, patch),
134
+ });
61
135
  this.runs.set(runId, next);
62
136
  if ('searchAttributes' in patch)
63
137
  this.reindexAttributes(runId, next.searchAttributes);
@@ -68,15 +142,33 @@ export class InMemoryStateStore {
68
142
  const existing = this.runs.get(runId);
69
143
  if (!existing || !expectedStatuses.includes(existing.status))
70
144
  return false;
71
- const next = { ...existing, ...patch };
145
+ const next = withNormalizedNamespace({
146
+ ...existing,
147
+ ...patch,
148
+ ...releasedSlot(existing, patch),
149
+ });
72
150
  this.runs.set(runId, next);
73
151
  if ('searchAttributes' in patch)
74
152
  this.reindexAttributes(runId, next.searchAttributes);
75
153
  return true;
76
154
  }
155
+ async tryAdmitSingleton(runId, tag, workflow, limit, retryWakeAt) {
156
+ // No `await` between the snapshot and the claim: this synchronous turn is the critical section.
157
+ const runs = [...this.runs.values()];
158
+ const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);
159
+ const run = this.runs.get(runId);
160
+ if (!tags || !run) {
161
+ const parked = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);
162
+ if (parked && run)
163
+ this.runs.set(runId, { ...run, ...parked });
164
+ return false;
165
+ }
166
+ this.runs.set(runId, { ...run, tags });
167
+ return true;
168
+ }
77
169
  async getRun(runId) {
78
170
  const run = this.runs.get(runId);
79
- return run ? { ...run } : null;
171
+ return run && this.inScope(run) ? copyRun(run) : null;
80
172
  }
81
173
  async deleteRun(runId) {
82
174
  this.runs.delete(runId);
@@ -91,6 +183,10 @@ export class InMemoryStateStore {
91
183
  // Drop the run's normalized attribute rows (reindex with no attributes clears them).
92
184
  this.reindexAttributes(runId, undefined);
93
185
  }
186
+ async deleteRuns(runIds) {
187
+ for (const runId of runIds)
188
+ await this.deleteRun(runId);
189
+ }
94
190
  async getCheckpoint(runId, seq) {
95
191
  const cp = this.checkpoints.get(this.key(runId, seq));
96
192
  return cp ? { ...cp } : null;
@@ -105,6 +201,15 @@ export class InMemoryStateStore {
105
201
  this.checkpoints.set(key, { ...checkpoint });
106
202
  return true;
107
203
  }
204
+ async saveCheckpointsIfPending(checkpoints) {
205
+ return checkpoints.map((checkpoint) => {
206
+ const key = this.key(checkpoint.runId, checkpoint.seq);
207
+ if (this.checkpoints.get(key)?.status !== 'pending')
208
+ return false;
209
+ this.checkpoints.set(key, { ...checkpoint });
210
+ return true;
211
+ });
212
+ }
108
213
  /** Mirror of `LucidStateStore.recordStepHeartbeat`: mutate in place, no-op when absent. */
109
214
  async recordStepHeartbeat(runId, seq, at, progress) {
110
215
  const cp = this.checkpoints.get(this.key(runId, seq));
@@ -114,34 +219,38 @@ export class InMemoryStateStore {
114
219
  cp.heartbeatProgress = progress;
115
220
  }
116
221
  async listIncompleteRuns(namespace) {
117
- return [...this.runs.values()]
118
- .filter((r) => r.status === 'running' && (namespace === undefined || r.namespace === namespace))
119
- .map((r) => ({ ...r }));
222
+ return this.visibleRuns()
223
+ .filter((r) => r.status === 'running' &&
224
+ (namespace === undefined || namespaceMatches(r.namespace, namespace)))
225
+ .map(copyRun);
120
226
  }
121
227
  async listPendingRuns(limit, namespace) {
122
- return [...this.runs.values()]
123
- .filter((r) => r.status === 'pending' && (namespace === undefined || r.namespace === namespace))
228
+ return this.visibleRuns()
229
+ .filter((r) => r.status === 'pending' &&
230
+ (namespace === undefined || namespaceMatches(r.namespace, namespace)))
124
231
  .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime() || a.id.localeCompare(b.id))
125
232
  .slice(0, limit)
126
- .map((r) => ({ ...r }));
233
+ .map(copyRun);
127
234
  }
128
235
  async listDueTimers(nowMs, namespace, limit) {
129
- const due = [...this.runs.values()].filter((r) => r.status === 'suspended' &&
236
+ const due = this.visibleRuns().filter((r) => r.status === 'suspended' &&
130
237
  r.wakeAt !== undefined &&
131
238
  r.wakeAt <= nowMs &&
132
- (namespace === undefined || r.namespace === namespace));
239
+ (namespace === undefined || namespaceMatches(r.namespace, namespace)));
133
240
  // Most overdue first (mirrors the SQL stores' ORDER BY wake_at).
134
241
  due.sort((a, b) => (a.wakeAt ?? 0) - (b.wakeAt ?? 0));
135
- return (limit === undefined ? due : due.slice(0, limit)).map((r) => ({ ...r }));
242
+ return (limit === undefined ? due : due.slice(0, limit)).map(copyRun);
136
243
  }
137
- async listOrphanedRuns(nowMs, limit, namespace) {
138
- return [...this.runs.values()]
244
+ async listOrphanedRuns(nowMs, limit, namespace, owner) {
245
+ return this.visibleRuns()
139
246
  .filter((r) => r.status === 'running' &&
140
- (r.lockedUntil === undefined || r.lockedUntil <= nowMs) &&
141
- (namespace === undefined || r.namespace === namespace))
247
+ (r.lockedUntil === undefined ||
248
+ r.lockedUntil <= nowMs ||
249
+ (owner !== undefined && r.lockedBy === owner)) &&
250
+ (namespace === undefined || namespaceMatches(r.namespace, namespace)))
142
251
  .sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime())
143
252
  .slice(0, limit)
144
- .map((r) => ({ ...r }));
253
+ .map(copyRun);
145
254
  }
146
255
  async tryLockRun(runId, owner, leaseUntilMs, nowMs) {
147
256
  const run = this.runs.get(runId);
@@ -224,12 +333,24 @@ export class InMemoryStateStore {
224
333
  async transaction(work) {
225
334
  return work({ raw: this, saveCheckpoint: (cp) => this.saveCheckpoint(cp) });
226
335
  }
227
- bufferedSignals = new Map();
336
+ get bufferedSignals() {
337
+ return this.state.bufferedSignals;
338
+ }
228
339
  async bufferSignal(token, payload) {
229
340
  const queue = this.bufferedSignals.get(token) ?? [];
230
341
  queue.push(payload);
231
342
  this.bufferedSignals.set(token, queue);
232
343
  }
344
+ async listBufferedSignalTokens(prefix, limit) {
345
+ const out = [];
346
+ for (const [token, queue] of this.bufferedSignals) {
347
+ if (out.length >= limit)
348
+ break;
349
+ if (token.startsWith(prefix) && queue.length > 0)
350
+ out.push(token);
351
+ }
352
+ return out;
353
+ }
233
354
  async takeBufferedSignal(token) {
234
355
  const queue = this.bufferedSignals.get(token);
235
356
  if (!queue || queue.length === 0)
@@ -241,7 +362,9 @@ export class InMemoryStateStore {
241
362
  }
242
363
  /** `id -> row`, so {@link removeBufferedEvent} can delete an exact row regardless of iteration
243
364
  * order — mirrors the SQL store's PK-by-id delete. */
244
- bufferedEvents = new Map();
365
+ get bufferedEvents() {
366
+ return this.state.bufferedEvents;
367
+ }
245
368
  async bufferEvent(input) {
246
369
  this.bufferedEvents.set(input.id, {
247
370
  name: input.name,
@@ -259,6 +382,15 @@ export class InMemoryStateStore {
259
382
  async removeBufferedEvent(id) {
260
383
  return this.bufferedEvents.delete(id);
261
384
  }
385
+ async pruneBufferedEvents(publishedBefore, limit) {
386
+ const expired = [...this.bufferedEvents.entries()]
387
+ .filter(([, e]) => e.publishedAt < publishedBefore)
388
+ .sort((a, b) => a[1].publishedAt - b[1].publishedAt)
389
+ .slice(0, Math.max(0, limit));
390
+ for (const [id] of expired)
391
+ this.bufferedEvents.delete(id);
392
+ return expired.length;
393
+ }
262
394
  /**
263
395
  * Candidate run ids satisfying ONE attribute predicate, served from {@link attributeIndex} — the
264
396
  * pushdown step. Numeric predicates scan only `numValue` rows under the key; string/boolean ones
@@ -318,9 +450,18 @@ export class InMemoryStateStore {
318
450
  async countRuns(query) {
319
451
  return (await this.listRuns(query)).length;
320
452
  }
321
- schedules = new Map();
453
+ async runFacets(query) {
454
+ const runs = await this.listRuns(query);
455
+ return mergeRunFacetRows(runs.map((r) => ({ status: r.status, origin: r.origin, count: 1 })));
456
+ }
457
+ get schedules() {
458
+ return this.state.schedules;
459
+ }
322
460
  async saveSchedule(record) {
323
- this.schedules.set(record.id, structuredClone(record));
461
+ this.schedules.set(record.id, {
462
+ ...structuredClone(record),
463
+ namespace: normalizeNamespace(record.namespace),
464
+ });
324
465
  }
325
466
  async getSchedule(id) {
326
467
  const record = this.schedules.get(id);
@@ -332,7 +473,8 @@ export class InMemoryStateStore {
332
473
  return false;
333
474
  if (expectedNextFireAt !== undefined && record.nextFireAt !== expectedNextFireAt)
334
475
  return false;
335
- this.schedules.set(id, { ...record, ...structuredClone(patch) });
476
+ const next = { ...record, ...structuredClone(patch) };
477
+ this.schedules.set(id, { ...next, namespace: normalizeNamespace(next.namespace) });
336
478
  return true;
337
479
  }
338
480
  async deleteSchedule(id) {
@@ -340,7 +482,7 @@ export class InMemoryStateStore {
340
482
  }
341
483
  async listSchedules(query) {
342
484
  const rows = [...this.schedules.values()]
343
- .filter((s) => query.namespace === undefined || s.namespace === query.namespace)
485
+ .filter((s) => query.namespace === undefined || namespaceMatches(s.namespace, query.namespace))
344
486
  .filter((s) => query.workflow === undefined || s.workflow === query.workflow)
345
487
  .filter((s) => query.tag === undefined || (s.tags ?? []).includes(query.tag))
346
488
  .filter((s) => query.paused === undefined || s.paused === query.paused)
@@ -354,7 +496,7 @@ export class InMemoryStateStore {
354
496
  .map((s) => structuredClone(s));
355
497
  }
356
498
  async listRuns(query) {
357
- let runs = [...this.runs.values()];
499
+ let runs = this.visibleRuns();
358
500
  if (query.workflow)
359
501
  runs = runs.filter((r) => r.workflow === query.workflow);
360
502
  if (query.workflows) {
@@ -363,13 +505,15 @@ export class InMemoryStateStore {
363
505
  ? []
364
506
  : runs.filter((r) => query.workflows?.includes(r.workflow));
365
507
  }
366
- if (query.namespace !== undefined)
367
- runs = runs.filter((r) => r.namespace === query.namespace);
508
+ if (query.namespace !== undefined) {
509
+ const namespace = query.namespace;
510
+ runs = runs.filter((r) => namespaceMatches(r.namespace, namespace));
511
+ }
368
512
  if (query.namespaces) {
369
513
  runs =
370
514
  query.namespaces.length === 0
371
515
  ? []
372
- : runs.filter((r) => r.namespace !== undefined && query.namespaces?.includes(r.namespace));
516
+ : runs.filter((r) => query.namespaces?.some((ns) => namespaceMatches(r.namespace, ns)) ?? false);
373
517
  }
374
518
  if (query.origin)
375
519
  runs = runs.filter((r) => r.origin === query.origin);
@@ -425,9 +569,7 @@ export class InMemoryStateStore {
425
569
  runs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
426
570
  // 1-based `page`/`size` in, 0-based slice out — same resolution the SQL adapters apply.
427
571
  const { limit, offset } = runPageWindow(query);
428
- return runs
429
- .slice(offset, limit === undefined ? undefined : offset + limit)
430
- .map((r) => ({ ...r }));
572
+ return runs.slice(offset, limit === undefined ? undefined : offset + limit).map(copyRun);
431
573
  }
432
574
  /**
433
575
  * The distinct values of ONE filter axis over the runs matching `query`, with counts — what a
@@ -444,8 +586,21 @@ export class InMemoryStateStore {
444
586
  .sort((a, b) => a.seq - b.seq)
445
587
  .map((cp) => ({ ...cp }));
446
588
  this.lastCheckpointRowsRead = rows.length;
589
+ this.checkpointRowsRead += rows.length;
590
+ return rows;
591
+ }
592
+ async checkpointStats(runId, opts) {
593
+ return checkpointStatsOf(this.runCheckpoints(runId), opts);
594
+ }
595
+ async queryCheckpoints(runId, query) {
596
+ const rows = queryCheckpointsOf(this.runCheckpoints(runId), query).map((cp) => ({ ...cp }));
597
+ this.lastCheckpointRowsRead = rows.length;
598
+ this.checkpointRowsRead += rows.length;
447
599
  return rows;
448
600
  }
601
+ runCheckpoints(runId) {
602
+ return [...this.checkpoints.values()].filter((cp) => cp.runId === runId);
603
+ }
449
604
  async getLatestCheckpointByName(runId, name) {
450
605
  let latest;
451
606
  for (const cp of this.checkpoints.values()) {
@@ -474,7 +629,15 @@ export class InMemoryStateStore {
474
629
  .sort((a, b) => a.seq - b.seq)
475
630
  .map((cp) => ({ ...cp }));
476
631
  this.lastCheckpointRowsRead = rows.length;
632
+ this.checkpointRowsRead += rows.length;
477
633
  return rows;
478
634
  }
479
635
  }
636
+ /** A terminal settle releases the run's singleton slot: drop the admission marker from its tags. */
637
+ function releasedSlot(existing, patch) {
638
+ if (!settlesTerminally(patch))
639
+ return undefined;
640
+ const tags = withoutAdmission('tags' in patch ? patch.tags : existing.tags);
641
+ return tags ? { tags } : undefined;
642
+ }
480
643
  //# sourceMappingURL=in-memory-state-store.js.map