Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ Try other [TanStack](https://tanstack.com) libraries:
You may know **TanSack Pacer** by our adapter names, too!

- [**React Pacer**](https://tanstack.com/pacer/latest/docs/framework/react/react-pacer)
- [**Solid Pacer**](https://tanstack.com/pacer/latest/docs/framework/solid/solid-pacer)
- Angular Pacer - needs a contributor!
- Preact Pacer - Coming soon! (After React Pacer is more fleshed out)
- Svelte Pacer - needs a contributor!
- Vue Pacer - needs a contributor!

## Summary

Expand All @@ -64,6 +69,7 @@ Take control of your application's timing with TanStack Pacer's rate limiting, t
- **Rate Limiting**
- Limit the rate at which a function can fire
- Synchronous or Asynchronous Rate Limiting utilities with promise support and error handling
- Fixed or Sliding window types
- **Queuing**
- Queue functions to be executed in a specific order
- Choose from FIFO, LIFO, and Priority queue implementations
Expand All @@ -90,6 +96,7 @@ Install one of the following packages based on your framework of choice:
```bash
# Npm
npm install @tanstack/react-pacer
npm install @tanstack/solid-pacer
npm install @tanstack/pacer # no framework, just vanilla js
```

Expand Down
19 changes: 15 additions & 4 deletions docs/framework/react/reference/functions/useasyncratelimiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: useAsyncRateLimiter
function useAsyncRateLimiter<TFn>(fn, options): AsyncRateLimiter<TFn>
```

Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:43](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L43)
Defined in: [react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts:54](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/async-rate-limiter/useAsyncRateLimiter.ts#L54)

A low-level React hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window.

Expand All @@ -22,6 +22,16 @@ Rate limiting allows an async function to execute up to a specified limit within
then blocks subsequent calls until the window passes. This is useful for respecting API rate limits,
managing resource constraints, or controlling bursts of async operations.

Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function,
making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call
instead of setting the result on a state variable from within the rate-limited function.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All executions within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows executions as old ones expire. This provides a more
consistent rate of execution over time.

## Type Parameters

• **TFn** *extends* `AnyAsyncFunction`
Expand All @@ -43,21 +53,22 @@ managing resource constraints, or controlling bursts of async operations.
## Example

```tsx
// Basic API call rate limiting
// Basic API call rate limiting with return value
const { maybeExecute } = useAsyncRateLimiter(
async (id: string) => {
const data = await api.fetchData(id);
return data;
return data; // Return value is preserved
},
{ limit: 5, window: 1000 } // 5 calls per second
);

// With state management
// With state management and return value
const [data, setData] = useState(null);
const { maybeExecute } = useAsyncRateLimiter(
async (query) => {
const result = await searchAPI(query);
setData(result);
return result; // Return value can be used by the caller
},
{
limit: 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: useRateLimitedCallback
function useRateLimitedCallback<TFn, TArgs>(fn, options): (...args) => boolean
```

Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:52](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L52)
Defined in: [react-pacer/src/rate-limiter/useRateLimitedCallback.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedCallback.ts#L59)

A React hook that creates a rate-limited version of a callback function.
This hook is essentially a wrapper around the basic `rateLimiter` function
Expand All @@ -24,6 +24,12 @@ or debouncing, it does not attempt to space out or intelligently collapse calls.
This can lead to bursts of rapid executions followed by periods where all calls
are blocked.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All executions within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows executions as old ones expire. This provides a more
consistent rate of execution over time.

For smoother execution patterns, consider:
- useThrottledCallback: When you want consistent spacing between executions (e.g. UI updates)
- useDebouncedCallback: When you want to collapse rapid calls into a single execution (e.g. search input)
Expand Down Expand Up @@ -74,14 +80,15 @@ Consider using the `useRateLimiter` hook instead.
## Example

```tsx
// Rate limit API calls to maximum 5 calls per minute
// Rate limit API calls to maximum 5 calls per minute with a sliding window
const makeApiCall = useRateLimitedCallback(
(data: ApiData) => {
return fetch('/api/endpoint', { method: 'POST', body: JSON.stringify(data) });
},
{
limit: 5,
window: 60000, // 1 minute
windowType: 'sliding',
onReject: () => {
console.warn('API rate limit reached. Please wait before trying again.');
}
Expand Down
16 changes: 12 additions & 4 deletions docs/framework/react/reference/functions/useratelimitedstate.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: useRateLimitedState
function useRateLimitedState<TValue>(value, options): [TValue, Dispatch<SetStateAction<TValue>>, RateLimiter<Dispatch<SetStateAction<TValue>>>]
```

Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:59](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L59)
Defined in: [react-pacer/src/rate-limiter/useRateLimitedState.ts:66](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedState.ts#L66)

A React hook that creates a rate-limited state value that enforces a hard limit on state updates within a time window.
This hook combines React's useState with rate limiting functionality to provide controlled state updates.
Expand All @@ -20,6 +20,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th
subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out
or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All updates within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows updates as old ones expire. This provides a more
consistent rate of updates over time.

For smoother update patterns, consider:
- useThrottledState: When you want consistent spacing between updates (e.g. UI changes)
- useDebouncedState: When you want to collapse rapid updates into a single update (e.g. search input)
Expand Down Expand Up @@ -55,16 +61,18 @@ consider using the lower-level useRateLimiter hook instead.
## Example

```tsx
// Basic rate limiting - update state at most 5 times per minute
// Basic rate limiting - update state at most 5 times per minute with a sliding window
const [value, setValue, rateLimiter] = useRateLimitedState(0, {
limit: 5,
window: 60000
window: 60000,
windowType: 'sliding'
});

// With rejection callback
// With rejection callback and fixed window
const [value, setValue] = useRateLimitedState(0, {
limit: 3,
window: 5000,
windowType: 'fixed',
onReject: (rateLimiter) => {
alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
}
Expand Down
16 changes: 12 additions & 4 deletions docs/framework/react/reference/functions/useratelimitedvalue.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: useRateLimitedValue
function useRateLimitedValue<TValue>(value, options): [TValue, RateLimiter<Dispatch<SetStateAction<TValue>>>]
```

Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:47](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L47)
Defined in: [react-pacer/src/rate-limiter/useRateLimitedValue.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimitedValue.ts#L55)

A high-level React 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 React's useState internally to manage the rate-limited state.
Expand All @@ -20,6 +20,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th
subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out
or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All updates within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows updates as old ones expire. This provides a more
consistent rate of updates over time.

For smoother update patterns, consider:
- useThrottledValue: When you want consistent spacing between updates (e.g. UI changes)
- useDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input)
Expand Down Expand Up @@ -54,16 +60,18 @@ consider using the lower-level useRateLimiter hook instead.
## Example

```tsx
// Basic rate limiting - update at most 5 times per minute
// Basic rate limiting - update at most 5 times per minute with a sliding window
const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, {
limit: 5,
window: 60000
window: 60000,
windowType: 'sliding'
});

// With rejection callback
// With rejection callback and fixed window
const [rateLimitedValue, rateLimiter] = useRateLimitedValue(rawValue, {
limit: 3,
window: 5000,
windowType: 'fixed',
onReject: (rateLimiter) => {
console.log(`Update rejected. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
}
Expand Down
11 changes: 9 additions & 2 deletions docs/framework/react/reference/functions/useratelimiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: useRateLimiter
function useRateLimiter<TFn>(fn, options): RateLimiter<TFn>
```

Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:48](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L48)
Defined in: [react-pacer/src/rate-limiter/useRateLimiter.ts:55](https://github.com/TanStack/pacer/blob/main/packages/react-pacer/src/rate-limiter/useRateLimiter.ts#L55)

A low-level React hook that creates a `RateLimiter` instance to enforce rate limits on function execution.

Expand All @@ -22,6 +22,12 @@ Rate limiting is a simple "hard limit" approach that allows executions until a m
a time window, then blocks all subsequent calls until the window resets. Unlike throttling or debouncing,
it does not attempt to space out or collapse executions intelligently.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All executions within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows executions as old ones expire. This provides a more
consistent rate of execution over time.

For smoother execution patterns:
- Use throttling when you want consistent spacing between executions (e.g. UI updates)
- Use debouncing when you want to collapse rapid-fire events (e.g. search input)
Expand Down Expand Up @@ -55,10 +61,11 @@ The hook returns an object containing:
## Example

```tsx
// Basic rate limiting - max 5 calls per minute
// Basic rate limiting - max 5 calls per minute with a sliding window
const { maybeExecute } = useRateLimiter(apiCall, {
limit: 5,
window: 60000,
windowType: 'sliding',
});

// Monitor rate limit status
Expand Down
19 changes: 15 additions & 4 deletions docs/framework/solid/reference/functions/createasyncratelimiter.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: createAsyncRateLimiter
function createAsyncRateLimiter<TFn>(fn, initialOptions): SolidAsyncRateLimiter<TFn>
```

Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:62](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L62)
Defined in: [async-rate-limiter/createAsyncRateLimiter.ts:73](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/async-rate-limiter/createAsyncRateLimiter.ts#L73)

A low-level Solid hook that creates an `AsyncRateLimiter` instance to limit how many times an async function can execute within a time window.

Expand All @@ -22,6 +22,16 @@ Rate limiting allows an async function to execute up to a specified limit within
then blocks subsequent calls until the window passes. This is useful for respecting API rate limits,
managing resource constraints, or controlling bursts of async operations.

Unlike the non-async RateLimiter, this async version supports returning values from the rate-limited function,
making it ideal for API calls and other async operations where you want the result of the `maybeExecute` call
instead of setting the result on a state variable from within the rate-limited function.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All executions within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows executions as old ones expire. This provides a more
consistent rate of execution over time.

## Type Parameters

• **TFn** *extends* `AnyAsyncFunction`
Expand All @@ -43,21 +53,22 @@ managing resource constraints, or controlling bursts of async operations.
## Example

```tsx
// Basic API call rate limiting
// Basic API call rate limiting with return value
const { maybeExecute } = createAsyncRateLimiter(
async (id: string) => {
const data = await api.fetchData(id);
return data;
return data; // Return value is preserved
},
{ limit: 5, window: 1000 } // 5 calls per second
);

// With state management
// With state management and return value
const [data, setData] = createSignal(null);
const { maybeExecute } = createAsyncRateLimiter(
async (query) => {
const result = await searchAPI(query);
setData(result);
return result; // Return value can be used by the caller
},
{
limit: 10,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: createRateLimitedSignal
function createRateLimitedSignal<TValue>(value, initialOptions): [Accessor<TValue>, Setter<TValue>, SolidRateLimiter<Setter<TValue>>]
```

Defined in: [rate-limiter/createRateLimitedSignal.ts:57](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L57)
Defined in: [rate-limiter/createRateLimitedSignal.ts:65](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedSignal.ts#L65)

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.
Expand All @@ -20,6 +20,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th
subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out
or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All updates within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows updates as old ones expire. This provides a more
consistent rate of updates over time.

For smoother update patterns, consider:
- createThrottledSignal: When you want consistent spacing between updates (e.g. UI changes)
- createDebouncedSignal: When you want to collapse rapid updates into a single update (e.g. search input)
Expand Down Expand Up @@ -55,16 +61,18 @@ consider using the lower-level createRateLimiter hook instead.
## Example

```tsx
// Basic rate limiting - update state at most 5 times per minute
// Basic rate limiting - update state at most 5 times per minute with a sliding window
const [value, setValue, rateLimiter] = createRateLimitedSignal(0, {
limit: 5,
window: 60000
window: 60000,
windowType: 'sliding'
});

// With rejection callback
// With rejection callback and fixed window
const [value, setValue] = createRateLimitedSignal(0, {
limit: 3,
window: 5000,
windowType: 'fixed',
onReject: (rateLimiter) => {
alert(`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`);
}
Expand Down
13 changes: 10 additions & 3 deletions docs/framework/solid/reference/functions/createratelimitedvalue.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ title: createRateLimitedValue
function createRateLimitedValue<TValue>(value, initialOptions): [Accessor<TValue>, SolidRateLimiter<Setter<TValue>>]
```

Defined in: [rate-limiter/createRateLimitedValue.ts:43](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L43)
Defined in: [rate-limiter/createRateLimitedValue.ts:50](https://github.com/TanStack/pacer/blob/main/packages/solid-pacer/src/rate-limiter/createRateLimitedValue.ts#L50)

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.
Expand All @@ -20,6 +20,12 @@ Rate limiting is a simple "hard limit" approach - it allows all updates until th
subsequent updates until the window resets. Unlike throttling or debouncing, it does not attempt to space out
or intelligently collapse updates. This can lead to bursts of rapid updates followed by periods of no updates.

The rate limiter supports two types of windows:
- 'fixed': A strict window that resets after the window period. All updates within the window count
towards the limit, and the window resets completely after the period.
- 'sliding': A rolling window that allows updates as old ones expire. This provides a more
consistent rate of updates over time.

For smoother update patterns, consider:
- createThrottledValue: When you want consistent spacing between updates (e.g. UI changes)
- createDebouncedValue: When you want to collapse rapid updates into a single update (e.g. search input)
Expand Down Expand Up @@ -54,10 +60,11 @@ consider using the lower-level createRateLimiter hook instead.
## Example

```tsx
// Basic rate limiting - update at most 5 times per minute
// Basic rate limiting - update at most 5 times per minute with a sliding window
const [rateLimitedValue, rateLimiter] = createRateLimitedValue(rawValue, {
limit: 5,
window: 60000
window: 60000,
windowType: 'sliding'
});

// Use the rate-limited value
Expand Down
Loading