Hi. I have an engine that let my users pre-process data going into a HTTP API. For example if someone POST
an item with firstName
and lastName
they can write a simple snippet to concatenate this into a new fullName
field. I use deno_core to run their code in a sandbox. They run in a context where item
is a globally available variable, which they can read and write to. Something like this:
item.fullName = item.firstName + ' ' + item.lastName;
This works fine, and with this I have support for both JS and TS.
But with wasm I could in theory add support for a bunch of other languages and cool features.
I thought this would be easy, just let people send in a wasm module instead of JS and I pass in the item. But it turns out it is a bit more complicated in wasm world.
Any suggestions on how to make this as pleasant for my users as possible (the people making the modules)?
Everything I've tried so far, of wasmtime, assemblyscript, kotlin, c++ etc. is not very language agnostic, it seems there is not even an agreement on what a string should look like.
This made me look into compoment model and WIT. But I'm not sure it does what I really want.
WIT seems like what I want, but the truth is that host system doesn't actually know the item type, it just passes JSON. This made me think I could let end users bundle in JSON parser/writer in their wasm and do JSON in and out. But even that won't work if a string isn't common.
Perhaps WIT with just string in/out? And shouldn't compoment model without WIT define a string?
Using very new features is not a problem, it is better for users to wait for proper support in their language than some home-made solution.
Any suggestions? I'm a bit lost :sweat_smile:
wit and the component model aren't distinct topics - the component model defines the binary and text encoding for components, which includes component types (as opposed to the core wasm types) for string, records, variants, resources and so on. components have a s-expression wat representation just like core wasm, but that representation isnt really human-friendly for reading or writing, so the wit syntax is an alternative representation of component types that is meant to be easily read and written
strings are a primitive value type in the component type system https://github.com/WebAssembly/component-model/blob/main/design/mvp/Binary.md#type-definitions
if the host system passes unstructured json, then you should just use a component model string
to pass that to/from your components
if the json is actually structured and can be described using the wit concepts of array, record, variant etc, then you could write that structure down in a .wit, and have the host system parse it into that structure, and pass the structure to/from components.
if you havent yet read https://component-model.bytecodealliance.org/ it may help, but you are welcome to ask more questions here too
Thank you for the answer.
I was a bit put off by all the code generation (wit-bindgen and jco), and I had issues running wit-bindgen because of required "--with" argument. Found an issue on that on GH, installing from main branch fixed it.
I'm going to have some helper methods on host side, such as "log" and "get" (simplified fetch). So I think WIT would be a perfect fit.
I did a test now where I started with a plain rust lib, wrote my own WIT, generated with wit-bindgen and built with cargo-component.
Then I generated JS with jco from the wasm file, wrote a simple test script and ran that in node.
It all worked as expected.
I'm not going to run in node, my host is rust, I just needed some platform where it was easy to test.
jco
created module imports for my host functions so that didn't go as expected, but could be I did something wrong or it won't work like that in rust.
if your host is in rust then you should use wasmtime to execute the component created by jco componentize
for host bindings generation, you'll use wasmtime::component::bindgen!
https://docs.rs/wasmtime/latest/wasmtime/component/bindgen_examples/index.html
Thank you. I've been playing around with this, but I'm struggling to return strings.
In WIT:
export yo: func() -> string;
In code:
fn yo() -> String { "yo".to_string() }
But when I consume the wasm from this in a rust runtime I get:
Error: component imports instance
wasi:cli/environment@0.2.0
, but a matching implementation > was not found in the linkerCaused by:
0: instance exportget-environment
has the wrong type
1: function implementation is missing
https://docs.rs/wasmtime-wasi/latest/wasmtime_wasi/fn.add_to_linker_sync.html
Last updated: Dec 23 2024 at 13:07 UTC