Stream: wit-bindgen

Topic: Extend a imported resource


view this post on Zulip Jeremy Slater (Feb 28 2024 at 19:11):

I'm defining a factory resource (i.e. resource object {}, resource factory { create: func() -> object; }for a javascript class. I am importing, and defining the class in an external js file (i,e. class Factory { create() } and using --map to map it into bindgen. The problem is that when I extend the factory js and register the factory, later when rust uses the factory, the base/super class factory function is called, and not the extended class function. The issue is that the codegen is calling the superclass prototype directly instead of the class instance function. i.e. - Factory.prototype.create.call(rsc0);. If I hot patch the generated js I can work around this, but the question is, what is the right way to do this, and does wit even support the concept of a trait/protocol for me to do what I'm trying to do.

view this post on Zulip Alex Crichton (Feb 28 2024 at 19:50):

cc @Guy Bedford

view this post on Zulip Guy Bedford (Feb 29 2024 at 01:31):

Thanks for the ping @Alex Crichton we can make this work by calling whatever instance method is defined, allowing JS-defined resources to behave more like JS classes and to have method variations per reference passed. This asks the next question - should static methods also be subclassed? So instead of Class.staticMethod we call obj.constructor.staticMethod? Perhaps. Constructors of course can only come from the defined resource. This seems a little magical but it could work. Would be curious to get feedback from others on this... Alex?

view this post on Zulip Guy Bedford (Feb 29 2024 at 01:32):

Basically do we want to allow for JS-defined resources that the following works:

const x = new MyClass();
witFunction(x);
x.myMethod = () => console.log('new method');
witFunction(x);

where myMethod is a wit resource method being updated to the monkey patched version in the above

view this post on Zulip Jeremy Slater (Feb 29 2024 at 14:38):

And so on the Rust side I assume then that it would still appear as a concrete object of the base/parent resource just with the functionality of the extended/overridden functions? Rather than being just a trait? I guess espectially if the constructor cannot be overridden, it would be cool if 'imported' and mapped resources were generated as traits.
Also, would this allow for 'exported' resources to be extended as well?

view this post on Zulip Alex Crichton (Feb 29 2024 at 16:15):

Oh I won't pretend to know much about JS idioms, so I don't know what's best/expected/etc here

view this post on Zulip Guy Bedford (Feb 29 2024 at 19:57):

one issue with the dynamic dispatch mechanism here is that it will work for methods, but not static methods

view this post on Zulip Guy Bedford (Feb 29 2024 at 19:57):

because we don't have a resource parameter in static methods to pick up the constructor from

view this post on Zulip Guy Bedford (Feb 29 2024 at 19:57):

so subclass static methods and constructors don't get used

view this post on Zulip Guy Bedford (Feb 29 2024 at 19:57):

but perhaps that's not so bad? I'm still not sure how I feel about that inconsistency though

view this post on Zulip Guy Bedford (Feb 29 2024 at 20:00):

posted https://github.com/bytecodealliance/jco/pull/390

This updates the resource method calls for JS-defined resources to use resource.method(arg) instead of ResourceClass.prototype.method.call(resource, arg) allowing more flexibility in dynamic subcla...

view this post on Zulip Jeremy Slater (Feb 29 2024 at 21:01):

Thanks @Guy Bedford !


Last updated: Dec 23 2024 at 12:05 UTC