-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Comlink uses MessagePorts internally for proxy endpoints and Electron has MessageChannel support via MessageChannelMain now.
By patching the MessagePortMain, it can now be used in main.js as a Comlink endpoint. This seems to work pretty well in my limited testing (example below).
Unfortunately, I've been unable to get proxy working. I was hoping replacing the proxyTransferHandler would be enough but while the MessagePorts are transferable, it seems they are not StructuredCloneable :(
I'm guessing it would be possible to get proxy working if we had access to the transferred MessagePort itself in deserialize. Not sure where to go from here but it seems potentially doable. Thoughts?
// main.js
const proxyTransferHandler = {
canHandle: (val) => !!val && val[comlink.proxyMarker],
serialize(obj) {
const { port1, port2 } = new MessageChannelMain();
console.log(obj, port1, port2);
comlink.expose(obj, patchMessagePort(port1));
return [port2, [port2]];
},
deserialize(port) {
console.log(port);
port.start();
return comlink.wrap(patchMessagePort(port));
},
};
comlink.transferHandlers.set("proxy", proxyTransferHandler);
function patchMessagePort(port) {
if (!port.addEventListener) port.addEventListener = port.on;
if (!port.removeEventListener) port.removeEventListener = port.off;
return port;
}
ipcMain.on("comlink1", ({ ports }) => {
const port = ports[0];
const obj = { log: console.log, inc: (a) => a + 1, callWith1: (cb) => cb(1) };
comlink.expose(obj, patchMessagePort(port));
});
ipcMain.on("comlink2", ({ ports }) => {
const port = ports[0];
const remote = comlink.wrap(patchMessagePort(port));
remote.log("hello from main");
console.log("4+1=", remote.inc(4));
// console.log('cb', remote.callWith2(comlink.proxy((a)=>a+1)))
});
// preload.js
function comlinkExample1() {
const { port1, port2 } = new MessageChannel();
ipcRenderer.postMessage("comlink1", null, [port2]);
const remote = wrap(port1);
remote.log("hello from preload");
console.log("2+1=", remote.inc(2));
// console.log('cb', remote.callWith1(proxy((a)=>a+1)))
}
comlinkExample1();
function comlinkExample2() {
const { port1, port2 } = new MessageChannel();
ipcRenderer.postMessage("comlink2", null, [port2]);
const obj = { log: console.log, inc: (a) => a + 1, callWith2: (cb) => cb(2) };
expose(obj, port1);
}
comlinkExample2();
Metadata
Metadata
Assignees
Labels
No labels