@shivaedev/jobs 0.0.0 → 0.19.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.
- package/CHANGELOG.md +319 -0
- package/LICENSE +21 -0
- package/README.md +527 -1
- package/dist/server/client.d.ts +25 -0
- package/dist/server/client.d.ts.map +1 -0
- package/dist/server/client.js +3 -0
- package/dist/server/client.js.map +1 -0
- package/dist/server/definition.d.ts +96 -0
- package/dist/server/definition.d.ts.map +1 -0
- package/dist/server/definition.js +40 -0
- package/dist/server/definition.js.map +1 -0
- package/dist/server/error.d.ts +51 -0
- package/dist/server/error.d.ts.map +1 -0
- package/dist/server/error.js +37 -0
- package/dist/server/error.js.map +1 -0
- package/dist/server/health.d.ts +51 -0
- package/dist/server/health.d.ts.map +1 -0
- package/dist/server/health.js +4 -0
- package/dist/server/health.js.map +1 -0
- package/dist/server/internal/batchHandler.d.ts +5 -0
- package/dist/server/internal/batchHandler.d.ts.map +1 -0
- package/dist/server/internal/batchHandler.js +51 -0
- package/dist/server/internal/batchHandler.js.map +1 -0
- package/dist/server/internal/clientCache.d.ts +8 -0
- package/dist/server/internal/clientCache.d.ts.map +1 -0
- package/dist/server/internal/clientCache.js +61 -0
- package/dist/server/internal/clientCache.js.map +1 -0
- package/dist/server/internal/clientErrors.d.ts +8 -0
- package/dist/server/internal/clientErrors.d.ts.map +1 -0
- package/dist/server/internal/clientErrors.js +49 -0
- package/dist/server/internal/clientErrors.js.map +1 -0
- package/dist/server/internal/countsFor.d.ts +5 -0
- package/dist/server/internal/countsFor.d.ts.map +1 -0
- package/dist/server/internal/countsFor.js +28 -0
- package/dist/server/internal/countsFor.js.map +1 -0
- package/dist/server/internal/deadlineOf.d.ts +3 -0
- package/dist/server/internal/deadlineOf.d.ts.map +1 -0
- package/dist/server/internal/deadlineOf.js +7 -0
- package/dist/server/internal/deadlineOf.js.map +1 -0
- package/dist/server/internal/deferrableAttempt.d.ts +7 -0
- package/dist/server/internal/deferrableAttempt.d.ts.map +1 -0
- package/dist/server/internal/deferrableAttempt.js +28 -0
- package/dist/server/internal/deferrableAttempt.js.map +1 -0
- package/dist/server/internal/deferral.d.ts +15 -0
- package/dist/server/internal/deferral.d.ts.map +1 -0
- package/dist/server/internal/deferral.js +14 -0
- package/dist/server/internal/deferral.js.map +1 -0
- package/dist/server/internal/deferralStorePlan.d.ts +2 -0
- package/dist/server/internal/deferralStorePlan.d.ts.map +1 -0
- package/dist/server/internal/deferralStorePlan.js +35 -0
- package/dist/server/internal/deferralStorePlan.js.map +1 -0
- package/dist/server/internal/definitionOptions.d.ts +17 -0
- package/dist/server/internal/definitionOptions.d.ts.map +1 -0
- package/dist/server/internal/definitionOptions.js +12 -0
- package/dist/server/internal/definitionOptions.js.map +1 -0
- package/dist/server/internal/enqueueFor.d.ts +4 -0
- package/dist/server/internal/enqueueFor.d.ts.map +1 -0
- package/dist/server/internal/enqueueFor.js +23 -0
- package/dist/server/internal/enqueueFor.js.map +1 -0
- package/dist/server/internal/ensureQueue.d.ts +4 -0
- package/dist/server/internal/ensureQueue.d.ts.map +1 -0
- package/dist/server/internal/ensureQueue.js +44 -0
- package/dist/server/internal/ensureQueue.js.map +1 -0
- package/dist/server/internal/expireAttempt.d.ts +3 -0
- package/dist/server/internal/expireAttempt.d.ts.map +1 -0
- package/dist/server/internal/expireAttempt.js +17 -0
- package/dist/server/internal/expireAttempt.js.map +1 -0
- package/dist/server/internal/healthFor.d.ts +5 -0
- package/dist/server/internal/healthFor.d.ts.map +1 -0
- package/dist/server/internal/healthFor.js +27 -0
- package/dist/server/internal/healthFor.js.map +1 -0
- package/dist/server/internal/jobControl.d.ts +5 -0
- package/dist/server/internal/jobControl.d.ts.map +1 -0
- package/dist/server/internal/jobControl.js +35 -0
- package/dist/server/internal/jobControl.js.map +1 -0
- package/dist/server/internal/lifecycle.d.ts +17 -0
- package/dist/server/internal/lifecycle.d.ts.map +1 -0
- package/dist/server/internal/lifecycle.js +55 -0
- package/dist/server/internal/lifecycle.js.map +1 -0
- package/dist/server/internal/listJobs.d.ts +5 -0
- package/dist/server/internal/listJobs.d.ts.map +1 -0
- package/dist/server/internal/listJobs.js +69 -0
- package/dist/server/internal/listJobs.js.map +1 -0
- package/dist/server/internal/makeService.d.ts +4 -0
- package/dist/server/internal/makeService.d.ts.map +1 -0
- package/dist/server/internal/makeService.js +17 -0
- package/dist/server/internal/makeService.js.map +1 -0
- package/dist/server/internal/nativeClient.d.ts +3 -0
- package/dist/server/internal/nativeClient.d.ts.map +1 -0
- package/dist/server/internal/nativeClient.js +28 -0
- package/dist/server/internal/nativeClient.js.map +1 -0
- package/dist/server/internal/observeTestingSettlements.d.ts +6 -0
- package/dist/server/internal/observeTestingSettlements.d.ts.map +1 -0
- package/dist/server/internal/observeTestingSettlements.js +35 -0
- package/dist/server/internal/observeTestingSettlements.js.map +1 -0
- package/dist/server/internal/register.d.ts +8 -0
- package/dist/server/internal/register.d.ts.map +1 -0
- package/dist/server/internal/register.js +98 -0
- package/dist/server/internal/register.js.map +1 -0
- package/dist/server/internal/registerReleasedJobs.d.ts +5 -0
- package/dist/server/internal/registerReleasedJobs.d.ts.map +1 -0
- package/dist/server/internal/registerReleasedJobs.js +35 -0
- package/dist/server/internal/registerReleasedJobs.js.map +1 -0
- package/dist/server/internal/registerWorker.d.ts +5 -0
- package/dist/server/internal/registerWorker.d.ts.map +1 -0
- package/dist/server/internal/registerWorker.js +33 -0
- package/dist/server/internal/registerWorker.js.map +1 -0
- package/dist/server/internal/runSchemaPlan.d.ts +7 -0
- package/dist/server/internal/runSchemaPlan.d.ts.map +1 -0
- package/dist/server/internal/runSchemaPlan.js +25 -0
- package/dist/server/internal/runSchemaPlan.js.map +1 -0
- package/dist/server/internal/scheduleDefinition.d.ts +3 -0
- package/dist/server/internal/scheduleDefinition.d.ts.map +1 -0
- package/dist/server/internal/scheduleDefinition.js +19 -0
- package/dist/server/internal/scheduleDefinition.js.map +1 -0
- package/dist/server/internal/schemaIndexBuilds.d.ts +4 -0
- package/dist/server/internal/schemaIndexBuilds.d.ts.map +1 -0
- package/dist/server/internal/schemaIndexBuilds.js +34 -0
- package/dist/server/internal/schemaIndexBuilds.js.map +1 -0
- package/dist/server/internal/settleDeferral.d.ts +7 -0
- package/dist/server/internal/settleDeferral.d.ts.map +1 -0
- package/dist/server/internal/settleDeferral.js +48 -0
- package/dist/server/internal/settleDeferral.js.map +1 -0
- package/dist/server/internal/storedRows.d.ts +6 -0
- package/dist/server/internal/storedRows.d.ts.map +1 -0
- package/dist/server/internal/storedRows.js +10 -0
- package/dist/server/internal/storedRows.js.map +1 -0
- package/dist/server/internal/testingClient.d.ts +13 -0
- package/dist/server/internal/testingClient.d.ts.map +1 -0
- package/dist/server/internal/testingClient.js +117 -0
- package/dist/server/internal/testingClient.js.map +1 -0
- package/dist/server/internal/testingDeferrals.d.ts +11 -0
- package/dist/server/internal/testingDeferrals.d.ts.map +1 -0
- package/dist/server/internal/testingDeferrals.js +29 -0
- package/dist/server/internal/testingDeferrals.js.map +1 -0
- package/dist/server/internal/testingExpirations.d.ts +6 -0
- package/dist/server/internal/testingExpirations.d.ts.map +1 -0
- package/dist/server/internal/testingExpirations.js +27 -0
- package/dist/server/internal/testingExpirations.js.map +1 -0
- package/dist/server/internal/testingIdle.d.ts +16 -0
- package/dist/server/internal/testingIdle.d.ts.map +1 -0
- package/dist/server/internal/testingIdle.js +31 -0
- package/dist/server/internal/testingIdle.js.map +1 -0
- package/dist/server/internal/testingReadout.d.ts +44 -0
- package/dist/server/internal/testingReadout.d.ts.map +1 -0
- package/dist/server/internal/testingReadout.js +13 -0
- package/dist/server/internal/testingReadout.js.map +1 -0
- package/dist/server/internal/testingSignal.d.ts +7 -0
- package/dist/server/internal/testingSignal.d.ts.map +1 -0
- package/dist/server/internal/testingSignal.js +29 -0
- package/dist/server/internal/testingSignal.js.map +1 -0
- package/dist/server/internal/testingSnapshot.d.ts +6 -0
- package/dist/server/internal/testingSnapshot.d.ts.map +1 -0
- package/dist/server/internal/testingSnapshot.js +32 -0
- package/dist/server/internal/testingSnapshot.js.map +1 -0
- package/dist/server/internal/tracing.d.ts +6 -0
- package/dist/server/internal/tracing.d.ts.map +1 -0
- package/dist/server/internal/tracing.js +37 -0
- package/dist/server/internal/tracing.js.map +1 -0
- package/dist/server/internal/waitForBatchExpiry.d.ts +6 -0
- package/dist/server/internal/waitForBatchExpiry.d.ts.map +1 -0
- package/dist/server/internal/waitForBatchExpiry.js +28 -0
- package/dist/server/internal/waitForBatchExpiry.js.map +1 -0
- package/dist/server/schema.d.ts +10 -0
- package/dist/server/schema.d.ts.map +1 -0
- package/dist/server/schema.js +67 -0
- package/dist/server/schema.js.map +1 -0
- package/dist/server/service.d.ts +29 -0
- package/dist/server/service.d.ts.map +1 -0
- package/dist/server/service.js +33 -0
- package/dist/server/service.js.map +1 -0
- package/dist/server/testing.d.ts +77 -0
- package/dist/server/testing.d.ts.map +1 -0
- package/dist/server/testing.js +90 -0
- package/dist/server/testing.js.map +1 -0
- package/package.json +71 -4
- package/src/server/client.ts +40 -0
- package/src/server/definition.ts +140 -0
- package/src/server/error.ts +73 -0
- package/src/server/health.ts +60 -0
- package/src/server/internal/batchHandler.ts +71 -0
- package/src/server/internal/clientCache.ts +73 -0
- package/src/server/internal/clientErrors.ts +64 -0
- package/src/server/internal/countsFor.ts +34 -0
- package/src/server/internal/deadlineOf.ts +8 -0
- package/src/server/internal/deferrableAttempt.ts +41 -0
- package/src/server/internal/deferral.ts +19 -0
- package/src/server/internal/deferralStorePlan.ts +35 -0
- package/src/server/internal/definitionOptions.ts +14 -0
- package/src/server/internal/enqueueFor.ts +39 -0
- package/src/server/internal/ensureQueue.ts +47 -0
- package/src/server/internal/expireAttempt.ts +21 -0
- package/src/server/internal/healthFor.ts +35 -0
- package/src/server/internal/jobControl.ts +44 -0
- package/src/server/internal/lifecycle.ts +68 -0
- package/src/server/internal/listJobs.ts +98 -0
- package/src/server/internal/makeService.ts +19 -0
- package/src/server/internal/nativeClient.ts +30 -0
- package/src/server/internal/observeTestingSettlements.ts +36 -0
- package/src/server/internal/register.ts +145 -0
- package/src/server/internal/registerReleasedJobs.ts +44 -0
- package/src/server/internal/registerWorker.ts +56 -0
- package/src/server/internal/runSchemaPlan.ts +32 -0
- package/src/server/internal/scheduleDefinition.ts +21 -0
- package/src/server/internal/schemaIndexBuilds.ts +44 -0
- package/src/server/internal/settleDeferral.ts +54 -0
- package/src/server/internal/storedRows.ts +17 -0
- package/src/server/internal/testingClient.ts +134 -0
- package/src/server/internal/testingDeferrals.ts +44 -0
- package/src/server/internal/testingExpirations.ts +31 -0
- package/src/server/internal/testingIdle.ts +52 -0
- package/src/server/internal/testingReadout.ts +19 -0
- package/src/server/internal/testingSignal.ts +30 -0
- package/src/server/internal/testingSnapshot.ts +53 -0
- package/src/server/internal/tracing.ts +44 -0
- package/src/server/internal/waitForBatchExpiry.ts +30 -0
- package/src/server/schema.ts +84 -0
- package/src/server/service.ts +100 -0
- package/src/server/testing.ts +118 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeClient.d.ts","sourceRoot":"","sources":["../../../src/server/internal/nativeClient.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,kBAAkB,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1D,wBAAgB,YAAY,CAAC,OAAO,EAAE,kBAAkB,UA0BvD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Socket } from "node:net";
|
|
2
|
+
import { PgBoss } from "pg-boss";
|
|
3
|
+
export function nativeClient(options) {
|
|
4
|
+
const disconnected = new Set();
|
|
5
|
+
const config = {
|
|
6
|
+
...options,
|
|
7
|
+
stream: () => {
|
|
8
|
+
const socket = new Socket();
|
|
9
|
+
const closed = new Promise((resolve) => socket.once("close", () => {
|
|
10
|
+
disconnected.delete(closed);
|
|
11
|
+
resolve();
|
|
12
|
+
}));
|
|
13
|
+
disconnected.add(closed);
|
|
14
|
+
return socket;
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
const client = new PgBoss(config);
|
|
18
|
+
const stop = client.stop.bind(client);
|
|
19
|
+
client.stop = async (stopOptions) => {
|
|
20
|
+
await stop(stopOptions);
|
|
21
|
+
// pg-boss's pool shutdown does not wait for its transports to disconnect.
|
|
22
|
+
if (stopOptions?.close !== false) {
|
|
23
|
+
await Promise.all([...disconnected]);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
return client;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=nativeClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeClient.js","sourceRoot":"","sources":["../../../src/server/internal/nativeClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAA2B,MAAM,EAAE,MAAM,SAAS,CAAC;AAE1D,MAAM,UAAU,YAAY,CAAC,OAA2B;IACvD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAiB,CAAC;IAC9C,MAAM,MAAM,GAAG;QACd,GAAG,OAAO;QACV,MAAM,EAAE,GAAG,EAAE;YACZ,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;gBACzB,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC5B,OAAO,EAAE,CAAC;YACX,CAAC,CAAC,CACF,CAAC;YACF,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzB,OAAO,MAAM,CAAC;QACf,CAAC;KACD,CAAC;IACF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IAClC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,CAAC,IAAI,GAAG,KAAK,EAAE,WAAW,EAAE,EAAE;QACnC,MAAM,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,0EAA0E;QAC1E,IAAI,WAAW,EAAE,KAAK,KAAK,KAAK,EAAE,CAAC;YAClC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;QACtC,CAAC;IACF,CAAC,CAAC;IACF,OAAO,MAAM,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observeTestingSettlements.d.ts","sourceRoot":"","sources":["../../../src/server/internal/observeTestingSettlements.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI;IAGvF,KAAK;IAML,KAAK,OAAO,MAAM;EAwBnB"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function observeTestingSettlements(client, settled) {
|
|
2
|
+
const observers = new Map();
|
|
3
|
+
return {
|
|
4
|
+
close() {
|
|
5
|
+
for (const close of observers.values()) {
|
|
6
|
+
close();
|
|
7
|
+
}
|
|
8
|
+
observers.clear();
|
|
9
|
+
},
|
|
10
|
+
watch(name) {
|
|
11
|
+
if (observers.has(name)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const spy = client.getSpy(name);
|
|
15
|
+
let open = true;
|
|
16
|
+
async function observe() {
|
|
17
|
+
while (true) {
|
|
18
|
+
await Promise.race([spy.waitForJob(() => true, "completed"), spy.waitForJob(() => true, "failed")]);
|
|
19
|
+
if (!open) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
// This controller owns the spy; clear history and the losing wait before rearming both outcomes.
|
|
23
|
+
spy.clear();
|
|
24
|
+
settled(name);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
observers.set(name, () => {
|
|
28
|
+
open = false;
|
|
29
|
+
spy.clear();
|
|
30
|
+
});
|
|
31
|
+
void observe().catch((error) => client.emit("error", error instanceof Error ? error : new Error(String(error))));
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=observeTestingSettlements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observeTestingSettlements.js","sourceRoot":"","sources":["../../../src/server/internal/observeTestingSettlements.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,yBAAyB,CAAC,MAAc,EAAE,OAA+B;IACxF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAsB,CAAC;IAChD,OAAO;QACN,KAAK;YACJ,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxC,KAAK,EAAE,CAAC;YACT,CAAC;YACD,SAAS,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QACD,KAAK,CAAC,IAAY;YACjB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,OAAO;YACR,CAAC;YACD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAChC,IAAI,IAAI,GAAG,IAAI,CAAC;YAChB,KAAK,UAAU,OAAO;gBACrB,OAAO,IAAI,EAAE,CAAC;oBACb,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACpG,IAAI,CAAC,IAAI,EAAE,CAAC;wBACX,OAAO;oBACR,CAAC;oBACD,iGAAiG;oBACjG,GAAG,CAAC,KAAK,EAAE,CAAC;oBACZ,OAAO,CAAC,IAAI,CAAC,CAAC;gBACf,CAAC;YACF,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE;gBACxB,IAAI,GAAG,KAAK,CAAC;gBACb,GAAG,CAAC,KAAK,EAAE,CAAC;YACb,CAAC,CAAC,CAAC;YACH,KAAK,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3H,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type Context, Effect, type Scope } from "effect";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
import { type JobRegistration } from "#definition.ts";
|
|
4
|
+
import { PgBossError, PgBossQueueOptionsError } from "#error.ts";
|
|
5
|
+
export declare function registrationName(registration: JobRegistration): string;
|
|
6
|
+
export declare function registrationNames(registrations: readonly JobRegistration[]): readonly string[];
|
|
7
|
+
export declare function registerJobs<R>(client: PgBossClient, registrations: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema?: string, startWorkers?: boolean): Effect.Effect<void, PgBossError | PgBossQueueOptionsError, Scope.Scope>;
|
|
8
|
+
//# sourceMappingURL=register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.d.ts","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAoB,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EACN,KAAK,eAAe,EAMpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,WAAW,EAAsB,uBAAuB,EAAiB,MAAM,WAAW,CAAC;AA8BpG,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,eAAe,GAAG,MAAM,CAEtE;AAiED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,MAAM,EAAE,CAM9F;AAED,wBAAgB,YAAY,CAAC,CAAC,EAC7B,MAAM,EAAE,YAAY,EACpB,aAAa,EAAE,SAAS,eAAe,EAAE,EACzC,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAC3B,cAAc,EAAE,OAAO,EACvB,MAAM,SAAW,EACjB,YAAY,UAAO,GACjB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,uBAAuB,EAAE,KAAK,CAAC,KAAK,CAAC,CAqBzE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Effect, Redacted, Schema } from "effect";
|
|
2
|
+
import { jobContext, } from "#definition.ts";
|
|
3
|
+
import { PgBossError, PgBossPayloadError, PgBossQueueOptionsError, toPgBossError } from "#error.ts";
|
|
4
|
+
import { ensureQueue } from "#internal/ensureQueue.ts";
|
|
5
|
+
import { registerWorker } from "#internal/registerWorker.ts";
|
|
6
|
+
import { payloadOf } from "#internal/tracing.ts";
|
|
7
|
+
function isQueueWorker(registration) {
|
|
8
|
+
return registration._tag === "QueueWorker";
|
|
9
|
+
}
|
|
10
|
+
function isScheduledWorker(registration) {
|
|
11
|
+
return registration._tag === "ScheduledWorker";
|
|
12
|
+
}
|
|
13
|
+
function isQueueDefinition(registration) {
|
|
14
|
+
return registration._tag === "QueueDefinition";
|
|
15
|
+
}
|
|
16
|
+
function registrationDefinition(registration) {
|
|
17
|
+
if (isQueueDefinition(registration)) {
|
|
18
|
+
return registration;
|
|
19
|
+
}
|
|
20
|
+
if (isQueueWorker(registration)) {
|
|
21
|
+
return registration.queue;
|
|
22
|
+
}
|
|
23
|
+
if (isScheduledWorker(registration)) {
|
|
24
|
+
return registration.schedule;
|
|
25
|
+
}
|
|
26
|
+
throw new TypeError(`Unknown pg-boss registration: ${registration._tag}`);
|
|
27
|
+
}
|
|
28
|
+
export function registrationName(registration) {
|
|
29
|
+
return registrationDefinition(registration).name;
|
|
30
|
+
}
|
|
31
|
+
async function prepareQueues(client, registrations, replaceWorkers) {
|
|
32
|
+
for (const registration of registrations) {
|
|
33
|
+
if (replaceWorkers && !isQueueDefinition(registration)) {
|
|
34
|
+
await client.offWork(registrationName(registration));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const registration of registrations) {
|
|
38
|
+
const definition = registrationDefinition(registration);
|
|
39
|
+
try {
|
|
40
|
+
await ensureQueue(client, definition.name, definition.queueOptions);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
throw error instanceof PgBossQueueOptionsError ? error : toPgBossError("register", error, definition.name);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function workerContext(context) {
|
|
48
|
+
return context;
|
|
49
|
+
}
|
|
50
|
+
function runQueueWorker(worker, job) {
|
|
51
|
+
return Schema.decodeUnknownEffect(worker.queue.schema)(payloadOf(job.data)).pipe(Effect.mapError((error) => new PgBossPayloadError({
|
|
52
|
+
direction: "decode",
|
|
53
|
+
original: Redacted.make(error),
|
|
54
|
+
queue: worker.queue.name,
|
|
55
|
+
})), Effect.flatMap((payload) => worker.handler(payload, jobContext(job))));
|
|
56
|
+
}
|
|
57
|
+
async function registerQueue(client, registration, context, scope, schema) {
|
|
58
|
+
const queue = registration._tag === "QueueWorker" ? registration.queue : registration;
|
|
59
|
+
const name = queue.name;
|
|
60
|
+
if (registration._tag === "QueueDefinition") {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
await registerWorker(client, name, queue.workerOptions, (job) => runQueueWorker(registration, job), scope, schema, queue.maxDeferrals, context);
|
|
64
|
+
}
|
|
65
|
+
async function registerSchedule(client, worker, context, scope, schema) {
|
|
66
|
+
const { schedule } = worker;
|
|
67
|
+
await registerWorker(client, schedule.name, schedule.workerOptions, () => worker.effect, scope, schema, schedule.maxDeferrals, context);
|
|
68
|
+
await client.schedule(schedule.name, schedule.cron, null, schedule.scheduleOptions);
|
|
69
|
+
}
|
|
70
|
+
export function registrationNames(registrations) {
|
|
71
|
+
const names = registrations.map(registrationName);
|
|
72
|
+
if (new Set(names).size !== names.length) {
|
|
73
|
+
throw new TypeError("pg-boss job names must be unique");
|
|
74
|
+
}
|
|
75
|
+
return names;
|
|
76
|
+
}
|
|
77
|
+
export function registerJobs(client, registrations, context, replaceWorkers, schema = "pgboss", startWorkers = true) {
|
|
78
|
+
return Effect.flatMap(Effect.scope, (scope) => Effect.tryPromise({
|
|
79
|
+
catch: (error) => (error instanceof PgBossQueueOptionsError || error instanceof PgBossError ? error : toPgBossError("register", error)),
|
|
80
|
+
try: async () => {
|
|
81
|
+
registrationNames(registrations);
|
|
82
|
+
await prepareQueues(client, registrations, replaceWorkers);
|
|
83
|
+
if (!startWorkers) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const provided = workerContext(context);
|
|
87
|
+
for (const registration of registrations) {
|
|
88
|
+
if (isQueueWorker(registration) || isQueueDefinition(registration)) {
|
|
89
|
+
await registerQueue(client, registration, provided, scope, schema);
|
|
90
|
+
}
|
|
91
|
+
else if (isScheduledWorker(registration)) {
|
|
92
|
+
await registerSchedule(client, registration, provided, scope, schema);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/server/internal/register.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Context, Effect, Scope } from "effect";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
import type { JobRegistration } from "#definition.ts";
|
|
4
|
+
export declare const registerReleasedJobs: <R>(client: PgBossClient, jobs: readonly JobRegistration[], context: Context.Context<R>, replaceWorkers: boolean, schema?: string | undefined) => Effect.Effect<void, import("#error.ts").PgBossError | import("#error.ts").PgBossQueueOptionsError, Scope.Scope>;
|
|
5
|
+
//# sourceMappingURL=registerReleasedJobs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerReleasedJobs.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE7D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,eAAO,MAAM,oBAAoB,GAAgC,CAAC,+PAoChE,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Effect, Option, Scope } from "effect";
|
|
2
|
+
import { WorkerRelease } from "@shivaedev/sql/WorkerRelease.ts";
|
|
3
|
+
import { toPgBossError } from "#error.ts";
|
|
4
|
+
import { registerJobs, registrationName } from "./register.js";
|
|
5
|
+
export const registerReleasedJobs = Effect.fnUntraced(function* (client, jobs, context, replaceWorkers, schema) {
|
|
6
|
+
const signal = yield* Effect.serviceOption(WorkerRelease);
|
|
7
|
+
const workers = jobs.filter((job) => job._tag !== "QueueDefinition");
|
|
8
|
+
const scope = yield* Effect.scope;
|
|
9
|
+
const register = registerJobs(client, jobs, context, replaceWorkers, schema).pipe(Effect.provideService(Scope.Scope, scope));
|
|
10
|
+
if (Option.isNone(signal) || workers.length === 0) {
|
|
11
|
+
return yield* register;
|
|
12
|
+
}
|
|
13
|
+
yield* registerJobs(client, jobs, context, replaceWorkers, schema, false);
|
|
14
|
+
let working = replaceWorkers;
|
|
15
|
+
let paused = false;
|
|
16
|
+
yield* signal.value.register((active) => Effect.gen(function* () {
|
|
17
|
+
if (active) {
|
|
18
|
+
yield* register;
|
|
19
|
+
working = true;
|
|
20
|
+
if (paused) {
|
|
21
|
+
yield* Effect.logInfo("Workers resumed for database release");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (working) {
|
|
25
|
+
yield* Effect.tryPromise({
|
|
26
|
+
catch: (error) => toPgBossError("register", error),
|
|
27
|
+
try: () => Promise.all(workers.map((job) => client.offWork(registrationName(job)))),
|
|
28
|
+
});
|
|
29
|
+
working = false;
|
|
30
|
+
paused = true;
|
|
31
|
+
yield* Effect.logInfo("Workers paused for another database release");
|
|
32
|
+
}
|
|
33
|
+
}).pipe(Effect.provide(context)));
|
|
34
|
+
});
|
|
35
|
+
//# sourceMappingURL=registerReleasedJobs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerReleasedJobs.js","sourceRoot":"","sources":["../../../src/server/internal/registerReleasedJobs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAGhE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAC9D,MAAoB,EACpB,IAAgC,EAChC,OAA2B,EAC3B,cAAuB,EACvB,MAAe;IAEf,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,iBAAiB,CAAC,CAAC;IACrE,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;IAClC,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7H,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnD,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC;IACxB,CAAC;IACD,KAAK,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IAC1E,IAAI,OAAO,GAAG,cAAc,CAAC;IAC7B,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,CACvC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QACnB,IAAI,MAAM,EAAE,CAAC;YACZ,KAAK,CAAC,CAAC,QAAQ,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,IAAI,MAAM,EAAE,CAAC;gBACZ,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,sCAAsC,CAAC,CAAC;YAC/D,CAAC;QACF,CAAC;aAAM,IAAI,OAAO,EAAE,CAAC;YACpB,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBACxB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,KAAK,CAAC;gBAClD,GAAG,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACnF,CAAC,CAAC;YACH,OAAO,GAAG,KAAK,CAAC;YAChB,MAAM,GAAG,IAAI,CAAC;YACd,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,6CAA6C,CAAC,CAAC;QACtE,CAAC;IACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAChC,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type Context, Effect, type Scope } from "effect";
|
|
2
|
+
import type { Job, WorkOptions } from "pg-boss";
|
|
3
|
+
import type { PgBossClient } from "#client.ts";
|
|
4
|
+
export declare function registerWorker(client: PgBossClient, name: string, options: WorkOptions, run: (job: Job<unknown>) => Effect.Effect<unknown, unknown, unknown>, scope: Scope.Scope, schema: string, maxDeferrals: number, context: Context.Context<unknown>): Promise<string>;
|
|
5
|
+
//# sourceMappingURL=registerWorker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerWorker.d.ts","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,OAAO,EAAE,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,QAAQ,CAAC;AACjE,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,wBAAgB,cAAc,CAC7B,MAAM,EAAE,YAAY,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EACpE,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Clock, Effect } from "effect";
|
|
2
|
+
import { batchHandler } from "#internal/batchHandler.ts";
|
|
3
|
+
import { deferrableAttempt } from "#internal/deferrableAttempt.ts";
|
|
4
|
+
import { traceJob } from "#internal/tracing.ts";
|
|
5
|
+
export function registerWorker(client, name, options, run, scope, schema, maxDeferrals, context) {
|
|
6
|
+
const registration = client.work(name, { ...options, includeMetadata: true }, batchHandler(client, name, (job) => {
|
|
7
|
+
const attempt = traceJob(deferrableAttempt(run(job), client, schema, job, maxDeferrals), job, name);
|
|
8
|
+
return Effect.provide(attempt, context);
|
|
9
|
+
}, async (attempt) => {
|
|
10
|
+
if (client.findJobs === undefined || client.notifyWorker === undefined) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const job = (await client.findJobs(name, { id: attempt.id }))[0];
|
|
14
|
+
if (job?.state !== "retry") {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const workId = await registration;
|
|
18
|
+
await Effect.runPromise(Effect.gen(function* () {
|
|
19
|
+
const now = yield* Clock.currentTimeMillis;
|
|
20
|
+
// PostgreSQL timestamps retain sub-millisecond precision that Date drops.
|
|
21
|
+
yield* Effect.sleep(Math.max(0, job.startAfter.getTime() + 1 - now));
|
|
22
|
+
const workerIds = client
|
|
23
|
+
.getWipData?.()
|
|
24
|
+
.filter((worker) => worker.workId === workId)
|
|
25
|
+
.map((worker) => worker.id) ?? [workId];
|
|
26
|
+
for (const workerId of workerIds) {
|
|
27
|
+
client.notifyWorker?.(workerId);
|
|
28
|
+
}
|
|
29
|
+
}).pipe(Effect.forkIn(scope)));
|
|
30
|
+
}, Effect.runPromiseWith(context)));
|
|
31
|
+
return registration;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=registerWorker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registerWorker.js","sourceRoot":"","sources":["../../../src/server/internal/registerWorker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAgB,MAAM,EAAc,MAAM,QAAQ,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEhD,MAAM,UAAU,cAAc,CAC7B,MAAoB,EACpB,IAAY,EACZ,OAAoB,EACpB,GAAoE,EACpE,KAAkB,EAClB,MAAc,EACd,YAAoB,EACpB,OAAiC;IAEjC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAC/B,IAAI,EACJ,EAAE,GAAG,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,EACrC,YAAY,CACX,MAAM,EACN,IAAI,EACJ,CAAC,GAAG,EAAE,EAAE;QACP,MAAM,OAAO,GAAG,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,YAAY,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC;QACpG,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,EACD,KAAK,EAAE,OAAO,EAAE,EAAE;QACjB,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACxE,OAAO;QACR,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,IAAI,GAAG,EAAE,KAAK,KAAK,OAAO,EAAE,CAAC;YAC5B,OAAO;QACR,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC;QAClC,MAAM,MAAM,CAAC,UAAU,CACtB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,iBAAiB,CAAC;YAC3C,0EAA0E;YAC1E,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;YACrE,MAAM,SAAS,GAAG,MAAM;iBACtB,UAAU,EAAE,EAAE;iBACd,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,KAAK,MAAM,CAAC;iBAC5C,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACzC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAClC,MAAM,CAAC,YAAY,EAAE,CAAC,QAAQ,CAAC,CAAC;YACjC,CAAC;QACF,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAC7B,CAAC;IACH,CAAC,EACD,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAC9B,CACD,CAAC;IACF,OAAO,YAAY,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Effect } from "effect";
|
|
2
|
+
import type { Connection } from "effect/sql/SqlConnection";
|
|
3
|
+
export declare function runSchemaPlan(connection: Connection, plan: string, run: <A, E>(effect: Effect.Effect<A, E>) => Promise<A>, upgrade?: {
|
|
4
|
+
readonly schema: string;
|
|
5
|
+
readonly version: number;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=runSchemaPlan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSchemaPlan.d.ts","sourceRoot":"","sources":["../../../src/server/internal/runSchemaPlan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACrC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAG3D,wBAAsB,aAAa,CAClC,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,EACtD,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC7D,OAAO,CAAC,IAAI,CAAC,CAsBf"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { pendingIndexInserts } from "./schemaIndexBuilds.js";
|
|
2
|
+
export async function runSchemaPlan(connection, plan, run, upgrade) {
|
|
3
|
+
// Native exported plans append concurrent index DDL after the migration transaction.
|
|
4
|
+
const parts = /^\s*BEGIN;(?<body>[\s\S]*)\n {4}COMMIT;(?<concurrent>[\s\S]*)$/u.exec(plan);
|
|
5
|
+
if (parts?.groups === undefined) {
|
|
6
|
+
throw new Error("Unrecognized pg-boss schema plan transaction");
|
|
7
|
+
}
|
|
8
|
+
const { body = "", concurrent = "" } = parts.groups;
|
|
9
|
+
function quote(text) {
|
|
10
|
+
return `'${text.replaceAll("'", "''")}'`;
|
|
11
|
+
}
|
|
12
|
+
const commands = concurrent
|
|
13
|
+
.trim()
|
|
14
|
+
.split(/;\s*(?:\n|$)/u)
|
|
15
|
+
.filter((statement) => statement.trim() !== "");
|
|
16
|
+
const pending = upgrade === undefined ? "" : pendingIndexInserts(upgrade.schema, upgrade.version, commands, quote);
|
|
17
|
+
// Effect SQL uses the extended protocol, which accepts one statement per command.
|
|
18
|
+
await run(connection.executeRaw(`DO ${quote(`BEGIN EXECUTE ${quote(`${body}\n${pending}`)}; END`)}`, []));
|
|
19
|
+
if (upgrade === undefined) {
|
|
20
|
+
for (const statement of commands) {
|
|
21
|
+
await run(connection.executeRaw(statement, []));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=runSchemaPlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runSchemaPlan.js","sourceRoot":"","sources":["../../../src/server/internal/runSchemaPlan.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,UAAsB,EACtB,IAAY,EACZ,GAAsD,EACtD,OAA+D;IAE/D,qFAAqF;IACrF,MAAM,KAAK,GAAG,iEAAiE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC3F,IAAI,KAAK,EAAE,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC;IACpD,SAAS,KAAK,CAAC,IAAY;QAC1B,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;IAC1C,CAAC;IACD,MAAM,QAAQ,GAAG,UAAU;SACzB,IAAI,EAAE;SACN,KAAK,CAAC,eAAe,CAAC;SACtB,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;IACnH,kFAAkF;IAClF,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,iBAAiB,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC1G,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;YAClC,MAAM,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC;QACjD,CAAC;IACF,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduleDefinition.d.ts","sourceRoot":"","sources":["../../../src/server/internal/scheduleDefinition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGhF,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,OAAO,EAAE,qBAAqB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAiB/H"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
2
|
+
export function scheduleDefinition(options) {
|
|
3
|
+
const definition = {
|
|
4
|
+
_tag: "ScheduleDefinition",
|
|
5
|
+
cron: options.cron,
|
|
6
|
+
maxDeferrals: maxDeferrals(options.queue),
|
|
7
|
+
name: options.name,
|
|
8
|
+
queueOptions: nativeQueueOptions(options.queue),
|
|
9
|
+
run: (effect) => Object.freeze({
|
|
10
|
+
_tag: "ScheduledWorker",
|
|
11
|
+
effect,
|
|
12
|
+
schedule: definition,
|
|
13
|
+
}),
|
|
14
|
+
scheduleOptions: Object.freeze({ tz: "UTC", ...options.schedule }),
|
|
15
|
+
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
16
|
+
};
|
|
17
|
+
return Object.freeze(definition);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=scheduleDefinition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduleDefinition.js","sourceRoot":"","sources":["../../../src/server/internal/scheduleDefinition.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAElF,MAAM,UAAU,kBAAkB,CAA6B,OAAqC;IACnG,MAAM,UAAU,GAA8B;QAC7C,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC;QACzC,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC;QAC/C,GAAG,EAAE,CAAC,MAAM,EAAE,EAAE,CACf,MAAM,CAAC,MAAM,CAAC;YACb,IAAI,EAAE,iBAA0B;YAChC,MAAM;YACN,QAAQ,EAAE,UAAU;SACpB,CAAC;QACH,eAAe,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAClE,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;KAC5F,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PgBoss } from "pg-boss";
|
|
2
|
+
export declare function pendingIndexInserts(schema: string, version: number, commands: readonly string[], quote: (text: string) => string): string;
|
|
3
|
+
export declare function resumeSchemaIndexes(client: PgBoss, schema: string): Promise<void>;
|
|
4
|
+
//# sourceMappingURL=schemaIndexBuilds.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaIndexBuilds.d.ts","sourceRoot":"","sources":["../../../src/server/internal/schemaIndexBuilds.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAgBtC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,CAQzI;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBvF"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
const BUILD_PREFIX = "effect-pg-boss-schema:";
|
|
2
|
+
function indexName(command) {
|
|
3
|
+
const match = /^\s*(?:CREATE (?:UNIQUE )?INDEX CONCURRENTLY IF NOT EXISTS |DROP INDEX CONCURRENTLY IF EXISTS (?:(?:"[^"]+"|\w+)\.))(?<name>\w+)/mu.exec(command);
|
|
4
|
+
const name = match?.groups?.name;
|
|
5
|
+
if (name === undefined) {
|
|
6
|
+
throw new Error("Unrecognized pg-boss concurrent index command");
|
|
7
|
+
}
|
|
8
|
+
return name;
|
|
9
|
+
}
|
|
10
|
+
export function pendingIndexInserts(schema, version, commands, quote) {
|
|
11
|
+
return commands
|
|
12
|
+
.map((command, position) => {
|
|
13
|
+
const table = indexName(command).replace(/_i\d+$/u, "");
|
|
14
|
+
const name = `${BUILD_PREFIX}${String(position).padStart(6, "0")}`;
|
|
15
|
+
return `INSERT INTO ${schema}.bam (name, version, table_name, command) VALUES (${quote(name)}, ${version}, ${quote(table)}, ${quote(command)});`;
|
|
16
|
+
})
|
|
17
|
+
.join("\n");
|
|
18
|
+
}
|
|
19
|
+
export async function resumeSchemaIndexes(client, schema) {
|
|
20
|
+
const db = client.getDb();
|
|
21
|
+
const { rows } = await db.executeSql(`SELECT id, command FROM ${schema}.bam WHERE starts_with(name, $1) AND status <> 'completed' ORDER BY created_on, name`, [BUILD_PREFIX]);
|
|
22
|
+
for (const row of rows) {
|
|
23
|
+
const name = indexName(row.command);
|
|
24
|
+
if (/^\s*CREATE /mu.test(row.command)) {
|
|
25
|
+
const probe = await db.executeSql("SELECT NOT indisvalid AS invalid FROM pg_index WHERE indexrelid = to_regclass($1)", [`${schema}.${name}`]);
|
|
26
|
+
if (probe.rows[0]?.invalid === true) {
|
|
27
|
+
await db.executeSql(`DROP INDEX CONCURRENTLY IF EXISTS ${schema}."${name}"`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
await db.executeSql(row.command);
|
|
31
|
+
await db.executeSql(`UPDATE ${schema}.bam SET status = 'completed', completed_on = clock_timestamp() WHERE id = $1`, [row.id]);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=schemaIndexBuilds.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemaIndexBuilds.js","sourceRoot":"","sources":["../../../src/server/internal/schemaIndexBuilds.ts"],"names":[],"mappings":"AAEA,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAE9C,SAAS,SAAS,CAAC,OAAe;IACjC,MAAM,KAAK,GACV,oIAAoI,CAAC,IAAI,CACxI,OAAO,CACP,CAAC;IACH,MAAM,IAAI,GAAG,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC;IACjC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAc,EAAE,OAAe,EAAE,QAA2B,EAAE,KAA+B;IAChI,OAAO,QAAQ;SACb,GAAG,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE;QAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,GAAG,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;QACnE,OAAO,eAAe,MAAM,qDAAqD,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,KAAK,KAAK,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IAClJ,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAc,EAAE,MAAc;IACvE,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC1B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,EAAE,CAAC,UAAU,CACnC,2BAA2B,MAAM,sFAAsF,EACvH,CAAC,YAAY,CAAC,CACd,CAAC;IACF,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,mFAAmF,EAAE,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YAC9I,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;gBACrC,MAAM,EAAE,CAAC,UAAU,CAAC,qCAAqC,MAAM,KAAK,IAAI,GAAG,CAAC,CAAC;YAC9E,CAAC;QACF,CAAC;QACD,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACjC,MAAM,EAAE,CAAC,UAAU,CAAC,UAAU,MAAM,+EAA+E,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAChI,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Job } from "pg-boss";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
export declare function settleDeferral(client: PgBossClient, schema: string, job: Job<unknown>, at: string, reason: string, maxDeferrals: number): Promise<{
|
|
4
|
+
readonly claimed: boolean;
|
|
5
|
+
readonly deferred: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
//# sourceMappingURL=settleDeferral.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settleDeferral.d.ts","sourceRoot":"","sources":["../../../src/server/internal/settleDeferral.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,wBAAsB,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;;;GA6C7I"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
import { STATELY_DEFERRAL_POLICY } from "#internal/deferral.ts";
|
|
3
|
+
import { quotedSchema } from "#internal/storedRows.ts";
|
|
4
|
+
const Settlement = Schema.Struct({ claimed: Schema.Boolean, deferred: Schema.Boolean });
|
|
5
|
+
export async function settleDeferral(client, schema, job, at, reason, maxDeferrals) {
|
|
6
|
+
if (client.getDb === undefined) {
|
|
7
|
+
throw new TypeError("This pg-boss client does not support getDb for RetryAt");
|
|
8
|
+
}
|
|
9
|
+
const quoted = quotedSchema(schema);
|
|
10
|
+
// Native failure settlement deletes and reinserts jobs, so a cascading job foreign key would erase the counter.
|
|
11
|
+
const { rows } = await client.getDb().executeSql(`WITH claimed AS MATERIALIZED (
|
|
12
|
+
SELECT name, id, created_on,
|
|
13
|
+
GREATEST(keep_until, $4::timestamptz + (keep_until - start_after)) AS keep_until
|
|
14
|
+
FROM ${quoted}.job
|
|
15
|
+
WHERE name = $1 AND id = $2 AND state = 'active' AND retry_count = $3
|
|
16
|
+
AND date_trunc('milliseconds', started_on) = $6::timestamptz
|
|
17
|
+
FOR UPDATE
|
|
18
|
+
), counted AS (
|
|
19
|
+
INSERT INTO ${quoted}.effect_job_deferral AS previous (name, id, created_on, count, keep_until)
|
|
20
|
+
SELECT name, id, created_on, 1, keep_until FROM claimed
|
|
21
|
+
ON CONFLICT (name, id) DO UPDATE SET
|
|
22
|
+
count = CASE WHEN previous.created_on = EXCLUDED.created_on THEN previous.count + 1 ELSE 1 END,
|
|
23
|
+
created_on = EXCLUDED.created_on, keep_until = EXCLUDED.keep_until
|
|
24
|
+
WHERE previous.created_on <> EXCLUDED.created_on OR previous.count < $7
|
|
25
|
+
RETURNING name, id, keep_until
|
|
26
|
+
), deferred AS (
|
|
27
|
+
UPDATE ${quoted}.job AS job SET state = 'retry', start_after = $4::timestamptz,
|
|
28
|
+
policy = CASE WHEN job.policy = 'stately' THEN '${STATELY_DEFERRAL_POLICY}' ELSE job.policy END,
|
|
29
|
+
keep_until = counted.keep_until, started_on = NULL, heartbeat_on = NULL,
|
|
30
|
+
output = jsonb_build_object('jobDeferral', jsonb_build_object('at', $4::text, 'reason', $5::text))
|
|
31
|
+
FROM counted WHERE job.name = counted.name AND job.id = counted.id
|
|
32
|
+
RETURNING job.id
|
|
33
|
+
), cleaned AS (
|
|
34
|
+
DELETE FROM ${quoted}.effect_job_deferral WHERE (name, id) IN (
|
|
35
|
+
SELECT stale.name, stale.id FROM ${quoted}.effect_job_deferral AS stale
|
|
36
|
+
WHERE EXISTS (SELECT 1 FROM counted) AND stale.keep_until < ${quoted}.job_now()
|
|
37
|
+
AND (stale.name, stale.id) <> ($1, $2)
|
|
38
|
+
AND NOT EXISTS (
|
|
39
|
+
SELECT 1 FROM ${quoted}.job AS live
|
|
40
|
+
WHERE live.name = stale.name AND live.id = stale.id AND live.created_on = stale.created_on
|
|
41
|
+
)
|
|
42
|
+
ORDER BY stale.name, stale.id LIMIT 100 FOR UPDATE OF stale SKIP LOCKED
|
|
43
|
+
)
|
|
44
|
+
)
|
|
45
|
+
SELECT EXISTS (SELECT 1 FROM claimed) AS claimed, EXISTS (SELECT 1 FROM deferred) AS deferred`, [job.name, job.id, job.retryCount, at, reason, Reflect.get(job, "startedOn"), maxDeferrals]);
|
|
46
|
+
return Schema.decodeUnknownSync(Settlement)(rows[0]);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=settleDeferral.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settleDeferral.js","sourceRoot":"","sources":["../../../src/server/internal/settleDeferral.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;AAExF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAoB,EAAE,MAAc,EAAE,GAAiB,EAAE,EAAU,EAAE,MAAc,EAAE,YAAoB;IAC7I,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,SAAS,CAAC,wDAAwD,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACpC,gHAAgH;IAChH,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,UAAU,CAC/C;;;UAGQ,MAAM;;;;;iBAKC,MAAM;;;;;;;;YAQX,MAAM;sDACoC,uBAAuB;;;;;;iBAM5D,MAAM;uCACgB,MAAM;kEACqB,MAAM;;;qBAGnD,MAAM;;;;;;gGAMqE,EAC9F,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,YAAY,CAAC,CAC3F,CAAC;IACF,OAAO,MAAM,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { JobPayloadSchema, QueueDefinition } from "#definition.ts";
|
|
3
|
+
import { PgBossPayloadError } from "#error.ts";
|
|
4
|
+
export declare function quotedSchema(schema: string): string;
|
|
5
|
+
export declare function decodeStoredData<const TName extends string, const TPayload extends JobPayloadSchema>(queue: Pick<QueueDefinition<TName, TPayload>, "name" | "schema">, data: unknown): Effect.Effect<TPayload["Type"], PgBossPayloadError, TPayload["DecodingServices"]>;
|
|
6
|
+
//# sourceMappingURL=storedRows.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storedRows.d.ts","sourceRoot":"","sources":["../../../src/server/internal/storedRows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAoB,MAAM,QAAQ,CAAC;AAClD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAG/C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EACnG,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,EAChE,IAAI,EAAE,OAAO,GACX,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAInF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Effect, Redacted, Schema } from "effect";
|
|
2
|
+
import { PgBossPayloadError } from "#error.ts";
|
|
3
|
+
import { payloadOf } from "#internal/tracing.ts";
|
|
4
|
+
export function quotedSchema(schema) {
|
|
5
|
+
return `"${schema.replaceAll('"', '""')}"`;
|
|
6
|
+
}
|
|
7
|
+
export function decodeStoredData(queue, data) {
|
|
8
|
+
return Schema.decodeUnknownEffect(queue.schema)(payloadOf(data)).pipe(Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue: queue.name })));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=storedRows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storedRows.js","sourceRoot":"","sources":["../../../src/server/internal/storedRows.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAElD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,UAAU,YAAY,CAAC,MAAc;IAC1C,OAAO,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC/B,KAAgE,EAChE,IAAa;IAEb,OAAO,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CACpE,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAC9H,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PgBoss, SendOptions } from "pg-boss";
|
|
2
|
+
import type { PgBossClient } from "#client.ts";
|
|
3
|
+
import type { TestingWork } from "#internal/testingIdle.ts";
|
|
4
|
+
export interface TestingControls {
|
|
5
|
+
readonly changed: () => void;
|
|
6
|
+
readonly expirations: Map<string, number>;
|
|
7
|
+
readonly expirySeconds: Map<string, number>;
|
|
8
|
+
readonly failures: Set<string>;
|
|
9
|
+
readonly retryPolicy: Pick<SendOptions, "retryBackoff" | "retryDelay">;
|
|
10
|
+
readonly work: TestingWork;
|
|
11
|
+
}
|
|
12
|
+
export declare function testingClient(client: PgBoss, schema: string, controls: TestingControls): PgBossClient;
|
|
13
|
+
//# sourceMappingURL=testingClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testingClient.d.ts","sourceRoot":"","sources":["../../../src/server/internal/testingClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAO,MAAM,EAAE,WAAW,EAAgD,MAAM,SAAS,CAAC;AACtG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,KAAK,EAAgB,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAE1E,MAAM,WAAW,eAAe;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,cAAc,GAAG,YAAY,CAAC,CAAC;IACvE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;CAC3B;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,YAAY,CAoHrG"}
|