<script lang="ts">
import { TanStackDevtools } from '@tanstack/svelte-devtools'
import { pacerDevtoolsPlugin } from '@tanstack/svelte-pacer-devtools'
import { asyncRateLimit } from '@tanstack/svelte-pacer/async-rate-limiter'
let windowType = $state<'fixed' | 'sliding'>('fixed')
let searchText = $state('')
let rateLimitedSearchText = $state('')
let searchResults = $state<Array<string>>([])
let loading = $state(false)
const simulateSearch = async (query: string) => {
await new Promise((resolve) => setTimeout(resolve, 800))
return [
`Result 1 for ${query}`,
`Result 2 for ${query}`,
`Result 3 for ${query}`,
]
}
const rateLimitedSetSearch = $derived.by(() =>
asyncRateLimit(
async (value: string) => {
try {
loading = true
rateLimitedSearchText = value
const results = await simulateSearch(value)
searchResults = results
} catch (err) {
searchResults = []
} finally {
loading = false
}
},
{
limit: 5,
window: 5000,
windowType: windowType,
onReject: (_args, rateLimiter) => {
console.log(
`Rate limit reached. Try again in ${rateLimiter.getMsUntilNextWindow()}ms`,
)
},
},
),
)
</script>
<div>
<h1>TanStack Pacer asyncRateLimit Example</h1>
<div style="display: grid; gap: 0.5rem; margin-bottom: 1rem">
<label
><input
type="radio"
name="windowType"
value="fixed"
checked={windowType === 'fixed'}
oninput={() => (windowType = 'fixed')}
/>Fixed Window</label
><label
><input
type="radio"
name="windowType"
value="sliding"
checked={windowType === 'sliding'}
oninput={() => (windowType = 'sliding')}
/>Sliding Window</label
>
</div>
<div>
<input
type="search"
value={searchText}
oninput={(e) => {
const newValue = (e.target as HTMLInputElement).value
searchText = newValue
rateLimitedSetSearch(newValue)
}}
placeholder="Type to search..."
style="width: 100%"
/>{#if loading}<div>Loading...</div>{/if}
</div>
<table>
<tbody
><tr><td>Instant Search:</td><td>{searchText}</td></tr><tr
><td>Rate Limited Search:</td><td>{rateLimitedSearchText}</td></tr
></tbody
>
</table>
<div>
<h3>Search Results:</h3>
<ul>
{#each searchResults as result, i (i)}<li>{result}</li>{/each}
</ul>
</div>
</div>
{#if import.meta.env.DEV}<TanStackDevtools
plugins={[pacerDevtoolsPlugin()]}
/>{/if}