π File detail
utils/combinedAbortSignal.ts
π§© .tsπ 48 linesπΎ 1,714 bytesπ text
β Back to All Filesπ― Use case
This file lives under βutils/β, which covers cross-cutting helpers (shell, tempfiles, settings, messages, process input, β¦). On the API surface it exposes createCombinedAbortSignal β mainly functions, hooks, or classes. It composes internal code from abortController (relative imports).
Generated from folder role, exports, dependency roots, and inline comments β not hand-reviewed for every path.
π§ Inline summary
import { createAbortController } from './abortController.js' /** * Creates a combined AbortSignal that aborts when the input signal aborts, * an optional second signal aborts, or an optional timeout elapses.
π€ Exports (heuristic)
createCombinedAbortSignal
π₯οΈ Source preview
import { createAbortController } from './abortController.js'
/**
* Creates a combined AbortSignal that aborts when the input signal aborts,
* an optional second signal aborts, or an optional timeout elapses.
* Returns both the signal and a cleanup function that removes event listeners
* and clears the internal timeout timer.
*
* Use `timeoutMs` instead of passing `AbortSignal.timeout(ms)` as a signal β
* under Bun, `AbortSignal.timeout` timers are finalized lazily and accumulate
* in native memory until they fire (measured ~2.4KB/call held for the full
* timeout duration). This implementation uses `setTimeout` + `clearTimeout`
* so the timer is freed immediately on cleanup.
*/
export function createCombinedAbortSignal(
signal: AbortSignal | undefined,
opts?: { signalB?: AbortSignal; timeoutMs?: number },
): { signal: AbortSignal; cleanup: () => void } {
const { signalB, timeoutMs } = opts ?? {}
const combined = createAbortController()
if (signal?.aborted || signalB?.aborted) {
combined.abort()
return { signal: combined.signal, cleanup: () => {} }
}
let timer: ReturnType<typeof setTimeout> | undefined
const abortCombined = () => {
if (timer !== undefined) clearTimeout(timer)
combined.abort()
}
if (timeoutMs !== undefined) {
timer = setTimeout(abortCombined, timeoutMs)
timer.unref?.()
}
signal?.addEventListener('abort', abortCombined)
signalB?.addEventListener('abort', abortCombined)
const cleanup = () => {
if (timer !== undefined) clearTimeout(timer)
signal?.removeEventListener('abort', abortCombined)
signalB?.removeEventListener('abort', abortCombined)
}
return { signal: combined.signal, cleanup }
}