Closed WestXu closed 3 years ago
Currently there isn't a way to access the generated wasm manually. Trunk automatically injects that first script
tag into the generated html file.
Instead, you can set window.my_function
and window.MyStruct
from inside WASM by using web_sys
and js_sys::Reflect
Currently there isn't a way to access the generated wasm manually. Trunk automatically injects that first
script
tag into the generated html file.Instead, you can set
window.my_function
andwindow.MyStruct
from inside WASM by usingweb_sys
andjs_sys::Reflect
Is there any snippets your can share on this?
I tried this:
use js_sys::Reflect;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn my_function() -> Result<(), JsValue> {
Ok(())
}
fn main() {
let window = web_sys::window().expect("no global `window` exists");
Reflect::set(&window, &"my_function".into(), &my_function.into())
.expect("Failed reflecting my_function.");
}
But I got:
error[E0277]: the trait bound `wasm_bindgen::JsValue: From<fn() -> Result<(), wasm_bindgen::JsValue> {my_function}>` is not satisfied
--> src/main.rs:17:63
|
17 | Reflect::set(&window, &"my_function".into(), &my_function.into())
| ^^^^ the trait `From<fn() -> Result<(), wasm_bindgen::JsValue> {my_function}>` is not implemented for `wasm_bindgen::JsValue`
|
= help: the following implementations were found:
<wasm_bindgen::JsValue as From<&'a String>>
<wasm_bindgen::JsValue as From<&'a T>>
<wasm_bindgen::JsValue as From<&'a str>>
<wasm_bindgen::JsValue as From<Array>>
and 70 others
= note: required because of the requirements on the impl of `Into<wasm_bindgen::JsValue>` for `fn() -> Result<(), wasm_bindgen::JsValue> {my_function}`
error: aborting due to previous error; 1 warning emitted
Ah yes, you must create a Closure instead and cast it into a JsValue
. There are docs on how to do that here: https://docs.rs/wasm-bindgen/0.2.75/wasm_bindgen/closure/struct.Closure.html
@WestXu looks like you are probably in need of something like this: https://github.com/thedodd/trunk/pull/184 Which allows customization of the app's init script.
Otherwise, you could use the snippets system (https://trunkrs.dev/assets/#js-snippets) and pass along a Rust/WASM function for the JS function to use.
Not 100% sure what your requirements are. Perhaps describing what your ultimate goal is will help folks to find a viable solution.
Ah yes, you must create a Closure instead and cast it into a
JsValue
. There are docs on how to do that here: https://docs.rs/wasm-bindgen/0.2.75/wasm_bindgen/closure/struct.Closure.html
Wow I literally don't understand a single word in this pile of whatever:
Closure::wrap(Box::new(|| {
web_sys::console::log_1(&"inverval elapsed!".into());
}) as Box<dyn FnMut()>).as_ref().unchecked_ref(),;
I eventually go with this:
#[wasm_bindgen]
pub struct Wrapper {}
#[wasm_bindgen]
impl Wrapper {
#[wasm_bindgen]
pub fn my_function(&self) -> Result<(), JsValue> {
Ok(())
}
}
fn main() {
Reflect::set(
&web_sys::window().unwrap(),
&JsValue::from("wrapper"),
&JsValue::from(Wrapper {}),
)
.unwrap();
}
And use it like this:
<script>
window.wrapper.my_function();
</script>
Yea, as long as it works.
@WestXu looks like you are probably in need of something like this: #184 Which allows customization of the app's init script.
This is definitely helpful.
@WestXu yea, until browsers start exposing a more direct WASM ABI with something similar to WASI, the browser ABI will have this rough FFI feel to it. Lots of frameworks offer a slightly nicer pattern on top of this, but ultimately you are passing a boxed fn as a closure.
@WestXu yea, until browsers start exposing a more direct WASM ABI with something similar to WASI, the browser ABI will have this rough FFI feel to it. Lots of frameworks offer a slightly nicer pattern on top of this, but ultimately you are passing a boxed fn as a closure.
I won't blame it though. This project is amazing already. I'm happy with what it is doing now.
Feel free to close it.
Sounds good! Thanks for the discussion and sharing your findings.
Newbie here.
Previously I use wasm-pack doing this:
What's the equivalent
pub fn main()
using trunk?And if this is not the right way to call wasm function from js, what is?