@tanstack/solid-pacer 0.2.0 → 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/dist/cjs/async-debouncer/createAsyncDebouncer.cjs +22 -7
- package/dist/cjs/async-debouncer/createAsyncDebouncer.cjs.map +1 -1
- package/dist/cjs/async-debouncer/createAsyncDebouncer.d.cts +6 -3
- package/dist/cjs/async-queuer/createAsyncQueuer.cjs.map +1 -1
- package/dist/cjs/async-queuer/createAsyncQueuer.d.cts +5 -1
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs +20 -9
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs.map +1 -1
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.d.cts +5 -3
- package/dist/cjs/async-throttler/createAsyncThrottler.cjs +32 -10
- package/dist/cjs/async-throttler/createAsyncThrottler.cjs.map +1 -1
- package/dist/cjs/async-throttler/createAsyncThrottler.d.cts +7 -3
- package/dist/cjs/debouncer/createDebouncedSignal.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncedSignal.d.cts +1 -5
- package/dist/cjs/debouncer/createDebouncedValue.cjs +0 -3
- package/dist/cjs/debouncer/createDebouncedValue.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncedValue.d.cts +5 -11
- package/dist/cjs/debouncer/createDebouncer.cjs +7 -2
- package/dist/cjs/debouncer/createDebouncer.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncer.d.cts +2 -2
- package/dist/cjs/queuer/createQueuer.cjs +2 -2
- package/dist/cjs/queuer/createQueuer.cjs.map +1 -1
- package/dist/cjs/queuer/createQueuer.d.cts +4 -0
- package/dist/cjs/rate-limiter/createRateLimitedSignal.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimitedSignal.d.cts +1 -5
- package/dist/cjs/rate-limiter/createRateLimitedValue.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimitedValue.d.cts +9 -20
- package/dist/cjs/rate-limiter/createRateLimiter.cjs +4 -2
- package/dist/cjs/rate-limiter/createRateLimiter.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimiter.d.cts +2 -2
- package/dist/cjs/throttler/createThrottledSignal.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottledSignal.d.cts +1 -5
- package/dist/cjs/throttler/createThrottledValue.cjs +0 -3
- package/dist/cjs/throttler/createThrottledValue.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottledValue.d.cts +10 -14
- package/dist/cjs/throttler/createThrottler.cjs +7 -2
- package/dist/cjs/throttler/createThrottler.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottler.d.cts +2 -2
- package/dist/esm/async-debouncer/createAsyncDebouncer.d.ts +6 -3
- package/dist/esm/async-debouncer/createAsyncDebouncer.js +22 -7
- package/dist/esm/async-debouncer/createAsyncDebouncer.js.map +1 -1
- package/dist/esm/async-queuer/createAsyncQueuer.d.ts +5 -1
- package/dist/esm/async-queuer/createAsyncQueuer.js.map +1 -1
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.d.ts +5 -3
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js +20 -9
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js.map +1 -1
- package/dist/esm/async-throttler/createAsyncThrottler.d.ts +7 -3
- package/dist/esm/async-throttler/createAsyncThrottler.js +32 -10
- package/dist/esm/async-throttler/createAsyncThrottler.js.map +1 -1
- package/dist/esm/debouncer/createDebouncedSignal.d.ts +1 -5
- package/dist/esm/debouncer/createDebouncedSignal.js.map +1 -1
- package/dist/esm/debouncer/createDebouncedValue.d.ts +5 -11
- package/dist/esm/debouncer/createDebouncedValue.js +1 -4
- package/dist/esm/debouncer/createDebouncedValue.js.map +1 -1
- package/dist/esm/debouncer/createDebouncer.d.ts +2 -2
- package/dist/esm/debouncer/createDebouncer.js +8 -3
- package/dist/esm/debouncer/createDebouncer.js.map +1 -1
- package/dist/esm/queuer/createQueuer.d.ts +4 -0
- package/dist/esm/queuer/createQueuer.js +2 -2
- package/dist/esm/queuer/createQueuer.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimitedSignal.d.ts +1 -5
- package/dist/esm/rate-limiter/createRateLimitedSignal.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimitedValue.d.ts +9 -20
- package/dist/esm/rate-limiter/createRateLimitedValue.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimiter.d.ts +2 -2
- package/dist/esm/rate-limiter/createRateLimiter.js +4 -2
- package/dist/esm/rate-limiter/createRateLimiter.js.map +1 -1
- package/dist/esm/throttler/createThrottledSignal.d.ts +1 -5
- package/dist/esm/throttler/createThrottledSignal.js.map +1 -1
- package/dist/esm/throttler/createThrottledValue.d.ts +10 -14
- package/dist/esm/throttler/createThrottledValue.js +1 -4
- package/dist/esm/throttler/createThrottledValue.js.map +1 -1
- package/dist/esm/throttler/createThrottler.d.ts +2 -2
- package/dist/esm/throttler/createThrottler.js +8 -3
- package/dist/esm/throttler/createThrottler.js.map +1 -1
- package/package.json +2 -2
- package/src/async-debouncer/createAsyncDebouncer.ts +40 -24
- package/src/async-queuer/createAsyncQueuer.ts +6 -2
- package/src/async-rate-limiter/createAsyncRateLimiter.ts +34 -26
- package/src/async-throttler/createAsyncThrottler.ts +49 -24
- package/src/debouncer/createDebouncedSignal.ts +2 -6
- package/src/debouncer/createDebouncedValue.ts +7 -16
- package/src/debouncer/createDebouncer.ts +16 -15
- package/src/queuer/createQueuer.ts +7 -3
- package/src/rate-limiter/createRateLimitedSignal.ts +2 -6
- package/src/rate-limiter/createRateLimitedValue.ts +10 -21
- package/src/rate-limiter/createRateLimiter.ts +14 -15
- package/src/throttler/createThrottledSignal.ts +2 -6
- package/src/throttler/createThrottledValue.ts +12 -19
- package/src/throttler/createThrottler.ts +17 -16
|
@@ -18,7 +18,9 @@ import type { RateLimiterOptions } from '@tanstack/pacer/rate-limiter'
|
|
|
18
18
|
*
|
|
19
19
|
* Rate limiting should primarily be used when you need to enforce strict limits, like API rate limits.
|
|
20
20
|
*
|
|
21
|
-
* The hook returns
|
|
21
|
+
* The hook returns a tuple containing:
|
|
22
|
+
* - An accessor function that provides the rate-limited value
|
|
23
|
+
* - The rate limiter instance with control methods
|
|
22
24
|
*
|
|
23
25
|
* For more direct control over rate limiting behavior without Solid state management,
|
|
24
26
|
* consider using the lower-level createRateLimiter hook instead.
|
|
@@ -26,35 +28,22 @@ import type { RateLimiterOptions } from '@tanstack/pacer/rate-limiter'
|
|
|
26
28
|
* @example
|
|
27
29
|
* ```tsx
|
|
28
30
|
* // Basic rate limiting - update at most 5 times per minute
|
|
29
|
-
* const [rateLimitedValue] = createRateLimitedValue(rawValue, {
|
|
31
|
+
* const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, {
|
|
30
32
|
* limit: 5,
|
|
31
33
|
* window: 60000
|
|
32
34
|
* });
|
|
33
35
|
*
|
|
34
|
-
* //
|
|
35
|
-
*
|
|
36
|
-
* limit: 3,
|
|
37
|
-
* window: 5000,
|
|
38
|
-
* onReject: (rateLimiter) => {
|
|
39
|
-
* console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
|
|
40
|
-
* }
|
|
41
|
-
* });
|
|
36
|
+
* // Use the rate-limited value
|
|
37
|
+
* console.log(rateLimitedValue()); // Access the current rate-limited value
|
|
42
38
|
*
|
|
43
|
-
* //
|
|
44
|
-
*
|
|
45
|
-
* const remaining = rateLimiter.remainingInWindow();
|
|
46
|
-
* if (remaining > 0) {
|
|
47
|
-
* console.log(`${remaining} updates remaining in this window`);
|
|
48
|
-
* } else {
|
|
49
|
-
* console.log('Rate limit reached for this window');
|
|
50
|
-
* }
|
|
51
|
-
* };
|
|
39
|
+
* // Control the rate limiter
|
|
40
|
+
* rateLimiter.reset(); // Reset the rate limit window
|
|
52
41
|
* ```
|
|
53
42
|
*/
|
|
54
43
|
export function createRateLimitedValue<TValue>(
|
|
55
44
|
value: Accessor<TValue>,
|
|
56
|
-
initialOptions: RateLimiterOptions<Setter<TValue
|
|
57
|
-
): [Accessor<TValue>, SolidRateLimiter<Setter<TValue
|
|
45
|
+
initialOptions: RateLimiterOptions<Setter<TValue>>,
|
|
46
|
+
): [Accessor<TValue>, SolidRateLimiter<Setter<TValue>>] {
|
|
58
47
|
const [rateLimitedValue, setRateLimitedValue, rateLimiter] =
|
|
59
48
|
createRateLimitedSignal(value(), initialOptions)
|
|
60
49
|
|
|
@@ -5,11 +5,9 @@ import type { Accessor } from 'solid-js'
|
|
|
5
5
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
6
6
|
import type { RateLimiterOptions } from '@tanstack/pacer/rate-limiter'
|
|
7
7
|
|
|
8
|
-
export interface SolidRateLimiter<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
> extends Omit<
|
|
12
|
-
RateLimiter<TFn, TArgs>,
|
|
8
|
+
export interface SolidRateLimiter<TFn extends AnyFunction>
|
|
9
|
+
extends Omit<
|
|
10
|
+
RateLimiter<TFn>,
|
|
13
11
|
| 'getExecutionCount'
|
|
14
12
|
| 'getMsUntilNextWindow'
|
|
15
13
|
| 'getRejectionCount'
|
|
@@ -60,14 +58,13 @@ export interface SolidRateLimiter<
|
|
|
60
58
|
* console.log('Next window in:', rateLimiter.msUntilNextWindow());
|
|
61
59
|
* ```
|
|
62
60
|
*/
|
|
63
|
-
export function createRateLimiter<
|
|
64
|
-
TFn extends AnyFunction,
|
|
65
|
-
TArgs extends Parameters<TFn>,
|
|
66
|
-
>(
|
|
61
|
+
export function createRateLimiter<TFn extends AnyFunction>(
|
|
67
62
|
fn: TFn,
|
|
68
|
-
initialOptions: RateLimiterOptions<TFn
|
|
69
|
-
): SolidRateLimiter<TFn
|
|
70
|
-
const rateLimiter =
|
|
63
|
+
initialOptions: RateLimiterOptions<TFn>,
|
|
64
|
+
): SolidRateLimiter<TFn> {
|
|
65
|
+
const rateLimiter = bindInstanceMethods(
|
|
66
|
+
new RateLimiter<TFn>(fn, initialOptions),
|
|
67
|
+
)
|
|
71
68
|
|
|
72
69
|
const [executionCount, setExecutionCount] = createSignal(
|
|
73
70
|
rateLimiter.getExecutionCount(),
|
|
@@ -82,13 +79,14 @@ export function createRateLimiter<
|
|
|
82
79
|
rateLimiter.getMsUntilNextWindow(),
|
|
83
80
|
)
|
|
84
81
|
|
|
85
|
-
function setOptions(newOptions: Partial<RateLimiterOptions<TFn
|
|
82
|
+
function setOptions(newOptions: Partial<RateLimiterOptions<TFn>>) {
|
|
86
83
|
rateLimiter.setOptions({
|
|
87
84
|
...newOptions,
|
|
88
85
|
onExecute: (rateLimiter) => {
|
|
89
86
|
setExecutionCount(rateLimiter.getExecutionCount())
|
|
90
87
|
setRemainingInWindow(rateLimiter.getRemainingInWindow())
|
|
91
88
|
setMsUntilNextWindow(rateLimiter.getMsUntilNextWindow())
|
|
89
|
+
|
|
92
90
|
const onExecute = newOptions.onExecute ?? initialOptions.onExecute
|
|
93
91
|
onExecute?.(rateLimiter)
|
|
94
92
|
},
|
|
@@ -96,6 +94,7 @@ export function createRateLimiter<
|
|
|
96
94
|
setRejectionCount(rateLimiter.getRejectionCount())
|
|
97
95
|
setRemainingInWindow(rateLimiter.getRemainingInWindow())
|
|
98
96
|
setMsUntilNextWindow(rateLimiter.getMsUntilNextWindow())
|
|
97
|
+
|
|
99
98
|
const onReject = newOptions.onReject ?? initialOptions.onReject
|
|
100
99
|
onReject?.(rateLimiter)
|
|
101
100
|
},
|
|
@@ -105,11 +104,11 @@ export function createRateLimiter<
|
|
|
105
104
|
setOptions(initialOptions)
|
|
106
105
|
|
|
107
106
|
return {
|
|
108
|
-
...
|
|
107
|
+
...rateLimiter,
|
|
109
108
|
executionCount,
|
|
110
109
|
rejectionCount,
|
|
111
110
|
remainingInWindow,
|
|
112
111
|
msUntilNextWindow,
|
|
113
112
|
setOptions,
|
|
114
|
-
}
|
|
113
|
+
} as SolidRateLimiter<TFn>
|
|
115
114
|
}
|
|
@@ -40,12 +40,8 @@ import type { ThrottlerOptions } from '@tanstack/pacer/throttler'
|
|
|
40
40
|
*/
|
|
41
41
|
export function createThrottledSignal<TValue>(
|
|
42
42
|
value: TValue,
|
|
43
|
-
initialOptions: ThrottlerOptions<Setter<TValue
|
|
44
|
-
): [
|
|
45
|
-
Accessor<TValue>,
|
|
46
|
-
Setter<TValue>,
|
|
47
|
-
SolidThrottler<Setter<TValue>, [Accessor<TValue>]>,
|
|
48
|
-
] {
|
|
43
|
+
initialOptions: ThrottlerOptions<Setter<TValue>>,
|
|
44
|
+
): [Accessor<TValue>, Setter<TValue>, SolidThrottler<Setter<TValue>>] {
|
|
49
45
|
const [throttledValue, setThrottledValue] = createSignal<TValue>(value)
|
|
50
46
|
const throttler = createThrottler(setThrottledValue, initialOptions)
|
|
51
47
|
return [throttledValue, throttler.maybeExecute as Setter<TValue>, throttler]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createEffect
|
|
1
|
+
import { createEffect } from 'solid-js'
|
|
2
2
|
import { createThrottledSignal } from './createThrottledSignal'
|
|
3
3
|
import type { SolidThrottler } from './createThrottler'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
@@ -11,7 +11,10 @@ import type { ThrottlerOptions } from '@tanstack/pacer/throttler'
|
|
|
11
11
|
* Throttling ensures the value updates occur at a controlled rate regardless of how frequently the input value changes.
|
|
12
12
|
* This is useful for rate-limiting expensive re-renders or API calls that depend on rapidly changing values.
|
|
13
13
|
*
|
|
14
|
-
* The hook returns
|
|
14
|
+
* The hook returns a tuple containing:
|
|
15
|
+
* - An accessor function that provides the throttled value
|
|
16
|
+
* - The throttler instance with control methods
|
|
17
|
+
*
|
|
15
18
|
* The throttled value will update according to the leading/trailing edge behavior specified in the options.
|
|
16
19
|
*
|
|
17
20
|
* For more direct control over throttling behavior without Solid state management,
|
|
@@ -20,26 +23,19 @@ import type { ThrottlerOptions } from '@tanstack/pacer/throttler'
|
|
|
20
23
|
* @example
|
|
21
24
|
* ```tsx
|
|
22
25
|
* // Basic throttling - update at most once per second
|
|
23
|
-
* const [throttledValue] = createThrottledValue(rawValue, { wait: 1000 });
|
|
26
|
+
* const [throttledValue, throttler] = createThrottledValue(rawValue, { wait: 1000 });
|
|
24
27
|
*
|
|
25
|
-
* //
|
|
26
|
-
*
|
|
27
|
-
* wait: 1000,
|
|
28
|
-
* leading: true, // Update immediately on first change
|
|
29
|
-
* trailing: false // Skip trailing edge updates
|
|
30
|
-
* });
|
|
28
|
+
* // Use the throttled value
|
|
29
|
+
* console.log(throttledValue()); // Access the current throttled value
|
|
31
30
|
*
|
|
32
|
-
* //
|
|
33
|
-
*
|
|
34
|
-
* console.log('Is pending:', throttler.isPending());
|
|
35
|
-
* console.log('Last execution:', throttler.lastExecutionTime());
|
|
36
|
-
* console.log('Next execution:', throttler.nextExecutionTime());
|
|
31
|
+
* // Control the throttler
|
|
32
|
+
* throttler.cancel(); // Cancel any pending updates
|
|
37
33
|
* ```
|
|
38
34
|
*/
|
|
39
35
|
export function createThrottledValue<TValue>(
|
|
40
36
|
value: Accessor<TValue>,
|
|
41
|
-
initialOptions: ThrottlerOptions<Setter<TValue
|
|
42
|
-
): [Accessor<TValue>, SolidThrottler<Setter<TValue
|
|
37
|
+
initialOptions: ThrottlerOptions<Setter<TValue>>,
|
|
38
|
+
): [Accessor<TValue>, SolidThrottler<Setter<TValue>>] {
|
|
43
39
|
const [throttledValue, setThrottledValue, throttler] = createThrottledSignal(
|
|
44
40
|
value(),
|
|
45
41
|
initialOptions,
|
|
@@ -47,9 +43,6 @@ export function createThrottledValue<TValue>(
|
|
|
47
43
|
|
|
48
44
|
createEffect(() => {
|
|
49
45
|
setThrottledValue(value() as any)
|
|
50
|
-
onCleanup(() => {
|
|
51
|
-
throttler.cancel()
|
|
52
|
-
})
|
|
53
46
|
})
|
|
54
47
|
|
|
55
48
|
return [throttledValue, throttler]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Throttler } from '@tanstack/pacer/throttler'
|
|
2
|
-
import { createSignal } from 'solid-js'
|
|
2
|
+
import { createEffect, createSignal, onCleanup } from 'solid-js'
|
|
3
3
|
import { bindInstanceMethods } from '@tanstack/pacer/utils'
|
|
4
4
|
import type { Accessor } from 'solid-js'
|
|
5
5
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
@@ -8,11 +8,9 @@ import type { ThrottlerOptions } from '@tanstack/pacer/throttler'
|
|
|
8
8
|
/**
|
|
9
9
|
* An extension of the Throttler class that adds Solid signals to access the internal state of the throttler
|
|
10
10
|
*/
|
|
11
|
-
export interface SolidThrottler<
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
> extends Omit<
|
|
15
|
-
Throttler<TFn, TArgs>,
|
|
11
|
+
export interface SolidThrottler<TFn extends AnyFunction>
|
|
12
|
+
extends Omit<
|
|
13
|
+
Throttler<TFn>,
|
|
16
14
|
| 'getExecutionCount'
|
|
17
15
|
| 'getIsPending'
|
|
18
16
|
| 'getLastExecutionTime'
|
|
@@ -58,14 +56,11 @@ export interface SolidThrottler<
|
|
|
58
56
|
* console.log(throttler.nextExecutionTime()); // timestamp of next allowed execution
|
|
59
57
|
* ```
|
|
60
58
|
*/
|
|
61
|
-
export function createThrottler<
|
|
62
|
-
TFn extends AnyFunction,
|
|
63
|
-
TArgs extends Parameters<TFn>,
|
|
64
|
-
>(
|
|
59
|
+
export function createThrottler<TFn extends AnyFunction>(
|
|
65
60
|
fn: TFn,
|
|
66
|
-
initialOptions: ThrottlerOptions<TFn
|
|
67
|
-
): SolidThrottler<TFn
|
|
68
|
-
const throttler = new Throttler<TFn
|
|
61
|
+
initialOptions: ThrottlerOptions<TFn>,
|
|
62
|
+
): SolidThrottler<TFn> {
|
|
63
|
+
const throttler = bindInstanceMethods(new Throttler<TFn>(fn, initialOptions))
|
|
69
64
|
|
|
70
65
|
const [executionCount, setExecutionCount] = createSignal(
|
|
71
66
|
throttler.getExecutionCount(),
|
|
@@ -78,7 +73,7 @@ export function createThrottler<
|
|
|
78
73
|
throttler.getNextExecutionTime(),
|
|
79
74
|
)
|
|
80
75
|
|
|
81
|
-
function setOptions(newOptions: Partial<ThrottlerOptions<TFn
|
|
76
|
+
function setOptions(newOptions: Partial<ThrottlerOptions<TFn>>) {
|
|
82
77
|
throttler.setOptions({
|
|
83
78
|
...newOptions,
|
|
84
79
|
onExecute: (throttler) => {
|
|
@@ -95,12 +90,18 @@ export function createThrottler<
|
|
|
95
90
|
|
|
96
91
|
setOptions(initialOptions)
|
|
97
92
|
|
|
93
|
+
createEffect(() => {
|
|
94
|
+
onCleanup(() => {
|
|
95
|
+
throttler.cancel()
|
|
96
|
+
})
|
|
97
|
+
})
|
|
98
|
+
|
|
98
99
|
return {
|
|
99
|
-
...
|
|
100
|
+
...throttler,
|
|
100
101
|
executionCount,
|
|
101
102
|
isPending,
|
|
102
103
|
lastExecutionTime,
|
|
103
104
|
nextExecutionTime,
|
|
104
105
|
setOptions,
|
|
105
|
-
}
|
|
106
|
+
} as SolidThrottler<TFn>
|
|
106
107
|
}
|