UNPKG

@noxfly/noxus

Version:

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

111 lines (89 loc) 2.93 kB
/** * @copyright 2025 NoxFly * @license MIT * @author NoxFly */ /** * Lightweight event registry to help renderer processes subscribe to * push messages sent by the main process through Noxus. */ import { IRendererEventMessage, isRendererEventMessage } from 'src/request'; export type RendererEventHandler<TPayload = unknown> = (payload: TPayload) => void; export interface RendererEventSubscription { unsubscribe(): void; } export class RendererEventRegistry { private readonly listeners = new Map<string, Set<RendererEventHandler>>(); /** * */ public subscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): RendererEventSubscription { const normalizedEventName = eventName.trim(); if(normalizedEventName.length === 0) { throw new Error('Renderer event name must be a non-empty string.'); } const handlers = this.listeners.get(normalizedEventName) ?? new Set<RendererEventHandler>(); handlers.add(handler as RendererEventHandler); this.listeners.set(normalizedEventName, handlers); return { unsubscribe: () => this.unsubscribe(normalizedEventName, handler as RendererEventHandler), }; } /** * */ public unsubscribe<TPayload>(eventName: string, handler: RendererEventHandler<TPayload>): void { const handlers = this.listeners.get(eventName); if(!handlers) { return; } handlers.delete(handler as RendererEventHandler); if(handlers.size === 0) { this.listeners.delete(eventName); } } /** * */ public clear(eventName?: string): void { if(eventName) { this.listeners.delete(eventName); return; } this.listeners.clear(); } /** * */ public dispatch<TPayload>(message: IRendererEventMessage<TPayload>): void { const handlers = this.listeners.get(message.event); if(!handlers || handlers.size === 0) { return; } handlers.forEach((handler) => { try { handler(message.payload as TPayload); } catch(error) { console.error(`[Noxus] Renderer event handler for "${message.event}" threw an error.`, error); } }); } /** * */ public tryDispatchFromMessageEvent(event: MessageEvent): boolean { if(!isRendererEventMessage(event.data)) { return false; } this.dispatch(event.data); return true; } /** * */ public hasHandlers(eventName: string): boolean { const handlers = this.listeners.get(eventName); return !!handlers && handlers.size > 0; } }