@tanstack/solid-pacer 0.8.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/cjs/async-batcher/createAsyncBatcher.cjs +14 -0
  2. package/dist/cjs/async-batcher/createAsyncBatcher.cjs.map +1 -0
  3. package/dist/cjs/async-batcher/createAsyncBatcher.d.cts +72 -0
  4. package/dist/cjs/async-batcher/index.cjs +12 -0
  5. package/dist/cjs/{compare → async-batcher}/index.cjs.map +1 -1
  6. package/dist/cjs/async-batcher/index.d.cts +2 -0
  7. package/dist/cjs/async-debouncer/createAsyncDebouncer.cjs +9 -36
  8. package/dist/cjs/async-debouncer/createAsyncDebouncer.cjs.map +1 -1
  9. package/dist/cjs/async-debouncer/createAsyncDebouncer.d.cts +10 -9
  10. package/dist/cjs/async-queuer/createAsyncQueuer.cjs +5 -73
  11. package/dist/cjs/async-queuer/createAsyncQueuer.cjs.map +1 -1
  12. package/dist/cjs/async-queuer/createAsyncQueuer.d.cts +7 -53
  13. package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs +5 -52
  14. package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.cjs.map +1 -1
  15. package/dist/cjs/async-rate-limiter/createAsyncRateLimiter.d.cts +4 -9
  16. package/dist/cjs/async-throttler/createAsyncThrottler.cjs +5 -55
  17. package/dist/cjs/async-throttler/createAsyncThrottler.cjs.map +1 -1
  18. package/dist/cjs/async-throttler/createAsyncThrottler.d.cts +9 -11
  19. package/dist/cjs/batcher/createBatcher.cjs +5 -49
  20. package/dist/cjs/batcher/createBatcher.cjs.map +1 -1
  21. package/dist/cjs/batcher/createBatcher.d.cts +9 -27
  22. package/dist/cjs/debouncer/createDebouncedSignal.cjs +2 -2
  23. package/dist/cjs/debouncer/createDebouncedSignal.cjs.map +1 -1
  24. package/dist/cjs/debouncer/createDebouncedSignal.d.cts +6 -2
  25. package/dist/cjs/debouncer/createDebouncedValue.cjs +3 -2
  26. package/dist/cjs/debouncer/createDebouncedValue.cjs.map +1 -1
  27. package/dist/cjs/debouncer/createDebouncedValue.d.cts +2 -2
  28. package/dist/cjs/debouncer/createDebouncer.cjs +7 -24
  29. package/dist/cjs/debouncer/createDebouncer.cjs.map +1 -1
  30. package/dist/cjs/debouncer/createDebouncer.d.cts +9 -8
  31. package/dist/cjs/index.cjs +2 -0
  32. package/dist/cjs/index.cjs.map +1 -1
  33. package/dist/cjs/index.d.cts +1 -0
  34. package/dist/cjs/queuer/createQueuer.cjs +5 -59
  35. package/dist/cjs/queuer/createQueuer.cjs.map +1 -1
  36. package/dist/cjs/queuer/createQueuer.d.cts +7 -37
  37. package/dist/cjs/rate-limiter/createRateLimitedSignal.cjs +7 -3
  38. package/dist/cjs/rate-limiter/createRateLimitedSignal.cjs.map +1 -1
  39. package/dist/cjs/rate-limiter/createRateLimitedSignal.d.cts +6 -2
  40. package/dist/cjs/rate-limiter/createRateLimitedValue.cjs +2 -2
  41. package/dist/cjs/rate-limiter/createRateLimitedValue.cjs.map +1 -1
  42. package/dist/cjs/rate-limiter/createRateLimitedValue.d.cts +2 -2
  43. package/dist/cjs/rate-limiter/createRateLimiter.cjs +5 -43
  44. package/dist/cjs/rate-limiter/createRateLimiter.cjs.map +1 -1
  45. package/dist/cjs/rate-limiter/createRateLimiter.d.cts +9 -7
  46. package/dist/cjs/throttler/createThrottledSignal.cjs +2 -2
  47. package/dist/cjs/throttler/createThrottledSignal.cjs.map +1 -1
  48. package/dist/cjs/throttler/createThrottledSignal.d.cts +6 -2
  49. package/dist/cjs/throttler/createThrottledValue.cjs +3 -2
  50. package/dist/cjs/throttler/createThrottledValue.cjs.map +1 -1
  51. package/dist/cjs/throttler/createThrottledValue.d.cts +2 -2
  52. package/dist/cjs/throttler/createThrottler.cjs +7 -34
  53. package/dist/cjs/throttler/createThrottler.cjs.map +1 -1
  54. package/dist/cjs/throttler/createThrottler.d.cts +9 -10
  55. package/dist/esm/async-batcher/createAsyncBatcher.d.ts +72 -0
  56. package/dist/esm/async-batcher/createAsyncBatcher.js +14 -0
  57. package/dist/esm/async-batcher/createAsyncBatcher.js.map +1 -0
  58. package/dist/esm/async-batcher/index.d.ts +2 -0
  59. package/dist/esm/async-batcher/index.js +6 -0
  60. package/dist/esm/{compare → async-batcher}/index.js.map +1 -1
  61. package/dist/esm/async-debouncer/createAsyncDebouncer.d.ts +10 -9
  62. package/dist/esm/async-debouncer/createAsyncDebouncer.js +10 -37
  63. package/dist/esm/async-debouncer/createAsyncDebouncer.js.map +1 -1
  64. package/dist/esm/async-queuer/createAsyncQueuer.d.ts +7 -53
  65. package/dist/esm/async-queuer/createAsyncQueuer.js +5 -73
  66. package/dist/esm/async-queuer/createAsyncQueuer.js.map +1 -1
  67. package/dist/esm/async-rate-limiter/createAsyncRateLimiter.d.ts +4 -9
  68. package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js +5 -52
  69. package/dist/esm/async-rate-limiter/createAsyncRateLimiter.js.map +1 -1
  70. package/dist/esm/async-throttler/createAsyncThrottler.d.ts +9 -11
  71. package/dist/esm/async-throttler/createAsyncThrottler.js +5 -55
  72. package/dist/esm/async-throttler/createAsyncThrottler.js.map +1 -1
  73. package/dist/esm/batcher/createBatcher.d.ts +9 -27
  74. package/dist/esm/batcher/createBatcher.js +5 -49
  75. package/dist/esm/batcher/createBatcher.js.map +1 -1
  76. package/dist/esm/debouncer/createDebouncedSignal.d.ts +6 -2
  77. package/dist/esm/debouncer/createDebouncedSignal.js +2 -2
  78. package/dist/esm/debouncer/createDebouncedSignal.js.map +1 -1
  79. package/dist/esm/debouncer/createDebouncedValue.d.ts +2 -2
  80. package/dist/esm/debouncer/createDebouncedValue.js +3 -2
  81. package/dist/esm/debouncer/createDebouncedValue.js.map +1 -1
  82. package/dist/esm/debouncer/createDebouncer.d.ts +9 -8
  83. package/dist/esm/debouncer/createDebouncer.js +8 -25
  84. package/dist/esm/debouncer/createDebouncer.js.map +1 -1
  85. package/dist/esm/index.d.ts +1 -0
  86. package/dist/esm/index.js +2 -0
  87. package/dist/esm/index.js.map +1 -1
  88. package/dist/esm/queuer/createQueuer.d.ts +7 -37
  89. package/dist/esm/queuer/createQueuer.js +5 -59
  90. package/dist/esm/queuer/createQueuer.js.map +1 -1
  91. package/dist/esm/rate-limiter/createRateLimitedSignal.d.ts +6 -2
  92. package/dist/esm/rate-limiter/createRateLimitedSignal.js +7 -3
  93. package/dist/esm/rate-limiter/createRateLimitedSignal.js.map +1 -1
  94. package/dist/esm/rate-limiter/createRateLimitedValue.d.ts +2 -2
  95. package/dist/esm/rate-limiter/createRateLimitedValue.js +2 -2
  96. package/dist/esm/rate-limiter/createRateLimitedValue.js.map +1 -1
  97. package/dist/esm/rate-limiter/createRateLimiter.d.ts +9 -7
  98. package/dist/esm/rate-limiter/createRateLimiter.js +5 -43
  99. package/dist/esm/rate-limiter/createRateLimiter.js.map +1 -1
  100. package/dist/esm/throttler/createThrottledSignal.d.ts +6 -2
  101. package/dist/esm/throttler/createThrottledSignal.js +2 -2
  102. package/dist/esm/throttler/createThrottledSignal.js.map +1 -1
  103. package/dist/esm/throttler/createThrottledValue.d.ts +2 -2
  104. package/dist/esm/throttler/createThrottledValue.js +3 -2
  105. package/dist/esm/throttler/createThrottledValue.js.map +1 -1
  106. package/dist/esm/throttler/createThrottler.d.ts +9 -10
  107. package/dist/esm/throttler/createThrottler.js +8 -35
  108. package/dist/esm/throttler/createThrottler.js.map +1 -1
  109. package/package.json +14 -3
  110. package/src/async-batcher/createAsyncBatcher.ts +98 -0
  111. package/src/async-batcher/index.ts +3 -0
  112. package/src/async-debouncer/createAsyncDebouncer.ts +31 -56
  113. package/src/async-queuer/createAsyncQueuer.ts +18 -141
  114. package/src/async-rate-limiter/createAsyncRateLimiter.ts +20 -75
  115. package/src/async-throttler/createAsyncThrottler.ts +25 -81
  116. package/src/batcher/createBatcher.ts +17 -94
  117. package/src/debouncer/createDebouncedSignal.ts +15 -4
  118. package/src/debouncer/createDebouncedValue.ts +11 -3
  119. package/src/debouncer/createDebouncer.ts +28 -38
  120. package/src/index.ts +3 -0
  121. package/src/queuer/createQueuer.ts +15 -115
  122. package/src/rate-limiter/createRateLimitedSignal.ts +17 -5
  123. package/src/rate-limiter/createRateLimitedValue.ts +8 -4
  124. package/src/rate-limiter/createRateLimiter.ts +25 -62
  125. package/src/throttler/createThrottledSignal.ts +15 -4
  126. package/src/throttler/createThrottledValue.ts +11 -3
  127. package/src/throttler/createThrottler.ts +28 -56
  128. package/dist/cjs/compare/index.cjs +0 -10
  129. package/dist/cjs/compare/index.d.cts +0 -1
  130. package/dist/esm/compare/index.d.ts +0 -1
  131. package/dist/esm/compare/index.js +0 -2
  132. package/src/compare/index.ts +0 -1
@@ -1,26 +1,17 @@
1
1
  import { AsyncRateLimiter } from '@tanstack/pacer/async-rate-limiter'
2
- import { createSignal } from 'solid-js'
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 { AsyncRateLimiterOptions } from '@tanstack/pacer/async-rate-limiter'
5
+ import type {
6
+ AsyncRateLimiterOptions,
7
+ AsyncRateLimiterState,
8
+ } from '@tanstack/pacer/async-rate-limiter'
7
9
 
8
- export interface SolidAsyncRateLimiter<TFn extends AnyAsyncFunction>
9
- extends Omit<
10
- AsyncRateLimiter<TFn>,
11
- | 'getSuccessCount'
12
- | 'getSettleCount'
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<TFn extends AnyAsyncFunction>(
79
+ export function createAsyncRateLimiter<
80
+ TFn extends AnyAsyncFunction,
81
+ TSelected = AsyncRateLimiterState<TFn>,
82
+ >(
89
83
  fn: TFn,
90
84
  initialOptions: AsyncRateLimiterOptions<TFn>,
91
- ): SolidAsyncRateLimiter<TFn> {
85
+ selector?: (state: AsyncRateLimiterState<TFn>) => TSelected,
86
+ ): SolidAsyncRateLimiter<TFn, TSelected> {
92
87
  const asyncRateLimiter = new AsyncRateLimiter<TFn>(fn, initialOptions)
93
88
 
94
- const [successCount, setSuccessCount] = createSignal(
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
- ...bindInstanceMethods(asyncRateLimiter),
142
- errorCount,
143
- remainingInWindow,
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 { createSignal } from 'solid-js'
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 { AsyncThrottlerOptions } from '@tanstack/pacer/async-throttler'
5
+ import type {
6
+ AsyncThrottlerOptions,
7
+ AsyncThrottlerState,
8
+ } from '@tanstack/pacer/async-throttler'
7
9
 
8
- export interface SolidAsyncThrottler<TFn extends AnyAsyncFunction>
9
- extends Omit<
10
- AsyncThrottler<TFn>,
11
- | 'getSuccessCount'
12
- | 'getSettleCount'
13
- | 'getErrorCount'
14
- | 'getIsPending'
15
- | 'getIsExecuting'
16
- | 'getLastResult'
17
- | 'getLastExecutionTime'
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<TFn extends AnyAsyncFunction>(
72
+ export function createAsyncThrottler<
73
+ TFn extends AnyAsyncFunction,
74
+ TSelected = AsyncThrottlerState<TFn>,
75
+ >(
81
76
  fn: TFn,
82
77
  initialOptions: AsyncThrottlerOptions<TFn>,
83
- ): SolidAsyncThrottler<TFn> {
84
- const asyncThrottler = bindInstanceMethods(
85
- new AsyncThrottler<TFn>(fn, initialOptions),
86
- )
78
+ selector?: (state: AsyncThrottlerState<TFn>) => TSelected,
79
+ ): SolidAsyncThrottler<TFn, TSelected> {
80
+ const asyncThrottler = new AsyncThrottler(fn, initialOptions)
87
81
 
88
- const [successCount, setSuccessCount] = createSignal(
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
- errorCount,
135
- isExecuting,
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 { createSignal } from 'solid-js'
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
- * Signal version of `peekAllItems`
9
+ * Reactive state that will be updated when the batcher state changes
10
+ *
11
+ * Use this instead of `batcher.store.state`
19
12
  */
20
- allItems: Accessor<Array<TValue>>
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.batchExecutionCount());
87
- * console.log('Item count:', batcher.itemExecutionCount());
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
- ): SolidBatcher<TValue> {
94
- const batcher = bindInstanceMethods(new Batcher<TValue>(fn, initialOptions))
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
- allItems,
145
- batchExecutionCount,
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 { DebouncerOptions } from '@tanstack/pacer/debouncer'
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<TValue>(
49
+ export function createDebouncedSignal<
50
+ TValue,
51
+ TSelected = DebouncerState<Setter<TValue>>,
52
+ >(
47
53
  value: TValue,
48
54
  initialOptions: DebouncerOptions<Setter<TValue>>,
49
- ): [Accessor<TValue>, Setter<TValue>, SolidDebouncer<Setter<TValue>>] {
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 { DebouncerOptions } from '@tanstack/pacer/debouncer'
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<TValue>(
44
+ export function createDebouncedValue<
45
+ TValue,
46
+ TSelected = DebouncerState<Setter<TValue>>,
47
+ >(
42
48
  value: Accessor<TValue>,
43
49
  initialOptions: DebouncerOptions<Setter<TValue>>,
44
- ): [Accessor<TValue>, SolidDebouncer<Setter<TValue>>] {
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, createSignal, onCleanup } from 'solid-js'
3
- import { bindInstanceMethods } from '@tanstack/pacer/utils'
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 { DebouncerOptions } from '@tanstack/pacer/debouncer'
6
+ import type {
7
+ DebouncerOptions,
8
+ DebouncerState,
9
+ } from '@tanstack/pacer/debouncer'
7
10
 
8
- /**
9
- * An extension of the Debouncer class that adds Solid signals to access the internal state of the debouncer
10
- */
11
- export interface SolidDebouncer<TFn extends AnyFunction>
12
- extends Omit<Debouncer<TFn>, 'getExecutionCount' | 'getIsPending'> {
13
- executionCount: Accessor<number>
14
- isPending: Accessor<boolean>
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<TFn extends AnyFunction>(
59
+ export function createDebouncer<
60
+ TFn extends AnyFunction,
61
+ TSelected = DebouncerState<TFn>,
62
+ >(
54
63
  fn: TFn,
55
64
  initialOptions: DebouncerOptions<TFn>,
56
- ): SolidDebouncer<TFn> {
57
- const debouncer = bindInstanceMethods(new Debouncer<TFn>(fn, initialOptions))
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
- setOptions(initialOptions)
69
+ const state = useStore(asyncDebouncer.store, selector)
78
70
 
79
71
  createEffect(() => {
80
72
  onCleanup(() => {
81
- debouncer.cancel()
73
+ asyncDebouncer.cancel()
82
74
  })
83
75
  })
84
76
 
85
77
  return {
86
- ...debouncer,
87
- executionCount,
88
- isPending,
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
@@ -5,6 +5,9 @@ export * from '@tanstack/pacer'
5
5
  * Export every hook individually - DON'T export from barrel files
6
6
  */
7
7
 
8
+ // async-batcher
9
+ export * from './async-batcher/createAsyncBatcher'
10
+
8
11
  // async-debouncer
9
12
  export * from './async-debouncer/createAsyncDebouncer'
10
13