| 1 | // AbortSignal.timeout() is currently baseline 2024
|
|---|
| 2 | export const timeoutSignal = (milliseconds: number) => {
|
|---|
| 3 | const abortController = new AbortController()
|
|---|
| 4 | setTimeout(() => {
|
|---|
| 5 | const message = 'signal timed out'
|
|---|
| 6 | const name = 'TimeoutError'
|
|---|
| 7 | abortController.abort(
|
|---|
| 8 | // some environments (React Native, Node) don't have DOMException
|
|---|
| 9 | typeof DOMException !== 'undefined'
|
|---|
| 10 | ? new DOMException(message, name)
|
|---|
| 11 | : Object.assign(new Error(message), { name }),
|
|---|
| 12 | )
|
|---|
| 13 | }, milliseconds)
|
|---|
| 14 | return abortController.signal
|
|---|
| 15 | }
|
|---|
| 16 |
|
|---|
| 17 | // AbortSignal.any() is currently baseline 2024
|
|---|
| 18 | export const anySignal = (...signals: AbortSignal[]) => {
|
|---|
| 19 | // if any are already aborted, return an already aborted signal
|
|---|
| 20 | for (const signal of signals)
|
|---|
| 21 | if (signal.aborted) return AbortSignal.abort(signal.reason)
|
|---|
| 22 |
|
|---|
| 23 | // otherwise, create a new signal that aborts when any of the given signals abort
|
|---|
| 24 | const abortController = new AbortController()
|
|---|
| 25 | for (const signal of signals) {
|
|---|
| 26 | signal.addEventListener(
|
|---|
| 27 | 'abort',
|
|---|
| 28 | () => abortController.abort(signal.reason),
|
|---|
| 29 | { signal: abortController.signal, once: true },
|
|---|
| 30 | )
|
|---|
| 31 | }
|
|---|
| 32 | return abortController.signal
|
|---|
| 33 | }
|
|---|