power-queues 2.0.3 → 2.0.5

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/dist/index.d.ts CHANGED
@@ -1,285 +1,93 @@
1
- import { Jsonish, PowerRedis } from 'power-redis';
1
+ import { JsonPrimitiveOrUndefined, PowerRedis, IORedisLike } from 'power-redis';
2
2
 
3
- /**
4
- * @summary
5
- * A normalized map representing the **result data** returned by a task execution.
6
- *
7
- * @remarks
8
- * Each task may produce structured output (status objects, partial results, metrics, etc.)
9
- * that are merged across multiple lifecycle hooks — such as
10
- * {@link PowerQueue.afterExecution} and {@link PowerQueue.onSuccess}.
11
- *
12
- * The keys are arbitrary strings, and the values can be any **JSON-like**
13
- * (serializable) value supported by {@link Jsonish}.
14
- *
15
- * @example
16
- * ```ts
17
- * const result: TaskResult = {
18
- * status: 'ok',
19
- * durationMs: 152,
20
- * response: { code: 200, message: 'OK' }
21
- * };
22
- * ```
23
- *
24
- * @since 2.0.0
25
- * @category Task Model
26
- */
27
- type TaskResult = Record<string, Jsonish>;
28
- /**
29
- * @summary
30
- * Describes the **multi-queue execution chain** configuration for a task.
31
- *
32
- * @remarks
33
- * A task chain represents a sequential flow of queues.
34
- * When a task completes successfully in one queue, it is automatically
35
- * enqueued into the next queue in the chain — until all queues are processed.
36
- *
37
- * Example: `['resize', 'compress', 'upload']`
38
- * means that after a task finishes in the `"resize"` queue, it will
39
- * automatically move to `"compress"`, then `"upload"`.
40
- *
41
- * @property queues - Ordered list of queue names forming the execution chain.
42
- * @property index - Current **0-based index** pointing to the active queue
43
- * within {@link TaskChain.queues}.
44
- *
45
- * @example
46
- * ```ts
47
- * const chain: TaskChain = {
48
- * queues: ['prepare', 'process', 'finalize'],
49
- * index: 1, // currently in "process"
50
- * };
51
- * ```
52
- *
53
- * @since 2.0.0
54
- * @category Task Model
55
- */
56
- type TaskChain = {
57
- /** Ordered list of queue names forming the execution pipeline. */
58
- queues: string[];
59
- /** Current 0-based position within {@link TaskChain.queues}. */
60
- index: number;
3
+ type SavedScript = {
4
+ codeReady?: string;
5
+ codeBody: string;
61
6
  };
62
- /**
63
- * @summary
64
- * Tracks the **temporal progress** and retry lifecycle of a task instance.
65
- *
66
- * @remarks
67
- * Each task stores its processing timestamps and retry moments for precise
68
- * auditability and performance tracking.
69
- *
70
- * The timestamps are expressed in **milliseconds since epoch (UNIX time)**.
71
- *
72
- * @property createdAt - Time when the task object was first created.
73
- * @property successAt - Time when the task (or its chain) completed successfully (0 if not yet).
74
- * @property errorAt - Time when a non-fatal recoverable error occurred (0 if never).
75
- * @property failAt - Time when all attempts were exhausted and the task was moved to a `fail` list (0 if never).
76
- * @property fatalAt - Time when an unrecoverable fatal condition occurred (0 if never).
77
- * @property retries - Array of timestamps when each retry attempt was initiated.
78
- * @property chain - Array of timestamps when each chain hop successfully completed.
79
- *
80
- * @example
81
- * ```ts
82
- * const progress: TaskProgress = {
83
- * createdAt: Date.now(),
84
- * successAt: 0,
85
- * errorAt: 0,
86
- * failAt: 0,
87
- * fatalAt: 0,
88
- * retries: [],
89
- * chain: []
90
- * };
91
- * ```
92
- *
93
- * @since 2.0.0
94
- * @category Task Model
95
- */
96
- type TaskProgress = {
97
- /** Milliseconds since epoch when the task object was created. */
98
- createdAt: number;
99
- /** Milliseconds when the task chain completed successfully (0 if not yet). */
100
- successAt: number;
101
- /** Milliseconds when a non-fatal error was observed (0 if never). */
102
- errorAt: number;
103
- /** Milliseconds when task exhausted attempts and moved to a *fail* list (0 if never). */
104
- failAt: number;
105
- /** Milliseconds when an unrecoverable fatal condition occurred (0 if never). */
106
- fatalAt: number;
107
- /** Retry timestamps (ms) per attempt performed. */
108
- retries: number[];
109
- /** Timestamps (ms) when each chain hop completed. */
110
- chain: number[];
7
+ type AddTasksOptions = {
8
+ nomkstream?: boolean;
9
+ maxlen?: number;
10
+ minidWindowMs?: number;
11
+ minidExact?: boolean;
12
+ approx?: boolean;
13
+ exact?: boolean;
14
+ trimLimit?: number;
15
+ id?: string;
111
16
  };
112
- /**
113
- * @summary
114
- * Represents a **single job (task)** managed by the `PowerQueue` framework.
115
- *
116
- * @remarks
117
- * A `Task` object encapsulates:
118
- * - Its queue and iteration context.
119
- * - Retry and chain configuration.
120
- * - Mutable progress tracking.
121
- * - Payload (input) and result (output) data.
122
- *
123
- * It is the fundamental unit of work passed through the queue system
124
- * and processed by worker logic implemented in {@link PowerQueue.execute}.
125
- *
126
- * ### Life cycle
127
- * 1. **Enqueued** — via {@link PowerQueue.enqueue} or {@link PowerQueue.addTask}.
128
- * 2. **Reserved** — moved from `ready` to `processing` via Lua script.
129
- * 3. **Executed** — processed by worker code (`execute()`).
130
- * 4. **Acknowledged** — upon success (removed from `processing`).
131
- * 5. **Requeued or Failed** — upon error or exceeded retry limit.
132
- *
133
- * ### Field overview
134
- * | Property | Description |
135
- * |-----------|-------------|
136
- * | `queueName` | Queue identifier (base Redis key prefix). |
137
- * | `iterationId` | Correlation ID grouping tasks within a batch or iteration. |
138
- * | `iterationLength` | Total number of tasks in this iteration (informational). |
139
- * | `id` | Unique task identifier (UUID). |
140
- * | `maxAttempts` | Max retry attempts before marking as failed. |
141
- * | `currentAttempt` | Current 0-based retry attempt counter. |
142
- * | `chain` | Optional chain configuration for multi-queue routing. |
143
- * | `progress` | Mutable structure tracking timestamps and retries. |
144
- * | `payload` | Arbitrary JSON-compatible input object. |
145
- * | `result` | Mutable JSON-compatible output accumulator. |
146
- *
147
- * ### Serialization
148
- * Tasks are stored in Redis as JSON strings.
149
- * Both `payload` and `result` must be serializable and compact to avoid overhead.
150
- *
151
- * @example
152
- * ```ts
153
- * const task: Task = {
154
- * queueName: 'emails',
155
- * iterationId: 'iter-2025-10-21',
156
- * iterationLength: 10,
157
- * id: 'a47fdf38-1234-4c55-a9f9-cd89e42a7baf',
158
- * maxAttempts: 3,
159
- * currentAttempt: 0,
160
- * chain: { queues: ['emails', 'logs'], index: 0 },
161
- * progress: {
162
- * createdAt: Date.now(),
163
- * successAt: 0,
164
- * errorAt: 0,
165
- * failAt: 0,
166
- * fatalAt: 0,
167
- * retries: [],
168
- * chain: [],
169
- * },
170
- * payload: { to: 'user@example.com', subject: 'Welcome!' },
171
- * result: {},
172
- * };
173
- * ```
174
- *
175
- * @since 2.0.0
176
- * @category Task Model
177
- * @see {@link PowerQueue} — Abstract base class that manages task lifecycles.
178
- * @see {@link TaskProgress} — Tracks time-based lifecycle data.
179
- * @see {@link TaskChain} — Defines sequential queue execution flow.
180
- */
181
17
  type Task = {
182
- /** Logical queue name (base prefix used for keys). */
183
- queueName: string;
184
- /** Iteration correlation identifier for analytics and grouping. */
185
- iterationId: string;
186
- /** Number of tasks planned for the current iteration (informational). */
187
- iterationLength: number;
188
- /** Unique task id (UUID). */
189
- id: string;
190
- /** Max attempts permitted before moving to *fail* list. */
191
- maxAttempts: number;
192
- /** Current 0-based attempt index. */
193
- currentAttempt: number;
194
- /** Optional chain configuration. */
195
- chain: TaskChain;
196
- /** Mutable time/attempt history. */
197
- progress: TaskProgress;
198
- /**
199
- * User payload: strongly recommended to be JSON-serializable.
200
- * @defaultValue {}
201
- */
202
- payload: Record<string, any>;
203
- /**
204
- * Execution result accumulator (merged across before/after hooks and execute()).
205
- * @defaultValue {}
206
- */
207
- result: Record<string, any>;
18
+ job: string;
19
+ id?: string;
20
+ createdAt?: number;
21
+ payload: any;
22
+ idemKey?: string;
23
+ } | {
24
+ job: string;
25
+ id?: string;
26
+ createdAt?: number;
27
+ flat: JsonPrimitiveOrUndefined[];
28
+ idemKey?: string;
208
29
  };
209
30
 
210
- declare abstract class PowerQueue extends PowerRedis {
211
- private reserveSha?;
212
- private reserveShaRpoplpush?;
213
- private requeueSha?;
214
- private promoteSha?;
215
- readonly iterationTimeout: number;
216
- readonly portionLength: number;
217
- readonly expireStatusSec: number;
218
- readonly maxAttempts: number;
219
- readonly concurrency: number;
220
- readonly visibilityTimeoutSec: number;
221
- readonly retryBaseSec: number;
222
- readonly retryMaxSec: number;
223
- private runners;
224
- private processingRaw;
225
- private heartbeatTimers;
226
- private nowSec;
227
- private readyKey;
228
- private processingKey;
229
- private processingVtKey;
230
- private delayedKey;
231
- toKeyString(...parts: Array<string | number>): string;
232
- private getReserveScriptLMOVE;
233
- private getReserveScriptRPOPLPUSH;
234
- private getRequeueScript;
235
- private getPromoteScript;
236
- private ensureReserveScript;
237
- private ensureRequeueScript;
238
- private ensurePromoteScript;
239
- private moveOneToProcessing;
240
- private evalshaWithReload;
241
- private zaddCompatXXCH;
242
- private startHeartbeat;
243
- private stopHeartbeat;
244
- reserveMany(source: string, processing: string, processingVt: string, limit?: number, visibilitySec?: number): Promise<string[]>;
245
- ackProcessing(processing: string, processingVt: string, raw: string): Promise<void>;
246
- requeueExpired(processing: string, processingVt: string, ready: string, nowTs?: number, chunk?: number): Promise<number>;
247
- promoteDelayed(delayed: string, ready: string, nowTs?: number, chunk?: number): Promise<number>;
248
- enqueue(ready: string, delayed: string, payload: any, delaySec?: number): Promise<number>;
249
- extendVisibility(processingVt: string, raw: string, visibilitySec: number): Promise<void>;
250
- run(queueName: string): void;
251
- stop(queueName: string): void;
252
- buildTask(data: Partial<Task>): Task;
253
- addTask(data: Partial<Task>, delaySec?: number): Promise<number>;
254
- addTasks(data: {
255
- queueName: string;
256
- payloads: Array<any | Partial<Task>>;
257
- delaySec?: number | number[];
258
- }): Promise<number>;
259
- iteration(tasks: Array<Task>): Promise<void>;
260
- beforeIterationExecution(data: Array<Task>): Promise<Array<Task>>;
261
- afterIterationExecution(data: Array<Task>, results: Array<TaskResult>): Promise<void>;
262
- beforeExecution(task: Task): Promise<Task>;
263
- afterExecution(task: Task, result: TaskResult): Promise<TaskResult>;
264
- execute(task: Task): Promise<TaskResult>;
265
- onRetry(task: Task): Promise<void>;
266
- onError(err: Error, task: Task): Promise<void>;
267
- onFail(err: Error, task: Task): Promise<void>;
268
- onFatal(err: Error, task: Task): Promise<void>;
269
- onSuccess(task: Task, result: TaskResult): Promise<void>;
270
- onChainSuccess(task: Task, result: TaskResult): Promise<void>;
271
- onIterationError(err: Error, queueName: string): Promise<void>;
272
- private logic;
273
- private jitteredBackoffSec;
274
- private retry;
275
- private iterationError;
276
- private error;
277
- private fail;
31
+ declare class PowerQueues extends PowerRedis {
32
+ abort: AbortController;
33
+ redis: IORedisLike;
34
+ readonly strictCheckingConnection: boolean;
35
+ readonly scripts: Record<string, SavedScript>;
36
+ readonly addingBatchTasksCount: number;
37
+ readonly addingBatchKeysLimit: number;
38
+ readonly idemOn: boolean;
39
+ readonly idemKey: string;
40
+ readonly workerExecuteLockTimeoutMs: number;
41
+ readonly workerCacheTaskTimeoutMs: number;
42
+ readonly approveBatchTasksCount: number;
43
+ readonly removeOnExecuted: boolean;
44
+ readonly executeBatchAtOnce: boolean;
45
+ readonly executeJobStatus: boolean;
46
+ readonly executeJobStatusTtlSec: number;
47
+ readonly consumerHost: string;
48
+ readonly stream: string;
49
+ readonly group: string;
50
+ readonly workerBatchTasksCount: number;
51
+ readonly recoveryStuckTasksTimeoutMs: number;
52
+ readonly workerLoopIntervalMs: number;
53
+ readonly workerSelectionTimeoutMs: number;
54
+ onSelected(data: Array<[string, any[], number, string, string]>): Promise<[string, any[], number, string, string][]>;
55
+ onExecute(id: string, payload: any, createdAt: number, job: string, key: string): Promise<void>;
56
+ onExecuted(data: Array<[string, any[], number, string, string]>): Promise<void>;
57
+ onSuccess(id: string, payload: any, createdAt: number, job: string, key: string): Promise<void>;
58
+ runQueue(): Promise<void>;
59
+ consumerLoop(): Promise<void>;
60
+ addTasks(queueName: string, data: any[], opts?: AddTasksOptions): Promise<string[]>;
61
+ loadScripts(full?: boolean): Promise<void>;
62
+ private loadScript;
63
+ private saveScript;
64
+ private runScript;
65
+ private xaddBatch;
66
+ private payloadBatch;
67
+ private buildBatches;
68
+ private keysLength;
278
69
  private success;
279
70
  private status;
280
- private loop;
281
- private data;
282
- private ack;
71
+ private execute;
72
+ private executeProcess;
73
+ private approve;
74
+ private idempotency;
75
+ private idempotencyKeys;
76
+ private idempotencyAllow;
77
+ private idempotencyStart;
78
+ private idempotencyDone;
79
+ private idempotencyFree;
80
+ private createGroup;
81
+ private select;
82
+ private selectStuck;
83
+ private selectFresh;
84
+ private waitAbortable;
85
+ private heartbeat;
86
+ private normalizeEntries;
87
+ private values;
88
+ private payload;
89
+ private signal;
90
+ private consumer;
283
91
  }
284
92
 
285
- export { PowerQueue, type Task, type TaskChain, type TaskProgress, type TaskResult };
93
+ export { type AddTasksOptions, PowerQueues, type Task };