@nest-native/jobs 0.1.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/README.md +115 -0
- package/dist/dialects/mysql/index.d.ts +2 -0
- package/dist/dialects/mysql/index.js +21 -0
- package/dist/dialects/mysql/index.js.map +1 -0
- package/dist/dialects/mysql/job-store.d.ts +35 -0
- package/dist/dialects/mysql/job-store.js +150 -0
- package/dist/dialects/mysql/job-store.js.map +1 -0
- package/dist/dialects/mysql/schema.d.ts +255 -0
- package/dist/dialects/mysql/schema.js +47 -0
- package/dist/dialects/mysql/schema.js.map +1 -0
- package/dist/dialects/postgres/index.d.ts +2 -0
- package/dist/dialects/postgres/index.js +21 -0
- package/dist/dialects/postgres/index.js.map +1 -0
- package/dist/dialects/postgres/job-store.d.ts +32 -0
- package/dist/dialects/postgres/job-store.js +145 -0
- package/dist/dialects/postgres/job-store.js.map +1 -0
- package/dist/dialects/postgres/schema.d.ts +262 -0
- package/dist/dialects/postgres/schema.js +37 -0
- package/dist/dialects/postgres/schema.js.map +1 -0
- package/dist/dialects/sqlite/index.d.ts +2 -0
- package/dist/dialects/sqlite/index.js +21 -0
- package/dist/dialects/sqlite/index.js.map +1 -0
- package/dist/dialects/sqlite/job-store.d.ts +32 -0
- package/dist/dialects/sqlite/job-store.js +155 -0
- package/dist/dialects/sqlite/job-store.js.map +1 -0
- package/dist/dialects/sqlite/schema.d.ts +279 -0
- package/dist/dialects/sqlite/schema.js +37 -0
- package/dist/dialects/sqlite/schema.js.map +1 -0
- package/dist/enqueue-input.d.ts +12 -0
- package/dist/enqueue-input.js +26 -0
- package/dist/enqueue-input.js.map +1 -0
- package/dist/errors.d.ts +18 -0
- package/dist/errors.js +33 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces.d.ts +125 -0
- package/dist/interfaces.js +10 -0
- package/dist/interfaces.js.map +1 -0
- package/dist/job-handler.decorator.d.ts +31 -0
- package/dist/job-handler.decorator.js +18 -0
- package/dist/job-handler.decorator.js.map +1 -0
- package/dist/jobs-claimer.service.d.ts +37 -0
- package/dist/jobs-claimer.service.js +121 -0
- package/dist/jobs-claimer.service.js.map +1 -0
- package/dist/jobs-handler.explorer.d.ts +24 -0
- package/dist/jobs-handler.explorer.js +67 -0
- package/dist/jobs-handler.explorer.js.map +1 -0
- package/dist/jobs-worker.d.ts +21 -0
- package/dist/jobs-worker.js +40 -0
- package/dist/jobs-worker.js.map +1 -0
- package/dist/jobs.module.d.ts +19 -0
- package/dist/jobs.module.js +49 -0
- package/dist/jobs.module.js.map +1 -0
- package/dist/jobs.service.d.ts +25 -0
- package/dist/jobs.service.js +55 -0
- package/dist/jobs.service.js.map +1 -0
- package/dist/testing/harness.d.ts +61 -0
- package/dist/testing/harness.js +86 -0
- package/dist/testing/harness.js.map +1 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +19 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/tokens.d.ts +10 -0
- package/dist/tokens.js +15 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +107 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// @nest-native/jobs/postgres — the node-postgres (async) dialect:
|
|
18
|
+
// the `jobs` table definition + the Postgres store.
|
|
19
|
+
__exportStar(require("./schema"), exports);
|
|
20
|
+
__exportStar(require("./job-store"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dialects/postgres/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,kEAAkE;AAClE,oDAAoD;AACpD,2CAAyB;AACzB,8CAA4B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EnqueueJobInput, JobRow, JobStore, ResolvedRunnerConfig } from '../../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* Postgres surfaces a unique-constraint violation with SQLSTATE `23505`
|
|
4
|
+
* (`unique_violation`). node-postgres exposes it as `error.code === '23505'`;
|
|
5
|
+
* Drizzle wraps driver errors in a `DrizzleQueryError`, so the code may instead
|
|
6
|
+
* sit on `error.cause`. Check both so the predicate is robust to wrapping.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isPgUniqueViolation(error: unknown): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Postgres (node-postgres) job store. Every method is **asynchronous** —
|
|
11
|
+
* `enqueue` awaits the insert (call it with `await` inside an async
|
|
12
|
+
* `@Transactional` body), and the claimer's batch claim runs in an async
|
|
13
|
+
* transaction.
|
|
14
|
+
*
|
|
15
|
+
* A `(name, unique_key)` unique violation on `enqueue` is the active-dedup
|
|
16
|
+
* no-op: the store returns the EXISTING active row instead of inserting.
|
|
17
|
+
*/
|
|
18
|
+
export declare class PostgresJobStore implements JobStore {
|
|
19
|
+
enqueue(db: unknown, input: EnqueueJobInput<object>): Promise<JobRow>;
|
|
20
|
+
/**
|
|
21
|
+
* On a unique violation with a `uniqueKey`, the ACTIVE row that owns the
|
|
22
|
+
* `(name, uniqueKey)` pair — terminal rows cannot own it (their key is
|
|
23
|
+
* cleared to NULL). Any other error, or a vanished row (the owner completed
|
|
24
|
+
* between the insert and this read), resolves undefined so the caller
|
|
25
|
+
* rethrows the original error.
|
|
26
|
+
*/
|
|
27
|
+
private findActiveDuplicate;
|
|
28
|
+
claimBatch(db: unknown, cfg: ResolvedRunnerConfig): Promise<JobRow[]>;
|
|
29
|
+
markCompleted(db: unknown, id: string): Promise<void>;
|
|
30
|
+
retry(db: unknown, id: string, delayMs: number, lastError?: string): Promise<void>;
|
|
31
|
+
markFailed(db: unknown, id: string, reason: string): Promise<void>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostgresJobStore = void 0;
|
|
4
|
+
exports.isPgUniqueViolation = isPgUniqueViolation;
|
|
5
|
+
const node_crypto_1 = require("node:crypto");
|
|
6
|
+
const drizzle_orm_1 = require("drizzle-orm");
|
|
7
|
+
const enqueue_input_1 = require("../../enqueue-input");
|
|
8
|
+
const schema_1 = require("./schema");
|
|
9
|
+
/**
|
|
10
|
+
* Postgres surfaces a unique-constraint violation with SQLSTATE `23505`
|
|
11
|
+
* (`unique_violation`). node-postgres exposes it as `error.code === '23505'`;
|
|
12
|
+
* Drizzle wraps driver errors in a `DrizzleQueryError`, so the code may instead
|
|
13
|
+
* sit on `error.cause`. Check both so the predicate is robust to wrapping.
|
|
14
|
+
*/
|
|
15
|
+
function isPgUniqueViolation(error) {
|
|
16
|
+
return hasCode(error, '23505') || hasCode(error?.cause, '23505');
|
|
17
|
+
}
|
|
18
|
+
function hasCode(error, code) {
|
|
19
|
+
return (typeof error === 'object' &&
|
|
20
|
+
error !== null &&
|
|
21
|
+
'code' in error &&
|
|
22
|
+
error.code === code);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Postgres (node-postgres) job store. Every method is **asynchronous** —
|
|
26
|
+
* `enqueue` awaits the insert (call it with `await` inside an async
|
|
27
|
+
* `@Transactional` body), and the claimer's batch claim runs in an async
|
|
28
|
+
* transaction.
|
|
29
|
+
*
|
|
30
|
+
* A `(name, unique_key)` unique violation on `enqueue` is the active-dedup
|
|
31
|
+
* no-op: the store returns the EXISTING active row instead of inserting.
|
|
32
|
+
*/
|
|
33
|
+
class PostgresJobStore {
|
|
34
|
+
async enqueue(db, input) {
|
|
35
|
+
const availableAt = (0, enqueue_input_1.resolveAvailableAt)(input).toISOString();
|
|
36
|
+
try {
|
|
37
|
+
const [row] = await db
|
|
38
|
+
.insert(schema_1.jobs)
|
|
39
|
+
.values({
|
|
40
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
41
|
+
name: input.name,
|
|
42
|
+
// The one place the structural input payload widens to the stored shape.
|
|
43
|
+
payload: input.payload,
|
|
44
|
+
status: 'pending',
|
|
45
|
+
maxAttempts: input.maxAttempts ?? 10,
|
|
46
|
+
uniqueKey: input.uniqueKey ?? null,
|
|
47
|
+
priority: input.priority ?? 0,
|
|
48
|
+
availableAt,
|
|
49
|
+
createdAt: new Date().toISOString(),
|
|
50
|
+
})
|
|
51
|
+
.returning();
|
|
52
|
+
return row;
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const existing = await this.findActiveDuplicate(db, input, error);
|
|
56
|
+
if (!existing)
|
|
57
|
+
throw error;
|
|
58
|
+
return existing;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* On a unique violation with a `uniqueKey`, the ACTIVE row that owns the
|
|
63
|
+
* `(name, uniqueKey)` pair — terminal rows cannot own it (their key is
|
|
64
|
+
* cleared to NULL). Any other error, or a vanished row (the owner completed
|
|
65
|
+
* between the insert and this read), resolves undefined so the caller
|
|
66
|
+
* rethrows the original error.
|
|
67
|
+
*/
|
|
68
|
+
async findActiveDuplicate(db, input, error) {
|
|
69
|
+
if (!isPgUniqueViolation(error) || input.uniqueKey == null) {
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
const [existing] = await db
|
|
73
|
+
.select()
|
|
74
|
+
.from(schema_1.jobs)
|
|
75
|
+
.where((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.jobs.name, input.name), (0, drizzle_orm_1.eq)(schema_1.jobs.uniqueKey, input.uniqueKey)));
|
|
76
|
+
return existing;
|
|
77
|
+
}
|
|
78
|
+
async claimBatch(db, cfg) {
|
|
79
|
+
const now = new Date();
|
|
80
|
+
const nowIso = now.toISOString();
|
|
81
|
+
const stuckCutoff = new Date(now.getTime() - cfg.stuckTimeoutMs).toISOString();
|
|
82
|
+
return db.transaction(async (tx) => {
|
|
83
|
+
const candidates = await tx
|
|
84
|
+
.select({ id: schema_1.jobs.id })
|
|
85
|
+
.from(schema_1.jobs)
|
|
86
|
+
.where((0, drizzle_orm_1.or)((0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.jobs.status, 'pending'), (0, drizzle_orm_1.lte)(schema_1.jobs.availableAt, nowIso)), (0, drizzle_orm_1.and)((0, drizzle_orm_1.eq)(schema_1.jobs.status, 'processing'), (0, drizzle_orm_1.lte)(schema_1.jobs.claimedAt, stuckCutoff))))
|
|
87
|
+
.orderBy((0, drizzle_orm_1.desc)(schema_1.jobs.priority), (0, drizzle_orm_1.asc)(schema_1.jobs.availableAt))
|
|
88
|
+
.limit(cfg.batchSize);
|
|
89
|
+
if (candidates.length === 0)
|
|
90
|
+
return [];
|
|
91
|
+
const ids = candidates.map((c) => c.id);
|
|
92
|
+
await tx
|
|
93
|
+
.update(schema_1.jobs)
|
|
94
|
+
.set({ status: 'processing', claimedAt: nowIso, claimedBy: cfg.workerInstanceId })
|
|
95
|
+
.where((0, drizzle_orm_1.inArray)(schema_1.jobs.id, ids));
|
|
96
|
+
return tx
|
|
97
|
+
.select()
|
|
98
|
+
.from(schema_1.jobs)
|
|
99
|
+
.where((0, drizzle_orm_1.inArray)(schema_1.jobs.id, ids))
|
|
100
|
+
.orderBy((0, drizzle_orm_1.desc)(schema_1.jobs.priority), (0, drizzle_orm_1.asc)(schema_1.jobs.availableAt));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
async markCompleted(db, id) {
|
|
104
|
+
await db
|
|
105
|
+
.update(schema_1.jobs)
|
|
106
|
+
.set({
|
|
107
|
+
status: 'completed',
|
|
108
|
+
processedAt: new Date().toISOString(),
|
|
109
|
+
lastError: null,
|
|
110
|
+
// Terminal → release the active-dedup key.
|
|
111
|
+
uniqueKey: null,
|
|
112
|
+
})
|
|
113
|
+
.where((0, drizzle_orm_1.eq)(schema_1.jobs.id, id));
|
|
114
|
+
}
|
|
115
|
+
async retry(db, id, delayMs, lastError) {
|
|
116
|
+
const nextAvailable = new Date(Date.now() + delayMs).toISOString();
|
|
117
|
+
await db
|
|
118
|
+
.update(schema_1.jobs)
|
|
119
|
+
.set({
|
|
120
|
+
status: 'pending',
|
|
121
|
+
attempts: (0, drizzle_orm_1.sql) `${schema_1.jobs.attempts} + 1`,
|
|
122
|
+
availableAt: nextAvailable,
|
|
123
|
+
claimedAt: null,
|
|
124
|
+
claimedBy: null,
|
|
125
|
+
lastError: lastError ?? null,
|
|
126
|
+
// Still active → the uniqueKey stays claimed.
|
|
127
|
+
})
|
|
128
|
+
.where((0, drizzle_orm_1.eq)(schema_1.jobs.id, id));
|
|
129
|
+
}
|
|
130
|
+
async markFailed(db, id, reason) {
|
|
131
|
+
await db
|
|
132
|
+
.update(schema_1.jobs)
|
|
133
|
+
.set({
|
|
134
|
+
status: 'failed',
|
|
135
|
+
attempts: (0, drizzle_orm_1.sql) `${schema_1.jobs.attempts} + 1`,
|
|
136
|
+
lastError: reason,
|
|
137
|
+
processedAt: new Date().toISOString(),
|
|
138
|
+
// Terminal → release the active-dedup key.
|
|
139
|
+
uniqueKey: null,
|
|
140
|
+
})
|
|
141
|
+
.where((0, drizzle_orm_1.eq)(schema_1.jobs.id, id));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
exports.PostgresJobStore = PostgresJobStore;
|
|
145
|
+
//# sourceMappingURL=job-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-store.js","sourceRoot":"","sources":["../../../dialects/postgres/job-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Postgres `jobs` table. Add it to your Drizzle schema and generate a
|
|
3
|
+
* migration with drizzle-kit. Timestamps are stored as ISO-8601 `text` so the
|
|
4
|
+
* row shape is identical across dialects (ISO-8601 compares lexicographically,
|
|
5
|
+
* which the claimer's `available_at` range query relies on).
|
|
6
|
+
*
|
|
7
|
+
* The **full** unique index on `(name, unique_key)` is the active-dedup
|
|
8
|
+
* primitive: Postgres treats `NULL`s as distinct in unique indexes (the
|
|
9
|
+
* default `NULLS DISTINCT`), so jobs without a `uniqueKey` never collide,
|
|
10
|
+
* and — because terminal transitions clear `unique_key` to `NULL` —
|
|
11
|
+
* uniqueness only constrains ACTIVE jobs. No partial index needed, so the
|
|
12
|
+
* same shape works on every dialect.
|
|
13
|
+
*/
|
|
14
|
+
export declare const jobs: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
15
|
+
name: "jobs";
|
|
16
|
+
schema: undefined;
|
|
17
|
+
columns: {
|
|
18
|
+
id: import("drizzle-orm/pg-core").PgColumn<{
|
|
19
|
+
name: "id";
|
|
20
|
+
tableName: "jobs";
|
|
21
|
+
dataType: "string";
|
|
22
|
+
columnType: "PgText";
|
|
23
|
+
data: string;
|
|
24
|
+
driverParam: string;
|
|
25
|
+
notNull: true;
|
|
26
|
+
hasDefault: false;
|
|
27
|
+
isPrimaryKey: true;
|
|
28
|
+
isAutoincrement: false;
|
|
29
|
+
hasRuntimeDefault: false;
|
|
30
|
+
enumValues: [string, ...string[]];
|
|
31
|
+
baseColumn: never;
|
|
32
|
+
identity: undefined;
|
|
33
|
+
generated: undefined;
|
|
34
|
+
}, {}, {}>;
|
|
35
|
+
name: import("drizzle-orm/pg-core").PgColumn<{
|
|
36
|
+
name: "name";
|
|
37
|
+
tableName: "jobs";
|
|
38
|
+
dataType: "string";
|
|
39
|
+
columnType: "PgText";
|
|
40
|
+
data: string;
|
|
41
|
+
driverParam: string;
|
|
42
|
+
notNull: true;
|
|
43
|
+
hasDefault: false;
|
|
44
|
+
isPrimaryKey: false;
|
|
45
|
+
isAutoincrement: false;
|
|
46
|
+
hasRuntimeDefault: false;
|
|
47
|
+
enumValues: [string, ...string[]];
|
|
48
|
+
baseColumn: never;
|
|
49
|
+
identity: undefined;
|
|
50
|
+
generated: undefined;
|
|
51
|
+
}, {}, {}>;
|
|
52
|
+
payload: import("drizzle-orm/pg-core").PgColumn<{
|
|
53
|
+
name: "payload";
|
|
54
|
+
tableName: "jobs";
|
|
55
|
+
dataType: "json";
|
|
56
|
+
columnType: "PgJsonb";
|
|
57
|
+
data: Record<string, unknown>;
|
|
58
|
+
driverParam: unknown;
|
|
59
|
+
notNull: true;
|
|
60
|
+
hasDefault: false;
|
|
61
|
+
isPrimaryKey: false;
|
|
62
|
+
isAutoincrement: false;
|
|
63
|
+
hasRuntimeDefault: false;
|
|
64
|
+
enumValues: undefined;
|
|
65
|
+
baseColumn: never;
|
|
66
|
+
identity: undefined;
|
|
67
|
+
generated: undefined;
|
|
68
|
+
}, {}, {
|
|
69
|
+
$type: Record<string, unknown>;
|
|
70
|
+
}>;
|
|
71
|
+
status: import("drizzle-orm/pg-core").PgColumn<{
|
|
72
|
+
name: "status";
|
|
73
|
+
tableName: "jobs";
|
|
74
|
+
dataType: "string";
|
|
75
|
+
columnType: "PgText";
|
|
76
|
+
data: "pending" | "processing" | "completed" | "failed";
|
|
77
|
+
driverParam: string;
|
|
78
|
+
notNull: true;
|
|
79
|
+
hasDefault: false;
|
|
80
|
+
isPrimaryKey: false;
|
|
81
|
+
isAutoincrement: false;
|
|
82
|
+
hasRuntimeDefault: false;
|
|
83
|
+
enumValues: [string, ...string[]];
|
|
84
|
+
baseColumn: never;
|
|
85
|
+
identity: undefined;
|
|
86
|
+
generated: undefined;
|
|
87
|
+
}, {}, {
|
|
88
|
+
$type: "pending" | "processing" | "completed" | "failed";
|
|
89
|
+
}>;
|
|
90
|
+
attempts: import("drizzle-orm/pg-core").PgColumn<{
|
|
91
|
+
name: "attempts";
|
|
92
|
+
tableName: "jobs";
|
|
93
|
+
dataType: "number";
|
|
94
|
+
columnType: "PgInteger";
|
|
95
|
+
data: number;
|
|
96
|
+
driverParam: string | number;
|
|
97
|
+
notNull: true;
|
|
98
|
+
hasDefault: true;
|
|
99
|
+
isPrimaryKey: false;
|
|
100
|
+
isAutoincrement: false;
|
|
101
|
+
hasRuntimeDefault: false;
|
|
102
|
+
enumValues: undefined;
|
|
103
|
+
baseColumn: never;
|
|
104
|
+
identity: undefined;
|
|
105
|
+
generated: undefined;
|
|
106
|
+
}, {}, {}>;
|
|
107
|
+
maxAttempts: import("drizzle-orm/pg-core").PgColumn<{
|
|
108
|
+
name: "max_attempts";
|
|
109
|
+
tableName: "jobs";
|
|
110
|
+
dataType: "number";
|
|
111
|
+
columnType: "PgInteger";
|
|
112
|
+
data: number;
|
|
113
|
+
driverParam: string | number;
|
|
114
|
+
notNull: true;
|
|
115
|
+
hasDefault: true;
|
|
116
|
+
isPrimaryKey: false;
|
|
117
|
+
isAutoincrement: false;
|
|
118
|
+
hasRuntimeDefault: false;
|
|
119
|
+
enumValues: undefined;
|
|
120
|
+
baseColumn: never;
|
|
121
|
+
identity: undefined;
|
|
122
|
+
generated: undefined;
|
|
123
|
+
}, {}, {}>;
|
|
124
|
+
uniqueKey: import("drizzle-orm/pg-core").PgColumn<{
|
|
125
|
+
name: "unique_key";
|
|
126
|
+
tableName: "jobs";
|
|
127
|
+
dataType: "string";
|
|
128
|
+
columnType: "PgText";
|
|
129
|
+
data: string;
|
|
130
|
+
driverParam: string;
|
|
131
|
+
notNull: false;
|
|
132
|
+
hasDefault: false;
|
|
133
|
+
isPrimaryKey: false;
|
|
134
|
+
isAutoincrement: false;
|
|
135
|
+
hasRuntimeDefault: false;
|
|
136
|
+
enumValues: [string, ...string[]];
|
|
137
|
+
baseColumn: never;
|
|
138
|
+
identity: undefined;
|
|
139
|
+
generated: undefined;
|
|
140
|
+
}, {}, {}>;
|
|
141
|
+
priority: import("drizzle-orm/pg-core").PgColumn<{
|
|
142
|
+
name: "priority";
|
|
143
|
+
tableName: "jobs";
|
|
144
|
+
dataType: "number";
|
|
145
|
+
columnType: "PgInteger";
|
|
146
|
+
data: number;
|
|
147
|
+
driverParam: string | number;
|
|
148
|
+
notNull: true;
|
|
149
|
+
hasDefault: true;
|
|
150
|
+
isPrimaryKey: false;
|
|
151
|
+
isAutoincrement: false;
|
|
152
|
+
hasRuntimeDefault: false;
|
|
153
|
+
enumValues: undefined;
|
|
154
|
+
baseColumn: never;
|
|
155
|
+
identity: undefined;
|
|
156
|
+
generated: undefined;
|
|
157
|
+
}, {}, {}>;
|
|
158
|
+
availableAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
159
|
+
name: "available_at";
|
|
160
|
+
tableName: "jobs";
|
|
161
|
+
dataType: "string";
|
|
162
|
+
columnType: "PgText";
|
|
163
|
+
data: string;
|
|
164
|
+
driverParam: string;
|
|
165
|
+
notNull: true;
|
|
166
|
+
hasDefault: false;
|
|
167
|
+
isPrimaryKey: false;
|
|
168
|
+
isAutoincrement: false;
|
|
169
|
+
hasRuntimeDefault: false;
|
|
170
|
+
enumValues: [string, ...string[]];
|
|
171
|
+
baseColumn: never;
|
|
172
|
+
identity: undefined;
|
|
173
|
+
generated: undefined;
|
|
174
|
+
}, {}, {}>;
|
|
175
|
+
claimedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
176
|
+
name: "claimed_at";
|
|
177
|
+
tableName: "jobs";
|
|
178
|
+
dataType: "string";
|
|
179
|
+
columnType: "PgText";
|
|
180
|
+
data: string;
|
|
181
|
+
driverParam: string;
|
|
182
|
+
notNull: false;
|
|
183
|
+
hasDefault: false;
|
|
184
|
+
isPrimaryKey: false;
|
|
185
|
+
isAutoincrement: false;
|
|
186
|
+
hasRuntimeDefault: false;
|
|
187
|
+
enumValues: [string, ...string[]];
|
|
188
|
+
baseColumn: never;
|
|
189
|
+
identity: undefined;
|
|
190
|
+
generated: undefined;
|
|
191
|
+
}, {}, {}>;
|
|
192
|
+
claimedBy: import("drizzle-orm/pg-core").PgColumn<{
|
|
193
|
+
name: "claimed_by";
|
|
194
|
+
tableName: "jobs";
|
|
195
|
+
dataType: "string";
|
|
196
|
+
columnType: "PgText";
|
|
197
|
+
data: string;
|
|
198
|
+
driverParam: string;
|
|
199
|
+
notNull: false;
|
|
200
|
+
hasDefault: false;
|
|
201
|
+
isPrimaryKey: false;
|
|
202
|
+
isAutoincrement: false;
|
|
203
|
+
hasRuntimeDefault: false;
|
|
204
|
+
enumValues: [string, ...string[]];
|
|
205
|
+
baseColumn: never;
|
|
206
|
+
identity: undefined;
|
|
207
|
+
generated: undefined;
|
|
208
|
+
}, {}, {}>;
|
|
209
|
+
processedAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
210
|
+
name: "processed_at";
|
|
211
|
+
tableName: "jobs";
|
|
212
|
+
dataType: "string";
|
|
213
|
+
columnType: "PgText";
|
|
214
|
+
data: string;
|
|
215
|
+
driverParam: string;
|
|
216
|
+
notNull: false;
|
|
217
|
+
hasDefault: false;
|
|
218
|
+
isPrimaryKey: false;
|
|
219
|
+
isAutoincrement: false;
|
|
220
|
+
hasRuntimeDefault: false;
|
|
221
|
+
enumValues: [string, ...string[]];
|
|
222
|
+
baseColumn: never;
|
|
223
|
+
identity: undefined;
|
|
224
|
+
generated: undefined;
|
|
225
|
+
}, {}, {}>;
|
|
226
|
+
lastError: import("drizzle-orm/pg-core").PgColumn<{
|
|
227
|
+
name: "last_error";
|
|
228
|
+
tableName: "jobs";
|
|
229
|
+
dataType: "string";
|
|
230
|
+
columnType: "PgText";
|
|
231
|
+
data: string;
|
|
232
|
+
driverParam: string;
|
|
233
|
+
notNull: false;
|
|
234
|
+
hasDefault: false;
|
|
235
|
+
isPrimaryKey: false;
|
|
236
|
+
isAutoincrement: false;
|
|
237
|
+
hasRuntimeDefault: false;
|
|
238
|
+
enumValues: [string, ...string[]];
|
|
239
|
+
baseColumn: never;
|
|
240
|
+
identity: undefined;
|
|
241
|
+
generated: undefined;
|
|
242
|
+
}, {}, {}>;
|
|
243
|
+
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
244
|
+
name: "created_at";
|
|
245
|
+
tableName: "jobs";
|
|
246
|
+
dataType: "string";
|
|
247
|
+
columnType: "PgText";
|
|
248
|
+
data: string;
|
|
249
|
+
driverParam: string;
|
|
250
|
+
notNull: true;
|
|
251
|
+
hasDefault: false;
|
|
252
|
+
isPrimaryKey: false;
|
|
253
|
+
isAutoincrement: false;
|
|
254
|
+
hasRuntimeDefault: false;
|
|
255
|
+
enumValues: [string, ...string[]];
|
|
256
|
+
baseColumn: never;
|
|
257
|
+
identity: undefined;
|
|
258
|
+
generated: undefined;
|
|
259
|
+
}, {}, {}>;
|
|
260
|
+
};
|
|
261
|
+
dialect: "pg";
|
|
262
|
+
}>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.jobs = void 0;
|
|
4
|
+
const pg_core_1 = require("drizzle-orm/pg-core");
|
|
5
|
+
/**
|
|
6
|
+
* Postgres `jobs` table. Add it to your Drizzle schema and generate a
|
|
7
|
+
* migration with drizzle-kit. Timestamps are stored as ISO-8601 `text` so the
|
|
8
|
+
* row shape is identical across dialects (ISO-8601 compares lexicographically,
|
|
9
|
+
* which the claimer's `available_at` range query relies on).
|
|
10
|
+
*
|
|
11
|
+
* The **full** unique index on `(name, unique_key)` is the active-dedup
|
|
12
|
+
* primitive: Postgres treats `NULL`s as distinct in unique indexes (the
|
|
13
|
+
* default `NULLS DISTINCT`), so jobs without a `uniqueKey` never collide,
|
|
14
|
+
* and — because terminal transitions clear `unique_key` to `NULL` —
|
|
15
|
+
* uniqueness only constrains ACTIVE jobs. No partial index needed, so the
|
|
16
|
+
* same shape works on every dialect.
|
|
17
|
+
*/
|
|
18
|
+
exports.jobs = (0, pg_core_1.pgTable)('jobs', {
|
|
19
|
+
id: (0, pg_core_1.text)('id').primaryKey(),
|
|
20
|
+
name: (0, pg_core_1.text)('name').notNull(),
|
|
21
|
+
payload: (0, pg_core_1.jsonb)('payload').$type().notNull(),
|
|
22
|
+
status: (0, pg_core_1.text)('status').$type().notNull(),
|
|
23
|
+
attempts: (0, pg_core_1.integer)('attempts').notNull().default(0),
|
|
24
|
+
maxAttempts: (0, pg_core_1.integer)('max_attempts').notNull().default(10),
|
|
25
|
+
uniqueKey: (0, pg_core_1.text)('unique_key'),
|
|
26
|
+
priority: (0, pg_core_1.integer)('priority').notNull().default(0),
|
|
27
|
+
availableAt: (0, pg_core_1.text)('available_at').notNull(),
|
|
28
|
+
claimedAt: (0, pg_core_1.text)('claimed_at'),
|
|
29
|
+
claimedBy: (0, pg_core_1.text)('claimed_by'),
|
|
30
|
+
processedAt: (0, pg_core_1.text)('processed_at'),
|
|
31
|
+
lastError: (0, pg_core_1.text)('last_error'),
|
|
32
|
+
createdAt: (0, pg_core_1.text)('created_at').notNull(),
|
|
33
|
+
}, (table) => [
|
|
34
|
+
(0, pg_core_1.uniqueIndex)('jobs_name_unique_key_unique').on(table.name, table.uniqueKey),
|
|
35
|
+
(0, pg_core_1.index)('jobs_status_available_idx').on(table.status, table.availableAt),
|
|
36
|
+
]);
|
|
37
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../dialects/postgres/schema.ts"],"names":[],"mappings":";;;AAAA,iDAO6B;AAG7B;;;;;;;;;;;;GAYG;AACU,QAAA,IAAI,GAAG,IAAA,iBAAO,EACzB,MAAM,EACN;IACE,EAAE,EAAE,IAAA,cAAI,EAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC3B,IAAI,EAAE,IAAA,cAAI,EAAC,MAAM,CAAC,CAAC,OAAO,EAAE;IAC5B,OAAO,EAAE,IAAA,eAAK,EAAC,SAAS,CAAC,CAAC,KAAK,EAA2B,CAAC,OAAO,EAAE;IACpE,MAAM,EAAE,IAAA,cAAI,EAAC,QAAQ,CAAC,CAAC,KAAK,EAAa,CAAC,OAAO,EAAE;IACnD,QAAQ,EAAE,IAAA,iBAAO,EAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,WAAW,EAAE,IAAA,iBAAO,EAAC,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC1D,SAAS,EAAE,IAAA,cAAI,EAAC,YAAY,CAAC;IAC7B,QAAQ,EAAE,IAAA,iBAAO,EAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC,CAAC,OAAO,EAAE;IAC3C,SAAS,EAAE,IAAA,cAAI,EAAC,YAAY,CAAC;IAC7B,SAAS,EAAE,IAAA,cAAI,EAAC,YAAY,CAAC;IAC7B,WAAW,EAAE,IAAA,cAAI,EAAC,cAAc,CAAC;IACjC,SAAS,EAAE,IAAA,cAAI,EAAC,YAAY,CAAC;IAC7B,SAAS,EAAE,IAAA,cAAI,EAAC,YAAY,CAAC,CAAC,OAAO,EAAE;CACxC,EACD,CAAC,KAAK,EAAE,EAAE,CAAC;IACT,IAAA,qBAAW,EAAC,6BAA6B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1E,IAAA,eAAK,EAAC,2BAA2B,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC;CACvE,CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
// @nest-native/jobs/sqlite — the better-sqlite3 (synchronous) dialect:
|
|
18
|
+
// the `jobs` table definition + the SQLite store.
|
|
19
|
+
__exportStar(require("./schema"), exports);
|
|
20
|
+
__exportStar(require("./job-store"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../dialects/sqlite/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,uEAAuE;AACvE,kDAAkD;AAClD,2CAAyB;AACzB,8CAA4B"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EnqueueJobInput, JobRow, JobStore, ResolvedRunnerConfig } from '../../interfaces';
|
|
2
|
+
/**
|
|
3
|
+
* better-sqlite3 surfaces a unique-constraint violation as a `SqliteError` with
|
|
4
|
+
* `code === 'SQLITE_CONSTRAINT_UNIQUE'`. Match on the code (stable across driver
|
|
5
|
+
* versions), not the message. Drizzle may wrap driver errors in a
|
|
6
|
+
* `DrizzleQueryError`, so the code may instead sit on `error.cause` — check both.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isSqliteUniqueViolation(error: unknown): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* SQLite (better-sqlite3) job store. Every method runs **synchronously** —
|
|
11
|
+
* `enqueue` returns the row directly so it composes inside a synchronous
|
|
12
|
+
* `@Transactional` body, and the rest wrap their synchronous result in a
|
|
13
|
+
* resolved Promise for the engine to await from outside the transaction.
|
|
14
|
+
*
|
|
15
|
+
* A `(name, unique_key)` unique violation on `enqueue` is the active-dedup
|
|
16
|
+
* no-op: the store returns the EXISTING active row instead of inserting.
|
|
17
|
+
*/
|
|
18
|
+
export declare class SqliteJobStore implements JobStore {
|
|
19
|
+
enqueue(db: unknown, input: EnqueueJobInput<object>): JobRow;
|
|
20
|
+
/**
|
|
21
|
+
* On a unique violation with a `uniqueKey`, the ACTIVE row that owns the
|
|
22
|
+
* `(name, uniqueKey)` pair — terminal rows cannot own it (their key is
|
|
23
|
+
* cleared to NULL). Any other error, or a vanished row (the owner completed
|
|
24
|
+
* between the insert and this read), returns undefined so the caller
|
|
25
|
+
* rethrows the original error.
|
|
26
|
+
*/
|
|
27
|
+
private findActiveDuplicate;
|
|
28
|
+
claimBatch(db: unknown, cfg: ResolvedRunnerConfig): Promise<JobRow[]>;
|
|
29
|
+
markCompleted(db: unknown, id: string): Promise<void>;
|
|
30
|
+
retry(db: unknown, id: string, delayMs: number, lastError?: string): Promise<void>;
|
|
31
|
+
markFailed(db: unknown, id: string, reason: string): Promise<void>;
|
|
32
|
+
}
|