feat: all sync tools should respect aborting

This commit is contained in:
Simon
2026-06-05 21:23:18 +08:00
parent 1c82030a21
commit 78b6e2ad3c
5 changed files with 121 additions and 23 deletions

View File

@@ -2,8 +2,49 @@ import chalk from 'chalk'
export * from './autoFixer'
export async function waitFor(seconds: number): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, seconds * 1000))
/**
* Wait for `seconds`. If a `signal` is provided, the wait is cancellable:
* aborting rejects with the signal's reason (an `AbortError`).
*/
export async function waitFor(seconds: number, signal?: AbortSignal): Promise<void> {
if (!signal) {
await new Promise((resolve) => setTimeout(resolve, seconds * 1000))
return
}
signal.throwIfAborted()
await new Promise<void>((resolve, reject) => {
const timer = setTimeout(() => {
signal.removeEventListener('abort', onAbort)
resolve()
}, seconds * 1000)
const onAbort = () => {
clearTimeout(timer)
// reason is a DOMException AbortError.
reject(signal.reason as DOMException)
}
signal.addEventListener('abort', onAbort, { once: true })
})
}
/**
* Diagnostic deadline: fire `callback` if `signal` stays aborted for `ms`,
* surfacing async work that ignores abort. Returns an unsubscribe to call once
* the awaited work settles.
*/
export function onAbortTimeout(signal: AbortSignal, ms: number, callback: () => void): () => void {
if (signal.aborted) {
callback()
return () => {}
}
let timer: ReturnType<typeof setTimeout> | null = null
const onAbort = () => {
timer = setTimeout(callback, ms)
}
signal.addEventListener('abort', onAbort, { once: true })
return () => {
signal.removeEventListener('abort', onAbort)
if (timer) clearTimeout(timer)
}
}
//