1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00
lens/src/common/ipc-helpers.ts
Roman 547d7f8bbe fixes
Signed-off-by: Roman <ixrock@gmail.com>
2020-07-15 12:52:50 +03:00

68 lines
2.2 KiB
TypeScript

// Inter-protocol communications (main <-> renderer)
// https://www.electronjs.org/docs/api/ipc-main
// https://www.electronjs.org/docs/api/ipc-renderer
import { ipcMain, ipcRenderer, WebContents, webContents } from "electron"
import logger from "../main/logger";
export type IpcChannel = string;
export interface IpcMessageOptions {
timeout?: number;
}
export interface IpcMessageHandler<T extends any[] = any> {
(...args: T): any;
}
export interface IpcBroadcastOpts {
channel: IpcChannel
filter?: (webContent: WebContents) => boolean
}
export function broadcastMessage({ channel, filter }: IpcBroadcastOpts, ...args: any[]) {
if (!filter) {
filter = webContent => webContent.getType() === "window"
}
webContents.getAllWebContents().filter(filter).forEach(webContent => {
logger.info(`[IPC]: broadcasting ${channel} to ${webContent.getType()}=${webContent.id}`);
webContent.send(channel, ...args);
})
}
// fixme: support timeout
export async function invokeMessage<T = any>(channel: IpcChannel, ...args: any[]): Promise<T> {
logger.info(`[IPC]: invoke channel "${channel}"`, { args });
return ipcRenderer.invoke(channel, ...args);
}
// todo: make isomorphic api
export function handleMessage<T extends any[]>(channel: IpcChannel, handler: IpcMessageHandler<T>, options: IpcMessageOptions = {}) {
const { timeout = 0 } = options;
ipcMain.handle(channel, async (event, ...args: T) => {
logger.info(`[IPC]: handle "${channel}"`, { event, args });
return new Promise(async (resolve, reject) => {
let timerId;
if (timeout) {
timerId = setTimeout(() => {
const timeoutError = new Error("[IPC]: response timeout");
reject(timeoutError);
}, timeout);
}
try {
const result = await handler(...args); // todo: maybe exec in separate thread/worker
clearTimeout(timerId);
return result;
} catch (err) {
logger.debug(`[IPC]: handling "${channel}" error`, err);
}
})
})
}
export function handleMessages(messages: Record<string, IpcMessageHandler>, options?: IpcMessageOptions) {
Object.entries(messages).forEach(([channel, handler]) => {
handleMessage(channel, handler, options);
})
}