@shivaedev/effect-pg-boss 0.11.0 → 0.12.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 +10 -0
- package/README.md +29 -2
- package/dist/server/definition.d.ts +46 -24
- package/dist/server/definition.d.ts.map +1 -1
- package/dist/server/definition.js +17 -37
- package/dist/server/definition.js.map +1 -1
- 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/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/service.js +1 -1
- package/dist/server/internal/service.js.map +1 -1
- package/dist/server/internal/testingDeferrals.d.ts +2 -2
- package/dist/server/internal/testingDeferrals.d.ts.map +1 -1
- package/dist/server/internal/testingDeferrals.js.map +1 -1
- package/dist/server/service.d.ts +5 -3
- package/dist/server/service.d.ts.map +1 -1
- package/dist/server/testing.d.ts +5 -5
- package/dist/server/testing.d.ts.map +1 -1
- package/dist/server/testing.js.map +1 -1
- package/package.json +4 -4
- package/src/server/definition.ts +64 -71
- package/src/server/internal/definitionOptions.ts +14 -0
- package/src/server/internal/scheduleDefinition.ts +21 -0
- package/src/server/internal/service.ts +1 -1
- package/src/server/internal/testingDeferrals.ts +2 -2
- package/src/server/service.ts +6 -6
- package/src/server/testing.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.12.0 - 2026-10-18
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Export `QueuePolicy` as the pinned pg-boss policy literals. Singleton queue definitions require `key: (payload) => string`, evaluated from the decoded payload when enqueueing. Related tagged-union job kinds can share one entity key: PostgreSQL allows one active job per key, other keys can run in parallel, and jobs waiting to retry or sent to the dead-letter queue leave the key available. Singleton does not guarantee ordering; applications keep handlers idempotent and guard writes against stale sources.
|
|
8
|
+
|
|
9
|
+
### Breaking
|
|
10
|
+
|
|
11
|
+
- `defineQueue` rejects unknown policy strings and requires `key` for `queue.policy: "singleton"`. Move per-job `singletonKey` options into the queue definition's key callback and remove them from `enqueue` calls for singleton queues. Ordinary queues retain native send options. Let `enqueue` infer its type arguments, or supply the queue-definition type as its third type argument in explicit generic calls.
|
|
12
|
+
|
|
3
13
|
## 0.11.0 - 2026-10-18
|
|
4
14
|
|
|
5
15
|
### Added
|
package/README.md
CHANGED
|
@@ -148,6 +148,33 @@ The same job returns to waiting with `startAfter` set to `at`; its ID, singleton
|
|
|
148
148
|
|
|
149
149
|
Set `queue: { maxDeferrals: 20 }` on a queue or schedule to change the default limit of ten deferrals per job. The limit must be a nonnegative safe integer; zero disables deferral. Once the limit is reached, `RetryAt` follows the normal failure and retry path. The adapter stores the count in its own table in the pg-boss schema, preserving it across worker restarts, ordinary failures, expiry and heartbeat timeouts. Automatic migrations and `installPgBossSchema` create this table and the stately claim trigger; use `installPgBossSchema` before starting workers with `migrate: false`.
|
|
150
150
|
|
|
151
|
+
### One active job per entity
|
|
152
|
+
|
|
153
|
+
Put related job kinds in one tagged-union queue and choose the entity key in the definition:
|
|
154
|
+
|
|
155
|
+
```ts
|
|
156
|
+
const PullRequestJobs = defineQueue({
|
|
157
|
+
name: "pull-request",
|
|
158
|
+
schema: Schema.Union([
|
|
159
|
+
Schema.TaggedStruct("Refresh", { pullRequestId: Schema.NumberFromString }),
|
|
160
|
+
Schema.TaggedStruct("Reconcile", { pullRequestId: Schema.NumberFromString }),
|
|
161
|
+
]),
|
|
162
|
+
queue: { policy: "singleton" },
|
|
163
|
+
key: ({ pullRequestId }) => `pr:${pullRequestId.toFixed(0)}`,
|
|
164
|
+
worker: { batchSize: 1, localConcurrency: 3 },
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const refresh = Effect.flatMap(Jobs, (jobs) =>
|
|
168
|
+
jobs.enqueue(PullRequestJobs, { _tag: "Refresh", pullRequestId: 42 }),
|
|
169
|
+
);
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`queue.policy` accepts pg-boss's policy literals and rejects typos. The `singleton` policy requires `key: (payload) => string`. The callback sees the decoded payload, so `pullRequestId` is a number. `enqueue` supplies pg-boss's `singletonKey` automatically; callers cannot supply a conflicting key in send options.
|
|
173
|
+
|
|
174
|
+
PostgreSQL guarantees one active job per key across workers, including different job kinds in this queue. Different keys can run in parallel when workers have capacity. A job waiting to retry frees its key for another job; exhausting retries sends it to the dead-letter queue and leaves the key available.
|
|
175
|
+
|
|
176
|
+
Singleton guarantees one active job per key, not order. Ordering stays the application's job. Keep handlers idempotent and write state only when the source is newer than what is stored, so an older event or retry cannot overwrite newer state.
|
|
177
|
+
|
|
151
178
|
### Size batches against expiry
|
|
152
179
|
|
|
153
180
|
pg-boss marks every job in a fetched batch active together. Each job's expiry window starts at its stored `startedOn`, including time waiting for earlier handlers. Size each queue's batch so its sequential work fits within that window; use a small batch for long-running work and keep the default for short work:
|
|
@@ -411,7 +438,7 @@ Import the module that defines the name; the package has no root entry.
|
|
|
411
438
|
|
|
412
439
|
| Module | Public names |
|
|
413
440
|
| --- | --- |
|
|
414
|
-
| `@shivaedev/effect-pg-boss/definition.ts` | `defineQueue`, `defineSchedule`, `jobContext`, `RetryAt`; `DefineQueueOptions`, `DefineScheduleOptions`, `JobContext`, `JobPayloadSchema`, `JobRegistration`, `QueueDefinition`, `QueueOptions`, `QueueWorker`, `RegistrationRequirements`, `ScheduleDefinition`, `ScheduledWorker` |
|
|
441
|
+
| `@shivaedev/effect-pg-boss/definition.ts` | `defineQueue`, `defineSchedule`, `jobContext`, `RetryAt`; `DefineQueueOptions`, `DefineScheduleOptions`, `JobContext`, `JobPayloadSchema`, `JobRegistration`, `QueueDefinition`, `QueueOptions`, `QueuePolicy`, `QueueWorker`, `RegistrationRequirements`, `ScheduleDefinition`, `ScheduledWorker` |
|
|
415
442
|
| `@shivaedev/effect-pg-boss/service.ts` | `makePgBoss`; `PgBossDefinition`, `PgBossLayerOptions`, `PgBossService` |
|
|
416
443
|
| `@shivaedev/effect-pg-boss/schema.ts` | `installPgBossSchema`; `PgBossSchemaOptions` |
|
|
417
444
|
| `@shivaedev/effect-pg-boss/health.ts` | `deadLetterQueueName`; `JobsHealth`, `QueueCounts`, `QueueHealth` |
|
|
@@ -419,7 +446,7 @@ Import the module that defines the name; the package has no root entry.
|
|
|
419
446
|
| `@shivaedev/effect-pg-boss/client.ts` | `defaultClientFactory`; `PgBossClient`, `PgBossClientFactory` |
|
|
420
447
|
| `@shivaedev/effect-pg-boss/testing.ts` | `makePgBossTesting`, `testRetryPolicy`; `PgBossTesting`, `PgBossTestingOptions` |
|
|
421
448
|
|
|
422
|
-
The definition options keep the pg-boss names: `queue` uses `QueueOptions` (`Queue` except `name` and `deadLetter`,
|
|
449
|
+
The definition options keep the pg-boss names: `queue` uses `QueueOptions` (`Queue` except `name` and `deadLetter`, with literal `QueuePolicy` values and `maxDeferrals`), `worker` uses `WorkOptions`, and a schedule's `schedule` uses `ScheduleOptions`. A queue also requires `name` and `schema`; a schedule requires `name` and `cron`.
|
|
423
450
|
|
|
424
451
|
`Jobs.layer(options)` accepts pg-boss `ConstructorOptions` plus the adapter's own options. Custom clients must supply native `complete` and `fail` capabilities to register queue or schedule workers; missing settlement capabilities fail Layer acquisition with a registration `PgBossError`. Producer-only clients do not need them. Custom clients can also supply the optional native capabilities `findJobs`, `retry`, `update`, `getDb` and `updateQueue` for lookup, retry, live counts, deferral and reconciliation; a requested operation fails with `PgBossError` if its required capability is absent.
|
|
425
452
|
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { Duration, Effect, Schema } from "effect";
|
|
2
|
-
import type { Job, Queue, ScheduleOptions, WorkOptions } from "pg-boss";
|
|
2
|
+
import type { Job, policies, Queue, ScheduleOptions, WorkOptions } from "pg-boss";
|
|
3
3
|
declare const RetryAt_base: Schema.Class<RetryAt, Schema.TaggedStruct<"RetryAt", {
|
|
4
4
|
readonly at: Schema.DateTimeUtc;
|
|
5
5
|
readonly reason: Schema.String;
|
|
6
6
|
}>, import("effect/Cause").YieldableError>;
|
|
7
7
|
export declare class RetryAt extends RetryAt_base {
|
|
8
8
|
}
|
|
9
|
-
export type
|
|
9
|
+
export type QueuePolicy = (typeof policies)[keyof typeof policies];
|
|
10
|
+
export type QueueOptions = Omit<Queue, "name" | "deadLetter" | "policy"> & {
|
|
10
11
|
readonly maxDeferrals?: number;
|
|
12
|
+
readonly policy?: QueuePolicy;
|
|
11
13
|
};
|
|
12
14
|
export interface JobPayloadSchema extends Schema.Top {
|
|
13
15
|
readonly Encoded: object;
|
|
@@ -21,54 +23,74 @@ export interface JobContext {
|
|
|
21
23
|
readonly remainingBudget: Effect.Effect<Duration.Duration>;
|
|
22
24
|
readonly signal: AbortSignal;
|
|
23
25
|
}
|
|
24
|
-
export interface QueueDefinition<
|
|
26
|
+
export interface QueueDefinition<TName extends string = string, TPayload extends JobPayloadSchema = JobPayloadSchema> {
|
|
25
27
|
readonly _tag: "QueueDefinition";
|
|
26
|
-
readonly handle: <E, R>(handler: (payload: Schema.Schema.Type<
|
|
28
|
+
readonly handle: <E, R>(handler: (payload: Schema.Schema.Type<TPayload>, job: JobContext) => Effect.Effect<unknown, E, R>) => QueueWorker<TPayload, R>;
|
|
29
|
+
readonly key?: ((payload: Schema.Schema.Type<TPayload>) => string) | undefined;
|
|
27
30
|
readonly maxDeferrals: number;
|
|
28
|
-
readonly name:
|
|
31
|
+
readonly name: TName;
|
|
29
32
|
readonly queueOptions: Omit<Queue, "name" | "deadLetter">;
|
|
30
|
-
readonly schema:
|
|
33
|
+
readonly schema: TPayload;
|
|
31
34
|
readonly workerOptions: WorkOptions;
|
|
32
35
|
}
|
|
33
|
-
export interface QueueWorker<
|
|
36
|
+
export interface QueueWorker<TPayload extends JobPayloadSchema = JobPayloadSchema, TRequirements = unknown> {
|
|
34
37
|
readonly _tag: "QueueWorker";
|
|
35
|
-
readonly handler: (payload: Schema.Schema.Type<
|
|
36
|
-
readonly queue: QueueDefinition<string,
|
|
38
|
+
readonly handler: (payload: Schema.Schema.Type<TPayload>, job: JobContext) => Effect.Effect<unknown, unknown, TRequirements>;
|
|
39
|
+
readonly queue: QueueDefinition<string, TPayload>;
|
|
37
40
|
}
|
|
38
41
|
export interface JobRegistration {
|
|
39
42
|
readonly _tag: "QueueDefinition" | "QueueWorker" | "ScheduledWorker";
|
|
40
43
|
}
|
|
41
|
-
export interface ScheduleDefinition<
|
|
44
|
+
export interface ScheduleDefinition<TName extends string = string> {
|
|
42
45
|
readonly _tag: "ScheduleDefinition";
|
|
43
46
|
readonly cron: string;
|
|
44
47
|
readonly maxDeferrals: number;
|
|
45
|
-
readonly name:
|
|
48
|
+
readonly name: TName;
|
|
46
49
|
readonly queueOptions: Omit<Queue, "name" | "deadLetter">;
|
|
47
50
|
readonly run: <E, R>(effect: Effect.Effect<unknown, E, R>) => ScheduledWorker<R>;
|
|
48
51
|
readonly scheduleOptions: ScheduleOptions;
|
|
49
52
|
readonly workerOptions: WorkOptions;
|
|
50
53
|
}
|
|
51
|
-
export interface ScheduledWorker<
|
|
54
|
+
export interface ScheduledWorker<TRequirements = unknown> {
|
|
52
55
|
readonly _tag: "ScheduledWorker";
|
|
53
|
-
readonly effect: Effect.Effect<unknown, unknown,
|
|
56
|
+
readonly effect: Effect.Effect<unknown, unknown, TRequirements>;
|
|
54
57
|
readonly schedule: ScheduleDefinition;
|
|
55
58
|
}
|
|
56
|
-
export type RegistrationRequirements<
|
|
57
|
-
export
|
|
58
|
-
readonly name:
|
|
59
|
-
readonly
|
|
60
|
-
readonly schema: Payload;
|
|
59
|
+
export type RegistrationRequirements<TRegistrations extends readonly JobRegistration[]> = TRegistrations[number] extends infer TRegistration ? TRegistration extends QueueWorker<infer TPayload, infer TRequirements> ? TRequirements | TPayload["DecodingServices"] : TRegistration extends ScheduledWorker<infer TRequirements> ? TRequirements : never : never;
|
|
60
|
+
export type DefineQueueOptions<TName extends string, TPayload extends JobPayloadSchema> = {
|
|
61
|
+
readonly name: TName;
|
|
62
|
+
readonly schema: TPayload;
|
|
61
63
|
readonly worker?: WorkOptions;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
} & ({
|
|
65
|
+
readonly key: (payload: Schema.Schema.Type<TPayload>) => string;
|
|
66
|
+
readonly queue: QueueOptions & {
|
|
67
|
+
readonly policy: "singleton";
|
|
68
|
+
};
|
|
69
|
+
} | {
|
|
70
|
+
readonly key?: never;
|
|
71
|
+
readonly queue?: QueueOptions & {
|
|
72
|
+
readonly policy?: Exclude<QueuePolicy, "singleton">;
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
export declare function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(options: DefineQueueOptions<TName, TPayload> & {
|
|
76
|
+
readonly key: (payload: Schema.Schema.Type<TPayload>) => string;
|
|
77
|
+
}): QueueDefinition<TName, TPayload> & {
|
|
78
|
+
readonly key: (payload: Schema.Schema.Type<TPayload>) => string;
|
|
79
|
+
};
|
|
80
|
+
export declare function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(options: DefineQueueOptions<TName, TPayload> & {
|
|
81
|
+
readonly key?: never;
|
|
82
|
+
}): QueueDefinition<TName, TPayload> & {
|
|
83
|
+
readonly key?: never;
|
|
84
|
+
};
|
|
85
|
+
export declare function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(options: DefineQueueOptions<TName, TPayload>): QueueDefinition<TName, TPayload>;
|
|
86
|
+
export interface DefineScheduleOptions<TName extends string> {
|
|
65
87
|
readonly cron: string;
|
|
66
|
-
readonly name:
|
|
88
|
+
readonly name: TName;
|
|
67
89
|
readonly queue?: QueueOptions;
|
|
68
90
|
readonly schedule?: ScheduleOptions;
|
|
69
91
|
readonly worker?: WorkOptions;
|
|
70
92
|
}
|
|
71
|
-
export declare
|
|
72
|
-
export declare
|
|
93
|
+
export declare function defineSchedule<const TName extends string>(options: DefineScheduleOptions<TName>): ScheduleDefinition<TName>;
|
|
94
|
+
export declare function jobContext(job: Job<unknown>): JobContext;
|
|
73
95
|
export {};
|
|
74
96
|
//# sourceMappingURL=definition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;;;;;
|
|
1
|
+
{"version":3,"file":"definition.d.ts","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +1,16 @@
|
|
|
1
1
|
import { Clock, Duration, Effect, Schema } from "effect";
|
|
2
2
|
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
3
|
+
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
4
|
+
import { scheduleDefinition } from "#internal/scheduleDefinition.ts";
|
|
3
5
|
export class RetryAt extends Schema.TaggedError()("RetryAt", {
|
|
4
6
|
at: Schema.DateTimeUtc,
|
|
5
7
|
reason: Schema.String,
|
|
6
8
|
}) {
|
|
7
9
|
}
|
|
8
|
-
function
|
|
9
|
-
const limit = options?.maxDeferrals ?? 10;
|
|
10
|
-
if (!Number.isSafeInteger(limit) || limit < 0) {
|
|
11
|
-
throw new RangeError("maxDeferrals must be a nonnegative safe integer");
|
|
12
|
-
}
|
|
13
|
-
return limit;
|
|
14
|
-
}
|
|
15
|
-
function nativeQueueOptions(options) {
|
|
16
|
-
const { maxDeferrals: _limit, ...native } = options ?? {};
|
|
17
|
-
return Object.freeze(native);
|
|
18
|
-
}
|
|
19
|
-
export const defineQueue = (options) => {
|
|
10
|
+
export function defineQueue(options) {
|
|
20
11
|
const definition = {
|
|
21
12
|
_tag: "QueueDefinition",
|
|
13
|
+
...(options.key === undefined ? {} : { key: options.key }),
|
|
22
14
|
handle: (handler) => Object.freeze({
|
|
23
15
|
_tag: "QueueWorker",
|
|
24
16
|
handler,
|
|
@@ -31,30 +23,18 @@ export const defineQueue = (options) => {
|
|
|
31
23
|
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
32
24
|
};
|
|
33
25
|
return Object.freeze(definition);
|
|
34
|
-
}
|
|
35
|
-
export
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}),
|
|
47
|
-
scheduleOptions: Object.freeze({ tz: "UTC", ...options.schedule }),
|
|
48
|
-
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
26
|
+
}
|
|
27
|
+
export function defineSchedule(options) {
|
|
28
|
+
return scheduleDefinition(options);
|
|
29
|
+
}
|
|
30
|
+
export function jobContext(job) {
|
|
31
|
+
return {
|
|
32
|
+
expireInSeconds: job.expireInSeconds,
|
|
33
|
+
heartbeatSeconds: job.heartbeatSeconds,
|
|
34
|
+
id: job.id,
|
|
35
|
+
name: job.name,
|
|
36
|
+
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0, deadlineOf(job) - now))),
|
|
37
|
+
signal: job.signal,
|
|
49
38
|
};
|
|
50
|
-
|
|
51
|
-
};
|
|
52
|
-
export const jobContext = (job) => ({
|
|
53
|
-
expireInSeconds: job.expireInSeconds,
|
|
54
|
-
heartbeatSeconds: job.heartbeatSeconds,
|
|
55
|
-
id: job.id,
|
|
56
|
-
name: job.name,
|
|
57
|
-
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0, deadlineOf(job) - now))),
|
|
58
|
-
signal: job.signal,
|
|
59
|
-
});
|
|
39
|
+
}
|
|
60
40
|
//# sourceMappingURL=definition.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"definition.js","sourceRoot":"","sources":["../../src/server/definition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAClF,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAErE,MAAM,OAAO,OAAQ,SAAQ,MAAM,CAAC,WAAW,EAAW,CAAC,SAAS,EAAE;IACrE,EAAE,EAAE,MAAM,CAAC,WAAW;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM;CACrB,CAAC;CAAG;AAwFL,MAAM,UAAU,WAAW,CAC1B,OAA4C;IAE5C,MAAM,UAAU,GAAqC;QACpD,IAAI,EAAE,iBAAiB;QACvB,GAAG,CAAC,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1D,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CACnB,MAAM,CAAC,MAAM,CAAC;YACb,IAAI,EAAE,aAAsB;YAC5B,OAAO;YACP,KAAK,EAAE,UAAU;SACjB,CAAC;QACH,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,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,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;AAUD,MAAM,UAAU,cAAc,CAA6B,OAAqC;IAC/F,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAiB;IAC3C,OAAO;QACN,eAAe,EAAE,GAAG,CAAC,eAAe;QACpC,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;QACtC,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,eAAe,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAClH,MAAM,EAAE,GAAG,CAAC,MAAM;KAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { QueueOptions } from "#definition.ts";
|
|
2
|
+
export declare function maxDeferrals(options: QueueOptions | undefined): number;
|
|
3
|
+
export declare function nativeQueueOptions(options: QueueOptions | undefined): Readonly<{
|
|
4
|
+
expireInSeconds?: number;
|
|
5
|
+
retentionSeconds?: number;
|
|
6
|
+
deleteAfterSeconds?: number;
|
|
7
|
+
retryLimit?: number;
|
|
8
|
+
retryDelay?: number;
|
|
9
|
+
retryBackoff?: boolean;
|
|
10
|
+
retryDelayMax?: number;
|
|
11
|
+
partition?: boolean;
|
|
12
|
+
warningQueueSize?: number;
|
|
13
|
+
heartbeatSeconds?: number;
|
|
14
|
+
notify?: boolean;
|
|
15
|
+
policy?: import("#definition.ts").QueuePolicy;
|
|
16
|
+
}>;
|
|
17
|
+
//# sourceMappingURL=definitionOptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitionOptions.d.ts","sourceRoot":"","sources":["../../../src/server/internal/definitionOptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAEnD,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,CAMtE;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,SAAS;;;;;;;;;;;;;GAGnE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function maxDeferrals(options) {
|
|
2
|
+
const limit = options?.maxDeferrals ?? 10;
|
|
3
|
+
if (!Number.isSafeInteger(limit) || limit < 0) {
|
|
4
|
+
throw new RangeError("maxDeferrals must be a nonnegative safe integer");
|
|
5
|
+
}
|
|
6
|
+
return limit;
|
|
7
|
+
}
|
|
8
|
+
export function nativeQueueOptions(options) {
|
|
9
|
+
const { maxDeferrals: _limit, ...native } = options ?? {};
|
|
10
|
+
return Object.freeze(native);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=definitionOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitionOptions.js","sourceRoot":"","sources":["../../../src/server/internal/definitionOptions.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,YAAY,CAAC,OAAiC;IAC7D,MAAM,KAAK,GAAG,OAAO,EAAE,YAAY,IAAI,EAAE,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC/C,MAAM,IAAI,UAAU,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAiC;IACnE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,IAAI,EAAE,CAAC;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC9B,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"}
|
|
@@ -20,7 +20,7 @@ export const makeService = (client, names, schema = "pgboss") => ({
|
|
|
20
20
|
}
|
|
21
21
|
return capturePayload(encoded).pipe(Effect.flatMap((data) => Effect.tryPromise({
|
|
22
22
|
catch: (error) => toPgBossError("enqueue", error, queue.name),
|
|
23
|
-
try: () => client.send(queue.name, data, options),
|
|
23
|
+
try: () => client.send(queue.name, data, queue.key === undefined ? options : { ...options, singletonKey: queue.key(payload) }),
|
|
24
24
|
})), Effect.map(Option.fromNullishOr));
|
|
25
25
|
})),
|
|
26
26
|
getJob: getJobFor(client),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/server/internal/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EAAoB,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAoB,EAAE,KAAwB,EAAE,MAAM,GAAG,QAAQ,EAAiB,EAAE,CAAC,CAAC;IACjH,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;IACxD,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CACpC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CACrD,MAAM,CAAC,QAAQ,CACd,CAAC,KAAK,EAAE,EAAE,CACT,IAAI,kBAAkB,CAAC;QACtB,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CACH,EACD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAA0E,EAAE;QAClG,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrD,OAAO,MAAM,CAAC,IAAI,CACjB,IAAI,kBAAkB,CAAC;gBACtB,SAAS,EAAE,QAAQ;gBACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,yCAAyC,CAAC,CAAC;gBACjF,KAAK,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CACF,CAAC;QACH,CAAC;QACD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAClC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACvB,MAAM,CAAC,UAAU,CAAC;YACjB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7D,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/server/internal/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1D,OAAO,EAAoB,kBAAkB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAoB,EAAE,KAAwB,EAAE,MAAM,GAAG,QAAQ,EAAiB,EAAE,CAAC,CAAC;IACjH,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;IACxD,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE,CACpC,MAAM,CAAC,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CACrD,MAAM,CAAC,QAAQ,CACd,CAAC,KAAK,EAAE,EAAE,CACT,IAAI,kBAAkB,CAAC;QACtB,SAAS,EAAE,QAAQ;QACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,KAAK,EAAE,KAAK,CAAC,IAAI;KACjB,CAAC,CACH,EACD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,EAA0E,EAAE;QAClG,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrD,OAAO,MAAM,CAAC,IAAI,CACjB,IAAI,kBAAkB,CAAC;gBACtB,SAAS,EAAE,QAAQ;gBACnB,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,yCAAyC,CAAC,CAAC;gBACjF,KAAK,EAAE,KAAK,CAAC,IAAI;aACjB,CAAC,CACF,CAAC;QACH,CAAC;QACD,OAAO,cAAc,CAAC,OAAO,CAAC,CAAC,IAAI,CAClC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACvB,MAAM,CAAC,UAAU,CAAC;YACjB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC;YAC7D,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;SAC9H,CAAC,CACF,EACD,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,CAChC,CAAC;IACH,CAAC,CAAC,CACF;IACF,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC;IAChC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC;CACvB,CAAC,CAAC"}
|
|
@@ -2,10 +2,10 @@ import { DateTime } from "effect";
|
|
|
2
2
|
import type { PgBoss } from "pg-boss";
|
|
3
3
|
import type { QueueDefinition } from "#definition.ts";
|
|
4
4
|
export declare function testingDeferrals(client: () => PgBoss, schema: () => string, changed: () => void): {
|
|
5
|
-
deferred: (queue: QueueDefinition) => import("effect/Effect").Effect<{
|
|
5
|
+
deferred: (queue: Pick<QueueDefinition, "name">) => import("effect/Effect").Effect<{
|
|
6
6
|
at: DateTime.Utc;
|
|
7
7
|
reason: string;
|
|
8
8
|
}[], import("../error").PgBossTestingError, never>;
|
|
9
|
-
runDeferredNow: (queue: QueueDefinition) => import("effect/Effect").Effect<void, import("../error").PgBossTestingError, never>;
|
|
9
|
+
runDeferredNow: (queue: Pick<QueueDefinition, "name">) => import("effect/Effect").Effect<void, import("../error").PgBossTestingError, never>;
|
|
10
10
|
};
|
|
11
11
|
//# sourceMappingURL=testingDeferrals.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testingDeferrals.d.ts","sourceRoot":"","sources":["../../../src/server/internal/testingDeferrals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI;IAE9F,QAAQ,UAAU,eAAe;;;;
|
|
1
|
+
{"version":3,"file":"testingDeferrals.d.ts","sourceRoot":"","sources":["../../../src/server/internal/testingDeferrals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,MAAM,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI;IAE9F,QAAQ,UAAU,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;;;;IAY/C,cAAc,UAAU,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;EAsBtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testingDeferrals.js","sourceRoot":"","sources":["../../../src/server/internal/testingDeferrals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,MAAM,UAAU,gBAAgB,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;IAC/F,OAAO;QACN,QAAQ,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"testingDeferrals.js","sourceRoot":"","sources":["../../../src/server/internal/testingDeferrals.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAE/D,MAAM,UAAU,gBAAgB,CAAC,MAAoB,EAAE,MAAoB,EAAE,OAAmB;IAC/F,OAAO;QACN,QAAQ,EAAE,CAAC,KAAoC,EAAE,EAAE,CAClD,gBAAgB,CACf,UAAU,EACV,KAAK,IAAI,EAAE;YACV,MAAM,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC3B,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,KAAK,OAAO,IAAI,GAAG,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAC/F,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7G,CAAC,CAAC,CAAC;QACJ,CAAC,EACD,KAAK,CAAC,IAAI,CACV;QACF,cAAc,EAAE,CAAC,KAAoC,EAAE,EAAE,CACxD,gBAAgB,CACf,gBAAgB,EAChB,KAAK,IAAI,EAAE;YACV,MAAM,YAAY,GAAG,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;YAC3D,MAAM,MAAM,EAAE;iBACZ,KAAK,EAAE;iBACP,UAAU,CACV,UAAU,YAAY,0BAA0B,YAAY;0FACuB,EACnF,CAAC,KAAK,CAAC,IAAI,CAAC,CACZ,CAAC;YACH,OAAO,EAAE,CAAC;YACV,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE;iBAC3B,UAAU,EAAE;iBACZ,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxD,MAAM,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC;QACF,CAAC,EACD,KAAK,CAAC,IAAI,CACV;KACF,CAAC;AACH,CAAC"}
|
package/dist/server/service.d.ts
CHANGED
|
@@ -5,11 +5,13 @@ import type { JobPayloadSchema, JobRegistration, QueueDefinition, RegistrationRe
|
|
|
5
5
|
import type { PgBossError, PgBossPayloadError, PgBossQueueOptionsError } from "#error.ts";
|
|
6
6
|
import type { JobsHealth, QueueCounts } from "#health.ts";
|
|
7
7
|
export interface PgBossService {
|
|
8
|
-
readonly counts: (queue: QueueDefinition) => Effect.Effect<QueueCounts, PgBossError>;
|
|
9
|
-
readonly enqueue: <const TName extends string, const TPayload extends JobPayloadSchema
|
|
8
|
+
readonly counts: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<QueueCounts, PgBossError>;
|
|
9
|
+
readonly enqueue: <const TName extends string, const TPayload extends JobPayloadSchema, const TQueue extends QueueDefinition<TName, TPayload>>(queue: QueueDefinition<TName, TPayload> & TQueue, payload: NoInfer<Schema.Schema.Type<TPayload>>, options?: NoInfer<TQueue["key"] extends undefined ? SendOptions : Omit<SendOptions, "singletonKey"> & {
|
|
10
|
+
readonly singletonKey?: never;
|
|
11
|
+
}>) => Effect.Effect<Option.Option<string>, PgBossError | PgBossPayloadError, TPayload["EncodingServices"]>;
|
|
10
12
|
readonly getJob: <const TName extends string, const TPayload extends JobPayloadSchema>(queue: QueueDefinition<TName, TPayload>, id: string) => Effect.Effect<Option.Option<JobWithMetadata<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
|
|
11
13
|
readonly health: Effect.Effect<JobsHealth, PgBossError>;
|
|
12
|
-
readonly retry: (queue: QueueDefinition, id: string) => Effect.Effect<void, PgBossError>;
|
|
14
|
+
readonly retry: (queue: Pick<QueueDefinition, "name">, id: string) => Effect.Effect<void, PgBossError>;
|
|
13
15
|
}
|
|
14
16
|
export type PgBossLayerOptions<TRegistrations extends readonly JobRegistration[], TErrorRequirements> = ConstructorOptions & {
|
|
15
17
|
readonly clientFactory?: PgBossClientFactory;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM1D,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7F,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,KAAK,EAAE,WAAW,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAC1F,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM1D,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACnG,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EAAE,KAAK,CAAC,MAAM,SAAS,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EAC5I,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,MAAM,EAChD,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAC9C,OAAO,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,SAAS,GAAG,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG;QAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAA;KAAE,CAAC,KACpI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC1G,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EACpF,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EACvC,EAAE,EAAE,MAAM,KACN,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACrI,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACxD,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;CACvG;AAED,MAAM,MAAM,kBAAkB,CAAC,cAAc,SAAS,SAAS,eAAe,EAAE,EAAE,kBAAkB,IAAI,kBAAkB,GAAG;IAC5H,QAAQ,CAAC,aAAa,CAAC,EAAE,mBAAmB,CAAC;IAE7C,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACvF,QAAQ,CAAC,IAAI,CAAC,EAAE,WAAW,CAAC;CAC5B,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,WAAW,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,aAAa,CAAC;IACzH,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,cAAc,SAAS,SAAS,eAAe,EAAE,EAAE,kBAAkB,GAAG,KAAK,EACnG,OAAO,EAAE,kBAAkB,CAAC,cAAc,EAAE,kBAAkB,CAAC,KAC3D,KAAK,CAAC,KAAK,CACf,WAAW,EACX,WAAW,GAAG,uBAAuB,EACrC,OAAO,CAAC,wBAAwB,CAAC,cAAc,CAAC,EAAE,WAAW,CAAC,GAAG,kBAAkB,CACnF,CAAC;CACF;AAED,eAAO,MAAM,UAAU,GAAI,KAAK,CAAC,WAAW,SAAS,MAAM,cAAc,WAAW,KAAG,gBAAgB,CAAC,WAAW,CA6ClH,CAAC"}
|
package/dist/server/testing.d.ts
CHANGED
|
@@ -10,16 +10,16 @@ export interface PgBossTestingOptions {
|
|
|
10
10
|
readonly retryPolicy?: typeof testRetryPolicy;
|
|
11
11
|
}
|
|
12
12
|
export declare function makePgBossTesting(options?: PgBossTestingOptions): {
|
|
13
|
-
deferred: (queue: QueueDefinition) => Effect.Effect<{
|
|
13
|
+
deferred: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<{
|
|
14
14
|
at: import("effect/DateTime").Utc;
|
|
15
15
|
reason: string;
|
|
16
16
|
}[], PgBossTestingError, never>;
|
|
17
|
-
runDeferredNow: (queue: QueueDefinition) => Effect.Effect<void, PgBossTestingError, never>;
|
|
18
|
-
checkBatchWindow: (queue: QueueDefinition, millisecondsPerJob: number) => Effect.Effect<void, PgBossTestingError, never>;
|
|
17
|
+
runDeferredNow: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<void, PgBossTestingError, never>;
|
|
18
|
+
checkBatchWindow: (queue: Pick<QueueDefinition, "name" | "workerOptions">, millisecondsPerJob: number) => Effect.Effect<void, PgBossTestingError, never>;
|
|
19
19
|
checkSchemaVersion: (expected: number) => Effect.Effect<void, PgBossTestingError, never>;
|
|
20
20
|
clientFactory: PgBossClientFactory;
|
|
21
|
-
expireAfter: (queue: QueueDefinition, attempts: number) => Effect.Effect<void, PgBossTestingError, never>;
|
|
22
|
-
failNextSend: (queue: QueueDefinition) => Effect.Effect<void, never, never>;
|
|
21
|
+
expireAfter: (queue: Pick<QueueDefinition, "name">, attempts: number) => Effect.Effect<void, PgBossTestingError, never>;
|
|
22
|
+
failNextSend: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<void, never, never>;
|
|
23
23
|
jobs: <TName extends string, TPayload extends import("#definition.ts").JobPayloadSchema>(queue: QueueDefinition<TName, TPayload>, options?: import("pg-boss").FindJobsOptions) => Effect.Effect<{
|
|
24
24
|
id: string;
|
|
25
25
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAM/C,eAAO,MAAM,eAAe;;;EAAwD,CAAC;AAErF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,eAAe,CAAC;CAC9C;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,oBAAyB;;;;;;8BA0BxC,eAAe,sBAAsB,MAAM;
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAY,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAM/C,eAAO,MAAM,eAAe;;;EAAwD,CAAC;AAErF,MAAM,WAAW,oBAAoB;IACpC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,eAAe,CAAC;CAC9C;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,oBAAyB;;;;;;8BA0BxC,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,eAAe,CAAC,sBAAsB,MAAM;mCAqBtE,MAAM;;yBAOhB,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,YAAY,MAAM;0BAU9C,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAMpD;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAGjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAE3D,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;AAMrF,MAAM,UAAU,iBAAiB,CAAC,OAAO,GAAyB,EAAE;IACnE,IAAI,OAA2B,CAAC;IAChC,IAAI,MAAM,GAAG,QAAQ,CAAC;IACtB,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAG;QAChB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,IAAI,GAAG,EAAkB;QACtC,QAAQ,EAAE,IAAI,GAAG,EAAU;QAC3B,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,EAAE;KACtC,CAAC;IACF,SAAS,MAAM;QACd,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,MAAM,aAAa,GAAwB,CAAC,aAAa,EAAE,EAAE;QAC5D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,4EAA4E,CAAC,CAAC;QAC/F,CAAC;QACD,MAAM,GAAG,aAAa,CAAC,MAAM,IAAI,QAAQ,CAAC;QAC1C,OAAO,GAAG,IAAI,MAAM,CAAC,EAAE,GAAG,aAAa,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;QACxE,OAAO,aAAa,CAAC,OAAO,EAAE,aAAa,CAAC,MAAM,IAAI,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC3E,CAAC,CAAC;IACF,OAAO;QACN,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC;QACzD,gBAAgB,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../src/server/testing.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-pg-boss",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"description": "Effect-native jobs and lifecycle management for pg-boss",
|
|
5
5
|
"homepage": "https://github.com/ShivaeDev/platform/tree/main/packages/effect-pg-boss#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
],
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@shivaedev/effect-test": "0.7.1",
|
|
45
|
-
"@shivaedev/effect-test-sql": "0.6.
|
|
46
|
-
"@shivaedev/quality": "0.
|
|
47
|
-
"@shivaedev/test-story": "0.
|
|
45
|
+
"@shivaedev/effect-test-sql": "0.6.1",
|
|
46
|
+
"@shivaedev/quality": "0.28.0",
|
|
47
|
+
"@shivaedev/test-story": "0.12.0",
|
|
48
48
|
"@types/node": "24.19.2",
|
|
49
49
|
"effect": "4.0.4",
|
|
50
50
|
"pg-boss": "12.37.1",
|
package/src/server/definition.ts
CHANGED
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import { Clock, Duration, Effect, Schema } from "effect";
|
|
2
|
-
import type { Job, Queue, ScheduleOptions, WorkOptions } from "pg-boss";
|
|
2
|
+
import type { Job, policies, Queue, ScheduleOptions, WorkOptions } from "pg-boss";
|
|
3
3
|
import { deadlineOf } from "#internal/deadlineOf.ts";
|
|
4
|
+
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
5
|
+
import { scheduleDefinition } from "#internal/scheduleDefinition.ts";
|
|
4
6
|
|
|
5
7
|
export class RetryAt extends Schema.TaggedError<RetryAt>()("RetryAt", {
|
|
6
8
|
at: Schema.DateTimeUtc,
|
|
7
9
|
reason: Schema.String,
|
|
8
10
|
}) {}
|
|
9
11
|
|
|
10
|
-
export type
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
throw new RangeError("maxDeferrals must be a nonnegative safe integer");
|
|
16
|
-
}
|
|
17
|
-
return limit;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function nativeQueueOptions(options: QueueOptions | undefined) {
|
|
21
|
-
const { maxDeferrals: _limit, ...native } = options ?? {};
|
|
22
|
-
return Object.freeze(native);
|
|
23
|
-
}
|
|
12
|
+
export type QueuePolicy = (typeof policies)[keyof typeof policies];
|
|
13
|
+
export type QueueOptions = Omit<Queue, "name" | "deadLetter" | "policy"> & {
|
|
14
|
+
readonly maxDeferrals?: number;
|
|
15
|
+
readonly policy?: QueuePolicy;
|
|
16
|
+
};
|
|
24
17
|
|
|
25
18
|
export interface JobPayloadSchema extends Schema.Top {
|
|
26
19
|
readonly Encoded: object;
|
|
@@ -36,65 +29,78 @@ export interface JobContext {
|
|
|
36
29
|
readonly signal: AbortSignal;
|
|
37
30
|
}
|
|
38
31
|
|
|
39
|
-
export interface QueueDefinition<
|
|
32
|
+
export interface QueueDefinition<TName extends string = string, TPayload extends JobPayloadSchema = JobPayloadSchema> {
|
|
40
33
|
readonly _tag: "QueueDefinition";
|
|
41
34
|
readonly handle: <E, R>(
|
|
42
|
-
handler: (payload: Schema.Schema.Type<
|
|
43
|
-
) => QueueWorker<
|
|
35
|
+
handler: (payload: Schema.Schema.Type<TPayload>, job: JobContext) => Effect.Effect<unknown, E, R>,
|
|
36
|
+
) => QueueWorker<TPayload, R>;
|
|
37
|
+
readonly key?: ((payload: Schema.Schema.Type<TPayload>) => string) | undefined;
|
|
44
38
|
readonly maxDeferrals: number;
|
|
45
|
-
readonly name:
|
|
39
|
+
readonly name: TName;
|
|
46
40
|
readonly queueOptions: Omit<Queue, "name" | "deadLetter">;
|
|
47
|
-
readonly schema:
|
|
41
|
+
readonly schema: TPayload;
|
|
48
42
|
readonly workerOptions: WorkOptions;
|
|
49
43
|
}
|
|
50
44
|
|
|
51
|
-
export interface QueueWorker<
|
|
45
|
+
export interface QueueWorker<TPayload extends JobPayloadSchema = JobPayloadSchema, TRequirements = unknown> {
|
|
52
46
|
readonly _tag: "QueueWorker";
|
|
53
|
-
readonly handler: (payload: Schema.Schema.Type<
|
|
54
|
-
readonly queue: QueueDefinition<string,
|
|
47
|
+
readonly handler: (payload: Schema.Schema.Type<TPayload>, job: JobContext) => Effect.Effect<unknown, unknown, TRequirements>;
|
|
48
|
+
readonly queue: QueueDefinition<string, TPayload>;
|
|
55
49
|
}
|
|
56
50
|
|
|
57
51
|
export interface JobRegistration {
|
|
58
52
|
readonly _tag: "QueueDefinition" | "QueueWorker" | "ScheduledWorker";
|
|
59
53
|
}
|
|
60
54
|
|
|
61
|
-
export interface ScheduleDefinition<
|
|
55
|
+
export interface ScheduleDefinition<TName extends string = string> {
|
|
62
56
|
readonly _tag: "ScheduleDefinition";
|
|
63
57
|
readonly cron: string;
|
|
64
58
|
readonly maxDeferrals: number;
|
|
65
|
-
readonly name:
|
|
59
|
+
readonly name: TName;
|
|
66
60
|
readonly queueOptions: Omit<Queue, "name" | "deadLetter">;
|
|
67
61
|
readonly run: <E, R>(effect: Effect.Effect<unknown, E, R>) => ScheduledWorker<R>;
|
|
68
62
|
readonly scheduleOptions: ScheduleOptions;
|
|
69
63
|
readonly workerOptions: WorkOptions;
|
|
70
64
|
}
|
|
71
65
|
|
|
72
|
-
export interface ScheduledWorker<
|
|
66
|
+
export interface ScheduledWorker<TRequirements = unknown> {
|
|
73
67
|
readonly _tag: "ScheduledWorker";
|
|
74
|
-
readonly effect: Effect.Effect<unknown, unknown,
|
|
68
|
+
readonly effect: Effect.Effect<unknown, unknown, TRequirements>;
|
|
75
69
|
readonly schedule: ScheduleDefinition;
|
|
76
70
|
}
|
|
77
71
|
|
|
78
|
-
export type RegistrationRequirements<
|
|
79
|
-
?
|
|
80
|
-
?
|
|
81
|
-
:
|
|
82
|
-
?
|
|
72
|
+
export type RegistrationRequirements<TRegistrations extends readonly JobRegistration[]> = TRegistrations[number] extends infer TRegistration
|
|
73
|
+
? TRegistration extends QueueWorker<infer TPayload, infer TRequirements>
|
|
74
|
+
? TRequirements | TPayload["DecodingServices"]
|
|
75
|
+
: TRegistration extends ScheduledWorker<infer TRequirements>
|
|
76
|
+
? TRequirements
|
|
83
77
|
: never
|
|
84
78
|
: never;
|
|
85
79
|
|
|
86
|
-
export
|
|
87
|
-
readonly name:
|
|
88
|
-
readonly
|
|
89
|
-
readonly schema: Payload;
|
|
80
|
+
export type DefineQueueOptions<TName extends string, TPayload extends JobPayloadSchema> = {
|
|
81
|
+
readonly name: TName;
|
|
82
|
+
readonly schema: TPayload;
|
|
90
83
|
readonly worker?: WorkOptions;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
84
|
+
} & (
|
|
85
|
+
| { readonly key: (payload: Schema.Schema.Type<TPayload>) => string; readonly queue: QueueOptions & { readonly policy: "singleton" } }
|
|
86
|
+
| { readonly key?: never; readonly queue?: QueueOptions & { readonly policy?: Exclude<QueuePolicy, "singleton"> } }
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
export function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(
|
|
90
|
+
options: DefineQueueOptions<TName, TPayload> & { readonly key: (payload: Schema.Schema.Type<TPayload>) => string },
|
|
91
|
+
): QueueDefinition<TName, TPayload> & { readonly key: (payload: Schema.Schema.Type<TPayload>) => string };
|
|
92
|
+
export function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(
|
|
93
|
+
options: DefineQueueOptions<TName, TPayload> & { readonly key?: never },
|
|
94
|
+
): QueueDefinition<TName, TPayload> & { readonly key?: never };
|
|
95
|
+
export function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(
|
|
96
|
+
options: DefineQueueOptions<TName, TPayload>,
|
|
97
|
+
): QueueDefinition<TName, TPayload>;
|
|
98
|
+
export function defineQueue<const TName extends string, const TPayload extends JobPayloadSchema>(
|
|
99
|
+
options: DefineQueueOptions<TName, TPayload>,
|
|
100
|
+
): QueueDefinition<TName, TPayload> {
|
|
101
|
+
const definition: QueueDefinition<TName, TPayload> = {
|
|
97
102
|
_tag: "QueueDefinition",
|
|
103
|
+
...(options.key === undefined ? {} : { key: options.key }),
|
|
98
104
|
handle: (handler) =>
|
|
99
105
|
Object.freeze({
|
|
100
106
|
_tag: "QueueWorker" as const,
|
|
@@ -108,40 +114,27 @@ export const defineQueue = <const Name extends string, const Payload extends Job
|
|
|
108
114
|
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
109
115
|
};
|
|
110
116
|
return Object.freeze(definition);
|
|
111
|
-
}
|
|
117
|
+
}
|
|
112
118
|
|
|
113
|
-
export interface DefineScheduleOptions<
|
|
119
|
+
export interface DefineScheduleOptions<TName extends string> {
|
|
114
120
|
readonly cron: string;
|
|
115
|
-
readonly name:
|
|
121
|
+
readonly name: TName;
|
|
116
122
|
readonly queue?: QueueOptions;
|
|
117
123
|
readonly schedule?: ScheduleOptions;
|
|
118
124
|
readonly worker?: WorkOptions;
|
|
119
125
|
}
|
|
120
126
|
|
|
121
|
-
export
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
cron: options.cron,
|
|
125
|
-
maxDeferrals: maxDeferrals(options.queue),
|
|
126
|
-
name: options.name,
|
|
127
|
-
queueOptions: nativeQueueOptions(options.queue),
|
|
128
|
-
run: (effect) =>
|
|
129
|
-
Object.freeze({
|
|
130
|
-
_tag: "ScheduledWorker" as const,
|
|
131
|
-
effect,
|
|
132
|
-
schedule: definition,
|
|
133
|
-
}),
|
|
134
|
-
scheduleOptions: Object.freeze({ tz: "UTC", ...options.schedule }),
|
|
135
|
-
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
136
|
-
};
|
|
137
|
-
return Object.freeze(definition);
|
|
138
|
-
};
|
|
127
|
+
export function defineSchedule<const TName extends string>(options: DefineScheduleOptions<TName>): ScheduleDefinition<TName> {
|
|
128
|
+
return scheduleDefinition(options);
|
|
129
|
+
}
|
|
139
130
|
|
|
140
|
-
export
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
131
|
+
export function jobContext(job: Job<unknown>): JobContext {
|
|
132
|
+
return {
|
|
133
|
+
expireInSeconds: job.expireInSeconds,
|
|
134
|
+
heartbeatSeconds: job.heartbeatSeconds,
|
|
135
|
+
id: job.id,
|
|
136
|
+
name: job.name,
|
|
137
|
+
remainingBudget: Effect.map(Clock.currentTimeMillis, (now) => Duration.millis(Math.max(0, deadlineOf(job) - now))),
|
|
138
|
+
signal: job.signal,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { QueueOptions } from "#definition.ts";
|
|
2
|
+
|
|
3
|
+
export function maxDeferrals(options: QueueOptions | undefined): number {
|
|
4
|
+
const limit = options?.maxDeferrals ?? 10;
|
|
5
|
+
if (!Number.isSafeInteger(limit) || limit < 0) {
|
|
6
|
+
throw new RangeError("maxDeferrals must be a nonnegative safe integer");
|
|
7
|
+
}
|
|
8
|
+
return limit;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function nativeQueueOptions(options: QueueOptions | undefined) {
|
|
12
|
+
const { maxDeferrals: _limit, ...native } = options ?? {};
|
|
13
|
+
return Object.freeze(native);
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { DefineScheduleOptions, ScheduleDefinition } from "#definition.ts";
|
|
2
|
+
import { maxDeferrals, nativeQueueOptions } from "#internal/definitionOptions.ts";
|
|
3
|
+
|
|
4
|
+
export function scheduleDefinition<const TName extends string>(options: DefineScheduleOptions<TName>): ScheduleDefinition<TName> {
|
|
5
|
+
const definition: ScheduleDefinition<TName> = {
|
|
6
|
+
_tag: "ScheduleDefinition",
|
|
7
|
+
cron: options.cron,
|
|
8
|
+
maxDeferrals: maxDeferrals(options.queue),
|
|
9
|
+
name: options.name,
|
|
10
|
+
queueOptions: nativeQueueOptions(options.queue),
|
|
11
|
+
run: (effect) =>
|
|
12
|
+
Object.freeze({
|
|
13
|
+
_tag: "ScheduledWorker" as const,
|
|
14
|
+
effect,
|
|
15
|
+
schedule: definition,
|
|
16
|
+
}),
|
|
17
|
+
scheduleOptions: Object.freeze({ tz: "UTC", ...options.schedule }),
|
|
18
|
+
workerOptions: Object.freeze({ batchSize: 10, burstWhenBatchFull: true, ...options.worker }),
|
|
19
|
+
};
|
|
20
|
+
return Object.freeze(definition);
|
|
21
|
+
}
|
|
@@ -33,7 +33,7 @@ export const makeService = (client: PgBossClient, names: readonly string[], sche
|
|
|
33
33
|
Effect.flatMap((data) =>
|
|
34
34
|
Effect.tryPromise({
|
|
35
35
|
catch: (error) => toPgBossError("enqueue", error, queue.name),
|
|
36
|
-
try: () => client.send(queue.name, data, options),
|
|
36
|
+
try: () => client.send(queue.name, data, queue.key === undefined ? options : { ...options, singletonKey: queue.key(payload) }),
|
|
37
37
|
}),
|
|
38
38
|
),
|
|
39
39
|
Effect.map(Option.fromNullishOr),
|
|
@@ -6,7 +6,7 @@ import { testingOperation } from "#internal/testingReadout.ts";
|
|
|
6
6
|
|
|
7
7
|
export function testingDeferrals(client: () => PgBoss, schema: () => string, changed: () => void) {
|
|
8
8
|
return {
|
|
9
|
-
deferred: (queue: QueueDefinition) =>
|
|
9
|
+
deferred: (queue: Pick<QueueDefinition, "name">) =>
|
|
10
10
|
testingOperation(
|
|
11
11
|
"deferred",
|
|
12
12
|
async () => {
|
|
@@ -18,7 +18,7 @@ export function testingDeferrals(client: () => PgBoss, schema: () => string, cha
|
|
|
18
18
|
},
|
|
19
19
|
queue.name,
|
|
20
20
|
),
|
|
21
|
-
runDeferredNow: (queue: QueueDefinition) =>
|
|
21
|
+
runDeferredNow: (queue: Pick<QueueDefinition, "name">) =>
|
|
22
22
|
testingOperation(
|
|
23
23
|
"runDeferredNow",
|
|
24
24
|
async () => {
|
package/src/server/service.ts
CHANGED
|
@@ -10,18 +10,18 @@ import { registerJobs, registrationName } from "#internal/register.ts";
|
|
|
10
10
|
import { makeService } from "#internal/service.ts";
|
|
11
11
|
|
|
12
12
|
export interface PgBossService {
|
|
13
|
-
readonly counts: (queue: QueueDefinition) => Effect.Effect<QueueCounts, PgBossError>;
|
|
14
|
-
readonly enqueue: <const TName extends string, const TPayload extends JobPayloadSchema
|
|
15
|
-
queue: QueueDefinition<TName, TPayload
|
|
16
|
-
payload: Schema.Schema.Type<TPayload
|
|
17
|
-
options?: SendOptions,
|
|
13
|
+
readonly counts: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<QueueCounts, PgBossError>;
|
|
14
|
+
readonly enqueue: <const TName extends string, const TPayload extends JobPayloadSchema, const TQueue extends QueueDefinition<TName, TPayload>>(
|
|
15
|
+
queue: QueueDefinition<TName, TPayload> & TQueue,
|
|
16
|
+
payload: NoInfer<Schema.Schema.Type<TPayload>>,
|
|
17
|
+
options?: NoInfer<TQueue["key"] extends undefined ? SendOptions : Omit<SendOptions, "singletonKey"> & { readonly singletonKey?: never }>,
|
|
18
18
|
) => Effect.Effect<Option.Option<string>, PgBossError | PgBossPayloadError, TPayload["EncodingServices"]>;
|
|
19
19
|
readonly getJob: <const TName extends string, const TPayload extends JobPayloadSchema>(
|
|
20
20
|
queue: QueueDefinition<TName, TPayload>,
|
|
21
21
|
id: string,
|
|
22
22
|
) => Effect.Effect<Option.Option<JobWithMetadata<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
|
|
23
23
|
readonly health: Effect.Effect<JobsHealth, PgBossError>;
|
|
24
|
-
readonly retry: (queue: QueueDefinition, id: string) => Effect.Effect<void, PgBossError>;
|
|
24
|
+
readonly retry: (queue: Pick<QueueDefinition, "name">, id: string) => Effect.Effect<void, PgBossError>;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export type PgBossLayerOptions<TRegistrations extends readonly JobRegistration[], TErrorRequirements> = ConstructorOptions & {
|
package/src/server/testing.ts
CHANGED
|
@@ -40,7 +40,7 @@ export function makePgBossTesting(options: PgBossTestingOptions = {}) {
|
|
|
40
40
|
};
|
|
41
41
|
return {
|
|
42
42
|
...testingDeferrals(client, () => schema, signal.changed),
|
|
43
|
-
checkBatchWindow: (queue: QueueDefinition, millisecondsPerJob: number) =>
|
|
43
|
+
checkBatchWindow: (queue: Pick<QueueDefinition, "name" | "workerOptions">, millisecondsPerJob: number) =>
|
|
44
44
|
testingOperation(
|
|
45
45
|
"checkBatchWindow",
|
|
46
46
|
async () => {
|
|
@@ -68,7 +68,7 @@ export function makePgBossTesting(options: PgBossTestingOptions = {}) {
|
|
|
68
68
|
}
|
|
69
69
|
}),
|
|
70
70
|
clientFactory,
|
|
71
|
-
expireAfter: (queue: QueueDefinition, attempts: number) =>
|
|
71
|
+
expireAfter: (queue: Pick<QueueDefinition, "name">, attempts: number) =>
|
|
72
72
|
Effect.try({
|
|
73
73
|
catch: (original) => new PgBossTestingError({ operation: "expireAfter", original: Redacted.make(original), queue: queue.name }),
|
|
74
74
|
try: () => {
|
|
@@ -78,7 +78,7 @@ export function makePgBossTesting(options: PgBossTestingOptions = {}) {
|
|
|
78
78
|
controls.expirations.set(queue.name, attempts);
|
|
79
79
|
},
|
|
80
80
|
}),
|
|
81
|
-
failNextSend: (queue: QueueDefinition) => Effect.sync(() => controls.failures.add(queue.name)).pipe(Effect.asVoid),
|
|
81
|
+
failNextSend: (queue: Pick<QueueDefinition, "name">) => Effect.sync(() => controls.failures.add(queue.name)).pipe(Effect.asVoid),
|
|
82
82
|
jobs: testingReadout(client),
|
|
83
83
|
revision: signal.revision,
|
|
84
84
|
schemaVersion: testingOperation("schemaVersion", () => client().schemaVersion()),
|