1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/common/ipc/ipc.ts
Sebastian Malton 1470103fd4
Add lens:// protocol handling with a routing mechanism (#1949)
- Add lens:// protocol handling with a routing mechanism

- document the methods in an extension guide

- remove handlers when an extension is deactivated or removed

- make sure that the found extension when routing a request is currently enabled (as a backup)

- added documentation about the above behaviour to the guide

- tweaked the naming convention so that it is clearer that the router uses extension names as not IDs (which currently are folder paths)

- Convert the extension API to use an array for registering handlers

- switch design to execute both main and renderer handlers simultaneously, without any overlap checking

- change open to be a dev dep

- improve docs, export types for extensions, skip integration tests

- switch to event emitting renderer being ready

- Add logging and fix renderer:loaded send to main

Signed-off-by: Sebastian Malton <sebastian@malton.name>
2021-02-25 09:32:40 -05:00

86 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Inter-process communications (main <-> renderer)
// https://www.electronjs.org/docs/api/ipc-main
// https://www.electronjs.org/docs/api/ipc-renderer
import { ipcMain, ipcRenderer, webContents, remote } from "electron";
import { toJS } from "mobx";
import logger from "../../main/logger";
import { ClusterFrameInfo, clusterFrameMap } from "../cluster-frames";
const subFramesChannel = "ipc:get-sub-frames";
export function handleRequest(channel: string, listener: (event: Electron.IpcMainInvokeEvent, ...args: any[]) => any) {
ipcMain.handle(channel, listener);
}
export async function requestMain(channel: string, ...args: any[]) {
return ipcRenderer.invoke(channel, ...args);
}
function getSubFrames(): ClusterFrameInfo[] {
return toJS(Array.from(clusterFrameMap.values()), { recurseEverything: true });
}
export async function broadcastMessage(channel: string, ...args: any[]) {
const views = (webContents || remote?.webContents)?.getAllWebContents();
if (!views) return;
if (ipcRenderer) {
ipcRenderer.send(channel, ...args);
} else {
ipcMain.emit(channel, ...args);
}
for (const view of views) {
const type = view.getType();
logger.silly(`[IPC]: broadcasting "${channel}" to ${type}=${view.id}`, { args });
view.send(channel, ...args);
try {
const subFrames: ClusterFrameInfo[] = ipcRenderer
? await requestMain(subFramesChannel)
: getSubFrames();
for (const frameInfo of subFrames) {
view.sendToFrame([frameInfo.processId, frameInfo.frameId], channel, ...args);
}
} catch (error) {
logger.error("[IPC]: failed to send IPC message", { error: String(error) });
}
}
}
export function subscribeToBroadcast(channel: string, listener: (...args: any[]) => any) {
if (ipcRenderer) {
ipcRenderer.on(channel, listener);
} else {
ipcMain.on(channel, listener);
}
return listener;
}
export function unsubscribeFromBroadcast(channel: string, listener: (...args: any[]) => any) {
if (ipcRenderer) {
ipcRenderer.off(channel, listener);
} else {
ipcMain.off(channel, listener);
}
}
export function unsubscribeAllFromBroadcast(channel: string) {
if (ipcRenderer) {
ipcRenderer.removeAllListeners(channel);
} else {
ipcMain.removeAllListeners(channel);
}
}
export function bindBroadcastHandlers() {
handleRequest(subFramesChannel, () => {
return getSubFrames();
});
}