diff --git a/.changeset/add-solid-queued-hooks.md b/.changeset/add-solid-queued-hooks.md new file mode 100644 index 00000000..8c803f7b --- /dev/null +++ b/.changeset/add-solid-queued-hooks.md @@ -0,0 +1,8 @@ +--- +'@tanstack/solid-pacer': minor +--- + +Add new Solid hooks for queue management and provider + +- Add `createQueuedSignal` - Solid equivalent of `useQueuedState` with signal-based queue item tracking +- Add `PacerProvider` - Context provider for setting default pacer options in Solid apps diff --git a/docs/config.json b/docs/config.json index df95b5cc..9667aaed 100644 --- a/docs/config.json +++ b/docs/config.json @@ -540,6 +540,10 @@ { "label": "createAsyncQueuer", "to": "framework/solid/reference/functions/createAsyncQueuer" + }, + { + "label": "createQueuedSignal", + "to": "framework/solid/reference/functions/createQueuedSignal" } ] } @@ -939,6 +943,10 @@ { "label": "createAsyncQueuer", "to": "framework/solid/examples/createAsyncQueuer" + }, + { + "label": "createQueuedSignal", + "to": "framework/solid/examples/createQueuedSignal" } ] } diff --git a/docs/framework/solid/reference/functions/PacerProvider.md b/docs/framework/solid/reference/functions/PacerProvider.md new file mode 100644 index 00000000..0d5238b0 --- /dev/null +++ b/docs/framework/solid/reference/functions/PacerProvider.md @@ -0,0 +1,22 @@ +--- +id: PacerProvider +title: PacerProvider +--- + +# Function: PacerProvider() + +```ts +function PacerProvider(props): Element; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:44](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L44) + +## Parameters + +### props + +[`PacerProviderProps`](../../interfaces/PacerProviderProps.md) + +## Returns + +`Element` diff --git a/docs/framework/solid/reference/functions/createAsyncBatcher.md b/docs/framework/solid/reference/functions/createAsyncBatcher.md index c3add6ed..c2b5aaf5 100644 --- a/docs/framework/solid/reference/functions/createAsyncBatcher.md +++ b/docs/framework/solid/reference/functions/createAsyncBatcher.md @@ -8,11 +8,11 @@ title: createAsyncBatcher ```ts function createAsyncBatcher( fn, - initialOptions, + options, selector): SolidAsyncBatcher; ``` -Defined in: [async-batcher/createAsyncBatcher.ts:128](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L128) +Defined in: [solid-pacer/src/async-batcher/createAsyncBatcher.ts:129](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L129) Creates a Solid-compatible AsyncBatcher instance for managing asynchronous batches of items, exposing Solid signals for all stateful properties. @@ -132,7 +132,7 @@ const { items, isExecuting } = asyncBatcher.state(); (`items`) => `Promise`\<`any`\> -### initialOptions +### options `AsyncBatcherOptions`\<`TValue`\> = `{}` diff --git a/docs/framework/solid/reference/functions/createAsyncDebouncer.md b/docs/framework/solid/reference/functions/createAsyncDebouncer.md index 9b833963..aa277d93 100644 --- a/docs/framework/solid/reference/functions/createAsyncDebouncer.md +++ b/docs/framework/solid/reference/functions/createAsyncDebouncer.md @@ -8,11 +8,11 @@ title: createAsyncDebouncer ```ts function createAsyncDebouncer( fn, - initialOptions, + options, selector): SolidAsyncDebouncer; ``` -Defined in: [async-debouncer/createAsyncDebouncer.ts:118](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L118) +Defined in: [solid-pacer/src/async-debouncer/createAsyncDebouncer.ts:119](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L119) A low-level Solid hook that creates an `AsyncDebouncer` instance to delay execution of an async function. @@ -76,7 +76,7 @@ Available state properties: `TFn` -### initialOptions +### options `AsyncDebouncerOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/createAsyncQueuer.md b/docs/framework/solid/reference/functions/createAsyncQueuer.md index 43d41d96..ccc646ce 100644 --- a/docs/framework/solid/reference/functions/createAsyncQueuer.md +++ b/docs/framework/solid/reference/functions/createAsyncQueuer.md @@ -8,11 +8,11 @@ title: createAsyncQueuer ```ts function createAsyncQueuer( fn, - initialOptions, + options, selector): SolidAsyncQueuer; ``` -Defined in: [async-queuer/createAsyncQueuer.ts:120](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L120) +Defined in: [solid-pacer/src/async-queuer/createAsyncQueuer.ts:121](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L121) Creates a Solid-compatible AsyncQueuer instance for managing an asynchronous queue of items, exposing Solid signals for all stateful properties. @@ -124,7 +124,7 @@ const { pendingItems, activeItems } = asyncQueuer.state(); (`value`) => `Promise`\<`any`\> -### initialOptions +### options `AsyncQueuerOptions`\<`TValue`\> = `{}` diff --git a/docs/framework/solid/reference/functions/createAsyncRateLimiter.md b/docs/framework/solid/reference/functions/createAsyncRateLimiter.md index 1125a6aa..2b7a941c 100644 --- a/docs/framework/solid/reference/functions/createAsyncRateLimiter.md +++ b/docs/framework/solid/reference/functions/createAsyncRateLimiter.md @@ -8,11 +8,11 @@ title: createAsyncRateLimiter ```ts function createAsyncRateLimiter( fn, - initialOptions, + options, selector): SolidAsyncRateLimiter; ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:129](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L129) +Defined in: [solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts:130](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L130) A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window. @@ -87,7 +87,7 @@ Available state properties: `TFn` -### initialOptions +### options `AsyncRateLimiterOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/createAsyncThrottler.md b/docs/framework/solid/reference/functions/createAsyncThrottler.md index 4f167018..57d47735 100644 --- a/docs/framework/solid/reference/functions/createAsyncThrottler.md +++ b/docs/framework/solid/reference/functions/createAsyncThrottler.md @@ -8,11 +8,11 @@ title: createAsyncThrottler ```ts function createAsyncThrottler( fn, - initialOptions, + options, selector): SolidAsyncThrottler; ``` -Defined in: [async-throttler/createAsyncThrottler.ts:117](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L117) +Defined in: [solid-pacer/src/async-throttler/createAsyncThrottler.ts:118](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L118) A low-level Solid hook that creates an `AsyncThrottler` instance to limit how often an async function can execute. @@ -76,7 +76,7 @@ Available state properties: `TFn` -### initialOptions +### options `AsyncThrottlerOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/createBatcher.md b/docs/framework/solid/reference/functions/createBatcher.md index c77dd816..af94f347 100644 --- a/docs/framework/solid/reference/functions/createBatcher.md +++ b/docs/framework/solid/reference/functions/createBatcher.md @@ -8,11 +8,11 @@ title: createBatcher ```ts function createBatcher( fn, - initialOptions, + options, selector): SolidBatcher; ``` -Defined in: [batcher/createBatcher.ts:100](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L100) +Defined in: [solid-pacer/src/batcher/createBatcher.ts:101](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L101) Creates a Solid-compatible Batcher instance for managing batches of items, exposing Solid signals for all stateful properties. @@ -107,7 +107,7 @@ const { items, isRunning } = batcher.state(); (`items`) => `void` -### initialOptions +### options `BatcherOptions`\<`TValue`\> = `{}` diff --git a/docs/framework/solid/reference/functions/createDebouncedSignal.md b/docs/framework/solid/reference/functions/createDebouncedSignal.md index 48efe06d..71892879 100644 --- a/docs/framework/solid/reference/functions/createDebouncedSignal.md +++ b/docs/framework/solid/reference/functions/createDebouncedSignal.md @@ -12,7 +12,7 @@ function createDebouncedSignal( selector?): [Accessor, Setter, SolidDebouncer, TSelected>]; ``` -Defined in: [debouncer/createDebouncedSignal.ts:81](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncedSignal.ts#L81) +Defined in: [solid-pacer/src/debouncer/createDebouncedSignal.ts:81](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncedSignal.ts#L81) A Solid hook that creates a debounced state value, combining Solid's createSignal with debouncing functionality. This hook provides both the current debounced value and methods to update it. diff --git a/docs/framework/solid/reference/functions/createDebouncedValue.md b/docs/framework/solid/reference/functions/createDebouncedValue.md index feacb217..ecbb4597 100644 --- a/docs/framework/solid/reference/functions/createDebouncedValue.md +++ b/docs/framework/solid/reference/functions/createDebouncedValue.md @@ -12,7 +12,7 @@ function createDebouncedValue( selector?): [Accessor, SolidDebouncer, TSelected>]; ``` -Defined in: [debouncer/createDebouncedValue.ts:72](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncedValue.ts#L72) +Defined in: [solid-pacer/src/debouncer/createDebouncedValue.ts:72](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncedValue.ts#L72) A Solid hook that creates a debounced value that updates only after a specified delay. Unlike createDebouncedSignal, this hook automatically tracks changes to the input value diff --git a/docs/framework/solid/reference/functions/createDebouncer.md b/docs/framework/solid/reference/functions/createDebouncer.md index ea25da94..eabdc748 100644 --- a/docs/framework/solid/reference/functions/createDebouncer.md +++ b/docs/framework/solid/reference/functions/createDebouncer.md @@ -8,11 +8,11 @@ title: createDebouncer ```ts function createDebouncer( fn, - initialOptions, + options, selector): SolidDebouncer; ``` -Defined in: [debouncer/createDebouncer.ts:103](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L103) +Defined in: [solid-pacer/src/debouncer/createDebouncer.ts:104](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L104) A Solid hook that creates and manages a Debouncer instance. @@ -63,7 +63,7 @@ Available state properties: `TFn` -### initialOptions +### options `DebouncerOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/createQueuedSignal.md b/docs/framework/solid/reference/functions/createQueuedSignal.md new file mode 100644 index 00000000..66760cc3 --- /dev/null +++ b/docs/framework/solid/reference/functions/createQueuedSignal.md @@ -0,0 +1,157 @@ +--- +id: createQueuedSignal +title: createQueuedSignal +--- + +# Function: createQueuedSignal() + +```ts +function createQueuedSignal( + fn, + options, + selector): [() => TValue[], (item, position?, runOnItemsChange?) => boolean, SolidQueuer]; +``` + +Defined in: [solid-pacer/src/queuer/createQueuedSignal.ts:119](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuedSignal.ts#L119) + +A Solid primitive that creates a queuer with managed state, combining Solid's signals with queuing functionality. +This primitive provides both the current queue state and queue control methods. + +The queue state is automatically updated whenever items are added, removed, or reordered in the queue. +All queue operations are reflected in the state array returned by the primitive. + +The queue can be started and stopped to automatically process items at a specified interval, +making it useful as a scheduler. When started, it will process one item per tick, with an +optional wait time between ticks. + +The primitive returns a tuple containing: +- The current queue state as an array +- The queue instance with methods for queue manipulation + +## State Management and Selector + +The primitive uses Solid's reactive state management via the underlying queuer instance. +The `selector` parameter allows you to specify which queuer state changes will trigger a re-render, +optimizing performance by preventing unnecessary re-renders when irrelevant state changes occur. + +**By default, there will be no reactive state subscriptions** and you must opt-in to state +tracking by providing a selector function. This prevents unnecessary re-renders and gives you +full control over when your component updates. Only when you provide a selector will the +component re-render when the selected state values change. + +Available queuer state properties: +- `executionCount`: Number of items that have been processed by the queuer +- `expirationCount`: Number of items that have been removed due to expiration +- `isEmpty`: Whether the queuer has no items to process +- `isFull`: Whether the queuer has reached its maximum capacity +- `isIdle`: Whether the queuer is not currently processing any items +- `isRunning`: Whether the queuer is active and will process items automatically +- `items`: Array of items currently waiting to be processed +- `itemTimestamps`: Timestamps when items were added for expiration tracking +- `pendingTick`: Whether the queuer has a pending timeout for processing the next item +- `rejectionCount`: Number of items that have been rejected from being added +- `size`: Number of items currently in the queue +- `status`: Current processing status ('idle' | 'running' | 'stopped') + +## Type Parameters + +### TValue + +`TValue` + +### TSelected + +`TSelected` *extends* `Pick`\<`QueuerState`\<`TValue`\>, `"items"`\> = `Pick`\<`QueuerState`\<`TValue`\>, `"items"`\> + +## Parameters + +### fn + +(`item`) => `void` + +### options + +`QueuerOptions`\<`TValue`\> = `{}` + +### selector + +(`state`) => `TSelected` + +## Returns + +\[() => `TValue`[], (`item`, `position?`, `runOnItemsChange?`) => `boolean`, [`SolidQueuer`](../../interfaces/SolidQueuer.md)\<`TValue`, `TSelected`\>\] + +## Example + +```tsx +// Default behavior - no reactive state subscriptions +const [items, addItem, queue] = createQueuedSignal( + (item) => console.log('Processing:', item), + { + initialItems: ['item1', 'item2'], + started: true, + wait: 1000, + getPriority: (item) => item.priority + } +); + +// Opt-in to re-render when queue contents change (optimized for displaying queue items) +const [items, addItem, queue] = createQueuedSignal( + (item) => console.log('Processing:', item), + { started: true, wait: 1000 }, + (state) => ({ + items: state.items, + size: state.size, + isEmpty: state.isEmpty + }) +); + +// Opt-in to re-render when processing state changes (optimized for loading indicators) +const [items, addItem, queue] = createQueuedSignal( + (item) => console.log('Processing:', item), + { started: true, wait: 1000 }, + (state) => ({ + isRunning: state.isRunning, + isIdle: state.isIdle, + status: state.status, + pendingTick: state.pendingTick + }) +); + +// Opt-in to re-render when execution metrics change (optimized for stats display) +const [items, addItem, queue] = createQueuedSignal( + (item) => console.log('Processing:', item), + { started: true, wait: 1000 }, + (state) => ({ + executionCount: state.executionCount, + expirationCount: state.expirationCount, + rejectionCount: state.rejectionCount + }) +); + +// Add items to queue +const handleAdd = (item) => { + addItem(item); +}; + +// Start automatic processing +const startProcessing = () => { + queue.start(); +}; + +// Stop automatic processing +const stopProcessing = () => { + queue.stop(); +}; + +// Manual processing still available +const handleProcess = () => { + const nextItem = queue.getNextItem(); + if (nextItem) { + processItem(nextItem); + } +}; + +// Access the selected queuer state (will be empty object {} unless selector provided) +const { size, isRunning, executionCount } = queue.state; +``` diff --git a/docs/framework/solid/reference/functions/createQueuer.md b/docs/framework/solid/reference/functions/createQueuer.md index ca9666a0..20fb30cc 100644 --- a/docs/framework/solid/reference/functions/createQueuer.md +++ b/docs/framework/solid/reference/functions/createQueuer.md @@ -8,11 +8,11 @@ title: createQueuer ```ts function createQueuer( fn, - initialOptions, + options, selector): SolidQueuer; ``` -Defined in: [queuer/createQueuer.ts:101](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L101) +Defined in: [solid-pacer/src/queuer/createQueuer.ts:102](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L102) Creates a Solid-compatible Queuer instance for managing a synchronous queue of items, exposing Solid signals for all stateful properties. @@ -108,7 +108,7 @@ const { items, isRunning } = queue.state(); (`item`) => `void` -### initialOptions +### options `QueuerOptions`\<`TValue`\> = `{}` diff --git a/docs/framework/solid/reference/functions/createRateLimitedSignal.md b/docs/framework/solid/reference/functions/createRateLimitedSignal.md index 7cfec1b4..01835bc5 100644 --- a/docs/framework/solid/reference/functions/createRateLimitedSignal.md +++ b/docs/framework/solid/reference/functions/createRateLimitedSignal.md @@ -12,7 +12,7 @@ function createRateLimitedSignal( selector?): [Accessor, Setter, SolidRateLimiter, TSelected>]; ``` -Defined in: [rate-limiter/createRateLimitedSignal.ts:95](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L95) +Defined in: [solid-pacer/src/rate-limiter/createRateLimitedSignal.ts:95](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L95) A Solid hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window. This hook combines Solid's createSignal with rate limiting functionality to provide controlled state updates. diff --git a/docs/framework/solid/reference/functions/createRateLimitedValue.md b/docs/framework/solid/reference/functions/createRateLimitedValue.md index abe85e1d..7dcc9e24 100644 --- a/docs/framework/solid/reference/functions/createRateLimitedValue.md +++ b/docs/framework/solid/reference/functions/createRateLimitedValue.md @@ -12,7 +12,7 @@ function createRateLimitedValue( selector?): [Accessor, SolidRateLimiter, TSelected>]; ``` -Defined in: [rate-limiter/createRateLimitedValue.ts:83](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L83) +Defined in: [solid-pacer/src/rate-limiter/createRateLimitedValue.ts:97](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L97) A high-level Solid hook that creates a rate-limited version of a value that updates at most a certain number of times within a time window. This hook uses Solid's createSignal internally to manage the rate-limited state. @@ -52,13 +52,9 @@ full control over when your component subscribes to state changes. Only when you the reactive system track the selected state values. Available rate limiter state properties: -- `callsInWindow`: Number of calls made in the current window -- `remainingInWindow`: Number of calls remaining in the current window -- `windowStart`: Unix timestamp when the current window started -- `nextWindowStart`: Unix timestamp when the next window will start -- `msUntilNextWindow`: Milliseconds until the next window starts -- `isAtLimit`: Whether the call limit for the current window has been reached -- `status`: Current status ('disabled' | 'idle' | 'at-limit') +- `executionCount`: Number of function executions that have been completed +- `executionTimes`: Array of timestamps when executions occurred for rate limiting calculations +- `rejectionCount`: Number of function executions that have been rejected due to rate limiting ## Type Parameters @@ -99,19 +95,37 @@ const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { windowType: 'sliding' }); -// Opt-in to reactive updates when limit state changes (optimized for UI feedback) +// Opt-in to reactive updates when execution count changes (optimized for tracking successful updates) const [rateLimitedValue, rateLimiter] = createRateLimitedValue( rawValue, - { limit: 5, window: 60000 }, - (state) => ({ isAtLimit: state.isAtLimit, remainingInWindow: state.remainingInWindow }) + { limit: 5, window: 60000, windowType: 'sliding' }, + (state) => ({ executionCount: state.executionCount }) ); -// Use the rate-limited value -console.log(rateLimitedValue()); // Access the current rate-limited value +// Opt-in to reactive updates when rejection count changes (optimized for tracking rate limit violations) +const [rateLimitedValue, rateLimiter] = createRateLimitedValue( + rawValue, + { limit: 5, window: 60000, windowType: 'sliding' }, + (state) => ({ rejectionCount: state.rejectionCount }) +); -// Access rate limiter state via signals -console.log('Is at limit:', rateLimiter.state().isAtLimit); +// Opt-in to reactive updates when execution times change (optimized for window calculations) +const [rateLimitedValue, rateLimiter] = createRateLimitedValue( + rawValue, + { limit: 5, window: 60000, windowType: 'sliding' }, + (state) => ({ executionTimes: state.executionTimes }) +); + +// With rejection callback and fixed window +const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { + limit: 3, + window: 5000, + windowType: 'fixed', + onReject: (rateLimiter) => { + console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); + } +}); -// Control the rate limiter -rateLimiter.reset(); // Reset the rate limit window +// Access the selected rate limiter state (will be empty object {} unless selector provided) +const { executionCount, rejectionCount } = rateLimiter.state; ``` diff --git a/docs/framework/solid/reference/functions/createRateLimiter.md b/docs/framework/solid/reference/functions/createRateLimiter.md index 29c3659d..90cb4576 100644 --- a/docs/framework/solid/reference/functions/createRateLimiter.md +++ b/docs/framework/solid/reference/functions/createRateLimiter.md @@ -8,11 +8,11 @@ title: createRateLimiter ```ts function createRateLimiter( fn, - initialOptions, + options, selector): SolidRateLimiter; ``` -Defined in: [rate-limiter/createRateLimiter.ts:102](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L102) +Defined in: [solid-pacer/src/rate-limiter/createRateLimiter.ts:103](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L103) A low-level Solid hook that creates a `RateLimiter` instance to enforce rate limits on function execution. @@ -69,7 +69,7 @@ Available state properties: `TFn` -### initialOptions +### options `RateLimiterOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/createThrottledSignal.md b/docs/framework/solid/reference/functions/createThrottledSignal.md index 5876b4bf..65696c96 100644 --- a/docs/framework/solid/reference/functions/createThrottledSignal.md +++ b/docs/framework/solid/reference/functions/createThrottledSignal.md @@ -12,7 +12,7 @@ function createThrottledSignal( selector?): [Accessor, Setter, SolidThrottler, TSelected>]; ``` -Defined in: [throttler/createThrottledSignal.ts:72](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottledSignal.ts#L72) +Defined in: [solid-pacer/src/throttler/createThrottledSignal.ts:72](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottledSignal.ts#L72) A Solid hook that creates a throttled state value that updates at most once within a specified time window. This hook combines Solid's createSignal with throttling functionality to provide controlled state updates. diff --git a/docs/framework/solid/reference/functions/createThrottledValue.md b/docs/framework/solid/reference/functions/createThrottledValue.md index 8b43a9f9..54595b76 100644 --- a/docs/framework/solid/reference/functions/createThrottledValue.md +++ b/docs/framework/solid/reference/functions/createThrottledValue.md @@ -12,7 +12,7 @@ function createThrottledValue( selector?): [Accessor, SolidThrottler, TSelected>]; ``` -Defined in: [throttler/createThrottledValue.ts:69](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottledValue.ts#L69) +Defined in: [solid-pacer/src/throttler/createThrottledValue.ts:69](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottledValue.ts#L69) A high-level Solid hook that creates a throttled version of a value that updates at most once within a specified time window. This hook uses Solid's createSignal internally to manage the throttled state. diff --git a/docs/framework/solid/reference/functions/createThrottler.md b/docs/framework/solid/reference/functions/createThrottler.md index 3e5b0d11..4acfccd2 100644 --- a/docs/framework/solid/reference/functions/createThrottler.md +++ b/docs/framework/solid/reference/functions/createThrottler.md @@ -8,11 +8,11 @@ title: createThrottler ```ts function createThrottler( fn, - initialOptions, + options, selector): SolidThrottler; ``` -Defined in: [throttler/createThrottler.ts:99](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L99) +Defined in: [solid-pacer/src/throttler/createThrottler.ts:100](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L100) A low-level Solid hook that creates a `Throttler` instance that limits how often the provided function can execute. @@ -62,7 +62,7 @@ Available state properties: `TFn` -### initialOptions +### options `ThrottlerOptions`\<`TFn`\> diff --git a/docs/framework/solid/reference/functions/useDefaultPacerOptions.md b/docs/framework/solid/reference/functions/useDefaultPacerOptions.md new file mode 100644 index 00000000..6a5c554e --- /dev/null +++ b/docs/framework/solid/reference/functions/useDefaultPacerOptions.md @@ -0,0 +1,16 @@ +--- +id: useDefaultPacerOptions +title: useDefaultPacerOptions +--- + +# Function: useDefaultPacerOptions() + +```ts +function useDefaultPacerOptions(): PacerProviderOptions; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:60](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L60) + +## Returns + +[`PacerProviderOptions`](../../interfaces/PacerProviderOptions.md) diff --git a/docs/framework/solid/reference/functions/usePacerContext.md b/docs/framework/solid/reference/functions/usePacerContext.md new file mode 100644 index 00000000..12ef5ce1 --- /dev/null +++ b/docs/framework/solid/reference/functions/usePacerContext.md @@ -0,0 +1,16 @@ +--- +id: usePacerContext +title: usePacerContext +--- + +# Function: usePacerContext() + +```ts +function usePacerContext(): PacerContextValue | null; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:56](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L56) + +## Returns + +`PacerContextValue` \| `null` diff --git a/docs/framework/solid/reference/index.md b/docs/framework/solid/reference/index.md index 0a439eee..178e989e 100644 --- a/docs/framework/solid/reference/index.md +++ b/docs/framework/solid/reference/index.md @@ -7,6 +7,8 @@ title: "@tanstack/solid-pacer" ## Interfaces +- [PacerProviderOptions](../interfaces/PacerProviderOptions.md) +- [PacerProviderProps](../interfaces/PacerProviderProps.md) - [SolidAsyncBatcher](../interfaces/SolidAsyncBatcher.md) - [SolidAsyncDebouncer](../interfaces/SolidAsyncDebouncer.md) - [SolidAsyncQueuer](../interfaces/SolidAsyncQueuer.md) @@ -29,6 +31,7 @@ title: "@tanstack/solid-pacer" - [createDebouncedSignal](../functions/createDebouncedSignal.md) - [createDebouncedValue](../functions/createDebouncedValue.md) - [createDebouncer](../functions/createDebouncer.md) +- [createQueuedSignal](../functions/createQueuedSignal.md) - [createQueuer](../functions/createQueuer.md) - [createRateLimitedSignal](../functions/createRateLimitedSignal.md) - [createRateLimitedValue](../functions/createRateLimitedValue.md) @@ -36,3 +39,6 @@ title: "@tanstack/solid-pacer" - [createThrottledSignal](../functions/createThrottledSignal.md) - [createThrottledValue](../functions/createThrottledValue.md) - [createThrottler](../functions/createThrottler.md) +- [PacerProvider](../functions/PacerProvider.md) +- [useDefaultPacerOptions](../functions/useDefaultPacerOptions.md) +- [usePacerContext](../functions/usePacerContext.md) diff --git a/docs/framework/solid/reference/interfaces/PacerProviderOptions.md b/docs/framework/solid/reference/interfaces/PacerProviderOptions.md new file mode 100644 index 00000000..b0b79171 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/PacerProviderOptions.md @@ -0,0 +1,108 @@ +--- +id: PacerProviderOptions +title: PacerProviderOptions +--- + +# Interface: PacerProviderOptions + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:18](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L18) + +## Properties + +### asyncBatcher? + +```ts +optional asyncBatcher: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:19](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L19) + +*** + +### asyncDebouncer? + +```ts +optional asyncDebouncer: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L20) + +*** + +### asyncQueuer? + +```ts +optional asyncQueuer: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L21) + +*** + +### asyncRateLimiter? + +```ts +optional asyncRateLimiter: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:22](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L22) + +*** + +### asyncThrottler? + +```ts +optional asyncThrottler: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:23](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L23) + +*** + +### batcher? + +```ts +optional batcher: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:24](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L24) + +*** + +### debouncer? + +```ts +optional debouncer: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:25](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L25) + +*** + +### queuer? + +```ts +optional queuer: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:26](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L26) + +*** + +### rateLimiter? + +```ts +optional rateLimiter: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:27](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L27) + +*** + +### throttler? + +```ts +optional throttler: Partial>; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:28](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L28) diff --git a/docs/framework/solid/reference/interfaces/PacerProviderProps.md b/docs/framework/solid/reference/interfaces/PacerProviderProps.md new file mode 100644 index 00000000..e28eb225 --- /dev/null +++ b/docs/framework/solid/reference/interfaces/PacerProviderProps.md @@ -0,0 +1,28 @@ +--- +id: PacerProviderProps +title: PacerProviderProps +--- + +# Interface: PacerProviderProps + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:37](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L37) + +## Properties + +### children + +```ts +children: Element; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:38](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L38) + +*** + +### defaultOptions? + +```ts +optional defaultOptions: PacerProviderOptions; +``` + +Defined in: [solid-pacer/src/provider/PacerProvider.tsx:39](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/provider/PacerProvider.tsx#L39) diff --git a/docs/framework/solid/reference/interfaces/SolidAsyncBatcher.md b/docs/framework/solid/reference/interfaces/SolidAsyncBatcher.md index 1823888f..1fa55a0b 100644 --- a/docs/framework/solid/reference/interfaces/SolidAsyncBatcher.md +++ b/docs/framework/solid/reference/interfaces/SolidAsyncBatcher.md @@ -5,7 +5,7 @@ title: SolidAsyncBatcher # Interface: SolidAsyncBatcher\ -Defined in: [async-batcher/createAsyncBatcher.ts:10](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L10) +Defined in: [solid-pacer/src/async-batcher/createAsyncBatcher.ts:11](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L11) ## Extends @@ -30,7 +30,7 @@ Defined in: [async-batcher/createAsyncBatcher.ts:10](https://github.com/TanStack readonly state: Accessor>; ``` -Defined in: [async-batcher/createAsyncBatcher.ts:17](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L17) +Defined in: [solid-pacer/src/async-batcher/createAsyncBatcher.ts:18](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L18) Reactive state that will be updated when the batcher state changes @@ -44,7 +44,7 @@ Use this instead of `batcher.store.state` readonly store: Store>>; ``` -Defined in: [async-batcher/createAsyncBatcher.ts:23](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L23) +Defined in: [solid-pacer/src/async-batcher/createAsyncBatcher.ts:24](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts#L24) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidAsyncDebouncer.md b/docs/framework/solid/reference/interfaces/SolidAsyncDebouncer.md index a73561e7..3614e257 100644 --- a/docs/framework/solid/reference/interfaces/SolidAsyncDebouncer.md +++ b/docs/framework/solid/reference/interfaces/SolidAsyncDebouncer.md @@ -5,7 +5,7 @@ title: SolidAsyncDebouncer # Interface: SolidAsyncDebouncer\ -Defined in: [async-debouncer/createAsyncDebouncer.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L12) +Defined in: [solid-pacer/src/async-debouncer/createAsyncDebouncer.ts:13](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L13) ## Extends @@ -30,7 +30,7 @@ Defined in: [async-debouncer/createAsyncDebouncer.ts:12](https://github.com/TanS readonly state: Accessor>; ``` -Defined in: [async-debouncer/createAsyncDebouncer.ts:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L21) +Defined in: [solid-pacer/src/async-debouncer/createAsyncDebouncer.ts:22](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L22) Reactive state that will be updated when the debouncer state changes @@ -44,7 +44,7 @@ Use this instead of `debouncer.store.state` readonly store: Store>>; ``` -Defined in: [async-debouncer/createAsyncDebouncer.ts:27](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L27) +Defined in: [solid-pacer/src/async-debouncer/createAsyncDebouncer.ts:28](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts#L28) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidAsyncQueuer.md b/docs/framework/solid/reference/interfaces/SolidAsyncQueuer.md index 65e5ec07..b749f3b8 100644 --- a/docs/framework/solid/reference/interfaces/SolidAsyncQueuer.md +++ b/docs/framework/solid/reference/interfaces/SolidAsyncQueuer.md @@ -5,7 +5,7 @@ title: SolidAsyncQueuer # Interface: SolidAsyncQueuer\ -Defined in: [async-queuer/createAsyncQueuer.ts:10](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L10) +Defined in: [solid-pacer/src/async-queuer/createAsyncQueuer.ts:11](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L11) ## Extends @@ -30,7 +30,7 @@ Defined in: [async-queuer/createAsyncQueuer.ts:10](https://github.com/TanStack/p readonly state: Accessor>; ``` -Defined in: [async-queuer/createAsyncQueuer.ts:17](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L17) +Defined in: [solid-pacer/src/async-queuer/createAsyncQueuer.ts:18](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L18) Reactive state that will be updated when the queuer state changes @@ -44,7 +44,7 @@ Use this instead of `queuer.store.state` readonly store: Store>>; ``` -Defined in: [async-queuer/createAsyncQueuer.ts:23](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L23) +Defined in: [solid-pacer/src/async-queuer/createAsyncQueuer.ts:24](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts#L24) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidAsyncRateLimiter.md b/docs/framework/solid/reference/interfaces/SolidAsyncRateLimiter.md index 008aecf7..85111b2b 100644 --- a/docs/framework/solid/reference/interfaces/SolidAsyncRateLimiter.md +++ b/docs/framework/solid/reference/interfaces/SolidAsyncRateLimiter.md @@ -5,7 +5,7 @@ title: SolidAsyncRateLimiter # Interface: SolidAsyncRateLimiter\ -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:11](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L11) +Defined in: [solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L12) ## Extends @@ -30,7 +30,7 @@ Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:11](https://github.com readonly state: Accessor>; ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L20) +Defined in: [solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L21) Reactive state that will be updated when the rate limiter state changes @@ -44,7 +44,7 @@ Use this instead of `rateLimiter.store.state` readonly store: Store>>; ``` -Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:26](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L26) +Defined in: [solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts:27](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L27) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidAsyncThrottler.md b/docs/framework/solid/reference/interfaces/SolidAsyncThrottler.md index 0cb85154..5fe34f91 100644 --- a/docs/framework/solid/reference/interfaces/SolidAsyncThrottler.md +++ b/docs/framework/solid/reference/interfaces/SolidAsyncThrottler.md @@ -5,7 +5,7 @@ title: SolidAsyncThrottler # Interface: SolidAsyncThrottler\ -Defined in: [async-throttler/createAsyncThrottler.ts:11](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L11) +Defined in: [solid-pacer/src/async-throttler/createAsyncThrottler.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L12) ## Extends @@ -30,7 +30,7 @@ Defined in: [async-throttler/createAsyncThrottler.ts:11](https://github.com/TanS readonly state: Accessor>; ``` -Defined in: [async-throttler/createAsyncThrottler.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L20) +Defined in: [solid-pacer/src/async-throttler/createAsyncThrottler.ts:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L21) Reactive state that will be updated when the throttler state changes @@ -44,7 +44,7 @@ Use this instead of `throttler.store.state` readonly store: Store>>; ``` -Defined in: [async-throttler/createAsyncThrottler.ts:26](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L26) +Defined in: [solid-pacer/src/async-throttler/createAsyncThrottler.ts:27](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts#L27) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidBatcher.md b/docs/framework/solid/reference/interfaces/SolidBatcher.md index 955ae9ec..373bee4e 100644 --- a/docs/framework/solid/reference/interfaces/SolidBatcher.md +++ b/docs/framework/solid/reference/interfaces/SolidBatcher.md @@ -5,7 +5,7 @@ title: SolidBatcher # Interface: SolidBatcher\ -Defined in: [batcher/createBatcher.ts:7](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L7) +Defined in: [solid-pacer/src/batcher/createBatcher.ts:8](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L8) ## Extends @@ -30,7 +30,7 @@ Defined in: [batcher/createBatcher.ts:7](https://github.com/TanStack/pacer/blob/ readonly state: Accessor>; ``` -Defined in: [batcher/createBatcher.ts:14](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L14) +Defined in: [solid-pacer/src/batcher/createBatcher.ts:15](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L15) Reactive state that will be updated when the batcher state changes @@ -44,7 +44,7 @@ Use this instead of `batcher.store.state` readonly store: Store>>; ``` -Defined in: [batcher/createBatcher.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L20) +Defined in: [solid-pacer/src/batcher/createBatcher.ts:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/batcher/createBatcher.ts#L21) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidDebouncer.md b/docs/framework/solid/reference/interfaces/SolidDebouncer.md index 0ef37e0a..c4d394ef 100644 --- a/docs/framework/solid/reference/interfaces/SolidDebouncer.md +++ b/docs/framework/solid/reference/interfaces/SolidDebouncer.md @@ -5,7 +5,7 @@ title: SolidDebouncer # Interface: SolidDebouncer\ -Defined in: [debouncer/createDebouncer.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L12) +Defined in: [solid-pacer/src/debouncer/createDebouncer.ts:13](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L13) ## Extends @@ -30,7 +30,7 @@ Defined in: [debouncer/createDebouncer.ts:12](https://github.com/TanStack/pacer/ readonly state: Accessor>; ``` -Defined in: [debouncer/createDebouncer.ts:19](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L19) +Defined in: [solid-pacer/src/debouncer/createDebouncer.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L20) Reactive state that will be updated when the debouncer state changes @@ -44,7 +44,7 @@ Use this instead of `debouncer.store.state` readonly store: Store>>; ``` -Defined in: [debouncer/createDebouncer.ts:25](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L25) +Defined in: [solid-pacer/src/debouncer/createDebouncer.ts:26](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/debouncer/createDebouncer.ts#L26) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidQueuer.md b/docs/framework/solid/reference/interfaces/SolidQueuer.md index 15c5a5d8..1998468e 100644 --- a/docs/framework/solid/reference/interfaces/SolidQueuer.md +++ b/docs/framework/solid/reference/interfaces/SolidQueuer.md @@ -5,7 +5,7 @@ title: SolidQueuer # Interface: SolidQueuer\ -Defined in: [queuer/createQueuer.ts:7](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L7) +Defined in: [solid-pacer/src/queuer/createQueuer.ts:8](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L8) ## Extends @@ -30,7 +30,7 @@ Defined in: [queuer/createQueuer.ts:7](https://github.com/TanStack/pacer/blob/ma readonly state: Accessor>; ``` -Defined in: [queuer/createQueuer.ts:14](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L14) +Defined in: [solid-pacer/src/queuer/createQueuer.ts:15](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L15) Reactive state that will be updated when the queuer state changes @@ -44,7 +44,7 @@ Use this instead of `queuer.store.state` readonly store: Store>>; ``` -Defined in: [queuer/createQueuer.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L20) +Defined in: [solid-pacer/src/queuer/createQueuer.ts:21](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/queuer/createQueuer.ts#L21) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidRateLimiter.md b/docs/framework/solid/reference/interfaces/SolidRateLimiter.md index 0ae5cbe2..96e80156 100644 --- a/docs/framework/solid/reference/interfaces/SolidRateLimiter.md +++ b/docs/framework/solid/reference/interfaces/SolidRateLimiter.md @@ -5,7 +5,7 @@ title: SolidRateLimiter # Interface: SolidRateLimiter\ -Defined in: [rate-limiter/createRateLimiter.ts:11](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L11) +Defined in: [solid-pacer/src/rate-limiter/createRateLimiter.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L12) ## Extends @@ -30,7 +30,7 @@ Defined in: [rate-limiter/createRateLimiter.ts:11](https://github.com/TanStack/p readonly state: Accessor>; ``` -Defined in: [rate-limiter/createRateLimiter.ts:18](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L18) +Defined in: [solid-pacer/src/rate-limiter/createRateLimiter.ts:19](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L19) Reactive state that will be updated when the rate limiter state changes @@ -44,7 +44,7 @@ Use this instead of `rateLimiter.store.state` readonly store: Store>; ``` -Defined in: [rate-limiter/createRateLimiter.ts:24](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L24) +Defined in: [solid-pacer/src/rate-limiter/createRateLimiter.ts:25](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts#L25) #### Deprecated diff --git a/docs/framework/solid/reference/interfaces/SolidThrottler.md b/docs/framework/solid/reference/interfaces/SolidThrottler.md index eca6b76c..1b8f1414 100644 --- a/docs/framework/solid/reference/interfaces/SolidThrottler.md +++ b/docs/framework/solid/reference/interfaces/SolidThrottler.md @@ -5,7 +5,7 @@ title: SolidThrottler # Interface: SolidThrottler\ -Defined in: [throttler/createThrottler.ts:12](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L12) +Defined in: [solid-pacer/src/throttler/createThrottler.ts:13](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L13) ## Extends @@ -30,7 +30,7 @@ Defined in: [throttler/createThrottler.ts:12](https://github.com/TanStack/pacer/ readonly state: Accessor>; ``` -Defined in: [throttler/createThrottler.ts:19](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L19) +Defined in: [solid-pacer/src/throttler/createThrottler.ts:20](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L20) Reactive state that will be updated when the throttler state changes @@ -44,7 +44,7 @@ Use this instead of `throttler.store.state` readonly store: Store>>; ``` -Defined in: [throttler/createThrottler.ts:25](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L25) +Defined in: [solid-pacer/src/throttler/createThrottler.ts:26](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/throttler/createThrottler.ts#L26) #### Deprecated diff --git a/examples/react/useAsyncDebouncedCallback/package.json b/examples/react/useAsyncDebouncedCallback/package.json index ed861400..52a5dfe7 100644 --- a/examples/react/useAsyncDebouncedCallback/package.json +++ b/examples/react/useAsyncDebouncedCallback/package.json @@ -3,7 +3,7 @@ "private": true, "type": "module", "scripts": { - "dev": "vite --port=3007", + "dev": "vite --port=3005", "build": "vite build", "preview": "vite preview", "test:types": "tsc" diff --git a/examples/solid/createQueuedSignal/README.md b/examples/solid/createQueuedSignal/README.md new file mode 100644 index 00000000..7e67cbca --- /dev/null +++ b/examples/solid/createQueuedSignal/README.md @@ -0,0 +1,20 @@ +# TanStack Pacer `createQueuedSignal` Example + +This is a simple example of TanStack Pacer's `createQueuedSignal` hook, which manages a queue with built-in signal-based state management. + +## Features Demonstrated + +- Creating a queuer with managed state using `createQueuedSignal` +- Adding and processing items in a queue +- Controlling queue processing (start/stop/reset/clear) +- Reactive state tracking with optional selectors +- Automatic state updates through Solid's reactivity + +## Key Differences from React + +- Uses `createQueuedSignal` instead of `useQueuedState` +- Returns signals that need to be called as functions: `queueItems()` +- Uses Solid's `createSignal` for local state management +- Event handlers use `onInput` instead of `onChange` + +The `createQueuedSignal` hook combines a queuer instance with Solid's reactive system to automatically track queue items as a signal, making it easy to build reactive UIs around queue state. diff --git a/examples/solid/createQueuedSignal/index.html b/examples/solid/createQueuedSignal/index.html new file mode 100644 index 00000000..9b2af20b --- /dev/null +++ b/examples/solid/createQueuedSignal/index.html @@ -0,0 +1,16 @@ + + + + + + + + + TanStack Pacer Example + + + +
+ + + diff --git a/examples/solid/createQueuedSignal/package.json b/examples/solid/createQueuedSignal/package.json new file mode 100644 index 00000000..680c3707 --- /dev/null +++ b/examples/solid/createQueuedSignal/package.json @@ -0,0 +1,33 @@ +{ + "name": "@tanstack/pacer-example-solid-create-queued-signal", + "private": true, + "type": "module", + "scripts": { + "dev": "vite --port=3005", + "build": "vite build", + "preview": "vite preview", + "test:types": "tsc" + }, + "dependencies": { + "@tanstack/solid-devtools": "0.7.14", + "@tanstack/solid-pacer": "^0.15.3", + "@tanstack/solid-pacer-devtools": "0.4.0", + "solid-js": "^1.9.10" + }, + "devDependencies": { + "vite": "^7.2.2", + "vite-plugin-solid": "^2.11.10" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } +} diff --git a/examples/solid/createQueuedSignal/public/emblem-light.svg b/examples/solid/createQueuedSignal/public/emblem-light.svg new file mode 100644 index 00000000..a58e69ad --- /dev/null +++ b/examples/solid/createQueuedSignal/public/emblem-light.svg @@ -0,0 +1,13 @@ + + + + emblem-light + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/examples/solid/createQueuedSignal/src/index.tsx b/examples/solid/createQueuedSignal/src/index.tsx new file mode 100644 index 00000000..0eb4323c --- /dev/null +++ b/examples/solid/createQueuedSignal/src/index.tsx @@ -0,0 +1,223 @@ +import { render } from 'solid-js/web' +import { createQueuedSignal } from '@tanstack/solid-pacer/queuer' +import { createSignal } from 'solid-js' + +function App1() { + // Queuer that uses Solid signals under the hood + function processItem(item: number) { + console.log('processing item', item) + } + + const [queueItems, addItem, queuer] = createQueuedSignal( + processItem, + { + maxSize: 25, + initialItems: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], + started: false, + wait: 1000, // wait 1 second between processing items - wait is optional! + }, + // Optional Selector function to pick the state you want to track and use + (state) => ({ + items: state.items, // required for createQueuedSignal + size: state.size, + isFull: state.isFull, + isEmpty: state.isEmpty, + isIdle: state.isIdle, + status: state.status, + executionCount: state.executionCount, + isRunning: state.isRunning, + }), + ) + + return ( +
+

TanStack Pacer createQueuedSignal Example 1

+
Queue Size: {queuer.state().size}
+
Queue Max Size: {25}
+
Queue Full: {queuer.state().isFull ? 'Yes' : 'No'}
+
Queue Peek: {queuer.peekNextItem()}
+
Queue Empty: {queuer.state().isEmpty ? 'Yes' : 'No'}
+
Queue Idle: {queuer.state().isIdle ? 'Yes' : 'No'}
+
Queuer Status: {queuer.state().status}
+
Items Processed: {queuer.state().executionCount}
+
Queue Items: {queueItems().join(', ')}
+
+ + + + + + +
+
+        {JSON.stringify(queuer.store.state, null, 2)}
+      
+
+ ) +} + +function App2() { + const [currentValue, setCurrentValue] = createSignal(50) + const [instantExecutionCount, setInstantExecutionCount] = createSignal(0) + + // Queuer that processes a single value with delays + const [, addItem, queuer] = createQueuedSignal( + (_item: number) => { + // This will update automatically through the queue + }, + { + maxSize: 100, + started: true, + wait: 100, + }, + (state) => ({ + items: state.items, // required for createQueuedSignal + size: state.size, + isFull: state.isFull, + isEmpty: state.isEmpty, + isIdle: state.isIdle, + status: state.status, + executionCount: state.executionCount, + isRunning: state.isRunning, + }), + ) + + function handleRangeChange(e: Event) { + const target = e.target as HTMLInputElement + const newValue = parseInt(target.value, 10) + setCurrentValue(newValue) + setInstantExecutionCount((c) => c + 1) + addItem(newValue) + } + + return ( +
+

TanStack Pacer createQueuedSignal Example 2

+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Queue Size:{queuer.state().size}
Queue Full:{queuer.state().isFull ? 'Yes' : 'No'}
Queue Empty:{queuer.state().isEmpty ? 'Yes' : 'No'}
Queue Idle:{queuer.state().isIdle ? 'Yes' : 'No'}
Queuer Status:{queuer.state().status}
Instant Executions:{instantExecutionCount()}
Items Processed:{queuer.state().executionCount}
Saved Executions:{instantExecutionCount() - queuer.state().executionCount}
% Reduction: + {instantExecutionCount() === 0 + ? '0' + : Math.round( + ((instantExecutionCount() - queuer.state().executionCount) / + instantExecutionCount()) * + 100, + )} + % +
+
+

Queued with 100ms wait time

+
+
+        {JSON.stringify(queuer.store.state, null, 2)}
+      
+
+ ) +} + +render( + () => ( +
+ +
+ +
+ ), + document.getElementById('root')!, +) diff --git a/examples/solid/createQueuedSignal/tsconfig.json b/examples/solid/createQueuedSignal/tsconfig.json new file mode 100644 index 00000000..a0784796 --- /dev/null +++ b/examples/solid/createQueuedSignal/tsconfig.json @@ -0,0 +1,24 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "Bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "preserve", + "jsxImportSource": "solid-js", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src", "vite.config.ts"] +} diff --git a/examples/solid/createQueuedSignal/vite.config.ts b/examples/solid/createQueuedSignal/vite.config.ts new file mode 100644 index 00000000..6d47c41e --- /dev/null +++ b/examples/solid/createQueuedSignal/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import solid from 'vite-plugin-solid' + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [solid({})], +}) diff --git a/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts b/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts index 3d26a741..d8439fda 100644 --- a/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts +++ b/packages/solid-pacer/src/async-batcher/createAsyncBatcher.ts @@ -1,5 +1,6 @@ import { AsyncBatcher } from '@tanstack/pacer/async-batcher' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { @@ -127,11 +128,16 @@ export interface SolidAsyncBatcher */ export function createAsyncBatcher( fn: (items: Array) => Promise, - initialOptions: AsyncBatcherOptions = {}, + options: AsyncBatcherOptions = {}, selector: (state: AsyncBatcherState) => TSelected = () => ({}) as TSelected, ): SolidAsyncBatcher { - const asyncBatcher = new AsyncBatcher(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().asyncBatcher, + ...options, + } as AsyncBatcherOptions + + const asyncBatcher = new AsyncBatcher(fn, mergedOptions) const state = useStore(asyncBatcher.store, selector) diff --git a/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts b/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts index 8b0f573c..3dddbd70 100644 --- a/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts +++ b/packages/solid-pacer/src/async-debouncer/createAsyncDebouncer.ts @@ -1,6 +1,7 @@ import { AsyncDebouncer } from '@tanstack/pacer/async-debouncer' import { useStore } from '@tanstack/solid-store' import { createEffect, onCleanup } from 'solid-js' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { @@ -120,11 +121,16 @@ export function createAsyncDebouncer< TSelected = {}, >( fn: TFn, - initialOptions: AsyncDebouncerOptions, + options: AsyncDebouncerOptions, selector: (state: AsyncDebouncerState) => TSelected = () => ({}) as TSelected, ): SolidAsyncDebouncer { - const asyncDebouncer = new AsyncDebouncer(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().asyncDebouncer, + ...options, + } as AsyncDebouncerOptions + + const asyncDebouncer = new AsyncDebouncer(fn, mergedOptions) const state = useStore(asyncDebouncer.store, selector) diff --git a/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts b/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts index 5e83a982..5940483a 100644 --- a/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts +++ b/packages/solid-pacer/src/async-queuer/createAsyncQueuer.ts @@ -1,5 +1,6 @@ import { AsyncQueuer } from '@tanstack/pacer/async-queuer' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { @@ -119,11 +120,16 @@ export interface SolidAsyncQueuer */ export function createAsyncQueuer( fn: (value: TValue) => Promise, - initialOptions: AsyncQueuerOptions = {}, + options: AsyncQueuerOptions = {}, selector: (state: AsyncQueuerState) => TSelected = () => ({}) as TSelected, ): SolidAsyncQueuer { - const asyncQueuer = new AsyncQueuer(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().asyncQueuer, + ...options, + } as AsyncQueuerOptions + + const asyncQueuer = new AsyncQueuer(fn, mergedOptions) const state = useStore(asyncQueuer.store, selector) diff --git a/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts b/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts index 15eb6119..36b62c1d 100644 --- a/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts +++ b/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts @@ -1,5 +1,6 @@ import { AsyncRateLimiter } from '@tanstack/pacer/async-rate-limiter' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { AnyAsyncFunction } from '@tanstack/pacer/types' @@ -131,11 +132,16 @@ export function createAsyncRateLimiter< TSelected = {}, >( fn: TFn, - initialOptions: AsyncRateLimiterOptions, + options: AsyncRateLimiterOptions, selector: (state: AsyncRateLimiterState) => TSelected = () => ({}) as TSelected, ): SolidAsyncRateLimiter { - const asyncRateLimiter = new AsyncRateLimiter(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().asyncRateLimiter, + ...options, + } as AsyncRateLimiterOptions + + const asyncRateLimiter = new AsyncRateLimiter(fn, mergedOptions) const state = useStore(asyncRateLimiter.store, selector) diff --git a/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts b/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts index c3efba33..1d0c49fe 100644 --- a/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts +++ b/packages/solid-pacer/src/async-throttler/createAsyncThrottler.ts @@ -1,5 +1,6 @@ import { AsyncThrottler } from '@tanstack/pacer/async-throttler' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { AnyAsyncFunction } from '@tanstack/pacer/types' @@ -119,11 +120,16 @@ export function createAsyncThrottler< TSelected = {}, >( fn: TFn, - initialOptions: AsyncThrottlerOptions, + options: AsyncThrottlerOptions, selector: (state: AsyncThrottlerState) => TSelected = () => ({}) as TSelected, ): SolidAsyncThrottler { - const asyncThrottler = new AsyncThrottler(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().asyncThrottler, + ...options, + } as AsyncThrottlerOptions + + const asyncThrottler = new AsyncThrottler(fn, mergedOptions) const state = useStore(asyncThrottler.store, selector) diff --git a/packages/solid-pacer/src/batcher/createBatcher.ts b/packages/solid-pacer/src/batcher/createBatcher.ts index af8681e6..711be724 100644 --- a/packages/solid-pacer/src/batcher/createBatcher.ts +++ b/packages/solid-pacer/src/batcher/createBatcher.ts @@ -1,5 +1,6 @@ import { Batcher } from '@tanstack/pacer/batcher' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { BatcherOptions, BatcherState } from '@tanstack/pacer/batcher' @@ -99,11 +100,16 @@ export interface SolidBatcher */ export function createBatcher( fn: (items: Array) => void, - initialOptions: BatcherOptions = {}, + options: BatcherOptions = {}, selector: (state: BatcherState) => TSelected = () => ({}) as TSelected, ): SolidBatcher { - const batcher = new Batcher(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().batcher, + ...options, + } as BatcherOptions + + const batcher = new Batcher(fn, mergedOptions) const state = useStore(batcher.store, selector) return { diff --git a/packages/solid-pacer/src/debouncer/createDebouncer.ts b/packages/solid-pacer/src/debouncer/createDebouncer.ts index 2a638cc8..7eed21ff 100644 --- a/packages/solid-pacer/src/debouncer/createDebouncer.ts +++ b/packages/solid-pacer/src/debouncer/createDebouncer.ts @@ -1,6 +1,7 @@ import { Debouncer } from '@tanstack/pacer/debouncer' import { createEffect, onCleanup } from 'solid-js' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { AnyFunction } from '@tanstack/pacer/types' @@ -102,10 +103,15 @@ export interface SolidDebouncer */ export function createDebouncer( fn: TFn, - initialOptions: DebouncerOptions, + options: DebouncerOptions, selector: (state: DebouncerState) => TSelected = () => ({}) as TSelected, ): SolidDebouncer { - const asyncDebouncer = new Debouncer(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().debouncer, + ...options, + } as DebouncerOptions + + const asyncDebouncer = new Debouncer(fn, mergedOptions) const state = useStore(asyncDebouncer.store, selector) diff --git a/packages/solid-pacer/src/index.ts b/packages/solid-pacer/src/index.ts index 9ad6c4de..853e5994 100644 --- a/packages/solid-pacer/src/index.ts +++ b/packages/solid-pacer/src/index.ts @@ -1,6 +1,9 @@ // re-export everything from the core pacer package export * from '@tanstack/pacer' +// provider +export * from './provider/PacerProvider' + /** * Export every hook individually - DON'T export from barrel files */ @@ -30,6 +33,7 @@ export * from './debouncer/createDebouncer' // queuer export * from './queuer/createQueuer' +export * from './queuer/createQueuedSignal' // rate-limiter export * from './rate-limiter/createRateLimiter' diff --git a/packages/solid-pacer/src/provider/PacerProvider.tsx b/packages/solid-pacer/src/provider/PacerProvider.tsx new file mode 100644 index 00000000..a2469b16 --- /dev/null +++ b/packages/solid-pacer/src/provider/PacerProvider.tsx @@ -0,0 +1,63 @@ +import { createContext, useContext } from 'solid-js' +import type { JSX } from 'solid-js' +import type { + AnyAsyncFunction, + AnyFunction, + AsyncBatcherOptions, + AsyncDebouncerOptions, + AsyncQueuerOptions, + AsyncRateLimiterOptions, + AsyncThrottlerOptions, + BatcherOptions, + DebouncerOptions, + QueuerOptions, + RateLimiterOptions, + ThrottlerOptions, +} from '@tanstack/pacer' + +export interface PacerProviderOptions { + asyncBatcher?: Partial> + asyncDebouncer?: Partial> + asyncQueuer?: Partial> + asyncRateLimiter?: Partial> + asyncThrottler?: Partial> + batcher?: Partial> + debouncer?: Partial> + queuer?: Partial> + rateLimiter?: Partial> + throttler?: Partial> +} + +interface PacerContextValue { + defaultOptions: PacerProviderOptions +} + +const PacerContext = createContext(null) + +export interface PacerProviderProps { + children: JSX.Element + defaultOptions?: PacerProviderOptions +} + +const DEFAULT_OPTIONS: PacerProviderOptions = {} + +export function PacerProvider(props: PacerProviderProps) { + const contextValue: PacerContextValue = { + defaultOptions: props.defaultOptions ?? DEFAULT_OPTIONS, + } + + return ( + + {props.children} + + ) +} + +export function usePacerContext() { + return useContext(PacerContext) +} + +export function useDefaultPacerOptions() { + const context = useContext(PacerContext) + return context?.defaultOptions ?? {} +} diff --git a/packages/solid-pacer/src/queuer/createQueuedSignal.ts b/packages/solid-pacer/src/queuer/createQueuedSignal.ts new file mode 100644 index 00000000..77a2833a --- /dev/null +++ b/packages/solid-pacer/src/queuer/createQueuedSignal.ts @@ -0,0 +1,138 @@ +import { createQueuer } from './createQueuer' +import type { SolidQueuer } from './createQueuer' +import type { QueuerOptions, QueuerState } from '@tanstack/pacer/queuer' + +/** + * A Solid primitive that creates a queuer with managed state, combining Solid's signals with queuing functionality. + * This primitive provides both the current queue state and queue control methods. + * + * The queue state is automatically updated whenever items are added, removed, or reordered in the queue. + * All queue operations are reflected in the state array returned by the primitive. + * + * The queue can be started and stopped to automatically process items at a specified interval, + * making it useful as a scheduler. When started, it will process one item per tick, with an + * optional wait time between ticks. + * + * The primitive returns a tuple containing: + * - The current queue state as an array + * - The queue instance with methods for queue manipulation + * + * ## State Management and Selector + * + * The primitive uses Solid's reactive state management via the underlying queuer instance. + * The `selector` parameter allows you to specify which queuer state changes will trigger a re-render, + * optimizing performance by preventing unnecessary re-renders when irrelevant state changes occur. + * + * **By default, there will be no reactive state subscriptions** and you must opt-in to state + * tracking by providing a selector function. This prevents unnecessary re-renders and gives you + * full control over when your component updates. Only when you provide a selector will the + * component re-render when the selected state values change. + * + * Available queuer state properties: + * - `executionCount`: Number of items that have been processed by the queuer + * - `expirationCount`: Number of items that have been removed due to expiration + * - `isEmpty`: Whether the queuer has no items to process + * - `isFull`: Whether the queuer has reached its maximum capacity + * - `isIdle`: Whether the queuer is not currently processing any items + * - `isRunning`: Whether the queuer is active and will process items automatically + * - `items`: Array of items currently waiting to be processed + * - `itemTimestamps`: Timestamps when items were added for expiration tracking + * - `pendingTick`: Whether the queuer has a pending timeout for processing the next item + * - `rejectionCount`: Number of items that have been rejected from being added + * - `size`: Number of items currently in the queue + * - `status`: Current processing status ('idle' | 'running' | 'stopped') + * + * @example + * ```tsx + * // Default behavior - no reactive state subscriptions + * const [items, addItem, queue] = createQueuedSignal( + * (item) => console.log('Processing:', item), + * { + * initialItems: ['item1', 'item2'], + * started: true, + * wait: 1000, + * getPriority: (item) => item.priority + * } + * ); + * + * // Opt-in to re-render when queue contents change (optimized for displaying queue items) + * const [items, addItem, queue] = createQueuedSignal( + * (item) => console.log('Processing:', item), + * { started: true, wait: 1000 }, + * (state) => ({ + * items: state.items, + * size: state.size, + * isEmpty: state.isEmpty + * }) + * ); + * + * // Opt-in to re-render when processing state changes (optimized for loading indicators) + * const [items, addItem, queue] = createQueuedSignal( + * (item) => console.log('Processing:', item), + * { started: true, wait: 1000 }, + * (state) => ({ + * isRunning: state.isRunning, + * isIdle: state.isIdle, + * status: state.status, + * pendingTick: state.pendingTick + * }) + * ); + * + * // Opt-in to re-render when execution metrics change (optimized for stats display) + * const [items, addItem, queue] = createQueuedSignal( + * (item) => console.log('Processing:', item), + * { started: true, wait: 1000 }, + * (state) => ({ + * executionCount: state.executionCount, + * expirationCount: state.expirationCount, + * rejectionCount: state.rejectionCount + * }) + * ); + * + * // Add items to queue + * const handleAdd = (item) => { + * addItem(item); + * }; + * + * // Start automatic processing + * const startProcessing = () => { + * queue.start(); + * }; + * + * // Stop automatic processing + * const stopProcessing = () => { + * queue.stop(); + * }; + * + * // Manual processing still available + * const handleProcess = () => { + * const nextItem = queue.getNextItem(); + * if (nextItem) { + * processItem(nextItem); + * } + * }; + * + * // Access the selected queuer state (will be empty object {} unless selector provided) + * const { size, isRunning, executionCount } = queue.state; + * ``` + */ +export function createQueuedSignal< + TValue, + TSelected extends Pick, 'items'> = Pick< + QueuerState, + 'items' + >, +>( + fn: (item: TValue) => void, + options: QueuerOptions = {}, + selector: (state: QueuerState) => TSelected = (state) => + ({ items: state.items }) as TSelected, +): [ + () => Array, + SolidQueuer['addItem'], + SolidQueuer, +] { + const queue = createQueuer(fn, options, selector) + + return [() => queue.state().items, queue.addItem, queue] +} diff --git a/packages/solid-pacer/src/queuer/createQueuer.ts b/packages/solid-pacer/src/queuer/createQueuer.ts index 9204dabf..1da21636 100644 --- a/packages/solid-pacer/src/queuer/createQueuer.ts +++ b/packages/solid-pacer/src/queuer/createQueuer.ts @@ -1,5 +1,6 @@ import { Queuer } from '@tanstack/pacer/queuer' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { QueuerOptions, QueuerState } from '@tanstack/pacer/queuer' @@ -100,10 +101,15 @@ export interface SolidQueuer */ export function createQueuer( fn: (item: TValue) => void, - initialOptions: QueuerOptions = {}, + options: QueuerOptions = {}, selector: (state: QueuerState) => TSelected = () => ({}) as TSelected, ): SolidQueuer { - const queuer = new Queuer(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().queuer, + ...options, + } as QueuerOptions + + const queuer = new Queuer(fn, mergedOptions) const state = useStore(queuer.store, selector) diff --git a/packages/solid-pacer/src/queuer/index.ts b/packages/solid-pacer/src/queuer/index.ts index 8594c18f..83633039 100644 --- a/packages/solid-pacer/src/queuer/index.ts +++ b/packages/solid-pacer/src/queuer/index.ts @@ -1,3 +1,4 @@ export * from '@tanstack/pacer/queuer' export * from './createQueuer' +export * from './createQueuedSignal' diff --git a/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts b/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts index 82e9102b..68049890 100644 --- a/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts +++ b/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts @@ -46,13 +46,9 @@ import type { * the reactive system track the selected state values. * * Available rate limiter state properties: - * - `callsInWindow`: Number of calls made in the current window - * - `remainingInWindow`: Number of calls remaining in the current window - * - `windowStart`: Unix timestamp when the current window started - * - `nextWindowStart`: Unix timestamp when the next window will start - * - `msUntilNextWindow`: Milliseconds until the next window starts - * - `isAtLimit`: Whether the call limit for the current window has been reached - * - `status`: Current status ('disabled' | 'idle' | 'at-limit') + * - `executionCount`: Number of function executions that have been completed + * - `executionTimes`: Array of timestamps when executions occurred for rate limiting calculations + * - `rejectionCount`: Number of function executions that have been rejected due to rate limiting * * @example * ```tsx @@ -63,21 +59,39 @@ import type { * windowType: 'sliding' * }); * - * // Opt-in to reactive updates when limit state changes (optimized for UI feedback) + * // Opt-in to reactive updates when execution count changes (optimized for tracking successful updates) * const [rateLimitedValue, rateLimiter] = createRateLimitedValue( * rawValue, - * { limit: 5, window: 60000 }, - * (state) => ({ isAtLimit: state.isAtLimit, remainingInWindow: state.remainingInWindow }) + * { limit: 5, window: 60000, windowType: 'sliding' }, + * (state) => ({ executionCount: state.executionCount }) * ); * - * // Use the rate-limited value - * console.log(rateLimitedValue()); // Access the current rate-limited value + * // Opt-in to reactive updates when rejection count changes (optimized for tracking rate limit violations) + * const [rateLimitedValue, rateLimiter] = createRateLimitedValue( + * rawValue, + * { limit: 5, window: 60000, windowType: 'sliding' }, + * (state) => ({ rejectionCount: state.rejectionCount }) + * ); * - * // Access rate limiter state via signals - * console.log('Is at limit:', rateLimiter.state().isAtLimit); + * // Opt-in to reactive updates when execution times change (optimized for window calculations) + * const [rateLimitedValue, rateLimiter] = createRateLimitedValue( + * rawValue, + * { limit: 5, window: 60000, windowType: 'sliding' }, + * (state) => ({ executionTimes: state.executionTimes }) + * ); + * + * // With rejection callback and fixed window + * const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, { + * limit: 3, + * window: 5000, + * windowType: 'fixed', + * onReject: (rateLimiter) => { + * console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`); + * } + * }); * - * // Control the rate limiter - * rateLimiter.reset(); // Reset the rate limit window + * // Access the selected rate limiter state (will be empty object {} unless selector provided) + * const { executionCount, rejectionCount } = rateLimiter.state; * ``` */ export function createRateLimitedValue( diff --git a/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts b/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts index 0a599db5..57d74580 100644 --- a/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts +++ b/packages/solid-pacer/src/rate-limiter/createRateLimiter.ts @@ -1,5 +1,6 @@ import { RateLimiter } from '@tanstack/pacer/rate-limiter' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { AnyFunction } from '@tanstack/pacer/types' @@ -101,10 +102,15 @@ export interface SolidRateLimiter */ export function createRateLimiter( fn: TFn, - initialOptions: RateLimiterOptions, + options: RateLimiterOptions, selector: (state: RateLimiterState) => TSelected = () => ({}) as TSelected, ): SolidRateLimiter { - const rateLimiter = new RateLimiter(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().rateLimiter, + ...options, + } as RateLimiterOptions + + const rateLimiter = new RateLimiter(fn, mergedOptions) const state = useStore(rateLimiter.store, selector) diff --git a/packages/solid-pacer/src/throttler/createThrottler.ts b/packages/solid-pacer/src/throttler/createThrottler.ts index c7bc06b9..dfa6941c 100644 --- a/packages/solid-pacer/src/throttler/createThrottler.ts +++ b/packages/solid-pacer/src/throttler/createThrottler.ts @@ -1,6 +1,7 @@ import { Throttler } from '@tanstack/pacer/throttler' import { createEffect, onCleanup } from 'solid-js' import { useStore } from '@tanstack/solid-store' +import { useDefaultPacerOptions } from '../provider/PacerProvider' import type { Store } from '@tanstack/solid-store' import type { Accessor } from 'solid-js' import type { AnyFunction } from '@tanstack/pacer/types' @@ -98,10 +99,15 @@ export interface SolidThrottler */ export function createThrottler( fn: TFn, - initialOptions: ThrottlerOptions, + options: ThrottlerOptions, selector: (state: ThrottlerState) => TSelected = () => ({}) as TSelected, ): SolidThrottler { - const asyncThrottler = new Throttler(fn, initialOptions) + const mergedOptions = { + ...useDefaultPacerOptions().throttler, + ...options, + } as ThrottlerOptions + + const asyncThrottler = new Throttler(fn, mergedOptions) const state = useStore(asyncThrottler.store, selector) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 67cb353a..37515cbd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1431,6 +1431,28 @@ importers: specifier: ^2.11.10 version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.0)(yaml@2.8.1)) + examples/solid/createQueuedSignal: + dependencies: + '@tanstack/solid-devtools': + specifier: 0.7.14 + version: 0.7.14(csstype@3.1.3)(solid-js@1.9.10) + '@tanstack/solid-pacer': + specifier: ^0.15.3 + version: link:../../../packages/solid-pacer + '@tanstack/solid-pacer-devtools': + specifier: 0.4.0 + version: link:../../../packages/solid-pacer-devtools + solid-js: + specifier: ^1.9.10 + version: 1.9.10 + devDependencies: + vite: + specifier: ^7.2.2 + version: 7.2.2(@types/node@24.10.1)(jiti@2.6.0)(yaml@2.8.1) + vite-plugin-solid: + specifier: ^2.11.10 + version: 2.11.10(@testing-library/jest-dom@6.9.1)(solid-js@1.9.10)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.0)(yaml@2.8.1)) + examples/solid/createQueuer: dependencies: '@tanstack/solid-devtools':