(
signal: AbortSignal | undefined,
opts?: { signalB?: AbortSignal; timeoutMs?: number },
)
| 13 | * so the timer is freed immediately on cleanup. |
| 14 | */ |
| 15 | export function createCombinedAbortSignal( |
| 16 | signal: AbortSignal | undefined, |
| 17 | opts?: { signalB?: AbortSignal; timeoutMs?: number }, |
| 18 | ): { signal: AbortSignal; cleanup: () => void } { |
| 19 | const { signalB, timeoutMs } = opts ?? {} |
| 20 | const combined = createAbortController() |
| 21 | |
| 22 | if (signal?.aborted || signalB?.aborted) { |
| 23 | combined.abort() |
| 24 | return { signal: combined.signal, cleanup: () => {} } |
| 25 | } |
| 26 | |
| 27 | let timer: ReturnType<typeof setTimeout> | undefined |
| 28 | const abortCombined = () => { |
| 29 | if (timer !== undefined) clearTimeout(timer) |
| 30 | combined.abort() |
| 31 | } |
| 32 | |
| 33 | if (timeoutMs !== undefined) { |
| 34 | timer = setTimeout(abortCombined, timeoutMs) |
| 35 | timer.unref?.() |
| 36 | } |
| 37 | signal?.addEventListener('abort', abortCombined) |
| 38 | signalB?.addEventListener('abort', abortCombined) |
| 39 | |
| 40 | const cleanup = () => { |
| 41 | if (timer !== undefined) clearTimeout(timer) |
| 42 | signal?.removeEventListener('abort', abortCombined) |
| 43 | signalB?.removeEventListener('abort', abortCombined) |
| 44 | } |
| 45 | |
| 46 | return { signal: combined.signal, cleanup } |
| 47 | } |
| 48 |
no test coverage detected