@tanstack/pacer-lite 0.2.2 → 0.3.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/README.md +21 -6
- package/dist/lite-batcher.d.ts +4 -6
- package/dist/lite-batcher.js +72 -45
- package/dist/lite-debouncer.d.ts +4 -7
- package/dist/lite-debouncer.js +58 -40
- package/dist/lite-queuer.d.ts +5 -7
- package/dist/lite-queuer.js +170 -89
- package/dist/lite-rate-limiter.d.ts +4 -7
- package/dist/lite-rate-limiter.js +89 -63
- package/dist/lite-throttler.d.ts +4 -7
- package/dist/lite-throttler.js +63 -40
- package/dist/pacer/dist/types.d.ts +2 -7
- package/package.json +13 -33
- package/dist/index.cjs +0 -17
- package/dist/index.d.cts +0 -6
- package/dist/lite-batcher.cjs +0 -176
- package/dist/lite-batcher.cjs.map +0 -1
- package/dist/lite-batcher.d.cts +0 -184
- package/dist/lite-batcher.js.map +0 -1
- package/dist/lite-debouncer.cjs +0 -126
- package/dist/lite-debouncer.cjs.map +0 -1
- package/dist/lite-debouncer.d.cts +0 -126
- package/dist/lite-debouncer.js.map +0 -1
- package/dist/lite-queuer.cjs +0 -209
- package/dist/lite-queuer.cjs.map +0 -1
- package/dist/lite-queuer.d.cts +0 -243
- package/dist/lite-queuer.js.map +0 -1
- package/dist/lite-rate-limiter.cjs +0 -150
- package/dist/lite-rate-limiter.cjs.map +0 -1
- package/dist/lite-rate-limiter.d.cts +0 -148
- package/dist/lite-rate-limiter.js.map +0 -1
- package/dist/lite-throttler.cjs +0 -128
- package/dist/lite-throttler.cjs.map +0 -1
- package/dist/lite-throttler.d.cts +0 -133
- package/dist/lite-throttler.js.map +0 -1
- package/dist/pacer/dist/types.d.cts +0 -12
- package/src/index.ts +0 -5
- package/src/lite-batcher.ts +0 -267
- package/src/lite-debouncer.ts +0 -184
- package/src/lite-queuer.ts +0 -434
- package/src/lite-rate-limiter.ts +0 -246
- package/src/lite-throttler.ts +0 -195
package/README.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
<div align="center">
|
|
2
|
-
<
|
|
2
|
+
<picture>
|
|
3
|
+
<source
|
|
4
|
+
media="(prefers-color-scheme: dark)"
|
|
5
|
+
srcset="https://tanstack.com/api/readme/pacer.png?theme=dark"
|
|
6
|
+
/>
|
|
7
|
+
<source
|
|
8
|
+
media="(prefers-color-scheme: light)"
|
|
9
|
+
srcset="https://tanstack.com/api/readme/pacer.png"
|
|
10
|
+
/>
|
|
11
|
+
<img
|
|
12
|
+
src="https://tanstack.com/api/readme/pacer.png"
|
|
13
|
+
alt="TanStack Pacer"
|
|
14
|
+
width="900"
|
|
15
|
+
/>
|
|
16
|
+
</picture>
|
|
3
17
|
</div>
|
|
4
18
|
|
|
5
19
|
<br />
|
|
@@ -29,8 +43,9 @@
|
|
|
29
43
|
</div>
|
|
30
44
|
|
|
31
45
|
<div align="center">
|
|
32
|
-
|
|
46
|
+
|
|
33
47
|
### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
|
|
48
|
+
|
|
34
49
|
</div>
|
|
35
50
|
|
|
36
51
|
# TanStack Pacer
|
|
@@ -88,10 +103,10 @@ A lightweight timing and scheduling library for debouncing, throttling, rate lim
|
|
|
88
103
|
> [!NOTE]
|
|
89
104
|
> You may know **TanStack Pacer** by our adapter names, too!
|
|
90
105
|
>
|
|
91
|
-
> - [**React Pacer**](https://tanstack.com/pacer/latest/docs/framework/react
|
|
92
|
-
> - [**Preact Pacer**](https://tanstack.com/pacer/latest/docs/framework/preact
|
|
93
|
-
> - [**Solid Pacer**](https://tanstack.com/pacer/latest/docs/framework/solid
|
|
94
|
-
> - [**Angular Pacer**](https://tanstack.com/pacer/latest/docs/framework/angular
|
|
106
|
+
> - [**React Pacer**](https://tanstack.com/pacer/latest/docs/framework/react)
|
|
107
|
+
> - [**Preact Pacer**](https://tanstack.com/pacer/latest/docs/framework/preact)
|
|
108
|
+
> - [**Solid Pacer**](https://tanstack.com/pacer/latest/docs/framework/solid)
|
|
109
|
+
> - [**Angular Pacer**](https://tanstack.com/pacer/latest/docs/framework/angular)
|
|
95
110
|
> - Svelte Pacer - needs a contributor!
|
|
96
111
|
> - Vue Pacer - needs a contributor!
|
|
97
112
|
|
package/dist/lite-batcher.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* Options for configuring a lite batcher instance
|
|
4
4
|
*/
|
|
5
|
-
interface LiteBatcherOptions<TValue> {
|
|
5
|
+
export interface LiteBatcherOptions<TValue> {
|
|
6
6
|
/**
|
|
7
7
|
* Custom function to determine if a batch should be processed
|
|
8
8
|
* Return true to process the batch immediately
|
|
@@ -103,7 +103,7 @@ interface LiteBatcherOptions<TValue> {
|
|
|
103
103
|
* batcher.addItem({ name: 'urgent', urgent: true }); // Triggers immediate processing
|
|
104
104
|
* ```
|
|
105
105
|
*/
|
|
106
|
-
declare class LiteBatcher<TValue> {
|
|
106
|
+
export declare class LiteBatcher<TValue> {
|
|
107
107
|
fn: (items: Array<TValue>) => void;
|
|
108
108
|
options: LiteBatcherOptions<TValue>;
|
|
109
109
|
private items;
|
|
@@ -178,7 +178,5 @@ declare class LiteBatcher<TValue> {
|
|
|
178
178
|
* batchItems(3); // Triggers batch processing
|
|
179
179
|
* ```
|
|
180
180
|
*/
|
|
181
|
-
declare function liteBatch<TValue>(fn: (items: Array<TValue>) => void, options?: LiteBatcherOptions<TValue>): (item: TValue) => void;
|
|
182
|
-
//#endregion
|
|
183
|
-
export { LiteBatcher, LiteBatcherOptions, liteBatch };
|
|
184
|
-
//# sourceMappingURL=lite-batcher.d.ts.map
|
|
181
|
+
export declare function liteBatch<TValue>(fn: (items: Array<TValue>) => void, options?: LiteBatcherOptions<TValue>): (item: TValue) => void;
|
|
182
|
+
//#endregion
|
package/dist/lite-batcher.js
CHANGED
|
@@ -69,52 +69,14 @@
|
|
|
69
69
|
* ```
|
|
70
70
|
*/
|
|
71
71
|
var LiteBatcher = class {
|
|
72
|
+
fn;
|
|
73
|
+
options;
|
|
74
|
+
items = [];
|
|
75
|
+
timeoutId = null;
|
|
76
|
+
_isPending = false;
|
|
72
77
|
constructor(fn, options = {}) {
|
|
73
78
|
this.fn = fn;
|
|
74
79
|
this.options = options;
|
|
75
|
-
this.items = [];
|
|
76
|
-
this.timeoutId = null;
|
|
77
|
-
this._isPending = false;
|
|
78
|
-
this.addItem = (item) => {
|
|
79
|
-
this.items.push(item);
|
|
80
|
-
this._isPending = this.options.wait !== Infinity;
|
|
81
|
-
this.options.onItemsChange?.(this);
|
|
82
|
-
if (this.items.length >= this.options.maxSize || this.options.getShouldExecute(this.items, this)) this.execute();
|
|
83
|
-
else if (this.options.wait !== Infinity) {
|
|
84
|
-
this.clearTimeout();
|
|
85
|
-
this.timeoutId = setTimeout(() => this.execute(), this.getWait());
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
this.execute = () => {
|
|
89
|
-
if (this.items.length === 0) return;
|
|
90
|
-
const batch = this.peekAllItems();
|
|
91
|
-
this.clear();
|
|
92
|
-
this.fn(batch);
|
|
93
|
-
this.options.onExecute?.(batch, this);
|
|
94
|
-
};
|
|
95
|
-
this.flush = () => {
|
|
96
|
-
this.clearTimeout();
|
|
97
|
-
this.execute();
|
|
98
|
-
};
|
|
99
|
-
this.peekAllItems = () => {
|
|
100
|
-
return [...this.items];
|
|
101
|
-
};
|
|
102
|
-
this.clearTimeout = () => {
|
|
103
|
-
if (this.timeoutId) {
|
|
104
|
-
clearTimeout(this.timeoutId);
|
|
105
|
-
this.timeoutId = null;
|
|
106
|
-
}
|
|
107
|
-
};
|
|
108
|
-
this.clear = () => {
|
|
109
|
-
const hadItems = this.items.length > 0;
|
|
110
|
-
this.items = [];
|
|
111
|
-
this._isPending = false;
|
|
112
|
-
if (hadItems) this.options.onItemsChange?.(this);
|
|
113
|
-
};
|
|
114
|
-
this.cancel = () => {
|
|
115
|
-
this.clearTimeout();
|
|
116
|
-
this._isPending = false;
|
|
117
|
-
};
|
|
118
80
|
this.options.maxSize = this.options.maxSize ?? Infinity;
|
|
119
81
|
this.options.started = this.options.started ?? true;
|
|
120
82
|
this.options.wait = this.options.wait ?? Infinity;
|
|
@@ -142,6 +104,72 @@ var LiteBatcher = class {
|
|
|
142
104
|
if (typeof this.options.wait === "function") return this.options.wait(this);
|
|
143
105
|
return this.options.wait;
|
|
144
106
|
}
|
|
107
|
+
/**
|
|
108
|
+
* Adds an item to the batcher
|
|
109
|
+
* If the batch size is reached, timeout occurs, or getShouldExecute returns true, the batch will be processed
|
|
110
|
+
*/
|
|
111
|
+
addItem = (item) => {
|
|
112
|
+
this.items.push(item);
|
|
113
|
+
this._isPending = this.options.wait !== Infinity;
|
|
114
|
+
this.options.onItemsChange?.(this);
|
|
115
|
+
if (this.items.length >= this.options.maxSize || this.options.getShouldExecute(this.items, this)) this.execute();
|
|
116
|
+
else if (this.options.wait !== Infinity) {
|
|
117
|
+
this.clearTimeout();
|
|
118
|
+
this.timeoutId = setTimeout(() => this.execute(), this.getWait());
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
/**
|
|
122
|
+
* Processes the current batch of items.
|
|
123
|
+
* This method will automatically be triggered if the batcher is running and any of these conditions are met:
|
|
124
|
+
* - The number of items reaches maxSize
|
|
125
|
+
* - The wait duration has elapsed
|
|
126
|
+
* - The getShouldExecute function returns true upon adding an item
|
|
127
|
+
*
|
|
128
|
+
* You can also call this method manually to process the current batch at any time.
|
|
129
|
+
*/
|
|
130
|
+
execute = () => {
|
|
131
|
+
if (this.items.length === 0) return;
|
|
132
|
+
const batch = this.peekAllItems();
|
|
133
|
+
this.clear();
|
|
134
|
+
this.fn(batch);
|
|
135
|
+
this.options.onExecute?.(batch, this);
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Processes the current batch of items immediately
|
|
139
|
+
*/
|
|
140
|
+
flush = () => {
|
|
141
|
+
this.clearTimeout();
|
|
142
|
+
this.execute();
|
|
143
|
+
};
|
|
144
|
+
/**
|
|
145
|
+
* Returns a copy of all items in the batcher
|
|
146
|
+
*/
|
|
147
|
+
peekAllItems = () => {
|
|
148
|
+
return [...this.items];
|
|
149
|
+
};
|
|
150
|
+
clearTimeout = () => {
|
|
151
|
+
if (this.timeoutId) {
|
|
152
|
+
clearTimeout(this.timeoutId);
|
|
153
|
+
this.timeoutId = null;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Removes all items from the batcher
|
|
158
|
+
*/
|
|
159
|
+
clear = () => {
|
|
160
|
+
const hadItems = this.items.length > 0;
|
|
161
|
+
this.items = [];
|
|
162
|
+
this._isPending = false;
|
|
163
|
+
if (hadItems) this.options.onItemsChange?.(this);
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* Cancels any pending execution that was scheduled.
|
|
167
|
+
* Does NOT clear out the items.
|
|
168
|
+
*/
|
|
169
|
+
cancel = () => {
|
|
170
|
+
this.clearTimeout();
|
|
171
|
+
this._isPending = false;
|
|
172
|
+
};
|
|
145
173
|
};
|
|
146
174
|
/**
|
|
147
175
|
* Creates a batcher that processes items in batches.
|
|
@@ -169,5 +197,4 @@ function liteBatch(fn, options = {}) {
|
|
|
169
197
|
}
|
|
170
198
|
|
|
171
199
|
//#endregion
|
|
172
|
-
export { LiteBatcher, liteBatch };
|
|
173
|
-
//# sourceMappingURL=lite-batcher.js.map
|
|
200
|
+
export { LiteBatcher, liteBatch };
|
package/dist/lite-debouncer.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { AnyFunction } from "./pacer/dist/types.js";
|
|
2
|
-
|
|
3
2
|
//#region src/lite-debouncer.d.ts
|
|
4
3
|
/**
|
|
5
4
|
* Options for configuring a lite debounced function
|
|
6
5
|
*/
|
|
7
|
-
interface LiteDebouncerOptions<TFn extends AnyFunction = AnyFunction> {
|
|
6
|
+
export interface LiteDebouncerOptions<TFn extends AnyFunction = AnyFunction> {
|
|
8
7
|
/**
|
|
9
8
|
* Whether to execute on the leading edge of the timeout.
|
|
10
9
|
* The first call will execute immediately and the rest will wait the delay.
|
|
@@ -65,7 +64,7 @@ interface LiteDebouncerOptions<TFn extends AnyFunction = AnyFunction> {
|
|
|
65
64
|
* });
|
|
66
65
|
* ```
|
|
67
66
|
*/
|
|
68
|
-
declare class LiteDebouncer<TFn extends AnyFunction> {
|
|
67
|
+
export declare class LiteDebouncer<TFn extends AnyFunction> {
|
|
69
68
|
fn: TFn;
|
|
70
69
|
options: LiteDebouncerOptions<TFn>;
|
|
71
70
|
private timeoutId;
|
|
@@ -120,7 +119,5 @@ declare class LiteDebouncer<TFn extends AnyFunction> {
|
|
|
120
119
|
* }, { wait: 300, leading: true });
|
|
121
120
|
* ```
|
|
122
121
|
*/
|
|
123
|
-
declare function liteDebounce<TFn extends AnyFunction>(fn: TFn, options: LiteDebouncerOptions<TFn>): (...args: Parameters<TFn>) => void;
|
|
124
|
-
//#endregion
|
|
125
|
-
export { LiteDebouncer, LiteDebouncerOptions, liteDebounce };
|
|
126
|
-
//# sourceMappingURL=lite-debouncer.d.ts.map
|
|
122
|
+
export declare function liteDebounce<TFn extends AnyFunction>(fn: TFn, options: LiteDebouncerOptions<TFn>): (...args: Parameters<TFn>) => void;
|
|
123
|
+
//#endregion
|
package/dist/lite-debouncer.js
CHANGED
|
@@ -40,50 +40,69 @@
|
|
|
40
40
|
* ```
|
|
41
41
|
*/
|
|
42
42
|
var LiteDebouncer = class {
|
|
43
|
+
fn;
|
|
44
|
+
options;
|
|
45
|
+
timeoutId;
|
|
46
|
+
lastArgs;
|
|
47
|
+
canLeadingExecute = true;
|
|
43
48
|
constructor(fn, options) {
|
|
44
49
|
this.fn = fn;
|
|
45
50
|
this.options = options;
|
|
46
|
-
this.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
this.
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
this.timeoutId = void 0;
|
|
70
|
-
const args = this.lastArgs;
|
|
71
|
-
this.fn(...args);
|
|
72
|
-
this.options.onExecute?.(args, this);
|
|
73
|
-
this.lastArgs = void 0;
|
|
74
|
-
this.canLeadingExecute = true;
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
this.cancel = () => {
|
|
78
|
-
if (this.timeoutId) {
|
|
79
|
-
clearTimeout(this.timeoutId);
|
|
80
|
-
this.timeoutId = void 0;
|
|
51
|
+
if (this.options.leading === void 0 && this.options.trailing === void 0) this.options.trailing = true;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Attempts to execute the debounced function.
|
|
55
|
+
* If leading is true and this is the first call, executes immediately.
|
|
56
|
+
* Otherwise, queues the execution for after the wait time.
|
|
57
|
+
* Each new call resets the timer.
|
|
58
|
+
*/
|
|
59
|
+
maybeExecute = (...args) => {
|
|
60
|
+
let didLeadingExecute = false;
|
|
61
|
+
if (this.options.leading && this.canLeadingExecute) {
|
|
62
|
+
this.canLeadingExecute = false;
|
|
63
|
+
didLeadingExecute = true;
|
|
64
|
+
this.fn(...args);
|
|
65
|
+
this.options.onExecute?.(args, this);
|
|
66
|
+
}
|
|
67
|
+
this.lastArgs = args;
|
|
68
|
+
if (this.timeoutId) clearTimeout(this.timeoutId);
|
|
69
|
+
this.timeoutId = setTimeout(() => {
|
|
70
|
+
this.canLeadingExecute = true;
|
|
71
|
+
if (this.options.trailing && !didLeadingExecute && this.lastArgs) {
|
|
72
|
+
this.fn(...this.lastArgs);
|
|
73
|
+
this.options.onExecute?.(this.lastArgs, this);
|
|
81
74
|
}
|
|
82
75
|
this.lastArgs = void 0;
|
|
76
|
+
}, this.options.wait);
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Processes the current pending execution immediately.
|
|
80
|
+
* If there's a pending execution, it will be executed right away
|
|
81
|
+
* and the timeout will be cleared.
|
|
82
|
+
*/
|
|
83
|
+
flush = () => {
|
|
84
|
+
if (this.timeoutId && this.lastArgs) {
|
|
85
|
+
clearTimeout(this.timeoutId);
|
|
86
|
+
this.timeoutId = void 0;
|
|
87
|
+
const args = this.lastArgs;
|
|
88
|
+
this.fn(...args);
|
|
89
|
+
this.options.onExecute?.(args, this);
|
|
90
|
+
this.lastArgs = void 0;
|
|
83
91
|
this.canLeadingExecute = true;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Cancels any pending execution.
|
|
96
|
+
* Clears the timeout and resets the internal state.
|
|
97
|
+
*/
|
|
98
|
+
cancel = () => {
|
|
99
|
+
if (this.timeoutId) {
|
|
100
|
+
clearTimeout(this.timeoutId);
|
|
101
|
+
this.timeoutId = void 0;
|
|
102
|
+
}
|
|
103
|
+
this.lastArgs = void 0;
|
|
104
|
+
this.canLeadingExecute = true;
|
|
105
|
+
};
|
|
87
106
|
};
|
|
88
107
|
/**
|
|
89
108
|
* Creates a lightweight debounced function that delays invoking the provided function until after a specified wait time.
|
|
@@ -119,5 +138,4 @@ function liteDebounce(fn, options) {
|
|
|
119
138
|
}
|
|
120
139
|
|
|
121
140
|
//#endregion
|
|
122
|
-
export { LiteDebouncer, liteDebounce };
|
|
123
|
-
//# sourceMappingURL=lite-debouncer.js.map
|
|
141
|
+
export { LiteDebouncer, liteDebounce };
|
package/dist/lite-queuer.d.ts
CHANGED
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* - 'front': Operate on the front of the queue (FIFO for getNextItem)
|
|
6
6
|
* - 'back': Operate on the back of the queue (LIFO for getNextItem)
|
|
7
7
|
*/
|
|
8
|
-
type QueuePosition = 'front' | 'back';
|
|
8
|
+
export type QueuePosition = 'front' | 'back';
|
|
9
9
|
/**
|
|
10
10
|
* Options for configuring a lite queuer instance
|
|
11
11
|
*/
|
|
12
|
-
interface LiteQueuerOptions<TValue> {
|
|
12
|
+
export interface LiteQueuerOptions<TValue> {
|
|
13
13
|
/**
|
|
14
14
|
* Default position to add items to the queue
|
|
15
15
|
* @default 'back'
|
|
@@ -105,7 +105,7 @@ interface LiteQueuerOptions<TValue> {
|
|
|
105
105
|
* // Processes high priority task first
|
|
106
106
|
* ```
|
|
107
107
|
*/
|
|
108
|
-
declare class LiteQueuer<TValue> {
|
|
108
|
+
export declare class LiteQueuer<TValue> {
|
|
109
109
|
fn: (item: TValue) => void;
|
|
110
110
|
options: LiteQueuerOptions<TValue>;
|
|
111
111
|
private items;
|
|
@@ -237,7 +237,5 @@ declare class LiteQueuer<TValue> {
|
|
|
237
237
|
* // Processes each item with 1 second delay between them
|
|
238
238
|
* ```
|
|
239
239
|
*/
|
|
240
|
-
declare function liteQueue<TValue>(fn: (item: TValue) => void, options?: LiteQueuerOptions<TValue>): (item: TValue) => boolean;
|
|
241
|
-
//#endregion
|
|
242
|
-
export { LiteQueuer, LiteQueuerOptions, QueuePosition, liteQueue };
|
|
243
|
-
//# sourceMappingURL=lite-queuer.d.ts.map
|
|
240
|
+
export declare function liteQueue<TValue>(fn: (item: TValue) => void, options?: LiteQueuerOptions<TValue>): (item: TValue) => boolean;
|
|
241
|
+
//#endregion
|
package/dist/lite-queuer.js
CHANGED
|
@@ -60,96 +60,15 @@
|
|
|
60
60
|
* ```
|
|
61
61
|
*/
|
|
62
62
|
var LiteQueuer = class {
|
|
63
|
+
fn;
|
|
64
|
+
options;
|
|
65
|
+
items = [];
|
|
66
|
+
timeoutId = null;
|
|
67
|
+
isRunning = true;
|
|
68
|
+
pendingTick = false;
|
|
63
69
|
constructor(fn, options = {}) {
|
|
64
70
|
this.fn = fn;
|
|
65
71
|
this.options = options;
|
|
66
|
-
this.items = [];
|
|
67
|
-
this.timeoutId = null;
|
|
68
|
-
this.isRunning = true;
|
|
69
|
-
this.pendingTick = false;
|
|
70
|
-
this.addItem = (item, position = this.options.addItemsTo, startProcessing = true) => {
|
|
71
|
-
if (this.items.length >= this.options.maxSize) return false;
|
|
72
|
-
if (this.options.getPriority) {
|
|
73
|
-
const priority = this.options.getPriority(item);
|
|
74
|
-
if (priority !== void 0) {
|
|
75
|
-
const insertIndex = this.items.findIndex((existing) => {
|
|
76
|
-
return (this.options.getPriority(existing) ?? -Infinity) < priority;
|
|
77
|
-
});
|
|
78
|
-
if (insertIndex === -1) this.items.push(item);
|
|
79
|
-
else this.items.splice(insertIndex, 0, item);
|
|
80
|
-
} else this.insertAtPosition(item, position);
|
|
81
|
-
} else this.insertAtPosition(item, position);
|
|
82
|
-
if (startProcessing && this.isRunning && !this.pendingTick) this.tick();
|
|
83
|
-
return true;
|
|
84
|
-
};
|
|
85
|
-
this.insertAtPosition = (item, position) => {
|
|
86
|
-
if (position === "front") this.items.unshift(item);
|
|
87
|
-
else this.items.push(item);
|
|
88
|
-
};
|
|
89
|
-
this.getNextItem = (position = this.options.getItemsFrom) => {
|
|
90
|
-
if (this.items.length === 0) return;
|
|
91
|
-
let item;
|
|
92
|
-
if (this.options.getPriority || position === "front") item = this.items.shift();
|
|
93
|
-
else item = this.items.pop();
|
|
94
|
-
return item;
|
|
95
|
-
};
|
|
96
|
-
this.execute = (position) => {
|
|
97
|
-
const item = this.getNextItem(position);
|
|
98
|
-
if (item !== void 0) this.fn(item);
|
|
99
|
-
return item;
|
|
100
|
-
};
|
|
101
|
-
this.tick = () => {
|
|
102
|
-
if (!this.isRunning) {
|
|
103
|
-
this.pendingTick = false;
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.pendingTick = true;
|
|
107
|
-
while (this.items.length > 0) {
|
|
108
|
-
if (this.execute(this.options.getItemsFrom) === void 0) break;
|
|
109
|
-
const wait = this.options.wait;
|
|
110
|
-
if (wait > 0) {
|
|
111
|
-
this.timeoutId = setTimeout(() => this.tick(), wait);
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
this.pendingTick = false;
|
|
116
|
-
};
|
|
117
|
-
this.start = () => {
|
|
118
|
-
this.isRunning = true;
|
|
119
|
-
if (!this.pendingTick && this.items.length > 0) this.tick();
|
|
120
|
-
};
|
|
121
|
-
this.stop = () => {
|
|
122
|
-
this.clearTimeout();
|
|
123
|
-
this.isRunning = false;
|
|
124
|
-
this.pendingTick = false;
|
|
125
|
-
};
|
|
126
|
-
this.clearTimeout = () => {
|
|
127
|
-
if (this.timeoutId) {
|
|
128
|
-
clearTimeout(this.timeoutId);
|
|
129
|
-
this.timeoutId = null;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
this.peekNextItem = (position = "front") => {
|
|
133
|
-
if (this.items.length === 0) return;
|
|
134
|
-
if (this.options.getPriority || position === "front") return this.items[0];
|
|
135
|
-
else return this.items[this.items.length - 1];
|
|
136
|
-
};
|
|
137
|
-
this.peekAllItems = () => {
|
|
138
|
-
return [...this.items];
|
|
139
|
-
};
|
|
140
|
-
this.flush = (numberOfItems = this.items.length, position) => {
|
|
141
|
-
this.clearTimeout();
|
|
142
|
-
for (let i = 0; i < numberOfItems && this.items.length > 0; i++) this.execute(position);
|
|
143
|
-
if (this.isRunning && this.items.length > 0 && !this.pendingTick) this.tick();
|
|
144
|
-
};
|
|
145
|
-
this.flushAsBatch = (batchFunction) => {
|
|
146
|
-
const items = this.peekAllItems();
|
|
147
|
-
this.clear();
|
|
148
|
-
batchFunction(items);
|
|
149
|
-
};
|
|
150
|
-
this.clear = () => {
|
|
151
|
-
this.items = [];
|
|
152
|
-
};
|
|
153
72
|
this.options.addItemsTo = this.options.addItemsTo ?? "back";
|
|
154
73
|
this.options.getItemsFrom = this.options.getItemsFrom ?? "front";
|
|
155
74
|
this.options.maxSize = this.options.maxSize ?? Infinity;
|
|
@@ -177,6 +96,169 @@ var LiteQueuer = class {
|
|
|
177
96
|
get isQueueRunning() {
|
|
178
97
|
return this.isRunning;
|
|
179
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Adds an item to the queue. If the queue is full, the item is rejected.
|
|
101
|
+
* Items can be inserted at the front or back, and priority ordering is applied if getPriority is configured.
|
|
102
|
+
*
|
|
103
|
+
* Returns true if the item was added, false if the queue is full.
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ```ts
|
|
107
|
+
* queue.addItem('task1'); // Add to default position (back)
|
|
108
|
+
* queue.addItem('task2', 'front'); // Add to front
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
111
|
+
addItem = (item, position = this.options.addItemsTo, startProcessing = true) => {
|
|
112
|
+
if (this.items.length >= this.options.maxSize) return false;
|
|
113
|
+
if (this.options.getPriority) {
|
|
114
|
+
const priority = this.options.getPriority(item);
|
|
115
|
+
if (priority !== void 0) {
|
|
116
|
+
const insertIndex = this.items.findIndex((existing) => {
|
|
117
|
+
return (this.options.getPriority(existing) ?? -Infinity) < priority;
|
|
118
|
+
});
|
|
119
|
+
if (insertIndex === -1) this.items.push(item);
|
|
120
|
+
else this.items.splice(insertIndex, 0, item);
|
|
121
|
+
} else this.insertAtPosition(item, position);
|
|
122
|
+
} else this.insertAtPosition(item, position);
|
|
123
|
+
if (startProcessing && this.isRunning && !this.pendingTick) this.tick();
|
|
124
|
+
return true;
|
|
125
|
+
};
|
|
126
|
+
insertAtPosition = (item, position) => {
|
|
127
|
+
if (position === "front") this.items.unshift(item);
|
|
128
|
+
else this.items.push(item);
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Removes and returns the next item from the queue without executing the function.
|
|
132
|
+
* Use for manual queue management. Normally, use execute() to process items.
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```ts
|
|
136
|
+
* const nextItem = queue.getNextItem(); // Get from default position (front)
|
|
137
|
+
* const lastItem = queue.getNextItem('back'); // Get from back (LIFO)
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
getNextItem = (position = this.options.getItemsFrom) => {
|
|
141
|
+
if (this.items.length === 0) return;
|
|
142
|
+
let item;
|
|
143
|
+
if (this.options.getPriority || position === "front") item = this.items.shift();
|
|
144
|
+
else item = this.items.pop();
|
|
145
|
+
return item;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Removes and returns the next item from the queue and processes it using the provided function.
|
|
149
|
+
*
|
|
150
|
+
* @example
|
|
151
|
+
* ```ts
|
|
152
|
+
* queue.execute(); // Execute from default position
|
|
153
|
+
* queue.execute('back'); // Execute from back (LIFO)
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
execute = (position) => {
|
|
157
|
+
const item = this.getNextItem(position);
|
|
158
|
+
if (item !== void 0) this.fn(item);
|
|
159
|
+
return item;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* Internal method that processes items in the queue with wait intervals
|
|
163
|
+
*/
|
|
164
|
+
tick = () => {
|
|
165
|
+
if (!this.isRunning) {
|
|
166
|
+
this.pendingTick = false;
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.pendingTick = true;
|
|
170
|
+
while (this.items.length > 0) {
|
|
171
|
+
if (this.execute(this.options.getItemsFrom) === void 0) break;
|
|
172
|
+
const wait = this.options.wait;
|
|
173
|
+
if (wait > 0) {
|
|
174
|
+
this.timeoutId = setTimeout(() => this.tick(), wait);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
this.pendingTick = false;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* Starts processing items in the queue. If already running, does nothing.
|
|
182
|
+
*/
|
|
183
|
+
start = () => {
|
|
184
|
+
this.isRunning = true;
|
|
185
|
+
if (!this.pendingTick && this.items.length > 0) this.tick();
|
|
186
|
+
};
|
|
187
|
+
/**
|
|
188
|
+
* Stops processing items in the queue. Does not clear the queue.
|
|
189
|
+
*/
|
|
190
|
+
stop = () => {
|
|
191
|
+
this.clearTimeout();
|
|
192
|
+
this.isRunning = false;
|
|
193
|
+
this.pendingTick = false;
|
|
194
|
+
};
|
|
195
|
+
/**
|
|
196
|
+
* Clears any pending timeout
|
|
197
|
+
*/
|
|
198
|
+
clearTimeout = () => {
|
|
199
|
+
if (this.timeoutId) {
|
|
200
|
+
clearTimeout(this.timeoutId);
|
|
201
|
+
this.timeoutId = null;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
/**
|
|
205
|
+
* Returns the next item in the queue without removing it.
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* const next = queue.peekNextItem(); // Peek at front
|
|
210
|
+
* const last = queue.peekNextItem('back'); // Peek at back
|
|
211
|
+
* ```
|
|
212
|
+
*/
|
|
213
|
+
peekNextItem = (position = "front") => {
|
|
214
|
+
if (this.items.length === 0) return;
|
|
215
|
+
if (this.options.getPriority || position === "front") return this.items[0];
|
|
216
|
+
else return this.items[this.items.length - 1];
|
|
217
|
+
};
|
|
218
|
+
/**
|
|
219
|
+
* Returns a copy of all items in the queue.
|
|
220
|
+
*/
|
|
221
|
+
peekAllItems = () => {
|
|
222
|
+
return [...this.items];
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Processes a specified number of items immediately with no wait time.
|
|
226
|
+
* If no numberOfItems is provided, all items will be processed.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* ```ts
|
|
230
|
+
* queue.flush(); // Process all items immediately
|
|
231
|
+
* queue.flush(3); // Process next 3 items immediately
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
flush = (numberOfItems = this.items.length, position) => {
|
|
235
|
+
this.clearTimeout();
|
|
236
|
+
for (let i = 0; i < numberOfItems && this.items.length > 0; i++) this.execute(position);
|
|
237
|
+
if (this.isRunning && this.items.length > 0 && !this.pendingTick) this.tick();
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Processes all items in the queue as a batch using the provided function.
|
|
241
|
+
* The queue is cleared after processing.
|
|
242
|
+
*
|
|
243
|
+
* @example
|
|
244
|
+
* ```ts
|
|
245
|
+
* queue.flushAsBatch((items) => {
|
|
246
|
+
* console.log('Processing batch:', items);
|
|
247
|
+
* // Process all items together
|
|
248
|
+
* });
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
flushAsBatch = (batchFunction) => {
|
|
252
|
+
const items = this.peekAllItems();
|
|
253
|
+
this.clear();
|
|
254
|
+
batchFunction(items);
|
|
255
|
+
};
|
|
256
|
+
/**
|
|
257
|
+
* Removes all items from the queue. Does not affect items being processed.
|
|
258
|
+
*/
|
|
259
|
+
clear = () => {
|
|
260
|
+
this.items = [];
|
|
261
|
+
};
|
|
180
262
|
};
|
|
181
263
|
/**
|
|
182
264
|
* Creates a lightweight queue that processes items using the provided function.
|
|
@@ -202,5 +284,4 @@ function liteQueue(fn, options = {}) {
|
|
|
202
284
|
}
|
|
203
285
|
|
|
204
286
|
//#endregion
|
|
205
|
-
export { LiteQueuer, liteQueue };
|
|
206
|
-
//# sourceMappingURL=lite-queuer.js.map
|
|
287
|
+
export { LiteQueuer, liteQueue };
|