@nsshunt/stsmessaging 1.0.37 → 1.0.39

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"stsmessaging.mjs","sources":["../src/messagingManager.ts","../src/redisMessageHandler.ts","../src/ipcMessageHandler.ts","../src/ipcMessageHandlerPair.ts"],"sourcesContent":["/* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF\nimport { ISTSLogger, JSONObject } from '@nsshunt/stsutils'\n\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes'\n\nexport interface MessagingManagerOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n groups: string[]\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => void\n ProcessRequestMessage: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>\n ProcessResponseMessage?: (reesponses: Record<string, IIPCMessageProcessorIPCPayload>, options: any) => Promise<boolean>\n messageReceiverStart: (options: any) => void\n messageReceiverStop: (options: any) => void\n}\n/**\n * todo\n * @typedef {Object} options - todo\n * @property {boolean} [wssServer=false] - Create a web socket server on this worker instance\n */\nexport class MessagingManager {\n #id: string;\n #options: MessagingManagerOptions;\n #inflightMessages: Record<string, IIPCMessageProcessorWorkerRecord> = { };\n #messageHeader: string;\n\n constructor(options: MessagingManagerOptions) {\n this.#id = uuidv4();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;\n }\n\n get id() {\n return this.#id;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ReceivedMessageFromMaster(msg: any) {\n // Override in subclass if required\n }\n\n SendMessageNoResponse = (payload: JSONObject, options?: any): void => {\n this.#SendMessageNoResponse(payload, options);\n };\n\n SendMessage = (payload: JSONObject, options?: any): Promise<JSONObject> => {\n return new Promise((resolve, reject) => {\n this.#SendMessage(payload, options,\n (payload: IIPCMessageProcessorIPCPayload) => {\n resolve(payload.responsePayload);\n },\n (payload: IIPCMessageProcessorIPCPayload) => {\n reject(payload.requestPayload);\n })\n })\n }\n\n #SendMessageNoResponse = (payload: JSONObject, options: any): void => {\n const messageId: string = uuidv4();\n const requestPayload: IIPCMessageProcessorIPCPayload = {\n header: this.#messageHeader,\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload: payload,\n responsePayload: { },\n pid: process.pid.toString(),\n messageType: 'REQUEST_NO_RESPONSE'\n }\n\n //console.log(chalk.blue(`#SendMessageNoResponse: [${JSON.stringify(requestPayload)}]`))\n this.#options.messageSender(requestPayload, options);\n }\n\n #SendMessage = (payload: JSONObject, options: any,\n callBack: (payload: IIPCMessageProcessorIPCPayload) => void, \n errorCallBack: (payload: IIPCMessageProcessorIPCPayload) => void\n ): void => {\n const messageId: string = uuidv4();\n const requestPayload: IIPCMessageProcessorIPCPayload = {\n header: this.#messageHeader,\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload: payload,\n responsePayload: { },\n pid: process.pid.toString(),\n messageType: 'REQUEST'\n }\n const messageRecord = {\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload,\n responses: { }, // record\n startTime: performance.now(),\n endTime: 0,\n timeout: setTimeout(() => {\n //this.#LogDebugMessage(chalk.red(`Timeout has occurred after: [${this.#options.requestResponseMessageTimeout}]ms with message id: [${messageRecord.messageId}]. Details: [${JSON.stringify(this.#inflightMessages[messageRecord.messageId].requestPayload)}]`));\n setTimeout(() => {\n delete this.#inflightMessages[messageRecord.messageId];\n }, 0).unref();\n errorCallBack(requestPayload);\n }, this.#options.requestResponseMessageTimeout).unref(),// max message timeout allowed\n callBack,\n errorCallBack\n }\n this.#inflightMessages[messageRecord.messageId] = messageRecord;\n //this.#LogDebugMessage(chalk.cyan(`sending: [${JSON.stringify(requestPayload)}]`));\n //console.log(chalk.blue(`#SendMessage: [${JSON.stringify(requestPayload)}]`))\n\n this.#options.messageSender(requestPayload, options);\n }\n\n #ProcessMessage = async (msg: any, options: any): Promise<void> => {\n if (msg.header && msg.header.localeCompare(this.#messageHeader) === 0) {\n const message = (msg as IIPCMessageProcessorIPCPayload);\n if (this.#inflightMessages[message.messageId]) {\n const inFlightMessageRecord: IIPCMessageProcessorWorkerRecord = this.#inflightMessages[message.messageId];\n inFlightMessageRecord.responses[message.senderId ] = { ...message };\n let completed = true; // Defaults to true\n if (this.#options.ProcessResponseMessage) {\n completed = await this.#options.ProcessResponseMessage(inFlightMessageRecord.responses, options);\n if (completed) {\n inFlightMessageRecord.endTime = performance.now();\n clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);\n inFlightMessageRecord.callBack({\n responsePayload: Object.values(inFlightMessageRecord.responses).map(r => r.responsePayload)\n } as any, options) // \n delete this.#inflightMessages[message.messageId];\n }\n } else if (completed) {\n inFlightMessageRecord.endTime = performance.now();\n clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);\n inFlightMessageRecord.callBack(message, options) // inFlightMessageRecord.responses\n //@@inFlightMessageRecord.callBack(Object.values(inFlightMessageRecord.responses), options) // \n delete this.#inflightMessages[message.messageId];\n } else {\n //console.log(chalk.grey(`#ProcessMessage:5`));\n }\n } else {\n //throw new Error(`Could not find Request/Response message with id: [${message.messageId}]`); //@@\n }\n }\n }\n\n Start = (options?: any) => {\n this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;\n this.#options.messageReceiverStart(options);\n }\n\n Stop = (options?: any) => {\n // Kill in-flight messages\n this.#options.messageReceiverStop(options);\n\n for (const [, iPCMessageProcessorWorkerRecord] of Object.entries(this.#inflightMessages)) {\n if (iPCMessageProcessorWorkerRecord.timeout) {\n clearTimeout(iPCMessageProcessorWorkerRecord.timeout);\n }\n }\n this.#inflightMessages = { };\n }\n\n // Process a message recieved from a worker\n ProcessMessage = async (msg: any, options: any) => {\n if (msg.header) {\n const checkName = `__STS__${this.#options.namespace}__`; //@@ this is a broadcast becuase the unique uuid is not part of the header test\n if ((msg.header as string).includes(checkName)) {\n const message = (msg as IIPCMessageProcessorIPCPayload);\n if (msg.messageType.localeCompare('REQUEST') === 0 || msg.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n let processMessage = true;\n if (message.requestPayload.args && message.requestPayload.args.length > 0 && message.requestPayload.args[0].group) {\n const group = message.requestPayload.args[0].group;\n processMessage = (this.#options.groups.indexOf(group) === -1) ? false : true;\n }\n if (processMessage) {\n if (msg.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#options.ProcessRequestMessage(message, options);\n } else {\n message.responsePayload = await this.#options.ProcessRequestMessage(message, options);\n message.senderId = this.#id;\n message.messageType = 'RESPONSE';\n this.#options.messageSender(message, options);\n }\n }\n } else {\n // Received a response (to my request)\n this.#ProcessMessage(msg, options);\n }\n }\n }\n }\n}\n","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\nimport { Redis, RedisOptions } from \"ioredis\";\n\nimport chalk from 'chalk';\n\nconst REQUEST_CHANNEL = '__STS__SVC_stsappframework_request'\nconst RESPONSE_CHANNEL = '__STS__SVC_stsappframework_response'\n\nexport interface IRedisAdminManagerOptions {\n redisUrl: string\n logger: ISTSLogger\n role: 'SERVER' | 'CLIENT'\n namespace: string\n groups: string[]\n ignoreEvents?: string[]\n extraData?: JSONObject\n}\n\nexport interface IClientRecord {\n id: string\n clientConnected: Date\n pingCount: number\n timeout: NodeJS.Timeout\n groups: string[]\n extraData?: JSONObject\n}\n\nexport interface IEventRecord {\n event: string\n callback: any,\n ctx?: any\n}\n\nexport interface IPingData {\n id: string\n groups: string[]\n extraData?: JSONObject\n}\n\nexport class RedisMessageHandler extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IRedisAdminManagerOptions;\n #events: Record<string, IEventRecord> = { };\n #requestChannel: string;\n #responseChannel: string;\n #redisSubscriber: Redis;\n #redisPublisher: Redis;\n #clients: Record<string, IClientRecord> = { };\n #pingTimeout: NodeJS.Timeout | null = null;\n\n constructor(options: IRedisAdminManagerOptions) {\n super();\n this.#options = options;\n\n this.#requestChannel = REQUEST_CHANNEL\n this.#responseChannel = RESPONSE_CHANNEL\n\n const redisOptions: RedisOptions = {\n showFriendlyErrorStack: true,\n maxRetriesPerRequest: 20\n }\n\n this.#redisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#redisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#redisSubscriber.on(\"error\", (error: Error) => {\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisSubscriber on error): [${error}]`));\n });\n\n this.#redisPublisher.on(\"error\", (error: Error) => {\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisPublisher on error): [${error}]`));\n });\n\n this.#redisSubscriber.subscribe(this.#requestChannel, this.#responseChannel, (error, count) => {\n if (error) {\n // Just like other commands, subscribe() can fail for some reasons, // ex network issues.\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error - Failed to subscribe: [${error}]`));\n } else {\n // `count` represents the number of channels this client is currently subscribed to.\n this.#LogInfo(chalk.white(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Subscribed successfully! This client is currently subscribed to ${count} channels.`));\n }\n });\n\n this.SetupPrimary();\n\n /*\n const ping = () => {\n this.#pingTimeout = setTimeout(() => {\n const pingData: IPingData = {\n id: (this.#messagingManager as MessagingManager).id,\n groups: this.#options.groups,\n }\n if (this.#options.extraData) {\n pingData.extraData = this.#options.extraData;\n }\n this.emit('ping', pingData, (response: any) => { });\n ping();\n }, 1000).unref();\n }\n ping();\n\n this.on('ping', (pingData: IPingData, callback: any) => {\n const { id, groups, extraData } = pingData;\n if (this.#clients[id]) {\n clearTimeout(this.#clients[id].timeout);\n this.#clients[id].pingCount++;\n this.#clients[id].timeout = setTimeout(() => {\n delete this.#clients[id];\n }, 2000);\n this.#clients[id].groups = groups;\n this.#clients[id].extraData = extraData;\n } else {\n this.#clients[id] = {\n id,\n clientConnected: new Date(),\n pingCount: 0,\n timeout: setTimeout(() => {\n delete this.#clients[id];\n }, 2000),\n groups,\n extraData\n }\n }\n callback('ok');\n });\n */\n\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n const ping = () => {\n this.#pingTimeout = setTimeout(() => {\n const pingData: IPingData = {\n id: (this.#messagingManager as MessagingManager).id,\n groups: this.#options.groups,\n }\n if (this.#options.extraData) {\n pingData.extraData = this.#options.extraData;\n }\n //this.emit('ping', pingData, (response: any) => { });\n this.emitNoResponse('ping', pingData);\n ping();\n }, 1000).unref();\n }\n ping();\n } else {\n this.on('ping', (pingData: IPingData, callback: any) => {\n const { id, groups, extraData } = pingData;\n if (this.#clients[id]) {\n clearTimeout(this.#clients[id].timeout);\n this.#clients[id].pingCount++;\n this.#clients[id].timeout = setTimeout(() => {\n delete this.#clients[id];\n }, 2000);\n this.#clients[id].groups = groups;\n this.#clients[id].extraData = extraData;\n } else {\n this.#clients[id] = {\n id,\n clientConnected: new Date(),\n pingCount: 0,\n timeout: setTimeout(() => {\n delete this.#clients[id];\n }, 2000),\n groups,\n extraData\n }\n }\n //callback('ok');\n });\n }\n }\n\n #LogInfo(message: any) {\n this.#options.logger.info(message);\n }\n\n #LogError(message: any) {\n this.#options.logger.error(message);\n }\n\n #processRawMessage = (channel: string, rawmessage: string) => {\n const message = JSON.parse(rawmessage);\n\n /*\n if (message.requestPayload.__eventName.localeCompare('ping') !== 0) {\n console.log(chalk.cyan(`RedisMessageHandler:#processRawMessage(): Role: [${this.#options.role}] Channel: [${channel}] Message: [${JSON.stringify(message)}]`));\n }\n */\n\n this.#messagingManager?.ProcessMessage(message, { channel });\n }\n\n get clients(): Record<string, IClientRecord> {\n return this.#clients;\n }\n\n get groups(): string[] {\n return this.#options.groups;\n }\n \n AddGroup = (group: string) => {\n const index = this.#options.groups.indexOf(group);\n if (index === -1) {\n this.#options.groups.push(group);\n }\n }\n\n RemoveGroup = (group: string) => {\n const removeIndex = this.#options.groups.indexOf(group);\n if (removeIndex !== -1) {\n this.#options.groups.splice(removeIndex, 1);\n }\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: this.#options.logger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: this.#options.role,\n groups: this.#options.groups,\n messageSender: this.#messageSender,\n // This method is used to calculate if all responses have been received from multiple clients (broadcast)\n // returns true/false.\n ProcessResponseMessage: this.#ProcessResponseMessage,\n // This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)\n ProcessRequestMessage: this.#processPayload,\n \n messageReceiverStart: (options: any) => {\n this.#redisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#redisSubscriber.off(\"message\", this.#processRawMessage);\n }\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n \n #messageSender = (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n\n\n //console.log(chalk.grey(JSON.stringify(payload)));\n\n\n this.#redisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#redisPublisher.publish(this.#responseChannel, JSON.stringify(payload));\n }\n }\n\n \n #ProcessResponseMessage = async (responses: Record<string, IIPCMessageProcessorIPCPayload>, options: any): Promise<boolean> => {\n // Now check if we have all responses ...\n\n /*\n let allFound = false;\n\n for (const [responseId, response] of Object.entries(responses)) {\n if (response.senderRole.localeCompare('CLIENT') === 0) {\n allFound = true;\n break;\n }\n }\n if (allFound) {\n return allFound;\n }\n */\n\n let found = true;\n\n // Sender role here is SERVER\n let requestGroup = null;\n for (const [responseId, response] of Object.entries(responses)) {\n if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {\n requestGroup = response.requestPayload.args[0].group;\n break;\n }\n }\n\n if (requestGroup) {\n const clientsInGroup = Object.values(this.#clients).filter(c => {\n if (c.groups.indexOf(requestGroup) === -1) {\n return false;\n }\n return true;\n });\n\n // Now make sure that all clients are in the responses\n found = true;\n clientsInGroup.forEach(c => {\n if (!responses[c.id]) {\n found = false;\n }\n })\n } else {\n const clientsInGroup = Object.values(this.#clients)\n\n // Now make sure that all clients are in the responses\n found = true;\n clientsInGroup.forEach(c => {\n if (!responses[c.id]) {\n found = false;\n }\n })\n }\n\n return found;\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject: IEventRecord = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n }\n\n Start = () => {\n this.#messagingManager?.Start();\n }\n\n Stop = () => {\n if (this.#pingTimeout) {\n clearTimeout(this.#pingTimeout);\n this.#pingTimeout = null;\n }\n\n this.#messagingManager?.Stop();\n\n this.#redisSubscriber.quit();\n this.#redisSubscriber.disconnect();\n\n this.#redisPublisher.quit();\n this.#redisPublisher.disconnect();\n }\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n const retVal = await this.#messagingManager?.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload); \n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitWithError(event: string, args: JSONObject, responseCb: (response: JSONObject | undefined) => void, errorCb: (error: any) => void): this {\n (async () => {\n try {\n const retVal = await this.#messagingManager?.SendMessage({\n __eventName: event,\n args: [ args ]\n } as IEventPayload); \n // Invoke the response callback\n responseCb(retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n //this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n errorCb(error);\n }\n })();\n return this;\n }\n\n emitex = async(event: string, ...args: any[]): Promise<JSONObject> => {\n return (this.#messagingManager as MessagingManager).SendMessage({\n __eventName: event,\n args\n } as IEventPayload); \n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n }\n}","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\n\nimport chalk from 'chalk';\n\nimport { v4 as uuidv4 } from 'uuid';\n\nexport interface IPCMessageHandlerOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n ignoreEvents?: string[]\n}\n\ndeclare interface IClientRecord {\n client: any\n processMessage: (client: any) => void\n}\n\n/**\n * IPC Message Handling.\n * \n * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.\n * This class can be used for both tghe cluster primary and the cluster worker.\n * Note: Currently groups handling is not supported. Use the redis version for this capability.\n */\nexport class IPCMessageHandler extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IPCMessageHandlerOptions;\n #clients: Record<string, IClientRecord> = { };\n #events: JSONObject = { };\n #startWorkerOptions: any;\n\n constructor(options: IPCMessageHandlerOptions) {\n super();\n this.#options = options;\n if (options.role.localeCompare('CLIENT') === 0) {\n this.SetupWorker();\n } else {\n this.SetupPrimary();\n }\n }\n\n get __events() {\n return this.#events;\n }\n\n AddClient = (client: any): string => {\n const id = uuidv4();\n\n const processMessage = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, { client });\n };\n\n client.on('message', processMessage);\n this.#clients[id] = {\n client,\n processMessage\n }\n return id;\n }\n\n RemoveClient = (id: string) => {\n const clientRecord = this.#clients[id];\n if (clientRecord) {\n clientRecord.client.off('message', clientRecord.processMessage);\n delete this.#clients[id];\n }\n }\n\n get clients() {\n return this.#clients;\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: 'SERVER',\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n (options.client as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n\n\n //@@ also need way to add/remove a worker/child to the collection\n //@@ the ping should also auto remove (such as a failed worker)\n \n\n messageReceiverStart: (options: any) => { //@@ options should be complete collection of workers\n // Receive a message to process from a worker\n },\n messageReceiverStop: (options: any) => { //@@ options should be complete collection of workers\n\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n #ProcessWorkerMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);\n }\n\n SetupWorker = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,\n namespace: this.#options.namespace,\n role: 'CLIENT',\n \n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n // Options not required for sending payloads to the master process\n (process as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n messageReceiverStart: (options: any) => {\n // Receive a message response back from the primary thread\n this.#startWorkerOptions = { ...options };\n process.on('message', this.#ProcessWorkerMessageRaw);\n },\n messageReceiverStop: (options: any) => { \n process.off('message', this.#ProcessWorkerMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n SendMessage = async (payload: JSONObject): Promise<JSONObject> => {\n if (this.#messagingManager) {\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n return this.#messagingManager?.SendMessage(payload, { });\n } else {\n //@@ send to all clients\n const promArray: Promise<JSONObject>[] = [ ];\n for (const [clientId, clientRecord] of Object.entries(this.#clients)) {\n promArray.push(this.#messagingManager?.SendMessage(payload, { client: clientRecord.client }));\n }\n\n try {\n const retVal = await Promise.all(promArray);\n return {\n result: retVal\n };\n } catch (error) {\n return { };\n }\n }\n } else {\n // Error state - no #ipcMessageManager set\n return { };\n }\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n //return super.on(event, callback, ctx);\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n //return super.off(event, callback);\n }\n\n // Supply complete collection of workers\n Start = () => {\n this.#messagingManager?.Start({ });\n }\n\n // Supply complete collection of workers\n Stop = () => {\n this.#messagingManager?.Stop({ });\n }\n\n /*\n override emit(event: string, ...args: any[]): this {\n const sendMessage = async () => {\n const retVal = await this.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n });\n // Invoke the response callback\n args[args.length-1](retVal);\n };\n sendMessage();\n return this;\n //return super.emit(event, ...args);\n }\n */\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n //const retVal = await this.#messagingManager?.SendMessage({\n const retVal = await this.SendMessage({ \n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload);\n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n console.log(error);\n this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n } else {\n //@@ send to all clients\n for (const [clientId, clientRecord] of Object.entries(this.#clients)) {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload, { client: clientRecord.client });\n }\n }\n }\n}","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\n\nimport chalk from 'chalk';\n\nexport interface IPCMessageHandlerPairOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n ignoreEvents?: string[]\n}\n\n/**\n * IPC Message Handling.\n * \n * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.\n * This class can be used for both tghe cluster primary and the cluster worker.\n * Note: Currently groups handling is not supported. Use the redis version for this capability.\n */\nexport class IPCMessageHandlerPair extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IPCMessageHandlerPairOptions;\n #worker: any = null;\n #events: JSONObject = { };\n #startWorkerOptions: any;\n #startPrimaryWorker: Worker | null = null;\n\n constructor(options: IPCMessageHandlerPairOptions) {\n super();\n this.#options = options;\n if (options.role.localeCompare('CLIENT') === 0) {\n this.SetupWorker();\n } else {\n this.SetupPrimary();\n }\n }\n\n get __events() {\n return this.#events;\n }\n\n #ProcessPrimaryMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, { worker: this.#startPrimaryWorker as Worker });\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: 'SERVER',\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n (options.worker as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n\n\n //@@ also need way to add/remove a worker/child to the collection\n //@@ the ping should also auto remove (such as a failed worker)\n \n\n messageReceiverStart: (options: any) => { //@@ options should be complete collection of workers\n // Receive a message to process from a worker\n const worker = (options.worker as any);\n this.#startPrimaryWorker = worker;\n worker.on('message', this.#ProcessPrimaryMessageRaw);\n },\n messageReceiverStop: (options: any) => { //@@ options should be complete collection of workers\n const worker = (options.worker as any);\n worker.off('message', this.#ProcessPrimaryMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n #ProcessWorkerMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);\n }\n\n SetupWorker = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,\n namespace: this.#options.namespace,\n role: 'CLIENT',\n \n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n // Options not required for sending payloads to the master process\n (process as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n messageReceiverStart: (options: any) => {\n // Receive a message response back from the primary thread\n this.#startWorkerOptions = { ...options };\n process.on('message', this.#ProcessWorkerMessageRaw);\n },\n messageReceiverStop: (options: any) => { \n process.off('message', this.#ProcessWorkerMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n SendMessage = async (payload: JSONObject): Promise<JSONObject> => {\n if (this.#messagingManager) {\n if (this.#worker) {\n return this.#messagingManager?.SendMessage(payload, { worker: this.#worker });\n } else {\n return this.#messagingManager?.SendMessage(payload, { });\n }\n } else {\n // Error state - no #ipcMessageManager set\n return { };\n }\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n //return super.on(event, callback, ctx);\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n //return super.off(event, callback);\n }\n\n // Supply complete collection of workers\n Start = (worker?: any) => {\n if (worker) {\n this.#messagingManager?.Start({ worker });\n this.#worker = worker;\n } else {\n this.#messagingManager?.Start({ });\n }\n }\n\n // Supply complete collection of workers\n Stop = () => {\n if (this.#worker) {\n this.#messagingManager?.Stop({ worker: this.#worker });\n this.#worker = null;\n } else {\n this.#messagingManager?.Stop({ });\n }\n }\n\n get worker(): Worker | null {\n return this.#worker;\n }\n\n /*\n override emit(event: string, ...args: any[]): this {\n const sendMessage = async () => {\n const retVal = await this.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n });\n // Invoke the response callback\n args[args.length-1](retVal);\n };\n sendMessage();\n return this;\n //return super.emit(event, ...args);\n }\n */\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n //const retVal = await this.#messagingManager?.SendMessage({\n const retVal = await this.SendMessage({ \n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload);\n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n console.log(error);\n this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n }\n}"],"names":["payload","uuidv4","_options","_messagingManager","_clients","_events","_processPayload","_startWorkerOptions","_ProcessWorkerMessageRaw"],"mappings":"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"}
1
+ {"version":3,"file":"stsmessaging.mjs","sources":["../src/messagingManager.ts","../src/redisMessageHandler.ts","../src/ipcMessageHandler.ts","../src/ipcMessageHandlerPair.ts"],"sourcesContent":["/* eslint @typescript-eslint/no-explicit-any: 0 */ // --> OFF\nimport { ISTSLogger, JSONObject } from '@nsshunt/stsutils'\n\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes'\n\nexport interface MessagingManagerOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n groups: string[]\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => void\n ProcessRequestMessage: (payload: IIPCMessageProcessorIPCPayload, options: any) => Promise<JSONObject>\n ProcessResponseMessage?: (reesponses: Record<string, IIPCMessageProcessorIPCPayload>, options: any) => Promise<boolean>\n messageReceiverStart: (options: any) => void\n messageReceiverStop: (options: any) => void\n}\n/**\n * todo\n * @typedef {Object} options - todo\n * @property {boolean} [wssServer=false] - Create a web socket server on this worker instance\n */\nexport class MessagingManager {\n #id: string;\n #options: MessagingManagerOptions;\n #inflightMessages: Record<string, IIPCMessageProcessorWorkerRecord> = { };\n #messageHeader: string;\n\n constructor(options: MessagingManagerOptions) {\n this.#id = uuidv4();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;\n }\n\n get id() {\n return this.#id;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n ReceivedMessageFromMaster(msg: any) {\n // Override in subclass if required\n }\n\n SendMessageNoResponse = (payload: JSONObject, options?: any): void => {\n this.#SendMessageNoResponse(payload, options);\n };\n\n SendMessage = (payload: JSONObject, options?: any): Promise<JSONObject> => {\n return new Promise((resolve, reject) => {\n this.#SendMessage(payload, options,\n (payload: IIPCMessageProcessorIPCPayload) => {\n resolve(payload.responsePayload);\n },\n (payload: IIPCMessageProcessorIPCPayload) => {\n reject(payload.requestPayload);\n })\n })\n }\n\n #SendMessageNoResponse = (payload: JSONObject, options: any): void => {\n const messageId: string = uuidv4();\n const requestPayload: IIPCMessageProcessorIPCPayload = {\n header: this.#messageHeader,\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload: payload,\n responsePayload: { },\n pid: process.pid.toString(),\n messageType: 'REQUEST_NO_RESPONSE'\n }\n\n //console.log(chalk.blue(`#SendMessageNoResponse: [${JSON.stringify(requestPayload)}]`))\n this.#options.messageSender(requestPayload, options);\n }\n\n #SendMessage = (payload: JSONObject, options: any,\n callBack: (payload: IIPCMessageProcessorIPCPayload) => void, \n errorCallBack: (payload: IIPCMessageProcessorIPCPayload) => void\n ): void => {\n const messageId: string = uuidv4();\n const requestPayload: IIPCMessageProcessorIPCPayload = {\n header: this.#messageHeader,\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload: payload,\n responsePayload: { },\n pid: process.pid.toString(),\n messageType: 'REQUEST'\n }\n const messageRecord = {\n messageId,\n senderId: this.#id,\n senderRole: this.#options.role,\n requestPayload,\n responses: { }, // record\n startTime: performance.now(),\n endTime: 0,\n timeout: setTimeout(() => {\n //this.#LogDebugMessage(chalk.red(`Timeout has occurred after: [${this.#options.requestResponseMessageTimeout}]ms with message id: [${messageRecord.messageId}]. Details: [${JSON.stringify(this.#inflightMessages[messageRecord.messageId].requestPayload)}]`));\n setTimeout(() => {\n delete this.#inflightMessages[messageRecord.messageId];\n }, 0).unref();\n errorCallBack(requestPayload);\n }, this.#options.requestResponseMessageTimeout).unref(),// max message timeout allowed\n callBack,\n errorCallBack\n }\n this.#inflightMessages[messageRecord.messageId] = messageRecord;\n //this.#LogDebugMessage(chalk.cyan(`sending: [${JSON.stringify(requestPayload)}]`));\n //console.log(chalk.blue(`#SendMessage: [${JSON.stringify(requestPayload)}]`))\n\n this.#options.messageSender(requestPayload, options);\n }\n\n #ProcessMessage = async (msg: any, options: any): Promise<void> => {\n if (msg.header && msg.header.localeCompare(this.#messageHeader) === 0) {\n const message = (msg as IIPCMessageProcessorIPCPayload);\n if (this.#inflightMessages[message.messageId]) {\n const inFlightMessageRecord: IIPCMessageProcessorWorkerRecord = this.#inflightMessages[message.messageId];\n inFlightMessageRecord.responses[message.senderId ] = { ...message };\n let completed = true; // Defaults to true\n if (this.#options.ProcessResponseMessage) {\n completed = await this.#options.ProcessResponseMessage(inFlightMessageRecord.responses, options);\n if (completed) {\n inFlightMessageRecord.endTime = performance.now();\n clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);\n inFlightMessageRecord.callBack({\n responsePayload: Object.values(inFlightMessageRecord.responses).map(r => r.responsePayload)\n } as any, options) // \n delete this.#inflightMessages[message.messageId];\n }\n } else if (completed) {\n inFlightMessageRecord.endTime = performance.now();\n clearTimeout(inFlightMessageRecord.timeout as NodeJS.Timeout);\n inFlightMessageRecord.callBack(message, options) // inFlightMessageRecord.responses\n //@@inFlightMessageRecord.callBack(Object.values(inFlightMessageRecord.responses), options) // \n delete this.#inflightMessages[message.messageId];\n } else {\n //console.log(chalk.grey(`#ProcessMessage:5`));\n }\n } else {\n //throw new Error(`Could not find Request/Response message with id: [${message.messageId}]`); //@@\n }\n }\n }\n\n Start = (options?: any) => {\n this.#messageHeader = `__STS__${this.#options.namespace}__${uuidv4()}`;\n this.#options.messageReceiverStart(options);\n }\n\n Stop = (options?: any) => {\n // Kill in-flight messages\n this.#options.messageReceiverStop(options);\n\n for (const [, iPCMessageProcessorWorkerRecord] of Object.entries(this.#inflightMessages)) {\n if (iPCMessageProcessorWorkerRecord.timeout) {\n clearTimeout(iPCMessageProcessorWorkerRecord.timeout);\n }\n }\n this.#inflightMessages = { };\n }\n\n // Process a message recieved from a worker\n ProcessMessage = async (msg: any, options: any) => {\n if (msg.header) {\n const checkName = `__STS__${this.#options.namespace}__`; //@@ this is a broadcast becuase the unique uuid is not part of the header test\n if ((msg.header as string).includes(checkName)) {\n const message = (msg as IIPCMessageProcessorIPCPayload);\n if (msg.messageType.localeCompare('REQUEST') === 0 || msg.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n let processMessage = true;\n if (message.requestPayload.args && message.requestPayload.args.length > 0 && message.requestPayload.args[0].group) {\n const group = message.requestPayload.args[0].group;\n processMessage = (this.#options.groups.indexOf(group) === -1) ? false : true;\n }\n if (processMessage) {\n if (msg.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#options.ProcessRequestMessage(message, options);\n } else {\n message.responsePayload = await this.#options.ProcessRequestMessage(message, options);\n message.senderId = this.#id;\n message.messageType = 'RESPONSE';\n this.#options.messageSender(message, options);\n }\n }\n } else {\n // Received a response (to my request)\n this.#ProcessMessage(msg, options);\n }\n }\n }\n }\n}\n","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\nimport { Redis, RedisOptions } from \"ioredis\";\n\nimport chalk from 'chalk';\n\nconst REQUEST_CHANNEL = '__STS__SVC_stsappframework_request'\nconst RESPONSE_CHANNEL = '__STS__SVC_stsappframework_response'\n\nexport interface IRedisAdminManagerOptions {\n redisUrl: string\n logger: ISTSLogger\n role: 'SERVER' | 'CLIENT'\n namespace: string\n groups: string[]\n ignoreEvents?: string[]\n extraData?: JSONObject\n}\n\nexport interface IClientRecord {\n id: string\n clientConnected: Date\n pingCount: number\n timeout: NodeJS.Timeout\n groups: string[]\n extraData?: JSONObject\n}\n\nexport interface IEventRecord {\n event: string\n callback: any,\n ctx?: any\n}\n\nexport interface IPingData {\n id: string\n groups: string[]\n extraData?: JSONObject\n}\n\nexport class RedisMessageHandler extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IRedisAdminManagerOptions;\n #events: Record<string, IEventRecord> = { };\n #requestChannel: string;\n #responseChannel: string;\n #redisSubscriber: Redis;\n #redisPublisher: Redis;\n #clients: Record<string, IClientRecord> = { };\n #pingTimeout: NodeJS.Timeout | null = null;\n\n constructor(options: IRedisAdminManagerOptions) {\n super();\n this.#options = options;\n\n this.#requestChannel = REQUEST_CHANNEL\n this.#responseChannel = RESPONSE_CHANNEL\n\n const redisOptions: RedisOptions = {\n showFriendlyErrorStack: true,\n maxRetriesPerRequest: 20\n }\n\n this.#redisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#redisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#redisSubscriber.on(\"error\", (error: Error) => {\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisSubscriber on error): [${error}]`));\n });\n\n this.#redisPublisher.on(\"error\", (error: Error) => {\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error (redisPublisher on error): [${error}]`));\n });\n\n this.#redisSubscriber.subscribe(this.#requestChannel, this.#responseChannel, (error, count) => {\n if (error) {\n // Just like other commands, subscribe() can fail for some reasons, // ex network issues.\n this.#LogError(chalk.red(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Error - Failed to subscribe: [${error}]`));\n } else {\n // `count` represents the number of channels this client is currently subscribed to.\n this.#LogInfo(chalk.white(`RedisMessageHandler:constructor(): PID: [${process.pid}] Role: [${this.#options.role}] Subscribed successfully! This client is currently subscribed to ${count} channels.`));\n }\n });\n\n this.SetupPrimary();\n\n /*\n const ping = () => {\n this.#pingTimeout = setTimeout(() => {\n const pingData: IPingData = {\n id: (this.#messagingManager as MessagingManager).id,\n groups: this.#options.groups,\n }\n if (this.#options.extraData) {\n pingData.extraData = this.#options.extraData;\n }\n this.emit('ping', pingData, (response: any) => { });\n ping();\n }, 1000).unref();\n }\n ping();\n\n this.on('ping', (pingData: IPingData, callback: any) => {\n const { id, groups, extraData } = pingData;\n if (this.#clients[id]) {\n clearTimeout(this.#clients[id].timeout);\n this.#clients[id].pingCount++;\n this.#clients[id].timeout = setTimeout(() => {\n delete this.#clients[id];\n }, 2000);\n this.#clients[id].groups = groups;\n this.#clients[id].extraData = extraData;\n } else {\n this.#clients[id] = {\n id,\n clientConnected: new Date(),\n pingCount: 0,\n timeout: setTimeout(() => {\n delete this.#clients[id];\n }, 2000),\n groups,\n extraData\n }\n }\n callback('ok');\n });\n */\n\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n const ping = () => {\n this.#pingTimeout = setTimeout(() => {\n const pingData: IPingData = {\n id: (this.#messagingManager as MessagingManager).id,\n groups: this.#options.groups,\n }\n if (this.#options.extraData) {\n pingData.extraData = this.#options.extraData;\n }\n //this.emit('ping', pingData, (response: any) => { });\n this.emitNoResponse('ping', pingData);\n ping();\n }, 1000).unref();\n }\n ping();\n } else {\n this.on('ping', (pingData: IPingData, callback: any) => {\n const { id, groups, extraData } = pingData;\n if (this.#clients[id]) {\n clearTimeout(this.#clients[id].timeout);\n this.#clients[id].pingCount++;\n this.#clients[id].timeout = setTimeout(() => {\n delete this.#clients[id];\n }, 2000);\n this.#clients[id].groups = groups;\n this.#clients[id].extraData = extraData;\n } else {\n this.#clients[id] = {\n id,\n clientConnected: new Date(),\n pingCount: 0,\n timeout: setTimeout(() => {\n delete this.#clients[id];\n }, 2000),\n groups,\n extraData\n }\n }\n //callback('ok');\n });\n }\n }\n\n #LogInfo(message: any) {\n this.#options.logger.info(message);\n }\n\n #LogError(message: any) {\n this.#options.logger.error(message);\n }\n\n #processRawMessage = (channel: string, rawmessage: string) => {\n const message = JSON.parse(rawmessage);\n\n /*\n if (message.requestPayload.__eventName.localeCompare('ping') !== 0) {\n console.log(chalk.cyan(`RedisMessageHandler:#processRawMessage(): Role: [${this.#options.role}] Channel: [${channel}] Message: [${JSON.stringify(message)}]`));\n }\n */\n\n this.#messagingManager?.ProcessMessage(message, { channel });\n }\n\n get clients(): Record<string, IClientRecord> {\n return this.#clients;\n }\n\n get groups(): string[] {\n return this.#options.groups;\n }\n \n AddGroup = (group: string) => {\n const index = this.#options.groups.indexOf(group);\n if (index === -1) {\n this.#options.groups.push(group);\n }\n }\n\n RemoveGroup = (group: string) => {\n const removeIndex = this.#options.groups.indexOf(group);\n if (removeIndex !== -1) {\n this.#options.groups.splice(removeIndex, 1);\n }\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: this.#options.logger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: this.#options.role,\n groups: this.#options.groups,\n messageSender: this.#messageSender,\n // This method is used to calculate if all responses have been received from multiple clients (broadcast)\n // returns true/false.\n ProcessResponseMessage: this.#ProcessResponseMessage,\n // This gets called when an event is received from a message receiver (when ProcessMessage is invoked from the receiver event handler)\n ProcessRequestMessage: this.#processPayload,\n \n messageReceiverStart: (options: any) => {\n this.#redisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#redisSubscriber.off(\"message\", this.#processRawMessage);\n }\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n \n #messageSender = (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n\n\n //console.log(chalk.grey(JSON.stringify(payload)));\n\n\n this.#redisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#redisPublisher.publish(this.#responseChannel, JSON.stringify(payload));\n }\n }\n\n \n #ProcessResponseMessage = async (responses: Record<string, IIPCMessageProcessorIPCPayload>, options: any): Promise<boolean> => {\n // Now check if we have all responses ...\n\n /*\n let allFound = false;\n\n for (const [responseId, response] of Object.entries(responses)) {\n if (response.senderRole.localeCompare('CLIENT') === 0) {\n allFound = true;\n break;\n }\n }\n if (allFound) {\n return allFound;\n }\n */\n\n let found = true;\n\n // Sender role here is SERVER\n let requestGroup = null;\n for (const [responseId, response] of Object.entries(responses)) {\n if (response.requestPayload.args.length > 0 && response.requestPayload.args[0].group) {\n requestGroup = response.requestPayload.args[0].group;\n break;\n }\n }\n\n if (requestGroup) {\n const clientsInGroup = Object.values(this.#clients).filter(c => {\n if (c.groups.indexOf(requestGroup) === -1) {\n return false;\n }\n return true;\n });\n\n // Now make sure that all clients are in the responses\n found = true;\n clientsInGroup.forEach(c => {\n if (!responses[c.id]) {\n found = false;\n }\n })\n } else {\n const clientsInGroup = Object.values(this.#clients)\n\n // Now make sure that all clients are in the responses\n found = true;\n clientsInGroup.forEach(c => {\n if (!responses[c.id]) {\n found = false;\n }\n })\n }\n\n return found;\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject: IEventRecord = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n }\n\n Start = () => {\n this.#messagingManager?.Start();\n }\n\n Stop = () => {\n if (this.#pingTimeout) {\n clearTimeout(this.#pingTimeout);\n this.#pingTimeout = null;\n }\n\n this.#messagingManager?.Stop();\n\n this.#redisSubscriber.quit();\n this.#redisSubscriber.disconnect();\n\n this.#redisPublisher.quit();\n this.#redisPublisher.disconnect();\n }\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n const retVal = await this.#messagingManager?.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload); \n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitWithError(event: string, args: JSONObject, responseCb: (response: JSONObject | undefined) => void, errorCb: (error: any) => void): this {\n (async () => {\n try {\n const retVal = await this.#messagingManager?.SendMessage({\n __eventName: event,\n args: [ args ]\n } as IEventPayload); \n // Invoke the response callback\n responseCb(retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n //this.#options.logger.error(chalk.red(`RedisMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n errorCb(error);\n }\n })();\n return this;\n }\n\n emitex = async(event: string, ...args: any[]): Promise<JSONObject> => {\n return (this.#messagingManager as MessagingManager).SendMessage({\n __eventName: event,\n args\n } as IEventPayload); \n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n }\n}","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\n\nimport chalk from 'chalk';\n\nimport { v4 as uuidv4 } from 'uuid';\n\nexport interface IPCMessageHandlerOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n ignoreEvents?: string[]\n}\n\ndeclare interface IClientRecord {\n client: any\n processMessage: (client: any) => void\n}\n\n/**\n * IPC Message Handling.\n * \n * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.\n * This class can be used for both tghe cluster primary and the cluster worker.\n * Note: Currently groups handling is not supported. Use the redis version for this capability.\n */\nexport class IPCMessageHandler extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IPCMessageHandlerOptions;\n #clients: Record<string, IClientRecord> = { };\n #events: JSONObject = { };\n #startWorkerOptions: any;\n\n constructor(options: IPCMessageHandlerOptions) {\n super();\n this.#options = options;\n if (options.role.localeCompare('CLIENT') === 0) {\n this.SetupWorker();\n } else {\n this.SetupPrimary();\n }\n }\n\n get __events() {\n return this.#events;\n }\n\n AddClient = (client: any): string => {\n const id = uuidv4();\n\n const processMessage = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, { client });\n };\n\n client.on('message', processMessage);\n this.#clients[id] = {\n client,\n processMessage\n }\n return id;\n }\n\n RemoveClient = (id: string) => {\n const clientRecord = this.#clients[id];\n if (clientRecord) {\n clientRecord.client.off('message', clientRecord.processMessage);\n delete this.#clients[id];\n }\n }\n\n get clients() {\n return this.#clients;\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: 'SERVER',\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n (options.client as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n\n\n //@@ also need way to add/remove a worker/child to the collection\n //@@ the ping should also auto remove (such as a failed worker)\n \n\n messageReceiverStart: (options: any) => { //@@ options should be complete collection of workers\n // Receive a message to process from a worker\n },\n messageReceiverStop: (options: any) => { //@@ options should be complete collection of workers\n\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n #ProcessWorkerMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);\n }\n\n SetupWorker = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,\n namespace: this.#options.namespace,\n role: 'CLIENT',\n \n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n // Options not required for sending payloads to the master process\n (process as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n messageReceiverStart: (options: any) => {\n // Receive a message response back from the primary thread\n this.#startWorkerOptions = { ...options };\n process.on('message', this.#ProcessWorkerMessageRaw);\n },\n messageReceiverStop: (options: any) => { \n process.off('message', this.#ProcessWorkerMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n SendMessage = async (payload: JSONObject): Promise<JSONObject> => {\n if (this.#messagingManager) {\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n return this.#messagingManager?.SendMessage(payload, { });\n } else {\n //@@ send to all clients\n const promArray: Promise<JSONObject>[] = [ ];\n for (const [clientId, clientRecord] of Object.entries(this.#clients)) {\n promArray.push(this.#messagingManager?.SendMessage(payload, { client: clientRecord.client }));\n }\n\n try {\n const retVal = await Promise.all(promArray);\n return {\n result: retVal\n };\n } catch (error) {\n return { };\n }\n }\n } else {\n // Error state - no #ipcMessageManager set\n return { };\n }\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n //return super.on(event, callback, ctx);\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n //return super.off(event, callback);\n }\n\n // Supply complete collection of workers\n Start = () => {\n this.#messagingManager?.Start({ });\n }\n\n // Supply complete collection of workers\n Stop = () => {\n this.#messagingManager?.Stop({ });\n }\n\n /*\n override emit(event: string, ...args: any[]): this {\n const sendMessage = async () => {\n const retVal = await this.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n });\n // Invoke the response callback\n args[args.length-1](retVal);\n };\n sendMessage();\n return this;\n //return super.emit(event, ...args);\n }\n */\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n //const retVal = await this.#messagingManager?.SendMessage({\n const retVal = await this.SendMessage({ \n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload);\n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n console.log(error);\n this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n if (this.#options.role.localeCompare('CLIENT') === 0) {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n } else {\n //@@ send to all clients\n for (const [clientId, clientRecord] of Object.entries(this.#clients)) {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload, { client: clientRecord.client });\n }\n }\n }\n}","/* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF */ // --> OFF\nimport { TinyEmitter } from \"tiny-emitter\";\nimport { ISTSLogger, JSONObject, defaultLogger } from '@nsshunt/stsutils'\n\nimport { IIPCMessageProcessorIPCPayload, IEventPayload } from './commonTypes'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager'\n\nimport chalk from 'chalk';\n\nexport interface IPCMessageHandlerPairOptions {\n logger: ISTSLogger\n requestResponseMessageTimeout: number\n namespace: string\n role: 'SERVER' | 'CLIENT'\n ignoreEvents?: string[]\n}\n\n/**\n * IPC Message Handling.\n * \n * This class can be used to support messages between cluster.primary and cluster.worker instances using IPC.\n * This class can be used for both tghe cluster primary and the cluster worker.\n * Note: Currently groups handling is not supported. Use the redis version for this capability.\n */\nexport class IPCMessageHandlerPair extends TinyEmitter {\n #messagingManager: MessagingManager | null = null;\n #options: IPCMessageHandlerPairOptions;\n #worker: any = null;\n #events: JSONObject = { };\n #startWorkerOptions: any;\n #startPrimaryWorker: Worker | null = null;\n\n constructor(options: IPCMessageHandlerPairOptions) {\n super();\n this.#options = options;\n if (options.role.localeCompare('CLIENT') === 0) {\n this.SetupWorker();\n } else {\n this.SetupPrimary();\n }\n }\n\n get __events() {\n return this.#events;\n }\n\n #ProcessPrimaryMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, { worker: this.#startPrimaryWorker as Worker });\n }\n\n SetupPrimary = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: 5000,\n namespace: this.#options.namespace,\n role: 'SERVER',\n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n (options.worker as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n\n\n //@@ also need way to add/remove a worker/child to the collection\n //@@ the ping should also auto remove (such as a failed worker)\n \n\n messageReceiverStart: (options: any) => { //@@ options should be complete collection of workers\n // Receive a message to process from a worker\n const worker = (options.worker as any);\n this.#startPrimaryWorker = worker;\n worker.on('message', this.#ProcessPrimaryMessageRaw);\n },\n messageReceiverStop: (options: any) => { //@@ options should be complete collection of workers\n const worker = (options.worker as any);\n worker.off('message', this.#ProcessPrimaryMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n #ProcessWorkerMessageRaw = (payload: any) => {\n this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);\n }\n\n SetupWorker = () => {\n const ipcMessageManagerOptions: MessagingManagerOptions = {\n logger: defaultLogger,\n requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,\n namespace: this.#options.namespace,\n role: 'CLIENT',\n \n messageSender: (payload: IIPCMessageProcessorIPCPayload, options: any) => {\n // Options not required for sending payloads to the master process\n (process as any).send(payload);\n },\n ProcessRequestMessage: async (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n return this.#processPayload(payload, options);\n },\n messageReceiverStart: (options: any) => {\n // Receive a message response back from the primary thread\n this.#startWorkerOptions = { ...options };\n process.on('message', this.#ProcessWorkerMessageRaw);\n },\n messageReceiverStop: (options: any) => { \n process.off('message', this.#ProcessWorkerMessageRaw);\n },\n groups: [ ]\n }\n this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);\n }\n\n SendMessage = async (payload: JSONObject): Promise<JSONObject> => {\n if (this.#messagingManager) {\n if (this.#worker) {\n return this.#messagingManager?.SendMessage(payload, { worker: this.#worker });\n } else {\n return this.#messagingManager?.SendMessage(payload, { });\n }\n } else {\n // Error state - no #ipcMessageManager set\n return { };\n }\n }\n\n #processPayload = (payload: IIPCMessageProcessorIPCPayload, options: any): Promise<JSONObject> => {\n // check the event name from the collection and invoke that function\n return new Promise<JSONObject>((resolve, reject) => {\n if (payload.messageType.localeCompare('REQUEST') === 0 || payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n if (payload.requestPayload['__eventName']) {\n const eventName = payload.requestPayload['__eventName'];\n // Only process events that I have registered interest in (using .on)\n if (this.#events[eventName]) {\n try {\n if (payload.messageType.localeCompare('REQUEST_NO_RESPONSE') === 0) {\n this.#events[eventName].callback(...payload.requestPayload.args);\n resolve({});\n } else {\n this.#events[eventName].callback(...payload.requestPayload.args, (responseMessage: any) => {\n resolve(responseMessage);\n });\n }\n } catch (error) {\n reject(error);\n }\n }\n }\n }\n });\n }\n\n // p.on('fromworker', (arg1: number, arg2: string, callback: any) => {\n override on(event: string, callback: any, ctx?: any): this {\n if (this.#events[event]) {\n // Update the event with the same name\n delete this.#events[event];\n }\n const eventObject = {\n event,\n callback,\n ctx\n }\n this.#events[eventObject.event] = eventObject;\n return this;\n //return super.on(event, callback, ctx);\n }\n\n override off(event: string, callback?: any): this {\n if (this.#events[event]) {\n delete this.#events[event];\n }\n return this;\n //return super.off(event, callback);\n }\n\n // Supply complete collection of workers\n Start = (worker?: any) => {\n if (worker) {\n this.#messagingManager?.Start({ worker });\n this.#worker = worker;\n } else {\n this.#messagingManager?.Start({ });\n }\n }\n\n // Supply complete collection of workers\n Stop = () => {\n if (this.#worker) {\n this.#messagingManager?.Stop({ worker: this.#worker });\n this.#worker = null;\n } else {\n this.#messagingManager?.Stop({ });\n }\n }\n\n get worker(): Worker | null {\n return this.#worker;\n }\n\n /*\n override emit(event: string, ...args: any[]): this {\n const sendMessage = async () => {\n const retVal = await this.SendMessage({\n __eventName: event,\n args: args.slice(0, args.length-1)\n });\n // Invoke the response callback\n args[args.length-1](retVal);\n };\n sendMessage();\n return this;\n //return super.emit(event, ...args);\n }\n */\n\n override emit(event: string, ...args: any[]): this {\n (async () => {\n try {\n //const retVal = await this.#messagingManager?.SendMessage({\n const retVal = await this.SendMessage({ \n __eventName: event,\n args: args.slice(0, args.length-1)\n } as IEventPayload);\n // Invoke the response callback\n args[args.length-1](retVal);\n } catch (error) {\n if (this.#options.ignoreEvents) {\n //console.log(chalk.red(`RedisMessageHandler:emit(): ignoreEvents: [${this.#options.ignoreEvents}]`))\n if (this.#options.ignoreEvents.indexOf((error as any).__eventName) !== -1) {\n return;\n }\n }\n console.log(error);\n this.#options.logger.error(chalk.red(`IPCMessageHandler:emit(): Error: [${JSON.stringify(error)}]`));\n }\n })();\n return this;\n }\n\n emitNoResponse = async(event: string, ...args: any[]): Promise<void> => {\n (this.#messagingManager as MessagingManager).SendMessageNoResponse({\n __eventName: event,\n args\n } as IEventPayload); \n }\n}"],"names":["uuidv4","payload"],"mappings":"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"}