Repository navigation
Wrapping Event in a C++ class so that every where you pass an event it works. #1661
Description
Activity
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.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 extendEventTarget[Exposed=(Window, Worker), SecureContext
interface GPUDevice : EventTarget {
...
}This means, for example, if you patch
dispatchEventonEventTargetand calldispatchEventon aGPUDeviceit must go through the patched functionEventTarget.prototype.dispatchEvent = (function(origFn) { return function(event) { console.log('type:', event.type); return origFn.call(this, event); }; })(EventTarget.prototype.dispatchEvent); someGPUDevice.dispatchEvent(new Event('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 particularGPUUncapturedErrorEventextendsEventExposed=(Window, Worker), SecureContext]] interface GPUUncapturedErrorEvent : Event { constructor( DOMString type, GPUUncapturedErrorEventInit gpuUncapturedErrorEventInitDict ); [SameObject] readonly attribute GPUError error; }; dictionary GPUUncapturedErrorEventInit : EventInit { required GPUError error; };This means for example, it's valid to dispatchEvent an
GPUncaptureErrorEventthrough anEventTargetconst target = new EventTarget(); target.dispatchEvent(new GPUUncapturedErrorEvent('uncapturederror', { error: new GPUValidationError('msg'), });
Which is the issue above.
Several other requirements
GPUDevice.prototype instanceof EventTarget // should be true someGPUDevice instanceof EventTarget // should be true someGPUDevice instanceof GPUDevice // 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 ofsomeGPUDevice instanceof GPUDevice === true🤷Perhaps look at #229 for some other discussions regarding same.
Let us know how it turns out!
- added a commit that references this issue
on May 21, 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.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.
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');@jackdenied , not sure the point of your reply. This post is about C++, not JavaScript
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsHas PR
in JavaScript I can do this
Is it possible to have
MyEventbe a C++ class?In my current attempt, when I call
target.dispatchEventI getI tried setting the prototype chain in C++ and this passes
but of course it's not actually an
Event, it's a non-event who's prototype chain containsEventwhich is what node is complaining about.