UNPKG

netkitty

Version:
100 lines (85 loc) 3.29 kB
import EventEmitter from 'events' import {MessageConnection} from 'socket-ipc' import {PipeMessage, PipeMessageType} from './PipeMessage' import {PipeMessageHandler} from './PipeMessageHandler' import {SocketDownError} from '../../errors/SocketDownError' export interface IPipeClientSocketOptions { id: string connection: MessageConnection actions: Record<string, (...args: any[]) => Promise<any>> } export class PipeClientSocket extends EventEmitter { readonly #id: string readonly #connection: MessageConnection #connected: boolean protected readonly pipeMessageHandler: PipeMessageHandler public readonly actions: Record<string, (...args: any[]) => Promise<any>> = {} /** * ClientId */ public get id(): string { return this.#id } /** * Is client socket connected */ public get connected(): boolean { return this.#connected } constructor(options: IPipeClientSocketOptions) { super() this.#id = options.id this.#connection = options.connection this.actions = options.actions ? options.actions : {} this.#connected = true this.#connection .on('error', (err: Error): boolean => this.emit('error', err)) .once('close', (): void => { this.#connected = false this.emit('disconnect') this.removeAllListeners() }) this.pipeMessageHandler = new PipeMessageHandler(this, this.#connection) } /** * Invoke client side action * @param act * @param args */ public async invoke(act: string, ...args: any[]): Promise<any> { return new Promise((resolve, reject): void => { const pipeMessage: PipeMessage = new PipeMessage() pipeMessage.type = PipeMessageType.REQUEST pipeMessage.payload = [act, ...args] this.once(pipeMessage.messageId, (resultOrError: any | Error): void => resultOrError instanceof Error ? reject(resultOrError) : resolve(resultOrError)) if (!this.connected) { this.removeAllListeners(pipeMessage.messageId) return reject(new SocketDownError('Socket is down')) } this.#connection.send(pipeMessage.serialize()) }) } /** * Notify event to pipe client * @param event * @param args */ public notify(event: string, ...args: any[]): void { const pipeMessage: PipeMessage = new PipeMessage() pipeMessage.type = PipeMessageType.EVENT pipeMessage.payload = [event, ...args] if (this.connected) this.#connection.send(pipeMessage.serialize()) } public on(eventName: 'disconnect', listener: () => void): this public on(eventName: string, listener: (...args: any) => void): this public on(eventName: string, listener: (...args: any) => void): this { super.on(eventName, listener) return this } public once(eventName: 'disconnect', listener: () => void): this public once(eventName: string, listener: (...args: any) => void): this public once(eventName: string, listener: (...args: any) => void): this { super.once(eventName, listener) return this } }