/** * Async utility functions */ /** * Sleep for a specified number of milliseconds */ export function sleep(ms: number): Promise { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Retry a function with exponential backoff */ export async function retry( fn: () => Promise, options: { maxAttempts?: number; initialDelay?: number; maxDelay?: number; backoffMultiplier?: number; } = {} ): Promise { const { maxAttempts = 3, initialDelay = 1000, maxDelay = 10000, backoffMultiplier = 2 } = options; let lastError: Error | undefined; let delay = initialDelay; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await fn(); } catch (error) { lastError = error as Error; if (attempt === maxAttempts) { break; } await sleep(delay); delay = Math.min(delay * backoffMultiplier, maxDelay); } } throw lastError; } /** * Debounce a function */ export function debounce any>( fn: T, delay: number ): (...args: Parameters) => void { let timeoutId: ReturnType | null = null; return (...args: Parameters) => { if (timeoutId) { clearTimeout(timeoutId); } timeoutId = setTimeout(() => { fn(...args); timeoutId = null; }, delay); }; }