export interface RetryOptions { retries?: number delayMs?: number factor?: number label?: string } function sleep(delayMs: number) { return new Promise((resolve) => setTimeout(resolve, delayMs)) } export async function withRetry( operation: () => Promise, options: RetryOptions = {} ) { const retries = options.retries ?? 10 const delayMs = options.delayMs ?? 1_000 const factor = options.factor ?? 1.5 const label = options.label ?? 'operation' let attempt = 0 let currentDelay = delayMs while (true) { try { return await operation() } catch (error) { attempt += 1 if (attempt > retries) { throw error } console.warn(`${label} failed on attempt ${attempt}. Retrying in ${currentDelay}ms.`) await sleep(currentDelay) currentDelay = Math.round(currentDelay * factor) } } }