type DelayedPromise = Promise; export function delay(t: number, val: T): DelayedPromise { return new Promise((resolve) => { setTimeout(() => resolve(val), t); }); } export interface RaceResult { value: T; elapsed?: number; error?: string; } export function raceAllPerformance( promises: Promise[], timeoutTime: number, timeoutVal: T ): Promise[]> { return Promise.all( promises.map((p) => { const startTime = performance.now(); let timeoutId: ReturnType | undefined; const resultPromise = p.then((value) => { if (timeoutId !== undefined) clearTimeout(timeoutId); return { value, elapsed: performance.now() - startTime }; }).catch((err: unknown) => { if (timeoutId !== undefined) clearTimeout(timeoutId); return { value: timeoutVal, elapsed: performance.now() - startTime, error: err instanceof Error ? err.message : String(err), }; }); const timeoutPromise = new Promise>((resolve) => { timeoutId = setTimeout(() => { resolve({ value: timeoutVal, elapsed: performance.now() - startTime, error: 'timeout', }); }, timeoutTime); }); return Promise.race([resultPromise, timeoutPromise]); }) ); } export function raceAll(promises: Promise[], timeoutTime: number, timeoutVal: T): Promise<(T | undefined)[]> { return Promise.all(promises.map((p) => { return Promise.race([p.catch(() => timeoutVal), delay(timeoutTime, timeoutVal)]); })); }