@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.
Files changed (42) hide show
  1. package/README.md +21 -6
  2. package/dist/lite-batcher.d.ts +4 -6
  3. package/dist/lite-batcher.js +72 -45
  4. package/dist/lite-debouncer.d.ts +4 -7
  5. package/dist/lite-debouncer.js +58 -40
  6. package/dist/lite-queuer.d.ts +5 -7
  7. package/dist/lite-queuer.js +170 -89
  8. package/dist/lite-rate-limiter.d.ts +4 -7
  9. package/dist/lite-rate-limiter.js +89 -63
  10. package/dist/lite-throttler.d.ts +4 -7
  11. package/dist/lite-throttler.js +63 -40
  12. package/dist/pacer/dist/types.d.ts +2 -7
  13. package/package.json +13 -33
  14. package/dist/index.cjs +0 -17
  15. package/dist/index.d.cts +0 -6
  16. package/dist/lite-batcher.cjs +0 -176
  17. package/dist/lite-batcher.cjs.map +0 -1
  18. package/dist/lite-batcher.d.cts +0 -184
  19. package/dist/lite-batcher.js.map +0 -1
  20. package/dist/lite-debouncer.cjs +0 -126
  21. package/dist/lite-debouncer.cjs.map +0 -1
  22. package/dist/lite-debouncer.d.cts +0 -126
  23. package/dist/lite-debouncer.js.map +0 -1
  24. package/dist/lite-queuer.cjs +0 -209
  25. package/dist/lite-queuer.cjs.map +0 -1
  26. package/dist/lite-queuer.d.cts +0 -243
  27. package/dist/lite-queuer.js.map +0 -1
  28. package/dist/lite-rate-limiter.cjs +0 -150
  29. package/dist/lite-rate-limiter.cjs.map +0 -1
  30. package/dist/lite-rate-limiter.d.cts +0 -148
  31. package/dist/lite-rate-limiter.js.map +0 -1
  32. package/dist/lite-throttler.cjs +0 -128
  33. package/dist/lite-throttler.cjs.map +0 -1
  34. package/dist/lite-throttler.d.cts +0 -133
  35. package/dist/lite-throttler.js.map +0 -1
  36. package/dist/pacer/dist/types.d.cts +0 -12
  37. package/src/index.ts +0 -5
  38. package/src/lite-batcher.ts +0 -267
  39. package/src/lite-debouncer.ts +0 -184
  40. package/src/lite-queuer.ts +0 -434
  41. package/src/lite-rate-limiter.ts +0 -246
  42. package/src/lite-throttler.ts +0 -195
package/README.md CHANGED
@@ -1,5 +1,19 @@
1
1
  <div align="center">
2
- <img src="./media/header_pacer.png" >
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/react-pacer)
92
- > - [**Preact Pacer**](https://tanstack.com/pacer/latest/docs/framework/preact/preact-pacer)
93
- > - [**Solid Pacer**](https://tanstack.com/pacer/latest/docs/framework/solid/solid-pacer)
94
- > - [**Angular Pacer**](https://tanstack.com/pacer/latest/docs/framework/angular/angular-pacer)
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
 
@@ -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
@@ -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 };
@@ -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
@@ -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.canLeadingExecute = true;
47
- this.maybeExecute = (...args) => {
48
- let didLeadingExecute = false;
49
- if (this.options.leading && this.canLeadingExecute) {
50
- this.canLeadingExecute = false;
51
- didLeadingExecute = true;
52
- this.fn(...args);
53
- this.options.onExecute?.(args, this);
54
- }
55
- this.lastArgs = args;
56
- if (this.timeoutId) clearTimeout(this.timeoutId);
57
- this.timeoutId = setTimeout(() => {
58
- this.canLeadingExecute = true;
59
- if (this.options.trailing && !didLeadingExecute && this.lastArgs) {
60
- this.fn(...this.lastArgs);
61
- this.options.onExecute?.(this.lastArgs, this);
62
- }
63
- this.lastArgs = void 0;
64
- }, this.options.wait);
65
- };
66
- this.flush = () => {
67
- if (this.timeoutId && this.lastArgs) {
68
- clearTimeout(this.timeoutId);
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
- if (this.options.leading === void 0 && this.options.trailing === void 0) this.options.trailing = true;
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 };
@@ -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
@@ -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 };