@shivaedev/jobs 0.29.2 → 0.31.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 (383) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +74 -22
  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/installSchema.d.ts +1 -1
  39. package/dist/server/adapters/installSchema.d.ts.map +1 -1
  40. package/dist/server/adapters/installSchema.js +1 -1
  41. package/dist/server/adapters/installSchema.js.map +1 -1
  42. package/dist/server/adapters/jobEngine.d.ts +5 -0
  43. package/dist/server/adapters/jobEngine.d.ts.map +1 -0
  44. package/dist/server/adapters/jobEngine.js +50 -0
  45. package/dist/server/adapters/jobEngine.js.map +1 -0
  46. package/dist/server/adapters/lifecycle.d.ts +11 -0
  47. package/dist/server/adapters/lifecycle.d.ts.map +1 -0
  48. package/dist/server/adapters/lifecycle.js +48 -0
  49. package/dist/server/adapters/lifecycle.js.map +1 -0
  50. package/dist/server/adapters/listJobs.d.ts +5 -0
  51. package/dist/server/adapters/listJobs.d.ts.map +1 -0
  52. package/dist/server/adapters/listJobs.js +37 -0
  53. package/dist/server/adapters/listJobs.js.map +1 -0
  54. package/dist/server/adapters/observeTestingSettlements.d.ts +6 -0
  55. package/dist/server/adapters/observeTestingSettlements.d.ts.map +1 -0
  56. package/dist/server/adapters/observeTestingSettlements.js.map +1 -0
  57. package/dist/server/adapters/queueAdministration.d.ts +4 -0
  58. package/dist/server/adapters/queueAdministration.d.ts.map +1 -0
  59. package/dist/server/adapters/queueAdministration.js +42 -0
  60. package/dist/server/adapters/queueAdministration.js.map +1 -0
  61. package/dist/server/adapters/registerWorker.d.ts +5 -3
  62. package/dist/server/adapters/registerWorker.d.ts.map +1 -1
  63. package/dist/server/adapters/registerWorker.js +16 -7
  64. package/dist/server/adapters/registerWorker.js.map +1 -1
  65. package/dist/server/adapters/retireJobs.d.ts +3 -3
  66. package/dist/server/adapters/retireJobs.d.ts.map +1 -1
  67. package/dist/server/adapters/retireJobs.js +3 -3
  68. package/dist/server/adapters/retireJobs.js.map +1 -1
  69. package/dist/server/adapters/schemaIndexBuilds.d.ts +2 -2
  70. package/dist/server/adapters/schemaIndexBuilds.d.ts.map +1 -1
  71. package/dist/server/adapters/schemaIndexBuilds.js.map +1 -1
  72. package/dist/server/adapters/settleDeferral.d.ts +7 -0
  73. package/dist/server/adapters/settleDeferral.d.ts.map +1 -0
  74. package/dist/server/{internal → adapters}/settleDeferral.js +2 -2
  75. package/dist/server/adapters/settleDeferral.js.map +1 -0
  76. package/dist/server/adapters/testingClient.d.ts +14 -0
  77. package/dist/server/adapters/testingClient.d.ts.map +1 -0
  78. package/dist/server/{internal → adapters}/testingClient.js +15 -11
  79. package/dist/server/adapters/testingClient.js.map +1 -0
  80. package/dist/server/adapters/testingController.d.ts +34 -0
  81. package/dist/server/adapters/testingController.d.ts.map +1 -0
  82. package/dist/server/adapters/testingController.js +98 -0
  83. package/dist/server/adapters/testingController.js.map +1 -0
  84. package/dist/server/adapters/testingDueNow.d.ts +3 -3
  85. package/dist/server/adapters/testingDueNow.d.ts.map +1 -1
  86. package/dist/server/adapters/testingDueNow.js +2 -2
  87. package/dist/server/adapters/testingDueNow.js.map +1 -1
  88. package/dist/server/adapters/testingEngine.d.ts +5 -0
  89. package/dist/server/adapters/testingEngine.d.ts.map +1 -0
  90. package/dist/server/adapters/testingEngine.js +23 -0
  91. package/dist/server/adapters/testingEngine.js.map +1 -0
  92. package/dist/server/adapters/testingExpirations.d.ts +6 -4
  93. package/dist/server/adapters/testingExpirations.d.ts.map +1 -1
  94. package/dist/server/adapters/testingExpirations.js.map +1 -1
  95. package/dist/server/adapters/transactionDb.d.ts +2 -2
  96. package/dist/server/adapters/transactionDb.d.ts.map +1 -1
  97. package/dist/server/adapters/transactionDb.js.map +1 -1
  98. package/dist/server/client.d.ts +92 -18
  99. package/dist/server/client.d.ts.map +1 -1
  100. package/dist/server/clientOptions.d.ts +75 -0
  101. package/dist/server/clientOptions.d.ts.map +1 -0
  102. package/dist/server/clientOptions.js +2 -0
  103. package/dist/server/clientOptions.js.map +1 -0
  104. package/dist/server/defineSchedule.d.ts +1 -1
  105. package/dist/server/defineSchedule.d.ts.map +1 -1
  106. package/dist/server/defineSchedule.js +2 -1
  107. package/dist/server/defineSchedule.js.map +1 -1
  108. package/dist/server/definition.d.ts +20 -18
  109. package/dist/server/definition.d.ts.map +1 -1
  110. package/dist/server/definition.js +3 -1
  111. package/dist/server/definition.js.map +1 -1
  112. package/dist/server/engineClient.d.ts +26 -0
  113. package/dist/server/engineClient.d.ts.map +1 -0
  114. package/dist/server/engineClient.js +2 -0
  115. package/dist/server/engineClient.js.map +1 -0
  116. package/dist/server/enqueueOptions.d.ts +22 -0
  117. package/dist/server/enqueueOptions.d.ts.map +1 -0
  118. package/dist/server/enqueueOptions.js +2 -0
  119. package/dist/server/enqueueOptions.js.map +1 -0
  120. package/dist/server/error.d.ts +11 -1
  121. package/dist/server/error.d.ts.map +1 -1
  122. package/dist/server/error.js +8 -1
  123. package/dist/server/error.js.map +1 -1
  124. package/dist/server/health.d.ts +2 -2
  125. package/dist/server/health.d.ts.map +1 -1
  126. package/dist/server/internal/acquireClient.d.ts +11 -0
  127. package/dist/server/internal/acquireClient.d.ts.map +1 -0
  128. package/dist/server/internal/acquireClient.js +21 -0
  129. package/dist/server/internal/acquireClient.js.map +1 -0
  130. package/dist/server/internal/adapters/testingFetches.d.ts +2 -2
  131. package/dist/server/internal/adapters/testingFetches.d.ts.map +1 -1
  132. package/dist/server/internal/adapters/testingFetches.js.map +1 -1
  133. package/dist/server/internal/clientErrors.d.ts +1 -1
  134. package/dist/server/internal/clientErrors.d.ts.map +1 -1
  135. package/dist/server/internal/countsFor.d.ts +3 -3
  136. package/dist/server/internal/countsFor.d.ts.map +1 -1
  137. package/dist/server/internal/countsFor.js +2 -2
  138. package/dist/server/internal/countsFor.js.map +1 -1
  139. package/dist/server/internal/deadLetterResolutionPlan.js +1 -1
  140. package/dist/server/internal/deadLetterResolutionPlan.js.map +1 -1
  141. package/dist/server/internal/deadlineOf.d.ts +2 -2
  142. package/dist/server/internal/deadlineOf.d.ts.map +1 -1
  143. package/dist/server/internal/deadlineOf.js.map +1 -1
  144. package/dist/server/internal/deferrableAttempt.d.ts +4 -5
  145. package/dist/server/internal/deferrableAttempt.d.ts.map +1 -1
  146. package/dist/server/internal/deferrableAttempt.js +5 -14
  147. package/dist/server/internal/deferrableAttempt.js.map +1 -1
  148. package/dist/server/internal/deferral.d.ts +3 -3
  149. package/dist/server/internal/deferral.d.ts.map +1 -1
  150. package/dist/server/internal/deferral.js.map +1 -1
  151. package/dist/server/internal/deferralStorePlan.js +2 -2
  152. package/dist/server/internal/deferralStorePlan.js.map +1 -1
  153. package/dist/server/internal/definitionOptions.d.ts +7 -7
  154. package/dist/server/internal/definitionOptions.d.ts.map +1 -1
  155. package/dist/server/internal/engine.d.ts +30 -0
  156. package/dist/server/internal/engine.d.ts.map +1 -0
  157. package/dist/server/internal/engine.js +6 -0
  158. package/dist/server/internal/engine.js.map +1 -0
  159. package/dist/server/internal/enqueueFor.d.ts +2 -2
  160. package/dist/server/internal/enqueueFor.d.ts.map +1 -1
  161. package/dist/server/internal/enqueueFor.js +3 -3
  162. package/dist/server/internal/enqueueFor.js.map +1 -1
  163. package/dist/server/internal/ensureQueue.d.ts +2 -3
  164. package/dist/server/internal/ensureQueue.d.ts.map +1 -1
  165. package/dist/server/internal/ensureQueue.js +2 -2
  166. package/dist/server/internal/ensureQueue.js.map +1 -1
  167. package/dist/server/internal/healthFor.d.ts +3 -3
  168. package/dist/server/internal/healthFor.d.ts.map +1 -1
  169. package/dist/server/internal/healthFor.js +2 -2
  170. package/dist/server/internal/healthFor.js.map +1 -1
  171. package/dist/server/internal/jobControl.d.ts +9 -4
  172. package/dist/server/internal/jobControl.d.ts.map +1 -1
  173. package/dist/server/internal/jobControl.js +13 -40
  174. package/dist/server/internal/jobControl.js.map +1 -1
  175. package/dist/server/internal/jobListings.d.ts +16 -0
  176. package/dist/server/internal/jobListings.d.ts.map +1 -0
  177. package/dist/server/internal/jobListings.js +52 -0
  178. package/dist/server/internal/jobListings.js.map +1 -0
  179. package/dist/server/internal/jobStorePlans.js +2 -2
  180. package/dist/server/internal/jobStorePlans.js.map +1 -1
  181. package/dist/server/internal/lifecycle.d.ts +11 -7
  182. package/dist/server/internal/lifecycle.d.ts.map +1 -1
  183. package/dist/server/internal/lifecycle.js +2 -49
  184. package/dist/server/internal/lifecycle.js.map +1 -1
  185. package/dist/server/internal/makeService.d.ts +5 -3
  186. package/dist/server/internal/makeService.d.ts.map +1 -1
  187. package/dist/server/internal/makeService.js +15 -11
  188. package/dist/server/internal/makeService.js.map +1 -1
  189. package/dist/server/internal/register.d.ts +5 -5
  190. package/dist/server/internal/register.d.ts.map +1 -1
  191. package/dist/server/internal/register.js +17 -29
  192. package/dist/server/internal/register.js.map +1 -1
  193. package/dist/server/internal/registerReleasedJobs.d.ts +4 -4
  194. package/dist/server/internal/registerReleasedJobs.d.ts.map +1 -1
  195. package/dist/server/internal/registerReleasedJobs.js +2 -2
  196. package/dist/server/internal/registerReleasedJobs.js.map +1 -1
  197. package/dist/server/internal/retryWake.d.ts +1 -1
  198. package/dist/server/internal/retryWake.d.ts.map +1 -1
  199. package/dist/server/internal/retryWake.js +2 -2
  200. package/dist/server/internal/retryWake.js.map +1 -1
  201. package/dist/server/internal/runQueueWorker.d.ts +6 -4
  202. package/dist/server/internal/runQueueWorker.d.ts.map +1 -1
  203. package/dist/server/internal/runQueueWorker.js +5 -5
  204. package/dist/server/internal/runQueueWorker.js.map +1 -1
  205. package/dist/server/internal/storedRows.d.ts +2 -2
  206. package/dist/server/internal/storedRows.d.ts.map +1 -1
  207. package/dist/server/internal/storedRows.js +2 -2
  208. package/dist/server/internal/storedRows.js.map +1 -1
  209. package/dist/server/internal/testingDeferrals.d.ts +3 -3
  210. package/dist/server/internal/testingDeferrals.d.ts.map +1 -1
  211. package/dist/server/internal/testingDeferrals.js +2 -2
  212. package/dist/server/internal/testingDeferrals.js.map +1 -1
  213. package/dist/server/internal/testingIdle.d.ts +3 -3
  214. package/dist/server/internal/testingIdle.d.ts.map +1 -1
  215. package/dist/server/internal/testingIdle.js +11 -5
  216. package/dist/server/internal/testingIdle.js.map +1 -1
  217. package/dist/server/internal/testingReadout.d.ts +7 -41
  218. package/dist/server/internal/testingReadout.d.ts.map +1 -1
  219. package/dist/server/internal/testingReadout.js +2 -2
  220. package/dist/server/internal/testingReadout.js.map +1 -1
  221. package/dist/server/internal/testingRegistrations.d.ts +4 -0
  222. package/dist/server/internal/testingRegistrations.d.ts.map +1 -0
  223. package/dist/server/internal/testingRegistrations.js +8 -0
  224. package/dist/server/internal/testingRegistrations.js.map +1 -0
  225. package/dist/server/internal/testingSchedules.d.ts +3 -3
  226. package/dist/server/internal/testingSchedules.d.ts.map +1 -1
  227. package/dist/server/internal/testingSchedules.js +1 -1
  228. package/dist/server/internal/testingSchedules.js.map +1 -1
  229. package/dist/server/internal/testingSnapshot.d.ts +4 -4
  230. package/dist/server/internal/testingSnapshot.d.ts.map +1 -1
  231. package/dist/server/internal/testingSnapshot.js +7 -4
  232. package/dist/server/internal/testingSnapshot.js.map +1 -1
  233. package/dist/server/internal/testingWaits.d.ts +8 -7
  234. package/dist/server/internal/testingWaits.d.ts.map +1 -1
  235. package/dist/server/internal/testingWaits.js +3 -3
  236. package/dist/server/internal/testingWaits.js.map +1 -1
  237. package/dist/server/internal/tracing.d.ts +2 -2
  238. package/dist/server/internal/tracing.d.ts.map +1 -1
  239. package/dist/server/internal/tracing.js.map +1 -1
  240. package/dist/server/internal/validateQueueNames.d.ts +2 -2
  241. package/dist/server/internal/validateQueueNames.d.ts.map +1 -1
  242. package/dist/server/internal/validateQueueNames.js +1 -1
  243. package/dist/server/internal/validateQueueNames.js.map +1 -1
  244. package/dist/server/internal/waitForBatchExpiry.d.ts +4 -4
  245. package/dist/server/internal/waitForBatchExpiry.d.ts.map +1 -1
  246. package/dist/server/internal/waitForBatchExpiry.js +1 -1
  247. package/dist/server/internal/waitForBatchExpiry.js.map +1 -1
  248. package/dist/server/job.d.ts +42 -0
  249. package/dist/server/job.d.ts.map +1 -0
  250. package/dist/server/job.js +2 -0
  251. package/dist/server/job.js.map +1 -0
  252. package/dist/server/jobModule.d.ts +9 -0
  253. package/dist/server/jobModule.d.ts.map +1 -0
  254. package/dist/server/jobModule.js +15 -0
  255. package/dist/server/jobModule.js.map +1 -0
  256. package/dist/server/queueOptions.d.ts +19 -0
  257. package/dist/server/queueOptions.d.ts.map +1 -0
  258. package/dist/server/queueOptions.js +2 -0
  259. package/dist/server/queueOptions.js.map +1 -0
  260. package/dist/server/readJobFailure.d.ts +5 -0
  261. package/dist/server/readJobFailure.d.ts.map +1 -0
  262. package/dist/server/readJobFailure.js +8 -0
  263. package/dist/server/readJobFailure.js.map +1 -0
  264. package/dist/server/schema.d.ts +1 -1
  265. package/dist/server/schema.d.ts.map +1 -1
  266. package/dist/server/schema.js +18 -7
  267. package/dist/server/schema.js.map +1 -1
  268. package/dist/server/service.d.ts +15 -10
  269. package/dist/server/service.d.ts.map +1 -1
  270. package/dist/server/service.js +26 -33
  271. package/dist/server/service.js.map +1 -1
  272. package/dist/server/testing.d.ts +32 -70
  273. package/dist/server/testing.d.ts.map +1 -1
  274. package/dist/server/testing.js +9 -96
  275. package/dist/server/testing.js.map +1 -1
  276. package/dist/server/workerOptions.d.ts +25 -0
  277. package/dist/server/workerOptions.d.ts.map +1 -0
  278. package/dist/server/workerOptions.js +2 -0
  279. package/dist/server/workerOptions.js.map +1 -0
  280. package/package.json +11 -16
  281. package/src/display.ts +12 -0
  282. package/src/server/ClientDatabase.ts +7 -0
  283. package/src/server/PgBoss.ts +2 -2
  284. package/src/server/adapters/batchClockOffset.ts +8 -5
  285. package/src/server/{internal → adapters}/batchHandler.ts +13 -13
  286. package/src/server/{internal → adapters}/clientCache.ts +10 -22
  287. package/src/server/adapters/clientErrorLogger.ts +1 -1
  288. package/src/server/{defaultClientFactory.ts → adapters/defaultClientFactory.ts} +4 -2
  289. package/src/server/adapters/deferralCount.ts +5 -5
  290. package/src/server/{internal → adapters}/expireAttempt.ts +4 -3
  291. package/src/server/adapters/installSchema.ts +2 -2
  292. package/src/server/adapters/jobEngine.ts +59 -0
  293. package/src/server/adapters/lifecycle.ts +67 -0
  294. package/src/server/adapters/listJobs.ts +43 -0
  295. package/src/server/{internal → adapters}/observeTestingSettlements.ts +2 -2
  296. package/src/server/adapters/queueAdministration.ts +47 -0
  297. package/src/server/adapters/registerWorker.ts +24 -13
  298. package/src/server/adapters/retireJobs.ts +5 -5
  299. package/src/server/adapters/schemaIndexBuilds.ts +2 -2
  300. package/src/server/{internal → adapters}/settleDeferral.ts +5 -5
  301. package/src/server/{internal → adapters}/testingClient.ts +34 -26
  302. package/src/server/adapters/testingController.ts +109 -0
  303. package/src/server/adapters/testingDueNow.ts +5 -5
  304. package/src/server/adapters/testingEngine.ts +28 -0
  305. package/src/server/adapters/testingExpirations.ts +6 -4
  306. package/src/server/adapters/transactionDb.ts +2 -2
  307. package/src/server/client.ts +83 -30
  308. package/src/server/clientOptions.ts +81 -0
  309. package/src/server/defineSchedule.ts +3 -2
  310. package/src/server/definition.ts +24 -20
  311. package/src/server/engineClient.ts +24 -0
  312. package/src/server/enqueueOptions.ts +20 -0
  313. package/src/server/error.ts +17 -2
  314. package/src/server/health.ts +2 -2
  315. package/src/server/internal/acquireClient.ts +26 -0
  316. package/src/server/internal/adapters/testingFetches.ts +2 -2
  317. package/src/server/internal/clientErrors.ts +1 -1
  318. package/src/server/internal/countsFor.ts +5 -5
  319. package/src/server/internal/deadLetterResolutionPlan.ts +1 -1
  320. package/src/server/internal/deadlineOf.ts +2 -2
  321. package/src/server/internal/deferrableAttempt.ts +5 -22
  322. package/src/server/internal/deferral.ts +3 -3
  323. package/src/server/internal/deferralStorePlan.ts +2 -2
  324. package/src/server/internal/definitionOptions.ts +1 -1
  325. package/src/server/internal/engine.ts +41 -0
  326. package/src/server/internal/enqueueFor.ts +5 -5
  327. package/src/server/internal/ensureQueue.ts +5 -6
  328. package/src/server/internal/healthFor.ts +4 -4
  329. package/src/server/internal/jobControl.ts +15 -50
  330. package/src/server/internal/jobListings.ts +85 -0
  331. package/src/server/internal/jobStorePlans.ts +2 -2
  332. package/src/server/internal/lifecycle.ts +14 -55
  333. package/src/server/internal/makeService.ts +21 -13
  334. package/src/server/internal/register.ts +27 -45
  335. package/src/server/internal/registerReleasedJobs.ts +6 -6
  336. package/src/server/internal/retryWake.ts +3 -3
  337. package/src/server/internal/runQueueWorker.ts +14 -8
  338. package/src/server/internal/storedRows.ts +3 -3
  339. package/src/server/internal/testingDeferrals.ts +5 -5
  340. package/src/server/internal/testingIdle.ts +13 -8
  341. package/src/server/internal/testingReadout.ts +12 -6
  342. package/src/server/internal/testingRegistrations.ts +10 -0
  343. package/src/server/internal/testingSchedules.ts +4 -4
  344. package/src/server/internal/testingSnapshot.ts +11 -8
  345. package/src/server/internal/testingWaits.ts +11 -10
  346. package/src/server/internal/tracing.ts +2 -2
  347. package/src/server/internal/validateQueueNames.ts +2 -2
  348. package/src/server/internal/waitForBatchExpiry.ts +4 -4
  349. package/src/server/job.ts +42 -0
  350. package/src/server/jobModule.ts +30 -0
  351. package/src/server/queueOptions.ts +20 -0
  352. package/src/server/readJobFailure.ts +12 -0
  353. package/src/server/schema.ts +18 -7
  354. package/src/server/service.ts +63 -59
  355. package/src/server/testing.ts +17 -108
  356. package/src/server/workerOptions.ts +28 -0
  357. package/dist/server/defaultClientFactory.d.ts +0 -3
  358. package/dist/server/defaultClientFactory.d.ts.map +0 -1
  359. package/dist/server/defaultClientFactory.js.map +0 -1
  360. package/dist/server/internal/batchHandler.d.ts +0 -5
  361. package/dist/server/internal/batchHandler.d.ts.map +0 -1
  362. package/dist/server/internal/batchHandler.js.map +0 -1
  363. package/dist/server/internal/clientCache.d.ts +0 -8
  364. package/dist/server/internal/clientCache.d.ts.map +0 -1
  365. package/dist/server/internal/clientCache.js.map +0 -1
  366. package/dist/server/internal/expireAttempt.d.ts +0 -3
  367. package/dist/server/internal/expireAttempt.d.ts.map +0 -1
  368. package/dist/server/internal/listJobs.d.ts +0 -5
  369. package/dist/server/internal/listJobs.d.ts.map +0 -1
  370. package/dist/server/internal/listJobs.js +0 -75
  371. package/dist/server/internal/listJobs.js.map +0 -1
  372. package/dist/server/internal/observeTestingSettlements.d.ts +0 -6
  373. package/dist/server/internal/observeTestingSettlements.d.ts.map +0 -1
  374. package/dist/server/internal/observeTestingSettlements.js.map +0 -1
  375. package/dist/server/internal/settleDeferral.d.ts +0 -7
  376. package/dist/server/internal/settleDeferral.d.ts.map +0 -1
  377. package/dist/server/internal/settleDeferral.js.map +0 -1
  378. package/dist/server/internal/testingClient.d.ts +0 -13
  379. package/dist/server/internal/testingClient.d.ts.map +0 -1
  380. package/dist/server/internal/testingClient.js.map +0 -1
  381. package/src/server/internal/listJobs.ts +0 -116
  382. /package/dist/server/{defaultClientFactory.js → adapters/defaultClientFactory.js} +0 -0
  383. /package/dist/server/{internal → adapters}/observeTestingSettlements.js +0 -0
@@ -1,9 +1,9 @@
1
1
  import { Effect, Option, Redacted, Schema } from "effect";
2
- import { transactionDb } from "#adapters/transactionDb.ts";
3
- import type { PgBossClient } from "#client.ts";
4
- import { PgBossPayloadError, toPgBossError } from "#error.ts";
5
- import { capturePayload } from "#internal/tracing.ts";
6
- import type { PgBossService } from "#service.ts";
2
+ import { transactionDb } from "#server/adapters/transactionDb.ts";
3
+ import type { PgBossClient } from "#server/client.ts";
4
+ import { PgBossPayloadError, toPgBossError } from "#server/error.ts";
5
+ import { capturePayload } from "#server/internal/tracing.ts";
6
+ import type { PgBossService } from "#server/service.ts";
7
7
 
8
8
  export function enqueueFor(client: PgBossClient): PgBossService["enqueue"] {
9
9
  return (queue, payload, options) =>
@@ -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,5 +1,5 @@
1
- import { deadLetterResolutionPlan } from "#internal/deadLetterResolutionPlan.ts";
2
- import { deferralStorePlan } from "#internal/deferralStorePlan.ts";
1
+ import { deadLetterResolutionPlan } from "#server/internal/deadLetterResolutionPlan.ts";
2
+ import { deferralStorePlan } from "#server/internal/deferralStorePlan.ts";
3
3
 
4
4
  export function jobStorePlans(schema: string): readonly string[] {
5
5
  return [deferralStorePlan(schema), deadLetterResolutionPlan(schema)];
@@ -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,27 @@
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 type { PgBossClient } from "#server/client.ts";
3
+ import { countsFor } from "#server/internal/countsFor.ts";
4
+ import { JobEngine } from "#server/internal/engine.ts";
5
+ import { enqueueFor } from "#server/internal/enqueueFor.ts";
6
+ import { healthFor } from "#server/internal/healthFor.ts";
7
+ import { jobControl } from "#server/internal/jobControl.ts";
8
+ import { jobListings } from "#server/internal/jobListings.ts";
9
+ import type { PgBossService } from "#server/service.ts";
8
10
 
9
- export function makeService(client: PgBossClient, names: readonly string[], schema = "pgboss"): PgBossService {
11
+ export const makeService = Effect.fnUntraced(function* (
12
+ client: PgBossClient,
13
+ names: readonly string[],
14
+ schema = "pgboss",
15
+ ): Effect.fn.Return<PgBossService, never, JobEngine> {
16
+ const engine = yield* JobEngine;
10
17
  return {
11
18
  counts: (queue) => countsFor(client, schema, queue.name),
12
- deadLetteredJobs: deadLetteredJobsFor(client, schema),
19
+ deleteQueue: engine.deleteQueue,
20
+ ...(yield* jobListings),
13
21
  enqueue: enqueueFor(client),
14
- failedJobs: failedJobsFor(client, schema),
15
- getJob: getJobFor(client),
22
+ ...(yield* jobControl),
16
23
  health: (queues) => healthFor(client, queues === undefined ? names : queues.map((queue) => queue.name)),
17
- retry: retryFor(client),
24
+ refreshQueueStats: engine.refreshQueueStats,
25
+ unschedule: engine.unschedule,
18
26
  };
19
- }
27
+ });
@@ -1,36 +1,22 @@
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 { 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
-
11
- function isQueueWorker(registration: JobRegistration): registration is QueueWorker {
12
- return registration._tag === "QueueWorker";
13
- }
14
-
15
- function isScheduledWorker(registration: JobRegistration): registration is ScheduledWorker {
16
- return registration._tag === "ScheduledWorker";
17
- }
18
-
19
- function isQueueDefinition(registration: JobRegistration): registration is QueueDefinition {
20
- return registration._tag === "QueueDefinition";
21
- }
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";
10
+ import { registerTestingQueue } from "#server/internal/testingRegistrations.ts";
22
11
 
23
12
  function registrationDefinition(registration: JobRegistration): QueueDefinition | ScheduleDefinition {
24
- if (isQueueDefinition(registration)) {
13
+ if (registration._tag === "QueueDefinition") {
25
14
  return registration;
26
15
  }
27
- if (isQueueWorker(registration)) {
16
+ if (registration._tag === "QueueWorker") {
28
17
  return registration.queue;
29
18
  }
30
- if (isScheduledWorker(registration)) {
31
- return registration.schedule;
32
- }
33
- throw new TypeError(`Unknown pg-boss registration: ${registration._tag}`);
19
+ return registration.schedule;
34
20
  }
35
21
 
36
22
  export function registrationName(registration: JobRegistration): string {
@@ -39,7 +25,7 @@ export function registrationName(registration: JobRegistration): string {
39
25
 
40
26
  const prepareQueues = Effect.fnUntraced(function* (client: PgBossClient, registrations: readonly JobRegistration[], replaceWorkers: boolean) {
41
27
  for (const registration of registrations) {
42
- if (replaceWorkers && !isQueueDefinition(registration)) {
28
+ if (replaceWorkers && registration._tag !== "QueueDefinition") {
43
29
  yield* Effect.tryPromise({ catch: (error) => toPgBossError("register", error), try: () => client.offWork(registrationName(registration)) });
44
30
  }
45
31
  }
@@ -51,16 +37,10 @@ const prepareQueues = Effect.fnUntraced(function* (client: PgBossClient, registr
51
37
  }
52
38
  });
53
39
 
54
- // The layer requires RegistrationRequirements of its jobs, so its context provides every registered worker.
55
- function workerContext<R>(context: Context.Context<R>): Context.Context<unknown>;
56
- function workerContext(context: unknown): unknown {
57
- return context;
58
- }
59
-
60
- const registerQueue = Effect.fnUntraced(function* (
40
+ const registerQueue = Effect.fnUntraced(function* <R>(
61
41
  client: PgBossClient,
62
- registration: QueueWorker | QueueDefinition,
63
- context: Context.Context<unknown>,
42
+ registration: QueueWorker<JobPayloadSchema & { readonly DecodingServices: R }, R> | QueueDefinition,
43
+ context: Context.Context<R>,
64
44
  scope: Scope.Scope,
65
45
  schema: string,
66
46
  stop: StopOptions | undefined,
@@ -82,10 +62,10 @@ const registerQueue = Effect.fnUntraced(function* (
82
62
  ).pipe(Effect.provide(context));
83
63
  });
84
64
 
85
- const registerSchedule = Effect.fnUntraced(function* (
65
+ const registerSchedule = Effect.fnUntraced(function* <R>(
86
66
  client: PgBossClient,
87
- worker: ScheduledWorker,
88
- context: Context.Context<unknown>,
67
+ worker: ScheduledWorker<R>,
68
+ context: Context.Context<R>,
89
69
  scope: Scope.Scope,
90
70
  schema: string,
91
71
  stop: StopOptions | undefined,
@@ -117,7 +97,7 @@ export function registrationNames(registrations: readonly JobRegistration[]): re
117
97
 
118
98
  export const registerJobs = Effect.fnUntraced(function* <R>(
119
99
  client: PgBossClient,
120
- registrations: readonly JobRegistration[],
100
+ registrations: readonly JobRegistration<R>[],
121
101
  context: Context.Context<R>,
122
102
  replaceWorkers: boolean,
123
103
  schema = "pgboss",
@@ -127,15 +107,17 @@ export const registerJobs = Effect.fnUntraced(function* <R>(
127
107
  const scope = yield* Scope.fork(yield* Effect.scope, "parallel");
128
108
  yield* Effect.try({ catch: (error) => toPgBossError("register", error), try: () => registrationNames(registrations) });
129
109
  yield* prepareQueues(client, registrations, replaceWorkers);
110
+ for (const registration of registrations) {
111
+ registerTestingQueue(client, registrationName(registration));
112
+ }
130
113
  if (!startWorkers) {
131
114
  return;
132
115
  }
133
- const provided = workerContext(context);
134
116
  for (const registration of registrations) {
135
- if (isQueueWorker(registration) || isQueueDefinition(registration)) {
136
- yield* registerQueue(client, registration, provided, scope, schema, stop);
137
- } else if (isScheduledWorker(registration)) {
138
- yield* registerSchedule(client, registration, provided, scope, schema, stop);
117
+ if (registration._tag === "QueueWorker" || registration._tag === "QueueDefinition") {
118
+ yield* registerQueue(client, registration, context, scope, schema, stop);
119
+ } else {
120
+ yield* registerSchedule(client, registration, context, scope, schema, stop);
139
121
  }
140
122
  }
141
123
  });
@@ -1,15 +1,15 @@
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>(
11
11
  client: PgBossClient,
12
- jobs: readonly JobRegistration[],
12
+ jobs: readonly JobRegistration<R>[],
13
13
  context: Context.Context<R>,
14
14
  replaceWorkers: boolean,
15
15
  schema: string | undefined,
@@ -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,13 +1,19 @@
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 { 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
- export function runQueueWorker(worker: QueueWorker, job: Job<unknown>, deadline: number, client: PgBossClient, schema: string) {
10
+ export function runQueueWorker<R>(
11
+ worker: QueueWorker<JobPayloadSchema & { readonly DecodingServices: R }, R>,
12
+ job: WorkerJob<unknown>,
13
+ deadline: number,
14
+ client: PgBossClient,
15
+ schema: string,
16
+ ) {
11
17
  return Schema.decodeUnknownEffect(Schema.toCodecJson(worker.queue.schema))(payloadOf(job.data)).pipe(
12
18
  Effect.mapError(
13
19
  (error) =>
@@ -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
1
  import { DateTime } from "effect";
2
- import type { PgBoss } from "pg-boss";
3
- import type { QueueDefinition } from "#definition.ts";
4
- import { deferralOf } from "#internal/deferral.ts";
5
- import { testingOperation } from "#internal/testingReadout.ts";
2
+ import type { QueueDefinition } from "#server/definition.ts";
3
+ import type { EngineClient } from "#server/engineClient.ts";
4
+ import { deferralOf } from "#server/internal/deferral.ts";
5
+ import { testingOperation } from "#server/internal/testingReadout.ts";
6
6
 
7
- export function testingDeferrals(client: () => PgBoss) {
7
+ export function testingDeferrals(client: () => EngineClient) {
8
8
  return {
9
9
  deferred: (queue: Pick<QueueDefinition, "name">) =>
10
10
  testingOperation(
@@ -1,8 +1,8 @@
1
- import { 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, Schema } from "effect";
2
+ import type { EngineClient } from "#server/engineClient.ts";
3
+ import type { PgBossTestingError } from "#server/error.ts";
4
+ import { quotedSchema } from "#server/internal/storedRows.ts";
5
+ import { testingOperation } from "#server/internal/testingReadout.ts";
6
6
 
7
7
  export interface TestingBatch {
8
8
  readonly name: string;
@@ -17,7 +17,7 @@ export interface TestingWork {
17
17
  const Busy = Schema.Struct({ busy: Schema.Boolean });
18
18
 
19
19
  export function testingIdle(
20
- client: () => PgBoss,
20
+ client: () => EngineClient,
21
21
  schema: () => string,
22
22
  work: TestingWork,
23
23
  signal: { readonly revision: Effect.Effect<number>; readonly waitForChange: (after: number) => Effect.Effect<number> },
@@ -46,7 +46,12 @@ export function testingIdle(
46
46
  if (work.queues.size === 0 || !(unsettled || (yield* busy))) {
47
47
  return;
48
48
  }
49
- yield* signal.waitForChange(revision);
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
+ }
50
55
  }
51
- });
56
+ }).pipe(Effect.provideService(Clock.Clock, Clock.Clock.defaultValue()));
52
57
  }
@@ -1,8 +1,11 @@
1
1
  import { Effect, Redacted } from "effect";
2
- import type { FindJobsOptions, PgBoss } from "pg-boss";
3
- import type { JobPayloadSchema, QueueDefinition } from "#definition.ts";
4
- import { PgBossTestingError } from "#error.ts";
5
- import { decodeStoredData } from "#internal/storedRows.ts";
2
+ import type { JobReadOptions } from "#server/client.ts";
3
+ import type { JobPayloadSchema, QueueDefinition } from "#server/definition.ts";
4
+ import type { EngineClient } from "#server/engineClient.ts";
5
+ import type { PgBossPayloadError } from "#server/error.ts";
6
+ import { PgBossTestingError } from "#server/error.ts";
7
+ import { decodeStoredData } from "#server/internal/storedRows.ts";
8
+ import type { Job } from "#server/job.ts";
6
9
 
7
10
  export function testingOperation<A>(operation: string, run: () => Promise<A>, queue?: string) {
8
11
  return Effect.tryPromise({
@@ -11,8 +14,11 @@ export function testingOperation<A>(operation: string, run: () => Promise<A>, qu
11
14
  });
12
15
  }
13
16
 
14
- export function testingReadout(client: () => PgBoss) {
15
- return <TName extends string, TPayload extends JobPayloadSchema>(queue: QueueDefinition<TName, TPayload>, options?: FindJobsOptions) =>
17
+ export function testingReadout(client: () => EngineClient) {
18
+ return <TName extends string, TPayload extends JobPayloadSchema>(
19
+ queue: QueueDefinition<TName, TPayload>,
20
+ options?: JobReadOptions,
21
+ ): Effect.Effect<Job<TPayload["Type"]>[], PgBossTestingError | PgBossPayloadError, TPayload["DecodingServices"]> =>
16
22
  testingOperation("jobs", () => client().findJobs<unknown>(queue.name, options), queue.name).pipe(
17
23
  Effect.flatMap((jobs) => Effect.forEach(jobs, (job) => decodeStoredData(queue, job.data).pipe(Effect.map((data) => ({ ...job, data }))))),
18
24
  );