@tanstack/pacer 0.21.1 → 0.23.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 (101) hide show
  1. package/README.md +21 -6
  2. package/dist/async-batcher.d.ts +11 -14
  3. package/dist/async-batcher.js +186 -132
  4. package/dist/async-debouncer.d.ts +10 -13
  5. package/dist/async-debouncer.js +187 -146
  6. package/dist/async-queuer.d.ts +12 -14
  7. package/dist/async-queuer.js +384 -259
  8. package/dist/async-rate-limiter.d.ts +9 -12
  9. package/dist/async-rate-limiter.js +198 -147
  10. package/dist/async-retryer.d.ts +10 -10
  11. package/dist/async-retryer.js +209 -188
  12. package/dist/async-throttler.d.ts +10 -13
  13. package/dist/async-throttler.js +215 -161
  14. package/dist/batcher.d.ts +5 -8
  15. package/dist/batcher.js +107 -87
  16. package/dist/debouncer.d.ts +6 -9
  17. package/dist/debouncer.js +99 -86
  18. package/dist/event-client.d.ts +8 -11
  19. package/dist/event-client.js +1 -2
  20. package/dist/index.js +1 -1
  21. package/dist/queuer.d.ts +8 -10
  22. package/dist/queuer.js +277 -207
  23. package/dist/rate-limiter.d.ts +6 -9
  24. package/dist/rate-limiter.js +127 -109
  25. package/dist/throttler.d.ts +6 -9
  26. package/dist/throttler.js +127 -90
  27. package/dist/types.d.ts +4 -6
  28. package/dist/utils.d.ts +3 -6
  29. package/dist/utils.js +1 -2
  30. package/package.json +23 -70
  31. package/dist/async-batcher.cjs +0 -337
  32. package/dist/async-batcher.cjs.map +0 -1
  33. package/dist/async-batcher.d.cts +0 -344
  34. package/dist/async-batcher.js.map +0 -1
  35. package/dist/async-debouncer.cjs +0 -330
  36. package/dist/async-debouncer.cjs.map +0 -1
  37. package/dist/async-debouncer.d.cts +0 -300
  38. package/dist/async-debouncer.js.map +0 -1
  39. package/dist/async-queuer.cjs +0 -484
  40. package/dist/async-queuer.cjs.map +0 -1
  41. package/dist/async-queuer.d.cts +0 -440
  42. package/dist/async-queuer.js.map +0 -1
  43. package/dist/async-rate-limiter.cjs +0 -373
  44. package/dist/async-rate-limiter.cjs.map +0 -1
  45. package/dist/async-rate-limiter.d.cts +0 -357
  46. package/dist/async-rate-limiter.js.map +0 -1
  47. package/dist/async-retryer.cjs +0 -374
  48. package/dist/async-retryer.cjs.map +0 -1
  49. package/dist/async-retryer.d.cts +0 -319
  50. package/dist/async-retryer.js.map +0 -1
  51. package/dist/async-throttler.cjs +0 -347
  52. package/dist/async-throttler.cjs.map +0 -1
  53. package/dist/async-throttler.d.cts +0 -320
  54. package/dist/async-throttler.js.map +0 -1
  55. package/dist/batcher.cjs +0 -200
  56. package/dist/batcher.cjs.map +0 -1
  57. package/dist/batcher.d.cts +0 -180
  58. package/dist/batcher.js.map +0 -1
  59. package/dist/debouncer.cjs +0 -203
  60. package/dist/debouncer.cjs.map +0 -1
  61. package/dist/debouncer.d.cts +0 -167
  62. package/dist/debouncer.js.map +0 -1
  63. package/dist/event-client.cjs +0 -64
  64. package/dist/event-client.cjs.map +0 -1
  65. package/dist/event-client.d.cts +0 -66
  66. package/dist/event-client.js.map +0 -1
  67. package/dist/index.cjs +0 -52
  68. package/dist/index.d.cts +0 -15
  69. package/dist/queuer.cjs +0 -401
  70. package/dist/queuer.cjs.map +0 -1
  71. package/dist/queuer.d.cts +0 -345
  72. package/dist/queuer.js.map +0 -1
  73. package/dist/rate-limiter.cjs +0 -263
  74. package/dist/rate-limiter.cjs.map +0 -1
  75. package/dist/rate-limiter.d.cts +0 -215
  76. package/dist/rate-limiter.js.map +0 -1
  77. package/dist/throttler.cjs +0 -215
  78. package/dist/throttler.cjs.map +0 -1
  79. package/dist/throttler.d.cts +0 -207
  80. package/dist/throttler.js.map +0 -1
  81. package/dist/types.cjs +0 -0
  82. package/dist/types.d.cts +0 -13
  83. package/dist/utils.cjs +0 -14
  84. package/dist/utils.cjs.map +0 -1
  85. package/dist/utils.d.cts +0 -8
  86. package/dist/utils.js.map +0 -1
  87. package/src/async-batcher.ts +0 -594
  88. package/src/async-debouncer.ts +0 -565
  89. package/src/async-queuer.ts +0 -925
  90. package/src/async-rate-limiter.ts +0 -647
  91. package/src/async-retryer.ts +0 -684
  92. package/src/async-throttler.ts +0 -633
  93. package/src/batcher.ts +0 -329
  94. package/src/debouncer.ts +0 -334
  95. package/src/event-client.ts +0 -129
  96. package/src/index.ts +0 -24
  97. package/src/queuer.ts +0 -740
  98. package/src/rate-limiter.ts +0 -429
  99. package/src/throttler.ts +0 -380
  100. package/src/types.ts +0 -12
  101. package/src/utils.ts +0 -12
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
 
@@ -1,17 +1,16 @@
1
1
  import { OptionalKeys } from "./types.js";
2
2
  import { AsyncRetryer, AsyncRetryerOptions } from "./async-retryer.js";
3
3
  import { Store } from "@tanstack/store";
4
-
5
4
  //#region src/async-batcher.d.ts
6
- interface AsyncBatcherState<TValue> {
5
+ export interface AsyncBatcherState<TValue> {
7
6
  /**
8
7
  * Number of batch executions that have resulted in errors
9
8
  */
10
9
  errorCount: number;
11
10
  /**
12
- * Number of batch executions that have been executed
11
+ * Number of batch executions that have been started
13
12
  */
14
- executeCount: number;
13
+ executionCount: number;
15
14
  /**
16
15
  * Array of items that failed during batch processing
17
16
  */
@@ -64,7 +63,7 @@ interface AsyncBatcherState<TValue> {
64
63
  /**
65
64
  * Options for configuring an AsyncBatcher instance
66
65
  */
67
- interface AsyncBatcherOptions<TValue> {
66
+ export interface AsyncBatcherOptions<TValue> {
68
67
  /**
69
68
  * Options for configuring the underlying async retryer
70
69
  */
@@ -129,7 +128,7 @@ interface AsyncBatcherOptions<TValue> {
129
128
  * Utility function for sharing common `AsyncBatcherOptions` options between different `AsyncBatcher` instances.
130
129
  *
131
130
  */
132
- declare function asyncBatcherOptions<TValue = any, TOptions extends Partial<AsyncBatcherOptions<TValue>> = Partial<AsyncBatcherOptions<TValue>>>(options: TOptions): TOptions;
131
+ export declare function asyncBatcherOptions<TValue = any, TOptions extends Partial<AsyncBatcherOptions<TValue>> = Partial<AsyncBatcherOptions<TValue>>>(options: TOptions): TOptions;
133
132
  type AsyncBatcherOptionsWithOptionalCallbacks<TValue> = OptionalKeys<Required<AsyncBatcherOptions<TValue>>, 'initialState' | 'onError' | 'onItemsChange' | 'onSettled' | 'onSuccess' | 'key'>;
134
133
  /**
135
134
  * A class that collects items and processes them in batches asynchronously.
@@ -198,7 +197,7 @@ type AsyncBatcherOptionsWithOptionalCallbacks<TValue> = OptionalKeys<Required<As
198
197
  * // batcher.execute() // manually trigger a batch
199
198
  * ```
200
199
  */
201
- declare class AsyncBatcher<TValue> {
200
+ export declare class AsyncBatcher<TValue> {
202
201
  #private;
203
202
  fn: (items: Array<TValue>) => Promise<any>;
204
203
  readonly store: Store<Readonly<AsyncBatcherState<TValue>>>;
@@ -234,10 +233,10 @@ declare class AsyncBatcher<TValue> {
234
233
  clear: () => void;
235
234
  /**
236
235
  * Returns the AbortSignal for a specific execution.
237
- * If no executeCount is provided, returns the signal for the most recent execution.
236
+ * If no executionCount is provided, returns the signal for the most recent execution.
238
237
  * Returns null if no execution is found or not currently executing.
239
238
  *
240
- * @param executeCount - Optional specific execution to get signal for
239
+ * @param executionCount - Optional specific execution to get signal for
241
240
  * @example
242
241
  * ```typescript
243
242
  * const batcher = new AsyncBatcher(
@@ -256,7 +255,7 @@ declare class AsyncBatcher<TValue> {
256
255
  * )
257
256
  * ```
258
257
  */
259
- getAbortSignal: (executeCount?: number) => AbortSignal | null;
258
+ getAbortSignal: (executionCount?: number) => AbortSignal | null;
260
259
  /**
261
260
  * Aborts all ongoing executions with the internal abort controllers.
262
261
  * Does NOT cancel any pending execution that have not started yet.
@@ -338,7 +337,5 @@ declare class AsyncBatcher<TValue> {
338
337
  * batchItems(3); // Triggers batch processing
339
338
  * ```
340
339
  */
341
- declare function asyncBatch<TValue>(fn: (items: Array<TValue>) => Promise<any>, options: AsyncBatcherOptions<TValue>): (item: TValue) => Promise<any>;
342
- //#endregion
343
- export { AsyncBatcher, AsyncBatcherOptions, AsyncBatcherState, asyncBatch, asyncBatcherOptions };
344
- //# sourceMappingURL=async-batcher.d.ts.map
340
+ export declare function asyncBatch<TValue>(fn: (items: Array<TValue>) => Promise<any>, options: AsyncBatcherOptions<TValue>): (item: TValue) => Promise<any>;
341
+ //#endregion
@@ -1,13 +1,13 @@
1
1
  import { parseFunctionOrValue } from "./utils.js";
2
- import { emitChange, pacerEventClient } from "./event-client.js";
3
2
  import { AsyncRetryer } from "./async-retryer.js";
3
+ import { emitChange, pacerEventClient } from "./event-client.js";
4
4
  import { Store } from "@tanstack/store";
5
5
 
6
6
  //#region src/async-batcher.ts
7
7
  function getDefaultAsyncBatcherState() {
8
8
  return {
9
9
  errorCount: 0,
10
- executeCount: 0,
10
+ executionCount: 0,
11
11
  failedItems: [],
12
12
  isEmpty: true,
13
13
  isExecuting: false,
@@ -105,132 +105,14 @@ const defaultOptions = {
105
105
  * ```
106
106
  */
107
107
  var AsyncBatcher = class {
108
- #timeoutId;
108
+ fn;
109
+ store = new Store(getDefaultAsyncBatcherState());
110
+ key;
111
+ options;
112
+ asyncRetryers = /* @__PURE__ */ new Map();
113
+ #timeoutId = null;
109
114
  constructor(fn, initialOptions) {
110
115
  this.fn = fn;
111
- this.store = new Store(getDefaultAsyncBatcherState());
112
- this.asyncRetryers = /* @__PURE__ */ new Map();
113
- this.#timeoutId = null;
114
- this.setOptions = (newOptions) => {
115
- this.options = {
116
- ...this.options,
117
- ...newOptions
118
- };
119
- };
120
- this.#setState = (newState) => {
121
- this.store.setState((state) => {
122
- const combinedState = {
123
- ...state,
124
- ...newState
125
- };
126
- const { isExecuting, isPending, items } = combinedState;
127
- const size = items.length;
128
- const isEmpty = size === 0;
129
- return {
130
- ...combinedState,
131
- isEmpty,
132
- size,
133
- status: isExecuting ? "executing" : isPending ? "pending" : isEmpty ? "idle" : "populated"
134
- };
135
- });
136
- emitChange("AsyncBatcher", this);
137
- };
138
- this.#getWait = () => {
139
- return parseFunctionOrValue(this.options.wait, this);
140
- };
141
- this.addItem = async (item) => {
142
- this.#setState({
143
- items: [...this.store.state.items, item],
144
- isPending: this.options.wait !== Infinity
145
- });
146
- this.options.onItemsChange?.(this);
147
- if (this.store.state.items.length >= this.options.maxSize || this.options.getShouldExecute(this.store.state.items, this)) return await this.#execute();
148
- else if (this.options.wait !== Infinity) {
149
- this.#clearTimeout();
150
- this.#timeoutId = setTimeout(() => this.#execute(), this.#getWait());
151
- await new Promise((resolve) => setTimeout(resolve, this.#getWait()));
152
- }
153
- };
154
- this.#execute = async () => {
155
- if (this.store.state.items.length === 0) return;
156
- const currentExecuteCount = this.store.state.executeCount + 1;
157
- const batch = this.peekAllItems();
158
- this.clear();
159
- this.options.onItemsChange?.(this);
160
- this.#setState({
161
- isExecuting: true,
162
- executeCount: currentExecuteCount
163
- });
164
- try {
165
- const currentAsyncRetryer = new AsyncRetryer(this.fn, this.options.asyncRetryerOptions);
166
- this.asyncRetryers.set(currentExecuteCount, currentAsyncRetryer);
167
- const result = await currentAsyncRetryer.execute(batch);
168
- this.#setState({
169
- totalItemsProcessed: this.store.state.totalItemsProcessed + batch.length,
170
- lastResult: result,
171
- successCount: this.store.state.successCount + 1
172
- });
173
- this.options.onSuccess?.(result, batch, this);
174
- return result;
175
- } catch (error) {
176
- this.#setState({
177
- errorCount: this.store.state.errorCount + 1,
178
- failedItems: [...this.store.state.failedItems, ...batch],
179
- totalItemsFailed: this.store.state.totalItemsFailed + batch.length
180
- });
181
- this.options.onError?.(error, batch, this);
182
- if (this.options.throwOnError) throw error;
183
- return;
184
- } finally {
185
- this.asyncRetryers.delete(currentExecuteCount);
186
- this.#setState({
187
- isExecuting: false,
188
- settleCount: this.store.state.settleCount + 1
189
- });
190
- this.options.onSettled?.(batch, this);
191
- }
192
- };
193
- this.flush = async () => {
194
- this.#clearTimeout();
195
- return await this.#execute();
196
- };
197
- this.peekAllItems = () => {
198
- return [...this.store.state.items];
199
- };
200
- this.peekFailedItems = () => {
201
- return [...this.store.state.failedItems];
202
- };
203
- this.#clearTimeout = () => {
204
- if (this.#timeoutId) {
205
- clearTimeout(this.#timeoutId);
206
- this.#timeoutId = null;
207
- }
208
- };
209
- this.clear = () => {
210
- this.#setState({
211
- items: [],
212
- failedItems: [],
213
- isPending: false
214
- });
215
- };
216
- this.getAbortSignal = (executeCount) => {
217
- const count = executeCount ?? this.store.state.executeCount;
218
- return this.asyncRetryers.get(count)?.getAbortSignal() ?? null;
219
- };
220
- this.abort = () => {
221
- this.asyncRetryers.forEach((retryer) => retryer.abort());
222
- this.asyncRetryers.clear();
223
- this.#setState({ isExecuting: false });
224
- };
225
- this.cancel = () => {
226
- this.#clearTimeout();
227
- this.#setState({ isPending: false });
228
- };
229
- this.reset = () => {
230
- this.#setState(getDefaultAsyncBatcherState());
231
- this.options.onItemsChange?.(this);
232
- this.asyncRetryers.forEach((retryer) => retryer.reset());
233
- };
234
116
  this.key = initialOptions.key;
235
117
  this.options = {
236
118
  ...defaultOptions,
@@ -244,8 +126,57 @@ var AsyncBatcher = class {
244
126
  this.setOptions(event.payload.options);
245
127
  });
246
128
  }
247
- #setState;
248
- #getWait;
129
+ /**
130
+ * Updates the async batcher options
131
+ */
132
+ setOptions = (newOptions) => {
133
+ this.options = {
134
+ ...this.options,
135
+ ...newOptions
136
+ };
137
+ };
138
+ #setState = (newState) => {
139
+ this.store.setState((state) => {
140
+ const combinedState = {
141
+ ...state,
142
+ ...newState
143
+ };
144
+ const { isExecuting, isPending, items } = combinedState;
145
+ const size = items.length;
146
+ const isEmpty = size === 0;
147
+ return {
148
+ ...combinedState,
149
+ isEmpty,
150
+ size,
151
+ status: isExecuting ? "executing" : isPending ? "pending" : isEmpty ? "idle" : "populated"
152
+ };
153
+ });
154
+ emitChange("AsyncBatcher", this);
155
+ };
156
+ #getWait = () => {
157
+ return parseFunctionOrValue(this.options.wait, this);
158
+ };
159
+ /**
160
+ * Adds an item to the async batcher
161
+ * If the batch size is reached, timeout occurs, or shouldProcess returns true, the batch will be processed
162
+ *
163
+ * @returns The result from the batch function, or undefined if an error occurred and was handled by onError
164
+ *
165
+ * @throws The error from the batch function if no onError handler is configured or throwOnError is true
166
+ */
167
+ addItem = async (item) => {
168
+ this.#setState({
169
+ items: [...this.store.state.items, item],
170
+ isPending: this.options.wait !== Infinity
171
+ });
172
+ this.options.onItemsChange?.(this);
173
+ if (this.store.state.items.length >= this.options.maxSize || this.options.getShouldExecute(this.store.state.items, this)) return await this.#execute();
174
+ else if (this.options.wait !== Infinity) {
175
+ this.#clearTimeout();
176
+ this.#timeoutId = setTimeout(() => this.#execute(), this.#getWait());
177
+ await new Promise((resolve) => setTimeout(resolve, this.#getWait()));
178
+ }
179
+ };
249
180
  /**
250
181
  * Processes the current batch of items asynchronously.
251
182
  * This method will automatically be triggered if the batcher is running and any of these conditions are met:
@@ -258,8 +189,132 @@ var AsyncBatcher = class {
258
189
  * @returns A promise that resolves with the result of the batch function, or undefined if an error occurred and was handled by onError
259
190
  * @throws The error from the batch function if no onError handler is configured or throwOnError is true
260
191
  */
261
- #execute;
262
- #clearTimeout;
192
+ #execute = async () => {
193
+ if (this.store.state.items.length === 0) return;
194
+ const currentExecutionCount = this.store.state.executionCount + 1;
195
+ const batch = this.peekAllItems();
196
+ this.clear();
197
+ this.options.onItemsChange?.(this);
198
+ this.#setState({
199
+ isExecuting: true,
200
+ executionCount: currentExecutionCount
201
+ });
202
+ try {
203
+ const currentAsyncRetryer = new AsyncRetryer(this.fn, this.options.asyncRetryerOptions);
204
+ this.asyncRetryers.set(currentExecutionCount, currentAsyncRetryer);
205
+ const result = await currentAsyncRetryer.execute(batch);
206
+ this.#setState({
207
+ totalItemsProcessed: this.store.state.totalItemsProcessed + batch.length,
208
+ lastResult: result,
209
+ successCount: this.store.state.successCount + 1
210
+ });
211
+ this.options.onSuccess?.(result, batch, this);
212
+ return result;
213
+ } catch (error) {
214
+ this.#setState({
215
+ errorCount: this.store.state.errorCount + 1,
216
+ failedItems: [...this.store.state.failedItems, ...batch],
217
+ totalItemsFailed: this.store.state.totalItemsFailed + batch.length
218
+ });
219
+ this.options.onError?.(error, batch, this);
220
+ if (this.options.throwOnError) throw error;
221
+ return;
222
+ } finally {
223
+ this.asyncRetryers.delete(currentExecutionCount);
224
+ this.#setState({
225
+ isExecuting: false,
226
+ settleCount: this.store.state.settleCount + 1
227
+ });
228
+ this.options.onSettled?.(batch, this);
229
+ }
230
+ };
231
+ /**
232
+ * Processes the current batch of items immediately
233
+ */
234
+ flush = async () => {
235
+ this.#clearTimeout();
236
+ return await this.#execute();
237
+ };
238
+ /**
239
+ * Returns a copy of all items in the async batcher
240
+ */
241
+ peekAllItems = () => {
242
+ return [...this.store.state.items];
243
+ };
244
+ peekFailedItems = () => {
245
+ return [...this.store.state.failedItems];
246
+ };
247
+ #clearTimeout = () => {
248
+ if (this.#timeoutId) {
249
+ clearTimeout(this.#timeoutId);
250
+ this.#timeoutId = null;
251
+ }
252
+ };
253
+ /**
254
+ * Removes all items from the async batcher
255
+ */
256
+ clear = () => {
257
+ this.#setState({
258
+ items: [],
259
+ failedItems: [],
260
+ isPending: false
261
+ });
262
+ };
263
+ /**
264
+ * Returns the AbortSignal for a specific execution.
265
+ * If no executionCount is provided, returns the signal for the most recent execution.
266
+ * Returns null if no execution is found or not currently executing.
267
+ *
268
+ * @param executionCount - Optional specific execution to get signal for
269
+ * @example
270
+ * ```typescript
271
+ * const batcher = new AsyncBatcher(
272
+ * async (items: string[]) => {
273
+ * const signal = batcher.getAbortSignal()
274
+ * if (signal) {
275
+ * const response = await fetch('/api/batch', {
276
+ * method: 'POST',
277
+ * body: JSON.stringify(items),
278
+ * signal
279
+ * })
280
+ * return response.json()
281
+ * }
282
+ * },
283
+ * { maxSize: 10, wait: 100 }
284
+ * )
285
+ * ```
286
+ */
287
+ getAbortSignal = (executionCount) => {
288
+ const count = executionCount ?? this.store.state.executionCount;
289
+ return this.asyncRetryers.get(count)?.getAbortSignal() ?? null;
290
+ };
291
+ /**
292
+ * Aborts all ongoing executions with the internal abort controllers.
293
+ * Does NOT cancel any pending execution that have not started yet.
294
+ * Does NOT clear out the items.
295
+ */
296
+ abort = () => {
297
+ this.asyncRetryers.forEach((retryer) => retryer.abort());
298
+ this.asyncRetryers.clear();
299
+ this.#setState({ isExecuting: false });
300
+ };
301
+ /**
302
+ * Cancels any pending execution that have not started yet.
303
+ * Does NOT abort any execution already in progress.
304
+ * Does NOT clear out the items.
305
+ */
306
+ cancel = () => {
307
+ this.#clearTimeout();
308
+ this.#setState({ isPending: false });
309
+ };
310
+ /**
311
+ * Resets the async batcher state to its default values
312
+ */
313
+ reset = () => {
314
+ this.#setState(getDefaultAsyncBatcherState());
315
+ this.options.onItemsChange?.(this);
316
+ this.asyncRetryers.forEach((retryer) => retryer.reset());
317
+ };
263
318
  };
264
319
  /**
265
320
  * Creates an async batcher that processes items in batches.
@@ -330,5 +385,4 @@ function asyncBatch(fn, options) {
330
385
  }
331
386
 
332
387
  //#endregion
333
- export { AsyncBatcher, asyncBatch, asyncBatcherOptions };
334
- //# sourceMappingURL=async-batcher.js.map
388
+ export { AsyncBatcher, asyncBatch, asyncBatcherOptions };
@@ -1,9 +1,8 @@
1
1
  import { AnyAsyncFunction } from "./types.js";
2
2
  import { AsyncRetryer, AsyncRetryerOptions } from "./async-retryer.js";
3
3
  import { Store } from "@tanstack/store";
4
-
5
4
  //#region src/async-debouncer.d.ts
6
- interface AsyncDebouncerState<TFn extends AnyAsyncFunction> {
5
+ export interface AsyncDebouncerState<TFn extends AnyAsyncFunction> {
7
6
  /**
8
7
  * Whether the debouncer can execute on the leading edge of the timeout
9
8
  */
@@ -27,7 +26,7 @@ interface AsyncDebouncerState<TFn extends AnyAsyncFunction> {
27
26
  /**
28
27
  * The result from the most recent successful function execution
29
28
  */
30
- lastResult: ReturnType<TFn> | undefined;
29
+ lastResult: Awaited<ReturnType<TFn>> | undefined;
31
30
  /**
32
31
  * Number of times maybeExecute has been called (for reduction calculations)
33
32
  */
@@ -48,7 +47,7 @@ interface AsyncDebouncerState<TFn extends AnyAsyncFunction> {
48
47
  /**
49
48
  * Options for configuring an async debounced function
50
49
  */
51
- interface AsyncDebouncerOptions<TFn extends AnyAsyncFunction> {
50
+ export interface AsyncDebouncerOptions<TFn extends AnyAsyncFunction> {
52
51
  /**
53
52
  * Options for configuring the underlying async retryer
54
53
  */
@@ -86,7 +85,7 @@ interface AsyncDebouncerOptions<TFn extends AnyAsyncFunction> {
86
85
  /**
87
86
  * Optional callback to call when the debounced function is executed
88
87
  */
89
- onSuccess?: (result: ReturnType<TFn>, args: Parameters<TFn>, debouncer: AsyncDebouncer<TFn>) => void;
88
+ onSuccess?: (result: Awaited<ReturnType<TFn>>, args: Parameters<TFn>, debouncer: AsyncDebouncer<TFn>) => void;
90
89
  /**
91
90
  * Whether to throw errors when they occur.
92
91
  * Defaults to true if no onError handler is provided, false if an onError handler is provided.
@@ -108,7 +107,7 @@ interface AsyncDebouncerOptions<TFn extends AnyAsyncFunction> {
108
107
  /**
109
108
  * Utility function for sharing common `AsyncDebouncerOptions` options between different `AsyncDebouncer` instances.
110
109
  */
111
- declare function asyncDebouncerOptions<TFn extends AnyAsyncFunction = AnyAsyncFunction, TOptions extends Partial<AsyncDebouncerOptions<TFn>> = Partial<AsyncDebouncerOptions<TFn>>>(options: TOptions): TOptions;
110
+ export declare function asyncDebouncerOptions<TFn extends AnyAsyncFunction = AnyAsyncFunction, TOptions extends Partial<AsyncDebouncerOptions<TFn>> = Partial<AsyncDebouncerOptions<TFn>>>(options: TOptions): TOptions;
112
111
  /**
113
112
  * A class that creates an async debounced function.
114
113
  *
@@ -163,7 +162,7 @@ declare function asyncDebouncerOptions<TFn extends AnyAsyncFunction = AnyAsyncFu
163
162
  * const results = await asyncDebouncer.maybeExecute(inputElement.value);
164
163
  * ```
165
164
  */
166
- declare class AsyncDebouncer<TFn extends AnyAsyncFunction> {
165
+ export declare class AsyncDebouncer<TFn extends AnyAsyncFunction> {
167
166
  #private;
168
167
  fn: TFn;
169
168
  readonly store: Store<Readonly<AsyncDebouncerState<TFn>>>;
@@ -189,11 +188,11 @@ declare class AsyncDebouncer<TFn extends AnyAsyncFunction> {
189
188
  * @returns A promise that resolves with the function's return value, or undefined if an error occurred and was handled by onError
190
189
  * @throws The error from the debounced function if no onError handler is configured
191
190
  */
192
- maybeExecute: (...args: Parameters<TFn>) => Promise<ReturnType<TFn> | undefined>;
191
+ maybeExecute: (...args: Parameters<TFn>) => Promise<Awaited<ReturnType<TFn>> | undefined>;
193
192
  /**
194
193
  * Processes the current pending execution immediately
195
194
  */
196
- flush: () => Promise<ReturnType<TFn> | undefined>;
195
+ flush: () => Promise<Awaited<ReturnType<TFn>> | undefined>;
197
196
  /**
198
197
  * Returns the AbortSignal for a specific execution.
199
198
  * If no maybeExecuteCount is provided, returns the signal for the most recent execution.
@@ -294,7 +293,5 @@ declare class AsyncDebouncer<TFn extends AnyAsyncFunction> {
294
293
  * const result = await debounced("third");
295
294
  * ```
296
295
  */
297
- declare function asyncDebounce<TFn extends AnyAsyncFunction>(fn: TFn, initialOptions: AsyncDebouncerOptions<TFn>): (...args: Parameters<TFn>) => Promise<ReturnType<TFn> | undefined>;
298
- //#endregion
299
- export { AsyncDebouncer, AsyncDebouncerOptions, AsyncDebouncerState, asyncDebounce, asyncDebouncerOptions };
300
- //# sourceMappingURL=async-debouncer.d.ts.map
296
+ export declare function asyncDebounce<TFn extends AnyAsyncFunction>(fn: TFn, initialOptions: AsyncDebouncerOptions<TFn>): (...args: Parameters<TFn>) => Promise<Awaited<ReturnType<TFn>> | undefined>;
297
+ //#endregion