import {delay} from '../delay'; import {ExpectError} from '../errors/ExpectError'; import {TimeoutError} from '../errors/TimeoutError'; import {type AwaiterParams} from './AwaiterParams'; export const awaiter = async ( fn: () => any, params: AwaiterParams & { awaiterName: string; originalFn?: () => any; expect?: unknown; }, ) => { const startTime = Date.now(); const {awaiterName, expect, message, id, originalFn} = params; const interval = params.interval ?? params.retryDelay ?? 30; const timeout = params.timeout ?? 1_000; let lastError: Error = new Error(); while (Date.now() - startTime < timeout) { try { const received: unknown = await fn(); if ('expect' in params) { if (expect === received) { return; } else { throw new ExpectError({expected: expect, received}); } } return; } catch (e) { lastError = e instanceof Error ? e : new Error(String(e)); await delay(interval); } } throw new TimeoutError({ awaiterName, fn: originalFn ?? fn, cause: lastError, timeout, message, id, }); };