Combine multiple AbortSignals into one. Aborts if any source aborts.
(...signals: (AbortSignal | undefined)[])
| 38 | |
| 39 | /** Combine multiple AbortSignals into one. Aborts if any source aborts. */ |
| 40 | function combineSignals(...signals: (AbortSignal | undefined)[]): { |
| 41 | signal: AbortSignal; |
| 42 | cleanup: () => void; |
| 43 | } { |
| 44 | const controller = new AbortController(); |
| 45 | const listeners: Array<() => void> = []; |
| 46 | |
| 47 | for (const sig of signals) { |
| 48 | if (!sig) continue; |
| 49 | if (sig.aborted) { |
| 50 | controller.abort(sig.reason); |
| 51 | break; |
| 52 | } |
| 53 | const listener = () => controller.abort(sig.reason); |
| 54 | sig.addEventListener("abort", listener, { once: true }); |
| 55 | listeners.push(() => sig.removeEventListener("abort", listener)); |
| 56 | } |
| 57 | |
| 58 | return { |
| 59 | signal: controller.signal, |
| 60 | cleanup: () => listeners.forEach((fn) => fn()), |
| 61 | }; |
| 62 | } |
| 63 | |
| 64 | async function toApiError(res: Response): Promise<ApiError> { |
| 65 | let message = `Request failed with status ${res.status}`; |