@shivaedev/effect-pg-boss 0.12.0 → 0.14.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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.14.0 - 2026-10-19
4
+
5
+ ### Added
6
+
7
+ - The jobs service lists a queue's failed jobs with `failedJobs(queue, { limit, cursor })` and the jobs in its dead-letter queue with `deadLetteredJobs(queue, { limit, cursor })`, newest first in pages with an opaque cursor. Each entry carries the job's ID, queue, state, attempt and retry counts, UTC times, the output pg-boss stored, and `data` decoded by the queue's Schema; invalid stored data fails with `PgBossPayloadError`. Dead-letter entries add the original job's ID and error. A failed entry's ID can be passed to `retry`.
8
+
9
+ ## 0.13.0 - 2026-10-19
10
+
11
+ ### Added
12
+
13
+ - Quality's `manifests/exports-shape` rule checks exports at the package root and in workspace members by default. Modules use one file-preserving TypeScript wildcard with matching source, types and runtime targets; root entries, exact non-code assets, package metadata and null blocks are allowed.
14
+
15
+ ### Breaking
16
+
17
+ - Quality's Biome preset moves from `@shivaedev/quality/biome` to `@shivaedev/quality/biome/preset.json`. Change the `extends` entry in your Biome config to the new path; the old alias is removed. TypeScript preset paths are unchanged.
18
+ - `@shivaedev/effect-pg-boss`, `@shivaedev/effect-test-sql`, `@shivaedev/local-postgres` and `@shivaedev/test-story` expose server modules at their file paths. Add `/server/` after the package name in imports, for example `@shivaedev/test-story/server/storyKit.ts`. The shortened paths are removed; internal server modules remain blocked.
19
+ - Work Board moves `@shivaedev/work-board/client/client.ts` to `@shivaedev/work-board/browserClient.ts`; change browser-client imports to that file path. `@shivaedev/work-board/client/document/View.ts` is removed: consume document queries with your own renderer, or use the bundled Board browser UI. The client bundle stays private and the old export overrides are removed.
20
+
3
21
  ## 0.12.0 - 2026-10-18
4
22
 
5
23
  ### Added
package/README.md CHANGED
@@ -7,7 +7,7 @@ Run PostgreSQL jobs through the same Effect services as the rest of your applica
7
7
  A background worker lives outside the request that queued it. Without a shared boundary, the producer writes one payload shape, the worker assumes another, and every worker rebuilds its dependencies and shutdown plumbing. This package puts those decisions in one place:
8
8
 
9
9
  ```ts
10
- import { defineQueue } from "@shivaedev/effect-pg-boss/definition.ts";
10
+ import { defineQueue } from "@shivaedev/effect-pg-boss/server/definition.ts";
11
11
  import { Effect, Schema } from "effect";
12
12
  import { Mail } from "./services.ts";
13
13
 
@@ -31,7 +31,7 @@ A **queue definition** names a pg-boss queue and the Schema of its payload. Appl
31
31
 
32
32
  A **schedule definition** describes a queue with a cron trigger. `schedule.run(effect)` pairs it with an Effect that needs no payload. Queue workers and scheduled workers are **registrations**: the values you put in the jobs Layer's `jobs` list.
33
33
 
34
- The application creates one jobs service with `makePgBoss(identifier)`. Its Layer starts a client, registers the job list and captures the services those workers need. The Layer's scope owns its client reference and releases it when the scope ends; the final reference closes the client. Callers use the jobs service to enqueue a decoded payload, look up or retry a job, or read queue health and live counts.
34
+ The application creates one jobs service with `makePgBoss(identifier)`. Its Layer starts a client, registers the job list and captures the services those workers need. The Layer's scope owns its client reference and releases it when the scope ends; the final reference closes the client. Callers use the jobs service to enqueue a decoded payload, look up or retry a job, read queue health and live counts, or list failed and dead-lettered jobs.
35
35
 
36
36
  Use a distinct literal identifier for each jobs service. The service and its Layer keep that identifier in their types, so providing a Layer for a different identifier leaves the required jobs service unprovided at compile time.
37
37
 
@@ -42,7 +42,7 @@ The work separates naturally: declare the application services once, define a qu
42
42
  `installPgBossSchema` installs or upgrades pg-boss through the provided Effect SQL client without starting workers or schedules. Run it outside an application transaction, in a release step or the `fixtures` Effect of `makePostgresTestLayer`, so stories inherit the schema from the migrated template:
43
43
 
44
44
  ```ts
45
- import { installPgBossSchema } from "@shivaedev/effect-pg-boss/schema.ts";
45
+ import { installPgBossSchema } from "@shivaedev/effect-pg-boss/server/schema.ts";
46
46
 
47
47
  const jobsFixture = installPgBossSchema({ schema: "app_jobs" });
48
48
  ```
@@ -56,7 +56,7 @@ After installation, pass the same schema and `migrate: false` to `Jobs.layer` to
56
56
  Define the application's jobs service and worker dependencies in `services.ts`:
57
57
 
58
58
  ```ts
59
- import { makePgBoss } from "@shivaedev/effect-pg-boss/service.ts";
59
+ import { makePgBoss } from "@shivaedev/effect-pg-boss/server/service.ts";
60
60
  import { Context, Effect, Layer } from "effect";
61
61
 
62
62
  export const Jobs = makePgBoss("@app/Jobs");
@@ -79,7 +79,7 @@ export const MailLive = Layer.succeed(Mail, {
79
79
  Define the feature's registrations in `jobs.ts`:
80
80
 
81
81
  ```ts
82
- import { defineQueue, defineSchedule } from "@shivaedev/effect-pg-boss/definition.ts";
82
+ import { defineQueue, defineSchedule } from "@shivaedev/effect-pg-boss/server/definition.ts";
83
83
  import { Effect, Schema } from "effect";
84
84
  import { Mail } from "./services.ts";
85
85
 
@@ -136,7 +136,7 @@ Fail a queue handler or scheduled Effect with `RetryAt` when a provider gives a
136
136
 
137
137
  ```ts
138
138
  import { DateTime, Effect } from "effect";
139
- import { RetryAt } from "@shivaedev/effect-pg-boss/definition.ts";
139
+ import { RetryAt } from "@shivaedev/effect-pg-boss/server/definition.ts";
140
140
 
141
141
  const waitForQuota = Effect.fail(new RetryAt({
142
142
  at: DateTime.makeUnsafe("2030-01-01T00:01:00Z"),
@@ -318,6 +318,33 @@ export const inspectEmail = (id: string) => Effect.gen(function* () {
318
318
 
319
319
  `getJob(queue, id)` returns `None` when the ID is absent, or `Some` pg-boss job metadata with `data` decoded by the queue's Schema. Invalid stored data fails with `PgBossPayloadError`, and the Effect requires the Schema's decoding services. `retry(queue, id)` reuses the original ID: it makes a failed job eligible for another attempt and pulls a retry-waiting job forward to run now. Missing IDs and jobs in other states are left unchanged. It does not remove an earlier copy from the dead-letter queue.
320
320
 
321
+ ### List failed and dead-lettered jobs
322
+
323
+ ```ts
324
+ import { Effect, Option } from "effect";
325
+ import { SendEmail } from "./jobs.ts";
326
+ import { Jobs } from "./services.ts";
327
+
328
+ export const failedEmails = (cursor?: string) => Effect.gen(function* () {
329
+ const jobs = yield* Jobs;
330
+ const failed = yield* jobs.failedJobs(SendEmail, { cursor, limit: 20 });
331
+ const deadLettered = yield* jobs.deadLetteredJobs(SendEmail, { limit: 20 });
332
+ return {
333
+ deadLettered: deadLettered.jobs.map((job) => ({ id: job.id, original: Option.getOrNull(job.sourceId), error: job.sourceOutput })),
334
+ failed: failed.jobs.map((job) => ({ id: job.id, attempt: job.attempt, error: job.output, userId: job.data.userId })),
335
+ next: Option.getOrUndefined(failed.next),
336
+ };
337
+ });
338
+ ```
339
+
340
+ `health` and `counts` say how many jobs failed; these two listings say which ones and why. `failedJobs(queue, options)` lists the queue's jobs in the `failed` state, the ones that used up their retries. `deadLetteredJobs(queue, options)` lists every job in the queue's dead-letter queue. Dead-letter entries live in the `-dlq` queue: each is a new job with its own ID that pg-boss copied there when the original failed for good. Both listings read pg-boss's `job` table on each call, through the jobs Layer's own pg-boss connection and in its configured schema, so applications never query pg-boss tables themselves. A custom client needs the native `getDb` capability for them.
341
+
342
+ Each page holds at most `limit` jobs, newest first by creation time; a dead-letter copy is created when its original fails for good. `limit` must be a positive integer. When more jobs remain, `next` is `Some` opaque cursor; pass it back as `cursor` for the following page, and stop when `next` is `None`. Paging continues from the last job it returned, so jobs that fail while you page appear in a fresh listing instead of shifting later pages, and no job appears twice. A malformed cursor or limit fails with `PgBossError` whose `operation` names the listing.
343
+
344
+ An entry carries the job's `id`, `queue`, native `state`, `retryCount`, `retryLimit` and `attempt`, the one-based number of its last started attempt (zero for a job that never started). `createdOn` is a UTC `DateTime`; `startedOn` and `completedOn` are `Option`s of UTC `DateTime`s. `output` is the job's stored output as pg-boss recorded it: for a failed job, the error its last attempt failed with, and `null` when pg-boss stored none. `data` is decoded by the queue's Schema, including traced payloads; invalid stored data fails the listing with `PgBossPayloadError`, as `getJob` does, and the Effect requires the Schema's decoding services. A dead-letter entry adds `sourceId`, the original job's ID as an `Option`, and `sourceOutput`, the error the original failed with. The copy has not run, so its own `output` stays `null` and its `attempt` is zero.
345
+
346
+ Pass a failed entry's `id` to `retry(queue, id)` to run that job again under its original ID; once it completes it leaves the failed listing. Dead-letter IDs belong to the `-dlq` queue, so `retry(queue, id)` does not find them and leaves them unchanged.
347
+
321
348
  ### Queue settings on startup
322
349
 
323
350
  `queue` accepts pg-boss `Queue` options except `name` and `deadLetter`, which the definition and adapter own, plus the adapter’s `maxDeferrals` limit. For prompt delivery, set `queue: { notify: true }` and enable `useListenNotify: true` in the worker Layer's constructor options.
@@ -392,8 +419,8 @@ This producer story uses the `SendEmail` definition and `Jobs` service from abov
392
419
  ```ts
393
420
  import { Context, Layer, Option } from "effect";
394
421
  import { expect } from "vitest";
395
- import { storyKit } from "@shivaedev/test-story/storyKit.ts";
396
- import { makePgBossTesting, testRetryPolicy } from "@shivaedev/effect-pg-boss/testing.ts";
422
+ import { storyKit } from "@shivaedev/test-story/server/storyKit.ts";
423
+ import { makePgBossTesting, testRetryPolicy } from "@shivaedev/effect-pg-boss/server/testing.ts";
397
424
 
398
425
  const emailStories = storyKit({
399
426
  clock: "live",
@@ -438,17 +465,17 @@ Import the module that defines the name; the package has no root entry.
438
465
 
439
466
  | Module | Public names |
440
467
  | --- | --- |
441
- | `@shivaedev/effect-pg-boss/definition.ts` | `defineQueue`, `defineSchedule`, `jobContext`, `RetryAt`; `DefineQueueOptions`, `DefineScheduleOptions`, `JobContext`, `JobPayloadSchema`, `JobRegistration`, `QueueDefinition`, `QueueOptions`, `QueuePolicy`, `QueueWorker`, `RegistrationRequirements`, `ScheduleDefinition`, `ScheduledWorker` |
442
- | `@shivaedev/effect-pg-boss/service.ts` | `makePgBoss`; `PgBossDefinition`, `PgBossLayerOptions`, `PgBossService` |
443
- | `@shivaedev/effect-pg-boss/schema.ts` | `installPgBossSchema`; `PgBossSchemaOptions` |
444
- | `@shivaedev/effect-pg-boss/health.ts` | `deadLetterQueueName`; `JobsHealth`, `QueueCounts`, `QueueHealth` |
445
- | `@shivaedev/effect-pg-boss/error.ts` | `PgBossError`, `PgBossPayloadError`, `PgBossQueueOptionsError`, `PgBossTestingError`, `toPgBossError`; `PgBossOperation` |
446
- | `@shivaedev/effect-pg-boss/client.ts` | `defaultClientFactory`; `PgBossClient`, `PgBossClientFactory` |
447
- | `@shivaedev/effect-pg-boss/testing.ts` | `makePgBossTesting`, `testRetryPolicy`; `PgBossTesting`, `PgBossTestingOptions` |
468
+ | `@shivaedev/effect-pg-boss/server/definition.ts` | `defineQueue`, `defineSchedule`, `jobContext`, `RetryAt`; `DefineQueueOptions`, `DefineScheduleOptions`, `JobContext`, `JobPayloadSchema`, `JobRegistration`, `QueueDefinition`, `QueueOptions`, `QueuePolicy`, `QueueWorker`, `RegistrationRequirements`, `ScheduleDefinition`, `ScheduledWorker` |
469
+ | `@shivaedev/effect-pg-boss/server/service.ts` | `makePgBoss`; `PgBossDefinition`, `PgBossLayerOptions`, `PgBossService` |
470
+ | `@shivaedev/effect-pg-boss/server/schema.ts` | `installPgBossSchema`; `PgBossSchemaOptions` |
471
+ | `@shivaedev/effect-pg-boss/server/health.ts` | `deadLetterQueueName`; `DeadLetteredJob`, `JobPage`, `JobPageOptions`, `JobsHealth`, `ListedJob`, `QueueCounts`, `QueueHealth` |
472
+ | `@shivaedev/effect-pg-boss/server/error.ts` | `PgBossError`, `PgBossPayloadError`, `PgBossQueueOptionsError`, `PgBossTestingError`, `toPgBossError`; `PgBossOperation` |
473
+ | `@shivaedev/effect-pg-boss/server/client.ts` | `defaultClientFactory`; `PgBossClient`, `PgBossClientFactory` |
474
+ | `@shivaedev/effect-pg-boss/server/testing.ts` | `makePgBossTesting`, `testRetryPolicy`; `PgBossTesting`, `PgBossTestingOptions` |
448
475
 
449
476
  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`.
450
477
 
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.
478
+ `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 and listings, deferral and reconciliation; a requested operation fails with `PgBossError` if its required capability is absent.
452
479
 
453
480
  `onError` handles pg-boss client `error` events using the services captured by the Layer. Only the owning jobs service is supplied automatically; a handler using another jobs definition still requires that definition's Layer.
454
481
 
@@ -1,5 +1,5 @@
1
1
  import { Redacted } from "effect";
2
- export type PgBossOperation = "counts" | "enqueue" | "getJob" | "health" | "install" | "register" | "retry" | "start" | "stop";
2
+ export type PgBossOperation = "counts" | "deadLetteredJobs" | "enqueue" | "failedJobs" | "getJob" | "health" | "install" | "register" | "retry" | "start" | "stop";
3
3
  declare const PgBossError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
4
4
  readonly _tag: "PgBossError";
5
5
  } & Readonly<A>;
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;;;;AAE/H,qBAAa,WAAY,SAAQ,iBAAgC;IAChE,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;IAED,IAAa,OAAO,IAAI,MAAM,CAG7B;CACD;;;;AAUD,qBAAa,uBAAwB,SAAQ,6BAA4C;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;CACtD,CAAC;IACD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACD;;;;AAED,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;CAAG;;;;AAEL,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;CAAG;AAEL,eAAO,MAAM,aAAa,cAAe,eAAe,SAAS,OAAO,UAAU,MAAM,KAAG,WAKxF,CAAC"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAExC,MAAM,MAAM,eAAe,GACxB,QAAQ,GACR,kBAAkB,GAClB,SAAS,GACT,YAAY,GACZ,QAAQ,GACR,QAAQ,GACR,SAAS,GACT,UAAU,GACV,OAAO,GACP,OAAO,GACP,MAAM,CAAC;;;;AAEV,qBAAa,WAAY,SAAQ,iBAAgC;IAChE,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;IAED,IAAa,OAAO,IAAI,MAAM,CAG7B;CACD;;;;AAUD,qBAAa,uBAAwB,SAAQ,6BAA4C;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,WAAW,GAAG,QAAQ,CAAC,EAAE,CAAC;CACtD,CAAC;IACD,IAAa,OAAO,IAAI,MAAM,CAE7B;CACD;;;;AAED,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,QAAQ,GAAG,QAAQ,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;CAC9C,CAAC;CAAG;;;;AAEL,qBAAa,kBAAmB,SAAQ,wBAAuC;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC9C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACpC,CAAC;CAAG;AAEL,eAAO,MAAM,aAAa,cAAe,eAAe,SAAS,OAAO,UAAU,MAAM,KAAG,WAKxF,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAIxC,MAAM,OAAO,WAAY,SAAQ,IAAI,CAAC,WAAW,CAAC,aAAa,CAI7D;IACD,yGAAyG;IACzG,IAAa,OAAO;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1E,OAAO,WAAW,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACpG,CAAC;CACD;AAED,SAAS,YAAY,CAAC,QAAiB;IACtC,IAAI,CAAC,CAAC,QAAQ,YAAY,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,QAAQ,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;AACtG,CAAC;AAED,MAAM,OAAO,uBAAwB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAGrF;IACD,IAAa,OAAO;QACnB,OAAO,SAAS,IAAI,CAAC,KAAK,0CAA0C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/F,CAAC;CACD;AAED,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAA0B,EAAE,KAAc,EAAE,KAAc,EAAe,EAAE,CACxG,IAAI,WAAW,CAAC;IACf,SAAS;IACT,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B,KAAK;CACL,CAAC,CAAC"}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/server/error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAexC,MAAM,OAAO,WAAY,SAAQ,IAAI,CAAC,WAAW,CAAC,aAAa,CAI7D;IACD,yGAAyG;IACzG,IAAa,OAAO;QACnB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1E,OAAO,WAAW,IAAI,CAAC,SAAS,GAAG,MAAM,YAAY,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACpG,CAAC;CACD;AAED,SAAS,YAAY,CAAC,QAAiB;IACtC,IAAI,CAAC,CAAC,QAAQ,YAAY,KAAK,CAAC,EAAE,CAAC;QAClC,OAAO,OAAO,QAAQ,CAAC;IACxB,CAAC;IACD,MAAM,IAAI,GAAY,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC;AACtG,CAAC;AAED,MAAM,OAAO,uBAAwB,SAAQ,IAAI,CAAC,WAAW,CAAC,yBAAyB,CAGrF;IACD,IAAa,OAAO;QACnB,OAAO,SAAS,IAAI,CAAC,KAAK,0CAA0C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAC/F,CAAC;CACD;AAED,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,OAAO,kBAAmB,SAAQ,IAAI,CAAC,WAAW,CAAC,oBAAoB,CAI3E;CAAG;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAA0B,EAAE,KAAc,EAAE,KAAc,EAAe,EAAE,CACxG,IAAI,WAAW,CAAC;IACf,SAAS;IACT,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;IAC9B,KAAK;CACL,CAAC,CAAC"}
@@ -1,3 +1,5 @@
1
+ import type { DateTime, Option } from "effect";
2
+ import type { JobWithMetadata } from "pg-boss";
1
3
  export interface QueueCounts {
2
4
  readonly activeCount: number;
3
5
  readonly failedCount: number;
@@ -21,4 +23,29 @@ export interface JobsHealth {
21
23
  readonly readyTotal: number;
22
24
  }
23
25
  export declare const deadLetterQueueName: (queueName: string) => string;
26
+ export interface ListedJob<TData> {
27
+ readonly attempt: number;
28
+ readonly completedOn: Option.Option<DateTime.Utc>;
29
+ readonly createdOn: DateTime.Utc;
30
+ readonly data: TData;
31
+ readonly id: string;
32
+ readonly output: unknown;
33
+ readonly queue: string;
34
+ readonly retryCount: number;
35
+ readonly retryLimit: number;
36
+ readonly startedOn: Option.Option<DateTime.Utc>;
37
+ readonly state: JobWithMetadata["state"];
38
+ }
39
+ export interface DeadLetteredJob<TData> extends ListedJob<TData> {
40
+ readonly sourceId: Option.Option<string>;
41
+ readonly sourceOutput: unknown;
42
+ }
43
+ export interface JobPageOptions {
44
+ readonly cursor?: string | undefined;
45
+ readonly limit: number;
46
+ }
47
+ export interface JobPage<TJob> {
48
+ readonly jobs: readonly TJob[];
49
+ readonly next: Option.Option<string>;
50
+ }
24
51
  //# sourceMappingURL=health.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/server/health.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,mBAAmB,cAAe,MAAM,KAAG,MAA4B,CAAC"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../../src/server/health.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,WAAW,EAAE,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,mBAAmB,cAAe,MAAM,KAAG,MAA4B,CAAC;AAErF,MAAM,WAAW,SAAS,CAAC,KAAK;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClD,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAChD,QAAQ,CAAC,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,eAAe,CAAC,KAAK,CAAE,SAAQ,SAAS,CAAC,KAAK,CAAC;IAC/D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACzC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,OAAO,CAAC,IAAI;IAC5B,QAAQ,CAAC,IAAI,EAAE,SAAS,IAAI,EAAE,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;CACrC"}
@@ -1 +1 @@
1
- {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/server/health.ts"],"names":[],"mappings":"AAyBA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,GAAG,SAAS,MAAM,CAAC"}
1
+ {"version":3,"file":"health.js","sourceRoot":"","sources":["../../src/server/health.ts"],"names":[],"mappings":"AA4BA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,SAAiB,EAAU,EAAE,CAAC,GAAG,SAAS,MAAM,CAAC"}
@@ -1,4 +1,4 @@
1
- const cacheSymbol = Symbol.for("@shivaedev/effect-pg-boss/client-cache");
1
+ const cacheSymbol = Symbol.for("@shivaedev/effect-pg-boss/server/client-cache");
2
2
  const shared = Reflect.get(globalThis, cacheSymbol);
3
3
  const clients = shared instanceof Map ? shared : new Map();
4
4
  Reflect.set(globalThis, cacheSymbol, clients);
@@ -1 +1 @@
1
- {"version":3,"file":"clientCache.js","sourceRoot":"","sources":["../../../src/server/internal/clientCache.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;AACzE,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC7D,MAAM,OAAO,GAAkC,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAA4B,CAAC;AACpH,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAE9C,SAAS,QAAQ,CAAC,GAAoB;IACrC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACrC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;WACtB,KAAK,KAAK,IAAI;WACd,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,OAAO;WAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,QAAQ,CACvD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAoB,EAAE,KAAkC;IACjG,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC;YACJ,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;YACzB,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC;IACD,MAAM,KAAK,GAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC;QACJ,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAoB;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;IACR,CAAC;IACD,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;IACtB,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO;IACR,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC,MAAM,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"clientCache.js","sourceRoot":"","sources":["../../../src/server/internal/clientCache.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;AAChF,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;AAC7D,MAAM,OAAO,GAAkC,MAAM,YAAY,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,EAA4B,CAAC;AACpH,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;AAE9C,SAAS,QAAQ,CAAC,GAAoB;IACrC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC/B,OAAO,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAED,SAAS,cAAc,CAAC,KAAc;IACrC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;WACtB,KAAK,KAAK,IAAI;WACd,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,OAAO;WAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,YAAY,CAAC,KAAK,QAAQ,CACvD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAoB,EAAE,KAAkC;IACjG,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC/B,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC;YACJ,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,QAAQ,CAAC,UAAU,IAAI,CAAC,CAAC;YACzB,MAAM,KAAK,CAAC;QACb,CAAC;IACF,CAAC;IACD,MAAM,KAAK,GAAiB,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACxB,IAAI,CAAC;QACJ,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC;YAChC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAoB;IACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO;IACR,CAAC;IACD,KAAK,CAAC,UAAU,IAAI,CAAC,CAAC;IACtB,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO;IACR,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACpB,OAAO,KAAK,CAAC,MAAM,CAAC;AACrB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- const key = Symbol.for("@shivaedev/effect-pg-boss/error-observers");
2
+ const key = Symbol.for("@shivaedev/effect-pg-boss/server/error-observers");
3
3
  const shared = Reflect.get(globalThis, key);
4
4
  const observers = shared instanceof WeakMap ? shared : new WeakMap();
5
5
  Reflect.set(globalThis, key, observers);
@@ -1 +1 @@
1
- {"version":3,"file":"clientErrors.js","sourceRoot":"","sources":["../../../src/server/internal/clientErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAUhC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;AACpE,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACrD,MAAM,SAAS,GAA8B,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,EAAoB,CAAC;AAClH,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;AAExC,MAAM,UAAU,cAAc,CAAC,KAAY;IAC1C,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IACnE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAoB,EAAE,QAAkB;IAC3E,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;IACtC,MAAM,QAAQ,GAAa,CAAC,KAAK,EAAE,EAAE;QACpC,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAChC,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;QACF,CAAC;IACF,CAAC,CAAC;IACF,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAoB,EAAE,QAAkB;IAC7E,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzD,CAAC;IACD,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAoB;IAC9C,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,MAAoB;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IACjC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;WACtB,KAAK,KAAK,IAAI;WACd,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,UAAU;WACnD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,YAAY,GAAG,CACjD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"clientErrors.js","sourceRoot":"","sources":["../../../src/server/internal/clientErrors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAUhC,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;AAC3E,MAAM,MAAM,GAAY,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACrD,MAAM,SAAS,GAA8B,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,OAAO,EAAoB,CAAC;AAClH,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,EAAE,SAAS,CAAC,CAAC;AAExC,MAAM,UAAU,cAAc,CAAC,KAAY;IAC1C,MAAM,OAAO,GAAG,EAAE,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IACnE,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAoB,EAAE,QAAkB;IAC3E,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAY,CAAC;IACtC,MAAM,QAAQ,GAAa,CAAC,KAAK,EAAE,EAAE;QACpC,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC1B,QAAQ,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;aAAM,CAAC;YACP,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;gBAChC,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;QACF,CAAC;IACF,CAAC,CAAC;IACF,qEAAqE;IACrE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7B,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;AACpF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAoB,EAAE,QAAkB;IAC7E,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzD,CAAC;IACD,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACjC,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,iBAAiB,CAAC,MAAoB;IAC9C,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;IAC/B,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,WAAW,CAAC,MAAoB;IACxC,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IACjC,OAAO,CACN,OAAO,KAAK,KAAK,QAAQ;WACtB,KAAK,KAAK,IAAI;WACd,OAAO,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,KAAK,UAAU;WACnD,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,WAAW,CAAC,YAAY,GAAG,CACjD,CAAC;AACH,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { PgBossClient } from "#client.ts";
2
+ import type { PgBossService } from "#service.ts";
3
+ export declare function failedJobsFor(client: PgBossClient, schema: string): PgBossService["failedJobs"];
4
+ export declare function deadLetteredJobsFor(client: PgBossClient, schema: string): PgBossService["deadLetteredJobs"];
5
+ //# sourceMappingURL=listJobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listJobs.d.ts","sourceRoot":"","sources":["../../../src/server/internal/listJobs.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAwBjD,wBAAgB,aAAa,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,YAAY,CAAC,CAK/F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,kBAAkB,CAAC,CAE3G"}
@@ -0,0 +1,69 @@
1
+ import { Effect, Option, Redacted, Schema } from "effect";
2
+ import { PgBossPayloadError, toPgBossError } from "#error.ts";
3
+ import { deadLetterQueueName } from "#health.ts";
4
+ import { payloadOf } from "#internal/tracing.ts";
5
+ const Cursor = Schema.StringFromBase64Url.pipe(Schema.decodeTo(Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String]))));
6
+ const Row = Schema.Struct({
7
+ completedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
8
+ createdOn: Schema.DateTimeUtcFromDate,
9
+ cursorAt: Schema.String,
10
+ data: Schema.Unknown,
11
+ id: Schema.String,
12
+ output: Schema.Unknown,
13
+ queue: Schema.String,
14
+ retryCount: Schema.Number,
15
+ retryLimit: Schema.Number,
16
+ sourceId: Schema.OptionFromNullOr(Schema.String),
17
+ sourceOutput: Schema.Unknown,
18
+ startedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
19
+ state: Schema.Literals(["created", "retry", "active", "completed", "cancelled", "failed"]),
20
+ });
21
+ const Rows = Schema.Array(Row);
22
+ export function failedJobsFor(client, schema) {
23
+ return (queue, options) => listJobs(client, schema, "failedJobs", queue, options).pipe(Effect.map(({ jobs, next }) => ({ jobs: jobs.map(({ sourceId: _id, sourceOutput: _output, ...job }) => job), next })));
24
+ }
25
+ export function deadLetteredJobsFor(client, schema) {
26
+ return (queue, options) => listJobs(client, schema, "deadLetteredJobs", queue, options);
27
+ }
28
+ function listJobs(client, schema, listing, queue, options) {
29
+ return Effect.tryPromise({
30
+ catch: (error) => toPgBossError(listing, error, queue.name),
31
+ try: async () => {
32
+ if (client.getDb === undefined) {
33
+ throw new TypeError("This pg-boss client does not support getDb");
34
+ }
35
+ if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
36
+ throw new RangeError("The page limit must be a positive integer");
37
+ }
38
+ const after = options.cursor === undefined ? undefined : await Schema.decodeUnknownPromise(Cursor)(options.cursor);
39
+ const quotedSchema = `"${schema.replaceAll('"', '""')}"`;
40
+ const { rows } = await client.getDb().executeSql(`SELECT
41
+ id,
42
+ name AS queue,
43
+ state,
44
+ retry_count AS "retryCount",
45
+ retry_limit AS "retryLimit",
46
+ created_on AS "createdOn",
47
+ started_on AS "startedOn",
48
+ completed_on AS "completedOn",
49
+ output,
50
+ data,
51
+ source_id AS "sourceId",
52
+ source_output AS "sourceOutput",
53
+ to_json(created_on) #>> '{}' AS "cursorAt"
54
+ FROM ${quotedSchema}.job
55
+ WHERE name = $1
56
+ ${listing === "failedJobs" ? "AND state = 'failed'" : ""}
57
+ AND ($2::timestamptz IS NULL OR (created_on, id) < ($2::timestamptz, $3::uuid))
58
+ ORDER BY created_on DESC, id DESC
59
+ LIMIT $4`, [listing === "failedJobs" ? queue.name : deadLetterQueueName(queue.name), after?.[0] ?? null, after?.[1] ?? null, options.limit + 1]);
60
+ return Schema.decodeUnknownPromise(Rows)(rows);
61
+ },
62
+ }).pipe(Effect.flatMap((rows) => {
63
+ const page = rows.slice(0, options.limit);
64
+ const last = page.at(-1);
65
+ const next = rows.length > options.limit && last !== undefined ? Option.some(Schema.encodeSync(Cursor)([last.cursorAt, last.id])) : Option.none();
66
+ return Effect.forEach(page, ({ cursorAt: _, data, ...row }) => Schema.decodeUnknownEffect(queue.schema)(payloadOf(data)).pipe(Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue: queue.name })), Effect.map((decoded) => ({ ...row, attempt: Option.isSome(row.startedOn) ? row.retryCount + 1 : 0, data: decoded })))).pipe(Effect.map((jobs) => ({ jobs, next })));
67
+ }));
68
+ }
69
+ //# sourceMappingURL=listJobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listJobs.js","sourceRoot":"","sources":["../../../src/server/internal/listJobs.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/server/internal/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAM/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,WAAW,WAAY,YAAY,SAAS,SAAS,MAAM,EAAE,sBAAsB,aAoC9F,CAAC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/server/internal/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,WAAW,WAAY,YAAY,SAAS,SAAS,MAAM,EAAE,sBAAsB,aAsC9F,CAAC"}
@@ -3,9 +3,11 @@ import { PgBossPayloadError, toPgBossError } from "#error.ts";
3
3
  import { countsFor } from "#internal/countsFor.ts";
4
4
  import { healthFor } from "#internal/health.ts";
5
5
  import { getJobFor, retryFor } from "#internal/jobControl.ts";
6
+ import { deadLetteredJobsFor, failedJobsFor } from "#internal/listJobs.ts";
6
7
  import { capturePayload } from "#internal/tracing.ts";
7
8
  export const makeService = (client, names, schema = "pgboss") => ({
8
9
  counts: (queue) => countsFor(client, schema, queue.name),
10
+ deadLetteredJobs: deadLetteredJobsFor(client, schema),
9
11
  enqueue: (queue, payload, options) => Schema.encodeUnknownEffect(queue.schema)(payload).pipe(Effect.mapError((error) => new PgBossPayloadError({
10
12
  direction: "encode",
11
13
  original: Redacted.make(error),
@@ -23,6 +25,7 @@ export const makeService = (client, names, schema = "pgboss") => ({
23
25
  try: () => client.send(queue.name, data, queue.key === undefined ? options : { ...options, singletonKey: queue.key(payload) }),
24
26
  })), Effect.map(Option.fromNullishOr));
25
27
  })),
28
+ failedJobs: failedJobsFor(client, schema),
26
29
  getJob: getJobFor(client),
27
30
  health: healthFor(client, names),
28
31
  retry: retryFor(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,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"}
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,mBAAmB,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,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,gBAAgB,EAAE,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC;IACrD,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,UAAU,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC;IACzC,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"}
@@ -3,12 +3,14 @@ import type { ConstructorOptions, JobWithMetadata, SendOptions, StopOptions } fr
3
3
  import type { PgBossClientFactory } from "#client.ts";
4
4
  import type { JobPayloadSchema, JobRegistration, QueueDefinition, RegistrationRequirements } from "#definition.ts";
5
5
  import type { PgBossError, PgBossPayloadError, PgBossQueueOptionsError } from "#error.ts";
6
- import type { JobsHealth, QueueCounts } from "#health.ts";
6
+ import type { DeadLetteredJob, JobPage, JobPageOptions, JobsHealth, ListedJob, QueueCounts } from "#health.ts";
7
7
  export interface PgBossService {
8
8
  readonly counts: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<QueueCounts, PgBossError>;
9
+ readonly deadLetteredJobs: <const TName extends string, const TPayload extends JobPayloadSchema>(queue: QueueDefinition<TName, TPayload>, options: JobPageOptions) => Effect.Effect<JobPage<DeadLetteredJob<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
9
10
  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
11
  readonly singletonKey?: never;
11
12
  }>) => Effect.Effect<Option.Option<string>, PgBossError | PgBossPayloadError, TPayload["EncodingServices"]>;
13
+ readonly failedJobs: <const TName extends string, const TPayload extends JobPayloadSchema>(queue: QueueDefinition<TName, TPayload>, options: JobPageOptions) => Effect.Effect<JobPage<ListedJob<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
12
14
  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"]>;
13
15
  readonly health: Effect.Effect<JobsHealth, PgBossError>;
14
16
  readonly retry: (queue: Pick<QueueDefinition, "name">, id: string) => Effect.Effect<void, PgBossError>;
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"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"}
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,eAAe,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM/G,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,gBAAgB,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EAC9F,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EACvC,OAAO,EAAE,cAAc,KACnB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IAC/H,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,UAAU,EAAE,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,KAAK,CAAC,QAAQ,SAAS,gBAAgB,EACxF,KAAK,EAAE,eAAe,CAAC,KAAK,EAAE,QAAQ,CAAC,EACvC,OAAO,EAAE,cAAc,KACnB,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,WAAW,GAAG,kBAAkB,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACzH,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"}
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/server/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAA4B,MAAM,QAAQ,CAAC;AAM1E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAoCnD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAmC,UAAuB,EAAiC,EAAE;IACtH,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAA6B,UAAU,CAAC,CAAC;IAExE,MAAM,KAAK,GAAG,CACb,OAA+D,EAK9D,EAAE;QAEH,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACjD,MAAM,EAAE,aAAa,EAAE,cAAc,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,kBAAkB,EAAE,GAAG,OAAO,CAAC;QAE9F,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,CACpC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YACnB,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,EAAgB,CAAC;YAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC;gBACrC,cAAc;gBACd,aAAa;gBACb,WAAW,EAAE,kBAAkB;aAC/B,CAAC,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC/E,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YAC5D,MAAM,WAAW,GAAgF,OAAO,IAAI,cAAc,CAAC;YAC3H,MAAM,aAAa,GAAG,CAAC,KAAY,EAAE,EAAE;gBACtC,KAAK,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YAClF,CAAC,CAAC;YACF,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;YAC1E,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAC9G,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC,IAAI,CAC9B,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,EAC7C,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CACnG,CAAC;QACH,CAAC,CAAC,EACF,CAAC,QAAQ,EAAE,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAC7G,CAAC;QAEF,OAAO,KAAK,CAAC,MAAM,CAClB,OAAO,EACP,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,CAC7C,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1C,CAAC,CAAC"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/server/service.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.12.0",
3
+ "version": "0.14.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": {
@@ -24,12 +24,12 @@
24
24
  },
25
25
  "exports": {
26
26
  "./*.ts": {
27
- "source": "./src/server/*.ts",
28
- "types": "./dist/server/*.d.ts",
29
- "default": "./dist/server/*.js"
27
+ "source": "./src/*.ts",
28
+ "types": "./dist/*.d.ts",
29
+ "default": "./dist/*.js"
30
30
  },
31
- "./internal/*": null,
32
- "./package.json": "./package.json"
31
+ "./package.json": "./package.json",
32
+ "./server/internal/*": null
33
33
  },
34
34
  "files": [
35
35
  "dist",
@@ -42,9 +42,9 @@
42
42
  ],
43
43
  "devDependencies": {
44
44
  "@shivaedev/effect-test": "0.7.1",
45
- "@shivaedev/effect-test-sql": "0.6.1",
46
- "@shivaedev/quality": "0.28.0",
47
- "@shivaedev/test-story": "0.12.0",
45
+ "@shivaedev/effect-test-sql": "0.8.1",
46
+ "@shivaedev/quality": "0.31.0",
47
+ "@shivaedev/test-story": "0.17.0",
48
48
  "@types/node": "24.19.2",
49
49
  "effect": "4.0.4",
50
50
  "pg-boss": "12.37.1",
@@ -1,6 +1,17 @@
1
1
  import { Data, Redacted } from "effect";
2
2
 
3
- export type PgBossOperation = "counts" | "enqueue" | "getJob" | "health" | "install" | "register" | "retry" | "start" | "stop";
3
+ export type PgBossOperation =
4
+ | "counts"
5
+ | "deadLetteredJobs"
6
+ | "enqueue"
7
+ | "failedJobs"
8
+ | "getJob"
9
+ | "health"
10
+ | "install"
11
+ | "register"
12
+ | "retry"
13
+ | "start"
14
+ | "stop";
4
15
 
5
16
  export class PgBossError extends Data.TaggedError("PgBossError")<{
6
17
  readonly operation: PgBossOperation;
@@ -1,3 +1,6 @@
1
+ import type { DateTime, Option } from "effect";
2
+ import type { JobWithMetadata } from "pg-boss";
3
+
1
4
  export interface QueueCounts {
2
5
  readonly activeCount: number;
3
6
  readonly failedCount: number;
@@ -24,3 +27,32 @@ export interface JobsHealth {
24
27
  }
25
28
 
26
29
  export const deadLetterQueueName = (queueName: string): string => `${queueName}-dlq`;
30
+
31
+ export interface ListedJob<TData> {
32
+ readonly attempt: number;
33
+ readonly completedOn: Option.Option<DateTime.Utc>;
34
+ readonly createdOn: DateTime.Utc;
35
+ readonly data: TData;
36
+ readonly id: string;
37
+ readonly output: unknown;
38
+ readonly queue: string;
39
+ readonly retryCount: number;
40
+ readonly retryLimit: number;
41
+ readonly startedOn: Option.Option<DateTime.Utc>;
42
+ readonly state: JobWithMetadata["state"];
43
+ }
44
+
45
+ export interface DeadLetteredJob<TData> extends ListedJob<TData> {
46
+ readonly sourceId: Option.Option<string>;
47
+ readonly sourceOutput: unknown;
48
+ }
49
+
50
+ export interface JobPageOptions {
51
+ readonly cursor?: string | undefined;
52
+ readonly limit: number;
53
+ }
54
+
55
+ export interface JobPage<TJob> {
56
+ readonly jobs: readonly TJob[];
57
+ readonly next: Option.Option<string>;
58
+ }
@@ -5,7 +5,7 @@ interface CachedClient {
5
5
  references: number;
6
6
  }
7
7
 
8
- const cacheSymbol = Symbol.for("@shivaedev/effect-pg-boss/client-cache");
8
+ const cacheSymbol = Symbol.for("@shivaedev/effect-pg-boss/server/client-cache");
9
9
  const shared: unknown = Reflect.get(globalThis, cacheSymbol);
10
10
  const clients: Map<string | symbol, unknown> = shared instanceof Map ? shared : new Map<string | symbol, unknown>();
11
11
  Reflect.set(globalThis, cacheSymbol, clients);
@@ -8,7 +8,7 @@ interface Observer {
8
8
  readonly listeners: Set<Listener>;
9
9
  }
10
10
 
11
- const key = Symbol.for("@shivaedev/effect-pg-boss/error-observers");
11
+ const key = Symbol.for("@shivaedev/effect-pg-boss/server/error-observers");
12
12
  const shared: unknown = Reflect.get(globalThis, key);
13
13
  const observers: WeakMap<WeakKey, unknown> = shared instanceof WeakMap ? shared : new WeakMap<WeakKey, unknown>();
14
14
  Reflect.set(globalThis, key, observers);
@@ -0,0 +1,99 @@
1
+ import { Effect, Option, Redacted, Schema } from "effect";
2
+ import type { PgBossClient } from "#client.ts";
3
+ import type { JobPayloadSchema, QueueDefinition } from "#definition.ts";
4
+ import { type PgBossError, PgBossPayloadError, toPgBossError } from "#error.ts";
5
+ import { type DeadLetteredJob, deadLetterQueueName, type JobPage, type JobPageOptions } from "#health.ts";
6
+ import { payloadOf } from "#internal/tracing.ts";
7
+ import type { PgBossService } from "#service.ts";
8
+
9
+ const Cursor = Schema.StringFromBase64Url.pipe(Schema.decodeTo(Schema.fromJsonString(Schema.Tuple([Schema.String, Schema.String]))));
10
+
11
+ const Row = Schema.Struct({
12
+ completedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
13
+ createdOn: Schema.DateTimeUtcFromDate,
14
+ cursorAt: Schema.String,
15
+ data: Schema.Unknown,
16
+ id: Schema.String,
17
+ output: Schema.Unknown,
18
+ queue: Schema.String,
19
+ retryCount: Schema.Number,
20
+ retryLimit: Schema.Number,
21
+ sourceId: Schema.OptionFromNullOr(Schema.String),
22
+ sourceOutput: Schema.Unknown,
23
+ startedOn: Schema.OptionFromNullOr(Schema.DateTimeUtcFromDate),
24
+ state: Schema.Literals(["created", "retry", "active", "completed", "cancelled", "failed"]),
25
+ });
26
+
27
+ const Rows = Schema.Array(Row);
28
+
29
+ type Listing = "deadLetteredJobs" | "failedJobs";
30
+
31
+ export function failedJobsFor(client: PgBossClient, schema: string): PgBossService["failedJobs"] {
32
+ return (queue, options) =>
33
+ listJobs(client, schema, "failedJobs", queue, options).pipe(
34
+ Effect.map(({ jobs, next }) => ({ jobs: jobs.map(({ sourceId: _id, sourceOutput: _output, ...job }) => job), next })),
35
+ );
36
+ }
37
+
38
+ export function deadLetteredJobsFor(client: PgBossClient, schema: string): PgBossService["deadLetteredJobs"] {
39
+ return (queue, options) => listJobs(client, schema, "deadLetteredJobs", queue, options);
40
+ }
41
+
42
+ function listJobs<const TName extends string, const TPayload extends JobPayloadSchema>(
43
+ client: PgBossClient,
44
+ schema: string,
45
+ listing: Listing,
46
+ queue: QueueDefinition<TName, TPayload>,
47
+ options: JobPageOptions,
48
+ ): Effect.Effect<JobPage<DeadLetteredJob<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]> {
49
+ return Effect.tryPromise({
50
+ catch: (error) => toPgBossError(listing, error, queue.name),
51
+ try: async () => {
52
+ if (client.getDb === undefined) {
53
+ throw new TypeError("This pg-boss client does not support getDb");
54
+ }
55
+ if (!Number.isSafeInteger(options.limit) || options.limit < 1) {
56
+ throw new RangeError("The page limit must be a positive integer");
57
+ }
58
+ const after = options.cursor === undefined ? undefined : await Schema.decodeUnknownPromise(Cursor)(options.cursor);
59
+ const quotedSchema = `"${schema.replaceAll('"', '""')}"`;
60
+ const { rows } = await client.getDb().executeSql(
61
+ `SELECT
62
+ id,
63
+ name AS queue,
64
+ state,
65
+ retry_count AS "retryCount",
66
+ retry_limit AS "retryLimit",
67
+ created_on AS "createdOn",
68
+ started_on AS "startedOn",
69
+ completed_on AS "completedOn",
70
+ output,
71
+ data,
72
+ source_id AS "sourceId",
73
+ source_output AS "sourceOutput",
74
+ to_json(created_on) #>> '{}' AS "cursorAt"
75
+ FROM ${quotedSchema}.job
76
+ WHERE name = $1
77
+ ${listing === "failedJobs" ? "AND state = 'failed'" : ""}
78
+ AND ($2::timestamptz IS NULL OR (created_on, id) < ($2::timestamptz, $3::uuid))
79
+ ORDER BY created_on DESC, id DESC
80
+ LIMIT $4`,
81
+ [listing === "failedJobs" ? queue.name : deadLetterQueueName(queue.name), after?.[0] ?? null, after?.[1] ?? null, options.limit + 1],
82
+ );
83
+ return Schema.decodeUnknownPromise(Rows)(rows);
84
+ },
85
+ }).pipe(
86
+ Effect.flatMap((rows) => {
87
+ const page = rows.slice(0, options.limit);
88
+ const last = page.at(-1);
89
+ const next =
90
+ rows.length > options.limit && last !== undefined ? Option.some(Schema.encodeSync(Cursor)([last.cursorAt, last.id])) : Option.none();
91
+ return Effect.forEach(page, ({ cursorAt: _, data, ...row }) =>
92
+ Schema.decodeUnknownEffect(queue.schema)(payloadOf(data)).pipe(
93
+ Effect.mapError((error) => new PgBossPayloadError({ direction: "decode", original: Redacted.make(error), queue: queue.name })),
94
+ Effect.map((decoded) => ({ ...row, attempt: Option.isSome(row.startedOn) ? row.retryCount + 1 : 0, data: decoded })),
95
+ ),
96
+ ).pipe(Effect.map((jobs) => ({ jobs, next })));
97
+ }),
98
+ );
99
+ }
@@ -4,11 +4,13 @@ import { type PgBossError, PgBossPayloadError, toPgBossError } from "#error.ts";
4
4
  import { countsFor } from "#internal/countsFor.ts";
5
5
  import { healthFor } from "#internal/health.ts";
6
6
  import { getJobFor, retryFor } from "#internal/jobControl.ts";
7
+ import { deadLetteredJobsFor, failedJobsFor } from "#internal/listJobs.ts";
7
8
  import { capturePayload } from "#internal/tracing.ts";
8
9
  import type { PgBossService } from "#service.ts";
9
10
 
10
11
  export const makeService = (client: PgBossClient, names: readonly string[], schema = "pgboss"): PgBossService => ({
11
12
  counts: (queue) => countsFor(client, schema, queue.name),
13
+ deadLetteredJobs: deadLetteredJobsFor(client, schema),
12
14
  enqueue: (queue, payload, options) =>
13
15
  Schema.encodeUnknownEffect(queue.schema)(payload).pipe(
14
16
  Effect.mapError(
@@ -40,6 +42,7 @@ export const makeService = (client: PgBossClient, names: readonly string[], sche
40
42
  );
41
43
  }),
42
44
  ),
45
+ failedJobs: failedJobsFor(client, schema),
43
46
  getJob: getJobFor(client),
44
47
  health: healthFor(client, names),
45
48
  retry: retryFor(client),
@@ -3,7 +3,7 @@ import type { ConstructorOptions, JobWithMetadata, SendOptions, StopOptions } fr
3
3
  import type { PgBossClientFactory } from "#client.ts";
4
4
  import type { JobPayloadSchema, JobRegistration, QueueDefinition, RegistrationRequirements } from "#definition.ts";
5
5
  import type { PgBossError, PgBossPayloadError, PgBossQueueOptionsError } from "#error.ts";
6
- import type { JobsHealth, QueueCounts } from "#health.ts";
6
+ import type { DeadLetteredJob, JobPage, JobPageOptions, JobsHealth, ListedJob, QueueCounts } from "#health.ts";
7
7
  import { logClientError, subscribeClientErrors } from "#internal/clientErrors.ts";
8
8
  import { acquireClient, releaseClient } from "#internal/lifecycle.ts";
9
9
  import { registerJobs, registrationName } from "#internal/register.ts";
@@ -11,11 +11,19 @@ import { makeService } from "#internal/service.ts";
11
11
 
12
12
  export interface PgBossService {
13
13
  readonly counts: (queue: Pick<QueueDefinition, "name">) => Effect.Effect<QueueCounts, PgBossError>;
14
+ readonly deadLetteredJobs: <const TName extends string, const TPayload extends JobPayloadSchema>(
15
+ queue: QueueDefinition<TName, TPayload>,
16
+ options: JobPageOptions,
17
+ ) => Effect.Effect<JobPage<DeadLetteredJob<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
14
18
  readonly enqueue: <const TName extends string, const TPayload extends JobPayloadSchema, const TQueue extends QueueDefinition<TName, TPayload>>(
15
19
  queue: QueueDefinition<TName, TPayload> & TQueue,
16
20
  payload: NoInfer<Schema.Schema.Type<TPayload>>,
17
21
  options?: NoInfer<TQueue["key"] extends undefined ? SendOptions : Omit<SendOptions, "singletonKey"> & { readonly singletonKey?: never }>,
18
22
  ) => Effect.Effect<Option.Option<string>, PgBossError | PgBossPayloadError, TPayload["EncodingServices"]>;
23
+ readonly failedJobs: <const TName extends string, const TPayload extends JobPayloadSchema>(
24
+ queue: QueueDefinition<TName, TPayload>,
25
+ options: JobPageOptions,
26
+ ) => Effect.Effect<JobPage<ListedJob<TPayload["Type"]>>, PgBossError | PgBossPayloadError, TPayload["DecodingServices"]>;
19
27
  readonly getJob: <const TName extends string, const TPayload extends JobPayloadSchema>(
20
28
  queue: QueueDefinition<TName, TPayload>,
21
29
  id: string,