@pingpolls/redisq 1.0.3 → 1.0.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/dist/app.d.ts CHANGED
@@ -1,57 +1,149 @@
1
1
  import { RedisClient as BunRedisClient } from "bun";
2
+ /**
3
+ * Options for initializing the RedisQ client.
4
+ * You can either provide a Redis client instance or connection details.
5
+ */
2
6
  export type QueueOptions = {
7
+ /** A Bun Redis client instance. */
3
8
  redis: BunRedisClient;
4
9
  } | {
10
+ /** Redis server host. */
5
11
  host: string;
12
+ /** Redis server port. */
6
13
  port: string;
14
+ /** Redis server user. */
7
15
  user?: string;
16
+ /** Redis server password. */
8
17
  password?: string;
18
+ /** Namespace for all Redis keys. */
9
19
  namespace?: string;
20
+ /** Whether to use TLS for the connection. */
10
21
  tls?: boolean;
11
22
  };
23
+ /**
24
+ * Options for creating a new queue.
25
+ * The options are different for regular and batch queues.
26
+ */
12
27
  export type CreateQueueOptions<QueueName extends string = string> = QueueName extends `${string}:batch` ? {
28
+ /**
29
+ * The name of the queue. Must end with `:batch` for batch queues.
30
+ * @example "my-queue:batch"
31
+ */
13
32
  qname: QueueName;
33
+ /** Maximum message size in bytes.
34
+ * @default 65536
35
+ */
14
36
  maxsize?: number;
37
+ /**
38
+ * Maximum number of retries for a message.
39
+ * `0` = no retry, `-1` = unlimited, `n` = max retries.
40
+ * @default 0
41
+ */
15
42
  maxRetries?: number;
43
+ /**
44
+ * Maximum backoff time in seconds for exponential backoff.
45
+ * @default 30
46
+ */
16
47
  maxBackoffSeconds?: number;
48
+ /**
49
+ * Batch processing interval in seconds.
50
+ * @default 60
51
+ */
17
52
  every?: number;
18
53
  } : {
54
+ /**
55
+ * The name of the queue.
56
+ * @example "my-queue"
57
+ */
19
58
  qname: QueueName;
59
+ /** Maximum message size in bytes.
60
+ * @default 65536
61
+ */
20
62
  maxsize?: number;
63
+ /**
64
+ * Maximum number of retries for a message.
65
+ * `0` = no retry, `-1` = unlimited, `n` = max retries.
66
+ * @default 0
67
+ */
21
68
  maxRetries?: number;
69
+ /**
70
+ * Maximum backoff time in seconds for exponential backoff.
71
+ * @default 30
72
+ */
22
73
  maxBackoffSeconds?: number;
23
74
  };
75
+ /**
76
+ * Attributes of a queue.
77
+ */
24
78
  export interface QueueAttributes {
79
+ /** Maximum message size in bytes. */
25
80
  maxsize: number;
81
+ /** Timestamp when the queue was created. */
26
82
  created: number;
83
+ /** Number of pending messages in the queue. */
27
84
  msgs: number;
85
+ /** Whether the queue is a batch queue. */
28
86
  isBatch: boolean;
87
+ /** Maximum number of retries for a message. */
29
88
  maxRetries: number;
89
+ /** Maximum backoff time in seconds for exponential backoff. */
30
90
  maxBackoffSeconds: number;
91
+ /** Batch processing interval in seconds (for batch queues only). */
31
92
  every?: number;
32
93
  }
94
+ /**
95
+ * Options for sending a message to a regular queue.
96
+ */
33
97
  export interface SendMessageOptions {
98
+ /** The name of the queue. */
34
99
  qname: string;
100
+ /** The message content. */
35
101
  message: string;
102
+ /** Optional delay in milliseconds before the message is processed. */
36
103
  delay?: number;
37
104
  }
105
+ /**
106
+ * Options for sending a message to a batch queue.
107
+ */
38
108
  export interface SendBatchMessageOptions {
109
+ /** The name of the batch queue. */
39
110
  qname: string;
111
+ /**
112
+ * The ID of the batch. Messages with the same `batchId` are processed together.
113
+ */
40
114
  batchId: string;
115
+ /** The message content. */
41
116
  message: string;
42
117
  }
118
+ /**
119
+ * A message received from a regular queue.
120
+ */
43
121
  export interface Message {
122
+ /** The unique ID of the message. */
44
123
  id: string;
124
+ /** The message content. */
45
125
  message: string;
126
+ /** Timestamp when the message was sent. */
46
127
  sent: number;
128
+ /** The current attempt number (1-based). */
47
129
  attempt: number;
48
130
  }
131
+ /**
132
+ * A batch of messages received from a batch queue.
133
+ */
49
134
  export interface BatchMessage {
135
+ /** The ID of the batch. */
50
136
  batchId: string;
137
+ /** Array of messages in the batch. */
51
138
  messages: Omit<Message, "attempt">[];
139
+ /** Timestamp when the batch was created. */
52
140
  sent: number;
141
+ /** The current attempt number for the batch (1-based). */
53
142
  attempt: number;
54
143
  }
144
+ /**
145
+ * A lightweight, type-safe Redis-based message queue for Bun.
146
+ */
55
147
  export declare class RedisQ {
56
148
  private redis;
57
149
  private redisUrl;
@@ -59,14 +151,47 @@ export declare class RedisQ {
59
151
  private workers;
60
152
  private batchJobs;
61
153
  private isClosing;
154
+ /**
155
+ * Initializes the RedisQ client.
156
+ * @param options - Options for initializing the client.
157
+ */
62
158
  constructor(options: QueueOptions);
63
159
  private getKey;
64
160
  private isBatchQueue;
161
+ /**
162
+ * Creates a new queue with the specified options.
163
+ * @param options - Options for creating the queue.
164
+ * @returns `true` if the queue was created, `false` if it already exists.
165
+ */
65
166
  createQueue<QueueName extends string>(options: CreateQueueOptions<QueueName>): Promise<boolean>;
167
+ /**
168
+ * Lists all queue names.
169
+ * @returns An array of queue names.
170
+ */
66
171
  listQueues(): Promise<string[]>;
172
+ /**
173
+ * Gets the attributes of a queue.
174
+ * @param qname - The name of the queue.
175
+ * @returns The queue attributes, or `null` if the queue does not exist.
176
+ */
67
177
  getQueue(qname: string): Promise<QueueAttributes | null>;
178
+ /**
179
+ * Deletes a queue and all its data.
180
+ * @param qname - The name of the queue to delete.
181
+ * @returns `true` if the queue was deleted, `false` if it did not exist.
182
+ */
68
183
  deleteQueue(qname: string): Promise<boolean>;
184
+ /**
185
+ * Sends a message to a regular queue.
186
+ * @param options - Options for sending the message.
187
+ * @returns The unique ID of the message.
188
+ */
69
189
  sendMessage(options: SendMessageOptions): Promise<string>;
190
+ /**
191
+ * Sends a message to a batch queue.
192
+ * @param options - Options for sending the batch message.
193
+ * @returns The unique ID of the message.
194
+ */
70
195
  sendBatchMessage(options: SendBatchMessageOptions): Promise<string>;
71
196
  private encodeMessage;
72
197
  private decodeMessage;
@@ -74,12 +199,24 @@ export declare class RedisQ {
74
199
  private decodeBatchMeta;
75
200
  private fetchMessages;
76
201
  private fetchBatchMessage;
202
+ /**
203
+ * Manually deletes a message from the queue.
204
+ * @param qname - The name of the queue.
205
+ * @param id - The ID of the message to delete.
206
+ * @returns `true` if the message was deleted, `false` otherwise.
207
+ */
77
208
  deleteMessage(qname: string, id: string): Promise<boolean>;
78
209
  private deleteBatch;
79
210
  private retryMessage;
80
211
  private retryBatch;
81
212
  private processDelayedMessages;
82
213
  private processBatches;
214
+ /**
215
+ * Starts a worker to process messages from a queue.
216
+ * @param qname - The name of the queue.
217
+ * @param handler - The function to process messages.
218
+ * @param options - Options for the worker.
219
+ */
83
220
  startWorker<QueueName extends `${string}:batch` | (string & {})>(qname: QueueName, handler: (received: QueueName extends `${string}:batch` ? BatchMessage : Message) => Promise<{
84
221
  success: boolean;
85
222
  }>, options?: {
@@ -87,6 +224,13 @@ export declare class RedisQ {
87
224
  silent?: boolean;
88
225
  }): Promise<void>;
89
226
  private runWorker;
227
+ /**
228
+ * Stops a specific worker.
229
+ * @param qname - The name of the queue for which to stop the worker.
230
+ */
90
231
  stopWorker(qname: string): void;
232
+ /**
233
+ * Closes all workers and the Redis connection gracefully.
234
+ */
91
235
  close(): Promise<void>;
92
236
  }
package/dist/app.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { RedisClient as BunRedisClient } from "bun";
2
2
  import { Cron } from "croner";
3
+ /**
4
+ * A lightweight, type-safe Redis-based message queue for Bun.
5
+ */
3
6
  export class RedisQ {
4
7
  redis;
5
8
  redisUrl;
@@ -7,6 +10,10 @@ export class RedisQ {
7
10
  workers = new Map();
8
11
  batchJobs = new Map();
9
12
  isClosing = false;
13
+ /**
14
+ * Initializes the RedisQ client.
15
+ * @param options - Options for initializing the client.
16
+ */
10
17
  constructor(options) {
11
18
  if ("redis" in options) {
12
19
  this.redis = options.redis;
@@ -34,6 +41,11 @@ export class RedisQ {
34
41
  isBatchQueue(qname) {
35
42
  return qname.endsWith(":batch");
36
43
  }
44
+ /**
45
+ * Creates a new queue with the specified options.
46
+ * @param options - Options for creating the queue.
47
+ * @returns `true` if the queue was created, `false` if it already exists.
48
+ */
37
49
  async createQueue(options) {
38
50
  const { qname, maxsize = 65536, maxRetries = 0, maxBackoffSeconds = 30, } = options;
39
51
  if (!/^[a-zA-Z0-9_:-]{1,160}$/.test(qname)) {
@@ -58,6 +70,10 @@ export class RedisQ {
58
70
  await this.redis.hset(key, attrs);
59
71
  return true;
60
72
  }
73
+ /**
74
+ * Lists all queue names.
75
+ * @returns An array of queue names.
76
+ */
61
77
  async listQueues() {
62
78
  const pattern = `${this.ns}:*`;
63
79
  const keys = await this.redis.keys(pattern);
@@ -65,6 +81,11 @@ export class RedisQ {
65
81
  .map((k) => k.replace(`${this.ns}:`, ""))
66
82
  .filter((k) => !k.includes(":") || k.endsWith(":batch"));
67
83
  }
84
+ /**
85
+ * Gets the attributes of a queue.
86
+ * @param qname - The name of the queue.
87
+ * @returns The queue attributes, or `null` if the queue does not exist.
88
+ */
68
89
  async getQueue(qname) {
69
90
  const key = this.getKey(qname);
70
91
  const attrs = await this.redis.hgetall(key);
@@ -91,6 +112,11 @@ export class RedisQ {
91
112
  }
92
113
  return result;
93
114
  }
115
+ /**
116
+ * Deletes a queue and all its data.
117
+ * @param qname - The name of the queue to delete.
118
+ * @returns `true` if the queue was deleted, `false` if it did not exist.
119
+ */
94
120
  async deleteQueue(qname) {
95
121
  const pattern = `${this.ns}:${qname}*`;
96
122
  let cursor = "0";
@@ -105,6 +131,11 @@ export class RedisQ {
105
131
  } while (cursor !== "0");
106
132
  return keysFound;
107
133
  }
134
+ /**
135
+ * Sends a message to a regular queue.
136
+ * @param options - Options for sending the message.
137
+ * @returns The unique ID of the message.
138
+ */
108
139
  async sendMessage(options) {
109
140
  const { qname, message, delay } = options;
110
141
  if (this.isBatchQueue(qname)) {
@@ -147,6 +178,11 @@ export class RedisQ {
147
178
  }
148
179
  return id;
149
180
  }
181
+ /**
182
+ * Sends a message to a batch queue.
183
+ * @param options - Options for sending the batch message.
184
+ * @returns The unique ID of the message.
185
+ */
150
186
  async sendBatchMessage(options) {
151
187
  const { qname, batchId, message } = options;
152
188
  if (!this.isBatchQueue(qname)) {
@@ -256,6 +292,12 @@ export class RedisQ {
256
292
  sent: meta.sent,
257
293
  };
258
294
  }
295
+ /**
296
+ * Manually deletes a message from the queue.
297
+ * @param qname - The name of the queue.
298
+ * @param id - The ID of the message to delete.
299
+ * @returns `true` if the message was deleted, `false` otherwise.
300
+ */
259
301
  async deleteMessage(qname, id) {
260
302
  const messagesKey = this.getKey(qname, "messages");
261
303
  const deleted = await this.redis.hdel(messagesKey, id);
@@ -388,6 +430,12 @@ export class RedisQ {
388
430
  });
389
431
  await Promise.all(batchPromises);
390
432
  }
433
+ /**
434
+ * Starts a worker to process messages from a queue.
435
+ * @param qname - The name of the queue.
436
+ * @param handler - The function to process messages.
437
+ * @param options - Options for the worker.
438
+ */
391
439
  async startWorker(qname, handler, options = {}) {
392
440
  const { concurrency = 1, silent = false } = options;
393
441
  if (this.workers.has(qname)) {
@@ -462,6 +510,10 @@ export class RedisQ {
462
510
  }
463
511
  }
464
512
  }
513
+ /**
514
+ * Stops a specific worker.
515
+ * @param qname - The name of the queue for which to stop the worker.
516
+ */
465
517
  stopWorker(qname) {
466
518
  const controller = this.workers.get(qname);
467
519
  if (controller) {
@@ -474,6 +526,9 @@ export class RedisQ {
474
526
  this.batchJobs.delete(qname);
475
527
  }
476
528
  }
529
+ /**
530
+ * Closes all workers and the Redis connection gracefully.
531
+ */
477
532
  async close() {
478
533
  this.isClosing = true;
479
534
  for (const qname of this.workers.keys()) {
package/package.json CHANGED
@@ -43,5 +43,5 @@
43
43
  },
44
44
  "type": "module",
45
45
  "types": "./dist/app.d.ts",
46
- "version": "1.0.3"
46
+ "version": "1.0.4"
47
47
  }