bunqueue 2.8.59 → 2.9.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 (380) hide show
  1. package/README.md +109 -77
  2. package/dist/application/background/dlq.js +2 -0
  3. package/dist/application/contextFactory.js +5 -0
  4. package/dist/application/dlqManager.d.ts +11 -1
  5. package/dist/application/dlqManager.js +48 -10
  6. package/dist/application/dlqRetry.js +59 -38
  7. package/dist/application/eventsManager.d.ts +1 -1
  8. package/dist/application/eventsManager.js +30 -26
  9. package/dist/application/lockManager.js +1 -1
  10. package/dist/application/operations/jobManagement.d.ts +4 -0
  11. package/dist/application/operations/jobMoveOperations.js +9 -4
  12. package/dist/application/postgres-queue-manager/batchSnapshot.d.ts +16 -0
  13. package/dist/application/postgres-queue-manager/batchSnapshot.js +17 -0
  14. package/dist/application/postgres-queue-manager/cloud.d.ts +30 -0
  15. package/dist/application/postgres-queue-manager/cloud.js +55 -0
  16. package/dist/application/postgres-queue-manager/config.d.ts +5 -0
  17. package/dist/application/postgres-queue-manager/config.js +1 -0
  18. package/dist/application/postgres-queue-manager/control.d.ts +26 -0
  19. package/dist/application/postgres-queue-manager/control.js +186 -0
  20. package/dist/application/postgres-queue-manager/deferredWrites.d.ts +13 -0
  21. package/dist/application/postgres-queue-manager/deferredWrites.js +60 -0
  22. package/dist/application/postgres-queue-manager/delivery.d.ts +19 -0
  23. package/dist/application/postgres-queue-manager/delivery.js +80 -0
  24. package/dist/application/postgres-queue-manager/lease.d.ts +13 -0
  25. package/dist/application/postgres-queue-manager/lease.js +88 -0
  26. package/dist/application/postgres-queue-manager/lifetimeMetrics.d.ts +32 -0
  27. package/dist/application/postgres-queue-manager/lifetimeMetrics.js +53 -0
  28. package/dist/application/postgres-queue-manager/maintenance.d.ts +14 -0
  29. package/dist/application/postgres-queue-manager/maintenance.js +100 -0
  30. package/dist/application/postgres-queue-manager/operationGate.d.ts +26 -0
  31. package/dist/application/postgres-queue-manager/operationGate.js +96 -0
  32. package/dist/application/postgres-queue-manager/operations.d.ts +25 -0
  33. package/dist/application/postgres-queue-manager/operations.js +194 -0
  34. package/dist/application/postgres-queue-manager/projectionRefreshes.d.ts +43 -0
  35. package/dist/application/postgres-queue-manager/projectionRefreshes.js +170 -0
  36. package/dist/application/postgres-queue-manager/queries.d.ts +142 -0
  37. package/dist/application/postgres-queue-manager/queries.js +231 -0
  38. package/dist/application/postgres-queue-manager/relationships.d.ts +10 -0
  39. package/dist/application/postgres-queue-manager/relationships.js +45 -0
  40. package/dist/application/postgres-queue-manager/services.d.ts +31 -0
  41. package/dist/application/postgres-queue-manager/services.js +149 -0
  42. package/dist/application/postgres-queue-manager/snapshot.d.ts +51 -0
  43. package/dist/application/postgres-queue-manager/snapshot.js +236 -0
  44. package/dist/application/postgres-queue-manager/snapshotViews.d.ts +15 -0
  45. package/dist/application/postgres-queue-manager/snapshotViews.js +100 -0
  46. package/dist/application/postgres-queue-manager/startupEventBuffer.d.ts +12 -0
  47. package/dist/application/postgres-queue-manager/startupEventBuffer.js +36 -0
  48. package/dist/application/postgres-queue-manager/state.d.ts +47 -0
  49. package/dist/application/postgres-queue-manager/state.js +273 -0
  50. package/dist/application/postgres-queue-manager/terminalDelivery.d.ts +20 -0
  51. package/dist/application/postgres-queue-manager/terminalDelivery.js +100 -0
  52. package/dist/application/postgresQueueManager.d.ts +2 -0
  53. package/dist/application/postgresQueueManager.js +1 -0
  54. package/dist/application/queue-manager/ack.js +1 -1
  55. package/dist/application/queue-manager/delivery.js +1 -1
  56. package/dist/application/queue-manager/flow-failures.js +4 -0
  57. package/dist/application/queue-manager/limits.d.ts +2 -0
  58. package/dist/application/queue-manager/limits.js +4 -0
  59. package/dist/application/queue-manager/observability.js +15 -3
  60. package/dist/application/queue-manager/queries.d.ts +7 -0
  61. package/dist/application/queue-manager/queries.js +9 -0
  62. package/dist/application/queue-manager/services.d.ts +1 -1
  63. package/dist/application/queue-manager/services.js +4 -2
  64. package/dist/application/queue-manager/state.js +16 -1
  65. package/dist/application/statsManager.d.ts +1 -1
  66. package/dist/application/statsManager.js +1 -1
  67. package/dist/cli/commands/server.js +1 -1
  68. package/dist/client/events.js +2 -2
  69. package/dist/client/flow.js +0 -1
  70. package/dist/client/forwarder.d.ts +6 -4
  71. package/dist/client/forwarder.js +5 -3
  72. package/dist/client/queue/dlq.d.ts +2 -0
  73. package/dist/client/queue/dlq.js +14 -0
  74. package/dist/client/queue/dlqOps.d.ts +2 -0
  75. package/dist/client/queue/dlqOps.js +4 -0
  76. package/dist/client/queue/helpers.js +2 -0
  77. package/dist/client/queue/operations/add/single.js +1 -1
  78. package/dist/client/queue/runtime/configuration.d.ts +4 -0
  79. package/dist/client/queue/runtime/configuration.js +8 -0
  80. package/dist/client/sandboxed/runtime/state.js +2 -2
  81. package/dist/client/tcp/connection.d.ts +1 -1
  82. package/dist/client/tcp/connection.js +1 -1
  83. package/dist/client/tcp/runtime/state.js +2 -2
  84. package/dist/client/types/metrics.d.ts +1 -1
  85. package/dist/client/worker/runtime/control.js +0 -1
  86. package/dist/client/worker/runtime/execution.js +3 -8
  87. package/dist/client/worker/runtime/lifecycle.js +0 -1
  88. package/dist/client/worker/runtime/polling.d.ts +1 -0
  89. package/dist/client/worker/runtime/polling.js +9 -0
  90. package/dist/client/worker/runtime/state.js +3 -3
  91. package/dist/client/workflow/compensationChild.d.ts +2 -0
  92. package/dist/client/workflow/compensationChild.js +3 -1
  93. package/dist/client/workflow/compensationPass.d.ts +1 -0
  94. package/dist/client/workflow/compensationPass.js +18 -2
  95. package/dist/client/workflow/compensator.d.ts +2 -1
  96. package/dist/client/workflow/compensator.js +11 -3
  97. package/dist/client/workflow/engine.js +1 -1
  98. package/dist/client/workflow/executionFence.d.ts +15 -0
  99. package/dist/client/workflow/executionFence.js +29 -0
  100. package/dist/client/workflow/executor.d.ts +5 -11
  101. package/dist/client/workflow/executor.js +48 -47
  102. package/dist/client/workflow/executorLifecycle.d.ts +1 -0
  103. package/dist/client/workflow/executorLifecycle.js +41 -10
  104. package/dist/client/workflow/executorNodes.d.ts +1 -0
  105. package/dist/client/workflow/executorNodes.js +45 -16
  106. package/dist/client/workflow/executorQueue.d.ts +9 -0
  107. package/dist/client/workflow/executorQueue.js +15 -0
  108. package/dist/client/workflow/forEachRunner.d.ts +4 -0
  109. package/dist/client/workflow/forEachRunner.js +70 -0
  110. package/dist/client/workflow/loops.d.ts +4 -5
  111. package/dist/client/workflow/loops.js +27 -93
  112. package/dist/client/workflow/mapRunner.d.ts +1 -1
  113. package/dist/client/workflow/mapRunner.js +11 -2
  114. package/dist/client/workflow/recovery.d.ts +1 -0
  115. package/dist/client/workflow/recovery.js +24 -18
  116. package/dist/client/workflow/rollbackControl.d.ts +1 -0
  117. package/dist/client/workflow/rollbackControl.js +5 -2
  118. package/dist/client/workflow/runner.d.ts +3 -1
  119. package/dist/client/workflow/runner.js +26 -3
  120. package/dist/client/workflow/stepTypes.js +1 -1
  121. package/dist/client/workflow/subWorkflowRunner.d.ts +1 -0
  122. package/dist/client/workflow/subWorkflowRunner.js +7 -0
  123. package/dist/client/workflow/waitFor.d.ts +4 -0
  124. package/dist/client/workflow/waitFor.js +23 -11
  125. package/dist/client/workflow/workflowDecisions.d.ts +1 -1
  126. package/dist/client/workflow/workflowDecisions.js +3 -1
  127. package/dist/config/resolve.d.ts +14 -0
  128. package/dist/config/resolve.js +50 -5
  129. package/dist/config/types.d.ts +18 -0
  130. package/dist/domain/queue/dlqShard.d.ts +2 -0
  131. package/dist/domain/queue/dlqShard.js +16 -0
  132. package/dist/domain/queue/shard/dlq.d.ts +1 -0
  133. package/dist/domain/queue/shard/dlq.js +3 -0
  134. package/dist/domain/types/commands/dlq.d.ts +5 -0
  135. package/dist/domain/types/commands/union.d.ts +1 -1
  136. package/dist/domain/types/cron.d.ts +5 -0
  137. package/dist/domain/types/cron.js +14 -3
  138. package/dist/domain/types/dlq.d.ts +1 -1
  139. package/dist/domain/types/dlq.js +1 -2
  140. package/dist/domain/types/jobs/model.d.ts +1 -1
  141. package/dist/infrastructure/cloud/commandHandler.js +5 -3
  142. package/dist/infrastructure/cloud/commands/integrations.js +11 -11
  143. package/dist/infrastructure/cloud/commands/jobs.js +48 -40
  144. package/dist/infrastructure/cloud/commands/queues.js +61 -75
  145. package/dist/infrastructure/cloud/queueAdapter/local.d.ts +41 -0
  146. package/dist/infrastructure/cloud/queueAdapter/local.js +187 -0
  147. package/dist/infrastructure/cloud/queueAdapter/postgres.d.ts +42 -0
  148. package/dist/infrastructure/cloud/queueAdapter/postgres.js +188 -0
  149. package/dist/infrastructure/cloud/queueAdapter/registry.d.ts +4 -0
  150. package/dist/infrastructure/cloud/queueAdapter/registry.js +15 -0
  151. package/dist/infrastructure/cloud/queueAdapter/types.d.ts +87 -0
  152. package/dist/infrastructure/cloud/queueAdapter/types.js +1 -0
  153. package/dist/infrastructure/cloud/snapshot/analytics.d.ts +2 -0
  154. package/dist/infrastructure/cloud/snapshot/analytics.js +7 -0
  155. package/dist/infrastructure/cloud/snapshot/collector.d.ts +4 -0
  156. package/dist/infrastructure/cloud/snapshot/collector.js +39 -1
  157. package/dist/infrastructure/cloud/snapshot/config.d.ts +3 -0
  158. package/dist/infrastructure/cloud/snapshot/config.js +43 -0
  159. package/dist/infrastructure/cloud/snapshot/jobs.d.ts +3 -0
  160. package/dist/infrastructure/cloud/snapshot/jobs.js +32 -1
  161. package/dist/infrastructure/cloud/snapshotCollector.js +20 -35
  162. package/dist/infrastructure/cloud/snapshotHelpers.d.ts +3 -3
  163. package/dist/infrastructure/cloud/snapshotHelpers.js +3 -3
  164. package/dist/infrastructure/cloud/statsRefresh.js +2 -1
  165. package/dist/infrastructure/cloud/types/command.d.ts +2 -2
  166. package/dist/infrastructure/persistence/postgres/admission.d.ts +18 -0
  167. package/dist/infrastructure/persistence/postgres/admission.js +193 -0
  168. package/dist/infrastructure/persistence/postgres/admissionParent.d.ts +5 -0
  169. package/dist/infrastructure/persistence/postgres/admissionParent.js +35 -0
  170. package/dist/infrastructure/persistence/postgres/admissionResult.d.ts +9 -0
  171. package/dist/infrastructure/persistence/postgres/admissionResult.js +1 -0
  172. package/dist/infrastructure/persistence/postgres/admissionStore.d.ts +12 -0
  173. package/dist/infrastructure/persistence/postgres/admissionStore.js +101 -0
  174. package/dist/infrastructure/persistence/postgres/advisoryLocks.d.ts +2 -0
  175. package/dist/infrastructure/persistence/postgres/advisoryLocks.js +13 -0
  176. package/dist/infrastructure/persistence/postgres/batchAdmission.d.ts +11 -0
  177. package/dist/infrastructure/persistence/postgres/batchAdmission.js +110 -0
  178. package/dist/infrastructure/persistence/postgres/batchCompletion.d.ts +4 -0
  179. package/dist/infrastructure/persistence/postgres/batchCompletion.js +174 -0
  180. package/dist/infrastructure/persistence/postgres/batchEvents.d.ts +14 -0
  181. package/dist/infrastructure/persistence/postgres/batchEvents.js +72 -0
  182. package/dist/infrastructure/persistence/postgres/brokerSessions.d.ts +14 -0
  183. package/dist/infrastructure/persistence/postgres/brokerSessions.js +94 -0
  184. package/dist/infrastructure/persistence/postgres/claimBatch.d.ts +11 -0
  185. package/dist/infrastructure/persistence/postgres/claimBatch.js +56 -0
  186. package/dist/infrastructure/persistence/postgres/claimSelection.d.ts +4 -0
  187. package/dist/infrastructure/persistence/postgres/claimSelection.js +198 -0
  188. package/dist/infrastructure/persistence/postgres/claims.d.ts +3 -0
  189. package/dist/infrastructure/persistence/postgres/claims.js +137 -0
  190. package/dist/infrastructure/persistence/postgres/cloudReadModel.d.ts +26 -0
  191. package/dist/infrastructure/persistence/postgres/cloudReadModel.js +123 -0
  192. package/dist/infrastructure/persistence/postgres/codec.d.ts +30 -0
  193. package/dist/infrastructure/persistence/postgres/codec.js +82 -0
  194. package/dist/infrastructure/persistence/postgres/completionEvents.d.ts +11 -0
  195. package/dist/infrastructure/persistence/postgres/completionEvents.js +21 -0
  196. package/dist/infrastructure/persistence/postgres/completionLifecycle.d.ts +11 -0
  197. package/dist/infrastructure/persistence/postgres/completionLifecycle.js +145 -0
  198. package/dist/infrastructure/persistence/postgres/completionOutcome.d.ts +4 -0
  199. package/dist/infrastructure/persistence/postgres/completionOutcome.js +112 -0
  200. package/dist/infrastructure/persistence/postgres/completionQueries.d.ts +10 -0
  201. package/dist/infrastructure/persistence/postgres/completionQueries.js +87 -0
  202. package/dist/infrastructure/persistence/postgres/connection.d.ts +3 -0
  203. package/dist/infrastructure/persistence/postgres/connection.js +15 -0
  204. package/dist/infrastructure/persistence/postgres/context.d.ts +28 -0
  205. package/dist/infrastructure/persistence/postgres/context.js +74 -0
  206. package/dist/infrastructure/persistence/postgres/control.d.ts +23 -0
  207. package/dist/infrastructure/persistence/postgres/control.js +105 -0
  208. package/dist/infrastructure/persistence/postgres/crons.d.ts +18 -0
  209. package/dist/infrastructure/persistence/postgres/crons.js +205 -0
  210. package/dist/infrastructure/persistence/postgres/deduplication.d.ts +9 -0
  211. package/dist/infrastructure/persistence/postgres/deduplication.js +47 -0
  212. package/dist/infrastructure/persistence/postgres/dependencyDestruction.d.ts +14 -0
  213. package/dist/infrastructure/persistence/postgres/dependencyDestruction.js +74 -0
  214. package/dist/infrastructure/persistence/postgres/dependencyPromotion.d.ts +29 -0
  215. package/dist/infrastructure/persistence/postgres/dependencyPromotion.js +212 -0
  216. package/dist/infrastructure/persistence/postgres/destructiveMutations.d.ts +4 -0
  217. package/dist/infrastructure/persistence/postgres/destructiveMutations.js +111 -0
  218. package/dist/infrastructure/persistence/postgres/dlqLifecycle.d.ts +13 -0
  219. package/dist/infrastructure/persistence/postgres/dlqLifecycle.js +184 -0
  220. package/dist/infrastructure/persistence/postgres/dlqMaintenance.d.ts +6 -0
  221. package/dist/infrastructure/persistence/postgres/dlqMaintenance.js +36 -0
  222. package/dist/infrastructure/persistence/postgres/dlqRetryPlan.d.ts +21 -0
  223. package/dist/infrastructure/persistence/postgres/dlqRetryPlan.js +92 -0
  224. package/dist/infrastructure/persistence/postgres/eventCommitGc.d.ts +27 -0
  225. package/dist/infrastructure/persistence/postgres/eventCommitGc.js +62 -0
  226. package/dist/infrastructure/persistence/postgres/eventJournal.d.ts +18 -0
  227. package/dist/infrastructure/persistence/postgres/eventJournal.js +76 -0
  228. package/dist/infrastructure/persistence/postgres/eventJournalSchema.d.ts +5 -0
  229. package/dist/infrastructure/persistence/postgres/eventJournalSchema.js +253 -0
  230. package/dist/infrastructure/persistence/postgres/eventPruneWatermarks.d.ts +24 -0
  231. package/dist/infrastructure/persistence/postgres/eventPruneWatermarks.js +111 -0
  232. package/dist/infrastructure/persistence/postgres/eventRetention.d.ts +18 -0
  233. package/dist/infrastructure/persistence/postgres/eventRetention.js +76 -0
  234. package/dist/infrastructure/persistence/postgres/events.d.ts +45 -0
  235. package/dist/infrastructure/persistence/postgres/events.js +249 -0
  236. package/dist/infrastructure/persistence/postgres/expiry.d.ts +3 -0
  237. package/dist/infrastructure/persistence/postgres/expiry.js +74 -0
  238. package/dist/infrastructure/persistence/postgres/flowFailures.d.ts +17 -0
  239. package/dist/infrastructure/persistence/postgres/flowFailures.js +199 -0
  240. package/dist/infrastructure/persistence/postgres/jobData.d.ts +3 -0
  241. package/dist/infrastructure/persistence/postgres/jobData.js +32 -0
  242. package/dist/infrastructure/persistence/postgres/leaseRelease.d.ts +9 -0
  243. package/dist/infrastructure/persistence/postgres/leaseRelease.js +120 -0
  244. package/dist/infrastructure/persistence/postgres/leaseRenewal.d.ts +4 -0
  245. package/dist/infrastructure/persistence/postgres/leaseRenewal.js +35 -0
  246. package/dist/infrastructure/persistence/postgres/lifetimeMetrics.d.ts +15 -0
  247. package/dist/infrastructure/persistence/postgres/lifetimeMetrics.js +46 -0
  248. package/dist/infrastructure/persistence/postgres/lifetimeMetricsFinalizer.d.ts +4 -0
  249. package/dist/infrastructure/persistence/postgres/lifetimeMetricsFinalizer.js +13 -0
  250. package/dist/infrastructure/persistence/postgres/logs.d.ts +6 -0
  251. package/dist/infrastructure/persistence/postgres/logs.js +70 -0
  252. package/dist/infrastructure/persistence/postgres/maintenance.d.ts +6 -0
  253. package/dist/infrastructure/persistence/postgres/maintenance.js +138 -0
  254. package/dist/infrastructure/persistence/postgres/maintenanceFlights.d.ts +14 -0
  255. package/dist/infrastructure/persistence/postgres/maintenanceFlights.js +66 -0
  256. package/dist/infrastructure/persistence/postgres/metricWrites.d.ts +9 -0
  257. package/dist/infrastructure/persistence/postgres/metricWrites.js +94 -0
  258. package/dist/infrastructure/persistence/postgres/mutations.d.ts +9 -0
  259. package/dist/infrastructure/persistence/postgres/mutations.js +171 -0
  260. package/dist/infrastructure/persistence/postgres/outcomes.d.ts +4 -0
  261. package/dist/infrastructure/persistence/postgres/outcomes.js +194 -0
  262. package/dist/infrastructure/persistence/postgres/policies.d.ts +11 -0
  263. package/dist/infrastructure/persistence/postgres/policies.js +18 -0
  264. package/dist/infrastructure/persistence/postgres/postCommitMaintenance.d.ts +17 -0
  265. package/dist/infrastructure/persistence/postgres/postCommitMaintenance.js +117 -0
  266. package/dist/infrastructure/persistence/postgres/promotion.d.ts +3 -0
  267. package/dist/infrastructure/persistence/postgres/promotion.js +43 -0
  268. package/dist/infrastructure/persistence/postgres/queries.d.ts +22 -0
  269. package/dist/infrastructure/persistence/postgres/queries.js +152 -0
  270. package/dist/infrastructure/persistence/postgres/queueDestruction.d.ts +3 -0
  271. package/dist/infrastructure/persistence/postgres/queueDestruction.js +154 -0
  272. package/dist/infrastructure/persistence/postgres/queueLifecycle.d.ts +10 -0
  273. package/dist/infrastructure/persistence/postgres/queueLifecycle.js +60 -0
  274. package/dist/infrastructure/persistence/postgres/rateLimit.d.ts +6 -0
  275. package/dist/infrastructure/persistence/postgres/rateLimit.js +10 -0
  276. package/dist/infrastructure/persistence/postgres/readModels.d.ts +32 -0
  277. package/dist/infrastructure/persistence/postgres/readModels.js +72 -0
  278. package/dist/infrastructure/persistence/postgres/recovery.d.ts +3 -0
  279. package/dist/infrastructure/persistence/postgres/recovery.js +178 -0
  280. package/dist/infrastructure/persistence/postgres/relationships.d.ts +9 -0
  281. package/dist/infrastructure/persistence/postgres/relationships.js +201 -0
  282. package/dist/infrastructure/persistence/postgres/removeUnprocessedChildren.d.ts +4 -0
  283. package/dist/infrastructure/persistence/postgres/removeUnprocessedChildren.js +241 -0
  284. package/dist/infrastructure/persistence/postgres/repeatMutations.d.ts +5 -0
  285. package/dist/infrastructure/persistence/postgres/repeatMutations.js +37 -0
  286. package/dist/infrastructure/persistence/postgres/runtime.d.ts +46 -0
  287. package/dist/infrastructure/persistence/postgres/runtime.js +236 -0
  288. package/dist/infrastructure/persistence/postgres/runtimeConfig.d.ts +21 -0
  289. package/dist/infrastructure/persistence/postgres/runtimeConfig.js +39 -0
  290. package/dist/infrastructure/persistence/postgres/schema.d.ts +4 -0
  291. package/dist/infrastructure/persistence/postgres/schema.js +257 -0
  292. package/dist/infrastructure/persistence/postgres/schemaInitialization.d.ts +3 -0
  293. package/dist/infrastructure/persistence/postgres/schemaInitialization.js +221 -0
  294. package/dist/infrastructure/persistence/postgres/serialAdmission.d.ts +6 -0
  295. package/dist/infrastructure/persistence/postgres/serialAdmission.js +96 -0
  296. package/dist/infrastructure/persistence/postgres/snapshotBudget.d.ts +3 -0
  297. package/dist/infrastructure/persistence/postgres/snapshotBudget.js +83 -0
  298. package/dist/infrastructure/persistence/postgres/storageHealth.d.ts +10 -0
  299. package/dist/infrastructure/persistence/postgres/storageHealth.js +29 -0
  300. package/dist/infrastructure/persistence/postgres/store.d.ts +90 -0
  301. package/dist/infrastructure/persistence/postgres/store.js +136 -0
  302. package/dist/infrastructure/persistence/postgres/telemetry.d.ts +6 -0
  303. package/dist/infrastructure/persistence/postgres/telemetry.js +88 -0
  304. package/dist/infrastructure/persistence/postgres/terminal.d.ts +8 -0
  305. package/dist/infrastructure/persistence/postgres/terminal.js +137 -0
  306. package/dist/infrastructure/persistence/postgres/transactionRetry.d.ts +6 -0
  307. package/dist/infrastructure/persistence/postgres/transactionRetry.js +42 -0
  308. package/dist/infrastructure/persistence/postgres/types.d.ts +175 -0
  309. package/dist/infrastructure/persistence/postgres/types.js +1 -0
  310. package/dist/infrastructure/persistence/postgres/workers.d.ts +15 -0
  311. package/dist/infrastructure/persistence/postgres/workers.js +126 -0
  312. package/dist/infrastructure/persistence/postgres.d.ts +2 -0
  313. package/dist/infrastructure/persistence/postgres.js +1 -0
  314. package/dist/infrastructure/persistence/sqlite/jobs.js +2 -0
  315. package/dist/infrastructure/persistence/sqlite.d.ts +1 -1
  316. package/dist/infrastructure/scheduler/cron/persisted.d.ts +5 -0
  317. package/dist/infrastructure/scheduler/cron/persisted.js +27 -0
  318. package/dist/infrastructure/scheduler/cron/runtime.js +5 -10
  319. package/dist/infrastructure/scheduler/cron/validation.d.ts +3 -0
  320. package/dist/infrastructure/scheduler/cron/validation.js +11 -0
  321. package/dist/infrastructure/scheduler/cronParser.d.ts +1 -1
  322. package/dist/infrastructure/scheduler/cronParser.js +144 -11
  323. package/dist/infrastructure/server/bootstrap.d.ts +2 -3
  324. package/dist/infrastructure/server/bootstrap.js +33 -59
  325. package/dist/infrastructure/server/errors.d.ts +4 -0
  326. package/dist/infrastructure/server/errors.js +54 -0
  327. package/dist/infrastructure/server/handler-routes/control.d.ts +5 -5
  328. package/dist/infrastructure/server/handler-routes/control.js +3 -1
  329. package/dist/infrastructure/server/handler-routes/jobs.js +0 -3
  330. package/dist/infrastructure/server/handler-routes/monitoring.d.ts +2 -2
  331. package/dist/infrastructure/server/handler.js +9 -11
  332. package/dist/infrastructure/server/handlerRoutes.d.ts +2 -2
  333. package/dist/infrastructure/server/handlerRoutes.js +2 -2
  334. package/dist/infrastructure/server/handlers/advanced/dependencies.js +7 -6
  335. package/dist/infrastructure/server/handlers/advanced/jobs.js +19 -6
  336. package/dist/infrastructure/server/handlers/advanced/queue.d.ts +9 -9
  337. package/dist/infrastructure/server/handlers/advanced/queue.js +91 -27
  338. package/dist/infrastructure/server/handlers/core.js +32 -31
  339. package/dist/infrastructure/server/handlers/cron.d.ts +4 -4
  340. package/dist/infrastructure/server/handlers/cron.js +60 -59
  341. package/dist/infrastructure/server/handlers/dashboard.d.ts +1 -1
  342. package/dist/infrastructure/server/handlers/dashboard.js +21 -8
  343. package/dist/infrastructure/server/handlers/dlq.d.ts +6 -3
  344. package/dist/infrastructure/server/handlers/dlq.js +35 -9
  345. package/dist/infrastructure/server/handlers/flow.js +2 -1
  346. package/dist/infrastructure/server/handlers/management.d.ts +5 -5
  347. package/dist/infrastructure/server/handlers/management.js +36 -9
  348. package/dist/infrastructure/server/handlers/monitoring/health.d.ts +5 -5
  349. package/dist/infrastructure/server/handlers/monitoring/health.js +45 -16
  350. package/dist/infrastructure/server/handlers/monitoring/operations.d.ts +1 -1
  351. package/dist/infrastructure/server/handlers/monitoring/operations.js +8 -1
  352. package/dist/infrastructure/server/handlers/monitoring/workers.d.ts +3 -3
  353. package/dist/infrastructure/server/handlers/monitoring/workers.js +31 -7
  354. package/dist/infrastructure/server/handlers/pushBatchValidation.d.ts +3 -1
  355. package/dist/infrastructure/server/handlers/pushBatchValidation.js +52 -7
  356. package/dist/infrastructure/server/handlers/query.d.ts +1 -1
  357. package/dist/infrastructure/server/handlers/query.js +5 -4
  358. package/dist/infrastructure/server/http.js +2 -2
  359. package/dist/infrastructure/server/httpDashboardEndpoints.d.ts +1 -1
  360. package/dist/infrastructure/server/httpDashboardEndpoints.js +19 -6
  361. package/dist/infrastructure/server/httpEndpoints.js +20 -7
  362. package/dist/infrastructure/server/httpRouteQueues.js +11 -1
  363. package/dist/infrastructure/server/shutdownCoordinator.d.ts +24 -0
  364. package/dist/infrastructure/server/shutdownCoordinator.js +106 -0
  365. package/dist/infrastructure/server/sseHandler.js +8 -3
  366. package/dist/infrastructure/server/storageAdapter.d.ts +29 -0
  367. package/dist/infrastructure/server/storageAdapter.js +61 -0
  368. package/dist/infrastructure/server/storageManager.d.ts +12 -0
  369. package/dist/infrastructure/server/storageManager.js +102 -0
  370. package/dist/infrastructure/server/tcp.js +2 -3
  371. package/dist/infrastructure/server/ws/snapshots.d.ts +1 -1
  372. package/dist/infrastructure/server/ws/snapshots.js +19 -4
  373. package/dist/infrastructure/server/wsHandler.js +10 -5
  374. package/dist/main.js +1 -1
  375. package/dist/mcp/backend/embedded/services.js +2 -1
  376. package/dist/mcp/index.d.ts +2 -2
  377. package/dist/mcp/index.js +2 -2
  378. package/dist/shared/storageHealth.d.ts +9 -0
  379. package/dist/shared/storageHealth.js +12 -0
  380. package/package.json +85 -74
@@ -0,0 +1,221 @@
1
+ import { postgresAdvisoryLockName } from './advisoryLocks';
2
+ import { databaseNow } from './context';
3
+ import { POSTGRES_ASSIGN_EVENT_COMMIT_BODY, POSTGRES_REGISTER_EVENT_ROWS_BODY, POSTGRES_REGISTER_WATERMARK_ROWS_BODY, } from './eventJournalSchema';
4
+ import { POSTGRES_SCHEMA, POSTGRES_SCHEMA_VERSION } from './schema';
5
+ const EXPECTED_FUNCTION_BODIES = new Map([
6
+ ['bunqueue_register_event_rows', POSTGRES_REGISTER_EVENT_ROWS_BODY],
7
+ ['bunqueue_register_watermark_rows', POSTGRES_REGISTER_WATERMARK_ROWS_BODY],
8
+ ['bunqueue_assign_event_commit', POSTGRES_ASSIGN_EVENT_COMMIT_BODY],
9
+ ]);
10
+ function normalizeFunctionBody(value) {
11
+ return value.replaceAll(/\s+/g, ' ').trim();
12
+ }
13
+ async function hasCurrentSchema(tx) {
14
+ const [table] = await tx `
15
+ SELECT to_regclass('bunqueue_schema_migrations') IS NOT NULL AS exists
16
+ `;
17
+ if (!table.exists)
18
+ return false;
19
+ const [migration] = await tx `
20
+ SELECT
21
+ EXISTS (
22
+ SELECT 1 FROM bunqueue_schema_migrations
23
+ WHERE version = ${POSTGRES_SCHEMA_VERSION}
24
+ ) AS current,
25
+ MAX(version) AS latest
26
+ FROM bunqueue_schema_migrations
27
+ `;
28
+ const latest = Number(migration.latest ?? 0);
29
+ if (latest > POSTGRES_SCHEMA_VERSION) {
30
+ throw new Error(`PostgreSQL schema version ${latest} is newer than supported version ${POSTGRES_SCHEMA_VERSION}`);
31
+ }
32
+ if (!migration.current)
33
+ return false;
34
+ const [objects] = await tx `
35
+ WITH expected_columns(table_name, column_name, type_name, not_null, default_kind) AS (
36
+ VALUES
37
+ ('bunqueue_events', 'transaction_id', 'bigint', TRUE, 'transaction'),
38
+ ('bunqueue_event_commits', 'namespace', 'text', TRUE, 'none'),
39
+ ('bunqueue_event_commits', 'transaction_id', 'bigint', TRUE, 'none'),
40
+ ('bunqueue_event_commits', 'commit_seq', 'bigint', FALSE, 'none'),
41
+ ('bunqueue_event_prune_watermarks', 'transaction_id', 'bigint', TRUE, 'transaction'),
42
+ ('bunqueue_event_prune_watermarks', 'commit_seq', 'bigint', FALSE, 'none'),
43
+ ('bunqueue_event_prune_watermarks', 'pruned_commit_seq', 'bigint', TRUE, 'zero'),
44
+ ('bunqueue_event_prune_watermarks', 'prunes_current_transaction', 'boolean', TRUE, 'false'),
45
+ ('bunqueue_brokers', 'session_id', 'text', FALSE, 'none'),
46
+ ('bunqueue_jobs', 'lease_broker_session_id', 'text', FALSE, 'none'),
47
+ ('bunqueue_workers', 'broker_session_id', 'text', FALSE, 'none')
48
+ ), expected_indexes(
49
+ index_name, table_name, columns, descending, predicate, is_unique
50
+ ) AS (
51
+ VALUES
52
+ ('bunqueue_events_transaction_idx', 'bunqueue_events',
53
+ ARRAY['namespace', 'transaction_id', 'id'], ARRAY[FALSE, FALSE, FALSE], '', FALSE),
54
+ ('bunqueue_event_commits_replay_idx', 'bunqueue_event_commits',
55
+ ARRAY['namespace', 'commit_seq', 'transaction_id'], ARRAY[FALSE, FALSE, FALSE],
56
+ 'commit_seqisnotnull', FALSE),
57
+ ('bunqueue_event_prune_watermarks_commit_idx', 'bunqueue_event_prune_watermarks',
58
+ ARRAY['namespace', 'queue', 'commit_seq'], ARRAY[FALSE, FALSE, TRUE],
59
+ 'commit_seqisnotnull', FALSE),
60
+ ('bunqueue_event_prune_watermarks_pending_commit_idx',
61
+ 'bunqueue_event_prune_watermarks', ARRAY['namespace', 'transaction_id'],
62
+ ARRAY[FALSE, FALSE], 'commit_seqisnull', FALSE),
63
+ ('bunqueue_event_prune_watermarks_transaction_idx',
64
+ 'bunqueue_event_prune_watermarks', ARRAY['namespace', 'transaction_id'],
65
+ ARRAY[FALSE, FALSE], '', FALSE),
66
+ ('bunqueue_jobs_broker_session_lease_idx', 'bunqueue_jobs',
67
+ ARRAY['namespace', 'lease_broker_id', 'lease_broker_session_id', 'id'],
68
+ ARRAY[FALSE, FALSE, FALSE, FALSE], 'state=''active''::text', FALSE),
69
+ ('bunqueue_workers_broker_session_idx', 'bunqueue_workers',
70
+ ARRAY['namespace', 'broker_id', 'broker_session_id', 'client_id'],
71
+ ARRAY[FALSE, FALSE, FALSE, FALSE], '', FALSE),
72
+ ('bunqueue_jobs_live_unique_key_idx', 'bunqueue_jobs',
73
+ ARRAY['namespace', 'queue', 'unique_key'], ARRAY[FALSE, FALSE, FALSE],
74
+ 'unique_keyisnotnullandstate=anyarray[''waiting''::text,''prioritized''::text,' ||
75
+ '''delayed''::text,''waiting-children''::text,''active''::text]', TRUE)
76
+ ), expected_triggers(
77
+ trigger_name, table_name, function_name, trigger_type, new_table,
78
+ is_constraint, is_deferrable
79
+ ) AS (
80
+ VALUES
81
+ ('bunqueue_events_register_commit', 'bunqueue_events',
82
+ 'bunqueue_register_event_rows', 4, 'new_event_rows', FALSE, FALSE),
83
+ ('bunqueue_watermarks_insert_register_commit', 'bunqueue_event_prune_watermarks',
84
+ 'bunqueue_register_watermark_rows', 4, 'new_watermark_rows', FALSE, FALSE),
85
+ ('bunqueue_watermarks_update_register_commit', 'bunqueue_event_prune_watermarks',
86
+ 'bunqueue_register_watermark_rows', 16, 'new_watermark_rows', FALSE, FALSE),
87
+ ('bunqueue_assign_event_commit', 'bunqueue_event_commits',
88
+ 'bunqueue_assign_event_commit', 5, NULL, TRUE, TRUE)
89
+ )
90
+ SELECT
91
+ EXISTS (
92
+ SELECT 1 FROM pg_sequence
93
+ WHERE seqrelid = to_regclass('bunqueue_event_commit_seq')
94
+ AND seqtypid = to_regtype('bigint')
95
+ AND seqincrement = 1 AND seqmin = 1
96
+ AND seqmax = 9223372036854775807
97
+ AND NOT seqcycle
98
+ AND seqcache = 1
99
+ )
100
+ AND to_regclass('bunqueue_event_commits') IS NOT NULL
101
+ AND (
102
+ SELECT COALESCE(bool_and(COALESCE(
103
+ attribute.atttypid = to_regtype(expected.type_name)
104
+ AND attribute.attnotnull = expected.not_null
105
+ AND CASE expected.default_kind
106
+ WHEN 'transaction' THEN regexp_replace(
107
+ lower(COALESCE(pg_get_expr(defaults.adbin, defaults.adrelid), '')),
108
+ '[()[:space:]]', '', 'g'
109
+ ) = 'pg_current_xact_id::text::bigint'
110
+ WHEN 'zero' THEN regexp_replace(
111
+ lower(COALESCE(pg_get_expr(defaults.adbin, defaults.adrelid), '')),
112
+ '[()[:space:]]', '', 'g'
113
+ ) IN ('0', '0::bigint')
114
+ WHEN 'false' THEN regexp_replace(
115
+ lower(COALESCE(pg_get_expr(defaults.adbin, defaults.adrelid), '')),
116
+ '[()[:space:]]', '', 'g'
117
+ ) IN ('false', 'false::boolean')
118
+ ELSE defaults.oid IS NULL
119
+ END,
120
+ FALSE
121
+ )), FALSE)
122
+ FROM expected_columns AS expected
123
+ LEFT JOIN pg_attribute AS attribute
124
+ ON attribute.attrelid = to_regclass(expected.table_name)
125
+ AND attribute.attname = expected.column_name AND NOT attribute.attisdropped
126
+ LEFT JOIN pg_attrdef AS defaults
127
+ ON defaults.adrelid = attribute.attrelid AND defaults.adnum = attribute.attnum
128
+ )
129
+ AND (
130
+ SELECT COALESCE(bool_and(COALESCE(
131
+ indexes.indrelid = to_regclass(expected.table_name)
132
+ AND indexes.indisvalid AND indexes.indisready
133
+ AND indexes.indisunique = expected.is_unique
134
+ AND NOT indexes.indisexclusion
135
+ AND indexes.indnkeyatts = cardinality(expected.columns)
136
+ AND indexes.indnatts = indexes.indnkeyatts
137
+ AND indexes.indexprs IS NULL
138
+ AND access_method.amname = 'btree'
139
+ AND ARRAY(
140
+ SELECT attribute.attname::text
141
+ FROM unnest(indexes.indkey::smallint[]) WITH ORDINALITY AS key(attnum, position)
142
+ JOIN pg_attribute AS attribute
143
+ ON attribute.attrelid = indexes.indrelid AND attribute.attnum = key.attnum
144
+ ORDER BY key.position
145
+ ) = expected.columns
146
+ AND ARRAY(
147
+ SELECT (option & 1) = 1
148
+ FROM unnest(indexes.indoption::smallint[]) WITH ORDINALITY AS ordering(option, position)
149
+ ORDER BY ordering.position
150
+ ) = expected.descending
151
+ AND regexp_replace(
152
+ lower(COALESCE(pg_get_expr(indexes.indpred, indexes.indrelid), '')),
153
+ '[()[:space:]]', '', 'g'
154
+ ) = expected.predicate,
155
+ FALSE
156
+ )), FALSE)
157
+ FROM expected_indexes AS expected
158
+ LEFT JOIN pg_class AS index_class ON index_class.oid = to_regclass(expected.index_name)
159
+ LEFT JOIN pg_index AS indexes ON indexes.indexrelid = index_class.oid
160
+ LEFT JOIN pg_am AS access_method ON access_method.oid = index_class.relam
161
+ )
162
+ AND (
163
+ SELECT COALESCE(bool_and(EXISTS (
164
+ SELECT 1 FROM pg_trigger AS trigger
165
+ WHERE trigger.tgrelid = to_regclass(expected.table_name)
166
+ AND trigger.tgname = expected.trigger_name
167
+ AND trigger.tgfoid = to_regprocedure(expected.function_name || '()')
168
+ AND NOT trigger.tgisinternal AND trigger.tgenabled = 'O'
169
+ AND trigger.tgtype = expected.trigger_type
170
+ AND trigger.tgnewtable IS NOT DISTINCT FROM expected.new_table
171
+ AND trigger.tgoldtable IS NULL
172
+ AND trigger.tgqual IS NULL AND trigger.tgnargs = 0
173
+ AND (trigger.tgconstraint <> 0) = expected.is_constraint
174
+ AND trigger.tgdeferrable = expected.is_deferrable
175
+ AND trigger.tginitdeferred = expected.is_deferrable
176
+ )), FALSE)
177
+ FROM expected_triggers AS expected
178
+ ) AS valid
179
+ `;
180
+ if (!objects.valid)
181
+ return false;
182
+ const functions = await tx `
183
+ SELECT expected.name, functions.prosrc AS body,
184
+ functions.prorettype = to_regtype('trigger')
185
+ AND language.lanname = 'plpgsql'
186
+ AND functions.prokind = 'f'
187
+ AND functions.provolatile = 'v'
188
+ AND functions.proparallel = 'u'
189
+ AND NOT functions.prosecdef
190
+ AND NOT functions.proisstrict
191
+ AND functions.proconfig IS NULL
192
+ AND NOT functions.proleakproof AS canonical
193
+ FROM unnest(${tx.array([...EXPECTED_FUNCTION_BODIES.keys()], 'TEXT')}) AS expected(name)
194
+ LEFT JOIN pg_proc AS functions
195
+ ON functions.oid = to_regprocedure(expected.name || '()')
196
+ LEFT JOIN pg_language AS language ON language.oid = functions.prolang
197
+ `;
198
+ return (functions.length === EXPECTED_FUNCTION_BODIES.size &&
199
+ functions.every(({ name, body, canonical }) => {
200
+ const expected = EXPECTED_FUNCTION_BODIES.get(name);
201
+ return canonical && body !== null && expected !== undefined
202
+ ? normalizeFunctionBody(body) === normalizeFunctionBody(expected)
203
+ : false;
204
+ }));
205
+ }
206
+ /** Initialize or migrate the shared schema without locking live tables when current. */
207
+ export async function initializePostgresSchema(ctx) {
208
+ const lockName = postgresAdvisoryLockName('schema');
209
+ await ctx.sql.begin(async (tx) => {
210
+ await tx `SELECT pg_advisory_xact_lock(hashtextextended(${lockName}, 0))`;
211
+ if (await hasCurrentSchema(tx))
212
+ return;
213
+ await tx.unsafe(POSTGRES_SCHEMA).simple();
214
+ const appliedAt = await databaseNow(tx);
215
+ await tx `
216
+ INSERT INTO bunqueue_schema_migrations (version, applied_at)
217
+ VALUES (${POSTGRES_SCHEMA_VERSION}, ${appliedAt})
218
+ ON CONFLICT (version) DO NOTHING
219
+ `;
220
+ });
221
+ }
@@ -0,0 +1,6 @@
1
+ import type { TransactionSQL } from 'bun';
2
+ import type { Job } from '../../../domain/types/job';
3
+ import { type PostgresContext } from './context';
4
+ import type { PostgresAdmissionResult } from './admissionResult';
5
+ /** Reconcile same-batch dependency generations without reordering admission events. */
6
+ export declare function reconcilePostgresSerialAdmissions(tx: TransactionSQL, ctx: PostgresContext, admissions: readonly PostgresAdmissionResult[]): Promise<Job[]>;
@@ -0,0 +1,96 @@
1
+ import { decodePostgresJob, encodePostgresValue, eventPayload, postgresByteaBase64, postgresStateForJob, } from './codec';
2
+ import { databaseNow } from './context';
3
+ function latestInsertions(admissions) {
4
+ const latest = new Map();
5
+ for (let index = 0; index < admissions.length; index++) {
6
+ if (admissions[index].inserted)
7
+ latest.set(String(admissions[index].job.id), index);
8
+ }
9
+ return latest;
10
+ }
11
+ function correctedJob(row, admission, now) {
12
+ const stored = decodePostgresJob(row);
13
+ const state = postgresStateForJob(stored.job, row.dependencies_satisfied, now);
14
+ if (admission.timelineIndex === undefined)
15
+ return { job: stored.job, state };
16
+ const timeline = [...stored.job.timeline];
17
+ const entry = timeline[admission.timelineIndex];
18
+ if (entry)
19
+ timeline[admission.timelineIndex] = { ...entry, state };
20
+ return { job: { ...stored.job, timeline }, state };
21
+ }
22
+ async function loadFinalRows(tx, ctx, ids) {
23
+ return await tx `
24
+ SELECT job.*, NOT EXISTS (
25
+ SELECT 1
26
+ FROM bunqueue_dependencies AS dependency
27
+ WHERE dependency.namespace = job.namespace AND dependency.job_id = job.id
28
+ AND NOT EXISTS (
29
+ SELECT 1 FROM bunqueue_completions AS completion
30
+ WHERE completion.namespace = dependency.namespace
31
+ AND completion.job_id = dependency.dependency_id
32
+ )
33
+ AND NOT EXISTS (
34
+ SELECT 1 FROM bunqueue_jobs AS completed
35
+ WHERE completed.namespace = dependency.namespace
36
+ AND completed.id = dependency.dependency_id AND completed.state = 'completed'
37
+ )
38
+ ) AS dependencies_satisfied
39
+ FROM bunqueue_jobs AS job
40
+ WHERE job.namespace = ${ctx.config.namespace}
41
+ AND job.id = ANY(${tx.array([...ids], 'TEXT')})
42
+ ORDER BY job.id
43
+ FOR UPDATE OF job
44
+ `;
45
+ }
46
+ async function persistFinalRows(tx, ctx, prepared) {
47
+ if (prepared.length === 0)
48
+ return;
49
+ await tx `
50
+ UPDATE bunqueue_jobs AS job
51
+ SET payload = decode(batch.payload_base64, 'base64'), state = batch.state
52
+ FROM unnest(
53
+ ${tx.array(prepared.map(({ id }) => id), 'TEXT')},
54
+ ${tx.array(prepared.map(({ payload }) => payload), 'TEXT')},
55
+ ${tx.array(prepared.map(({ state }) => state), 'TEXT')}
56
+ ) AS batch(id, payload_base64, state)
57
+ WHERE job.namespace = ${ctx.config.namespace} AND job.id = batch.id
58
+ `;
59
+ await tx `
60
+ UPDATE bunqueue_events AS event
61
+ SET payload = decode(batch.payload_base64, 'base64')
62
+ FROM unnest(
63
+ ${tx.array(prepared.map(({ eventId }) => eventId), 'BIGINT')},
64
+ ${tx.array(prepared.map(({ eventPayload: payload }) => payload), 'TEXT')}
65
+ ) AS batch(id, payload_base64)
66
+ WHERE event.namespace = ${ctx.config.namespace} AND event.id = batch.id
67
+ `;
68
+ }
69
+ /** Reconcile same-batch dependency generations without reordering admission events. */
70
+ export async function reconcilePostgresSerialAdmissions(tx, ctx, admissions) {
71
+ const latest = latestInsertions(admissions);
72
+ if (latest.size === 0)
73
+ return admissions.map(({ job }) => job);
74
+ const now = await databaseNow(tx);
75
+ const rows = await loadFinalRows(tx, ctx, [...latest.keys()]);
76
+ const prepared = rows.map((row) => {
77
+ const insertionIndex = latest.get(row.id);
78
+ const admission = admissions[insertionIndex];
79
+ const { job, state } = correctedJob(row, admission, now);
80
+ return {
81
+ id: row.id,
82
+ job,
83
+ state,
84
+ payload: postgresByteaBase64(encodePostgresValue(job)),
85
+ eventId: admission.pushedEventId,
86
+ eventPayload: postgresByteaBase64(eventPayload({ job, state })),
87
+ insertionIndex,
88
+ };
89
+ });
90
+ await persistFinalRows(tx, ctx, prepared);
91
+ const survivors = new Map(prepared.map((entry) => [entry.id, entry]));
92
+ return admissions.map((admission, index) => {
93
+ const survivor = survivors.get(String(admission.job.id));
94
+ return survivor && index >= survivor.insertionIndex ? survivor.job : admission.job;
95
+ });
96
+ }
@@ -0,0 +1,3 @@
1
+ import type { PostgresContext, PostgresReadSql } from './context';
2
+ /** Reject an unsafe local read model before allocating or decoding its payloads. */
3
+ export declare function assertPostgresSnapshotBudget(ctx: PostgresContext, sql: PostgresReadSql, queue?: string): Promise<void>;
@@ -0,0 +1,83 @@
1
+ /** Reject an unsafe local read model before allocating or decoding its payloads. */
2
+ export async function assertPostgresSnapshotBudget(ctx, sql, queue) {
3
+ const queueFilter = queue ?? null;
4
+ const [weight] = await sql `
5
+ WITH retained_jobs AS MATERIALIZED (
6
+ SELECT payload, result, dlq_entry, dlq_retry_state
7
+ FROM bunqueue_jobs
8
+ WHERE namespace = ${ctx.config.namespace}
9
+ AND (${queueFilter}::text IS NULL OR queue = ${queueFilter})
10
+ AND (${queueFilter}::text IS NOT NULL OR state <> 'completed')
11
+ UNION ALL
12
+ (
13
+ SELECT payload, result, dlq_entry, dlq_retry_state
14
+ FROM bunqueue_jobs
15
+ WHERE namespace = ${ctx.config.namespace}
16
+ AND ${queueFilter}::text IS NULL
17
+ AND state = 'completed'
18
+ ORDER BY completed_at DESC NULLS LAST, id DESC
19
+ LIMIT ${ctx.config.maxCompletedJobs}
20
+ )
21
+ ), pinned AS MATERIALIZED (
22
+ SELECT DISTINCT dependency.dependency_id AS job_id
23
+ FROM bunqueue_dependencies AS dependency
24
+ JOIN bunqueue_jobs AS consumer
25
+ ON consumer.namespace = dependency.namespace AND consumer.id = dependency.job_id
26
+ WHERE dependency.namespace = ${ctx.config.namespace}
27
+ AND consumer.state = ANY(${sql.array(['waiting', 'prioritized', 'delayed', 'waiting-children', 'active'], 'TEXT')})
28
+ ), recent_completions AS MATERIALIZED (
29
+ SELECT completion.job_id, completion.result
30
+ FROM bunqueue_completions AS completion
31
+ WHERE completion.namespace = ${ctx.config.namespace}
32
+ AND (${queueFilter}::text IS NULL OR completion.queue = ${queueFilter})
33
+ AND NOT EXISTS (
34
+ SELECT 1 FROM pinned WHERE pinned.job_id = completion.job_id
35
+ )
36
+ ORDER BY completion.completed_at DESC, completion.job_id DESC
37
+ LIMIT ${ctx.config.maxJobResults}
38
+ ), selected_completions AS MATERIALIZED (
39
+ SELECT completion.job_id, completion.result
40
+ FROM bunqueue_completions AS completion
41
+ JOIN pinned ON pinned.job_id = completion.job_id
42
+ WHERE completion.namespace = ${ctx.config.namespace}
43
+ AND (${queueFilter}::text IS NULL OR completion.queue = ${queueFilter})
44
+ UNION ALL
45
+ SELECT job_id, result FROM recent_completions
46
+ )
47
+ SELECT
48
+ (
49
+ (SELECT COUNT(*) FROM retained_jobs) +
50
+ (SELECT COUNT(*) FROM selected_completions)
51
+ )::bigint AS items,
52
+ (
53
+ COALESCE((
54
+ SELECT SUM(
55
+ octet_length(payload) + COALESCE(octet_length(result), 0) +
56
+ COALESCE(octet_length(dlq_entry), 0) +
57
+ COALESCE(octet_length(dlq_retry_state), 0)
58
+ ) FROM retained_jobs
59
+ ), 0) +
60
+ COALESCE((SELECT SUM(COALESCE(octet_length(result), 0)) FROM selected_completions), 0) +
61
+ COALESCE((
62
+ SELECT SUM(octet_length(payload)) FROM bunqueue_crons
63
+ WHERE namespace = ${ctx.config.namespace} AND ${queueFilter}::text IS NULL
64
+ ), 0) +
65
+ COALESCE((
66
+ SELECT SUM(
67
+ COALESCE(octet_length(stall_config), 0) +
68
+ COALESCE(octet_length(dlq_config), 0)
69
+ ) FROM bunqueue_queue_state
70
+ WHERE namespace = ${ctx.config.namespace}
71
+ AND (${queueFilter}::text IS NULL OR queue = ${queueFilter})
72
+ ), 0)
73
+ )::bigint AS payload_bytes
74
+ `;
75
+ const scope = queue === undefined ? 'manager' : `queue "${queue}"`;
76
+ if (Number(weight.items) > ctx.config.maxSnapshotJobs) {
77
+ throw new Error(`PostgreSQL ${scope} snapshot exceeds maxSnapshotJobs=${ctx.config.maxSnapshotJobs}`);
78
+ }
79
+ if (Number(weight.payload_bytes) > ctx.config.maxSnapshotPayloadBytes) {
80
+ throw new Error(`PostgreSQL ${scope} snapshot exceeds ` +
81
+ `maxSnapshotPayloadBytes=${ctx.config.maxSnapshotPayloadBytes}`);
82
+ }
83
+ }
@@ -0,0 +1,10 @@
1
+ import type { PostgresStorageHealth, ResolvedPostgresStorageConfig } from './types';
2
+ /** Aggregate independent PostgreSQL subsystem failures without hiding older degradation. */
3
+ export declare class PostgresStorageHealthTracker {
4
+ private readonly config;
5
+ private readonly errors;
6
+ constructor(config: ResolvedPostgresStorageConfig);
7
+ record(key: string, error: unknown, prefix?: string): void;
8
+ clear(key: string): void;
9
+ snapshot(): PostgresStorageHealth;
10
+ }
@@ -0,0 +1,29 @@
1
+ /** Aggregate independent PostgreSQL subsystem failures without hiding older degradation. */
2
+ export class PostgresStorageHealthTracker {
3
+ config;
4
+ errors = new Map();
5
+ constructor(config) {
6
+ this.config = config;
7
+ }
8
+ record(key, error, prefix = '') {
9
+ const message = error instanceof Error ? error.message : String(error);
10
+ const since = this.errors.get(key)?.since ?? Date.now();
11
+ this.errors.set(key, { message: `${prefix}${message}`, since });
12
+ }
13
+ clear(key) {
14
+ this.errors.delete(key);
15
+ }
16
+ snapshot() {
17
+ const errors = [...this.errors.entries()].sort(([left], [right]) => left.localeCompare(right));
18
+ const messages = errors.map(([, { message }]) => message);
19
+ const sinceValues = errors.map(([, { since }]) => since);
20
+ return {
21
+ ok: messages.length === 0,
22
+ error: messages.length > 0 ? messages.join('; ') : null,
23
+ since: sinceValues.length > 0 ? Math.min(...sinceValues) : null,
24
+ backend: 'postgres',
25
+ brokerId: this.config.brokerId,
26
+ namespace: this.config.namespace,
27
+ };
28
+ }
29
+ }
@@ -0,0 +1,90 @@
1
+ import type { JobId } from '../../../domain/types/job';
2
+ import { setPostgresDlqConfig, setPostgresStallConfig } from './control';
3
+ import { type ListPostgresJobsOptions } from './queries';
4
+ import { PostgresAdmissionStore } from './admissionStore';
5
+ import type { CronJobInput } from '../../../domain/types/cron';
6
+ import type { Worker } from '../../../domain/types/worker';
7
+ import type { QueueMetricType } from '../../../domain/types/metrics';
8
+ import type { ClaimedPostgresJob, PostgresCompletionInput, PostgresFailureInput } from './types';
9
+ import { finalizePostgresLifetimeMetrics } from './lifetimeMetricsFinalizer';
10
+ import { loadPostgresJobProjections } from './readModels';
11
+ /** Database-authoritative PostgreSQL queue store safe for concurrent brokers. */
12
+ export declare class PostgresQueueStore extends PostgresAdmissionStore {
13
+ now(): Promise<number>;
14
+ claim(queue: string, count: number, owner?: string, leaseDurationMs?: number): Promise<ClaimedPostgresJob[]>;
15
+ complete(id: JobId, token: string, result?: unknown, remove?: boolean): Promise<import("./types").PostgresTransitionResult>;
16
+ completeMany(items: readonly PostgresCompletionInput[]): Promise<import("./types").PostgresBatchCompletionResult[]>;
17
+ fail(input: PostgresFailureInput): Promise<import("./types").PostgresTransitionResult>;
18
+ renew(id: JobId, token: string, durationMs: number): Promise<number | null>;
19
+ recoverExpired(limit?: number): Promise<number>;
20
+ maintainDlq(limit?: number): Promise<import("./dlqLifecycle").PostgresDlqMaintenanceResult>;
21
+ addCron: (input: CronJobInput) => Promise<import("../../../domain/types").CronJob>;
22
+ getCron: (name: string) => Promise<import("../../../domain/types").CronJob | undefined>;
23
+ listCrons: () => Promise<import("../../../domain/types").CronJob[]>;
24
+ removeCron: (name: string) => Promise<boolean>;
25
+ processCrons: (limit?: number) => Promise<number>;
26
+ saveWorker: (worker: Worker) => Promise<void>;
27
+ heartbeatWorker: (id: string, stats?: {
28
+ activeJobs?: number;
29
+ processed?: number;
30
+ failed?: number;
31
+ }, clientId?: string) => Promise<boolean>;
32
+ removeWorker: (id: string, clientId?: string) => Promise<boolean>;
33
+ removeClientWorkers: (clientId: string) => Promise<number>;
34
+ listWorkers: () => Promise<Worker[]>;
35
+ getQueueMetrics: (queue: string, type: QueueMetricType, start?: number, end?: number) => Promise<import("../../../client").QueueMetrics>;
36
+ trimQueueEvents: (queue: string, maxLength: number) => Promise<number>;
37
+ releaseClientLease: (id: JobId, token: string) => Promise<boolean>;
38
+ getJob: (id: JobId) => Promise<import("./types").PostgresStoredJob | null>;
39
+ getJobs: (ids: readonly JobId[]) => Promise<import("./types").PostgresStoredJob[]>;
40
+ findMissingDependencies: (ids: readonly JobId[]) => Promise<JobId[]>;
41
+ getResult: (id: JobId) => Promise<{
42
+ found: boolean;
43
+ result: unknown;
44
+ }>;
45
+ getCounts: (queue?: string) => Promise<import("./types").PostgresCounts>;
46
+ getQueues: () => Promise<string[]>;
47
+ getDlq: (queue: string, limit?: number) => Promise<import("../../../domain/types/dlq").DlqEntry[]>;
48
+ getChildrenValues: (id: JobId) => Promise<Record<string, unknown>>;
49
+ getFailedChildrenValues: (id: JobId) => Promise<Record<string, string>>;
50
+ getIgnoredChildrenFailures: (id: JobId) => Promise<Record<string, string>>;
51
+ addLog: (id: JobId, message: string, level: "info" | "warn" | "error") => Promise<boolean>;
52
+ getLogs: (id: JobId) => Promise<import("../../../domain/types/worker").JobLogEntry[]>;
53
+ clearLogs: (id: JobId, keepLogs?: number) => Promise<void>;
54
+ getQueueState: (queue: string) => Promise<import("./types").PostgresQueueState>;
55
+ list: (queue: string, options?: ListPostgresJobsOptions) => Promise<import("./types").PostgresStoredJob[]>;
56
+ loadAll: () => Promise<import("./types").PostgresStoredJob[]>;
57
+ loadResults: (queue?: string) => Promise<import("./types").PostgresCompletionResult[]>;
58
+ latestEventId: () => Promise<number>;
59
+ loadLifetimeMetrics: () => Promise<import("./lifetimeMetrics").PostgresLifetimeMetricsSnapshot>;
60
+ finalizeLifetimeMetrics: (apply: Parameters<typeof finalizePostgresLifetimeMetrics>[1]) => Promise<void>;
61
+ loadCloudReadModel: () => Promise<import("./cloudReadModel").PostgresCloudReadModel>;
62
+ loadManagerSnapshot: () => Promise<import("./readModels").PostgresManagerSnapshot>;
63
+ loadQueueReadModel: (queue: string) => Promise<import("./readModels").PostgresQueueReadModel>;
64
+ loadJobProjections: (requests: Parameters<typeof loadPostgresJobProjections>[1]) => Promise<ReadonlyMap<JobId, import("./readModels").PostgresJobProjection>>;
65
+ updateData: (id: JobId, data: unknown) => Promise<boolean>;
66
+ updateProgress: (id: JobId, value: number, message?: string) => Promise<boolean>;
67
+ changePriority: (id: JobId, priority: number, lifo?: boolean) => Promise<boolean>;
68
+ changeDelay: (id: JobId, runAt: number, token?: string) => Promise<boolean>;
69
+ moveToWaitingChildren: (id: JobId, token?: string) => Promise<boolean>;
70
+ clearUniqueKey: (id: JobId) => Promise<boolean>;
71
+ removeDependency: (id: JobId) => Promise<boolean>;
72
+ removeUnprocessedChildren: (parentId: JobId) => Promise<JobId[]>;
73
+ updateParent: (childId: JobId, parentId: JobId) => Promise<void>;
74
+ promote: (id: JobId) => Promise<boolean>;
75
+ cancel: (id: JobId) => Promise<boolean>;
76
+ discard: (id: JobId, token?: string) => Promise<boolean>;
77
+ remove: (id: JobId, token?: string) => Promise<boolean>;
78
+ removeDlq: (queue: string, id: JobId) => Promise<boolean>;
79
+ purgeDlq: (queue: string) => Promise<JobId[]>;
80
+ clean: (queue: string, graceMs: number, state?: string, limit?: number) => Promise<JobId[]>;
81
+ retry: (id: JobId, timestamp?: number) => Promise<boolean>;
82
+ pause: (queue: string, paused: boolean) => Promise<void>;
83
+ setRateLimit: (queue: string, limit: number | null, durationMs: number | null, ttlMs?: number | null) => Promise<void>;
84
+ setConcurrency: (queue: string, limit: number | null) => Promise<void>;
85
+ setStallConfig: (queue: string, config: Parameters<typeof setPostgresStallConfig>[2]) => Promise<void>;
86
+ setDlqConfig: (queue: string, config: Parameters<typeof setPostgresDlqConfig>[2]) => Promise<void>;
87
+ drain: (queue: string) => Promise<number>;
88
+ obliterate: (queue: string) => Promise<number>;
89
+ promoteMany: (queue: string, count?: number) => Promise<JobId[]>;
90
+ }