Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465// The globals each process runtime installs, in one place, before the entry runs (CJS and// ESM alike). queueMicrotask is the one global the kernel installs, as Node does (lib's is// a plain JS function over the engine's queueMicrotask, wired to AsyncContextFrame; stage 1// gives ours the same shape over async_hooks.ts's frame instead).import { Buffer } from "./buffer";import { capture, runInFrame } from "./async_hooks";import { invalidArgType } from "./errors";import type { GuestProcess } from "./process";import type { Timeout, Timers } from "./timers";
// Captured before any global replaces it, as loop.ts does for setTimeout.const nativeQueueMicrotask = globalThis.queueMicrotask.bind(globalThis);
/** Node's queueMicrotask (lib/internal/process/task_queues.js): same name, length and * validation, over the engine's own microtask queue so ordering against native * promise jobs is unchanged. The callback runs in the frame current when * queueMicrotask() was called, restored afterwards. */function queueMicrotask(callback: unknown): void { if (typeof callback !== "function") throw invalidArgType("callback", "of type function", callback); const frame = capture(); const cb = callback as () => void; nativeQueueMicrotask(() => runInFrame(frame, cb));}
/** The Node globals a browser worker lacks. */export function installNodeGlobals(timers: Timers, process: GuestProcess): void { Object.assign(globalThis, { global: globalThis, process, Buffer, setTimeout: timers.setTimeout, clearTimeout: timers.clearTimeout, setInterval: timers.setInterval, clearInterval: timers.clearInterval, setImmediate: timers.setImmediate, clearImmediate: timers.clearImmediate, queueMicrotask, }); // Node has no `self`, so a guest's `globalThis.self = …` creates one; the worker's // is a getter-only accessor, which a strict-mode assignment throws on. napi-rs's // wasi-worker.mjs assigns it before a binding's thread can start. Object.defineProperty(globalThis, "self", { value: globalThis, writable: true, configurable: true, enumerable: true });}
/** Web-shaped timers that still hold the loop, so a pending timer keeps the process * alive: they return the numeric id, which clearTimeout already accepts. close() exits * the process: the worker's own would end it without the kernel ever hearing. */export function installWebGlobals(timers: Timers, process: GuestProcess): void { const byId = (start: (fn: () => void, ms?: unknown, ...args: unknown[]) => Timeout) => (fn: () => void, ms?: unknown, ...args: unknown[]): number => Number(start(fn, ms, ...args)); let closing = false; Object.assign(globalThis, { setTimeout: byId(timers.setTimeout), clearTimeout: timers.clearTimeout, setInterval: byId(timers.setInterval), clearInterval: timers.clearInterval, // As in a worker, the current task runs to its end and nothing queued after it does. close(): void { if (closing) return; closing = true; queueMicrotask(() => process.exit(0)); }, });}