queue-jobs-worker 1.0.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 +76 -0
- package/LICENSE +21 -0
- package/README.md +821 -0
- package/dist/core/backoff.d.ts +24 -0
- package/dist/core/backoff.d.ts.map +1 -0
- package/dist/core/client.d.ts +93 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/id.d.ts +9 -0
- package/dist/core/id.d.ts.map +1 -0
- package/dist/core/index.d.ts +7 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/job.d.ts +75 -0
- package/dist/core/job.d.ts.map +1 -0
- package/dist/core/queue.d.ts +70 -0
- package/dist/core/queue.d.ts.map +1 -0
- package/dist/core/worker.d.ts +65 -0
- package/dist/core/worker.d.ts.map +1 -0
- package/dist/events/emitter.d.ts +24 -0
- package/dist/events/emitter.d.ts.map +1 -0
- package/dist/index.cjs +2229 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2219 -0
- package/dist/index.js.map +1 -0
- package/dist/storage/in-memory.adapter.d.ts +32 -0
- package/dist/storage/in-memory.adapter.d.ts.map +1 -0
- package/dist/storage/index.d.ts +5 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/mysql.adapter.d.ts +37 -0
- package/dist/storage/mysql.adapter.d.ts.map +1 -0
- package/dist/storage/postgres.adapter.d.ts +37 -0
- package/dist/storage/postgres.adapter.d.ts.map +1 -0
- package/dist/storage/redis.adapter.d.ts +44 -0
- package/dist/storage/redis.adapter.d.ts.map +1 -0
- package/dist/types/client.types.d.ts +41 -0
- package/dist/types/client.types.d.ts.map +1 -0
- package/dist/types/events.types.d.ts +22 -0
- package/dist/types/events.types.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/job.types.d.ts +97 -0
- package/dist/types/job.types.d.ts.map +1 -0
- package/dist/types/queue.types.d.ts +43 -0
- package/dist/types/queue.types.d.ts.map +1 -0
- package/dist/types/storage.types.d.ts +120 -0
- package/dist/types/storage.types.d.ts.map +1 -0
- package/dist/types/worker.types.d.ts +25 -0
- package/dist/types/worker.types.d.ts.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backoff strategies
|
|
3
|
+
*
|
|
4
|
+
* Calculates the delay (in ms) before a failed job is re-queued.
|
|
5
|
+
*
|
|
6
|
+
* - fixed — always uses `baseDelay`
|
|
7
|
+
* - linear — baseDelay × attemptNumber
|
|
8
|
+
* - exponential — baseDelay × 2^(attemptNumber - 1), capped at MAX_DELAY
|
|
9
|
+
*/
|
|
10
|
+
import type { BackoffStrategy } from "../types/job.types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Returns the retry delay in milliseconds for the given attempt.
|
|
13
|
+
*
|
|
14
|
+
* @param strategy - Backoff strategy name.
|
|
15
|
+
* @param baseDelay - Base delay in ms (from job / queue / client config).
|
|
16
|
+
* @param attemptNumber - The 1-based attempt number that just failed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function calculateBackoff(strategy: BackoffStrategy, baseDelay: number, attemptNumber: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* Returns the ISO timestamp at which a job should next become eligible,
|
|
21
|
+
* given the current time and the calculated delay.
|
|
22
|
+
*/
|
|
23
|
+
export declare function nextRunAt(delayMs: number, fromDate?: Date): string;
|
|
24
|
+
//# sourceMappingURL=backoff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backoff.d.ts","sourceRoot":"","sources":["../../src/core/backoff.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,MAAM,CAuBR;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,IAAiB,GAAG,MAAM,CAE9E"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QueueClient
|
|
3
|
+
*
|
|
4
|
+
* Primary entry point for the queue-jobs-worker package.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
*
|
|
8
|
+
* // In-memory (dev / tests)
|
|
9
|
+
* const client = new QueueClient();
|
|
10
|
+
* // init() is optional for "memory" but always safe to call
|
|
11
|
+
*
|
|
12
|
+
* // Redis
|
|
13
|
+
* const client = new QueueClient({ dialect: "redis", connectionString: "redis://localhost:6379" });
|
|
14
|
+
* await client.init(); // connects, pings Redis
|
|
15
|
+
*
|
|
16
|
+
* // PostgreSQL
|
|
17
|
+
* const client = new QueueClient({ dialect: "postgres", connectionString: "postgresql://..." });
|
|
18
|
+
* await client.init(); // connects, auto-creates qjw_ tables if missing
|
|
19
|
+
*
|
|
20
|
+
* // MySQL
|
|
21
|
+
* const client = new QueueClient({ dialect: "mysql", connectionString: "mysql://..." });
|
|
22
|
+
* await client.init(); // connects, auto-creates qjw_ tables if missing
|
|
23
|
+
*/
|
|
24
|
+
import type { QueueClientOptions } from "../types/client.types.js";
|
|
25
|
+
import type { QueueOptions } from "../types/queue.types.js";
|
|
26
|
+
import type { StorageAdapter } from "../types/storage.types.js";
|
|
27
|
+
import type { QueueEvents } from "../types/events.types.js";
|
|
28
|
+
import { Queue } from "./queue.js";
|
|
29
|
+
export declare class QueueClient {
|
|
30
|
+
/** @internal — mutable so withAdapter() can replace it */
|
|
31
|
+
_storage: StorageAdapter;
|
|
32
|
+
private readonly emitter;
|
|
33
|
+
private readonly defaults;
|
|
34
|
+
private readonly dialect;
|
|
35
|
+
private readonly connectionString;
|
|
36
|
+
private readonly queues;
|
|
37
|
+
private initialised;
|
|
38
|
+
private closed;
|
|
39
|
+
constructor(options?: QueueClientOptions);
|
|
40
|
+
private buildMemoryOrEagerAdapter;
|
|
41
|
+
/**
|
|
42
|
+
* Initialise the client and storage adapter.
|
|
43
|
+
*
|
|
44
|
+
* **Must be called** before creating queues when using Redis, PostgreSQL,
|
|
45
|
+
* or MySQL.
|
|
46
|
+
*
|
|
47
|
+
* What each adapter does:
|
|
48
|
+
* - **memory** — no-op (always safe to call)
|
|
49
|
+
* - **redis** — connects, sends PING, verifies PONG
|
|
50
|
+
* - **postgres** — connects, runs `SELECT 1`, auto-creates `qjw_` tables
|
|
51
|
+
* - **mysql** — connects, runs `SELECT 1`, auto-creates `qjw_` tables
|
|
52
|
+
*
|
|
53
|
+
* Idempotent — safe to call multiple times.
|
|
54
|
+
*/
|
|
55
|
+
init(): Promise<void>;
|
|
56
|
+
/** @deprecated Use `init()`. */
|
|
57
|
+
initialize(): Promise<void>;
|
|
58
|
+
private resolveAdapter;
|
|
59
|
+
/**
|
|
60
|
+
* Create a named queue with optional per-queue configuration.
|
|
61
|
+
*
|
|
62
|
+
* For external dialects (redis/postgres/mysql), call `await client.init()`
|
|
63
|
+
* first.
|
|
64
|
+
*/
|
|
65
|
+
createQueue<TPayload = unknown>(name: string, options?: QueueOptions): Queue<TPayload>;
|
|
66
|
+
/** Returns the queue with the given name, or `undefined`. */
|
|
67
|
+
getQueue<TPayload = unknown>(name: string): Queue<TPayload> | undefined;
|
|
68
|
+
/** Returns the queue with the given name, or throws. */
|
|
69
|
+
requireQueue<TPayload = unknown>(name: string): Queue<TPayload>;
|
|
70
|
+
/** Names of all queues registered on this client. */
|
|
71
|
+
get queueNames(): string[];
|
|
72
|
+
/** `true` after `init()` has completed successfully. */
|
|
73
|
+
get isInitialised(): boolean;
|
|
74
|
+
on<K extends keyof QueueEvents>(event: K, listener: (...args: QueueEvents[K]) => void): this;
|
|
75
|
+
once<K extends keyof QueueEvents>(event: K, listener: (...args: QueueEvents[K]) => void): this;
|
|
76
|
+
off<K extends keyof QueueEvents>(event: K, listener: (...args: QueueEvents[K]) => void): this;
|
|
77
|
+
/**
|
|
78
|
+
* Stop all workers, close all queues, and release the storage connection.
|
|
79
|
+
* Safe to call multiple times.
|
|
80
|
+
*/
|
|
81
|
+
close(): Promise<void>;
|
|
82
|
+
/**
|
|
83
|
+
* Create a QueueClient with a fully custom StorageAdapter.
|
|
84
|
+
*
|
|
85
|
+
* `init()` will call `adapter.initialize()`.
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* const client = QueueClient.withAdapter(myAdapter);
|
|
89
|
+
* await client.init();
|
|
90
|
+
*/
|
|
91
|
+
static withAdapter(adapter: StorageAdapter, options?: Omit<QueueClientOptions, "dialect" | "connectionString">): QueueClient;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/core/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAkB,MAAM,0BAA0B,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAwBnC,qBAAa,WAAW;IACtB,0DAA0D;IAC1D,QAAQ,EAAE,cAAc,CAAC;IAEzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAqB;IACtD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAAS;gBAEX,OAAO,GAAE,kBAAuB;IAe5C,OAAO,CAAC,yBAAyB;IAajC;;;;;;;;;;;;;OAaG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,gCAAgC;IAC1B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;YAInB,cAAc;IAkC5B;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC;IAgBtF,6DAA6D;IAC7D,QAAQ,CAAC,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,SAAS;IAIvE,wDAAwD;IACxD,YAAY,CAAC,QAAQ,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC;IAQ/D,qDAAqD;IACrD,IAAI,UAAU,IAAI,MAAM,EAAE,CAEzB;IAED,wDAAwD;IACxD,IAAI,aAAa,IAAI,OAAO,CAE3B;IAMD,EAAE,CAAC,CAAC,SAAS,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAK5F,IAAI,CAAC,CAAC,SAAS,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAK9F,GAAG,CAAC,CAAC,SAAS,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAS7F;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;;;;;;;OAQG;IACH,MAAM,CAAC,WAAW,CAChB,OAAO,EAAE,cAAc,EACvB,OAAO,GAAE,IAAI,CAAC,kBAAkB,EAAE,SAAS,GAAG,kBAAkB,CAAM,GACrE,WAAW;CAKf"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job ID generation
|
|
3
|
+
*
|
|
4
|
+
* Uses the built-in `crypto.randomUUID()` available in Node.js >= 14.17.
|
|
5
|
+
* No external dependency needed.
|
|
6
|
+
*/
|
|
7
|
+
/** Generate a new unique job ID. */
|
|
8
|
+
export declare function generateJobId(): string;
|
|
9
|
+
//# sourceMappingURL=id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../src/core/id.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,oCAAoC;AACpC,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { Job } from "./job.js";
|
|
2
|
+
export { Queue } from "./queue.js";
|
|
3
|
+
export { Worker } from "./worker.js";
|
|
4
|
+
export { QueueClient } from "./client.js";
|
|
5
|
+
export { calculateBackoff, nextRunAt } from "./backoff.js";
|
|
6
|
+
export { generateJobId } from "./id.js";
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job
|
|
3
|
+
*
|
|
4
|
+
* A rich wrapper around the raw JobData record stored in the storage layer.
|
|
5
|
+
* Exposes read-only accessors for all fields and a small set of helpers used
|
|
6
|
+
* by Queue and Worker internals.
|
|
7
|
+
*
|
|
8
|
+
* The Job instance is passed directly to user-supplied Processor functions.
|
|
9
|
+
* Users should never mutate the internal data object — all mutations happen
|
|
10
|
+
* through the storage adapter.
|
|
11
|
+
*/
|
|
12
|
+
import type { JobData, JobStatus, JobAttempt, BackoffStrategy } from "../types/job.types.js";
|
|
13
|
+
export declare class Job<TPayload = unknown> {
|
|
14
|
+
/** @internal Raw data record — treat as immutable outside storage layer. */
|
|
15
|
+
readonly _data: JobData<TPayload>;
|
|
16
|
+
constructor(data: JobData<TPayload>);
|
|
17
|
+
/** Unique, stable job identifier. */
|
|
18
|
+
get id(): string;
|
|
19
|
+
/** Name of the queue this job belongs to. */
|
|
20
|
+
get queue(): string;
|
|
21
|
+
/** Application-defined job type (matches the registered processor). */
|
|
22
|
+
get type(): string;
|
|
23
|
+
/**
|
|
24
|
+
* User-supplied job payload.
|
|
25
|
+
* Never log this value — it may contain sensitive data.
|
|
26
|
+
*/
|
|
27
|
+
get data(): TPayload;
|
|
28
|
+
/** Current lifecycle status. */
|
|
29
|
+
get status(): JobStatus;
|
|
30
|
+
/** Number of attempts already executed (0 = not yet started). */
|
|
31
|
+
get attemptsMade(): number;
|
|
32
|
+
/** Maximum allowed attempts. */
|
|
33
|
+
get maxAttempts(): number;
|
|
34
|
+
/** How many attempts remain (including the current one). */
|
|
35
|
+
get attemptsRemaining(): number;
|
|
36
|
+
/** Ordered list of past attempt records. */
|
|
37
|
+
get attemptHistory(): readonly JobAttempt[];
|
|
38
|
+
/** Base delay in ms between retry attempts. */
|
|
39
|
+
get retryDelay(): number;
|
|
40
|
+
/** Backoff strategy applied on retry. */
|
|
41
|
+
get backoff(): BackoffStrategy;
|
|
42
|
+
/** Per-attempt timeout in ms. */
|
|
43
|
+
get timeout(): number;
|
|
44
|
+
/** Processing priority — higher numbers are processed first. */
|
|
45
|
+
get priority(): number;
|
|
46
|
+
/** ISO timestamp when this job is eligible to run. */
|
|
47
|
+
get runAt(): string;
|
|
48
|
+
/** Cron expression for recurring jobs, or undefined. */
|
|
49
|
+
get cron(): string | undefined;
|
|
50
|
+
/** ID of the worker currently holding the lock, or null. */
|
|
51
|
+
get lockId(): string | null;
|
|
52
|
+
/** ISO timestamp when the current lock expires, or null. */
|
|
53
|
+
get lockExpiresAt(): string | null;
|
|
54
|
+
/** ISO timestamp when the job was first enqueued. */
|
|
55
|
+
get createdAt(): string;
|
|
56
|
+
/** ISO timestamp of the last status change. */
|
|
57
|
+
get updatedAt(): string;
|
|
58
|
+
/** ISO timestamp when the job completed successfully, or null. */
|
|
59
|
+
get completedAt(): string | null;
|
|
60
|
+
/** ISO timestamp when the job was moved to the DLQ, or null. */
|
|
61
|
+
get failedAt(): string | null;
|
|
62
|
+
/** Returns true when the job has been successfully processed. */
|
|
63
|
+
isCompleted(): boolean;
|
|
64
|
+
/** Returns true when the job is in the Dead Letter Queue. */
|
|
65
|
+
isDead(): boolean;
|
|
66
|
+
/** Returns true when the job is currently being processed by a worker. */
|
|
67
|
+
isActive(): boolean;
|
|
68
|
+
/** Returns true when the job is waiting to be claimed. */
|
|
69
|
+
isWaiting(): boolean;
|
|
70
|
+
/** Returns true when the job is scheduled for a future time. */
|
|
71
|
+
isDelayed(): boolean;
|
|
72
|
+
toJSON(): Record<string, unknown>;
|
|
73
|
+
toString(): string;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=job.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job.d.ts","sourceRoot":"","sources":["../../src/core/job.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7F,qBAAa,GAAG,CAAC,QAAQ,GAAG,OAAO;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAEtB,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC;IAQnC,qCAAqC;IACrC,IAAI,EAAE,IAAI,MAAM,CAEf;IAED,6CAA6C;IAC7C,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,uEAAuE;IACvE,IAAI,IAAI,IAAI,MAAM,CAEjB;IAMD;;;OAGG;IACH,IAAI,IAAI,IAAI,QAAQ,CAEnB;IAMD,gCAAgC;IAChC,IAAI,MAAM,IAAI,SAAS,CAEtB;IAED,iEAAiE;IACjE,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,gCAAgC;IAChC,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,4DAA4D;IAC5D,IAAI,iBAAiB,IAAI,MAAM,CAE9B;IAED,4CAA4C;IAC5C,IAAI,cAAc,IAAI,SAAS,UAAU,EAAE,CAE1C;IAMD,+CAA+C;IAC/C,IAAI,UAAU,IAAI,MAAM,CAEvB;IAED,yCAAyC;IACzC,IAAI,OAAO,IAAI,eAAe,CAE7B;IAMD,iCAAiC;IACjC,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,gEAAgE;IAChE,IAAI,QAAQ,IAAI,MAAM,CAErB;IAMD,sDAAsD;IACtD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,wDAAwD;IACxD,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAMD,4DAA4D;IAC5D,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,4DAA4D;IAC5D,IAAI,aAAa,IAAI,MAAM,GAAG,IAAI,CAEjC;IAMD,qDAAqD;IACrD,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,+CAA+C;IAC/C,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,kEAAkE;IAClE,IAAI,WAAW,IAAI,MAAM,GAAG,IAAI,CAE/B;IAED,gEAAgE;IAChE,IAAI,QAAQ,IAAI,MAAM,GAAG,IAAI,CAE5B;IAMD,iEAAiE;IACjE,WAAW,IAAI,OAAO;IAItB,6DAA6D;IAC7D,MAAM,IAAI,OAAO;IAIjB,0EAA0E;IAC1E,QAAQ,IAAI,OAAO;IAInB,0DAA0D;IAC1D,SAAS,IAAI,OAAO;IAIpB,gEAAgE;IAChE,SAAS,IAAI,OAAO;IAQpB,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkBjC,QAAQ,IAAI,MAAM;CAGnB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue
|
|
3
|
+
*
|
|
4
|
+
* Represents an independent stream of jobs. Applications use a Queue to:
|
|
5
|
+
* - Enqueue jobs (with optional scheduling, priority, retry config).
|
|
6
|
+
* - Register processors for job types.
|
|
7
|
+
* - Create workers that consume jobs from this queue.
|
|
8
|
+
* - Query job state and counts.
|
|
9
|
+
*
|
|
10
|
+
* Queue-level configuration overrides client defaults.
|
|
11
|
+
* Job-level options override queue configuration where applicable.
|
|
12
|
+
*/
|
|
13
|
+
import type { StorageAdapter } from "../types/storage.types.js";
|
|
14
|
+
import type { JobOptions, JobStatus } from "../types/job.types.js";
|
|
15
|
+
import type { QueueOptions } from "../types/queue.types.js";
|
|
16
|
+
import type { WorkerOptions, Processor } from "../types/worker.types.js";
|
|
17
|
+
import type { ClientDefaults } from "../types/client.types.js";
|
|
18
|
+
import { Job } from "./job.js";
|
|
19
|
+
import { Worker } from "./worker.js";
|
|
20
|
+
import type { QueueEventEmitter } from "../events/emitter.js";
|
|
21
|
+
type ResolvedDefaults = Required<ClientDefaults>;
|
|
22
|
+
export declare class Queue<TPayload = unknown> {
|
|
23
|
+
/** The name of this queue — unique within a QueueClient. */
|
|
24
|
+
readonly name: string;
|
|
25
|
+
private readonly storage;
|
|
26
|
+
private readonly emitter;
|
|
27
|
+
private readonly resolvedConfig;
|
|
28
|
+
private readonly clientDefaults;
|
|
29
|
+
/** Registered processors keyed by job type. */
|
|
30
|
+
private readonly processors;
|
|
31
|
+
/** Active worker instances created by this queue. */
|
|
32
|
+
private readonly workers;
|
|
33
|
+
constructor(name: string, storage: StorageAdapter, emitter: QueueEventEmitter, options: QueueOptions | undefined, defaults: ResolvedDefaults);
|
|
34
|
+
/**
|
|
35
|
+
* Add a new job to the queue.
|
|
36
|
+
*
|
|
37
|
+
* @param type - Job type string, must match a registered processor.
|
|
38
|
+
* @param payload - Arbitrary serialisable payload (never logged by default).
|
|
39
|
+
* @param options - Per-job overrides (attempts, delay, priority, etc.).
|
|
40
|
+
*/
|
|
41
|
+
enqueue(type: string, payload: TPayload, options?: JobOptions): Promise<Job<TPayload>>;
|
|
42
|
+
/**
|
|
43
|
+
* Register a processor function for a given job type.
|
|
44
|
+
*
|
|
45
|
+
* Only one processor per type per queue is supported.
|
|
46
|
+
* Registering a second processor for the same type replaces the first.
|
|
47
|
+
*/
|
|
48
|
+
process<P = TPayload>(type: string, processor: Processor<P>): void;
|
|
49
|
+
/**
|
|
50
|
+
* Create and start a Worker that consumes jobs from this queue.
|
|
51
|
+
*
|
|
52
|
+
* Worker-level `concurrency` overrides queue-level concurrency.
|
|
53
|
+
*/
|
|
54
|
+
createWorker(options?: WorkerOptions): Worker;
|
|
55
|
+
/** Fetch a single job by its ID. Returns null if not found or wrong queue. */
|
|
56
|
+
getJob(jobId: string): Promise<Job<TPayload> | null>;
|
|
57
|
+
/** Fetch jobs from this queue, optionally filtered by status. */
|
|
58
|
+
getJobs(status?: JobStatus, limit?: number, offset?: number): Promise<Job<TPayload>[]>;
|
|
59
|
+
/** Get job counts by status for this queue. */
|
|
60
|
+
getJobCounts(): Promise<Record<JobStatus, number>>;
|
|
61
|
+
/**
|
|
62
|
+
* Gracefully stop all workers attached to this queue.
|
|
63
|
+
* Called automatically by QueueClient.close().
|
|
64
|
+
*/
|
|
65
|
+
close(): Promise<void>;
|
|
66
|
+
/** Return all active worker instances on this queue. */
|
|
67
|
+
getWorkers(): readonly Worker[];
|
|
68
|
+
}
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/core/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;AA2BjD,qBAAa,KAAK,CAAC,QAAQ,GAAG,OAAO;IACnC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAyB;IACxD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;IAElD,+CAA+C;IAC/C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAyC;IAEpE,qDAAqD;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgB;gBAGtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,iBAAiB,EAC1B,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,QAAQ,EAAE,gBAAgB;IAa5B;;;;;;OAMG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAqC5F;;;;;OAKG;IACH,OAAO,CAAC,CAAC,GAAG,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI;IAQlE;;;;OAIG;IACH,YAAY,CAAC,OAAO,CAAC,EAAE,aAAa,GAAG,MAAM;IAoB7C,8EAA8E;IACxE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAM1D,iEAAiE;IAC3D,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,KAAK,SAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;IAUpF,+CAA+C;IACzC,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAQxD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAI5B,wDAAwD;IACxD,UAAU,IAAI,SAAS,MAAM,EAAE;CAGhC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker
|
|
3
|
+
*
|
|
4
|
+
* Claims jobs from a queue and executes registered processors concurrently.
|
|
5
|
+
*
|
|
6
|
+
* Key guarantees:
|
|
7
|
+
* - At-most `concurrency` jobs run simultaneously.
|
|
8
|
+
* - Job claiming is delegated to the storage adapter's atomic `claim()` call.
|
|
9
|
+
* - Failed jobs are requeued (with backoff) or moved to the DLQ.
|
|
10
|
+
* - Stalled jobs (expired locks from crashed workers) are recovered
|
|
11
|
+
* periodically.
|
|
12
|
+
* - Graceful shutdown: stop claiming, wait for active jobs, release any
|
|
13
|
+
* locks that could not be finished within shutdownTimeout.
|
|
14
|
+
* - Cron jobs: re-enqueued immediately after each successful execution.
|
|
15
|
+
*/
|
|
16
|
+
import type { StorageAdapter } from "../types/storage.types.js";
|
|
17
|
+
import type { WorkerOptions, WorkerStatus, Processor } from "../types/worker.types.js";
|
|
18
|
+
import type { QueueOptions } from "../types/queue.types.js";
|
|
19
|
+
import type { ClientDefaults } from "../types/client.types.js";
|
|
20
|
+
import type { QueueEventEmitter } from "../events/emitter.js";
|
|
21
|
+
type ResolvedDefaults = Required<ClientDefaults>;
|
|
22
|
+
export declare class Worker {
|
|
23
|
+
/** Unique identifier for this worker instance. */
|
|
24
|
+
readonly id: string;
|
|
25
|
+
private readonly queueName;
|
|
26
|
+
private readonly storage;
|
|
27
|
+
private readonly emitter;
|
|
28
|
+
private readonly processors;
|
|
29
|
+
private readonly config;
|
|
30
|
+
private _status;
|
|
31
|
+
private activeCount;
|
|
32
|
+
/**
|
|
33
|
+
* Tracks job IDs currently being processed so we can release their locks
|
|
34
|
+
* when graceful shutdown times out before they finish.
|
|
35
|
+
*/
|
|
36
|
+
private readonly activeJobIds;
|
|
37
|
+
private pollTimer;
|
|
38
|
+
private stalledTimer;
|
|
39
|
+
/** Resolves when all active jobs finish during shutdown. */
|
|
40
|
+
private drainResolve;
|
|
41
|
+
constructor(queueName: string, storage: StorageAdapter, emitter: QueueEventEmitter, processors: Map<string, Processor<unknown>>, workerOptions: WorkerOptions, queueOptions: QueueOptions, defaults: ResolvedDefaults);
|
|
42
|
+
get status(): WorkerStatus;
|
|
43
|
+
/** Start polling for jobs. */
|
|
44
|
+
start(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Gracefully stop the worker.
|
|
47
|
+
*
|
|
48
|
+
* 1. Stop accepting new jobs.
|
|
49
|
+
* 2. Wait up to `shutdownTimeout` ms for active jobs to finish.
|
|
50
|
+
* 3. Release locks on any jobs that did not finish in time so another
|
|
51
|
+
* worker can reclaim them.
|
|
52
|
+
* 4. Emit stopped event.
|
|
53
|
+
*/
|
|
54
|
+
stop(): Promise<void>;
|
|
55
|
+
private schedulePoll;
|
|
56
|
+
private poll;
|
|
57
|
+
private claimNext;
|
|
58
|
+
private executeJob;
|
|
59
|
+
private enqueueCronNext;
|
|
60
|
+
private handleFailure;
|
|
61
|
+
private scheduleStallCheck;
|
|
62
|
+
private recoverStalledJobs;
|
|
63
|
+
}
|
|
64
|
+
export {};
|
|
65
|
+
//# sourceMappingURL=worker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/core/worker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACvF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI/D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,KAAK,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,CAAC;AAyBjD,qBAAa,MAAM;IACjB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmC;IAE1D,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,WAAW,CAAK;IAExB;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAElD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,YAAY,CAA+B;IAEnD,4DAA4D;IAC5D,OAAO,CAAC,YAAY,CAA6B;gBAG/C,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,OAAO,EAAE,iBAAiB,EAC1B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC,EAC3C,aAAa,EAAE,aAAa,EAC5B,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,gBAAgB;IAc5B,IAAI,MAAM,IAAI,YAAY,CAEzB;IAED,8BAA8B;IAC9B,KAAK,IAAI,IAAI;IAab;;;;;;;;OAQG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAiD3B,OAAO,CAAC,YAAY;YAQN,IAAI;YAsBJ,SAAS;YAiCT,UAAU;YAwDV,eAAe;YAwDf,aAAa;IA0C3B,OAAO,CAAC,kBAAkB;YAQZ,kBAAkB;CAkBjC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QueueEventEmitter
|
|
3
|
+
*
|
|
4
|
+
* A strongly-typed, lightweight event emitter built on top of Node.js
|
|
5
|
+
* EventEmitter. All queue/worker/job lifecycle events flow through here.
|
|
6
|
+
*
|
|
7
|
+
* Using typed generics ensures that each event name maps to its exact
|
|
8
|
+
* argument tuple — no runtime guessing.
|
|
9
|
+
*/
|
|
10
|
+
import type { QueueEvents } from "../types/events.types.js";
|
|
11
|
+
type EventKey = keyof QueueEvents;
|
|
12
|
+
type EventArgs<K extends EventKey> = QueueEvents[K];
|
|
13
|
+
export declare class QueueEventEmitter {
|
|
14
|
+
private readonly emitter;
|
|
15
|
+
constructor();
|
|
16
|
+
on<K extends EventKey>(event: K, listener: (...args: EventArgs<K>) => void): this;
|
|
17
|
+
once<K extends EventKey>(event: K, listener: (...args: EventArgs<K>) => void): this;
|
|
18
|
+
off<K extends EventKey>(event: K, listener: (...args: EventArgs<K>) => void): this;
|
|
19
|
+
emit<K extends EventKey>(event: K, ...args: EventArgs<K>): boolean;
|
|
20
|
+
removeAllListeners(event?: EventKey): this;
|
|
21
|
+
listenerCount(event: EventKey): number;
|
|
22
|
+
}
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emitter.d.ts","sourceRoot":"","sources":["../../src/events/emitter.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAM5D,KAAK,QAAQ,GAAG,MAAM,WAAW,CAAC;AAClC,KAAK,SAAS,CAAC,CAAC,SAAS,QAAQ,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;AAEpD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;;IAavC,EAAE,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAKjF,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IAKnF,GAAG,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI;IASlF,IAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG,OAAO;IAQlE,kBAAkB,CAAC,KAAK,CAAC,EAAE,QAAQ,GAAG,IAAI;IAS1C,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM;CAGvC"}
|