UNPKG

@noxfly/noxus

Version:

Simulate lightweight HTTP-like requests between renderer and main process in Electron applications with MessagePort, with structured and modular design.

74 lines (58 loc) 2.43 kB
/** * @copyright 2025 NoxFly * @license MIT * @author NoxFly */ /** * Centralizes MessagePort storage for renderer communication and handles * push-event delivery back to renderer processes. */ import { Injectable } from 'src/decorators/injectable.decorator'; import { createRendererEventMessage } from 'src/request'; import { Logger } from 'src/utils/logger'; interface RendererChannels { request: Electron.MessageChannelMain; socket: Electron.MessageChannelMain; } @Injectable('singleton') export class NoxSocket { private readonly channels = new Map<number, RendererChannels>(); public register(senderId: number, requestChannel: Electron.MessageChannelMain, socketChannel: Electron.MessageChannelMain): void { this.channels.set(senderId, { request: requestChannel, socket: socketChannel }); } public get(senderId: number): RendererChannels | undefined { return this.channels.get(senderId); } public unregister(senderId: number): void { this.channels.delete(senderId); } public getSenderIds(): number[] { return [...this.channels.keys()]; } public emit<TPayload = unknown>(eventName: string, payload?: TPayload, targetSenderIds?: number[]): number { const normalizedEvent = eventName.trim(); if(normalizedEvent.length === 0) { throw new Error('Renderer event name must be a non-empty string.'); } const recipients = targetSenderIds ?? this.getSenderIds(); let delivered = 0; for(const senderId of recipients) { const channel = this.channels.get(senderId); if(!channel) { Logger.warn(`No message channel found for sender ID: ${senderId} while emitting "${normalizedEvent}".`); continue; } try { channel.socket.port1.postMessage(createRendererEventMessage(normalizedEvent, payload)); delivered++; } catch(error) { Logger.error(`[Noxus] Failed to emit "${normalizedEvent}" to sender ${senderId}.`, error); } } return delivered; } public emitToRenderer<TPayload = unknown>(senderId: number, eventName: string, payload?: TPayload): boolean { return this.emit(eventName, payload, [senderId]) > 0; } }