export async function waitForCleanup( cleanup: Promise, timeoutMs: number ): Promise { let timeout: NodeJS.Timeout | undefined const timedOut = new Promise((resolve) => { timeout = setTimeout(() => resolve(false), timeoutMs) }) const settled = Promise.resolve(cleanup).then( () => true as const, () => true as const ) const completed = await Promise.race([settled, timedOut]) if (timeout) { clearTimeout(timeout) } return completed } export type CleanupOperation = () => unknown | Promise export async function settleCleanupPhases( phases: readonly (readonly CleanupOperation[])[] ): Promise { for (const phase of phases) { await Promise.allSettled( phase.map((operation) => Promise.resolve().then(operation)) ) } } export async function runCleanupBeforeDeadline( cleanup: Promise, timeoutMs: number, finalize: () => unknown | Promise ): Promise { const completed = await waitForCleanup(cleanup, timeoutMs) if (completed) { await finalize() } return completed }