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
@@ -18,6 +18,7 @@ export declare class QueueState<T> {
18
18
  embedded: boolean;
19
19
  tcp: TcpConnectionPool | null;
20
20
  prefixKey: string;
21
+ dataPath: string | undefined;
21
22
  };
22
23
  protected get addCtx(): {
23
24
  opts: QueueOptions;
@@ -55,6 +56,7 @@ export declare class QueueState<T> {
55
56
  embedded: boolean;
56
57
  tcp: TcpConnectionPool | null;
57
58
  prefixKey: string;
59
+ dataPath: string | undefined;
58
60
  };
59
61
  protected get queryCtx(): {
60
62
  getJobState: (id: string) => Promise<import("../../types").JobStateType>;
@@ -84,6 +86,7 @@ export declare class QueueState<T> {
84
86
  embedded: boolean;
85
87
  tcp: TcpConnectionPool | null;
86
88
  prefixKey: string;
89
+ dataPath: string | undefined;
87
90
  };
88
91
  protected get moveCtx(): {
89
92
  getJobState: (id: string) => Promise<import("../../types").JobStateType>;
@@ -92,6 +95,7 @@ export declare class QueueState<T> {
92
95
  embedded: boolean;
93
96
  tcp: TcpConnectionPool | null;
94
97
  prefixKey: string;
98
+ dataPath: string | undefined;
95
99
  };
96
100
  protected releaseConnection(): void;
97
101
  }
@@ -78,6 +78,7 @@ export class QueueState {
78
78
  embedded: this.embedded,
79
79
  tcp: this.tcpPool,
80
80
  prefixKey: this.prefixKey,
81
+ dataPath: this.opts.dataPath,
81
82
  };
82
83
  }
83
84
  get addCtx() {
@@ -4,7 +4,7 @@ export type { ActiveEvent, CompletedEvent, DelayedEvent, DrainedEvent, Duplicate
4
4
  export type { FlowJobData, Processor, QueueEventType } from './flow';
5
5
  export type { ChangePriorityOpts, GetDependenciesOpts, Job, JobDependencies, JobDependenciesCount, JobJson, JobJsonRaw, JobStateType, } from './job';
6
6
  export type { QueueMetrics, QueueMetricsMeta, QueueMetricType } from './metrics';
7
- export type { BackoffOptions, DebounceOptions, DeduplicationOptions, JobOptions, KeepJobs, ParentOpts, RepeatOptions, } from './options';
8
- export type { RateLimiterOptions, StallConfig, WorkerOptions } from './worker';
7
+ export type { BackoffOptions, DebounceOptions, DeduplicationOptions, GroupJobOptions, JobOptions, KeepJobs, ParentOpts, RepeatOptions, } from './options';
8
+ export type { GroupWorkerOptions, RateLimiterOptions, StallConfig, WorkerOptions } from './worker';
9
9
  export { createPublicJob, toDlqEntry, toPublicJob } from '../jobConversion';
10
10
  export type { CreatePublicJobOptions, ToPublicJobOptions } from '../jobConversion';
@@ -33,6 +33,9 @@ export interface RepeatOptions {
33
33
  offset?: number;
34
34
  jobId?: string;
35
35
  }
36
+ export interface GroupJobOptions {
37
+ id: string | number;
38
+ }
36
39
  /** Options accepted when adding a job. */
37
40
  export interface JobOptions {
38
41
  priority?: number;
@@ -59,4 +62,5 @@ export interface JobOptions {
59
62
  timestamp?: number;
60
63
  deduplication?: DeduplicationOptions;
61
64
  debounce?: DebounceOptions;
65
+ group?: GroupJobOptions;
62
66
  }
@@ -4,6 +4,13 @@ export interface RateLimiterOptions {
4
4
  duration: number;
5
5
  groupKey?: string;
6
6
  }
7
+ export interface GroupWorkerOptions {
8
+ concurrency?: number;
9
+ limit?: {
10
+ max: number;
11
+ duration: number;
12
+ };
13
+ }
7
14
  export interface WorkerOptions {
8
15
  concurrency?: number;
9
16
  autorun?: boolean;
@@ -16,6 +23,7 @@ export interface WorkerOptions {
16
23
  pollTimeout?: number;
17
24
  useLocks?: boolean;
18
25
  limiter?: RateLimiterOptions;
26
+ group?: GroupWorkerOptions;
19
27
  lockDuration?: number;
20
28
  maxStalledCount?: number;
21
29
  skipStalledCheck?: boolean;
@@ -39,15 +39,10 @@ export class WorkerExecution extends WorkerPolling {
39
39
  if (this.groupLimiter)
40
40
  this.groupLimiter.decrement(job);
41
41
  if (this.running && !this._closing)
42
- this.poll();
42
+ this.scheduleProcessing();
43
43
  });
44
- if (this.activeJobs < this.opts.concurrency && !this._closing && !this.processingScheduled) {
45
- this.processingScheduled = true;
46
- setImmediate(() => {
47
- this.processingScheduled = false;
48
- void this.tryProcess();
49
- });
50
- }
44
+ if (this.activeJobs < this.opts.concurrency && !this._closing)
45
+ this.scheduleProcessing();
51
46
  return true;
52
47
  }
53
48
  registerWithServer() {
@@ -118,6 +113,7 @@ export class WorkerExecution extends WorkerPolling {
118
113
  useLocks: this.opts.useLocks,
119
114
  pollTimeout: this.opts.pollTimeout,
120
115
  lockDuration: this.opts.lockDuration,
116
+ group: this.opts.group,
121
117
  };
122
118
  }
123
119
  }
@@ -1,7 +1,9 @@
1
+ import { assertGroupPullOptions } from '../../../domain/types/group';
1
2
  import { resolveToken } from '../../resolveToken';
2
3
  import { TcpConnectionPool } from '../../tcpPool';
3
4
  import { WORKER_CONSTANTS } from '../constants';
4
5
  export function resolveWorkerOptions(options, embedded) {
6
+ assertGroupPullOptions(options.group);
5
7
  return {
6
8
  concurrency: options.concurrency ?? 1,
7
9
  autorun: options.autorun ?? true,
@@ -18,6 +20,7 @@ export function resolveWorkerOptions(options, embedded) {
18
20
  removeOnComplete: options.removeOnComplete,
19
21
  removeOnFail: options.removeOnFail,
20
22
  connection: options.connection,
23
+ group: options.group,
21
24
  };
22
25
  }
23
26
  export function createTcpPool(options, concurrency) {
@@ -3,6 +3,7 @@ import { WorkerBuffer } from './buffer';
3
3
  import type { PulledJob, WorkerDelivery } from './state';
4
4
  export declare abstract class WorkerPolling<T = unknown, R = unknown> extends WorkerBuffer<T, R> {
5
5
  protected poll(): void;
6
+ protected scheduleProcessing(): void;
6
7
  protected tryProcess(): Promise<void>;
7
8
  protected doPullBatch(): Promise<PulledJob[]>;
8
9
  private scheduleRateLimitPoll;
@@ -16,6 +16,15 @@ export class WorkerPolling extends WorkerBuffer {
16
16
  }
17
17
  void this.tryProcess();
18
18
  }
19
+ scheduleProcessing() {
20
+ if (!this.running || this._closing || this.processingScheduled)
21
+ return;
22
+ this.processingScheduled = true;
23
+ setImmediate(() => {
24
+ this.processingScheduled = false;
25
+ void this.tryProcess();
26
+ });
27
+ }
19
28
  async tryProcess() {
20
29
  if (!this.running || this._closing)
21
30
  return;
@@ -1,4 +1,4 @@
1
- import type { ConnectionOptions } from '../../types';
1
+ import type { ConnectionOptions, GroupWorkerOptions } from '../../types';
2
2
  export interface ExtendedWorkerOptions {
3
3
  concurrency: number;
4
4
  autorun: boolean;
@@ -21,4 +21,5 @@ export interface ExtendedWorkerOptions {
21
21
  count?: number;
22
22
  };
23
23
  connection?: ConnectionOptions;
24
+ group?: GroupWorkerOptions;
24
25
  }
@@ -4,6 +4,7 @@
4
4
  */
5
5
  import type { Job as InternalJob } from '../../domain/types/job';
6
6
  import type { TcpConnection } from './types';
7
+ import type { GroupWorkerOptions } from '../types';
7
8
  export interface PullConfig {
8
9
  readonly name: string;
9
10
  readonly workerId: string;
@@ -11,6 +12,7 @@ export interface PullConfig {
11
12
  readonly pollTimeout: number;
12
13
  /** Lock TTL in ms to request from the server on a lock-based pull. */
13
14
  readonly lockDuration?: number;
15
+ readonly group?: GroupWorkerOptions;
14
16
  }
15
17
  export declare function pullEmbedded(config: PullConfig, count: number): Promise<Array<{
16
18
  job: InternalJob;
@@ -10,18 +10,18 @@ export async function pullEmbedded(config, count) {
10
10
  // configured lock TTL is honored in embedded mode too (undefined → server default).
11
11
  if (config.useLocks) {
12
12
  if (count === 1) {
13
- const { job, token } = await manager.pullWithLock(config.name, config.workerId, 0, config.lockDuration);
13
+ const { job, token } = await manager.pullWithLock(config.name, config.workerId, 0, config.lockDuration, undefined, config.group);
14
14
  return job ? [{ job, token }] : [];
15
15
  }
16
- const { jobs, tokens } = await manager.pullBatchWithLock(config.name, count, config.workerId, 0, config.lockDuration);
16
+ const { jobs, tokens } = await manager.pullBatchWithLock(config.name, count, config.workerId, 0, config.lockDuration, undefined, config.group);
17
17
  return jobs.map((job, i) => ({ job, token: tokens[i] || null }));
18
18
  }
19
19
  // No locks - use regular pull
20
20
  if (count === 1) {
21
- const job = await manager.pull(config.name, 0);
21
+ const job = await manager.pull(config.name, 0, undefined, config.group);
22
22
  return job ? [{ job, token: null }] : [];
23
23
  }
24
- const jobs = await manager.pullBatch(config.name, count, 0);
24
+ const jobs = await manager.pullBatch(config.name, count, 0, undefined, config.group);
25
25
  return jobs.map((job) => ({ job, token: null }));
26
26
  }
27
27
  export async function pullTcp(config, tcp, count, closing) {
@@ -36,6 +36,8 @@ export async function pullTcp(config, tcp, count, closing) {
36
36
  };
37
37
  if (count > 1)
38
38
  cmd.count = count;
39
+ if (config.group)
40
+ cmd.group = config.group;
39
41
  // Only request lock ownership when useLocks is enabled
40
42
  if (config.useLocks) {
41
43
  cmd.owner = config.workerId;
@@ -16,6 +16,20 @@ export interface ResolvedConfig {
16
16
  tlsKeyFile: string | undefined;
17
17
  authTokens: string[];
18
18
  dataPath: string | undefined;
19
+ storageDriver: 'memory' | 'sqlite' | 'postgres';
20
+ postgresUrl: string | undefined;
21
+ postgresNamespace: string;
22
+ postgresBrokerId: string | undefined;
23
+ postgresPoolSize: number;
24
+ postgresLeaseDurationMs: number;
25
+ postgresPollIntervalMs: number;
26
+ postgresStatementTimeoutMs: number;
27
+ postgresLockTimeoutMs: number;
28
+ postgresIdleTransactionTimeoutMs: number;
29
+ postgresMaxConcurrentOperations: number;
30
+ postgresMaxQueuedOperations: number;
31
+ postgresMaxSnapshotJobs: number;
32
+ postgresMaxSnapshotPayloadBytes: number;
19
33
  corsOrigins: string[];
20
34
  requireAuthForMetrics: boolean;
21
35
  maxPrometheusQueues: number;
@@ -8,6 +8,19 @@ import { DEFAULTS as S3_DEFAULTS } from '../infrastructure/backup/s3BackupConfig
8
8
  /** Resolve server config: config file > env vars > defaults */
9
9
  export function resolveServerConfig(fileConfig) {
10
10
  const fc = fileConfig;
11
+ const dataPath = fc?.storage?.dataPath ??
12
+ Bun.env.BUNQUEUE_DATA_PATH ??
13
+ Bun.env.BQ_DATA_PATH ??
14
+ Bun.env.DATA_PATH ??
15
+ Bun.env.SQLITE_PATH;
16
+ const postgresUrl = fc?.storage?.url ?? Bun.env.BUNQUEUE_POSTGRES_URL;
17
+ const storageDriver = fc?.storage?.driver
18
+ ? resolveStorageDriver(fc.storage.driver, postgresUrl, dataPath)
19
+ : fc?.storage?.url
20
+ ? 'postgres'
21
+ : fc?.storage?.dataPath
22
+ ? 'sqlite'
23
+ : resolveStorageDriver(Bun.env.BUNQUEUE_STORAGE_DRIVER, postgresUrl, dataPath);
11
24
  return {
12
25
  tcpPort: fc?.server?.tcpPort ?? parseInt(Bun.env.TCP_PORT ?? '6789', 10),
13
26
  httpPort: fc?.server?.httpPort ?? parseInt(Bun.env.HTTP_PORT ?? '6790', 10),
@@ -17,11 +30,30 @@ export function resolveServerConfig(fileConfig) {
17
30
  tlsCertFile: fc?.server?.tlsCertFile ?? Bun.env.TLS_CERT_FILE,
18
31
  tlsKeyFile: fc?.server?.tlsKeyFile ?? Bun.env.TLS_KEY_FILE,
19
32
  authTokens: fc?.auth?.tokens ?? Bun.env.AUTH_TOKENS?.split(',').filter(Boolean) ?? [],
20
- dataPath: fc?.storage?.dataPath ??
21
- Bun.env.BUNQUEUE_DATA_PATH ??
22
- Bun.env.BQ_DATA_PATH ??
23
- Bun.env.DATA_PATH ??
24
- Bun.env.SQLITE_PATH,
33
+ dataPath,
34
+ storageDriver,
35
+ postgresUrl,
36
+ postgresNamespace: fc?.storage?.namespace ?? Bun.env.BUNQUEUE_POSTGRES_NAMESPACE ?? 'default',
37
+ postgresBrokerId: fc?.storage?.brokerId ?? Bun.env.BUNQUEUE_BROKER_ID,
38
+ postgresPoolSize: positiveInteger(fc?.storage?.poolSize ?? parseInt(Bun.env.BUNQUEUE_POSTGRES_POOL_SIZE ?? '4', 10), 4),
39
+ postgresLeaseDurationMs: positiveInteger(fc?.storage?.leaseDurationMs ??
40
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_LEASE_DURATION_MS ?? '30000', 10), 30_000),
41
+ postgresPollIntervalMs: positiveInteger(fc?.storage?.pollIntervalMs ??
42
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_POLL_INTERVAL_MS ?? '250', 10), 250),
43
+ postgresStatementTimeoutMs: positiveInteger(fc?.storage?.statementTimeoutMs ??
44
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_STATEMENT_TIMEOUT_MS ?? '30000', 10), 30_000),
45
+ postgresLockTimeoutMs: positiveInteger(fc?.storage?.lockTimeoutMs ??
46
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_LOCK_TIMEOUT_MS ?? '5000', 10), 5_000),
47
+ postgresIdleTransactionTimeoutMs: positiveInteger(fc?.storage?.idleTransactionTimeoutMs ??
48
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_IDLE_TRANSACTION_TIMEOUT_MS ?? '30000', 10), 30_000),
49
+ postgresMaxConcurrentOperations: positiveInteger(fc?.storage?.maxConcurrentOperations ??
50
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_MAX_CONCURRENT_OPERATIONS ?? '16', 10), 16),
51
+ postgresMaxQueuedOperations: nonNegativeInteger(fc?.storage?.maxQueuedOperations ??
52
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_MAX_QUEUED_OPERATIONS ?? '128', 10), 128),
53
+ postgresMaxSnapshotJobs: positiveInteger(fc?.storage?.maxSnapshotJobs ??
54
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_MAX_SNAPSHOT_JOBS ?? '100000', 10), 100_000),
55
+ postgresMaxSnapshotPayloadBytes: positiveInteger(fc?.storage?.maxSnapshotPayloadBytes ??
56
+ parseInt(Bun.env.BUNQUEUE_POSTGRES_MAX_SNAPSHOT_PAYLOAD_BYTES ?? '268435456', 10), 256 * 1024 * 1024),
25
57
  corsOrigins: fc?.cors?.origins ?? Bun.env.CORS_ALLOW_ORIGIN?.split(',').filter(Boolean) ?? [],
26
58
  requireAuthForMetrics: fc?.auth?.requireAuthForMetrics ?? Bun.env.METRICS_AUTH === 'true',
27
59
  maxPrometheusQueues: nonNegativeInteger(fc?.telemetry?.maxPrometheusQueues ?? parseInt(Bun.env.METRICS_MAX_QUEUES ?? '100', 10), 100),
@@ -31,9 +63,22 @@ export function resolveServerConfig(fileConfig) {
31
63
  statsIntervalMs: fc?.timeouts?.stats ?? parseInt(Bun.env.STATS_INTERVAL_MS ?? '300000', 10),
32
64
  };
33
65
  }
66
+ function resolveStorageDriver(configured, postgresUrl, dataPath) {
67
+ if (configured === 'memory' || configured === 'sqlite' || configured === 'postgres') {
68
+ return configured;
69
+ }
70
+ if (configured)
71
+ throw new Error(`Unsupported storage driver: ${configured}`);
72
+ if (postgresUrl)
73
+ return 'postgres';
74
+ return dataPath ? 'sqlite' : 'memory';
75
+ }
34
76
  function nonNegativeInteger(value, fallback) {
35
77
  return Number.isFinite(value) && value >= 0 ? Math.floor(value) : fallback;
36
78
  }
79
+ function positiveInteger(value, fallback) {
80
+ return Number.isFinite(value) && value > 0 ? Math.floor(value) : fallback;
81
+ }
37
82
  /**
38
83
  * Resolve server TLS options from resolved config. Returns null when TLS is
39
84
  * not configured; throws when only one of cert/key is set (fail fast at
@@ -20,7 +20,25 @@ export interface BunqueueConfig {
20
20
  requireAuthForMetrics?: boolean;
21
21
  };
22
22
  storage?: {
23
+ /** Persistence backend. Inferred from url/dataPath when omitted. */
24
+ driver?: 'memory' | 'sqlite' | 'postgres';
23
25
  dataPath?: string;
26
+ /** PostgreSQL connection URL. Required when driver is postgres. */
27
+ url?: string;
28
+ /** Isolates independent bunqueue installations sharing one PostgreSQL database. */
29
+ namespace?: string;
30
+ /** Stable identifier for this broker process; generated automatically when omitted. */
31
+ brokerId?: string;
32
+ poolSize?: number;
33
+ leaseDurationMs?: number;
34
+ pollIntervalMs?: number;
35
+ statementTimeoutMs?: number;
36
+ lockTimeoutMs?: number;
37
+ idleTransactionTimeoutMs?: number;
38
+ maxConcurrentOperations?: number;
39
+ maxQueuedOperations?: number;
40
+ maxSnapshotJobs?: number;
41
+ maxSnapshotPayloadBytes?: number;
24
42
  };
25
43
  telemetry?: {
26
44
  /** Maximum queue label values exposed to Prometheus; zero disables per-queue series. */
@@ -0,0 +1,9 @@
1
+ import type { Job } from '../types/jobs/model';
2
+ /** Read the broker-internal admission order used by grouped FIFO lanes. */
3
+ export declare function getGroupFifoOrder(job: Job): bigint | null;
4
+ /** Stamp a stable order without exposing it through the public job protocol. */
5
+ export declare function setGroupFifoOrder(job: Job, order: bigint): void;
6
+ /** Preserve the hidden order when an immutable job replacement is created. */
7
+ export declare function copyGroupFifoOrder(source: Job, target: Job): void;
8
+ /** Restore a validated decimal order from SQLite extended options. */
9
+ export declare function restoreGroupFifoOrder(job: Job, stored: string | null): void;
@@ -0,0 +1,26 @@
1
+ const GROUP_FIFO_ORDER = Symbol('bunqueue.groupFifoOrder');
2
+ /** Read the broker-internal admission order used by grouped FIFO lanes. */
3
+ export function getGroupFifoOrder(job) {
4
+ return job[GROUP_FIFO_ORDER] ?? null;
5
+ }
6
+ /** Stamp a stable order without exposing it through the public job protocol. */
7
+ export function setGroupFifoOrder(job, order) {
8
+ Object.defineProperty(job, GROUP_FIFO_ORDER, {
9
+ value: order,
10
+ enumerable: true,
11
+ configurable: true,
12
+ writable: false,
13
+ });
14
+ }
15
+ /** Preserve the hidden order when an immutable job replacement is created. */
16
+ export function copyGroupFifoOrder(source, target) {
17
+ const order = getGroupFifoOrder(source);
18
+ if (order !== null)
19
+ setGroupFifoOrder(target, order);
20
+ }
21
+ /** Restore a validated decimal order from SQLite extended options. */
22
+ export function restoreGroupFifoOrder(job, stored) {
23
+ if (stored === null || !/^[1-9]\d*$/.test(stored))
24
+ return;
25
+ setGroupFifoOrder(job, BigInt(stored));
26
+ }
@@ -44,6 +44,8 @@ export declare class DlqShard {
44
44
  getFiltered(queue: string, filter: DlqFilter): DlqEntry[];
45
45
  /** Remove entry from DLQ by job ID */
46
46
  remove(queue: string, jobId: JobId): DlqEntry | null;
47
+ /** Remove every entry with the same job ID from one queue. */
48
+ removeAll(queue: string, jobId: JobId): DlqEntry[];
47
49
  /** Get entries ready for auto-retry */
48
50
  getAutoRetryEntries(queue: string, now?: number): DlqEntry[];
49
51
  /** Get expired entries for cleanup */
@@ -135,6 +135,22 @@ export class DlqShard {
135
135
  this.stats.decrementDlq();
136
136
  return entries.splice(idx, 1)[0];
137
137
  }
138
+ /** Remove every entry with the same job ID from one queue. */
139
+ removeAll(queue, jobId) {
140
+ const entries = this.dlq.get(queue);
141
+ if (!entries)
142
+ return [];
143
+ const removed = [];
144
+ const remaining = [];
145
+ for (const entry of entries) {
146
+ (entry.job.id === jobId ? removed : remaining).push(entry);
147
+ }
148
+ if (removed.length === 0)
149
+ return removed;
150
+ this.dlq.set(queue, remaining);
151
+ this.stats.decrementDlq(removed.length);
152
+ return removed;
153
+ }
138
154
  /** Get entries ready for auto-retry */
139
155
  getAutoRetryEntries(queue, now = Date.now()) {
140
156
  const entries = this.dlq.get(queue);
@@ -0,0 +1,23 @@
1
+ import { type GroupPullOptions, type GroupRateLimitOverride } from '../types/group';
2
+ export interface GroupLimitStatus {
3
+ eligible: boolean;
4
+ retryAt: number | null;
5
+ }
6
+ /** Stored group overrides and broker-authoritative runtime rate windows. */
7
+ export declare class GroupLimiterManager {
8
+ private readonly rateOverrides;
9
+ private readonly concurrencyOverrides;
10
+ private readonly windows;
11
+ status(queue: string, groupId: string, defaults: GroupPullOptions | undefined, active: number, now?: number): GroupLimitStatus;
12
+ acquire(queue: string, groupId: string, defaults: GroupPullOptions | undefined, active: number, now?: number): boolean;
13
+ setRateLimit(queue: string, groupId: string, max: number, duration: number): void;
14
+ getRateLimit(queue: string, groupId: string): GroupRateLimitOverride | null;
15
+ removeRateLimit(queue: string, groupId: string): number;
16
+ getRateLimitTtl(queue: string, groupId: string, maxJobs?: number, now?: number): number;
17
+ setConcurrency(queue: string, groupId: string, concurrency: number): void;
18
+ getConcurrency(queue: string, groupId: string): number | null;
19
+ removeConcurrency(queue: string, groupId: string): number;
20
+ clearQueue(queue: string): void;
21
+ pruneExpiredWindows(now?: number): void;
22
+ private currentWindow;
23
+ }
@@ -0,0 +1,107 @@
1
+ import { assertPositiveSafeInteger, } from '../types/group';
2
+ function key(queue, groupId) {
3
+ return `${queue}\0${groupId}`;
4
+ }
5
+ /** Stored group overrides and broker-authoritative runtime rate windows. */
6
+ export class GroupLimiterManager {
7
+ rateOverrides = new Map();
8
+ concurrencyOverrides = new Map();
9
+ windows = new Map();
10
+ status(queue, groupId, defaults, active, now = Date.now()) {
11
+ const groupKey = key(queue, groupId);
12
+ if (defaults?.concurrency !== undefined) {
13
+ const concurrency = this.concurrencyOverrides.get(groupKey) ?? defaults.concurrency;
14
+ if (active >= concurrency)
15
+ return { eligible: false, retryAt: null };
16
+ }
17
+ if (!defaults?.limit)
18
+ return { eligible: true, retryAt: null };
19
+ const limit = this.rateOverrides.get(groupKey) ?? defaults.limit;
20
+ const window = this.currentWindow(groupKey, limit.max, limit.duration, now);
21
+ if (window && window.count >= limit.max) {
22
+ return { eligible: false, retryAt: window.startedAt + window.duration };
23
+ }
24
+ return { eligible: true, retryAt: null };
25
+ }
26
+ acquire(queue, groupId, defaults, active, now = Date.now()) {
27
+ const status = this.status(queue, groupId, defaults, active, now);
28
+ if (!status.eligible)
29
+ return false;
30
+ if (!defaults?.limit)
31
+ return true;
32
+ const groupKey = key(queue, groupId);
33
+ const limit = this.rateOverrides.get(groupKey) ?? defaults.limit;
34
+ let window = this.currentWindow(groupKey, limit.max, limit.duration, now);
35
+ if (!window) {
36
+ window = { max: limit.max, duration: limit.duration, startedAt: now, count: 0 };
37
+ this.windows.set(groupKey, window);
38
+ }
39
+ window.count++;
40
+ return true;
41
+ }
42
+ setRateLimit(queue, groupId, max, duration) {
43
+ assertPositiveSafeInteger(max, 'max');
44
+ assertPositiveSafeInteger(duration, 'duration');
45
+ const groupKey = key(queue, groupId);
46
+ this.rateOverrides.set(groupKey, { max, duration });
47
+ this.windows.delete(groupKey);
48
+ }
49
+ getRateLimit(queue, groupId) {
50
+ return this.rateOverrides.get(key(queue, groupId)) ?? null;
51
+ }
52
+ removeRateLimit(queue, groupId) {
53
+ const groupKey = key(queue, groupId);
54
+ this.windows.delete(groupKey);
55
+ return this.rateOverrides.delete(groupKey) ? 1 : 0;
56
+ }
57
+ getRateLimitTtl(queue, groupId, maxJobs, now = Date.now()) {
58
+ const groupKey = key(queue, groupId);
59
+ const window = this.windows.get(groupKey);
60
+ if (!window)
61
+ return -2;
62
+ if (now >= window.startedAt + window.duration) {
63
+ this.windows.delete(groupKey);
64
+ return -2;
65
+ }
66
+ if (maxJobs !== undefined && window.count < maxJobs)
67
+ return 0;
68
+ return window.startedAt + window.duration - now;
69
+ }
70
+ setConcurrency(queue, groupId, concurrency) {
71
+ assertPositiveSafeInteger(concurrency, 'concurrency');
72
+ this.concurrencyOverrides.set(key(queue, groupId), concurrency);
73
+ }
74
+ getConcurrency(queue, groupId) {
75
+ return this.concurrencyOverrides.get(key(queue, groupId)) ?? null;
76
+ }
77
+ removeConcurrency(queue, groupId) {
78
+ return this.concurrencyOverrides.delete(key(queue, groupId)) ? 1 : 0;
79
+ }
80
+ clearQueue(queue) {
81
+ const prefix = `${queue}\0`;
82
+ for (const map of [this.rateOverrides, this.concurrencyOverrides, this.windows]) {
83
+ for (const groupKey of map.keys()) {
84
+ if (groupKey.startsWith(prefix))
85
+ map.delete(groupKey);
86
+ }
87
+ }
88
+ }
89
+ pruneExpiredWindows(now = Date.now()) {
90
+ for (const [groupKey, window] of this.windows) {
91
+ if (now >= window.startedAt + window.duration)
92
+ this.windows.delete(groupKey);
93
+ }
94
+ }
95
+ currentWindow(groupKey, max, duration, now) {
96
+ const window = this.windows.get(groupKey);
97
+ if (!window)
98
+ return null;
99
+ if (now >= window.startedAt + window.duration ||
100
+ window.max !== max ||
101
+ window.duration !== duration) {
102
+ this.windows.delete(groupKey);
103
+ return null;
104
+ }
105
+ return window;
106
+ }
107
+ }
@@ -0,0 +1,31 @@
1
+ import { type Job } from '../types/job';
2
+ export interface GroupEligibility {
3
+ eligible: boolean;
4
+ retryAt: number | null;
5
+ }
6
+ export interface GroupCandidate {
7
+ job: Job | null;
8
+ nextRunAt: number | null;
9
+ }
10
+ /** Lazy secondary ready/group indexes; the primary queue remains authoritative. */
11
+ export declare class GroupScheduler {
12
+ private readonly queues;
13
+ private nextFifoOrder;
14
+ assignFifoOrder(job: Job): void;
15
+ observeFifoOrder(job: Job): void;
16
+ insert(queue: string, job: Job, primaryJobs: () => readonly Job[], now?: number): boolean;
17
+ remove(queue: string, job: Job): boolean;
18
+ isActive(queue: string): boolean;
19
+ peek(queue: string, now: number, eligibility: (groupId: string) => GroupEligibility): GroupCandidate;
20
+ advance(queue: string, groupId: string): void;
21
+ getGroupJobsCount(queue: string, groupId: string): number;
22
+ getGroupsJobsCount(queue: string): number;
23
+ clearQueue(queue: string): void;
24
+ private createState;
25
+ private insertTracked;
26
+ private promoteDue;
27
+ private insertReady;
28
+ private demoteReady;
29
+ private attachLane;
30
+ private detachLane;
31
+ }