GoogleChromeLabs / comlink

Comlink makes WebWorkers enjoyable.
Apache License 2.0
11k stars 382 forks source link

Calling `expose` in an async scope? #628

Closed ivancuric closed 1 year ago

ivancuric commented 1 year ago

is there any way of using Comlink.expose inside an async scope?

I am loading some emscripten-compiled WASM inside a worker. It has a loader function inside its JS bundle which resolves a Promise once it's done downloading the WASM and .data file.

I'd love to just proxy the members on the returned module via Comlink, instead of having to wrap them in basically simple proxy wrapper functions which I need to declare beforehand.

Sadly, any sort of await before the expose breaks it.

Eg, this won't work:

// worker.ts
const test = {
  log: () => console.log("hello"),
};

new Promise((res) => setTimeout(() => res("res"), 1)).then(() =>
  expose(test)
);

Weirdly, in this comment it's implied that it should work: https://github.com/GoogleChromeLabs/comlink/issues/549#issuecomment-865135167

surma commented 1 year ago

You missed the most important part: What’s the error message? Calling expose async should be absolutely fine. Can you provide a minimal test case?

ivancuric commented 1 year ago

There is absolutely no error message, however the issue was that I was calling log on the main thread before the promise resolved...

Repro: https://stackblitz.com/edit/vitejs-vite-oqalmd?file=worker.js,main.js&terminal=dev

run with npm run build && npm run preview as the dev mode doesn't work properly.

surma commented 1 year ago

The stackblitz works for me? I see a 1 logged in DevTools.

But yeah, it’s currently the developers responsibility to ensure a proxy doesn’t get used before expose has been called.