@tanstack/pacer 0.6.0 → 0.8.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.
Files changed (71) hide show
  1. package/dist/cjs/async-debouncer.cjs +10 -6
  2. package/dist/cjs/async-debouncer.cjs.map +1 -1
  3. package/dist/cjs/async-debouncer.d.cts +2 -2
  4. package/dist/cjs/async-queuer.cjs +140 -111
  5. package/dist/cjs/async-queuer.cjs.map +1 -1
  6. package/dist/cjs/async-queuer.d.cts +121 -93
  7. package/dist/cjs/async-rate-limiter.cjs +3 -4
  8. package/dist/cjs/async-rate-limiter.cjs.map +1 -1
  9. package/dist/cjs/async-rate-limiter.d.cts +1 -2
  10. package/dist/cjs/async-throttler.cjs +14 -4
  11. package/dist/cjs/async-throttler.cjs.map +1 -1
  12. package/dist/cjs/async-throttler.d.cts +3 -2
  13. package/dist/cjs/batcher.cjs +138 -0
  14. package/dist/cjs/batcher.cjs.map +1 -0
  15. package/dist/cjs/batcher.d.cts +149 -0
  16. package/dist/cjs/debouncer.cjs +3 -4
  17. package/dist/cjs/debouncer.cjs.map +1 -1
  18. package/dist/cjs/debouncer.d.cts +1 -2
  19. package/dist/cjs/index.cjs +3 -0
  20. package/dist/cjs/index.cjs.map +1 -1
  21. package/dist/cjs/index.d.cts +1 -0
  22. package/dist/cjs/queuer.cjs +70 -43
  23. package/dist/cjs/queuer.cjs.map +1 -1
  24. package/dist/cjs/queuer.d.cts +126 -95
  25. package/dist/cjs/rate-limiter.cjs +3 -4
  26. package/dist/cjs/rate-limiter.cjs.map +1 -1
  27. package/dist/cjs/rate-limiter.d.cts +1 -2
  28. package/dist/cjs/throttler.cjs +3 -4
  29. package/dist/cjs/throttler.cjs.map +1 -1
  30. package/dist/cjs/throttler.d.cts +1 -2
  31. package/dist/esm/async-debouncer.d.ts +2 -2
  32. package/dist/esm/async-debouncer.js +10 -6
  33. package/dist/esm/async-debouncer.js.map +1 -1
  34. package/dist/esm/async-queuer.d.ts +121 -93
  35. package/dist/esm/async-queuer.js +140 -111
  36. package/dist/esm/async-queuer.js.map +1 -1
  37. package/dist/esm/async-rate-limiter.d.ts +1 -2
  38. package/dist/esm/async-rate-limiter.js +3 -4
  39. package/dist/esm/async-rate-limiter.js.map +1 -1
  40. package/dist/esm/async-throttler.d.ts +3 -2
  41. package/dist/esm/async-throttler.js +14 -4
  42. package/dist/esm/async-throttler.js.map +1 -1
  43. package/dist/esm/batcher.d.ts +149 -0
  44. package/dist/esm/batcher.js +138 -0
  45. package/dist/esm/batcher.js.map +1 -0
  46. package/dist/esm/debouncer.d.ts +1 -2
  47. package/dist/esm/debouncer.js +3 -4
  48. package/dist/esm/debouncer.js.map +1 -1
  49. package/dist/esm/index.d.ts +1 -0
  50. package/dist/esm/index.js +3 -0
  51. package/dist/esm/index.js.map +1 -1
  52. package/dist/esm/queuer.d.ts +126 -95
  53. package/dist/esm/queuer.js +70 -43
  54. package/dist/esm/queuer.js.map +1 -1
  55. package/dist/esm/rate-limiter.d.ts +1 -2
  56. package/dist/esm/rate-limiter.js +3 -4
  57. package/dist/esm/rate-limiter.js.map +1 -1
  58. package/dist/esm/throttler.d.ts +1 -2
  59. package/dist/esm/throttler.js +3 -4
  60. package/dist/esm/throttler.js.map +1 -1
  61. package/package.json +11 -1
  62. package/src/async-debouncer.ts +12 -6
  63. package/src/async-queuer.ts +217 -194
  64. package/src/async-rate-limiter.ts +3 -4
  65. package/src/async-throttler.ts +18 -4
  66. package/src/batcher.ts +253 -0
  67. package/src/debouncer.ts +3 -4
  68. package/src/index.ts +1 -0
  69. package/src/queuer.ts +145 -101
  70. package/src/rate-limiter.ts +3 -4
  71. package/src/throttler.ts +3 -4
@@ -12,7 +12,8 @@ const defaultOptions = {
12
12
  wait: 0
13
13
  };
14
14
  class AsyncQueuer {
15
- constructor(initialOptions = defaultOptions) {
15
+ constructor(fn, initialOptions) {
16
+ this.fn = fn;
16
17
  this._activeItems = /* @__PURE__ */ new Set();
17
18
  this._successCount = 0;
18
19
  this._errorCount = 0;
@@ -35,32 +36,33 @@ class AsyncQueuer {
35
36
  }
36
37
  }
37
38
  /**
38
- * Updates the queuer options
39
- * Returns the new options state
39
+ * Updates the queuer options. New options are merged with existing options.
40
40
  */
41
41
  setOptions(newOptions) {
42
42
  this._options = { ...this._options, ...newOptions };
43
43
  }
44
44
  /**
45
- * Returns the current queuer options
45
+ * Returns the current queuer options, including defaults and any overrides.
46
46
  */
47
47
  getOptions() {
48
48
  return this._options;
49
49
  }
50
50
  /**
51
- * Returns the current wait time between processing items
51
+ * Returns the current wait time (in milliseconds) between processing items.
52
+ * If a function is provided, it is called with the queuer instance.
52
53
  */
53
54
  getWait() {
54
55
  return parseFunctionOrValue(this._options.wait, this);
55
56
  }
56
57
  /**
57
- * Returns the current concurrency limit
58
+ * Returns the current concurrency limit for processing items.
59
+ * If a function is provided, it is called with the queuer instance.
58
60
  */
59
61
  getConcurrency() {
60
62
  return parseFunctionOrValue(this._options.concurrency, this);
61
63
  }
62
64
  /**
63
- * Processes items in the queuer
65
+ * Processes items in the queue up to the concurrency limit. Internal use only.
64
66
  */
65
67
  tick() {
66
68
  var _a, _b;
@@ -70,33 +72,14 @@ class AsyncQueuer {
70
72
  }
71
73
  this.checkExpiredItems();
72
74
  while (this._activeItems.size < this.getConcurrency() && !this.getIsEmpty()) {
73
- const nextFn = this.getNextItem();
74
- if (!nextFn) {
75
+ const nextItem = this.peekNextItem();
76
+ if (!nextItem) {
75
77
  break;
76
78
  }
77
- this._activeItems.add(nextFn);
79
+ this._activeItems.add(nextItem);
78
80
  (_b = (_a = this._options).onItemsChange) == null ? void 0 : _b.call(_a, this);
79
81
  (async () => {
80
- var _a2, _b2, _c, _d, _e, _f, _g, _h;
81
- let res;
82
- try {
83
- res = await nextFn();
84
- this._successCount++;
85
- (_b2 = (_a2 = this._options).onSuccess) == null ? void 0 : _b2.call(_a2, res, this);
86
- } catch (error) {
87
- this._errorCount++;
88
- (_d = (_c = this._options).onError) == null ? void 0 : _d.call(_c, error, this);
89
- if (this._options.throwOnError) {
90
- throw error;
91
- } else {
92
- console.error(error);
93
- }
94
- } finally {
95
- this._settledCount++;
96
- this._activeItems.delete(nextFn);
97
- (_f = (_e = this._options).onItemsChange) == null ? void 0 : _f.call(_e, this);
98
- (_h = (_g = this._options).onSettled) == null ? void 0 : _h.call(_g, this);
99
- }
82
+ this._lastResult = await this.execute();
100
83
  const wait = this.getWait();
101
84
  if (wait > 0) {
102
85
  setTimeout(() => this.tick(), wait);
@@ -108,40 +91,7 @@ class AsyncQueuer {
108
91
  this._pendingTick = false;
109
92
  }
110
93
  /**
111
- * Checks for and removes expired items from the queuer
112
- */
113
- checkExpiredItems() {
114
- var _a, _b, _c, _d;
115
- if (this._options.expirationDuration === Infinity && this._options.getIsExpired === defaultOptions.getIsExpired)
116
- return;
117
- const now = Date.now();
118
- const expiredIndices = [];
119
- for (let i = 0; i < this._items.length; i++) {
120
- const timestamp = this._itemTimestamps[i];
121
- if (timestamp === void 0) continue;
122
- const item = this._items[i];
123
- if (item === void 0) continue;
124
- const isExpired = this._options.getIsExpired !== defaultOptions.getIsExpired ? this._options.getIsExpired(item, timestamp) : now - timestamp > this._options.expirationDuration;
125
- if (isExpired) {
126
- expiredIndices.push(i);
127
- }
128
- }
129
- for (let i = expiredIndices.length - 1; i >= 0; i--) {
130
- const index = expiredIndices[i];
131
- if (index === void 0) continue;
132
- const expiredItem = this._items[index];
133
- if (expiredItem === void 0) continue;
134
- this._items.splice(index, 1);
135
- this._itemTimestamps.splice(index, 1);
136
- this._expirationCount++;
137
- (_b = (_a = this._options).onExpire) == null ? void 0 : _b.call(_a, expiredItem, this);
138
- }
139
- if (expiredIndices.length > 0) {
140
- (_d = (_c = this._options).onItemsChange) == null ? void 0 : _d.call(_c, this);
141
- }
142
- }
143
- /**
144
- * Starts the queuer and processes items
94
+ * Starts processing items in the queue. If already running, does nothing.
145
95
  */
146
96
  start() {
147
97
  var _a, _b;
@@ -151,19 +101,9 @@ class AsyncQueuer {
151
101
  this.tick();
152
102
  }
153
103
  (_b = (_a = this._options).onIsRunningChange) == null ? void 0 : _b.call(_a, this);
154
- return new Promise((resolve) => {
155
- const checkIdle = () => {
156
- if (this.getIsIdle()) {
157
- resolve();
158
- } else {
159
- setTimeout(checkIdle, 100);
160
- }
161
- };
162
- checkIdle();
163
- });
164
104
  }
165
105
  /**
166
- * Stops the queuer from processing items
106
+ * Stops processing items in the queue. Does not clear the queue.
167
107
  */
168
108
  stop() {
169
109
  var _a, _b;
@@ -172,7 +112,7 @@ class AsyncQueuer {
172
112
  (_b = (_a = this._options).onIsRunningChange) == null ? void 0 : _b.call(_a, this);
173
113
  }
174
114
  /**
175
- * Removes all items from the queuer
115
+ * Removes all pending items from the queue. Does not affect active tasks.
176
116
  */
177
117
  clear() {
178
118
  var _a, _b;
@@ -180,7 +120,8 @@ class AsyncQueuer {
180
120
  (_b = (_a = this._options).onItemsChange) == null ? void 0 : _b.call(_a, this);
181
121
  }
182
122
  /**
183
- * Resets the queuer to its initial state
123
+ * Resets the queuer to its initial state. Optionally repopulates with initial items.
124
+ * Does not affect callbacks or options.
184
125
  */
185
126
  reset(withInitialItems) {
186
127
  this.clear();
@@ -193,34 +134,41 @@ class AsyncQueuer {
193
134
  this._running = this._options.started;
194
135
  }
195
136
  /**
196
- * Adds a task to the queuer
137
+ * Adds an item to the queue. If the queue is full, the item is rejected and onReject is called.
138
+ * Items can be inserted based on priority or at the front/back depending on configuration.
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * queuer.addItem({ value: 'task', priority: 10 });
143
+ * queuer.addItem('task2', 'front');
144
+ * ```
197
145
  */
198
- addItem(fn, position = this._options.addItemsTo, runOnItemsChange = true) {
146
+ addItem(item, position = this._options.addItemsTo, runOnItemsChange = true) {
199
147
  var _a, _b, _c, _d;
200
148
  if (this.getIsFull()) {
201
149
  this._rejectionCount++;
202
- (_b = (_a = this._options).onReject) == null ? void 0 : _b.call(_a, fn, this);
150
+ (_b = (_a = this._options).onReject) == null ? void 0 : _b.call(_a, item, this);
203
151
  return;
204
152
  }
205
- const priority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(fn) : fn.priority;
153
+ const priority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(item) : item.priority;
206
154
  if (priority !== void 0) {
207
155
  const insertIndex = this._items.findIndex((existing) => {
208
156
  const existingPriority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(existing) : existing.priority;
209
- return existingPriority > priority;
157
+ return existingPriority < priority;
210
158
  });
211
159
  if (insertIndex === -1) {
212
- this._items.push(fn);
160
+ this._items.push(item);
213
161
  this._itemTimestamps.push(Date.now());
214
162
  } else {
215
- this._items.splice(insertIndex, 0, fn);
163
+ this._items.splice(insertIndex, 0, item);
216
164
  this._itemTimestamps.splice(insertIndex, 0, Date.now());
217
165
  }
218
166
  } else {
219
167
  if (position === "front") {
220
- this._items.unshift(fn);
168
+ this._items.unshift(item);
221
169
  this._itemTimestamps.unshift(Date.now());
222
170
  } else {
223
- this._items.push(fn);
171
+ this._items.push(item);
224
172
  this._itemTimestamps.push(Date.now());
225
173
  }
226
174
  }
@@ -233,10 +181,19 @@ class AsyncQueuer {
233
181
  }
234
182
  }
235
183
  /**
236
- * Removes and returns an item from the queuer
184
+ * Removes and returns the next item from the queue without executing the task function.
185
+ * Use for manual queue management. Normally, use execute() to process items.
186
+ *
187
+ * @example
188
+ * ```ts
189
+ * // FIFO
190
+ * queuer.getNextItem();
191
+ * // LIFO
192
+ * queuer.getNextItem('back');
193
+ * ```
237
194
  */
238
195
  getNextItem(position = this._options.getItemsFrom) {
239
- var _a, _b, _c, _d;
196
+ var _a, _b;
240
197
  let item;
241
198
  if (position === "front") {
242
199
  item = this._items.shift();
@@ -247,101 +204,173 @@ class AsyncQueuer {
247
204
  }
248
205
  if (item !== void 0) {
249
206
  (_b = (_a = this._options).onItemsChange) == null ? void 0 : _b.call(_a, this);
250
- (_d = (_c = this._options).onGetNextItem) == null ? void 0 : _d.call(_c, item, this);
251
207
  }
252
208
  return item;
253
209
  }
254
210
  /**
255
- * Returns an item without removing it
211
+ * Removes and returns the next item from the queue and executes the task function with it.
212
+ *
213
+ * @example
214
+ * ```ts
215
+ * queuer.execute();
216
+ * // LIFO
217
+ * queuer.execute('back');
218
+ * ```
219
+ */
220
+ async execute(position) {
221
+ var _a, _b, _c, _d, _e, _f, _g, _h;
222
+ const item = this.getNextItem(position);
223
+ if (item !== void 0) {
224
+ try {
225
+ this._lastResult = await this.fn(item);
226
+ this._successCount++;
227
+ (_b = (_a = this._options).onSuccess) == null ? void 0 : _b.call(_a, this._lastResult, this);
228
+ } catch (error) {
229
+ this._errorCount++;
230
+ (_d = (_c = this._options).onError) == null ? void 0 : _d.call(_c, error, this);
231
+ if (this._options.throwOnError) {
232
+ throw error;
233
+ }
234
+ } finally {
235
+ this._settledCount++;
236
+ this._activeItems.delete(item);
237
+ (_f = (_e = this._options).onItemsChange) == null ? void 0 : _f.call(_e, this);
238
+ (_h = (_g = this._options).onSettled) == null ? void 0 : _h.call(_g, this);
239
+ }
240
+ }
241
+ return item;
242
+ }
243
+ /**
244
+ * Checks for expired items in the queue and removes them. Calls onExpire for each expired item.
245
+ * Internal use only.
246
+ */
247
+ checkExpiredItems() {
248
+ var _a, _b, _c, _d;
249
+ if (this._options.expirationDuration === Infinity && this._options.getIsExpired === defaultOptions.getIsExpired)
250
+ return;
251
+ const now = Date.now();
252
+ const expiredIndices = [];
253
+ for (let i = 0; i < this._items.length; i++) {
254
+ const timestamp = this._itemTimestamps[i];
255
+ if (timestamp === void 0) continue;
256
+ const item = this._items[i];
257
+ if (item === void 0) continue;
258
+ const isExpired = this._options.getIsExpired !== defaultOptions.getIsExpired ? this._options.getIsExpired(item, timestamp) : now - timestamp > this._options.expirationDuration;
259
+ if (isExpired) {
260
+ expiredIndices.push(i);
261
+ }
262
+ }
263
+ for (let i = expiredIndices.length - 1; i >= 0; i--) {
264
+ const index = expiredIndices[i];
265
+ if (index === void 0) continue;
266
+ const expiredItem = this._items[index];
267
+ if (expiredItem === void 0) continue;
268
+ this._items.splice(index, 1);
269
+ this._itemTimestamps.splice(index, 1);
270
+ this._expirationCount++;
271
+ (_b = (_a = this._options).onExpire) == null ? void 0 : _b.call(_a, expiredItem, this);
272
+ }
273
+ if (expiredIndices.length > 0) {
274
+ (_d = (_c = this._options).onItemsChange) == null ? void 0 : _d.call(_c, this);
275
+ }
276
+ }
277
+ /**
278
+ * Returns the next item in the queue without removing it.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * queuer.peekNextItem(); // front
283
+ * queuer.peekNextItem('back'); // back
284
+ * ```
256
285
  */
257
- getPeek(position = "front") {
286
+ peekNextItem(position = "front") {
258
287
  if (position === "front") {
259
288
  return this._items[0];
260
289
  }
261
290
  return this._items[this._items.length - 1];
262
291
  }
263
292
  /**
264
- * Returns true if the queuer is empty
293
+ * Returns true if the queue is empty (no pending items).
265
294
  */
266
295
  getIsEmpty() {
267
296
  return this._items.length === 0;
268
297
  }
269
298
  /**
270
- * Returns true if the queuer is full
299
+ * Returns true if the queue is full (reached maxSize).
271
300
  */
272
301
  getIsFull() {
273
302
  return this._items.length >= this._options.maxSize;
274
303
  }
275
304
  /**
276
- * Returns the current size of the queuer
305
+ * Returns the number of pending items in the queue.
277
306
  */
278
307
  getSize() {
279
308
  return this._items.length;
280
309
  }
281
310
  /**
282
- * Returns a copy of all items in the queuer
311
+ * Returns a copy of all items in the queue, including active and pending items.
283
312
  */
284
- getAllItems() {
285
- return [...this.getActiveItems(), ...this.getPendingItems()];
313
+ peekAllItems() {
314
+ return [...this.peekActiveItems(), ...this.peekPendingItems()];
286
315
  }
287
316
  /**
288
- * Returns the active items
317
+ * Returns the items currently being processed (active tasks).
289
318
  */
290
- getActiveItems() {
319
+ peekActiveItems() {
291
320
  return Array.from(this._activeItems);
292
321
  }
293
322
  /**
294
- * Returns the pending items
323
+ * Returns the items waiting to be processed (pending tasks).
295
324
  */
296
- getPendingItems() {
325
+ peekPendingItems() {
297
326
  return [...this._items];
298
327
  }
299
328
  /**
300
- * Returns the number of items that have been successfully processed
329
+ * Returns the number of items that have been successfully processed.
301
330
  */
302
331
  getSuccessCount() {
303
332
  return this._successCount;
304
333
  }
305
334
  /**
306
- * Returns the number of items that have failed processing
335
+ * Returns the number of items that have failed processing.
307
336
  */
308
337
  getErrorCount() {
309
338
  return this._errorCount;
310
339
  }
311
340
  /**
312
- * Returns the number of items that have completed processing (success or error)
341
+ * Returns the number of items that have completed processing (success or error).
313
342
  */
314
343
  getSettledCount() {
315
344
  return this._settledCount;
316
345
  }
317
346
  /**
318
- * Returns the number of items that have been rejected from the queuer
347
+ * Returns the number of items that have been rejected from being added to the queue.
319
348
  */
320
349
  getRejectionCount() {
321
350
  return this._rejectionCount;
322
351
  }
323
352
  /**
324
- * Returns true if the queuer is running
353
+ * Returns true if the queuer is currently running (processing items).
325
354
  */
326
355
  getIsRunning() {
327
356
  return this._running;
328
357
  }
329
358
  /**
330
- * Returns true if the queuer is running but has no items to process
359
+ * Returns true if the queuer is running but has no items to process and no active tasks.
331
360
  */
332
361
  getIsIdle() {
333
362
  return this._running && this.getIsEmpty() && this._activeItems.size === 0;
334
363
  }
335
364
  /**
336
- * Returns the number of items that have expired from the queuer
365
+ * Returns the number of items that have expired and been removed from the queue.
337
366
  */
338
367
  getExpirationCount() {
339
368
  return this._expirationCount;
340
369
  }
341
370
  }
342
- function asyncQueue(options) {
343
- const queuer = new AsyncQueuer(options);
344
- return queuer.addItem.bind(queuer);
371
+ function asyncQueue(fn, initialOptions) {
372
+ const asyncQueuer = new AsyncQueuer(fn, initialOptions);
373
+ return asyncQueuer.addItem.bind(asyncQueuer);
345
374
  }
346
375
  export {
347
376
  AsyncQueuer,
@@ -1 +1 @@
1
- {"version":3,"file":"async-queuer.js","sources":["../../src/async-queuer.ts"],"sourcesContent":["import { parseFunctionOrValue } from './utils'\nimport type { AnyAsyncFunction, OptionalKeys } from './types'\nimport type { QueuePosition } from './queuer'\n\nexport type AsyncQueuerFn = AnyAsyncFunction & { priority?: number }\n\nexport interface AsyncQueuerOptions<TFn extends AsyncQueuerFn> {\n /**\n * Default position to add items to the queuer\n * @default 'back'\n */\n addItemsTo?: QueuePosition\n /**\n * Maximum number of concurrent tasks to process.\n * Can be a number or a function that returns a number.\n * @default 1\n */\n concurrency?: number | ((queuer: AsyncQueuer<TFn>) => number)\n /**\n * Maximum time in milliseconds that an item can stay in the queue\n * If not provided, items will never expire\n */\n expirationDuration?: number\n /**\n * Function to determine if an item has expired\n * If provided, this overrides the expirationDuration behavior\n */\n getIsExpired?: (item: TFn, addedAt: number) => boolean\n /**\n * Default position to get items from during processing\n * @default 'front'\n */\n getItemsFrom?: QueuePosition\n /**\n * Function to determine priority of items in the queuer\n * Higher priority items will be processed first\n * If not provided, will use static priority values attached to tasks\n */\n getPriority?: (item: TFn) => number\n /**\n * Initial items to populate the queuer with\n */\n initialItems?: Array<TFn & { priority?: number }>\n /**\n * Maximum number of items allowed in the queuer\n */\n maxSize?: number\n /**\n * Optional error handler for when a task throws.\n * If provided, the handler will be called with the error and queuer instance.\n * This can be used alongside throwOnError - the handler will be called before any error is thrown.\n */\n onError?: (error: unknown, queuer: AsyncQueuer<TFn>) => void\n /**\n * Callback fired whenever an item expires in the queuer\n */\n onExpire?: (item: TFn, queuer: AsyncQueuer<TFn>) => void\n /**\n * Callback fired whenever an item is removed from the queuer\n */\n onGetNextItem?: (item: TFn, queuer: AsyncQueuer<TFn>) => void\n /**\n * Callback fired whenever the queuer's running state changes\n */\n onIsRunningChange?: (queuer: AsyncQueuer<TFn>) => void\n /**\n * Callback fired whenever an item is added or removed from the queuer\n */\n onItemsChange?: (queuer: AsyncQueuer<TFn>) => void\n /**\n * Callback fired whenever an item is rejected from being added to the queuer\n */\n onReject?: (item: TFn, queuer: AsyncQueuer<TFn>) => void\n /**\n * Optional callback to call when a task is settled\n */\n onSettled?: (queuer: AsyncQueuer<TFn>) => void\n /**\n * Optional callback to call when a task succeeds\n */\n onSuccess?: (result: TFn, queuer: AsyncQueuer<TFn>) => void\n /**\n * Whether the queuer should start processing tasks immediately or not.\n */\n started?: boolean\n /**\n * Whether to throw errors when they occur.\n * Defaults to true if no onError handler is provided, false if an onError handler is provided.\n * Can be explicitly set to override these defaults.\n */\n throwOnError?: boolean\n /**\n * Time in milliseconds to wait between processing items.\n * Can be a number or a function that returns a number.\n * @default 0\n */\n wait?: number | ((queuer: AsyncQueuer<TFn>) => number)\n}\n\ntype AsyncQueuerOptionsWithOptionalCallbacks = OptionalKeys<\n Required<AsyncQueuerOptions<any>>,\n | 'onError'\n | 'onExpire'\n | 'onGetNextItem'\n | 'onIsRunningChange'\n | 'onItemsChange'\n | 'onReject'\n | 'onSettled'\n | 'onSuccess'\n | 'throwOnError'\n>\n\nconst defaultOptions: AsyncQueuerOptionsWithOptionalCallbacks = {\n addItemsTo: 'back',\n concurrency: 1,\n expirationDuration: Infinity,\n getIsExpired: () => false,\n getItemsFrom: 'front',\n getPriority: (item: any) => item?.priority ?? 0,\n initialItems: [],\n maxSize: Infinity,\n started: true,\n wait: 0,\n}\n\n/**\n * A flexible asynchronous queue that processes tasks with configurable concurrency control.\n *\n * Features:\n * - Priority queue support via getPriority option\n * - Configurable concurrency limit\n * - Task success/error/completion callbacks\n * - FIFO (First In First Out) or LIFO (Last In First Out) queue behavior\n * - Pause/resume task processing\n * - Task cancellation\n * - Item expiration to clear stale items from the queue\n *\n * Tasks are processed concurrently up to the configured concurrency limit. When a task completes,\n * the next pending task is processed if below the concurrency limit.\n *\n * Error Handling:\n * - If an `onError` handler is provided, it will be called with the error and queuer instance\n * - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown\n * - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed\n * - Both onError and throwOnError can be used together - the handler will be called before any error is thrown\n * - The error state can be checked using the underlying AsyncQueuer instance\n *\n * @example\n * ```ts\n * const asyncQueuer = new AsyncQueuer<string>({\n * concurrency: 2,\n * onSuccess: (result) => {\n * console.log(result); // 'Hello'\n * }\n * });\n *\n * asyncQueuer.addItem(async () => {\n * return 'Hello';\n * });\n *\n * asyncQueuer.start();\n * ```\n */\nexport class AsyncQueuer<TFn extends AsyncQueuerFn> {\n private _options: AsyncQueuerOptionsWithOptionalCallbacks\n private _activeItems: Set<TFn> = new Set()\n private _successCount = 0\n private _errorCount = 0\n private _settledCount = 0\n private _rejectionCount = 0\n private _expirationCount = 0\n private _items: Array<TFn> = []\n private _itemTimestamps: Array<number> = []\n private _pendingTick = false\n private _running: boolean\n\n constructor(initialOptions: AsyncQueuerOptions<TFn> = defaultOptions) {\n this._options = {\n ...defaultOptions,\n ...initialOptions,\n throwOnError: initialOptions.throwOnError ?? !initialOptions.onError,\n }\n this._running = this._options.started\n\n for (let i = 0; i < this._options.initialItems.length; i++) {\n const item = this._options.initialItems[i]!\n const isLast = i === this._options.initialItems.length - 1\n this.addItem(item, this._options.addItemsTo, isLast)\n }\n }\n\n /**\n * Updates the queuer options\n * Returns the new options state\n */\n setOptions(newOptions: Partial<AsyncQueuerOptions<TFn>>): void {\n this._options = { ...this._options, ...newOptions }\n }\n\n /**\n * Returns the current queuer options\n */\n getOptions(): AsyncQueuerOptions<TFn> {\n return this._options\n }\n\n /**\n * Returns the current wait time between processing items\n */\n getWait(): number {\n return parseFunctionOrValue(this._options.wait, this)\n }\n\n /**\n * Returns the current concurrency limit\n */\n getConcurrency(): number {\n return parseFunctionOrValue(this._options.concurrency, this)\n }\n\n /**\n * Processes items in the queuer\n */\n private tick() {\n if (!this._running) {\n this._pendingTick = false\n return\n }\n\n // Check for expired items\n this.checkExpiredItems()\n\n while (\n this._activeItems.size < this.getConcurrency() &&\n !this.getIsEmpty()\n ) {\n const nextFn = this.getNextItem()\n if (!nextFn) {\n break\n }\n this._activeItems.add(nextFn)\n this._options.onItemsChange?.(this)\n ;(async () => {\n let res!: TFn\n\n try {\n res = await nextFn()\n this._successCount++\n this._options.onSuccess?.(res, this)\n } catch (error) {\n this._errorCount++\n this._options.onError?.(error, this)\n if (this._options.throwOnError) {\n throw error\n } else {\n console.error(error)\n }\n } finally {\n this._settledCount++\n this._activeItems.delete(nextFn)\n this._options.onItemsChange?.(this)\n this._options.onSettled?.(this)\n }\n\n const wait = this.getWait()\n if (wait > 0) {\n setTimeout(() => this.tick(), wait)\n return\n }\n\n this.tick()\n })()\n }\n\n this._pendingTick = false\n }\n\n /**\n * Checks for and removes expired items from the queuer\n */\n private checkExpiredItems(): void {\n if (\n this._options.expirationDuration === Infinity &&\n this._options.getIsExpired === defaultOptions.getIsExpired\n )\n return\n\n const now = Date.now()\n const expiredIndices: Array<number> = []\n\n // Find indices of expired items\n for (let i = 0; i < this._items.length; i++) {\n const timestamp = this._itemTimestamps[i]\n if (timestamp === undefined) continue\n\n const item = this._items[i]\n if (item === undefined) continue\n\n const isExpired =\n this._options.getIsExpired !== defaultOptions.getIsExpired\n ? this._options.getIsExpired(item, timestamp)\n : now - timestamp > this._options.expirationDuration\n\n if (isExpired) {\n expiredIndices.push(i)\n }\n }\n\n // Remove expired items from back to front to maintain indices\n for (let i = expiredIndices.length - 1; i >= 0; i--) {\n const index = expiredIndices[i]\n if (index === undefined) continue\n\n const expiredItem = this._items[index]\n if (expiredItem === undefined) continue\n\n this._items.splice(index, 1)\n this._itemTimestamps.splice(index, 1)\n this._expirationCount++\n this._options.onExpire?.(expiredItem, this)\n }\n\n if (expiredIndices.length > 0) {\n this._options.onItemsChange?.(this)\n }\n }\n\n /**\n * Starts the queuer and processes items\n */\n start(): Promise<void> {\n this._running = true\n if (!this._pendingTick && !this.getIsEmpty()) {\n this._pendingTick = true\n this.tick()\n }\n this._options.onIsRunningChange?.(this)\n\n return new Promise<void>((resolve) => {\n const checkIdle = () => {\n if (this.getIsIdle()) {\n resolve()\n } else {\n setTimeout(checkIdle, 100)\n }\n }\n checkIdle()\n })\n }\n\n /**\n * Stops the queuer from processing items\n */\n stop(): void {\n this._running = false\n this._pendingTick = false\n this._options.onIsRunningChange?.(this)\n }\n\n /**\n * Removes all items from the queuer\n */\n clear(): void {\n this._items = []\n this._options.onItemsChange?.(this)\n }\n\n /**\n * Resets the queuer to its initial state\n */\n reset(withInitialItems?: boolean): void {\n this.clear()\n this._successCount = 0\n this._errorCount = 0\n this._settledCount = 0\n if (withInitialItems) {\n this._items = [...this._options.initialItems]\n }\n this._running = this._options.started\n }\n\n /**\n * Adds a task to the queuer\n */\n addItem(\n fn: TFn,\n position: QueuePosition = this._options.addItemsTo,\n runOnItemsChange: boolean = true,\n ): void {\n if (this.getIsFull()) {\n this._rejectionCount++\n this._options.onReject?.(fn, this)\n return\n }\n\n // Get priority either from the function or from getPriority option\n const priority =\n this._options.getPriority !== defaultOptions.getPriority\n ? this._options.getPriority(fn)\n : fn.priority\n\n if (priority !== undefined) {\n // Insert based on priority\n const insertIndex = this._items.findIndex((existing) => {\n const existingPriority =\n this._options.getPriority !== defaultOptions.getPriority\n ? this._options.getPriority(existing)\n : (existing as any).priority\n return existingPriority > priority\n })\n\n if (insertIndex === -1) {\n this._items.push(fn)\n this._itemTimestamps.push(Date.now())\n } else {\n this._items.splice(insertIndex, 0, fn)\n this._itemTimestamps.splice(insertIndex, 0, Date.now())\n }\n } else {\n if (position === 'front') {\n // Default FIFO/LIFO behavior\n this._items.unshift(fn)\n this._itemTimestamps.unshift(Date.now())\n } else {\n // LIFO\n this._items.push(fn)\n this._itemTimestamps.push(Date.now())\n }\n }\n\n if (runOnItemsChange) {\n this._options.onItemsChange?.(this)\n }\n\n if (this._running && !this._pendingTick) {\n this._pendingTick = true\n this.tick()\n }\n }\n\n /**\n * Removes and returns an item from the queuer\n */\n getNextItem(\n position: QueuePosition = this._options.getItemsFrom,\n ): TFn | undefined {\n let item: TFn | undefined\n\n if (position === 'front') {\n item = this._items.shift()\n this._itemTimestamps.shift()\n } else {\n item = this._items.pop()\n this._itemTimestamps.pop()\n }\n\n if (item !== undefined) {\n this._options.onItemsChange?.(this)\n this._options.onGetNextItem?.(item, this)\n }\n return item\n }\n\n /**\n * Returns an item without removing it\n */\n getPeek(position: QueuePosition = 'front'): TFn | undefined {\n if (position === 'front') {\n return this._items[0]\n }\n return this._items[this._items.length - 1]\n }\n\n /**\n * Returns true if the queuer is empty\n */\n getIsEmpty(): boolean {\n return this._items.length === 0\n }\n\n /**\n * Returns true if the queuer is full\n */\n getIsFull(): boolean {\n return this._items.length >= this._options.maxSize\n }\n\n /**\n * Returns the current size of the queuer\n */\n getSize(): number {\n return this._items.length\n }\n\n /**\n * Returns a copy of all items in the queuer\n */\n getAllItems(): Array<TFn> {\n return [...this.getActiveItems(), ...this.getPendingItems()]\n }\n\n /**\n * Returns the active items\n */\n getActiveItems(): Array<TFn> {\n return Array.from(this._activeItems)\n }\n\n /**\n * Returns the pending items\n */\n getPendingItems(): Array<TFn> {\n return [...this._items]\n }\n\n /**\n * Returns the number of items that have been successfully processed\n */\n getSuccessCount(): number {\n return this._successCount\n }\n\n /**\n * Returns the number of items that have failed processing\n */\n getErrorCount(): number {\n return this._errorCount\n }\n\n /**\n * Returns the number of items that have completed processing (success or error)\n */\n getSettledCount(): number {\n return this._settledCount\n }\n\n /**\n * Returns the number of items that have been rejected from the queuer\n */\n getRejectionCount(): number {\n return this._rejectionCount\n }\n\n /**\n * Returns true if the queuer is running\n */\n getIsRunning(): boolean {\n return this._running\n }\n\n /**\n * Returns true if the queuer is running but has no items to process\n */\n getIsIdle(): boolean {\n return this._running && this.getIsEmpty() && this._activeItems.size === 0\n }\n\n /**\n * Returns the number of items that have expired from the queuer\n */\n getExpirationCount(): number {\n return this._expirationCount\n }\n}\n\n/**\n * Creates a new AsyncQueuer instance with the given options and returns a bound addItem function.\n * The queuer is automatically started and ready to process items.\n *\n * Error Handling:\n * - If an `onError` handler is provided, it will be called with the error and queuer instance\n * - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown\n * - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed\n * - Both onError and throwOnError can be used together - the handler will be called before any error is thrown\n * - The error state can be checked using the underlying AsyncQueuer instance\n *\n * @example\n * ```ts\n * const enqueue = asyncQueue<string>();\n *\n * // Add items to be processed\n * enqueue(async () => {\n * return 'Hello';\n * });\n * ```\n *\n * @param options - Configuration options for the AsyncQueuer\n * @returns A bound addItem function that can be used to add tasks to the queuer\n */\nexport function asyncQueue<TFn extends AsyncQueuerFn>(\n options: AsyncQueuerOptions<TFn>,\n) {\n const queuer = new AsyncQueuer<TFn>(options)\n return queuer.addItem.bind(queuer)\n}\n"],"names":["_b","_a"],"mappings":";AAgHA,MAAM,iBAA0D;AAAA,EAC9D,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,oBAAoB;AAAA,EACpB,cAAc,MAAM;AAAA,EACpB,cAAc;AAAA,EACd,aAAa,CAAC,UAAc,6BAAM,aAAY;AAAA,EAC9C,cAAc,CAAC;AAAA,EACf,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;AAwCO,MAAM,YAAuC;AAAA,EAalD,YAAY,iBAA0C,gBAAgB;AAX9D,SAAA,mCAA6B,IAAI;AACzC,SAAQ,gBAAgB;AACxB,SAAQ,cAAc;AACtB,SAAQ,gBAAgB;AACxB,SAAQ,kBAAkB;AAC1B,SAAQ,mBAAmB;AAC3B,SAAQ,SAAqB,CAAC;AAC9B,SAAQ,kBAAiC,CAAC;AAC1C,SAAQ,eAAe;AAIrB,SAAK,WAAW;AAAA,MACd,GAAG;AAAA,MACH,GAAG;AAAA,MACH,cAAc,eAAe,gBAAgB,CAAC,eAAe;AAAA,IAC/D;AACK,SAAA,WAAW,KAAK,SAAS;AAE9B,aAAS,IAAI,GAAG,IAAI,KAAK,SAAS,aAAa,QAAQ,KAAK;AAC1D,YAAM,OAAO,KAAK,SAAS,aAAa,CAAC;AACzC,YAAM,SAAS,MAAM,KAAK,SAAS,aAAa,SAAS;AACzD,WAAK,QAAQ,MAAM,KAAK,SAAS,YAAY,MAAM;AAAA,IAAA;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAOF,WAAW,YAAoD;AAC7D,SAAK,WAAW,EAAE,GAAG,KAAK,UAAU,GAAG,WAAW;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMpD,aAAsC;AACpC,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,UAAkB;AAChB,WAAO,qBAAqB,KAAK,SAAS,MAAM,IAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMtD,iBAAyB;AACvB,WAAO,qBAAqB,KAAK,SAAS,aAAa,IAAI;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMrD,OAAO;;AACT,QAAA,CAAC,KAAK,UAAU;AAClB,WAAK,eAAe;AACpB;AAAA,IAAA;AAIF,SAAK,kBAAkB;AAGrB,WAAA,KAAK,aAAa,OAAO,KAAK,oBAC9B,CAAC,KAAK,cACN;AACM,YAAA,SAAS,KAAK,YAAY;AAChC,UAAI,CAAC,QAAQ;AACX;AAAA,MAAA;AAEG,WAAA,aAAa,IAAI,MAAM;AACvB,uBAAA,UAAS,kBAAT,4BAAyB;AAC7B,OAAC,YAAY;;AACR,YAAA;AAEA,YAAA;AACF,gBAAM,MAAM,OAAO;AACd,eAAA;AACA,WAAAA,OAAAC,MAAA,KAAA,UAAS,cAAT,gBAAAD,IAAA,KAAAC,KAAqB,KAAK;AAAA,iBACxB,OAAO;AACT,eAAA;AACA,2BAAA,UAAS,YAAT,4BAAmB,OAAO;AAC3B,cAAA,KAAK,SAAS,cAAc;AACxB,kBAAA;AAAA,UAAA,OACD;AACL,oBAAQ,MAAM,KAAK;AAAA,UAAA;AAAA,QACrB,UACA;AACK,eAAA;AACA,eAAA,aAAa,OAAO,MAAM;AAC1B,2BAAA,UAAS,kBAAT,4BAAyB;AACzB,2BAAA,UAAS,cAAT,4BAAqB;AAAA,QAAI;AAG1B,cAAA,OAAO,KAAK,QAAQ;AAC1B,YAAI,OAAO,GAAG;AACZ,qBAAW,MAAM,KAAK,KAAK,GAAG,IAAI;AAClC;AAAA,QAAA;AAGF,aAAK,KAAK;AAAA,MAAA,GACT;AAAA,IAAA;AAGL,SAAK,eAAe;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,oBAA0B;;AAChC,QACE,KAAK,SAAS,uBAAuB,YACrC,KAAK,SAAS,iBAAiB,eAAe;AAE9C;AAEI,UAAA,MAAM,KAAK,IAAI;AACrB,UAAM,iBAAgC,CAAC;AAGvC,aAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AACrC,YAAA,YAAY,KAAK,gBAAgB,CAAC;AACxC,UAAI,cAAc,OAAW;AAEvB,YAAA,OAAO,KAAK,OAAO,CAAC;AAC1B,UAAI,SAAS,OAAW;AAExB,YAAM,YACJ,KAAK,SAAS,iBAAiB,eAAe,eAC1C,KAAK,SAAS,aAAa,MAAM,SAAS,IAC1C,MAAM,YAAY,KAAK,SAAS;AAEtC,UAAI,WAAW;AACb,uBAAe,KAAK,CAAC;AAAA,MAAA;AAAA,IACvB;AAIF,aAAS,IAAI,eAAe,SAAS,GAAG,KAAK,GAAG,KAAK;AAC7C,YAAA,QAAQ,eAAe,CAAC;AAC9B,UAAI,UAAU,OAAW;AAEnB,YAAA,cAAc,KAAK,OAAO,KAAK;AACrC,UAAI,gBAAgB,OAAW;AAE1B,WAAA,OAAO,OAAO,OAAO,CAAC;AACtB,WAAA,gBAAgB,OAAO,OAAO,CAAC;AAC/B,WAAA;AACA,uBAAA,UAAS,aAAT,4BAAoB,aAAa;AAAA,IAAI;AAGxC,QAAA,eAAe,SAAS,GAAG;AACxB,uBAAA,UAAS,kBAAT,4BAAyB;AAAA,IAAI;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAMF,QAAuB;;AACrB,SAAK,WAAW;AAChB,QAAI,CAAC,KAAK,gBAAgB,CAAC,KAAK,cAAc;AAC5C,WAAK,eAAe;AACpB,WAAK,KAAK;AAAA,IAAA;AAEP,qBAAA,UAAS,sBAAT,4BAA6B;AAE3B,WAAA,IAAI,QAAc,CAAC,YAAY;AACpC,YAAM,YAAY,MAAM;AAClB,YAAA,KAAK,aAAa;AACZ,kBAAA;AAAA,QAAA,OACH;AACL,qBAAW,WAAW,GAAG;AAAA,QAAA;AAAA,MAE7B;AACU,gBAAA;AAAA,IAAA,CACX;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMH,OAAa;;AACX,SAAK,WAAW;AAChB,SAAK,eAAe;AACf,qBAAA,UAAS,sBAAT,4BAA6B;AAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAMxC,QAAc;;AACZ,SAAK,SAAS,CAAC;AACV,qBAAA,UAAS,kBAAT,4BAAyB;AAAA,EAAI;AAAA;AAAA;AAAA;AAAA,EAMpC,MAAM,kBAAkC;AACtC,SAAK,MAAM;AACX,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,QAAI,kBAAkB;AACpB,WAAK,SAAS,CAAC,GAAG,KAAK,SAAS,YAAY;AAAA,IAAA;AAEzC,SAAA,WAAW,KAAK,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMhC,QACE,IACA,WAA0B,KAAK,SAAS,YACxC,mBAA4B,MACtB;;AACF,QAAA,KAAK,aAAa;AACf,WAAA;AACA,uBAAA,UAAS,aAAT,4BAAoB,IAAI;AAC7B;AAAA,IAAA;AAII,UAAA,WACJ,KAAK,SAAS,gBAAgB,eAAe,cACzC,KAAK,SAAS,YAAY,EAAE,IAC5B,GAAG;AAET,QAAI,aAAa,QAAW;AAE1B,YAAM,cAAc,KAAK,OAAO,UAAU,CAAC,aAAa;AAChD,cAAA,mBACJ,KAAK,SAAS,gBAAgB,eAAe,cACzC,KAAK,SAAS,YAAY,QAAQ,IACjC,SAAiB;AACxB,eAAO,mBAAmB;AAAA,MAAA,CAC3B;AAED,UAAI,gBAAgB,IAAI;AACjB,aAAA,OAAO,KAAK,EAAE;AACnB,aAAK,gBAAgB,KAAK,KAAK,IAAA,CAAK;AAAA,MAAA,OAC/B;AACL,aAAK,OAAO,OAAO,aAAa,GAAG,EAAE;AACrC,aAAK,gBAAgB,OAAO,aAAa,GAAG,KAAK,KAAK;AAAA,MAAA;AAAA,IACxD,OACK;AACL,UAAI,aAAa,SAAS;AAEnB,aAAA,OAAO,QAAQ,EAAE;AACtB,aAAK,gBAAgB,QAAQ,KAAK,IAAA,CAAK;AAAA,MAAA,OAClC;AAEA,aAAA,OAAO,KAAK,EAAE;AACnB,aAAK,gBAAgB,KAAK,KAAK,IAAA,CAAK;AAAA,MAAA;AAAA,IACtC;AAGF,QAAI,kBAAkB;AACf,uBAAA,UAAS,kBAAT,4BAAyB;AAAA,IAAI;AAGpC,QAAI,KAAK,YAAY,CAAC,KAAK,cAAc;AACvC,WAAK,eAAe;AACpB,WAAK,KAAK;AAAA,IAAA;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAMF,YACE,WAA0B,KAAK,SAAS,cACvB;;AACb,QAAA;AAEJ,QAAI,aAAa,SAAS;AACjB,aAAA,KAAK,OAAO,MAAM;AACzB,WAAK,gBAAgB,MAAM;AAAA,IAAA,OACtB;AACE,aAAA,KAAK,OAAO,IAAI;AACvB,WAAK,gBAAgB,IAAI;AAAA,IAAA;AAG3B,QAAI,SAAS,QAAW;AACjB,uBAAA,UAAS,kBAAT,4BAAyB;AACzB,uBAAA,UAAS,kBAAT,4BAAyB,MAAM;AAAA,IAAI;AAEnC,WAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMT,QAAQ,WAA0B,SAA0B;AAC1D,QAAI,aAAa,SAAS;AACjB,aAAA,KAAK,OAAO,CAAC;AAAA,IAAA;AAEtB,WAAO,KAAK,OAAO,KAAK,OAAO,SAAS,CAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAM3C,aAAsB;AACb,WAAA,KAAK,OAAO,WAAW;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMhC,YAAqB;AACnB,WAAO,KAAK,OAAO,UAAU,KAAK,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAM7C,UAAkB;AAChB,WAAO,KAAK,OAAO;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMrB,cAA0B;AACjB,WAAA,CAAC,GAAG,KAAK,kBAAkB,GAAG,KAAK,iBAAiB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAM7D,iBAA6B;AACpB,WAAA,MAAM,KAAK,KAAK,YAAY;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMrC,kBAA8B;AACrB,WAAA,CAAC,GAAG,KAAK,MAAM;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMxB,kBAA0B;AACxB,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,gBAAwB;AACtB,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,kBAA0B;AACxB,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,oBAA4B;AAC1B,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,eAAwB;AACtB,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,YAAqB;AACnB,WAAO,KAAK,YAAY,KAAK,WAAgB,KAAA,KAAK,aAAa,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAM1E,qBAA6B;AAC3B,WAAO,KAAK;AAAA,EAAA;AAEhB;AA0BO,SAAS,WACd,SACA;AACM,QAAA,SAAS,IAAI,YAAiB,OAAO;AACpC,SAAA,OAAO,QAAQ,KAAK,MAAM;AACnC;"}
1
+ {"version":3,"file":"async-queuer.js","sources":["../../src/async-queuer.ts"],"sourcesContent":["import { parseFunctionOrValue } from './utils'\nimport type { OptionalKeys } from './types'\nimport type { QueuePosition } from './queuer'\n\nexport interface AsyncQueuerOptions<TValue> {\n /**\n * Default position to add items to the queuer\n * @default 'back'\n */\n addItemsTo?: QueuePosition\n /**\n * Maximum number of concurrent tasks to process.\n * Can be a number or a function that returns a number.\n * @default 1\n */\n concurrency?: number | ((queuer: AsyncQueuer<TValue>) => number)\n /**\n * Maximum time in milliseconds that an item can stay in the queue\n * If not provided, items will never expire\n */\n expirationDuration?: number\n /**\n * Function to determine if an item has expired\n * If provided, this overrides the expirationDuration behavior\n */\n getIsExpired?: (item: TValue, addedAt: number) => boolean\n /**\n * Default position to get items from during processing\n * @default 'front'\n */\n getItemsFrom?: QueuePosition\n /**\n * Function to determine priority of items in the queuer\n * Higher priority items will be processed first\n * If not provided, will use static priority values attached to tasks\n */\n getPriority?: (item: TValue) => number\n /**\n * Initial items to populate the queuer with\n */\n initialItems?: Array<TValue>\n /**\n * Maximum number of items allowed in the queuer\n */\n maxSize?: number\n /**\n * Optional error handler for when a task throws.\n * If provided, the handler will be called with the error and queuer instance.\n * This can be used alongside throwOnError - the handler will be called before any error is thrown.\n */\n onError?: (error: unknown, queuer: AsyncQueuer<TValue>) => void\n /**\n * Callback fired whenever an item expires in the queuer\n */\n onExpire?: (item: TValue, queuer: AsyncQueuer<TValue>) => void\n /**\n * Callback fired whenever the queuer's running state changes\n */\n onIsRunningChange?: (queuer: AsyncQueuer<TValue>) => void\n /**\n * Callback fired whenever an item is added or removed from the queuer\n */\n onItemsChange?: (queuer: AsyncQueuer<TValue>) => void\n /**\n * Callback fired whenever an item is rejected from being added to the queuer\n */\n onReject?: (item: TValue, queuer: AsyncQueuer<TValue>) => void\n /**\n * Optional callback to call when a task is settled\n */\n onSettled?: (queuer: AsyncQueuer<TValue>) => void\n /**\n * Optional callback to call when a task succeeds\n */\n onSuccess?: (result: TValue, queuer: AsyncQueuer<TValue>) => void\n /**\n * Whether the queuer should start processing tasks immediately or not.\n */\n started?: boolean\n /**\n * Whether to throw errors when they occur.\n * Defaults to true if no onError handler is provided, false if an onError handler is provided.\n * Can be explicitly set to override these defaults.\n */\n throwOnError?: boolean\n /**\n * Time in milliseconds to wait between processing items.\n * Can be a number or a function that returns a number.\n * @default 0\n */\n wait?: number | ((queuer: AsyncQueuer<TValue>) => number)\n}\n\ntype AsyncQueuerOptionsWithOptionalCallbacks = OptionalKeys<\n Required<AsyncQueuerOptions<any>>,\n | 'throwOnError'\n | 'onSuccess'\n | 'onSettled'\n | 'onReject'\n | 'onItemsChange'\n | 'onIsRunningChange'\n | 'onExpire'\n | 'onError'\n>\n\nconst defaultOptions: AsyncQueuerOptionsWithOptionalCallbacks = {\n addItemsTo: 'back',\n concurrency: 1,\n expirationDuration: Infinity,\n getIsExpired: () => false,\n getItemsFrom: 'front',\n getPriority: (item: any) => item?.priority ?? 0,\n initialItems: [],\n maxSize: Infinity,\n started: true,\n wait: 0,\n}\n\n/**\n * A flexible asynchronous queue for processing tasks with configurable concurrency, priority, and expiration.\n *\n * Features:\n * - Priority queue support via the getPriority option\n * - Configurable concurrency limit\n * - Callbacks for task success, error, completion, and queue state changes\n * - FIFO (First In First Out) or LIFO (Last In First Out) queue behavior\n * - Pause and resume processing\n * - Task cancellation\n * - Item expiration to remove stale items from the queue\n *\n * Tasks are processed concurrently up to the configured concurrency limit. When a task completes,\n * the next pending task is processed if the concurrency limit allows.\n *\n * Error Handling:\n * - If an `onError` handler is provided, it will be called with the error and queuer instance\n * - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown\n * - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed\n * - Both onError and throwOnError can be used together; the handler will be called before any error is thrown\n * - The error state can be checked using the AsyncQueuer instance\n *\n * Example usage:\n * ```ts\n * const asyncQueuer = new AsyncQueuer<string>(async (item) => {\n * // process item\n * return item.toUpperCase();\n * }, {\n * concurrency: 2,\n * onSuccess: (result) => {\n * console.log(result);\n * }\n * });\n *\n * asyncQueuer.addItem('hello');\n * asyncQueuer.start();\n * ```\n */\nexport class AsyncQueuer<TValue> {\n private _options: AsyncQueuerOptionsWithOptionalCallbacks\n private _activeItems: Set<TValue> = new Set()\n private _successCount = 0\n private _errorCount = 0\n private _settledCount = 0\n private _rejectionCount = 0\n private _expirationCount = 0\n private _items: Array<TValue> = []\n private _itemTimestamps: Array<number> = []\n private _pendingTick = false\n private _running: boolean\n private _lastResult: any\n\n constructor(\n private fn: (value: TValue) => Promise<any>,\n initialOptions: AsyncQueuerOptions<TValue>,\n ) {\n this._options = {\n ...defaultOptions,\n ...initialOptions,\n throwOnError: initialOptions.throwOnError ?? !initialOptions.onError,\n }\n this._running = this._options.started\n\n for (let i = 0; i < this._options.initialItems.length; i++) {\n const item = this._options.initialItems[i]!\n const isLast = i === this._options.initialItems.length - 1\n this.addItem(item, this._options.addItemsTo, isLast)\n }\n }\n\n /**\n * Updates the queuer options. New options are merged with existing options.\n */\n setOptions(newOptions: Partial<AsyncQueuerOptions<TValue>>): void {\n this._options = { ...this._options, ...newOptions }\n }\n\n /**\n * Returns the current queuer options, including defaults and any overrides.\n */\n getOptions(): AsyncQueuerOptions<TValue> {\n return this._options\n }\n\n /**\n * Returns the current wait time (in milliseconds) between processing items.\n * If a function is provided, it is called with the queuer instance.\n */\n getWait(): number {\n return parseFunctionOrValue(this._options.wait, this)\n }\n\n /**\n * Returns the current concurrency limit for processing items.\n * If a function is provided, it is called with the queuer instance.\n */\n getConcurrency(): number {\n return parseFunctionOrValue(this._options.concurrency, this)\n }\n\n /**\n * Processes items in the queue up to the concurrency limit. Internal use only.\n */\n private tick() {\n if (!this._running) {\n this._pendingTick = false\n return\n }\n\n // Check for expired items\n this.checkExpiredItems()\n\n // Process items concurrently up to the concurrency limit\n while (\n this._activeItems.size < this.getConcurrency() &&\n !this.getIsEmpty()\n ) {\n const nextItem = this.peekNextItem()\n if (!nextItem) {\n break\n }\n this._activeItems.add(nextItem)\n this._options.onItemsChange?.(this)\n ;(async () => {\n this._lastResult = await this.execute()\n\n const wait = this.getWait()\n if (wait > 0) {\n setTimeout(() => this.tick(), wait)\n return\n }\n\n this.tick()\n })()\n }\n\n this._pendingTick = false\n }\n\n /**\n * Starts processing items in the queue. If already running, does nothing.\n */\n start(): void {\n this._running = true\n if (!this._pendingTick && !this.getIsEmpty()) {\n this._pendingTick = true\n this.tick()\n }\n this._options.onIsRunningChange?.(this)\n }\n\n /**\n * Stops processing items in the queue. Does not clear the queue.\n */\n stop(): void {\n this._running = false\n this._pendingTick = false\n this._options.onIsRunningChange?.(this)\n }\n\n /**\n * Removes all pending items from the queue. Does not affect active tasks.\n */\n clear(): void {\n this._items = []\n this._options.onItemsChange?.(this)\n }\n\n /**\n * Resets the queuer to its initial state. Optionally repopulates with initial items.\n * Does not affect callbacks or options.\n */\n reset(withInitialItems?: boolean): void {\n this.clear()\n this._successCount = 0\n this._errorCount = 0\n this._settledCount = 0\n if (withInitialItems) {\n this._items = [...this._options.initialItems]\n }\n this._running = this._options.started\n }\n\n /**\n * Adds an item to the queue. If the queue is full, the item is rejected and onReject is called.\n * Items can be inserted based on priority or at the front/back depending on configuration.\n *\n * @example\n * ```ts\n * queuer.addItem({ value: 'task', priority: 10 });\n * queuer.addItem('task2', 'front');\n * ```\n */\n addItem(\n item: TValue & { priority?: number },\n position: QueuePosition = this._options.addItemsTo,\n runOnItemsChange: boolean = true,\n ): void {\n if (this.getIsFull()) {\n this._rejectionCount++\n this._options.onReject?.(item, this)\n return\n }\n\n // Get priority either from the function or from getPriority option\n const priority =\n this._options.getPriority !== defaultOptions.getPriority\n ? this._options.getPriority(item)\n : item.priority\n\n if (priority !== undefined) {\n // Insert based on priority - higher priority items go to front\n const insertIndex = this._items.findIndex((existing) => {\n const existingPriority =\n this._options.getPriority !== defaultOptions.getPriority\n ? this._options.getPriority(existing)\n : (existing as any).priority\n return existingPriority < priority\n })\n\n if (insertIndex === -1) {\n this._items.push(item)\n this._itemTimestamps.push(Date.now())\n } else {\n this._items.splice(insertIndex, 0, item)\n this._itemTimestamps.splice(insertIndex, 0, Date.now())\n }\n } else {\n if (position === 'front') {\n // Default FIFO/LIFO behavior\n this._items.unshift(item)\n this._itemTimestamps.unshift(Date.now())\n } else {\n // LIFO\n this._items.push(item)\n this._itemTimestamps.push(Date.now())\n }\n }\n\n if (runOnItemsChange) {\n this._options.onItemsChange?.(this)\n }\n\n if (this._running && !this._pendingTick) {\n this._pendingTick = true\n this.tick()\n }\n }\n\n /**\n * Removes and returns the next item from the queue without executing the task function.\n * Use for manual queue management. Normally, use execute() to process items.\n *\n * @example\n * ```ts\n * // FIFO\n * queuer.getNextItem();\n * // LIFO\n * queuer.getNextItem('back');\n * ```\n */\n getNextItem(\n position: QueuePosition = this._options.getItemsFrom,\n ): TValue | undefined {\n let item: TValue | undefined\n\n if (position === 'front') {\n item = this._items.shift()\n this._itemTimestamps.shift()\n } else {\n item = this._items.pop()\n this._itemTimestamps.pop()\n }\n\n if (item !== undefined) {\n this._options.onItemsChange?.(this)\n }\n\n return item\n }\n\n /**\n * Removes and returns the next item from the queue and executes the task function with it.\n *\n * @example\n * ```ts\n * queuer.execute();\n * // LIFO\n * queuer.execute('back');\n * ```\n */\n async execute(position?: QueuePosition): Promise<any> {\n const item = this.getNextItem(position)\n if (item !== undefined) {\n try {\n this._lastResult = await this.fn(item)\n this._successCount++\n this._options.onSuccess?.(this._lastResult, this)\n } catch (error) {\n this._errorCount++\n this._options.onError?.(error, this)\n if (this._options.throwOnError) {\n throw error\n }\n } finally {\n this._settledCount++\n this._activeItems.delete(item)\n this._options.onItemsChange?.(this)\n this._options.onSettled?.(this)\n }\n }\n return item\n }\n\n /**\n * Checks for expired items in the queue and removes them. Calls onExpire for each expired item.\n * Internal use only.\n */\n private checkExpiredItems(): void {\n if (\n this._options.expirationDuration === Infinity &&\n this._options.getIsExpired === defaultOptions.getIsExpired\n )\n return\n\n const now = Date.now()\n const expiredIndices: Array<number> = []\n\n // Find indices of expired items\n for (let i = 0; i < this._items.length; i++) {\n const timestamp = this._itemTimestamps[i]\n if (timestamp === undefined) continue\n\n const item = this._items[i]\n if (item === undefined) continue\n\n const isExpired =\n this._options.getIsExpired !== defaultOptions.getIsExpired\n ? this._options.getIsExpired(item, timestamp)\n : now - timestamp > this._options.expirationDuration\n\n if (isExpired) {\n expiredIndices.push(i)\n }\n }\n\n // Remove expired items from back to front to maintain indices\n for (let i = expiredIndices.length - 1; i >= 0; i--) {\n const index = expiredIndices[i]\n if (index === undefined) continue\n\n const expiredItem = this._items[index]\n if (expiredItem === undefined) continue\n\n this._items.splice(index, 1)\n this._itemTimestamps.splice(index, 1)\n this._expirationCount++\n this._options.onExpire?.(expiredItem, this)\n }\n\n if (expiredIndices.length > 0) {\n this._options.onItemsChange?.(this)\n }\n }\n\n /**\n * Returns the next item in the queue without removing it.\n *\n * @example\n * ```ts\n * queuer.peekNextItem(); // front\n * queuer.peekNextItem('back'); // back\n * ```\n */\n peekNextItem(position: QueuePosition = 'front'): TValue | undefined {\n if (position === 'front') {\n return this._items[0]\n }\n return this._items[this._items.length - 1]\n }\n\n /**\n * Returns true if the queue is empty (no pending items).\n */\n getIsEmpty(): boolean {\n return this._items.length === 0\n }\n\n /**\n * Returns true if the queue is full (reached maxSize).\n */\n getIsFull(): boolean {\n return this._items.length >= this._options.maxSize\n }\n\n /**\n * Returns the number of pending items in the queue.\n */\n getSize(): number {\n return this._items.length\n }\n\n /**\n * Returns a copy of all items in the queue, including active and pending items.\n */\n peekAllItems(): Array<TValue> {\n return [...this.peekActiveItems(), ...this.peekPendingItems()]\n }\n\n /**\n * Returns the items currently being processed (active tasks).\n */\n peekActiveItems(): Array<TValue> {\n return Array.from(this._activeItems)\n }\n\n /**\n * Returns the items waiting to be processed (pending tasks).\n */\n peekPendingItems(): Array<TValue> {\n return [...this._items]\n }\n\n /**\n * Returns the number of items that have been successfully processed.\n */\n getSuccessCount(): number {\n return this._successCount\n }\n\n /**\n * Returns the number of items that have failed processing.\n */\n getErrorCount(): number {\n return this._errorCount\n }\n\n /**\n * Returns the number of items that have completed processing (success or error).\n */\n getSettledCount(): number {\n return this._settledCount\n }\n\n /**\n * Returns the number of items that have been rejected from being added to the queue.\n */\n getRejectionCount(): number {\n return this._rejectionCount\n }\n\n /**\n * Returns true if the queuer is currently running (processing items).\n */\n getIsRunning(): boolean {\n return this._running\n }\n\n /**\n * Returns true if the queuer is running but has no items to process and no active tasks.\n */\n getIsIdle(): boolean {\n return this._running && this.getIsEmpty() && this._activeItems.size === 0\n }\n\n /**\n * Returns the number of items that have expired and been removed from the queue.\n */\n getExpirationCount(): number {\n return this._expirationCount\n }\n}\n\n/**\n * Creates a new AsyncQueuer instance and returns a bound addItem function for adding tasks.\n * The queuer is started automatically and ready to process items.\n *\n * Error Handling:\n * - If an `onError` handler is provided, it will be called with the error and queuer instance\n * - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown\n * - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed\n * - Both onError and throwOnError can be used together; the handler will be called before any error is thrown\n * - The error state can be checked using the underlying AsyncQueuer instance\n *\n * Example usage:\n * ```ts\n * const enqueue = asyncQueue<string>(async (item) => {\n * return item.toUpperCase();\n * }, {...options});\n *\n * enqueue('hello');\n * ```\n */\nexport function asyncQueue<TValue>(\n fn: (value: TValue) => Promise<any>,\n initialOptions: AsyncQueuerOptions<TValue>,\n) {\n const asyncQueuer = new AsyncQueuer<TValue>(fn, initialOptions)\n return asyncQueuer.addItem.bind(asyncQueuer)\n}\n"],"names":[],"mappings":"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"}
@@ -118,7 +118,6 @@ export declare class AsyncRateLimiter<TFn extends AnyAsyncFunction> {
118
118
  constructor(fn: TFn, initialOptions: AsyncRateLimiterOptions<TFn>);
119
119
  /**
120
120
  * Updates the rate limiter options
121
- * Returns the new options state
122
121
  */
123
122
  setOptions(newOptions: Partial<AsyncRateLimiterOptions<TFn>>): void;
124
123
  /**
@@ -167,7 +166,7 @@ export declare class AsyncRateLimiter<TFn extends AnyAsyncFunction> {
167
166
  * ```
168
167
  */
169
168
  maybeExecute(...args: Parameters<TFn>): Promise<ReturnType<TFn> | undefined>;
170
- private executeFunction;
169
+ private execute;
171
170
  private rejectFunction;
172
171
  private cleanupOldExecutions;
173
172
  /**
@@ -20,7 +20,6 @@ class AsyncRateLimiter {
20
20
  }
21
21
  /**
22
22
  * Updates the rate limiter options
23
- * Returns the new options state
24
23
  */
25
24
  setOptions(newOptions) {
26
25
  this._options = { ...this._options, ...newOptions };
@@ -84,7 +83,7 @@ class AsyncRateLimiter {
84
83
  const window = this.getWindow();
85
84
  if (this._options.windowType === "sliding") {
86
85
  if (this._executionTimes.length < limit) {
87
- await this.executeFunction(...args);
86
+ await this.execute(...args);
88
87
  return this._lastResult;
89
88
  }
90
89
  } else {
@@ -92,14 +91,14 @@ class AsyncRateLimiter {
92
91
  const oldestExecution = Math.min(...this._executionTimes);
93
92
  const isNewWindow = oldestExecution + window <= now;
94
93
  if (isNewWindow || this._executionTimes.length < limit) {
95
- await this.executeFunction(...args);
94
+ await this.execute(...args);
96
95
  return this._lastResult;
97
96
  }
98
97
  }
99
98
  this.rejectFunction();
100
99
  return void 0;
101
100
  }
102
- async executeFunction(...args) {
101
+ async execute(...args) {
103
102
  var _a, _b, _c, _d, _e, _f;
104
103
  if (!this.getEnabled()) return;
105
104
  this._isExecuting = true;