Open alamminsalo opened 10 months ago
AFAIK audio worklets support dynamic imports for a while now. Which browser are you experiencing this on?
Chrome and Firefox both throw error of "TypeError: import() is disallowed on WorkletGlobalScope." for the following initialization code (in AudioWorkletProcessor).
const wasm = await import(`../wasm/default?t=${Date.now()}`);
await wasm.default(bytes);
Where ../wasm/default.js
is the generated js file with __wbg_init etc.
Ah right, I looked it up again, static imports are supported but not dynamic ones.
I think in general we should not be using any global variables in the no-modules target, but I didn't look into how that could be done, but AFAIK it should be possible. We were also discussing before to completely remove the no-modules target in #3355, so that would pose a problem for you.
Generally speaking though, it is considered a bad idea to use wasm-bindgen
to produce modules for a plugin system, because the JS bindings can do whatever they want. Usually the solution is to develop a proper plugin API that plugins can use so they are properly sandboxed.
just now had a related problem in which the wasm object is re-used if, on a single-page web app, you navigate away from the page with wasm and back. a quick partial solution would be to add a way to destroy the wasm object held in the generated module e.g.,
export function __wbg_reset(){
wasm = null
}
that way next time you run the __wbg_init you'll get a brand new wasm object
A workaround is in #3818
Motivation
Lets say a user wants to create an audio plugin system using webassembly which uses a common interface that a plugin must implement in order to load. Currently, when loading multiple plugins using an AudioWorkletProcessor script, 'wasm' variable is set on first call on __wbg_init. This means subsequent loading of next plugin leads to using the already set 'wasm' variable, making it bit challenging to implement such system. Note that AudioWorkletProcessor scripts cannot use dynamic imports, making it hard to get fresh module by for example setting url parameters to bypass cache.
I fixed the problem by wrapping the generated .js file inside a function that returns __wbg_init, initSync and defined Rust types. However, this means I need to redo the modification the module each time it is generated.
Proposed Solution
A flag for web target that allows to load initialize multiple different instances of wasm blobs using the same module. My take was to wrap it inside a function but maybe there is another alternative approach that makes it possible to not break web target api.
Alternative Solutions
In case there is a simple fix that can be implemented using the current codebase, let me know!