This question relates to the Comlink WebWorker library and specifically to the usage of Comlink.proxy
. Consider the following situation:
worker.ts
import * as Comlink from 'comlink';
export class Foo { ... }
export class Bar {
makeFoo () {
return Comlink.proxy(new Foo);
}
useFoo (foo: Foo) { ... }
}
Comlink.expose(Bar);
main.ts
import type { Foo, Bar } from './worker.ts';
import * as Comlink from 'comlink';
const worker = new Worker('./worker.ts');
const bar: Comlink.Remote<Bar> = await new Comlink.wrap(worker);
const foo: Comlink.Remote<Foo> = await bar.makeFoo();
await bar.useFoo(foo);
Up until the last line there, everything works as expected: foo
and bar
on the main thread are proxies to Foo
and Bar
instances that live on the worker, respectively. The last line (await bar.useFoo(foo)
) is where issues arise; the intention is for the proxy to get automatically unwrapped and to receive the unproxied Foo
instance back on the worker side, but as-written this instead results in an error (obj is undefined
).
Is there a way to achieve this within the bounds of what Comlink offers?
The alternative would be to never expose a proxied Foo
to the main thread at all and instead rely on a layer of indirection, by assigning and returning unique IDs/handles to individual Foo
instances created via makeFoo
and passing those to useFoo
. The main disadvantage of such an approach is the obvious complexity increase, especially as Foo
's public API grows:
// with a proxy:
await foo.method1(arg1, arg2);
await foo.method2(arg1);
// with a handle:
await bar.fooMethod1(fooHandle, arg1, arg2);
await bar.fooMethod2(fooHandle, arg1);