@uns-kit/core 3.0.25 → 3.0.27

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.
Files changed (56) hide show
  1. package/MIGRATIONS.md +51 -0
  2. package/dist/runtime/compatibility/energenti-authorization-v1.d.ts +95 -0
  3. package/dist/runtime/compatibility/energenti-authorization-v1.d.ts.map +1 -0
  4. package/dist/runtime/compatibility/energenti-authorization-v1.js +315 -0
  5. package/dist/runtime/compatibility/energenti-authorization-v1.js.map +1 -0
  6. package/dist/runtime/compatibility/energenti-descriptor-v1.d.ts +10 -0
  7. package/dist/runtime/compatibility/energenti-descriptor-v1.d.ts.map +1 -0
  8. package/dist/runtime/compatibility/energenti-descriptor-v1.js +18 -0
  9. package/dist/runtime/compatibility/energenti-descriptor-v1.js.map +1 -0
  10. package/dist/runtime/process-group-authorization.d.ts +107 -0
  11. package/dist/runtime/process-group-authorization.d.ts.map +1 -0
  12. package/dist/runtime/process-group-authorization.js +352 -0
  13. package/dist/runtime/process-group-authorization.js.map +1 -0
  14. package/dist/runtime/process-group-contract.d.ts +65 -0
  15. package/dist/runtime/process-group-contract.d.ts.map +1 -0
  16. package/dist/runtime/process-group-contract.js +171 -0
  17. package/dist/runtime/process-group-contract.js.map +1 -0
  18. package/dist/runtime/process-group-control-contract.d.ts +56 -0
  19. package/dist/runtime/process-group-control-contract.d.ts.map +1 -0
  20. package/dist/runtime/process-group-control-contract.js +37 -0
  21. package/dist/runtime/process-group-control-contract.js.map +1 -0
  22. package/dist/runtime/process-group-inspection.d.ts +22 -0
  23. package/dist/runtime/process-group-inspection.d.ts.map +1 -0
  24. package/dist/runtime/process-group-inspection.js +185 -0
  25. package/dist/runtime/process-group-inspection.js.map +1 -0
  26. package/dist/runtime/process-group-launch-environment.d.ts +3 -0
  27. package/dist/runtime/process-group-launch-environment.d.ts.map +1 -0
  28. package/dist/runtime/process-group-launch-environment.js +12 -0
  29. package/dist/runtime/process-group-launch-environment.js.map +1 -0
  30. package/dist/runtime/process-group-legacy-start.d.ts +2 -0
  31. package/dist/runtime/process-group-legacy-start.d.ts.map +1 -0
  32. package/dist/runtime/process-group-legacy-start.js +16 -0
  33. package/dist/runtime/process-group-legacy-start.js.map +1 -0
  34. package/dist/runtime/process-group-resources.d.ts +8 -0
  35. package/dist/runtime/process-group-resources.d.ts.map +1 -0
  36. package/dist/runtime/process-group-resources.js +96 -0
  37. package/dist/runtime/process-group-resources.js.map +1 -0
  38. package/dist/runtime/process-group-snapshot.mjs +199 -0
  39. package/dist/runtime/process-group-staging.d.ts +5 -0
  40. package/dist/runtime/process-group-staging.d.ts.map +1 -0
  41. package/dist/runtime/process-group-staging.js +63 -0
  42. package/dist/runtime/process-group-staging.js.map +1 -0
  43. package/dist/runtime/process-group-supervision.d.ts +13 -0
  44. package/dist/runtime/process-group-supervision.d.ts.map +1 -0
  45. package/dist/runtime/process-group-supervision.js +34 -0
  46. package/dist/runtime/process-group-supervision.js.map +1 -0
  47. package/dist/uns/uns-attributes.d.ts +2 -2
  48. package/dist/uns-mqtt/mqtt-proxy.d.ts +3 -0
  49. package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
  50. package/dist/uns-mqtt/mqtt-proxy.js +38 -0
  51. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  52. package/dist/uns-mqtt/subscription-readiness.d.ts +23 -0
  53. package/dist/uns-mqtt/subscription-readiness.d.ts.map +1 -0
  54. package/dist/uns-mqtt/subscription-readiness.js +50 -0
  55. package/dist/uns-mqtt/subscription-readiness.js.map +1 -0
  56. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { SubscriptionReadiness } from "./subscription-readiness.js";
1
2
  import mqtt from "mqtt";
2
3
  import logger from "../logger.js";
3
4
  import { UnsEventEmitter } from "../uns/uns-event-emitter.js";
@@ -20,6 +21,8 @@ export default class MqttProxy {
20
21
  subscribedMessageBytes = 0;
21
22
  mqttWorker;
22
23
  isConnected = false;
24
+ subscriptionReadiness = new SubscriptionReadiness();
25
+ lastSubscriptionReady = null;
23
26
  rejectUnauthorized;
24
27
  pendingReconnectWait = null;
25
28
  hasEstablishedConnection = false;
@@ -67,6 +70,14 @@ export default class MqttProxy {
67
70
  }, 60000);
68
71
  }
69
72
  }
73
+ emitSubscriptionReadiness(force = false) {
74
+ const ready = this.subscriptionReadiness.ready();
75
+ if (!force && ready === this.lastSubscriptionReady)
76
+ return;
77
+ this.lastSubscriptionReady = ready;
78
+ this.event.emit("mqttProxyStatus", { event: "mqtt-subscriptions-ready", value: ready ? 1 : 0,
79
+ uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + "mqtt-subscriptions-ready" });
80
+ }
70
81
  subscribeToTopics() {
71
82
  if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {
72
83
  logger.debug(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);
@@ -165,6 +176,14 @@ export default class MqttProxy {
165
176
  }
166
177
  const onConnect = () => this.handleMqttConnect();
167
178
  this.mqttClient.on("connect", onConnect);
179
+ this.mqttClient.on("packetsend", packet => {
180
+ this.subscriptionReadiness.sent(packet);
181
+ this.emitSubscriptionReadiness();
182
+ });
183
+ this.mqttClient.on("packetreceive", packet => {
184
+ this.subscriptionReadiness.received(packet);
185
+ this.emitSubscriptionReadiness();
186
+ });
168
187
  this.mqttClient.on("message", (topic, message, packet) => {
169
188
  try {
170
189
  logger.debug(`${this.instanceName} - Message received on topic ${topic}`);
@@ -183,6 +202,8 @@ export default class MqttProxy {
183
202
  const errorInfo = formatMqttError(error);
184
203
  logger.error(`${this.instanceName} - MQTT client error: ${errorInfo.message}`);
185
204
  this.isConnected = false;
205
+ this.subscriptionReadiness.connection(false);
206
+ this.emitSubscriptionReadiness();
186
207
  this.event.emit("error", {
187
208
  code: typeof errorInfo.code === "number" ? errorInfo.code : 0,
188
209
  message: errorInfo.message,
@@ -195,23 +216,33 @@ export default class MqttProxy {
195
216
  this.mqttClient.on("close", () => {
196
217
  logger.debug(`${this.instanceName} - MQTT connection closed.`);
197
218
  this.isConnected = false;
219
+ this.subscriptionReadiness.connection(false);
220
+ this.emitSubscriptionReadiness();
198
221
  });
199
222
  this.mqttClient.on("offline", () => {
200
223
  logger.debug(`${this.instanceName} - MQTT client is offline.`);
201
224
  this.isConnected = false;
225
+ this.subscriptionReadiness.connection(false);
226
+ this.emitSubscriptionReadiness();
202
227
  });
203
228
  this.mqttClient.on("end", () => {
204
229
  logger.debug(`${this.instanceName} - MQTT client connection ended.`);
205
230
  this.isConnected = false;
231
+ this.subscriptionReadiness.connection(false);
232
+ this.emitSubscriptionReadiness();
206
233
  });
207
234
  this.mqttClient.on("disconnect", (packet) => {
208
235
  logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);
209
236
  this.isConnected = false;
237
+ this.subscriptionReadiness.connection(false);
238
+ this.emitSubscriptionReadiness();
210
239
  });
211
240
  }
212
241
  catch (error) {
213
242
  logger.error(`${this.instanceName} - Error starting MQTT proxy: ${formatMqttError(error).message}`);
214
243
  this.isConnected = false;
244
+ this.subscriptionReadiness.connection(false);
245
+ this.emitSubscriptionReadiness();
215
246
  reject(error);
216
247
  }
217
248
  });
@@ -260,6 +291,8 @@ export default class MqttProxy {
260
291
  return new Promise((resolve, reject) => {
261
292
  const resetState = () => {
262
293
  this.isConnected = false;
294
+ this.subscriptionReadiness.connection(false);
295
+ this.emitSubscriptionReadiness();
263
296
  this.pendingReconnectWait = null;
264
297
  this.startupSettled = false;
265
298
  this.hasEstablishedConnection = false;
@@ -311,6 +344,8 @@ export default class MqttProxy {
311
344
  this.startupSettled = true;
312
345
  this.hasEstablishedConnection = true;
313
346
  this.isConnected = true;
347
+ this.subscriptionReadiness.connection(true);
348
+ this.emitSubscriptionReadiness();
314
349
  if (isFirstConnect) {
315
350
  logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);
316
351
  this.subscribeToTopics();
@@ -329,11 +364,14 @@ export default class MqttProxy {
329
364
  catch (error) {
330
365
  logger.error(`${this.instanceName} - Error in MQTT connect handler: ${formatMqttError(error).message}`);
331
366
  this.isConnected = false;
367
+ this.subscriptionReadiness.connection(false);
368
+ this.emitSubscriptionReadiness();
332
369
  reject(error);
333
370
  }
334
371
  }
335
372
  emitStatusUpdates() {
336
373
  try {
374
+ this.emitSubscriptionReadiness(true);
337
375
  const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);
338
376
  this.event.emit("mqttProxyStatus", { event: "uptime", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + "uptime" });
339
377
  this.event.emit("mqttProxyStatus", { event: "alive", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + "alive" });
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt, { IClientOptions, MqttClient } from \"mqtt\";\nimport logger from \"../logger.js\";\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\n\nexport type MqttStopOptions = {\n silent?: boolean;\n reason?: \"retry\" | \"shutdown\";\n};\n\ntype MqttErrorInfo = {\n code: string | number;\n message: string;\n};\n\nexport default class MqttProxy {\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n public statusTopic: string;\n public instanceName: string;\n private mqttHost: string;\n private mqttSubToTopics: string | string[];\n private mqttSSL: boolean;\n private mqttClient: MqttClient;\n private startDate: Date;\n private mqttParameters: IMqttParameters;\n private statusUpdateInterval: ReturnType<typeof setInterval>;\n private transformationStatsInterval: NodeJS.Timeout | null = null;\n private publishedMessageCount = 0;\n private publishedMessageBytes = 0;\n private subscribedMessageCount = 0;\n private subscribedMessageBytes = 0;\n private mqttWorker: MqttWorker;\n public isConnected = false;\n private rejectUnauthorized: boolean;\n private pendingReconnectWait: Promise<void> | null = null;\n private hasEstablishedConnection = false;\n private startupSettled = false;\n private startupResolve: (() => void) | null = null;\n private startupReject: ((error: unknown) => void) | null = null;\n\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\n this.rejectUnauthorized = mqttParameters.rejectUnauthorized ?? false;\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\n this.mqttHost = mqttHost;\n this.startDate = new Date();\n this.instanceName = instanceName ?? \"process\";\n this.statusTopic = `${mqttParameters?.statusTopic}`;\n this.mqttParameters = mqttParameters ?? {};\n this.mqttWorker = mqttWorker;\n }\n\n private resolveProtocol(): IMqttParameters[\"protocol\"] {\n return this.mqttParameters.protocol ?? (this.mqttSSL ? \"mqtts\" : \"mqtt\");\n }\n\n private resolveDefaultPort(protocol: IMqttParameters[\"protocol\"]): number {\n switch (protocol) {\n case \"mqtts\":\n case \"ssl\":\n return 8883;\n case \"wss\":\n return 443;\n case \"ws\":\n return 80;\n case \"tcp\":\n case \"mqtt\":\n default:\n return 1883;\n }\n }\n\n private ensureStatusUpdateInterval(): void {\n if (this.statusTopic && !this.statusUpdateInterval) {\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\n }\n }\n\n private ensureTransformationStatsInterval(): void {\n if (!this.transformationStatsInterval) {\n this.transformationStatsInterval = setInterval(() => {\n this.emitTransformationStatistics();\n }, 60000);\n }\n }\n\n private subscribeToTopics(): void {\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\n logger.debug(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\n }\n }\n\n private buildServers(defaultProtocol: IMqttParameters[\"protocol\"]): IClientOptions[\"servers\"] | undefined {\n const servers: IClientOptions[\"servers\"] = [];\n const { port } = this.mqttParameters;\n const protocol = this.mqttParameters.protocol ?? defaultProtocol;\n\n if (Array.isArray(this.mqttParameters.servers) && this.mqttParameters.servers.length > 0) {\n for (const server of this.mqttParameters.servers) {\n if (!server?.host) continue;\n const resolvedProtocol = server.protocol ?? protocol;\n const resolvedPort =\n typeof server.port === \"number\"\n ? server.port\n : typeof port === \"number\"\n ? port\n : this.resolveDefaultPort(resolvedProtocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host: server.host,\n port: resolvedPort,\n };\n if (resolvedProtocol) {\n entry.protocol = resolvedProtocol;\n }\n servers.push(entry);\n }\n } else if (Array.isArray(this.mqttParameters.hosts) && this.mqttParameters.hosts.length > 0) {\n for (const host of this.mqttParameters.hosts) {\n if (!host) continue;\n const resolvedPort = typeof port === \"number\" ? port : this.resolveDefaultPort(protocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host,\n port: resolvedPort,\n };\n if (protocol) {\n entry.protocol = protocol;\n }\n servers.push(entry);\n }\n }\n\n return servers.length > 0 ? servers : undefined;\n }\n\n public async start(): Promise<void> {\n logger.debug(`${this.instanceName} - Connecting to MQTT broker...`);\n this.startupSettled = false;\n\n return new Promise<void>((resolve, reject) => {\n this.startupResolve = resolve;\n this.startupReject = reject;\n try {\n const username = this.mqttParameters.username;\n const password = this.mqttParameters.password;\n const clientId = this.mqttParameters.clientId ?? this.instanceName;\n const protocol = this.resolveProtocol();\n\n const options: IClientOptions = {\n username,\n password,\n protocolVersion: 5,\n rejectUnauthorized: this.rejectUnauthorized,\n keepalive: this.mqttParameters.keepalive,\n clean: this.mqttParameters.clean ?? true,\n connectTimeout: this.mqttParameters.connectTimeout,\n reconnectPeriod: this.mqttParameters.reconnectPeriod,\n reconnectOnConnackError: this.mqttParameters.reconnectOnConnackError,\n resubscribe: this.mqttParameters.resubscribe,\n queueQoSZero: this.mqttParameters.queueQoSZero,\n properties: this.mqttParameters.properties,\n ca: this.mqttParameters.ca,\n cert: this.mqttParameters.cert,\n key: this.mqttParameters.key,\n servername: this.mqttParameters.servername,\n \n will: {\n topic: `${this.statusTopic}alive`,\n payload: Buffer.from(\"\"),\n qos: 0,\n retain: true,\n properties: { messageExpiryInterval: 3600 },\n },\n clientId,\n };\n\n const servers = this.buildServers(protocol);\n if (servers) {\n options.servers = servers;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n } else {\n options.host = this.mqttHost;\n options.port = this.mqttParameters.port;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n }\n\n const onConnect = () => this.handleMqttConnect();\n\n this.mqttClient.on(\"connect\", onConnect);\n\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\n try {\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\n this.event.emit(\"input\", {\n message: message.toString(),\n topic: topic,\n packet: packet,\n });\n this.updateSubscribeTransformationStats(message.length);\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\n }\n });\n\n this.mqttClient.on(\"error\", (error) => {\n const errorInfo = formatMqttError(error);\n logger.error(`${this.instanceName} - MQTT client error: ${errorInfo.message}`);\n this.isConnected = false;\n this.event.emit(\"error\", {\n code: typeof errorInfo.code === \"number\" ? errorInfo.code : 0,\n message: errorInfo.message,\n });\n reject(error);\n });\n\n this.mqttClient.on(\"reconnect\", () => {\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\n });\n\n this.mqttClient.on(\"close\", () => {\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"offline\", () => {\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"end\", () => {\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"disconnect\", (packet) => {\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\n this.isConnected = false;\n });\n } catch (error) {\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${formatMqttError(error).message}`);\n this.isConnected = false;\n reject(error);\n }\n });\n }\n\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\n this.updatePublishTransformationStats(JSON.stringify(message).length);\n const client = this.mqttClient;\n if (!client) {\n throw new Error(`${this.instanceName} - MQTT client missing; cannot publish to ${topic}`);\n }\n\n if (!client.connected) {\n // Wait briefly for reconnection before giving up.\n await this.waitForReconnect(client, 5000);\n }\n\n if (!client.connected) {\n throw new Error(`${this.instanceName} - MQTT client still disconnected; publish failed for ${topic}`);\n }\n\n return new Promise((resolve, reject) => {\n client.publish(topic, message, options || {}, (err) => {\n if (err) {\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\n return reject(err);\n }\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\n resolve();\n });\n });\n }\n\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\n return this.mqttClient.subscribeAsync(topic, options);\n }\n\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\n const topics = Array.isArray(topic) ? topic.filter((t) => typeof t === \"string\" && t.length > 0) : [topic].filter((t): t is string => typeof t === \"string\" && t.length > 0);\n if (topics.length === 0) {\n logger.warn(`${this.instanceName} - unsubscribeAsync called with empty topic list; skipping.`);\n return Promise.resolve(undefined);\n }\n return this.mqttClient.unsubscribeAsync(topics);\n }\n\n public stop(options: MqttStopOptions = {}): Promise<void> {\n const silent = options.silent === true || options.reason === \"retry\";\n const shouldLogDisconnect = !silent && this.hasEstablishedConnection;\n\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnecting from MQTT broker...`);\n }\n\n return new Promise((resolve, reject) => {\n const resetState = () => {\n this.isConnected = false;\n this.pendingReconnectWait = null;\n this.startupSettled = false;\n this.hasEstablishedConnection = false;\n this.startupResolve = null;\n this.startupReject = null;\n };\n\n try {\n if (this.statusUpdateInterval) {\n clearInterval(this.statusUpdateInterval);\n this.statusUpdateInterval = null;\n }\n if (this.transformationStatsInterval) {\n clearInterval(this.transformationStatsInterval);\n this.transformationStatsInterval = null;\n }\n if (this.mqttClient) {\n this.mqttClient.end(false, () => {\n resetState();\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);\n }\n resolve();\n });\n } else {\n resetState();\n resolve();\n }\n } catch (error) {\n resetState();\n const reason = error instanceof Error ? error : new Error(String(error));\n if (!silent) {\n logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(reason).message}`);\n }\n reject(reason);\n }\n });\n }\n\n private handleMqttConnect(): void {\n const resolve = this.startupResolve;\n const reject = this.startupReject;\n if (!resolve || !reject) {\n return;\n }\n\n try {\n this.mqttClient.stream.setMaxListeners(0);\n const isFirstConnect = !this.startupSettled;\n this.startupSettled = true;\n this.hasEstablishedConnection = true;\n this.isConnected = true;\n\n if (isFirstConnect) {\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\n this.subscribeToTopics();\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n resolve();\n return;\n }\n\n logger.info(`${this.instanceName} - Reconnected to MQTT broker at ${this.mqttHost}`);\n if (this.mqttParameters.resubscribe === false) {\n this.subscribeToTopics();\n }\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${formatMqttError(error).message}`);\n this.isConnected = false;\n reject(error);\n }\n }\n\n private emitStatusUpdates() {\n try {\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\n\n if (this.mqttWorker !== undefined) {\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\n }\n } catch (error) {\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\n }\n }\n\n private updatePublishTransformationStats(messageSizeOut: number): void {\n this.publishedMessageCount += 1;\n this.publishedMessageBytes += messageSizeOut;\n }\n\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\n this.subscribedMessageCount += 1;\n this.subscribedMessageBytes += messageSizeIn;\n }\n\n private waitForReconnect(client: mqtt.MqttClient, timeoutMs: number): Promise<void> {\n if (client.connected) {\n return Promise.resolve();\n }\n\n if (this.pendingReconnectWait) {\n return this.pendingReconnectWait;\n }\n\n this.pendingReconnectWait = new Promise<void>((resolve) => {\n if (client.connected) return resolve();\n\n const onConnect = () => {\n cleanup();\n resolve();\n };\n const onClose = () => {\n // stay waiting; close is expected during reconnect attempts\n };\n const cleanup = () => {\n client.off(\"connect\", onConnect);\n client.off(\"close\", onClose);\n };\n\n client.on(\"connect\", onConnect);\n client.on(\"close\", onClose);\n\n setTimeout(() => {\n cleanup();\n resolve();\n }, timeoutMs).unref?.();\n }).finally(() => {\n this.pendingReconnectWait = null;\n });\n\n return this.pendingReconnectWait;\n }\n\n private async emitTransformationStatistics(): Promise<void> {\n if (this.statusTopic !== \"\") {\n try {\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-count\",\n value: this.publishedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"published-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-bytes\",\n value: Math.round(this.publishedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"published-message-bytes\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-count\",\n value: this.subscribedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"subscribed-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-bytes\",\n value: Math.round(this.subscribedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\n });\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n } catch (error: any) {\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\n }\n }\n }\n}\n\nexport function formatMqttError(error: unknown): MqttErrorInfo {\n const parts: string[] = [];\n const codes: Array<string | number> = [];\n collectMqttErrorParts(error, parts, codes);\n\n const uniqueParts = Array.from(new Set(parts.map((part) => part.trim()).filter(Boolean)));\n const message = uniqueParts.join(\"; \") || \"Unknown MQTT error\";\n\n return {\n code: codes[0] ?? 0,\n message,\n };\n}\n\nfunction collectMqttErrorParts(\n error: unknown,\n parts: string[],\n codes: Array<string | number>,\n): void {\n if (error instanceof AggregateError) {\n if (typeof error.message === \"string\" && error.message.trim()) {\n parts.push(error.message.trim());\n }\n for (const nested of error.errors) {\n collectMqttErrorParts(nested, parts, codes);\n }\n return;\n }\n\n if (typeof error === \"string\") {\n if (error.trim()) {\n parts.push(error.trim());\n }\n return;\n }\n\n if (!error || typeof error !== \"object\") {\n return;\n }\n\n const record = error as {\n message?: unknown;\n name?: unknown;\n code?: unknown;\n address?: unknown;\n port?: unknown;\n cause?: unknown;\n };\n\n const code =\n typeof record.code === \"string\" || typeof record.code === \"number\"\n ? record.code\n : undefined;\n if (code !== undefined) {\n codes.push(code);\n }\n\n const message =\n typeof record.message === \"string\" && record.message.trim()\n ? record.message.trim()\n : undefined;\n const address =\n typeof record.address === \"string\" && record.address.trim()\n ? record.address.trim()\n : undefined;\n const port = typeof record.port === \"number\" ? record.port : undefined;\n const endpoint =\n address || port !== undefined\n ? `${address ?? \"\"}${address && port !== undefined ? \":\" : \"\"}${port ?? \"\"}`.trim()\n : undefined;\n\n const detailParts = [\n code !== undefined && !message?.includes(String(code)) ? String(code) : undefined,\n message,\n endpoint && !message?.includes(endpoint) ? endpoint : undefined,\n ].filter((part): part is string => typeof part === \"string\" && part.length > 0);\n\n if (detailParts.length > 0) {\n parts.push(detailParts.join(\" \"));\n } else if (typeof record.name === \"string\" && record.name.trim()) {\n parts.push(record.name.trim());\n }\n\n if (record.cause !== undefined) {\n collectMqttErrorParts(record.cause, parts, codes);\n }\n}\n"]}
1
+ {"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { SubscriptionReadiness } from \"./subscription-readiness.js\";\nimport mqtt, { IClientOptions, MqttClient } from \"mqtt\";\nimport logger from \"../logger.js\";\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\n\nexport type MqttStopOptions = {\n silent?: boolean;\n reason?: \"retry\" | \"shutdown\";\n};\n\ntype MqttErrorInfo = {\n code: string | number;\n message: string;\n};\n\nexport default class MqttProxy {\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n public statusTopic: string;\n public instanceName: string;\n private mqttHost: string;\n private mqttSubToTopics: string | string[];\n private mqttSSL: boolean;\n private mqttClient: MqttClient;\n private startDate: Date;\n private mqttParameters: IMqttParameters;\n private statusUpdateInterval: ReturnType<typeof setInterval>;\n private transformationStatsInterval: NodeJS.Timeout | null = null;\n private publishedMessageCount = 0;\n private publishedMessageBytes = 0;\n private subscribedMessageCount = 0;\n private subscribedMessageBytes = 0;\n private mqttWorker: MqttWorker;\n public isConnected = false;\n private subscriptionReadiness = new SubscriptionReadiness();\n private lastSubscriptionReady: boolean | null = null;\n private rejectUnauthorized: boolean;\n private pendingReconnectWait: Promise<void> | null = null;\n private hasEstablishedConnection = false;\n private startupSettled = false;\n private startupResolve: (() => void) | null = null;\n private startupReject: ((error: unknown) => void) | null = null;\n\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\n this.rejectUnauthorized = mqttParameters.rejectUnauthorized ?? false;\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\n this.mqttHost = mqttHost;\n this.startDate = new Date();\n this.instanceName = instanceName ?? \"process\";\n this.statusTopic = `${mqttParameters?.statusTopic}`;\n this.mqttParameters = mqttParameters ?? {};\n this.mqttWorker = mqttWorker;\n }\n\n private resolveProtocol(): IMqttParameters[\"protocol\"] {\n return this.mqttParameters.protocol ?? (this.mqttSSL ? \"mqtts\" : \"mqtt\");\n }\n\n private resolveDefaultPort(protocol: IMqttParameters[\"protocol\"]): number {\n switch (protocol) {\n case \"mqtts\":\n case \"ssl\":\n return 8883;\n case \"wss\":\n return 443;\n case \"ws\":\n return 80;\n case \"tcp\":\n case \"mqtt\":\n default:\n return 1883;\n }\n }\n\n private ensureStatusUpdateInterval(): void {\n if (this.statusTopic && !this.statusUpdateInterval) {\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\n }\n }\n\n private ensureTransformationStatsInterval(): void {\n if (!this.transformationStatsInterval) {\n this.transformationStatsInterval = setInterval(() => {\n this.emitTransformationStatistics();\n }, 60000);\n }\n }\n\n private emitSubscriptionReadiness(force = false): void {\n const ready = this.subscriptionReadiness.ready();\n if (!force && ready === this.lastSubscriptionReady) return;\n this.lastSubscriptionReady = ready;\n this.event.emit(\"mqttProxyStatus\", {event: \"mqtt-subscriptions-ready\", value: ready ? 1 : 0,\n uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"mqtt-subscriptions-ready\"});\n }\n\n private subscribeToTopics(): void {\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\n logger.debug(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\n }\n }\n\n private buildServers(defaultProtocol: IMqttParameters[\"protocol\"]): IClientOptions[\"servers\"] | undefined {\n const servers: IClientOptions[\"servers\"] = [];\n const { port } = this.mqttParameters;\n const protocol = this.mqttParameters.protocol ?? defaultProtocol;\n\n if (Array.isArray(this.mqttParameters.servers) && this.mqttParameters.servers.length > 0) {\n for (const server of this.mqttParameters.servers) {\n if (!server?.host) continue;\n const resolvedProtocol = server.protocol ?? protocol;\n const resolvedPort =\n typeof server.port === \"number\"\n ? server.port\n : typeof port === \"number\"\n ? port\n : this.resolveDefaultPort(resolvedProtocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host: server.host,\n port: resolvedPort,\n };\n if (resolvedProtocol) {\n entry.protocol = resolvedProtocol;\n }\n servers.push(entry);\n }\n } else if (Array.isArray(this.mqttParameters.hosts) && this.mqttParameters.hosts.length > 0) {\n for (const host of this.mqttParameters.hosts) {\n if (!host) continue;\n const resolvedPort = typeof port === \"number\" ? port : this.resolveDefaultPort(protocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host,\n port: resolvedPort,\n };\n if (protocol) {\n entry.protocol = protocol;\n }\n servers.push(entry);\n }\n }\n\n return servers.length > 0 ? servers : undefined;\n }\n\n public async start(): Promise<void> {\n logger.debug(`${this.instanceName} - Connecting to MQTT broker...`);\n this.startupSettled = false;\n\n return new Promise<void>((resolve, reject) => {\n this.startupResolve = resolve;\n this.startupReject = reject;\n try {\n const username = this.mqttParameters.username;\n const password = this.mqttParameters.password;\n const clientId = this.mqttParameters.clientId ?? this.instanceName;\n const protocol = this.resolveProtocol();\n\n const options: IClientOptions = {\n username,\n password,\n protocolVersion: 5,\n rejectUnauthorized: this.rejectUnauthorized,\n keepalive: this.mqttParameters.keepalive,\n clean: this.mqttParameters.clean ?? true,\n connectTimeout: this.mqttParameters.connectTimeout,\n reconnectPeriod: this.mqttParameters.reconnectPeriod,\n reconnectOnConnackError: this.mqttParameters.reconnectOnConnackError,\n resubscribe: this.mqttParameters.resubscribe,\n queueQoSZero: this.mqttParameters.queueQoSZero,\n properties: this.mqttParameters.properties,\n ca: this.mqttParameters.ca,\n cert: this.mqttParameters.cert,\n key: this.mqttParameters.key,\n servername: this.mqttParameters.servername,\n \n will: {\n topic: `${this.statusTopic}alive`,\n payload: Buffer.from(\"\"),\n qos: 0,\n retain: true,\n properties: { messageExpiryInterval: 3600 },\n },\n clientId,\n };\n\n const servers = this.buildServers(protocol);\n if (servers) {\n options.servers = servers;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n } else {\n options.host = this.mqttHost;\n options.port = this.mqttParameters.port;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n }\n\n const onConnect = () => this.handleMqttConnect();\n\n this.mqttClient.on(\"connect\", onConnect);\n this.mqttClient.on(\"packetsend\", packet => {\n this.subscriptionReadiness.sent(packet as Parameters<SubscriptionReadiness[\"sent\"]>[0]);\n this.emitSubscriptionReadiness();\n });\n this.mqttClient.on(\"packetreceive\", packet => {\n this.subscriptionReadiness.received(packet as Parameters<SubscriptionReadiness[\"received\"]>[0]);\n this.emitSubscriptionReadiness();\n });\n\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\n try {\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\n this.event.emit(\"input\", {\n message: message.toString(),\n topic: topic,\n packet: packet,\n });\n this.updateSubscribeTransformationStats(message.length);\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\n }\n });\n\n this.mqttClient.on(\"error\", (error) => {\n const errorInfo = formatMqttError(error);\n logger.error(`${this.instanceName} - MQTT client error: ${errorInfo.message}`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n this.event.emit(\"error\", {\n code: typeof errorInfo.code === \"number\" ? errorInfo.code : 0,\n message: errorInfo.message,\n });\n reject(error);\n });\n\n this.mqttClient.on(\"reconnect\", () => {\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\n });\n\n this.mqttClient.on(\"close\", () => {\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n });\n\n this.mqttClient.on(\"offline\", () => {\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n });\n\n this.mqttClient.on(\"end\", () => {\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n });\n\n this.mqttClient.on(\"disconnect\", (packet) => {\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n });\n } catch (error) {\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${formatMqttError(error).message}`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n reject(error);\n }\n });\n }\n\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\n this.updatePublishTransformationStats(JSON.stringify(message).length);\n const client = this.mqttClient;\n if (!client) {\n throw new Error(`${this.instanceName} - MQTT client missing; cannot publish to ${topic}`);\n }\n\n if (!client.connected) {\n // Wait briefly for reconnection before giving up.\n await this.waitForReconnect(client, 5000);\n }\n\n if (!client.connected) {\n throw new Error(`${this.instanceName} - MQTT client still disconnected; publish failed for ${topic}`);\n }\n\n return new Promise((resolve, reject) => {\n client.publish(topic, message, options || {}, (err) => {\n if (err) {\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\n return reject(err);\n }\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\n resolve();\n });\n });\n }\n\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\n return this.mqttClient.subscribeAsync(topic, options);\n }\n\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\n const topics = Array.isArray(topic) ? topic.filter((t) => typeof t === \"string\" && t.length > 0) : [topic].filter((t): t is string => typeof t === \"string\" && t.length > 0);\n if (topics.length === 0) {\n logger.warn(`${this.instanceName} - unsubscribeAsync called with empty topic list; skipping.`);\n return Promise.resolve(undefined);\n }\n return this.mqttClient.unsubscribeAsync(topics);\n }\n\n public stop(options: MqttStopOptions = {}): Promise<void> {\n const silent = options.silent === true || options.reason === \"retry\";\n const shouldLogDisconnect = !silent && this.hasEstablishedConnection;\n\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnecting from MQTT broker...`);\n }\n\n return new Promise((resolve, reject) => {\n const resetState = () => {\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n this.pendingReconnectWait = null;\n this.startupSettled = false;\n this.hasEstablishedConnection = false;\n this.startupResolve = null;\n this.startupReject = null;\n };\n\n try {\n if (this.statusUpdateInterval) {\n clearInterval(this.statusUpdateInterval);\n this.statusUpdateInterval = null;\n }\n if (this.transformationStatsInterval) {\n clearInterval(this.transformationStatsInterval);\n this.transformationStatsInterval = null;\n }\n if (this.mqttClient) {\n this.mqttClient.end(false, () => {\n resetState();\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);\n }\n resolve();\n });\n } else {\n resetState();\n resolve();\n }\n } catch (error) {\n resetState();\n const reason = error instanceof Error ? error : new Error(String(error));\n if (!silent) {\n logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(reason).message}`);\n }\n reject(reason);\n }\n });\n }\n\n private handleMqttConnect(): void {\n const resolve = this.startupResolve;\n const reject = this.startupReject;\n if (!resolve || !reject) {\n return;\n }\n\n try {\n this.mqttClient.stream.setMaxListeners(0);\n const isFirstConnect = !this.startupSettled;\n this.startupSettled = true;\n this.hasEstablishedConnection = true;\n this.isConnected = true;\n this.subscriptionReadiness.connection(true);\n this.emitSubscriptionReadiness();\n\n if (isFirstConnect) {\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\n this.subscribeToTopics();\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n resolve();\n return;\n }\n\n logger.info(`${this.instanceName} - Reconnected to MQTT broker at ${this.mqttHost}`);\n if (this.mqttParameters.resubscribe === false) {\n this.subscribeToTopics();\n }\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${formatMqttError(error).message}`);\n this.isConnected = false;\n this.subscriptionReadiness.connection(false);\n this.emitSubscriptionReadiness();\n reject(error);\n }\n }\n\n private emitStatusUpdates() {\n try {\n this.emitSubscriptionReadiness(true);\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\n\n if (this.mqttWorker !== undefined) {\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\n }\n } catch (error) {\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\n }\n }\n\n private updatePublishTransformationStats(messageSizeOut: number): void {\n this.publishedMessageCount += 1;\n this.publishedMessageBytes += messageSizeOut;\n }\n\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\n this.subscribedMessageCount += 1;\n this.subscribedMessageBytes += messageSizeIn;\n }\n\n private waitForReconnect(client: mqtt.MqttClient, timeoutMs: number): Promise<void> {\n if (client.connected) {\n return Promise.resolve();\n }\n\n if (this.pendingReconnectWait) {\n return this.pendingReconnectWait;\n }\n\n this.pendingReconnectWait = new Promise<void>((resolve) => {\n if (client.connected) return resolve();\n\n const onConnect = () => {\n cleanup();\n resolve();\n };\n const onClose = () => {\n // stay waiting; close is expected during reconnect attempts\n };\n const cleanup = () => {\n client.off(\"connect\", onConnect);\n client.off(\"close\", onClose);\n };\n\n client.on(\"connect\", onConnect);\n client.on(\"close\", onClose);\n\n setTimeout(() => {\n cleanup();\n resolve();\n }, timeoutMs).unref?.();\n }).finally(() => {\n this.pendingReconnectWait = null;\n });\n\n return this.pendingReconnectWait;\n }\n\n private async emitTransformationStatistics(): Promise<void> {\n if (this.statusTopic !== \"\") {\n try {\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-count\",\n value: this.publishedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"published-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-bytes\",\n value: Math.round(this.publishedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"published-message-bytes\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-count\",\n value: this.subscribedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"subscribed-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-bytes\",\n value: Math.round(this.subscribedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\n });\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n } catch (error: any) {\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\n }\n }\n }\n}\n\nexport function formatMqttError(error: unknown): MqttErrorInfo {\n const parts: string[] = [];\n const codes: Array<string | number> = [];\n collectMqttErrorParts(error, parts, codes);\n\n const uniqueParts = Array.from(new Set(parts.map((part) => part.trim()).filter(Boolean)));\n const message = uniqueParts.join(\"; \") || \"Unknown MQTT error\";\n\n return {\n code: codes[0] ?? 0,\n message,\n };\n}\n\nfunction collectMqttErrorParts(\n error: unknown,\n parts: string[],\n codes: Array<string | number>,\n): void {\n if (error instanceof AggregateError) {\n if (typeof error.message === \"string\" && error.message.trim()) {\n parts.push(error.message.trim());\n }\n for (const nested of error.errors) {\n collectMqttErrorParts(nested, parts, codes);\n }\n return;\n }\n\n if (typeof error === \"string\") {\n if (error.trim()) {\n parts.push(error.trim());\n }\n return;\n }\n\n if (!error || typeof error !== \"object\") {\n return;\n }\n\n const record = error as {\n message?: unknown;\n name?: unknown;\n code?: unknown;\n address?: unknown;\n port?: unknown;\n cause?: unknown;\n };\n\n const code =\n typeof record.code === \"string\" || typeof record.code === \"number\"\n ? record.code\n : undefined;\n if (code !== undefined) {\n codes.push(code);\n }\n\n const message =\n typeof record.message === \"string\" && record.message.trim()\n ? record.message.trim()\n : undefined;\n const address =\n typeof record.address === \"string\" && record.address.trim()\n ? record.address.trim()\n : undefined;\n const port = typeof record.port === \"number\" ? record.port : undefined;\n const endpoint =\n address || port !== undefined\n ? `${address ?? \"\"}${address && port !== undefined ? \":\" : \"\"}${port ?? \"\"}`.trim()\n : undefined;\n\n const detailParts = [\n code !== undefined && !message?.includes(String(code)) ? String(code) : undefined,\n message,\n endpoint && !message?.includes(endpoint) ? endpoint : undefined,\n ].filter((part): part is string => typeof part === \"string\" && part.length > 0);\n\n if (detailParts.length > 0) {\n parts.push(detailParts.join(\" \"));\n } else if (typeof record.name === \"string\" && record.name.trim()) {\n parts.push(record.name.trim());\n }\n\n if (record.cause !== undefined) {\n collectMqttErrorParts(record.cause, parts, codes);\n }\n}\n"]}
@@ -0,0 +1,23 @@
1
+ /** Transport evidence only. No extra subscriptions, topics or credentials are published. */
2
+ export declare class SubscriptionReadiness {
3
+ private connected;
4
+ private sequence;
5
+ private filters;
6
+ private pending;
7
+ connection(connected: boolean): void;
8
+ sent(packet: {
9
+ cmd: string;
10
+ messageId?: number;
11
+ subscriptions?: Array<{
12
+ topic: string;
13
+ }>;
14
+ unsubscriptions?: string[];
15
+ }): void;
16
+ received(packet: {
17
+ cmd: string;
18
+ messageId?: number;
19
+ granted?: number[];
20
+ }): void;
21
+ ready(): boolean;
22
+ }
23
+ //# sourceMappingURL=subscription-readiness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-readiness.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/subscription-readiness.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,qBAAa,qBAAqB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,OAAO,CAAgE;IAC/E,OAAO,CAAC,OAAO,CAA2F;IAE1G,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI;IAKpC,IAAI,CAAC,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,KAAK,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAC,CAAC,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;KAAC,GAAG,IAAI;IAYzH,QAAQ,CAAC,MAAM,EAAE;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAC,GAAG,IAAI;IAc7E,KAAK,IAAI,OAAO;CAIjB"}
@@ -0,0 +1,50 @@
1
+ /** Transport evidence only. No extra subscriptions, topics or credentials are published. */
2
+ export class SubscriptionReadiness {
3
+ connected = false;
4
+ sequence = 0;
5
+ filters = new Map();
6
+ pending = new Map();
7
+ connection(connected) {
8
+ this.connected = connected;
9
+ if (!connected) {
10
+ this.filters.clear();
11
+ this.pending.clear();
12
+ }
13
+ }
14
+ sent(packet) {
15
+ if (!['subscribe', 'unsubscribe'].includes(packet.cmd) || !Number.isInteger(packet.messageId))
16
+ return;
17
+ const topics = packet.cmd === 'subscribe' ? packet.subscriptions?.map(s => s.topic) : packet.unsubscriptions;
18
+ if (!topics?.length)
19
+ return;
20
+ const filters = topics.map(topic => {
21
+ const revision = ++this.sequence;
22
+ this.filters.set(topic, { revision, acknowledged: false });
23
+ return { topic, revision };
24
+ });
25
+ this.pending.set(packet.messageId, { remove: packet.cmd === 'unsubscribe', filters });
26
+ }
27
+ received(packet) {
28
+ if (!['suback', 'unsuback'].includes(packet.cmd) || packet.messageId === undefined)
29
+ return;
30
+ const pending = this.pending.get(packet.messageId);
31
+ if (!pending || pending.remove !== (packet.cmd === 'unsuback'))
32
+ return;
33
+ this.pending.delete(packet.messageId);
34
+ pending.filters.forEach(({ topic, revision }, index) => {
35
+ if (this.filters.get(topic)?.revision !== revision)
36
+ return;
37
+ const grant = packet.granted?.[index];
38
+ const accepted = pending.remove ? grant === undefined || grant === 0 || grant === 17 : grant === 0 || grant === 1 || grant === 2;
39
+ if (pending.remove && accepted)
40
+ this.filters.delete(topic);
41
+ else
42
+ this.filters.set(topic, { revision, acknowledged: accepted && !pending.remove });
43
+ });
44
+ }
45
+ ready() {
46
+ return this.connected && this.filters.size > 0 && this.pending.size === 0
47
+ && [...this.filters.values()].every(filter => filter.acknowledged);
48
+ }
49
+ }
50
+ //# sourceMappingURL=subscription-readiness.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscription-readiness.js","sourceRoot":"","sources":["../../src/uns-mqtt/subscription-readiness.ts"],"names":[],"mappings":"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","sourcesContent":["/** Transport evidence only. No extra subscriptions, topics or credentials are published. */\nexport class SubscriptionReadiness {\n private connected = false;\n private sequence = 0;\n private filters = new Map<string, {revision: number; acknowledged: boolean}>();\n private pending = new Map<number, {remove: boolean; filters: Array<{topic: string; revision: number}>}>();\n\n connection(connected: boolean): void {\n this.connected = connected;\n if (!connected) { this.filters.clear(); this.pending.clear(); }\n }\n\n sent(packet: {cmd: string; messageId?: number; subscriptions?: Array<{topic: string}>; unsubscriptions?: string[]}): void {\n if (!['subscribe', 'unsubscribe'].includes(packet.cmd) || !Number.isInteger(packet.messageId)) return;\n const topics = packet.cmd === 'subscribe' ? packet.subscriptions?.map(s => s.topic) : packet.unsubscriptions;\n if (!topics?.length) return;\n const filters = topics.map(topic => {\n const revision = ++this.sequence;\n this.filters.set(topic, {revision, acknowledged: false});\n return {topic, revision};\n });\n this.pending.set(packet.messageId!, {remove: packet.cmd === 'unsubscribe', filters});\n }\n\n received(packet: {cmd: string; messageId?: number; granted?: number[]}): void {\n if (!['suback', 'unsuback'].includes(packet.cmd) || packet.messageId === undefined) return;\n const pending = this.pending.get(packet.messageId);\n if (!pending || pending.remove !== (packet.cmd === 'unsuback')) return;\n this.pending.delete(packet.messageId);\n pending.filters.forEach(({topic, revision}, index) => {\n if (this.filters.get(topic)?.revision !== revision) return;\n const grant = packet.granted?.[index];\n const accepted = pending.remove ? grant === undefined || grant === 0 || grant === 17 : grant === 0 || grant === 1 || grant === 2;\n if (pending.remove && accepted) this.filters.delete(topic);\n else this.filters.set(topic, {revision, acknowledged: accepted && !pending.remove});\n });\n }\n\n ready(): boolean {\n return this.connected && this.filters.size > 0 && this.pending.size === 0\n && [...this.filters.values()].every(filter => filter.acknowledged);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uns-kit/core",
3
- "version": "3.0.25",
3
+ "version": "3.0.27",
4
4
  "description": "Core utilities and runtime building blocks for UNS-based realtime transformers.",
5
5
  "type": "module",
6
6
  "license": "MIT",