Weiterführung der IPC Verbindung

This commit is contained in:
nwaschk 2025-06-22 15:53:05 +02:00
parent 56c16a6ab8
commit 23c052e98b
4 changed files with 86 additions and 6 deletions

View File

@ -1,11 +1,8 @@
import {app, BrowserWindow} from 'electron';
import path from 'path';
import {getPreloadPath, inDevelopment} from './utils.js';
import {getPreloadPath, getUIPath, inDevelopment} from './utils.js';
import {ipcMain} from 'electron/main';
import {ProdressConnection} from './pdr2com/connection.js';
const APPLICATION_PATH = path.join(app.getAppPath(), '/dist-svelte/index.html');
app.on('ready', async () => {
const mainWindow = new BrowserWindow({
webPreferences: {
@ -15,7 +12,7 @@ app.on('ready', async () => {
if (inDevelopment()) {
mainWindow.loadURL('http://localhost:5123/');
} else {
mainWindow.loadFile(APPLICATION_PATH);
mainWindow.loadFile(getUIPath());
}
ipcMain.handle('ping', () => {

View File

@ -3,3 +3,27 @@ const electron: typeof Electron = require('electron');
electron.contextBridge.exposeInMainWorld('electron', {
ping: () => electron.ipcRenderer.invoke('ping'),
} satisfies Window['electron']);
/**
* adapter for the ipcRenderer invoke function
* - invokes an event to from the frontend to the backend
*@param event
* @returns the response from the backend
*/
function ipcInvoke<Event extends keyof EventPayloadMapping>(event: Event): Promise<EventPayloadMapping[Event]> {
return electron.ipcRenderer.invoke(event);
}
/**
* adapter for the ipcRenderer on function
* - subscribes to an event from the backend
* @param event
*/
function ipcOn<Event extends keyof EventPayloadMapping>(
event: Event,
subscribeFunction: SubscribeFunction<Event>,
): UnsubscribeFunction {
const callback = (_: Electron.IpcRendererEvent, payload: EventPayloadMapping[Event]) => subscribeFunction(payload);
electron.ipcRenderer.on(event, callback);
return () => electron.ipcRenderer.off(event, callback);
}

View File

@ -1,5 +1,6 @@
import path from 'path';
import {app} from 'electron';
import {app, ipcMain, WebContents, WebFrameMain} from 'electron';
import {pathToFileURL} from 'url';
/**
* @returns true, when the application is starded in develpoment mode
@ -34,3 +35,56 @@ export function getPreloadPath(): string {
const preloadScript = '/dist-electron/preload.cjs';
return path.join(app.getAppPath(), inDevelopment() ? '.' : '..', preloadScript);
}
/**
* resolves teh path of the build ui
* @returns the path of the ui
*/
export function getUIPath(): string {
return path.join(app.getAppPath(), '/dist-svelte/index.html');
}
/**
* @todo
* adapter for the ipc handle function
* @param event
* @param handler
*/
export function ipcMainHandle<Event extends keyof EventPayloadMapping>(
event: Event,
handler: () => EventPayloadMapping[Event],
): void {
ipcMain.handle(event, (eventInstance) => {
validateEventFrame(eventInstance.senderFrame);
return handler();
});
}
/**
* @todo
* adapter for the webContents send function
* @param event
* @param webContents
* @param payload
*/
export function ipcWebContentsSend<Event extends keyof EventPayloadMapping>(
event: Event,
webContents: WebContents,
payload: EventPayloadMapping[Event],
): void {
webContents.send(event, payload);
}
/**
* barebones event validation
* @param frame
* @throws when an event gets listend to which is not invoked by the mainframe
*/
export function validateEventFrame(frame: WebFrameMain | null) {
if (inDevelopment() && frame && new URL(frame.url).host === 'localhost:5123') {
return;
}
if (!frame || frame.url !== pathToFileURL(getUIPath()).toString()) {
throw new Error('Malicious Event');
}
}

5
types.d.ts vendored
View File

@ -1,3 +1,5 @@
type EventPayloadMapping = {};
/**
* Extends the Main "Window" Interface
*/
@ -6,3 +8,6 @@ interface Window {
ping: () => Promise<string>;
};
}
type UnsubscribeFunction = () => void;
type SubscribeFunction<Event extends keyof EventPayloadMapping> = (payload: EventPayloadMapping[Event]) => void;