@nsshunt/stsmessaging 1.0.67 → 1.0.69

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.
package/dist/index.cjs CHANGED
@@ -255,7 +255,7 @@ var RedisMessageHandler = class extends tiny_emitter.TinyEmitter {
255
255
  if (removeIndex !== -1) this.#options.groups.splice(removeIndex, 1);
256
256
  };
257
257
  SetupPrimary = () => {
258
- this.#messagingManager = new MessagingManager({
258
+ const ipcMessageManagerOptions = {
259
259
  logger: this.#options.logger,
260
260
  requestResponseMessageTimeout: 5e3,
261
261
  namespace: this.#options.namespace,
@@ -270,7 +270,8 @@ var RedisMessageHandler = class extends tiny_emitter.TinyEmitter {
270
270
  messageReceiverStop: (options) => {
271
271
  this.#ioredisSubscriber.off("message", this.#processRawMessage);
272
272
  }
273
- });
273
+ };
274
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
274
275
  };
275
276
  #messageSender = (payload, options) => {
276
277
  if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) this.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
@@ -441,7 +442,7 @@ var IPCMessageHandler = class extends tiny_emitter.TinyEmitter {
441
442
  return this.#clients;
442
443
  }
443
444
  SetupPrimary = () => {
444
- this.#messagingManager = new MessagingManager({
445
+ const ipcMessageManagerOptions = {
445
446
  logger: _nsshunt_stsutils.defaultLogger,
446
447
  requestResponseMessageTimeout: 5e3,
447
448
  namespace: this.#options.namespace,
@@ -455,13 +456,14 @@ var IPCMessageHandler = class extends tiny_emitter.TinyEmitter {
455
456
  messageReceiverStart: (options) => {},
456
457
  messageReceiverStop: (options) => {},
457
458
  groups: []
458
- });
459
+ };
460
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
459
461
  };
460
462
  #ProcessWorkerMessageRaw = (payload) => {
461
463
  this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
462
464
  };
463
465
  SetupWorker = () => {
464
- this.#messagingManager = new MessagingManager({
466
+ const ipcMessageManagerOptions = {
465
467
  logger: _nsshunt_stsutils.defaultLogger,
466
468
  requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
467
469
  namespace: this.#options.namespace,
@@ -480,7 +482,8 @@ var IPCMessageHandler = class extends tiny_emitter.TinyEmitter {
480
482
  process.off("message", this.#ProcessWorkerMessageRaw);
481
483
  },
482
484
  groups: []
483
- });
485
+ };
486
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
484
487
  };
485
488
  SendMessage = async (payload) => {
486
489
  if (this.#messagingManager) if (this.#options.role.localeCompare("CLIENT") === 0) return this.#messagingManager?.SendMessage(payload, {});
@@ -592,7 +595,7 @@ var IPCMessageHandlerPair = class extends tiny_emitter.TinyEmitter {
592
595
  this.#messagingManager?.ProcessMessage(payload, { worker: this.#startPrimaryWorker });
593
596
  };
594
597
  SetupPrimary = () => {
595
- this.#messagingManager = new MessagingManager({
598
+ const ipcMessageManagerOptions = {
596
599
  logger: _nsshunt_stsutils.defaultLogger,
597
600
  requestResponseMessageTimeout: 5e3,
598
601
  namespace: this.#options.namespace,
@@ -612,13 +615,14 @@ var IPCMessageHandlerPair = class extends tiny_emitter.TinyEmitter {
612
615
  options.worker.off("message", this.#ProcessPrimaryMessageRaw);
613
616
  },
614
617
  groups: []
615
- });
618
+ };
619
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
616
620
  };
617
621
  #ProcessWorkerMessageRaw = (payload) => {
618
622
  this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
619
623
  };
620
624
  SetupWorker = () => {
621
- this.#messagingManager = new MessagingManager({
625
+ const ipcMessageManagerOptions = {
622
626
  logger: _nsshunt_stsutils.defaultLogger,
623
627
  requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
624
628
  namespace: this.#options.namespace,
@@ -637,7 +641,8 @@ var IPCMessageHandlerPair = class extends tiny_emitter.TinyEmitter {
637
641
  process.off("message", this.#ProcessWorkerMessageRaw);
638
642
  },
639
643
  groups: []
640
- });
644
+ };
645
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
641
646
  };
642
647
  SendMessage = async (payload) => {
643
648
  if (this.#messagingManager) if (this.#worker) return this.#messagingManager?.SendMessage(payload, { worker: this.#worker });
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["#id","#options","#messageHeader","#SendMessageNoResponse","#SendMessage","#inflightMessages","#ProcessMessage","#options","#requestChannel","#responseChannel","#ioredisSubscriber","#ioredisPublisher","#LogError","#LogInfo","#pingTimeout","#messagingManager","#clients","#messageSender","#ProcessResponseMessage","#processPayload","#processRawMessage","#events","#options","#events","#messagingManager","#clients","#processPayload","#startWorkerOptions","#ProcessWorkerMessageRaw","#options","#events","#messagingManager","#startPrimaryWorker","#processPayload","#ProcessPrimaryMessageRaw","#startWorkerOptions","#ProcessWorkerMessageRaw","#worker"],"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\n//import { randomUUID } from 'node:crypto';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes.js'\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 = globalThis.crypto.randomUUID(); // randomUUID();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${globalThis.crypto.randomUUID()}`; // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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}__${globalThis.crypto.randomUUID()}`; // randomUUID()\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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 #ioredisSubscriber: Redis;\n #ioredisPublisher: 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.#ioredisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#ioredisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#ioredisSubscriber.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.#ioredisPublisher.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.#ioredisSubscriber.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.#ioredisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#ioredisSubscriber.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.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#ioredisPublisher.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.#ioredisSubscriber.quit();\n this.#ioredisSubscriber.disconnect();\n\n this.#ioredisPublisher.quit();\n this.#ioredisPublisher.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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\n\nimport chalk from 'chalk';\n\n//import { randomUUID } from 'node:crypto';\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 = globalThis.crypto.randomUUID(); // randomUUID();\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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}"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["#id","#options","#messageHeader","#SendMessageNoResponse","#SendMessage","#inflightMessages","#ProcessMessage","#options","#requestChannel","#responseChannel","#ioredisSubscriber","#ioredisPublisher","#LogError","#LogInfo","#pingTimeout","#messagingManager","#clients","#messageSender","#ProcessResponseMessage","#processPayload","#processRawMessage","#events","#options","#events","#messagingManager","#clients","#processPayload","#startWorkerOptions","#ProcessWorkerMessageRaw","#options","#events","#messagingManager","#startPrimaryWorker","#processPayload","#ProcessPrimaryMessageRaw","#startWorkerOptions","#ProcessWorkerMessageRaw","#worker"],"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\n//import { randomUUID } from 'node:crypto';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes.js'\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 = globalThis.crypto.randomUUID(); // randomUUID();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${globalThis.crypto.randomUUID()}`; // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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}__${globalThis.crypto.randomUUID()}`; // randomUUID()\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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 #ioredisSubscriber: Redis;\n #ioredisPublisher: 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.#ioredisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#ioredisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#ioredisSubscriber.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.#ioredisPublisher.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.#ioredisSubscriber.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.#ioredisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#ioredisSubscriber.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.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#ioredisPublisher.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.#ioredisSubscriber.quit();\n this.#ioredisSubscriber.disconnect();\n\n this.#ioredisPublisher.quit();\n this.#ioredisPublisher.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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\n\nimport chalk from 'chalk';\n\n//import { randomUUID } from 'node:crypto';\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 = globalThis.crypto.randomUUID(); // randomUUID();\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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}"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -231,7 +231,7 @@ var RedisMessageHandler = class extends TinyEmitter {
231
231
  if (removeIndex !== -1) this.#options.groups.splice(removeIndex, 1);
232
232
  };
233
233
  SetupPrimary = () => {
234
- this.#messagingManager = new MessagingManager({
234
+ const ipcMessageManagerOptions = {
235
235
  logger: this.#options.logger,
236
236
  requestResponseMessageTimeout: 5e3,
237
237
  namespace: this.#options.namespace,
@@ -246,7 +246,8 @@ var RedisMessageHandler = class extends TinyEmitter {
246
246
  messageReceiverStop: (options) => {
247
247
  this.#ioredisSubscriber.off("message", this.#processRawMessage);
248
248
  }
249
- });
249
+ };
250
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
250
251
  };
251
252
  #messageSender = (payload, options) => {
252
253
  if (payload.messageType.localeCompare("REQUEST") === 0 || payload.messageType.localeCompare("REQUEST_NO_RESPONSE") === 0) this.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));
@@ -417,7 +418,7 @@ var IPCMessageHandler = class extends TinyEmitter {
417
418
  return this.#clients;
418
419
  }
419
420
  SetupPrimary = () => {
420
- this.#messagingManager = new MessagingManager({
421
+ const ipcMessageManagerOptions = {
421
422
  logger: defaultLogger,
422
423
  requestResponseMessageTimeout: 5e3,
423
424
  namespace: this.#options.namespace,
@@ -431,13 +432,14 @@ var IPCMessageHandler = class extends TinyEmitter {
431
432
  messageReceiverStart: (options) => {},
432
433
  messageReceiverStop: (options) => {},
433
434
  groups: []
434
- });
435
+ };
436
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
435
437
  };
436
438
  #ProcessWorkerMessageRaw = (payload) => {
437
439
  this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
438
440
  };
439
441
  SetupWorker = () => {
440
- this.#messagingManager = new MessagingManager({
442
+ const ipcMessageManagerOptions = {
441
443
  logger: defaultLogger,
442
444
  requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
443
445
  namespace: this.#options.namespace,
@@ -456,7 +458,8 @@ var IPCMessageHandler = class extends TinyEmitter {
456
458
  process.off("message", this.#ProcessWorkerMessageRaw);
457
459
  },
458
460
  groups: []
459
- });
461
+ };
462
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
460
463
  };
461
464
  SendMessage = async (payload) => {
462
465
  if (this.#messagingManager) if (this.#options.role.localeCompare("CLIENT") === 0) return this.#messagingManager?.SendMessage(payload, {});
@@ -568,7 +571,7 @@ var IPCMessageHandlerPair = class extends TinyEmitter {
568
571
  this.#messagingManager?.ProcessMessage(payload, { worker: this.#startPrimaryWorker });
569
572
  };
570
573
  SetupPrimary = () => {
571
- this.#messagingManager = new MessagingManager({
574
+ const ipcMessageManagerOptions = {
572
575
  logger: defaultLogger,
573
576
  requestResponseMessageTimeout: 5e3,
574
577
  namespace: this.#options.namespace,
@@ -588,13 +591,14 @@ var IPCMessageHandlerPair = class extends TinyEmitter {
588
591
  options.worker.off("message", this.#ProcessPrimaryMessageRaw);
589
592
  },
590
593
  groups: []
591
- });
594
+ };
595
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
592
596
  };
593
597
  #ProcessWorkerMessageRaw = (payload) => {
594
598
  this.#messagingManager?.ProcessMessage(payload, this.#startWorkerOptions);
595
599
  };
596
600
  SetupWorker = () => {
597
- this.#messagingManager = new MessagingManager({
601
+ const ipcMessageManagerOptions = {
598
602
  logger: defaultLogger,
599
603
  requestResponseMessageTimeout: this.#options.requestResponseMessageTimeout,
600
604
  namespace: this.#options.namespace,
@@ -613,7 +617,8 @@ var IPCMessageHandlerPair = class extends TinyEmitter {
613
617
  process.off("message", this.#ProcessWorkerMessageRaw);
614
618
  },
615
619
  groups: []
616
- });
620
+ };
621
+ this.#messagingManager = new MessagingManager(ipcMessageManagerOptions);
617
622
  };
618
623
  SendMessage = async (payload) => {
619
624
  if (this.#messagingManager) if (this.#worker) return this.#messagingManager?.SendMessage(payload, { worker: this.#worker });
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["#id","#options","#messageHeader","#SendMessageNoResponse","#SendMessage","#inflightMessages","#ProcessMessage","#options","#requestChannel","#responseChannel","#ioredisSubscriber","#ioredisPublisher","#LogError","#LogInfo","#pingTimeout","#messagingManager","#clients","#messageSender","#ProcessResponseMessage","#processPayload","#processRawMessage","#events","#options","#events","#messagingManager","#clients","#processPayload","#startWorkerOptions","#ProcessWorkerMessageRaw","#options","#events","#messagingManager","#startPrimaryWorker","#processPayload","#ProcessPrimaryMessageRaw","#startWorkerOptions","#ProcessWorkerMessageRaw","#worker"],"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\n//import { randomUUID } from 'node:crypto';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes.js'\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 = globalThis.crypto.randomUUID(); // randomUUID();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${globalThis.crypto.randomUUID()}`; // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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}__${globalThis.crypto.randomUUID()}`; // randomUUID()\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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 #ioredisSubscriber: Redis;\n #ioredisPublisher: 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.#ioredisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#ioredisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#ioredisSubscriber.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.#ioredisPublisher.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.#ioredisSubscriber.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.#ioredisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#ioredisSubscriber.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.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#ioredisPublisher.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.#ioredisSubscriber.quit();\n this.#ioredisSubscriber.disconnect();\n\n this.#ioredisPublisher.quit();\n this.#ioredisPublisher.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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\n\nimport chalk from 'chalk';\n\n//import { randomUUID } from 'node:crypto';\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 = globalThis.crypto.randomUUID(); // randomUUID();\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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}"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#id","#options","#messageHeader","#SendMessageNoResponse","#SendMessage","#inflightMessages","#ProcessMessage","#options","#requestChannel","#responseChannel","#ioredisSubscriber","#ioredisPublisher","#LogError","#LogInfo","#pingTimeout","#messagingManager","#clients","#messageSender","#ProcessResponseMessage","#processPayload","#processRawMessage","#events","#options","#events","#messagingManager","#clients","#processPayload","#startWorkerOptions","#ProcessWorkerMessageRaw","#options","#events","#messagingManager","#startPrimaryWorker","#processPayload","#ProcessPrimaryMessageRaw","#startWorkerOptions","#ProcessWorkerMessageRaw","#worker"],"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\n//import { randomUUID } from 'node:crypto';\n\nimport { IIPCMessageProcessorIPCPayload, IIPCMessageProcessorWorkerRecord } from './commonTypes.js'\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 = globalThis.crypto.randomUUID(); // randomUUID();\n this.#options = options;\n this.#messageHeader = `__STS__${this.#options.namespace}__${globalThis.crypto.randomUUID()}`; // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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 = globalThis.crypto.randomUUID(); // randomUUID();\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}__${globalThis.crypto.randomUUID()}`; // randomUUID()\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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 #ioredisSubscriber: Redis;\n #ioredisPublisher: 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.#ioredisSubscriber = new Redis(this.#options.redisUrl, redisOptions);\n this.#ioredisPublisher = new Redis(this.#options.redisUrl, redisOptions);\n\n this.#ioredisSubscriber.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.#ioredisPublisher.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.#ioredisSubscriber.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.#ioredisSubscriber.on(\"message\", this.#processRawMessage);\n },\n \n messageReceiverStop: (options: any) => {\n this.#ioredisSubscriber.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.#ioredisPublisher.publish(this.#requestChannel, JSON.stringify(payload));\n } else if (payload.messageType.localeCompare('RESPONSE') === 0) {\n this.#ioredisPublisher.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.#ioredisSubscriber.quit();\n this.#ioredisSubscriber.disconnect();\n\n this.#ioredisPublisher.quit();\n this.#ioredisPublisher.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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\n\nimport chalk from 'chalk';\n\n//import { randomUUID } from 'node:crypto';\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 = globalThis.crypto.randomUUID(); // randomUUID();\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.js'\n\nimport { MessagingManager, MessagingManagerOptions } from './messagingManager.js'\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}"],"mappings":";;;;;;;;;;AAwBA,IAAa,mBAAb,MAA8B;CAC1B;CACA;CACA,oBAAsE,EAAG;CACzE;CAEA,YAAY,SAAkC;AAC1C,QAAA,KAAW,WAAW,OAAO,YAAY;AACzC,QAAA,UAAgB;AAChB,QAAA,gBAAsB,UAAU,MAAA,QAAc,UAAU,IAAI,WAAW,OAAO,YAAY;;CAG9F,IAAI,KAAK;AACL,SAAO,MAAA;;CAIX,0BAA0B,KAAU;CAIpC,yBAAyB,SAAqB,YAAwB;AAClE,QAAA,sBAA4B,SAAS,QAAQ;;CAGjD,eAAe,SAAqB,YAAuC;AACvE,SAAO,IAAI,SAAS,SAAS,WAAW;AACpC,SAAA,YAAkB,SAAS,UACtB,YAA4C;AACzC,YAAQ,QAAQ,gBAAgB;OAEnC,YAA4C;AACzC,WAAO,QAAQ,eAAe;KAChC;IACR;;CAGN,0BAA0B,SAAqB,YAAuB;EAClE,MAAM,YAAoB,WAAW,OAAO,YAAY;EACxD,MAAM,iBAAiD;GACnD,QAAQ,MAAA;GACR;GACA,UAAU,MAAA;GACV,YAAY,MAAA,QAAc;GAC1B,gBAAgB;GAChB,iBAAiB,EAAG;GACpB,KAAK,QAAQ,IAAI,UAAU;GAC3B,aAAa;GAChB;AAGD,QAAA,QAAc,cAAc,gBAAgB,QAAQ;;CAGxD,gBAAgB,SAAqB,SACjC,UACA,kBACO;EACP,MAAM,YAAoB,WAAW,OAAO,YAAY;EACxD,MAAM,iBAAiD;GACnD,QAAQ,MAAA;GACR;GACA,UAAU,MAAA;GACV,YAAY,MAAA,QAAc;GAC1B,gBAAgB;GAChB,iBAAiB,EAAG;GACpB,KAAK,QAAQ,IAAI,UAAU;GAC3B,aAAa;GAChB;EACD,MAAM,gBAAgB;GAClB;GACA,UAAU,MAAA;GACV,YAAY,MAAA,QAAc;GAC1B;GACA,WAAW,EAAG;GACd,WAAW,YAAY,KAAK;GAC5B,SAAS;GACT,SAAS,iBAAiB;AAEtB,qBAAiB;AACb,YAAO,MAAA,iBAAuB,cAAc;OAC7C,EAAE,CAAC,OAAO;AACb,kBAAc,eAAe;MAC9B,MAAA,QAAc,8BAA8B,CAAC,OAAO;GACvD;GACA;GACH;AACD,QAAA,iBAAuB,cAAc,aAAa;AAIlD,QAAA,QAAc,cAAc,gBAAgB,QAAQ;;CAGxD,kBAAkB,OAAO,KAAU,YAAgC;AAC/D,MAAI,IAAI,UAAU,IAAI,OAAO,cAAc,MAAA,cAAoB,KAAK,GAAG;GACnE,MAAM,UAAW;AACjB,OAAI,MAAA,iBAAuB,QAAQ,YAAY;IAC3C,MAAM,wBAA0D,MAAA,iBAAuB,QAAQ;AAC/F,0BAAsB,UAAU,QAAQ,YAAa,EAAE,GAAG,SAAS;IACnE,IAAI,YAAY;AAChB,QAAI,MAAA,QAAc,wBAAwB;AACtC,iBAAY,MAAM,MAAA,QAAc,uBAAuB,sBAAsB,WAAW,QAAQ;AAChG,SAAI,WAAW;AACX,4BAAsB,UAAU,YAAY,KAAK;AACjD,mBAAa,sBAAsB,QAA0B;AAC7D,4BAAsB,SAAS,EAC3B,iBAAiB,OAAO,OAAO,sBAAsB,UAAU,CAAC,KAAI,MAAK,EAAE,gBAAgB,EAC9F,EAAS,QAAQ;AAClB,aAAO,MAAA,iBAAuB,QAAQ;;eAEnC,WAAW;AAClB,2BAAsB,UAAU,YAAY,KAAK;AACjD,kBAAa,sBAAsB,QAA0B;AAC7D,2BAAsB,SAAS,SAAS,QAAQ;AAEhD,YAAO,MAAA,iBAAuB,QAAQ;;;;;CAUtD,SAAS,YAAkB;AACvB,QAAA,gBAAsB,UAAU,MAAA,QAAc,UAAU,IAAI,WAAW,OAAO,YAAY;AAC1F,QAAA,QAAc,qBAAqB,QAAQ;;CAG/C,QAAQ,YAAkB;AAEtB,QAAA,QAAc,oBAAoB,QAAQ;AAE1C,OAAK,MAAM,GAAG,oCAAoC,OAAO,QAAQ,MAAA,iBAAuB,CACpF,KAAI,gCAAgC,QAChC,cAAa,gCAAgC,QAAQ;AAG7D,QAAA,mBAAyB,EAAG;;CAIhC,iBAAiB,OAAO,KAAU,YAAiB;AAC/C,MAAI,IAAI,QAAQ;GACZ,MAAM,YAAY,UAAU,MAAA,QAAc,UAAU;AACpD,OAAK,IAAI,OAAkB,SAAS,UAAU,EAAE;IAC5C,MAAM,UAAW;AACjB,QAAI,IAAI,YAAY,cAAc,UAAU,KAAK,KAAK,IAAI,YAAY,cAAc,sBAAsB,KAAK,GAAG;KAC9G,IAAI,iBAAiB;AACrB,SAAI,QAAQ,eAAe,QAAQ,QAAQ,eAAe,KAAK,SAAS,KAAK,QAAQ,eAAe,KAAK,GAAG,OAAO;MAC/G,MAAM,QAAQ,QAAQ,eAAe,KAAK,GAAG;AAC7C,uBAAkB,MAAA,QAAc,OAAO,QAAQ,MAAM,KAAK,KAAM,QAAQ;;AAE5E,SAAI,eACA,KAAI,IAAI,YAAY,cAAc,sBAAsB,KAAK,EACzD,OAAA,QAAc,sBAAsB,SAAS,QAAQ;UAClD;AACH,cAAQ,kBAAkB,MAAM,MAAA,QAAc,sBAAsB,SAAS,QAAQ;AACrF,cAAQ,WAAW,MAAA;AACnB,cAAQ,cAAc;AACtB,YAAA,QAAc,cAAc,SAAS,QAAQ;;UAKrD,OAAA,eAAqB,KAAK,QAAQ;;;;;;;ACpLtD,IAAM,kBAAkB;AACxB,IAAM,mBAAmB;AAiCzB,IAAa,sBAAb,cAAyC,YAAY;CACjD,oBAA6C;CAC7C;CACA,UAAwC,EAAG;CAC3C;CACA;CACA;CACA;CACA,WAA0C,EAAG;CAC7C,eAAsC;CAEtC,YAAY,SAAoC;AAC5C,SAAO;AACP,QAAA,UAAgB;AAEhB,QAAA,iBAAuB;AACvB,QAAA,kBAAwB;EAExB,MAAM,eAA6B;GAC/B,wBAAwB;GACxB,sBAAsB;GACzB;AAED,QAAA,oBAA0B,IAAI,MAAM,MAAA,QAAc,UAAU,aAAa;AACzE,QAAA,mBAAyB,IAAI,MAAM,MAAA,QAAc,UAAU,aAAa;AAExE,QAAA,kBAAwB,GAAG,UAAU,UAAiB;AAClD,SAAA,SAAe,MAAM,IAAI,4CAA4C,QAAQ,IAAI,WAAW,MAAA,QAAc,KAAK,uCAAuC,MAAM,GAAG,CAAC;IAClK;AAEF,QAAA,iBAAuB,GAAG,UAAU,UAAiB;AACjD,SAAA,SAAe,MAAM,IAAI,4CAA4C,QAAQ,IAAI,WAAW,MAAA,QAAc,KAAK,sCAAsC,MAAM,GAAG,CAAC;IACjK;AAEF,QAAA,kBAAwB,UAAU,MAAA,gBAAsB,MAAA,kBAAwB,OAAO,UAAU;AAC7F,OAAI,MAEA,OAAA,SAAe,MAAM,IAAI,4CAA4C,QAAQ,IAAI,WAAW,MAAA,QAAc,KAAK,kCAAkC,MAAM,GAAG,CAAC;OAG3J,OAAA,QAAc,MAAM,MAAM,4CAA4C,QAAQ,IAAI,WAAW,MAAA,QAAc,KAAK,oEAAoE,MAAM,YAAY,CAAC;IAE7M;AAEF,OAAK,cAAc;AA4CnB,MAAI,MAAA,QAAc,KAAK,cAAc,SAAS,KAAK,GAAG;GAClD,MAAM,aAAa;AACf,UAAA,cAAoB,iBAAiB;KACjC,MAAM,WAAsB;MACxB,IAAK,MAAA,iBAA4C;MACjD,QAAQ,MAAA,QAAc;MACzB;AACD,SAAI,MAAA,QAAc,UACd,UAAS,YAAY,MAAA,QAAc;AAGvC,UAAK,eAAe,QAAQ,SAAS;AACrC,WAAM;OACP,IAAK,CAAC,OAAO;;AAEpB,SAAM;QAEN,MAAK,GAAG,SAAS,UAAqB,aAAkB;GACpD,MAAM,EAAE,IAAI,QAAQ,cAAc;AAClC,OAAI,MAAA,QAAc,KAAK;AACnB,iBAAa,MAAA,QAAc,IAAI,QAAQ;AACvC,UAAA,QAAc,IAAI;AAClB,UAAA,QAAc,IAAI,UAAU,iBAAiB;AACzC,YAAO,MAAA,QAAc;OACtB,IAAK;AACR,UAAA,QAAc,IAAI,SAAS;AAC3B,UAAA,QAAc,IAAI,YAAY;SAE9B,OAAA,QAAc,MAAM;IAChB;IACA,iCAAiB,IAAI,MAAM;IAC3B,WAAW;IACX,SAAS,iBAAiB;AACtB,YAAO,MAAA,QAAc;OACtB,IAAK;IACR;IACA;IACH;IAGP;;CAIV,SAAS,SAAc;AACnB,QAAA,QAAc,OAAO,KAAK,QAAQ;;CAGtC,UAAU,SAAc;AACpB,QAAA,QAAc,OAAO,MAAM,QAAQ;;CAGvC,sBAAsB,SAAiB,eAAuB;EAC1D,MAAM,UAAU,KAAK,MAAM,WAAW;AAQtC,QAAA,kBAAwB,eAAe,SAAS,EAAE,SAAS,CAAC;;CAGhE,IAAI,UAAyC;AACzC,SAAO,MAAA;;CAGX,IAAI,SAAmB;AACnB,SAAO,MAAA,QAAc;;CAGzB,YAAY,UAAkB;AAE1B,MADc,MAAA,QAAc,OAAO,QAAQ,MACvC,KAAU,GACV,OAAA,QAAc,OAAO,KAAK,MAAM;;CAIxC,eAAe,UAAkB;EAC7B,MAAM,cAAc,MAAA,QAAc,OAAO,QAAQ,MAAM;AACvD,MAAI,gBAAgB,GAChB,OAAA,QAAc,OAAO,OAAO,aAAa,EAAE;;CAInD,qBAAqB;EACjB,MAAM,2BAAoD;GACtD,QAAQ,MAAA,QAAc;GACtB,+BAA+B;GAC/B,WAAW,MAAA,QAAc;GACzB,MAAM,MAAA,QAAc;GACpB,QAAQ,MAAA,QAAc;GACtB,eAAe,MAAA;GAGf,wBAAwB,MAAA;GAExB,uBAAuB,MAAA;GAEvB,uBAAuB,YAAiB;AACpC,UAAA,kBAAwB,GAAG,WAAW,MAAA,kBAAwB;;GAGlE,sBAAsB,YAAiB;AACnC,UAAA,kBAAwB,IAAI,WAAW,MAAA,kBAAwB;;GAEtE;AACD,QAAA,mBAAyB,IAAI,iBAAiB,yBAAyB;;CAI3E,kBAAkB,SAAyC,YAAiB;AACxE,MAAI,QAAQ,YAAY,cAAc,UAAU,KAAK,KAAK,QAAQ,YAAY,cAAc,sBAAsB,KAAK,EAMnH,OAAA,iBAAuB,QAAQ,MAAA,gBAAsB,KAAK,UAAU,QAAQ,CAAC;WACtE,QAAQ,YAAY,cAAc,WAAW,KAAK,EACzD,OAAA,iBAAuB,QAAQ,MAAA,iBAAuB,KAAK,UAAU,QAAQ,CAAC;;CAKtF,0BAA0B,OAAO,WAA2D,YAAmC;EAiB3H,IAAI,QAAQ;EAGZ,IAAI,eAAe;AACnB,OAAK,MAAM,CAAC,YAAY,aAAa,OAAO,QAAQ,UAAU,CAC1D,KAAI,SAAS,eAAe,KAAK,SAAS,KAAK,SAAS,eAAe,KAAK,GAAG,OAAO;AAClF,kBAAe,SAAS,eAAe,KAAK,GAAG;AAC/C;;AAIR,MAAI,cAAc;GACd,MAAM,iBAAiB,OAAO,OAAO,MAAA,QAAc,CAAC,QAAO,MAAK;AAC5D,QAAI,EAAE,OAAO,QAAQ,aAAa,KAAK,GACnC,QAAO;AAEX,WAAO;KACT;AAGF,WAAQ;AACR,kBAAe,SAAQ,MAAK;AACxB,QAAI,CAAC,UAAU,EAAE,IACb,SAAQ;KAEd;SACC;GACH,MAAM,iBAAiB,OAAO,OAAO,MAAA,QAAc;AAGnD,WAAQ;AACR,kBAAe,SAAQ,MAAK;AACxB,QAAI,CAAC,UAAU,EAAE,IACb,SAAQ;KAEd;;AAGN,SAAO;;CAGX,mBAAmB,SAAyC,YAAsC;AAE9F,SAAO,IAAI,SAAqB,SAAS,WAAW;AAChD,OAAI,QAAQ,YAAY,cAAc,UAAU,KAAK,KAAK,QAAQ,YAAY,cAAc,sBAAsB,KAAK;QAC/G,QAAQ,eAAe,gBAAgB;KACvC,MAAM,YAAY,QAAQ,eAAe;AAEzC,SAAI,MAAA,OAAa,WACb,KAAI;AACA,UAAI,QAAQ,YAAY,cAAc,sBAAsB,KAAK,GAAG;AAChE,aAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,KAAK;AAChE,eAAQ,EAAE,CAAC;YAEX,OAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,OAAO,oBAAyB;AACvF,eAAQ,gBAAgB;QAC1B;cAED,OAAO;AACZ,aAAO,MAAM;;;;IAK/B;;CAIN,GAAY,OAAe,UAAe,KAAiB;AACvD,MAAI,MAAA,OAAa,OAEb,QAAO,MAAA,OAAa;EAExB,MAAM,cAA4B;GAC9B;GACA;GACA;GACH;AACD,QAAA,OAAa,YAAY,SAAS;AAClC,SAAO;;CAGX,IAAa,OAAe,UAAsB;AAC9C,MAAI,MAAA,OAAa,OACb,QAAO,MAAA,OAAa;AAExB,SAAO;;CAGX,cAAc;AACV,QAAA,kBAAwB,OAAO;;CAGnC,aAAa;AACT,MAAI,MAAA,aAAmB;AACnB,gBAAa,MAAA,YAAkB;AAC/B,SAAA,cAAoB;;AAGxB,QAAA,kBAAwB,MAAM;AAE9B,QAAA,kBAAwB,MAAM;AAC9B,QAAA,kBAAwB,YAAY;AAEpC,QAAA,iBAAuB,MAAM;AAC7B,QAAA,iBAAuB,YAAY;;CAGvC,KAAc,OAAe,GAAG,MAAmB;AAC/C,GAAC,YAAY;AACT,OAAI;IACA,MAAM,SAAS,MAAM,MAAA,kBAAwB,YAAY;KACrD,aAAa;KACb,MAAM,KAAK,MAAM,GAAG,KAAK,SAAO,EAAE;KACrC,CAAkB;AAEnB,SAAK,KAAK,SAAO,GAAG,OAAO;YACtB,OAAO;AACZ,QAAI,MAAA,QAAc;SAEV,MAAA,QAAc,aAAa,QAAS,MAAc,YAAY,KAAK,GACnE;;AAGR,UAAA,QAAc,OAAO,MAAM,MAAM,IAAI,uCAAuC,KAAK,UAAU,MAAM,CAAC,GAAG,CAAC;;MAE1G;AACJ,SAAO;;CAGX,cAAc,OAAe,MAAkB,YAAwD,SAAqC;AACxI,GAAC,YAAY;AACT,OAAI;AAMA,eAAW,MALU,MAAA,kBAAwB,YAAY;KACrD,aAAa;KACb,MAAM,CAAE,KAAM;KACjB,CAAkB,CAED;YACb,OAAO;AACZ,QAAI,MAAA,QAAc;SAEV,MAAA,QAAc,aAAa,QAAS,MAAc,YAAY,KAAK,GACnE;;AAIR,YAAQ,MAAM;;MAElB;AACJ,SAAO;;CAGX,SAAS,OAAM,OAAe,GAAG,SAAqC;AAClE,SAAQ,MAAA,iBAA4C,YAAY;GAC5D,aAAa;GACb;GACH,CAAkB;;CAGvB,iBAAiB,OAAM,OAAe,GAAG,SAA+B;AACnE,QAAA,iBAA4C,sBAAsB;GAC/D,aAAa;GACb;GACH,CAAkB;;;;;;;;;;;;ACxZ3B,IAAa,oBAAb,cAAuC,YAAY;CAC/C,oBAA6C;CAC7C;CACA,WAA0C,EAAG;CAC7C,UAAsB,EAAG;CACzB;CAEA,YAAY,SAAmC;AAC3C,SAAO;AACP,QAAA,UAAgB;AAChB,MAAI,QAAQ,KAAK,cAAc,SAAS,KAAK,EACzC,MAAK,aAAa;MAElB,MAAK,cAAc;;CAI3B,IAAI,WAAW;AACX,SAAO,MAAA;;CAGX,aAAa,WAAwB;EACjC,MAAM,KAAK,WAAW,OAAO,YAAY;EAEzC,MAAM,kBAAkB,YAAiB;AACrC,SAAA,kBAAwB,eAAe,SAAS,EAAE,QAAQ,CAAC;;AAG/D,SAAO,GAAG,WAAW,eAAe;AACpC,QAAA,QAAc,MAAM;GAChB;GACA;GACH;AACD,SAAO;;CAGX,gBAAgB,OAAe;EAC3B,MAAM,eAAgB,MAAA,QAAc;AACpC,MAAI,cAAc;AACd,gBAAa,OAAO,IAAI,WAAW,aAAa,eAAe;AAC/D,UAAO,MAAA,QAAc;;;CAI7B,IAAI,UAAU;AACV,SAAO,MAAA;;CAGX,qBAAqB;EACjB,MAAM,2BAAoD;GACtD,QAAQ;GACR,+BAA+B;GAC/B,WAAW,MAAA,QAAc;GACzB,MAAM;GACN,gBAAgB,SAAyC,YAAiB;AACrE,YAAQ,OAAe,KAAK,QAAQ;;GAEzC,uBAAuB,OAAO,SAAyC,YAAsC;AACzG,WAAO,MAAA,eAAqB,SAAS,QAAQ;;GAQjD,uBAAuB,YAAiB;GAGxC,sBAAsB,YAAiB;GAGvC,QAAQ,EAAG;GACd;AACD,QAAA,mBAAyB,IAAI,iBAAiB,yBAAyB;;CAG3E,4BAA4B,YAAiB;AACzC,QAAA,kBAAwB,eAAe,SAAS,MAAA,mBAAyB;;CAG7E,oBAAoB;EAChB,MAAM,2BAAoD;GACtD,QAAQ;GACR,+BAA+B,MAAA,QAAc;GAC7C,WAAW,MAAA,QAAc;GACzB,MAAM;GAEN,gBAAgB,SAAyC,YAAiB;AAErE,YAAgB,KAAK,QAAQ;;GAElC,uBAAuB,OAAO,SAAyC,YAAsC;AACzG,WAAO,MAAA,eAAqB,SAAS,QAAQ;;GAEjD,uBAAuB,YAAiB;AAEpC,UAAA,qBAA2B,EAAE,GAAG,SAAS;AACzC,YAAQ,GAAG,WAAW,MAAA,wBAA8B;;GAExD,sBAAsB,YAAiB;AACnC,YAAQ,IAAI,WAAW,MAAA,wBAA8B;;GAEzD,QAAQ,EAAG;GACd;AACD,QAAA,mBAAyB,IAAI,iBAAiB,yBAAyB;;CAG3E,cAAc,OAAO,YAA6C;AAC9D,MAAI,MAAA,iBACA,KAAI,MAAA,QAAc,KAAK,cAAc,SAAS,KAAK,EAC/C,QAAO,MAAA,kBAAwB,YAAY,SAAS,EAAG,CAAC;OACrD;GAEH,MAAM,YAAmC,EAAG;AAC5C,QAAK,MAAM,CAAC,UAAU,iBAAiB,OAAO,QAAQ,MAAA,QAAc,CAChE,WAAU,KAAK,MAAA,kBAAwB,YAAY,SAAS,EAAE,QAAQ,aAAa,QAAQ,CAAC,CAAC;AAGjG,OAAI;AAEA,WAAO,EACH,QAAQ,MAFS,QAAQ,IAAI,UAAU,EAG1C;YACI,OAAO;AACZ,WAAO,EAAG;;;MAKlB,QAAO,EAAG;;CAIlB,mBAAmB,SAAyC,YAAsC;AAE9F,SAAO,IAAI,SAAqB,SAAS,WAAW;AAChD,OAAI,QAAQ,YAAY,cAAc,UAAU,KAAK,KAAK,QAAQ,YAAY,cAAc,sBAAsB,KAAK;QAC/G,QAAQ,eAAe,gBAAgB;KACvC,MAAM,YAAY,QAAQ,eAAe;AAEzC,SAAI,MAAA,OAAa,WACb,KAAI;AACA,UAAI,QAAQ,YAAY,cAAc,sBAAsB,KAAK,GAAG;AAChE,aAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,KAAK;AAChE,eAAQ,EAAE,CAAC;YAEX,OAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,OAAO,oBAAyB;AACvF,eAAQ,gBAAgB;QAC1B;cAED,OAAO;AACZ,aAAO,MAAM;;;;IAK/B;;CAIN,GAAY,OAAe,UAAe,KAAiB;AACvD,MAAI,MAAA,OAAa,OAEb,QAAO,MAAA,OAAa;EAExB,MAAM,cAAc;GAChB;GACA;GACA;GACH;AACD,QAAA,OAAa,YAAY,SAAS;AAClC,SAAO;;CAIX,IAAa,OAAe,UAAsB;AAC9C,MAAI,MAAA,OAAa,OACb,QAAO,MAAA,OAAa;AAExB,SAAO;;CAKX,cAAc;AACV,QAAA,kBAAwB,MAAM,EAAG,CAAC;;CAItC,aAAa;AACT,QAAA,kBAAwB,KAAK,EAAG,CAAC;;CAmBrC,KAAc,OAAe,GAAG,MAAmB;AAC/C,GAAC,YAAY;AACT,OAAI;IAEA,MAAM,SAAS,MAAM,KAAK,YAAY;KAClC,aAAa;KACb,MAAM,KAAK,MAAM,GAAG,KAAK,SAAO,EAAE;KACrC,CAAkB;AAEnB,SAAK,KAAK,SAAO,GAAG,OAAO;YACtB,OAAO;AACZ,QAAI,MAAA,QAAc;SAEV,MAAA,QAAc,aAAa,QAAS,MAAc,YAAY,KAAK,GACnE;;AAGR,YAAQ,IAAI,MAAM;AAClB,UAAA,QAAc,OAAO,MAAM,MAAM,IAAI,qCAAqC,KAAK,UAAU,MAAM,CAAC,GAAG,CAAC;;MAExG;AACJ,SAAO;;CAGX,iBAAiB,OAAM,OAAe,GAAG,SAA+B;AACpE,MAAI,MAAA,QAAc,KAAK,cAAc,SAAS,KAAK,EAC9C,OAAA,iBAA4C,sBAAsB;GAC/D,aAAa;GACb;GACH,CAAkB;MAGnB,MAAK,MAAM,CAAC,UAAU,iBAAiB,OAAO,QAAQ,MAAA,QAAc,CAC/D,OAAA,iBAA4C,sBAAsB;GAC/D,aAAa;GACb;GACH,EAAmB,EAAE,QAAQ,aAAa,QAAQ,CAAC;;;;;;;;;;;;AC7PpE,IAAa,wBAAb,cAA2C,YAAY;CACnD,oBAA6C;CAC7C;CACA,UAAe;CACf,UAAsB,EAAG;CACzB;CACA,sBAAqC;CAErC,YAAY,SAAuC;AAC/C,SAAO;AACP,QAAA,UAAgB;AAChB,MAAI,QAAQ,KAAK,cAAc,SAAS,KAAK,EACzC,MAAK,aAAa;MAElB,MAAK,cAAc;;CAI3B,IAAI,WAAW;AACX,SAAO,MAAA;;CAGX,6BAA6B,YAAiB;AAC1C,QAAA,kBAAwB,eAAe,SAAS,EAAE,QAAQ,MAAA,oBAAoC,CAAC;;CAGnG,qBAAqB;EACjB,MAAM,2BAAoD;GACtD,QAAQ;GACR,+BAA+B;GAC/B,WAAW,MAAA,QAAc;GACzB,MAAM;GACN,gBAAgB,SAAyC,YAAiB;AACrE,YAAQ,OAAe,KAAK,QAAQ;;GAEzC,uBAAuB,OAAO,SAAyC,YAAsC;AACzG,WAAO,MAAA,eAAqB,SAAS,QAAQ;;GAQjD,uBAAuB,YAAiB;IAEpC,MAAM,SAAU,QAAQ;AACxB,UAAA,qBAA2B;AAC3B,WAAO,GAAG,WAAW,MAAA,yBAA+B;;GAExD,sBAAsB,YAAiB;AACnB,YAAQ,OACjB,IAAI,WAAW,MAAA,yBAA+B;;GAEzD,QAAQ,EAAG;GACd;AACD,QAAA,mBAAyB,IAAI,iBAAiB,yBAAyB;;CAG3E,4BAA4B,YAAiB;AACzC,QAAA,kBAAwB,eAAe,SAAS,MAAA,mBAAyB;;CAG7E,oBAAoB;EAChB,MAAM,2BAAoD;GACtD,QAAQ;GACR,+BAA+B,MAAA,QAAc;GAC7C,WAAW,MAAA,QAAc;GACzB,MAAM;GAEN,gBAAgB,SAAyC,YAAiB;AAErE,YAAgB,KAAK,QAAQ;;GAElC,uBAAuB,OAAO,SAAyC,YAAsC;AACzG,WAAO,MAAA,eAAqB,SAAS,QAAQ;;GAEjD,uBAAuB,YAAiB;AAEpC,UAAA,qBAA2B,EAAE,GAAG,SAAS;AACzC,YAAQ,GAAG,WAAW,MAAA,wBAA8B;;GAExD,sBAAsB,YAAiB;AACnC,YAAQ,IAAI,WAAW,MAAA,wBAA8B;;GAEzD,QAAQ,EAAG;GACd;AACD,QAAA,mBAAyB,IAAI,iBAAiB,yBAAyB;;CAG3E,cAAc,OAAO,YAA6C;AAC9D,MAAI,MAAA,iBACA,KAAI,MAAA,OACA,QAAO,MAAA,kBAAwB,YAAY,SAAS,EAAE,QAAQ,MAAA,QAAc,CAAC;MAE7E,QAAO,MAAA,kBAAwB,YAAY,SAAS,EAAG,CAAC;MAI5D,QAAO,EAAG;;CAIlB,mBAAmB,SAAyC,YAAsC;AAE9F,SAAO,IAAI,SAAqB,SAAS,WAAW;AAChD,OAAI,QAAQ,YAAY,cAAc,UAAU,KAAK,KAAK,QAAQ,YAAY,cAAc,sBAAsB,KAAK;QAC/G,QAAQ,eAAe,gBAAgB;KACvC,MAAM,YAAY,QAAQ,eAAe;AAEzC,SAAI,MAAA,OAAa,WACb,KAAI;AACA,UAAI,QAAQ,YAAY,cAAc,sBAAsB,KAAK,GAAG;AAChE,aAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,KAAK;AAChE,eAAQ,EAAE,CAAC;YAEX,OAAA,OAAa,WAAW,SAAS,GAAG,QAAQ,eAAe,OAAO,oBAAyB;AACvF,eAAQ,gBAAgB;QAC1B;cAED,OAAO;AACZ,aAAO,MAAM;;;;IAK/B;;CAIN,GAAY,OAAe,UAAe,KAAiB;AACvD,MAAI,MAAA,OAAa,OAEb,QAAO,MAAA,OAAa;EAExB,MAAM,cAAc;GAChB;GACA;GACA;GACH;AACD,QAAA,OAAa,YAAY,SAAS;AAClC,SAAO;;CAIX,IAAa,OAAe,UAAsB;AAC9C,MAAI,MAAA,OAAa,OACb,QAAO,MAAA,OAAa;AAExB,SAAO;;CAKX,SAAS,WAAiB;AACtB,MAAI,QAAQ;AACR,SAAA,kBAAwB,MAAM,EAAE,QAAQ,CAAC;AACzC,SAAA,SAAe;QAEf,OAAA,kBAAwB,MAAM,EAAG,CAAC;;CAK1C,aAAa;AACT,MAAI,MAAA,QAAc;AACd,SAAA,kBAAwB,KAAK,EAAE,QAAQ,MAAA,QAAc,CAAC;AACtD,SAAA,SAAe;QAEf,OAAA,kBAAwB,KAAK,EAAG,CAAC;;CAIzC,IAAI,SAAwB;AACxB,SAAO,MAAA;;CAmBX,KAAc,OAAe,GAAG,MAAmB;AAC/C,GAAC,YAAY;AACT,OAAI;IAEA,MAAM,SAAS,MAAM,KAAK,YAAY;KAClC,aAAa;KACb,MAAM,KAAK,MAAM,GAAG,KAAK,SAAO,EAAE;KACrC,CAAkB;AAEnB,SAAK,KAAK,SAAO,GAAG,OAAO;YACtB,OAAO;AACZ,QAAI,MAAA,QAAc;SAEV,MAAA,QAAc,aAAa,QAAS,MAAc,YAAY,KAAK,GACnE;;AAGR,YAAQ,IAAI,MAAM;AAClB,UAAA,QAAc,OAAO,MAAM,MAAM,IAAI,qCAAqC,KAAK,UAAU,MAAM,CAAC,GAAG,CAAC;;MAExG;AACJ,SAAO;;CAGX,iBAAiB,OAAM,OAAe,GAAG,SAA+B;AACnE,QAAA,iBAA4C,sBAAsB;GAC/D,aAAa;GACb;GACH,CAAkB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nsshunt/stsmessaging",
3
- "version": "1.0.67",
3
+ "version": "1.0.69",
4
4
  "description": "STS Messeging",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -41,19 +41,19 @@
41
41
  },
42
42
  "homepage": "https://github.com/nsshunt/stsmessaging#readme",
43
43
  "devDependencies": {
44
- "@types/node": "^25.5.2",
45
- "@typescript-eslint/eslint-plugin": "8.58.1",
46
- "@typescript-eslint/parser": "8.58.1",
47
- "eslint": "^10.2.0",
48
- "globals": "17.4.0",
44
+ "@types/node": "^25.6.0",
45
+ "@typescript-eslint/eslint-plugin": "8.59.1",
46
+ "@typescript-eslint/parser": "8.59.1",
47
+ "eslint": "^10.2.1",
48
+ "globals": "17.5.0",
49
49
  "testcontainers": "11.14.0",
50
50
  "ts-node": "^10.9.2",
51
- "typescript": "^6.0.2",
52
- "vite": "8.0.8",
53
- "vitest": "4.1.3"
51
+ "typescript": "^6.0.3",
52
+ "vite": "8.0.10",
53
+ "vitest": "4.1.5"
54
54
  },
55
55
  "dependencies": {
56
- "@nsshunt/stsutils": "^1.19.100",
56
+ "@nsshunt/stsutils": "^1.19.103",
57
57
  "chalk": "^5.6.2",
58
58
  "ioredis": "^5.10.1",
59
59
  "tiny-emitter": "^2.1.0"