@zucker-framework/queue 1.0.2 → 1.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/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @zucker-framework/queue
2
+
3
+ `BullMqQueueProvider` owns producers; `BullMqWorkerHost` owns workers. Consumers retain outboxes, transaction boundaries, authorization, quota decisions and cancellation policy. Neither transport makes a business transaction atomic.
4
+
5
+ ## Producer lifecycle
6
+
7
+ Construct with explicit `connection` and optional `prefix`, `onError(queueName, error)`. Call `waitUntilReady(['queue-name'])` to prewarm producers without adding a job; the no-argument form only waits for already-created queues. Close producers **after** gracefully closing workers that may still publish work. Error callbacks should redact connection errors before logging.
8
+
9
+ `addBulk(queueName, entries)` on the BullMQ adapter preserves native bulk submission, validating all job IDs before creating the queue; empty batches create no connection. `add` preserves stable transport IDs. `ensure` may replace terminal records: do not use it when a terminal job must remain evidence for outbox failure reconciliation. `getJob` exposes normalized status and failed reason. `getStats` combines waiting/prioritized with a read-only legacy paused-list count; BullMQ 6 does not accept `paused` as a getJobCounts type. This does not resume or migrate legacy queues and is not proof of v5→v6 compatibility. `getJobCounts(queueName)` retains BullMQ's native default count keys (including `waiting-children`) for backend-specific monitoring contracts without merging counts.
10
+
11
+ ## Workers
12
+
13
+ `register({ queueName, handler, concurrency, lockDurationMs, stalledIntervalMs, autorun })` requires positive safe-integer settings. Handler jobs include `attempt` (one-based) and `maxAttempts` (configured budget, default 1), allowing product terminal-attempt policy without reaching into raw BullMQ jobs. BullMQ unrecoverable errors can still be thrown directly by a handler.
14
+
15
+ `close(false)` drains workers; concurrent calls share the same drain promise. Every close is awaited even if another close throws/rejects; failures are reported together as `AggregateError`, so a failed drain cannot signal completion while another worker is still active. Closed hosts/providers cannot register workers or reopen producers. Force closing has different recovery implications. `probeHealth` is a bounded read-only connection probe, not a task execution probe. Test with fake factories or explicitly isolated disposable Redis; never use existing queues for compatibility experiments.
16
+
17
+ New prewarm/error/retry-budget/stalled-interval contracts are local source additions pending a new formal release; 1.0.2 consumers must not import sibling source to obtain them.
package/dist/index.d.mts CHANGED
@@ -93,14 +93,21 @@ interface BullMqQueueProviderOptions {
93
93
  prefix?: string;
94
94
  defaultJobName?: string;
95
95
  queueFactory?: QueueFactory;
96
+ onError?: (queueName: string, error: Error) => void;
96
97
  }
97
98
  declare class BullMqQueueProvider implements QueueProvider {
98
99
  private readonly options;
99
100
  private readonly queues;
101
+ private closing?;
100
102
  private readonly defaultJobName;
101
103
  private readonly queueFactory;
102
104
  constructor(options: BullMqQueueProviderOptions);
103
105
  add<T>(queueName: string, data: T, options?: JobOptions): Promise<Job<T>>;
106
+ /** Preserve BullMQ native bulk submission semantics rather than looping add(). */
107
+ addBulk<T>(queueName: string, entries: readonly {
108
+ data: T;
109
+ options?: JobOptions;
110
+ }[]): Promise<Job<T>[]>;
104
111
  ensure<T>(queueName: string, data: T, options: JobOptions & {
105
112
  jobId: string;
106
113
  }): Promise<Job<T>>;
@@ -110,8 +117,11 @@ declare class BullMqQueueProvider implements QueueProvider {
110
117
  removeJob(queueName: string, jobId: string): Promise<void>;
111
118
  pause(queueName: string): Promise<void>;
112
119
  resume(queueName: string): Promise<void>;
120
+ /** Native count keys for existing BullMQ monitoring contracts. Unlike
121
+ * getStats(), this does not merge prioritized/legacy-paused into waiting. */
122
+ getJobCounts(queueName: string): Promise<Record<string, number>>;
113
123
  getStats(queueName: string): Promise<QueueStats>;
114
- waitUntilReady(): Promise<void>;
124
+ waitUntilReady(queueNames?: readonly string[]): Promise<void>;
115
125
  close(): Promise<void>;
116
126
  onModuleDestroy(): Promise<void>;
117
127
  private getQueue;
@@ -133,6 +143,8 @@ interface QueueWorkerJob<TData> {
133
143
  name: string;
134
144
  data: TData;
135
145
  attempt: number;
146
+ /** Configured retry budget, including this attempt. */
147
+ maxAttempts: number;
136
148
  updateProgress(progress: JobProgress): Promise<void>;
137
149
  log(message: string): Promise<number>;
138
150
  }
@@ -142,6 +154,7 @@ interface QueueWorkerDefinition<TData = unknown, TResult = unknown> {
142
154
  handler: QueueJobHandler<TData, TResult>;
143
155
  concurrency?: number;
144
156
  lockDurationMs?: number;
157
+ stalledIntervalMs?: number;
145
158
  autorun?: boolean;
146
159
  }
147
160
  type WorkerFactory = (queueName: string, processor: (job: Job$1) => Promise<unknown>, options: WorkerOptions) => Worker;
@@ -160,6 +173,7 @@ declare class BullMqWorkerHost {
160
173
  private readonly options;
161
174
  private readonly workers;
162
175
  private readonly readyQueues;
176
+ private closing?;
163
177
  private readonly workerFactory;
164
178
  constructor(options: BullMqWorkerHostOptions);
165
179
  register<TData, TResult>(definition: QueueWorkerDefinition<TData, TResult>): void;
package/dist/index.d.ts CHANGED
@@ -93,14 +93,21 @@ interface BullMqQueueProviderOptions {
93
93
  prefix?: string;
94
94
  defaultJobName?: string;
95
95
  queueFactory?: QueueFactory;
96
+ onError?: (queueName: string, error: Error) => void;
96
97
  }
97
98
  declare class BullMqQueueProvider implements QueueProvider {
98
99
  private readonly options;
99
100
  private readonly queues;
101
+ private closing?;
100
102
  private readonly defaultJobName;
101
103
  private readonly queueFactory;
102
104
  constructor(options: BullMqQueueProviderOptions);
103
105
  add<T>(queueName: string, data: T, options?: JobOptions): Promise<Job<T>>;
106
+ /** Preserve BullMQ native bulk submission semantics rather than looping add(). */
107
+ addBulk<T>(queueName: string, entries: readonly {
108
+ data: T;
109
+ options?: JobOptions;
110
+ }[]): Promise<Job<T>[]>;
104
111
  ensure<T>(queueName: string, data: T, options: JobOptions & {
105
112
  jobId: string;
106
113
  }): Promise<Job<T>>;
@@ -110,8 +117,11 @@ declare class BullMqQueueProvider implements QueueProvider {
110
117
  removeJob(queueName: string, jobId: string): Promise<void>;
111
118
  pause(queueName: string): Promise<void>;
112
119
  resume(queueName: string): Promise<void>;
120
+ /** Native count keys for existing BullMQ monitoring contracts. Unlike
121
+ * getStats(), this does not merge prioritized/legacy-paused into waiting. */
122
+ getJobCounts(queueName: string): Promise<Record<string, number>>;
113
123
  getStats(queueName: string): Promise<QueueStats>;
114
- waitUntilReady(): Promise<void>;
124
+ waitUntilReady(queueNames?: readonly string[]): Promise<void>;
115
125
  close(): Promise<void>;
116
126
  onModuleDestroy(): Promise<void>;
117
127
  private getQueue;
@@ -133,6 +143,8 @@ interface QueueWorkerJob<TData> {
133
143
  name: string;
134
144
  data: TData;
135
145
  attempt: number;
146
+ /** Configured retry budget, including this attempt. */
147
+ maxAttempts: number;
136
148
  updateProgress(progress: JobProgress): Promise<void>;
137
149
  log(message: string): Promise<number>;
138
150
  }
@@ -142,6 +154,7 @@ interface QueueWorkerDefinition<TData = unknown, TResult = unknown> {
142
154
  handler: QueueJobHandler<TData, TResult>;
143
155
  concurrency?: number;
144
156
  lockDurationMs?: number;
157
+ stalledIntervalMs?: number;
145
158
  autorun?: boolean;
146
159
  }
147
160
  type WorkerFactory = (queueName: string, processor: (job: Job$1) => Promise<unknown>, options: WorkerOptions) => Worker;
@@ -160,6 +173,7 @@ declare class BullMqWorkerHost {
160
173
  private readonly options;
161
174
  private readonly workers;
162
175
  private readonly readyQueues;
176
+ private closing?;
163
177
  private readonly workerFactory;
164
178
  constructor(options: BullMqWorkerHostOptions);
165
179
  register<TData, TResult>(definition: QueueWorkerDefinition<TData, TResult>): void;
package/dist/index.js CHANGED
@@ -161,6 +161,7 @@ var BullMqQueueProvider = class {
161
161
  }
162
162
  options;
163
163
  queues = /* @__PURE__ */ new Map();
164
+ closing;
164
165
  defaultJobName;
165
166
  queueFactory;
166
167
  constructor(options) {
@@ -173,6 +174,17 @@ var BullMqQueueProvider = class {
173
174
  const job = await this.getQueue(queueName).add(options?.name ?? this.defaultJobName, data, this.toBullMqOptions(options));
174
175
  return this.toJob(job);
175
176
  }
177
+ /** Preserve BullMQ native bulk submission semantics rather than looping add(). */
178
+ async addBulk(queueName, entries) {
179
+ for (const entry of entries) this.assertValidJobId(entry.options?.jobId);
180
+ if (entries.length === 0) return [];
181
+ const jobs = await this.getQueue(queueName).addBulk(entries.map(({ data, options }) => ({
182
+ name: options?.name ?? this.defaultJobName,
183
+ data,
184
+ opts: this.toBullMqOptions(options)
185
+ })));
186
+ return Promise.all(jobs.map((job) => this.toJob(job)));
187
+ }
176
188
  async ensure(queueName, data, options) {
177
189
  this.assertValidJobId(options.jobId);
178
190
  const queue = this.getQueue(queueName);
@@ -222,39 +234,54 @@ var BullMqQueueProvider = class {
222
234
  async resume(queueName) {
223
235
  await this.getQueue(queueName).resume();
224
236
  }
237
+ /** Native count keys for existing BullMQ monitoring contracts. Unlike
238
+ * getStats(), this does not merge prioritized/legacy-paused into waiting. */
239
+ async getJobCounts(queueName) {
240
+ return this.getQueue(queueName).getJobCounts();
241
+ }
225
242
  async getStats(queueName) {
226
- const pausedStateForStats = "paused";
227
- const counts = await this.getQueue(queueName).getJobCounts("wait", "active", "completed", "failed", "delayed", "prioritized", pausedStateForStats);
243
+ const queue = this.getQueue(queueName);
244
+ const counts = await queue.getJobCounts("wait", "active", "completed", "failed", "delayed", "prioritized");
245
+ const client = await queue.backend.client;
246
+ const paused = await client.llen(queue.toKey("paused"));
228
247
  return {
229
- waiting: (counts.wait ?? 0) + (counts.prioritized ?? 0) + (counts.paused ?? 0),
248
+ waiting: (counts.wait ?? 0) + (counts.prioritized ?? 0) + paused,
230
249
  active: counts.active ?? 0,
231
250
  completed: counts.completed ?? 0,
232
251
  failed: counts.failed ?? 0,
233
252
  delayed: counts.delayed ?? 0
234
253
  };
235
254
  }
236
- async waitUntilReady() {
255
+ async waitUntilReady(queueNames = []) {
256
+ for (const name of queueNames) this.getQueue(name);
237
257
  await Promise.all([
238
258
  ...this.queues.values()
239
259
  ].map((queue) => queue.waitUntilReady()));
240
260
  }
241
- async close() {
261
+ close() {
262
+ if (this.closing) return this.closing;
242
263
  const queues = [
243
264
  ...this.queues.values()
244
265
  ];
245
266
  this.queues.clear();
246
- await Promise.all(queues.map((queue) => queue.close()));
267
+ this.closing = Promise.allSettled(queues.map(async (queue) => queue.close())).then((results) => {
268
+ const failures = results.filter((result) => result.status === "rejected");
269
+ if (failures.length) throw new AggregateError(failures.map((result) => result.reason), "Queue shutdown failed");
270
+ });
271
+ return this.closing;
247
272
  }
248
273
  async onModuleDestroy() {
249
274
  await this.close();
250
275
  }
251
276
  getQueue(name) {
277
+ if (this.closing) throw new Error("Queue provider is closing");
252
278
  const existing = this.queues.get(name);
253
279
  if (existing) return existing;
254
280
  const queue = this.queueFactory(name, {
255
281
  connection: this.options.connection,
256
282
  prefix: this.options.prefix
257
283
  });
284
+ if (this.options.onError) queue.on("error", (error) => this.options.onError(name, error));
258
285
  this.queues.set(name, queue);
259
286
  return queue;
260
287
  }
@@ -344,24 +371,30 @@ var BullMqWorkerHost = class {
344
371
  options;
345
372
  workers = /* @__PURE__ */ new Map();
346
373
  readyQueues = /* @__PURE__ */ new Set();
374
+ closing;
347
375
  workerFactory;
348
376
  constructor(options) {
349
377
  this.options = options;
350
378
  this.workerFactory = options.workerFactory ?? ((queueName, processor, workerOptions) => new import_bullmq2.Worker(queueName, processor, workerOptions));
351
379
  }
352
380
  register(definition) {
381
+ if (this.closing) throw new Error("Worker host is closing");
353
382
  if (this.workers.has(definition.queueName)) {
354
383
  throw new Error(`Worker already registered for queue: ${definition.queueName}`);
355
384
  }
356
- if ((definition.concurrency ?? 1) < 1) throw new RangeError("concurrency must be at least 1");
357
- if ((definition.lockDurationMs ?? 3e4) < 1) {
358
- throw new RangeError("lockDurationMs must be at least 1");
385
+ for (const [name, value] of Object.entries({
386
+ concurrency: definition.concurrency ?? 1,
387
+ lockDurationMs: definition.lockDurationMs ?? 3e4,
388
+ stalledIntervalMs: definition.stalledIntervalMs ?? 3e4
389
+ })) {
390
+ if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${name} must be a positive safe integer`);
359
391
  }
360
392
  const worker = this.workerFactory(definition.queueName, async (job) => definition.handler({
361
393
  id: String(job.id),
362
394
  name: job.name,
363
395
  data: job.data,
364
396
  attempt: job.attemptsMade + 1,
397
+ maxAttempts: job.opts?.attempts ?? 1,
365
398
  updateProgress: /* @__PURE__ */ __name((progress) => job.updateProgress(progress), "updateProgress"),
366
399
  log: /* @__PURE__ */ __name((message) => job.log(message), "log")
367
400
  }), {
@@ -369,9 +402,14 @@ var BullMqWorkerHost = class {
369
402
  prefix: this.options.prefix,
370
403
  concurrency: definition.concurrency ?? 1,
371
404
  lockDuration: definition.lockDurationMs ?? 3e4,
372
- autorun: definition.autorun ?? true
405
+ autorun: definition.autorun ?? true,
406
+ ...definition.stalledIntervalMs === void 0 ? {} : {
407
+ stalledInterval: definition.stalledIntervalMs
408
+ }
409
+ });
410
+ worker.on("ready", () => {
411
+ if (!this.closing) this.readyQueues.add(definition.queueName);
373
412
  });
374
- worker.on("ready", () => this.readyQueues.add(definition.queueName));
375
413
  worker.on("error", (error) => {
376
414
  this.readyQueues.delete(definition.queueName);
377
415
  this.options.onError?.(definition.queueName, error);
@@ -447,13 +485,18 @@ var BullMqWorkerHost = class {
447
485
  ...this.workers.values()
448
486
  ].map((worker) => worker.resume()));
449
487
  }
450
- async close(force = false) {
488
+ close(force = false) {
489
+ if (this.closing) return this.closing;
451
490
  const workers = [
452
491
  ...this.workers.values()
453
492
  ];
454
493
  this.workers.clear();
455
494
  this.readyQueues.clear();
456
- await Promise.all(workers.map((worker) => worker.close(force)));
495
+ this.closing = Promise.allSettled(workers.map(async (worker) => worker.close(force))).then((results) => {
496
+ const failures = results.filter((result) => result.status === "rejected");
497
+ if (failures.length) throw new AggregateError(failures.map((result) => result.reason), "Worker shutdown failed");
498
+ });
499
+ return this.closing;
457
500
  }
458
501
  async onModuleDestroy() {
459
502
  await this.close();
package/dist/index.mjs CHANGED
@@ -127,6 +127,7 @@ var BullMqQueueProvider = class {
127
127
  }
128
128
  options;
129
129
  queues = /* @__PURE__ */ new Map();
130
+ closing;
130
131
  defaultJobName;
131
132
  queueFactory;
132
133
  constructor(options) {
@@ -139,6 +140,17 @@ var BullMqQueueProvider = class {
139
140
  const job = await this.getQueue(queueName).add(options?.name ?? this.defaultJobName, data, this.toBullMqOptions(options));
140
141
  return this.toJob(job);
141
142
  }
143
+ /** Preserve BullMQ native bulk submission semantics rather than looping add(). */
144
+ async addBulk(queueName, entries) {
145
+ for (const entry of entries) this.assertValidJobId(entry.options?.jobId);
146
+ if (entries.length === 0) return [];
147
+ const jobs = await this.getQueue(queueName).addBulk(entries.map(({ data, options }) => ({
148
+ name: options?.name ?? this.defaultJobName,
149
+ data,
150
+ opts: this.toBullMqOptions(options)
151
+ })));
152
+ return Promise.all(jobs.map((job) => this.toJob(job)));
153
+ }
142
154
  async ensure(queueName, data, options) {
143
155
  this.assertValidJobId(options.jobId);
144
156
  const queue = this.getQueue(queueName);
@@ -188,39 +200,54 @@ var BullMqQueueProvider = class {
188
200
  async resume(queueName) {
189
201
  await this.getQueue(queueName).resume();
190
202
  }
203
+ /** Native count keys for existing BullMQ monitoring contracts. Unlike
204
+ * getStats(), this does not merge prioritized/legacy-paused into waiting. */
205
+ async getJobCounts(queueName) {
206
+ return this.getQueue(queueName).getJobCounts();
207
+ }
191
208
  async getStats(queueName) {
192
- const pausedStateForStats = "paused";
193
- const counts = await this.getQueue(queueName).getJobCounts("wait", "active", "completed", "failed", "delayed", "prioritized", pausedStateForStats);
209
+ const queue = this.getQueue(queueName);
210
+ const counts = await queue.getJobCounts("wait", "active", "completed", "failed", "delayed", "prioritized");
211
+ const client = await queue.backend.client;
212
+ const paused = await client.llen(queue.toKey("paused"));
194
213
  return {
195
- waiting: (counts.wait ?? 0) + (counts.prioritized ?? 0) + (counts.paused ?? 0),
214
+ waiting: (counts.wait ?? 0) + (counts.prioritized ?? 0) + paused,
196
215
  active: counts.active ?? 0,
197
216
  completed: counts.completed ?? 0,
198
217
  failed: counts.failed ?? 0,
199
218
  delayed: counts.delayed ?? 0
200
219
  };
201
220
  }
202
- async waitUntilReady() {
221
+ async waitUntilReady(queueNames = []) {
222
+ for (const name of queueNames) this.getQueue(name);
203
223
  await Promise.all([
204
224
  ...this.queues.values()
205
225
  ].map((queue) => queue.waitUntilReady()));
206
226
  }
207
- async close() {
227
+ close() {
228
+ if (this.closing) return this.closing;
208
229
  const queues = [
209
230
  ...this.queues.values()
210
231
  ];
211
232
  this.queues.clear();
212
- await Promise.all(queues.map((queue) => queue.close()));
233
+ this.closing = Promise.allSettled(queues.map(async (queue) => queue.close())).then((results) => {
234
+ const failures = results.filter((result) => result.status === "rejected");
235
+ if (failures.length) throw new AggregateError(failures.map((result) => result.reason), "Queue shutdown failed");
236
+ });
237
+ return this.closing;
213
238
  }
214
239
  async onModuleDestroy() {
215
240
  await this.close();
216
241
  }
217
242
  getQueue(name) {
243
+ if (this.closing) throw new Error("Queue provider is closing");
218
244
  const existing = this.queues.get(name);
219
245
  if (existing) return existing;
220
246
  const queue = this.queueFactory(name, {
221
247
  connection: this.options.connection,
222
248
  prefix: this.options.prefix
223
249
  });
250
+ if (this.options.onError) queue.on("error", (error) => this.options.onError(name, error));
224
251
  this.queues.set(name, queue);
225
252
  return queue;
226
253
  }
@@ -310,24 +337,30 @@ var BullMqWorkerHost = class {
310
337
  options;
311
338
  workers = /* @__PURE__ */ new Map();
312
339
  readyQueues = /* @__PURE__ */ new Set();
340
+ closing;
313
341
  workerFactory;
314
342
  constructor(options) {
315
343
  this.options = options;
316
344
  this.workerFactory = options.workerFactory ?? ((queueName, processor, workerOptions) => new Worker(queueName, processor, workerOptions));
317
345
  }
318
346
  register(definition) {
347
+ if (this.closing) throw new Error("Worker host is closing");
319
348
  if (this.workers.has(definition.queueName)) {
320
349
  throw new Error(`Worker already registered for queue: ${definition.queueName}`);
321
350
  }
322
- if ((definition.concurrency ?? 1) < 1) throw new RangeError("concurrency must be at least 1");
323
- if ((definition.lockDurationMs ?? 3e4) < 1) {
324
- throw new RangeError("lockDurationMs must be at least 1");
351
+ for (const [name, value] of Object.entries({
352
+ concurrency: definition.concurrency ?? 1,
353
+ lockDurationMs: definition.lockDurationMs ?? 3e4,
354
+ stalledIntervalMs: definition.stalledIntervalMs ?? 3e4
355
+ })) {
356
+ if (!Number.isSafeInteger(value) || value < 1) throw new RangeError(`${name} must be a positive safe integer`);
325
357
  }
326
358
  const worker = this.workerFactory(definition.queueName, async (job) => definition.handler({
327
359
  id: String(job.id),
328
360
  name: job.name,
329
361
  data: job.data,
330
362
  attempt: job.attemptsMade + 1,
363
+ maxAttempts: job.opts?.attempts ?? 1,
331
364
  updateProgress: /* @__PURE__ */ __name((progress) => job.updateProgress(progress), "updateProgress"),
332
365
  log: /* @__PURE__ */ __name((message) => job.log(message), "log")
333
366
  }), {
@@ -335,9 +368,14 @@ var BullMqWorkerHost = class {
335
368
  prefix: this.options.prefix,
336
369
  concurrency: definition.concurrency ?? 1,
337
370
  lockDuration: definition.lockDurationMs ?? 3e4,
338
- autorun: definition.autorun ?? true
371
+ autorun: definition.autorun ?? true,
372
+ ...definition.stalledIntervalMs === void 0 ? {} : {
373
+ stalledInterval: definition.stalledIntervalMs
374
+ }
375
+ });
376
+ worker.on("ready", () => {
377
+ if (!this.closing) this.readyQueues.add(definition.queueName);
339
378
  });
340
- worker.on("ready", () => this.readyQueues.add(definition.queueName));
341
379
  worker.on("error", (error) => {
342
380
  this.readyQueues.delete(definition.queueName);
343
381
  this.options.onError?.(definition.queueName, error);
@@ -413,13 +451,18 @@ var BullMqWorkerHost = class {
413
451
  ...this.workers.values()
414
452
  ].map((worker) => worker.resume()));
415
453
  }
416
- async close(force = false) {
454
+ close(force = false) {
455
+ if (this.closing) return this.closing;
417
456
  const workers = [
418
457
  ...this.workers.values()
419
458
  ];
420
459
  this.workers.clear();
421
460
  this.readyQueues.clear();
422
- await Promise.all(workers.map((worker) => worker.close(force)));
461
+ this.closing = Promise.allSettled(workers.map(async (worker) => worker.close(force))).then((results) => {
462
+ const failures = results.filter((result) => result.status === "rejected");
463
+ if (failures.length) throw new AggregateError(failures.map((result) => result.reason), "Worker shutdown failed");
464
+ });
465
+ return this.closing;
423
466
  }
424
467
  async onModuleDestroy() {
425
468
  await this.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zucker-framework/queue",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",