@wentools/simmer
v0.1.0
Published
Async control flow primitives: debounce, retry, eventual, sleep
Downloads
213
Maintainers
Readme
@wentools/simmer
Async control flow primitives: debounce, retry, eventual, sleep.
Install
# JSR (Deno)
deno add jsr:@wentools/simmer
# npm
npm install @wentools/simmerUsage
Sleep
import { sleep } from '@wentools/simmer'
await sleep(1000) // wait 1 secondDebounce
import { debounce, debounceAsync } from '@wentools/simmer'
// Synchronous debounce
const debouncedSearch = debounce((query: string) => {
console.log('Searching:', query)
}, 300)
// Async debounce - cancels stale calls
const debouncedFetch = debounceAsync(async (query: string) => {
const response = await fetch(`/api/search?q=${query}`)
return response.json()
}, 300)Retry
import { withRetry, retryPromise } from '@wentools/simmer'
// Retry a Result-returning function
const result = await withRetry(
() => fetchUser(userId),
{ maxAttempts: 3, initialDelayMs: 1000, backoffStrategy: 'exponential' }
)
// Retry a Promise-returning function
const result = await retryPromise(
() => fetch('/api/data').then(r => r.json()),
{ maxAttempts: 3, initialDelayMs: 500 }
)Eventual (Stale-While-Revalidate)
import { eventual, mapEventual, combineEventual } from '@wentools/simmer'
// Return cached data immediately, refresh in background
const result = eventual(cachedData, fetchFreshData())
result.current // cached data (available now)
result.fresh // Promise<fresh data> | null
result.isStale // true if fresh !== null
// Transform values
const mapped = mapEventual(result, data => data.map(formatItem))
// Combine multiple
const combined = combineEventual({
users: eventual(cachedUsers, fetchUsers()),
count: eventual(cachedCount, fetchCount()),
})API
Sleep
sleep(ms)- Promise that resolves aftermsmilliseconds
Debounce
debounce(fn, wait)- Debounce a synchronous functiondebounceAsync(fn, wait)- Debounce an async function with promise cancellation
Retry
withRetry(fn, options?)- Retry aResult-returning functionretryPromise(fn, options?)- Retry aPromise-returning functionmakeRetryable(fn, options?)- Create a retryable wrapperwithRetryMetadata(fn, options?)- Retry with full execution trackingcalculateDelay(attempt, options)- Calculate delay for a retry attemptdefaultRetryOptions- Default retry configuration
Eventual
eventual(current, fresh)- Create anEventualResulteventualIf(current, isStale, getFresh)- Lazily create fresh promisemapEventual(result, fn)- Transform both current and fresh valuescombineEventual(results)- Combine multipleEventualResults
License
MIT
