@softure-ai/jobs 0.1.2 → 0.1.4
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 +40 -0
- package/README.md +110 -10
- package/dist/contract.d.ts +1 -1
- package/dist/contract.d.ts.map +1 -1
- package/dist/contract.js.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/messages/en.d.ts +2 -0
- package/dist/messages/en.d.ts.map +1 -1
- package/dist/messages/en.js +2 -0
- package/dist/messages/en.js.map +1 -1
- package/dist/messages/index.d.ts +2 -0
- package/dist/messages/index.d.ts.map +1 -1
- package/dist/options.d.ts +3 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +4 -2
- package/dist/options.js.map +1 -1
- package/dist/schema.d.ts +287 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +21 -1
- package/dist/schema.js.map +1 -1
- package/dist/server/claim.d.ts +2 -1
- package/dist/server/claim.d.ts.map +1 -1
- package/dist/server/claim.js +22 -14
- package/dist/server/claim.js.map +1 -1
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +2 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/schedules.d.ts +8 -0
- package/dist/server/schedules.d.ts.map +1 -1
- package/dist/server/schedules.js +12 -1
- package/dist/server/schedules.js.map +1 -1
- package/dist/server/sync-cursors.d.ts +23 -0
- package/dist/server/sync-cursors.d.ts.map +1 -0
- package/dist/server/sync-cursors.js +53 -0
- package/dist/server/sync-cursors.js.map +1 -0
- package/dist/server/sync-items.d.ts +45 -0
- package/dist/server/sync-items.d.ts.map +1 -0
- package/dist/server/sync-items.js +195 -0
- package/dist/server/sync-items.js.map +1 -0
- package/dist/sync.d.ts +65 -0
- package/dist/sync.d.ts.map +1 -0
- package/dist/sync.js +10 -0
- package/dist/sync.js.map +1 -0
- package/dist/testing/index.d.ts +9 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +8 -1
- package/dist/testing/index.js.map +1 -1
- package/dist/worker/health.d.ts +30 -0
- package/dist/worker/health.d.ts.map +1 -0
- package/dist/worker/health.js +53 -0
- package/dist/worker/health.js.map +1 -0
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/index.d.ts.map +1 -1
- package/dist/worker/index.js +3 -2
- package/dist/worker/index.js.map +1 -1
- package/dist/worker/process.d.ts +8 -2
- package/dist/worker/process.d.ts.map +1 -1
- package/dist/worker/process.js +27 -3
- package/dist/worker/process.js.map +1 -1
- package/dist/worker/run-job-worker.d.ts +5 -0
- package/dist/worker/run-job-worker.d.ts.map +1 -1
- package/dist/worker/run-job-worker.js +18 -0
- package/dist/worker/run-job-worker.js.map +1 -1
- package/migrations/0003_add_schedule_failures.sql +8 -0
- package/migrations/0004_create_sync_state.sql +41 -0
- package/module.json +2 -2
- package/package.json +1 -1
- package/src/contract.ts +3 -1
- package/src/index.ts +14 -3
- package/src/messages/en.ts +2 -0
- package/src/options.ts +4 -2
- package/src/schema.ts +29 -1
- package/src/server/claim.ts +20 -14
- package/src/server/index.ts +9 -0
- package/src/server/schedules.ts +18 -1
- package/src/server/sync-cursors.ts +67 -0
- package/src/server/sync-items.ts +236 -0
- package/src/sync.ts +59 -0
- package/src/testing/index.ts +18 -2
- package/src/worker/health.ts +64 -0
- package/src/worker/index.ts +3 -2
- package/src/worker/process.ts +32 -4
- package/src/worker/run-job-worker.ts +20 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,46 @@ Newest first. Each version lists what changed for an app that uses `@softure-ai/
|
|
|
4
4
|
production, the version gets a line `verified in: <app>@<commit>` ([docs/05](../../docs/05-adoption-playbook.md),
|
|
5
5
|
"Definition of done").
|
|
6
6
|
|
|
7
|
+
## 0.1.4
|
|
8
|
+
|
|
9
|
+
- Sync state for jobs that poll a third-party source (#639): a cursor per source and a processed-item ledger, so a
|
|
10
|
+
second run never acts twice on the same item, a failed item is retried a bounded number of times and an overview
|
|
11
|
+
shows what passed, what failed and why. New in `@softure-ai/jobs/server`: `getSyncCursor`, `advanceSyncCursor`
|
|
12
|
+
(compare-and-set; `jobs.sync_cursor_moved` when another run moved it first), `processSyncItem` (runs the callback in
|
|
13
|
+
the item's transaction, so the app's writes commit with the ledger's `done`; returns `handled`, `retrying`, `failed`
|
|
14
|
+
or `skipped`), `listSyncItems`, `pruneSyncItems`. New in `@softure-ai/jobs`: `skipSyncItem`, `failSyncItem`, the
|
|
15
|
+
`SyncItem*` types, `SYNC_ITEM_STATUSES`, `jobSyncCursorsTable`, `jobSyncItemsTable`; in `@softure-ai/jobs/testing`:
|
|
16
|
+
`listSyncState`. Error codes `jobs.sync_cursor_moved` and `jobs.sync_item_threw` with their `errors.*` copy.
|
|
17
|
+
- `retention.syncItemsDays` (default 90): ledger items no run met for that long are deleted by the worker's hourly
|
|
18
|
+
prune (or `pruneSyncItems` from a cron).
|
|
19
|
+
- Migration for an app: run the module migrations (`0004_create_sync_state.sql` adds `jobs.sync_cursors` and
|
|
20
|
+
`jobs.sync_items`). An app that keeps its own cursor and processed-items tables for a polling job can move to these
|
|
21
|
+
(copy its rows into them, then drop its tables); nothing changes for an app that does not poll. Code or tests that
|
|
22
|
+
compare the whole parsed `retention` option with `toEqual` see the new key.
|
|
23
|
+
|
|
24
|
+
## 0.1.3
|
|
25
|
+
|
|
26
|
+
- A health check of the worker's loop (#610): `runJobWorkerProcess({ healthFile })` (and `runJobWorker`) touches the
|
|
27
|
+
file after each round whose claims reached the database, removes a stale one at start and its own after a clean
|
|
28
|
+
stop; started with `--health`, the same entry checks the file instead of running (exit 0 when no older than
|
|
29
|
+
`healthMaxAgeMs`, default five poll intervals and at least 30 s; 1 when missing or older, or without `healthFile`).
|
|
30
|
+
New exports from `@softure-ai/jobs/worker`: `checkJobWorkerHealth`, `getJobWorkerHealthMaxAgeMs`, `JobWorkerHealth`.
|
|
31
|
+
Off by default: an app that passes no `healthFile` sees no change.
|
|
32
|
+
- Migration for an app whose worker runs in Docker with a liveness check of PID 1 (`node -e "process.kill(1, 0)"`):
|
|
33
|
+
after upgrading to this version, pass `healthFile: "/tmp/softure-jobs-worker.alive"` in `scripts/worker.ts` and set
|
|
34
|
+
the worker service's `healthcheck.test` to `["CMD", "node", "worker.mjs", "--health"]` in the production compose
|
|
35
|
+
file (and the integration one, if it has a worker). Do it in that order: an older worker does not know `--health`.
|
|
36
|
+
- `getQueueStats` reports a scheduled queue's last failure (#603): each `schedule` gains `lastFailedAt` (when a job of
|
|
37
|
+
the queue last ended `failed`: attempts used up, `failJob`, an invalid payload or an expired lease with no attempts
|
|
38
|
+
left; a retried attempt does not count), `lastFailureCode` (that job's error code, never an error's text) and
|
|
39
|
+
`isFailing` (`lastFailedAt` later than `lastSucceededAt`, or a failure and no success yet). Stored in
|
|
40
|
+
`jobs.schedules` in the same transaction as the failed job, so it outlives pruning; migration
|
|
41
|
+
`0003_add_schedule_failures.sql` adds two nullable columns.
|
|
42
|
+
- Migration for an app: run the module migrations (`0003` adds the columns; failures before it are not back-filled).
|
|
43
|
+
An app that kept a log of its own runs only to tell whether the latest run failed reads
|
|
44
|
+
`stats.schedule.isFailing`, `lastFailedAt` and `lastFailureCode` from `getQueueStats` instead and can drop that log.
|
|
45
|
+
Code or tests that compare a whole `schedule` with `toEqual` see the three new fields.
|
|
46
|
+
|
|
7
47
|
## 0.1.2
|
|
8
48
|
|
|
9
49
|
- Schedules at local times of day (#554): `schedules: { "<queue>": { at: ["09:00", "21:00"], timeZone: "Europe/Warsaw" } }`
|
package/README.md
CHANGED
|
@@ -10,7 +10,8 @@ received message.
|
|
|
10
10
|
A job queue in one table (`jobs.jobs`) with enqueue inside the caller's transaction and dedup keys, claims with
|
|
11
11
|
`FOR UPDATE SKIP LOCKED` under a lease, fenced completion, retry with exponential backoff, a worker process with
|
|
12
12
|
graceful shutdown, recurring schedules that run once per period however many workers run, and an in-process runner
|
|
13
|
-
for tests and cron-driven apps.
|
|
13
|
+
for tests and cron-driven apps. For jobs that poll a third-party source: a cursor per source and a processed-item
|
|
14
|
+
ledger, so a second run never acts twice on the same item (§3, "Sync state for polling").
|
|
14
15
|
|
|
15
16
|
## 2. Installation
|
|
16
17
|
|
|
@@ -53,7 +54,7 @@ export default defineSoftureConfig({
|
|
|
53
54
|
| `schedules.<queue>.payload` | `{}` | the payload of every scheduled run |
|
|
54
55
|
| `pollIntervalMs` | `1000` | how often an idle worker looks for due jobs |
|
|
55
56
|
| `shutdownGraceMs` | `20000` | how long a stopping worker waits for running handlers before releasing their jobs |
|
|
56
|
-
| `retention` | `{ succeededDays: 7, failedDays: 30, cancelledDays: 7 }` | how long finished jobs are kept; the worker prunes once an hour |
|
|
57
|
+
| `retention` | `{ succeededDays: 7, failedDays: 30, cancelledDays: 7, syncItemsDays: 90 }` | how long finished jobs, and sync ledger items no run met, are kept; the worker prunes once an hour |
|
|
57
58
|
|
|
58
59
|
A queue name is lowercase letters, digits, `_`, `.` and `-`. A queue the config does not define is refused by
|
|
59
60
|
`enqueueJob` and by the worker: a typo is a bug, not a new queue. A schedule defines its queue too, with the default
|
|
@@ -151,6 +152,31 @@ On SIGTERM the worker stops claiming, waits up to `shutdownGraceMs` for running
|
|
|
151
152
|
releases their jobs (pending again, due now, the attempt given back). Database errors while claiming or recording are
|
|
152
153
|
logged and retried on the next round; a database restart does not end the worker.
|
|
153
154
|
|
|
155
|
+
**Health check of the loop.** A process that is alive is not a loop that runs: a hung claim query or a database
|
|
156
|
+
connection the worker never gets back leaves the process up and the jobs untouched. With `healthFile`, the loop
|
|
157
|
+
touches that file after each round in which every claim reached the database (it removes a file left by an earlier
|
|
158
|
+
run at start, and removes its own after a clean stop), and the same entry answers `--health` instead of running:
|
|
159
|
+
|
|
160
|
+
```ts
|
|
161
|
+
// scripts/worker.ts
|
|
162
|
+
await runJobWorkerProcess({ config, handlers, healthFile: "/tmp/softure-jobs-worker.alive" });
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
# docker compose: the worker service
|
|
167
|
+
healthcheck:
|
|
168
|
+
test: ["CMD", "node", "worker.mjs", "--health"]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`node worker.mjs --health` opens no database and starts no loop: it exits 0 when the file is no older than
|
|
172
|
+
`healthMaxAgeMs` (default five poll intervals, at least 30 s: `getJobWorkerHealthMaxAgeMs(config)`) and 1 when it is
|
|
173
|
+
missing or older, with one line saying which. `--health` without `healthFile` exits 1 rather than start a second
|
|
174
|
+
worker; an older jobs version has no `--health` and would start one, so switch the check only after upgrading. An app
|
|
175
|
+
that runs the loop itself passes `healthFile` to `runJobWorker` and checks with
|
|
176
|
+
`checkJobWorkerHealth({ healthFile, maxAgeMs })`. `docker compose up --wait` then waits for a loop that reached the
|
|
177
|
+
database, and the container reads `unhealthy` while it is stuck; Docker's `restart:` policy does not act on that
|
|
178
|
+
status (a monitor or an orchestrator does). `@softure-ai/deploy` writes both lines from `init`.
|
|
179
|
+
|
|
154
180
|
`runJobWorker({ db, config, handlers, signal })` is the loop without the process part, for an app that runs it inside
|
|
155
181
|
a process of its own.
|
|
156
182
|
|
|
@@ -166,7 +192,7 @@ import { securityJobSchedules } from "@softure-ai/security/jobs";
|
|
|
166
192
|
jobs({
|
|
167
193
|
schedules: {
|
|
168
194
|
...authJobSchedules, // auth.prune-sessions hourly, auth.prune-password-resets daily
|
|
169
|
-
...securityJobSchedules, // security.prune-rate-limits hourly
|
|
195
|
+
...securityJobSchedules, // security.prune-rate-limits hourly, security.prune-webhook-deliveries daily
|
|
170
196
|
"app.digest": { every: "1d", payload: { kind: "weekly" } },
|
|
171
197
|
// The trial-ending reminder at 09:00 and 21:00 in the users' time zone, in place of billing's daily UTC period.
|
|
172
198
|
"billing.access-reminders": { at: ["09:00", "21:00"], timeZone: "Europe/Warsaw" },
|
|
@@ -201,9 +227,24 @@ export const handlers: JobHandlers = { ...authJobHandlers, ...securityJobHandler
|
|
|
201
227
|
optional peer.
|
|
202
228
|
|
|
203
229
|
`getQueueStats` reports each scheduled queue's `schedule`: `everySeconds` (for an `at` schedule the longest gap
|
|
204
|
-
between two of its times, 24h for one time), `lastEnqueuedAt` (the start of the latest slot a run was enqueued for), `lastSucceededAt` (any succeeded job of the queue, a run enqueued by hand too)
|
|
205
|
-
`
|
|
206
|
-
|
|
230
|
+
between two of its times, 24h for one time), `lastEnqueuedAt` (the start of the latest slot a run was enqueued for), `lastSucceededAt` (any succeeded job of the queue, a run enqueued by hand too),
|
|
231
|
+
`lastFailedAt` and `lastFailureCode` (the latest job of the queue that ended `failed`, with its error code: the
|
|
232
|
+
handler's code, `jobs.handler_threw`, `jobs.invalid_payload` or `jobs.lease_expired`, never an error's text; a retried
|
|
233
|
+
attempt is not a failure until the attempts are used up), `isFailing` and `isLate`. A queue is failing when its latest
|
|
234
|
+
outcome is a failure: `isFailing` is `lastFailedAt !== null && (lastSucceededAt === null || lastFailedAt >
|
|
235
|
+
lastSucceededAt)`. It is late when no run succeeded within two periods, counted from when a worker first saw the
|
|
236
|
+
schedule, or no worker has seen it at all. Successes and failures are recorded once a worker has taken the schedule's
|
|
237
|
+
first slot (its row in `jobs.schedules` exists), and they outlive the pruned jobs.
|
|
238
|
+
|
|
239
|
+
An app that shows how fresh a synced source is needs nothing else:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
const sync = (await getQueueStats(ctx)).find((stats) => stats.queue === "app.sync")?.schedule;
|
|
243
|
+
// "Updated at {lastSucceededAt}", plus "the last update failed ({lastFailureCode})" while isFailing.
|
|
244
|
+
const freshness = { updatedAt: sync?.lastSucceededAt ?? null, isFailing: sync?.isFailing ?? false };
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
The module's health check does not fail on a late schedule (a late cleanup must not take the app out of
|
|
207
248
|
rotation); an app that wants an alarm adds a check of its own:
|
|
208
249
|
|
|
209
250
|
```ts
|
|
@@ -224,6 +265,54 @@ among its queues, then runs every due job once, in this process, one after anoth
|
|
|
224
265
|
`{ succeeded, retried, failed, stale }`. A cron can drain a queue with it; call `pruneJobs(ctx)` from the same cron.
|
|
225
266
|
`enqueueDueSchedules(ctx, { queues? })` only enqueues the due scheduled runs.
|
|
226
267
|
|
|
268
|
+
### Sync state for polling
|
|
269
|
+
|
|
270
|
+
A job that polls a source (new mails under a label, changed tasks in a list, rows flagged for export) needs a cursor
|
|
271
|
+
that moves only after its batch was handled, and a ledger that remembers which items were handled. From
|
|
272
|
+
`@softure-ai/jobs/server`:
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
import { err, ok } from "@softure-ai/core";
|
|
276
|
+
import { skipSyncItem } from "@softure-ai/jobs";
|
|
277
|
+
import { advanceSyncCursor, getSyncCursor, processSyncItem } from "@softure-ai/jobs/server";
|
|
278
|
+
|
|
279
|
+
const from = await getSyncCursor(ctx, "gmail.inbox");
|
|
280
|
+
const batch = await gmail.listSince(from); // the app's own client
|
|
281
|
+
for (const message of batch.messages) {
|
|
282
|
+
await processSyncItem(ctx, { source: "gmail.inbox", itemId: message.id, maxAttempts: 3 }, async ({ db }) => {
|
|
283
|
+
if (!isTask(message)) return skipSyncItem("app.not_a_task");
|
|
284
|
+
const created = await createTask(db, message); // written through the item's transaction
|
|
285
|
+
return created.ok ? ok({ status: "done", resultRef: created.value.id }) : err("app.task_failed");
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
await advanceSyncCursor(ctx, { source: "gmail.inbox", from, to: batch.nextCursor });
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
- `processSyncItem(ctx, { source, itemId, maxAttempts? }, run)` takes the item's ledger row (inserting it on first
|
|
292
|
+
sight, locking it so two workers on one item take turns) and runs `run` unless the item is already `done`,
|
|
293
|
+
`skipped` or `failed`, which returns `{ kind: "skipped", item }`. `run` gets `{ ...ctx, db, attempt }` where `db` is
|
|
294
|
+
the item's transaction: writes through it commit together with the ledger's `done`, so "effect first, then
|
|
295
|
+
acknowledge" needs no code of the app's. `ok()` or `ok({ status: "done", resultRef })` → `handled`, item `done`;
|
|
296
|
+
`skipSyncItem(reason?)` → `handled`, item `skipped`; an `Err` → the writes roll back, the attempt counts, the item
|
|
297
|
+
stays `pending` (`retrying`) until `maxAttempts` (default 5) runs failed, then `failed`; `failSyncItem(code)` fails
|
|
298
|
+
it at once. A throw is recorded as a failed attempt with `jobs.sync_item_threw` and rethrown, so a poison item still
|
|
299
|
+
ends `failed`.
|
|
300
|
+
- A call outside the database (an API) is not rolled back: a crash after it and before the commit repeats it on the
|
|
301
|
+
next run. Keep it idempotent where the source allows, and keep each item short: its transaction stays open while
|
|
302
|
+
`run` runs.
|
|
303
|
+
- `getSyncCursor(ctx, source)` returns the cursor or `null`. `advanceSyncCursor(ctx, { source, from, to })` is a
|
|
304
|
+
compare-and-set: refused with `jobs.sync_cursor_moved` when the stored cursor is no longer `from`, so a slower
|
|
305
|
+
worker cannot move it back; re-read and go on. Pass a transaction as `ctx.db` to move it with the batch's last write.
|
|
306
|
+
- `listSyncItems(ctx, { source?, status?, since?, limit? })` lists the ledger, most recently changed first (default
|
|
307
|
+
100, at most 1000): what passed, what failed and with which code, for an overview page or an MCP tool.
|
|
308
|
+
- `pruneSyncItems(ctx)` deletes items no `processSyncItem` call met for `retention.syncItemsDays` (90), whatever
|
|
309
|
+
their status; every call touches `last_seen_at`, so an item the source still returns is never forgotten (and never
|
|
310
|
+
handled twice). The worker runs it with its hourly prune; an app without a worker calls it from its cron.
|
|
311
|
+
- A source name is lowercase letters, digits, `_ . : -`, starting with a letter, up to 127 characters (`gmail.inbox`,
|
|
312
|
+
`todoist:project-42`); an item id up to 500 characters.
|
|
313
|
+
- In tests, `listSyncState(db)` from `@softure-ai/jobs/testing` returns `{ cursors, items }` for assertions after
|
|
314
|
+
`runDueJobs` ran the polling job.
|
|
315
|
+
|
|
227
316
|
### Steering and overview
|
|
228
317
|
|
|
229
318
|
From `@softure-ai/jobs/server`, each on `ctx = { db, clock, config }`:
|
|
@@ -246,7 +335,8 @@ Nothing to mount: the module has no routes or pages. The worker is a process (§
|
|
|
246
335
|
|
|
247
336
|
## 5. Migrations and tables
|
|
248
337
|
|
|
249
|
-
Schema `jobs`,
|
|
338
|
+
Schema `jobs`, four tables, `migrations/0001_create_jobs.sql`, `migrations/0002_create_schedules.sql`,
|
|
339
|
+
`migrations/0003_add_schedule_failures.sql` and `migrations/0004_create_sync_state.sql`:
|
|
250
340
|
|
|
251
341
|
`jobs.jobs`: `id` (bigint identity; a string in the API), `queue`, `payload` (jsonb), `status` (`pending`, `running`,
|
|
252
342
|
`succeeded`, `failed`, `cancelled`), `attempts`, `max_attempts`, `run_at`, `locked_until`, `locked_by` (the worker,
|
|
@@ -255,9 +345,17 @@ Schema `jobs`, two tables, `migrations/0001_create_jobs.sql` and `migrations/000
|
|
|
255
345
|
for finished jobs; a partial unique index allows one live job per queue and dedup key.
|
|
256
346
|
|
|
257
347
|
`jobs.schedules`: `name` (the schedule's queue, primary key), `last_slot_at` (the start of the latest period a run
|
|
258
|
-
was enqueued for), `last_succeeded_at`, `
|
|
348
|
+
was enqueued for), `last_succeeded_at`, `last_failed_at`, `last_failure_code` (an error code, never a message),
|
|
349
|
+
`created_at`, `updated_at`. One row per schedule a worker has seen; a row of
|
|
259
350
|
a schedule removed from the config stays and is ignored.
|
|
260
351
|
|
|
352
|
+
`jobs.sync_cursors`: `source` (primary key), `cursor` (1 to 2000 characters), `created_at`, `updated_at`.
|
|
353
|
+
|
|
354
|
+
`jobs.sync_items`: `source` and `item_id` (primary key), `status` (`pending`, `done`, `skipped`, `failed`),
|
|
355
|
+
`error_code` (the last failure's code or the skip reason, never a message), `attempts`, `result_ref` (done items only),
|
|
356
|
+
`first_seen_at`, `last_seen_at`, `updated_at`, `finished_at`. Checks keep `finished_at` set exactly for final items and
|
|
357
|
+
an error code on failed ones.
|
|
358
|
+
|
|
261
359
|
The app role needs `SELECT, INSERT, UPDATE, DELETE` on the tables, which the `@softure-ai/ops` roles recipe grants on
|
|
262
360
|
every schema the migrator creates.
|
|
263
361
|
|
|
@@ -276,7 +374,8 @@ No UI.
|
|
|
276
374
|
## 9. Copy
|
|
277
375
|
|
|
278
376
|
`errors.*` in `src/messages/en.ts`, one key per error code (`invalid_payload`, `handler_threw`, `lease_expired`,
|
|
279
|
-
`not_found`, `not_cancellable`, `not_retryable`, `dedup_key_taken`), for an
|
|
377
|
+
`not_found`, `not_cancellable`, `not_retryable`, `dedup_key_taken`, `sync_cursor_moved`, `sync_item_threw`), for an
|
|
378
|
+
admin screen that shows a job's or a sync item's state.
|
|
280
379
|
|
|
281
380
|
## 10. Hooks
|
|
282
381
|
|
|
@@ -288,7 +387,8 @@ a release, pruning.
|
|
|
288
387
|
|
|
289
388
|
No export or deletion contributor: jobs are transient and pruned (§3, `retention`). Keep personal data out of
|
|
290
389
|
payloads (ids only); then a deleted account leaves nothing personal in `jobs.jobs`. `last_error` holds codes, and the
|
|
291
|
-
logger gets payload paths, never values, for a payload that does not match its schema.
|
|
390
|
+
logger gets payload paths, never values, for a payload that does not match its schema. The sync ledger holds the
|
|
391
|
+
source's item ids, not their content; if an id is personal (an e-mail address), the app hashes it before passing it.
|
|
292
392
|
|
|
293
393
|
## 12. Limitations
|
|
294
394
|
|
package/dist/contract.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Err, ErrorCode } from "@softure-ai/core";
|
|
2
|
-
export type JobsErrorCode = "jobs.invalid_payload" | "jobs.handler_threw" | "jobs.lease_expired" | "jobs.not_found" | "jobs.not_cancellable" | "jobs.not_retryable" | "jobs.dedup_key_taken";
|
|
2
|
+
export type JobsErrorCode = "jobs.invalid_payload" | "jobs.handler_threw" | "jobs.lease_expired" | "jobs.not_found" | "jobs.not_cancellable" | "jobs.not_retryable" | "jobs.dedup_key_taken" | "jobs.sync_cursor_moved" | "jobs.sync_item_threw";
|
|
3
3
|
export declare const JOB_STATUSES: readonly ["pending", "running", "succeeded", "failed", "cancelled"];
|
|
4
4
|
export type JobStatus = (typeof JOB_STATUSES)[number];
|
|
5
5
|
/** One job as the module's functions return it. */
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,CAAC;AAE3B,eAAO,MAAM,YAAY,qEAAsE,CAAC;AAEhG,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,mDAAmD;AACnD,MAAM,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,gDAAgD;AAChD,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACrD,0GAA0G;GACxG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,gBAAgB,GAChB,sBAAsB,GACtB,oBAAoB,GACpB,sBAAsB,GACtB,wBAAwB,GACxB,sBAAsB,CAAC;AAE3B,eAAO,MAAM,YAAY,qEAAsE,CAAC;AAEhG,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtD,mDAAmD;AACnD,MAAM,WAAW,GAAG;IAClB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,iDAAiD;IACjD,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,IAAI,GAAG,IAAI,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,SAAS,CAAC,GAAG;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC,CAAC;AAEF,gDAAgD;AAChD,MAAM,MAAM,UAAU,GAClB;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAA;CAAE,GAC1E;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACrD,0GAA0G;GACxG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC"}
|
package/dist/contract.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAeA,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAU,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export declare const jobs: import("@softure-ai/core").ModuleFactory<{}, {
|
|
|
12
12
|
not_cancellable: string;
|
|
13
13
|
not_retryable: string;
|
|
14
14
|
dedup_key_taken: string;
|
|
15
|
+
sync_cursor_moved: string;
|
|
16
|
+
sync_item_threw: string;
|
|
15
17
|
};
|
|
16
18
|
}, import("zod").ZodPipe<import("zod").ZodObject<{
|
|
17
19
|
queues: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
|
|
@@ -40,6 +42,7 @@ export declare const jobs: import("@softure-ai/core").ModuleFactory<{}, {
|
|
|
40
42
|
succeededDays: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
41
43
|
failedDays: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
42
44
|
cancelledDays: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
45
|
+
syncItemsDays: import("zod").ZodDefault<import("zod").ZodNumber>;
|
|
43
46
|
}, import("zod/v4/core").$strict>>;
|
|
44
47
|
}, import("zod/v4/core").$strict>, import("zod").ZodTransform<{
|
|
45
48
|
queues: {
|
|
@@ -60,6 +63,7 @@ export declare const jobs: import("@softure-ai/core").ModuleFactory<{}, {
|
|
|
60
63
|
succeededDays: number;
|
|
61
64
|
failedDays: number;
|
|
62
65
|
cancelledDays: number;
|
|
66
|
+
syncItemsDays: number;
|
|
63
67
|
};
|
|
64
68
|
}, {
|
|
65
69
|
queues: Record<string, {
|
|
@@ -78,11 +82,13 @@ export declare const jobs: import("@softure-ai/core").ModuleFactory<{}, {
|
|
|
78
82
|
succeededDays: number;
|
|
79
83
|
failedDays: number;
|
|
80
84
|
cancelledDays: number;
|
|
85
|
+
syncItemsDays: number;
|
|
81
86
|
};
|
|
82
87
|
}>>>;
|
|
83
88
|
export { JOB_STATUSES, type Job, type JobFailure, type JobOutcome, type JobsErrorCode, type JobStatus, } from "./contract.js";
|
|
84
89
|
export { jobsMessages, type JobsMessages } from "./messages/index.js";
|
|
85
90
|
export { jobsOptionsSchema, type JobQueueOptions, type JobScheduleOptions, type JobSchedulesInput, type JobsOptions, type JobsOptionsInput, type LocalTimeScheduleOptions, type PeriodScheduleOptions, } from "./options.js";
|
|
86
91
|
export { defineJobHandler, failJob, retryJobLater, type JobHandler, type JobHandlerContext, type JobHandlers } from "./handlers.js";
|
|
87
|
-
export { jobs as jobsTable, schedules as jobSchedulesTable } from "./schema.js";
|
|
92
|
+
export { jobs as jobsTable, schedules as jobSchedulesTable, syncCursors as jobSyncCursorsTable, syncItems as jobSyncItemsTable } from "./schema.js";
|
|
93
|
+
export { failSyncItem, skipSyncItem, SYNC_ITEM_STATUSES, type SyncItem, type SyncItemCompletion, type SyncItemFailure, type SyncItemOutcome, type SyncItemRunResult, type SyncItemStatus, } from "./sync.js";
|
|
88
94
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,SAAS,SAAS,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,IAAI
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,SAAS,SAAS,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiBf,CAAC;AAEH,OAAO,EACL,YAAY,EACZ,KAAK,GAAG,EACR,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACtE,OAAO,EACL,iBAAiB,EACjB,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,wBAAwB,EAC7B,KAAK,qBAAqB,GAC3B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,KAAK,UAAU,EAAE,KAAK,iBAAiB,EAAE,KAAK,WAAW,EAAE,MAAM,eAAe,CAAC;AACpI,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,SAAS,IAAI,iBAAiB,EAAE,WAAW,IAAI,mBAAmB,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpJ,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,GACpB,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -13,10 +13,10 @@ export const MODULE_ID = "jobs";
|
|
|
13
13
|
export const jobs = defineModule({
|
|
14
14
|
manifest: {
|
|
15
15
|
id: MODULE_ID,
|
|
16
|
-
version: "0.1.
|
|
16
|
+
version: "0.1.4",
|
|
17
17
|
dependsOn: {},
|
|
18
18
|
dbSchema: "jobs",
|
|
19
|
-
tables: ["jobs", "schedules"],
|
|
19
|
+
tables: ["jobs", "schedules", "sync_cursors", "sync_items"],
|
|
20
20
|
env: [],
|
|
21
21
|
switches: [],
|
|
22
22
|
routes: {},
|
|
@@ -32,5 +32,6 @@ export { JOB_STATUSES, } from "./contract.js";
|
|
|
32
32
|
export { jobsMessages } from "./messages/index.js";
|
|
33
33
|
export { jobsOptionsSchema, } from "./options.js";
|
|
34
34
|
export { defineJobHandler, failJob, retryJobLater } from "./handlers.js";
|
|
35
|
-
export { jobs as jobsTable, schedules as jobSchedulesTable } from "./schema.js";
|
|
35
|
+
export { jobs as jobsTable, schedules as jobSchedulesTable, syncCursors as jobSyncCursorsTable, syncItems as jobSyncItemsTable } from "./schema.js";
|
|
36
|
+
export { failSyncItem, skipSyncItem, SYNC_ITEM_STATUSES, } from "./sync.js";
|
|
36
37
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAC/G,oHAAoH;AACpH,uCAAuC;AACvC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEhC;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,YAAY,CAAC;IAC/B,QAAQ,EAAE;QACR,EAAE,EAAE,SAAS;QACb,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,EAAE;QACb,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,+GAA+G;AAC/G,oHAAoH;AACpH,uCAAuC;AACvC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC;AAEhC;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,YAAY,CAAC;IAC/B,QAAQ,EAAE;QACR,EAAE,EAAE,SAAS;QACb,OAAO,EAAE,OAAO;QAChB,SAAS,EAAE,EAAE;QACb,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,CAAC;QAC3D,GAAG,EAAE,EAAE;QACP,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,EAAE;QACV,KAAK,EAAE,EAAE;QACT,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE;KAC5C;IACD,QAAQ,EAAE,YAAY;IACtB,OAAO,EAAE,iBAAiB;IAC1B,UAAU,EAAE,EAAE,GAAG,EAAE,oBAAoB,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,EAAE;IAC5E,MAAM,EAAE,cAAc;CACvB,CAAC,CAAC;AAEH,OAAO,EACL,YAAY,GAMb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAqB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EACL,iBAAiB,GAQlB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAA6D,MAAM,eAAe,CAAC;AACpI,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE,SAAS,IAAI,iBAAiB,EAAE,WAAW,IAAI,mBAAmB,EAAE,SAAS,IAAI,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACpJ,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,kBAAkB,GAOnB,MAAM,WAAW,CAAC"}
|
package/dist/messages/en.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;CAYd,CAAC"}
|
package/dist/messages/en.js
CHANGED
|
@@ -7,6 +7,8 @@ export const en = {
|
|
|
7
7
|
not_cancellable: "Only a job that has not started can be cancelled.",
|
|
8
8
|
not_retryable: "Only a failed or cancelled job can be run again.",
|
|
9
9
|
dedup_key_taken: "Another job for the same work is already waiting or running.",
|
|
10
|
+
sync_cursor_moved: "Another run moved the sync position first.",
|
|
11
|
+
sync_item_threw: "Handling the item failed unexpectedly.",
|
|
10
12
|
},
|
|
11
13
|
};
|
|
12
14
|
//# sourceMappingURL=en.js.map
|
package/dist/messages/en.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,MAAM,EAAE;QACN,eAAe,EAAE,8BAA8B;QAC/C,aAAa,EAAE,sDAAsD;QACrE,aAAa,EAAE,iCAAiC;QAChD,SAAS,EAAE,yBAAyB;QACpC,eAAe,EAAE,mDAAmD;QACpE,aAAa,EAAE,kDAAkD;QACjE,eAAe,EAAE,8DAA8D;
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,MAAM,EAAE;QACN,eAAe,EAAE,8BAA8B;QAC/C,aAAa,EAAE,sDAAsD;QACrE,aAAa,EAAE,iCAAiC;QAChD,SAAS,EAAE,yBAAyB;QACpC,eAAe,EAAE,mDAAmD;QACpE,aAAa,EAAE,kDAAkD;QACjE,eAAe,EAAE,8DAA8D;QAC/E,iBAAiB,EAAE,4CAA4C;QAC/D,eAAe,EAAE,wCAAwC;KAC1D;CACF,CAAC"}
|
package/dist/messages/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,0GAA0G;AAC1G,eAAO,MAAM,YAAY
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/messages/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAE7B,0GAA0G;AAC1G,eAAO,MAAM,YAAY;;;;;;;;;;;;;;CAAS,CAAC;AAEnC,MAAM,MAAM,YAAY,GAAG,OAAO,EAAE,CAAC"}
|
package/dist/options.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export declare const jobsOptionsSchema: z.ZodPipe<z.ZodObject<{
|
|
|
39
39
|
succeededDays: z.ZodDefault<z.ZodNumber>;
|
|
40
40
|
failedDays: z.ZodDefault<z.ZodNumber>;
|
|
41
41
|
cancelledDays: z.ZodDefault<z.ZodNumber>;
|
|
42
|
+
syncItemsDays: z.ZodDefault<z.ZodNumber>;
|
|
42
43
|
}, z.core.$strict>>;
|
|
43
44
|
}, z.core.$strict>, z.ZodTransform<{
|
|
44
45
|
queues: {
|
|
@@ -59,6 +60,7 @@ export declare const jobsOptionsSchema: z.ZodPipe<z.ZodObject<{
|
|
|
59
60
|
succeededDays: number;
|
|
60
61
|
failedDays: number;
|
|
61
62
|
cancelledDays: number;
|
|
63
|
+
syncItemsDays: number;
|
|
62
64
|
};
|
|
63
65
|
}, {
|
|
64
66
|
queues: Record<string, {
|
|
@@ -77,6 +79,7 @@ export declare const jobsOptionsSchema: z.ZodPipe<z.ZodObject<{
|
|
|
77
79
|
succeededDays: number;
|
|
78
80
|
failedDays: number;
|
|
79
81
|
cancelledDays: number;
|
|
82
|
+
syncItemsDays: number;
|
|
80
83
|
};
|
|
81
84
|
}>>;
|
|
82
85
|
export type JobsOptionsInput = z.input<typeof jobsOptionsSchema>;
|
package/dist/options.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwBtB,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9D;AAyCH,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,iFAAiF;AACjF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwBtB,8GAA8G;AAC9G,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9D;AAyCH,4DAA4D;AAC5D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AAED,iFAAiF;AACjF,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC3C;AA2BD,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyB1B,CAAC;AAQL,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AACjE,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC7D,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC;AAC5D,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAClE,iGAAiG;AACjG,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,CAAC"}
|
package/dist/options.js
CHANGED
|
@@ -84,6 +84,8 @@ const retentionSchema = z.strictObject({
|
|
|
84
84
|
failedDays: z.number().int().min(1).max(3650).default(30),
|
|
85
85
|
/** Days a cancelled job is kept. */
|
|
86
86
|
cancelledDays: z.number().int().min(0).max(3650).default(7),
|
|
87
|
+
/** Days a sync ledger item is kept after the last run that met it (`processSyncItem`). */
|
|
88
|
+
syncItemsDays: z.number().int().min(1).max(3650).default(90),
|
|
87
89
|
});
|
|
88
90
|
export const jobsOptionsSchema = z
|
|
89
91
|
.strictObject({
|
|
@@ -99,8 +101,8 @@ export const jobsOptionsSchema = z
|
|
|
99
101
|
pollIntervalMs: z.number().int().min(50).max(60_000).default(1000),
|
|
100
102
|
/** How long a stopping worker waits for running handlers before it releases their jobs. */
|
|
101
103
|
shutdownGraceMs: z.number().int().min(0).max(10 * 60_000).default(20_000),
|
|
102
|
-
/** How long finished jobs are kept; the worker prunes once an hour. */
|
|
103
|
-
retention: retentionSchema.default({ succeededDays: 7, failedDays: 30, cancelledDays: 7 }),
|
|
104
|
+
/** How long finished jobs and unseen sync ledger items are kept; the worker prunes once an hour. */
|
|
105
|
+
retention: retentionSchema.default({ succeededDays: 7, failedDays: 30, cancelledDays: 7, syncItemsDays: 90 }),
|
|
104
106
|
})
|
|
105
107
|
.superRefine((options, context) => {
|
|
106
108
|
if (Object.keys(options.queues).length === 0 && Object.keys(options.schedules).length === 0) {
|
package/dist/options.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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"}
|