@tanstack/pacer 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/async-debouncer.cjs +24 -13
- package/dist/cjs/async-debouncer.cjs.map +1 -1
- package/dist/cjs/async-debouncer.d.cts +49 -7
- package/dist/cjs/async-queuer.cjs +83 -114
- package/dist/cjs/async-queuer.cjs.map +1 -1
- package/dist/cjs/async-queuer.d.cts +79 -50
- package/dist/cjs/async-rate-limiter.cjs +20 -9
- package/dist/cjs/async-rate-limiter.cjs.map +1 -1
- package/dist/cjs/async-rate-limiter.d.cts +53 -3
- package/dist/cjs/async-throttler.cjs +24 -13
- package/dist/cjs/async-throttler.cjs.map +1 -1
- package/dist/cjs/async-throttler.d.cts +48 -6
- package/dist/cjs/types.d.cts +1 -0
- package/dist/esm/async-debouncer.d.ts +49 -7
- package/dist/esm/async-debouncer.js +24 -13
- package/dist/esm/async-debouncer.js.map +1 -1
- package/dist/esm/async-queuer.d.ts +79 -50
- package/dist/esm/async-queuer.js +83 -114
- package/dist/esm/async-queuer.js.map +1 -1
- package/dist/esm/async-rate-limiter.d.ts +53 -3
- package/dist/esm/async-rate-limiter.js +20 -9
- package/dist/esm/async-rate-limiter.js.map +1 -1
- package/dist/esm/async-throttler.d.ts +48 -6
- package/dist/esm/async-throttler.js +24 -13
- package/dist/esm/async-throttler.js.map +1 -1
- package/dist/esm/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/async-debouncer.ts +66 -16
- package/src/async-queuer.ts +180 -169
- package/src/async-rate-limiter.ts +70 -12
- package/src/async-throttler.ts +66 -16
- package/src/types.ts +3 -0
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { AnyAsyncFunction } from './types.js';
|
|
2
2
|
import { QueuePosition } from './queuer.js';
|
|
3
|
-
export
|
|
3
|
+
export type AsyncQueuerFn = AnyAsyncFunction & {
|
|
4
|
+
priority?: number;
|
|
5
|
+
};
|
|
6
|
+
export interface AsyncQueuerOptions<TFn extends AsyncQueuerFn> {
|
|
4
7
|
/**
|
|
5
8
|
* Default position to add items to the queuer
|
|
6
9
|
* @default 'back'
|
|
@@ -11,7 +14,7 @@ export interface AsyncQueuerOptions<TValue> {
|
|
|
11
14
|
* Can be a number or a function that returns a number.
|
|
12
15
|
* @default 1
|
|
13
16
|
*/
|
|
14
|
-
concurrency?: number | ((queuer: AsyncQueuer<
|
|
17
|
+
concurrency?: number | ((queuer: AsyncQueuer<TFn>) => number);
|
|
15
18
|
/**
|
|
16
19
|
* Maximum time in milliseconds that an item can stay in the queue
|
|
17
20
|
* If not provided, items will never expire
|
|
@@ -21,7 +24,7 @@ export interface AsyncQueuerOptions<TValue> {
|
|
|
21
24
|
* Function to determine if an item has expired
|
|
22
25
|
* If provided, this overrides the expirationDuration behavior
|
|
23
26
|
*/
|
|
24
|
-
getIsExpired?: (item:
|
|
27
|
+
getIsExpired?: (item: TFn, addedAt: number) => boolean;
|
|
25
28
|
/**
|
|
26
29
|
* Default position to get items from during processing
|
|
27
30
|
* @default 'front'
|
|
@@ -32,47 +35,67 @@ export interface AsyncQueuerOptions<TValue> {
|
|
|
32
35
|
* Higher priority items will be processed first
|
|
33
36
|
* If not provided, will use static priority values attached to tasks
|
|
34
37
|
*/
|
|
35
|
-
getPriority?: (item:
|
|
38
|
+
getPriority?: (item: TFn) => number;
|
|
36
39
|
/**
|
|
37
40
|
* Initial items to populate the queuer with
|
|
38
41
|
*/
|
|
39
|
-
initialItems?: Array<
|
|
42
|
+
initialItems?: Array<TFn & {
|
|
40
43
|
priority?: number;
|
|
41
44
|
}>;
|
|
42
45
|
/**
|
|
43
46
|
* Maximum number of items allowed in the queuer
|
|
44
47
|
*/
|
|
45
48
|
maxSize?: number;
|
|
49
|
+
/**
|
|
50
|
+
* Optional error handler for when a task throws.
|
|
51
|
+
* If provided, the handler will be called with the error and queuer instance.
|
|
52
|
+
* This can be used alongside throwOnError - the handler will be called before any error is thrown.
|
|
53
|
+
*/
|
|
54
|
+
onError?: (error: unknown, queuer: AsyncQueuer<TFn>) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Callback fired whenever an item expires in the queuer
|
|
57
|
+
*/
|
|
58
|
+
onExpire?: (item: TFn, queuer: AsyncQueuer<TFn>) => void;
|
|
46
59
|
/**
|
|
47
60
|
* Callback fired whenever an item is removed from the queuer
|
|
48
61
|
*/
|
|
49
|
-
onGetNextItem?: (item:
|
|
62
|
+
onGetNextItem?: (item: TFn, queuer: AsyncQueuer<TFn>) => void;
|
|
50
63
|
/**
|
|
51
64
|
* Callback fired whenever the queuer's running state changes
|
|
52
65
|
*/
|
|
53
|
-
onIsRunningChange?: (queuer: AsyncQueuer<
|
|
66
|
+
onIsRunningChange?: (queuer: AsyncQueuer<TFn>) => void;
|
|
54
67
|
/**
|
|
55
68
|
* Callback fired whenever an item is added or removed from the queuer
|
|
56
69
|
*/
|
|
57
|
-
onItemsChange?: (queuer: AsyncQueuer<
|
|
70
|
+
onItemsChange?: (queuer: AsyncQueuer<TFn>) => void;
|
|
58
71
|
/**
|
|
59
72
|
* Callback fired whenever an item is rejected from being added to the queuer
|
|
60
73
|
*/
|
|
61
|
-
onReject?: (item:
|
|
74
|
+
onReject?: (item: TFn, queuer: AsyncQueuer<TFn>) => void;
|
|
62
75
|
/**
|
|
63
|
-
*
|
|
76
|
+
* Optional callback to call when a task is settled
|
|
64
77
|
*/
|
|
65
|
-
|
|
78
|
+
onSettled?: (queuer: AsyncQueuer<TFn>) => void;
|
|
79
|
+
/**
|
|
80
|
+
* Optional callback to call when a task succeeds
|
|
81
|
+
*/
|
|
82
|
+
onSuccess?: (result: TFn, queuer: AsyncQueuer<TFn>) => void;
|
|
66
83
|
/**
|
|
67
84
|
* Whether the queuer should start processing tasks immediately or not.
|
|
68
85
|
*/
|
|
69
86
|
started?: boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Whether to throw errors when they occur.
|
|
89
|
+
* Defaults to true if no onError handler is provided, false if an onError handler is provided.
|
|
90
|
+
* Can be explicitly set to override these defaults.
|
|
91
|
+
*/
|
|
92
|
+
throwOnError?: boolean;
|
|
70
93
|
/**
|
|
71
94
|
* Time in milliseconds to wait between processing items.
|
|
72
95
|
* Can be a number or a function that returns a number.
|
|
73
96
|
* @default 0
|
|
74
97
|
*/
|
|
75
|
-
wait?: number | ((queuer: AsyncQueuer<
|
|
98
|
+
wait?: number | ((queuer: AsyncQueuer<TFn>) => number);
|
|
76
99
|
}
|
|
77
100
|
/**
|
|
78
101
|
* A flexible asynchronous queue that processes tasks with configurable concurrency control.
|
|
@@ -89,44 +112,51 @@ export interface AsyncQueuerOptions<TValue> {
|
|
|
89
112
|
* Tasks are processed concurrently up to the configured concurrency limit. When a task completes,
|
|
90
113
|
* the next pending task is processed if below the concurrency limit.
|
|
91
114
|
*
|
|
115
|
+
* Error Handling:
|
|
116
|
+
* - If an `onError` handler is provided, it will be called with the error and queuer instance
|
|
117
|
+
* - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown
|
|
118
|
+
* - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed
|
|
119
|
+
* - Both onError and throwOnError can be used together - the handler will be called before any error is thrown
|
|
120
|
+
* - The error state can be checked using the underlying AsyncQueuer instance
|
|
121
|
+
*
|
|
92
122
|
* @example
|
|
93
123
|
* ```ts
|
|
94
|
-
* const asyncQueuer = new AsyncQueuer<string>({
|
|
124
|
+
* const asyncQueuer = new AsyncQueuer<string>({
|
|
125
|
+
* concurrency: 2,
|
|
126
|
+
* onSuccess: (result) => {
|
|
127
|
+
* console.log(result); // 'Hello'
|
|
128
|
+
* }
|
|
129
|
+
* });
|
|
95
130
|
*
|
|
96
131
|
* asyncQueuer.addItem(async () => {
|
|
97
132
|
* return 'Hello';
|
|
98
133
|
* });
|
|
99
134
|
*
|
|
100
135
|
* asyncQueuer.start();
|
|
101
|
-
*
|
|
102
|
-
* asyncQueuer.onSuccess((result) => {
|
|
103
|
-
* console.log(result); // 'Hello'
|
|
104
|
-
* });
|
|
105
136
|
* ```
|
|
106
137
|
*/
|
|
107
|
-
export declare class AsyncQueuer<
|
|
138
|
+
export declare class AsyncQueuer<TFn extends AsyncQueuerFn> {
|
|
108
139
|
private _options;
|
|
109
140
|
private _activeItems;
|
|
110
|
-
private
|
|
141
|
+
private _successCount;
|
|
142
|
+
private _errorCount;
|
|
143
|
+
private _settledCount;
|
|
111
144
|
private _rejectionCount;
|
|
112
145
|
private _expirationCount;
|
|
113
146
|
private _items;
|
|
114
147
|
private _itemTimestamps;
|
|
115
|
-
private _onErrorCallbacks;
|
|
116
|
-
private _onSettledCallbacks;
|
|
117
|
-
private _onSuccessCallbacks;
|
|
118
148
|
private _pendingTick;
|
|
119
149
|
private _running;
|
|
120
|
-
constructor(initialOptions?: AsyncQueuerOptions<
|
|
150
|
+
constructor(initialOptions?: AsyncQueuerOptions<TFn>);
|
|
121
151
|
/**
|
|
122
152
|
* Updates the queuer options
|
|
123
153
|
* Returns the new options state
|
|
124
154
|
*/
|
|
125
|
-
setOptions(newOptions: Partial<AsyncQueuerOptions<
|
|
155
|
+
setOptions(newOptions: Partial<AsyncQueuerOptions<TFn>>): void;
|
|
126
156
|
/**
|
|
127
157
|
* Returns the current queuer options
|
|
128
158
|
*/
|
|
129
|
-
getOptions():
|
|
159
|
+
getOptions(): AsyncQueuerOptions<TFn>;
|
|
130
160
|
/**
|
|
131
161
|
* Returns the current wait time between processing items
|
|
132
162
|
*/
|
|
@@ -162,17 +192,15 @@ export declare class AsyncQueuer<TValue> {
|
|
|
162
192
|
/**
|
|
163
193
|
* Adds a task to the queuer
|
|
164
194
|
*/
|
|
165
|
-
addItem(fn:
|
|
166
|
-
priority?: number;
|
|
167
|
-
}, position?: QueuePosition, runOnItemsChange?: boolean): Promise<TValue>;
|
|
195
|
+
addItem(fn: TFn, position?: QueuePosition, runOnItemsChange?: boolean): void;
|
|
168
196
|
/**
|
|
169
197
|
* Removes and returns an item from the queuer
|
|
170
198
|
*/
|
|
171
|
-
getNextItem(position?: QueuePosition):
|
|
199
|
+
getNextItem(position?: QueuePosition): TFn | undefined;
|
|
172
200
|
/**
|
|
173
201
|
* Returns an item without removing it
|
|
174
202
|
*/
|
|
175
|
-
getPeek(position?: QueuePosition):
|
|
203
|
+
getPeek(position?: QueuePosition): TFn | undefined;
|
|
176
204
|
/**
|
|
177
205
|
* Returns true if the queuer is empty
|
|
178
206
|
*/
|
|
@@ -188,19 +216,27 @@ export declare class AsyncQueuer<TValue> {
|
|
|
188
216
|
/**
|
|
189
217
|
* Returns a copy of all items in the queuer
|
|
190
218
|
*/
|
|
191
|
-
getAllItems(): Array<
|
|
219
|
+
getAllItems(): Array<TFn>;
|
|
192
220
|
/**
|
|
193
221
|
* Returns the active items
|
|
194
222
|
*/
|
|
195
|
-
getActiveItems(): Array<
|
|
223
|
+
getActiveItems(): Array<TFn>;
|
|
196
224
|
/**
|
|
197
225
|
* Returns the pending items
|
|
198
226
|
*/
|
|
199
|
-
getPendingItems(): Array<
|
|
227
|
+
getPendingItems(): Array<TFn>;
|
|
228
|
+
/**
|
|
229
|
+
* Returns the number of items that have been successfully processed
|
|
230
|
+
*/
|
|
231
|
+
getSuccessCount(): number;
|
|
200
232
|
/**
|
|
201
|
-
* Returns the number of items that have
|
|
233
|
+
* Returns the number of items that have failed processing
|
|
202
234
|
*/
|
|
203
|
-
|
|
235
|
+
getErrorCount(): number;
|
|
236
|
+
/**
|
|
237
|
+
* Returns the number of items that have completed processing (success or error)
|
|
238
|
+
*/
|
|
239
|
+
getSettledCount(): number;
|
|
204
240
|
/**
|
|
205
241
|
* Returns the number of items that have been rejected from the queuer
|
|
206
242
|
*/
|
|
@@ -213,18 +249,6 @@ export declare class AsyncQueuer<TValue> {
|
|
|
213
249
|
* Returns true if the queuer is running but has no items to process
|
|
214
250
|
*/
|
|
215
251
|
getIsIdle(): boolean;
|
|
216
|
-
/**
|
|
217
|
-
* Adds a callback to be called when a task succeeds
|
|
218
|
-
*/
|
|
219
|
-
onSuccess(cb: (result: TValue) => void): () => void;
|
|
220
|
-
/**
|
|
221
|
-
* Adds a callback to be called when a task errors
|
|
222
|
-
*/
|
|
223
|
-
onError(cb: (error: Error) => void): () => void;
|
|
224
|
-
/**
|
|
225
|
-
* Adds a callback to be called when a task is settled
|
|
226
|
-
*/
|
|
227
|
-
onSettled(cb: (result: TValue | Error) => void): () => void;
|
|
228
252
|
/**
|
|
229
253
|
* Returns the number of items that have expired from the queuer
|
|
230
254
|
*/
|
|
@@ -234,6 +258,13 @@ export declare class AsyncQueuer<TValue> {
|
|
|
234
258
|
* Creates a new AsyncQueuer instance with the given options and returns a bound addItem function.
|
|
235
259
|
* The queuer is automatically started and ready to process items.
|
|
236
260
|
*
|
|
261
|
+
* Error Handling:
|
|
262
|
+
* - If an `onError` handler is provided, it will be called with the error and queuer instance
|
|
263
|
+
* - If `throwOnError` is true (default when no onError handler is provided), the error will be thrown
|
|
264
|
+
* - If `throwOnError` is false (default when onError handler is provided), the error will be swallowed
|
|
265
|
+
* - Both onError and throwOnError can be used together - the handler will be called before any error is thrown
|
|
266
|
+
* - The error state can be checked using the underlying AsyncQueuer instance
|
|
267
|
+
*
|
|
237
268
|
* @example
|
|
238
269
|
* ```ts
|
|
239
270
|
* const enqueue = asyncQueue<string>();
|
|
@@ -247,6 +278,4 @@ export declare class AsyncQueuer<TValue> {
|
|
|
247
278
|
* @param options - Configuration options for the AsyncQueuer
|
|
248
279
|
* @returns A bound addItem function that can be used to add tasks to the queuer
|
|
249
280
|
*/
|
|
250
|
-
export declare function asyncQueue<
|
|
251
|
-
priority?: number;
|
|
252
|
-
}, position?: QueuePosition, runOnItemsChange?: boolean) => Promise<TValue>;
|
|
281
|
+
export declare function asyncQueue<TFn extends AsyncQueuerFn>(options: AsyncQueuerOptions<TFn>): (fn: TFn, position?: QueuePosition, runOnItemsChange?: boolean) => void;
|
package/dist/esm/async-queuer.js
CHANGED
|
@@ -8,32 +8,25 @@ const defaultOptions = {
|
|
|
8
8
|
getPriority: (item) => (item == null ? void 0 : item.priority) ?? 0,
|
|
9
9
|
initialItems: [],
|
|
10
10
|
maxSize: Infinity,
|
|
11
|
-
onGetNextItem: () => {
|
|
12
|
-
},
|
|
13
|
-
onIsRunningChange: () => {
|
|
14
|
-
},
|
|
15
|
-
onItemsChange: () => {
|
|
16
|
-
},
|
|
17
|
-
onReject: () => {
|
|
18
|
-
},
|
|
19
|
-
onExpire: () => {
|
|
20
|
-
},
|
|
21
11
|
started: true,
|
|
22
12
|
wait: 0
|
|
23
13
|
};
|
|
24
14
|
class AsyncQueuer {
|
|
25
15
|
constructor(initialOptions = defaultOptions) {
|
|
26
16
|
this._activeItems = /* @__PURE__ */ new Set();
|
|
27
|
-
this.
|
|
17
|
+
this._successCount = 0;
|
|
18
|
+
this._errorCount = 0;
|
|
19
|
+
this._settledCount = 0;
|
|
28
20
|
this._rejectionCount = 0;
|
|
29
21
|
this._expirationCount = 0;
|
|
30
22
|
this._items = [];
|
|
31
23
|
this._itemTimestamps = [];
|
|
32
|
-
this._onErrorCallbacks = [];
|
|
33
|
-
this._onSettledCallbacks = [];
|
|
34
|
-
this._onSuccessCallbacks = [];
|
|
35
24
|
this._pendingTick = false;
|
|
36
|
-
this._options = {
|
|
25
|
+
this._options = {
|
|
26
|
+
...defaultOptions,
|
|
27
|
+
...initialOptions,
|
|
28
|
+
throwOnError: initialOptions.throwOnError ?? !initialOptions.onError
|
|
29
|
+
};
|
|
37
30
|
this._running = this._options.started;
|
|
38
31
|
for (let i = 0; i < this._options.initialItems.length; i++) {
|
|
39
32
|
const item = this._options.initialItems[i];
|
|
@@ -70,6 +63,7 @@ class AsyncQueuer {
|
|
|
70
63
|
* Processes items in the queuer
|
|
71
64
|
*/
|
|
72
65
|
tick() {
|
|
66
|
+
var _a, _b;
|
|
73
67
|
if (!this._running) {
|
|
74
68
|
this._pendingTick = false;
|
|
75
69
|
return;
|
|
@@ -81,26 +75,28 @@ class AsyncQueuer {
|
|
|
81
75
|
break;
|
|
82
76
|
}
|
|
83
77
|
this._activeItems.add(nextFn);
|
|
84
|
-
this._options.onItemsChange(this);
|
|
78
|
+
(_b = (_a = this._options).onItemsChange) == null ? void 0 : _b.call(_a, this);
|
|
85
79
|
(async () => {
|
|
86
|
-
|
|
80
|
+
var _a2, _b2, _c, _d, _e, _f, _g, _h;
|
|
87
81
|
let res;
|
|
88
|
-
let error;
|
|
89
82
|
try {
|
|
90
83
|
res = await nextFn();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
94
|
} finally {
|
|
95
|
+
this._settledCount++;
|
|
95
96
|
this._activeItems.delete(nextFn);
|
|
96
|
-
this._options.onItemsChange(this);
|
|
97
|
-
|
|
98
|
-
if (success) {
|
|
99
|
-
this._onSuccessCallbacks.forEach((cb) => cb(res));
|
|
100
|
-
} else {
|
|
101
|
-
this._onErrorCallbacks.forEach((cb) => cb(error));
|
|
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);
|
|
102
99
|
}
|
|
103
|
-
this._onSettledCallbacks.forEach((cb) => cb(success ? res : error));
|
|
104
100
|
const wait = this.getWait();
|
|
105
101
|
if (wait > 0) {
|
|
106
102
|
setTimeout(() => this.tick(), wait);
|
|
@@ -115,6 +111,7 @@ class AsyncQueuer {
|
|
|
115
111
|
* Checks for and removes expired items from the queuer
|
|
116
112
|
*/
|
|
117
113
|
checkExpiredItems() {
|
|
114
|
+
var _a, _b, _c, _d;
|
|
118
115
|
if (this._options.expirationDuration === Infinity && this._options.getIsExpired === defaultOptions.getIsExpired)
|
|
119
116
|
return;
|
|
120
117
|
const now = Date.now();
|
|
@@ -137,22 +134,23 @@ class AsyncQueuer {
|
|
|
137
134
|
this._items.splice(index, 1);
|
|
138
135
|
this._itemTimestamps.splice(index, 1);
|
|
139
136
|
this._expirationCount++;
|
|
140
|
-
this._options.onExpire(expiredItem, this);
|
|
137
|
+
(_b = (_a = this._options).onExpire) == null ? void 0 : _b.call(_a, expiredItem, this);
|
|
141
138
|
}
|
|
142
139
|
if (expiredIndices.length > 0) {
|
|
143
|
-
this._options.onItemsChange(this);
|
|
140
|
+
(_d = (_c = this._options).onItemsChange) == null ? void 0 : _d.call(_c, this);
|
|
144
141
|
}
|
|
145
142
|
}
|
|
146
143
|
/**
|
|
147
144
|
* Starts the queuer and processes items
|
|
148
145
|
*/
|
|
149
146
|
start() {
|
|
147
|
+
var _a, _b;
|
|
150
148
|
this._running = true;
|
|
151
149
|
if (!this._pendingTick && !this.getIsEmpty()) {
|
|
152
150
|
this._pendingTick = true;
|
|
153
151
|
this.tick();
|
|
154
152
|
}
|
|
155
|
-
this._options.onIsRunningChange(this);
|
|
153
|
+
(_b = (_a = this._options).onIsRunningChange) == null ? void 0 : _b.call(_a, this);
|
|
156
154
|
return new Promise((resolve) => {
|
|
157
155
|
const checkIdle = () => {
|
|
158
156
|
if (this.getIsIdle()) {
|
|
@@ -168,23 +166,27 @@ class AsyncQueuer {
|
|
|
168
166
|
* Stops the queuer from processing items
|
|
169
167
|
*/
|
|
170
168
|
stop() {
|
|
169
|
+
var _a, _b;
|
|
171
170
|
this._running = false;
|
|
172
171
|
this._pendingTick = false;
|
|
173
|
-
this._options.onIsRunningChange(this);
|
|
172
|
+
(_b = (_a = this._options).onIsRunningChange) == null ? void 0 : _b.call(_a, this);
|
|
174
173
|
}
|
|
175
174
|
/**
|
|
176
175
|
* Removes all items from the queuer
|
|
177
176
|
*/
|
|
178
177
|
clear() {
|
|
178
|
+
var _a, _b;
|
|
179
179
|
this._items = [];
|
|
180
|
-
this._options.onItemsChange(this);
|
|
180
|
+
(_b = (_a = this._options).onItemsChange) == null ? void 0 : _b.call(_a, this);
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
183
|
* Resets the queuer to its initial state
|
|
184
184
|
*/
|
|
185
185
|
reset(withInitialItems) {
|
|
186
186
|
this.clear();
|
|
187
|
-
this.
|
|
187
|
+
this._successCount = 0;
|
|
188
|
+
this._errorCount = 0;
|
|
189
|
+
this._settledCount = 0;
|
|
188
190
|
if (withInitialItems) {
|
|
189
191
|
this._items = [...this._options.initialItems];
|
|
190
192
|
}
|
|
@@ -194,60 +196,47 @@ class AsyncQueuer {
|
|
|
194
196
|
* Adds a task to the queuer
|
|
195
197
|
*/
|
|
196
198
|
addItem(fn, position = this._options.addItemsTo, runOnItemsChange = true) {
|
|
199
|
+
var _a, _b, _c, _d;
|
|
197
200
|
if (this.getIsFull()) {
|
|
198
201
|
this._rejectionCount++;
|
|
199
|
-
this._options.onReject(fn, this);
|
|
200
|
-
return
|
|
202
|
+
(_b = (_a = this._options).onReject) == null ? void 0 : _b.call(_a, fn, this);
|
|
203
|
+
return;
|
|
201
204
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
throw error;
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
{ priority: fn.priority ?? void 0 }
|
|
215
|
-
);
|
|
216
|
-
const priority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(task) : task.priority;
|
|
217
|
-
if (priority !== void 0) {
|
|
218
|
-
const insertIndex = this._items.findIndex((existing) => {
|
|
219
|
-
const existingPriority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(existing) : existing.priority;
|
|
220
|
-
return existingPriority > priority;
|
|
221
|
-
});
|
|
222
|
-
if (insertIndex === -1) {
|
|
223
|
-
this._items.push(task);
|
|
224
|
-
this._itemTimestamps.push(Date.now());
|
|
225
|
-
} else {
|
|
226
|
-
this._items.splice(insertIndex, 0, task);
|
|
227
|
-
this._itemTimestamps.splice(insertIndex, 0, Date.now());
|
|
228
|
-
}
|
|
205
|
+
const priority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(fn) : fn.priority;
|
|
206
|
+
if (priority !== void 0) {
|
|
207
|
+
const insertIndex = this._items.findIndex((existing) => {
|
|
208
|
+
const existingPriority = this._options.getPriority !== defaultOptions.getPriority ? this._options.getPriority(existing) : existing.priority;
|
|
209
|
+
return existingPriority > priority;
|
|
210
|
+
});
|
|
211
|
+
if (insertIndex === -1) {
|
|
212
|
+
this._items.push(fn);
|
|
213
|
+
this._itemTimestamps.push(Date.now());
|
|
229
214
|
} else {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this._itemTimestamps.unshift(Date.now());
|
|
233
|
-
} else {
|
|
234
|
-
this._items.push(task);
|
|
235
|
-
this._itemTimestamps.push(Date.now());
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if (runOnItemsChange) {
|
|
239
|
-
this._options.onItemsChange(this);
|
|
215
|
+
this._items.splice(insertIndex, 0, fn);
|
|
216
|
+
this._itemTimestamps.splice(insertIndex, 0, Date.now());
|
|
240
217
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
this.
|
|
218
|
+
} else {
|
|
219
|
+
if (position === "front") {
|
|
220
|
+
this._items.unshift(fn);
|
|
221
|
+
this._itemTimestamps.unshift(Date.now());
|
|
222
|
+
} else {
|
|
223
|
+
this._items.push(fn);
|
|
224
|
+
this._itemTimestamps.push(Date.now());
|
|
244
225
|
}
|
|
245
|
-
}
|
|
226
|
+
}
|
|
227
|
+
if (runOnItemsChange) {
|
|
228
|
+
(_d = (_c = this._options).onItemsChange) == null ? void 0 : _d.call(_c, this);
|
|
229
|
+
}
|
|
230
|
+
if (this._running && !this._pendingTick) {
|
|
231
|
+
this._pendingTick = true;
|
|
232
|
+
this.tick();
|
|
233
|
+
}
|
|
246
234
|
}
|
|
247
235
|
/**
|
|
248
236
|
* Removes and returns an item from the queuer
|
|
249
237
|
*/
|
|
250
238
|
getNextItem(position = this._options.getItemsFrom) {
|
|
239
|
+
var _a, _b, _c, _d;
|
|
251
240
|
let item;
|
|
252
241
|
if (position === "front") {
|
|
253
242
|
item = this._items.shift();
|
|
@@ -257,9 +246,8 @@ class AsyncQueuer {
|
|
|
257
246
|
this._itemTimestamps.pop();
|
|
258
247
|
}
|
|
259
248
|
if (item !== void 0) {
|
|
260
|
-
this.
|
|
261
|
-
this._options.
|
|
262
|
-
this._options.onGetNextItem(item, this);
|
|
249
|
+
(_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);
|
|
263
251
|
}
|
|
264
252
|
return item;
|
|
265
253
|
}
|
|
@@ -309,10 +297,22 @@ class AsyncQueuer {
|
|
|
309
297
|
return [...this._items];
|
|
310
298
|
}
|
|
311
299
|
/**
|
|
312
|
-
* Returns the number of items that have been
|
|
300
|
+
* Returns the number of items that have been successfully processed
|
|
301
|
+
*/
|
|
302
|
+
getSuccessCount() {
|
|
303
|
+
return this._successCount;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Returns the number of items that have failed processing
|
|
313
307
|
*/
|
|
314
|
-
|
|
315
|
-
return this.
|
|
308
|
+
getErrorCount() {
|
|
309
|
+
return this._errorCount;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Returns the number of items that have completed processing (success or error)
|
|
313
|
+
*/
|
|
314
|
+
getSettledCount() {
|
|
315
|
+
return this._settledCount;
|
|
316
316
|
}
|
|
317
317
|
/**
|
|
318
318
|
* Returns the number of items that have been rejected from the queuer
|
|
@@ -332,37 +332,6 @@ class AsyncQueuer {
|
|
|
332
332
|
getIsIdle() {
|
|
333
333
|
return this._running && this.getIsEmpty() && this._activeItems.size === 0;
|
|
334
334
|
}
|
|
335
|
-
/**
|
|
336
|
-
* Adds a callback to be called when a task succeeds
|
|
337
|
-
*/
|
|
338
|
-
onSuccess(cb) {
|
|
339
|
-
this._onSuccessCallbacks.push(cb);
|
|
340
|
-
return () => {
|
|
341
|
-
this._onSuccessCallbacks = this._onSuccessCallbacks.filter(
|
|
342
|
-
(d) => d !== cb
|
|
343
|
-
);
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
/**
|
|
347
|
-
* Adds a callback to be called when a task errors
|
|
348
|
-
*/
|
|
349
|
-
onError(cb) {
|
|
350
|
-
this._onErrorCallbacks.push(cb);
|
|
351
|
-
return () => {
|
|
352
|
-
this._onErrorCallbacks = this._onErrorCallbacks.filter((d) => d !== cb);
|
|
353
|
-
};
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Adds a callback to be called when a task is settled
|
|
357
|
-
*/
|
|
358
|
-
onSettled(cb) {
|
|
359
|
-
this._onSettledCallbacks.push(cb);
|
|
360
|
-
return () => {
|
|
361
|
-
this._onSettledCallbacks = this._onSettledCallbacks.filter(
|
|
362
|
-
(d) => d !== cb
|
|
363
|
-
);
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
335
|
/**
|
|
367
336
|
* Returns the number of items that have expired from the queuer
|
|
368
337
|
*/
|