Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/js/node/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ const kCapture: typeof shared.kCapture = shared.kCapture;
// writes `undefined` instead of `delete`, keeping one shared JSC Structure
// so the (StructureID, name)-keyed megamorphic cache stays hot.
const kShapeMode: typeof shared.kShapeMode = shared.kShapeMode;
const kErrorMonitor = Symbol.for("events.errorMonitor");
const kErrorMonitor = Symbol("events.errorMonitor");
const kMaxEventTargetListeners = Symbol("events.maxEventTargetListeners");
const kMaxEventTargetListenersWarned = Symbol("events.maxEventTargetListenersWarned");
const kWatermarkData = Symbol.for("nodejs.watermarkData");
Expand Down
2 changes: 1 addition & 1 deletion src/node-fallbacks/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
const SymbolFor = Symbol.for;

const kCapture = Symbol("kCapture");
const kErrorMonitor = SymbolFor("events.errorMonitor");
const kErrorMonitor = Symbol("events.errorMonitor");
Comment thread
robobun marked this conversation as resolved.
Resolved
const kMaxEventTargetListeners = Symbol("events.maxEventTargetListeners");
const kMaxEventTargetListenersWarned = Symbol("events.maxEventTargetListenersWarned");
const kRejection = SymbolFor("nodejs.rejection");
Expand Down
30 changes: 30 additions & 0 deletions test/bundler/bundler_browser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,36 @@ describe("bundler", () => {
assert(!out.includes("$newPromiseCapability"), "events polyfill must not reference a JSC builtin intrinsic");
},
});
// The polyfill is its own copy of the emitter. As in node, its errorMonitor
// is not the symbol that Symbol.for("events.errorMonitor") returns.
itBundled("browser/NodeEventsErrorMonitor", {
files: {
"/entry.js": /* js */ `
import { EventEmitter } from "node:events";
const e = new EventEmitter();
const calls = [];
e.on(EventEmitter.errorMonitor, err => calls.push("monitor:" + err.message));
e.on(Symbol.for("events.errorMonitor"), err => calls.push("registered:" + err.message));
try {
e.emit("error", new Error("boom"));
} catch (err) {
calls.push("threw:" + err.message);
}
console.log(JSON.stringify({
keyFor: Symbol.keyFor(EventEmitter.errorMonitor) ?? null,
calls,
monitors: e.listenerCount(EventEmitter.errorMonitor),
}));
`,
},
target: "browser",
run: {
stdout: '{"keyFor":null,"calls":["monitor:boom","threw:boom"],"monitors":1}',
},
onAfterBundle(api) {
api.expectFile("out.js").not.toInclude("import ");
},
});
itBundled("browser/NodeUrlProtocolTablesIgnorePrototype", {
files: {
"/entry.js": /* js */ `
Expand Down
37 changes: 37 additions & 0 deletions test/js/node/events/event-emitter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { join } from "path";
// our transpiler transform changes this to a var with import.meta.require
import EventEmitter, {
captureRejectionSymbol,
errorMonitor,
getEventListeners,
getMaxListeners,
listenerCount,
Expand Down Expand Up @@ -757,6 +758,42 @@ describe("EventEmitter error handling", () => {

expect(handled).toBe(true);
});

test("errorMonitor is not in the global symbol registry", () => {
expect({
namedExport: errorMonitor === EventEmitter.errorMonitor,
sameAsRegistered: errorMonitor === Symbol.for("events.errorMonitor"),
keyFor: Symbol.keyFor(errorMonitor),
description: errorMonitor.description,
}).toEqual({
namedExport: true,
sameAsRegistered: false,
keyFor: undefined,
description: "events.errorMonitor",
});
});

test("a listener under Symbol.for('events.errorMonitor') is not an error monitor", () => {
const registered = Symbol.for("events.errorMonitor");
const myEmitter = new EventEmitter();

const calls: unknown[][] = [];
myEmitter.on(registered, (...args) => calls.push(args));

expect(() => {
myEmitter.emit("error", new Error("boom"));
}).toThrow("boom");
expect(calls).toEqual([]);

expect(myEmitter.emit(registered, "direct")).toBe(true);
expect(calls).toEqual([["direct"]]);

myEmitter.on(errorMonitor, () => {});
expect({
monitors: myEmitter.listenerCount(errorMonitor),
registered: myEmitter.listenerCount(registered),
}).toEqual({ monitors: 1, registered: 1 });
});
});

describe("EventEmitter captureRejections", () => {
Expand Down
Loading