Stream: javy

Topic: ✔ Adding custom "builtin" modules and plugin model


view this post on Zulip Damian Reeves (May 01 2024 at 13:58):

I'm sure this is just something I'm not understanding, but how can I add my own builtin standard library and not incur the cost of the size of that library for each of my plugins/extensions built with javy that use that library?

I think I read this is what shopify did in their original usecase, but I am unclear on the steps I need to achieve to accomplish this.

I have started the process of having my own forked CLI, since I want this to be functionality in my own toolchain (in case that is a relevant step), but it seems like the onus for providing the implementation of my builtins has to occur at runtime.

Hoping someone can steer me in the right direction.

view this post on Zulip Jeff Charles (May 01 2024 at 15:43):

how can I add my own builtin standard library and not incur the cost of the size of that library for each of my plugins/extensions built with javy that use that library?

Do you mean using Javy's dynamic linking support? That is, having multiple Wasm modules produced by Javy dynamically link against a single runtime Wasm module such that the Wasm modules produced by Javy are much smaller.

Also have you read over the documentation for extending Javy?

JS to WebAssembly toolchain. Contribute to bytecodealliance/javy development by creating an account on GitHub.
JS to WebAssembly toolchain. Contribute to bytecodealliance/javy development by creating an account on GitHub.

view this post on Zulip Damian Reeves (May 01 2024 at 18:34):

Jeff Charles said:

Do you mean using Javy's dynamic linking support? That is, having multiple Wasm modules produced by Javy dynamically link against a single runtime Wasm module such that the Wasm modules produced by Javy are much smaller.

Yup that's it. And you are right, I've focused on the extending.md doc and not that section of the ReadMe

view this post on Zulip Jeff Charles (May 01 2024 at 19:19):

The direct answer is, if you also fork the core crate and register your APIs in runtime.rs, those APIs will be present in the Wasm file emitted from building the core crate as a Wasm cdylib. That Wasm cdylib module is what the modules produced by Javy will be trying to link against.

For some context, at a high level, the modules produced by running javy compile -d (that is, producing a module that uses dynamic linking) just contain QuickJS bytecode and a minimal set of Wasm instructions to trigger an evaluation of that QuickJS bytecode.

JS to WebAssembly toolchain. Contribute to bytecodealliance/javy development by creating an account on GitHub.

view this post on Zulip Damian Reeves (May 01 2024 at 19:22):

So if I were to go ahead and add my fork of core and add my APIs and then have a fork of the cli, my cli should produce the correct Wasm binaries when I do the -d option?

view this post on Zulip Damian Reeves (May 01 2024 at 19:22):

Also is it possible to add modules to the API via JavaScript? Or do these all need to be backed by Rust code?

view this post on Zulip Jeff Charles (May 01 2024 at 19:32):

So if I were to go ahead and add my fork of core and add my APIs and then have a fork of the cli, my cli should produce the correct Wasm binaries when I do the -d option?

Yes but you'll need to link those modules against the cdylib Wasm module produced from compiling your core crate (as opposed to the javy-quickjs_provider.wasm file that's available as a release asset) when instantiating those modules.

view this post on Zulip Damian Reeves (May 01 2024 at 19:38):

Thanks.

view this post on Zulip Damian Reeves (May 01 2024 at 19:39):

What about extending via JS, is that a possibility? I'm actually thinking of mixing a combination of Rust code plus some JS based modules

view this post on Zulip Jeff Charles (May 01 2024 at 19:40):

Also is it possible to add modules to the API via JavaScript? Or do these all need to be backed by Rust code?

I'm not entirely sure I completely understand what you're asking. You would need to write _some_ Rust to add the APIs. But the implementation for the register function could just invoke context.eval_global in Rust to run JS code in the global context (we do this to add some text encoding and stream I/O APIs).

view this post on Zulip Jeff Charles (May 01 2024 at 19:41):

What about extending via JS, is that a possibility? I'm actually thinking of mixing a combination of Rust code plus some JS based modules

Take a look at https://github.com/bytecodealliance/javy/blob/main/crates/apis/src/stream_io/mod.rs and https://github.com/bytecodealliance/javy/blob/main/crates/apis/src/text_encoding/mod.rs for a couple examples where we have mixed Rust and JS implementations.

JS to WebAssembly toolchain. Contribute to bytecodealliance/javy development by creating an account on GitHub.
JS to WebAssembly toolchain. Contribute to bytecodealliance/javy development by creating an account on GitHub.

view this post on Zulip Damian Reeves (May 01 2024 at 19:41):

I think that addresses my question. I want to define some modules in JS and load it as part of registration.

view this post on Zulip Damian Reeves (May 01 2024 at 19:43):

Those links are perfect.

view this post on Zulip Jeff Charles (May 01 2024 at 19:45):

One other thing to keep in mind is we're considering on merging a PR switching our quickjs bindings to use rquickjs so that would likely change the APIs you would call for API definitions. The rquickjs bindings are quite a bit more ergonomic. But there shouldn't be any other architectural changes that would affect what you're doing.

High level bindings to the quickjs javascript engine - DelSkayn/rquickjs

view this post on Zulip Damian Reeves (May 01 2024 at 19:48):

Thanks for the info and heads up. I'm glad to know a more modern quickjs version is being linked in, as I was considering whether I should use javy or directly build my own javy like thing ontop of one of these more modern quickjs crates.

Hopefully last question: Can I add top level exports for this module that will be my equivalent of the quick_js_provider.wasm, or must this module also subscribe to the WASI command pattern?

view this post on Zulip Jeff Charles (May 01 2024 at 19:56):

If it's in the lib.rs file for core, they're not subject to the command pattern. It's just if you add the exports to main.rs which would be used in a static linking context (that is, where the runtime is included in the module produced by javy compile), then it would be subject to the command pattern.

view this post on Zulip Damian Reeves (May 01 2024 at 19:57):

Thanks that is what I thought, but wanted to check my understanding.

view this post on Zulip Notification Bot (May 02 2024 at 11:42):

Damian Reeves has marked this topic as resolved.


Last updated: Dec 23 2024 at 12:05 UTC