mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-13 21:05:19 +00:00
feat(core): new worker workspace engine (#9257)
This commit is contained in:
@@ -2,11 +2,13 @@ import '@sentry/electron/preload';
|
||||
|
||||
import { contextBridge } from 'electron';
|
||||
|
||||
import { apis, appInfo, events, requestWebWorkerPort } from './electron-api';
|
||||
import { apis, appInfo, events } from './electron-api';
|
||||
import { sharedStorage } from './shared-storage';
|
||||
import { listenWorkerApis } from './worker';
|
||||
|
||||
contextBridge.exposeInMainWorld('__appInfo', appInfo);
|
||||
contextBridge.exposeInMainWorld('__apis', apis);
|
||||
contextBridge.exposeInMainWorld('__events', events);
|
||||
contextBridge.exposeInMainWorld('__sharedStorage', sharedStorage);
|
||||
contextBridge.exposeInMainWorld('__requestWebWorkerPort', requestWebWorkerPort);
|
||||
|
||||
listenWorkerApis();
|
||||
|
||||
@@ -248,53 +248,3 @@ export const events = {
|
||||
...mainAPIs.events,
|
||||
...helperAPIs.events,
|
||||
};
|
||||
|
||||
/**
|
||||
* Create MessagePort that can be used by web workers
|
||||
*
|
||||
* !!!
|
||||
* SHOULD ONLY BE USED IN RENDERER PROCESS
|
||||
* !!!
|
||||
*/
|
||||
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(() => {
|
||||
// @ts-expect-error this function should only be evaluated in the renderer process
|
||||
window.postMessage(
|
||||
{
|
||||
type: 'electron:request-api-port',
|
||||
portId,
|
||||
ports: [remotePort],
|
||||
},
|
||||
'*',
|
||||
[remotePort]
|
||||
);
|
||||
});
|
||||
|
||||
localPort.start();
|
||||
|
||||
return { portId, cleanup };
|
||||
}
|
||||
|
||||
33
packages/frontend/apps/electron/src/preload/worker.ts
Normal file
33
packages/frontend/apps/electron/src/preload/worker.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { ipcRenderer } from 'electron';
|
||||
|
||||
export function listenWorkerApis() {
|
||||
ipcRenderer.on('worker-connect', (ev, data) => {
|
||||
const portForRenderer = ev.ports[0];
|
||||
|
||||
// @ts-expect-error this function should only be evaluated in the renderer process
|
||||
if (document.readyState === 'complete') {
|
||||
// @ts-expect-error this function should only be evaluated in the renderer process
|
||||
window.postMessage(
|
||||
{
|
||||
type: 'electron:worker-connect',
|
||||
portId: data.portId,
|
||||
},
|
||||
'*',
|
||||
[portForRenderer]
|
||||
);
|
||||
} else {
|
||||
// @ts-expect-error this function should only be evaluated in the renderer process
|
||||
window.addEventListener('load', () => {
|
||||
// @ts-expect-error this function should only be evaluated in the renderer process
|
||||
window.postMessage(
|
||||
{
|
||||
type: 'electron:worker-connect',
|
||||
portId: data.portId,
|
||||
},
|
||||
'*',
|
||||
[portForRenderer]
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user