Description
Motivation
I'm embedding a Bevy game in a Vue app. i'd like for them to be able to communicate. since there's no apparent way for a rust function called from JS to interact with the ECS (or, i haven't found it) i'd like to be able to call a JS function from rust which returns a queue of recent events.
The function I want to call will be in a .vue file (and, even if i put it in a .ts file, i can't figure out how to get #[wasm_bindgen(module=...)]
to play nice with Vite) which makes it impossible to import. So i'd like to be able to provide it at runtime, presumably while calling __wbg_init
as a bonus, this would make it always possible to link to a function with any bundler.
Proposed Solution
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(dynamic)]
fn foo() -> u32;
}
import init, {main} from "my-wasm-whatever";
function whatever() {
return 1337;
}
init(undefined, {foo: whatever}).then(main);
modify __wbg_init to something like
async function __wbg_init(input, import_overrides = undefined) {
if (wasm !== undefined) return wasm;
if (typeof input === 'undefined') {
input = "/assets/my_wasm_whatever.wasm"
}
const imports = __wbg_get_imports();
if (import_overrides !== undefined){ // \
Object.assign(imports, import_overrides); // )- the added part
} // /
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
input = fetch(input);
}
__wbg_init_memory(imports);
const { instance, module } = await __wbg_load(await input, imports);
return __wbg_finalize_init(instance, module);
}
Alternatives
If this is already possible i couldn't find it in the documentation.
Activity
thy486 commentedon Nov 13, 2023
It's my idea. declare
foo
function in#[wasm_bindgen]
extern,wasm_bindgen
expose a function for importfoo
function (likeset_foo_ns
):It will print
1
on console.khoover commentedon Jan 21, 2024
An alternative would be to define a wrapper that lives in a .ts/.js file and calls the Vue function itself, and then import the wrapper into WASM.
stefnotch commentedon Feb 2, 2024
I believe the simplest way is
myJsValue.unchecked_into::<MyClass>();
The documentation could definitely be improved.
ghost commentedon Mar 17, 2024
@stefnotch I think this is a good way. I'm just commenting an example I created when adding dynamic import to another project. (as it wasn't obvious to me on how to fully complete it)
I like it better than
inline_js=
as I think it's likely this will work more frequently with different rust frameworks. This is becauseinline_js
bindings require the creator of the framework to explicitly support them.