secs4js 0.4.2 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractSecsCommunicator.d.ts","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAWA;AAoBA;AAeA;;AACgB,UApCC,sBAAA,CAoCD;EAAkC,OAAA,EAAA,CAnCvC,WAmCuC,CAAA;EAChD,KAAA,EAAA,CAnCO,KAmCP,CAAA;EAK0B,SAAA,EAAA,EAAA;EAeV,YAAA,EAAA,EAAA;;;;;;;;;;;;;;;AAoEN,UAzGK,sBAAA,CAyGL;EAAR,QAAA,EAAA,MAAA;EAkEU,OAAA,EAAA,OAAA;EAGN,IAAA,CAAA,EAAA,MAAA;EACJ,GAAA,CAAA,EA3KG,gBA2KH;EAmC0B,SAAA,CAAA,EAAA,MAAA;EAhMpB,SAAA,CAAA,EAAA,MAAA;EAAY,SAAA,CAAA,EAAA,MAAA;;;;;;;uBAHA,wCACN,aAAa,qBAAqB,yBAChD,gCACQ,YAAA;;;;6BAIkB;;;;;;;;;;2BAYJ;mBAGN;kBACD;WACP,MAAA,CAAO;;sBAII;mBAoBH;oBACC;;wCAgBoB,SAAS;yFAKtC,eACD,0BACL;sFASI,gDAEJ;2DAMI,2BACJ,QAAQ;oBAkEE,kDAGN,2BACJ;;+BAmC0B"}
1
+ {"version":3,"file":"AbstractSecsCommunicator.d.ts","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAWA;AAoBA;AAeA;;AACgB,UApCC,sBAAA,CAoCD;EAAkC,OAAA,EAAA,CAnCvC,WAmCuC,CAAA;EAChD,KAAA,EAAA,CAnCO,KAmCP,CAAA;EAK0B,SAAA,EAAA,EAAA;EAeV,YAAA,EAAA,EAAA;;;;;;;;;;;;;;;AAoEN,UAzGK,sBAAA,CAyGL;EAAR,QAAA,EAAA,MAAA;EAmEU,OAAA,EAAA,OAAA;EAGN,IAAA,CAAA,EAAA,MAAA;EACJ,GAAA,CAAA,EA5KG,gBA4KH;EA0C0B,SAAA,CAAA,EAAA,MAAA;EAxMpB,SAAA,CAAA,EAAA,MAAA;EAAY,SAAA,CAAA,EAAA,MAAA;;;;;;;uBAHA,wCACN,aAAa,qBAAqB,yBAChD,gCACQ,YAAA;;;;6BAIkB;;;;;;;;;;2BAYJ;mBAGN;kBACD;WACP,MAAA,CAAO;;sBAII;mBAoBH;oBACC;;wCAgBoB,SAAS;yFAKtC,eACD,0BACL;sFASI,gDAEJ;2DAMI,2BACJ,QAAQ;oBAmEE,kDAGN,2BACJ;;+BA0C0B"}
@@ -47,7 +47,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
47
47
  const systemBytes = this.getNextSystemBytes();
48
48
  const msg = this.createMessage(stream, func, wBit, body, systemBytes);
49
49
  const sml = msg.toSml();
50
- this.logger.logSecs2("Sent", sml);
50
+ const buffer = msg.toBuffer();
51
+ this.logger.logSecs2("Sent", sml, this.deviceId, systemBytes, buffer);
51
52
  this.logger.detail.debug({
52
53
  protocol: "SECS",
53
54
  dir: "Sent",
@@ -69,7 +70,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
69
70
  reject,
70
71
  timer
71
72
  });
72
- this.sendBufferWithLogs("Sent", "SECS", msg.toBuffer(), {
73
+ this.sendBufferWithLogs("Sent", "SECS", buffer, {
73
74
  stream,
74
75
  func,
75
76
  wBit,
@@ -88,7 +89,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
88
89
  });
89
90
  });
90
91
  else {
91
- await this.sendBufferWithLogs("Sent", "SECS", msg.toBuffer(), {
92
+ await this.sendBufferWithLogs("Sent", "SECS", buffer, {
92
93
  stream,
93
94
  func,
94
95
  wBit,
@@ -100,7 +101,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
100
101
  async reply(primaryMsg, stream, func, body = null) {
101
102
  const msg = this.createMessage(stream, func, false, body, primaryMsg.systemBytes);
102
103
  const sml = msg.toSml();
103
- this.logger.logSecs2("Sent", sml);
104
+ const buffer = msg.toBuffer();
105
+ this.logger.logSecs2("Sent", sml, this.deviceId, primaryMsg.systemBytes, buffer);
104
106
  this.logger.detail.debug({
105
107
  protocol: "SECS",
106
108
  dir: "Sent",
@@ -110,7 +112,7 @@ var AbstractSecsCommunicator = class extends EventEmitter {
110
112
  systemBytes: primaryMsg.systemBytes,
111
113
  sml
112
114
  }, "sml");
113
- await this.sendBufferWithLogs("Sent", "SECS", msg.toBuffer(), {
115
+ await this.sendBufferWithLogs("Sent", "SECS", buffer, {
114
116
  stream,
115
117
  func,
116
118
  wBit: false,
@@ -123,7 +125,8 @@ var AbstractSecsCommunicator = class extends EventEmitter {
123
125
  }
124
126
  handleMessage(msg) {
125
127
  const sml = msg.toSml();
126
- this.logger.logSecs2("Received", sml);
128
+ const buffer = msg.toBuffer();
129
+ this.logger.logSecs2("Received", sml, this.deviceId, msg.systemBytes, buffer);
127
130
  this.logger.detail.debug({
128
131
  protocol: "SECS",
129
132
  dir: "Received",
@@ -1 +1 @@
1
- {"version":3,"file":"AbstractSecsCommunicator.js","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { SecsMessage } from \"./AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"./secs2item/AbstractSecs2Item.js\";\nimport { SecsLogger, type SecsLoggerConfig } from \"../logging/SecsLogger.js\";\n\n/**\n * @param message The message received.\n * @param error The error occurred.\n * @param connected The connection is established.\n * @param disconnected The connection is closed.\n */\nexport interface SecsCommunicatorEvents {\n\tmessage: [SecsMessage];\n\terror: [Error];\n\tconnected: [];\n\tdisconnected: [];\n}\n\n/**\n * @param deviceId The device ID.\n * @param isEquip Whether the device is an equip.\n * @param name The name of the connection.\n * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.\n * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.\n * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.\n * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.\n * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.\n * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.\n * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.\n * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message\n */\nexport interface SecsCommunicatorConfig {\n\tdeviceId: number;\n\tisEquip: boolean;\n\tname?: string;\n\tlog?: SecsLoggerConfig;\n\ttimeoutT1?: number;\n\ttimeoutT2?: number;\n\ttimeoutT3?: number;\n\ttimeoutT4?: number;\n\ttimeoutT5?: number;\n\ttimeoutT6?: number;\n\ttimeoutT7?: number;\n\ttimeoutT8?: number;\n}\n\nexport abstract class AbstractSecsCommunicator<\n\tEvents extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents =\n\t\tSecsCommunicatorEvents,\n> extends EventEmitter {\n\tpublic readonly deviceId: number;\n\tpublic readonly isEquip: boolean;\n\tpublic readonly name: string;\n\tprotected readonly logger: SecsLogger;\n\n\tpublic timeoutT1 = 1;\n\tpublic timeoutT2 = 15;\n\tpublic timeoutT3 = 45;\n\tpublic timeoutT4 = 45;\n\tpublic timeoutT5 = 10;\n\tpublic timeoutT6 = 5;\n\tpublic timeoutT7 = 10;\n\tpublic timeoutT8 = 5;\n\n\tprotected _systemBytesCounter = 0;\n\tprotected _transactions = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (msg: SecsMessage) => void;\n\t\t\treject: (err: Error) => void;\n\t\t\ttimer: NodeJS.Timeout;\n\t\t}\n\t>();\n\n\tconstructor(config: SecsCommunicatorConfig) {\n\t\tsuper();\n\t\tthis.deviceId = config.deviceId;\n\t\tthis.isEquip = config.isEquip;\n\t\tthis.name = config.name ?? \"SecsCommunicator\";\n\t\tif (config.timeoutT1 !== undefined) this.timeoutT1 = config.timeoutT1;\n\t\tif (config.timeoutT2 !== undefined) this.timeoutT2 = config.timeoutT2;\n\t\tif (config.timeoutT3 !== undefined) this.timeoutT3 = config.timeoutT3;\n\t\tif (config.timeoutT4 !== undefined) this.timeoutT4 = config.timeoutT4;\n\t\tif (config.timeoutT5 !== undefined) this.timeoutT5 = config.timeoutT5;\n\t\tif (config.timeoutT6 !== undefined) this.timeoutT6 = config.timeoutT6;\n\t\tif (config.timeoutT7 !== undefined) this.timeoutT7 = config.timeoutT7;\n\t\tif (config.timeoutT8 !== undefined) this.timeoutT8 = config.timeoutT8;\n\t\tthis.logger = SecsLogger.create(config.log, {\n\t\t\tname: this.name,\n\t\t\tdeviceId: this.deviceId,\n\t\t\tisEquip: this.isEquip,\n\t\t});\n\t}\n\n\tabstract open(): Promise<void>;\n\tabstract close(): Promise<void>;\n\n\tprotected emitInternal(\n\t\teventName: string | symbol,\n\t\t...args: unknown[]\n\t): boolean {\n\t\treturn (\n\t\t\tsuper.emit as (\n\t\t\t\tthis: AbstractSecsCommunicator<Events>,\n\t\t\t\teventName: string | symbol,\n\t\t\t\t...args: unknown[]\n\t\t\t) => boolean\n\t\t).call(this, eventName, ...args);\n\t}\n\n\t// This method sends the message bytes. To be implemented by subclasses.\n\tprotected abstract sendBuffer(buffer: Buffer): Promise<void>;\n\n\tprotected async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tthis.logger.logBytes(direction, protocol, buffer, meta);\n\t\tawait this.sendBuffer(buffer);\n\t}\n\n\tprotected abstract createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage;\n\n\tasync send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = this.createMessage(stream, func, wBit, body, systemBytes);\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Sent\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\n\t\tif (wBit) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\tif (this._transactions.has(systemBytes)) {\n\t\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, this.timeoutT3 * 1000);\n\n\t\t\t\tthis._transactions.set(systemBytes, { resolve, reject, timer });\n\n\t\t\t\tthis.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\t\t\tstream,\n\t\t\t\t\tfunc,\n\t\t\t\t\twBit,\n\t\t\t\t\tsystemBytes,\n\t\t\t\t}).catch((err: unknown) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\tthis.logger.detail.error(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terr: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"send failed\",\n\t\t\t\t\t);\n\t\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync reply(\n\t\tprimaryMsg: SecsMessage,\n\t\tstream: number,\n\t\tfunc: number,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<void> {\n\t\tconst msg = this.createMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\tfalse,\n\t\t\tbody,\n\t\t\tprimaryMsg.systemBytes,\n\t\t);\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Sent\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit: false,\n\t\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", msg.toBuffer(), {\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit: false,\n\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t});\n\t}\n\n\tprotected getNextSystemBytes(): number {\n\t\tthis._systemBytesCounter = (this._systemBytesCounter + 1) >>> 0; // Ensure 32-bit unsigned\n\t\treturn this._systemBytesCounter;\n\t}\n\n\tprotected handleMessage(msg: SecsMessage) {\n\t\tconst sml = msg.toSml();\n\t\tthis.logger.logSecs2(\"Received\", sml);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Received\",\n\t\t\t\tstream: msg.stream,\n\t\t\t\tfunc: msg.func,\n\t\t\t\twBit: msg.wBit,\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"message\",\n\t\t);\n\t\t// Check if it's a reply\n\t\t// Usually, if we have a transaction waiting for this SystemBytes, we treat it as a reply.\n\t\t// However, Stream 0 (HSMS Control) messages are never replies to SECS-II messages.\n\t\t// SECS-II replies usually have the same SystemBytes as the primary.\n\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// If not a reply, emit event\n\t\tthis.emitInternal(\"message\", msg);\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AbstractSecsCommunicator.js","names":[],"sources":["../../src/core/AbstractSecsCommunicator.ts"],"sourcesContent":["import { EventEmitter } from \"events\";\nimport { SecsMessage } from \"./AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"./secs2item/AbstractSecs2Item.js\";\nimport { SecsLogger, type SecsLoggerConfig } from \"../logging/SecsLogger.js\";\n\n/**\n * @param message The message received.\n * @param error The error occurred.\n * @param connected The connection is established.\n * @param disconnected The connection is closed.\n */\nexport interface SecsCommunicatorEvents {\n\tmessage: [SecsMessage];\n\terror: [Error];\n\tconnected: [];\n\tdisconnected: [];\n}\n\n/**\n * @param deviceId The device ID.\n * @param isEquip Whether the device is an equip.\n * @param name The name of the connection.\n * @param timeoutT1 Only SECS-I supports this parameter, ENQ retransmission interval.\n * @param timeoutT2 Only SECS-I supports this parameter, ENQ wait-for-response timeout.\n * @param timeoutT3 Support SECS-I and SECS-II, W-Bit timeout.\n * @param timeoutT4 Only SECS-I supports this parameter, data block retransmission interval.\n * @param timeoutT5 Support SECS-I and SECS-II, establishment of communication session timeout.\n * @param timeoutT6 Only HSMS supports this parameter, reply control message timeout.\n * @param timeoutT7 Only HSMS supports this parameter, create connection timeout.\n * @param timeoutT8 Only HSMS supports this parameter, the maximum time interval between message bytes when receiving a message\n */\nexport interface SecsCommunicatorConfig {\n\tdeviceId: number;\n\tisEquip: boolean;\n\tname?: string;\n\tlog?: SecsLoggerConfig;\n\ttimeoutT1?: number;\n\ttimeoutT2?: number;\n\ttimeoutT3?: number;\n\ttimeoutT4?: number;\n\ttimeoutT5?: number;\n\ttimeoutT6?: number;\n\ttimeoutT7?: number;\n\ttimeoutT8?: number;\n}\n\nexport abstract class AbstractSecsCommunicator<\n\tEvents extends Record<keyof Events, unknown[]> & SecsCommunicatorEvents =\n\t\tSecsCommunicatorEvents,\n> extends EventEmitter {\n\tpublic readonly deviceId: number;\n\tpublic readonly isEquip: boolean;\n\tpublic readonly name: string;\n\tprotected readonly logger: SecsLogger;\n\n\tpublic timeoutT1 = 1;\n\tpublic timeoutT2 = 15;\n\tpublic timeoutT3 = 45;\n\tpublic timeoutT4 = 45;\n\tpublic timeoutT5 = 10;\n\tpublic timeoutT6 = 5;\n\tpublic timeoutT7 = 10;\n\tpublic timeoutT8 = 5;\n\n\tprotected _systemBytesCounter = 0;\n\tprotected _transactions = new Map<\n\t\tnumber,\n\t\t{\n\t\t\tresolve: (msg: SecsMessage) => void;\n\t\t\treject: (err: Error) => void;\n\t\t\ttimer: NodeJS.Timeout;\n\t\t}\n\t>();\n\n\tconstructor(config: SecsCommunicatorConfig) {\n\t\tsuper();\n\t\tthis.deviceId = config.deviceId;\n\t\tthis.isEquip = config.isEquip;\n\t\tthis.name = config.name ?? \"SecsCommunicator\";\n\t\tif (config.timeoutT1 !== undefined) this.timeoutT1 = config.timeoutT1;\n\t\tif (config.timeoutT2 !== undefined) this.timeoutT2 = config.timeoutT2;\n\t\tif (config.timeoutT3 !== undefined) this.timeoutT3 = config.timeoutT3;\n\t\tif (config.timeoutT4 !== undefined) this.timeoutT4 = config.timeoutT4;\n\t\tif (config.timeoutT5 !== undefined) this.timeoutT5 = config.timeoutT5;\n\t\tif (config.timeoutT6 !== undefined) this.timeoutT6 = config.timeoutT6;\n\t\tif (config.timeoutT7 !== undefined) this.timeoutT7 = config.timeoutT7;\n\t\tif (config.timeoutT8 !== undefined) this.timeoutT8 = config.timeoutT8;\n\t\tthis.logger = SecsLogger.create(config.log, {\n\t\t\tname: this.name,\n\t\t\tdeviceId: this.deviceId,\n\t\t\tisEquip: this.isEquip,\n\t\t});\n\t}\n\n\tabstract open(): Promise<void>;\n\tabstract close(): Promise<void>;\n\n\tprotected emitInternal(\n\t\teventName: string | symbol,\n\t\t...args: unknown[]\n\t): boolean {\n\t\treturn (\n\t\t\tsuper.emit as (\n\t\t\t\tthis: AbstractSecsCommunicator<Events>,\n\t\t\t\teventName: string | symbol,\n\t\t\t\t...args: unknown[]\n\t\t\t) => boolean\n\t\t).call(this, eventName, ...args);\n\t}\n\n\t// This method sends the message bytes. To be implemented by subclasses.\n\tprotected abstract sendBuffer(buffer: Buffer): Promise<void>;\n\n\tprotected async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tthis.logger.logBytes(direction, protocol, buffer, meta);\n\t\tawait this.sendBuffer(buffer);\n\t}\n\n\tprotected abstract createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage;\n\n\tasync send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = this.createMessage(stream, func, wBit, body, systemBytes);\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\"Sent\", sml, this.deviceId, systemBytes, buffer);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\n\t\tif (wBit) {\n\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\tconst timer = setTimeout(() => {\n\t\t\t\t\tif (this._transactions.has(systemBytes)) {\n\t\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t`T3 Timeout waiting for reply to S${String(stream)}F${String(func)} [SysBytes=${String(systemBytes)}]`,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}, this.timeoutT3 * 1000);\n\n\t\t\t\tthis._transactions.set(systemBytes, { resolve, reject, timer });\n\n\t\t\t\tthis.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\t\t\tstream,\n\t\t\t\t\tfunc,\n\t\t\t\t\twBit,\n\t\t\t\t\tsystemBytes,\n\t\t\t\t}).catch((err: unknown) => {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\t\tthis.logger.detail.error(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terr: err instanceof Error ? err : new Error(String(err)),\n\t\t\t\t\t\t\tstream,\n\t\t\t\t\t\t\tfunc,\n\t\t\t\t\t\t\twBit,\n\t\t\t\t\t\t\tsystemBytes,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t\"send failed\",\n\t\t\t\t\t);\n\t\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t\t});\n\t\t\t});\n\t\t} else {\n\t\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit,\n\t\t\t\tsystemBytes,\n\t\t\t});\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tasync reply(\n\t\tprimaryMsg: SecsMessage,\n\t\tstream: number,\n\t\tfunc: number,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<void> {\n\t\tconst msg = this.createMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\tfalse,\n\t\t\tbody,\n\t\t\tprimaryMsg.systemBytes,\n\t\t);\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\n\t\t\t\"Sent\",\n\t\t\tsml,\n\t\t\tthis.deviceId,\n\t\t\tprimaryMsg.systemBytes,\n\t\t\tbuffer,\n\t\t);\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Sent\",\n\t\t\t\tstream,\n\t\t\t\tfunc,\n\t\t\t\twBit: false,\n\t\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"sml\",\n\t\t);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"SECS\", buffer, {\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit: false,\n\t\t\tsystemBytes: primaryMsg.systemBytes,\n\t\t});\n\t}\n\n\tprotected getNextSystemBytes(): number {\n\t\tthis._systemBytesCounter = (this._systemBytesCounter + 1) >>> 0; // Ensure 32-bit unsigned\n\t\treturn this._systemBytesCounter;\n\t}\n\n\tprotected handleMessage(msg: SecsMessage) {\n\t\tconst sml = msg.toSml();\n\t\tconst buffer = msg.toBuffer();\n\t\tthis.logger.logSecs2(\n\t\t\t\"Received\",\n\t\t\tsml,\n\t\t\tthis.deviceId,\n\t\t\tmsg.systemBytes,\n\t\t\tbuffer,\n\t\t);\n\n\t\tthis.logger.detail.debug(\n\t\t\t{\n\t\t\t\tprotocol: \"SECS\",\n\t\t\t\tdir: \"Received\",\n\t\t\t\tstream: msg.stream,\n\t\t\t\tfunc: msg.func,\n\t\t\t\twBit: msg.wBit,\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\tsml,\n\t\t\t},\n\t\t\t\"message\",\n\t\t);\n\t\t// Check if it's a reply\n\t\t// Usually, if we have a transaction waiting for this SystemBytes, we treat it as a reply.\n\t\t// However, Stream 0 (HSMS Control) messages are never replies to SECS-II messages.\n\t\t// SECS-II replies usually have the same SystemBytes as the primary.\n\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// If not a reply, emit event\n\t\tthis.emitInternal(\"message\", msg);\n\t}\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"HsmsCommunicator.d.ts","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;aAaY,SAAA;;EAAA,SAAA,GAAS,WAAA;EAAA;EAYJ,QAAA,GAAA,UAAA;AAMjB;AAKA;;;;;;AA0BU,UArCO,sBAAA,SAA+B,sBAqCtC,CAAA;EACD,EAAA,EAAA,MAAA;EACL,IAAA,EAAA,MAAA;EAYgC,gBAAA,CAAA,EAAA,MAAA;;AAiB5B,UA9DS,sBAAA,SAA+B,sBA8DxC,CAAA;EAEJ,QAAA,EAAA,EAAA;EAckC,UAAA,EAAA,EAAA;;AA0NN,uBAnSV,gBAAA,SAAyB,wBAmSf,CAnSwC,sBAmSxC,CAAA,CAAA;EA0BE,EAAA,EAAA,MAAA;EAIA,IAAA,EAAA,MAAA;EAWA,UAAA,MAAA,EAxUf,MAwUe,GAAA,IAAA;EAcA,UAAA,KAAA,EArVhB,SAqVgB;EAoBC,QAAA,MAAA;EAYC,QAAA,OAAA;EAA2B,QAAA,OAAA;EASzB,IAAA,eAAA,CAAA,CAAA,EAtXP,SAsXO;EAA2B,WAAA,CAAA,MAAA,EAlX5C,sBAkX4C;EAS3B,UAAA,kBAAA,CAAA,SAAA,EAAA,MAAA,GAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAlX5B,MAkX4B,EAAA,IAAA,CAAA,EAjX7B,MAiX6B,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EAhXlC,OAgXkC,CAAA,IAAA,CAAA;EAAW,UAAA,UAAA,CAAA,MAAA,EApWb,MAoWa,CAAA,EApWJ,OAoWI,CAAA,IAAA,CAAA;EAQhB,UAAA,aAAA,CAAA,MAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,OAAA,EAAA,IAAA,EA3VzB,iBA2VyB,GAAA,IAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EAzV7B,WAyV6B;EAAqB,UAAA,kBAAA,CAAA,MAAA,EA3UhB,MA2UgB,CAAA,EAAA,IAAA;EAAY,QAAA,YAAA;EAa1D,QAAA,YAAA;EACI,QAAA,YAAA;EAAR,QAAA,YAAA;EAQmC,QAAA,aAAA;EAAR,QAAA,kBAAA;EA+BE,QAAA,oBAAA;EA+BA,UAAA,eAAA,CAAA,GAAA,EAxND,WAwNC,CAAA,EAAA,IAAA;EAxec,UAAA,eAAA,CAAA,GAAA,EAmSf,WAnSe,CAAA,EAAA,IAAA;EAAwB,UAAA,iBAAA,CAAA,GAAA,EA6TrC,WA7TqC,CAAA,EAAA,IAAA;mCAiUrC;mCAWA;mCAcA;oCAoBC;+BAYC,8BAA2B;iCASzB,8BAA2B;iCAS3B,cAAW;4BAQhB,qBAAqB,eAAY;2DAa1D,2BACJ,QAAQ;mBAQmB,QAAQ;qBA+BN;qBA+BA"}
1
+ {"version":3,"file":"HsmsCommunicator.d.ts","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":[],"mappings":";;;;;;;;;aAaY,SAAA;;EAAA,SAAA,GAAS,WAAA;EAAA;EAYJ,QAAA,GAAA,UAAA;AAMjB;AAKA;;;;;;AA0BU,UArCO,sBAAA,SAA+B,sBAqCtC,CAAA;EACD,EAAA,EAAA,MAAA;EACL,IAAA,EAAA,MAAA;EAYgC,gBAAA,CAAA,EAAA,MAAA;;AAiB5B,UA9DS,sBAAA,SAA+B,sBA8DxC,CAAA;EAEJ,QAAA,EAAA,EAAA;EAckC,UAAA,EAAA,EAAA;;AAgON,uBAzSV,gBAAA,SAAyB,wBAySf,CAzSwC,sBAySxC,CAAA,CAAA;EA0BE,EAAA,EAAA,MAAA;EAIA,IAAA,EAAA,MAAA;EAWA,UAAA,MAAA,EA9Uf,MA8Ue,GAAA,IAAA;EAcA,UAAA,KAAA,EA3VhB,SA2VgB;EAoBC,QAAA,MAAA;EAYC,QAAA,OAAA;EAA2B,QAAA,OAAA;EASzB,IAAA,eAAA,CAAA,CAAA,EA5XP,SA4XO;EAA2B,WAAA,CAAA,MAAA,EAxX5C,sBAwX4C;EAS3B,UAAA,kBAAA,CAAA,SAAA,EAAA,MAAA,GAAA,UAAA,EAAA,QAAA,EAAA,MAAA,EAAA,MAAA,EAxX5B,MAwX4B,EAAA,IAAA,CAAA,EAvX7B,MAuX6B,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA,EAtXlC,OAsXkC,CAAA,IAAA,CAAA;EAAW,UAAA,UAAA,CAAA,MAAA,EA1Wb,MA0Wa,CAAA,EA1WJ,OA0WI,CAAA,IAAA,CAAA;EAQhB,UAAA,aAAA,CAAA,MAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,OAAA,EAAA,IAAA,EAjWzB,iBAiWyB,GAAA,IAAA,EAAA,WAAA,EAAA,MAAA,CAAA,EA/V7B,WA+V6B;EAAqB,UAAA,kBAAA,CAAA,MAAA,EAjVhB,MAiVgB,CAAA,EAAA,IAAA;EAAY,QAAA,YAAA;EAa1D,QAAA,YAAA;EACI,QAAA,YAAA;EAAR,QAAA,YAAA;EAQmC,QAAA,aAAA;EAAR,QAAA,kBAAA;EA+BE,QAAA,oBAAA;EA+BA,UAAA,eAAA,CAAA,GAAA,EAxND,WAwNC,CAAA,EAAA,IAAA;EA9ec,UAAA,eAAA,CAAA,GAAA,EAySf,WAzSe,CAAA,EAAA,IAAA;EAAwB,UAAA,iBAAA,CAAA,GAAA,EAmUrC,WAnUqC,CAAA,EAAA,IAAA;mCAuUrC;mCAWA;mCAcA;oCAoBC;+BAYC,8BAA2B;iCASzB,8BAA2B;iCAS3B,cAAW;4BAQhB,qBAAqB,eAAY;2DAa1D,2BACJ,QAAQ;mBAQmB,QAAQ;qBA+BN;qBA+BA"}
@@ -163,7 +163,7 @@ var HsmsCommunicator = class extends AbstractSecsCommunicator {
163
163
  return;
164
164
  }
165
165
  if (this.state !== HsmsState.Selected) {
166
- this.logger.logSecs2("Received", msg.toSml());
166
+ this.logger.logSecs2("Received", msg.toSml(), this.deviceId, msg.systemBytes, msg.toBuffer());
167
167
  this.sendReject(msg, RejectReason.NotSelected);
168
168
  return;
169
169
  }
@@ -1 +1 @@
1
- {"version":3,"file":"HsmsCommunicator.js","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":["import { Socket } from \"net\";\nimport {\n\tAbstractSecsCommunicator,\n\tSecsCommunicatorConfig,\n\tSecsCommunicatorEvents,\n} from \"../core/AbstractSecsCommunicator.js\";\nimport { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { HsmsMessage } from \"./HsmsMessage.js\";\nimport { HsmsControlType } from \"./enums/HsmsControlType.js\";\nimport { SelectStatus } from \"./enums/SelectStatus.js\";\nimport { RejectReason } from \"./enums/RejectReason.js\";\n\nexport enum HsmsState {\n\tNotConnected = \"NotConnected\",\n\tConnected = \"Connected\", // TCP Connected\n\tSelected = \"Selected\", // HSMS Selected\n}\n\n/**\n * @description HsmsCommunicatorConfig is the configuration interface for HsmsCommunicator.\n * @param ip The IP address of the remote device.\n * @param port The port number of the remote device.\n * @param linkTestInterval The interval in milliseconds to send link test messages.\n */\nexport interface HsmsCommunicatorConfig extends SecsCommunicatorConfig {\n\tip: string;\n\tport: number;\n\tlinkTestInterval?: number;\n}\n\nexport interface HsmsCommunicatorEvents extends SecsCommunicatorEvents {\n\tselected: [];\n\tdeselected: [];\n}\n\nexport abstract class HsmsCommunicator extends AbstractSecsCommunicator<HsmsCommunicatorEvents> {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprotected socket: Socket | null = null;\n\tprotected state: HsmsState = HsmsState.NotConnected;\n\tprivate buffer: Buffer = Buffer.alloc(0);\n\tprivate t7Timer: NodeJS.Timeout | null = null;\n\tprivate t8Timer: NodeJS.Timeout | null = null;\n\n\t// T6 Timer (Control Transaction)\n\t// We use the same _transactions map for Control messages if they expect reply\n\n\tpublic get connectionState(): HsmsState {\n\t\treturn this.state;\n\t}\n\n\tconstructor(config: HsmsCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t}\n\n\tprotected override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"HSMS\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\thsmsState: this.state,\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected async sendBuffer(buffer: Buffer): Promise<void> {\n\t\tconst socket = this.socket;\n\t\tif (!socket || socket.destroyed) {\n\t\t\tthrow new Error(\"Socket not connected\");\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tsocket.write(buffer, (err) => {\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprotected createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage {\n\t\t// For Data messages, pType=0, sType=0 (Data)\n\t\treturn new HsmsMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit,\n\t\t\tbody,\n\t\t\tsystemBytes,\n\t\t\tthis.deviceId,\n\t\t\t0,\n\t\t\tHsmsControlType.Data,\n\t\t);\n\t}\n\n\tprotected handleSocketEvents(socket: Socket) {\n\t\tthis.socket = socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, {\n\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\tremotePort: socket.remotePort,\n\t\t});\n\t\tthis.resetT7Timer();\n\t\tthis.emit(\"connected\");\n\n\t\tsocket.on(\"data\", (data) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", data, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\n\t\t\tthis.buffer = Buffer.concat([this.buffer, data]);\n\t\t\tthis.resetT8Timer();\n\t\t\tthis.processBuffer();\n\t\t\tif (this.buffer.length === 0) {\n\t\t\t\tthis.clearT8Timer();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"close\", () => {\n\t\t\tthis.rejectAllTransactions(new Error(\"Socket closed\"));\n\t\t\tthis.clearT7Timer();\n\t\t\tthis.clearT8Timer();\n\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\tconst prevState = this.state;\n\t\t\tthis.state = HsmsState.NotConnected;\n\t\t\tthis.logger.logState(\"HSMS\", prevState, this.state, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t});\n\t\t\tthis.socket = null;\n\t\t\tthis.emit(\"disconnected\");\n\t\t});\n\n\t\tsocket.on(\"end\", () => {\n\t\t\tif (this.socket && !this.socket.destroyed) {\n\t\t\t\tthis.socket.destroy();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"error\", (err) => {\n\t\t\tthis.emit(\"error\", err);\n\t\t\tif (!socket.destroyed) {\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate resetT7Timer() {\n\t\tthis.clearT7Timer();\n\t\tif (this.timeoutT7 <= 0) return;\n\t\tthis.t7Timer = setTimeout(() => {\n\t\t\tthis.t7Timer = null;\n\t\t\tif (this.state === HsmsState.Selected) return;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T7 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT7 * 1000);\n\t}\n\n\tprivate clearT7Timer() {\n\t\tif (this.t7Timer) {\n\t\t\tclearTimeout(this.t7Timer);\n\t\t\tthis.t7Timer = null;\n\t\t}\n\t}\n\n\tprivate resetT8Timer() {\n\t\tthis.clearT8Timer();\n\t\tif (this.timeoutT8 <= 0) return;\n\t\tthis.t8Timer = setTimeout(() => {\n\t\t\tthis.t8Timer = null;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed && this.buffer.length > 0) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T8 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT8 * 1000);\n\t}\n\n\tprivate clearT8Timer() {\n\t\tif (this.t8Timer) {\n\t\t\tclearTimeout(this.t8Timer);\n\t\t\tthis.t8Timer = null;\n\t\t}\n\t}\n\n\tprivate processBuffer() {\n\t\twhile (true) {\n\t\t\tif (this.buffer.length < 4) return;\n\n\t\t\tconst length = this.buffer.readUInt32BE(0);\n\t\t\tif (length < 10) {\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tthis.emit(\"error\", new Error(\"Receive message size < 10\"));\n\t\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\t\tsocket.destroy();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.buffer.length < 4 + length) return;\n\n\t\t\tconst msgBuffer = this.buffer.subarray(0, 4 + length);\n\t\t\tthis.buffer = this.buffer.subarray(4 + length);\n\n\t\t\ttry {\n\t\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", msgBuffer, {\n\t\t\t\t\tframeLength: length,\n\t\t\t\t});\n\t\t\t\tconst msg = HsmsMessage.fromBuffer(msgBuffer);\n\t\t\t\tthis.processHsmsMessage(msg);\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${err.message}`),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${String(err)}`),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate processHsmsMessage(msg: HsmsMessage) {\n\t\t// Handle Control Messages\n\t\tif (msg.sType !== HsmsControlType.Data) {\n\t\t\tthis.logger.detail.debug(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"HSMS\",\n\t\t\t\t\tcontrolType: msg.sType,\n\t\t\t\t\tpType: msg.pType,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\t},\n\t\t\t\t\"control\",\n\t\t\t);\n\t\t\tthis.handleControlMessage(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle Data Messages\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tthis.logger.logSecs2(\"Received\", msg.toSml());\n\t\t\tvoid this.sendReject(msg, RejectReason.NotSelected);\n\t\t\treturn;\n\t\t}\n\n\t\tsuper.handleMessage(msg);\n\t}\n\n\tprivate handleControlMessage(msg: HsmsMessage) {\n\t\tswitch (msg.sType as HsmsControlType) {\n\t\t\tcase HsmsControlType.SelectReq:\n\t\t\t\tthis.handleSelectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SelectRsp:\n\t\t\t\tthis.handleSelectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectReq:\n\t\t\t\tthis.handleDeselectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectRsp:\n\t\t\t\tthis.handleDeselectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestReq:\n\t\t\t\tthis.handleLinkTestReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestRsp:\n\t\t\t\tthis.handleLinkTestRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SeparateReq:\n\t\t\t\tthis.handleSeparateReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.RejectReq:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tvoid this.sendReject(\n\t\t\t\t\tmsg,\n\t\t\t\t\tmsg.pType !== 0\n\t\t\t\t\t\t? RejectReason.NotSupportTypeP\n\t\t\t\t\t\t: RejectReason.NotSupportTypeS,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprotected handleSelectReq(msg: HsmsMessage) {\n\t\t// Subclasses might override, but default behavior:\n\t\t// If already selected, return Actived/AlreadyUsed?\n\t\t// If not, accept.\n\n\t\t// Note: HSMS-SS says only one host.\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Actived); // Or AlreadyUsed?\n\t\t} else {\n\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\n\t\t\tthis.state = HsmsState.Selected;\n\t\t\tthis.clearT7Timer();\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"selected\");\n\t\t}\n\t}\n\n\tprotected handleSelectRsp(msg: HsmsMessage) {\n\t\t// Check if we are waiting for this.\n\t\t// Usually managed by sendSelectReq promise.\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\t// If status is Success, set state to Selected\n\t\t\t// msg.func holds the status (byte 3) if we mapped it correctly in HsmsMessage.fromBuffer\n\t\t\t// In HsmsMessage.fromBuffer, for Control msg, func = byte 3.\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success || status === SelectStatus.Actived) {\n\t\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\t\tselectStatus: status,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\n\t\t\t\tthis.state = HsmsState.Selected;\n\t\t\t\tthis.clearT7Timer();\n\t\t\t\tthis.emit(\"selected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleLinkTestReq(msg: HsmsMessage) {\n\t\tvoid this.sendLinkTestRsp(msg);\n\t}\n\n\tprotected handleLinkTestRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleDeselectReq(msg: HsmsMessage) {\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\n\t\t\tthis.state = HsmsState.Connected;\n\t\t\tthis.resetT7Timer();\n\t\t\tvoid this.sendDeselectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"deselected\");\n\t\t\treturn;\n\t\t}\n\t\tvoid this.sendDeselectRsp(msg, SelectStatus.NotReady);\n\t}\n\n\tprotected handleDeselectRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success) {\n\t\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\n\t\t\t\tthis.state = HsmsState.Connected;\n\t\t\t\tthis.resetT7Timer();\n\t\t\t\tthis.emit(\"deselected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleSeparateReq(_msg: HsmsMessage) {\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state);\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\t// Helper senders\n\tprotected async sendSelectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.selectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SelectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendDeselectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.deselectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.DeselectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendLinkTestRsp(req: HsmsMessage) {\n\t\tconst rsp = HsmsMessage.linkTestRsp(req);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.LinkTestRsp,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendReject(req: HsmsMessage, reason: RejectReason) {\n\t\tconst rsp = HsmsMessage.rejectReq(req, reason);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.RejectReq,\n\t\t\treason,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\toverride async send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tthrow new Error(\"HSMS not selected\");\n\t\t}\n\t\treturn super.send(stream, func, wBit, body);\n\t}\n\n\t// Public control methods\n\tpublic async sendSelectReq(): Promise<SelectStatus> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.selectReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for Select Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: (rsp) => {\n\t\t\t\t\tresolve(rsp.func as SelectStatus);\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.SelectReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendLinkTestReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.linkTestReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for LinkTest Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: () => {\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.LinkTestReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendSeparateReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.separateReq(systemBytes);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SeparateReq,\n\t\t\tsystemBytes,\n\t\t});\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, { systemBytes });\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\tprivate rejectAllTransactions(err: Error) {\n\t\tfor (const [systemBytes, tx] of this._transactions) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\ttx.reject(err);\n\t\t\tthis._transactions.delete(systemBytes);\n\t\t}\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"HsmsCommunicator.js","names":[],"sources":["../../src/hsms/HsmsCommunicator.ts"],"sourcesContent":["import { Socket } from \"net\";\nimport {\n\tAbstractSecsCommunicator,\n\tSecsCommunicatorConfig,\n\tSecsCommunicatorEvents,\n} from \"../core/AbstractSecsCommunicator.js\";\nimport { SecsMessage } from \"../core/AbstractSecsMessage.js\";\nimport { AbstractSecs2Item } from \"../core/secs2item/AbstractSecs2Item.js\";\nimport { HsmsMessage } from \"./HsmsMessage.js\";\nimport { HsmsControlType } from \"./enums/HsmsControlType.js\";\nimport { SelectStatus } from \"./enums/SelectStatus.js\";\nimport { RejectReason } from \"./enums/RejectReason.js\";\n\nexport enum HsmsState {\n\tNotConnected = \"NotConnected\",\n\tConnected = \"Connected\", // TCP Connected\n\tSelected = \"Selected\", // HSMS Selected\n}\n\n/**\n * @description HsmsCommunicatorConfig is the configuration interface for HsmsCommunicator.\n * @param ip The IP address of the remote device.\n * @param port The port number of the remote device.\n * @param linkTestInterval The interval in milliseconds to send link test messages.\n */\nexport interface HsmsCommunicatorConfig extends SecsCommunicatorConfig {\n\tip: string;\n\tport: number;\n\tlinkTestInterval?: number;\n}\n\nexport interface HsmsCommunicatorEvents extends SecsCommunicatorEvents {\n\tselected: [];\n\tdeselected: [];\n}\n\nexport abstract class HsmsCommunicator extends AbstractSecsCommunicator<HsmsCommunicatorEvents> {\n\tpublic ip: string;\n\tpublic port: number;\n\n\tprotected socket: Socket | null = null;\n\tprotected state: HsmsState = HsmsState.NotConnected;\n\tprivate buffer: Buffer = Buffer.alloc(0);\n\tprivate t7Timer: NodeJS.Timeout | null = null;\n\tprivate t8Timer: NodeJS.Timeout | null = null;\n\n\t// T6 Timer (Control Transaction)\n\t// We use the same _transactions map for Control messages if they expect reply\n\n\tpublic get connectionState(): HsmsState {\n\t\treturn this.state;\n\t}\n\n\tconstructor(config: HsmsCommunicatorConfig) {\n\t\tsuper(config);\n\t\tthis.ip = config.ip;\n\t\tthis.port = config.port;\n\t}\n\n\tprotected override async sendBufferWithLogs(\n\t\tdirection: \"Sent\" | \"Received\",\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): Promise<void> {\n\t\tawait super.sendBufferWithLogs(\n\t\t\tdirection,\n\t\t\tprotocol === \"SECS\" ? \"HSMS\" : protocol,\n\t\t\tbuffer,\n\t\t\t{\n\t\t\t\thsmsState: this.state,\n\t\t\t\t...meta,\n\t\t\t},\n\t\t);\n\t}\n\n\tprotected async sendBuffer(buffer: Buffer): Promise<void> {\n\t\tconst socket = this.socket;\n\t\tif (!socket || socket.destroyed) {\n\t\t\tthrow new Error(\"Socket not connected\");\n\t\t}\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tsocket.write(buffer, (err) => {\n\t\t\t\tif (err) reject(err);\n\t\t\t\telse resolve();\n\t\t\t});\n\t\t});\n\t}\n\n\tprotected createMessage(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null,\n\t\tsystemBytes: number,\n\t): SecsMessage {\n\t\t// For Data messages, pType=0, sType=0 (Data)\n\t\treturn new HsmsMessage(\n\t\t\tstream,\n\t\t\tfunc,\n\t\t\twBit,\n\t\t\tbody,\n\t\t\tsystemBytes,\n\t\t\tthis.deviceId,\n\t\t\t0,\n\t\t\tHsmsControlType.Data,\n\t\t);\n\t}\n\n\tprotected handleSocketEvents(socket: Socket) {\n\t\tthis.socket = socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, {\n\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\tremotePort: socket.remotePort,\n\t\t});\n\t\tthis.resetT7Timer();\n\t\tthis.emit(\"connected\");\n\n\t\tsocket.on(\"data\", (data) => {\n\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", data, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t\tchunkLength: data.length,\n\t\t\t});\n\t\t\tthis.buffer = Buffer.concat([this.buffer, data]);\n\t\t\tthis.resetT8Timer();\n\t\t\tthis.processBuffer();\n\t\t\tif (this.buffer.length === 0) {\n\t\t\t\tthis.clearT8Timer();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"close\", () => {\n\t\t\tthis.rejectAllTransactions(new Error(\"Socket closed\"));\n\t\t\tthis.clearT7Timer();\n\t\t\tthis.clearT8Timer();\n\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\tconst prevState = this.state;\n\t\t\tthis.state = HsmsState.NotConnected;\n\t\t\tthis.logger.logState(\"HSMS\", prevState, this.state, {\n\t\t\t\tremoteAddress: socket.remoteAddress,\n\t\t\t\tremotePort: socket.remotePort,\n\t\t\t});\n\t\t\tthis.socket = null;\n\t\t\tthis.emit(\"disconnected\");\n\t\t});\n\n\t\tsocket.on(\"end\", () => {\n\t\t\tif (this.socket && !this.socket.destroyed) {\n\t\t\t\tthis.socket.destroy();\n\t\t\t}\n\t\t});\n\n\t\tsocket.on(\"error\", (err) => {\n\t\t\tthis.emit(\"error\", err);\n\t\t\tif (!socket.destroyed) {\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t});\n\t}\n\n\tprivate resetT7Timer() {\n\t\tthis.clearT7Timer();\n\t\tif (this.timeoutT7 <= 0) return;\n\t\tthis.t7Timer = setTimeout(() => {\n\t\t\tthis.t7Timer = null;\n\t\t\tif (this.state === HsmsState.Selected) return;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T7 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT7 * 1000);\n\t}\n\n\tprivate clearT7Timer() {\n\t\tif (this.t7Timer) {\n\t\t\tclearTimeout(this.t7Timer);\n\t\t\tthis.t7Timer = null;\n\t\t}\n\t}\n\n\tprivate resetT8Timer() {\n\t\tthis.clearT8Timer();\n\t\tif (this.timeoutT8 <= 0) return;\n\t\tthis.t8Timer = setTimeout(() => {\n\t\t\tthis.t8Timer = null;\n\t\t\tconst socket = this.socket;\n\t\t\tif (socket && !socket.destroyed && this.buffer.length > 0) {\n\t\t\t\tthis.emit(\"error\", new Error(\"T8 Timeout\"));\n\t\t\t\tsocket.destroy();\n\t\t\t}\n\t\t}, this.timeoutT8 * 1000);\n\t}\n\n\tprivate clearT8Timer() {\n\t\tif (this.t8Timer) {\n\t\t\tclearTimeout(this.t8Timer);\n\t\t\tthis.t8Timer = null;\n\t\t}\n\t}\n\n\tprivate processBuffer() {\n\t\twhile (true) {\n\t\t\tif (this.buffer.length < 4) return;\n\n\t\t\tconst length = this.buffer.readUInt32BE(0);\n\t\t\tif (length < 10) {\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tthis.emit(\"error\", new Error(\"Receive message size < 10\"));\n\t\t\t\tthis.buffer = Buffer.alloc(0);\n\t\t\t\tif (socket && !socket.destroyed) {\n\t\t\t\t\tsocket.destroy();\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (this.buffer.length < 4 + length) return;\n\n\t\t\tconst msgBuffer = this.buffer.subarray(0, 4 + length);\n\t\t\tthis.buffer = this.buffer.subarray(4 + length);\n\n\t\t\ttry {\n\t\t\t\tthis.logger.logBytes(\"Received\", \"HSMS\", msgBuffer, {\n\t\t\t\t\tframeLength: length,\n\t\t\t\t});\n\t\t\t\tconst msg = HsmsMessage.fromBuffer(msgBuffer);\n\t\t\t\tthis.processHsmsMessage(msg);\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof Error) {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${err.message}`),\n\t\t\t\t\t);\n\t\t\t\t} else {\n\t\t\t\t\tthis.emit(\n\t\t\t\t\t\t\"error\",\n\t\t\t\t\t\tnew Error(`Failed to parse HSMS message: ${String(err)}`),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate processHsmsMessage(msg: HsmsMessage) {\n\t\t// Handle Control Messages\n\t\tif (msg.sType !== HsmsControlType.Data) {\n\t\t\tthis.logger.detail.debug(\n\t\t\t\t{\n\t\t\t\t\tprotocol: \"HSMS\",\n\t\t\t\t\tcontrolType: msg.sType,\n\t\t\t\t\tpType: msg.pType,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t\tdeviceId: msg.deviceId,\n\t\t\t\t},\n\t\t\t\t\"control\",\n\t\t\t);\n\t\t\tthis.handleControlMessage(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Handle Data Messages\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tthis.logger.logSecs2(\n\t\t\t\t\"Received\",\n\t\t\t\tmsg.toSml(),\n\t\t\t\tthis.deviceId,\n\t\t\t\tmsg.systemBytes,\n\t\t\t\tmsg.toBuffer(),\n\t\t\t);\n\t\t\tvoid this.sendReject(msg, RejectReason.NotSelected);\n\t\t\treturn;\n\t\t}\n\n\t\tsuper.handleMessage(msg);\n\t}\n\n\tprivate handleControlMessage(msg: HsmsMessage) {\n\t\tswitch (msg.sType as HsmsControlType) {\n\t\t\tcase HsmsControlType.SelectReq:\n\t\t\t\tthis.handleSelectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SelectRsp:\n\t\t\t\tthis.handleSelectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectReq:\n\t\t\t\tthis.handleDeselectReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.DeselectRsp:\n\t\t\t\tthis.handleDeselectRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestReq:\n\t\t\t\tthis.handleLinkTestReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.LinkTestRsp:\n\t\t\t\tthis.handleLinkTestRsp(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.SeparateReq:\n\t\t\t\tthis.handleSeparateReq(msg);\n\t\t\t\tbreak;\n\t\t\tcase HsmsControlType.RejectReq:\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tvoid this.sendReject(\n\t\t\t\t\tmsg,\n\t\t\t\t\tmsg.pType !== 0\n\t\t\t\t\t\t? RejectReason.NotSupportTypeP\n\t\t\t\t\t\t: RejectReason.NotSupportTypeS,\n\t\t\t\t);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprotected handleSelectReq(msg: HsmsMessage) {\n\t\t// Subclasses might override, but default behavior:\n\t\t// If already selected, return Actived/AlreadyUsed?\n\t\t// If not, accept.\n\n\t\t// Note: HSMS-SS says only one host.\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Actived); // Or AlreadyUsed?\n\t\t} else {\n\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\n\t\t\tthis.state = HsmsState.Selected;\n\t\t\tthis.clearT7Timer();\n\t\t\tvoid this.sendSelectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"selected\");\n\t\t}\n\t}\n\n\tprotected handleSelectRsp(msg: HsmsMessage) {\n\t\t// Check if we are waiting for this.\n\t\t// Usually managed by sendSelectReq promise.\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\t// If status is Success, set state to Selected\n\t\t\t// msg.func holds the status (byte 3) if we mapped it correctly in HsmsMessage.fromBuffer\n\t\t\t// In HsmsMessage.fromBuffer, for Control msg, func = byte 3.\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success || status === SelectStatus.Actived) {\n\t\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Selected, {\n\t\t\t\t\tselectStatus: status,\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\n\t\t\t\tthis.state = HsmsState.Selected;\n\t\t\t\tthis.clearT7Timer();\n\t\t\t\tthis.emit(\"selected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleLinkTestReq(msg: HsmsMessage) {\n\t\tvoid this.sendLinkTestRsp(msg);\n\t}\n\n\tprotected handleLinkTestRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleDeselectReq(msg: HsmsMessage) {\n\t\tif (this.state === HsmsState.Selected) {\n\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t});\n\t\t\tthis.state = HsmsState.Connected;\n\t\t\tthis.resetT7Timer();\n\t\t\tvoid this.sendDeselectRsp(msg, SelectStatus.Success);\n\t\t\tthis.emit(\"deselected\");\n\t\t\treturn;\n\t\t}\n\t\tvoid this.sendDeselectRsp(msg, SelectStatus.NotReady);\n\t}\n\n\tprotected handleDeselectRsp(msg: HsmsMessage) {\n\t\tconst tx = this._transactions.get(msg.systemBytes);\n\t\tif (tx) {\n\t\t\tconst status = msg.func as SelectStatus;\n\t\t\tif (status === SelectStatus.Success) {\n\t\t\t\tthis.logger.logState(\"HSMS\", this.state, HsmsState.Connected, {\n\t\t\t\t\tsystemBytes: msg.systemBytes,\n\t\t\t\t});\n\t\t\t\tthis.state = HsmsState.Connected;\n\t\t\t\tthis.resetT7Timer();\n\t\t\t\tthis.emit(\"deselected\");\n\t\t\t}\n\t\t\tclearTimeout(tx.timer);\n\t\t\tthis._transactions.delete(msg.systemBytes);\n\t\t\ttx.resolve(msg);\n\t\t} else {\n\t\t\tvoid this.sendReject(msg, RejectReason.TransactionNotOpen);\n\t\t}\n\t}\n\n\tprotected handleSeparateReq(_msg: HsmsMessage) {\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state);\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\t// Helper senders\n\tprotected async sendSelectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.selectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SelectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendDeselectRsp(req: HsmsMessage, status: number) {\n\t\tconst rsp = HsmsMessage.deselectRsp(req, status);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.DeselectRsp,\n\t\t\tstatus,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendLinkTestRsp(req: HsmsMessage) {\n\t\tconst rsp = HsmsMessage.linkTestRsp(req);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.LinkTestRsp,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\tprotected async sendReject(req: HsmsMessage, reason: RejectReason) {\n\t\tconst rsp = HsmsMessage.rejectReq(req, reason);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", rsp.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.RejectReq,\n\t\t\treason,\n\t\t\tsystemBytes: rsp.systemBytes,\n\t\t});\n\t}\n\n\toverride async send(\n\t\tstream: number,\n\t\tfunc: number,\n\t\twBit: boolean,\n\t\tbody: AbstractSecs2Item | null = null,\n\t): Promise<SecsMessage | null> {\n\t\tif (this.state !== HsmsState.Selected) {\n\t\t\tthrow new Error(\"HSMS not selected\");\n\t\t}\n\t\treturn super.send(stream, func, wBit, body);\n\t}\n\n\t// Public control methods\n\tpublic async sendSelectReq(): Promise<SelectStatus> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.selectReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for Select Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: (rsp) => {\n\t\t\t\t\tresolve(rsp.func as SelectStatus);\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.SelectReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendLinkTestReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.linkTestReq(systemBytes);\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\tconst socket = this.socket;\n\t\t\t\tif (socket && !socket.destroyed) socket.destroy();\n\t\t\t\treject(new Error(\"T6 Timeout waiting for LinkTest Rsp\"));\n\t\t\t}, this.timeoutT6 * 1000);\n\n\t\t\tthis._transactions.set(systemBytes, {\n\t\t\t\tresolve: () => {\n\t\t\t\t\tresolve();\n\t\t\t\t},\n\t\t\t\treject,\n\t\t\t\ttimer,\n\t\t\t});\n\n\t\t\tthis.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\t\tcontrolType: HsmsControlType.LinkTestReq,\n\t\t\t\tsystemBytes,\n\t\t\t}).catch((err: unknown) => {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\tthis._transactions.delete(systemBytes);\n\t\t\t\treject(err instanceof Error ? err : new Error(String(err)));\n\t\t\t});\n\t\t});\n\t}\n\n\tpublic async sendSeparateReq(): Promise<void> {\n\t\tconst systemBytes = this.getNextSystemBytes();\n\t\tconst msg = HsmsMessage.separateReq(systemBytes);\n\t\tawait this.sendBufferWithLogs(\"Sent\", \"HSMS\", msg.toBuffer(), {\n\t\t\tcontrolType: HsmsControlType.SeparateReq,\n\t\t\tsystemBytes,\n\t\t});\n\t\tconst socket = this.socket;\n\t\tconst prev = this.state;\n\t\tthis.state = HsmsState.Connected;\n\t\tthis.logger.logState(\"HSMS\", prev, this.state, { systemBytes });\n\t\tthis.clearT7Timer();\n\t\tif (socket && !socket.destroyed) {\n\t\t\tsocket.destroy();\n\t\t}\n\t}\n\n\tprivate rejectAllTransactions(err: Error) {\n\t\tfor (const [systemBytes, tx] of this._transactions) {\n\t\t\tclearTimeout(tx.timer);\n\t\t\ttx.reject(err);\n\t\t\tthis._transactions.delete(systemBytes);\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;AAaA,IAAY,kDAAL;AACN;AACA;AACA;;;AAoBD,IAAsB,mBAAtB,cAA+C,yBAAiD;CAC/F,AAAO;CACP,AAAO;CAEP,AAAU,SAAwB;CAClC,AAAU,QAAmB,UAAU;CACvC,AAAQ,SAAiB,OAAO,MAAM,EAAE;CACxC,AAAQ,UAAiC;CACzC,AAAQ,UAAiC;CAKzC,IAAW,kBAA6B;AACvC,SAAO,KAAK;;CAGb,YAAY,QAAgC;AAC3C,QAAM,OAAO;AACb,OAAK,KAAK,OAAO;AACjB,OAAK,OAAO,OAAO;;CAGpB,MAAyB,mBACxB,WACA,UACA,QACA,MACgB;AAChB,QAAM,MAAM,mBACX,WACA,aAAa,SAAS,SAAS,UAC/B,QACA;GACC,WAAW,KAAK;GAChB,GAAG;GACH,CACD;;CAGF,MAAgB,WAAW,QAA+B;EACzD,MAAM,SAAS,KAAK;AACpB,MAAI,CAAC,UAAU,OAAO,UACrB,OAAM,IAAI,MAAM,uBAAuB;AAExC,SAAO,IAAI,SAAS,SAAS,WAAW;AACvC,UAAO,MAAM,SAAS,QAAQ;AAC7B,QAAI,IAAK,QAAO,IAAI;QACf,UAAS;KACb;IACD;;CAGH,AAAU,cACT,QACA,MACA,MACA,MACA,aACc;AAEd,SAAO,IAAI,YACV,QACA,MACA,MACA,MACA,aACA,KAAK,UACL,GACA,gBAAgB,KAChB;;CAGF,AAAU,mBAAmB,QAAgB;AAC5C,OAAK,SAAS;EACd,MAAM,OAAO,KAAK;AAClB,OAAK,QAAQ,UAAU;AACvB,OAAK,OAAO,SAAS,QAAQ,MAAM,KAAK,OAAO;GAC9C,eAAe,OAAO;GACtB,YAAY,OAAO;GACnB,CAAC;AACF,OAAK,cAAc;AACnB,OAAK,KAAK,YAAY;AAEtB,SAAO,GAAG,SAAS,SAAS;AAC3B,QAAK,OAAO,SAAS,YAAY,QAAQ,MAAM;IAC9C,eAAe,OAAO;IACtB,YAAY,OAAO;IACnB,aAAa,KAAK;IAClB,CAAC;AACF,QAAK,SAAS,OAAO,OAAO,CAAC,KAAK,QAAQ,KAAK,CAAC;AAChD,QAAK,cAAc;AACnB,QAAK,eAAe;AACpB,OAAI,KAAK,OAAO,WAAW,EAC1B,MAAK,cAAc;IAEnB;AAEF,SAAO,GAAG,eAAe;AACxB,QAAK,sCAAsB,IAAI,MAAM,gBAAgB,CAAC;AACtD,QAAK,cAAc;AACnB,QAAK,cAAc;AACnB,QAAK,SAAS,OAAO,MAAM,EAAE;GAC7B,MAAM,YAAY,KAAK;AACvB,QAAK,QAAQ,UAAU;AACvB,QAAK,OAAO,SAAS,QAAQ,WAAW,KAAK,OAAO;IACnD,eAAe,OAAO;IACtB,YAAY,OAAO;IACnB,CAAC;AACF,QAAK,SAAS;AACd,QAAK,KAAK,eAAe;IACxB;AAEF,SAAO,GAAG,aAAa;AACtB,OAAI,KAAK,UAAU,CAAC,KAAK,OAAO,UAC/B,MAAK,OAAO,SAAS;IAErB;AAEF,SAAO,GAAG,UAAU,QAAQ;AAC3B,QAAK,KAAK,SAAS,IAAI;AACvB,OAAI,CAAC,OAAO,UACX,QAAO,SAAS;IAEhB;;CAGH,AAAQ,eAAe;AACtB,OAAK,cAAc;AACnB,MAAI,KAAK,aAAa,EAAG;AACzB,OAAK,UAAU,iBAAiB;AAC/B,QAAK,UAAU;AACf,OAAI,KAAK,UAAU,UAAU,SAAU;GACvC,MAAM,SAAS,KAAK;AACpB,OAAI,UAAU,CAAC,OAAO,WAAW;AAChC,SAAK,KAAK,yBAAS,IAAI,MAAM,aAAa,CAAC;AAC3C,WAAO,SAAS;;KAEf,KAAK,YAAY,IAAK;;CAG1B,AAAQ,eAAe;AACtB,MAAI,KAAK,SAAS;AACjB,gBAAa,KAAK,QAAQ;AAC1B,QAAK,UAAU;;;CAIjB,AAAQ,eAAe;AACtB,OAAK,cAAc;AACnB,MAAI,KAAK,aAAa,EAAG;AACzB,OAAK,UAAU,iBAAiB;AAC/B,QAAK,UAAU;GACf,MAAM,SAAS,KAAK;AACpB,OAAI,UAAU,CAAC,OAAO,aAAa,KAAK,OAAO,SAAS,GAAG;AAC1D,SAAK,KAAK,yBAAS,IAAI,MAAM,aAAa,CAAC;AAC3C,WAAO,SAAS;;KAEf,KAAK,YAAY,IAAK;;CAG1B,AAAQ,eAAe;AACtB,MAAI,KAAK,SAAS;AACjB,gBAAa,KAAK,QAAQ;AAC1B,QAAK,UAAU;;;CAIjB,AAAQ,gBAAgB;AACvB,SAAO,MAAM;AACZ,OAAI,KAAK,OAAO,SAAS,EAAG;GAE5B,MAAM,SAAS,KAAK,OAAO,aAAa,EAAE;AAC1C,OAAI,SAAS,IAAI;IAChB,MAAM,SAAS,KAAK;AACpB,SAAK,KAAK,yBAAS,IAAI,MAAM,4BAA4B,CAAC;AAC1D,SAAK,SAAS,OAAO,MAAM,EAAE;AAC7B,QAAI,UAAU,CAAC,OAAO,UACrB,QAAO,SAAS;AAEjB;;AAED,OAAI,KAAK,OAAO,SAAS,IAAI,OAAQ;GAErC,MAAM,YAAY,KAAK,OAAO,SAAS,GAAG,IAAI,OAAO;AACrD,QAAK,SAAS,KAAK,OAAO,SAAS,IAAI,OAAO;AAE9C,OAAI;AACH,SAAK,OAAO,SAAS,YAAY,QAAQ,WAAW,EACnD,aAAa,QACb,CAAC;IACF,MAAM,MAAM,YAAY,WAAW,UAAU;AAC7C,SAAK,mBAAmB,IAAI;YACpB,KAAK;AACb,QAAI,eAAe,MAClB,MAAK,KACJ,yBACA,IAAI,MAAM,iCAAiC,IAAI,UAAU,CACzD;QAED,MAAK,KACJ,yBACA,IAAI,MAAM,iCAAiC,OAAO,IAAI,GAAG,CACzD;;;;CAML,AAAQ,mBAAmB,KAAkB;AAE5C,MAAI,IAAI,UAAU,gBAAgB,MAAM;AACvC,QAAK,OAAO,OAAO,MAClB;IACC,UAAU;IACV,aAAa,IAAI;IACjB,OAAO,IAAI;IACX,aAAa,IAAI;IACjB,UAAU,IAAI;IACd,EACD,UACA;AACD,QAAK,qBAAqB,IAAI;AAC9B;;AAID,MAAI,KAAK,UAAU,UAAU,UAAU;AACtC,QAAK,OAAO,SACX,YACA,IAAI,OAAO,EACX,KAAK,UACL,IAAI,aACJ,IAAI,UAAU,CACd;AACD,GAAK,KAAK,WAAW,KAAK,aAAa,YAAY;AACnD;;AAGD,QAAM,cAAc,IAAI;;CAGzB,AAAQ,qBAAqB,KAAkB;AAC9C,UAAQ,IAAI,OAAZ;GACC,KAAK,gBAAgB;AACpB,SAAK,gBAAgB,IAAI;AACzB;GACD,KAAK,gBAAgB;AACpB,SAAK,gBAAgB,IAAI;AACzB;GACD,KAAK,gBAAgB;AACpB,SAAK,kBAAkB,IAAI;AAC3B;GACD,KAAK,gBAAgB;AACpB,SAAK,kBAAkB,IAAI;AAC3B;GACD,KAAK,gBAAgB;AACpB,SAAK,kBAAkB,IAAI;AAC3B;GACD,KAAK,gBAAgB;AACpB,SAAK,kBAAkB,IAAI;AAC3B;GACD,KAAK,gBAAgB;AACpB,SAAK,kBAAkB,IAAI;AAC3B;GACD,KAAK,gBAAgB,UACpB;GACD;AACC,IAAK,KAAK,WACT,KACA,IAAI,UAAU,IACX,aAAa,kBACb,aAAa,gBAChB;AACD;;;CAIH,AAAU,gBAAgB,KAAkB;AAM3C,MAAI,KAAK,UAAU,UAAU,SAC5B,CAAK,KAAK,cAAc,KAAK,aAAa,QAAQ;OAC5C;AACN,QAAK,OAAO,SAAS,QAAQ,KAAK,OAAO,UAAU,UAAU,EAC5D,aAAa,IAAI,aACjB,CAAC;AACF,QAAK,QAAQ,UAAU;AACvB,QAAK,cAAc;AACnB,GAAK,KAAK,cAAc,KAAK,aAAa,QAAQ;AAClD,QAAK,KAAK,WAAW;;;CAIvB,AAAU,gBAAgB,KAAkB;EAG3C,MAAM,KAAK,KAAK,cAAc,IAAI,IAAI,YAAY;AAClD,MAAI,IAAI;GAIP,MAAM,SAAS,IAAI;AACnB,OAAI,WAAW,aAAa,WAAW,WAAW,aAAa,SAAS;AACvE,SAAK,OAAO,SAAS,QAAQ,KAAK,OAAO,UAAU,UAAU;KAC5D,cAAc;KACd,aAAa,IAAI;KACjB,CAAC;AACF,SAAK,QAAQ,UAAU;AACvB,SAAK,cAAc;AACnB,SAAK,KAAK,WAAW;;AAEtB,gBAAa,GAAG,MAAM;AACtB,QAAK,cAAc,OAAO,IAAI,YAAY;AAC1C,MAAG,QAAQ,IAAI;QAEf,CAAK,KAAK,WAAW,KAAK,aAAa,mBAAmB;;CAI5D,AAAU,kBAAkB,KAAkB;AAC7C,EAAK,KAAK,gBAAgB,IAAI;;CAG/B,AAAU,kBAAkB,KAAkB;EAC7C,MAAM,KAAK,KAAK,cAAc,IAAI,IAAI,YAAY;AAClD,MAAI,IAAI;AACP,gBAAa,GAAG,MAAM;AACtB,QAAK,cAAc,OAAO,IAAI,YAAY;AAC1C,MAAG,QAAQ,IAAI;QAEf,CAAK,KAAK,WAAW,KAAK,aAAa,mBAAmB;;CAI5D,AAAU,kBAAkB,KAAkB;AAC7C,MAAI,KAAK,UAAU,UAAU,UAAU;AACtC,QAAK,OAAO,SAAS,QAAQ,KAAK,OAAO,UAAU,WAAW,EAC7D,aAAa,IAAI,aACjB,CAAC;AACF,QAAK,QAAQ,UAAU;AACvB,QAAK,cAAc;AACnB,GAAK,KAAK,gBAAgB,KAAK,aAAa,QAAQ;AACpD,QAAK,KAAK,aAAa;AACvB;;AAED,EAAK,KAAK,gBAAgB,KAAK,aAAa,SAAS;;CAGtD,AAAU,kBAAkB,KAAkB;EAC7C,MAAM,KAAK,KAAK,cAAc,IAAI,IAAI,YAAY;AAClD,MAAI,IAAI;AAEP,OADe,IAAI,SACJ,aAAa,SAAS;AACpC,SAAK,OAAO,SAAS,QAAQ,KAAK,OAAO,UAAU,WAAW,EAC7D,aAAa,IAAI,aACjB,CAAC;AACF,SAAK,QAAQ,UAAU;AACvB,SAAK,cAAc;AACnB,SAAK,KAAK,aAAa;;AAExB,gBAAa,GAAG,MAAM;AACtB,QAAK,cAAc,OAAO,IAAI,YAAY;AAC1C,MAAG,QAAQ,IAAI;QAEf,CAAK,KAAK,WAAW,KAAK,aAAa,mBAAmB;;CAI5D,AAAU,kBAAkB,MAAmB;EAC9C,MAAM,SAAS,KAAK;EACpB,MAAM,OAAO,KAAK;AAClB,OAAK,QAAQ,UAAU;AACvB,OAAK,OAAO,SAAS,QAAQ,MAAM,KAAK,MAAM;AAC9C,OAAK,cAAc;AACnB,MAAI,UAAU,CAAC,OAAO,UACrB,QAAO,SAAS;;CAKlB,MAAgB,cAAc,KAAkB,QAAgB;EAC/D,MAAM,MAAM,YAAY,UAAU,KAAK,OAAO;AAC9C,QAAM,KAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;GAC7D,aAAa,gBAAgB;GAC7B;GACA,aAAa,IAAI;GACjB,CAAC;;CAGH,MAAgB,gBAAgB,KAAkB,QAAgB;EACjE,MAAM,MAAM,YAAY,YAAY,KAAK,OAAO;AAChD,QAAM,KAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;GAC7D,aAAa,gBAAgB;GAC7B;GACA,aAAa,IAAI;GACjB,CAAC;;CAGH,MAAgB,gBAAgB,KAAkB;EACjD,MAAM,MAAM,YAAY,YAAY,IAAI;AACxC,QAAM,KAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;GAC7D,aAAa,gBAAgB;GAC7B,aAAa,IAAI;GACjB,CAAC;;CAGH,MAAgB,WAAW,KAAkB,QAAsB;EAClE,MAAM,MAAM,YAAY,UAAU,KAAK,OAAO;AAC9C,QAAM,KAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;GAC7D,aAAa,gBAAgB;GAC7B;GACA,aAAa,IAAI;GACjB,CAAC;;CAGH,MAAe,KACd,QACA,MACA,MACA,OAAiC,MACH;AAC9B,MAAI,KAAK,UAAU,UAAU,SAC5B,OAAM,IAAI,MAAM,oBAAoB;AAErC,SAAO,MAAM,KAAK,QAAQ,MAAM,MAAM,KAAK;;CAI5C,MAAa,gBAAuC;EACnD,MAAM,cAAc,KAAK,oBAAoB;EAC7C,MAAM,MAAM,YAAY,UAAU,YAAY;AAE9C,SAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,QAAQ,iBAAiB;AAC9B,SAAK,cAAc,OAAO,YAAY;IACtC,MAAM,SAAS,KAAK;AACpB,QAAI,UAAU,CAAC,OAAO,UAAW,QAAO,SAAS;AACjD,2BAAO,IAAI,MAAM,oCAAoC,CAAC;MACpD,KAAK,YAAY,IAAK;AAEzB,QAAK,cAAc,IAAI,aAAa;IACnC,UAAU,QAAQ;AACjB,aAAQ,IAAI,KAAqB;;IAElC;IACA;IACA,CAAC;AAEF,QAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;IACvD,aAAa,gBAAgB;IAC7B;IACA,CAAC,CAAC,OAAO,QAAiB;AAC1B,iBAAa,MAAM;AACnB,SAAK,cAAc,OAAO,YAAY;AACtC,WAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;KAC1D;IACD;;CAGH,MAAa,kBAAiC;EAC7C,MAAM,cAAc,KAAK,oBAAoB;EAC7C,MAAM,MAAM,YAAY,YAAY,YAAY;AAEhD,SAAO,IAAI,SAAS,SAAS,WAAW;GACvC,MAAM,QAAQ,iBAAiB;AAC9B,SAAK,cAAc,OAAO,YAAY;IACtC,MAAM,SAAS,KAAK;AACpB,QAAI,UAAU,CAAC,OAAO,UAAW,QAAO,SAAS;AACjD,2BAAO,IAAI,MAAM,sCAAsC,CAAC;MACtD,KAAK,YAAY,IAAK;AAEzB,QAAK,cAAc,IAAI,aAAa;IACnC,eAAe;AACd,cAAS;;IAEV;IACA;IACA,CAAC;AAEF,QAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;IACvD,aAAa,gBAAgB;IAC7B;IACA,CAAC,CAAC,OAAO,QAAiB;AAC1B,iBAAa,MAAM;AACnB,SAAK,cAAc,OAAO,YAAY;AACtC,WAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC,CAAC;KAC1D;IACD;;CAGH,MAAa,kBAAiC;EAC7C,MAAM,cAAc,KAAK,oBAAoB;EAC7C,MAAM,MAAM,YAAY,YAAY,YAAY;AAChD,QAAM,KAAK,mBAAmB,QAAQ,QAAQ,IAAI,UAAU,EAAE;GAC7D,aAAa,gBAAgB;GAC7B;GACA,CAAC;EACF,MAAM,SAAS,KAAK;EACpB,MAAM,OAAO,KAAK;AAClB,OAAK,QAAQ,UAAU;AACvB,OAAK,OAAO,SAAS,QAAQ,MAAM,KAAK,OAAO,EAAE,aAAa,CAAC;AAC/D,OAAK,cAAc;AACnB,MAAI,UAAU,CAAC,OAAO,UACrB,QAAO,SAAS;;CAIlB,AAAQ,sBAAsB,KAAY;AACzC,OAAK,MAAM,CAAC,aAAa,OAAO,KAAK,eAAe;AACnD,gBAAa,GAAG,MAAM;AACtB,MAAG,OAAO,IAAI;AACd,QAAK,cAAc,OAAO,YAAY"}
@@ -26,7 +26,7 @@ declare class SecsLogger {
26
26
  private readonly secs2Stream;
27
27
  private readonly maxHexBytes;
28
28
  private constructor();
29
- logSecs2(direction: SecsLogDirection, sml: string): void;
29
+ logSecs2(direction: SecsLogDirection, sml: string, deviceId: number, systemBytes: number, buffer?: Buffer): void;
30
30
  logBytes(direction: SecsLogDirection, protocol: string, buffer: Buffer, meta?: Record<string, unknown>): void;
31
31
  logState(protocol: string, prev: string, next: string, meta?: Record<string, unknown>): void;
32
32
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"SecsLogger.d.ts","names":[],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":[],"mappings":";;;KAKY,gBAAA;UAEK,gBAAA;EAFL,OAAA,CAAA,EAAA,OAAA;EAEK,OAAA,CAAA,EAAA,OAAA;EAUA,OAAA,CAAA,EAAA,MAAA;EAubJ,aAAU,CAAA,EAAA,MAAA;EACH,WAAA,CAAA,EA7bL,eA6bK;EAKV,UAAA,CAAA,EAjcI,eAicJ;EACH,WAAA,CAAA,EAAA,MAAA;;AA4EkB,UA1gBR,iBAAA,CA0gBQ;EAuBJ,IAAA,EAAA,MAAA;EAQR,QAAA,EAAA,MAAA;EAEH,OAAA,EAAA,OAAA;;AAmBD,cAvII,UAAA,CAuIJ;EAAM,OAAA,QAAA,CAAA,CAAA,EAtIK,UAsIL;wBAjIL,mCACH,oBACH;mBA2EqB;;;;;;;sBAuBJ;sBAQR,4CAEH,eACD;gEAkBA"}
1
+ {"version":3,"file":"SecsLogger.d.ts","names":[],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":[],"mappings":";;;KAKY,gBAAA;UAEK,gBAAA;EAFL,OAAA,CAAA,EAAA,OAAA;EAEK,OAAA,CAAA,EAAA,OAAA;EAUA,OAAA,CAAA,EAAA,MAAA;EA6bJ,aAAU,CAAA,EAAA,MAAA;EACH,WAAA,CAAA,EAncL,eAmcK;EAKV,UAAA,CAAA,EAvcI,eAucJ;EACH,WAAA,CAAA,EAAA,MAAA;;AAiFkB,UArhBR,iBAAA,CAqhBQ;EAwBZ,IAAA,EAAA,MAAA;EAIF,QAAA,EAAA,MAAA;EAeE,OAAA,EAAA,OAAA;;AAGJ,cAtII,UAAA,CAsIJ;EAkBA,OAAA,QAAA,CAAA,CAAA,EAvJW,UAuJX;EAAM,OAAA,MAAA,CAAA,MAAA,EAlJL,gBAkJK,GAAA,SAAA,EAAA,GAAA,EAjJR,iBAiJQ,CAAA,EAhJX,UAgJW;mBAhEU;;;;;;;sBAwBZ,+EAIF;sBAeE,4CAEH,eACD;gEAkBA"}
@@ -277,6 +277,8 @@ var Secs2LineTransformStream = class extends Writable {
277
277
  const timeValue = rec.time;
278
278
  const dirValue = rec.dir;
279
279
  const smlValue = rec.sml;
280
+ const deviceIdValue = rec.deviceId;
281
+ const systemBytesValue = rec.systemBytes;
280
282
  const dir = dirValue === "Sent" || dirValue === "Received" ? dirValue : null;
281
283
  const sml = typeof smlValue === "string" ? smlValue : null;
282
284
  if (!dir || !sml) return;
@@ -284,7 +286,9 @@ var Secs2LineTransformStream = class extends Writable {
284
286
  if (typeof timeValue === "number") date = new Date(timeValue);
285
287
  else if (typeof timeValue === "string") date = new Date(timeValue);
286
288
  else date = /* @__PURE__ */ new Date();
287
- const out = `${formatDateTime(date)} ${dir} \n${normalizeSmlForSingleLine(sml)}\n`;
289
+ const deviceId = typeof deviceIdValue === "number" ? deviceIdValue : 0;
290
+ const systemBytes = typeof systemBytesValue === "number" ? systemBytesValue : 0;
291
+ const out = `${formatDateTime(date)} ${dir} DeviceID: ${deviceId} SystemBytes: ${systemBytes} \n${normalizeSmlForSingleLine(sml)}\n`;
288
292
  this.target.write(out);
289
293
  }
290
294
  };
@@ -328,12 +332,14 @@ var SecsLogger = class SecsLogger {
328
332
  deviceId: ctx.deviceId,
329
333
  isEquip: ctx.isEquip
330
334
  };
331
- const detailStreams = [{ stream: detailStream }];
335
+ const detailPrettyStream = new PrettyPrintTransformStream();
336
+ detailPrettyStream.pipe(detailStream);
337
+ const detailStreams = [{ stream: detailPrettyStream }];
332
338
  if (consoleEnabled) {
333
- const prettyStream = new PrettyPrintTransformStream();
334
- prettyStream.pipe(process.stdout);
339
+ const consolePrettyStream = new PrettyPrintTransformStream();
340
+ consolePrettyStream.pipe(process.stdout);
335
341
  detailStreams.push({
336
- stream: prettyStream,
342
+ stream: consolePrettyStream,
337
343
  level: detailLevel
338
344
  });
339
345
  }
@@ -341,14 +347,16 @@ var SecsLogger = class SecsLogger {
341
347
  level: detailLevel,
342
348
  base: bindings
343
349
  }, pino.multistream(detailStreams));
344
- const secs2Streams = [{ stream: secs2Stream }];
350
+ const secs2ToDetailPrettyStream = new PrettyPrintTransformStream();
351
+ secs2ToDetailPrettyStream.pipe(detailStream);
352
+ const secs2Streams = [{ stream: secs2Stream }, { stream: secs2ToDetailPrettyStream }];
345
353
  if (consoleEnabled) secs2Streams.push({
346
354
  stream: process.stdout,
347
355
  level: secs2Level
348
356
  });
349
357
  const secs2 = pino({
350
358
  level: secs2Level,
351
- base: null,
359
+ base: bindings,
352
360
  messageKey: "msg"
353
361
  }, pino.multistream(secs2Streams));
354
362
  return new SecsLogger({
@@ -378,10 +386,13 @@ var SecsLogger = class SecsLogger {
378
386
  this.secs2Stream = params.secs2Stream;
379
387
  this.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;
380
388
  }
381
- logSecs2(direction, sml) {
389
+ logSecs2(direction, sml, deviceId, systemBytes, buffer) {
382
390
  this.secs2.info({
383
391
  dir: direction,
384
- sml: normalizeSmlForSingleLine(sml)
392
+ sml: normalizeSmlForSingleLine(sml),
393
+ deviceId,
394
+ systemBytes,
395
+ hex: buffer ? bufferToHex(buffer, this.maxHexBytes) : void 0
385
396
  }, "");
386
397
  }
387
398
  logBytes(direction, protocol, buffer, meta) {
@@ -1 +1 @@
1
- {"version":3,"file":"SecsLogger.js","names":["parts: string[]","pairs: string[]","entries: fs.Dirent[]","obj: unknown","date: Date","detailStreams: pino.StreamEntry[]","secs2Streams: pino.StreamEntry[]"],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { Writable, Transform } from \"stream\";\nimport pino, { type LevelWithSilent, type Logger } from \"pino\";\n\nexport type SecsLogDirection = \"Received\" | \"Sent\";\n\nexport interface SecsLoggerConfig {\n\tenabled?: boolean;\n\tconsole?: boolean;\n\tbaseDir?: string;\n\tretentionDays?: number;\n\tdetailLevel?: LevelWithSilent;\n\tsecs2Level?: LevelWithSilent;\n\tmaxHexBytes?: number;\n}\n\nexport interface SecsLoggerContext {\n\tname: string;\n\tdeviceId: number;\n\tisEquip: boolean;\n}\n\nfunction formatDate(date: Date): string {\n\tconst y = date.getFullYear();\n\tconst m = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst d = String(date.getDate()).padStart(2, \"0\");\n\treturn `${String(y)}-${m}-${d}`;\n}\n\nfunction formatDateTime(date: Date): string {\n\tconst ymd = formatDate(date);\n\tconst hh = String(date.getHours()).padStart(2, \"0\");\n\tconst mm = String(date.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(date.getSeconds()).padStart(2, \"0\");\n\tconst ms = String(date.getMilliseconds()).padStart(3, \"0\");\n\treturn `${ymd} ${hh}:${mm}:${ss}.${ms}`;\n}\n\nfunction tryParseYmdDirName(dirName: string): Date | null {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dirName);\n\tif (!m) return null;\n\tconst year = Number(m[1]);\n\tconst month = Number(m[2]);\n\tconst day = Number(m[3]);\n\tif (\n\t\t!Number.isFinite(year) ||\n\t\t!Number.isFinite(month) ||\n\t\t!Number.isFinite(day)\n\t)\n\t\treturn null;\n\tconst dt = new Date(year, month - 1, day);\n\tif (dt.getFullYear() !== year) return null;\n\tif (dt.getMonth() !== month - 1) return null;\n\tif (dt.getDate() !== day) return null;\n\treturn dt;\n}\n\nfunction normalizeSmlForSingleLine(sml: string): string {\n\treturn sml.trim();\n}\n\nfunction bufferToHex(buffer: Buffer, maxHexBytes: number): string {\n\tconst len = buffer.length;\n\tconst max = Math.max(0, maxHexBytes);\n\tconst slice = len <= max ? buffer : buffer.subarray(0, max);\n\tconst hex = slice.toString(\"hex\");\n\tconst suffix = len <= max ? \"\" : `…(+${String(len - max)} bytes)`;\n\treturn `${hex}${suffix}`;\n}\n\nclass PrettyPrintTransformStream extends Transform {\n\tprivate pending = \"\";\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\toverride _transform(\n\t\tchunk: Buffer | string,\n\t\t_encoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _flush(callback: (error?: Error | null) => void): void {\n\t\tcallback();\n\t}\n\n\tprivate flush(): void {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tconst obj = JSON.parse(line) as Record<string, unknown>;\n\t\t\tconst formatted = this.formatLine(obj);\n\t\t\tthis.push(formatted);\n\t\t}\n\t}\n\n\tprivate formatLine(obj: Record<string, unknown>): string {\n\t\tconst time = this.formatTime(obj.time);\n\t\tconst level = this.formatLevel(obj.level as number);\n\t\tconst extra = this.formatExtra(obj);\n\t\tconst msg = this.formatMessage(obj);\n\n\t\treturn `${time} ${level} ${extra} | ${msg}\\n`;\n\t}\n\n\tprivate formatTime(timeValue: unknown): string {\n\t\tif (typeof timeValue === \"number\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\tif (typeof timeValue === \"string\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\treturn formatDateTime(new Date());\n\t}\n\n\tprivate formatLevel(level: number): string {\n\t\tconst levels: Record<number, string> = {\n\t\t\t10: \"TRACE\",\n\t\t\t20: \"DEBUG\",\n\t\t\t30: \"INFO \",\n\t\t\t40: \"WARN \",\n\t\t\t50: \"ERROR\",\n\t\t\t60: \"FATAL\",\n\t\t};\n\t\treturn levels[level] ?? \"UNKNOWN\";\n\t}\n\n\tprivate formatExtra(obj: Record<string, unknown>): string {\n\t\tconst parts: string[] = [];\n\n\t\tif (typeof obj.protocol === \"string\") {\n\t\t\tparts.push(obj.protocol);\n\t\t}\n\t\tif (typeof obj.dir === \"string\") {\n\t\t\tparts.push(obj.dir);\n\t\t}\n\t\tif (typeof obj.prev === \"string\" && typeof obj.next === \"string\") {\n\t\t\tparts.push(`${obj.prev} -> ${obj.next}`);\n\t\t}\n\n\t\treturn parts.join(\" \");\n\t}\n\n\tprivate formatMessage(obj: Record<string, unknown>): string {\n\t\tconst msgValue = obj.msg;\n\t\tif (typeof msgValue === \"string\" && msgValue.trim().length > 0) {\n\t\t\treturn msgValue;\n\t\t}\n\n\t\tconst excludeKeys = new Set([\n\t\t\t\"time\",\n\t\t\t\"level\",\n\t\t\t\"msg\",\n\t\t\t\"name\",\n\t\t\t\"deviceId\",\n\t\t\t\"isEquip\",\n\t\t\t\"protocol\",\n\t\t\t\"dir\",\n\t\t\t\"prev\",\n\t\t\t\"next\",\n\t\t]);\n\n\t\tconst pairs: string[] = [];\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (excludeKeys.has(key)) continue;\n\t\t\tif (Buffer.isBuffer(value)) {\n\t\t\t\tpairs.push(`${key}=${value.toString(\"hex\")}`);\n\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\tpairs.push(`${key}=${value}`);\n\t\t\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\tpairs.push(`${key}=${String(value)}`);\n\t\t\t} else {\n\t\t\t\tpairs.push(`${key}=${this.formatValue(value)}`);\n\t\t\t}\n\t\t}\n\n\t\treturn pairs.join(\" \");\n\t}\n\n\tprivate formatValue(value: unknown): string {\n\t\tif (value === null) return \"null\";\n\t\tif (value === undefined) return \"undefined\";\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\treturn value.toString(\"hex\");\n\t\t}\n\t\tif (typeof value === \"object\") {\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn \"[object]\";\n\t\t\t}\n\t\t}\n\t\treturn String(value as string | number | bigint | boolean);\n\t}\n}\n\nclass DailyRotatingFileStream extends Writable {\n\tprivate readonly baseDir: string;\n\tprivate readonly fileNameForDate: (ymd: string) => string;\n\tprivate readonly retentionDays: number;\n\tprivate currentYmd: string | null = null;\n\tprivate currentStream: fs.WriteStream | null = null;\n\tprivate cleanupYmd: string | null = null;\n\tprivate pending = \"\";\n\n\tconstructor(params: {\n\t\tbaseDir: string;\n\t\tfileNameForDate: (ymd: string) => string;\n\t\tretentionDays: number;\n\t}) {\n\t\tsuper();\n\t\tthis.baseDir = params.baseDir;\n\t\tthis.fileNameForDate = params.fileNameForDate;\n\t\tthis.retentionDays = params.retentionDays;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flushCompleteLines();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tif (this.pending.length > 0) {\n\t\t\t\tthis.ensureStreamForNow();\n\t\t\t\tthis.currentStream?.write(this.pending);\n\t\t\t\tthis.pending = \"\";\n\t\t\t}\n\t\t\tthis.currentStream?.end(() => callback());\n\t\t\tthis.currentStream = null;\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flushCompleteLines() {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx + 1);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tthis.ensureStreamForNow();\n\t\t\tthis.currentStream?.write(line);\n\t\t}\n\t}\n\n\tprivate ensureStreamForNow() {\n\t\tconst now = new Date();\n\t\tconst ymd = formatDate(now);\n\t\tif (this.currentYmd === ymd && this.currentStream) return;\n\n\t\tif (this.currentStream) {\n\t\t\tthis.currentStream.end();\n\t\t\tthis.currentStream = null;\n\t\t}\n\n\t\tconst dir = path.join(this.baseDir, ymd);\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t\tconst filePath = path.join(dir, this.fileNameForDate(ymd));\n\t\tthis.currentStream = fs.createWriteStream(filePath, { flags: \"a\" });\n\t\tthis.currentYmd = ymd;\n\n\t\tif (this.retentionDays > 0 && this.cleanupYmd !== ymd) {\n\t\t\tthis.cleanupYmd = ymd;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tthis.cleanupOldDirs(now).catch(() => undefined);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async cleanupOldDirs(now: Date): Promise<void> {\n\t\tconst retentionDays = this.retentionDays;\n\t\tif (retentionDays <= 0) return;\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.promises.readdir(this.baseDir, {\n\t\t\t\twithFileTypes: true,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cutoff = new Date(\n\t\t\tnow.getFullYear(),\n\t\t\tnow.getMonth(),\n\t\t\tnow.getDate(),\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tcutoff.setDate(cutoff.getDate() - retentionDays);\n\n\t\tfor (const ent of entries) {\n\t\t\tif (!ent.isDirectory()) continue;\n\t\t\tconst dirName = ent.name;\n\t\t\tconst dirDate = tryParseYmdDirName(dirName);\n\t\t\tif (!dirDate) continue;\n\t\t\tif (dirDate >= cutoff) continue;\n\t\t\tconst full = path.join(this.baseDir, dirName);\n\t\t\ttry {\n\t\t\t\tawait fs.promises.rm(full, { recursive: true, force: true });\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass Secs2LineTransformStream extends Writable {\n\tprivate readonly target: DailyRotatingFileStream;\n\tprivate pending = \"\";\n\n\tconstructor(target: DailyRotatingFileStream) {\n\t\tsuper();\n\t\tthis.target = target;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tthis.flush(true);\n\t\t\tthis.target.end(() => callback());\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flush(flushAll = false) {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) {\n\t\t\t\tif (flushAll && this.pending.length > 0) {\n\t\t\t\t\tthis.handleLine(this.pending);\n\t\t\t\t\tthis.pending = \"\";\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tthis.handleLine(line);\n\t\t}\n\t}\n\n\tprivate handleLine(jsonLine: string) {\n\t\tlet obj: unknown;\n\t\ttry {\n\t\t\tobj = JSON.parse(jsonLine);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!obj || typeof obj !== \"object\") return;\n\t\tconst rec = obj as Record<string, unknown>;\n\t\tconst timeValue = rec.time;\n\t\tconst dirValue = rec.dir;\n\t\tconst smlValue = rec.sml;\n\n\t\tconst dir =\n\t\t\tdirValue === \"Sent\" || dirValue === \"Received\" ? dirValue : null;\n\t\tconst sml = typeof smlValue === \"string\" ? smlValue : null;\n\t\tif (!dir || !sml) return;\n\n\t\tlet date: Date;\n\t\tif (typeof timeValue === \"number\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else if (typeof timeValue === \"string\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t}\n\n\t\tconst out = `${formatDateTime(date)} ${dir} \\n${normalizeSmlForSingleLine(sml)}\\n`;\n\t\tthis.target.write(out);\n\t}\n}\n\nclass DisabledSecsLogger {\n\tdetail: Logger;\n\tsecs2: Logger;\n\tconstructor() {\n\t\tthis.detail = pino({ enabled: false });\n\t\tthis.secs2 = pino({ enabled: false });\n\t}\n\n\tlogSecs2(_direction: SecsLogDirection, _sml: string): void {\n\t\treturn;\n\t}\n\n\tlogBytes(\n\t\t_direction: SecsLogDirection,\n\t\t_protocol: string,\n\t\t_buffer: Buffer,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tlogState(\n\t\t_protocol: string,\n\t\t_prev: string,\n\t\t_next: string,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tclose(): void {\n\t\treturn;\n\t}\n}\n\nexport class SecsLogger {\n\tstatic disabled(): SecsLogger {\n\t\treturn new DisabledSecsLogger() as unknown as SecsLogger;\n\t}\n\n\tstatic create(\n\t\tconfig: SecsLoggerConfig | undefined,\n\t\tctx: SecsLoggerContext,\n\t): SecsLogger {\n\t\tconst enabled = config?.enabled ?? false;\n\t\tconst consoleEnabled = config?.console ?? false;\n\t\tif (!enabled) return SecsLogger.disabled();\n\n\t\tconst baseDir = config?.baseDir\n\t\t\t? path.resolve(config.baseDir)\n\t\t\t: path.resolve(process.cwd(), \"logs\");\n\t\tconst retentionDays = config?.retentionDays ?? 7;\n\t\tconst detailLevel = config?.detailLevel ?? \"debug\";\n\t\tconst secs2Level = config?.secs2Level ?? \"info\";\n\n\t\tconst detailStream = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-DETAIL.log`,\n\t\t\tretentionDays,\n\t\t});\n\n\t\tconst secs2Target = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-SECS-II.log`,\n\t\t\tretentionDays,\n\t\t});\n\t\tconst secs2Stream = new Secs2LineTransformStream(secs2Target);\n\n\t\tconst bindings = {\n\t\t\tname: ctx.name,\n\t\t\tdeviceId: ctx.deviceId,\n\t\t\tisEquip: ctx.isEquip,\n\t\t};\n\n\t\tconst detailStreams: pino.StreamEntry[] = [\n\t\t\t{ stream: detailStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tconst prettyStream = new PrettyPrintTransformStream();\n\t\t\tprettyStream.pipe(process.stdout);\n\t\t\tdetailStreams.push({\n\t\t\t\tstream: prettyStream,\n\t\t\t\tlevel: detailLevel as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst detail = pino(\n\t\t\t{ level: detailLevel, base: bindings },\n\t\t\tpino.multistream(detailStreams),\n\t\t);\n\n\t\tconst secs2Streams: pino.StreamEntry[] = [\n\t\t\t{ stream: secs2Stream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tsecs2Streams.push({\n\t\t\t\tstream: process.stdout,\n\t\t\t\tlevel: secs2Level as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst secs2 = pino(\n\t\t\t{\n\t\t\t\tlevel: secs2Level,\n\t\t\t\tbase: null,\n\t\t\t\tmessageKey: \"msg\",\n\t\t\t},\n\t\t\tpino.multistream(secs2Streams),\n\t\t);\n\n\t\treturn new SecsLogger({\n\t\t\tconfig: { ...config, baseDir, retentionDays },\n\t\t\tdetail,\n\t\t\tsecs2,\n\t\t\tdetailStream,\n\t\t\tsecs2Target,\n\t\t\tsecs2Stream,\n\t\t});\n\t}\n\n\tpublic readonly detail: Logger;\n\tprivate readonly secs2: Logger;\n\tprivate readonly detailStream: DailyRotatingFileStream;\n\tprivate readonly secs2Target: DailyRotatingFileStream;\n\tprivate readonly secs2Stream: Secs2LineTransformStream;\n\tprivate readonly maxHexBytes: number;\n\n\tprivate constructor(params: {\n\t\tconfig: SecsLoggerConfig;\n\t\tdetail: Logger;\n\t\tsecs2: Logger;\n\t\tdetailStream: DailyRotatingFileStream;\n\t\tsecs2Target: DailyRotatingFileStream;\n\t\tsecs2Stream: Secs2LineTransformStream;\n\t}) {\n\t\tthis.detail = params.detail;\n\t\tthis.secs2 = params.secs2;\n\t\tthis.detailStream = params.detailStream;\n\t\tthis.secs2Target = params.secs2Target;\n\t\tthis.secs2Stream = params.secs2Stream;\n\t\tthis.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;\n\t}\n\n\tlogSecs2(direction: SecsLogDirection, sml: string): void {\n\t\tthis.secs2.info(\n\t\t\t{ dir: direction, sml: normalizeSmlForSingleLine(sml) },\n\t\t\t\"\",\n\t\t);\n\t}\n\n\tlogBytes(\n\t\tdirection: SecsLogDirection,\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.trace(\n\t\t\t{\n\t\t\t\tprotocol,\n\t\t\t\tdir: direction,\n\t\t\t\tbyteLength: buffer.length,\n\t\t\t\thex: bufferToHex(buffer, this.maxHexBytes),\n\t\t\t\t...meta,\n\t\t\t},\n\t\t\t\"bytes\",\n\t\t);\n\t}\n\n\tlogState(\n\t\tprotocol: string,\n\t\tprev: string,\n\t\tnext: string,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.info({ protocol, prev, next, ...meta }, \"state\");\n\t}\n\n\tclose(): void {\n\t\tthis.secs2.flush();\n\t\tthis.detail.flush();\n\t\tthis.secs2Stream.end();\n\t\tthis.secs2Target.end();\n\t\tthis.detailStream.end();\n\t}\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SecsLogger.js","names":["parts: string[]","pairs: string[]","entries: fs.Dirent[]","obj: unknown","date: Date","detailStreams: pino.StreamEntry[]","secs2Streams: pino.StreamEntry[]"],"sources":["../../src/logging/SecsLogger.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { Writable, Transform } from \"stream\";\nimport pino, { type LevelWithSilent, type Logger } from \"pino\";\n\nexport type SecsLogDirection = \"Received\" | \"Sent\";\n\nexport interface SecsLoggerConfig {\n\tenabled?: boolean;\n\tconsole?: boolean;\n\tbaseDir?: string;\n\tretentionDays?: number;\n\tdetailLevel?: LevelWithSilent;\n\tsecs2Level?: LevelWithSilent;\n\tmaxHexBytes?: number;\n}\n\nexport interface SecsLoggerContext {\n\tname: string;\n\tdeviceId: number;\n\tisEquip: boolean;\n}\n\nfunction formatDate(date: Date): string {\n\tconst y = date.getFullYear();\n\tconst m = String(date.getMonth() + 1).padStart(2, \"0\");\n\tconst d = String(date.getDate()).padStart(2, \"0\");\n\treturn `${String(y)}-${m}-${d}`;\n}\n\nfunction formatDateTime(date: Date): string {\n\tconst ymd = formatDate(date);\n\tconst hh = String(date.getHours()).padStart(2, \"0\");\n\tconst mm = String(date.getMinutes()).padStart(2, \"0\");\n\tconst ss = String(date.getSeconds()).padStart(2, \"0\");\n\tconst ms = String(date.getMilliseconds()).padStart(3, \"0\");\n\treturn `${ymd} ${hh}:${mm}:${ss}.${ms}`;\n}\n\nfunction tryParseYmdDirName(dirName: string): Date | null {\n\tconst m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(dirName);\n\tif (!m) return null;\n\tconst year = Number(m[1]);\n\tconst month = Number(m[2]);\n\tconst day = Number(m[3]);\n\tif (\n\t\t!Number.isFinite(year) ||\n\t\t!Number.isFinite(month) ||\n\t\t!Number.isFinite(day)\n\t)\n\t\treturn null;\n\tconst dt = new Date(year, month - 1, day);\n\tif (dt.getFullYear() !== year) return null;\n\tif (dt.getMonth() !== month - 1) return null;\n\tif (dt.getDate() !== day) return null;\n\treturn dt;\n}\n\nfunction normalizeSmlForSingleLine(sml: string): string {\n\treturn sml.trim();\n}\n\nfunction bufferToHex(buffer: Buffer, maxHexBytes: number): string {\n\tconst len = buffer.length;\n\tconst max = Math.max(0, maxHexBytes);\n\tconst slice = len <= max ? buffer : buffer.subarray(0, max);\n\tconst hex = slice.toString(\"hex\");\n\tconst suffix = len <= max ? \"\" : `…(+${String(len - max)} bytes)`;\n\treturn `${hex}${suffix}`;\n}\n\nclass PrettyPrintTransformStream extends Transform {\n\tprivate pending = \"\";\n\n\tconstructor() {\n\t\tsuper();\n\t}\n\n\toverride _transform(\n\t\tchunk: Buffer | string,\n\t\t_encoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _flush(callback: (error?: Error | null) => void): void {\n\t\tcallback();\n\t}\n\n\tprivate flush(): void {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tconst obj = JSON.parse(line) as Record<string, unknown>;\n\t\t\tconst formatted = this.formatLine(obj);\n\t\t\tthis.push(formatted);\n\t\t}\n\t}\n\n\tprivate formatLine(obj: Record<string, unknown>): string {\n\t\tconst time = this.formatTime(obj.time);\n\t\tconst level = this.formatLevel(obj.level as number);\n\t\tconst extra = this.formatExtra(obj);\n\t\tconst msg = this.formatMessage(obj);\n\n\t\treturn `${time} ${level} ${extra} | ${msg}\\n`;\n\t}\n\n\tprivate formatTime(timeValue: unknown): string {\n\t\tif (typeof timeValue === \"number\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\tif (typeof timeValue === \"string\") {\n\t\t\treturn formatDateTime(new Date(timeValue));\n\t\t}\n\t\treturn formatDateTime(new Date());\n\t}\n\n\tprivate formatLevel(level: number): string {\n\t\tconst levels: Record<number, string> = {\n\t\t\t10: \"TRACE\",\n\t\t\t20: \"DEBUG\",\n\t\t\t30: \"INFO \",\n\t\t\t40: \"WARN \",\n\t\t\t50: \"ERROR\",\n\t\t\t60: \"FATAL\",\n\t\t};\n\t\treturn levels[level] ?? \"UNKNOWN\";\n\t}\n\n\tprivate formatExtra(obj: Record<string, unknown>): string {\n\t\tconst parts: string[] = [];\n\n\t\tif (typeof obj.protocol === \"string\") {\n\t\t\tparts.push(obj.protocol);\n\t\t}\n\t\tif (typeof obj.dir === \"string\") {\n\t\t\tparts.push(obj.dir);\n\t\t}\n\t\tif (typeof obj.prev === \"string\" && typeof obj.next === \"string\") {\n\t\t\tparts.push(`${obj.prev} -> ${obj.next}`);\n\t\t}\n\n\t\treturn parts.join(\" \");\n\t}\n\n\tprivate formatMessage(obj: Record<string, unknown>): string {\n\t\tconst msgValue = obj.msg;\n\t\tif (typeof msgValue === \"string\" && msgValue.trim().length > 0) {\n\t\t\treturn msgValue;\n\t\t}\n\n\t\tconst excludeKeys = new Set([\n\t\t\t\"time\",\n\t\t\t\"level\",\n\t\t\t\"msg\",\n\t\t\t\"name\",\n\t\t\t\"deviceId\",\n\t\t\t\"isEquip\",\n\t\t\t\"protocol\",\n\t\t\t\"dir\",\n\t\t\t\"prev\",\n\t\t\t\"next\",\n\t\t]);\n\n\t\tconst pairs: string[] = [];\n\t\tfor (const [key, value] of Object.entries(obj)) {\n\t\t\tif (excludeKeys.has(key)) continue;\n\t\t\tif (Buffer.isBuffer(value)) {\n\t\t\t\tpairs.push(`${key}=${value.toString(\"hex\")}`);\n\t\t\t} else if (typeof value === \"string\") {\n\t\t\t\tpairs.push(`${key}=${value}`);\n\t\t\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\t\tpairs.push(`${key}=${String(value)}`);\n\t\t\t} else {\n\t\t\t\tpairs.push(`${key}=${this.formatValue(value)}`);\n\t\t\t}\n\t\t}\n\n\t\treturn pairs.join(\" \");\n\t}\n\n\tprivate formatValue(value: unknown): string {\n\t\tif (value === null) return \"null\";\n\t\tif (value === undefined) return \"undefined\";\n\t\tif (typeof value === \"string\") return value;\n\t\tif (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\treturn String(value);\n\t\t}\n\t\tif (Buffer.isBuffer(value)) {\n\t\t\treturn value.toString(\"hex\");\n\t\t}\n\t\tif (typeof value === \"object\") {\n\t\t\ttry {\n\t\t\t\treturn JSON.stringify(value);\n\t\t\t} catch {\n\t\t\t\treturn \"[object]\";\n\t\t\t}\n\t\t}\n\t\treturn String(value as string | number | bigint | boolean);\n\t}\n}\n\nclass DailyRotatingFileStream extends Writable {\n\tprivate readonly baseDir: string;\n\tprivate readonly fileNameForDate: (ymd: string) => string;\n\tprivate readonly retentionDays: number;\n\tprivate currentYmd: string | null = null;\n\tprivate currentStream: fs.WriteStream | null = null;\n\tprivate cleanupYmd: string | null = null;\n\tprivate pending = \"\";\n\n\tconstructor(params: {\n\t\tbaseDir: string;\n\t\tfileNameForDate: (ymd: string) => string;\n\t\tretentionDays: number;\n\t}) {\n\t\tsuper();\n\t\tthis.baseDir = params.baseDir;\n\t\tthis.fileNameForDate = params.fileNameForDate;\n\t\tthis.retentionDays = params.retentionDays;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flushCompleteLines();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tif (this.pending.length > 0) {\n\t\t\t\tthis.ensureStreamForNow();\n\t\t\t\tthis.currentStream?.write(this.pending);\n\t\t\t\tthis.pending = \"\";\n\t\t\t}\n\t\t\tthis.currentStream?.end(() => callback());\n\t\t\tthis.currentStream = null;\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flushCompleteLines() {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) break;\n\t\t\tconst line = this.pending.slice(0, idx + 1);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tthis.ensureStreamForNow();\n\t\t\tthis.currentStream?.write(line);\n\t\t}\n\t}\n\n\tprivate ensureStreamForNow() {\n\t\tconst now = new Date();\n\t\tconst ymd = formatDate(now);\n\t\tif (this.currentYmd === ymd && this.currentStream) return;\n\n\t\tif (this.currentStream) {\n\t\t\tthis.currentStream.end();\n\t\t\tthis.currentStream = null;\n\t\t}\n\n\t\tconst dir = path.join(this.baseDir, ymd);\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t\tconst filePath = path.join(dir, this.fileNameForDate(ymd));\n\t\tthis.currentStream = fs.createWriteStream(filePath, { flags: \"a\" });\n\t\tthis.currentYmd = ymd;\n\n\t\tif (this.retentionDays > 0 && this.cleanupYmd !== ymd) {\n\t\t\tthis.cleanupYmd = ymd;\n\t\t\tqueueMicrotask(() => {\n\t\t\t\tthis.cleanupOldDirs(now).catch(() => undefined);\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async cleanupOldDirs(now: Date): Promise<void> {\n\t\tconst retentionDays = this.retentionDays;\n\t\tif (retentionDays <= 0) return;\n\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = await fs.promises.readdir(this.baseDir, {\n\t\t\t\twithFileTypes: true,\n\t\t\t});\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tconst cutoff = new Date(\n\t\t\tnow.getFullYear(),\n\t\t\tnow.getMonth(),\n\t\t\tnow.getDate(),\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t\t0,\n\t\t);\n\t\tcutoff.setDate(cutoff.getDate() - retentionDays);\n\n\t\tfor (const ent of entries) {\n\t\t\tif (!ent.isDirectory()) continue;\n\t\t\tconst dirName = ent.name;\n\t\t\tconst dirDate = tryParseYmdDirName(dirName);\n\t\t\tif (!dirDate) continue;\n\t\t\tif (dirDate >= cutoff) continue;\n\t\t\tconst full = path.join(this.baseDir, dirName);\n\t\t\ttry {\n\t\t\t\tawait fs.promises.rm(full, { recursive: true, force: true });\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n}\n\nclass Secs2LineTransformStream extends Writable {\n\tprivate readonly target: DailyRotatingFileStream;\n\tprivate pending = \"\";\n\n\tconstructor(target: DailyRotatingFileStream) {\n\t\tsuper();\n\t\tthis.target = target;\n\t}\n\n\toverride _write(\n\t\tchunk: Buffer | string,\n\t\tencoding: BufferEncoding,\n\t\tcallback: (error?: Error | null) => void,\n\t): void {\n\t\ttry {\n\t\t\tconst str = typeof chunk === \"string\" ? chunk : chunk.toString(\"utf8\");\n\t\t\tthis.pending += str;\n\t\t\tthis.flush();\n\t\t\tcallback();\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\toverride _final(callback: (error?: Error | null) => void): void {\n\t\ttry {\n\t\t\tthis.flush(true);\n\t\t\tthis.target.end(() => callback());\n\t\t} catch (e) {\n\t\t\tcallback(e instanceof Error ? e : new Error(String(e)));\n\t\t}\n\t}\n\n\tprivate flush(flushAll = false) {\n\t\twhile (true) {\n\t\t\tconst idx = this.pending.indexOf(\"\\n\");\n\t\t\tif (idx < 0) {\n\t\t\t\tif (flushAll && this.pending.length > 0) {\n\t\t\t\t\tthis.handleLine(this.pending);\n\t\t\t\t\tthis.pending = \"\";\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst line = this.pending.slice(0, idx);\n\t\t\tthis.pending = this.pending.slice(idx + 1);\n\t\t\tif (line.length === 0) continue;\n\t\t\tthis.handleLine(line);\n\t\t}\n\t}\n\n\tprivate handleLine(jsonLine: string) {\n\t\tlet obj: unknown;\n\t\ttry {\n\t\t\tobj = JSON.parse(jsonLine);\n\t\t} catch {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!obj || typeof obj !== \"object\") return;\n\t\tconst rec = obj as Record<string, unknown>;\n\t\tconst timeValue = rec.time;\n\t\tconst dirValue = rec.dir;\n\t\tconst smlValue = rec.sml;\n\t\tconst deviceIdValue = rec.deviceId;\n\t\tconst systemBytesValue = rec.systemBytes;\n\n\t\tconst dir =\n\t\t\tdirValue === \"Sent\" || dirValue === \"Received\" ? dirValue : null;\n\t\tconst sml = typeof smlValue === \"string\" ? smlValue : null;\n\t\tif (!dir || !sml) return;\n\n\t\tlet date: Date;\n\t\tif (typeof timeValue === \"number\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else if (typeof timeValue === \"string\") {\n\t\t\tdate = new Date(timeValue);\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t}\n\n\t\tconst deviceId = typeof deviceIdValue === \"number\" ? deviceIdValue : 0;\n\t\tconst systemBytes =\n\t\t\ttypeof systemBytesValue === \"number\" ? systemBytesValue : 0;\n\n\t\tconst out = `${formatDateTime(date)} ${dir} DeviceID: ${deviceId} SystemBytes: ${systemBytes} \\n${normalizeSmlForSingleLine(sml)}\\n`;\n\t\tthis.target.write(out);\n\t}\n}\n\nclass DisabledSecsLogger {\n\tdetail: Logger;\n\tsecs2: Logger;\n\tconstructor() {\n\t\tthis.detail = pino({ enabled: false });\n\t\tthis.secs2 = pino({ enabled: false });\n\t}\n\n\tlogSecs2(_direction: SecsLogDirection, _sml: string): void {\n\t\treturn;\n\t}\n\n\tlogBytes(\n\t\t_direction: SecsLogDirection,\n\t\t_protocol: string,\n\t\t_buffer: Buffer,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tlogState(\n\t\t_protocol: string,\n\t\t_prev: string,\n\t\t_next: string,\n\t\t_meta?: Record<string, unknown>,\n\t): void {\n\t\treturn;\n\t}\n\n\tclose(): void {\n\t\treturn;\n\t}\n}\n\nexport class SecsLogger {\n\tstatic disabled(): SecsLogger {\n\t\treturn new DisabledSecsLogger() as unknown as SecsLogger;\n\t}\n\n\tstatic create(\n\t\tconfig: SecsLoggerConfig | undefined,\n\t\tctx: SecsLoggerContext,\n\t): SecsLogger {\n\t\tconst enabled = config?.enabled ?? false;\n\t\tconst consoleEnabled = config?.console ?? false;\n\t\tif (!enabled) return SecsLogger.disabled();\n\n\t\tconst baseDir = config?.baseDir\n\t\t\t? path.resolve(config.baseDir)\n\t\t\t: path.resolve(process.cwd(), \"logs\");\n\t\tconst retentionDays = config?.retentionDays ?? 7;\n\t\tconst detailLevel = config?.detailLevel ?? \"debug\";\n\t\tconst secs2Level = config?.secs2Level ?? \"info\";\n\n\t\tconst detailStream = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-DETAIL.log`,\n\t\t\tretentionDays,\n\t\t});\n\n\t\tconst secs2Target = new DailyRotatingFileStream({\n\t\t\tbaseDir,\n\t\t\tfileNameForDate: (ymd) => `${ymd}-SECS-II.log`,\n\t\t\tretentionDays,\n\t\t});\n\t\tconst secs2Stream = new Secs2LineTransformStream(secs2Target);\n\n\t\tconst bindings = {\n\t\t\tname: ctx.name,\n\t\t\tdeviceId: ctx.deviceId,\n\t\t\tisEquip: ctx.isEquip,\n\t\t};\n\n\t\tconst detailPrettyStream = new PrettyPrintTransformStream();\n\t\tdetailPrettyStream.pipe(detailStream);\n\t\tconst detailStreams: pino.StreamEntry[] = [\n\t\t\t{ stream: detailPrettyStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tconst consolePrettyStream = new PrettyPrintTransformStream();\n\t\t\tconsolePrettyStream.pipe(process.stdout);\n\t\t\tdetailStreams.push({\n\t\t\t\tstream: consolePrettyStream,\n\t\t\t\tlevel: detailLevel as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst detail = pino(\n\t\t\t{ level: detailLevel, base: bindings },\n\t\t\tpino.multistream(detailStreams),\n\t\t);\n\n\t\tconst secs2ToDetailPrettyStream = new PrettyPrintTransformStream();\n\t\tsecs2ToDetailPrettyStream.pipe(detailStream);\n\t\tconst secs2Streams: pino.StreamEntry[] = [\n\t\t\t{ stream: secs2Stream as pino.DestinationStream },\n\t\t\t{ stream: secs2ToDetailPrettyStream as pino.DestinationStream },\n\t\t];\n\t\tif (consoleEnabled) {\n\t\t\tsecs2Streams.push({\n\t\t\t\tstream: process.stdout,\n\t\t\t\tlevel: secs2Level as pino.Level,\n\t\t\t});\n\t\t}\n\t\tconst secs2 = pino(\n\t\t\t{\n\t\t\t\tlevel: secs2Level,\n\t\t\t\tbase: bindings,\n\t\t\t\tmessageKey: \"msg\",\n\t\t\t},\n\t\t\tpino.multistream(secs2Streams),\n\t\t);\n\n\t\treturn new SecsLogger({\n\t\t\tconfig: { ...config, baseDir, retentionDays },\n\t\t\tdetail,\n\t\t\tsecs2,\n\t\t\tdetailStream,\n\t\t\tsecs2Target,\n\t\t\tsecs2Stream,\n\t\t});\n\t}\n\n\tpublic readonly detail: Logger;\n\tprivate readonly secs2: Logger;\n\tprivate readonly detailStream: DailyRotatingFileStream;\n\tprivate readonly secs2Target: DailyRotatingFileStream;\n\tprivate readonly secs2Stream: Secs2LineTransformStream;\n\tprivate readonly maxHexBytes: number;\n\n\tprivate constructor(params: {\n\t\tconfig: SecsLoggerConfig;\n\t\tdetail: Logger;\n\t\tsecs2: Logger;\n\t\tdetailStream: DailyRotatingFileStream;\n\t\tsecs2Target: DailyRotatingFileStream;\n\t\tsecs2Stream: Secs2LineTransformStream;\n\t}) {\n\t\tthis.detail = params.detail;\n\t\tthis.secs2 = params.secs2;\n\t\tthis.detailStream = params.detailStream;\n\t\tthis.secs2Target = params.secs2Target;\n\t\tthis.secs2Stream = params.secs2Stream;\n\t\tthis.maxHexBytes = params.config.maxHexBytes ?? 64 * 1024;\n\t}\n\n\tlogSecs2(\n\t\tdirection: SecsLogDirection,\n\t\tsml: string,\n\t\tdeviceId: number,\n\t\tsystemBytes: number,\n\t\tbuffer?: Buffer,\n\t): void {\n\t\tthis.secs2.info(\n\t\t\t{\n\t\t\t\tdir: direction,\n\t\t\t\tsml: normalizeSmlForSingleLine(sml),\n\t\t\t\tdeviceId,\n\t\t\t\tsystemBytes,\n\t\t\t\thex: buffer ? bufferToHex(buffer, this.maxHexBytes) : undefined,\n\t\t\t},\n\t\t\t\"\",\n\t\t);\n\t}\n\n\tlogBytes(\n\t\tdirection: SecsLogDirection,\n\t\tprotocol: string,\n\t\tbuffer: Buffer,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.trace(\n\t\t\t{\n\t\t\t\tprotocol,\n\t\t\t\tdir: direction,\n\t\t\t\tbyteLength: buffer.length,\n\t\t\t\thex: bufferToHex(buffer, this.maxHexBytes),\n\t\t\t\t...meta,\n\t\t\t},\n\t\t\t\"bytes\",\n\t\t);\n\t}\n\n\tlogState(\n\t\tprotocol: string,\n\t\tprev: string,\n\t\tnext: string,\n\t\tmeta?: Record<string, unknown>,\n\t): void {\n\t\tthis.detail.info({ protocol, prev, next, ...meta }, \"state\");\n\t}\n\n\tclose(): void {\n\t\tthis.secs2.flush();\n\t\tthis.detail.flush();\n\t\tthis.secs2Stream.end();\n\t\tthis.secs2Target.end();\n\t\tthis.detailStream.end();\n\t}\n}\n"],"mappings":";;;;;;AAuBA,SAAS,WAAW,MAAoB;CACvC,MAAM,IAAI,KAAK,aAAa;CAC5B,MAAM,IAAI,OAAO,KAAK,UAAU,GAAG,EAAE,CAAC,SAAS,GAAG,IAAI;CACtD,MAAM,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC,SAAS,GAAG,IAAI;AACjD,QAAO,GAAG,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG;;AAG7B,SAAS,eAAe,MAAoB;AAM3C,QAAO,GALK,WAAW,KAAK,CAKd,GAJH,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,GAAG,IAAI,CAI/B,GAHT,OAAO,KAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI,CAG3B,GAFf,OAAO,KAAK,YAAY,CAAC,CAAC,SAAS,GAAG,IAAI,CAErB,GADrB,OAAO,KAAK,iBAAiB,CAAC,CAAC,SAAS,GAAG,IAAI;;AAI3D,SAAS,mBAAmB,SAA8B;CACzD,MAAM,IAAI,4BAA4B,KAAK,QAAQ;AACnD,KAAI,CAAC,EAAG,QAAO;CACf,MAAM,OAAO,OAAO,EAAE,GAAG;CACzB,MAAM,QAAQ,OAAO,EAAE,GAAG;CAC1B,MAAM,MAAM,OAAO,EAAE,GAAG;AACxB,KACC,CAAC,OAAO,SAAS,KAAK,IACtB,CAAC,OAAO,SAAS,MAAM,IACvB,CAAC,OAAO,SAAS,IAAI,CAErB,QAAO;CACR,MAAM,KAAK,IAAI,KAAK,MAAM,QAAQ,GAAG,IAAI;AACzC,KAAI,GAAG,aAAa,KAAK,KAAM,QAAO;AACtC,KAAI,GAAG,UAAU,KAAK,QAAQ,EAAG,QAAO;AACxC,KAAI,GAAG,SAAS,KAAK,IAAK,QAAO;AACjC,QAAO;;AAGR,SAAS,0BAA0B,KAAqB;AACvD,QAAO,IAAI,MAAM;;AAGlB,SAAS,YAAY,QAAgB,aAA6B;CACjE,MAAM,MAAM,OAAO;CACnB,MAAM,MAAM,KAAK,IAAI,GAAG,YAAY;AAIpC,QAAO,IAHO,OAAO,MAAM,SAAS,OAAO,SAAS,GAAG,IAAI,EACzC,SAAS,MAAM,GAClB,OAAO,MAAM,KAAK,MAAM,OAAO,MAAM,IAAI,CAAC;;AAI1D,IAAM,6BAAN,cAAyC,UAAU;CAClD,AAAQ,UAAU;CAElB,cAAc;AACb,SAAO;;CAGR,AAAS,WACR,OACA,WACA,UACO;AACP,MAAI;GACH,MAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;AACtE,QAAK,WAAW;AAChB,QAAK,OAAO;AACZ,aAAU;WACF,GAAG;AACX,YAAS,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;;CAIzD,AAAS,OAAO,UAAgD;AAC/D,YAAU;;CAGX,AAAQ,QAAc;AACrB,SAAO,MAAM;GACZ,MAAM,MAAM,KAAK,QAAQ,QAAQ,KAAK;AACtC,OAAI,MAAM,EAAG;GACb,MAAM,OAAO,KAAK,QAAQ,MAAM,GAAG,IAAI;AACvC,QAAK,UAAU,KAAK,QAAQ,MAAM,MAAM,EAAE;AAC1C,OAAI,KAAK,WAAW,EAAG;GACvB,MAAM,MAAM,KAAK,MAAM,KAAK;GAC5B,MAAM,YAAY,KAAK,WAAW,IAAI;AACtC,QAAK,KAAK,UAAU;;;CAItB,AAAQ,WAAW,KAAsC;AAMxD,SAAO,GALM,KAAK,WAAW,IAAI,KAAK,CAKvB,GAJD,KAAK,YAAY,IAAI,MAAgB,CAI3B,GAHV,KAAK,YAAY,IAAI,CAGF,KAFrB,KAAK,cAAc,IAAI,CAEO;;CAG3C,AAAQ,WAAW,WAA4B;AAC9C,MAAI,OAAO,cAAc,SACxB,QAAO,eAAe,IAAI,KAAK,UAAU,CAAC;AAE3C,MAAI,OAAO,cAAc,SACxB,QAAO,eAAe,IAAI,KAAK,UAAU,CAAC;AAE3C,SAAO,+BAAe,IAAI,MAAM,CAAC;;CAGlC,AAAQ,YAAY,OAAuB;AAS1C,SARuC;GACtC,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,IAAI;GACJ,CACa,UAAU;;CAGzB,AAAQ,YAAY,KAAsC;EACzD,MAAMA,QAAkB,EAAE;AAE1B,MAAI,OAAO,IAAI,aAAa,SAC3B,OAAM,KAAK,IAAI,SAAS;AAEzB,MAAI,OAAO,IAAI,QAAQ,SACtB,OAAM,KAAK,IAAI,IAAI;AAEpB,MAAI,OAAO,IAAI,SAAS,YAAY,OAAO,IAAI,SAAS,SACvD,OAAM,KAAK,GAAG,IAAI,KAAK,MAAM,IAAI,OAAO;AAGzC,SAAO,MAAM,KAAK,IAAI;;CAGvB,AAAQ,cAAc,KAAsC;EAC3D,MAAM,WAAW,IAAI;AACrB,MAAI,OAAO,aAAa,YAAY,SAAS,MAAM,CAAC,SAAS,EAC5D,QAAO;EAGR,MAAM,cAAc,IAAI,IAAI;GAC3B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,CAAC;EAEF,MAAMC,QAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,IAAI,EAAE;AAC/C,OAAI,YAAY,IAAI,IAAI,CAAE;AAC1B,OAAI,OAAO,SAAS,MAAM,CACzB,OAAM,KAAK,GAAG,IAAI,GAAG,MAAM,SAAS,MAAM,GAAG;YACnC,OAAO,UAAU,SAC3B,OAAM,KAAK,GAAG,IAAI,GAAG,QAAQ;YACnB,OAAO,UAAU,YAAY,OAAO,UAAU,UACxD,OAAM,KAAK,GAAG,IAAI,GAAG,OAAO,MAAM,GAAG;OAErC,OAAM,KAAK,GAAG,IAAI,GAAG,KAAK,YAAY,MAAM,GAAG;;AAIjD,SAAO,MAAM,KAAK,IAAI;;CAGvB,AAAQ,YAAY,OAAwB;AAC3C,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,YAAY,OAAO,UAAU,UACjD,QAAO,OAAO,MAAM;AAErB,MAAI,OAAO,SAAS,MAAM,CACzB,QAAO,MAAM,SAAS,MAAM;AAE7B,MAAI,OAAO,UAAU,SACpB,KAAI;AACH,UAAO,KAAK,UAAU,MAAM;UACrB;AACP,UAAO;;AAGT,SAAO,OAAO,MAA4C;;;AAI5D,IAAM,0BAAN,cAAsC,SAAS;CAC9C,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAQ,aAA4B;CACpC,AAAQ,gBAAuC;CAC/C,AAAQ,aAA4B;CACpC,AAAQ,UAAU;CAElB,YAAY,QAIT;AACF,SAAO;AACP,OAAK,UAAU,OAAO;AACtB,OAAK,kBAAkB,OAAO;AAC9B,OAAK,gBAAgB,OAAO;;CAG7B,AAAS,OACR,OACA,UACA,UACO;AACP,MAAI;GACH,MAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;AACtE,QAAK,WAAW;AAChB,QAAK,oBAAoB;AACzB,aAAU;WACF,GAAG;AACX,YAAS,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;;CAIzD,AAAS,OAAO,UAAgD;AAC/D,MAAI;AACH,OAAI,KAAK,QAAQ,SAAS,GAAG;AAC5B,SAAK,oBAAoB;AACzB,SAAK,eAAe,MAAM,KAAK,QAAQ;AACvC,SAAK,UAAU;;AAEhB,QAAK,eAAe,UAAU,UAAU,CAAC;AACzC,QAAK,gBAAgB;WACb,GAAG;AACX,YAAS,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;;CAIzD,AAAQ,qBAAqB;AAC5B,SAAO,MAAM;GACZ,MAAM,MAAM,KAAK,QAAQ,QAAQ,KAAK;AACtC,OAAI,MAAM,EAAG;GACb,MAAM,OAAO,KAAK,QAAQ,MAAM,GAAG,MAAM,EAAE;AAC3C,QAAK,UAAU,KAAK,QAAQ,MAAM,MAAM,EAAE;AAC1C,QAAK,oBAAoB;AACzB,QAAK,eAAe,MAAM,KAAK;;;CAIjC,AAAQ,qBAAqB;EAC5B,MAAM,sBAAM,IAAI,MAAM;EACtB,MAAM,MAAM,WAAW,IAAI;AAC3B,MAAI,KAAK,eAAe,OAAO,KAAK,cAAe;AAEnD,MAAI,KAAK,eAAe;AACvB,QAAK,cAAc,KAAK;AACxB,QAAK,gBAAgB;;EAGtB,MAAM,MAAM,KAAK,KAAK,KAAK,SAAS,IAAI;AACxC,KAAG,UAAU,KAAK,EAAE,WAAW,MAAM,CAAC;EACtC,MAAM,WAAW,KAAK,KAAK,KAAK,KAAK,gBAAgB,IAAI,CAAC;AAC1D,OAAK,gBAAgB,GAAG,kBAAkB,UAAU,EAAE,OAAO,KAAK,CAAC;AACnE,OAAK,aAAa;AAElB,MAAI,KAAK,gBAAgB,KAAK,KAAK,eAAe,KAAK;AACtD,QAAK,aAAa;AAClB,wBAAqB;AACpB,SAAK,eAAe,IAAI,CAAC,YAAY,OAAU;KAC9C;;;CAIJ,MAAc,eAAe,KAA0B;EACtD,MAAM,gBAAgB,KAAK;AAC3B,MAAI,iBAAiB,EAAG;EAExB,IAAIC;AACJ,MAAI;AACH,aAAU,MAAM,GAAG,SAAS,QAAQ,KAAK,SAAS,EACjD,eAAe,MACf,CAAC;UACK;AACP;;EAGD,MAAM,SAAS,IAAI,KAClB,IAAI,aAAa,EACjB,IAAI,UAAU,EACd,IAAI,SAAS,EACb,GACA,GACA,GACA,EACA;AACD,SAAO,QAAQ,OAAO,SAAS,GAAG,cAAc;AAEhD,OAAK,MAAM,OAAO,SAAS;AAC1B,OAAI,CAAC,IAAI,aAAa,CAAE;GACxB,MAAM,UAAU,IAAI;GACpB,MAAM,UAAU,mBAAmB,QAAQ;AAC3C,OAAI,CAAC,QAAS;AACd,OAAI,WAAW,OAAQ;GACvB,MAAM,OAAO,KAAK,KAAK,KAAK,SAAS,QAAQ;AAC7C,OAAI;AACH,UAAM,GAAG,SAAS,GAAG,MAAM;KAAE,WAAW;KAAM,OAAO;KAAM,CAAC;WACrD;AACP;;;;;AAMJ,IAAM,2BAAN,cAAuC,SAAS;CAC/C,AAAiB;CACjB,AAAQ,UAAU;CAElB,YAAY,QAAiC;AAC5C,SAAO;AACP,OAAK,SAAS;;CAGf,AAAS,OACR,OACA,UACA,UACO;AACP,MAAI;GACH,MAAM,MAAM,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;AACtE,QAAK,WAAW;AAChB,QAAK,OAAO;AACZ,aAAU;WACF,GAAG;AACX,YAAS,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;;CAIzD,AAAS,OAAO,UAAgD;AAC/D,MAAI;AACH,QAAK,MAAM,KAAK;AAChB,QAAK,OAAO,UAAU,UAAU,CAAC;WACzB,GAAG;AACX,YAAS,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,EAAE,CAAC,CAAC;;;CAIzD,AAAQ,MAAM,WAAW,OAAO;AAC/B,SAAO,MAAM;GACZ,MAAM,MAAM,KAAK,QAAQ,QAAQ,KAAK;AACtC,OAAI,MAAM,GAAG;AACZ,QAAI,YAAY,KAAK,QAAQ,SAAS,GAAG;AACxC,UAAK,WAAW,KAAK,QAAQ;AAC7B,UAAK,UAAU;;AAEhB;;GAED,MAAM,OAAO,KAAK,QAAQ,MAAM,GAAG,IAAI;AACvC,QAAK,UAAU,KAAK,QAAQ,MAAM,MAAM,EAAE;AAC1C,OAAI,KAAK,WAAW,EAAG;AACvB,QAAK,WAAW,KAAK;;;CAIvB,AAAQ,WAAW,UAAkB;EACpC,IAAIC;AACJ,MAAI;AACH,SAAM,KAAK,MAAM,SAAS;UACnB;AACP;;AAGD,MAAI,CAAC,OAAO,OAAO,QAAQ,SAAU;EACrC,MAAM,MAAM;EACZ,MAAM,YAAY,IAAI;EACtB,MAAM,WAAW,IAAI;EACrB,MAAM,WAAW,IAAI;EACrB,MAAM,gBAAgB,IAAI;EAC1B,MAAM,mBAAmB,IAAI;EAE7B,MAAM,MACL,aAAa,UAAU,aAAa,aAAa,WAAW;EAC7D,MAAM,MAAM,OAAO,aAAa,WAAW,WAAW;AACtD,MAAI,CAAC,OAAO,CAAC,IAAK;EAElB,IAAIC;AACJ,MAAI,OAAO,cAAc,SACxB,QAAO,IAAI,KAAK,UAAU;WAChB,OAAO,cAAc,SAC/B,QAAO,IAAI,KAAK,UAAU;MAE1B,wBAAO,IAAI,MAAM;EAGlB,MAAM,WAAW,OAAO,kBAAkB,WAAW,gBAAgB;EACrE,MAAM,cACL,OAAO,qBAAqB,WAAW,mBAAmB;EAE3D,MAAM,MAAM,GAAG,eAAe,KAAK,CAAC,GAAG,IAAI,aAAa,SAAS,gBAAgB,YAAY,KAAK,0BAA0B,IAAI,CAAC;AACjI,OAAK,OAAO,MAAM,IAAI;;;AAIxB,IAAM,qBAAN,MAAyB;CACxB;CACA;CACA,cAAc;AACb,OAAK,SAAS,KAAK,EAAE,SAAS,OAAO,CAAC;AACtC,OAAK,QAAQ,KAAK,EAAE,SAAS,OAAO,CAAC;;CAGtC,SAAS,YAA8B,MAAoB;CAI3D,SACC,YACA,WACA,SACA,OACO;CAIR,SACC,WACA,OACA,OACA,OACO;CAIR,QAAc;;AAKf,IAAa,aAAb,MAAa,WAAW;CACvB,OAAO,WAAuB;AAC7B,SAAO,IAAI,oBAAoB;;CAGhC,OAAO,OACN,QACA,KACa;EACb,MAAM,UAAU,QAAQ,WAAW;EACnC,MAAM,iBAAiB,QAAQ,WAAW;AAC1C,MAAI,CAAC,QAAS,QAAO,WAAW,UAAU;EAE1C,MAAM,UAAU,QAAQ,UACrB,KAAK,QAAQ,OAAO,QAAQ,GAC5B,KAAK,QAAQ,QAAQ,KAAK,EAAE,OAAO;EACtC,MAAM,gBAAgB,QAAQ,iBAAiB;EAC/C,MAAM,cAAc,QAAQ,eAAe;EAC3C,MAAM,aAAa,QAAQ,cAAc;EAEzC,MAAM,eAAe,IAAI,wBAAwB;GAChD;GACA,kBAAkB,QAAQ,GAAG,IAAI;GACjC;GACA,CAAC;EAEF,MAAM,cAAc,IAAI,wBAAwB;GAC/C;GACA,kBAAkB,QAAQ,GAAG,IAAI;GACjC;GACA,CAAC;EACF,MAAM,cAAc,IAAI,yBAAyB,YAAY;EAE7D,MAAM,WAAW;GAChB,MAAM,IAAI;GACV,UAAU,IAAI;GACd,SAAS,IAAI;GACb;EAED,MAAM,qBAAqB,IAAI,4BAA4B;AAC3D,qBAAmB,KAAK,aAAa;EACrC,MAAMC,gBAAoC,CACzC,EAAE,QAAQ,oBAA8C,CACxD;AACD,MAAI,gBAAgB;GACnB,MAAM,sBAAsB,IAAI,4BAA4B;AAC5D,uBAAoB,KAAK,QAAQ,OAAO;AACxC,iBAAc,KAAK;IAClB,QAAQ;IACR,OAAO;IACP,CAAC;;EAEH,MAAM,SAAS,KACd;GAAE,OAAO;GAAa,MAAM;GAAU,EACtC,KAAK,YAAY,cAAc,CAC/B;EAED,MAAM,4BAA4B,IAAI,4BAA4B;AAClE,4BAA0B,KAAK,aAAa;EAC5C,MAAMC,eAAmC,CACxC,EAAE,QAAQ,aAAuC,EACjD,EAAE,QAAQ,2BAAqD,CAC/D;AACD,MAAI,eACH,cAAa,KAAK;GACjB,QAAQ,QAAQ;GAChB,OAAO;GACP,CAAC;EAEH,MAAM,QAAQ,KACb;GACC,OAAO;GACP,MAAM;GACN,YAAY;GACZ,EACD,KAAK,YAAY,aAAa,CAC9B;AAED,SAAO,IAAI,WAAW;GACrB,QAAQ;IAAE,GAAG;IAAQ;IAAS;IAAe;GAC7C;GACA;GACA;GACA;GACA;GACA,CAAC;;CAGH,AAAgB;CAChB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CACjB,AAAiB;CAEjB,AAAQ,YAAY,QAOjB;AACF,OAAK,SAAS,OAAO;AACrB,OAAK,QAAQ,OAAO;AACpB,OAAK,eAAe,OAAO;AAC3B,OAAK,cAAc,OAAO;AAC1B,OAAK,cAAc,OAAO;AAC1B,OAAK,cAAc,OAAO,OAAO,eAAe,KAAK;;CAGtD,SACC,WACA,KACA,UACA,aACA,QACO;AACP,OAAK,MAAM,KACV;GACC,KAAK;GACL,KAAK,0BAA0B,IAAI;GACnC;GACA;GACA,KAAK,SAAS,YAAY,QAAQ,KAAK,YAAY,GAAG;GACtD,EACD,GACA;;CAGF,SACC,WACA,UACA,QACA,MACO;AACP,OAAK,OAAO,MACX;GACC;GACA,KAAK;GACL,YAAY,OAAO;GACnB,KAAK,YAAY,QAAQ,KAAK,YAAY;GAC1C,GAAG;GACH,EACD,QACA;;CAGF,SACC,UACA,MACA,MACA,MACO;AACP,OAAK,OAAO,KAAK;GAAE;GAAU;GAAM;GAAM,GAAG;GAAM,EAAE,QAAQ;;CAG7D,QAAc;AACb,OAAK,MAAM,OAAO;AAClB,OAAK,OAAO,OAAO;AACnB,OAAK,YAAY,KAAK;AACtB,OAAK,YAAY,KAAK;AACtB,OAAK,aAAa,KAAK"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "secs4js",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "A simple, efficient, and user-friendly SECS/GEM protocol library implemented in TypeScript.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,7 +22,7 @@
22
22
  "license": "MIT",
23
23
  "author": {
24
24
  "name": "Ran Qian",
25
- "email": "1151264028@qq.com"
25
+ "email": "fizzdog.rq@foxmail.com"
26
26
  },
27
27
  "type": "module",
28
28
  "main": "./lib/index.js",