@tanstack/solid-pacer 0.8.0 → 0.9.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-batcher/createAsyncBatcher.cjs +14 -0
- package/dist/cjs/async-batcher/createAsyncBatcher.cjs.map +1 -0
- package/dist/cjs/async-batcher/createAsyncBatcher.d.cts +72 -0
- package/dist/cjs/async-batcher/index.cjs +12 -0
- package/dist/cjs/{compare → async-batcher}/index.cjs.map +1 -1
- package/dist/cjs/async-batcher/index.d.cts +2 -0
- package/dist/cjs/async-debouncer/createAsyncDebouncer.cjs +9 -36
- package/dist/cjs/async-debouncer/createAsyncDebouncer.cjs.map +1 -1
- package/dist/cjs/async-debouncer/createAsyncDebouncer.d.cts +10 -9
- package/dist/cjs/async-queuer/createAsyncQueuer.cjs +5 -73
- package/dist/cjs/async-queuer/createAsyncQueuer.cjs.map +1 -1
- package/dist/cjs/async-queuer/createAsyncQueuer.d.cts +7 -53
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs +5 -52
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs.map +1 -1
- package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.d.cts +4 -9
- package/dist/cjs/async-throttler/createAsyncThrottler.cjs +5 -55
- package/dist/cjs/async-throttler/createAsyncThrottler.cjs.map +1 -1
- package/dist/cjs/async-throttler/createAsyncThrottler.d.cts +9 -11
- package/dist/cjs/batcher/createBatcher.cjs +5 -49
- package/dist/cjs/batcher/createBatcher.cjs.map +1 -1
- package/dist/cjs/batcher/createBatcher.d.cts +9 -27
- package/dist/cjs/debouncer/createDebouncedSignal.cjs +2 -2
- package/dist/cjs/debouncer/createDebouncedSignal.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncedSignal.d.cts +6 -2
- package/dist/cjs/debouncer/createDebouncedValue.cjs +3 -2
- package/dist/cjs/debouncer/createDebouncedValue.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncedValue.d.cts +2 -2
- package/dist/cjs/debouncer/createDebouncer.cjs +7 -24
- package/dist/cjs/debouncer/createDebouncer.cjs.map +1 -1
- package/dist/cjs/debouncer/createDebouncer.d.cts +9 -8
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/index.d.cts +1 -0
- package/dist/cjs/queuer/createQueuer.cjs +5 -59
- package/dist/cjs/queuer/createQueuer.cjs.map +1 -1
- package/dist/cjs/queuer/createQueuer.d.cts +7 -37
- package/dist/cjs/rate-limiter/createRateLimitedSignal.cjs +7 -3
- package/dist/cjs/rate-limiter/createRateLimitedSignal.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimitedSignal.d.cts +6 -2
- package/dist/cjs/rate-limiter/createRateLimitedValue.cjs +2 -2
- package/dist/cjs/rate-limiter/createRateLimitedValue.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimitedValue.d.cts +2 -2
- package/dist/cjs/rate-limiter/createRateLimiter.cjs +5 -43
- package/dist/cjs/rate-limiter/createRateLimiter.cjs.map +1 -1
- package/dist/cjs/rate-limiter/createRateLimiter.d.cts +9 -7
- package/dist/cjs/throttler/createThrottledSignal.cjs +2 -2
- package/dist/cjs/throttler/createThrottledSignal.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottledSignal.d.cts +6 -2
- package/dist/cjs/throttler/createThrottledValue.cjs +3 -2
- package/dist/cjs/throttler/createThrottledValue.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottledValue.d.cts +2 -2
- package/dist/cjs/throttler/createThrottler.cjs +7 -34
- package/dist/cjs/throttler/createThrottler.cjs.map +1 -1
- package/dist/cjs/throttler/createThrottler.d.cts +9 -10
- package/dist/esm/async-batcher/createAsyncBatcher.d.ts +72 -0
- package/dist/esm/async-batcher/createAsyncBatcher.js +14 -0
- package/dist/esm/async-batcher/createAsyncBatcher.js.map +1 -0
- package/dist/esm/async-batcher/index.d.ts +2 -0
- package/dist/esm/async-batcher/index.js +6 -0
- package/dist/esm/{compare → async-batcher}/index.js.map +1 -1
- package/dist/esm/async-debouncer/createAsyncDebouncer.d.ts +10 -9
- package/dist/esm/async-debouncer/createAsyncDebouncer.js +10 -37
- package/dist/esm/async-debouncer/createAsyncDebouncer.js.map +1 -1
- package/dist/esm/async-queuer/createAsyncQueuer.d.ts +7 -53
- package/dist/esm/async-queuer/createAsyncQueuer.js +5 -73
- package/dist/esm/async-queuer/createAsyncQueuer.js.map +1 -1
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.d.ts +4 -9
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js +5 -52
- package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js.map +1 -1
- package/dist/esm/async-throttler/createAsyncThrottler.d.ts +9 -11
- package/dist/esm/async-throttler/createAsyncThrottler.js +5 -55
- package/dist/esm/async-throttler/createAsyncThrottler.js.map +1 -1
- package/dist/esm/batcher/createBatcher.d.ts +9 -27
- package/dist/esm/batcher/createBatcher.js +5 -49
- package/dist/esm/batcher/createBatcher.js.map +1 -1
- package/dist/esm/debouncer/createDebouncedSignal.d.ts +6 -2
- package/dist/esm/debouncer/createDebouncedSignal.js +2 -2
- package/dist/esm/debouncer/createDebouncedSignal.js.map +1 -1
- package/dist/esm/debouncer/createDebouncedValue.d.ts +2 -2
- package/dist/esm/debouncer/createDebouncedValue.js +3 -2
- package/dist/esm/debouncer/createDebouncedValue.js.map +1 -1
- package/dist/esm/debouncer/createDebouncer.d.ts +9 -8
- package/dist/esm/debouncer/createDebouncer.js +8 -25
- package/dist/esm/debouncer/createDebouncer.js.map +1 -1
- package/dist/esm/index.d.ts +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/queuer/createQueuer.d.ts +7 -37
- package/dist/esm/queuer/createQueuer.js +5 -59
- package/dist/esm/queuer/createQueuer.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimitedSignal.d.ts +6 -2
- package/dist/esm/rate-limiter/createRateLimitedSignal.js +7 -3
- package/dist/esm/rate-limiter/createRateLimitedSignal.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimitedValue.d.ts +2 -2
- package/dist/esm/rate-limiter/createRateLimitedValue.js +2 -2
- package/dist/esm/rate-limiter/createRateLimitedValue.js.map +1 -1
- package/dist/esm/rate-limiter/createRateLimiter.d.ts +9 -7
- package/dist/esm/rate-limiter/createRateLimiter.js +5 -43
- package/dist/esm/rate-limiter/createRateLimiter.js.map +1 -1
- package/dist/esm/throttler/createThrottledSignal.d.ts +6 -2
- package/dist/esm/throttler/createThrottledSignal.js +2 -2
- package/dist/esm/throttler/createThrottledSignal.js.map +1 -1
- package/dist/esm/throttler/createThrottledValue.d.ts +2 -2
- package/dist/esm/throttler/createThrottledValue.js +3 -2
- package/dist/esm/throttler/createThrottledValue.js.map +1 -1
- package/dist/esm/throttler/createThrottler.d.ts +9 -10
- package/dist/esm/throttler/createThrottler.js +8 -35
- package/dist/esm/throttler/createThrottler.js.map +1 -1
- package/package.json +14 -3
- package/src/async-batcher/createAsyncBatcher.ts +98 -0
- package/src/async-batcher/index.ts +3 -0
- package/src/async-debouncer/createAsyncDebouncer.ts +31 -56
- package/src/async-queuer/createAsyncQueuer.ts +18 -141
- package/src/async-rate-limiter/createAsyncRateLimiter.ts +20 -75
- package/src/async-throttler/createAsyncThrottler.ts +25 -81
- package/src/batcher/createBatcher.ts +17 -94
- package/src/debouncer/createDebouncedSignal.ts +15 -4
- package/src/debouncer/createDebouncedValue.ts +11 -3
- package/src/debouncer/createDebouncer.ts +28 -38
- package/src/index.ts +3 -0
- package/src/queuer/createQueuer.ts +15 -115
- package/src/rate-limiter/createRateLimitedSignal.ts +17 -5
- package/src/rate-limiter/createRateLimitedValue.ts +8 -4
- package/src/rate-limiter/createRateLimiter.ts +25 -62
- package/src/throttler/createThrottledSignal.ts +15 -4
- package/src/throttler/createThrottledValue.ts +11 -3
- package/src/throttler/createThrottler.ts +28 -56
- package/dist/cjs/compare/index.cjs +0 -10
- package/dist/cjs/compare/index.d.cts +0 -1
- package/dist/esm/compare/index.d.ts +0 -1
- package/dist/esm/compare/index.js +0 -2
- package/src/compare/index.ts +0 -1
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import { AsyncRateLimiter } from '@tanstack/pacer/async-rate-limiter'
|
|
2
|
-
import {
|
|
3
|
-
import { bindInstanceMethods } from '@tanstack/pacer/utils'
|
|
2
|
+
import { useStore } from '@tanstack/solid-store'
|
|
4
3
|
import type { Accessor } from 'solid-js'
|
|
5
4
|
import type { AnyAsyncFunction } from '@tanstack/pacer/types'
|
|
6
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
AsyncRateLimiterOptions,
|
|
7
|
+
AsyncRateLimiterState,
|
|
8
|
+
} from '@tanstack/pacer/async-rate-limiter'
|
|
7
9
|
|
|
8
|
-
export interface SolidAsyncRateLimiter<
|
|
9
|
-
extends
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
| 'getErrorCount'
|
|
14
|
-
| 'getRejectionCount'
|
|
15
|
-
| 'getRemainingInWindow'
|
|
16
|
-
| 'getMsUntilNextWindow'
|
|
17
|
-
> {
|
|
18
|
-
successCount: Accessor<number>
|
|
19
|
-
settleCount: Accessor<number>
|
|
20
|
-
errorCount: Accessor<number>
|
|
21
|
-
rejectionCount: Accessor<number>
|
|
22
|
-
remainingInWindow: Accessor<number>
|
|
23
|
-
msUntilNextWindow: Accessor<number>
|
|
10
|
+
export interface SolidAsyncRateLimiter<
|
|
11
|
+
TFn extends AnyAsyncFunction,
|
|
12
|
+
TSelected = AsyncRateLimiterState<TFn>,
|
|
13
|
+
> extends Omit<AsyncRateLimiter<TFn>, 'store'> {
|
|
14
|
+
readonly state: Accessor<Readonly<TSelected>>
|
|
24
15
|
}
|
|
25
16
|
|
|
26
17
|
/**
|
|
@@ -85,66 +76,20 @@ export interface SolidAsyncRateLimiter<TFn extends AnyAsyncFunction>
|
|
|
85
76
|
* );
|
|
86
77
|
* ```
|
|
87
78
|
*/
|
|
88
|
-
export function createAsyncRateLimiter<
|
|
79
|
+
export function createAsyncRateLimiter<
|
|
80
|
+
TFn extends AnyAsyncFunction,
|
|
81
|
+
TSelected = AsyncRateLimiterState<TFn>,
|
|
82
|
+
>(
|
|
89
83
|
fn: TFn,
|
|
90
84
|
initialOptions: AsyncRateLimiterOptions<TFn>,
|
|
91
|
-
|
|
85
|
+
selector?: (state: AsyncRateLimiterState<TFn>) => TSelected,
|
|
86
|
+
): SolidAsyncRateLimiter<TFn, TSelected> {
|
|
92
87
|
const asyncRateLimiter = new AsyncRateLimiter<TFn>(fn, initialOptions)
|
|
93
88
|
|
|
94
|
-
const
|
|
95
|
-
asyncRateLimiter.getSuccessCount(),
|
|
96
|
-
)
|
|
97
|
-
const [rejectionCount, setRejectionCount] = createSignal(
|
|
98
|
-
asyncRateLimiter.getRejectionCount(),
|
|
99
|
-
)
|
|
100
|
-
const [errorCount, setErrorCount] = createSignal(
|
|
101
|
-
asyncRateLimiter.getErrorCount(),
|
|
102
|
-
)
|
|
103
|
-
const [settleCount, setSettleCount] = createSignal(
|
|
104
|
-
asyncRateLimiter.getSettleCount(),
|
|
105
|
-
)
|
|
106
|
-
const [remainingInWindow, setRemainingInWindow] = createSignal(
|
|
107
|
-
asyncRateLimiter.getRemainingInWindow(),
|
|
108
|
-
)
|
|
109
|
-
const [msUntilNextWindow, setMsUntilNextWindow] = createSignal(
|
|
110
|
-
asyncRateLimiter.getMsUntilNextWindow(),
|
|
111
|
-
)
|
|
112
|
-
|
|
113
|
-
function setOptions(newOptions: Partial<AsyncRateLimiterOptions<TFn>>) {
|
|
114
|
-
asyncRateLimiter.setOptions({
|
|
115
|
-
...newOptions,
|
|
116
|
-
onSettled: (rateLimiter) => {
|
|
117
|
-
setSuccessCount(rateLimiter.getSuccessCount())
|
|
118
|
-
setSettleCount(rateLimiter.getSettleCount())
|
|
119
|
-
setErrorCount(rateLimiter.getErrorCount())
|
|
120
|
-
setRejectionCount(rateLimiter.getRejectionCount())
|
|
121
|
-
setRemainingInWindow(rateLimiter.getRemainingInWindow())
|
|
122
|
-
setMsUntilNextWindow(rateLimiter.getMsUntilNextWindow())
|
|
123
|
-
|
|
124
|
-
const onSettled = newOptions.onSettled ?? initialOptions.onSettled
|
|
125
|
-
onSettled?.(rateLimiter)
|
|
126
|
-
},
|
|
127
|
-
onReject: (rateLimiter) => {
|
|
128
|
-
setRejectionCount(rateLimiter.getRejectionCount())
|
|
129
|
-
setRemainingInWindow(rateLimiter.getRemainingInWindow())
|
|
130
|
-
setMsUntilNextWindow(rateLimiter.getMsUntilNextWindow())
|
|
131
|
-
|
|
132
|
-
const onReject = newOptions.onReject ?? initialOptions.onReject
|
|
133
|
-
onReject?.(rateLimiter)
|
|
134
|
-
},
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
setOptions(initialOptions)
|
|
89
|
+
const state = useStore(asyncRateLimiter.store, selector)
|
|
139
90
|
|
|
140
91
|
return {
|
|
141
|
-
...
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
msUntilNextWindow,
|
|
145
|
-
rejectionCount,
|
|
146
|
-
setOptions,
|
|
147
|
-
settleCount,
|
|
148
|
-
successCount,
|
|
149
|
-
} as SolidAsyncRateLimiter<TFn>
|
|
92
|
+
...asyncRateLimiter,
|
|
93
|
+
state,
|
|
94
|
+
} as SolidAsyncRateLimiter<TFn, TSelected>
|
|
150
95
|
}
|
|
@@ -1,30 +1,22 @@
|
|
|
1
1
|
import { AsyncThrottler } from '@tanstack/pacer/async-throttler'
|
|
2
|
-
import {
|
|
3
|
-
import { bindInstanceMethods } from '@tanstack/pacer/utils'
|
|
2
|
+
import { useStore } from '@tanstack/solid-store'
|
|
4
3
|
import type { Accessor } from 'solid-js'
|
|
5
4
|
import type { AnyAsyncFunction } from '@tanstack/pacer/types'
|
|
6
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
AsyncThrottlerOptions,
|
|
7
|
+
AsyncThrottlerState,
|
|
8
|
+
} from '@tanstack/pacer/async-throttler'
|
|
7
9
|
|
|
8
|
-
export interface SolidAsyncThrottler<
|
|
9
|
-
extends
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
| 'getNextExecutionTime'
|
|
19
|
-
> {
|
|
20
|
-
successCount: Accessor<number>
|
|
21
|
-
settleCount: Accessor<number>
|
|
22
|
-
errorCount: Accessor<number>
|
|
23
|
-
isPending: Accessor<boolean>
|
|
24
|
-
isExecuting: Accessor<boolean>
|
|
25
|
-
lastResult: Accessor<ReturnType<TFn> | undefined>
|
|
26
|
-
lastExecutionTime: Accessor<number>
|
|
27
|
-
nextExecutionTime: Accessor<number>
|
|
10
|
+
export interface SolidAsyncThrottler<
|
|
11
|
+
TFn extends AnyAsyncFunction,
|
|
12
|
+
TSelected = AsyncThrottlerState<TFn>,
|
|
13
|
+
> extends Omit<AsyncThrottler<TFn>, 'store'> {
|
|
14
|
+
/**
|
|
15
|
+
* Reactive state that will be updated and re-rendered when the throttler state changes
|
|
16
|
+
*
|
|
17
|
+
* Use this instead of `throttler.store.state`
|
|
18
|
+
*/
|
|
19
|
+
readonly state: Accessor<Readonly<TSelected>>
|
|
28
20
|
}
|
|
29
21
|
|
|
30
22
|
/**
|
|
@@ -77,68 +69,20 @@ export interface SolidAsyncThrottler<TFn extends AnyAsyncFunction>
|
|
|
77
69
|
* );
|
|
78
70
|
* ```
|
|
79
71
|
*/
|
|
80
|
-
export function createAsyncThrottler<
|
|
72
|
+
export function createAsyncThrottler<
|
|
73
|
+
TFn extends AnyAsyncFunction,
|
|
74
|
+
TSelected = AsyncThrottlerState<TFn>,
|
|
75
|
+
>(
|
|
81
76
|
fn: TFn,
|
|
82
77
|
initialOptions: AsyncThrottlerOptions<TFn>,
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
)
|
|
78
|
+
selector?: (state: AsyncThrottlerState<TFn>) => TSelected,
|
|
79
|
+
): SolidAsyncThrottler<TFn, TSelected> {
|
|
80
|
+
const asyncThrottler = new AsyncThrottler(fn, initialOptions)
|
|
87
81
|
|
|
88
|
-
const
|
|
89
|
-
asyncThrottler.getSuccessCount(),
|
|
90
|
-
)
|
|
91
|
-
const [settleCount, setSettleCount] = createSignal(
|
|
92
|
-
asyncThrottler.getSettleCount(),
|
|
93
|
-
)
|
|
94
|
-
const [errorCount, setErrorCount] = createSignal(
|
|
95
|
-
asyncThrottler.getErrorCount(),
|
|
96
|
-
)
|
|
97
|
-
const [isPending, setIsPending] = createSignal(asyncThrottler.getIsPending())
|
|
98
|
-
const [isExecuting, setIsExecuting] = createSignal(
|
|
99
|
-
asyncThrottler.getIsExecuting(),
|
|
100
|
-
)
|
|
101
|
-
const [lastResult, setLastResult] = createSignal(
|
|
102
|
-
asyncThrottler.getLastResult(),
|
|
103
|
-
)
|
|
104
|
-
const [lastExecutionTime, setLastExecutionTime] = createSignal(
|
|
105
|
-
asyncThrottler.getLastExecutionTime(),
|
|
106
|
-
)
|
|
107
|
-
const [nextExecutionTime, setNextExecutionTime] = createSignal(
|
|
108
|
-
asyncThrottler.getNextExecutionTime(),
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
function setOptions(newOptions: Partial<AsyncThrottlerOptions<TFn>>) {
|
|
112
|
-
asyncThrottler.setOptions({
|
|
113
|
-
...newOptions,
|
|
114
|
-
onSettled: (throttler) => {
|
|
115
|
-
setSuccessCount(throttler.getSuccessCount())
|
|
116
|
-
setSettleCount(throttler.getSettleCount())
|
|
117
|
-
setErrorCount(throttler.getErrorCount())
|
|
118
|
-
setIsPending(throttler.getIsPending())
|
|
119
|
-
setIsExecuting(throttler.getIsExecuting())
|
|
120
|
-
setLastExecutionTime(throttler.getLastExecutionTime())
|
|
121
|
-
setNextExecutionTime(throttler.getNextExecutionTime())
|
|
122
|
-
setLastResult(throttler.getLastResult())
|
|
123
|
-
|
|
124
|
-
const onSettled = newOptions.onSettled ?? initialOptions.onSettled
|
|
125
|
-
onSettled?.(throttler)
|
|
126
|
-
},
|
|
127
|
-
})
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
setOptions(initialOptions)
|
|
82
|
+
const state = useStore(asyncThrottler.store, selector)
|
|
131
83
|
|
|
132
84
|
return {
|
|
133
85
|
...asyncThrottler,
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
isPending,
|
|
137
|
-
lastExecutionTime,
|
|
138
|
-
lastResult,
|
|
139
|
-
nextExecutionTime,
|
|
140
|
-
setOptions,
|
|
141
|
-
settleCount,
|
|
142
|
-
successCount,
|
|
143
|
-
} as SolidAsyncThrottler<TFn>
|
|
86
|
+
state,
|
|
87
|
+
} as SolidAsyncThrottler<TFn, TSelected>
|
|
144
88
|
}
|
|
@@ -1,43 +1,16 @@
|
|
|
1
1
|
import { Batcher } from '@tanstack/pacer/batcher'
|
|
2
|
-
import {
|
|
3
|
-
import { bindInstanceMethods } from '@tanstack/pacer/utils'
|
|
2
|
+
import { useStore } from '@tanstack/solid-store'
|
|
4
3
|
import type { Accessor } from 'solid-js'
|
|
5
|
-
import type { BatcherOptions } from '@tanstack/pacer/batcher'
|
|
4
|
+
import type { BatcherOptions, BatcherState } from '@tanstack/pacer/batcher'
|
|
6
5
|
|
|
7
|
-
export interface SolidBatcher<TValue
|
|
8
|
-
extends Omit<
|
|
9
|
-
Batcher<TValue>,
|
|
10
|
-
| 'peekAllItems'
|
|
11
|
-
| 'getBatchExecutionCount'
|
|
12
|
-
| 'getIsEmpty'
|
|
13
|
-
| 'getIsRunning'
|
|
14
|
-
| 'getItemExecutionCount'
|
|
15
|
-
| 'getSize'
|
|
16
|
-
> {
|
|
6
|
+
export interface SolidBatcher<TValue, TSelected = BatcherState<TValue>>
|
|
7
|
+
extends Omit<Batcher<TValue>, 'store'> {
|
|
17
8
|
/**
|
|
18
|
-
*
|
|
9
|
+
* Reactive state that will be updated when the batcher state changes
|
|
10
|
+
*
|
|
11
|
+
* Use this instead of `batcher.store.state`
|
|
19
12
|
*/
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Signal version of `getBatchExecutionCount`
|
|
23
|
-
*/
|
|
24
|
-
batchExecutionCount: Accessor<number>
|
|
25
|
-
/**
|
|
26
|
-
* Signal version of `getIsEmpty`
|
|
27
|
-
*/
|
|
28
|
-
isEmpty: Accessor<boolean>
|
|
29
|
-
/**
|
|
30
|
-
* Signal version of `getIsRunning`
|
|
31
|
-
*/
|
|
32
|
-
isRunning: Accessor<boolean>
|
|
33
|
-
/**
|
|
34
|
-
* Signal version of `getItemExecutionCount`
|
|
35
|
-
*/
|
|
36
|
-
itemExecutionCount: Accessor<number>
|
|
37
|
-
/**
|
|
38
|
-
* Signal version of `getSize`
|
|
39
|
-
*/
|
|
40
|
-
size: Accessor<number>
|
|
13
|
+
readonly state: Accessor<Readonly<TSelected>>
|
|
41
14
|
}
|
|
42
15
|
|
|
43
16
|
/**
|
|
@@ -83,70 +56,20 @@ export interface SolidBatcher<TValue>
|
|
|
83
56
|
* console.log('Size:', batcher.size());
|
|
84
57
|
* console.log('Is empty:', batcher.isEmpty());
|
|
85
58
|
* console.log('Is running:', batcher.isRunning());
|
|
86
|
-
* console.log('Batch count:', batcher.
|
|
87
|
-
* console.log('Item count:', batcher.
|
|
59
|
+
* console.log('Batch count:', batcher.executionCount());
|
|
60
|
+
* console.log('Item count:', batcher.totalItemsProcessed());
|
|
88
61
|
* ```
|
|
89
62
|
*/
|
|
90
|
-
export function createBatcher<TValue
|
|
63
|
+
export function createBatcher<TValue, TSelected = BatcherState<TValue>>(
|
|
91
64
|
fn: (items: Array<TValue>) => void,
|
|
92
65
|
initialOptions: BatcherOptions<TValue> = {},
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const [allItems, setAllItems] = createSignal<Array<TValue>>(
|
|
97
|
-
batcher.peekAllItems(),
|
|
98
|
-
)
|
|
99
|
-
const [batchExecutionCount, setBatchExecutionCount] = createSignal(
|
|
100
|
-
batcher.getBatchExecutionCount(),
|
|
101
|
-
)
|
|
102
|
-
const [itemExecutionCount, setItemExecutionCount] = createSignal(
|
|
103
|
-
batcher.getItemExecutionCount(),
|
|
104
|
-
)
|
|
105
|
-
const [isEmpty, setIsEmpty] = createSignal(batcher.getIsEmpty())
|
|
106
|
-
const [isRunning, setIsRunning] = createSignal(batcher.getIsRunning())
|
|
107
|
-
const [size, setSize] = createSignal(batcher.getSize())
|
|
108
|
-
|
|
109
|
-
function setOptions(newOptions: Partial<BatcherOptions<TValue>>) {
|
|
110
|
-
batcher.setOptions({
|
|
111
|
-
...newOptions,
|
|
112
|
-
onItemsChange: (batcher) => {
|
|
113
|
-
setAllItems(batcher.peekAllItems())
|
|
114
|
-
setBatchExecutionCount(batcher.getBatchExecutionCount())
|
|
115
|
-
setItemExecutionCount(batcher.getItemExecutionCount())
|
|
116
|
-
setIsEmpty(batcher.getIsEmpty())
|
|
117
|
-
setSize(batcher.getSize())
|
|
118
|
-
|
|
119
|
-
const onItemsChange =
|
|
120
|
-
newOptions.onItemsChange ?? initialOptions.onItemsChange
|
|
121
|
-
onItemsChange?.(batcher)
|
|
122
|
-
},
|
|
123
|
-
onExecute: (batcher) => {
|
|
124
|
-
setBatchExecutionCount(batcher.getBatchExecutionCount())
|
|
125
|
-
setItemExecutionCount(batcher.getItemExecutionCount())
|
|
126
|
-
|
|
127
|
-
const onExecute = newOptions.onExecute ?? initialOptions.onExecute
|
|
128
|
-
onExecute?.(batcher)
|
|
129
|
-
},
|
|
130
|
-
onIsRunningChange: (batcher) => {
|
|
131
|
-
setIsRunning(batcher.getIsRunning())
|
|
132
|
-
|
|
133
|
-
const onIsRunningChange =
|
|
134
|
-
newOptions.onIsRunningChange ?? initialOptions.onIsRunningChange
|
|
135
|
-
onIsRunningChange?.(batcher)
|
|
136
|
-
},
|
|
137
|
-
})
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
setOptions(initialOptions)
|
|
66
|
+
selector?: (state: BatcherState<TValue>) => TSelected,
|
|
67
|
+
): SolidBatcher<TValue, TSelected> {
|
|
68
|
+
const batcher = new Batcher(fn, initialOptions)
|
|
141
69
|
|
|
70
|
+
const state = useStore(batcher.store, selector)
|
|
142
71
|
return {
|
|
143
72
|
...batcher,
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
isEmpty,
|
|
147
|
-
isRunning,
|
|
148
|
-
itemExecutionCount,
|
|
149
|
-
size,
|
|
150
|
-
setOptions,
|
|
151
|
-
} as SolidBatcher<TValue>
|
|
73
|
+
state,
|
|
74
|
+
} as SolidBatcher<TValue, TSelected>
|
|
152
75
|
}
|
|
@@ -2,7 +2,10 @@ import { createSignal } from 'solid-js'
|
|
|
2
2
|
import { createDebouncer } from './createDebouncer'
|
|
3
3
|
import type { SolidDebouncer } from './createDebouncer'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
DebouncerOptions,
|
|
7
|
+
DebouncerState,
|
|
8
|
+
} from '@tanstack/pacer/debouncer'
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* A Solid hook that creates a debounced state value, combining Solid's createSignal with debouncing functionality.
|
|
@@ -43,13 +46,21 @@ import type { DebouncerOptions } from '@tanstack/pacer/debouncer'
|
|
|
43
46
|
* });
|
|
44
47
|
* ```
|
|
45
48
|
*/
|
|
46
|
-
export function createDebouncedSignal<
|
|
49
|
+
export function createDebouncedSignal<
|
|
50
|
+
TValue,
|
|
51
|
+
TSelected = DebouncerState<Setter<TValue>>,
|
|
52
|
+
>(
|
|
47
53
|
value: TValue,
|
|
48
54
|
initialOptions: DebouncerOptions<Setter<TValue>>,
|
|
49
|
-
|
|
55
|
+
selector?: (state: DebouncerState<Setter<TValue>>) => TSelected,
|
|
56
|
+
): [
|
|
57
|
+
Accessor<TValue>,
|
|
58
|
+
Setter<TValue>,
|
|
59
|
+
SolidDebouncer<Setter<TValue>, TSelected>,
|
|
60
|
+
] {
|
|
50
61
|
const [debouncedValue, setDebouncedValue] = createSignal<TValue>(value)
|
|
51
62
|
|
|
52
|
-
const debouncer = createDebouncer(setDebouncedValue, initialOptions)
|
|
63
|
+
const debouncer = createDebouncer(setDebouncedValue, initialOptions, selector)
|
|
53
64
|
|
|
54
65
|
return [debouncedValue, debouncer.maybeExecute as Setter<TValue>, debouncer]
|
|
55
66
|
}
|
|
@@ -2,7 +2,10 @@ import { createEffect } from 'solid-js'
|
|
|
2
2
|
import { createDebouncedSignal } from './createDebouncedSignal'
|
|
3
3
|
import type { SolidDebouncer } from './createDebouncer'
|
|
4
4
|
import type { Accessor, Setter } from 'solid-js'
|
|
5
|
-
import type {
|
|
5
|
+
import type {
|
|
6
|
+
DebouncerOptions,
|
|
7
|
+
DebouncerState,
|
|
8
|
+
} from '@tanstack/pacer/debouncer'
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* A Solid hook that creates a debounced value that updates only after a specified delay.
|
|
@@ -38,13 +41,18 @@ import type { DebouncerOptions } from '@tanstack/pacer/debouncer'
|
|
|
38
41
|
* debouncer.cancel(); // Cancel any pending updates
|
|
39
42
|
* ```
|
|
40
43
|
*/
|
|
41
|
-
export function createDebouncedValue<
|
|
44
|
+
export function createDebouncedValue<
|
|
45
|
+
TValue,
|
|
46
|
+
TSelected = DebouncerState<Setter<TValue>>,
|
|
47
|
+
>(
|
|
42
48
|
value: Accessor<TValue>,
|
|
43
49
|
initialOptions: DebouncerOptions<Setter<TValue>>,
|
|
44
|
-
|
|
50
|
+
selector?: (state: DebouncerState<Setter<TValue>>) => TSelected,
|
|
51
|
+
): [Accessor<TValue>, SolidDebouncer<Setter<TValue>, TSelected>] {
|
|
45
52
|
const [debouncedValue, setDebouncedValue, debouncer] = createDebouncedSignal(
|
|
46
53
|
value(),
|
|
47
54
|
initialOptions,
|
|
55
|
+
selector,
|
|
48
56
|
)
|
|
49
57
|
|
|
50
58
|
createEffect(() => {
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
import { Debouncer } from '@tanstack/pacer/debouncer'
|
|
2
|
-
import { createEffect,
|
|
3
|
-
import {
|
|
2
|
+
import { createEffect, onCleanup } from 'solid-js'
|
|
3
|
+
import { useStore } from '@tanstack/solid-store'
|
|
4
4
|
import type { Accessor } from 'solid-js'
|
|
5
5
|
import type { AnyFunction } from '@tanstack/pacer/types'
|
|
6
|
-
import type {
|
|
6
|
+
import type {
|
|
7
|
+
DebouncerOptions,
|
|
8
|
+
DebouncerState,
|
|
9
|
+
} from '@tanstack/pacer/debouncer'
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export interface SolidDebouncer<
|
|
12
|
+
TFn extends AnyFunction,
|
|
13
|
+
TSelected = DebouncerState<TFn>,
|
|
14
|
+
> extends Omit<Debouncer<TFn>, 'store'> {
|
|
15
|
+
/**
|
|
16
|
+
* Reactive state that will be updated when the debouncer state changes
|
|
17
|
+
*
|
|
18
|
+
* Use this instead of `debouncer.store.state`
|
|
19
|
+
*/
|
|
20
|
+
readonly state: Accessor<Readonly<TSelected>>
|
|
15
21
|
}
|
|
16
22
|
|
|
17
23
|
/**
|
|
@@ -50,42 +56,26 @@ export interface SolidDebouncer<TFn extends AnyFunction>
|
|
|
50
56
|
* debouncer.setOptions({ wait: 1000 });
|
|
51
57
|
* ```
|
|
52
58
|
*/
|
|
53
|
-
export function createDebouncer<
|
|
59
|
+
export function createDebouncer<
|
|
60
|
+
TFn extends AnyFunction,
|
|
61
|
+
TSelected = DebouncerState<TFn>,
|
|
62
|
+
>(
|
|
54
63
|
fn: TFn,
|
|
55
64
|
initialOptions: DebouncerOptions<TFn>,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const [executionCount, setExecutionCount] = createSignal(
|
|
60
|
-
debouncer.getExecutionCount(),
|
|
61
|
-
)
|
|
62
|
-
const [isPending, setIsPending] = createSignal(debouncer.getIsPending())
|
|
63
|
-
|
|
64
|
-
function setOptions(newOptions: Partial<DebouncerOptions<TFn>>) {
|
|
65
|
-
debouncer.setOptions({
|
|
66
|
-
...newOptions,
|
|
67
|
-
onExecute: (debouncer) => {
|
|
68
|
-
setExecutionCount(debouncer.getExecutionCount())
|
|
69
|
-
setIsPending(debouncer.getIsPending())
|
|
70
|
-
|
|
71
|
-
const onExecute = newOptions.onExecute ?? initialOptions.onExecute
|
|
72
|
-
onExecute?.(debouncer)
|
|
73
|
-
},
|
|
74
|
-
})
|
|
75
|
-
}
|
|
65
|
+
selector?: (state: DebouncerState<TFn>) => TSelected,
|
|
66
|
+
): SolidDebouncer<TFn, TSelected> {
|
|
67
|
+
const asyncDebouncer = new Debouncer<TFn>(fn, initialOptions)
|
|
76
68
|
|
|
77
|
-
|
|
69
|
+
const state = useStore(asyncDebouncer.store, selector)
|
|
78
70
|
|
|
79
71
|
createEffect(() => {
|
|
80
72
|
onCleanup(() => {
|
|
81
|
-
|
|
73
|
+
asyncDebouncer.cancel()
|
|
82
74
|
})
|
|
83
75
|
})
|
|
84
76
|
|
|
85
77
|
return {
|
|
86
|
-
...
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
setOptions,
|
|
90
|
-
} as SolidDebouncer<TFn>
|
|
78
|
+
...asyncDebouncer,
|
|
79
|
+
state,
|
|
80
|
+
} as SolidDebouncer<TFn, TSelected> // omit `store` in favor of `state`
|
|
91
81
|
}
|
package/src/index.ts
CHANGED