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.
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?
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
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.
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?
Also is it possible to add modules to the API via JavaScript? Or do these all need to be backed by Rust code?
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.
Thanks.
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
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).
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.
I think that addresses my question. I want to define some modules in JS and load it as part of registration.
Those links are perfect.
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.
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?
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.
Thanks that is what I thought, but wanted to check my understanding.
Damian Reeves has marked this topic as resolved.
Last updated: Nov 22 2024 at 16:03 UTC