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
@@ -12,7 +12,7 @@ export declare class QueueManagerServices extends QueueManagerObservability {
12
12
  setDashboardEmit(fn: (event: string, data: Record<string, unknown>) => void): void;
13
13
  emitDashboardEvent(event: string, data: Record<string, unknown>): void;
14
14
  subscribe(callback: (event: JobEvent) => void): () => void;
15
- waitForJobCompletion(jobId: JobId, timeoutMs: number): Promise<boolean>;
15
+ waitForJobCompletion(jobId: JobId, timeoutMs: number, signal?: AbortSignal): Promise<boolean>;
16
16
  registerWorker(name: string, queues: string[], concurrency?: number, options?: CreateWorkerOptions): import("../../domain/types/worker").Worker;
17
17
  unregisterWorker(workerId: string): boolean;
18
18
  unregisterWorkersByClientId(clientId: string): number;
@@ -1,7 +1,9 @@
1
+ import { assertValidCronInput } from '../../infrastructure/scheduler/cron/validation';
1
2
  import { shardIndex } from '../../shared/hash';
2
3
  import { QueueManagerObservability } from './observability';
3
4
  export class QueueManagerServices extends QueueManagerObservability {
4
5
  addCron(input) {
6
+ assertValidCronInput(input);
5
7
  if (input.preventOverlap) {
6
8
  this.removeOrphanedCronJob(input.queue, input.uniqueKey ?? `cron:${input.name}`);
7
9
  }
@@ -54,8 +56,8 @@ export class QueueManagerServices extends QueueManagerObservability {
54
56
  subscribe(callback) {
55
57
  return this.eventsManager.subscribe(callback);
56
58
  }
57
- waitForJobCompletion(jobId, timeoutMs) {
58
- return this.eventsManager.waitForJobCompletion(jobId, timeoutMs);
59
+ waitForJobCompletion(jobId, timeoutMs, signal) {
60
+ return this.eventsManager.waitForJobCompletion(jobId, timeoutMs, signal);
59
61
  }
60
62
  registerWorker(name, queues, concurrency, options) {
61
63
  const worker = this.workerManager.register(name, queues, concurrency, options);
@@ -1,6 +1,7 @@
1
1
  import { Shard } from '../../domain/queue/shard';
2
2
  import { SqliteStorage } from '../../infrastructure/persistence/sqlite';
3
3
  import { CronScheduler } from '../../infrastructure/scheduler/cronScheduler';
4
+ import { assertPersistedCronsSupported } from '../../infrastructure/scheduler/cron/persisted';
4
5
  import { RWLock } from '../../shared/lock';
5
6
  import { SHARD_COUNT } from '../../shared/hash';
6
7
  import { BoundedMap, BoundedSet, LRUMap } from '../../shared/lru';
@@ -83,6 +84,20 @@ export class QueueManagerState {
83
84
  constructor(config = {}) {
84
85
  this.config = { ...DEFAULT_CONFIG, ...config };
85
86
  this.storage = config.dataPath ? new SqliteStorage({ path: config.dataPath }) : null;
87
+ let persistedCrons;
88
+ try {
89
+ persistedCrons = this.storage?.loadCronJobs() ?? [];
90
+ assertPersistedCronsSupported(persistedCrons);
91
+ }
92
+ catch (error) {
93
+ try {
94
+ this.storage?.close();
95
+ }
96
+ catch {
97
+ // Preserve the read/validation error that made construction fail.
98
+ }
99
+ throw error;
100
+ }
86
101
  this.telemetryJournal = new QueueTelemetryJournal(this.storage, this.config.maxQueueEvents, this.config.maxMetricDataPoints);
87
102
  this.completedJobsData = new BoundedMap(this.config.maxCompletedJobs);
88
103
  this.completedJobs = new BoundedSet(this.config.maxCompletedJobs, (id) => {
@@ -120,7 +135,7 @@ export class QueueManagerState {
120
135
  this.workerManager = new WorkerManager();
121
136
  this.cronScheduler.setWorkerCheckCallback((queue) => this.workerManager.getForQueue(queue).length > 0);
122
137
  this.eventsManager = new EventsManager(this.webhookManager);
123
- this.eventsManager.subscribe((event) => this.telemetryJournal.record(event));
138
+ this.eventsManager.subscribe((event) => this.telemetryJournal.record(event), (events) => this.telemetryJournal.recordBatch(events));
124
139
  this.contextFactory = new ContextFactory(createContextDependencies(managerRuntime(this)), createContextCallbacks(runtime));
125
140
  bgTasks.recover(this.contextFactory.getBackgroundContext());
126
141
  if (this.storage) {
@@ -138,7 +153,7 @@ export class QueueManagerState {
138
153
  }
139
154
  this.recoveryStats = { queues: this.queueNamesCache.size, jobs: this.jobIndex.size };
140
155
  if (this.storage)
141
- this.cronScheduler.load(this.storage.loadCronJobs());
156
+ this.cronScheduler.load(persistedCrons);
142
157
  this.backgroundTaskHandles = bgTasks.startBackgroundTasks(this.contextFactory.getBackgroundContext(), this.cronScheduler);
143
158
  }
144
159
  }
@@ -10,6 +10,8 @@ export declare class QueueTelemetryJournal {
10
10
  private readonly maxMetricDataPoints;
11
11
  constructor(storage: SqliteStorage | null, maxEvents: number, maxMetricDataPoints: number);
12
12
  record(event: JobEvent): void;
13
+ /** Persist a lifecycle batch atomically, with scalar fallback on write failure. */
14
+ recordBatch(events: readonly JobEvent[]): void;
13
15
  getMetrics(queue: string, type: QueueMetricType, start?: number, end?: number): QueueMetrics;
14
16
  trimEvents(queue: string, maxLength: number): number;
15
17
  clearQueue(queue: string): void;
@@ -55,6 +55,29 @@ export class QueueTelemetryJournal {
55
55
  queueMetrics.set(type, state);
56
56
  this.metrics.set(event.queue, queueMetrics);
57
57
  }
58
+ /** Persist a lifecycle batch atomically, with scalar fallback on write failure. */
59
+ recordBatch(events) {
60
+ if (events.length === 0)
61
+ return;
62
+ if (this.storage) {
63
+ try {
64
+ this.storage.recordQueueEventsBatch(events, this.maxEvents, this.maxMetricDataPoints);
65
+ }
66
+ catch {
67
+ for (const event of events) {
68
+ try {
69
+ this.storage.recordQueueEvent(event, this.maxEvents, this.maxMetricDataPoints);
70
+ }
71
+ catch {
72
+ // Match scalar subscriber isolation and continue with later events.
73
+ }
74
+ }
75
+ }
76
+ return;
77
+ }
78
+ for (const event of events)
79
+ this.record(event);
80
+ }
58
81
  getMetrics(queue, type, start = 0, end = -1) {
59
82
  assertNonNegativeInteger(start, 'start');
60
83
  if (end !== -1)
@@ -2,7 +2,7 @@ import type { Shard } from '../../domain/queue/shard';
2
2
  import type { FlowFailureRecord } from '../../domain/types/flow';
3
3
  import type { FailureReason } from '../../domain/types/dlq';
4
4
  import type { Job, JobId } from '../../domain/types/job';
5
- import type { EventType, JobLocation } from '../../domain/types/queue';
5
+ import type { EventType, JobEvent, JobLocation } from '../../domain/types/queue';
6
6
  import type { SqliteStorage } from '../../infrastructure/persistence/sqlite';
7
7
  import type { RWLock } from '../../shared/lock';
8
8
  import type { MapLike, SetLike } from '../../shared/lru';
@@ -43,6 +43,7 @@ export interface AckContext {
43
43
  prev?: string;
44
44
  terminal?: boolean;
45
45
  }) => void;
46
+ broadcastBatch?: (events: readonly JobEvent[]) => void;
46
47
  onJobCompleted: (jobId: JobId) => void;
47
48
  onJobFailed?: (jobId: JobId) => void;
48
49
  onJobsCompleted?: (jobIds: JobId[]) => void;
@@ -107,6 +108,7 @@ export interface FinalizeContext {
107
108
  timestamp: number;
108
109
  data?: unknown;
109
110
  }) => void;
111
+ broadcastBatch?: (events: readonly JobEvent[]) => void;
110
112
  onJobCompleted: (jobId: JobId) => void;
111
113
  onJobsCompleted?: (jobIds: JobId[]) => void;
112
114
  needsBroadcast?: () => boolean;
@@ -1,3 +1,3 @@
1
- export declare const CLI_NETWORK_COMMANDS: readonly ("push" | "queue" | "cron" | "dlq" | "job" | "fail" | "worker" | "concurrency" | "stats" | "ping" | "metrics" | "pull" | "ack" | "rate-limit" | "health" | "webhook")[];
1
+ export declare const CLI_NETWORK_COMMANDS: readonly ("push" | "queue" | "cron" | "concurrency" | "job" | "dlq" | "fail" | "worker" | "stats" | "ping" | "metrics" | "pull" | "ack" | "rate-limit" | "health" | "webhook")[];
2
2
  /** Build the protocol command for a routed network CLI command. */
3
3
  export declare function buildCommand(command: string, args: string[]): Promise<Record<string, unknown> | null>;
@@ -106,5 +106,5 @@ export async function runServer(args, showHelp) {
106
106
  const mergedConfig = applyCliFlags(fileConfig, flags);
107
107
  const config = resolveServerConfig(mergedConfig);
108
108
  // Same full server as the bare `bunqueue` entry (shared bootstrap)
109
- bootServer(mergedConfig, config);
109
+ await bootServer(mergedConfig, config);
110
110
  }
@@ -4,6 +4,10 @@
4
4
  */
5
5
  import { getSharedManager } from './manager';
6
6
  import { jobId } from '../domain/types/job';
7
+ import { normalizeGroupId } from './groupId';
8
+ function groupId(opts) {
9
+ return opts.group ? normalizeGroupId(opts.group.id) : undefined;
10
+ }
7
11
  /** Parse removeOnComplete/removeOnFail options */
8
12
  function parseRemoveOptions(opts) {
9
13
  return {
@@ -67,6 +71,7 @@ function managerOptions(opts) {
67
71
  removeDependencyOnFailure: opts.removeDependencyOnFailure,
68
72
  ignoreDependencyOnFailure: opts.ignoreDependencyOnFailure,
69
73
  continueParentOnFailure: opts.continueParentOnFailure,
74
+ groupId: groupId(opts),
70
75
  };
71
76
  }
72
77
  /** Full option set for the TCP PUSH command, mirroring buildPushPayload in add.ts (#90). */
@@ -94,6 +99,7 @@ function tcpOptions(opts) {
94
99
  removeDependencyOnFailure: opts.removeDependencyOnFailure,
95
100
  ignoreDependencyOnFailure: opts.ignoreDependencyOnFailure,
96
101
  continueParentOnFailure: opts.continueParentOnFailure,
102
+ groupId: groupId(opts),
97
103
  };
98
104
  }
99
105
  /** Push a job via embedded manager or TCP */
@@ -5,11 +5,13 @@
5
5
  * The edge pattern: jobs buffer in the local queue (typically embedded
6
6
  * SQLite on a gateway); the Forwarder drains them to a central server over
7
7
  * TCP/TLS. A remote failure makes the local job fail → local retry/backoff →
8
- * local DLQ, so nothing is lost while the uplink is down.
8
+ * local DLQ. With a persistent local `dataPath`, queued work survives uplink
9
+ * outages and process restarts; memory-only sources provide no such guarantee.
9
10
  *
10
11
  * Idempotency: every forwarded job carries the deterministic remote jobId
11
- * `fwd:<localQueueKey>:<localJobId>`. The server dedupes custom jobIds, so a
12
- * re-forward after a crash or retry never duplicates the job remotely.
12
+ * `fwd:<localQueueKey>:<localJobId>`. The server dedupes custom jobIds while
13
+ * their ownership is retained; after bounded retention or removal, downstream
14
+ * effects must still tolerate at-least-once delivery.
13
15
  */
14
16
  import { EventEmitter } from 'events';
15
17
  import type { ConnectionOptions, QueueOptions } from './types';
@@ -21,7 +23,7 @@ export interface ForwardOptions {
21
23
  queue?: string;
22
24
  /** Parallel forwards (default: 4) */
23
25
  concurrency?: number;
24
- /** Push to the remote with durable: true (immediate fsync server-side) */
26
+ /** Push with durable: true (bypasses SQLite buffering; PostgreSQL is already transactional). */
25
27
  durable?: boolean;
26
28
  }
27
29
  /** Source queue identity + config, provided by Queue.forward() */
@@ -5,11 +5,13 @@
5
5
  * The edge pattern: jobs buffer in the local queue (typically embedded
6
6
  * SQLite on a gateway); the Forwarder drains them to a central server over
7
7
  * TCP/TLS. A remote failure makes the local job fail → local retry/backoff →
8
- * local DLQ, so nothing is lost while the uplink is down.
8
+ * local DLQ. With a persistent local `dataPath`, queued work survives uplink
9
+ * outages and process restarts; memory-only sources provide no such guarantee.
9
10
  *
10
11
  * Idempotency: every forwarded job carries the deterministic remote jobId
11
- * `fwd:<localQueueKey>:<localJobId>`. The server dedupes custom jobIds, so a
12
- * re-forward after a crash or retry never duplicates the job remotely.
12
+ * `fwd:<localQueueKey>:<localJobId>`. The server dedupes custom jobIds while
13
+ * their ownership is retained; after bounded retention or removal, downstream
14
+ * effects must still tolerate at-least-once delivery.
13
15
  */
14
16
  import { EventEmitter } from 'events';
15
17
  import { Worker } from './worker';
@@ -0,0 +1 @@
1
+ export { normalizeGroupId } from '../domain/types/group';
@@ -0,0 +1 @@
1
+ export { normalizeGroupId } from '../domain/types/group';
@@ -38,7 +38,7 @@ export { shutdownManager } from './manager';
38
38
  export { closeSharedTcpClient } from './tcpClient';
39
39
  export type { ConnectionHealth } from './tcpClient';
40
40
  export { TcpConnectionPool, getSharedPool, closeAllSharedPools } from './tcpPool';
41
- export type { Job, JobOptions, JobJson, JobJsonRaw, QueueOptions, WorkerOptions, Processor, FlowJobData, StallConfig, DlqConfig, DlqEntry, DlqStats, DlqFilter, FailureReason, ConnectionOptions, ParentOpts, RateLimiterOptions, ChangePriorityOpts, GetDependenciesOpts, JobDependencies, JobDependenciesCount, QueueMetrics, QueueMetricsMeta, QueueMetricType, } from './types';
41
+ export type { Job, JobOptions, GroupJobOptions, GroupWorkerOptions, JobJson, JobJsonRaw, QueueOptions, WorkerOptions, Processor, FlowJobData, StallConfig, DlqConfig, DlqEntry, DlqStats, DlqFilter, FailureReason, ConnectionOptions, ParentOpts, RateLimiterOptions, ChangePriorityOpts, GetDependenciesOpts, JobDependencies, JobDependenciesCount, QueueMetrics, QueueMetricsMeta, QueueMetricType, } from './types';
42
42
  export type { FlowStep, FlowResult, FlowJob, JobNode, FlowProducerOptions, FlowOpts } from './flow';
43
43
  export type { RepeatOpts, JobTemplate, SchedulerInfo } from './queue/scheduler';
44
44
  export type { SandboxedWorkerOptions } from './sandboxedWorker';
@@ -97,6 +97,7 @@ export function buildJobOpts(job) {
97
97
  debounce: job.debounceId && job.debounceTtl !== null
98
98
  ? { id: job.debounceId, ttl: job.debounceTtl }
99
99
  : undefined,
100
+ group: job.groupId ? { id: job.groupId } : undefined,
100
101
  };
101
102
  }
102
103
  /** Build parent key from job */
@@ -52,6 +52,8 @@ export declare function purgeDlq(ctx: DlqContext): number;
52
52
  * purge-then-assert-empty patterns need this variant.
53
53
  */
54
54
  export declare function purgeDlqAsync(ctx: DlqContext): Promise<number>;
55
+ /** Remove one DLQ entry without re-enqueuing it. */
56
+ export declare function removeDlqJobAsync(ctx: DlqContext, id: string): Promise<boolean>;
55
57
  /** Retry completed job */
56
58
  export declare function retryCompleted(ctx: DlqContext, id?: string): number;
57
59
  /** Retry completed job (async) */
@@ -197,6 +197,20 @@ export async function purgeDlqAsync(ctx) {
197
197
  return 0;
198
198
  return (response.count ?? 0);
199
199
  }
200
+ /** Remove one DLQ entry without re-enqueuing it. */
201
+ export async function removeDlqJobAsync(ctx, id) {
202
+ if (ctx.embedded)
203
+ return dlqOps.removeDlqJobEmbedded(ctx.name, id);
204
+ if (!ctx.tcp)
205
+ return false;
206
+ const response = await ctx.tcp.send({ cmd: 'RemoveDlqJob', queue: ctx.name, jobId: id });
207
+ if (!response.ok) {
208
+ const error = typeof response.error === 'string' ? response.error : 'Failed to remove the DLQ job';
209
+ throw new Error(error);
210
+ }
211
+ const payload = response;
212
+ return payload.data?.removed === true;
213
+ }
200
214
  /** Retry completed job */
201
215
  export function retryCompleted(ctx, id) {
202
216
  if (ctx.embedded) {
@@ -18,6 +18,8 @@ export declare function retryDlqByFilterEmbedded(queue: string, filter: DlqFilte
18
18
  export declare function retryDlqEmbedded(queue: string, id?: string): number;
19
19
  /** Purge DLQ (embedded) */
20
20
  export declare function purgeDlqEmbedded(queue: string): number;
21
+ /** Remove one DLQ entry in embedded mode. */
22
+ export declare function removeDlqJobEmbedded(queue: string, id: string): boolean;
21
23
  /** Set stall config (embedded only) */
22
24
  export declare function setStallConfigEmbedded(queue: string, config: Record<string, unknown>): void;
23
25
  /** Get stall config (embedded only) */
@@ -50,6 +50,10 @@ export function retryDlqEmbedded(queue, id) {
50
50
  export function purgeDlqEmbedded(queue) {
51
51
  return getSharedManager().purgeDlq(queue);
52
52
  }
53
+ /** Remove one DLQ entry in embedded mode. */
54
+ export function removeDlqJobEmbedded(queue, id) {
55
+ return getSharedManager().removeDlqJob(queue, jobId(id));
56
+ }
53
57
  /** Set stall config (embedded only) */
54
58
  export function setStallConfigEmbedded(queue, config) {
55
59
  const manager = getSharedManager();
@@ -20,6 +20,8 @@ export function getDlqContext(manager) {
20
20
  shards: getShards(manager),
21
21
  jobIndex: manager.getJobIndex(),
22
22
  jobResults: manager.jobResults,
23
+ dependencyResults: manager.dependencyResults,
24
+ customIdMap: manager.customIdMap,
23
25
  jobLogs: manager.jobLogs,
24
26
  // #110-class: without storage, retryDlqByFilter's deleteDlqEntry/insertJob
25
27
  // silently no-op — filtered retries were never persisted in embedded mode
@@ -1,7 +1,7 @@
1
1
  import { getSharedManager } from '../../../manager';
2
2
  import { jobId } from '../../../../domain/types/job';
3
3
  import { createJobProxy, createSimpleJob } from '../../jobProxy';
4
- import { buildJobData, buildRepeatOptions, compact, reflectionMeta } from './payload';
4
+ import { buildJobData, buildRepeatOptions, compact, reflectionMeta, resolveGroupId, } from './payload';
5
5
  export async function addBulk(context, jobs) {
6
6
  if (jobs.length === 0)
7
7
  return [];
@@ -11,7 +11,7 @@ export async function addBulk(context, jobs) {
11
11
  ...opts,
12
12
  }));
13
13
  if (context.embedded) {
14
- const manager = getSharedManager();
14
+ const manager = getSharedManager(context.opts.dataPath);
15
15
  const inputs = jobs.map(({ name, data }, index) => {
16
16
  const options = merged[index];
17
17
  const removeOnComplete = typeof options.removeOnComplete === 'boolean' ? options.removeOnComplete : false;
@@ -30,7 +30,7 @@ export async function addBulk(context, jobs) {
30
30
  dependsOn: options.dependsOn?.map((id) => jobId(id)),
31
31
  parentId: options.parent ? jobId(options.parent.id) : undefined,
32
32
  tags: options.tags,
33
- groupId: options.groupId,
33
+ groupId: resolveGroupId(options),
34
34
  stallTimeout: options.stallTimeout,
35
35
  timestamp: options.timestamp,
36
36
  removeOnComplete,
@@ -84,7 +84,7 @@ export async function addBulk(context, jobs) {
84
84
  ttl: options.ttl,
85
85
  customId: options.jobId,
86
86
  tags: options.tags,
87
- groupId: options.groupId,
87
+ groupId: resolveGroupId(options),
88
88
  dependsOn: options.dependsOn?.map((id) => jobId(id)),
89
89
  parentId: options.parent ? jobId(options.parent.id) : undefined,
90
90
  uniqueKey: options.deduplication?.id,
@@ -16,6 +16,7 @@ export declare function buildRepeatOptions(repeat: NonNullable<JobOptions['repea
16
16
  jobId: string | undefined;
17
17
  };
18
18
  export declare function buildPushPayload(queue: string, name: string, data: unknown, options: ExtendedJobOptions): Record<string, unknown>;
19
+ export declare function resolveGroupId(options: ExtendedJobOptions): string | undefined;
19
20
  export declare function buildJobData(data: unknown, options: ExtendedJobOptions): unknown;
20
21
  export declare function reflectionMeta(options: ExtendedJobOptions): {
21
22
  priority?: number;
@@ -1,3 +1,4 @@
1
+ import { normalizeGroupId } from '../../../groupId';
1
2
  export function compact(object) {
2
3
  const output = {};
3
4
  for (const key in object) {
@@ -51,7 +52,7 @@ export function buildPushPayload(queue, name, data, options) {
51
52
  : undefined,
52
53
  dependsOn: options.dependsOn,
53
54
  tags: options.tags,
54
- groupId: options.groupId,
55
+ groupId: resolveGroupId(options),
55
56
  lifo: options.lifo,
56
57
  removeOnComplete: typeof options.removeOnComplete === 'boolean' ? options.removeOnComplete : undefined,
57
58
  removeOnFail: typeof options.removeOnFail === 'boolean' ? options.removeOnFail : undefined,
@@ -71,6 +72,11 @@ export function buildPushPayload(queue, name, data, options) {
71
72
  parentId: options.parent?.id,
72
73
  });
73
74
  }
75
+ export function resolveGroupId(options) {
76
+ if (options.group)
77
+ return normalizeGroupId(options.group.id);
78
+ return options.groupId === undefined ? undefined : normalizeGroupId(options.groupId);
79
+ }
74
80
  export function buildJobData(data, options) {
75
81
  if (!options.parent)
76
82
  return data;
@@ -3,12 +3,12 @@ import { removeJobDeduplicationKey } from '../../../jobDeduplication';
3
3
  import { toPublicJob } from '../../../types';
4
4
  import { jobId } from '../../../../domain/types/job';
5
5
  import { createJobProxy } from '../../jobProxy';
6
- import { buildJobData, buildPushPayload, buildRepeatOptions } from './payload';
6
+ import { buildJobData, buildPushPayload, buildRepeatOptions, resolveGroupId } from './payload';
7
7
  export async function add(context, jobName, data, options = {}) {
8
8
  const merged = { ...context.opts.defaultJobOptions, ...options };
9
9
  const jobData = buildJobData(data, merged);
10
10
  if (context.embedded) {
11
- const manager = getSharedManager();
11
+ const manager = getSharedManager(context.opts.dataPath);
12
12
  const removeOnComplete = typeof merged.removeOnComplete === 'boolean' ? merged.removeOnComplete : false;
13
13
  const removeOnFail = typeof merged.removeOnFail === 'boolean' ? merged.removeOnFail : false;
14
14
  const repeat = merged.repeat ? buildRepeatOptions(merged.repeat) : undefined;
@@ -25,7 +25,7 @@ export async function add(context, jobName, data, options = {}) {
25
25
  customId: merged.jobId,
26
26
  dependsOn: merged.dependsOn?.map((id) => jobId(id)),
27
27
  tags: merged.tags,
28
- groupId: merged.groupId,
28
+ groupId: resolveGroupId(merged),
29
29
  dedup: merged.deduplication
30
30
  ? {
31
31
  ttl: merged.deduplication.ttl,
@@ -0,0 +1,21 @@
1
+ import type { TcpConnectionPool } from '../../tcpPool';
2
+ interface GroupContext {
3
+ name: string;
4
+ embedded: boolean;
5
+ tcp: TcpConnectionPool | null;
6
+ dataPath: string | undefined;
7
+ }
8
+ export declare function getGroupJobsCount(ctx: GroupContext, groupId: string): Promise<number>;
9
+ export declare function getGroupsJobsCount(ctx: GroupContext, maxCount?: number): Promise<number>;
10
+ export declare function getGroupActiveCount(ctx: GroupContext, groupId: string): Promise<number>;
11
+ export declare function setGroupRateLimit(ctx: GroupContext, groupId: string, max: number, duration: number): Promise<void>;
12
+ export declare function getGroupRateLimit(ctx: GroupContext, groupId: string): Promise<{
13
+ max: number;
14
+ duration: number;
15
+ } | null>;
16
+ export declare function removeGroupRateLimit(ctx: GroupContext, groupId: string): Promise<number>;
17
+ export declare function getGroupRateLimitTtl(ctx: GroupContext, groupId: string, maxJobs?: number): Promise<number>;
18
+ export declare function setGroupConcurrency(ctx: GroupContext, groupId: string, concurrency: number): Promise<void>;
19
+ export declare function getGroupConcurrency(ctx: GroupContext, groupId: string): Promise<number | null>;
20
+ export declare function removeGroupConcurrency(ctx: GroupContext, groupId: string): Promise<number>;
21
+ export {};
@@ -0,0 +1,88 @@
1
+ import { getSharedManager } from '../../manager';
2
+ import { normalizeGroupId } from '../../groupId';
3
+ function manager(ctx) {
4
+ return getSharedManager(ctx.dataPath);
5
+ }
6
+ async function send(ctx, command) {
7
+ if (!ctx.tcp)
8
+ throw new Error('TCP connection is unavailable for group operation');
9
+ const response = await ctx.tcp.send({ ...command, queue: ctx.name });
10
+ if (!response.ok)
11
+ throw new Error(String(response.error ?? 'Group operation failed'));
12
+ const data = typeof response.data === 'object' && response.data !== null
13
+ ? response.data
14
+ : {};
15
+ return { ...response, ...data };
16
+ }
17
+ export async function getGroupJobsCount(ctx, groupId) {
18
+ const id = normalizeGroupId(groupId);
19
+ if (ctx.embedded)
20
+ return await manager(ctx).getGroupJobsCount(ctx.name, id);
21
+ const response = await send(ctx, { cmd: 'GetGroupJobsCount', groupId: id });
22
+ return Number(response.count ?? 0);
23
+ }
24
+ export async function getGroupsJobsCount(ctx, maxCount = 100) {
25
+ if (ctx.embedded)
26
+ return await manager(ctx).getGroupsJobsCount(ctx.name);
27
+ const response = await send(ctx, { cmd: 'GetGroupsJobsCount', maxCount });
28
+ return Number(response.count ?? 0);
29
+ }
30
+ export async function getGroupActiveCount(ctx, groupId) {
31
+ const id = normalizeGroupId(groupId);
32
+ if (ctx.embedded)
33
+ return await manager(ctx).getGroupActiveCount(ctx.name, id);
34
+ const response = await send(ctx, { cmd: 'GetGroupActiveCount', groupId: id });
35
+ return Number(response.count ?? 0);
36
+ }
37
+ export async function setGroupRateLimit(ctx, groupId, max, duration) {
38
+ const id = normalizeGroupId(groupId);
39
+ if (ctx.embedded) {
40
+ await manager(ctx).setGroupRateLimit(ctx.name, id, max, duration);
41
+ return;
42
+ }
43
+ await send(ctx, { cmd: 'SetGroupRateLimit', groupId: id, max, duration });
44
+ }
45
+ export async function getGroupRateLimit(ctx, groupId) {
46
+ const id = normalizeGroupId(groupId);
47
+ if (ctx.embedded)
48
+ return await manager(ctx).getGroupRateLimit(ctx.name, id);
49
+ const response = await send(ctx, { cmd: 'GetGroupRateLimit', groupId: id });
50
+ return response.limit ?? null;
51
+ }
52
+ export async function removeGroupRateLimit(ctx, groupId) {
53
+ const id = normalizeGroupId(groupId);
54
+ if (ctx.embedded)
55
+ return await manager(ctx).removeGroupRateLimit(ctx.name, id);
56
+ const response = await send(ctx, { cmd: 'RemoveGroupRateLimit', groupId: id });
57
+ return Number(response.removed ?? 0);
58
+ }
59
+ export async function getGroupRateLimitTtl(ctx, groupId, maxJobs) {
60
+ const id = normalizeGroupId(groupId);
61
+ if (ctx.embedded) {
62
+ return await manager(ctx).getGroupRateLimitTtl(ctx.name, id, maxJobs);
63
+ }
64
+ const response = await send(ctx, { cmd: 'GetGroupRateLimitTtl', groupId: id, maxJobs });
65
+ return Number(response.ttl ?? -2);
66
+ }
67
+ export async function setGroupConcurrency(ctx, groupId, concurrency) {
68
+ const id = normalizeGroupId(groupId);
69
+ if (ctx.embedded) {
70
+ await manager(ctx).setGroupConcurrency(ctx.name, id, concurrency);
71
+ return;
72
+ }
73
+ await send(ctx, { cmd: 'SetGroupConcurrency', groupId: id, concurrency });
74
+ }
75
+ export async function getGroupConcurrency(ctx, groupId) {
76
+ const id = normalizeGroupId(groupId);
77
+ if (ctx.embedded)
78
+ return await manager(ctx).getGroupConcurrency(ctx.name, id);
79
+ const response = await send(ctx, { cmd: 'GetGroupConcurrency', groupId: id });
80
+ return typeof response.concurrency === 'number' ? response.concurrency : null;
81
+ }
82
+ export async function removeGroupConcurrency(ctx, groupId) {
83
+ const id = normalizeGroupId(groupId);
84
+ if (ctx.embedded)
85
+ return await manager(ctx).removeGroupConcurrency(ctx.name, id);
86
+ const response = await send(ctx, { cmd: 'RemoveGroupConcurrency', groupId: id });
87
+ return Number(response.removed ?? 0);
88
+ }
@@ -21,6 +21,10 @@ export declare class QueueConfiguration<T> extends QueueControl<T> {
21
21
  retryDlqByFilterAsync(filter: DlqFilter): Promise<number>;
22
22
  purgeDlq(): number;
23
23
  purgeDlqAsync(): Promise<number>;
24
+ /** Remove one DLQ entry and resolve when the removal completes. */
25
+ removeDlqJob(id: string): Promise<boolean>;
26
+ /** Explicit async alias for removeDlqJob. */
27
+ removeDlqJobAsync(id: string): Promise<boolean>;
24
28
  retryCompleted(id?: string): number;
25
29
  retryCompletedAsync(id?: string): Promise<number>;
26
30
  setGlobalConcurrency(concurrency: number): void;
@@ -61,6 +61,14 @@ export class QueueConfiguration extends QueueControl {
61
61
  purgeDlqAsync() {
62
62
  return dlqOps.purgeDlqAsync(this.ctx);
63
63
  }
64
+ /** Remove one DLQ entry and resolve when the removal completes. */
65
+ removeDlqJob(id) {
66
+ return dlqOps.removeDlqJobAsync(this.ctx, id);
67
+ }
68
+ /** Explicit async alias for removeDlqJob. */
69
+ removeDlqJobAsync(id) {
70
+ return this.removeDlqJob(id);
71
+ }
64
72
  retryCompleted(id) {
65
73
  return dlqOps.retryCompleted(this.ctx, id);
66
74
  }
@@ -3,6 +3,19 @@ import * as countsOps from '../operations/counts';
3
3
  import { QueueState } from './state';
4
4
  /** Job creation, lookup, state-listing, and count operations. */
5
5
  export declare class QueueQueries<T> extends QueueState<T> {
6
+ getGroupJobsCount(groupId: string): Promise<number>;
7
+ getGroupsJobsCount(maxCount?: number): Promise<number>;
8
+ getGroupActiveCount(groupId: string): Promise<number>;
9
+ setGroupRateLimit(groupId: string, max: number, duration: number): Promise<void>;
10
+ getGroupRateLimit(groupId: string): Promise<{
11
+ max: number;
12
+ duration: number;
13
+ } | null>;
14
+ removeGroupRateLimit(groupId: string): Promise<number>;
15
+ getGroupRateLimitTtl(groupId: string, maxJobs?: number): Promise<number>;
16
+ setGroupConcurrency(groupId: string, concurrency: number): Promise<void>;
17
+ getGroupConcurrency(groupId: string): Promise<number | null>;
18
+ removeGroupConcurrency(groupId: string): Promise<number>;
6
19
  add(name: string, data: T, opts?: JobOptions): Promise<Job<T>>;
7
20
  addBulk(jobs: Array<{
8
21
  name: string;
@@ -2,9 +2,40 @@ import * as countsOps from '../operations/counts';
2
2
  import * as addOps from '../operations/add';
3
3
  import * as queryOps from '../operations/query';
4
4
  import * as queryStateOps from '../operations/queryStates';
5
+ import * as groupOps from '../operations/groups';
5
6
  import { QueueState } from './state';
6
7
  /** Job creation, lookup, state-listing, and count operations. */
7
8
  export class QueueQueries extends QueueState {
9
+ getGroupJobsCount(groupId) {
10
+ return groupOps.getGroupJobsCount(this.ctx, groupId);
11
+ }
12
+ getGroupsJobsCount(maxCount) {
13
+ return groupOps.getGroupsJobsCount(this.ctx, maxCount);
14
+ }
15
+ getGroupActiveCount(groupId) {
16
+ return groupOps.getGroupActiveCount(this.ctx, groupId);
17
+ }
18
+ setGroupRateLimit(groupId, max, duration) {
19
+ return groupOps.setGroupRateLimit(this.ctx, groupId, max, duration);
20
+ }
21
+ getGroupRateLimit(groupId) {
22
+ return groupOps.getGroupRateLimit(this.ctx, groupId);
23
+ }
24
+ removeGroupRateLimit(groupId) {
25
+ return groupOps.removeGroupRateLimit(this.ctx, groupId);
26
+ }
27
+ getGroupRateLimitTtl(groupId, maxJobs) {
28
+ return groupOps.getGroupRateLimitTtl(this.ctx, groupId, maxJobs);
29
+ }
30
+ setGroupConcurrency(groupId, concurrency) {
31
+ return groupOps.setGroupConcurrency(this.ctx, groupId, concurrency);
32
+ }
33
+ getGroupConcurrency(groupId) {
34
+ return groupOps.getGroupConcurrency(this.ctx, groupId);
35
+ }
36
+ removeGroupConcurrency(groupId) {
37
+ return groupOps.removeGroupConcurrency(this.ctx, groupId);
38
+ }
8
39
  add(name, data, opts) {
9
40
  if (this.addBatcher && !opts?.durable) {
10
41
  return this.addBatcher.enqueue(name, data, opts);