bunqueue 2.8.60 → 2.9.2

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 (427) hide show
  1. package/README.md +114 -78
  2. package/dist/application/background/dlq.js +2 -0
  3. package/dist/application/background/recovery/active.d.ts +1 -0
  4. package/dist/application/background/recovery/active.js +12 -0
  5. package/dist/application/background/recovery/index.js +3 -1
  6. package/dist/application/background/recovery/pending.js +1 -0
  7. package/dist/application/cleanupTasks.js +4 -16
  8. package/dist/application/contextFactory.js +8 -0
  9. package/dist/application/dlqManager.d.ts +10 -0
  10. package/dist/application/dlqManager.js +48 -9
  11. package/dist/application/dlqRetry.js +60 -38
  12. package/dist/application/eventsManager.d.ts +9 -2
  13. package/dist/application/eventsManager.js +106 -55
  14. package/dist/application/operations/ackHelpers.d.ts +1 -4
  15. package/dist/application/operations/ackHelpers.js +39 -14
  16. package/dist/application/operations/flowPush.js +1 -0
  17. package/dist/application/operations/flowValidation.js +4 -4
  18. package/dist/application/operations/jobManagement.d.ts +4 -0
  19. package/dist/application/operations/jobMoveOperations.js +9 -4
  20. package/dist/application/operations/pull.d.ts +7 -2
  21. package/dist/application/operations/pull.js +15 -57
  22. package/dist/application/operations/pullFinalization.d.ts +6 -0
  23. package/dist/application/operations/pullFinalization.js +69 -0
  24. package/dist/application/operations/pullStateTransition.d.ts +8 -7
  25. package/dist/application/operations/pullStateTransition.js +25 -18
  26. package/dist/application/operations/push.js +3 -0
  27. package/dist/application/operations/pushBatch.js +14 -7
  28. package/dist/application/operations/pushContext.d.ts +2 -1
  29. package/dist/application/postgres-queue-manager/batchSnapshot.d.ts +16 -0
  30. package/dist/application/postgres-queue-manager/batchSnapshot.js +17 -0
  31. package/dist/application/postgres-queue-manager/cloud.d.ts +30 -0
  32. package/dist/application/postgres-queue-manager/cloud.js +55 -0
  33. package/dist/application/postgres-queue-manager/config.d.ts +5 -0
  34. package/dist/application/postgres-queue-manager/config.js +1 -0
  35. package/dist/application/postgres-queue-manager/control.d.ts +30 -0
  36. package/dist/application/postgres-queue-manager/control.js +210 -0
  37. package/dist/application/postgres-queue-manager/deferredWrites.d.ts +13 -0
  38. package/dist/application/postgres-queue-manager/deferredWrites.js +60 -0
  39. package/dist/application/postgres-queue-manager/delivery.d.ts +20 -0
  40. package/dist/application/postgres-queue-manager/delivery.js +83 -0
  41. package/dist/application/postgres-queue-manager/groupQueries.d.ts +10 -0
  42. package/dist/application/postgres-queue-manager/groupQueries.js +40 -0
  43. package/dist/application/postgres-queue-manager/lease.d.ts +13 -0
  44. package/dist/application/postgres-queue-manager/lease.js +88 -0
  45. package/dist/application/postgres-queue-manager/lifetimeMetrics.d.ts +32 -0
  46. package/dist/application/postgres-queue-manager/lifetimeMetrics.js +53 -0
  47. package/dist/application/postgres-queue-manager/maintenance.d.ts +14 -0
  48. package/dist/application/postgres-queue-manager/maintenance.js +100 -0
  49. package/dist/application/postgres-queue-manager/operationGate.d.ts +26 -0
  50. package/dist/application/postgres-queue-manager/operationGate.js +96 -0
  51. package/dist/application/postgres-queue-manager/operations.d.ts +25 -0
  52. package/dist/application/postgres-queue-manager/operations.js +194 -0
  53. package/dist/application/postgres-queue-manager/projectionRefreshes.d.ts +43 -0
  54. package/dist/application/postgres-queue-manager/projectionRefreshes.js +170 -0
  55. package/dist/application/postgres-queue-manager/queries.d.ts +142 -0
  56. package/dist/application/postgres-queue-manager/queries.js +231 -0
  57. package/dist/application/postgres-queue-manager/relationships.d.ts +10 -0
  58. package/dist/application/postgres-queue-manager/relationships.js +45 -0
  59. package/dist/application/postgres-queue-manager/services.d.ts +31 -0
  60. package/dist/application/postgres-queue-manager/services.js +149 -0
  61. package/dist/application/postgres-queue-manager/snapshot.d.ts +51 -0
  62. package/dist/application/postgres-queue-manager/snapshot.js +236 -0
  63. package/dist/application/postgres-queue-manager/snapshotViews.d.ts +15 -0
  64. package/dist/application/postgres-queue-manager/snapshotViews.js +100 -0
  65. package/dist/application/postgres-queue-manager/startupEventBuffer.d.ts +12 -0
  66. package/dist/application/postgres-queue-manager/startupEventBuffer.js +36 -0
  67. package/dist/application/postgres-queue-manager/state.d.ts +47 -0
  68. package/dist/application/postgres-queue-manager/state.js +273 -0
  69. package/dist/application/postgres-queue-manager/terminalDelivery.d.ts +20 -0
  70. package/dist/application/postgres-queue-manager/terminalDelivery.js +100 -0
  71. package/dist/application/postgresQueueManager.d.ts +2 -0
  72. package/dist/application/postgresQueueManager.js +1 -0
  73. package/dist/application/queue-manager/control.js +1 -0
  74. package/dist/application/queue-manager/delivery.d.ts +5 -4
  75. package/dist/application/queue-manager/delivery.js +15 -8
  76. package/dist/application/queue-manager/flow-failures.js +4 -0
  77. package/dist/application/queue-manager/limits.d.ts +13 -0
  78. package/dist/application/queue-manager/limits.js +65 -0
  79. package/dist/application/queue-manager/observability.js +15 -3
  80. package/dist/application/queue-manager/queries.d.ts +7 -0
  81. package/dist/application/queue-manager/queries.js +9 -0
  82. package/dist/application/queue-manager/services.d.ts +1 -1
  83. package/dist/application/queue-manager/services.js +4 -2
  84. package/dist/application/queue-manager/state.js +17 -2
  85. package/dist/application/queueTelemetryJournal.d.ts +2 -0
  86. package/dist/application/queueTelemetryJournal.js +23 -0
  87. package/dist/application/types/ack.d.ts +3 -1
  88. package/dist/cli/commandRouter.d.ts +1 -1
  89. package/dist/cli/commands/server.js +1 -1
  90. package/dist/client/flowPush.js +6 -0
  91. package/dist/client/forwarder.d.ts +6 -4
  92. package/dist/client/forwarder.js +5 -3
  93. package/dist/client/groupId.d.ts +1 -0
  94. package/dist/client/groupId.js +1 -0
  95. package/dist/client/index.d.ts +1 -1
  96. package/dist/client/jobHelpers.js +1 -0
  97. package/dist/client/queue/dlq.d.ts +2 -0
  98. package/dist/client/queue/dlq.js +14 -0
  99. package/dist/client/queue/dlqOps.d.ts +2 -0
  100. package/dist/client/queue/dlqOps.js +4 -0
  101. package/dist/client/queue/helpers.js +2 -0
  102. package/dist/client/queue/operations/add/bulk.js +4 -4
  103. package/dist/client/queue/operations/add/payload.d.ts +1 -0
  104. package/dist/client/queue/operations/add/payload.js +7 -1
  105. package/dist/client/queue/operations/add/single.js +3 -3
  106. package/dist/client/queue/operations/groups.d.ts +21 -0
  107. package/dist/client/queue/operations/groups.js +88 -0
  108. package/dist/client/queue/runtime/configuration.d.ts +4 -0
  109. package/dist/client/queue/runtime/configuration.js +8 -0
  110. package/dist/client/queue/runtime/queries.d.ts +13 -0
  111. package/dist/client/queue/runtime/queries.js +31 -0
  112. package/dist/client/queue/runtime/state.d.ts +4 -0
  113. package/dist/client/queue/runtime/state.js +1 -0
  114. package/dist/client/types/index.d.ts +2 -2
  115. package/dist/client/types/options.d.ts +4 -0
  116. package/dist/client/types/worker.d.ts +8 -0
  117. package/dist/client/worker/runtime/execution.js +4 -8
  118. package/dist/client/worker/runtime/options.js +3 -0
  119. package/dist/client/worker/runtime/polling.d.ts +1 -0
  120. package/dist/client/worker/runtime/polling.js +9 -0
  121. package/dist/client/worker/types/options.d.ts +2 -1
  122. package/dist/client/worker/workerPull.d.ts +2 -0
  123. package/dist/client/worker/workerPull.js +6 -4
  124. package/dist/config/resolve.d.ts +14 -0
  125. package/dist/config/resolve.js +50 -5
  126. package/dist/config/types.d.ts +18 -0
  127. package/dist/domain/job/groupFifoOrder.d.ts +9 -0
  128. package/dist/domain/job/groupFifoOrder.js +26 -0
  129. package/dist/domain/queue/dlqShard.d.ts +2 -0
  130. package/dist/domain/queue/dlqShard.js +16 -0
  131. package/dist/domain/queue/groupLimiterManager.d.ts +23 -0
  132. package/dist/domain/queue/groupLimiterManager.js +107 -0
  133. package/dist/domain/queue/groupScheduler.d.ts +31 -0
  134. package/dist/domain/queue/groupScheduler.js +256 -0
  135. package/dist/domain/queue/groupSchedulerOrder.d.ts +6 -0
  136. package/dist/domain/queue/groupSchedulerOrder.js +30 -0
  137. package/dist/domain/queue/priorityQueue.d.ts +13 -23
  138. package/dist/domain/queue/priorityQueue.js +53 -42
  139. package/dist/domain/queue/shard/dlq.d.ts +1 -0
  140. package/dist/domain/queue/shard/dlq.js +3 -0
  141. package/dist/domain/queue/shard/keys.d.ts +1 -0
  142. package/dist/domain/queue/shard/keys.js +25 -2
  143. package/dist/domain/queue/shard/lifecycle.js +4 -0
  144. package/dist/domain/queue/shard/limits.d.ts +20 -1
  145. package/dist/domain/queue/shard/limits.js +56 -0
  146. package/dist/domain/queue/shard/state.d.ts +5 -0
  147. package/dist/domain/queue/shard/state.js +9 -1
  148. package/dist/domain/types/commands/core.d.ts +3 -0
  149. package/dist/domain/types/commands/dlq.d.ts +5 -0
  150. package/dist/domain/types/commands/limits.d.ts +41 -0
  151. package/dist/domain/types/commands/union.d.ts +1 -1
  152. package/dist/domain/types/cron.d.ts +5 -0
  153. package/dist/domain/types/cron.js +14 -3
  154. package/dist/domain/types/dlq.d.ts +1 -1
  155. package/dist/domain/types/dlq.js +1 -2
  156. package/dist/domain/types/group.d.ts +21 -0
  157. package/dist/domain/types/group.js +78 -0
  158. package/dist/domain/types/jobs/model.d.ts +1 -1
  159. package/dist/domain/types/priorityQueue.d.ts +1 -0
  160. package/dist/infrastructure/cloud/commandHandler.js +5 -3
  161. package/dist/infrastructure/cloud/commands/integrations.js +11 -11
  162. package/dist/infrastructure/cloud/commands/jobs.js +48 -40
  163. package/dist/infrastructure/cloud/commands/queues.js +61 -75
  164. package/dist/infrastructure/cloud/queueAdapter/local.d.ts +41 -0
  165. package/dist/infrastructure/cloud/queueAdapter/local.js +187 -0
  166. package/dist/infrastructure/cloud/queueAdapter/postgres.d.ts +42 -0
  167. package/dist/infrastructure/cloud/queueAdapter/postgres.js +188 -0
  168. package/dist/infrastructure/cloud/queueAdapter/registry.d.ts +4 -0
  169. package/dist/infrastructure/cloud/queueAdapter/registry.js +15 -0
  170. package/dist/infrastructure/cloud/queueAdapter/types.d.ts +87 -0
  171. package/dist/infrastructure/cloud/queueAdapter/types.js +1 -0
  172. package/dist/infrastructure/cloud/snapshot/analytics.d.ts +2 -0
  173. package/dist/infrastructure/cloud/snapshot/analytics.js +7 -0
  174. package/dist/infrastructure/cloud/snapshot/collector.d.ts +4 -0
  175. package/dist/infrastructure/cloud/snapshot/collector.js +39 -1
  176. package/dist/infrastructure/cloud/snapshot/config.d.ts +3 -0
  177. package/dist/infrastructure/cloud/snapshot/config.js +43 -0
  178. package/dist/infrastructure/cloud/snapshot/jobs.d.ts +3 -0
  179. package/dist/infrastructure/cloud/snapshot/jobs.js +32 -1
  180. package/dist/infrastructure/cloud/snapshotCollector.js +20 -35
  181. package/dist/infrastructure/cloud/snapshotHelpers.d.ts +3 -3
  182. package/dist/infrastructure/cloud/snapshotHelpers.js +3 -3
  183. package/dist/infrastructure/cloud/statsRefresh.js +2 -1
  184. package/dist/infrastructure/cloud/types/command.d.ts +2 -2
  185. package/dist/infrastructure/persistence/jobOptionsBlob.d.ts +1 -0
  186. package/dist/infrastructure/persistence/jobOptionsBlob.js +10 -2
  187. package/dist/infrastructure/persistence/migrations.js +11 -0
  188. package/dist/infrastructure/persistence/postgres/admission.d.ts +18 -0
  189. package/dist/infrastructure/persistence/postgres/admission.js +196 -0
  190. package/dist/infrastructure/persistence/postgres/admissionParent.d.ts +5 -0
  191. package/dist/infrastructure/persistence/postgres/admissionParent.js +35 -0
  192. package/dist/infrastructure/persistence/postgres/admissionResult.d.ts +9 -0
  193. package/dist/infrastructure/persistence/postgres/admissionResult.js +1 -0
  194. package/dist/infrastructure/persistence/postgres/admissionStore.d.ts +12 -0
  195. package/dist/infrastructure/persistence/postgres/admissionStore.js +101 -0
  196. package/dist/infrastructure/persistence/postgres/advisoryLocks.d.ts +2 -0
  197. package/dist/infrastructure/persistence/postgres/advisoryLocks.js +13 -0
  198. package/dist/infrastructure/persistence/postgres/batchAdmission.d.ts +11 -0
  199. package/dist/infrastructure/persistence/postgres/batchAdmission.js +128 -0
  200. package/dist/infrastructure/persistence/postgres/batchCompletion.d.ts +4 -0
  201. package/dist/infrastructure/persistence/postgres/batchCompletion.js +174 -0
  202. package/dist/infrastructure/persistence/postgres/batchEvents.d.ts +14 -0
  203. package/dist/infrastructure/persistence/postgres/batchEvents.js +72 -0
  204. package/dist/infrastructure/persistence/postgres/brokerSessions.d.ts +14 -0
  205. package/dist/infrastructure/persistence/postgres/brokerSessions.js +94 -0
  206. package/dist/infrastructure/persistence/postgres/claimBatch.d.ts +14 -0
  207. package/dist/infrastructure/persistence/postgres/claimBatch.js +69 -0
  208. package/dist/infrastructure/persistence/postgres/claimSelection.d.ts +11 -0
  209. package/dist/infrastructure/persistence/postgres/claimSelection.js +140 -0
  210. package/dist/infrastructure/persistence/postgres/claims.d.ts +10 -0
  211. package/dist/infrastructure/persistence/postgres/claims.js +153 -0
  212. package/dist/infrastructure/persistence/postgres/cloudReadModel.d.ts +26 -0
  213. package/dist/infrastructure/persistence/postgres/cloudReadModel.js +123 -0
  214. package/dist/infrastructure/persistence/postgres/codec.d.ts +30 -0
  215. package/dist/infrastructure/persistence/postgres/codec.js +82 -0
  216. package/dist/infrastructure/persistence/postgres/completionEvents.d.ts +11 -0
  217. package/dist/infrastructure/persistence/postgres/completionEvents.js +21 -0
  218. package/dist/infrastructure/persistence/postgres/completionLifecycle.d.ts +11 -0
  219. package/dist/infrastructure/persistence/postgres/completionLifecycle.js +145 -0
  220. package/dist/infrastructure/persistence/postgres/completionOutcome.d.ts +4 -0
  221. package/dist/infrastructure/persistence/postgres/completionOutcome.js +112 -0
  222. package/dist/infrastructure/persistence/postgres/completionQueries.d.ts +10 -0
  223. package/dist/infrastructure/persistence/postgres/completionQueries.js +87 -0
  224. package/dist/infrastructure/persistence/postgres/connection.d.ts +3 -0
  225. package/dist/infrastructure/persistence/postgres/connection.js +15 -0
  226. package/dist/infrastructure/persistence/postgres/context.d.ts +28 -0
  227. package/dist/infrastructure/persistence/postgres/context.js +74 -0
  228. package/dist/infrastructure/persistence/postgres/control.d.ts +23 -0
  229. package/dist/infrastructure/persistence/postgres/control.js +105 -0
  230. package/dist/infrastructure/persistence/postgres/crons.d.ts +18 -0
  231. package/dist/infrastructure/persistence/postgres/crons.js +205 -0
  232. package/dist/infrastructure/persistence/postgres/deduplication.d.ts +9 -0
  233. package/dist/infrastructure/persistence/postgres/deduplication.js +47 -0
  234. package/dist/infrastructure/persistence/postgres/dependencyDestruction.d.ts +14 -0
  235. package/dist/infrastructure/persistence/postgres/dependencyDestruction.js +74 -0
  236. package/dist/infrastructure/persistence/postgres/dependencyPromotion.d.ts +29 -0
  237. package/dist/infrastructure/persistence/postgres/dependencyPromotion.js +212 -0
  238. package/dist/infrastructure/persistence/postgres/destructiveMutations.d.ts +4 -0
  239. package/dist/infrastructure/persistence/postgres/destructiveMutations.js +111 -0
  240. package/dist/infrastructure/persistence/postgres/dlqLifecycle.d.ts +13 -0
  241. package/dist/infrastructure/persistence/postgres/dlqLifecycle.js +184 -0
  242. package/dist/infrastructure/persistence/postgres/dlqMaintenance.d.ts +6 -0
  243. package/dist/infrastructure/persistence/postgres/dlqMaintenance.js +36 -0
  244. package/dist/infrastructure/persistence/postgres/dlqRetryPlan.d.ts +21 -0
  245. package/dist/infrastructure/persistence/postgres/dlqRetryPlan.js +92 -0
  246. package/dist/infrastructure/persistence/postgres/eventCatchupCursors.d.ts +32 -0
  247. package/dist/infrastructure/persistence/postgres/eventCatchupCursors.js +66 -0
  248. package/dist/infrastructure/persistence/postgres/eventCommitGc.d.ts +27 -0
  249. package/dist/infrastructure/persistence/postgres/eventCommitGc.js +62 -0
  250. package/dist/infrastructure/persistence/postgres/eventJournal.d.ts +18 -0
  251. package/dist/infrastructure/persistence/postgres/eventJournal.js +76 -0
  252. package/dist/infrastructure/persistence/postgres/eventJournalSchema.d.ts +5 -0
  253. package/dist/infrastructure/persistence/postgres/eventJournalSchema.js +267 -0
  254. package/dist/infrastructure/persistence/postgres/eventPruneWatermarks.d.ts +26 -0
  255. package/dist/infrastructure/persistence/postgres/eventPruneWatermarks.js +129 -0
  256. package/dist/infrastructure/persistence/postgres/eventRetention.d.ts +18 -0
  257. package/dist/infrastructure/persistence/postgres/eventRetention.js +76 -0
  258. package/dist/infrastructure/persistence/postgres/events.d.ts +45 -0
  259. package/dist/infrastructure/persistence/postgres/events.js +276 -0
  260. package/dist/infrastructure/persistence/postgres/expiry.d.ts +3 -0
  261. package/dist/infrastructure/persistence/postgres/expiry.js +74 -0
  262. package/dist/infrastructure/persistence/postgres/flowFailures.d.ts +17 -0
  263. package/dist/infrastructure/persistence/postgres/flowFailures.js +199 -0
  264. package/dist/infrastructure/persistence/postgres/groupClaims.d.ts +15 -0
  265. package/dist/infrastructure/persistence/postgres/groupClaims.js +95 -0
  266. package/dist/infrastructure/persistence/postgres/groupSchema.d.ts +2 -0
  267. package/dist/infrastructure/persistence/postgres/groupSchema.js +155 -0
  268. package/dist/infrastructure/persistence/postgres/groupSchemaFingerprint.d.ts +3 -0
  269. package/dist/infrastructure/persistence/postgres/groupSchemaFingerprint.js +127 -0
  270. package/dist/infrastructure/persistence/postgres/groupStateRetention.d.ts +3 -0
  271. package/dist/infrastructure/persistence/postgres/groupStateRetention.js +93 -0
  272. package/dist/infrastructure/persistence/postgres/groups.d.ts +11 -0
  273. package/dist/infrastructure/persistence/postgres/groups.js +117 -0
  274. package/dist/infrastructure/persistence/postgres/jobData.d.ts +3 -0
  275. package/dist/infrastructure/persistence/postgres/jobData.js +32 -0
  276. package/dist/infrastructure/persistence/postgres/leaseRelease.d.ts +9 -0
  277. package/dist/infrastructure/persistence/postgres/leaseRelease.js +120 -0
  278. package/dist/infrastructure/persistence/postgres/leaseRenewal.d.ts +4 -0
  279. package/dist/infrastructure/persistence/postgres/leaseRenewal.js +35 -0
  280. package/dist/infrastructure/persistence/postgres/lifetimeMetrics.d.ts +15 -0
  281. package/dist/infrastructure/persistence/postgres/lifetimeMetrics.js +46 -0
  282. package/dist/infrastructure/persistence/postgres/lifetimeMetricsFinalizer.d.ts +4 -0
  283. package/dist/infrastructure/persistence/postgres/lifetimeMetricsFinalizer.js +13 -0
  284. package/dist/infrastructure/persistence/postgres/logs.d.ts +6 -0
  285. package/dist/infrastructure/persistence/postgres/logs.js +70 -0
  286. package/dist/infrastructure/persistence/postgres/maintenance.d.ts +6 -0
  287. package/dist/infrastructure/persistence/postgres/maintenance.js +138 -0
  288. package/dist/infrastructure/persistence/postgres/maintenanceFlights.d.ts +14 -0
  289. package/dist/infrastructure/persistence/postgres/maintenanceFlights.js +66 -0
  290. package/dist/infrastructure/persistence/postgres/metricWrites.d.ts +9 -0
  291. package/dist/infrastructure/persistence/postgres/metricWrites.js +94 -0
  292. package/dist/infrastructure/persistence/postgres/mutations.d.ts +9 -0
  293. package/dist/infrastructure/persistence/postgres/mutations.js +171 -0
  294. package/dist/infrastructure/persistence/postgres/outcomes.d.ts +4 -0
  295. package/dist/infrastructure/persistence/postgres/outcomes.js +194 -0
  296. package/dist/infrastructure/persistence/postgres/policies.d.ts +11 -0
  297. package/dist/infrastructure/persistence/postgres/policies.js +18 -0
  298. package/dist/infrastructure/persistence/postgres/postCommitMaintenance.d.ts +17 -0
  299. package/dist/infrastructure/persistence/postgres/postCommitMaintenance.js +117 -0
  300. package/dist/infrastructure/persistence/postgres/promotion.d.ts +3 -0
  301. package/dist/infrastructure/persistence/postgres/promotion.js +43 -0
  302. package/dist/infrastructure/persistence/postgres/queries.d.ts +22 -0
  303. package/dist/infrastructure/persistence/postgres/queries.js +152 -0
  304. package/dist/infrastructure/persistence/postgres/queueDestruction.d.ts +3 -0
  305. package/dist/infrastructure/persistence/postgres/queueDestruction.js +158 -0
  306. package/dist/infrastructure/persistence/postgres/queueLifecycle.d.ts +10 -0
  307. package/dist/infrastructure/persistence/postgres/queueLifecycle.js +60 -0
  308. package/dist/infrastructure/persistence/postgres/rateLimit.d.ts +6 -0
  309. package/dist/infrastructure/persistence/postgres/rateLimit.js +10 -0
  310. package/dist/infrastructure/persistence/postgres/readModels.d.ts +32 -0
  311. package/dist/infrastructure/persistence/postgres/readModels.js +72 -0
  312. package/dist/infrastructure/persistence/postgres/recovery.d.ts +3 -0
  313. package/dist/infrastructure/persistence/postgres/recovery.js +178 -0
  314. package/dist/infrastructure/persistence/postgres/relationships.d.ts +9 -0
  315. package/dist/infrastructure/persistence/postgres/relationships.js +201 -0
  316. package/dist/infrastructure/persistence/postgres/removeUnprocessedChildren.d.ts +4 -0
  317. package/dist/infrastructure/persistence/postgres/removeUnprocessedChildren.js +241 -0
  318. package/dist/infrastructure/persistence/postgres/repeatMutations.d.ts +5 -0
  319. package/dist/infrastructure/persistence/postgres/repeatMutations.js +37 -0
  320. package/dist/infrastructure/persistence/postgres/runtime.d.ts +45 -0
  321. package/dist/infrastructure/persistence/postgres/runtime.js +238 -0
  322. package/dist/infrastructure/persistence/postgres/runtimeConfig.d.ts +21 -0
  323. package/dist/infrastructure/persistence/postgres/runtimeConfig.js +39 -0
  324. package/dist/infrastructure/persistence/postgres/schema.d.ts +4 -0
  325. package/dist/infrastructure/persistence/postgres/schema.js +261 -0
  326. package/dist/infrastructure/persistence/postgres/schemaInitialization.d.ts +3 -0
  327. package/dist/infrastructure/persistence/postgres/schemaInitialization.js +226 -0
  328. package/dist/infrastructure/persistence/postgres/serialAdmission.d.ts +6 -0
  329. package/dist/infrastructure/persistence/postgres/serialAdmission.js +96 -0
  330. package/dist/infrastructure/persistence/postgres/snapshotBudget.d.ts +3 -0
  331. package/dist/infrastructure/persistence/postgres/snapshotBudget.js +83 -0
  332. package/dist/infrastructure/persistence/postgres/storageHealth.d.ts +10 -0
  333. package/dist/infrastructure/persistence/postgres/storageHealth.js +29 -0
  334. package/dist/infrastructure/persistence/postgres/store.d.ts +100 -0
  335. package/dist/infrastructure/persistence/postgres/store.js +180 -0
  336. package/dist/infrastructure/persistence/postgres/telemetry.d.ts +8 -0
  337. package/dist/infrastructure/persistence/postgres/telemetry.js +100 -0
  338. package/dist/infrastructure/persistence/postgres/terminal.d.ts +8 -0
  339. package/dist/infrastructure/persistence/postgres/terminal.js +137 -0
  340. package/dist/infrastructure/persistence/postgres/transactionRetry.d.ts +6 -0
  341. package/dist/infrastructure/persistence/postgres/transactionRetry.js +42 -0
  342. package/dist/infrastructure/persistence/postgres/types.d.ts +176 -0
  343. package/dist/infrastructure/persistence/postgres/types.js +1 -0
  344. package/dist/infrastructure/persistence/postgres/workers.d.ts +15 -0
  345. package/dist/infrastructure/persistence/postgres/workers.js +126 -0
  346. package/dist/infrastructure/persistence/postgres.d.ts +2 -0
  347. package/dist/infrastructure/persistence/postgres.js +1 -0
  348. package/dist/infrastructure/persistence/schema.d.ts +2 -2
  349. package/dist/infrastructure/persistence/schema.js +12 -1
  350. package/dist/infrastructure/persistence/sqlite/control.d.ts +14 -0
  351. package/dist/infrastructure/persistence/sqlite/control.js +69 -0
  352. package/dist/infrastructure/persistence/sqlite/jobs.d.ts +12 -0
  353. package/dist/infrastructure/persistence/sqlite/jobs.js +38 -0
  354. package/dist/infrastructure/persistence/sqlite/telemetry.d.ts +2 -1
  355. package/dist/infrastructure/persistence/sqlite/telemetry.js +5 -64
  356. package/dist/infrastructure/persistence/sqlite/telemetryWrites.d.ts +4 -0
  357. package/dist/infrastructure/persistence/sqlite/telemetryWrites.js +123 -0
  358. package/dist/infrastructure/persistence/sqliteSerializer.js +2 -0
  359. package/dist/infrastructure/scheduler/cron/persisted.d.ts +5 -0
  360. package/dist/infrastructure/scheduler/cron/persisted.js +27 -0
  361. package/dist/infrastructure/scheduler/cron/runtime.js +5 -10
  362. package/dist/infrastructure/scheduler/cron/validation.d.ts +3 -0
  363. package/dist/infrastructure/scheduler/cron/validation.js +11 -0
  364. package/dist/infrastructure/scheduler/cronParser.d.ts +1 -1
  365. package/dist/infrastructure/scheduler/cronParser.js +144 -11
  366. package/dist/infrastructure/server/bootstrap.d.ts +2 -3
  367. package/dist/infrastructure/server/bootstrap.js +33 -59
  368. package/dist/infrastructure/server/errors.d.ts +4 -0
  369. package/dist/infrastructure/server/errors.js +54 -0
  370. package/dist/infrastructure/server/handler-routes/control.d.ts +5 -5
  371. package/dist/infrastructure/server/handler-routes/control.js +16 -1
  372. package/dist/infrastructure/server/handler-routes/monitoring.d.ts +2 -2
  373. package/dist/infrastructure/server/handler.js +9 -11
  374. package/dist/infrastructure/server/handlers/advanced/dependencies.js +7 -6
  375. package/dist/infrastructure/server/handlers/advanced/jobs.js +19 -6
  376. package/dist/infrastructure/server/handlers/advanced/queue.d.ts +9 -9
  377. package/dist/infrastructure/server/handlers/advanced/queue.js +91 -27
  378. package/dist/infrastructure/server/handlers/core.d.ts +0 -5
  379. package/dist/infrastructure/server/handlers/core.js +47 -49
  380. package/dist/infrastructure/server/handlers/cron.d.ts +4 -4
  381. package/dist/infrastructure/server/handlers/cron.js +60 -59
  382. package/dist/infrastructure/server/handlers/dashboard.d.ts +1 -1
  383. package/dist/infrastructure/server/handlers/dashboard.js +21 -8
  384. package/dist/infrastructure/server/handlers/dlq.d.ts +6 -3
  385. package/dist/infrastructure/server/handlers/dlq.js +35 -9
  386. package/dist/infrastructure/server/handlers/flow.js +2 -1
  387. package/dist/infrastructure/server/handlers/groups.d.ts +11 -0
  388. package/dist/infrastructure/server/handlers/groups.js +55 -0
  389. package/dist/infrastructure/server/handlers/management.d.ts +5 -5
  390. package/dist/infrastructure/server/handlers/management.js +36 -9
  391. package/dist/infrastructure/server/handlers/monitoring/health.d.ts +5 -5
  392. package/dist/infrastructure/server/handlers/monitoring/health.js +45 -16
  393. package/dist/infrastructure/server/handlers/monitoring/operations.d.ts +1 -1
  394. package/dist/infrastructure/server/handlers/monitoring/operations.js +8 -1
  395. package/dist/infrastructure/server/handlers/monitoring/workers.d.ts +3 -3
  396. package/dist/infrastructure/server/handlers/monitoring/workers.js +31 -7
  397. package/dist/infrastructure/server/handlers/pushBatchValidation.d.ts +3 -1
  398. package/dist/infrastructure/server/handlers/pushBatchValidation.js +56 -8
  399. package/dist/infrastructure/server/handlers/query.d.ts +1 -1
  400. package/dist/infrastructure/server/handlers/query.js +5 -4
  401. package/dist/infrastructure/server/http.js +2 -2
  402. package/dist/infrastructure/server/httpDashboardEndpoints.d.ts +1 -1
  403. package/dist/infrastructure/server/httpDashboardEndpoints.js +19 -6
  404. package/dist/infrastructure/server/httpEndpoints.js +18 -7
  405. package/dist/infrastructure/server/httpRouteQueues.js +11 -1
  406. package/dist/infrastructure/server/protocol/validation.d.ts +1 -0
  407. package/dist/infrastructure/server/protocol/validation.js +1 -0
  408. package/dist/infrastructure/server/protocol.d.ts +1 -1
  409. package/dist/infrastructure/server/protocol.js +1 -1
  410. package/dist/infrastructure/server/shutdownCoordinator.d.ts +24 -0
  411. package/dist/infrastructure/server/shutdownCoordinator.js +106 -0
  412. package/dist/infrastructure/server/sseHandler.js +8 -3
  413. package/dist/infrastructure/server/storageAdapter.d.ts +29 -0
  414. package/dist/infrastructure/server/storageAdapter.js +61 -0
  415. package/dist/infrastructure/server/storageManager.d.ts +12 -0
  416. package/dist/infrastructure/server/storageManager.js +102 -0
  417. package/dist/infrastructure/server/tcp.js +2 -3
  418. package/dist/infrastructure/server/ws/snapshots.d.ts +1 -1
  419. package/dist/infrastructure/server/ws/snapshots.js +19 -4
  420. package/dist/infrastructure/server/wsHandler.js +10 -5
  421. package/dist/main.js +1 -1
  422. package/dist/mcp/backend/embedded/services.js +2 -1
  423. package/dist/mcp/index.d.ts +2 -2
  424. package/dist/mcp/index.js +2 -2
  425. package/dist/shared/storageHealth.d.ts +9 -0
  426. package/dist/shared/storageHealth.js +12 -0
  427. package/package.json +75 -65
@@ -0,0 +1,112 @@
1
+ import { buildRepeatSuccessor } from '../../../application/repeatJobs';
2
+ import { createJob, generateJobId, MAX_TIMELINE_ENTRIES, } from '../../../domain/types/job';
3
+ import { admitPostgresJob } from './admission';
4
+ import { decodePostgresJob, encodePostgresValue } from './codec';
5
+ import { databaseNow, recordPostgresEvent } from './context';
6
+ import { planPostgresDependencyCompletion } from './dependencyPromotion';
7
+ import { clearPostgresParentFlowFailures } from './flowFailures';
8
+ import { runPostgresTransactionWithRetry } from './transactionRetry';
9
+ import { tryLockPostgresRepeatQueues } from './queueLifecycle';
10
+ async function lockActiveJob(tx, ctx, id) {
11
+ const rows = await tx `
12
+ SELECT * FROM bunqueue_jobs
13
+ WHERE namespace = ${ctx.config.namespace} AND id = ${String(id)}
14
+ FOR UPDATE
15
+ `;
16
+ return rows[0] ?? null;
17
+ }
18
+ function notApplied(row) {
19
+ return {
20
+ applied: false,
21
+ alreadyFinalized: row?.state === 'completed' || row?.state === 'failed',
22
+ job: row ? decodePostgresJob(row).job : null,
23
+ state: row?.state ?? null,
24
+ };
25
+ }
26
+ async function deleteLiveJob(tx, ctx, id) {
27
+ await tx `
28
+ DELETE FROM bunqueue_job_logs
29
+ WHERE namespace = ${ctx.config.namespace} AND job_id = ${String(id)}
30
+ `;
31
+ await tx `
32
+ DELETE FROM bunqueue_dependencies
33
+ WHERE namespace = ${ctx.config.namespace} AND job_id = ${String(id)}
34
+ `;
35
+ await tx `
36
+ DELETE FROM bunqueue_jobs
37
+ WHERE namespace = ${ctx.config.namespace} AND id = ${String(id)}
38
+ `;
39
+ }
40
+ export async function completePostgresJob(ctx, id, token, result, removeOnComplete = false) {
41
+ return await runPostgresTransactionWithRetry(ctx, async (tx) => {
42
+ const dependencyCompletion = await planPostgresDependencyCompletion(tx, ctx, [id]);
43
+ const row = await lockActiveJob(tx, ctx, id);
44
+ const now = await databaseNow(tx);
45
+ if (row?.state !== 'active' ||
46
+ row.lease_token !== token ||
47
+ Number(row.lease_until ?? 0) <= now) {
48
+ return notApplied(row);
49
+ }
50
+ const job = decodePostgresJob(row).job;
51
+ job.completedAt = now;
52
+ job.progress = 100;
53
+ if (job.timeline.length < MAX_TIMELINE_ENTRIES) {
54
+ job.timeline.push({ state: 'completed', timestamp: now });
55
+ }
56
+ const resultPayload = encodePostgresValue(result);
57
+ await clearPostgresParentFlowFailures(tx, ctx, id);
58
+ await tx `
59
+ INSERT INTO bunqueue_completions (namespace, job_id, queue, completed_at, result)
60
+ VALUES (${ctx.config.namespace}, ${String(id)}, ${job.queue}, ${now}, ${resultPayload})
61
+ ON CONFLICT (namespace, job_id) DO UPDATE SET
62
+ queue = excluded.queue, completed_at = excluded.completed_at, result = excluded.result
63
+ `;
64
+ const removed = job.removeOnComplete || removeOnComplete;
65
+ if (removed) {
66
+ await deleteLiveJob(tx, ctx, id);
67
+ }
68
+ else {
69
+ await tx `
70
+ UPDATE bunqueue_jobs
71
+ SET payload = ${encodePostgresValue(job)}, state = 'completed', completed_at = ${now},
72
+ result = ${resultPayload}, lease_owner = NULL, lease_token = NULL,
73
+ lease_broker_id = NULL, lease_broker_session_id = NULL,
74
+ lease_until = NULL, dlq_retry_state = NULL,
75
+ version = version + 1
76
+ WHERE namespace = ${ctx.config.namespace} AND id = ${String(id)}
77
+ `;
78
+ }
79
+ await recordPostgresEvent(tx, ctx, {
80
+ queue: job.queue,
81
+ type: 'completed',
82
+ jobId: id,
83
+ occurredAt: now,
84
+ job,
85
+ state: 'completed',
86
+ result,
87
+ removed,
88
+ dlqEntry: null,
89
+ dlqRetryState: null,
90
+ });
91
+ await dependencyCompletion.promote(now);
92
+ const shouldRepeat = job.repeat !== null &&
93
+ (job.repeat.limit === undefined || job.repeat.count < job.repeat.limit);
94
+ const successorInput = shouldRepeat ? buildRepeatSuccessor(job, now) : null;
95
+ if (successorInput) {
96
+ if (!(await tryLockPostgresRepeatQueues(tx, ctx, [job.queue]))) {
97
+ throw new Error(`Queue ${job.queue} is being obliterated; retry completion`);
98
+ }
99
+ const successor = createJob(generateJobId(), job.queue, successorInput, now);
100
+ const admitted = await admitPostgresJob(tx, ctx, successor, {
101
+ linkParent: false,
102
+ queueLifecycleLocksHeld: true,
103
+ });
104
+ await tx `
105
+ INSERT INTO bunqueue_repeat_links (namespace, original_id, successor_id)
106
+ VALUES (${ctx.config.namespace}, ${String(job.id)}, ${String(admitted.job.id)})
107
+ ON CONFLICT (namespace, original_id) DO UPDATE SET successor_id = excluded.successor_id
108
+ `;
109
+ }
110
+ return { applied: true, alreadyFinalized: false, job, state: 'completed' };
111
+ });
112
+ }
@@ -0,0 +1,10 @@
1
+ import { type JobId } from '../../../domain/types/job';
2
+ import type { PostgresContext } from './context';
3
+ import type { PostgresReadSql } from './context';
4
+ import type { PostgresCompletionResult } from './types';
5
+ export declare function getPostgresCompletionResult(ctx: PostgresContext, id: JobId): Promise<{
6
+ found: boolean;
7
+ result: unknown;
8
+ }>;
9
+ export declare function loadPostgresCompletionResults(ctx: PostgresContext, queue?: string, sql?: PostgresReadSql): Promise<PostgresCompletionResult[]>;
10
+ export declare function getPostgresChildrenValues(ctx: PostgresContext, parentId: JobId): Promise<Record<string, unknown>>;
@@ -0,0 +1,87 @@
1
+ import { jobId } from '../../../domain/types/job';
2
+ import { decodePostgresValue } from './codec';
3
+ const LIVE_CONSUMER_STATES = [
4
+ 'waiting',
5
+ 'prioritized',
6
+ 'delayed',
7
+ 'waiting-children',
8
+ 'active',
9
+ ];
10
+ export async function getPostgresCompletionResult(ctx, id) {
11
+ const rows = await ctx.sql `
12
+ SELECT result FROM bunqueue_completions
13
+ WHERE namespace = ${ctx.config.namespace} AND job_id = ${String(id)}
14
+ `;
15
+ if (!rows[0])
16
+ return { found: false, result: undefined };
17
+ return {
18
+ found: true,
19
+ result: decodePostgresValue(rows[0].result, null, `postgresCompletion:${String(id)}`),
20
+ };
21
+ }
22
+ async function loadCompletionRows(ctx, queue, sql = ctx.sql) {
23
+ const queueFilter = queue === undefined ? null : queue;
24
+ return await sql `
25
+ WITH pinned AS MATERIALIZED (
26
+ SELECT DISTINCT dependency.dependency_id AS job_id
27
+ FROM bunqueue_dependencies AS dependency
28
+ JOIN bunqueue_jobs AS consumer
29
+ ON consumer.namespace = dependency.namespace AND consumer.id = dependency.job_id
30
+ WHERE dependency.namespace = ${ctx.config.namespace}
31
+ AND consumer.state = ANY(${ctx.sql.array([...LIVE_CONSUMER_STATES], 'TEXT')})
32
+ ), recent AS MATERIALIZED (
33
+ SELECT completion.job_id, completion.queue, completion.result,
34
+ FALSE AS pinned, completion.completed_at
35
+ FROM bunqueue_completions AS completion
36
+ WHERE completion.namespace = ${ctx.config.namespace}
37
+ AND (${queueFilter}::text IS NULL OR completion.queue = ${queueFilter})
38
+ AND NOT EXISTS (
39
+ SELECT 1 FROM pinned WHERE pinned.job_id = completion.job_id
40
+ )
41
+ ORDER BY completion.completed_at DESC, completion.job_id DESC
42
+ LIMIT ${ctx.config.maxJobResults}
43
+ )
44
+ SELECT completion.job_id, completion.queue, completion.result, TRUE AS pinned
45
+ FROM bunqueue_completions AS completion
46
+ JOIN pinned ON pinned.job_id = completion.job_id
47
+ WHERE completion.namespace = ${ctx.config.namespace}
48
+ AND (${queueFilter}::text IS NULL OR completion.queue = ${queueFilter})
49
+ UNION ALL
50
+ SELECT recent.job_id, recent.queue, recent.result, recent.pinned
51
+ FROM recent
52
+ ORDER BY job_id
53
+ `;
54
+ }
55
+ export async function loadPostgresCompletionResults(ctx, queue, sql = ctx.sql) {
56
+ const rows = await loadCompletionRows(ctx, queue, sql);
57
+ return rows.map((row) => ({
58
+ jobId: jobId(row.job_id),
59
+ queue: row.queue,
60
+ result: decodePostgresValue(row.result, null, `postgresCompletion:${row.job_id}`),
61
+ pinned: row.pinned,
62
+ }));
63
+ }
64
+ export async function getPostgresChildrenValues(ctx, parentId) {
65
+ const parents = await ctx.sql `
66
+ SELECT payload FROM bunqueue_jobs
67
+ WHERE namespace = ${ctx.config.namespace} AND id = ${String(parentId)}
68
+ `;
69
+ if (!parents[0])
70
+ return {};
71
+ const parent = decodePostgresValue(parents[0].payload, null, `postgresChildrenParent:${String(parentId)}`);
72
+ const childIds = [
73
+ ...new Set([...(parent?.childrenIds ?? []), ...(parent?.dependsOn ?? [])].map(String)),
74
+ ];
75
+ if (childIds.length === 0)
76
+ return {};
77
+ const rows = await ctx.sql `
78
+ SELECT job_id, queue, result FROM bunqueue_completions
79
+ WHERE namespace = ${ctx.config.namespace}
80
+ AND job_id = ANY(${ctx.sql.array(childIds, 'TEXT')})
81
+ ORDER BY job_id
82
+ `;
83
+ return Object.fromEntries(rows.map((row) => [
84
+ `${row.queue}:${row.job_id}`,
85
+ decodePostgresValue(row.result, null, `postgresChildResult:${row.job_id}`),
86
+ ]));
87
+ }
@@ -0,0 +1,3 @@
1
+ import { SQL } from 'bun';
2
+ import type { ResolvedPostgresStorageConfig } from './types';
3
+ export declare function createPostgresConnection(config: ResolvedPostgresStorageConfig): SQL;
@@ -0,0 +1,15 @@
1
+ import { SQL } from 'bun';
2
+ export function createPostgresConnection(config) {
3
+ return new SQL(config.url, {
4
+ max: config.poolSize,
5
+ connectionTimeout: 10,
6
+ idleTimeout: 30,
7
+ maxLifetime: 3600,
8
+ connection: {
9
+ application_name: `bunqueue:${config.brokerId}`.slice(0, 63),
10
+ statement_timeout: config.statementTimeoutMs,
11
+ lock_timeout: config.lockTimeoutMs,
12
+ idle_in_transaction_session_timeout: config.idleTransactionTimeoutMs,
13
+ },
14
+ });
15
+ }
@@ -0,0 +1,28 @@
1
+ import type { SQL, TransactionSQL } from 'bun';
2
+ import type { DlqEntry, DlqRetryState } from '../../../domain/types/dlq';
3
+ import type { Job, JobId } from '../../../domain/types/job';
4
+ import type { PostgresJobState, ResolvedPostgresStorageConfig } from './types';
5
+ export type PostgresReadSql = SQL | TransactionSQL;
6
+ export interface PostgresContext {
7
+ readonly sql: SQL;
8
+ readonly config: ResolvedPostgresStorageConfig;
9
+ readonly postCommitMaintenance?: (subsystem: string, operation: () => Promise<unknown>) => Promise<void>;
10
+ }
11
+ /** Run work that follows an already committed transition without changing its outcome. */
12
+ export declare function runPostgresPostCommitMaintenance(ctx: PostgresContext, subsystem: string, operation: () => Promise<unknown>): Promise<void>;
13
+ export declare function databaseNowSql(): string;
14
+ export declare function databaseNow(tx: SQL | TransactionSQL): Promise<number>;
15
+ export interface RecordPostgresEventInput {
16
+ readonly queue: string;
17
+ readonly type: string;
18
+ readonly jobId: JobId;
19
+ readonly occurredAt: number;
20
+ readonly job?: Job;
21
+ readonly state?: PostgresJobState;
22
+ readonly result?: unknown;
23
+ readonly error?: string;
24
+ readonly removed?: boolean;
25
+ readonly dlqEntry?: DlqEntry | null;
26
+ readonly dlqRetryState?: DlqRetryState | null;
27
+ }
28
+ export declare function recordPostgresEvent(tx: TransactionSQL, ctx: PostgresContext, input: RecordPostgresEventInput): Promise<number>;
@@ -0,0 +1,74 @@
1
+ import { eventPayload } from './codec';
2
+ import { recordPostgresEventPruneWatermarks, summarizePostgresPrunedEvents, } from './eventPruneWatermarks';
3
+ import { prunePostgresQueueEvents, tryLockPostgresEventRetention } from './eventRetention';
4
+ import { POSTGRES_EVENT_CHANNEL } from './schema';
5
+ import { recordPostgresMetricAdditions } from './metricWrites';
6
+ /** Run work that follows an already committed transition without changing its outcome. */
7
+ export async function runPostgresPostCommitMaintenance(ctx, subsystem, operation) {
8
+ if (ctx.postCommitMaintenance) {
9
+ await ctx.postCommitMaintenance(subsystem, operation);
10
+ return;
11
+ }
12
+ await operation();
13
+ }
14
+ export function databaseNowSql() {
15
+ return 'floor(extract(epoch from clock_timestamp()) * 1000)::bigint';
16
+ }
17
+ export async function databaseNow(tx) {
18
+ const [row] = await tx `
19
+ SELECT floor(extract(epoch from clock_timestamp()) * 1000)::bigint AS now
20
+ `;
21
+ return Number(row.now);
22
+ }
23
+ export async function recordPostgresEvent(tx, ctx, input) {
24
+ const payload = eventPayload({
25
+ ...(input.job && { job: input.job }),
26
+ ...(input.state && { state: input.state }),
27
+ ...(Object.hasOwn(input, 'result') && { result: input.result }),
28
+ ...(input.error !== undefined && { error: input.error }),
29
+ ...(input.removed !== undefined && { removed: input.removed }),
30
+ ...(Object.hasOwn(input, 'dlqEntry') && { dlqEntry: input.dlqEntry }),
31
+ ...(Object.hasOwn(input, 'dlqRetryState') && { dlqRetryState: input.dlqRetryState }),
32
+ });
33
+ const [row] = await tx `
34
+ INSERT INTO bunqueue_events
35
+ (namespace, queue, event_type, job_id, occurred_at, payload)
36
+ VALUES
37
+ (${ctx.config.namespace}, ${input.queue}, ${input.type}, ${String(input.jobId)},
38
+ ${input.occurredAt}, ${payload})
39
+ RETURNING id
40
+ `;
41
+ const eventId = Number(row.id);
42
+ const eventLimit = ctx.config.maxQueueEvents;
43
+ const retentionLockAcquired = await tryLockPostgresEventRetention(tx, ctx, input.queue);
44
+ const pruned = retentionLockAcquired
45
+ ? await prunePostgresQueueEvents(tx, ctx, input.queue, eventLimit)
46
+ : [];
47
+ const prune = summarizePostgresPrunedEvents(pruned);
48
+ const { prunedThrough } = prune;
49
+ if (prunedThrough > 0) {
50
+ await recordPostgresEventPruneWatermarks(tx, ctx, [
51
+ { queue: input.queue, sourceEventId: eventId, ...prune },
52
+ ]);
53
+ }
54
+ const metricType = input.type === 'completed'
55
+ ? 'completed'
56
+ : input.type === 'failed' && input.state === 'failed'
57
+ ? 'failed'
58
+ : null;
59
+ if (metricType) {
60
+ await recordPostgresMetricAdditions(tx, ctx, metricType, [{ queue: input.queue, count: 1 }], input.occurredAt);
61
+ }
62
+ await tx.notify(POSTGRES_EVENT_CHANNEL, JSON.stringify({
63
+ namespace: ctx.config.namespace,
64
+ queue: input.queue,
65
+ brokerId: ctx.config.brokerId,
66
+ eventId,
67
+ eventStartId: eventId,
68
+ eventEndId: eventId,
69
+ invalidateQueue: input.type.startsWith('queue-'),
70
+ ...(prunedThrough > 0 && { prunedThrough }),
71
+ ...(!retentionLockAcquired && { retentionRequested: true }),
72
+ }));
73
+ return eventId;
74
+ }
@@ -0,0 +1,23 @@
1
+ import { type DlqConfig } from '../../../domain/types/dlq';
2
+ import { type StallConfig } from '../../../domain/types/stall';
3
+ import { type PostgresContext, type PostgresReadSql } from './context';
4
+ import type { PostgresQueueState } from './types';
5
+ export interface PostgresQueueStateRow {
6
+ queue: string;
7
+ paused: boolean;
8
+ rate_limit: number | null;
9
+ rate_duration_ms: number | string | bigint | null;
10
+ rate_window_started_at: number | string | bigint | null;
11
+ rate_expires_at: number | string | bigint | null;
12
+ rate_count: number;
13
+ concurrency_limit: number | null;
14
+ stall_config: Uint8Array | null;
15
+ dlq_config: Uint8Array | null;
16
+ }
17
+ export declare function decodePostgresQueueState(queue: string, row?: PostgresQueueStateRow): PostgresQueueState;
18
+ export declare function getPostgresQueueState(ctx: PostgresContext, queue: string, sql?: PostgresReadSql): Promise<PostgresQueueState>;
19
+ export declare function setPostgresPaused(ctx: PostgresContext, queue: string, paused: boolean): Promise<void>;
20
+ export declare function setPostgresRateLimit(ctx: PostgresContext, queue: string, limit: number | null, durationMs: number | null, ttlMs?: number | null): Promise<void>;
21
+ export declare function setPostgresConcurrency(ctx: PostgresContext, queue: string, limit: number | null): Promise<void>;
22
+ export declare function setPostgresStallConfig(ctx: PostgresContext, queue: string, config: StallConfig): Promise<void>;
23
+ export declare function setPostgresDlqConfig(ctx: PostgresContext, queue: string, config: DlqConfig): Promise<void>;
@@ -0,0 +1,105 @@
1
+ import { DEFAULT_DLQ_CONFIG } from '../../../domain/types/dlq';
2
+ import { jobId } from '../../../domain/types/job';
3
+ import { DEFAULT_STALL_CONFIG } from '../../../domain/types/stall';
4
+ import { decodePostgresValue, encodePostgresValue } from './codec';
5
+ import { enforcePostgresDlqLimit } from './dlqLifecycle';
6
+ import { databaseNow, recordPostgresEvent, } from './context';
7
+ import { normalizePostgresRateLimit } from './rateLimit';
8
+ function optionalNumber(value) {
9
+ return value === null || value === undefined ? null : Number(value);
10
+ }
11
+ export function decodePostgresQueueState(queue, row) {
12
+ return {
13
+ queue,
14
+ paused: row?.paused ?? false,
15
+ rateLimit: row?.rate_limit ?? null,
16
+ rateDurationMs: optionalNumber(row?.rate_duration_ms),
17
+ rateWindowStartedAt: optionalNumber(row?.rate_window_started_at),
18
+ rateExpiresAt: optionalNumber(row?.rate_expires_at),
19
+ rateCount: row?.rate_count ?? 0,
20
+ concurrencyLimit: row?.concurrency_limit ?? null,
21
+ stallConfig: decodePostgresValue(row?.stall_config ?? null, DEFAULT_STALL_CONFIG, 'stallConfig'),
22
+ dlqConfig: decodePostgresValue(row?.dlq_config ?? null, DEFAULT_DLQ_CONFIG, 'dlqConfig'),
23
+ };
24
+ }
25
+ async function recordQueueInvalidation(tx, ctx, queue, type, occurredAt) {
26
+ await recordPostgresEvent(tx, ctx, {
27
+ queue,
28
+ type,
29
+ jobId: jobId(`__queue__:${queue}`),
30
+ occurredAt: occurredAt ?? (await databaseNow(tx)),
31
+ });
32
+ }
33
+ export async function getPostgresQueueState(ctx, queue, sql = ctx.sql) {
34
+ const rows = await sql `
35
+ SELECT queue, paused, rate_limit, rate_duration_ms, rate_window_started_at, rate_expires_at,
36
+ rate_count, concurrency_limit, stall_config, dlq_config
37
+ FROM bunqueue_queue_state
38
+ WHERE namespace = ${ctx.config.namespace} AND queue = ${queue}
39
+ `;
40
+ return decodePostgresQueueState(queue, rows[0]);
41
+ }
42
+ export async function setPostgresPaused(ctx, queue, paused) {
43
+ await ctx.sql.begin(async (tx) => {
44
+ await tx `
45
+ INSERT INTO bunqueue_queue_state (namespace, queue, paused)
46
+ VALUES (${ctx.config.namespace}, ${queue}, ${paused})
47
+ ON CONFLICT (namespace, queue) DO UPDATE SET paused = excluded.paused
48
+ `;
49
+ await recordQueueInvalidation(tx, ctx, queue, paused ? 'queue-paused' : 'queue-resumed');
50
+ });
51
+ }
52
+ export async function setPostgresRateLimit(ctx, queue, limit, durationMs, ttlMs) {
53
+ const normalized = normalizePostgresRateLimit(durationMs, ttlMs);
54
+ await ctx.sql.begin(async (tx) => {
55
+ const now = await databaseNow(tx);
56
+ const rateExpiresAt = limit !== null && normalized.ttlMs !== null ? now + normalized.ttlMs : null;
57
+ await tx `
58
+ INSERT INTO bunqueue_queue_state
59
+ (namespace, queue, rate_limit, rate_duration_ms, rate_window_started_at,
60
+ rate_expires_at, rate_count)
61
+ VALUES
62
+ (${ctx.config.namespace}, ${queue}, ${limit}, ${normalized.durationMs}, ${now},
63
+ ${rateExpiresAt}, 0)
64
+ ON CONFLICT (namespace, queue) DO UPDATE SET
65
+ rate_limit = excluded.rate_limit,
66
+ rate_duration_ms = excluded.rate_duration_ms,
67
+ rate_window_started_at = excluded.rate_window_started_at,
68
+ rate_expires_at = excluded.rate_expires_at,
69
+ rate_count = 0
70
+ `;
71
+ await recordQueueInvalidation(tx, ctx, queue, 'queue-rate-limit-changed', now);
72
+ });
73
+ }
74
+ export async function setPostgresConcurrency(ctx, queue, limit) {
75
+ await ctx.sql.begin(async (tx) => {
76
+ await tx `
77
+ INSERT INTO bunqueue_queue_state (namespace, queue, concurrency_limit)
78
+ VALUES (${ctx.config.namespace}, ${queue}, ${limit})
79
+ ON CONFLICT (namespace, queue) DO UPDATE SET concurrency_limit = excluded.concurrency_limit
80
+ `;
81
+ await recordQueueInvalidation(tx, ctx, queue, 'queue-concurrency-changed');
82
+ });
83
+ }
84
+ export async function setPostgresStallConfig(ctx, queue, config) {
85
+ await ctx.sql.begin(async (tx) => {
86
+ await tx `
87
+ INSERT INTO bunqueue_queue_state (namespace, queue, stall_config)
88
+ VALUES (${ctx.config.namespace}, ${queue}, ${encodePostgresValue(config)})
89
+ ON CONFLICT (namespace, queue) DO UPDATE SET stall_config = excluded.stall_config
90
+ `;
91
+ await recordQueueInvalidation(tx, ctx, queue, 'queue-stall-config-changed');
92
+ });
93
+ }
94
+ export async function setPostgresDlqConfig(ctx, queue, config) {
95
+ await ctx.sql.begin(async (tx) => {
96
+ const now = await databaseNow(tx);
97
+ await tx `
98
+ INSERT INTO bunqueue_queue_state (namespace, queue, dlq_config)
99
+ VALUES (${ctx.config.namespace}, ${queue}, ${encodePostgresValue(config)})
100
+ ON CONFLICT (namespace, queue) DO UPDATE SET dlq_config = excluded.dlq_config
101
+ `;
102
+ await recordQueueInvalidation(tx, ctx, queue, 'queue-dlq-config-changed', now);
103
+ });
104
+ await enforcePostgresDlqLimit(ctx, queue, config.maxEntries);
105
+ }
@@ -0,0 +1,18 @@
1
+ import { type CronJob, type CronJobInput } from '../../../domain/types/cron';
2
+ import { type PostgresContext, type PostgresReadSql } from './context';
3
+ export interface PostgresCronRow {
4
+ name: string;
5
+ payload: Uint8Array;
6
+ next_run: number | string | bigint;
7
+ executions: number;
8
+ max_limit: number | null;
9
+ }
10
+ export declare function decodePostgresCron(row: PostgresCronRow): CronJob;
11
+ export declare function upsertPostgresCron(ctx: PostgresContext, input: CronJobInput): Promise<CronJob>;
12
+ export declare function getPostgresCron(ctx: PostgresContext, name: string): Promise<CronJob | undefined>;
13
+ export declare function listPostgresCrons(ctx: PostgresContext, sql?: PostgresReadSql): Promise<CronJob[]>;
14
+ export declare function removePostgresCron(ctx: PostgresContext, name: string): Promise<boolean>;
15
+ /** Recalculate missed rows only on the oldest live broker for this namespace. */
16
+ export declare function reconcilePostgresCronsOnStartup(ctx: PostgresContext): Promise<number>;
17
+ /** Advance and enqueue each due cron once under PostgreSQL row locks. */
18
+ export declare function processPostgresCrons(ctx: PostgresContext, limit?: number): Promise<number>;