mcpField
T
tanstack-pacer

tanstack-pacer

github.com/tanstack-skills開発363.9k 回インストール39 週間前に更新
リポジトリ

tanstack-pacer について

tanstack-pacer は、TypeScript と React アプリで関数の実行タイミングを制御する型安全なツールキットです。クラス、ファクトリー関数、React Hooks によって、デバウンス、スロットリング、レート制限、キュー、バッチ処理を提供します。

主な機能

  1. 01デバウンスとスロットリング
  2. 02時間枠によるレート制限
  3. 03並行数を設定できるキュー
  4. 04件数または時間によるバッチ処理
  5. 05クラス、ファクトリー関数、React Hooks

活用シーン

  1. 01検索入力の処理を遅延
  2. 02スクロール更新頻度の制限
  3. 03ファイルアップロードの順次処理
  4. 04分析イベントをまとめて送信

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tanstack-skills/tanstack-skills --skill tanstack-pacer

インストール後、Claude Code で/tanstack-pacerを入力して読み込まれたか確認します。

詳細

概要

TanStack Pacer は、関数の実行タイミングを制御するための、統一された型安全なツールキットを提供します。デバウンス、スロットリング、レート制限、キューイング、バッチ処理のための、クラスベース API、ファクトリー関数、React フックを備えています。

コア: @tanstack/pacer React: @tanstack/react-pacer ステータス: ベータ

インストール

npm install @tanstack/pacer
npm install @tanstack/react-pacer  # React hooks

デバウンス

一定時間操作がない状態になってから実行します。

クラス API
import { Debouncer } from '@tanstack/pacer'

const debouncer = new Debouncer(
  (query: string) => fetchSearchResults(query),
  {
    wait: 300,            // ms of inactivity before execution
    leading: false,       // Execute on leading edge (default: false)
    trailing: true,       // Execute on trailing edge (default: true)
    maxWait: 1000,        // Force execution after 1s of continuous calls
    enabled: true,
    onExecute: (result) => console.log(result),
  }
)

debouncer.maybeExecute('search term')
debouncer.cancel()
debouncer.getExecutionCount()
debouncer.setOptions({ wait: 500 }) // Dynamic reconfiguration
ファクトリー関数
import { debounce } from '@tanstack/pacer'

const debouncedSearch = debounce(
  (query: string) => fetchResults(query),
  { wait: 300 }
)

debouncedSearch('term')
debouncedSearch.cancel()
React フック
import {
  useDebouncer,
  useDebouncedCallback,
  useDebouncedState,
  useDebouncedValue,
} from '@tanstack/react-pacer'

// Full debouncer instance
const debouncer = useDebouncer(fn, { wait: 300 })

// Simple debounced function
const debouncedFn = useDebouncedCallback(fn, { wait: 300 })

// Debounced state management
const [debouncedValue, setValue] = useDebouncedState(initialValue, { wait: 300 })

// Debounced reactive value
const debouncedValue = useDebouncedValue(reactiveValue, { wait: 300 })

スロットリング

一定間隔ごとに最大 1 回まで実行を制限します。

クラス API
import { Throttler } from '@tanstack/pacer'

const throttler = new Throttler(
  (position: { x: number; y: number }) => updatePosition(position),
  {
    wait: 100,            // Minimum interval between executions
    leading: true,        // Execute immediately on first call (default: true)
    trailing: true,       // Execute after interval with last args (default: true)
    enabled: true,
    onExecute: (result) => console.log(result),
  }
)

throttler.maybeExecute({ x: 100, y: 200 })
throttler.cancel()
React フック
import {
  useThrottler,
  useThrottledCallback,
  useThrottledState,
  useThrottledValue,
} from '@tanstack/react-pacer'

const throttledFn = useThrottledCallback(handleScroll, { wait: 100 })
const [throttledPos, setPos] = useThrottledState({ x: 0, y: 0 }, { wait: 100 })

レート制限

一定の時間枠内で最大実行回数を制御します。

クラス API
import { RateLimiter } from '@tanstack/pacer'

const limiter = new RateLimiter(
  async (endpoint: string) => fetch(endpoint).then(r => r.json()),
  {
    limit: 10,            // Max executions per window
    window: 60000,        // Time window in ms (60s)
    enabled: true,
    onExecute: (result) => console.log(result),
    onReject: (...args) => console.warn('Rate limited:', args),
  }
)

limiter.maybeExecute('/api/data')  // Rejected if limit exceeded
limiter.getExecutionCount()
limiter.getRejectionCount()
React フック
import {
  useRateLimiter,
  useRateLimitedCallback,
  useRateLimitedState,
  useRateLimitedValue,
} from '@tanstack/react-pacer'

const rateLimitedFn = useRateLimitedCallback(apiCall, { limit: 5, window: 1000 })

キューイング

設定可能な同時実行数で順次実行します。

import { Queue } from '@tanstack/pacer'

const queue = new Queue({
  concurrency: 1,         // Max concurrent tasks
  started: true,          // Start processing immediately
})

queue.add(() => uploadFile(file1))
queue.add(() => uploadFile(file2))

queue.start()
queue.pause()
queue.clear()
queue.getSize()           // Pending count
queue.getPending()        // Currently executing count

バッチ処理

呼び出しをまとめて一括処理します。

import { Batcher } from '@tanstack/pacer'

const batcher = new Batcher(
  (items: LogEntry[]) => sendBatchToServer(items),
  {
    maxSize: 50,          // Auto-flush at 50 items
    wait: 1000,           // Auto-flush after 1s
  }
)

batcher.add(logEntry)    // Accumulates
batcher.flush()          // Manual flush
batcher.getSize()        // Current batch size
batcher.clear()          // Discard batch

非同期バリアント

import { AsyncDebouncer, asyncDebounce, AsyncThrottler, asyncThrottle } from '@tanstack/pacer'

const asyncDebouncer = new AsyncDebouncer(
  async (query: string) => {
    const response = await fetch(`/api/search?q=${query}`)
    return response.json()
  },
  { wait: 300 }
)

// React async hooks
import { useAsyncDebouncer, useAsyncThrottler } from '@tanstack/react-pacer'

適切なユーティリティの選び方

シナリオユーティリティ理由
検索入力Debouncerユーザーが入力を止めるまで待機します
スクロールイベントThrottler操作中に定期的に更新します
API の保護RateLimiter呼び出し頻度に厳密な上限を設けます
ファイルのアップロードQueue順次処理します
分析イベントBatcher効率化のためにまとめます
ネットワークリクエストAsyncDebouncer中断や再試行を処理します

先頭エッジと末尾エッジ

  • 先頭(leading: true):即座に実行し、待機時間が経過するまで後続の実行を抑制します。ボタンのクリックに適しています。
  • 末尾(trailing: true):操作が止まった後に実行します。検索入力に適しています。
  • 両方:即座に実行し、最後の待機時間が経過した後にも実行します。スクロールのスロットリングに適しています。

ベストプラクティス

  1. デバウンスで maxWait を使用すると、操作が連続している間も実行を保証できます
  2. ネットワークリクエストには非同期バリアントを使用する(中断/キャンセルを処理します)
  3. React フックはクリーンアップを自動で処理します。手動での破棄は不要です
  4. 動的な再設定には setOptions を使用する(例:パワーユーザー向けに待機時間を短縮する)
  5. 複雑なシナリオではユーティリティを組み合わせる(レート制限付きキューなど)
  6. レート制限に達したときユーザーに知らせるには、RateLimiter で onReject を使用する

よくある落とし穴

  • スロットリングが必要な場面でデバウンスを使用する(デバウンスは操作がない状態になるまで待機しますが、スロットリングは定期的な実行を保証します)
  • 長時間続くイベントで、デバウンスに maxWait を指定しない
  • レンダリングのたびに新しいインスタンスを作成する(フックまたはモジュールレベルのインスタンスを使用してください)
  • React 以外の環境でクリーンアップを忘れる(cancel() を呼び出してください)

コメント