Files
bs-manager/src/main/services/ipc.service.ts
T

66 lines
2.4 KiB
TypeScript

import { IpcRequest } from "shared/models/ipc";
import { ipcMain } from "electron";
import { Observable } from "rxjs";
import { IpcChannel, IpcCompleteChannel, IpcErrorChannel } from "shared/models/ipc/ipc-response.interface";
import { AppWindow } from "shared/models/window-manager/app-window.model";
import { WindowManagerService } from "./window-manager.service";
import { IpcReplier } from "shared/models/ipc/ipc-request.interface";
import log from "electron-log";
export class IpcService {
private static instance: IpcService;
public static getInstance(): IpcService {
if (!IpcService.instance) { IpcService.instance = new IpcService(); }
return IpcService.instance;
}
private readonly windows: WindowManagerService;
private constructor() {
this.windows = WindowManagerService.getInstance();
}
private getErrorChannel(channel: IpcChannel): IpcErrorChannel {
return `${channel}_error`;
}
private getCompleteChannel(channel: IpcChannel): IpcCompleteChannel {
return `${channel}_complete`;
}
private buildProxyListener<T>(listener: (req: IpcRequest<T>, replier: IpcReplier) => void) {
return (event: Electron.IpcMainEvent, req: IpcRequest<T>) => {
const window = this.windows.getAppWindowFromWebContents(event.sender);
const replier = (data: Observable<unknown>) => this.connectStream(req.responceChannel, window, data);
listener(req, replier);
}
}
public send<T>(channel: IpcChannel, window: AppWindow, response?: T|Error): void{
this.windows.getWindow(window)?.webContents?.send(channel, response);
}
public connectStream(channel: IpcChannel, window: AppWindow, observable: Observable<unknown>): void{
observable.subscribe(data => {
this.send(channel, window, data);
}, error => {
log.error(error);
this.send(this.getErrorChannel(channel), window, error);
}, () => {
this.send(this.getCompleteChannel(channel), window);
});
}
public on<T>(channel: IpcChannel, listener: (req: IpcRequest<T>, replier: IpcReplier) => void): void{
ipcMain.on(channel, this.buildProxyListener(listener));
}
public once<T>(channel: IpcChannel, listener: (req: IpcRequest<T>, replier: IpcReplier) => void): void{
ipcMain.once(channel, this.buildProxyListener(listener));
}
}