@uns-kit/core 3.0.28 → 3.0.30

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 (103) hide show
  1. package/MIGRATIONS.md +100 -0
  2. package/README.md +10 -0
  3. package/dist/config/app-config.d.ts +14 -0
  4. package/dist/config/app-config.d.ts.map +1 -1
  5. package/dist/config/app-config.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/runtime/configuration-group-authorization.d.ts +50 -0
  11. package/dist/runtime/configuration-group-authorization.d.ts.map +1 -0
  12. package/dist/runtime/configuration-group-authorization.js +113 -0
  13. package/dist/runtime/configuration-group-authorization.js.map +1 -0
  14. package/dist/runtime/configuration-group-contract.d.ts +75 -0
  15. package/dist/runtime/configuration-group-contract.d.ts.map +1 -0
  16. package/dist/runtime/configuration-group-contract.js +233 -0
  17. package/dist/runtime/configuration-group-contract.js.map +1 -0
  18. package/dist/runtime/process-group-authorization.d.ts +2 -0
  19. package/dist/runtime/process-group-authorization.d.ts.map +1 -1
  20. package/dist/runtime/process-group-authorization.js +34 -12
  21. package/dist/runtime/process-group-authorization.js.map +1 -1
  22. package/dist/runtime/process-group-backup-contract.d.ts +22 -0
  23. package/dist/runtime/process-group-backup-contract.d.ts.map +1 -0
  24. package/dist/runtime/process-group-backup-contract.js +20 -0
  25. package/dist/runtime/process-group-backup-contract.js.map +1 -0
  26. package/dist/runtime/process-group-backup-contract.json +7 -0
  27. package/dist/runtime/process-group-configured-upgrade.d.ts +4 -0
  28. package/dist/runtime/process-group-configured-upgrade.d.ts.map +1 -0
  29. package/dist/runtime/process-group-configured-upgrade.js +107 -0
  30. package/dist/runtime/process-group-configured-upgrade.js.map +1 -0
  31. package/dist/runtime/process-group-generation.d.ts +166 -0
  32. package/dist/runtime/process-group-generation.d.ts.map +1 -0
  33. package/dist/runtime/process-group-generation.js +278 -0
  34. package/dist/runtime/process-group-generation.js.map +1 -0
  35. package/dist/runtime/process-group-inspection.d.ts +2 -0
  36. package/dist/runtime/process-group-inspection.d.ts.map +1 -1
  37. package/dist/runtime/process-group-inspection.js +120 -40
  38. package/dist/runtime/process-group-inspection.js.map +1 -1
  39. package/dist/runtime/process-group-resources.d.ts +1 -0
  40. package/dist/runtime/process-group-resources.d.ts.map +1 -1
  41. package/dist/runtime/process-group-resources.js +8 -0
  42. package/dist/runtime/process-group-resources.js.map +1 -1
  43. package/dist/runtime/process-group-runtime-selection.d.ts +14 -0
  44. package/dist/runtime/process-group-runtime-selection.d.ts.map +1 -0
  45. package/dist/runtime/process-group-runtime-selection.js +29 -0
  46. package/dist/runtime/process-group-runtime-selection.js.map +1 -0
  47. package/dist/runtime/process-group-snapshot.mjs +60 -8
  48. package/dist/runtime/process-group-staging.d.ts +2 -2
  49. package/dist/runtime/process-group-staging.d.ts.map +1 -1
  50. package/dist/runtime/process-group-staging.js +6 -4
  51. package/dist/runtime/process-group-staging.js.map +1 -1
  52. package/dist/runtime/process-group-supervision.d.ts +2 -2
  53. package/dist/runtime/process-group-supervision.d.ts.map +1 -1
  54. package/dist/runtime/process-group-supervision.js +3 -2
  55. package/dist/runtime/process-group-supervision.js.map +1 -1
  56. package/dist/runtime/process-group-upgrade.d.ts +76 -6
  57. package/dist/runtime/process-group-upgrade.d.ts.map +1 -1
  58. package/dist/runtime/process-group-upgrade.js +7 -1
  59. package/dist/runtime/process-group-upgrade.js.map +1 -1
  60. package/dist/uns/uns-interfaces.d.ts +3 -0
  61. package/dist/uns/uns-interfaces.d.ts.map +1 -1
  62. package/dist/uns/uns-interfaces.js.map +1 -1
  63. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  64. package/dist/uns/uns-proxy-process.js +3 -0
  65. package/dist/uns/uns-proxy-process.js.map +1 -1
  66. package/dist/uns-config/config-schema.d.ts +16 -0
  67. package/dist/uns-config/config-schema.d.ts.map +1 -1
  68. package/dist/uns-config/mqtt-channel.d.ts +1 -1
  69. package/dist/uns-config/mqtt-channel.d.ts.map +1 -1
  70. package/dist/uns-config/mqtt-channel.js +3 -0
  71. package/dist/uns-config/mqtt-channel.js.map +1 -1
  72. package/dist/uns-config/uns-core-schema.d.ts +137 -0
  73. package/dist/uns-config/uns-core-schema.d.ts.map +1 -1
  74. package/dist/uns-config/uns-core-schema.js +6 -1
  75. package/dist/uns-config/uns-core-schema.js.map +1 -1
  76. package/dist/uns-mqtt/mqtt-interfaces.d.ts +5 -0
  77. package/dist/uns-mqtt/mqtt-interfaces.d.ts.map +1 -1
  78. package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
  79. package/dist/uns-mqtt/mqtt-proxy.d.ts +3 -0
  80. package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
  81. package/dist/uns-mqtt/mqtt-proxy.js +26 -1
  82. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  83. package/dist/uns-mqtt/mqtt-worker.d.ts +3 -1
  84. package/dist/uns-mqtt/mqtt-worker.d.ts.map +1 -1
  85. package/dist/uns-mqtt/mqtt-worker.js +45 -8
  86. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  87. package/dist/uns-mqtt/publish-queue-contract.d.ts +33 -0
  88. package/dist/uns-mqtt/publish-queue-contract.d.ts.map +1 -0
  89. package/dist/uns-mqtt/publish-queue-contract.js +18 -0
  90. package/dist/uns-mqtt/publish-queue-contract.js.map +1 -0
  91. package/dist/uns-mqtt/publish-queue-store.d.ts +33 -0
  92. package/dist/uns-mqtt/publish-queue-store.d.ts.map +1 -0
  93. package/dist/uns-mqtt/publish-queue-store.js +177 -0
  94. package/dist/uns-mqtt/publish-queue-store.js.map +1 -0
  95. package/dist/uns-mqtt/publish-queue.d.ts +43 -0
  96. package/dist/uns-mqtt/publish-queue.d.ts.map +1 -0
  97. package/dist/uns-mqtt/publish-queue.js +235 -0
  98. package/dist/uns-mqtt/publish-queue.js.map +1 -0
  99. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +7 -0
  100. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
  101. package/dist/uns-mqtt/uns-mqtt-proxy.js +98 -5
  102. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  103. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { type MqttPublishQueueStatus } from "./publish-queue-contract.js";
1
2
  import { IClientPublishOptions } from "mqtt";
2
3
  import { IMqttPublishRequest, IUnsPacket, IUnsParameters, UnsEvents } from "../uns/uns-interfaces.js";
3
4
  import UnsProxy from "../uns/uns-proxy.js";
@@ -35,6 +36,10 @@ export default class UnsMqttProxy extends UnsProxy {
35
36
  private lifecycleState;
36
37
  private stopPromise;
37
38
  private expectedWorkerExit;
39
+ private publishQueueStatus?;
40
+ private admissionBytes;
41
+ private pendingAdmissionBytes;
42
+ private queueRequests;
38
43
  constructor(mqttHost: string, processName: string, instanceName: string, unsParameters?: IUnsParameters, publisherActive?: boolean, subscriberActive?: boolean);
39
44
  /**
40
45
  * Resolve object identity from explicit fields or the tail of the topic path.
@@ -140,6 +145,8 @@ export default class UnsMqttProxy extends UnsProxy {
140
145
  */
141
146
  stop(options?: UnsMqttProxyStopOptions): Promise<void>;
142
147
  private performStop;
148
+ getPublishQueueStatus(): MqttPublishQueueStatus | undefined;
149
+ private requestPublishQueue;
143
150
  private failPendingPublishes;
144
151
  private rejectOutstandingPublishes;
145
152
  private notifyDrainWaiters;
@@ -1 +1 @@
1
- {"version":3,"file":"uns-mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"uns-mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mqttPublishQueueSchema } from "./publish-queue-contract.js";
1
3
  import { readFileSync } from "fs";
2
4
  import * as path from "path";
3
5
  import { Worker } from "worker_threads";
@@ -46,6 +48,10 @@ export default class UnsMqttProxy extends UnsProxy {
46
48
  lifecycleState = "running";
47
49
  stopPromise = null;
48
50
  expectedWorkerExit = false;
51
+ publishQueueStatus;
52
+ admissionBytes = new Map();
53
+ pendingAdmissionBytes = 0;
54
+ queueRequests = new Map();
49
55
  constructor(mqttHost, processName, instanceName, unsParameters, publisherActive = false, subscriberActive = false) {
50
56
  super();
51
57
  this.instanceName = instanceName;
@@ -82,7 +88,12 @@ export default class UnsMqttProxy extends UnsProxy {
82
88
  key: unsParameters?.key,
83
89
  servername: unsParameters?.servername,
84
90
  };
85
- this.unsParameters = unsParameters ?? {};
91
+ this.unsParameters = { ...(unsParameters ?? {}) };
92
+ if (unsParameters?.publishQueue) {
93
+ this.unsParameters.publishQueue = mqttPublishQueueSchema.parse(unsParameters.publishQueue);
94
+ if ((unsParameters.publishConcurrency ?? 1) !== 1)
95
+ throw Error("Persistent MQTT output requires publishConcurrency=1");
96
+ }
86
97
  this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);
87
98
  }
88
99
  /**
@@ -134,6 +145,13 @@ export default class UnsMqttProxy extends UnsProxy {
134
145
  maxPendingPublishes: this.unsParameters.maxPendingPublishes,
135
146
  subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,
136
147
  persistToDisk: false,
148
+ publishQueue: this.unsParameters.publishQueue,
149
+ publishQueueIdentity: this.unsParameters.publishQueue ? JSON.stringify({
150
+ package: packageJson.name, owner: instanceNameWithSuffix,
151
+ host: mqttHost, port: mqttParameters.port ?? (mqttParameters.mqttSSL ? 8883 : 1883),
152
+ protocol: mqttParameters.protocol ?? (mqttParameters.mqttSSL ? "mqtts" : "mqtt"),
153
+ hosts: mqttParameters.hosts ?? null, servers: mqttParameters.servers ?? null,
154
+ }) : undefined,
137
155
  mqttHost: mqttHost,
138
156
  instanceNameWithSuffix: instanceNameWithSuffix,
139
157
  mqttParameters: mqttParameters,
@@ -143,10 +161,29 @@ export default class UnsMqttProxy extends UnsProxy {
143
161
  };
144
162
  this.worker = new Worker(workerScriptPath, { workerData });
145
163
  this.worker.on("message", (msg) => {
146
- if (msg && msg.command === "enqueueAccepted" && msg.id) {
164
+ if (msg?.command === "publishQueueStatus") {
165
+ this.publishQueueStatus = msg.status;
166
+ }
167
+ else if (msg?.command === "publishQueueReply") {
168
+ const pending = this.queueRequests.get(msg.id);
169
+ if (pending) {
170
+ clearTimeout(pending.timer);
171
+ this.queueRequests.delete(msg.id);
172
+ if (msg.status === "success")
173
+ pending.resolve();
174
+ else
175
+ pending.reject(new Error(msg.error));
176
+ }
177
+ }
178
+ else if (msg?.command === "publishQueueControlError") {
179
+ this.event.emit("error", { code: 0, message: msg.error });
180
+ }
181
+ else if (msg && msg.command === "enqueueAccepted" && msg.id) {
147
182
  const pending = this.pendingEnqueues.get(msg.id);
148
183
  if (pending) {
149
184
  this.pendingEnqueues.delete(msg.id);
185
+ this.pendingAdmissionBytes -= this.admissionBytes.get(msg.id) ?? 0;
186
+ this.admissionBytes.delete(msg.id);
150
187
  if (msg.status === "accepted") {
151
188
  this.pendingPublishCompletions.add(msg.id);
152
189
  pending.resolve();
@@ -210,19 +247,31 @@ export default class UnsMqttProxy extends UnsProxy {
210
247
  reject(this.workerFailure);
211
248
  return;
212
249
  }
213
- const maxPendingPublishes = this.unsParameters.maxPendingPublishes;
250
+ const maxPendingPublishes = this.unsParameters.maxPendingPublishes ?? this.unsParameters.publishQueue?.maxRecords;
214
251
  const pendingCount = this.pendingEnqueues.size + this.pendingPublishCompletions.size;
215
252
  if (maxPendingPublishes !== undefined && pendingCount >= maxPendingPublishes) {
216
253
  reject(new Error(`${this.instanceNameWithSuffix} - Publisher queue is full (${maxPendingPublishes}).`));
217
254
  return;
218
255
  }
219
- const id = `${Date.now()}-${Math.random()}`;
256
+ const bytes = Buffer.byteLength(topic) + Buffer.byteLength(message) + 256;
257
+ const queue = this.unsParameters.publishQueue;
258
+ if (queue && (bytes > queue.maxMessageBytes || this.pendingAdmissionBytes + bytes > queue.maxBytes)) {
259
+ reject(new Error("MQTT output admission byte limit reached"));
260
+ return;
261
+ }
262
+ const id = randomUUID();
263
+ if (queue) {
264
+ this.admissionBytes.set(id, bytes);
265
+ this.pendingAdmissionBytes += bytes;
266
+ }
220
267
  this.pendingEnqueues.set(id, { resolve, reject });
221
268
  try {
222
269
  this.worker.postMessage({ command: "enqueue", id, topic, message, options });
223
270
  }
224
271
  catch (error) {
225
272
  this.pendingEnqueues.delete(id);
273
+ this.pendingAdmissionBytes -= this.admissionBytes.get(id) ?? 0;
274
+ this.admissionBytes.delete(id);
226
275
  reject(error);
227
276
  }
228
277
  this.notifyDrainWaiters();
@@ -294,6 +343,10 @@ export default class UnsMqttProxy extends UnsProxy {
294
343
  if (this.workerFailure) {
295
344
  throw this.workerFailure;
296
345
  }
346
+ if (this.unsParameters.publishQueue) {
347
+ await this.requestPublishQueue("flushPublishes", timeoutMs);
348
+ return;
349
+ }
297
350
  if (this.pendingEnqueues.size === 0 && this.pendingPublishCompletions.size === 0) {
298
351
  return;
299
352
  }
@@ -614,7 +667,11 @@ export default class UnsMqttProxy extends UnsProxy {
614
667
  return this.stopPromise;
615
668
  }
616
669
  this.lifecycleState = "stopping";
617
- this.stopPromise = this.performStop(options);
670
+ this.stopPromise = this.performStop(options).catch(error => {
671
+ if (this.unsParameters.publishQueue && this.lifecycleState !== "stopped")
672
+ this.stopPromise = null;
673
+ throw error;
674
+ });
618
675
  return this.stopPromise;
619
676
  }
620
677
  async performStop(options) {
@@ -631,6 +688,10 @@ export default class UnsMqttProxy extends UnsProxy {
631
688
  logger.error(`${this.instanceNameWithSuffix} - Error draining publishes before stop: ${stopError.message}`);
632
689
  }
633
690
  }
691
+ if (this.worker && this.unsParameters.publishQueue && !this.workerFailure) {
692
+ // A failed spill must keep the live worker/RAM available for inspection or retry.
693
+ await this.requestPublishQueue("closePublisher", timeoutMs);
694
+ }
634
695
  if (this.worker) {
635
696
  this.expectedWorkerExit = true;
636
697
  try {
@@ -649,7 +710,37 @@ export default class UnsMqttProxy extends UnsProxy {
649
710
  throw stopError;
650
711
  }
651
712
  }
713
+ getPublishQueueStatus() {
714
+ return this.publishQueueStatus ? { ...this.publishQueueStatus } : undefined;
715
+ }
716
+ requestPublishQueue(command, timeoutMs) {
717
+ if (!Number.isFinite(timeoutMs) || timeoutMs <= 0)
718
+ return Promise.reject(new Error("MQTT queue timeout must be positive and finite"));
719
+ if (this.queueRequests.size >= 64)
720
+ return Promise.reject(new Error("Too many pending MQTT queue control requests"));
721
+ return new Promise((resolve, reject) => {
722
+ const id = randomUUID();
723
+ const timer = setTimeout(() => {
724
+ this.queueRequests.delete(id);
725
+ reject(new Error("MQTT queue control timed out; outcome unconfirmed"));
726
+ }, timeoutMs);
727
+ this.queueRequests.set(id, { resolve, reject, timer });
728
+ try {
729
+ this.worker.postMessage({ command, id, timeoutMs });
730
+ }
731
+ catch (error) {
732
+ clearTimeout(timer);
733
+ this.queueRequests.delete(id);
734
+ reject(error);
735
+ }
736
+ });
737
+ }
652
738
  failPendingPublishes(reason) {
739
+ for (const request of this.queueRequests.values()) {
740
+ clearTimeout(request.timer);
741
+ request.reject(reason);
742
+ }
743
+ this.queueRequests.clear();
653
744
  this.workerFailure = reason;
654
745
  this.rejectOutstandingPublishes(reason);
655
746
  }
@@ -658,6 +749,8 @@ export default class UnsMqttProxy extends UnsProxy {
658
749
  pending.reject(reason);
659
750
  }
660
751
  this.pendingEnqueues.clear();
752
+ this.admissionBytes.clear();
753
+ this.pendingAdmissionBytes = 0;
661
754
  this.pendingPublishCompletions.clear();
662
755
  const waiters = this.drainWaiters.splice(0);
663
756
  for (const waiter of waiters) {
@@ -1 +1 @@
1
- {"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport * as path from \"path\";\nimport { Worker } from \"worker_threads\";\nimport { fileURLToPath } from \"url\";\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttPublishRequest, IUnsLifecycleMetadata, IUnsMessage, IUnsPacket, IUnsParameters, IUnsRelationshipEvidenceMetadata, IUnsTableColumnMetadata, UnsAttribute, UnsAttributeSystemRole, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\nimport { getObjectTypeDescription, type UnsObjectId, type UnsObjectType } from \"../uns/uns-object.js\";\nimport type { UnsAsset } from \"../uns/uns-asset.js\";\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\nimport { UnsPacket } from \"../uns/uns-packet.js\";\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\nimport UnsProxy from \"../uns/uns-proxy.js\";\nimport { UnsAttributeType } from \"../graphql/schema.js\";\nimport { getAttributeDescription } from \"../uns/uns-attributes.js\";\nimport { UnsTags } from \"../uns/uns-tags.js\";\nimport { UnsTopics } from \"../uns/uns-topics.js\";\n\nconst packageJsonPath = path.join(basePath, \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\n\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\n\nexport enum MessageMode {\n Raw = 'raw', // Send only the original message\n /**\n * @deprecated Producer-side delta calculation loses state across restarts.\n * Publish raw cumulative counter values and request delta/rate from Datahub history APIs.\n */\n Delta = 'delta', // Send only the delta message\n /**\n * @deprecated Producer-side delta calculation loses state across restarts.\n * Publish raw cumulative counter values and request delta/rate from Datahub history APIs.\n */\n Both = 'both' // Send both the original and delta messages\n}\n\nexport interface UnsMqttProxyStopOptions {\n drain?: boolean;\n timeoutMs?: number;\n}\n\ntype UnsMqttProxyLifecycleState = \"running\" | \"stopping\" | \"stopped\";\n\ntype InternalMqttMessage = {\n topic: UnsTopics;\n attribute: UnsAttribute;\n asset: UnsAsset;\n assetDescription?: string;\n assetStableEntityId?: string;\n assetDisplayName?: string;\n assetIdentityProof?: string;\n assetProviderIdentity?: {\n providerId: string;\n externalSystem: string;\n externalType: string;\n externalId: string;\n };\n assetProviderIdentityProof?: string;\n objectType: UnsObjectType;\n objectTypeDescription?: string;\n objectId: UnsObjectId;\n virtualGroup?: string;\n description?: string;\n tags?: UnsTags[];\n attributeNeedsPersistence?: boolean | null;\n valueType?: string;\n presentationKind?: string;\n defaultAggregation?: string;\n counterResetPolicy?: string;\n tableColumns?: IUnsTableColumnMetadata[];\n systemRole?: UnsAttributeSystemRole;\n relationshipEvidence?: IUnsRelationshipEvidenceMetadata;\n lifecycle?: IUnsLifecycleMetadata;\n validityMode?: \"interval\" | \"lifecycle\" | \"static\";\n expectedIntervalMs?: number;\n lifecycleEndValue?: string;\n packet: IUnsPacket;\n};\n\nexport default class UnsMqttProxy extends UnsProxy {\n public static readonly DEFAULT_DRAIN_TIMEOUT_MS = 30_000;\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\n private worker: Worker;\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\n private pendingPublishCompletions = new Set<string>();\n private unsParameters: IUnsParameters;\n protected processStatusTopic: string;\n public instanceName: string;\n private currentSequenceId: Map<string, number> = new Map();\n private topicBuilder: MqttTopicBuilder;\n private deltaModeDeprecationWarned = false;\n private drainWaiters: Array<{ resolve: () => void; reject: (reason?: any) => void; timer?: NodeJS.Timeout }> = [];\n private workerFailure: Error | null = null;\n private lifecycleState: UnsMqttProxyLifecycleState = \"running\";\n private stopPromise: Promise<void> | null = null;\n private expectedWorkerExit = false;\n\n constructor(\n mqttHost: string,\n processName: string,\n instanceName: string,\n unsParameters?: IUnsParameters,\n publisherActive: boolean = false,\n subscriberActive: boolean = false\n ) {\n super();\n this.instanceName = instanceName;\n // Create the topic builder using packageJson values and the processName.\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\n\n // Generate the processStatusTopic using the builder.\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\n // Derive the instanceStatusTopic by appending the instance name.\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\n\n // Concatenate processName with instanceName for the worker identification.\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\n \n const mqttParameters: IMqttParameters = {\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\n username: unsParameters?.username ?? \"\",\n password: unsParameters?.password ?? \"\",\n mqttSSL: unsParameters?.mqttSSL ?? false,\n statusTopic: this.instanceStatusTopic,\n rejectUnauthorized: unsParameters?.rejectUnauthorized ?? false,\n clientId: unsParameters?.clientId,\n hosts: unsParameters?.hosts,\n servers: unsParameters?.servers,\n port: unsParameters?.port,\n protocol: unsParameters?.protocol,\n keepalive: unsParameters?.keepalive,\n clean: unsParameters?.clean,\n connectTimeout: unsParameters?.connectTimeout,\n reconnectPeriod: unsParameters?.reconnectPeriod,\n reconnectOnConnackError: unsParameters?.reconnectOnConnackError,\n resubscribe: unsParameters?.resubscribe,\n queueQoSZero: unsParameters?.queueQoSZero,\n properties: unsParameters?.properties,\n ca: unsParameters?.ca,\n cert: unsParameters?.cert,\n key: unsParameters?.key,\n servername: unsParameters?.servername,\n };\n this.unsParameters = unsParameters ?? {};\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\n }\n\n /**\n * Resolve object identity from explicit fields or the tail of the topic path.\n * Falls back to parsing when not provided for backward compatibility.\n */\n private resolveObjectIdentity(msg: InternalMqttMessage): { objectType?: UnsObjectType; objectId?: UnsObjectId; asset?: UnsAsset } {\n const providedType = msg.objectType;\n const providedId = msg.objectId;\n const providedAsset = msg.asset;\n\n const topicParts = msg.topic.split(\"/\").filter((part) => part.length > 0);\n const hasObjectTail = topicParts.length >= 2;\n const parsedType = hasObjectTail ? topicParts[topicParts.length - 2] as UnsObjectType : undefined;\n const parsedId = hasObjectTail ? topicParts[topicParts.length - 1] as UnsObjectId : undefined;\n const parsedAsset = hasObjectTail\n ? (topicParts.length >= 3 ? topicParts[topicParts.length - 3] as UnsAsset : undefined)\n : (topicParts.length >= 1 ? topicParts[topicParts.length - 1] as UnsAsset : undefined);\n\n const objectType = providedType ?? parsedType;\n const objectId = providedId ?? parsedId ?? \"main\";\n const asset = providedAsset ?? parsedAsset;\n\n // If values are provided, trust them; otherwise derive from topic.\n if (!providedType || !providedId) {\n if (parsedType && parsedId) {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; derived from topic tail ${parsedType}/${parsedId}`);\n } else {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; defaulting objectId to 'main' for topic '${msg.topic}'. Expected topic to end with '<objectType>/<objectId>/'`);\n }\n }\n // Asset is optional; no warning on mismatch to avoid noisy logs when base topics don't carry it.\n\n msg.objectType = objectType;\n msg.objectId = objectId;\n msg.asset = asset;\n\n return { objectType, objectId, asset };\n }\n\n /**\n * Ensure the topic ends with a trailing slash for attribute concatenation.\n */\n private normalizeTopicWithObject(topic: string): string {\n return topic.endsWith(\"/\") ? topic : `${topic}/`;\n }\n\n /**\n * Starts a worker thread to process the throttled publish queue.\n */\n private startQueueWorker(\n mqttHost: string,\n instanceNameWithSuffix: string,\n mqttParameters: IMqttParameters,\n publisherActive: boolean,\n subscriberActive: boolean\n ): void {\n const workerData: IMqttWorkerData = {\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\n publishConcurrency: this.unsParameters.publishConcurrency ?? 1,\n maxPendingPublishes: this.unsParameters.maxPendingPublishes,\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\n persistToDisk: false,\n mqttHost: mqttHost,\n instanceNameWithSuffix: instanceNameWithSuffix,\n mqttParameters: mqttParameters,\n publisherActive,\n subscriberActive,\n defaultPublishOptions: this.unsParameters.defaultPublishOptions,\n };\n\n this.worker = new Worker(workerScriptPath, { workerData });\n\n this.worker.on(\"message\", (msg) => {\n if (msg && msg.command === \"enqueueAccepted\" && msg.id) {\n const pending = this.pendingEnqueues.get(msg.id);\n if (pending) {\n this.pendingEnqueues.delete(msg.id);\n if (msg.status === \"accepted\") {\n this.pendingPublishCompletions.add(msg.id);\n pending.resolve();\n } else {\n pending.reject(new Error(msg.error));\n }\n this.notifyDrainWaiters();\n }\n } else if (msg && msg.command === \"publishResult\" && msg.id) {\n this.pendingPublishCompletions.delete(msg.id);\n if (msg.status === \"error\") {\n const errorMessage = msg.error ?? `Error publishing to topic ${msg.topic ?? \"unknown\"}`;\n this.event.emit(\"error\", { code: 0, message: errorMessage });\n }\n this.notifyDrainWaiters();\n } else if (msg && msg.command === \"input\") {\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\n } else if (msg && msg.command === \"mqttProxyStatus\") {\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\n }\n });\n\n this.worker.on(\"error\", (err) => {\n if (this.expectedWorkerExit) {\n return;\n }\n logger.error(\"Error in worker:\", err);\n const reason = err instanceof Error ? err : new Error(String(err));\n this.failPendingPublishes(reason);\n });\n\n this.worker.on(\"exit\", (code) => {\n if (this.expectedWorkerExit) {\n return;\n }\n logger.error(`Worker exited unexpectedly with code ${code}`);\n const reason = new Error(`MQTT worker exited unexpectedly with code ${code}`);\n this.failPendingPublishes(reason);\n });\n }\n\n /**\n * Enqueues a message to the worker queue.\n *\n * @param topic - The topic to which the message belongs.\n * @param message - The message to be enqueued.\n * @param options - Optional publish options.\n * @returns A promise that resolves when the message is accepted into the worker queue.\n */\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.lifecycleState !== \"running\") {\n reject(new Error(`${this.instanceNameWithSuffix} - MQTT proxy is ${this.lifecycleState}; publish rejected.`));\n return;\n }\n if (this.workerFailure) {\n reject(this.workerFailure);\n return;\n }\n const maxPendingPublishes = this.unsParameters.maxPendingPublishes;\n const pendingCount = this.pendingEnqueues.size + this.pendingPublishCompletions.size;\n if (maxPendingPublishes !== undefined && pendingCount >= maxPendingPublishes) {\n reject(new Error(`${this.instanceNameWithSuffix} - Publisher queue is full (${maxPendingPublishes}).`));\n return;\n }\n const id = `${Date.now()}-${Math.random()}`;\n this.pendingEnqueues.set(id, { resolve, reject });\n try {\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\n } catch (error) {\n this.pendingEnqueues.delete(id);\n reject(error);\n }\n this.notifyDrainWaiters();\n });\n }\n\n /**\n * Sets the publisher active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the publisher to passive mode.\n * @returns A promise that resolves when the publisher is set to passive.\n */\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setPublisherPassive\"});\n return new Promise((resolve) => {\n const handler = (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_publisher\") {\n this.event.off(\"mqttWorker\", handler);\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n };\n this.event.on(\"mqttWorker\", handler);\n });\n }\n\n /**\n * Sets the subscriber active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the subscriber to passive mode.\n * @returns A promise that resolves when the subscriber is set to passive.\n */\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\n return new Promise((resolve) => {\n const handler = (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_subscriber\") {\n this.event.off(\"mqttWorker\", handler);\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive.`);\n resolve(msg);\n }\n };\n this.event.on(\"mqttWorker\", handler);\n });\n }\n\n\n /**\n * Sets the subscriber to passive mode and allows the publisher to run\n * until the queue is empty (all messages are processed).\n */\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\n const mqttWorkerData = await this.setSubscriberPassive();\n await this.flush();\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\n return mqttWorkerData;\n }\n\n public async drainPublishes(timeoutMs: number = UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS): Promise<void> {\n if (this.workerFailure) {\n throw this.workerFailure;\n }\n if (this.pendingEnqueues.size === 0 && this.pendingPublishCompletions.size === 0) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const waiter = { resolve, reject, timer: undefined as NodeJS.Timeout | undefined };\n if (Number.isFinite(timeoutMs) && timeoutMs > 0) {\n waiter.timer = setTimeout(() => {\n this.removeDrainWaiter(waiter);\n reject(new Error(`Timed out waiting for MQTT publishes to drain after ${timeoutMs}ms.`));\n }, timeoutMs);\n }\n this.drainWaiters.push(waiter);\n this.notifyDrainWaiters();\n });\n }\n\n public async flush(timeoutMs: number = UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS): Promise<void> {\n await this.drainPublishes(timeoutMs);\n }\n\n /**\n * Processes and publishes MQTT messages based on the selected message mode.\n *\n * @param mqttMessage - The MQTT message object.\n * @param mode - The message mode. Delta and Both are deprecated because\n * producer-side delta calculation loses state across restarts.\n */\n public async publishMqttMessage(mqttMessage: IMqttPublishRequest | null, mode: MessageMode = MessageMode.Raw) {\n if (!mqttMessage) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\n return;\n }\n\n const attrs = Array.isArray(mqttMessage.attributes)\n ? mqttMessage.attributes\n : [mqttMessage.attributes];\n const {\n topic,\n asset,\n assetDescription,\n assetStableEntityId,\n assetDisplayName,\n assetIdentityProof,\n assetProviderIdentity,\n assetProviderIdentityProof,\n objectType,\n objectTypeDescription,\n objectId,\n virtualGroup: requestVirtualGroup,\n } = mqttMessage;\n const hasAssetIdentityMetadata = assetStableEntityId !== undefined\n || assetDisplayName !== undefined\n || assetIdentityProof !== undefined;\n const hasAssetProviderIdentityMetadata = assetProviderIdentity !== undefined\n || assetProviderIdentityProof !== undefined;\n if (hasAssetIdentityMetadata && hasAssetProviderIdentityMetadata) {\n throw new Error(\"Stable Asset identity metadata and provider candidate metadata are mutually exclusive.\");\n }\n if (hasAssetIdentityMetadata) {\n if (\n typeof assetStableEntityId !== \"string\"\n || !assetStableEntityId.trim()\n || typeof assetIdentityProof !== \"string\"\n || !assetIdentityProof.trim()\n || (assetDisplayName !== undefined\n && (typeof assetDisplayName !== \"string\" || !assetDisplayName.trim()))\n ) {\n throw new Error(\"Asset identity metadata requires assetStableEntityId and assetIdentityProof; assetDisplayName must be non-empty when supplied.\");\n }\n }\n if (hasAssetProviderIdentityMetadata) {\n const identity = assetProviderIdentity as Record<string, unknown> | undefined;\n if (\n !identity\n || typeof assetProviderIdentityProof !== \"string\"\n || !assetProviderIdentityProof.trim()\n || [\"providerId\", \"externalSystem\", \"externalType\", \"externalId\"].some(\n (key) => typeof identity[key] !== \"string\" || !(identity[key] as string).trim(),\n )\n ) {\n throw new Error(\"Provider Asset identity metadata requires providerId, externalSystem, externalType, externalId, and assetProviderIdentityProof.\");\n }\n }\n for (const attrEntry of attrs) {\n const attrDescription = attrEntry.description ?? getAttributeDescription(attrEntry.attribute);\n const message: IUnsMessage =\n \"message\" in attrEntry && attrEntry.message\n ? attrEntry.message\n : \"data\" in attrEntry && attrEntry.data\n ? { data: attrEntry.data, createdAt: attrEntry.createdAt, expiresAt: attrEntry.expiresAt }\n : \"table\" in attrEntry && attrEntry.table\n ? { table: attrEntry.table, createdAt: attrEntry.createdAt, expiresAt: attrEntry.expiresAt }\n : (() => { throw new Error(\"Attribute entry must include exactly one of data/table/message\"); })();\n const packet = await UnsPacket.unsPacketFromUnsMessage(message);\n const singleMsg: InternalMqttMessage = {\n topic,\n asset,\n assetDescription,\n ...(hasAssetIdentityMetadata ? {\n assetStableEntityId: assetStableEntityId!.trim().toLowerCase(),\n ...(assetDisplayName ? { assetDisplayName: assetDisplayName.trim() } : {}),\n assetIdentityProof: assetIdentityProof!.trim(),\n } : {}),\n ...(hasAssetProviderIdentityMetadata ? {\n assetProviderIdentity: {\n providerId: assetProviderIdentity!.providerId.trim().toLowerCase(),\n externalSystem: assetProviderIdentity!.externalSystem.trim().toLowerCase(),\n externalType: assetProviderIdentity!.externalType.trim().toLowerCase(),\n externalId: assetProviderIdentity!.externalId.trim(),\n },\n assetProviderIdentityProof: assetProviderIdentityProof!.trim(),\n } : {}),\n objectType,\n objectTypeDescription,\n objectId,\n virtualGroup: attrEntry.virtualGroup ?? requestVirtualGroup,\n attribute: attrEntry.attribute,\n description: attrDescription,\n tags: attrEntry.tags,\n attributeNeedsPersistence: attrEntry.attributeNeedsPersistence,\n valueType: attrEntry.valueType,\n presentationKind: attrEntry.presentationKind,\n defaultAggregation: attrEntry.defaultAggregation,\n counterResetPolicy: attrEntry.counterResetPolicy,\n tableColumns: attrEntry.tableColumns,\n systemRole: attrEntry.systemRole,\n relationshipEvidence: attrEntry.relationshipEvidence,\n lifecycle: attrEntry.lifecycle,\n ...(attrEntry.validityMode ? { validityMode: attrEntry.validityMode } : {}),\n ...(attrEntry.expectedIntervalMs ? { expectedIntervalMs: attrEntry.expectedIntervalMs } : {}),\n ...(attrEntry.lifecycleEndValue ? { lifecycleEndValue: attrEntry.lifecycleEndValue } : {}),\n packet,\n };\n\n // existing single-attribute flow\n const baseDescription =\n singleMsg.description ??\n getAttributeDescription(singleMsg.attribute) ??\n singleMsg.attribute;\n const mqttMessageWithDesc = { ...singleMsg, description: baseDescription };\n\n const time = UnsPacket.formatToISO8601(new Date());\n if (mode === MessageMode.Delta || mode === MessageMode.Both) {\n this.warnDeprecatedDeltaMode(mode);\n }\n switch (mode) {\n case MessageMode.Raw: {\n await this.processAndEnqueueMessage(mqttMessageWithDesc, time, false);\n break;\n }\n case MessageMode.Delta: {\n const deltaMessage = this.buildGeneratedDeltaMessage(mqttMessageWithDesc);\n await this.processAndEnqueueMessage(deltaMessage, time, true);\n break;\n }\n case MessageMode.Both: {\n await this.processAndEnqueueMessage(mqttMessageWithDesc, time, false);\n const deltaMessageBoth = this.buildGeneratedDeltaMessage(mqttMessageWithDesc);\n await this.processAndEnqueueMessage(deltaMessageBoth, time, true);\n break;\n }\n }\n }\n return;\n }\n\n private buildGeneratedDeltaMessage(message: InternalMqttMessage): InternalMqttMessage {\n return {\n ...message,\n attribute: `${message.attribute}-delta`,\n description: `${message.description ?? \"\"} (delta)`,\n // A calculated numeric increment is already a delta. Counter metadata\n // would ask history consumers to difference it a second time.\n ...(typeof message.packet.message.data?.value === \"number\" ? {\n presentationKind: \"delta\",\n defaultAggregation: \"sum\",\n counterResetPolicy: undefined,\n } : {}),\n };\n }\n\n private warnDeprecatedDeltaMode(mode: MessageMode): void {\n if (this.deltaModeDeprecationWarned) return;\n this.deltaModeDeprecationWarned = true;\n logger.warn(\n `${this.instanceNameWithSuffix} - MessageMode.${mode} is deprecated: producer-side delta calculation loses previous-value state across service restarts. Publish raw cumulative counter values and request delta/rate from Datahub history APIs.`,\n );\n }\n\n /**\n * Publishes a message to a specified topic.\n *\n * @param topic - The MQTT topic.\n * @param message - The message to publish.\n * @returns A promise that resolves when the message is accepted into the worker queue.\n */\n public publishMessage(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return this.enqueueMessageToWorkerQueue(topic, message, options);\n }\n\n /**\n * Parses an MQTT packet from a JSON string.\n *\n * @param mqttPacket - The MQTT packet string.\n * @returns A parsed IUnsPacket object or null.\n */\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\n }\n\n /**\n * Subscribes asynchronously to one or more topics.\n *\n * @param topics - A topic or list of topics.\n */\n public subscribeAsync(topics: string | string[]): void {\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\n }\n\n /**\n * Unsubscribes asynchronously from the given topics.\n *\n * @param topics - A list of topics.\n */\n public unsubscribeAsync(topics: string[]): void {\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\n }\n\n /**\n * Processes and enqueues a message to the worker queue, including handling\n * sequencing, value differences, and tracking of unique topics.\n *\n * @param msg - The MQTT message to process.\n * @param time - The timestamp.\n * @param valueIsCumulative - Whether the value is cumulative.\n */\n private async processAndEnqueueMessage(msg: InternalMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\n try {\n const attributeType =\n msg.packet.message.data ? UnsAttributeType.Data :\n msg.packet.message.table ? UnsAttributeType.Table : null;\n \n let dataGroup = \"\";\n if (attributeType == UnsAttributeType.Data)\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Table)\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\n\n const { objectType, objectId, asset } = this.resolveObjectIdentity(msg);\n const normalizedTopic = this.normalizeTopicWithObject(msg.topic);\n msg.topic = normalizedTopic;\n const description = msg.description ?? getAttributeDescription(msg.attribute as string) ?? \"\";\n const objectTypeDescription = msg.objectTypeDescription ?? (objectType ? getObjectTypeDescription(objectType) : undefined);\n\n // Runtime validation for validity fields\n if (msg.validityMode) {\n const validModes = new Set([\"interval\", \"lifecycle\", \"static\"]);\n if (!validModes.has(msg.validityMode)) {\n logger.warn(`${this.instanceNameWithSuffix} - Invalid validityMode \"${msg.validityMode}\" for attribute \"${msg.attribute}\". Expected: interval | lifecycle | static.`);\n }\n if (msg.expectedIntervalMs && msg.validityMode !== \"interval\") {\n logger.warn(`${this.instanceNameWithSuffix} - expectedIntervalMs is set but validityMode is \"${msg.validityMode}\" (only used with \"interval\") for attribute \"${msg.attribute}\".`);\n }\n if (msg.lifecycleEndValue && msg.validityMode !== \"lifecycle\") {\n logger.warn(`${this.instanceNameWithSuffix} - lifecycleEndValue is set but validityMode is \"${msg.validityMode}\" (only used with \"lifecycle\") for attribute \"${msg.attribute}\".`);\n }\n if (msg.validityMode === \"interval\" && !msg.expectedIntervalMs) {\n logger.debug(`${this.instanceNameWithSuffix} - validityMode \"interval\" without expectedIntervalMs for attribute \"${msg.attribute}\" — controller will use its default.`);\n }\n }\n\n this.registerUniqueTopic({\n timestamp: time,\n topic: msg.topic,\n attribute: msg.attribute,\n attributeType: attributeType,\n description,\n tags: msg.tags,\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\n valueType: msg.valueType,\n presentationKind: msg.presentationKind,\n defaultAggregation: msg.defaultAggregation,\n counterResetPolicy: msg.counterResetPolicy,\n tableColumns: msg.tableColumns,\n systemRole: msg.systemRole,\n relationshipEvidence: msg.relationshipEvidence,\n lifecycle: msg.lifecycle,\n dataGroup,\n virtualGroup: msg.virtualGroup,\n asset,\n assetDescription: msg.assetDescription,\n assetStableEntityId: msg.assetStableEntityId,\n assetDisplayName: msg.assetDisplayName,\n assetIdentityProof: msg.assetIdentityProof,\n assetProviderIdentity: msg.assetProviderIdentity,\n assetProviderIdentityProof: msg.assetProviderIdentityProof,\n objectType,\n objectTypeDescription,\n objectId,\n ...(msg.validityMode ? { validityMode: msg.validityMode } : {}),\n ...(msg.expectedIntervalMs ? { expectedIntervalMs: msg.expectedIntervalMs } : {}),\n ...(msg.lifecycleEndValue ? { lifecycleEndValue: msg.lifecycleEndValue } : {}),\n });\n\n const publishTopic = `${msg.topic}${asset ? `${asset}/` : \"\"}${objectType ? `${objectType}/` : \"\"}${objectId ? `${objectId}/` : \"\"}${msg.attribute}`;\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\n msg.packet.sequenceId = sequenceId;\n\n if (msg.packet.message.data) {\n const newValue = msg.packet.message.data.value;\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\n const lastValueEntry = this.lastValues.get(publishTopic);\n const currentTime = new Date(msg.packet.message.data.time);\n\n if (lastValueEntry) {\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\n const lastValue = lastValueEntry.value;\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n // Compute the delta and manage cumulative resets\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\n // Skip if newValue is 0 (likely a glitch)\n if (newValue === 0) {\n return; // Don't process or enqueue\n }\n const delta = newValue - lastValue;\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\n }\n msg.packet.interval = intervalBetweenMessages;\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${publishTopic}`);\n if (valueIsCumulative === false) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${publishTopic}`);\n }\n }\n } else if (msg.packet.message.table) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${publishTopic}: packet.message must include data or table`);\n }\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Stops the UnsProxy instance and cleans up resources.\n */\n public stop(options: UnsMqttProxyStopOptions = {}): Promise<void> {\n if (this.stopPromise) {\n return this.stopPromise;\n }\n\n this.lifecycleState = \"stopping\";\n this.stopPromise = this.performStop(options);\n return this.stopPromise;\n }\n\n private async performStop(options: UnsMqttProxyStopOptions): Promise<void> {\n await super.stop();\n const drain = options.drain ?? true;\n const timeoutMs = options.timeoutMs ?? UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS;\n let stopError: Error | null = null;\n\n if (drain) {\n try {\n await this.flush(timeoutMs);\n } catch (error: any) {\n stopError = error instanceof Error ? error : new Error(String(error));\n logger.error(`${this.instanceNameWithSuffix} - Error draining publishes before stop: ${stopError.message}`);\n }\n }\n\n if (this.worker) {\n this.expectedWorkerExit = true;\n try {\n const exitCode = await this.worker.terminate();\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\n } catch (error: any) {\n const terminationError = error instanceof Error ? error : new Error(String(error));\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${terminationError.message}`);\n stopError ??= terminationError;\n }\n }\n\n this.lifecycleState = \"stopped\";\n this.rejectOutstandingPublishes(stopError ?? new Error(\"UnsProxy has been stopped\"));\n\n if (stopError) {\n throw stopError;\n }\n }\n\n private failPendingPublishes(reason: Error): void {\n this.workerFailure = reason;\n this.rejectOutstandingPublishes(reason);\n }\n\n private rejectOutstandingPublishes(reason: Error): void {\n for (const pending of this.pendingEnqueues.values()) {\n pending.reject(reason);\n }\n this.pendingEnqueues.clear();\n this.pendingPublishCompletions.clear();\n\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.reject(reason);\n }\n }\n\n private notifyDrainWaiters(): void {\n if (this.workerFailure) {\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.reject(this.workerFailure);\n }\n return;\n }\n if (this.pendingEnqueues.size !== 0 || this.pendingPublishCompletions.size !== 0) {\n return;\n }\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.resolve();\n }\n }\n\n private removeDrainWaiter(waiterToRemove: { resolve: () => void; reject: (reason?: any) => void; timer?: NodeJS.Timeout }): void {\n this.drainWaiters = this.drainWaiters.filter((waiter) => waiter !== waiterToRemove);\n }\n\n}\n"]}
1
+ {"version":3,"file":"uns-mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/uns-mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { mqttPublishQueueSchema, type MqttPublishQueueStatus } from \"./publish-queue-contract.js\";\nimport { readFileSync } from \"fs\";\nimport { IClientPublishOptions } from \"mqtt\";\nimport * as path from \"path\";\nimport { Worker } from \"worker_threads\";\nimport { fileURLToPath } from \"url\";\nimport { basePath } from \"../base-path.js\";\nimport logger from \"../logger.js\";\nimport { IMqttPublishRequest, IUnsLifecycleMetadata, IUnsMessage, IUnsPacket, IUnsParameters, IUnsRelationshipEvidenceMetadata, IUnsTableColumnMetadata, UnsAttribute, UnsAttributeSystemRole, UnsEvents, ValueType } from \"../uns/uns-interfaces.js\";\nimport { getObjectTypeDescription, type UnsObjectId, type UnsObjectType } from \"../uns/uns-object.js\";\nimport type { UnsAsset } from \"../uns/uns-asset.js\";\nimport { MeasurementUnit } from \"../uns/uns-measurements.js\";\nimport { UnsPacket } from \"../uns/uns-packet.js\";\nimport { IMqttParameters, IMqttWorkerData } from \"./mqtt-interfaces.js\";\nimport { MqttTopicBuilder } from \"./mqtt-topic-builder.js\";\nimport UnsProxy from \"../uns/uns-proxy.js\";\nimport { UnsAttributeType } from \"../graphql/schema.js\";\nimport { getAttributeDescription } from \"../uns/uns-attributes.js\";\nimport { UnsTags } from \"../uns/uns-tags.js\";\nimport { UnsTopics } from \"../uns/uns-topics.js\";\n\nconst packageJsonPath = path.join(basePath, \"package.json\");\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, \"utf8\"));\n\nconst moduleDirectory = path.dirname(fileURLToPath(import.meta.url));\nconst packageRoot = path.resolve(moduleDirectory, \"..\", \"..\");\nconst workerScriptPath = path.join(packageRoot, \"dist/uns-mqtt/mqtt-worker-init.js\");\n\nexport enum MessageMode {\n Raw = 'raw', // Send only the original message\n /**\n * @deprecated Producer-side delta calculation loses state across restarts.\n * Publish raw cumulative counter values and request delta/rate from Datahub history APIs.\n */\n Delta = 'delta', // Send only the delta message\n /**\n * @deprecated Producer-side delta calculation loses state across restarts.\n * Publish raw cumulative counter values and request delta/rate from Datahub history APIs.\n */\n Both = 'both' // Send both the original and delta messages\n}\n\nexport interface UnsMqttProxyStopOptions {\n drain?: boolean;\n timeoutMs?: number;\n}\n\ntype UnsMqttProxyLifecycleState = \"running\" | \"stopping\" | \"stopped\";\n\ntype InternalMqttMessage = {\n topic: UnsTopics;\n attribute: UnsAttribute;\n asset: UnsAsset;\n assetDescription?: string;\n assetStableEntityId?: string;\n assetDisplayName?: string;\n assetIdentityProof?: string;\n assetProviderIdentity?: {\n providerId: string;\n externalSystem: string;\n externalType: string;\n externalId: string;\n };\n assetProviderIdentityProof?: string;\n objectType: UnsObjectType;\n objectTypeDescription?: string;\n objectId: UnsObjectId;\n virtualGroup?: string;\n description?: string;\n tags?: UnsTags[];\n attributeNeedsPersistence?: boolean | null;\n valueType?: string;\n presentationKind?: string;\n defaultAggregation?: string;\n counterResetPolicy?: string;\n tableColumns?: IUnsTableColumnMetadata[];\n systemRole?: UnsAttributeSystemRole;\n relationshipEvidence?: IUnsRelationshipEvidenceMetadata;\n lifecycle?: IUnsLifecycleMetadata;\n validityMode?: \"interval\" | \"lifecycle\" | \"static\";\n expectedIntervalMs?: number;\n lifecycleEndValue?: string;\n packet: IUnsPacket;\n};\n\nexport default class UnsMqttProxy extends UnsProxy {\n public static readonly DEFAULT_DRAIN_TIMEOUT_MS = 30_000;\n private lastValues: Map<string, { value: ValueType; uom: string; timestamp: Date }> = new Map();\n private worker: Worker;\n private pendingEnqueues: Map<string, { resolve: () => void; reject: (reason?: any) => void }> = new Map();\n private pendingPublishCompletions = new Set<string>();\n private unsParameters: IUnsParameters;\n protected processStatusTopic: string;\n public instanceName: string;\n private currentSequenceId: Map<string, number> = new Map();\n private topicBuilder: MqttTopicBuilder;\n private deltaModeDeprecationWarned = false;\n private drainWaiters: Array<{ resolve: () => void; reject: (reason?: any) => void; timer?: NodeJS.Timeout }> = [];\n private workerFailure: Error | null = null;\n private lifecycleState: UnsMqttProxyLifecycleState = \"running\";\n private stopPromise: Promise<void> | null = null;\n private expectedWorkerExit = false;\n private publishQueueStatus?: MqttPublishQueueStatus;\n private admissionBytes = new Map<string, number>();\n private pendingAdmissionBytes = 0;\n private queueRequests = new Map<string, { resolve: () => void; reject: (error: Error) => void; timer: ReturnType<typeof setTimeout> }>();\n\n\n constructor(\n mqttHost: string,\n processName: string,\n instanceName: string,\n unsParameters?: IUnsParameters,\n publisherActive: boolean = false,\n subscriberActive: boolean = false\n ) {\n super();\n this.instanceName = instanceName;\n // Create the topic builder using packageJson values and the processName.\n this.topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageJson.name)}/${MqttTopicBuilder.sanitizeTopicPart(packageJson.version)}/${MqttTopicBuilder.sanitizeTopicPart(processName)}/`);\n\n // Generate the processStatusTopic using the builder.\n this.processStatusTopic = this.topicBuilder.getProcessStatusTopic();\n // Derive the instanceStatusTopic by appending the instance name.\n this.instanceStatusTopic = this.processStatusTopic + instanceName + \"/\";\n\n // Concatenate processName with instanceName for the worker identification.\n this.instanceNameWithSuffix = `${processName}-${instanceName}`;\n \n const mqttParameters: IMqttParameters = {\n mqttSubToTopics: unsParameters?.mqttSubToTopics ?? [],\n username: unsParameters?.username ?? \"\",\n password: unsParameters?.password ?? \"\",\n mqttSSL: unsParameters?.mqttSSL ?? false,\n statusTopic: this.instanceStatusTopic,\n rejectUnauthorized: unsParameters?.rejectUnauthorized ?? false,\n clientId: unsParameters?.clientId,\n hosts: unsParameters?.hosts,\n servers: unsParameters?.servers,\n port: unsParameters?.port,\n protocol: unsParameters?.protocol,\n keepalive: unsParameters?.keepalive,\n clean: unsParameters?.clean,\n connectTimeout: unsParameters?.connectTimeout,\n reconnectPeriod: unsParameters?.reconnectPeriod,\n reconnectOnConnackError: unsParameters?.reconnectOnConnackError,\n resubscribe: unsParameters?.resubscribe,\n queueQoSZero: unsParameters?.queueQoSZero,\n properties: unsParameters?.properties,\n ca: unsParameters?.ca,\n cert: unsParameters?.cert,\n key: unsParameters?.key,\n servername: unsParameters?.servername,\n };\n this.unsParameters = { ...(unsParameters ?? {}) };\n if (unsParameters?.publishQueue) {\n this.unsParameters.publishQueue = mqttPublishQueueSchema.parse(unsParameters.publishQueue);\n if ((unsParameters.publishConcurrency ?? 1) !== 1) throw Error(\"Persistent MQTT output requires publishConcurrency=1\");\n }\n this.startQueueWorker(mqttHost, this.instanceNameWithSuffix, mqttParameters, publisherActive, subscriberActive);\n }\n\n /**\n * Resolve object identity from explicit fields or the tail of the topic path.\n * Falls back to parsing when not provided for backward compatibility.\n */\n private resolveObjectIdentity(msg: InternalMqttMessage): { objectType?: UnsObjectType; objectId?: UnsObjectId; asset?: UnsAsset } {\n const providedType = msg.objectType;\n const providedId = msg.objectId;\n const providedAsset = msg.asset;\n\n const topicParts = msg.topic.split(\"/\").filter((part) => part.length > 0);\n const hasObjectTail = topicParts.length >= 2;\n const parsedType = hasObjectTail ? topicParts[topicParts.length - 2] as UnsObjectType : undefined;\n const parsedId = hasObjectTail ? topicParts[topicParts.length - 1] as UnsObjectId : undefined;\n const parsedAsset = hasObjectTail\n ? (topicParts.length >= 3 ? topicParts[topicParts.length - 3] as UnsAsset : undefined)\n : (topicParts.length >= 1 ? topicParts[topicParts.length - 1] as UnsAsset : undefined);\n\n const objectType = providedType ?? parsedType;\n const objectId = providedId ?? parsedId ?? \"main\";\n const asset = providedAsset ?? parsedAsset;\n\n // If values are provided, trust them; otherwise derive from topic.\n if (!providedType || !providedId) {\n if (parsedType && parsedId) {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; derived from topic tail ${parsedType}/${parsedId}`);\n } else {\n logger.warn(`${this.instanceNameWithSuffix} - objectType/objectId missing; defaulting objectId to 'main' for topic '${msg.topic}'. Expected topic to end with '<objectType>/<objectId>/'`);\n }\n }\n // Asset is optional; no warning on mismatch to avoid noisy logs when base topics don't carry it.\n\n msg.objectType = objectType;\n msg.objectId = objectId;\n msg.asset = asset;\n\n return { objectType, objectId, asset };\n }\n\n /**\n * Ensure the topic ends with a trailing slash for attribute concatenation.\n */\n private normalizeTopicWithObject(topic: string): string {\n return topic.endsWith(\"/\") ? topic : `${topic}/`;\n }\n\n /**\n * Starts a worker thread to process the throttled publish queue.\n */\n private startQueueWorker(\n mqttHost: string,\n instanceNameWithSuffix: string,\n mqttParameters: IMqttParameters,\n publisherActive: boolean,\n subscriberActive: boolean\n ): void {\n const workerData: IMqttWorkerData = {\n publishThrottlingDelay: this.unsParameters.publishThrottlingDelay ?? 1,\n publishConcurrency: this.unsParameters.publishConcurrency ?? 1,\n maxPendingPublishes: this.unsParameters.maxPendingPublishes,\n subscribeThrottlingDelay: this.unsParameters.subscribeThrottlingDelay ?? 1,\n persistToDisk: false,\n publishQueue: this.unsParameters.publishQueue,\n publishQueueIdentity: this.unsParameters.publishQueue ? JSON.stringify({\n package: packageJson.name, owner: instanceNameWithSuffix,\n host: mqttHost, port: mqttParameters.port ?? (mqttParameters.mqttSSL ? 8883 : 1883),\n protocol: mqttParameters.protocol ?? (mqttParameters.mqttSSL ? \"mqtts\" : \"mqtt\"),\n hosts: mqttParameters.hosts ?? null, servers: mqttParameters.servers ?? null,\n }) : undefined,\n mqttHost: mqttHost,\n instanceNameWithSuffix: instanceNameWithSuffix,\n mqttParameters: mqttParameters,\n publisherActive,\n subscriberActive,\n defaultPublishOptions: this.unsParameters.defaultPublishOptions,\n };\n\n this.worker = new Worker(workerScriptPath, { workerData });\n\n this.worker.on(\"message\", (msg) => {\n if (msg?.command === \"publishQueueStatus\") {\n this.publishQueueStatus = msg.status;\n } else if (msg?.command === \"publishQueueReply\") {\n const pending = this.queueRequests.get(msg.id);\n if (pending) {\n clearTimeout(pending.timer); this.queueRequests.delete(msg.id);\n if (msg.status === \"success\") pending.resolve(); else pending.reject(new Error(msg.error));\n }\n } else if (msg?.command === \"publishQueueControlError\") {\n this.event.emit(\"error\", { code: 0, message: msg.error });\n } else if (msg && msg.command === \"enqueueAccepted\" && msg.id) {\n const pending = this.pendingEnqueues.get(msg.id);\n if (pending) {\n this.pendingEnqueues.delete(msg.id);\n this.pendingAdmissionBytes -= this.admissionBytes.get(msg.id) ?? 0;\n this.admissionBytes.delete(msg.id);\n if (msg.status === \"accepted\") {\n this.pendingPublishCompletions.add(msg.id);\n pending.resolve();\n } else {\n pending.reject(new Error(msg.error));\n }\n this.notifyDrainWaiters();\n }\n } else if (msg && msg.command === \"publishResult\" && msg.id) {\n this.pendingPublishCompletions.delete(msg.id);\n if (msg.status === \"error\") {\n const errorMessage = msg.error ?? `Error publishing to topic ${msg.topic ?? \"unknown\"}`;\n this.event.emit(\"error\", { code: 0, message: errorMessage });\n }\n this.notifyDrainWaiters();\n } else if (msg && msg.command === \"input\") {\n this.event.emit(\"input\", { topic: msg.topic, message: msg.message.toString(), packet: msg.packet });\n } else if (msg && (msg.command === \"handover_subscriber\" || msg.command === \"handover_publisher\")) {\n this.event.emit(\"mqttWorker\", { command: msg.command, batchSize: msg.batchSize, referenceHash: msg.referenceHash, instanceName: this.instanceName });\n } else if (msg && msg.command === \"mqttProxyStatus\") {\n this.event.emit(\"mqttProxyStatus\", { event: msg.event, value: msg.value, uom: msg.uom, statusTopic: msg.statusTopic });\n }\n });\n\n this.worker.on(\"error\", (err) => {\n if (this.expectedWorkerExit) {\n return;\n }\n logger.error(\"Error in worker:\", err);\n const reason = err instanceof Error ? err : new Error(String(err));\n this.failPendingPublishes(reason);\n });\n\n this.worker.on(\"exit\", (code) => {\n if (this.expectedWorkerExit) {\n return;\n }\n logger.error(`Worker exited unexpectedly with code ${code}`);\n const reason = new Error(`MQTT worker exited unexpectedly with code ${code}`);\n this.failPendingPublishes(reason);\n });\n }\n\n /**\n * Enqueues a message to the worker queue.\n *\n * @param topic - The topic to which the message belongs.\n * @param message - The message to be enqueued.\n * @param options - Optional publish options.\n * @returns A promise that resolves when the message is accepted into the worker queue.\n */\n private async enqueueMessageToWorkerQueue(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return new Promise((resolve, reject) => {\n if (this.lifecycleState !== \"running\") {\n reject(new Error(`${this.instanceNameWithSuffix} - MQTT proxy is ${this.lifecycleState}; publish rejected.`));\n return;\n }\n if (this.workerFailure) {\n reject(this.workerFailure);\n return;\n }\n const maxPendingPublishes = this.unsParameters.maxPendingPublishes ?? this.unsParameters.publishQueue?.maxRecords;\n const pendingCount = this.pendingEnqueues.size + this.pendingPublishCompletions.size;\n if (maxPendingPublishes !== undefined && pendingCount >= maxPendingPublishes) {\n reject(new Error(`${this.instanceNameWithSuffix} - Publisher queue is full (${maxPendingPublishes}).`));\n return;\n }\n const bytes = Buffer.byteLength(topic) + Buffer.byteLength(message) + 256;\n const queue = this.unsParameters.publishQueue;\n if (queue && (bytes > queue.maxMessageBytes! || this.pendingAdmissionBytes + bytes > queue.maxBytes!)) {\n reject(new Error(\"MQTT output admission byte limit reached\")); return;\n }\n const id = randomUUID();\n if (queue) { this.admissionBytes.set(id, bytes); this.pendingAdmissionBytes += bytes; }\n this.pendingEnqueues.set(id, { resolve, reject });\n try {\n this.worker.postMessage({ command: \"enqueue\", id, topic, message, options });\n } catch (error) {\n this.pendingEnqueues.delete(id);\n this.pendingAdmissionBytes -= this.admissionBytes.get(id) ?? 0; this.admissionBytes.delete(id);\n reject(error);\n }\n this.notifyDrainWaiters();\n });\n }\n\n /**\n * Sets the publisher active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setPublisherActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setPublisherActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the publisher to passive mode.\n * @returns A promise that resolves when the publisher is set to passive.\n */\n public setPublisherPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setPublisherPassive\"});\n return new Promise((resolve) => {\n const handler = (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_publisher\") {\n this.event.off(\"mqttWorker\", handler);\n logger.info(`${this.instanceNameWithSuffix} - Publisher set to passive.`);\n resolve(msg);\n }\n };\n this.event.on(\"mqttWorker\", handler);\n });\n }\n\n /**\n * Sets the subscriber active state.\n *\n * @param batchSize - Optional batch size.\n * @param referenceHash - Optional reference hash.\n */\n public setSubscriberActive(batchSize?: number, referenceHash?: string): void {\n this.worker.postMessage({ command: \"setSubscriberActive\", batchSize, referenceHash });\n }\n\n /**\n * Sets the subscriber to passive mode.\n * @returns A promise that resolves when the subscriber is set to passive.\n */\n public setSubscriberPassive(): Promise<UnsEvents[\"mqttWorker\"]> {\n this.worker.postMessage({ command: \"setSubscriberPassive\"});\n return new Promise((resolve) => {\n const handler = (msg: UnsEvents[\"mqttWorker\"]) => {\n if (msg.command === \"handover_subscriber\") {\n this.event.off(\"mqttWorker\", handler);\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive.`);\n resolve(msg);\n }\n };\n this.event.on(\"mqttWorker\", handler);\n });\n }\n\n\n /**\n * Sets the subscriber to passive mode and allows the publisher to run\n * until the queue is empty (all messages are processed).\n */\n public async setSubscriberPassiveAndDrainQueue(): Promise<UnsEvents[\"mqttWorker\"]> {\n const mqttWorkerData = await this.setSubscriberPassive();\n await this.flush();\n logger.info(`${this.instanceNameWithSuffix} - Subscriber set to passive and queue drained.`);\n return mqttWorkerData;\n }\n\n public async drainPublishes(timeoutMs: number = UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS): Promise<void> {\n if (this.workerFailure) {\n throw this.workerFailure;\n }\n if (this.unsParameters.publishQueue) {\n await this.requestPublishQueue(\"flushPublishes\", timeoutMs);\n return;\n }\n if (this.pendingEnqueues.size === 0 && this.pendingPublishCompletions.size === 0) {\n return;\n }\n await new Promise<void>((resolve, reject) => {\n const waiter = { resolve, reject, timer: undefined as NodeJS.Timeout | undefined };\n if (Number.isFinite(timeoutMs) && timeoutMs > 0) {\n waiter.timer = setTimeout(() => {\n this.removeDrainWaiter(waiter);\n reject(new Error(`Timed out waiting for MQTT publishes to drain after ${timeoutMs}ms.`));\n }, timeoutMs);\n }\n this.drainWaiters.push(waiter);\n this.notifyDrainWaiters();\n });\n }\n\n public async flush(timeoutMs: number = UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS): Promise<void> {\n await this.drainPublishes(timeoutMs);\n }\n\n /**\n * Processes and publishes MQTT messages based on the selected message mode.\n *\n * @param mqttMessage - The MQTT message object.\n * @param mode - The message mode. Delta and Both are deprecated because\n * producer-side delta calculation loses state across restarts.\n */\n public async publishMqttMessage(mqttMessage: IMqttPublishRequest | null, mode: MessageMode = MessageMode.Raw) {\n if (!mqttMessage) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing mqtt message: mqttMessage must be defined.`);\n return;\n }\n\n const attrs = Array.isArray(mqttMessage.attributes)\n ? mqttMessage.attributes\n : [mqttMessage.attributes];\n const {\n topic,\n asset,\n assetDescription,\n assetStableEntityId,\n assetDisplayName,\n assetIdentityProof,\n assetProviderIdentity,\n assetProviderIdentityProof,\n objectType,\n objectTypeDescription,\n objectId,\n virtualGroup: requestVirtualGroup,\n } = mqttMessage;\n const hasAssetIdentityMetadata = assetStableEntityId !== undefined\n || assetDisplayName !== undefined\n || assetIdentityProof !== undefined;\n const hasAssetProviderIdentityMetadata = assetProviderIdentity !== undefined\n || assetProviderIdentityProof !== undefined;\n if (hasAssetIdentityMetadata && hasAssetProviderIdentityMetadata) {\n throw new Error(\"Stable Asset identity metadata and provider candidate metadata are mutually exclusive.\");\n }\n if (hasAssetIdentityMetadata) {\n if (\n typeof assetStableEntityId !== \"string\"\n || !assetStableEntityId.trim()\n || typeof assetIdentityProof !== \"string\"\n || !assetIdentityProof.trim()\n || (assetDisplayName !== undefined\n && (typeof assetDisplayName !== \"string\" || !assetDisplayName.trim()))\n ) {\n throw new Error(\"Asset identity metadata requires assetStableEntityId and assetIdentityProof; assetDisplayName must be non-empty when supplied.\");\n }\n }\n if (hasAssetProviderIdentityMetadata) {\n const identity = assetProviderIdentity as Record<string, unknown> | undefined;\n if (\n !identity\n || typeof assetProviderIdentityProof !== \"string\"\n || !assetProviderIdentityProof.trim()\n || [\"providerId\", \"externalSystem\", \"externalType\", \"externalId\"].some(\n (key) => typeof identity[key] !== \"string\" || !(identity[key] as string).trim(),\n )\n ) {\n throw new Error(\"Provider Asset identity metadata requires providerId, externalSystem, externalType, externalId, and assetProviderIdentityProof.\");\n }\n }\n for (const attrEntry of attrs) {\n const attrDescription = attrEntry.description ?? getAttributeDescription(attrEntry.attribute);\n const message: IUnsMessage =\n \"message\" in attrEntry && attrEntry.message\n ? attrEntry.message\n : \"data\" in attrEntry && attrEntry.data\n ? { data: attrEntry.data, createdAt: attrEntry.createdAt, expiresAt: attrEntry.expiresAt }\n : \"table\" in attrEntry && attrEntry.table\n ? { table: attrEntry.table, createdAt: attrEntry.createdAt, expiresAt: attrEntry.expiresAt }\n : (() => { throw new Error(\"Attribute entry must include exactly one of data/table/message\"); })();\n const packet = await UnsPacket.unsPacketFromUnsMessage(message);\n const singleMsg: InternalMqttMessage = {\n topic,\n asset,\n assetDescription,\n ...(hasAssetIdentityMetadata ? {\n assetStableEntityId: assetStableEntityId!.trim().toLowerCase(),\n ...(assetDisplayName ? { assetDisplayName: assetDisplayName.trim() } : {}),\n assetIdentityProof: assetIdentityProof!.trim(),\n } : {}),\n ...(hasAssetProviderIdentityMetadata ? {\n assetProviderIdentity: {\n providerId: assetProviderIdentity!.providerId.trim().toLowerCase(),\n externalSystem: assetProviderIdentity!.externalSystem.trim().toLowerCase(),\n externalType: assetProviderIdentity!.externalType.trim().toLowerCase(),\n externalId: assetProviderIdentity!.externalId.trim(),\n },\n assetProviderIdentityProof: assetProviderIdentityProof!.trim(),\n } : {}),\n objectType,\n objectTypeDescription,\n objectId,\n virtualGroup: attrEntry.virtualGroup ?? requestVirtualGroup,\n attribute: attrEntry.attribute,\n description: attrDescription,\n tags: attrEntry.tags,\n attributeNeedsPersistence: attrEntry.attributeNeedsPersistence,\n valueType: attrEntry.valueType,\n presentationKind: attrEntry.presentationKind,\n defaultAggregation: attrEntry.defaultAggregation,\n counterResetPolicy: attrEntry.counterResetPolicy,\n tableColumns: attrEntry.tableColumns,\n systemRole: attrEntry.systemRole,\n relationshipEvidence: attrEntry.relationshipEvidence,\n lifecycle: attrEntry.lifecycle,\n ...(attrEntry.validityMode ? { validityMode: attrEntry.validityMode } : {}),\n ...(attrEntry.expectedIntervalMs ? { expectedIntervalMs: attrEntry.expectedIntervalMs } : {}),\n ...(attrEntry.lifecycleEndValue ? { lifecycleEndValue: attrEntry.lifecycleEndValue } : {}),\n packet,\n };\n\n // existing single-attribute flow\n const baseDescription =\n singleMsg.description ??\n getAttributeDescription(singleMsg.attribute) ??\n singleMsg.attribute;\n const mqttMessageWithDesc = { ...singleMsg, description: baseDescription };\n\n const time = UnsPacket.formatToISO8601(new Date());\n if (mode === MessageMode.Delta || mode === MessageMode.Both) {\n this.warnDeprecatedDeltaMode(mode);\n }\n switch (mode) {\n case MessageMode.Raw: {\n await this.processAndEnqueueMessage(mqttMessageWithDesc, time, false);\n break;\n }\n case MessageMode.Delta: {\n const deltaMessage = this.buildGeneratedDeltaMessage(mqttMessageWithDesc);\n await this.processAndEnqueueMessage(deltaMessage, time, true);\n break;\n }\n case MessageMode.Both: {\n await this.processAndEnqueueMessage(mqttMessageWithDesc, time, false);\n const deltaMessageBoth = this.buildGeneratedDeltaMessage(mqttMessageWithDesc);\n await this.processAndEnqueueMessage(deltaMessageBoth, time, true);\n break;\n }\n }\n }\n return;\n }\n\n private buildGeneratedDeltaMessage(message: InternalMqttMessage): InternalMqttMessage {\n return {\n ...message,\n attribute: `${message.attribute}-delta`,\n description: `${message.description ?? \"\"} (delta)`,\n // A calculated numeric increment is already a delta. Counter metadata\n // would ask history consumers to difference it a second time.\n ...(typeof message.packet.message.data?.value === \"number\" ? {\n presentationKind: \"delta\",\n defaultAggregation: \"sum\",\n counterResetPolicy: undefined,\n } : {}),\n };\n }\n\n private warnDeprecatedDeltaMode(mode: MessageMode): void {\n if (this.deltaModeDeprecationWarned) return;\n this.deltaModeDeprecationWarned = true;\n logger.warn(\n `${this.instanceNameWithSuffix} - MessageMode.${mode} is deprecated: producer-side delta calculation loses previous-value state across service restarts. Publish raw cumulative counter values and request delta/rate from Datahub history APIs.`,\n );\n }\n\n /**\n * Publishes a message to a specified topic.\n *\n * @param topic - The MQTT topic.\n * @param message - The message to publish.\n * @returns A promise that resolves when the message is accepted into the worker queue.\n */\n public publishMessage(topic: string, message: string, options?: IClientPublishOptions): Promise<void> {\n return this.enqueueMessageToWorkerQueue(topic, message, options);\n }\n\n /**\n * Parses an MQTT packet from a JSON string.\n *\n * @param mqttPacket - The MQTT packet string.\n * @returns A parsed IUnsPacket object or null.\n */\n public parseMqttPacket(mqttPacket: string): IUnsPacket | null {\n return UnsPacket.parseMqttPacket(mqttPacket, this.instanceNameWithSuffix);\n }\n\n /**\n * Subscribes asynchronously to one or more topics.\n *\n * @param topics - A topic or list of topics.\n */\n public subscribeAsync(topics: string | string[]): void {\n this.worker.postMessage({ command: \"subscribeAsync\", topics });\n }\n\n /**\n * Unsubscribes asynchronously from the given topics.\n *\n * @param topics - A list of topics.\n */\n public unsubscribeAsync(topics: string[]): void {\n this.worker.postMessage({ command: \"unsubscribeAsync\", topics });\n }\n\n /**\n * Processes and enqueues a message to the worker queue, including handling\n * sequencing, value differences, and tracking of unique topics.\n *\n * @param msg - The MQTT message to process.\n * @param time - The timestamp.\n * @param valueIsCumulative - Whether the value is cumulative.\n */\n private async processAndEnqueueMessage(msg: InternalMqttMessage, time: string, valueIsCumulative: boolean = false): Promise<void> {\n try {\n const attributeType =\n msg.packet.message.data ? UnsAttributeType.Data :\n msg.packet.message.table ? UnsAttributeType.Table : null;\n \n let dataGroup = \"\";\n if (attributeType == UnsAttributeType.Data)\n dataGroup = msg.packet.message.data.dataGroup ?? \"\";\n if (attributeType == UnsAttributeType.Table)\n dataGroup = msg.packet.message.table.dataGroup ?? \"\";\n\n const { objectType, objectId, asset } = this.resolveObjectIdentity(msg);\n const normalizedTopic = this.normalizeTopicWithObject(msg.topic);\n msg.topic = normalizedTopic;\n const description = msg.description ?? getAttributeDescription(msg.attribute as string) ?? \"\";\n const objectTypeDescription = msg.objectTypeDescription ?? (objectType ? getObjectTypeDescription(objectType) : undefined);\n\n // Runtime validation for validity fields\n if (msg.validityMode) {\n const validModes = new Set([\"interval\", \"lifecycle\", \"static\"]);\n if (!validModes.has(msg.validityMode)) {\n logger.warn(`${this.instanceNameWithSuffix} - Invalid validityMode \"${msg.validityMode}\" for attribute \"${msg.attribute}\". Expected: interval | lifecycle | static.`);\n }\n if (msg.expectedIntervalMs && msg.validityMode !== \"interval\") {\n logger.warn(`${this.instanceNameWithSuffix} - expectedIntervalMs is set but validityMode is \"${msg.validityMode}\" (only used with \"interval\") for attribute \"${msg.attribute}\".`);\n }\n if (msg.lifecycleEndValue && msg.validityMode !== \"lifecycle\") {\n logger.warn(`${this.instanceNameWithSuffix} - lifecycleEndValue is set but validityMode is \"${msg.validityMode}\" (only used with \"lifecycle\") for attribute \"${msg.attribute}\".`);\n }\n if (msg.validityMode === \"interval\" && !msg.expectedIntervalMs) {\n logger.debug(`${this.instanceNameWithSuffix} - validityMode \"interval\" without expectedIntervalMs for attribute \"${msg.attribute}\" — controller will use its default.`);\n }\n }\n\n this.registerUniqueTopic({\n timestamp: time,\n topic: msg.topic,\n attribute: msg.attribute,\n attributeType: attributeType,\n description,\n tags: msg.tags,\n attributeNeedsPersistence: msg.attributeNeedsPersistence,\n valueType: msg.valueType,\n presentationKind: msg.presentationKind,\n defaultAggregation: msg.defaultAggregation,\n counterResetPolicy: msg.counterResetPolicy,\n tableColumns: msg.tableColumns,\n systemRole: msg.systemRole,\n relationshipEvidence: msg.relationshipEvidence,\n lifecycle: msg.lifecycle,\n dataGroup,\n virtualGroup: msg.virtualGroup,\n asset,\n assetDescription: msg.assetDescription,\n assetStableEntityId: msg.assetStableEntityId,\n assetDisplayName: msg.assetDisplayName,\n assetIdentityProof: msg.assetIdentityProof,\n assetProviderIdentity: msg.assetProviderIdentity,\n assetProviderIdentityProof: msg.assetProviderIdentityProof,\n objectType,\n objectTypeDescription,\n objectId,\n ...(msg.validityMode ? { validityMode: msg.validityMode } : {}),\n ...(msg.expectedIntervalMs ? { expectedIntervalMs: msg.expectedIntervalMs } : {}),\n ...(msg.lifecycleEndValue ? { lifecycleEndValue: msg.lifecycleEndValue } : {}),\n });\n\n const publishTopic = `${msg.topic}${asset ? `${asset}/` : \"\"}${objectType ? `${objectType}/` : \"\"}${objectId ? `${objectId}/` : \"\"}${msg.attribute}`;\n const sequenceId = this.currentSequenceId.get(msg.topic) ?? 0;\n this.currentSequenceId.set(msg.topic, sequenceId + 1);\n msg.packet.sequenceId = sequenceId;\n\n if (msg.packet.message.data) {\n const newValue = msg.packet.message.data.value;\n const newUom: MeasurementUnit = msg.packet.message.data.uom;\n const lastValueEntry = this.lastValues.get(publishTopic);\n const currentTime = new Date(msg.packet.message.data.time);\n\n if (lastValueEntry) {\n const intervalBetweenMessages = currentTime.getTime() - lastValueEntry.timestamp.getTime();\n const lastValue = lastValueEntry.value;\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n // Compute the delta and manage cumulative resets\n if (valueIsCumulative == true && typeof newValue === \"number\" && typeof lastValue === \"number\") {\n // Skip if newValue is 0 (likely a glitch)\n if (newValue === 0) {\n return; // Don't process or enqueue\n }\n const delta = newValue - lastValue;\n msg.packet.message.data.value = delta < 0 ? newValue : delta;\n }\n msg.packet.interval = intervalBetweenMessages;\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n this.lastValues.set(publishTopic, { value: newValue, uom: newUom, timestamp: currentTime });\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate interval on topic ${publishTopic}`);\n if (valueIsCumulative === false) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n logger.debug(`${this.instanceNameWithSuffix} - Need one more packet to calculate difference on value in data for topic ${publishTopic}`);\n }\n }\n } else if (msg.packet.message.table) {\n await this.enqueueMessageToWorkerQueue(publishTopic, JSON.stringify(msg.packet));\n } else {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${publishTopic}: packet.message must include data or table`);\n }\n } catch (error: any) {\n logger.error(`${this.instanceNameWithSuffix} - Error publishing message to topic ${msg.topic}${msg.attribute}: ${error.message}`);\n throw error;\n }\n }\n\n /**\n * Stops the UnsProxy instance and cleans up resources.\n */\n public stop(options: UnsMqttProxyStopOptions = {}): Promise<void> {\n if (this.stopPromise) {\n return this.stopPromise;\n }\n\n this.lifecycleState = \"stopping\";\n this.stopPromise = this.performStop(options).catch(error => {\n if (this.unsParameters.publishQueue && this.lifecycleState !== \"stopped\") this.stopPromise = null;\n throw error;\n });\n return this.stopPromise;\n }\n\n private async performStop(options: UnsMqttProxyStopOptions): Promise<void> {\n await super.stop();\n const drain = options.drain ?? true;\n const timeoutMs = options.timeoutMs ?? UnsMqttProxy.DEFAULT_DRAIN_TIMEOUT_MS;\n let stopError: Error | null = null;\n\n if (drain) {\n try {\n await this.flush(timeoutMs);\n } catch (error: any) {\n stopError = error instanceof Error ? error : new Error(String(error));\n logger.error(`${this.instanceNameWithSuffix} - Error draining publishes before stop: ${stopError.message}`);\n }\n }\n\n if (this.worker && this.unsParameters.publishQueue && !this.workerFailure) {\n // A failed spill must keep the live worker/RAM available for inspection or retry.\n await this.requestPublishQueue(\"closePublisher\", timeoutMs);\n }\n if (this.worker) {\n this.expectedWorkerExit = true;\n try {\n const exitCode = await this.worker.terminate();\n logger.info(`${this.instanceNameWithSuffix} - Worker terminated with exit code ${exitCode}`);\n } catch (error: any) {\n const terminationError = error instanceof Error ? error : new Error(String(error));\n logger.error(`${this.instanceNameWithSuffix} - Error terminating worker: ${terminationError.message}`);\n stopError ??= terminationError;\n }\n }\n\n this.lifecycleState = \"stopped\";\n this.rejectOutstandingPublishes(stopError ?? new Error(\"UnsProxy has been stopped\"));\n\n if (stopError) {\n throw stopError;\n }\n }\n\n public getPublishQueueStatus(): MqttPublishQueueStatus | undefined {\n return this.publishQueueStatus ? { ...this.publishQueueStatus } : undefined;\n }\n\n private requestPublishQueue(command: \"flushPublishes\" | \"closePublisher\", timeoutMs: number): Promise<void> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) return Promise.reject(new Error(\"MQTT queue timeout must be positive and finite\"));\n if (this.queueRequests.size >= 64) return Promise.reject(new Error(\"Too many pending MQTT queue control requests\"));\n return new Promise((resolve, reject) => {\n const id = randomUUID();\n const timer = setTimeout(() => {\n this.queueRequests.delete(id); reject(new Error(\"MQTT queue control timed out; outcome unconfirmed\"));\n }, timeoutMs);\n this.queueRequests.set(id, { resolve, reject, timer });\n try { this.worker.postMessage({ command, id, timeoutMs }); }\n catch (error) { clearTimeout(timer); this.queueRequests.delete(id); reject(error); }\n });\n }\n\n private failPendingPublishes(reason: Error): void {\n for (const request of this.queueRequests.values()) { clearTimeout(request.timer); request.reject(reason); }\n this.queueRequests.clear();\n this.workerFailure = reason;\n this.rejectOutstandingPublishes(reason);\n }\n\n private rejectOutstandingPublishes(reason: Error): void {\n for (const pending of this.pendingEnqueues.values()) {\n pending.reject(reason);\n }\n this.pendingEnqueues.clear();\n this.admissionBytes.clear(); this.pendingAdmissionBytes = 0;\n this.pendingPublishCompletions.clear();\n\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.reject(reason);\n }\n }\n\n private notifyDrainWaiters(): void {\n if (this.workerFailure) {\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.reject(this.workerFailure);\n }\n return;\n }\n if (this.pendingEnqueues.size !== 0 || this.pendingPublishCompletions.size !== 0) {\n return;\n }\n const waiters = this.drainWaiters.splice(0);\n for (const waiter of waiters) {\n if (waiter.timer) {\n clearTimeout(waiter.timer);\n }\n waiter.resolve();\n }\n }\n\n private removeDrainWaiter(waiterToRemove: { resolve: () => void; reject: (reason?: any) => void; timer?: NodeJS.Timeout }): void {\n this.drainWaiters = this.drainWaiters.filter((waiter) => waiter !== waiterToRemove);\n }\n\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uns-kit/core",
3
- "version": "3.0.28",
3
+ "version": "3.0.30",
4
4
  "description": "Core utilities and runtime building blocks for UNS-based realtime transformers.",
5
5
  "type": "module",
6
6
  "license": "MIT",