<script lang="ts">
import { TanStackDevtools } from '@tanstack/svelte-devtools'
import { pacerDevtoolsPlugin } from '@tanstack/svelte-pacer-devtools'
import { asyncBatch } from '@tanstack/svelte-pacer/async-batcher'
const fakeProcessingTime = 1000
type Item = {
id: number
value: string
timestamp: number
}
let processedBatches = $state<
Array<{
items: Array<Item>
result: string
timestamp: number
}>
>([])
let errors = $state<Array<string>>([])
let pendingItems = $state<Array<Item>>([])
let isProcessing = $state(false)
let shouldFail = $state(false)
let successCount = $state(0)
let errorCount = $state(0)
const processBatch = async (items: Array<Item>): Promise<string> => {
console.log('Processing batch of', items.length, 'items:', items)
isProcessing = true
try {
await new Promise((resolve) => setTimeout(resolve, fakeProcessingTime))
if (shouldFail && Math.random() < 0.3) {
throw new Error(
`Processing failed for batch with ${items.length} items`,
)
}
const result = `Processed ${items.length} items: ${items.map((item) => item.value).join(', ')}`
processedBatches = [
...processedBatches,
{ items, result, timestamp: Date.now() },
]
successCount = successCount + 1
console.log('Batch succeeded:', result)
return result
} catch (error: any) {
errors = [
...errors,
`Error: ${error} (${new Date().toLocaleTimeString()})`,
]
errorCount = errorCount + 1
console.error('Batch failed:', error)
throw error
} finally {
isProcessing = false
}
}
let addToBatch = $state(
asyncBatch<Item>(processBatch, {
maxSize: 5,
wait: 3000,
getShouldExecute: (items) =>
items.some((item) => item.value.includes('urgent')),
throwOnError: false,
onItemsChange: (batcher) => {
pendingItems = batcher.peekAllItems()
},
onSuccess: (result, batch, batcher) => {
console.log('AsyncBatcher succeeded:', result)
console.log('Processed batch:', batch)
console.log(
'Total successful batches:',
batcher.store.state.successCount,
)
},
onError: (error: any, failedItems, batcher) => {
console.error('AsyncBatcher failed:', error)
console.log('Failed items:', failedItems)
console.log('Total failed batches:', batcher.store.state.errorCount)
},
onSettled: (batch, batcher) => {
console.log('Batch settled:', batch)
console.log(
'Total processed items:',
batcher.store.state.totalItemsProcessed,
)
},
}),
)
const addItem = (isUrgent = false) => {
const nextId = Date.now()
const item: Item = {
id: nextId,
value: isUrgent ? `urgent-${nextId}` : `item-${nextId}`,
timestamp: nextId,
}
addToBatch(item)
}
</script>
<div>
<h1>TanStack Pacer asyncBatch Example</h1>
<div>
<h3>Batch Status</h3>
<div>Pending Items: {pendingItems.length}</div>
<div>Max Batch Size: 5</div>
<div>Is Processing: {isProcessing ? 'Yes' : 'No'}</div>
<div>Successful Batches: {successCount}</div>
<div>Failed Batches: {errorCount}</div>
</div>
<div>
<h3>Current Pending Items</h3>
<div style="min-height: 100px">
{#if pendingItems.length === 0}<em>No items pending</em
>{:else}{#each pendingItems as item, index (index)}<div>
{index + 1}: {item.value} (added at{' '}{new Date(
item.timestamp,
).toLocaleTimeString()})
</div>{/each}{/if}
</div>
</div>
<div>
<h3>Controls</h3>
<div
style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; max-width: 600px"
>
<button onclick={() => addItem(false)}>Add Regular Item</button><button
onclick={() => addItem(true)}
>
Add Urgent Item (Processes Immediately)
</button>
</div>
<div>
<label
><input
type="checkbox"
checked={shouldFail}
oninput={(e) => (shouldFail = (e.target as HTMLInputElement).checked)}
/>{' '}Simulate random failures (30% chance)</label
>
</div>
</div>
<div>
<h3>Processed Batches ({processedBatches.length})</h3>
<div>
{#if processedBatches.length === 0}<em>No batches processed yet</em
>{:else}{#each processedBatches as batch, index (index)}<div>
<strong>Batch {index + 1}</strong> (processed at{' '}{new Date(
batch.timestamp,
).toLocaleTimeString()})
<div>{batch.result}</div>
</div>{/each}{/if}
</div>
</div>
{#if errors.length > 0}<div>
<h3>Errors ({errors.length})</h3>
<div>
{#each errors as error, index (index)}<div>{error}</div>{/each}
</div>
<button onclick={() => (errors = [])}>Clear Errors</button>
</div>{/if}
</div>
{#if import.meta.env.DEV}<TanStackDevtools
plugins={[pacerDevtoolsPlugin()]}
/>{/if}