Summary
class X extends EventTarget does not inherit addEventListener / removeEventListener / dispatchEvent. The subclass instance reports them as undefined, and calling one throws TypeError: value is not a function.
Repro
class Bus extends EventTarget {}
const b = new Bus();
console.log("typeof dispatchEvent:", typeof b.dispatchEvent);
console.log("typeof addEventListener:", typeof b.addEventListener);
|
output |
| node 26 |
function / function |
perry main @ 0960415 |
undefined / undefined |
Verified on a clean origin/main build.
Root cause (suspected)
EventTarget appears to be implemented as name-keyed native method dispatch (crates/perry-runtime/src/event_target.rs, registered in object/global_this_tables.rs) rather than as real function properties resident on a prototype object. The telling detail: on a plain new EventTarget(), t.addEventListener(...) works as a call (the listener fires) but typeof t.addEventListener is still undefined. Because there is nothing on the prototype, a subclass inherits nothing.
class A extends EventTarget {}; class B extends A {} is also undefined.
Likely the same shape as the prototype work in #6147/#6148/#6149: the methods need to live on a real prototype object rather than being resolved by receiver name.
Impact
This breaks any package whose class extends EventTarget. It is the actual root cause of #5931 ("Using cac with default command resulting in error"): cac v7's CAC class is class CAC extends EventTarget, and every matched command path calls this.dispatchEvent(...), so any matching command dies with TypeError: value is not a function. (#5931's title is misleading — it is not about the default command; a command with no .action() fails too.)
Summary
class X extends EventTargetdoes not inheritaddEventListener/removeEventListener/dispatchEvent. The subclass instance reports them asundefined, and calling one throwsTypeError: value is not a function.Repro
function/functionmain@ 0960415undefined/undefinedVerified on a clean
origin/mainbuild.Root cause (suspected)
EventTargetappears to be implemented as name-keyed native method dispatch (crates/perry-runtime/src/event_target.rs, registered inobject/global_this_tables.rs) rather than as real function properties resident on a prototype object. The telling detail: on a plainnew EventTarget(),t.addEventListener(...)works as a call (the listener fires) buttypeof t.addEventListeneris stillundefined. Because there is nothing on the prototype, a subclass inherits nothing.class A extends EventTarget {}; class B extends A {}is alsoundefined.Likely the same shape as the prototype work in #6147/#6148/#6149: the methods need to live on a real prototype object rather than being resolved by receiver name.
Impact
This breaks any package whose class extends
EventTarget. It is the actual root cause of #5931 ("Using cac with default command resulting in error"): cac v7'sCACclass isclass CAC extends EventTarget, and every matched command path callsthis.dispatchEvent(...), so any matching command dies withTypeError: value is not a function. (#5931's title is misleading — it is not about the default command; a command with no.action()fails too.)