Something went wrong. Try again.
Monorepo for the nibling.run platform
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518// node:events, in Node's own shape: a function constructor (so `EventEmitter.call(this)`// and prototype mixins work), listeners stored on `this._events` as a function or an// array, once-wrappers carrying `.listener`. An 'error' with no listener throws.import { AsyncResource } from "./async_hooks";import { nextTick } from "./ticks";
type Listener = (...args: any[]) => void;type Wrapped = Listener & { listener?: Listener };type Key = string | symbol;
export interface EventEmitter { _events: Record<Key, Wrapped | Wrapped[]> | undefined; _eventsCount: number; _maxListeners: number | undefined; /** Node's kCapture, under our own name since nothing outside this file keys off * the symbol's identity. */ _captureRejections: boolean; on(event: Key, fn: Listener): this; addListener(event: Key, fn: Listener): this; prependListener(event: Key, fn: Listener): this; once(event: Key, fn: Listener): this; prependOnceListener(event: Key, fn: Listener): this; off(event: Key, fn: Listener): this; removeListener(event: Key, fn: Listener): this; removeAllListeners(event?: Key): this; emit(event: Key, ...args: any[]): boolean; listeners(event: Key): Listener[]; rawListeners(event: Key): Listener[]; listenerCount(event: Key, fn?: Listener): number; eventNames(): Key[]; setMaxListeners(n: number): this; getMaxListeners(): number;}
export interface EventEmitterConstructor { new (options?: { captureRejections?: boolean }): EventEmitter; (this: unknown, options?: unknown): void; prototype: EventEmitter; EventEmitter: EventEmitterConstructor; defaultMaxListeners: number; usingDomains: boolean; readonly errorMonitor: symbol; readonly captureRejectionSymbol: symbol; captureRejections: boolean; once: typeof once; on: typeof on; getEventListeners: typeof getEventListeners; getMaxListeners: typeof getMaxListeners; setMaxListeners: typeof setMaxListeners; addAbortListener: typeof addAbortListener; EventEmitterAsyncResource: typeof EventEmitterAsyncResource; listenerCount(emitter: EventEmitter, event: Key): number; init(this: EventEmitter, options?: { captureRejections?: boolean }): void;}
function unhandledError(er: unknown): Error { if (er instanceof Error) return er; let shown: string; try { shown = typeof er === "string" ? `'${er}'` : String(er); } catch { shown = "[object]"; } return Object.assign(new Error(`Unhandled error. (${shown})`), { code: "ERR_UNHANDLED_ERROR", context: er });}
function checkListener(fn: unknown): asserts fn is Listener { if (typeof fn !== "function") { throw Object.assign(new TypeError(`The "listener" argument must be of type function. Received ${typeof fn}`), { code: "ERR_INVALID_ARG_TYPE", }); }}
function eventsOf(self: EventEmitter): Record<Key, Wrapped | Wrapped[]> { if (self._events === undefined || self._events === Object.getPrototypeOf(self)._events) { self._events = Object.create(null) as Record<Key, Wrapped | Wrapped[]>; self._eventsCount = 0; } return self._events;}
function listOf(self: EventEmitter, event: Key): Wrapped[] { const entry = self._events?.[event]; return entry === undefined ? [] : typeof entry === "function" ? [entry] : entry;}
function store(self: EventEmitter, event: Key, list: Wrapped[]): void { const events = eventsOf(self); const had = events[event] !== undefined; if (list.length === 0) { delete events[event]; if (had) self._eventsCount--; } else { events[event] = list.length === 1 ? list[0]! : list; if (!had) self._eventsCount++; }}
function add(self: EventEmitter, event: Key, fn: Wrapped, prepend: boolean): EventEmitter { checkListener(fn.listener ?? fn); if (self._events?.newListener !== undefined) self.emit("newListener", event, fn.listener ?? fn); const list = [...listOf(self, event)]; if (prepend) list.unshift(fn); else list.push(fn); store(self, event, list); return self;}
function onceWrapper(self: EventEmitter, event: Key, fn: Listener): Wrapped { checkListener(fn); let fired = false; const wrapped: Wrapped = function (this: unknown, ...args: unknown[]) { if (fired) return undefined; fired = true; self.removeListener(event, wrapped); return fn.apply(this, args); }; wrapped.listener = fn; return wrapped;}
function invalidArgType(name: string, expected: string, value: unknown): TypeError { const got = value === null ? "null" : value === undefined ? "undefined" : `type ${typeof value}`; return Object.assign(new TypeError(`The "${name}" argument must be ${expected}. Received ${got}`), { code: "ERR_INVALID_ARG_TYPE" });}
function init(this: EventEmitter, opts?: { captureRejections?: boolean }): void { eventsOf(this); this._maxListeners ??= undefined; if (opts?.captureRejections !== undefined) { if (typeof opts.captureRejections !== "boolean") throw invalidArgType("options.captureRejections", "of type boolean", opts.captureRejections); this._captureRejections = opts.captureRejections; } else { this._captureRejections = EventEmitter.prototype._captureRejections; }}
export const EventEmitter = function EventEmitter(this: EventEmitter, opts?: { captureRejections?: boolean }) { init.call(this, opts);} as unknown as EventEmitterConstructor;
EventEmitter.init = init;
EventEmitter.EventEmitter = EventEmitter;EventEmitter.defaultMaxListeners = 10;EventEmitter.usingDomains = false;Object.defineProperty(EventEmitter, "errorMonitor", { value: Symbol("events.errorMonitor"), enumerable: true });Object.defineProperty(EventEmitter, "captureRejectionSymbol", { value: Symbol.for("nodejs.rejection"), enumerable: true });Object.defineProperty(EventEmitter, "captureRejections", { enumerable: true, get(): boolean { return EventEmitter.prototype._captureRejections; }, set(value: unknown): void { if (typeof value !== "boolean") throw invalidArgType("EventEmitter.captureRejections", "of type boolean", value); EventEmitter.prototype._captureRejections = value; },});EventEmitter.listenerCount = (emitter, event) => emitter.listenerCount(event);
const proto = EventEmitter.prototype;proto._events = undefined;proto._eventsCount = 0;proto._maxListeners = undefined;proto._captureRejections = false;
proto.on = proto.addListener = function (event, fn) { return add(this, event, fn, false);};proto.prependListener = function (event, fn) { return add(this, event, fn, true);};// once routes through this.on, as in Node, so a subclass's `on` override (Readable// resuming on 'data') sees once-listeners too.proto.once = function (event, fn) { return this.on(event, onceWrapper(this, event, fn));};proto.prependOnceListener = function (event, fn) { return this.prependListener(event, onceWrapper(this, event, fn));};proto.off = proto.removeListener = function (event, fn) { checkListener(fn); const list = listOf(this, event); // Node removes the most recently added match, wrapped or not. for (let i = list.length - 1; i >= 0; i--) { const l = list[i]!; if (l !== fn && l.listener !== fn) continue; const next = [...list]; next.splice(i, 1); store(this, event, next); if (this._events?.removeListener !== undefined) this.emit("removeListener", event, l.listener ?? l); break; } return this;};proto.removeAllListeners = function (event) { // With 'removeListener' listeners, Node removes one at a time (last first) so each // removal is reported, and removes the 'removeListener' listeners themselves last. if (this._events?.removeListener !== undefined) { const keys = event === undefined ? Reflect.ownKeys(this._events).filter((k) => k !== "removeListener") : [event]; for (const key of keys) { for (let list = listOf(this, key); list.length; list = listOf(this, key)) this.removeListener(key, list.at(-1)!); } if (event !== undefined) return this; } if (event === undefined) { this._events = Object.create(null) as Record<Key, Wrapped | Wrapped[]>; this._eventsCount = 0; } else { store(this, event, []); } return this;};proto.emit = function (event, ...args) { if (event === "error") for (const l of listOf(this, EventEmitter.errorMonitor)) l.apply(this, args); const list = listOf(this, event); if (list.length === 0) { if (event === "error") throw unhandledError(args[0]); return false; } const capture = this._captureRejections; for (const l of list) { const result = l.apply(this, args); if (capture && result && typeof (result as { then?: unknown }).then === "function") { addCaptureCatch(this, result as Promise<unknown>, event, args); } } return true;};proto.listeners = function (event) { return listOf(this, event).map((l) => l.listener ?? l);};proto.rawListeners = function (event) { return [...listOf(this, event)];};proto.listenerCount = function (event, fn) { const list = listOf(this, event); return fn ? list.filter((l) => l === fn || l.listener === fn).length : list.length;};proto.eventNames = function () { return this._events ? Reflect.ownKeys(this._events) : [];};/** Leak warnings are not implemented; the limit is stored and reported back. */proto.setMaxListeners = function (n) { this._maxListeners = n; return this;};proto.getMaxListeners = function () { return this._maxListeners ?? EventEmitter.defaultMaxListeners;};
/** events.once: resolves with the args of the next `event`, rejects on 'error'. */export function once(emitter: EventEmitter, event: Key): Promise<unknown[]> { return new Promise((resolve, reject) => { const onError = (err: unknown): void => { emitter.off(event, onEvent); reject(err); }; const onEvent = (...args: unknown[]): void => { if (event !== "error") emitter.off("error", onError); resolve(args); }; emitter.once(event, onEvent); if (event !== "error") emitter.once("error", onError); });}EventEmitter.once = once;
/** When captureRejections is on, a listener's rejected promise becomes an 'error' * (or the captureRejectionSymbol handler, if the emitter has one) a tick later, * matching Node's addCatch/emitUnhandledRejectionOrErr. */function addCaptureCatch(emitter: EventEmitter, result: Promise<unknown>, event: Key, args: unknown[]): void { result.then(undefined, (err: unknown) => { nextTick(() => { const withRejection = emitter as unknown as Record<symbol, ((err: unknown, event: Key, ...args: unknown[]) => void) | undefined>; const handler = withRejection[EventEmitter.captureRejectionSymbol]; if (typeof handler === "function") { handler.call(emitter, err, event, ...args); return; } const prev = emitter._captureRejections; try { emitter._captureRejections = false; emitter.emit("error", err); } finally { emitter._captureRejections = prev; } }); });}
function invalidArgTypeList(name: string, types: string[], value: unknown): TypeError { const got = value === null ? "null" : value === undefined ? "undefined" : typeof value === "object" ? `an instance of ${(value as object).constructor?.name ?? "Object"}` : `type ${typeof value}`; return Object.assign(new TypeError(`The "${name}" argument must be one of type ${types.join(" or ")}. Received ${got}`), { code: "ERR_INVALID_ARG_TYPE", });}
/** events.getEventListeners: EventEmitter's own list for an EventEmitter. The browser's * native EventTarget keeps no public listener list, so that side refuses (see this * chunk's report: no platform API for it). */export function getEventListeners(emitterOrTarget: unknown, type: Key): Listener[] { const e = emitterOrTarget as { listeners?: (t: Key) => Listener[] }; if (typeof e.listeners === "function") return e.listeners(type); if (emitterOrTarget instanceof EventTarget) { throw Object.assign( new Error("ERR_NIB_UNSUPPORTED: node:events getEventListeners() is not supported for a native EventTarget (no public listener list)"), { code: "ERR_NIB_UNSUPPORTED" }, ); } throw invalidArgTypeList("emitter", ["EventEmitter", "EventTarget"], emitterOrTarget);}
const targetMaxListeners = new WeakMap<EventTarget, number>();
/** events.getMaxListeners: the EventEmitter's own limit, or the stored (unenforced) * limit for a native EventTarget — see proto.setMaxListeners's comment. */export function getMaxListeners(emitterOrTarget: unknown): number { const e = emitterOrTarget as { getMaxListeners?: () => number }; if (typeof e.getMaxListeners === "function") return e.getMaxListeners(); if (emitterOrTarget instanceof EventTarget) return targetMaxListeners.get(emitterOrTarget) ?? EventEmitter.defaultMaxListeners; throw invalidArgTypeList("emitter", ["EventEmitter", "EventTarget"], emitterOrTarget);}
function validateNumber(n: unknown, name: string): asserts n is number { if (typeof n !== "number") throw invalidArgTypeList(name, ["number"], n); if (Number.isNaN(n) || n < 0) { throw Object.assign(new RangeError(`The value of "${name}" is out of range. It must be >= 0. Received ${n}`), { code: "ERR_OUT_OF_RANGE" }); }}
/** events.setMaxListeners(n, ...targets): targets' own limit, or (with none) * EventEmitter.defaultMaxListeners for every emitter that hasn't set its own. */export function setMaxListeners(n: number = EventEmitter.defaultMaxListeners, ...eventTargets: unknown[]): void { validateNumber(n, "setMaxListeners"); if (eventTargets.length === 0) { EventEmitter.defaultMaxListeners = n; return; } for (const target of eventTargets) { if (target instanceof EventTarget) { targetMaxListeners.set(target, n); } else if (typeof (target as { setMaxListeners?: unknown }).setMaxListeners === "function") { (target as EventEmitter).setMaxListeners(n); } else { throw invalidArgTypeList("eventTargets", ["EventEmitter", "EventTarget"], target); } }}
/** events.addAbortListener: fires once, immediately if already aborted; returns a * disposable that removes the listener. */export function addAbortListener(signal: AbortSignal, listener: (this: AbortSignal, ev: Event) => void): { [Symbol.dispose](): void } { if (signal === undefined) throw invalidArgTypeList("signal", ["AbortSignal"], signal); if (!(signal instanceof AbortSignal)) throw invalidArgTypeList("signal", ["AbortSignal"], signal); if (typeof listener !== "function") throw invalidArgTypeList("listener", ["function"], listener); let remove: (() => void) | undefined; if (signal.aborted) { queueMicrotask(() => (listener as unknown as () => void).call(signal)); } else { const handler = (): void => (listener as unknown as () => void).call(signal); signal.addEventListener("abort", handler, { once: true }); remove = () => signal.removeEventListener("abort", handler); } return { [Symbol.dispose]: () => remove?.() };}EventEmitter.addAbortListener = addAbortListener;
const kWatermarkData = Symbol.for("nodejs.watermarkData");
/** events.on(emitter, event, options): an async iterator of an event's arguments, * queued between reads, pausing the emitter past highWaterMark if it is Readable-like * (Node calls emitter.pause()/resume(), which only exist on streams). */export function on(emitter: EventEmitter, event: Key, options: { signal?: AbortSignal; highWaterMark?: number; lowWaterMark?: number; close?: Key[];} = {}): AsyncIterableIterator<unknown[]> { const signal = options.signal; if (signal !== undefined && !(signal instanceof AbortSignal)) throw invalidArgTypeList("options.signal", ["AbortSignal"], signal); if (signal?.aborted) throw Object.assign(new Error("The operation was aborted"), { name: "AbortError", code: "ABORT_ERR", cause: signal.reason }); const highWaterMark = options.highWaterMark ?? Number.MAX_SAFE_INTEGER; const lowWaterMark = options.lowWaterMark ?? 1;
const queue: unknown[][] = []; const waiting: Array<{ resolve: (r: IteratorResult<unknown[]>) => void; reject: (e: unknown) => void }> = []; let paused = false; let error: unknown = null; let finished = false; const done = (): IteratorResult<unknown[]> => ({ value: undefined, done: true });
const pausable = emitter as unknown as { pause?: () => void; resume?: () => void };
const onEvent = (...args: unknown[]): void => { if (waiting.length) { waiting.shift()!.resolve({ value: args, done: false }); return; } queue.push(args); if (!paused && queue.length > highWaterMark) { paused = true; pausable.pause?.(); } }; const onError = (err: unknown): void => { if (waiting.length) waiting.shift()!.reject(err); else error = err; void iterator.return!(); }; const closeHandler = (): Promise<IteratorResult<unknown[]>> => { removeAll(); finished = true; paused = false; const result = done(); while (waiting.length) waiting.shift()!.resolve(result); return Promise.resolve(result); }; const removeAll = (): void => { emitter.removeListener(event, onEvent); if (event !== "error") emitter.removeListener("error", onError); for (const closeEvent of options.close ?? []) emitter.removeListener(closeEvent, closeHandler); abortDisposable?.[Symbol.dispose](); };
emitter.on(event, onEvent); if (event !== "error") emitter.on("error", onError); for (const closeEvent of options.close ?? []) emitter.on(closeEvent, closeHandler); const abortDisposable = signal ? addAbortListener(signal, () => onError(Object.assign( new Error("The operation was aborted"), { name: "AbortError", code: "ABORT_ERR", cause: signal.reason }, ))) : null;
const iterator = { next(): Promise<IteratorResult<unknown[]>> { if (queue.length) { const value = queue.shift()!; if (paused && queue.length < lowWaterMark) { paused = false; pausable.resume?.(); } return Promise.resolve({ value, done: false }); } if (error) { const e = error; error = null; return Promise.reject(e); } if (finished) return closeHandler(); return new Promise((resolve, reject) => waiting.push({ resolve, reject })); }, return(): Promise<IteratorResult<unknown[]>> { return closeHandler(); }, throw(err: unknown): Promise<never> { error = err; removeAll(); return Promise.reject(err); }, [Symbol.asyncIterator]() { return this; }, get [kWatermarkData]() { return { size: queue.length, low: lowWaterMark, high: highWaterMark, isPaused: paused }; }, }; return iterator as unknown as AsyncIterableIterator<unknown[]>;}EventEmitter.on = on;EventEmitter.getEventListeners = getEventListeners;EventEmitter.getMaxListeners = getMaxListeners;EventEmitter.setMaxListeners = setMaxListeners;
/** events.EventEmitterAsyncResource: an EventEmitter whose emit() runs inside its own * AsyncResource scope (see async_hooks.ts) — ported from Node's addaleax/ * eventemitter-asyncresource, as Node's own lazyEventEmitterAsyncResource is. */export class EventEmitterAsyncResource extends (EventEmitter as unknown as { new (opts?: unknown): EventEmitter }) { #resource: AsyncResource;
constructor(options?: string | { name?: string; triggerAsyncId?: number; requireManualDestroy?: boolean; captureRejections?: boolean }) { let name: string | undefined; let opts = options; if (typeof opts === "string") { name = opts; opts = undefined; } else { const o = opts as { name?: string } | undefined; if (new.target === EventEmitterAsyncResource && typeof o?.name !== "string") { throw Object.assign(new TypeError('The "options.name" argument must be of type string.'), { code: "ERR_INVALID_ARG_TYPE" }); } name = o?.name || new.target.name; } super(opts); this.#resource = new AsyncResource(name, opts); }
override emit(event: Key, ...args: unknown[]): boolean { const resource = this.#resource; return resource.runInAsyncScope(() => (EventEmitter.prototype.emit as (this: EventEmitter, e: Key, ...a: unknown[]) => boolean).call(this, event, ...args)); }
emitDestroy(): void { this.#resource.emitDestroy(); }
get asyncId(): number { return this.#resource.asyncId(); }
get triggerAsyncId(): number { return this.#resource.triggerAsyncId(); }
get asyncResource(): AsyncResource { return this.#resource; }}Object.defineProperty(EventEmitter, "EventEmitterAsyncResource", { value: EventEmitterAsyncResource, enumerable: true, configurable: true });