diff --git a/src/libs/set-immediate-polyfill.ts b/src/libs/set-immediate-polyfill.ts new file mode 100644 index 0000000..32a7009 --- /dev/null +++ b/src/libs/set-immediate-polyfill.ts @@ -0,0 +1,42 @@ +const originalSetImmediate = (globalThis as any).setImmediate +let setImmediateChannel: MessageChannel | null = null +const setImmediateQueue: (() => void)[] = [] + +function immediatePolyfill(callback: (...args: any[]) => void, ...args: any[]) { + if (typeof originalSetImmediate === 'function') { + return originalSetImmediate(callback, ...args) + } + + if (typeof MessageChannel !== 'undefined') { + if (!setImmediateChannel) { + setImmediateChannel = new MessageChannel() + setImmediateChannel.port1.addEventListener('message', () => { + const fn = setImmediateQueue.shift() + if (fn) { + try { + fn() + } catch {} + } + }) + setImmediateChannel.port1.start() + } + setImmediateQueue.push(() => callback(...args)) + setImmediateChannel.port2.postMessage(0) + return 0 + } + + return setTimeout(() => callback(...args), 0) +} + +export function installSetImmediatePolyfill() { + if (typeof (globalThis as any).setImmediate === 'function') { + return + } + ;(globalThis as any).setImmediate = immediatePolyfill +} + +export function uninstallSetImmediatePolyfill() { + if ((globalThis as any).setImmediate === immediatePolyfill) { + delete (globalThis as any).setImmediate + } +} diff --git a/src/libs/utils.ts b/src/libs/utils.ts index 58a6f56..de97a57 100644 --- a/src/libs/utils.ts +++ b/src/libs/utils.ts @@ -1,6 +1,9 @@ import { ResolvableFile } from '../classes/resolvable-file.ts' +import { uninstallSetImmediatePolyfill } from './set-immediate-polyfill.ts' import { vendors } from './vendors.ts' +export { installSetImmediatePolyfill, uninstallSetImmediatePolyfill } from './set-immediate-polyfill.ts' + const { path } = vendors export const textEncoder = new TextEncoder() @@ -238,24 +241,3 @@ export function isZip(uint8Array: Uint8Array) { (uint8Array[3] === 0x04 || uint8Array[3] === 0x06 || uint8Array[3] === 0x08) ) } - -const originalSetImmediate = globalThis.setImmediate -function setImmediate(callback: any) { - // eslint-disable-next-line @typescript-eslint/no-implied-eval - return originalSetImmediate ? originalSetImmediate(callback) : setTimeout(callback, 0) -} - -export function installSetImmediatePolyfill() { - if (typeof globalThis.setImmediate === 'function') { - return - } - // @ts-expect-error polyfill - globalThis.setImmediate = setImmediate -} - -export function uninstallSetImmediatePolyfill() { - if (globalThis.setImmediate === setImmediate) { - // @ts-expect-error remove polyfill - delete globalThis.setImmediate - } -}