mirror of
https://github.com/zero-peak/ZeroOmega.git
synced 2025-03-15 09:18:15 -04:00
29 lines
1.4 KiB
JavaScript
29 lines
1.4 KiB
JavaScript
// When running within Node.js (including jsdom), we want to use setImmediate
|
|
// (which runs immediately) rather than setTimeout (which enforces a minimum
|
|
// delay of 1ms, and on Windows only has a resolution of 15ms or so). jsdom
|
|
// doesn't provide setImmediate (to better match the browser environment) and
|
|
// sandboxes scripts, but its sandbox is by necessity imperfect, so we can break
|
|
// out of it:
|
|
//
|
|
// - https://github.com/jsdom/jsdom#executing-scripts
|
|
// - https://github.com/jsdom/jsdom/issues/2729
|
|
// - https://github.com/scala-js/scala-js-macrotask-executor/pull/17
|
|
function getSetImmediateFromJsdom() {
|
|
if (typeof navigator !== "undefined" && /jsdom/.test(navigator.userAgent)) {
|
|
const outerRealmFunctionConstructor = Node.constructor;
|
|
return new outerRealmFunctionConstructor("return setImmediate")();
|
|
} else {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
// Schedules a task to run later. Use Node.js's setImmediate if available and
|
|
// setTimeout otherwise. Note that options like process.nextTick or
|
|
// queueMicrotask will likely not work: IndexedDB semantics require that
|
|
// transactions are marked as not active when the event loop runs. The next
|
|
// tick queue and microtask queue run within the current event loop macrotask,
|
|
// so they'd process database operations too quickly.
|
|
export const queueTask = fn => {
|
|
const setImmediate = globalThis.setImmediate || getSetImmediateFromJsdom() || (fn => setTimeout(fn, 0));
|
|
setImmediate(fn);
|
|
}; |