@tanstack/solid-pacer 0.18.3 → 0.19.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 +1 -1
- package/dist/async-batcher/createAsyncBatcher.cjs +32 -2
- package/dist/async-batcher/createAsyncBatcher.cjs.map +1 -1
- package/dist/async-batcher/createAsyncBatcher.d.cts +28 -2
- package/dist/async-batcher/createAsyncBatcher.d.ts +28 -2
- package/dist/async-batcher/createAsyncBatcher.js +32 -2
- package/dist/async-batcher/createAsyncBatcher.js.map +1 -1
- package/dist/async-batcher/index.cjs +1 -0
- package/dist/async-batcher/index.d.cts +2 -2
- package/dist/async-batcher/index.d.ts +2 -2
- package/dist/async-debouncer/createAsyncDebouncer.cjs +26 -3
- package/dist/async-debouncer/createAsyncDebouncer.cjs.map +1 -1
- package/dist/async-debouncer/createAsyncDebouncer.d.cts +27 -2
- package/dist/async-debouncer/createAsyncDebouncer.d.ts +27 -2
- package/dist/async-debouncer/createAsyncDebouncer.js +26 -3
- package/dist/async-debouncer/createAsyncDebouncer.js.map +1 -1
- package/dist/async-debouncer/index.cjs +1 -0
- package/dist/async-debouncer/index.d.cts +2 -2
- package/dist/async-debouncer/index.d.ts +2 -2
- package/dist/async-queuer/createAsyncQueuer.cjs +32 -2
- package/dist/async-queuer/createAsyncQueuer.cjs.map +1 -1
- package/dist/async-queuer/createAsyncQueuer.d.cts +28 -2
- package/dist/async-queuer/createAsyncQueuer.d.ts +28 -2
- package/dist/async-queuer/createAsyncQueuer.js +32 -2
- package/dist/async-queuer/createAsyncQueuer.js.map +1 -1
- package/dist/async-queuer/index.cjs +1 -0
- package/dist/async-queuer/index.d.cts +2 -2
- package/dist/async-queuer/index.d.ts +2 -2
- package/dist/async-rate-limiter/createAsyncRateLimiter.cjs +16 -2
- package/dist/async-rate-limiter/createAsyncRateLimiter.cjs.map +1 -1
- package/dist/async-rate-limiter/createAsyncRateLimiter.d.cts +15 -2
- package/dist/async-rate-limiter/createAsyncRateLimiter.d.ts +15 -2
- package/dist/async-rate-limiter/createAsyncRateLimiter.js +16 -2
- package/dist/async-rate-limiter/createAsyncRateLimiter.js.map +1 -1
- package/dist/async-rate-limiter/index.cjs +1 -0
- package/dist/async-rate-limiter/index.d.cts +2 -2
- package/dist/async-rate-limiter/index.d.ts +2 -2
- package/dist/async-throttler/createAsyncThrottler.cjs +31 -2
- package/dist/async-throttler/createAsyncThrottler.cjs.map +1 -1
- package/dist/async-throttler/createAsyncThrottler.d.cts +27 -2
- package/dist/async-throttler/createAsyncThrottler.d.ts +27 -2
- package/dist/async-throttler/createAsyncThrottler.js +31 -2
- package/dist/async-throttler/createAsyncThrottler.js.map +1 -1
- package/dist/async-throttler/index.cjs +1 -0
- package/dist/async-throttler/index.d.cts +2 -2
- package/dist/async-throttler/index.d.ts +2 -2
- package/dist/batcher/createBatcher.cjs +23 -2
- package/dist/batcher/createBatcher.cjs.map +1 -1
- package/dist/batcher/createBatcher.d.cts +22 -2
- package/dist/batcher/createBatcher.d.ts +22 -2
- package/dist/batcher/createBatcher.js +23 -2
- package/dist/batcher/createBatcher.js.map +1 -1
- package/dist/batcher/index.cjs +1 -0
- package/dist/batcher/index.d.cts +2 -2
- package/dist/batcher/index.d.ts +2 -2
- package/dist/debouncer/createDebouncedSignal.cjs.map +1 -1
- package/dist/debouncer/createDebouncedSignal.d.cts +3 -4
- package/dist/debouncer/createDebouncedSignal.d.ts +3 -4
- package/dist/debouncer/createDebouncedSignal.js.map +1 -1
- package/dist/debouncer/createDebouncedValue.cjs.map +1 -1
- package/dist/debouncer/createDebouncedValue.d.cts +3 -4
- package/dist/debouncer/createDebouncedValue.d.ts +3 -4
- package/dist/debouncer/createDebouncedValue.js.map +1 -1
- package/dist/debouncer/createDebouncer.cjs +17 -3
- package/dist/debouncer/createDebouncer.cjs.map +1 -1
- package/dist/debouncer/createDebouncer.d.cts +21 -2
- package/dist/debouncer/createDebouncer.d.ts +21 -2
- package/dist/debouncer/createDebouncer.js +17 -3
- package/dist/debouncer/createDebouncer.js.map +1 -1
- package/dist/debouncer/index.cjs +1 -0
- package/dist/debouncer/index.d.cts +2 -2
- package/dist/debouncer/index.d.ts +2 -2
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/provider/index.cjs +1 -0
- package/dist/queuer/createQueuedSignal.cjs.map +1 -1
- package/dist/queuer/createQueuedSignal.d.cts +3 -4
- package/dist/queuer/createQueuedSignal.d.ts +3 -4
- package/dist/queuer/createQueuedSignal.js.map +1 -1
- package/dist/queuer/createQueuer.cjs +23 -2
- package/dist/queuer/createQueuer.cjs.map +1 -1
- package/dist/queuer/createQueuer.d.cts +22 -2
- package/dist/queuer/createQueuer.d.ts +22 -2
- package/dist/queuer/createQueuer.js +23 -2
- package/dist/queuer/createQueuer.js.map +1 -1
- package/dist/queuer/index.cjs +1 -0
- package/dist/queuer/index.d.cts +2 -2
- package/dist/queuer/index.d.ts +2 -2
- package/dist/rate-limiter/createRateLimitedSignal.cjs.map +1 -1
- package/dist/rate-limiter/createRateLimitedSignal.d.cts +3 -4
- package/dist/rate-limiter/createRateLimitedSignal.d.ts +3 -4
- package/dist/rate-limiter/createRateLimitedSignal.js.map +1 -1
- package/dist/rate-limiter/createRateLimitedValue.cjs.map +1 -1
- package/dist/rate-limiter/createRateLimitedValue.d.cts +3 -4
- package/dist/rate-limiter/createRateLimitedValue.d.ts +3 -4
- package/dist/rate-limiter/createRateLimitedValue.js.map +1 -1
- package/dist/rate-limiter/createRateLimiter.cjs +9 -2
- package/dist/rate-limiter/createRateLimiter.cjs.map +1 -1
- package/dist/rate-limiter/createRateLimiter.d.cts +9 -2
- package/dist/rate-limiter/createRateLimiter.d.ts +9 -2
- package/dist/rate-limiter/createRateLimiter.js +9 -2
- package/dist/rate-limiter/createRateLimiter.js.map +1 -1
- package/dist/rate-limiter/index.cjs +1 -0
- package/dist/rate-limiter/index.d.cts +2 -2
- package/dist/rate-limiter/index.d.ts +2 -2
- package/dist/throttler/createThrottledSignal.cjs.map +1 -1
- package/dist/throttler/createThrottledSignal.d.cts +3 -4
- package/dist/throttler/createThrottledSignal.d.ts +3 -4
- package/dist/throttler/createThrottledSignal.js.map +1 -1
- package/dist/throttler/createThrottledValue.cjs.map +1 -1
- package/dist/throttler/createThrottledValue.d.cts +3 -4
- package/dist/throttler/createThrottledValue.d.ts +3 -4
- package/dist/throttler/createThrottledValue.js.map +1 -1
- package/dist/throttler/createThrottler.cjs +17 -3
- package/dist/throttler/createThrottler.cjs.map +1 -1
- package/dist/throttler/createThrottler.d.cts +21 -2
- package/dist/throttler/createThrottler.d.ts +21 -2
- package/dist/throttler/createThrottler.js +17 -3
- package/dist/throttler/createThrottler.js.map +1 -1
- package/dist/throttler/index.cjs +1 -0
- package/dist/throttler/index.d.cts +2 -2
- package/dist/throttler/index.d.ts +2 -2
- package/package.json +33 -32
- package/src/async-batcher/createAsyncBatcher.ts +44 -3
- package/src/async-debouncer/createAsyncDebouncer.ts +37 -4
- package/src/async-queuer/createAsyncQueuer.ts +44 -3
- package/src/async-rate-limiter/createAsyncRateLimiter.ts +30 -3
- package/src/async-throttler/createAsyncThrottler.ts +43 -3
- package/src/batcher/createBatcher.ts +38 -3
- package/src/debouncer/createDebouncedSignal.ts +3 -6
- package/src/debouncer/createDebouncedValue.ts +3 -6
- package/src/debouncer/createDebouncer.ts +30 -4
- package/src/queuer/createQueuedSignal.ts +3 -3
- package/src/queuer/createQueuer.ts +37 -3
- package/src/rate-limiter/createRateLimitedSignal.ts +6 -6
- package/src/rate-limiter/createRateLimitedValue.ts +6 -6
- package/src/rate-limiter/createRateLimiter.ts +22 -3
- package/src/throttler/createThrottledSignal.ts +3 -6
- package/src/throttler/createThrottledValue.ts +3 -6
- package/src/throttler/createThrottler.ts +30 -4
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AsyncRateLimiter } from '@tanstack/pacer/async-rate-limiter'
|
|
2
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
2
3
|
import { useStore } from '@tanstack/solid-store'
|
|
3
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
4
5
|
import type { Store } from '@tanstack/solid-store'
|
|
@@ -9,6 +10,17 @@ import type {
|
|
|
9
10
|
AsyncRateLimiterState,
|
|
10
11
|
} from '@tanstack/pacer/async-rate-limiter'
|
|
11
12
|
|
|
13
|
+
export interface SolidAsyncRateLimiterOptions<
|
|
14
|
+
TFn extends AnyAsyncFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends AsyncRateLimiterOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the owning component unmounts. Receives the rate limiter instance.
|
|
19
|
+
* When provided, replaces the default cleanup (abort); use it to call reset(), add logging, etc.
|
|
20
|
+
*/
|
|
21
|
+
onUnmount?: (rateLimiter: SolidAsyncRateLimiter<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
12
24
|
export interface SolidAsyncRateLimiter<
|
|
13
25
|
TFn extends AnyAsyncFunction,
|
|
14
26
|
TSelected = {},
|
|
@@ -111,6 +123,12 @@ export interface SolidAsyncRateLimiter<
|
|
|
111
123
|
* - `rejectionCount`: Number of function calls that were rejected due to rate limiting
|
|
112
124
|
* - `remainingInWindow`: Number of executions remaining in the current window
|
|
113
125
|
*
|
|
126
|
+
* ## Unmount behavior
|
|
127
|
+
*
|
|
128
|
+
* By default, the primitive aborts any in-flight execution when the owning component unmounts.
|
|
129
|
+
* Abort only cancels underlying operations (e.g. fetch) when the abort signal from `getAbortSignal()` is passed to them.
|
|
130
|
+
* Use the `onUnmount` option to customize this.
|
|
131
|
+
*
|
|
114
132
|
* @example
|
|
115
133
|
* ```tsx
|
|
116
134
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -204,15 +222,14 @@ export function createAsyncRateLimiter<
|
|
|
204
222
|
TSelected = {},
|
|
205
223
|
>(
|
|
206
224
|
fn: TFn,
|
|
207
|
-
options:
|
|
225
|
+
options: SolidAsyncRateLimiterOptions<TFn, TSelected>,
|
|
208
226
|
selector: (state: AsyncRateLimiterState<TFn>) => TSelected = () =>
|
|
209
227
|
({}) as TSelected,
|
|
210
228
|
): SolidAsyncRateLimiter<TFn, TSelected> {
|
|
211
229
|
const mergedOptions = {
|
|
212
230
|
...useDefaultPacerOptions().asyncRateLimiter,
|
|
213
231
|
...options,
|
|
214
|
-
} as
|
|
215
|
-
|
|
232
|
+
} as SolidAsyncRateLimiterOptions<TFn, TSelected>
|
|
216
233
|
const asyncRateLimiter = new AsyncRateLimiter<TFn>(
|
|
217
234
|
fn,
|
|
218
235
|
mergedOptions,
|
|
@@ -231,6 +248,16 @@ export function createAsyncRateLimiter<
|
|
|
231
248
|
|
|
232
249
|
const state = useStore(asyncRateLimiter.store, selector)
|
|
233
250
|
|
|
251
|
+
createEffect(() => {
|
|
252
|
+
onCleanup(() => {
|
|
253
|
+
if (mergedOptions.onUnmount) {
|
|
254
|
+
mergedOptions.onUnmount(asyncRateLimiter)
|
|
255
|
+
} else {
|
|
256
|
+
asyncRateLimiter.abort()
|
|
257
|
+
}
|
|
258
|
+
})
|
|
259
|
+
})
|
|
260
|
+
|
|
234
261
|
return {
|
|
235
262
|
...asyncRateLimiter,
|
|
236
263
|
state,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
1
2
|
import { AsyncThrottler } from '@tanstack/pacer/async-throttler'
|
|
2
3
|
import { useStore } from '@tanstack/solid-store'
|
|
3
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
@@ -9,6 +10,17 @@ import type {
|
|
|
9
10
|
AsyncThrottlerState,
|
|
10
11
|
} from '@tanstack/pacer/async-throttler'
|
|
11
12
|
|
|
13
|
+
export interface SolidAsyncThrottlerOptions<
|
|
14
|
+
TFn extends AnyAsyncFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends AsyncThrottlerOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the owning component unmounts. Receives the throttler instance.
|
|
19
|
+
* When provided, replaces the default cleanup (cancel + abort); use it to call flush(), reset(), cancel(), add logging, etc.
|
|
20
|
+
*/
|
|
21
|
+
onUnmount?: (throttler: SolidAsyncThrottler<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
12
24
|
export interface SolidAsyncThrottler<
|
|
13
25
|
TFn extends AnyAsyncFunction,
|
|
14
26
|
TSelected = {},
|
|
@@ -100,6 +112,24 @@ export interface SolidAsyncThrottler<
|
|
|
100
112
|
* - `nextExecutionTime`: Timestamp of the next allowed execution
|
|
101
113
|
* - `status`: Current execution status ('disabled' | 'idle' | 'pending' | 'executing')
|
|
102
114
|
*
|
|
115
|
+
* ## Unmount behavior
|
|
116
|
+
*
|
|
117
|
+
* By default, the primitive cancels any pending execution and aborts any in-flight execution when the owning component unmounts.
|
|
118
|
+
* Abort only cancels underlying operations (e.g. fetch) when the abort signal from `getAbortSignal()` is passed to them.
|
|
119
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending work instead:
|
|
120
|
+
*
|
|
121
|
+
* ```tsx
|
|
122
|
+
* const throttler = createAsyncThrottler(fn, {
|
|
123
|
+
* wait: 1000,
|
|
124
|
+
* onUnmount: (t) => t.flush()
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* Note: For async utils, `flush()` returns a Promise and runs fire-and-forget in the cleanup.
|
|
129
|
+
* If your throttled function updates Solid signals, those updates may run after the component has
|
|
130
|
+
* unmounted, which can cause unexpected reactive updates. Guard your callbacks accordingly when
|
|
131
|
+
* using onUnmount with flush.
|
|
132
|
+
*
|
|
103
133
|
* @example
|
|
104
134
|
* ```tsx
|
|
105
135
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -147,15 +177,14 @@ export function createAsyncThrottler<
|
|
|
147
177
|
TSelected = {},
|
|
148
178
|
>(
|
|
149
179
|
fn: TFn,
|
|
150
|
-
options:
|
|
180
|
+
options: SolidAsyncThrottlerOptions<TFn, TSelected>,
|
|
151
181
|
selector: (state: AsyncThrottlerState<TFn>) => TSelected = () =>
|
|
152
182
|
({}) as TSelected,
|
|
153
183
|
): SolidAsyncThrottler<TFn, TSelected> {
|
|
154
184
|
const mergedOptions = {
|
|
155
185
|
...useDefaultPacerOptions().asyncThrottler,
|
|
156
186
|
...options,
|
|
157
|
-
} as
|
|
158
|
-
|
|
187
|
+
} as SolidAsyncThrottlerOptions<TFn, TSelected>
|
|
159
188
|
const asyncThrottler = new AsyncThrottler(
|
|
160
189
|
fn,
|
|
161
190
|
mergedOptions,
|
|
@@ -174,6 +203,17 @@ export function createAsyncThrottler<
|
|
|
174
203
|
|
|
175
204
|
const state = useStore(asyncThrottler.store, selector)
|
|
176
205
|
|
|
206
|
+
createEffect(() => {
|
|
207
|
+
onCleanup(() => {
|
|
208
|
+
if (mergedOptions.onUnmount) {
|
|
209
|
+
mergedOptions.onUnmount(asyncThrottler)
|
|
210
|
+
} else {
|
|
211
|
+
asyncThrottler.cancel()
|
|
212
|
+
asyncThrottler.abort()
|
|
213
|
+
}
|
|
214
|
+
})
|
|
215
|
+
})
|
|
216
|
+
|
|
177
217
|
return {
|
|
178
218
|
...asyncThrottler,
|
|
179
219
|
state,
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { Batcher } from '@tanstack/pacer/batcher'
|
|
2
2
|
import { useStore } from '@tanstack/solid-store'
|
|
3
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
3
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
4
5
|
import type { Store } from '@tanstack/solid-store'
|
|
5
6
|
import type { Accessor, JSX } from 'solid-js'
|
|
6
7
|
import type { BatcherOptions, BatcherState } from '@tanstack/pacer/batcher'
|
|
7
8
|
|
|
9
|
+
export interface SolidBatcherOptions<
|
|
10
|
+
TValue,
|
|
11
|
+
TSelected = {},
|
|
12
|
+
> extends BatcherOptions<TValue> {
|
|
13
|
+
/**
|
|
14
|
+
* Optional callback invoked when the owning component unmounts. Receives the batcher instance.
|
|
15
|
+
* When provided, replaces the default cleanup (cancel); use it to call flush(), reset(), cancel(), add logging, etc.
|
|
16
|
+
*/
|
|
17
|
+
onUnmount?: (batcher: SolidBatcher<TValue, TSelected>) => void
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export interface SolidBatcher<TValue, TSelected = {}> extends Omit<
|
|
9
21
|
Batcher<TValue>,
|
|
10
22
|
'store'
|
|
@@ -82,6 +94,19 @@ export interface SolidBatcher<TValue, TSelected = {}> extends Omit<
|
|
|
82
94
|
* - `items`: Array of items currently queued for batching
|
|
83
95
|
* - `totalItemsProcessed`: Total number of individual items that have been processed across all batches
|
|
84
96
|
*
|
|
97
|
+
* ## Unmount behavior
|
|
98
|
+
*
|
|
99
|
+
* By default, the primitive cancels any pending batch when the owning component unmounts.
|
|
100
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending work instead:
|
|
101
|
+
*
|
|
102
|
+
* ```tsx
|
|
103
|
+
* const batcher = createBatcher(fn, {
|
|
104
|
+
* maxSize: 10,
|
|
105
|
+
* wait: 2000,
|
|
106
|
+
* onUnmount: (b) => b.flush()
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*
|
|
85
110
|
* Example usage:
|
|
86
111
|
* ```tsx
|
|
87
112
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -129,15 +154,14 @@ export interface SolidBatcher<TValue, TSelected = {}> extends Omit<
|
|
|
129
154
|
*/
|
|
130
155
|
export function createBatcher<TValue, TSelected = {}>(
|
|
131
156
|
fn: (items: Array<TValue>) => void,
|
|
132
|
-
options:
|
|
157
|
+
options: SolidBatcherOptions<TValue, TSelected> = {},
|
|
133
158
|
selector: (state: BatcherState<TValue>) => TSelected = () =>
|
|
134
159
|
({}) as TSelected,
|
|
135
160
|
): SolidBatcher<TValue, TSelected> {
|
|
136
161
|
const mergedOptions = {
|
|
137
162
|
...useDefaultPacerOptions().batcher,
|
|
138
163
|
...options,
|
|
139
|
-
} as
|
|
140
|
-
|
|
164
|
+
} as SolidBatcherOptions<TValue, TSelected>
|
|
141
165
|
const batcher = new Batcher(fn, mergedOptions) as unknown as SolidBatcher<
|
|
142
166
|
TValue,
|
|
143
167
|
TSelected
|
|
@@ -155,6 +179,17 @@ export function createBatcher<TValue, TSelected = {}>(
|
|
|
155
179
|
}
|
|
156
180
|
|
|
157
181
|
const state = useStore(batcher.store, selector)
|
|
182
|
+
|
|
183
|
+
createEffect(() => {
|
|
184
|
+
onCleanup(() => {
|
|
185
|
+
if (mergedOptions.onUnmount) {
|
|
186
|
+
mergedOptions.onUnmount(batcher)
|
|
187
|
+
} else {
|
|
188
|
+
batcher.cancel()
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
158
193
|
return {
|
|
159
194
|
...batcher,
|
|
160
195
|
state,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createSignal } from 'solid-js'
|
|
2
2
|
import { createDebouncer } from './createDebouncer'
|
|
3
|
-
import type { SolidDebouncer } from './createDebouncer'
|
|
3
|
+
import type { SolidDebouncer, SolidDebouncerOptions } from './createDebouncer'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
6
|
-
DebouncerOptions,
|
|
7
|
-
DebouncerState,
|
|
8
|
-
} from '@tanstack/pacer/debouncer'
|
|
5
|
+
import type { DebouncerState } from '@tanstack/pacer/debouncer'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A Solid hook that creates a debounced state value, combining Solid's createSignal with debouncing functionality.
|
|
@@ -80,7 +77,7 @@ import type {
|
|
|
80
77
|
*/
|
|
81
78
|
export function createDebouncedSignal<TValue, TSelected = {}>(
|
|
82
79
|
value: TValue,
|
|
83
|
-
initialOptions:
|
|
80
|
+
initialOptions: SolidDebouncerOptions<Setter<TValue>, TSelected>,
|
|
84
81
|
selector?: (state: DebouncerState<Setter<TValue>>) => TSelected,
|
|
85
82
|
): [
|
|
86
83
|
Accessor<TValue>,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createEffect } from 'solid-js'
|
|
2
2
|
import { createDebouncedSignal } from './createDebouncedSignal'
|
|
3
|
-
import type { SolidDebouncer } from './createDebouncer'
|
|
3
|
+
import type { SolidDebouncer, SolidDebouncerOptions } from './createDebouncer'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
6
|
-
DebouncerOptions,
|
|
7
|
-
DebouncerState,
|
|
8
|
-
} from '@tanstack/pacer/debouncer'
|
|
5
|
+
import type { DebouncerState } from '@tanstack/pacer/debouncer'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A Solid hook that creates a debounced value that updates only after a specified delay.
|
|
@@ -71,7 +68,7 @@ import type {
|
|
|
71
68
|
*/
|
|
72
69
|
export function createDebouncedValue<TValue, TSelected = {}>(
|
|
73
70
|
value: Accessor<TValue>,
|
|
74
|
-
initialOptions:
|
|
71
|
+
initialOptions: SolidDebouncerOptions<Setter<TValue>, TSelected>,
|
|
75
72
|
selector?: (state: DebouncerState<Setter<TValue>>) => TSelected,
|
|
76
73
|
): [Accessor<TValue>, SolidDebouncer<Setter<TValue>, TSelected>] {
|
|
77
74
|
const [debouncedValue, setDebouncedValue, debouncer] = createDebouncedSignal(
|
|
@@ -10,6 +10,17 @@ import type {
|
|
|
10
10
|
DebouncerState,
|
|
11
11
|
} from '@tanstack/pacer/debouncer'
|
|
12
12
|
|
|
13
|
+
export interface SolidDebouncerOptions<
|
|
14
|
+
TFn extends AnyFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends DebouncerOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the owning component unmounts. Receives the debouncer instance.
|
|
19
|
+
* When provided, replaces the default cleanup (cancel); use it to call flush(), reset(), cancel(), add logging, etc.
|
|
20
|
+
*/
|
|
21
|
+
onUnmount?: (debouncer: SolidDebouncer<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
export interface SolidDebouncer<
|
|
14
25
|
TFn extends AnyFunction,
|
|
15
26
|
TSelected = {},
|
|
@@ -88,6 +99,18 @@ export interface SolidDebouncer<
|
|
|
88
99
|
* - `lastArgs`: The arguments from the most recent call to maybeExecute
|
|
89
100
|
* - `status`: Current execution status ('disabled' | 'idle' | 'pending')
|
|
90
101
|
*
|
|
102
|
+
* ## Unmount behavior
|
|
103
|
+
*
|
|
104
|
+
* By default, the primitive cancels any pending execution when the owning component unmounts.
|
|
105
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending work instead:
|
|
106
|
+
*
|
|
107
|
+
* ```tsx
|
|
108
|
+
* const debouncer = createDebouncer(fn, {
|
|
109
|
+
* wait: 500,
|
|
110
|
+
* onUnmount: (d) => d.flush()
|
|
111
|
+
* });
|
|
112
|
+
* ```
|
|
113
|
+
*
|
|
91
114
|
* @example
|
|
92
115
|
* ```tsx
|
|
93
116
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -132,14 +155,13 @@ export interface SolidDebouncer<
|
|
|
132
155
|
*/
|
|
133
156
|
export function createDebouncer<TFn extends AnyFunction, TSelected = {}>(
|
|
134
157
|
fn: TFn,
|
|
135
|
-
options:
|
|
158
|
+
options: SolidDebouncerOptions<TFn, TSelected>,
|
|
136
159
|
selector: (state: DebouncerState<TFn>) => TSelected = () => ({}) as TSelected,
|
|
137
160
|
): SolidDebouncer<TFn, TSelected> {
|
|
138
161
|
const mergedOptions = {
|
|
139
162
|
...useDefaultPacerOptions().debouncer,
|
|
140
163
|
...options,
|
|
141
|
-
} as
|
|
142
|
-
|
|
164
|
+
} as SolidDebouncerOptions<TFn, TSelected>
|
|
143
165
|
const asyncDebouncer = new Debouncer<TFn>(
|
|
144
166
|
fn,
|
|
145
167
|
mergedOptions,
|
|
@@ -160,7 +182,11 @@ export function createDebouncer<TFn extends AnyFunction, TSelected = {}>(
|
|
|
160
182
|
|
|
161
183
|
createEffect(() => {
|
|
162
184
|
onCleanup(() => {
|
|
163
|
-
|
|
185
|
+
if (mergedOptions.onUnmount) {
|
|
186
|
+
mergedOptions.onUnmount(asyncDebouncer)
|
|
187
|
+
} else {
|
|
188
|
+
asyncDebouncer.cancel()
|
|
189
|
+
}
|
|
164
190
|
})
|
|
165
191
|
})
|
|
166
192
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createQueuer } from './createQueuer'
|
|
2
|
-
import type { SolidQueuer } from './createQueuer'
|
|
3
|
-
import type {
|
|
2
|
+
import type { SolidQueuer, SolidQueuerOptions } from './createQueuer'
|
|
3
|
+
import type { QueuerState } from '@tanstack/pacer/queuer'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* A Solid primitive that creates a queuer with managed state, combining Solid's signals with queuing functionality.
|
|
@@ -124,7 +124,7 @@ export function createQueuedSignal<
|
|
|
124
124
|
>,
|
|
125
125
|
>(
|
|
126
126
|
fn: (item: TValue) => void,
|
|
127
|
-
options:
|
|
127
|
+
options: SolidQueuerOptions<TValue, TSelected> = {},
|
|
128
128
|
selector: (state: QueuerState<TValue>) => TSelected = (state) =>
|
|
129
129
|
({ items: state.items }) as TSelected,
|
|
130
130
|
): [
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { Queuer } from '@tanstack/pacer/queuer'
|
|
2
2
|
import { useStore } from '@tanstack/solid-store'
|
|
3
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
3
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
4
5
|
import type { Store } from '@tanstack/solid-store'
|
|
5
6
|
import type { Accessor, JSX } from 'solid-js'
|
|
6
7
|
import type { QueuerOptions, QueuerState } from '@tanstack/pacer/queuer'
|
|
7
8
|
|
|
9
|
+
export interface SolidQueuerOptions<
|
|
10
|
+
TValue,
|
|
11
|
+
TSelected = {},
|
|
12
|
+
> extends QueuerOptions<TValue> {
|
|
13
|
+
/**
|
|
14
|
+
* Optional callback invoked when the owning component unmounts. Receives the queuer instance.
|
|
15
|
+
* When provided, replaces the default cleanup (stop); use it to call flush(), flushAsBatch(), stop(), add logging, etc.
|
|
16
|
+
*/
|
|
17
|
+
onUnmount?: (queuer: SolidQueuer<TValue, TSelected>) => void
|
|
18
|
+
}
|
|
19
|
+
|
|
8
20
|
export interface SolidQueuer<TValue, TSelected = {}> extends Omit<
|
|
9
21
|
Queuer<TValue>,
|
|
10
22
|
'store'
|
|
@@ -84,6 +96,19 @@ export interface SolidQueuer<TValue, TSelected = {}> extends Omit<
|
|
|
84
96
|
* - `items`: Array of items currently queued for processing
|
|
85
97
|
* - `rejectionCount`: Number of items that were rejected (expired or failed validation)
|
|
86
98
|
*
|
|
99
|
+
* ## Unmount behavior
|
|
100
|
+
*
|
|
101
|
+
* By default, the primitive stops the queuer when the owning component unmounts.
|
|
102
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending items instead:
|
|
103
|
+
*
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const queue = createQueuer(fn, {
|
|
106
|
+
* started: true,
|
|
107
|
+
* wait: 1000,
|
|
108
|
+
* onUnmount: (q) => q.flush()
|
|
109
|
+
* });
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
87
112
|
* Example usage:
|
|
88
113
|
* ```tsx
|
|
89
114
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -130,14 +155,13 @@ export interface SolidQueuer<TValue, TSelected = {}> extends Omit<
|
|
|
130
155
|
*/
|
|
131
156
|
export function createQueuer<TValue, TSelected = {}>(
|
|
132
157
|
fn: (item: TValue) => void,
|
|
133
|
-
options:
|
|
158
|
+
options: SolidQueuerOptions<TValue, TSelected> = {},
|
|
134
159
|
selector: (state: QueuerState<TValue>) => TSelected = () => ({}) as TSelected,
|
|
135
160
|
): SolidQueuer<TValue, TSelected> {
|
|
136
161
|
const mergedOptions = {
|
|
137
162
|
...useDefaultPacerOptions().queuer,
|
|
138
163
|
...options,
|
|
139
|
-
} as
|
|
140
|
-
|
|
164
|
+
} as SolidQueuerOptions<TValue, TSelected>
|
|
141
165
|
const queuer = new Queuer(fn, mergedOptions) as unknown as SolidQueuer<
|
|
142
166
|
TValue,
|
|
143
167
|
TSelected
|
|
@@ -156,6 +180,16 @@ export function createQueuer<TValue, TSelected = {}>(
|
|
|
156
180
|
|
|
157
181
|
const state = useStore(queuer.store, selector)
|
|
158
182
|
|
|
183
|
+
createEffect(() => {
|
|
184
|
+
onCleanup(() => {
|
|
185
|
+
if (mergedOptions.onUnmount) {
|
|
186
|
+
mergedOptions.onUnmount(queuer)
|
|
187
|
+
} else {
|
|
188
|
+
queuer.stop()
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
})
|
|
192
|
+
|
|
159
193
|
return {
|
|
160
194
|
...queuer,
|
|
161
195
|
state,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createSignal } from 'solid-js'
|
|
2
2
|
import { createRateLimiter } from './createRateLimiter'
|
|
3
|
-
import type { SolidRateLimiter } from './createRateLimiter'
|
|
4
|
-
import type { Accessor, Setter } from 'solid-js'
|
|
5
3
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '
|
|
4
|
+
SolidRateLimiter,
|
|
5
|
+
SolidRateLimiterOptions,
|
|
6
|
+
} from './createRateLimiter'
|
|
7
|
+
import type { Accessor, Setter } from 'solid-js'
|
|
8
|
+
import type { RateLimiterState } from '@tanstack/pacer/rate-limiter'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window.
|
|
@@ -94,7 +94,7 @@ import type {
|
|
|
94
94
|
*/
|
|
95
95
|
export function createRateLimitedSignal<TValue, TSelected = {}>(
|
|
96
96
|
value: TValue,
|
|
97
|
-
initialOptions:
|
|
97
|
+
initialOptions: SolidRateLimiterOptions<Setter<TValue>, TSelected>,
|
|
98
98
|
selector?: (state: RateLimiterState) => TSelected,
|
|
99
99
|
): [
|
|
100
100
|
Accessor<TValue>,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createEffect } from 'solid-js'
|
|
2
2
|
import { createRateLimitedSignal } from './createRateLimitedSignal'
|
|
3
|
-
import type { SolidRateLimiter } from './createRateLimiter'
|
|
4
|
-
import type { Accessor, Setter } from 'solid-js'
|
|
5
3
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '
|
|
4
|
+
SolidRateLimiter,
|
|
5
|
+
SolidRateLimiterOptions,
|
|
6
|
+
} from './createRateLimiter'
|
|
7
|
+
import type { Accessor, Setter } from 'solid-js'
|
|
8
|
+
import type { RateLimiterState } from '@tanstack/pacer/rate-limiter'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window.
|
|
@@ -96,7 +96,7 @@ import type {
|
|
|
96
96
|
*/
|
|
97
97
|
export function createRateLimitedValue<TValue, TSelected = {}>(
|
|
98
98
|
value: Accessor<TValue>,
|
|
99
|
-
initialOptions:
|
|
99
|
+
initialOptions: SolidRateLimiterOptions<Setter<TValue>, TSelected>,
|
|
100
100
|
selector?: (state: RateLimiterState) => TSelected,
|
|
101
101
|
): [Accessor<TValue>, SolidRateLimiter<Setter<TValue>, TSelected>] {
|
|
102
102
|
const [rateLimitedValue, setRateLimitedValue, rateLimiter] =
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RateLimiter } from '@tanstack/pacer/rate-limiter'
|
|
2
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
2
3
|
import { useStore } from '@tanstack/solid-store'
|
|
3
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
4
5
|
import type { Store } from '@tanstack/solid-store'
|
|
@@ -9,6 +10,17 @@ import type {
|
|
|
9
10
|
RateLimiterState,
|
|
10
11
|
} from '@tanstack/pacer/rate-limiter'
|
|
11
12
|
|
|
13
|
+
export interface SolidRateLimiterOptions<
|
|
14
|
+
TFn extends AnyFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends RateLimiterOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the owning component unmounts. Receives the rate limiter instance.
|
|
19
|
+
* When provided, replaces the default cleanup; use it to call reset(), add logging, etc.
|
|
20
|
+
*/
|
|
21
|
+
onUnmount?: (rateLimiter: SolidRateLimiter<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
12
24
|
export interface SolidRateLimiter<
|
|
13
25
|
TFn extends AnyFunction,
|
|
14
26
|
TSelected = {},
|
|
@@ -172,14 +184,13 @@ export interface SolidRateLimiter<
|
|
|
172
184
|
*/
|
|
173
185
|
export function createRateLimiter<TFn extends AnyFunction, TSelected = {}>(
|
|
174
186
|
fn: TFn,
|
|
175
|
-
options:
|
|
187
|
+
options: SolidRateLimiterOptions<TFn, TSelected>,
|
|
176
188
|
selector: (state: RateLimiterState) => TSelected = () => ({}) as TSelected,
|
|
177
189
|
): SolidRateLimiter<TFn, TSelected> {
|
|
178
190
|
const mergedOptions = {
|
|
179
191
|
...useDefaultPacerOptions().rateLimiter,
|
|
180
192
|
...options,
|
|
181
|
-
} as
|
|
182
|
-
|
|
193
|
+
} as SolidRateLimiterOptions<TFn, TSelected>
|
|
183
194
|
const rateLimiter = new RateLimiter<TFn>(
|
|
184
195
|
fn,
|
|
185
196
|
mergedOptions,
|
|
@@ -198,6 +209,14 @@ export function createRateLimiter<TFn extends AnyFunction, TSelected = {}>(
|
|
|
198
209
|
|
|
199
210
|
const state = useStore(rateLimiter.store, selector)
|
|
200
211
|
|
|
212
|
+
createEffect(() => {
|
|
213
|
+
onCleanup(() => {
|
|
214
|
+
if (mergedOptions.onUnmount) {
|
|
215
|
+
mergedOptions.onUnmount(rateLimiter)
|
|
216
|
+
}
|
|
217
|
+
})
|
|
218
|
+
})
|
|
219
|
+
|
|
201
220
|
return {
|
|
202
221
|
...rateLimiter,
|
|
203
222
|
state,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createSignal } from 'solid-js'
|
|
2
2
|
import { createThrottler } from './createThrottler'
|
|
3
|
-
import type { SolidThrottler } from './createThrottler'
|
|
3
|
+
import type { SolidThrottler, SolidThrottlerOptions } from './createThrottler'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
6
|
-
ThrottlerOptions,
|
|
7
|
-
ThrottlerState,
|
|
8
|
-
} from '@tanstack/pacer/throttler'
|
|
5
|
+
import type { ThrottlerState } from '@tanstack/pacer/throttler'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A Solid hook that creates a throttled state value that updates at most once within a specified time window.
|
|
@@ -71,7 +68,7 @@ import type {
|
|
|
71
68
|
*/
|
|
72
69
|
export function createThrottledSignal<TValue, TSelected = {}>(
|
|
73
70
|
value: TValue,
|
|
74
|
-
initialOptions:
|
|
71
|
+
initialOptions: SolidThrottlerOptions<Setter<TValue>, TSelected>,
|
|
75
72
|
selector?: (state: ThrottlerState<Setter<TValue>>) => TSelected,
|
|
76
73
|
): [
|
|
77
74
|
Accessor<TValue>,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { createEffect } from 'solid-js'
|
|
2
2
|
import { createThrottledSignal } from './createThrottledSignal'
|
|
3
|
-
import type { SolidThrottler } from './createThrottler'
|
|
3
|
+
import type { SolidThrottler, SolidThrottlerOptions } from './createThrottler'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
6
|
-
ThrottlerOptions,
|
|
7
|
-
ThrottlerState,
|
|
8
|
-
} from '@tanstack/pacer/throttler'
|
|
5
|
+
import type { ThrottlerState } from '@tanstack/pacer/throttler'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A high-level Solid hook that creates a throttled version of a value that updates at most once within a specified time window.
|
|
@@ -68,7 +65,7 @@ import type {
|
|
|
68
65
|
*/
|
|
69
66
|
export function createThrottledValue<TValue, TSelected = {}>(
|
|
70
67
|
value: Accessor<TValue>,
|
|
71
|
-
initialOptions:
|
|
68
|
+
initialOptions: SolidThrottlerOptions<Setter<TValue>, TSelected>,
|
|
72
69
|
selector?: (state: ThrottlerState<Setter<TValue>>) => TSelected,
|
|
73
70
|
): [Accessor<TValue>, SolidThrottler<Setter<TValue>, TSelected>] {
|
|
74
71
|
const [throttledValue, setThrottledValue, throttler] = createThrottledSignal(
|
|
@@ -10,6 +10,17 @@ import type {
|
|
|
10
10
|
ThrottlerState,
|
|
11
11
|
} from '@tanstack/pacer/throttler'
|
|
12
12
|
|
|
13
|
+
export interface SolidThrottlerOptions<
|
|
14
|
+
TFn extends AnyFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends ThrottlerOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the owning component unmounts. Receives the throttler instance.
|
|
19
|
+
* When provided, replaces the default cleanup (cancel); use it to call flush(), reset(), cancel(), add logging, etc.
|
|
20
|
+
*/
|
|
21
|
+
onUnmount?: (throttler: SolidThrottler<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
export interface SolidThrottler<
|
|
14
25
|
TFn extends AnyFunction,
|
|
15
26
|
TSelected = {},
|
|
@@ -87,6 +98,18 @@ export interface SolidThrottler<
|
|
|
87
98
|
* - `nextExecutionTime`: Timestamp of the next allowed execution
|
|
88
99
|
* - `status`: Current execution status ('disabled' | 'idle' | 'pending')
|
|
89
100
|
*
|
|
101
|
+
* ## Unmount behavior
|
|
102
|
+
*
|
|
103
|
+
* By default, the primitive cancels any pending execution when the owning component unmounts.
|
|
104
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending work instead:
|
|
105
|
+
*
|
|
106
|
+
* ```tsx
|
|
107
|
+
* const throttler = createThrottler(fn, {
|
|
108
|
+
* wait: 1000,
|
|
109
|
+
* onUnmount: (t) => t.flush()
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
90
113
|
* @example
|
|
91
114
|
* ```tsx
|
|
92
115
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -135,14 +158,13 @@ export interface SolidThrottler<
|
|
|
135
158
|
*/
|
|
136
159
|
export function createThrottler<TFn extends AnyFunction, TSelected = {}>(
|
|
137
160
|
fn: TFn,
|
|
138
|
-
options:
|
|
161
|
+
options: SolidThrottlerOptions<TFn, TSelected>,
|
|
139
162
|
selector: (state: ThrottlerState<TFn>) => TSelected = () => ({}) as TSelected,
|
|
140
163
|
): SolidThrottler<TFn, TSelected> {
|
|
141
164
|
const mergedOptions = {
|
|
142
165
|
...useDefaultPacerOptions().throttler,
|
|
143
166
|
...options,
|
|
144
|
-
} as
|
|
145
|
-
|
|
167
|
+
} as SolidThrottlerOptions<TFn, TSelected>
|
|
146
168
|
const asyncThrottler = new Throttler<TFn>(
|
|
147
169
|
fn,
|
|
148
170
|
mergedOptions,
|
|
@@ -163,7 +185,11 @@ export function createThrottler<TFn extends AnyFunction, TSelected = {}>(
|
|
|
163
185
|
|
|
164
186
|
createEffect(() => {
|
|
165
187
|
onCleanup(() => {
|
|
166
|
-
|
|
188
|
+
if (mergedOptions.onUnmount) {
|
|
189
|
+
mergedOptions.onUnmount(asyncThrottler)
|
|
190
|
+
} else {
|
|
191
|
+
asyncThrottler.cancel()
|
|
192
|
+
}
|
|
167
193
|
})
|
|
168
194
|
})
|
|
169
195
|
|