feat(electron): expose electron apis to web worker (#9441)

fix AF-2044
This commit is contained in:
pengx17
2024-12-31 03:17:02 +00:00
parent 6883cc2ded
commit 887732179e
8 changed files with 165 additions and 22 deletions

View File

@@ -2,12 +2,11 @@ import '@sentry/electron/preload';
import { contextBridge } from 'electron';
import { appInfo, getElectronAPIs } from './electron-api';
import { apis, appInfo, events, requestWebWorkerPort } from './electron-api';
import { sharedStorage } from './shared-storage';
const { apis, events } = getElectronAPIs();
contextBridge.exposeInMainWorld('__appInfo', appInfo);
contextBridge.exposeInMainWorld('__apis', apis);
contextBridge.exposeInMainWorld('__events', events);
contextBridge.exposeInMainWorld('__sharedStorage', sharedStorage);
contextBridge.exposeInMainWorld('__requestWebWorkerPort', requestWebWorkerPort);

View File

@@ -13,22 +13,6 @@ import {
type RendererToHelper,
} from '../shared/type';
export function getElectronAPIs() {
const mainAPIs = getMainAPIs();
const helperAPIs = getHelperAPIs();
return {
apis: {
...mainAPIs.apis,
...helperAPIs.apis,
},
events: {
...mainAPIs.events,
...helperAPIs.events,
},
};
}
type Schema =
| 'affine'
| 'affine-canary'
@@ -248,3 +232,60 @@ function getHelperAPIs() {
return { apis: {}, events: {} };
}
}
const mainAPIs = getMainAPIs();
const helperAPIs = getHelperAPIs();
export const apis = {
...mainAPIs.apis,
...helperAPIs.apis,
};
export const events = {
...mainAPIs.events,
...helperAPIs.events,
};
// Create MessagePort that can be used by web workers
export function requestWebWorkerPort() {
const ch = new MessageChannel();
const localPort = ch.port1;
const remotePort = ch.port2;
// todo: should be able to let the web worker use the electron APIs directly for better performance
const flattenedAPIs = Object.entries(apis).flatMap(([namespace, api]) => {
return Object.entries(api as any).map(([method, fn]) => [
`${namespace}:${method}`,
fn,
]);
});
AsyncCall(Object.fromEntries(flattenedAPIs), {
channel: createMessagePortChannel(localPort),
log: false,
});
const cleanup = () => {
remotePort.close();
localPort.close();
};
const portId = crypto.randomUUID();
setTimeout(() => {
window.postMessage(
{
type: 'electron:request-api-port',
portId,
ports: [remotePort],
},
'*',
[remotePort]
);
});
localPort.start();
return { portId, cleanup };
}