You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Wrapping Event in a C++ class so that every where you pass an event it works. #1661
In my current attempt, when I call target.dispatchEvent I get
node:internal/event_target:220
throw new ERR_INVALID_THIS('Event');
^
TypeError [ERR_INVALID_THIS]: Value of "this" must be of type Event
at get type [as type] (node:internal/event_target:220:13)
at EventTarget.dispatchEvent (node:internal/event_target:755:40)
I tried setting the prototype chain in C++ and this passes
wrt, I'm trying to verify if this is possible or not. My impression is it's not possible and that I have to do something like create class MyEvent extends Event in JavaScript and then use it from my addon.
This means, for example, if you patch dispatchEvent on EventTarget and call dispatchEvent on a GPUDevice it must go through the patched function
EventTarget.prototype.dispatchEvent=(function(origFn){returnfunction(event){console.log('type:',event.type);returnorigFn.call(this,event);};})(EventTarget.prototype.dispatchEvent);someGPUDevice.dispatchEvent(newEvent('foobar'));// should see type: foobar in console
Similarly, as mentioned above, a custom event WebGPU event, implemented by dawn.node, needs to act like an Event. In particular GPUUncapturedErrorEvent extends Event
GPUDevice.prototypeinstanceofEventTarget// should be truesomeGPUDeviceinstanceofEventTarget// should be truesomeGPUDeviceinstanceofGPUDevice// should be true
I feel like I'm reading around the net and in issues in this repo that NAPI doesn't support what I'm trying to do and basically I'm trying to verify that.
Node-API does not currently provide a mechanism to create a C++ class that extends a JavaScript class. There's some technical limitations (as a class in V8 is a FunctionTemplate, which does not have a corresponding Node-API counterpart).
Have you tried prototype manipulation, eg. with Object.setPrototypeOf()? I am not sure if this would work, but if you have time to try it out... 👍 But it may not succeed in your requirement of someGPUDevice instanceof GPUDevice === true 🤷
Perhaps look at #229 for some other discussions regarding same.
So I did a bunch of hacking to get things to kind of work. The frustrating part is this works in the browsers (chrome/firefox/safari) that implement WebGPU but apparently with the current Napi design, and because limitations in v8 if I understand correctly, it's not possible in node addons.
My workarounds involved using a JavaScript object instead of C++ object for GPUUncapturedErrorEvent which works because GPUUncapturedErrorEvent is basically just a vehicle for some data. No functionality. I had to do similar things for GPUPipelineError as it's supposed to extend DOMException.
On the other hand, I could not workaround the fact that GPUDevice is supposed to extend EventTarget. That said, I know of no apis that take an EventTarget so it's unlikely to mater.
This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.
Activity
greggman commentedon May 15, 2025
wrt, I'm trying to verify if this is possible or not. My impression is it's not possible and that I have to do something like create
class MyEvent extends Eventin JavaScript and then use it from my addon.greggman commentedon May 15, 2025
Just to make it clear what my goal is here. I'm trying to get dawn.node to be spec compliant.
Dawn is Chromium's implementation of the WebGPU Spec and dawn.node is trying to bring the same API to node.js
That spec has a few requirements of extending existing classes
For example
GPUDeviceis supposed to extendEventTargetThis means, for example, if you patch
dispatchEventonEventTargetand calldispatchEventon aGPUDeviceit must go through the patched functionSimilarly, as mentioned above, a custom event WebGPU event, implemented by dawn.node, needs to act like an
Event. In particularGPUUncapturedErrorEventextendsEventThis means for example, it's valid to dispatchEvent an
GPUncaptureErrorEventthrough anEventTargetWhich is the issue above.
Several other requirements
I feel like I'm reading around the net and in issues in this repo that NAPI doesn't support what I'm trying to do and basically I'm trying to verify that.
KevinEady commentedon May 19, 2025
Node-API does not currently provide a mechanism to create a C++ class that extends a JavaScript class. There's some technical limitations (as a class in V8 is a FunctionTemplate, which does not have a corresponding Node-API counterpart).
Have you tried prototype manipulation, eg. with
Object.setPrototypeOf()? I am not sure if this would work, but if you have time to try it out... 👍 But it may not succeed in your requirement ofsomeGPUDevice instanceof GPUDevice === true🤷Perhaps look at #229 for some other discussions regarding same.
Let us know how it turns out!
Dawn.node: Make GPUUncapturedErrorEvent extend Event
greggman commentedon Jun 7, 2025
So I did a bunch of hacking to get things to kind of work. The frustrating part is this works in the browsers (chrome/firefox/safari) that implement WebGPU but apparently with the current Napi design, and because limitations in v8 if I understand correctly, it's not possible in node addons.
My workarounds involved using a JavaScript object instead of C++ object for
GPUUncapturedErrorEventwhich works becauseGPUUncapturedErrorEventis basically just a vehicle for some data. No functionality. I had to do similar things forGPUPipelineErroras it's supposed to extendDOMException.On the other hand, I could not workaround the fact that
GPUDeviceis supposed to extendEventTarget. That said, I know of no apis that take anEventTargetso it's unlikely to mater.legendecas commentedon Jun 19, 2025
@greggman I just realized that we can utilize a trick in JS to allow extending a JS class in node-addon-api, working around the limitation.
This should be already doable in C node-api. #1670 is a work to allow it in node-addon-api.
github-actions commentedon Oct 2, 2025
This issue is stale because it has been open many days with no activity. It will be closed soon unless the stale label is removed or a comment is made.
jackdenied commentedon Nov 4, 2025
class MyEvent extends Event {
constructor(type, msg) {
super(type);
this.message = msg;
}
}
const target = new EventTarget();
const e = await new Promise(resolve => {
target.addEventListener('custom', resolve);
target.dispatchEvent(new MyEvent('custom', 'hello'));
});
assert.ok(e.message === 'hello');
greggman commentedon Nov 4, 2025
@jackdenied , not sure the point of your reply. This post is about C++, not JavaScript