diff --git a/fluxer_app/src/app/AbortSignalPolyfill.ts b/fluxer_app/src/app/AbortSignalPolyfill.ts new file mode 100644 index 000000000..ec2a9e28e --- /dev/null +++ b/fluxer_app/src/app/AbortSignalPolyfill.ts @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later + +function abortSignalTimeout(milliseconds: number): AbortSignal { + const controller = new AbortController(); + setTimeout(() => controller.abort(new DOMException('The operation timed out.', 'TimeoutError')), milliseconds); + return controller.signal; +} + +function abortSignalAny(signals: Iterable): AbortSignal { + const controller = new AbortController(); + const sources = [...signals]; + const aborted = sources.find((source) => source.aborted); + if (aborted) { + controller.abort(aborted.reason); + return controller.signal; + } + for (const source of sources) { + source.addEventListener('abort', () => controller.abort(source.reason), {once: true, signal: controller.signal}); + } + return controller.signal; +} + +export function installAbortSignalPolyfill(target: typeof AbortSignal = AbortSignal): void { + if (typeof target.timeout !== 'function') { + target.timeout = abortSignalTimeout; + } + if (typeof target.any !== 'function') { + target.any = abortSignalAny; + } +} + +installAbortSignalPolyfill(); diff --git a/fluxer_app/src/index.tsx b/fluxer_app/src/index.tsx index e7618dabc..55305abec 100644 --- a/fluxer_app/src/index.tsx +++ b/fluxer_app/src/index.tsx @@ -1,5 +1,6 @@ // SPDX-License-Identifier: AGPL-3.0-or-later +import '@app/app/AbortSignalPolyfill'; import '@app/app/BootShell.css'; import {startAppStorage} from '@app/features/platform/state/AppStorageBootstrap'; import {installBrowserStorageAccessProtection} from '@app/features/platform/state/ProtectedWebStorage';