@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 +1 @@
1
- {"version":3,"file":"lucid.d.ts","sourceRoot":"","sources":["../../../src/stores/lucid.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lucid.d.ts","sourceRoot":"","sources":["../../../src/stores/lucid.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,10 @@
1
+ import { namespaceFilterValues, normalizeNamespace } from '../namespaces.js';
2
+ import { mergeRunFacetRows } from '../run-facets.js';
1
3
  import { runPageWindow } from '../run-pagination.js';
2
4
  import { axisIsRunColumn, mergeRunValueFacetRows, RUN_VALUE_FACET_LIMIT, scanRunValueFacets, } from '../run-value-facets.js';
3
5
  import { attributeColumnFor, attributeOperand, attributeOperands, normalizeAttributeRows, sqlComparator, } from '../search-attributes.js';
4
- import { checkpointToRow, rowToCheckpoint, rowToRun, rowToSignalWaiter, runPatchToRow, runToRow, } from './lucid-mappers.js';
6
+ import { SINGLETON_ACTIVE_STATUSES, SINGLETON_ADMITTED_TAG, settlesTerminally, singletonAdmissionDenialPatch, singletonAdmissionTags, withoutAdmission, } from '../singleton-admission.js';
7
+ import { checkpointToRow, parseJsonColumn, rowToCheckpoint, rowToRun, rowToSignalWaiter, runPatchToRow, runToRow, } from './lucid-mappers.js';
5
8
  import { createDurableTables, DURABLE_TABLES } from './lucid-schema.js';
6
9
  /**
7
10
  * A production-grade, persistent `StateStore` backed by AdonisJS **Lucid** (Knex). Runs, checkpoints,
@@ -17,9 +20,28 @@ import { createDurableTables, DURABLE_TABLES } from './lucid-schema.js';
17
20
  export class LucidStateStore {
18
21
  db;
19
22
  connectionName;
23
+ options;
24
+ /** The namespace run reads are fenced to, or undefined for the operator view. */
25
+ scopeNamespace;
20
26
  constructor(db, options = {}) {
21
27
  this.db = db;
22
28
  this.connectionName = options.connectionName;
29
+ this.options = options;
30
+ this.scopeNamespace = options.scope?.namespace;
31
+ }
32
+ /**
33
+ * A store over the same `Database` whose run reads are confined to `scope.namespace` (see
34
+ * {@link LucidStateStoreOptions.scope}). `{ namespace: undefined }` is the unscoped operator view.
35
+ */
36
+ withScope(scope) {
37
+ return new LucidStateStore(this.db, { ...this.options, scope });
38
+ }
39
+ /** Fence a runs-table read to the store's scope (no-op for the operator view). */
40
+ fenced(q) {
41
+ if (this.scopeNamespace !== undefined) {
42
+ q.whereIn('namespace', namespaceFilterValues(this.scopeNamespace));
43
+ }
44
+ return q;
23
45
  }
24
46
  /** The base query client (or a named connection's), used unless an explicit tx client is passed. */
25
47
  client() {
@@ -27,7 +49,7 @@ export class LucidStateStore {
27
49
  }
28
50
  /** Idempotently provision the durable tables (called on boot when `autoSchema` is on). */
29
51
  async ensureSchema() {
30
- await createDurableTables(this.db, this.connectionName);
52
+ await createDurableTables(this.db, this.connectionName, this.options.collation !== undefined ? { collation: this.options.collation } : {});
31
53
  }
32
54
  // --- runs ---------------------------------------------------------------
33
55
  async createRun(run) {
@@ -37,8 +59,8 @@ export class LucidStateStore {
37
59
  });
38
60
  }
39
61
  async updateRun(runId, patch) {
40
- const row = runPatchToRow(patch);
41
62
  await this.client().transaction(async (trx) => {
63
+ const row = await this.releaseSlot(trx, runId, patch);
42
64
  // Knex throws on an empty `.update({})`; skip the UPDATE when no mapped column changed.
43
65
  if (Object.keys(row).length) {
44
66
  await trx.from(DURABLE_TABLES.runs).where('id', runId).update(row);
@@ -49,8 +71,8 @@ export class LucidStateStore {
49
71
  });
50
72
  }
51
73
  async updateRunIf(runId, expectedStatuses, patch) {
52
- const row = runPatchToRow(patch);
53
74
  return this.client().transaction(async (trx) => {
75
+ const row = await this.releaseSlot(trx, runId, patch);
54
76
  let applied;
55
77
  if (Object.keys(row).length) {
56
78
  // The status predicate lives IN the UPDATE's WHERE clause, alongside `updateRun`'s existing
@@ -79,8 +101,89 @@ export class LucidStateStore {
79
101
  return applied;
80
102
  });
81
103
  }
104
+ /** Whether the runs table has `awaiting_decision_task_id`, probed once per store and cached. */
105
+ decisionMarkerColumn;
106
+ hasDecisionMarkerColumn(trx) {
107
+ // Probed on the caller's transaction: a single-connection pool (SQLite) has no other to use.
108
+ this.decisionMarkerColumn ??= trx.schema
109
+ .hasColumn(DURABLE_TABLES.runs, 'awaiting_decision_task_id')
110
+ .catch(() => {
111
+ this.decisionMarkerColumn = undefined; // a failed probe is retried, never cached
112
+ return true;
113
+ });
114
+ return this.decisionMarkerColumn;
115
+ }
116
+ /**
117
+ * The row patch for `patch`, plus — when it settles the run terminally — the run's tags without the
118
+ * singleton admission marker, so a terminal settle releases the slot. The current tags are read
119
+ * under a row lock (Postgres/MySQL) so an admission committing concurrently can't be overwritten
120
+ * with a stale tag list.
121
+ */
122
+ async releaseSlot(trx, runId, patch) {
123
+ const row = runPatchToRow(patch);
124
+ // A patch CLEARING the remote-workflow decision marker (cancel, requeue, settle) on a schema
125
+ // that predates the column (`autoSchema: false`, an old migration): leave it out, as `runToRow`
126
+ // does on insert — there is nothing to clear. Setting it still needs the column.
127
+ if ('awaiting_decision_task_id' in row &&
128
+ row.awaiting_decision_task_id == null &&
129
+ !(await this.hasDecisionMarkerColumn(trx))) {
130
+ delete row.awaiting_decision_task_id;
131
+ }
132
+ if (!settlesTerminally(patch))
133
+ return row;
134
+ let tags;
135
+ if ('tags' in patch) {
136
+ tags = patch.tags;
137
+ }
138
+ else {
139
+ const q = trx.from(DURABLE_TABLES.runs).where('id', runId).select('tags');
140
+ if (locksRows(trx))
141
+ q.forUpdate();
142
+ const current = (await q.first());
143
+ tags = parseJsonColumn(current?.tags, `${DURABLE_TABLES.runs}.tags`, runId);
144
+ }
145
+ const released = withoutAdmission(tags);
146
+ return released ? { ...row, ...runPatchToRow({ tags: released }) } : row;
147
+ }
148
+ async tryAdmitSingleton(runId, tag, workflow, limit, retryWakeAt) {
149
+ return this.client().transaction(async (trx) => {
150
+ // Every active run sharing the key. The tag LIKE may over-match (it is only a lock-scope
151
+ // narrowing); the decision re-filters exactly.
152
+ const sharing = () => trx
153
+ .from(DURABLE_TABLES.runs)
154
+ .where('workflow', workflow)
155
+ .whereIn('status', SINGLETON_ACTIVE_STATUSES)
156
+ .whereRaw(`tags like ? escape '!'`, [`%"${escapeLike(tag)}"%`]);
157
+ let rows;
158
+ if (locksRows(trx)) {
159
+ // Lock the key's active rows in a stable order (no lock-order deadlock between two claims).
160
+ // A competing claim blocks here until this one commits, then reads the committed holder.
161
+ rows = (await sharing().orderBy('id', 'asc').forUpdate());
162
+ }
163
+ else {
164
+ // SQLite has no row locks: take the database write lock FIRST with a no-op write, then read,
165
+ // so no other connection or process can claim between this read and the write below.
166
+ await sharing().update({ workflow });
167
+ rows = (await sharing());
168
+ }
169
+ const runs = rows.map(rowToRun);
170
+ const tags = singletonAdmissionTags(runs, runId, tag, workflow, limit);
171
+ if (!tags) {
172
+ const parked = singletonAdmissionDenialPatch(runs, runId, tag, workflow, retryWakeAt);
173
+ if (parked) {
174
+ await trx.from(DURABLE_TABLES.runs).where('id', runId).update(runPatchToRow(parked));
175
+ }
176
+ return false;
177
+ }
178
+ // Already a holder (a resumed turn): nothing to write.
179
+ if (!runs.find((r) => r.id === runId)?.tags?.includes(SINGLETON_ADMITTED_TAG)) {
180
+ await trx.from(DURABLE_TABLES.runs).where('id', runId).update(runPatchToRow({ tags }));
181
+ }
182
+ return true;
183
+ });
184
+ }
82
185
  async getRun(runId) {
83
- const row = await this.client().from(DURABLE_TABLES.runs).where('id', runId).first();
186
+ const row = await this.fenced(this.client().from(DURABLE_TABLES.runs).where('id', runId)).first();
84
187
  return row ? rowToRun(row) : null;
85
188
  }
86
189
  async deleteRun(runId) {
@@ -94,6 +197,22 @@ export class LucidStateStore {
94
197
  await trx.from(DURABLE_TABLES.runs).where('id', runId).delete();
95
198
  });
96
199
  }
200
+ async deleteRuns(runIds) {
201
+ const ids = [...new Set(runIds)];
202
+ if (ids.length === 0)
203
+ return;
204
+ // deleteRun's four statements, `IN (...)` over chunks that stay under every dialect's bind limit,
205
+ // all in one transaction.
206
+ await this.client().transaction(async (trx) => {
207
+ for (let at = 0; at < ids.length; at += DELETE_RUNS_CHUNK) {
208
+ const chunk = ids.slice(at, at + DELETE_RUNS_CHUNK);
209
+ await trx.from(DURABLE_TABLES.checkpoints).whereIn('run_id', chunk).delete();
210
+ await trx.from(DURABLE_TABLES.signalWaiters).whereIn('run_id', chunk).delete();
211
+ await trx.from(DURABLE_TABLES.attributes).whereIn('run_id', chunk).delete();
212
+ await trx.from(DURABLE_TABLES.runs).whereIn('id', chunk).delete();
213
+ }
214
+ });
215
+ }
97
216
  // --- checkpoints --------------------------------------------------------
98
217
  async getCheckpoint(runId, seq) {
99
218
  const row = await this.client()
@@ -107,14 +226,21 @@ export class LucidStateStore {
107
226
  await this.upsertCheckpoint(this.client(), checkpoint);
108
227
  }
109
228
  async saveCheckpointIfPending(checkpoint) {
110
- const { run_id: _runId, seq: _seq, ...row } = checkpointToRow(checkpoint);
111
- const affected = await this.client()
112
- .from(DURABLE_TABLES.checkpoints)
113
- .where('run_id', checkpoint.runId)
114
- .andWhere('seq', checkpoint.seq)
115
- .andWhere('status', 'pending')
116
- .update(row);
117
- return rowsAffected(affected) > 0;
229
+ return updateCheckpointIfPending(this.client(), checkpoint);
230
+ }
231
+ async saveCheckpointsIfPending(checkpoints) {
232
+ if (checkpoints.length === 0)
233
+ return [];
234
+ // The conditional UPDATE of `saveCheckpointIfPending`, once per entry and in order, in one
235
+ // transaction: one commit for the batch, and a rejection writes nothing. In order, so a second
236
+ // entry for the same row is compared against the first one's write.
237
+ return this.client().transaction(async (trx) => {
238
+ const wrote = [];
239
+ for (const checkpoint of checkpoints) {
240
+ wrote.push(await updateCheckpointIfPending(trx, checkpoint));
241
+ }
242
+ return wrote;
243
+ });
118
244
  }
119
245
  /** Persist the latest worker heartbeat on the step's checkpoint row (see the interface doc).
120
246
  * A targeted two-column UPDATE — never an upsert: a beat racing the checkpoint's own insert (or
@@ -146,31 +272,34 @@ export class LucidStateStore {
146
272
  }
147
273
  // --- recovery / dispatch queries ----------------------------------------
148
274
  async listIncompleteRuns(namespace) {
149
- const q = this.client().from(DURABLE_TABLES.runs).where('status', 'running');
275
+ const q = this.fenced(this.client().from(DURABLE_TABLES.runs).where('status', 'running'));
150
276
  if (namespace !== undefined)
151
- q.andWhere('namespace', namespace);
277
+ q.whereIn('namespace', namespaceFilterValues(namespace));
152
278
  const rows = await q;
153
279
  return rows.map(rowToRun);
154
280
  }
155
- async listOrphanedRuns(nowMs, limit, namespace) {
281
+ async listOrphanedRuns(nowMs, limit, namespace, owner) {
156
282
  // The lease predicate lives IN the query: only genuinely orphaned runs (no lease, or an expired
157
283
  // one) come back, so a healthy fleet's recovery tick fetches ~zero rows instead of every
158
- // running run — and issues ~zero lock-probe UPDATEs.
159
- const q = this.client()
284
+ // running run — and issues ~zero lock-probe UPDATEs. `owner` adds the runs still leased to that
285
+ // instance id (a rebooted instance's own leftovers; the engine filters what it is executing).
286
+ const q = this.fenced(this.client()
160
287
  .from(DURABLE_TABLES.runs)
161
288
  .where('status', 'running')
162
289
  .andWhere((sub) => {
163
290
  sub.whereNull('locked_until').orWhere('locked_until', '<=', nowMs);
164
- });
291
+ if (owner !== undefined)
292
+ sub.orWhere('locked_by', owner);
293
+ }));
165
294
  if (namespace !== undefined)
166
- q.andWhere('namespace', namespace);
295
+ q.whereIn('namespace', namespaceFilterValues(namespace));
167
296
  const rows = await q.orderBy('created_at', 'asc').limit(limit);
168
297
  return rows.map(rowToRun);
169
298
  }
170
299
  async listPendingRuns(limit, namespace) {
171
- const q = this.client().from(DURABLE_TABLES.runs).where('status', 'pending');
300
+ const q = this.fenced(this.client().from(DURABLE_TABLES.runs).where('status', 'pending'));
172
301
  if (namespace !== undefined)
173
- q.andWhere('namespace', namespace);
302
+ q.whereIn('namespace', namespaceFilterValues(namespace));
174
303
  const rows = await q
175
304
  .orderBy('created_at', 'asc') // FIFO dispatch
176
305
  .orderBy('id', 'asc') // stable tiebreak, mirrors the in-memory store
@@ -178,13 +307,13 @@ export class LucidStateStore {
178
307
  return rows.map(rowToRun);
179
308
  }
180
309
  async listDueTimers(nowMs, namespace, limit) {
181
- const q = this.client()
310
+ const q = this.fenced(this.client()
182
311
  .from(DURABLE_TABLES.runs)
183
312
  .where('status', 'suspended')
184
313
  .whereNotNull('wake_at')
185
- .andWhere('wake_at', '<=', nowMs);
314
+ .andWhere('wake_at', '<=', nowMs));
186
315
  if (namespace !== undefined)
187
- q.andWhere('namespace', namespace);
316
+ q.whereIn('namespace', namespaceFilterValues(namespace));
188
317
  // Most overdue first, bounded: a backlog drains over several polls instead of one unbounded
189
318
  // fetch (served by the existing (status, wake_at) index).
190
319
  q.orderBy('wake_at', 'asc');
@@ -344,6 +473,15 @@ export class LucidStateStore {
344
473
  .table(DURABLE_TABLES.bufferedSignals)
345
474
  .insert({ token, payload: payload === undefined ? null : JSON.stringify(payload) });
346
475
  }
476
+ async listBufferedSignalTokens(prefix, limit) {
477
+ const rows = (await this.client()
478
+ .from(DURABLE_TABLES.bufferedSignals)
479
+ .whereRaw(`token like ? escape '!'`, [`${escapeLike(prefix)}%`])
480
+ .distinct('token')
481
+ .orderBy('token', 'asc')
482
+ .limit(limit));
483
+ return rows.map((r) => r.token);
484
+ }
347
485
  async takeBufferedSignal(token) {
348
486
  return this.client().transaction(async (trx) => {
349
487
  const row = await trx
@@ -357,7 +495,9 @@ export class LucidStateStore {
357
495
  const deleted = await trx.from(DURABLE_TABLES.bufferedSignals).where('id', r.id).delete();
358
496
  if (rowsAffected(deleted) !== 1)
359
497
  return null;
360
- return { payload: r.payload == null ? undefined : JSON.parse(r.payload) };
498
+ return {
499
+ payload: parseJsonColumn(r.payload, `${DURABLE_TABLES.bufferedSignals}.payload`, String(r.id)),
500
+ };
361
501
  });
362
502
  }
363
503
  // --- buffered events (name-keyed, match-based consumption) ---------------
@@ -379,10 +519,31 @@ export class LucidStateStore {
379
519
  .limit(limit);
380
520
  return rows.map((r) => ({
381
521
  id: r.id,
382
- payload: r.payload == null ? undefined : JSON.parse(r.payload),
522
+ payload: parseJsonColumn(r.payload, `${DURABLE_TABLES.bufferedEvents}.payload`, r.id),
383
523
  publishedAt: Number(r.published_at),
384
524
  }));
385
525
  }
526
+ async pruneBufferedEvents(publishedBefore, limit) {
527
+ if (!(limit > 0))
528
+ return 0;
529
+ // Two statements, not `DELETE ... WHERE id IN (SELECT ... LIMIT n)`: MySQL rejects a LIMIT in an
530
+ // IN subquery. The age predicate is repeated on the DELETE so a row re-published under the same
531
+ // id meanwhile is left alone.
532
+ const rows = (await this.client()
533
+ .from(DURABLE_TABLES.bufferedEvents)
534
+ .select('id')
535
+ .where('published_at', '<', publishedBefore)
536
+ .orderBy('published_at', 'asc')
537
+ .limit(limit));
538
+ if (rows.length === 0)
539
+ return 0;
540
+ const deleted = await this.client()
541
+ .from(DURABLE_TABLES.bufferedEvents)
542
+ .whereIn('id', rows.map((r) => r.id))
543
+ .andWhere('published_at', '<', publishedBefore)
544
+ .delete();
545
+ return rowsAffected(deleted);
546
+ }
386
547
  async removeBufferedEvent(id) {
387
548
  // Atomic claim: whoever's delete affects the row (returns 1) is the one that gets to deliver;
388
549
  // a concurrent claimant sees 0 and backs off. `id` is the primary key.
@@ -403,6 +564,14 @@ export class LucidStateStore {
403
564
  }));
404
565
  }
405
566
  // --- dashboard queries --------------------------------------------------
567
+ /** One `GROUP BY status, origin` over the same predicates {@link listRuns} applies. */
568
+ async runFacets(query) {
569
+ const rows = (await this.scopedRuns(query)
570
+ .select('status', 'origin')
571
+ .count('* as count')
572
+ .groupBy('status', 'origin'));
573
+ return mergeRunFacetRows(rows.map((row) => ({ status: row.status, origin: row.origin, count: Number(row.count) })));
574
+ }
406
575
  /** One `COUNT(*)` over the same predicates {@link listRuns} applies. */
407
576
  async countRuns(query) {
408
577
  const rows = await this.scopedRuns(query).count('* as count');
@@ -426,7 +595,7 @@ export class LucidStateStore {
426
595
  async updateSchedule(id, patch, expectedNextFireAt) {
427
596
  const set = {};
428
597
  if (patch.namespace !== undefined)
429
- set.namespace = patch.namespace;
598
+ set.namespace = normalizeNamespace(patch.namespace);
430
599
  if (patch.workflow !== undefined)
431
600
  set.workflow = patch.workflow;
432
601
  if (patch.paused !== undefined)
@@ -456,8 +625,9 @@ export class LucidStateStore {
456
625
  }
457
626
  async listSchedules(query) {
458
627
  const q = this.client().from(DURABLE_TABLES.schedules);
459
- if (query.namespace !== undefined)
460
- q.where('namespace', query.namespace);
628
+ if (query.namespace !== undefined) {
629
+ q.whereIn('namespace', namespaceFilterValues(query.namespace));
630
+ }
461
631
  if (query.workflow !== undefined)
462
632
  q.where('workflow', query.workflow);
463
633
  if (query.paused !== undefined)
@@ -521,7 +691,11 @@ export class LucidStateStore {
521
691
  if (needle)
522
692
  q.andWhereRaw(`lower(${column}) like ? escape '!'`, [`%${escapeLike(needle)}%`]);
523
693
  const rows = (await q);
524
- return mergeRunValueFacetRows(rows.map((row) => ({ value: row.value, count: Number(row.count) })), { ...opts, search: undefined });
694
+ return mergeRunValueFacetRows(rows.map((row) => ({
695
+ // A legacy '' namespace counts as the default pool, as everywhere else.
696
+ value: column === 'namespace' ? normalizeNamespace(row.value) : row.value,
697
+ count: Number(row.count),
698
+ })), { ...opts, search: undefined });
525
699
  }
526
700
  /**
527
701
  * The runs matching `query`'s predicates (no ordering, no paging) — one source of truth shared by
@@ -529,7 +703,7 @@ export class LucidStateStore {
529
703
  * exactly the set the list would show.
530
704
  */
531
705
  scopedRuns(query) {
532
- const q = this.client().from(DURABLE_TABLES.runs);
706
+ const q = this.fenced(this.client().from(DURABLE_TABLES.runs));
533
707
  if (query.workflow)
534
708
  q.where('workflow', query.workflow);
535
709
  if (query.workflows) {
@@ -539,11 +713,13 @@ export class LucidStateStore {
539
713
  else
540
714
  q.whereRaw('1 = 0');
541
715
  }
542
- if (query.namespace !== undefined)
543
- q.where('namespace', query.namespace);
716
+ if (query.namespace !== undefined) {
717
+ q.whereIn('namespace', namespaceFilterValues(query.namespace));
718
+ }
544
719
  if (query.namespaces) {
545
- if (query.namespaces.length)
546
- q.whereIn('namespace', query.namespaces);
720
+ if (query.namespaces.length) {
721
+ q.whereIn('namespace', query.namespaces.flatMap(namespaceFilterValues));
722
+ }
547
723
  else
548
724
  q.whereRaw('1 = 0');
549
725
  }
@@ -668,6 +844,93 @@ export class LucidStateStore {
668
844
  .count('* as count');
669
845
  return Number(rows[0]?.count ?? 0);
670
846
  }
847
+ /**
848
+ * One `GROUP BY parallel_group, status, <name kind>` over the run's checkpoints — the buckets a run
849
+ * detail summarizes a fan from, without loading its rows. The name-kind `CASE` is the SQL of
850
+ * `checkpointNameKind` (case-sensitive prefix tests, like `startsWith`), and
851
+ * `min(coalesce(enqueued_at, started_at))` reads `enqueuedAt` the way {@link listCheckpoints} does.
852
+ */
853
+ async checkpointStats(runId, opts) {
854
+ const client = this.client();
855
+ const kind = nameKindSql(client.dialect.name);
856
+ const q = client
857
+ .from(DURABLE_TABLES.checkpoints)
858
+ .select('parallel_group as grp', 'status')
859
+ .select(client.raw(`${kind} as name_kind`))
860
+ .count('* as n')
861
+ .min('seq as min_seq')
862
+ .max('seq as max_seq')
863
+ .min('name as min_name')
864
+ .max('name as max_name')
865
+ .select(client.raw('min(coalesce(enqueued_at, started_at)) as min_enqueued_at'))
866
+ .min('started_at as min_started_at')
867
+ .max('started_at as max_started_at')
868
+ .max('finished_at as max_finished_at')
869
+ .sum('attempts as sum_attempts')
870
+ .where('run_id', runId);
871
+ if (opts?.group !== undefined)
872
+ q.andWhere('parallel_group', opts.group);
873
+ q.groupBy('parallel_group', 'status').groupByRaw(kind);
874
+ const rows = (await q);
875
+ // Counts, sums and bigint aggregates come back as strings on Postgres/MySQL.
876
+ const ms = (value) => new Date(Number(value));
877
+ return rows.map((row) => ({
878
+ group: row.grp ?? null,
879
+ status: row.status,
880
+ nameKind: row.name_kind,
881
+ count: Number(row.n),
882
+ minSeq: Number(row.min_seq),
883
+ maxSeq: Number(row.max_seq),
884
+ minName: String(row.min_name),
885
+ maxName: String(row.max_name),
886
+ minEnqueuedAt: ms(row.min_enqueued_at),
887
+ minStartedAt: ms(row.min_started_at),
888
+ maxStartedAt: ms(row.max_started_at),
889
+ maxFinishedAt: ms(row.max_finished_at),
890
+ sumAttempts: Number(row.sum_attempts),
891
+ }));
892
+ }
893
+ /**
894
+ * The run's checkpoints matching `query`, in `seq` order and paged in the database — a fan's
895
+ * failures or one page of its members without the rest of the run. An excluded group keeps the
896
+ * ungrouped rows (`parallel_group is null or not in (...)`); an empty `statuses`/`namePrefixes`
897
+ * matches nothing, so it returns before querying.
898
+ */
899
+ async queryCheckpoints(runId, query) {
900
+ if (query.statuses?.length === 0 || query.namePrefixes?.length === 0)
901
+ return [];
902
+ const client = this.client();
903
+ const q = client.from(DURABLE_TABLES.checkpoints).where('run_id', runId);
904
+ if (query.group !== undefined)
905
+ q.andWhere('parallel_group', query.group);
906
+ if (query.excludeGroups?.length) {
907
+ const excluded = query.excludeGroups;
908
+ q.andWhere((sub) => {
909
+ sub.whereNull('parallel_group').orWhereNotIn('parallel_group', excluded);
910
+ });
911
+ }
912
+ if (query.statuses)
913
+ q.whereIn('status', query.statuses);
914
+ if (query.namePrefixes) {
915
+ const prefixes = query.namePrefixes;
916
+ const dialect = client.dialect.name;
917
+ q.andWhere((sub) => {
918
+ for (const prefix of prefixes) {
919
+ sub.orWhereRaw(prefixSql(dialect, 'name', prefix), [prefix]);
920
+ }
921
+ });
922
+ }
923
+ q.orderBy('seq', 'asc');
924
+ if (query.limit !== undefined)
925
+ q.limit(query.limit);
926
+ if (query.offset) {
927
+ // An OFFSET alone is not valid SQL on SQLite/MySQL; an unbounded page gets a limit no run reaches.
928
+ if (query.limit === undefined)
929
+ q.limit(Number.MAX_SAFE_INTEGER);
930
+ q.offset(query.offset);
931
+ }
932
+ return (await q).map(rowToCheckpoint);
933
+ }
671
934
  // --- internals ----------------------------------------------------------
672
935
  /** Rewrite a run's normalized attribute rows: delete the old set, insert the current one. Mirrors
673
936
  * the in-memory store's reindex so the side-table always reflects the run's live searchAttributes. */
@@ -693,9 +956,49 @@ export class LucidStateStore {
693
956
  */
694
957
  /** Rows per multi-row INSERT in {@link LucidStateStore.registerChildWaits}. */
695
958
  const CHILD_WAIT_ROWS = 100;
959
+ /** Run ids per `IN (...)` in {@link LucidStateStore.deleteRuns}. */
960
+ const DELETE_RUNS_CHUNK = 500;
961
+ /**
962
+ * One conditional UPDATE: the `status = 'pending'` predicate is the compare, the affected-row count
963
+ * the answer. A missing row matches nothing, so it is never created.
964
+ */
965
+ async function updateCheckpointIfPending(client, checkpoint) {
966
+ const { run_id: _runId, seq: _seq, ...row } = checkpointToRow(checkpoint);
967
+ const affected = await client
968
+ .from(DURABLE_TABLES.checkpoints)
969
+ .where('run_id', checkpoint.runId)
970
+ .andWhere('seq', checkpoint.seq)
971
+ .andWhere('status', 'pending')
972
+ .update(row);
973
+ return rowsAffected(affected) > 0;
974
+ }
975
+ /**
976
+ * A case-sensitive "`column` starts with ?" predicate, binding the prefix once. `LIKE` would ignore
977
+ * case on SQLite and on MySQL's default collations (and treat `_` as a wildcard), where the JS
978
+ * `startsWith` this must agree with does not. MySQL compares bytes via `BINARY`.
979
+ */
980
+ function prefixSql(dialect, column, prefix) {
981
+ const head = `substr(${column}, 1, ${prefix.length})`;
982
+ return dialect === 'mysql' ? `binary ${head} = ?` : `${head} = ?`;
983
+ }
984
+ /** The SQL `CASE` of `checkpointNameKind` over the `name` column. */
985
+ function nameKindSql(dialect) {
986
+ const starts = (prefix) => {
987
+ const head = `substr(name, 1, ${prefix.length})`;
988
+ return dialect === 'mysql' ? `binary ${head} = '${prefix}'` : `${head} = '${prefix}'`;
989
+ };
990
+ return (`case when ${starts('signal:child:')} then 'child' ` +
991
+ `when ${starts('fan:')} then 'folded' ` +
992
+ `when ${starts('spawn:')} then 'spawn' else 'step' end`);
993
+ }
696
994
  function escapeLike(value) {
697
995
  return value.replace(/[!%_]/g, (c) => `!${c}`);
698
996
  }
997
+ /** Whether this connection's dialect supports `SELECT … FOR UPDATE` row locks. */
998
+ function locksRows(client) {
999
+ const name = client.dialect.name;
1000
+ return name === 'postgres' || name === 'mysql';
1001
+ }
699
1002
  /** Knex `.update()` / `.delete()` return the affected row count as a number across dialects. */
700
1003
  function rowsAffected(result) {
701
1004
  if (typeof result === 'number')
@@ -707,7 +1010,7 @@ function rowsAffected(result) {
707
1010
  function scheduleToRow(r) {
708
1011
  return {
709
1012
  id: r.id,
710
- namespace: r.namespace,
1013
+ namespace: normalizeNamespace(r.namespace),
711
1014
  workflow: r.workflow,
712
1015
  paused: r.paused,
713
1016
  next_fire_at: r.nextFireAt,
@@ -719,17 +1022,19 @@ function scheduleToRow(r) {
719
1022
  };
720
1023
  }
721
1024
  function rowToSchedule(row) {
722
- const tags = row.tags ? JSON.parse(row.tags) : undefined;
1025
+ const tags = row.tags
1026
+ ? parseJsonColumn(row.tags, `${DURABLE_TABLES.schedules}.tags`, row.id)
1027
+ : undefined;
723
1028
  return {
724
1029
  id: row.id,
725
- namespace: row.namespace,
1030
+ namespace: normalizeNamespace(row.namespace),
726
1031
  workflow: row.workflow,
727
1032
  // SQLite/MySQL hand a boolean column back as 0/1 (some drivers as a string).
728
1033
  paused: row.paused === true || row.paused === 1 || row.paused === '1' || row.paused === 'true',
729
1034
  nextFireAt: row.next_fire_at == null ? null : Number(row.next_fire_at),
730
1035
  ...(tags?.length ? { tags } : {}),
731
- spec: row.spec ? JSON.parse(row.spec) : {},
732
- state: row.state ? JSON.parse(row.state) : {},
1036
+ spec: parseJsonColumn(row.spec, `${DURABLE_TABLES.schedules}.spec`, row.id) ?? {},
1037
+ state: parseJsonColumn(row.state, `${DURABLE_TABLES.schedules}.state`, row.id) ?? {},
733
1038
  createdAt: new Date(Number(row.created_at)),
734
1039
  updatedAt: new Date(Number(row.updated_at)),
735
1040
  };