@shivaedev/jobs 0.30.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (447) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +88 -24
  3. package/dist/display.d.ts +14 -0
  4. package/dist/display.d.ts.map +1 -0
  5. package/dist/display.js +2 -0
  6. package/dist/display.js.map +1 -0
  7. package/dist/server/ClientDatabase.d.ts +21 -0
  8. package/dist/server/ClientDatabase.d.ts.map +1 -0
  9. package/dist/server/ClientDatabase.js +2 -0
  10. package/dist/server/ClientDatabase.js.map +1 -0
  11. package/dist/server/PgBoss.d.ts +2 -2
  12. package/dist/server/PgBoss.d.ts.map +1 -1
  13. package/dist/server/adapters/batchClockOffset.d.ts +2 -2
  14. package/dist/server/adapters/batchClockOffset.d.ts.map +1 -1
  15. package/dist/server/adapters/batchClockOffset.js +5 -4
  16. package/dist/server/adapters/batchClockOffset.js.map +1 -1
  17. package/dist/server/adapters/batchHandler.d.ts +5 -0
  18. package/dist/server/adapters/batchHandler.d.ts.map +1 -0
  19. package/dist/server/{internal → adapters}/batchHandler.js +6 -6
  20. package/dist/server/adapters/batchHandler.js.map +1 -0
  21. package/dist/server/adapters/clientCache.d.ts +10 -0
  22. package/dist/server/adapters/clientCache.d.ts.map +1 -0
  23. package/dist/server/{internal → adapters}/clientCache.js +5 -19
  24. package/dist/server/adapters/clientCache.js.map +1 -0
  25. package/dist/server/adapters/clientErrorLogger.js +1 -1
  26. package/dist/server/adapters/clientErrorLogger.js.map +1 -1
  27. package/dist/server/adapters/defaultClientFactory.d.ts +4 -0
  28. package/dist/server/adapters/defaultClientFactory.d.ts.map +1 -0
  29. package/dist/server/adapters/defaultClientFactory.js.map +1 -0
  30. package/dist/server/adapters/deferralCount.d.ts +3 -3
  31. package/dist/server/adapters/deferralCount.d.ts.map +1 -1
  32. package/dist/server/adapters/deferralCount.js +2 -2
  33. package/dist/server/adapters/deferralCount.js.map +1 -1
  34. package/dist/server/adapters/expireAttempt.d.ts +4 -0
  35. package/dist/server/adapters/expireAttempt.d.ts.map +1 -0
  36. package/dist/server/{internal → adapters}/expireAttempt.js +1 -1
  37. package/dist/server/{internal → adapters}/expireAttempt.js.map +1 -1
  38. package/dist/server/adapters/inspection.d.ts +5 -0
  39. package/dist/server/adapters/inspection.d.ts.map +1 -0
  40. package/dist/server/adapters/inspection.js +25 -0
  41. package/dist/server/adapters/inspection.js.map +1 -0
  42. package/dist/server/adapters/inspectionChanges.d.ts +7 -0
  43. package/dist/server/adapters/inspectionChanges.d.ts.map +1 -0
  44. package/dist/server/adapters/inspectionChanges.js +23 -0
  45. package/dist/server/adapters/inspectionChanges.js.map +1 -0
  46. package/dist/server/adapters/inspectionDeferrals.d.ts +10 -0
  47. package/dist/server/adapters/inspectionDeferrals.d.ts.map +1 -0
  48. package/dist/server/adapters/inspectionDeferrals.js +13 -0
  49. package/dist/server/adapters/inspectionDeferrals.js.map +1 -0
  50. package/dist/server/adapters/inspectionJobs.d.ts +50 -0
  51. package/dist/server/adapters/inspectionJobs.d.ts.map +1 -0
  52. package/dist/server/adapters/inspectionJobs.js +21 -0
  53. package/dist/server/adapters/inspectionJobs.js.map +1 -0
  54. package/dist/server/adapters/inspectionOperation.d.ts +3 -0
  55. package/dist/server/adapters/inspectionOperation.d.ts.map +1 -0
  56. package/dist/server/adapters/inspectionOperation.js +6 -0
  57. package/dist/server/adapters/inspectionOperation.js.map +1 -0
  58. package/dist/server/adapters/inspectionPlan.d.ts +3 -0
  59. package/dist/server/adapters/inspectionPlan.d.ts.map +1 -0
  60. package/dist/server/adapters/inspectionPlan.js +20 -0
  61. package/dist/server/adapters/inspectionPlan.js.map +1 -0
  62. package/dist/server/adapters/inspectionReads.d.ts +59 -0
  63. package/dist/server/adapters/inspectionReads.d.ts.map +1 -0
  64. package/dist/server/adapters/inspectionReads.js +44 -0
  65. package/dist/server/adapters/inspectionReads.js.map +1 -0
  66. package/dist/server/adapters/inspectionSnapshot.d.ts +6 -0
  67. package/dist/server/adapters/inspectionSnapshot.d.ts.map +1 -0
  68. package/dist/server/{internal/testingSnapshot.js → adapters/inspectionSnapshot.js} +10 -8
  69. package/dist/server/adapters/inspectionSnapshot.js.map +1 -0
  70. package/dist/server/adapters/installSchema.d.ts +1 -1
  71. package/dist/server/adapters/installSchema.d.ts.map +1 -1
  72. package/dist/server/adapters/installSchema.js +1 -1
  73. package/dist/server/adapters/installSchema.js.map +1 -1
  74. package/dist/server/adapters/jobEngine.d.ts +5 -0
  75. package/dist/server/adapters/jobEngine.d.ts.map +1 -0
  76. package/dist/server/adapters/jobEngine.js +46 -0
  77. package/dist/server/adapters/jobEngine.js.map +1 -0
  78. package/dist/server/adapters/lifecycle.d.ts +11 -0
  79. package/dist/server/adapters/lifecycle.d.ts.map +1 -0
  80. package/dist/server/adapters/lifecycle.js +48 -0
  81. package/dist/server/adapters/lifecycle.js.map +1 -0
  82. package/dist/server/adapters/listJobs.d.ts +5 -0
  83. package/dist/server/adapters/listJobs.d.ts.map +1 -0
  84. package/dist/server/adapters/listJobs.js +37 -0
  85. package/dist/server/adapters/listJobs.js.map +1 -0
  86. package/dist/server/adapters/payloadIdentity.d.ts +3 -0
  87. package/dist/server/adapters/payloadIdentity.d.ts.map +1 -0
  88. package/dist/server/adapters/payloadIdentity.js +14 -0
  89. package/dist/server/adapters/payloadIdentity.js.map +1 -0
  90. package/dist/server/adapters/queueAdministration.d.ts +4 -0
  91. package/dist/server/adapters/queueAdministration.d.ts.map +1 -0
  92. package/dist/server/adapters/queueAdministration.js +42 -0
  93. package/dist/server/adapters/queueAdministration.js.map +1 -0
  94. package/dist/server/{internal/testingSignal.d.ts → adapters/queueSignal.d.ts} +2 -2
  95. package/dist/server/adapters/queueSignal.d.ts.map +1 -0
  96. package/dist/server/{internal/testingSignal.js → adapters/queueSignal.js} +2 -2
  97. package/dist/server/adapters/queueSignal.js.map +1 -0
  98. package/dist/server/adapters/registerWorker.d.ts +5 -3
  99. package/dist/server/adapters/registerWorker.d.ts.map +1 -1
  100. package/dist/server/adapters/registerWorker.js +9 -6
  101. package/dist/server/adapters/registerWorker.js.map +1 -1
  102. package/dist/server/adapters/retireJobs.d.ts +3 -3
  103. package/dist/server/adapters/retireJobs.d.ts.map +1 -1
  104. package/dist/server/adapters/retireJobs.js +3 -3
  105. package/dist/server/adapters/retireJobs.js.map +1 -1
  106. package/dist/server/adapters/schemaIndexBuilds.d.ts +2 -2
  107. package/dist/server/adapters/schemaIndexBuilds.d.ts.map +1 -1
  108. package/dist/server/adapters/schemaIndexBuilds.js.map +1 -1
  109. package/dist/server/adapters/settleDeferral.d.ts +7 -0
  110. package/dist/server/adapters/settleDeferral.d.ts.map +1 -0
  111. package/dist/server/{internal → adapters}/settleDeferral.js +2 -2
  112. package/dist/server/adapters/settleDeferral.js.map +1 -0
  113. package/dist/server/adapters/testingClient.d.ts +13 -0
  114. package/dist/server/adapters/testingClient.d.ts.map +1 -0
  115. package/dist/server/{internal → adapters}/testingClient.js +27 -48
  116. package/dist/server/adapters/testingClient.js.map +1 -0
  117. package/dist/server/adapters/testingController.d.ts +79 -0
  118. package/dist/server/adapters/testingController.d.ts.map +1 -0
  119. package/dist/server/adapters/testingController.js +108 -0
  120. package/dist/server/adapters/testingController.js.map +1 -0
  121. package/dist/server/adapters/testingDueNow.d.ts +3 -3
  122. package/dist/server/adapters/testingDueNow.d.ts.map +1 -1
  123. package/dist/server/adapters/testingDueNow.js +2 -2
  124. package/dist/server/adapters/testingDueNow.js.map +1 -1
  125. package/dist/server/adapters/testingEngine.d.ts +5 -0
  126. package/dist/server/adapters/testingEngine.d.ts.map +1 -0
  127. package/dist/server/adapters/testingEngine.js +12 -0
  128. package/dist/server/adapters/testingEngine.js.map +1 -0
  129. package/dist/server/adapters/testingExpirations.d.ts +6 -4
  130. package/dist/server/adapters/testingExpirations.d.ts.map +1 -1
  131. package/dist/server/adapters/testingExpirations.js.map +1 -1
  132. package/dist/server/adapters/testingInspectionClient.d.ts +5 -0
  133. package/dist/server/adapters/testingInspectionClient.d.ts.map +1 -0
  134. package/dist/server/adapters/testingInspectionClient.js +52 -0
  135. package/dist/server/adapters/testingInspectionClient.js.map +1 -0
  136. package/dist/server/adapters/transactionDb.d.ts +2 -2
  137. package/dist/server/adapters/transactionDb.d.ts.map +1 -1
  138. package/dist/server/adapters/transactionDb.js.map +1 -1
  139. package/dist/server/client.d.ts +95 -18
  140. package/dist/server/client.d.ts.map +1 -1
  141. package/dist/server/clientOptions.d.ts +74 -0
  142. package/dist/server/clientOptions.d.ts.map +1 -0
  143. package/dist/server/clientOptions.js +2 -0
  144. package/dist/server/clientOptions.js.map +1 -0
  145. package/dist/server/defineSchedule.d.ts +1 -1
  146. package/dist/server/defineSchedule.d.ts.map +1 -1
  147. package/dist/server/defineSchedule.js +2 -1
  148. package/dist/server/defineSchedule.js.map +1 -1
  149. package/dist/server/definition.d.ts +29 -26
  150. package/dist/server/definition.d.ts.map +1 -1
  151. package/dist/server/definition.js +5 -2
  152. package/dist/server/definition.js.map +1 -1
  153. package/dist/server/engineClient.d.ts +21 -0
  154. package/dist/server/engineClient.d.ts.map +1 -0
  155. package/dist/server/engineClient.js +2 -0
  156. package/dist/server/engineClient.js.map +1 -0
  157. package/dist/server/enqueueOptions.d.ts +28 -0
  158. package/dist/server/enqueueOptions.d.ts.map +1 -0
  159. package/dist/server/enqueueOptions.js +2 -0
  160. package/dist/server/enqueueOptions.js.map +1 -0
  161. package/dist/server/error.d.ts +11 -1
  162. package/dist/server/error.d.ts.map +1 -1
  163. package/dist/server/error.js +8 -1
  164. package/dist/server/error.js.map +1 -1
  165. package/dist/server/health.d.ts +2 -2
  166. package/dist/server/health.d.ts.map +1 -1
  167. package/dist/server/inspection.d.ts +102 -0
  168. package/dist/server/inspection.d.ts.map +1 -0
  169. package/dist/server/inspection.js +30 -0
  170. package/dist/server/inspection.js.map +1 -0
  171. package/dist/server/internal/acquireClient.d.ts +11 -0
  172. package/dist/server/internal/acquireClient.d.ts.map +1 -0
  173. package/dist/server/internal/acquireClient.js +21 -0
  174. package/dist/server/internal/acquireClient.js.map +1 -0
  175. package/dist/server/internal/adapters/testingFetches.d.ts +2 -2
  176. package/dist/server/internal/adapters/testingFetches.d.ts.map +1 -1
  177. package/dist/server/internal/adapters/testingFetches.js.map +1 -1
  178. package/dist/server/internal/clientErrors.d.ts +1 -1
  179. package/dist/server/internal/clientErrors.d.ts.map +1 -1
  180. package/dist/server/internal/countsFor.d.ts +3 -3
  181. package/dist/server/internal/countsFor.d.ts.map +1 -1
  182. package/dist/server/internal/countsFor.js +2 -2
  183. package/dist/server/internal/countsFor.js.map +1 -1
  184. package/dist/server/internal/deadLetterResolutionPlan.js +1 -1
  185. package/dist/server/internal/deadLetterResolutionPlan.js.map +1 -1
  186. package/dist/server/internal/deadlineOf.d.ts +2 -2
  187. package/dist/server/internal/deadlineOf.d.ts.map +1 -1
  188. package/dist/server/internal/deadlineOf.js.map +1 -1
  189. package/dist/server/internal/deferrableAttempt.d.ts +4 -5
  190. package/dist/server/internal/deferrableAttempt.d.ts.map +1 -1
  191. package/dist/server/internal/deferrableAttempt.js +5 -14
  192. package/dist/server/internal/deferrableAttempt.js.map +1 -1
  193. package/dist/server/internal/deferral.d.ts +2 -4
  194. package/dist/server/internal/deferral.d.ts.map +1 -1
  195. package/dist/server/internal/deferral.js +0 -1
  196. package/dist/server/internal/deferral.js.map +1 -1
  197. package/dist/server/internal/deferralStorePlan.js +2 -2
  198. package/dist/server/internal/deferralStorePlan.js.map +1 -1
  199. package/dist/server/internal/definitionOptions.d.ts +7 -7
  200. package/dist/server/internal/definitionOptions.d.ts.map +1 -1
  201. package/dist/server/internal/engine.d.ts +25 -0
  202. package/dist/server/internal/engine.d.ts.map +1 -0
  203. package/dist/server/internal/engine.js +6 -0
  204. package/dist/server/internal/engine.js.map +1 -0
  205. package/dist/server/internal/enqueueFor.d.ts +2 -2
  206. package/dist/server/internal/enqueueFor.d.ts.map +1 -1
  207. package/dist/server/internal/enqueueFor.js +14 -4
  208. package/dist/server/internal/enqueueFor.js.map +1 -1
  209. package/dist/server/internal/ensureQueue.d.ts +2 -3
  210. package/dist/server/internal/ensureQueue.d.ts.map +1 -1
  211. package/dist/server/internal/ensureQueue.js +2 -2
  212. package/dist/server/internal/ensureQueue.js.map +1 -1
  213. package/dist/server/internal/healthFor.d.ts +3 -3
  214. package/dist/server/internal/healthFor.d.ts.map +1 -1
  215. package/dist/server/internal/healthFor.js +2 -2
  216. package/dist/server/internal/healthFor.js.map +1 -1
  217. package/dist/server/internal/jobControl.d.ts +9 -4
  218. package/dist/server/internal/jobControl.d.ts.map +1 -1
  219. package/dist/server/internal/jobControl.js +13 -40
  220. package/dist/server/internal/jobControl.js.map +1 -1
  221. package/dist/server/internal/jobListings.d.ts +16 -0
  222. package/dist/server/internal/jobListings.d.ts.map +1 -0
  223. package/dist/server/internal/jobListings.js +52 -0
  224. package/dist/server/internal/jobListings.js.map +1 -0
  225. package/dist/server/internal/jobStorePlans.d.ts.map +1 -1
  226. package/dist/server/internal/jobStorePlans.js +4 -3
  227. package/dist/server/internal/jobStorePlans.js.map +1 -1
  228. package/dist/server/internal/lifecycle.d.ts +11 -7
  229. package/dist/server/internal/lifecycle.d.ts.map +1 -1
  230. package/dist/server/internal/lifecycle.js +2 -49
  231. package/dist/server/internal/lifecycle.js.map +1 -1
  232. package/dist/server/internal/makeService.d.ts +5 -3
  233. package/dist/server/internal/makeService.d.ts.map +1 -1
  234. package/dist/server/internal/makeService.js +18 -13
  235. package/dist/server/internal/makeService.js.map +1 -1
  236. package/dist/server/internal/register.d.ts +5 -5
  237. package/dist/server/internal/register.d.ts.map +1 -1
  238. package/dist/server/internal/register.js +5 -9
  239. package/dist/server/internal/register.js.map +1 -1
  240. package/dist/server/internal/registerReleasedJobs.d.ts +4 -4
  241. package/dist/server/internal/registerReleasedJobs.d.ts.map +1 -1
  242. package/dist/server/internal/registerReleasedJobs.js +2 -2
  243. package/dist/server/internal/registerReleasedJobs.js.map +1 -1
  244. package/dist/server/internal/retryWake.d.ts +1 -1
  245. package/dist/server/internal/retryWake.d.ts.map +1 -1
  246. package/dist/server/internal/retryWake.js +2 -2
  247. package/dist/server/internal/retryWake.js.map +1 -1
  248. package/dist/server/internal/runQueueWorker.d.ts +4 -4
  249. package/dist/server/internal/runQueueWorker.d.ts.map +1 -1
  250. package/dist/server/internal/runQueueWorker.js +5 -5
  251. package/dist/server/internal/runQueueWorker.js.map +1 -1
  252. package/dist/server/internal/storedRows.d.ts +2 -2
  253. package/dist/server/internal/storedRows.d.ts.map +1 -1
  254. package/dist/server/internal/storedRows.js +2 -2
  255. package/dist/server/internal/storedRows.js.map +1 -1
  256. package/dist/server/internal/testingIdle.d.ts +4 -3
  257. package/dist/server/internal/testingIdle.d.ts.map +1 -1
  258. package/dist/server/internal/testingIdle.js +5 -25
  259. package/dist/server/internal/testingIdle.js.map +1 -1
  260. package/dist/server/internal/testingOperation.d.ts +5 -0
  261. package/dist/server/internal/testingOperation.d.ts.map +1 -0
  262. package/dist/server/internal/testingOperation.js +12 -0
  263. package/dist/server/internal/testingOperation.js.map +1 -0
  264. package/dist/server/internal/testingSchedules.d.ts +9 -6
  265. package/dist/server/internal/testingSchedules.d.ts.map +1 -1
  266. package/dist/server/internal/testingSchedules.js +14 -9
  267. package/dist/server/internal/testingSchedules.js.map +1 -1
  268. package/dist/server/internal/testingWaits.d.ts +12 -8
  269. package/dist/server/internal/testingWaits.d.ts.map +1 -1
  270. package/dist/server/internal/testingWaits.js +6 -7
  271. package/dist/server/internal/testingWaits.js.map +1 -1
  272. package/dist/server/internal/tracing.d.ts +2 -2
  273. package/dist/server/internal/tracing.d.ts.map +1 -1
  274. package/dist/server/internal/tracing.js.map +1 -1
  275. package/dist/server/internal/validateQueueNames.d.ts +2 -2
  276. package/dist/server/internal/validateQueueNames.d.ts.map +1 -1
  277. package/dist/server/internal/validateQueueNames.js +1 -1
  278. package/dist/server/internal/validateQueueNames.js.map +1 -1
  279. package/dist/server/internal/waitForBatchExpiry.d.ts +4 -4
  280. package/dist/server/internal/waitForBatchExpiry.d.ts.map +1 -1
  281. package/dist/server/internal/waitForBatchExpiry.js +1 -1
  282. package/dist/server/internal/waitForBatchExpiry.js.map +1 -1
  283. package/dist/server/job.d.ts +42 -0
  284. package/dist/server/job.d.ts.map +1 -0
  285. package/dist/server/job.js +2 -0
  286. package/dist/server/job.js.map +1 -0
  287. package/dist/server/jobModule.d.ts +6 -4
  288. package/dist/server/jobModule.d.ts.map +1 -1
  289. package/dist/server/jobModule.js +7 -5
  290. package/dist/server/jobModule.js.map +1 -1
  291. package/dist/server/queueOptions.d.ts +19 -0
  292. package/dist/server/queueOptions.d.ts.map +1 -0
  293. package/dist/server/queueOptions.js +2 -0
  294. package/dist/server/queueOptions.js.map +1 -0
  295. package/dist/server/readJobFailure.d.ts +5 -0
  296. package/dist/server/readJobFailure.d.ts.map +1 -0
  297. package/dist/server/readJobFailure.js +8 -0
  298. package/dist/server/readJobFailure.js.map +1 -0
  299. package/dist/server/schema.d.ts +1 -1
  300. package/dist/server/schema.d.ts.map +1 -1
  301. package/dist/server/schema.js +23 -7
  302. package/dist/server/schema.js.map +1 -1
  303. package/dist/server/service.d.ts +17 -12
  304. package/dist/server/service.d.ts.map +1 -1
  305. package/dist/server/service.js +19 -27
  306. package/dist/server/service.js.map +1 -1
  307. package/dist/server/testing.d.ts +63 -67
  308. package/dist/server/testing.d.ts.map +1 -1
  309. package/dist/server/testing.js +5 -97
  310. package/dist/server/testing.js.map +1 -1
  311. package/dist/server/workerOptions.d.ts +25 -0
  312. package/dist/server/workerOptions.d.ts.map +1 -0
  313. package/dist/server/workerOptions.js +2 -0
  314. package/dist/server/workerOptions.js.map +1 -0
  315. package/package.json +11 -16
  316. package/src/display.ts +12 -0
  317. package/src/server/ClientDatabase.ts +7 -0
  318. package/src/server/PgBoss.ts +2 -2
  319. package/src/server/adapters/batchClockOffset.ts +8 -5
  320. package/src/server/{internal → adapters}/batchHandler.ts +13 -13
  321. package/src/server/{internal → adapters}/clientCache.ts +10 -22
  322. package/src/server/adapters/clientErrorLogger.ts +1 -1
  323. package/src/server/{defaultClientFactory.ts → adapters/defaultClientFactory.ts} +4 -2
  324. package/src/server/adapters/deferralCount.ts +5 -5
  325. package/src/server/{internal → adapters}/expireAttempt.ts +4 -3
  326. package/src/server/adapters/inspection.ts +31 -0
  327. package/src/server/adapters/inspectionChanges.ts +31 -0
  328. package/src/server/adapters/inspectionDeferrals.ts +20 -0
  329. package/src/server/adapters/inspectionJobs.ts +28 -0
  330. package/src/server/adapters/inspectionOperation.ts +6 -0
  331. package/src/server/adapters/inspectionPlan.ts +21 -0
  332. package/src/server/adapters/inspectionReads.ts +55 -0
  333. package/src/server/{internal/testingSnapshot.ts → adapters/inspectionSnapshot.ts} +16 -18
  334. package/src/server/adapters/installSchema.ts +2 -2
  335. package/src/server/adapters/jobEngine.ts +55 -0
  336. package/src/server/adapters/lifecycle.ts +67 -0
  337. package/src/server/adapters/listJobs.ts +43 -0
  338. package/src/server/adapters/payloadIdentity.ts +15 -0
  339. package/src/server/adapters/queueAdministration.ts +47 -0
  340. package/src/server/{internal/testingSignal.ts → adapters/queueSignal.ts} +1 -1
  341. package/src/server/adapters/registerWorker.ts +17 -12
  342. package/src/server/adapters/retireJobs.ts +5 -5
  343. package/src/server/adapters/schemaIndexBuilds.ts +2 -2
  344. package/src/server/{internal → adapters}/settleDeferral.ts +5 -5
  345. package/src/server/{internal → adapters}/testingClient.ts +24 -40
  346. package/src/server/adapters/testingController.ts +125 -0
  347. package/src/server/adapters/testingDueNow.ts +5 -5
  348. package/src/server/adapters/testingEngine.ts +15 -0
  349. package/src/server/adapters/testingExpirations.ts +6 -4
  350. package/src/server/adapters/testingInspectionClient.ts +70 -0
  351. package/src/server/adapters/transactionDb.ts +2 -2
  352. package/src/server/client.ts +86 -30
  353. package/src/server/clientOptions.ts +80 -0
  354. package/src/server/defineSchedule.ts +3 -2
  355. package/src/server/definition.ts +38 -29
  356. package/src/server/engineClient.ts +22 -0
  357. package/src/server/enqueueOptions.ts +25 -0
  358. package/src/server/error.ts +18 -2
  359. package/src/server/health.ts +2 -2
  360. package/src/server/inspection.ts +50 -0
  361. package/src/server/internal/acquireClient.ts +26 -0
  362. package/src/server/internal/adapters/testingFetches.ts +2 -2
  363. package/src/server/internal/clientErrors.ts +1 -1
  364. package/src/server/internal/countsFor.ts +5 -5
  365. package/src/server/internal/deadLetterResolutionPlan.ts +1 -1
  366. package/src/server/internal/deadlineOf.ts +2 -2
  367. package/src/server/internal/deferrableAttempt.ts +5 -22
  368. package/src/server/internal/deferral.ts +2 -4
  369. package/src/server/internal/deferralStorePlan.ts +2 -2
  370. package/src/server/internal/definitionOptions.ts +1 -1
  371. package/src/server/internal/engine.ts +35 -0
  372. package/src/server/internal/enqueueFor.ts +19 -6
  373. package/src/server/internal/ensureQueue.ts +5 -6
  374. package/src/server/internal/healthFor.ts +4 -4
  375. package/src/server/internal/jobControl.ts +15 -50
  376. package/src/server/internal/jobListings.ts +85 -0
  377. package/src/server/internal/jobStorePlans.ts +4 -3
  378. package/src/server/internal/lifecycle.ts +14 -55
  379. package/src/server/internal/makeService.ts +24 -15
  380. package/src/server/internal/register.ts +8 -12
  381. package/src/server/internal/registerReleasedJobs.ts +5 -5
  382. package/src/server/internal/retryWake.ts +3 -3
  383. package/src/server/internal/runQueueWorker.ts +8 -8
  384. package/src/server/internal/storedRows.ts +3 -3
  385. package/src/server/internal/testingIdle.ts +8 -31
  386. package/src/server/internal/testingOperation.ts +18 -0
  387. package/src/server/internal/testingSchedules.ts +29 -17
  388. package/src/server/internal/testingWaits.ts +16 -16
  389. package/src/server/internal/tracing.ts +2 -2
  390. package/src/server/internal/validateQueueNames.ts +2 -2
  391. package/src/server/internal/waitForBatchExpiry.ts +4 -4
  392. package/src/server/job.ts +42 -0
  393. package/src/server/jobModule.ts +19 -7
  394. package/src/server/queueOptions.ts +20 -0
  395. package/src/server/readJobFailure.ts +12 -0
  396. package/src/server/schema.ts +23 -7
  397. package/src/server/service.ts +43 -44
  398. package/src/server/testing.ts +4 -117
  399. package/src/server/workerOptions.ts +28 -0
  400. package/dist/server/defaultClientFactory.d.ts +0 -3
  401. package/dist/server/defaultClientFactory.d.ts.map +0 -1
  402. package/dist/server/defaultClientFactory.js.map +0 -1
  403. package/dist/server/internal/batchHandler.d.ts +0 -5
  404. package/dist/server/internal/batchHandler.d.ts.map +0 -1
  405. package/dist/server/internal/batchHandler.js.map +0 -1
  406. package/dist/server/internal/clientCache.d.ts +0 -8
  407. package/dist/server/internal/clientCache.d.ts.map +0 -1
  408. package/dist/server/internal/clientCache.js.map +0 -1
  409. package/dist/server/internal/expireAttempt.d.ts +0 -3
  410. package/dist/server/internal/expireAttempt.d.ts.map +0 -1
  411. package/dist/server/internal/listJobs.d.ts +0 -5
  412. package/dist/server/internal/listJobs.d.ts.map +0 -1
  413. package/dist/server/internal/listJobs.js +0 -75
  414. package/dist/server/internal/listJobs.js.map +0 -1
  415. package/dist/server/internal/observeTestingSettlements.d.ts +0 -6
  416. package/dist/server/internal/observeTestingSettlements.d.ts.map +0 -1
  417. package/dist/server/internal/observeTestingSettlements.js +0 -35
  418. package/dist/server/internal/observeTestingSettlements.js.map +0 -1
  419. package/dist/server/internal/settleDeferral.d.ts +0 -7
  420. package/dist/server/internal/settleDeferral.d.ts.map +0 -1
  421. package/dist/server/internal/settleDeferral.js.map +0 -1
  422. package/dist/server/internal/testingClient.d.ts +0 -13
  423. package/dist/server/internal/testingClient.d.ts.map +0 -1
  424. package/dist/server/internal/testingClient.js.map +0 -1
  425. package/dist/server/internal/testingDeferrals.d.ts +0 -10
  426. package/dist/server/internal/testingDeferrals.d.ts.map +0 -1
  427. package/dist/server/internal/testingDeferrals.js +0 -15
  428. package/dist/server/internal/testingDeferrals.js.map +0 -1
  429. package/dist/server/internal/testingReadout.d.ts +0 -44
  430. package/dist/server/internal/testingReadout.d.ts.map +0 -1
  431. package/dist/server/internal/testingReadout.js +0 -13
  432. package/dist/server/internal/testingReadout.js.map +0 -1
  433. package/dist/server/internal/testingRegistrations.d.ts +0 -4
  434. package/dist/server/internal/testingRegistrations.d.ts.map +0 -1
  435. package/dist/server/internal/testingRegistrations.js +0 -8
  436. package/dist/server/internal/testingRegistrations.js.map +0 -1
  437. package/dist/server/internal/testingSignal.d.ts.map +0 -1
  438. package/dist/server/internal/testingSignal.js.map +0 -1
  439. package/dist/server/internal/testingSnapshot.d.ts +0 -6
  440. package/dist/server/internal/testingSnapshot.d.ts.map +0 -1
  441. package/dist/server/internal/testingSnapshot.js.map +0 -1
  442. package/src/server/internal/listJobs.ts +0 -116
  443. package/src/server/internal/observeTestingSettlements.ts +0 -36
  444. package/src/server/internal/testingDeferrals.ts +0 -22
  445. package/src/server/internal/testingReadout.ts +0 -19
  446. package/src/server/internal/testingRegistrations.ts +0 -10
  447. /package/dist/server/{defaultClientFactory.js → adapters/defaultClientFactory.js} +0 -0
@@ -1,15 +1,14 @@
1
1
  import { Effect, Schedule } from "effect";
2
- import type { Queue } from "pg-boss";
3
- import type { PgBossClient } from "#client.ts";
4
- import { PgBossQueueOptionsError } from "#error.ts";
5
- import { deadLetterQueueName } from "#health.ts";
2
+ import type { ClientQueueOptions, PgBossClient } from "#server/client.ts";
3
+ import { PgBossQueueOptionsError } from "#server/error.ts";
4
+ import { deadLetterQueueName } from "#server/health.ts";
6
5
 
7
6
  const DEADLOCK_DETECTED = "40P01";
8
7
  const CREATE_QUEUE_ATTEMPTS = 6;
9
8
 
10
9
  // A partitioned queue attaches its table to pg-boss's job table, which can deadlock with job traffic on other queues.
11
10
  // PostgreSQL rolls the whole creation back, so trying it again is safe.
12
- function createQueue(client: PgBossClient, name: string, options?: Omit<Queue, "name">) {
11
+ function createQueue(client: PgBossClient, name: string, options?: ClientQueueOptions) {
13
12
  return Effect.tryPromise({ catch: (error) => error, try: () => client.createQueue(name, options) }).pipe(
14
13
  Effect.retry({
15
14
  schedule: Schedule.exponential(25).pipe(Schedule.upTo({ times: CREATE_QUEUE_ATTEMPTS - 1 })),
@@ -18,7 +17,7 @@ function createQueue(client: PgBossClient, name: string, options?: Omit<Queue, "
18
17
  );
19
18
  }
20
19
 
21
- export const ensureQueue = Effect.fnUntraced(function* (client: PgBossClient, name: string, options: Omit<Queue, "name" | "deadLetter">) {
20
+ export const ensureQueue = Effect.fnUntraced(function* (client: PgBossClient, name: string, options: Omit<ClientQueueOptions, "deadLetter">) {
22
21
  const deadLetter = deadLetterQueueName(name);
23
22
  const desired = { retryBackoff: true, retryLimit: 3, ...options, deadLetter };
24
23
  yield* createQueue(client, deadLetter);
@@ -1,9 +1,9 @@
1
1
  import { Effect } from "effect";
2
- import type { PgBossClient } from "#client.ts";
3
- import { toPgBossError } from "#error.ts";
4
- import { deadLetterQueueName, type JobsHealth, type QueueHealth } from "#health.ts";
2
+ import type { PgBossClient } from "#server/client.ts";
3
+ import { toPgBossError } from "#server/error.ts";
4
+ import { deadLetterQueueName, type JobsHealth, type QueueHealth } from "#server/health.ts";
5
5
 
6
- export function healthFor(client: PgBossClient, names: readonly string[]): Effect.Effect<JobsHealth, import("#error.ts").PgBossError> {
6
+ export function healthFor(client: PgBossClient, names: readonly string[]): Effect.Effect<JobsHealth, import("#server/error.ts").PgBossError> {
7
7
  return Effect.forEach(
8
8
  names,
9
9
  (name) =>
@@ -1,62 +1,27 @@
1
- import { Effect, Option, Redacted, Schema } from "effect";
1
+ import { Effect, Option } from "effect";
2
2
  import { redact } from "@shivaedev/errors/redact.ts";
3
- import type { PgBossClient } from "#client.ts";
4
- import { PgBossPayloadError, toPgBossError } from "#error.ts";
5
- import { deferralOf } from "#internal/deferral.ts";
6
- import { decodeStoredData } from "#internal/storedRows.ts";
7
- import { JobFailure } from "#JobFailure.ts";
8
- import type { PgBossService } from "#service.ts";
3
+ import { deferralOf } from "#server/internal/deferral.ts";
4
+ import { JobEngine } from "#server/internal/engine.ts";
5
+ import { decodeStoredData } from "#server/internal/storedRows.ts";
6
+ import { readJobFailure } from "#server/readJobFailure.ts";
7
+ import type { PgBossService } from "#server/service.ts";
9
8
 
10
- const StoredFailure = Schema.Union([JobFailure, Schema.Struct({ value: JobFailure })]);
11
-
12
- function decodeFailure(queue: string, output: unknown) {
13
- return Schema.decodeUnknownEffect(StoredFailure)(output).pipe(
14
- Effect.map((failure) => ("value" in failure ? failure.value : failure)),
15
- Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue })),
16
- );
17
- }
18
-
19
- export function getJobFor(client: PgBossClient): PgBossService["getJob"] {
20
- return (queue, id) =>
21
- Effect.tryPromise({
22
- catch: (error) => toPgBossError("getJob", error, queue.name),
23
- try: async () => {
24
- if (client.findJobs === undefined) {
25
- throw new TypeError("This pg-boss client does not support findJobs");
26
- }
27
- return (await client.findJobs(queue.name, { id }))[0];
28
- },
29
- }).pipe(
9
+ export const jobControl = Effect.gen(function* () {
10
+ const engine = yield* JobEngine;
11
+ const getJob: PgBossService["getJob"] = (queue, id) =>
12
+ engine.getJob(queue.name, id).pipe(
30
13
  Effect.flatMap(
31
14
  Effect.fnUntraced(function* (job) {
32
15
  if (job === undefined) {
33
16
  return Option.none();
34
17
  }
35
18
  const data = yield* decodeStoredData(queue, job.data);
36
- const output = job.output === null || deferralOf(job) !== undefined ? job.output : yield* decodeFailure(queue.name, job.output);
37
- const sourceOutput = job.sourceOutput === null ? null : yield* decodeFailure(queue.name, job.sourceOutput);
19
+ const output = deferralOf(job) === undefined ? yield* readJobFailure(queue.name, job.output) : job.output;
20
+ const sourceOutput = yield* readJobFailure(queue.name, job.sourceOutput);
38
21
  return Option.some({ ...job, data: redact(data), output, sourceOutput });
39
22
  }),
40
23
  ),
41
24
  );
42
- }
43
-
44
- export function retryFor(client: PgBossClient): PgBossService["retry"] {
45
- return (queue, id) =>
46
- Effect.tryPromise({
47
- catch: (error) => toPgBossError("retry", error, queue.name),
48
- try: async () => {
49
- if (client.findJobs === undefined || client.retry === undefined || client.update === undefined) {
50
- throw new TypeError("This pg-boss client does not support findJobs, retry and update");
51
- }
52
- const job = (await client.findJobs(queue.name, { id }))[0];
53
- if (job?.state !== "failed" && job?.state !== "retry") {
54
- return;
55
- }
56
- if (job.state === "failed") {
57
- await client.retry(queue.name, id);
58
- }
59
- await client.update(queue.name, undefined, { id, startAfter: 0 });
60
- },
61
- });
62
- }
25
+ const retry: PgBossService["retry"] = (queue, id) => engine.retry(queue.name, id);
26
+ return { getJob, retry };
27
+ });
@@ -0,0 +1,85 @@
1
+ import { type Context, Effect, Option, Redacted, Schema } from "effect";
2
+ import { redact } from "@shivaedev/errors/redact.ts";
3
+ import type { JobPayloadSchema } from "#server/definition.ts";
4
+ import { type PgBossError, PgBossPayloadError } from "#server/error.ts";
5
+ import type { DeadLetteredJob, JobPage, JobPageOptions } from "#server/health.ts";
6
+ import { JobEngine, type Listing } from "#server/internal/engine.ts";
7
+ import { decodeStoredData } from "#server/internal/storedRows.ts";
8
+ import { readJobFailure } from "#server/readJobFailure.ts";
9
+ import type { PgBossService } from "#server/service.ts";
10
+
11
+ const Cursor = Schema.StringFromBase64Url.pipe(
12
+ Schema.decodeTo(
13
+ Schema.fromJsonString(
14
+ Schema.Tuple([
15
+ Schema.String.check(Schema.makeFilter((value) => Option.isSome(Schema.decodeUnknownOption(Schema.DateTimeUtcFromString)(value)))),
16
+ Schema.String.check(Schema.isUUID()),
17
+ ]),
18
+ ),
19
+ ),
20
+ );
21
+ const PageOptions = Schema.Struct({
22
+ cursor: Schema.optionalKey(Schema.UndefinedOr(Cursor)),
23
+ limit: Schema.Number.check(Schema.isInt(), Schema.isGreaterThan(0)),
24
+ });
25
+
26
+ const Row = Schema.Struct({
27
+ completedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
28
+ createdOn: Schema.DateTimeUtcFromDate,
29
+ cursorAt: Schema.String,
30
+ data: Schema.Unknown,
31
+ id: Schema.String,
32
+ output: Schema.Unknown,
33
+ queue: Schema.String,
34
+ retryCount: Schema.Number,
35
+ retryLimit: Schema.Number,
36
+ sourceId: Schema.OptionFromNullOr(Schema.String),
37
+ sourceOutput: Schema.Unknown,
38
+ startedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
39
+ state: Schema.Literals(["created", "retry", "active", "completed", "cancelled", "failed"]),
40
+ });
41
+
42
+ const Rows = Schema.Array(Row);
43
+
44
+ export const jobListings = Effect.gen(function* () {
45
+ const engine = yield* JobEngine;
46
+ const failedJobs: PgBossService["failedJobs"] = (queue, options) =>
47
+ listJobs(engine, "failedJobs", queue, options).pipe(
48
+ Effect.map(({ jobs, next }) => ({ jobs: jobs.map(({ sourceId: _id, sourceOutput: _output, ...job }) => job), next })),
49
+ );
50
+ const deadLetteredJobs: PgBossService["deadLetteredJobs"] = (queue, options) =>
51
+ listJobs(engine, "deadLetteredJobs", queue, options).pipe(
52
+ Effect.map(({ jobs, next }) => ({ jobs: jobs.map((job) => ({ ...job, sourceQueue: queue.name })), next })),
53
+ );
54
+ return { deadLetteredJobs, failedJobs };
55
+ });
56
+
57
+ const listJobs = Effect.fnUntraced(function* <const TName extends string, const TPayload extends JobPayloadSchema | typeof Schema.Null>(
58
+ engine: Context.Service.Shape<typeof JobEngine>,
59
+ listing: Listing,
60
+ queue: { readonly name: TName; readonly schema: TPayload },
61
+ options: JobPageOptions,
62
+ ): Effect.fn.Return<
63
+ JobPage<Omit<DeadLetteredJob<unknown>, "sourceQueue">>,
64
+ PgBossError | PgBossPayloadError | Schema.SchemaError,
65
+ TPayload["DecodingServices"]
66
+ > {
67
+ const { cursor: after, limit } = yield* Schema.decodeUnknownEffect(PageOptions)(options);
68
+ const rows = yield* engine.listJobs(listing, queue.name, after, limit);
69
+ const decodedRows = yield* Schema.decodeUnknownEffect(Rows)(rows).pipe(
70
+ Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue: queue.name })),
71
+ );
72
+ const page = decodedRows.slice(0, limit);
73
+ const last = page.at(-1);
74
+ const next = decodedRows.length > limit && last !== undefined ? Option.some(Schema.encodeSync(Cursor)([last.cursorAt, last.id])) : Option.none();
75
+ const jobs = yield* Effect.forEach(
76
+ page,
77
+ Effect.fnUntraced(function* ({ cursorAt: _, data, ...row }) {
78
+ const decoded = yield* decodeStoredData(queue, data);
79
+ const output = yield* readJobFailure(queue.name, row.output);
80
+ const sourceOutput = yield* readJobFailure(queue.name, row.sourceOutput);
81
+ return { ...row, attempt: Option.isSome(row.startedOn) ? row.retryCount + 1 : 0, data: redact(decoded), output, sourceOutput };
82
+ }),
83
+ );
84
+ return { jobs, next };
85
+ });
@@ -1,6 +1,7 @@
1
- import { deadLetterResolutionPlan } from "#internal/deadLetterResolutionPlan.ts";
2
- import { deferralStorePlan } from "#internal/deferralStorePlan.ts";
1
+ import { inspectionPlan } from "#server/adapters/inspectionPlan.ts";
2
+ import { deadLetterResolutionPlan } from "#server/internal/deadLetterResolutionPlan.ts";
3
+ import { deferralStorePlan } from "#server/internal/deferralStorePlan.ts";
3
4
 
4
5
  export function jobStorePlans(schema: string): readonly string[] {
5
- return [deferralStorePlan(schema), deadLetterResolutionPlan(schema)];
6
+ return [deferralStorePlan(schema), deadLetterResolutionPlan(schema), inspectionPlan(schema)];
6
7
  }
@@ -1,16 +1,12 @@
1
- import { Effect } from "effect";
2
- import type { ConstructorOptions, StopOptions } from "pg-boss";
3
- import type { PgBossClient, PgBossClientFactory } from "#client.ts";
4
- import { defaultClientFactory } from "#defaultClientFactory.ts";
5
- import { PgBossClientOptionsError, type PgBossError, toPgBossError } from "#error.ts";
6
- import { jobStorePlans } from "#internal/jobStorePlans.ts";
7
- import { acquireCachedClient, releaseCachedClient } from "./clientCache.ts";
8
- import { observeClientErrors } from "./clientErrors.ts";
1
+ import { Context, type Effect, type Scope } from "effect";
2
+ import type { PgBossClient, PgBossClientFactory } from "#server/client.ts";
3
+ import type { ClientOptions, StopOptions } from "#server/clientOptions.ts";
4
+ import type { PgBossClientOptionsError, PgBossError } from "#server/error.ts";
9
5
 
10
6
  export interface AcquireClientOptions {
11
7
  readonly clientCacheKey?: string | symbol | undefined;
12
8
  readonly clientFactory?: PgBossClientFactory | undefined;
13
- readonly constructor: ConstructorOptions;
9
+ readonly constructor: ClientOptions;
14
10
  }
15
11
 
16
12
  export interface AcquiredClient {
@@ -19,50 +15,13 @@ export interface AcquiredClient {
19
15
  readonly reused: boolean;
20
16
  }
21
17
 
22
- async function startClient(options: AcquireClientOptions, report: (error: Error) => void): Promise<PgBossClient> {
23
- const client = (options.clientFactory ?? defaultClientFactory)(options.constructor);
24
- observeClientErrors(client, report);
25
- try {
26
- await client.start();
27
- if (options.constructor.migrate !== false && client.getDb !== undefined) {
28
- for (const plan of jobStorePlans(options.constructor.schema ?? "pgboss")) {
29
- await client.getDb().executeSql(plan);
30
- }
31
- }
32
- return client;
33
- } catch (error) {
34
- try {
35
- await client.stop();
36
- } catch {
37
- // Preserve the startup failure; stop is best effort on failed acquisition.
38
- }
39
- throw error;
18
+ export class ClientEngine extends Context.Service<
19
+ ClientEngine,
20
+ {
21
+ readonly acquire: (
22
+ options: AcquireClientOptions,
23
+ report: (error: Error) => void,
24
+ stop?: StopOptions,
25
+ ) => Effect.Effect<AcquiredClient, PgBossError | PgBossClientOptionsError, Scope.Scope>;
40
26
  }
41
- }
42
-
43
- export function acquireClient(
44
- options: AcquireClientOptions,
45
- report: (error: Error) => void,
46
- ): Effect.Effect<AcquiredClient, PgBossError | PgBossClientOptionsError> {
47
- return Effect.tryPromise({
48
- catch: (error) => (error instanceof PgBossClientOptionsError ? error : toPgBossError("start", error)),
49
- try: async () => {
50
- const cacheKey = options.clientCacheKey;
51
- return cacheKey === undefined
52
- ? { client: await startClient(options, report), reused: false }
53
- : { cacheKey, ...(await acquireCachedClient(cacheKey, options.constructor, () => startClient(options, report))) };
54
- },
55
- });
56
- }
57
-
58
- export function releaseClient(acquired: AcquiredClient, stopOptions?: StopOptions): Effect.Effect<void> {
59
- return Effect.tryPromise({
60
- catch: (error) => toPgBossError("stop", error),
61
- try: async () => {
62
- const client = acquired.cacheKey === undefined ? acquired.client : await releaseCachedClient(acquired.cacheKey);
63
- if (client !== undefined) {
64
- await client.stop(stopOptions);
65
- }
66
- },
67
- }).pipe(Effect.catch((error) => Effect.logError(error)));
68
- }
27
+ >()("@shivaedev/jobs/ClientEngine") {}
@@ -1,19 +1,28 @@
1
- import type { PgBossClient } from "#client.ts";
2
- import { countsFor } from "#internal/countsFor.ts";
3
- import { enqueueFor } from "#internal/enqueueFor.ts";
4
- import { healthFor } from "#internal/healthFor.ts";
5
- import { getJobFor, retryFor } from "#internal/jobControl.ts";
6
- import { deadLetteredJobsFor, failedJobsFor } from "#internal/listJobs.ts";
7
- import type { PgBossService } from "#service.ts";
1
+ import { Effect } from "effect";
2
+ import { inspection } from "#server/adapters/inspection.ts";
3
+ import type { PgBossClient } from "#server/client.ts";
4
+ import { JobEngine } from "#server/internal/engine.ts";
5
+ import { enqueueFor } from "#server/internal/enqueueFor.ts";
6
+ import { jobControl } from "#server/internal/jobControl.ts";
7
+ import type { PgBossService } from "#server/service.ts";
8
8
 
9
- export function makeService(client: PgBossClient, names: readonly string[], schema = "pgboss"): PgBossService {
9
+ export const makeService = Effect.fnUntraced(function* (
10
+ client: PgBossClient,
11
+ names: readonly string[],
12
+ schema = "pgboss",
13
+ ): Effect.fn.Return<PgBossService, never, JobEngine> {
14
+ const engine = yield* JobEngine;
15
+ const reads = yield* inspection(client, schema);
10
16
  return {
11
- counts: (queue) => countsFor(client, schema, queue.name),
12
- deadLetteredJobs: deadLetteredJobsFor(client, schema),
17
+ counts: (queue) => reads.counts(queue),
18
+ deadLetteredJobs: reads.deadLetteredJobs,
19
+ deleteQueue: engine.deleteQueue,
13
20
  enqueue: enqueueFor(client),
14
- failedJobs: failedJobsFor(client, schema),
15
- getJob: getJobFor(client),
16
- health: (queues) => healthFor(client, queues === undefined ? names : queues.map((queue) => queue.name)),
17
- retry: retryFor(client),
21
+ failedJobs: reads.failedJobs,
22
+ inspection: () => Effect.succeed(reads),
23
+ ...(yield* jobControl),
24
+ health: (queues) => reads.health(queues ?? names.map((name) => ({ name }))),
25
+ refreshQueueStats: engine.refreshQueueStats,
26
+ unschedule: engine.unschedule,
18
27
  };
19
- }
28
+ });
@@ -1,13 +1,12 @@
1
1
  import { type Context, Effect, Scope } from "effect";
2
- import type { StopOptions } from "pg-boss";
3
- import { registerWorker } from "#adapters/registerWorker.ts";
4
- import { workerDiagnostics } from "#adapters/workerDiagnostics.ts";
5
- import type { PgBossClient } from "#client.ts";
6
- import type { JobPayloadSchema, JobRegistration, QueueDefinition, QueueWorker, ScheduleDefinition, ScheduledWorker } from "#definition.ts";
7
- import { PgBossQueueOptionsError, toPgBossError } from "#error.ts";
8
- import { ensureQueue } from "#internal/ensureQueue.ts";
9
- import { runQueueWorker } from "#internal/runQueueWorker.ts";
10
- import { registerTestingQueue } from "#internal/testingRegistrations.ts";
2
+ import { registerWorker } from "#server/adapters/registerWorker.ts";
3
+ import { workerDiagnostics } from "#server/adapters/workerDiagnostics.ts";
4
+ import type { PgBossClient } from "#server/client.ts";
5
+ import type { StopOptions } from "#server/clientOptions.ts";
6
+ import type { JobPayloadSchema, JobRegistration, QueueDefinition, QueueWorker, ScheduleDefinition, ScheduledWorker } from "#server/definition.ts";
7
+ import { PgBossQueueOptionsError, toPgBossError } from "#server/error.ts";
8
+ import { ensureQueue } from "#server/internal/ensureQueue.ts";
9
+ import { runQueueWorker } from "#server/internal/runQueueWorker.ts";
11
10
 
12
11
  function registrationDefinition(registration: JobRegistration): QueueDefinition | ScheduleDefinition {
13
12
  if (registration._tag === "QueueDefinition") {
@@ -107,9 +106,6 @@ export const registerJobs = Effect.fnUntraced(function* <R>(
107
106
  const scope = yield* Scope.fork(yield* Effect.scope, "parallel");
108
107
  yield* Effect.try({ catch: (error) => toPgBossError("register", error), try: () => registrationNames(registrations) });
109
108
  yield* prepareQueues(client, registrations, replaceWorkers);
110
- for (const registration of registrations) {
111
- registerTestingQueue(client, registrationName(registration));
112
- }
113
109
  if (!startWorkers) {
114
110
  return;
115
111
  }
@@ -1,10 +1,10 @@
1
1
  import { type Context, Effect, Option, Scope } from "effect";
2
- import type { StopOptions } from "pg-boss";
3
2
  import { WorkerRelease } from "@shivaedev/sql/WorkerRelease.ts";
4
- import { retireJobs } from "#adapters/retireJobs.ts";
5
- import type { PgBossClient } from "#client.ts";
6
- import type { JobRegistration } from "#definition.ts";
7
- import { toPgBossError } from "#error.ts";
3
+ import { retireJobs } from "#server/adapters/retireJobs.ts";
4
+ import type { PgBossClient } from "#server/client.ts";
5
+ import type { StopOptions } from "#server/clientOptions.ts";
6
+ import type { JobRegistration } from "#server/definition.ts";
7
+ import { toPgBossError } from "#server/error.ts";
8
8
  import { registerJobs, registrationName } from "./register.ts";
9
9
 
10
10
  export const registerReleasedJobs = Effect.fnUntraced(function* <R>(
@@ -1,8 +1,8 @@
1
1
  import { Clock, Effect } from "effect";
2
2
  import { redactDiagnosticCause } from "@shivaedev/errors/redactCause.ts";
3
- import { batchClockOffset } from "#adapters/batchClockOffset.ts";
4
- import type { PgBossClient } from "#client.ts";
5
- import { toPgBossError } from "#error.ts";
3
+ import { batchClockOffset } from "#server/adapters/batchClockOffset.ts";
4
+ import type { PgBossClient } from "#server/client.ts";
5
+ import { toPgBossError } from "#server/error.ts";
6
6
 
7
7
  export function retryWake(client: PgBossClient, schema: string, name: string, id: string, registration: Promise<string>): Effect.Effect<void> {
8
8
  return Effect.gen(function* () {
@@ -1,15 +1,15 @@
1
1
  import { Effect, Redacted, Schema } from "effect";
2
- import type { Job } from "pg-boss";
3
- import { deferralCount } from "#adapters/deferralCount.ts";
4
- import { workerDiagnostics } from "#adapters/workerDiagnostics.ts";
5
- import type { PgBossClient } from "#client.ts";
6
- import { type JobPayloadSchema, jobContext, type QueueWorker } from "#definition.ts";
7
- import { PgBossPayloadError } from "#error.ts";
8
- import { payloadOf } from "#internal/tracing.ts";
2
+ import { deferralCount } from "#server/adapters/deferralCount.ts";
3
+ import { workerDiagnostics } from "#server/adapters/workerDiagnostics.ts";
4
+ import type { PgBossClient } from "#server/client.ts";
5
+ import { type JobPayloadSchema, jobContext, type QueueWorker } from "#server/definition.ts";
6
+ import { PgBossPayloadError } from "#server/error.ts";
7
+ import { payloadOf } from "#server/internal/tracing.ts";
8
+ import type { WorkerJob } from "#server/job.ts";
9
9
 
10
10
  export function runQueueWorker<R>(
11
11
  worker: QueueWorker<JobPayloadSchema & { readonly DecodingServices: R }, R>,
12
- job: Job<unknown>,
12
+ job: WorkerJob<unknown>,
13
13
  deadline: number,
14
14
  client: PgBossClient,
15
15
  schema: string,
@@ -1,7 +1,7 @@
1
1
  import { Effect, Redacted, Schema } from "effect";
2
- import type { JobPayloadSchema } from "#definition.ts";
3
- import { PgBossPayloadError } from "#error.ts";
4
- import { payloadOf } from "#internal/tracing.ts";
2
+ import type { JobPayloadSchema } from "#server/definition.ts";
3
+ import { PgBossPayloadError } from "#server/error.ts";
4
+ import { payloadOf } from "#server/internal/tracing.ts";
5
5
 
6
6
  export function quotedSchema(schema: string): string {
7
7
  return `"${schema.replaceAll('"', '""')}"`;
@@ -1,10 +1,10 @@
1
- import { Clock, Effect, Schema } from "effect";
2
- import type { PgBoss } from "pg-boss";
3
- import type { PgBossTestingError } from "#error.ts";
4
- import { quotedSchema } from "#internal/storedRows.ts";
5
- import { testingOperation } from "#internal/testingReadout.ts";
1
+ import { Clock, Effect } from "effect";
2
+ import type { PgBossTestingError } from "#server/error.ts";
3
+ import type { PgBossInspectionService } from "#server/inspection.ts";
4
+ import { testingInspection } from "#server/internal/testingOperation.ts";
6
5
 
7
6
  export interface TestingBatch {
7
+ readonly jobs: ReadonlyMap<string, number>;
8
8
  readonly name: string;
9
9
  settled: boolean;
10
10
  }
@@ -14,30 +14,12 @@ export interface TestingWork {
14
14
  readonly queues: Set<string>;
15
15
  }
16
16
 
17
- const Busy = Schema.Struct({ busy: Schema.Boolean });
18
-
19
17
  export function testingIdle(
20
- client: () => PgBoss,
21
- schema: () => string,
18
+ inspection: () => PgBossInspectionService,
22
19
  work: TestingWork,
23
20
  signal: { readonly revision: Effect.Effect<number>; readonly waitForChange: (after: number) => Effect.Effect<number> },
24
21
  ): Effect.Effect<void, PgBossTestingError> {
25
- const busy = testingOperation("waitForIdle", async () => {
26
- const quoted = quotedSchema(schema());
27
- const { rows } = await client()
28
- .getDb()
29
- .executeSql(
30
- `/* jobs testing idle */ SELECT EXISTS (
31
- SELECT 1 FROM ${quoted}.job
32
- WHERE name = ANY($1::text[]) AND (
33
- (state < 'active' AND NOT blocked AND start_after <= ${quoted}.job_now())
34
- OR state = 'active'
35
- )
36
- ) AS busy`,
37
- [[...work.queues]],
38
- );
39
- return (await Schema.decodeUnknownPromise(Busy)(rows[0])).busy;
40
- });
22
+ const busy = Effect.suspend(() => testingInspection("waitForIdle", inspection().busy([...work.queues].map((name) => ({ name })))));
41
23
  return Effect.gen(function* () {
42
24
  while (true) {
43
25
  const revision = yield* signal.revision;
@@ -46,12 +28,7 @@ export function testingIdle(
46
28
  if (work.queues.size === 0 || !(unsettled || (yield* busy))) {
47
29
  return;
48
30
  }
49
- if (unsettled) {
50
- yield* signal.waitForChange(revision);
51
- } else {
52
- // Other clients have no local callback; PostgreSQL remains the source of idle state.
53
- yield* Effect.raceFirst(signal.waitForChange(revision), Effect.sleep("50 millis"));
54
- }
31
+ yield* signal.waitForChange(revision);
55
32
  }
56
33
  }).pipe(Effect.provideService(Clock.Clock, Clock.Clock.defaultValue()));
57
34
  }
@@ -0,0 +1,18 @@
1
+ import { Effect, Redacted } from "effect";
2
+ import { PgBossError, PgBossTestingError } from "#server/error.ts";
3
+
4
+ export function testingOperation<A>(operation: string, run: () => Promise<A>, queue?: string) {
5
+ return Effect.tryPromise({
6
+ catch: (original) => new PgBossTestingError({ operation, original: Redacted.make(original), queue }),
7
+ try: run,
8
+ });
9
+ }
10
+
11
+ export function testingInspection<A, E, R>(operation: string, effect: Effect.Effect<A, E | PgBossError, R>, queue?: string) {
12
+ return effect.pipe(
13
+ Effect.catchIf(
14
+ (error): error is PgBossError => error instanceof PgBossError,
15
+ (error) => Effect.fail(new PgBossTestingError({ operation, original: error.original, queue: queue ?? error.queue })),
16
+ ),
17
+ );
18
+ }
@@ -1,23 +1,35 @@
1
- import type { PgBoss } from "pg-boss";
2
- import type { ScheduleDefinition } from "#definition.ts";
3
- import { testingOperation } from "#internal/testingReadout.ts";
1
+ import { Effect, Redacted } from "effect";
2
+ import type { PgBossClient } from "#server/client.ts";
3
+ import type { ScheduleDefinition } from "#server/definition.ts";
4
+ import { PgBossTestingError } from "#server/error.ts";
5
+ import type { PgBossInspectionService } from "#server/inspection.ts";
6
+ import { testingInspection, testingOperation } from "#server/internal/testingOperation.ts";
4
7
 
5
- export function testingSchedules(client: () => PgBoss, changed: () => void) {
8
+ export function testingSchedules(client: () => PgBossClient, inspection: () => PgBossInspectionService) {
6
9
  return {
7
10
  schedules: () =>
8
- testingOperation("schedules", async () => (await client().getSchedules()).map(({ name, cron, timezone }) => ({ cron, name, timezone }))),
9
- trigger: (schedule: Pick<ScheduleDefinition, "name" | "scheduleOptions">) =>
10
- testingOperation(
11
- "trigger",
12
- async () => {
13
- const [registered] = await client().getSchedules(schedule.name, schedule.scheduleOptions.key ?? "");
14
- if (registered === undefined) {
15
- throw new Error("Schedule is not registered");
16
- }
17
- await client().send(registered.name, registered.data, { ...registered.options, startAfter: 0 });
18
- changed();
19
- },
20
- schedule.name,
11
+ Effect.suspend(() => testingInspection("schedules", inspection().schedules())).pipe(
12
+ Effect.map((schedules) => schedules.map(({ name, cron, timezone }) => ({ cron, name, timezone }))),
21
13
  ),
14
+ trigger: (schedule: Pick<ScheduleDefinition, "name" | "scheduleOptions">) =>
15
+ Effect.gen(function* () {
16
+ const [registered] = yield* testingInspection(
17
+ "trigger",
18
+ inspection().schedules(schedule.name, schedule.scheduleOptions.key ?? ""),
19
+ schedule.name,
20
+ );
21
+ if (registered === undefined) {
22
+ return yield* new PgBossTestingError({
23
+ operation: "trigger",
24
+ original: Redacted.make(new Error("Schedule is not registered")),
25
+ queue: schedule.name,
26
+ });
27
+ }
28
+ return yield* testingOperation(
29
+ "trigger",
30
+ () => client().send(registered.name, registered.data, { ...registered.options, startAfter: 0 }),
31
+ schedule.name,
32
+ );
33
+ }),
22
34
  };
23
35
  }