@tanstack/preact-pacer 0.19.4 → 0.21.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 +6 -6
- 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-batcher/useAsyncBatchedCallback.cjs +2 -2
- package/dist/async-batcher/useAsyncBatchedCallback.cjs.map +1 -1
- package/dist/async-batcher/useAsyncBatchedCallback.d.cts +2 -3
- package/dist/async-batcher/useAsyncBatchedCallback.d.ts +2 -3
- package/dist/async-batcher/useAsyncBatchedCallback.js +2 -2
- package/dist/async-batcher/useAsyncBatchedCallback.js.map +1 -1
- package/dist/async-batcher/useAsyncBatcher.cjs +30 -2
- package/dist/async-batcher/useAsyncBatcher.cjs.map +1 -1
- package/dist/async-batcher/useAsyncBatcher.d.cts +28 -2
- package/dist/async-batcher/useAsyncBatcher.d.ts +28 -2
- package/dist/async-batcher/useAsyncBatcher.js +32 -4
- package/dist/async-batcher/useAsyncBatcher.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-debouncer/useAsyncDebouncedCallback.cjs.map +1 -1
- package/dist/async-debouncer/useAsyncDebouncedCallback.d.cts +2 -2
- package/dist/async-debouncer/useAsyncDebouncedCallback.d.ts +2 -2
- package/dist/async-debouncer/useAsyncDebouncedCallback.js.map +1 -1
- package/dist/async-debouncer/useAsyncDebouncer.cjs +26 -4
- package/dist/async-debouncer/useAsyncDebouncer.cjs.map +1 -1
- package/dist/async-debouncer/useAsyncDebouncer.d.cts +28 -3
- package/dist/async-debouncer/useAsyncDebouncer.d.ts +27 -2
- package/dist/async-debouncer/useAsyncDebouncer.js +27 -5
- package/dist/async-debouncer/useAsyncDebouncer.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-queuer/useAsyncQueuedState.cjs.map +1 -1
- package/dist/async-queuer/useAsyncQueuedState.d.cts +3 -3
- package/dist/async-queuer/useAsyncQueuedState.d.ts +3 -3
- package/dist/async-queuer/useAsyncQueuedState.js.map +1 -1
- package/dist/async-queuer/useAsyncQueuer.cjs +30 -2
- package/dist/async-queuer/useAsyncQueuer.cjs.map +1 -1
- package/dist/async-queuer/useAsyncQueuer.d.cts +28 -2
- package/dist/async-queuer/useAsyncQueuer.d.ts +28 -2
- package/dist/async-queuer/useAsyncQueuer.js +32 -4
- package/dist/async-queuer/useAsyncQueuer.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-rate-limiter/useAsyncRateLimitedCallback.cjs.map +1 -1
- package/dist/async-rate-limiter/useAsyncRateLimitedCallback.d.cts +2 -2
- package/dist/async-rate-limiter/useAsyncRateLimitedCallback.d.ts +2 -2
- package/dist/async-rate-limiter/useAsyncRateLimitedCallback.js.map +1 -1
- package/dist/async-rate-limiter/useAsyncRateLimiter.cjs +14 -2
- package/dist/async-rate-limiter/useAsyncRateLimiter.cjs.map +1 -1
- package/dist/async-rate-limiter/useAsyncRateLimiter.d.cts +15 -2
- package/dist/async-rate-limiter/useAsyncRateLimiter.d.ts +15 -2
- package/dist/async-rate-limiter/useAsyncRateLimiter.js +16 -4
- package/dist/async-rate-limiter/useAsyncRateLimiter.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/async-throttler/useAsyncThrottledCallback.cjs.map +1 -1
- package/dist/async-throttler/useAsyncThrottledCallback.d.cts +2 -2
- package/dist/async-throttler/useAsyncThrottledCallback.d.ts +2 -2
- package/dist/async-throttler/useAsyncThrottledCallback.js.map +1 -1
- package/dist/async-throttler/useAsyncThrottler.cjs +28 -4
- package/dist/async-throttler/useAsyncThrottler.cjs.map +1 -1
- package/dist/async-throttler/useAsyncThrottler.d.cts +27 -2
- package/dist/async-throttler/useAsyncThrottler.d.ts +27 -2
- package/dist/async-throttler/useAsyncThrottler.js +29 -5
- package/dist/async-throttler/useAsyncThrottler.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/batcher/useBatchedCallback.cjs +1 -1
- package/dist/batcher/useBatchedCallback.cjs.map +1 -1
- package/dist/batcher/useBatchedCallback.d.cts +2 -3
- package/dist/batcher/useBatchedCallback.d.ts +2 -3
- package/dist/batcher/useBatchedCallback.js +1 -1
- package/dist/batcher/useBatchedCallback.js.map +1 -1
- package/dist/batcher/useBatcher.cjs +21 -2
- package/dist/batcher/useBatcher.cjs.map +1 -1
- package/dist/batcher/useBatcher.d.cts +22 -2
- package/dist/batcher/useBatcher.d.ts +22 -2
- package/dist/batcher/useBatcher.js +23 -4
- package/dist/batcher/useBatcher.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/debouncer/useDebouncedCallback.cjs.map +1 -1
- package/dist/debouncer/useDebouncedCallback.d.cts +2 -2
- package/dist/debouncer/useDebouncedCallback.d.ts +2 -2
- package/dist/debouncer/useDebouncedCallback.js.map +1 -1
- package/dist/debouncer/useDebouncedState.cjs.map +1 -1
- package/dist/debouncer/useDebouncedState.d.cts +3 -3
- package/dist/debouncer/useDebouncedState.d.ts +3 -3
- package/dist/debouncer/useDebouncedState.js.map +1 -1
- package/dist/debouncer/useDebouncedValue.cjs.map +1 -1
- package/dist/debouncer/useDebouncedValue.d.cts +3 -3
- package/dist/debouncer/useDebouncedValue.d.ts +3 -3
- package/dist/debouncer/useDebouncedValue.js.map +1 -1
- package/dist/debouncer/useDebouncer.cjs +17 -4
- package/dist/debouncer/useDebouncer.cjs.map +1 -1
- package/dist/debouncer/useDebouncer.d.cts +21 -2
- package/dist/debouncer/useDebouncer.d.ts +21 -2
- package/dist/debouncer/useDebouncer.js +18 -5
- package/dist/debouncer/useDebouncer.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +11 -11
- package/dist/index.d.ts +11 -11
- package/dist/provider/PacerProvider.cjs.map +1 -1
- package/dist/provider/PacerProvider.d.cts +2 -2
- package/dist/provider/PacerProvider.d.ts +2 -2
- package/dist/provider/PacerProvider.js.map +1 -1
- package/dist/provider/index.cjs +1 -0
- 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/queuer/useQueuedState.cjs.map +1 -1
- package/dist/queuer/useQueuedState.d.cts +3 -3
- package/dist/queuer/useQueuedState.d.ts +3 -3
- package/dist/queuer/useQueuedState.js.map +1 -1
- package/dist/queuer/useQueuedValue.cjs.map +1 -1
- package/dist/queuer/useQueuedValue.d.cts +3 -3
- package/dist/queuer/useQueuedValue.d.ts +3 -3
- package/dist/queuer/useQueuedValue.js.map +1 -1
- package/dist/queuer/useQueuer.cjs +21 -2
- package/dist/queuer/useQueuer.cjs.map +1 -1
- package/dist/queuer/useQueuer.d.cts +22 -2
- package/dist/queuer/useQueuer.d.ts +22 -2
- package/dist/queuer/useQueuer.js +23 -4
- package/dist/queuer/useQueuer.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/rate-limiter/useRateLimitedCallback.cjs.map +1 -1
- package/dist/rate-limiter/useRateLimitedCallback.d.cts +2 -2
- package/dist/rate-limiter/useRateLimitedCallback.d.ts +2 -2
- package/dist/rate-limiter/useRateLimitedCallback.js.map +1 -1
- package/dist/rate-limiter/useRateLimitedState.cjs.map +1 -1
- package/dist/rate-limiter/useRateLimitedState.d.cts +3 -3
- package/dist/rate-limiter/useRateLimitedState.d.ts +3 -3
- package/dist/rate-limiter/useRateLimitedState.js.map +1 -1
- package/dist/rate-limiter/useRateLimitedValue.cjs.map +1 -1
- package/dist/rate-limiter/useRateLimitedValue.d.cts +3 -3
- package/dist/rate-limiter/useRateLimitedValue.d.ts +3 -3
- package/dist/rate-limiter/useRateLimitedValue.js.map +1 -1
- package/dist/rate-limiter/useRateLimiter.cjs +7 -2
- package/dist/rate-limiter/useRateLimiter.cjs.map +1 -1
- package/dist/rate-limiter/useRateLimiter.d.cts +9 -2
- package/dist/rate-limiter/useRateLimiter.d.ts +9 -2
- package/dist/rate-limiter/useRateLimiter.js +9 -4
- package/dist/rate-limiter/useRateLimiter.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/dist/throttler/useThrottledCallback.cjs.map +1 -1
- package/dist/throttler/useThrottledCallback.d.cts +2 -2
- package/dist/throttler/useThrottledCallback.d.ts +2 -2
- package/dist/throttler/useThrottledCallback.js.map +1 -1
- package/dist/throttler/useThrottledState.cjs.map +1 -1
- package/dist/throttler/useThrottledState.d.cts +3 -3
- package/dist/throttler/useThrottledState.d.ts +3 -3
- package/dist/throttler/useThrottledState.js.map +1 -1
- package/dist/throttler/useThrottledValue.cjs.map +1 -1
- package/dist/throttler/useThrottledValue.d.cts +3 -3
- package/dist/throttler/useThrottledValue.d.ts +3 -3
- package/dist/throttler/useThrottledValue.js.map +1 -1
- package/dist/throttler/useThrottler.cjs +17 -4
- package/dist/throttler/useThrottler.cjs.map +1 -1
- package/dist/throttler/useThrottler.d.cts +21 -2
- package/dist/throttler/useThrottler.d.ts +21 -2
- package/dist/throttler/useThrottler.js +18 -5
- package/dist/throttler/useThrottler.js.map +1 -1
- package/package.json +36 -35
- package/src/async-batcher/useAsyncBatchedCallback.ts +7 -8
- package/src/async-batcher/useAsyncBatcher.ts +51 -7
- package/src/async-debouncer/useAsyncDebouncedCallback.ts +2 -2
- package/src/async-debouncer/useAsyncDebouncer.ts +45 -8
- package/src/async-queuer/useAsyncQueuedState.ts +5 -5
- package/src/async-queuer/useAsyncQueuer.ts +51 -7
- package/src/async-rate-limiter/useAsyncRateLimitedCallback.ts +2 -2
- package/src/async-rate-limiter/useAsyncRateLimiter.ts +37 -6
- package/src/async-throttler/useAsyncThrottledCallback.ts +2 -2
- package/src/async-throttler/useAsyncThrottler.ts +47 -8
- package/src/batcher/useBatchedCallback.ts +6 -10
- package/src/batcher/useBatcher.ts +44 -6
- package/src/debouncer/useDebouncedCallback.ts +2 -2
- package/src/debouncer/useDebouncedState.ts +3 -6
- package/src/debouncer/useDebouncedValue.ts +3 -6
- package/src/debouncer/useDebouncer.ts +38 -8
- package/src/queuer/useQueuedState.ts +3 -3
- package/src/queuer/useQueuedValue.ts +3 -3
- package/src/queuer/useQueuer.ts +44 -6
- package/src/rate-limiter/useRateLimitedCallback.ts +2 -2
- package/src/rate-limiter/useRateLimitedState.ts +6 -6
- package/src/rate-limiter/useRateLimitedValue.ts +6 -6
- package/src/rate-limiter/useRateLimiter.ts +29 -7
- package/src/throttler/useThrottledCallback.ts +2 -2
- package/src/throttler/useThrottledState.ts +3 -6
- package/src/throttler/useThrottledValue.ts +3 -6
- package/src/throttler/useThrottler.ts +38 -8
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { useEffect } from 'preact/hooks'
|
|
2
2
|
import { useRateLimitedState } from './useRateLimitedState'
|
|
3
|
-
import type { Dispatch, StateUpdater } from 'preact/hooks'
|
|
4
|
-
import type { PreactRateLimiter } from './useRateLimiter'
|
|
5
3
|
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
} from '
|
|
4
|
+
PreactRateLimiter,
|
|
5
|
+
PreactRateLimiterOptions,
|
|
6
|
+
} from './useRateLimiter'
|
|
7
|
+
import type { Dispatch, StateUpdater } from 'preact/hooks'
|
|
8
|
+
import type { RateLimiterState } from '@tanstack/pacer/rate-limiter'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* A high-level Preact 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 useRateLimitedValue<TValue, TSelected = RateLimiterState>(
|
|
98
98
|
value: TValue,
|
|
99
|
-
options:
|
|
99
|
+
options: PreactRateLimiterOptions<Dispatch<StateUpdater<TValue>>, TSelected>,
|
|
100
100
|
selector?: (state: RateLimiterState) => TSelected,
|
|
101
101
|
): [TValue, PreactRateLimiter<Dispatch<StateUpdater<TValue>>, TSelected>] {
|
|
102
102
|
const [rateLimitedValue, setRateLimitedValue, rateLimiter] =
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { useMemo, useState } from 'preact/hooks'
|
|
1
|
+
import { useEffect, useMemo, useState } from 'preact/hooks'
|
|
2
2
|
import { RateLimiter } from '@tanstack/pacer/rate-limiter'
|
|
3
|
-
import { useStore } from '@tanstack/preact-store'
|
|
3
|
+
import { shallow, useStore } from '@tanstack/preact-store'
|
|
4
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
5
5
|
import type { Store } from '@tanstack/preact-store'
|
|
6
6
|
import type {
|
|
@@ -10,6 +10,17 @@ import type {
|
|
|
10
10
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
11
11
|
import type { ComponentChildren } from 'preact'
|
|
12
12
|
|
|
13
|
+
export interface PreactRateLimiterOptions<
|
|
14
|
+
TFn extends AnyFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends RateLimiterOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the 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: PreactRateLimiter<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
export interface PreactRateLimiter<
|
|
14
25
|
TFn extends AnyFunction,
|
|
15
26
|
TSelected = {},
|
|
@@ -178,14 +189,13 @@ export interface PreactRateLimiter<
|
|
|
178
189
|
*/
|
|
179
190
|
export function useRateLimiter<TFn extends AnyFunction, TSelected = {}>(
|
|
180
191
|
fn: TFn,
|
|
181
|
-
options:
|
|
192
|
+
options: PreactRateLimiterOptions<TFn, TSelected>,
|
|
182
193
|
selector: (state: RateLimiterState) => TSelected = () => ({}) as TSelected,
|
|
183
194
|
): PreactRateLimiter<TFn, TSelected> {
|
|
184
195
|
const mergedOptions = {
|
|
185
196
|
...useDefaultPacerOptions().rateLimiter,
|
|
186
197
|
...options,
|
|
187
|
-
} as
|
|
188
|
-
|
|
198
|
+
} as PreactRateLimiterOptions<TFn, TSelected>
|
|
189
199
|
const [rateLimiter] = useState(() => {
|
|
190
200
|
const rateLimiterInstance = new RateLimiter<TFn>(
|
|
191
201
|
fn,
|
|
@@ -196,7 +206,9 @@ export function useRateLimiter<TFn extends AnyFunction, TSelected = {}>(
|
|
|
196
206
|
selector: (state: RateLimiterState) => TSelected
|
|
197
207
|
children: ((state: TSelected) => ComponentChildren) | ComponentChildren
|
|
198
208
|
}) {
|
|
199
|
-
const selected = useStore(rateLimiterInstance.store, props.selector
|
|
209
|
+
const selected = useStore(rateLimiterInstance.store, props.selector, {
|
|
210
|
+
equal: shallow,
|
|
211
|
+
})
|
|
200
212
|
|
|
201
213
|
return typeof props.children === 'function'
|
|
202
214
|
? props.children(selected)
|
|
@@ -209,7 +221,17 @@ export function useRateLimiter<TFn extends AnyFunction, TSelected = {}>(
|
|
|
209
221
|
rateLimiter.fn = fn
|
|
210
222
|
rateLimiter.setOptions(mergedOptions)
|
|
211
223
|
|
|
212
|
-
|
|
224
|
+
/* eslint-disable react-hooks/exhaustive-deps -- cleanup only; runs on unmount */
|
|
225
|
+
useEffect(() => {
|
|
226
|
+
return () => {
|
|
227
|
+
if (mergedOptions.onUnmount) {
|
|
228
|
+
mergedOptions.onUnmount(rateLimiter)
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}, [])
|
|
232
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
233
|
+
|
|
234
|
+
const state = useStore(rateLimiter.store, selector, { equal: shallow })
|
|
213
235
|
|
|
214
236
|
return useMemo(
|
|
215
237
|
() =>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback } from 'preact/hooks'
|
|
2
2
|
import { useThrottler } from './useThrottler'
|
|
3
|
-
import type {
|
|
3
|
+
import type { PreactThrottlerOptions } from './useThrottler'
|
|
4
4
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -42,7 +42,7 @@ import type { AnyFunction } from '@tanstack/pacer/types'
|
|
|
42
42
|
*/
|
|
43
43
|
export function useThrottledCallback<TFn extends AnyFunction>(
|
|
44
44
|
fn: TFn,
|
|
45
|
-
options:
|
|
45
|
+
options: PreactThrottlerOptions<TFn, {}>,
|
|
46
46
|
): (...args: Parameters<TFn>) => void {
|
|
47
47
|
const throttledFn = useThrottler(fn, options).maybeExecute
|
|
48
48
|
return useCallback(
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { useState } from 'preact/hooks'
|
|
2
2
|
import { useThrottler } from './useThrottler'
|
|
3
3
|
import type { Dispatch, StateUpdater } from 'preact/hooks'
|
|
4
|
-
import type { PreactThrottler } from './useThrottler'
|
|
5
|
-
import type {
|
|
6
|
-
ThrottlerOptions,
|
|
7
|
-
ThrottlerState,
|
|
8
|
-
} from '@tanstack/pacer/throttler'
|
|
4
|
+
import type { PreactThrottler, PreactThrottlerOptions } from './useThrottler'
|
|
5
|
+
import type { ThrottlerState } from '@tanstack/pacer/throttler'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A Preact hook that creates a throttled state value that updates at most once within a specified time window.
|
|
@@ -96,7 +93,7 @@ export function useThrottledState<
|
|
|
96
93
|
TSelected = ThrottlerState<Dispatch<StateUpdater<TValue>>>,
|
|
97
94
|
>(
|
|
98
95
|
value: TValue,
|
|
99
|
-
options:
|
|
96
|
+
options: PreactThrottlerOptions<Dispatch<StateUpdater<TValue>>, TSelected>,
|
|
100
97
|
selector?: (
|
|
101
98
|
state: ThrottlerState<Dispatch<StateUpdater<TValue>>>,
|
|
102
99
|
) => TSelected,
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { useEffect } from 'preact/hooks'
|
|
2
2
|
import { useThrottledState } from './useThrottledState'
|
|
3
3
|
import type { Dispatch, StateUpdater } from 'preact/hooks'
|
|
4
|
-
import type { PreactThrottler } from './useThrottler'
|
|
5
|
-
import type {
|
|
6
|
-
ThrottlerOptions,
|
|
7
|
-
ThrottlerState,
|
|
8
|
-
} from '@tanstack/pacer/throttler'
|
|
4
|
+
import type { PreactThrottler, PreactThrottlerOptions } from './useThrottler'
|
|
5
|
+
import type { ThrottlerState } from '@tanstack/pacer/throttler'
|
|
9
6
|
|
|
10
7
|
/**
|
|
11
8
|
* A high-level Preact hook that creates a throttled version of a value that updates at most once within a specified time window.
|
|
@@ -88,7 +85,7 @@ export function useThrottledValue<
|
|
|
88
85
|
TSelected = ThrottlerState<Dispatch<StateUpdater<TValue>>>,
|
|
89
86
|
>(
|
|
90
87
|
value: TValue,
|
|
91
|
-
options:
|
|
88
|
+
options: PreactThrottlerOptions<Dispatch<StateUpdater<TValue>>, TSelected>,
|
|
92
89
|
selector?: (
|
|
93
90
|
state: ThrottlerState<Dispatch<StateUpdater<TValue>>>,
|
|
94
91
|
) => TSelected,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useEffect, useMemo, useState } from 'preact/hooks'
|
|
2
2
|
import { Throttler } from '@tanstack/pacer/throttler'
|
|
3
|
-
import { useStore } from '@tanstack/preact-store'
|
|
3
|
+
import { shallow, useStore } from '@tanstack/preact-store'
|
|
4
4
|
import { useDefaultPacerOptions } from '../provider/PacerProvider'
|
|
5
5
|
import type { Store } from '@tanstack/preact-store'
|
|
6
6
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
@@ -10,6 +10,17 @@ import type {
|
|
|
10
10
|
} from '@tanstack/pacer/throttler'
|
|
11
11
|
import type { ComponentChildren } from 'preact'
|
|
12
12
|
|
|
13
|
+
export interface PreactThrottlerOptions<
|
|
14
|
+
TFn extends AnyFunction,
|
|
15
|
+
TSelected = {},
|
|
16
|
+
> extends ThrottlerOptions<TFn> {
|
|
17
|
+
/**
|
|
18
|
+
* Optional callback invoked when the 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: PreactThrottler<TFn, TSelected>) => void
|
|
22
|
+
}
|
|
23
|
+
|
|
13
24
|
export interface PreactThrottler<
|
|
14
25
|
TFn extends AnyFunction,
|
|
15
26
|
TSelected = {},
|
|
@@ -85,6 +96,18 @@ export interface PreactThrottler<
|
|
|
85
96
|
* - `isPending`: Whether the throttler is waiting for the timeout to trigger execution
|
|
86
97
|
* - `status`: Current execution status ('disabled' | 'idle' | 'pending')
|
|
87
98
|
*
|
|
99
|
+
* ## Unmount behavior
|
|
100
|
+
*
|
|
101
|
+
* By default, the hook cancels any pending execution when the component unmounts.
|
|
102
|
+
* Use the `onUnmount` option to customize this. For example, to flush pending work instead:
|
|
103
|
+
*
|
|
104
|
+
* ```tsx
|
|
105
|
+
* const throttler = useThrottler(fn, {
|
|
106
|
+
* wait: 1000,
|
|
107
|
+
* onUnmount: (t) => t.flush()
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*
|
|
88
111
|
* @example
|
|
89
112
|
* ```tsx
|
|
90
113
|
* // Default behavior - no reactive state subscriptions
|
|
@@ -144,14 +167,13 @@ export interface PreactThrottler<
|
|
|
144
167
|
*/
|
|
145
168
|
export function useThrottler<TFn extends AnyFunction, TSelected = {}>(
|
|
146
169
|
fn: TFn,
|
|
147
|
-
options:
|
|
170
|
+
options: PreactThrottlerOptions<TFn, TSelected>,
|
|
148
171
|
selector: (state: ThrottlerState<TFn>) => TSelected = () => ({}) as TSelected,
|
|
149
172
|
): PreactThrottler<TFn, TSelected> {
|
|
150
173
|
const mergedOptions = {
|
|
151
174
|
...useDefaultPacerOptions().throttler,
|
|
152
175
|
...options,
|
|
153
|
-
} as
|
|
154
|
-
|
|
176
|
+
} as PreactThrottlerOptions<TFn, TSelected>
|
|
155
177
|
const [throttler] = useState(() => {
|
|
156
178
|
const throttlerInstance = new Throttler<TFn>(
|
|
157
179
|
fn,
|
|
@@ -162,7 +184,9 @@ export function useThrottler<TFn extends AnyFunction, TSelected = {}>(
|
|
|
162
184
|
selector: (state: ThrottlerState<TFn>) => TSelected
|
|
163
185
|
children: ((state: TSelected) => ComponentChildren) | ComponentChildren
|
|
164
186
|
}) {
|
|
165
|
-
const selected = useStore(throttlerInstance.store, props.selector
|
|
187
|
+
const selected = useStore(throttlerInstance.store, props.selector, {
|
|
188
|
+
equal: shallow,
|
|
189
|
+
})
|
|
166
190
|
|
|
167
191
|
return typeof props.children === 'function'
|
|
168
192
|
? props.children(selected)
|
|
@@ -175,13 +199,19 @@ export function useThrottler<TFn extends AnyFunction, TSelected = {}>(
|
|
|
175
199
|
throttler.fn = fn
|
|
176
200
|
throttler.setOptions(mergedOptions)
|
|
177
201
|
|
|
178
|
-
const state = useStore(throttler.store, selector)
|
|
202
|
+
const state = useStore(throttler.store, selector, { equal: shallow })
|
|
179
203
|
|
|
204
|
+
/* eslint-disable react-hooks/exhaustive-deps -- cleanup only; runs on unmount */
|
|
180
205
|
useEffect(() => {
|
|
181
206
|
return () => {
|
|
182
|
-
|
|
207
|
+
if (mergedOptions.onUnmount) {
|
|
208
|
+
mergedOptions.onUnmount(throttler)
|
|
209
|
+
} else {
|
|
210
|
+
throttler.cancel()
|
|
211
|
+
}
|
|
183
212
|
}
|
|
184
|
-
}, [
|
|
213
|
+
}, [])
|
|
214
|
+
/* eslint-enable react-hooks/exhaustive-deps */
|
|
185
215
|
|
|
186
216
|
return useMemo(
|
|
187
217
|
() =>
|