Check if wasm thread if main thread of web worker?

    let t: String = js_sys::global().to_string().into();
    if t == "[object Window]" {

is there something better than the above ? I'm running into the problem where Window appears to not be defined in webworker threads, and thus I can't even do a dyn_into() without getting a JS runtime error.

more a JavaScript problem, does this help?

No. This is a web_sys problem. Quoting above:

For whatever reason, dyn_into panics because web_sys::Window isn't defined in web worker threads, and web_sys::WorkerGlobalScope isn't defined in the main thread.

1 Like

Yes, window is the global object in page scripts, self is the global object in workers (not just web workers), and globalThis is the global object as defined by Ecmascript, so all environments.

Pretty sure you want this: global in js_sys - Rust

I'm not sure why you would need this though, generally you want to detect features, not environments.

Suppose you want use webworkers. The only two options I see are:

  1. one crate/wasm file for main thread, a different crate/wasm file for webworker thread

or

  1. one crate/wasm file for both, but the wasm detects if it is running in the role of main thread or the role of web worker thread

Or have different entry points, called by different JavaScript, or pass in an option saying which environment you're in, or look at the url you're loaded on, or a bunch more specific options depending on what you're doing.

It sounds like you're trying to avoid writing any JavaScript at all; I don't feel like that's a particularly great time to be had. If nothing else, you are likely to end up with performance problems as we don't have WASM interfaces yet, so the FFI boundary is still pretty expensive.

Do you have an example of this ?

How do you pass the option ?

window.location.href is only accessible on main thread, as web_worker iirc do not have access to window object

This is false. I am fine with JS glue. It's just I don't understand the output of the rustc wasm32-unknown-unknown target well enough to do the things you are suggesting.

When you have a pub fn, you get a method on the wrapped WASM module. Your JavaScript just calls one or the other. AFAIK, the default code doesn't generate anything to call main anyway, how are you currently doing anything?

For example, the rust WASM hello world tutorial demonstrates calling a greet function as simply:

import * as wasm from "hello-wasm-pack";

wasm.greet();

I have one function marked wasm_bindgen(start) ( start - The `wasm-bindgen` Guide ), and I call that function in JS land via "init".

Rust

#[wasm_bindgen(start)]
pub async fn main() {
   do stuff
}

JS

import init, {main} from "./foobar.js";
await init();

====

I did not know you could just do that. Doesn't there need to be a main function ? Some setup of stack / heap before execution ? How is it possible that we just call a function ?

Rust doesn't support global constructors, so all global init is just static memory, natively supported by wasm.

I've actually never seen wasm_bindgen(start), docs say it's new.

I'm guessing it's just emitting a call inline in the wrapping JS, executing on import.

Edit: nope, wasm has a start function it invokes on init. You don't need bindgen at all.

1 Like

I'm really glad we had this debate. Did not realize JS/rust-wasm32 interop was this clean.