@uns-kit/core 2.0.40 → 2.0.42

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 (102) hide show
  1. package/README.md +38 -15
  2. package/dist/base-path.js.map +1 -1
  3. package/dist/config/project.config.extension.js.map +1 -1
  4. package/dist/config-file.js.map +1 -1
  5. package/dist/graphql/schema.js.map +1 -1
  6. package/dist/index.d.ts +9 -8
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +8 -7
  9. package/dist/index.js.map +1 -1
  10. package/dist/logger.js.map +1 -1
  11. package/dist/tools/auth/auth-client.js.map +1 -1
  12. package/dist/tools/auth/index.js.map +1 -1
  13. package/dist/tools/auth/secure-store.js.map +1 -1
  14. package/dist/tools/base-path.js.map +1 -1
  15. package/dist/tools/datahub/datahub-client.js.map +1 -1
  16. package/dist/tools/file-utils.d.ts +2 -2
  17. package/dist/tools/file-utils.js +24 -24
  18. package/dist/tools/file-utils.js.map +1 -1
  19. package/dist/tools/generate-config-schema.js.map +1 -1
  20. package/dist/tools/generate-uns-dictionary.d.ts +23 -23
  21. package/dist/tools/generate-uns-dictionary.js +147 -147
  22. package/dist/tools/generate-uns-dictionary.js.map +1 -1
  23. package/dist/tools/generate-uns-measurements.d.ts +21 -21
  24. package/dist/tools/generate-uns-measurements.js +119 -119
  25. package/dist/tools/generate-uns-measurements.js.map +1 -1
  26. package/dist/tools/generate-uns-reference.d.ts +2 -2
  27. package/dist/tools/generate-uns-reference.js +76 -76
  28. package/dist/tools/generate-uns-reference.js.map +1 -1
  29. package/dist/tools/pull-request.js.map +1 -1
  30. package/dist/tools/refresh-uns.js.map +1 -1
  31. package/dist/tools/schema.js.map +1 -1
  32. package/dist/tools/sync-uns-schema.d.ts +2 -2
  33. package/dist/tools/sync-uns-schema.js +472 -472
  34. package/dist/tools/sync-uns-schema.js.map +1 -1
  35. package/dist/uns/handover-manager-event-emitter.js.map +1 -1
  36. package/dist/uns/handover-manager.js.map +1 -1
  37. package/dist/uns/process-config.js.map +1 -1
  38. package/dist/uns/service-metadata.d.ts +53 -0
  39. package/dist/uns/service-metadata.d.ts.map +1 -0
  40. package/dist/uns/service-metadata.js +56 -0
  41. package/dist/uns/service-metadata.js.map +1 -0
  42. package/dist/uns/status-monitor.js.map +1 -1
  43. package/dist/uns/uns-asset.d.ts +1 -1
  44. package/dist/uns/uns-asset.js +1 -1
  45. package/dist/uns/uns-asset.js.map +1 -1
  46. package/dist/uns/uns-attributes.d.ts +6 -6
  47. package/dist/uns/uns-attributes.js +9 -9
  48. package/dist/uns/uns-attributes.js.map +1 -1
  49. package/dist/uns/uns-dictionary-registry.d.ts +4 -4
  50. package/dist/uns/uns-dictionary-registry.js +20 -20
  51. package/dist/uns/uns-dictionary-registry.js.map +1 -1
  52. package/dist/uns/uns-dictionary.generated.d.ts +663 -663
  53. package/dist/uns/uns-dictionary.generated.js +745 -745
  54. package/dist/uns/uns-dictionary.generated.js.map +1 -1
  55. package/dist/uns/uns-event-emitter.js.map +1 -1
  56. package/dist/uns/uns-interfaces.d.ts +365 -365
  57. package/dist/uns/uns-interfaces.js.map +1 -1
  58. package/dist/uns/uns-measurements.generated.d.ts +362 -362
  59. package/dist/uns/uns-measurements.generated.js +359 -359
  60. package/dist/uns/uns-measurements.generated.js.map +1 -1
  61. package/dist/uns/uns-measurements.js.map +1 -1
  62. package/dist/uns/uns-object.d.ts +20 -20
  63. package/dist/uns/uns-object.js +9 -9
  64. package/dist/uns/uns-object.js.map +1 -1
  65. package/dist/uns/uns-packet.js +263 -263
  66. package/dist/uns/uns-packet.js.map +1 -1
  67. package/dist/uns/uns-path.d.ts +2 -2
  68. package/dist/uns/uns-path.js +10 -10
  69. package/dist/uns/uns-path.js.map +1 -1
  70. package/dist/uns/uns-proxy-process.d.ts +11 -0
  71. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  72. package/dist/uns/uns-proxy-process.js +224 -203
  73. package/dist/uns/uns-proxy-process.js.map +1 -1
  74. package/dist/uns/uns-proxy.d.ts +51 -51
  75. package/dist/uns/uns-proxy.js +190 -190
  76. package/dist/uns/uns-proxy.js.map +1 -1
  77. package/dist/uns/uns-tags.js.map +1 -1
  78. package/dist/uns/uns-topic-matcher.js.map +1 -1
  79. package/dist/uns/uns-topics.js.map +1 -1
  80. package/dist/uns-config/config-schema.js.map +1 -1
  81. package/dist/uns-config/host-placeholders.js.map +1 -1
  82. package/dist/uns-config/schema-tolls.js.map +1 -1
  83. package/dist/uns-config/schema-tools.js.map +1 -1
  84. package/dist/uns-config/secret-placeholders.js.map +1 -1
  85. package/dist/uns-config/secret-resolver.js.map +1 -1
  86. package/dist/uns-config/uns-core-schema.d.ts +3276 -3276
  87. package/dist/uns-config/uns-core-schema.js.map +1 -1
  88. package/dist/uns-grpc/uns-gateway-cli.js.map +1 -1
  89. package/dist/uns-grpc/uns-gateway-server.js.map +1 -1
  90. package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
  91. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  92. package/dist/uns-mqtt/mqtt-topic-builder.d.ts +6 -0
  93. package/dist/uns-mqtt/mqtt-topic-builder.d.ts.map +1 -1
  94. package/dist/uns-mqtt/mqtt-topic-builder.js +8 -0
  95. package/dist/uns-mqtt/mqtt-topic-builder.js.map +1 -1
  96. package/dist/uns-mqtt/mqtt-worker-init.js.map +1 -1
  97. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  98. package/dist/uns-mqtt/throttled-queue.js.map +1 -1
  99. package/dist/uns-mqtt/uns-mqtt-proxy.js +477 -477
  100. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  101. package/dist/uns-mqtt/ws-proxy.js.map +1 -1
  102. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
- const normalizeSegment = (value) => value.trim().replace(/^\/+|\/+$/g, "");
2
- export function buildUnsIdentityPath(...segments) {
3
- return segments
4
- .map((segment) => normalizeSegment(String(segment ?? "")))
5
- .filter((segment) => segment.length > 0)
6
- .join("/");
7
- }
8
- export function buildUnsRoutePath(...segments) {
9
- return `/${buildUnsIdentityPath(...segments)}`.replace(/\/{2,}/g, "/");
10
- }
1
+ const normalizeSegment = (value) => value.trim().replace(/^\/+|\/+$/g, "");
2
+ export function buildUnsIdentityPath(...segments) {
3
+ return segments
4
+ .map((segment) => normalizeSegment(String(segment ?? "")))
5
+ .filter((segment) => segment.length > 0)
6
+ .join("/");
7
+ }
8
+ export function buildUnsRoutePath(...segments) {
9
+ return `/${buildUnsIdentityPath(...segments)}`.replace(/\/{2,}/g, "/");
10
+ }
11
11
  //# sourceMappingURL=uns-path.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uns-path.js","sourceRoot":"","sources":["../../src/uns/uns-path.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAE3F,MAAM,UAAU,oBAAoB,CAAC,GAAG,QAAkB;IACxD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;SACzD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACvC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAG,QAAkB;IACrD,OAAO,IAAI,oBAAoB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACzE,CAAC","sourcesContent":["const normalizeSegment = (value: string): string => value.trim().replace(/^\\/+|\\/+$/g, \"\");\n\nexport function buildUnsIdentityPath(...segments: string[]): string {\n return segments\n .map((segment) => normalizeSegment(String(segment ?? \"\")))\n .filter((segment) => segment.length > 0)\n .join(\"/\");\n}\n\nexport function buildUnsRoutePath(...segments: string[]): string {\n return `/${buildUnsIdentityPath(...segments)}`.replace(/\\/{2,}/g, \"/\");\n}\n"]}
1
+ {"version":3,"file":"uns-path.js","sourceRoot":"","sources":["../../src/uns/uns-path.ts"],"names":[],"mappings":"AAAA,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;AAE3F,MAAM,UAAU,oBAAoB,CAAC,GAAG,QAAkB;IACxD,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,gBAAgB,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC;SACzD,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;SACvC,IAAI,CAAC,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAG,QAAkB;IACrD,OAAO,IAAI,oBAAoB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AACzE,CAAC","sourcesContent":["const normalizeSegment = (value: string): string => value.trim().replace(/^\\/+|\\/+$/g, \"\");\r\n\r\nexport function buildUnsIdentityPath(...segments: string[]): string {\r\n return segments\r\n .map((segment) => normalizeSegment(String(segment ?? \"\")))\r\n .filter((segment) => segment.length > 0)\r\n .join(\"/\");\r\n}\r\n\r\nexport function buildUnsRoutePath(...segments: string[]): string {\r\n return `/${buildUnsIdentityPath(...segments)}`.replace(/\\/{2,}/g, \"/\");\r\n}\r\n"]}
@@ -1,5 +1,6 @@
1
1
  import { IUnsParameters, IUnsProcessParameters } from "./uns-interfaces.js";
2
2
  import UnsMqttProxy from "../uns-mqtt/uns-mqtt-proxy.js";
3
+ import { type UnsServiceMetadata, type UnsServiceMetadataInput } from "./service-metadata.js";
3
4
  /**
4
5
  * UnsProxyProcess is responsible for managing the process lifecycle,
5
6
  * configuring MQTT (subscriptions and publishing for status updates), and
@@ -26,6 +27,7 @@ declare class UnsProxyProcess {
26
27
  private processMqttProxy;
27
28
  private handoverManager;
28
29
  private statusMonitor;
30
+ private serviceMetadataTopic;
29
31
  static pluginApiVersion: number;
30
32
  private static registered;
31
33
  private static registeredMethodNames;
@@ -45,6 +47,14 @@ declare class UnsProxyProcess {
45
47
  */
46
48
  createUnsMqttProxy(mqttHost: string, instanceName: string, instanceMode: string, handover: boolean, unsParameters?: IUnsParameters): Promise<UnsMqttProxy>;
47
49
  waitForProcessConnection(): Promise<void>;
50
+ /**
51
+ * Publishes retained product/system service metadata for controller discovery.
52
+ *
53
+ * The payload is intentionally separate from the volatile active/alive status
54
+ * topics. Controllers can combine this retained identity/capability metadata
55
+ * with live process status to decide whether a service is currently healthy.
56
+ */
57
+ publishServiceMetadata(metadata: UnsServiceMetadataInput): Promise<UnsServiceMetadata>;
48
58
  /**
49
59
  * Shuts down the process by clearing intervals, timeouts, and removing
50
60
  * MQTT event listeners, and stopping the StatusMonitor.
@@ -54,5 +64,6 @@ declare class UnsProxyProcess {
54
64
  interface UnsProxyProcess {
55
65
  }
56
66
  export default UnsProxyProcess;
67
+ export type { UnsServiceMetadata, UnsServiceMetadataInput };
57
68
  export { UnsProxyProcess };
58
69
  //# sourceMappingURL=uns-proxy-process.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uns-proxy-process.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,cAAc,EAAE,qBAAqB,EAAa,MAAM,qBAAqB,CAAC;AAGpG,OAAO,YAAY,MAAM,+BAA+B,CAAC;AAUzD;;;;;;GAMG;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAEjG,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;AAEvF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACpD,eAAe,EAAE,OAAO,eAAe,CAAC;CACzC;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;AAE5E,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IAGrC,MAAM,CAAC,gBAAgB,SAAK;IAC5B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAoC;IAC7D,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAqB;IACzD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAS;IAE/B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB;IAOxC,OAAO,CAAC,MAAM,CAAC,WAAW;IA0B1B,OAAO,CAAC,MAAM,CAAC,QAAQ;IAOvB,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,QAAQ,EAAE,MAAM,EAAE,yBAAyB,EAAE,qBAAqB;IAsE9E;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACU,kBAAkB,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAuC7C,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtD;;;OAGG;IACI,QAAQ,IAAI,IAAI;CAuBxB;AAED,UAAU,eAAe;CAAG;AAE5B,eAAe,eAAe,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,CAAC"}
1
+ {"version":3,"file":"uns-proxy-process.d.ts","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"AAEA,OAAO,EAAe,cAAc,EAAE,qBAAqB,EAAa,MAAM,qBAAqB,CAAC;AAGpG,OAAO,YAAY,MAAM,+BAA+B,CAAC;AAQzD,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC7B,MAAM,uBAAuB,CAAC;AAG/B;;;;;;GAMG;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC;AAEjG,MAAM,MAAM,4BAA4B,GAAG,MAAM,CAAC,MAAM,EAAE,2BAA2B,CAAC,CAAC;AAEvF,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,OAAO,EAAE,4BAA4B,GAAG,IAAI,CAAC;IACpD,eAAe,EAAE,OAAO,eAAe,CAAC;CACzC;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,wBAAwB,KAAK,IAAI,CAAC;AAE5E,cAAM,eAAe;IACnB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAgB;IACrC,OAAO,CAAC,oBAAoB,CAAS;IAGrC,MAAM,CAAC,gBAAgB,SAAK;IAC5B,OAAO,CAAC,MAAM,CAAC,UAAU,CAAoC;IAC7D,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAAqB;IACzD,OAAO,CAAC,MAAM,CAAC,OAAO,CAAS;IAE/B,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,qBAAqB;IAOxC,OAAO,CAAC,MAAM,CAAC,WAAW;IA0B1B,OAAO,CAAC,MAAM,CAAC,QAAQ;IAOvB,OAAO,CAAC,gBAAgB,CAAuB;gBAEnC,QAAQ,EAAE,MAAM,EAAE,yBAAyB,EAAE,qBAAqB;IAwE9E;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IA2B3B;;OAEG;IACU,kBAAkB,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IAuC7C,wBAAwB,IAAI,OAAO,CAAC,IAAI,CAAC;IAMtD;;;;;;OAMG;IACU,sBAAsB,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAenG;;;OAGG;IACI,QAAQ,IAAI,IAAI;CAuBxB;AAED,UAAU,eAAe;CAAG;AAE5B,eAAe,eAAe,CAAC;AAC/B,YAAY,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,CAAC"}
@@ -1,204 +1,225 @@
1
- import logger from "../logger.js";
2
- import { randomBytes } from "crypto";
3
- import MqttProxy from "../uns-mqtt/mqtt-proxy.js";
4
- import UnsMqttProxy from "../uns-mqtt/uns-mqtt-proxy.js";
5
- import { HandoverManager } from "./handover-manager.js";
6
- // Import configuration and initialization modules.
7
- import { PACKAGE_INFO, MQTT_UPDATE_INTERVAL } from "./process-config.js";
8
- import { MqttTopicBuilder } from "../uns-mqtt/mqtt-topic-builder.js";
9
- import { StatusMonitor } from "./status-monitor.js";
10
- import { UnsPacket } from "./uns-packet.js";
11
- class UnsProxyProcess {
12
- active = false;
13
- processStatusTopic;
14
- processName;
15
- processId;
16
- unsMqttProxies;
17
- unsApiProxies;
18
- unsTemporalProxies;
19
- processMqttProxy;
20
- handoverManager;
21
- statusMonitor;
22
- // Plugin
23
- static pluginApiVersion = 1;
24
- static registered = new Set();
25
- static registeredMethodNames = new Set();
26
- static applied = false;
27
- static use(plugin) {
28
- if (this.registered.has(plugin))
29
- return this;
30
- this.registered.add(plugin);
31
- if (this.applied)
32
- this.applyPlugin(plugin);
33
- return this;
34
- }
35
- static applyPlugin(plugin) {
36
- const define = (methods) => {
37
- for (const [name, fn] of Object.entries(methods)) {
38
- if (typeof fn !== "function") {
39
- throw new TypeError(`UnsProxyProcess plugin attempted to register non-function member \"${name}\".`);
40
- }
41
- if (this.registeredMethodNames.has(name) || Reflect.has(this.prototype, name)) {
42
- throw new Error(`UnsProxyProcess plugin attempted to overwrite existing member \"${name}\".`);
43
- }
44
- Object.defineProperty(this.prototype, name, {
45
- value: fn,
46
- writable: true,
47
- configurable: true,
48
- enumerable: false,
49
- });
50
- this.registeredMethodNames.add(name);
51
- }
52
- };
53
- plugin({
54
- define,
55
- version: this.pluginApiVersion,
56
- UnsProxyProcess: this,
57
- });
58
- }
59
- static applyAll() {
60
- if (this.applied)
61
- return;
62
- this.applied = true;
63
- for (const p of this.registered)
64
- this.applyPlugin(p);
65
- }
66
- // References for cleanup.
67
- mqttInputHandler;
68
- constructor(mqttHost, unsProxyProcessParameters) {
69
- this.constructor.applyAll(); // Activate all the plugins
70
- this.unsMqttProxies = [];
71
- this.unsApiProxies = [];
72
- this.unsTemporalProxies = [];
73
- if (!unsProxyProcessParameters?.processName) {
74
- throw new Error("UnsProxyProcess requires a processName in configuration.");
75
- }
76
- this.processName = unsProxyProcessParameters.processName;
77
- this.processId = randomBytes(16).toString("hex");
78
- const { name: packageName, version } = PACKAGE_INFO;
79
- // Instantiate the topic builder.
80
- const topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageName)}/${MqttTopicBuilder.sanitizeTopicPart(version)}/${MqttTopicBuilder.sanitizeTopicPart(this.processName)}/`);
81
- // Generate topics.
82
- const processStatusTopic = topicBuilder.getProcessStatusTopic();
83
- const handoverTopic = topicBuilder.getHandoverTopic();
84
- const wildcardActiveTopic = topicBuilder.getWildcardActiveTopic();
85
- this.processStatusTopic = processStatusTopic;
86
- // Configure MQTT topics for subscription.
87
- const mqttSubToTopics = unsProxyProcessParameters?.mqttSubToTopics ?? [
88
- wildcardActiveTopic,
89
- handoverTopic,
90
- ];
91
- const mqttParameters = {
92
- mqttSubToTopics,
93
- username: unsProxyProcessParameters?.username ?? "",
94
- password: unsProxyProcessParameters?.password ?? "",
95
- mqttSSL: unsProxyProcessParameters?.mqttSSL ?? false,
96
- statusTopic: this.processStatusTopic,
97
- clientId: unsProxyProcessParameters?.clientId ?? `${this.processName}-${this.processId}`,
98
- hosts: unsProxyProcessParameters?.hosts,
99
- servers: unsProxyProcessParameters?.servers,
100
- port: unsProxyProcessParameters?.port,
101
- protocol: unsProxyProcessParameters?.protocol,
102
- keepalive: unsProxyProcessParameters?.keepalive,
103
- clean: unsProxyProcessParameters?.clean,
104
- connectTimeout: unsProxyProcessParameters?.connectTimeout,
105
- reconnectPeriod: unsProxyProcessParameters?.reconnectPeriod,
106
- reconnectOnConnackError: unsProxyProcessParameters?.reconnectOnConnackError,
107
- resubscribe: unsProxyProcessParameters?.resubscribe,
108
- queueQoSZero: unsProxyProcessParameters?.queueQoSZero,
109
- rejectUnauthorized: unsProxyProcessParameters?.rejectUnauthorized ?? false,
110
- properties: unsProxyProcessParameters?.properties,
111
- ca: unsProxyProcessParameters?.ca,
112
- cert: unsProxyProcessParameters?.cert,
113
- key: unsProxyProcessParameters?.key,
114
- servername: unsProxyProcessParameters?.servername,
115
- };
116
- // Initialize MQTT proxy and start connection.
117
- this.processMqttProxy = new MqttProxy(mqttHost, this.processName, mqttParameters);
118
- this.processMqttProxy.start();
119
- // Instantiate and start the StatusMonitor for memory and status updates.
120
- this.statusMonitor = new StatusMonitor(this.processMqttProxy, this.processStatusTopic, () => this.active, MQTT_UPDATE_INTERVAL, MQTT_UPDATE_INTERVAL, { processName: this.processName, processId: this.processId });
121
- this.statusMonitor.start();
122
- }
123
- /**
124
- * Initializes the HandoverManager instance and sets up event listeners for handover and MQTT input events.
125
- * Determines handover and force start modes based on process arguments.
126
- */
127
- initHandoverManager(instanceMode, handover) {
128
- const handoverRequestEnabled = instanceMode == "handover" ? true : false;
129
- const forceStartEnabled = instanceMode == "force" ? true : false;
130
- this.handoverManager = new HandoverManager(this.processName, this.processId, this.processMqttProxy, this.unsMqttProxies, handoverRequestEnabled, handover ?? true, forceStartEnabled);
131
- // Listen for handover events.
132
- this.handoverManager.event.on("handoverManager", (event) => {
133
- this.active = event.active;
134
- });
135
- // Delegate MQTT events to the HandoverManager.
136
- this.mqttInputHandler = async (event) => {
137
- await this.handoverManager.handleMqttMessage(event);
138
- };
139
- this.processMqttProxy.event.on("input", this.mqttInputHandler);
140
- }
141
- /**
142
- * Creates a new UNS proxy instance and stores it for future management.
143
- */
144
- async createUnsMqttProxy(mqttHost, instanceName, instanceMode, handover, unsParameters) {
145
- // Wait until the MQTT connection is established before proceeding.
146
- await this.waitForProcessConnection();
147
- // Currently handover manager can handle only mqtt events
148
- if (!this.handoverManager) {
149
- this.initHandoverManager(instanceMode, handover);
150
- }
151
- const resolvedUnsParameters = {
152
- ...(unsParameters ?? {}),
153
- clientId: unsParameters?.clientId ?? `${this.processName}-${instanceName}-${this.processId}`,
154
- };
155
- const unsMqttProxy = new UnsMqttProxy(mqttHost, this.processName, instanceName, resolvedUnsParameters);
156
- // Listen for UNS proxy producing topics and publish them via MQTT.
157
- unsMqttProxy.event.on("unsProxyProducedTopics", (event) => {
158
- this.processMqttProxy.publish(event.statusTopic, JSON.stringify(event.producedTopics));
159
- });
160
- // Listen for UNS proxy status events and publish them via MQTT.
161
- unsMqttProxy.event.on("mqttProxyStatus", (event) => {
162
- const time = UnsPacket.formatToISO8601(new Date());
163
- const unsMessage = { data: { time, value: event.value, uom: event.uom } };
164
- UnsPacket.unsPacketFromUnsMessage(unsMessage).then((packet) => {
165
- this.processMqttProxy.publish(event.statusTopic, JSON.stringify(packet));
166
- });
167
- });
168
- this.unsMqttProxies.push(unsMqttProxy);
169
- return unsMqttProxy;
170
- }
171
- async waitForProcessConnection() {
172
- while (!this.processMqttProxy?.isConnected) {
173
- await new Promise((resolve) => setTimeout(resolve, 100));
174
- }
175
- }
176
- /**
177
- * Shuts down the process by clearing intervals, timeouts, and removing
178
- * MQTT event listeners, and stopping the StatusMonitor.
179
- */
180
- shutdown() {
181
- logger.info(`${this.processName} - Shutting down UnsProxyProcess...`);
182
- try {
183
- this.statusMonitor.stop();
184
- }
185
- catch (e) {
186
- logger.error(`${this.processName} - Error stopping StatusMonitor: ${e.message}`);
187
- }
188
- if (this.mqttInputHandler) {
189
- this.processMqttProxy.event.off("input", this.mqttInputHandler);
190
- }
191
- try {
192
- if (typeof this.processMqttProxy.stop === "function") {
193
- this.processMqttProxy.stop();
194
- }
195
- }
196
- catch (e) {
197
- logger.error(`${this.processName} - Error stopping MQTT proxy: ${e.message}`);
198
- }
199
- logger.info(`${this.processName} - Shutdown complete.`);
200
- }
201
- }
202
- export default UnsProxyProcess;
203
- export { UnsProxyProcess };
1
+ import logger from "../logger.js";
2
+ import { randomBytes } from "crypto";
3
+ import MqttProxy from "../uns-mqtt/mqtt-proxy.js";
4
+ import UnsMqttProxy from "../uns-mqtt/uns-mqtt-proxy.js";
5
+ import { HandoverManager } from "./handover-manager.js";
6
+ // Import configuration and initialization modules.
7
+ import { PACKAGE_INFO, MQTT_UPDATE_INTERVAL } from "./process-config.js";
8
+ import { MqttTopicBuilder } from "../uns-mqtt/mqtt-topic-builder.js";
9
+ import { StatusMonitor } from "./status-monitor.js";
10
+ import { UnsPacket } from "./uns-packet.js";
11
+ import { buildUnsServiceMetadata, } from "./service-metadata.js";
12
+ class UnsProxyProcess {
13
+ active = false;
14
+ processStatusTopic;
15
+ processName;
16
+ processId;
17
+ unsMqttProxies;
18
+ unsApiProxies;
19
+ unsTemporalProxies;
20
+ processMqttProxy;
21
+ handoverManager;
22
+ statusMonitor;
23
+ serviceMetadataTopic;
24
+ // Plugin
25
+ static pluginApiVersion = 1;
26
+ static registered = new Set();
27
+ static registeredMethodNames = new Set();
28
+ static applied = false;
29
+ static use(plugin) {
30
+ if (this.registered.has(plugin))
31
+ return this;
32
+ this.registered.add(plugin);
33
+ if (this.applied)
34
+ this.applyPlugin(plugin);
35
+ return this;
36
+ }
37
+ static applyPlugin(plugin) {
38
+ const define = (methods) => {
39
+ for (const [name, fn] of Object.entries(methods)) {
40
+ if (typeof fn !== "function") {
41
+ throw new TypeError(`UnsProxyProcess plugin attempted to register non-function member \"${name}\".`);
42
+ }
43
+ if (this.registeredMethodNames.has(name) || Reflect.has(this.prototype, name)) {
44
+ throw new Error(`UnsProxyProcess plugin attempted to overwrite existing member \"${name}\".`);
45
+ }
46
+ Object.defineProperty(this.prototype, name, {
47
+ value: fn,
48
+ writable: true,
49
+ configurable: true,
50
+ enumerable: false,
51
+ });
52
+ this.registeredMethodNames.add(name);
53
+ }
54
+ };
55
+ plugin({
56
+ define,
57
+ version: this.pluginApiVersion,
58
+ UnsProxyProcess: this,
59
+ });
60
+ }
61
+ static applyAll() {
62
+ if (this.applied)
63
+ return;
64
+ this.applied = true;
65
+ for (const p of this.registered)
66
+ this.applyPlugin(p);
67
+ }
68
+ // References for cleanup.
69
+ mqttInputHandler;
70
+ constructor(mqttHost, unsProxyProcessParameters) {
71
+ this.constructor.applyAll(); // Activate all the plugins
72
+ this.unsMqttProxies = [];
73
+ this.unsApiProxies = [];
74
+ this.unsTemporalProxies = [];
75
+ if (!unsProxyProcessParameters?.processName) {
76
+ throw new Error("UnsProxyProcess requires a processName in configuration.");
77
+ }
78
+ this.processName = unsProxyProcessParameters.processName;
79
+ this.processId = randomBytes(16).toString("hex");
80
+ const { name: packageName, version } = PACKAGE_INFO;
81
+ // Instantiate the topic builder.
82
+ const topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageName)}/${MqttTopicBuilder.sanitizeTopicPart(version)}/${MqttTopicBuilder.sanitizeTopicPart(this.processName)}/`);
83
+ // Generate topics.
84
+ const processStatusTopic = topicBuilder.getProcessStatusTopic();
85
+ const handoverTopic = topicBuilder.getHandoverTopic();
86
+ const wildcardActiveTopic = topicBuilder.getWildcardActiveTopic();
87
+ const serviceMetadataTopic = topicBuilder.getServiceMetadataTopic();
88
+ this.processStatusTopic = processStatusTopic;
89
+ this.serviceMetadataTopic = serviceMetadataTopic;
90
+ // Configure MQTT topics for subscription.
91
+ const mqttSubToTopics = unsProxyProcessParameters?.mqttSubToTopics ?? [
92
+ wildcardActiveTopic,
93
+ handoverTopic,
94
+ ];
95
+ const mqttParameters = {
96
+ mqttSubToTopics,
97
+ username: unsProxyProcessParameters?.username ?? "",
98
+ password: unsProxyProcessParameters?.password ?? "",
99
+ mqttSSL: unsProxyProcessParameters?.mqttSSL ?? false,
100
+ statusTopic: this.processStatusTopic,
101
+ clientId: unsProxyProcessParameters?.clientId ?? `${this.processName}-${this.processId}`,
102
+ hosts: unsProxyProcessParameters?.hosts,
103
+ servers: unsProxyProcessParameters?.servers,
104
+ port: unsProxyProcessParameters?.port,
105
+ protocol: unsProxyProcessParameters?.protocol,
106
+ keepalive: unsProxyProcessParameters?.keepalive,
107
+ clean: unsProxyProcessParameters?.clean,
108
+ connectTimeout: unsProxyProcessParameters?.connectTimeout,
109
+ reconnectPeriod: unsProxyProcessParameters?.reconnectPeriod,
110
+ reconnectOnConnackError: unsProxyProcessParameters?.reconnectOnConnackError,
111
+ resubscribe: unsProxyProcessParameters?.resubscribe,
112
+ queueQoSZero: unsProxyProcessParameters?.queueQoSZero,
113
+ rejectUnauthorized: unsProxyProcessParameters?.rejectUnauthorized ?? false,
114
+ properties: unsProxyProcessParameters?.properties,
115
+ ca: unsProxyProcessParameters?.ca,
116
+ cert: unsProxyProcessParameters?.cert,
117
+ key: unsProxyProcessParameters?.key,
118
+ servername: unsProxyProcessParameters?.servername,
119
+ };
120
+ // Initialize MQTT proxy and start connection.
121
+ this.processMqttProxy = new MqttProxy(mqttHost, this.processName, mqttParameters);
122
+ this.processMqttProxy.start();
123
+ // Instantiate and start the StatusMonitor for memory and status updates.
124
+ this.statusMonitor = new StatusMonitor(this.processMqttProxy, this.processStatusTopic, () => this.active, MQTT_UPDATE_INTERVAL, MQTT_UPDATE_INTERVAL, { processName: this.processName, processId: this.processId });
125
+ this.statusMonitor.start();
126
+ }
127
+ /**
128
+ * Initializes the HandoverManager instance and sets up event listeners for handover and MQTT input events.
129
+ * Determines handover and force start modes based on process arguments.
130
+ */
131
+ initHandoverManager(instanceMode, handover) {
132
+ const handoverRequestEnabled = instanceMode == "handover" ? true : false;
133
+ const forceStartEnabled = instanceMode == "force" ? true : false;
134
+ this.handoverManager = new HandoverManager(this.processName, this.processId, this.processMqttProxy, this.unsMqttProxies, handoverRequestEnabled, handover ?? true, forceStartEnabled);
135
+ // Listen for handover events.
136
+ this.handoverManager.event.on("handoverManager", (event) => {
137
+ this.active = event.active;
138
+ });
139
+ // Delegate MQTT events to the HandoverManager.
140
+ this.mqttInputHandler = async (event) => {
141
+ await this.handoverManager.handleMqttMessage(event);
142
+ };
143
+ this.processMqttProxy.event.on("input", this.mqttInputHandler);
144
+ }
145
+ /**
146
+ * Creates a new UNS proxy instance and stores it for future management.
147
+ */
148
+ async createUnsMqttProxy(mqttHost, instanceName, instanceMode, handover, unsParameters) {
149
+ // Wait until the MQTT connection is established before proceeding.
150
+ await this.waitForProcessConnection();
151
+ // Currently handover manager can handle only mqtt events
152
+ if (!this.handoverManager) {
153
+ this.initHandoverManager(instanceMode, handover);
154
+ }
155
+ const resolvedUnsParameters = {
156
+ ...(unsParameters ?? {}),
157
+ clientId: unsParameters?.clientId ?? `${this.processName}-${instanceName}-${this.processId}`,
158
+ };
159
+ const unsMqttProxy = new UnsMqttProxy(mqttHost, this.processName, instanceName, resolvedUnsParameters);
160
+ // Listen for UNS proxy producing topics and publish them via MQTT.
161
+ unsMqttProxy.event.on("unsProxyProducedTopics", (event) => {
162
+ this.processMqttProxy.publish(event.statusTopic, JSON.stringify(event.producedTopics));
163
+ });
164
+ // Listen for UNS proxy status events and publish them via MQTT.
165
+ unsMqttProxy.event.on("mqttProxyStatus", (event) => {
166
+ const time = UnsPacket.formatToISO8601(new Date());
167
+ const unsMessage = { data: { time, value: event.value, uom: event.uom } };
168
+ UnsPacket.unsPacketFromUnsMessage(unsMessage).then((packet) => {
169
+ this.processMqttProxy.publish(event.statusTopic, JSON.stringify(packet));
170
+ });
171
+ });
172
+ this.unsMqttProxies.push(unsMqttProxy);
173
+ return unsMqttProxy;
174
+ }
175
+ async waitForProcessConnection() {
176
+ while (!this.processMqttProxy?.isConnected) {
177
+ await new Promise((resolve) => setTimeout(resolve, 100));
178
+ }
179
+ }
180
+ /**
181
+ * Publishes retained product/system service metadata for controller discovery.
182
+ *
183
+ * The payload is intentionally separate from the volatile active/alive status
184
+ * topics. Controllers can combine this retained identity/capability metadata
185
+ * with live process status to decide whether a service is currently healthy.
186
+ */
187
+ async publishServiceMetadata(metadata) {
188
+ await this.waitForProcessConnection();
189
+ const resolved = buildUnsServiceMetadata({
190
+ processName: this.processName,
191
+ processId: this.processId,
192
+ metadata,
193
+ });
194
+ await this.processMqttProxy.publish(this.serviceMetadataTopic, JSON.stringify(resolved), { retain: true });
195
+ return resolved;
196
+ }
197
+ /**
198
+ * Shuts down the process by clearing intervals, timeouts, and removing
199
+ * MQTT event listeners, and stopping the StatusMonitor.
200
+ */
201
+ shutdown() {
202
+ logger.info(`${this.processName} - Shutting down UnsProxyProcess...`);
203
+ try {
204
+ this.statusMonitor.stop();
205
+ }
206
+ catch (e) {
207
+ logger.error(`${this.processName} - Error stopping StatusMonitor: ${e.message}`);
208
+ }
209
+ if (this.mqttInputHandler) {
210
+ this.processMqttProxy.event.off("input", this.mqttInputHandler);
211
+ }
212
+ try {
213
+ if (typeof this.processMqttProxy.stop === "function") {
214
+ this.processMqttProxy.stop();
215
+ }
216
+ }
217
+ catch (e) {
218
+ logger.error(`${this.processName} - Error stopping MQTT proxy: ${e.message}`);
219
+ }
220
+ logger.info(`${this.processName} - Shutdown complete.`);
221
+ }
222
+ }
223
+ export default UnsProxyProcess;
224
+ export { UnsProxyProcess };
204
225
  //# sourceMappingURL=uns-proxy-process.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"uns-proxy-process.js","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"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","sourcesContent":["import logger from \"../logger.js\";\nimport { randomBytes } from \"crypto\";\nimport { IUnsMessage, IUnsParameters, IUnsProcessParameters, UnsEvents } from \"./uns-interfaces.js\";\nimport { IMqttParameters } from \"../uns-mqtt/mqtt-interfaces.js\";\nimport MqttProxy from \"../uns-mqtt/mqtt-proxy.js\";\nimport UnsMqttProxy from \"../uns-mqtt/uns-mqtt-proxy.js\";\nimport { HandoverManager } from \"./handover-manager.js\";\n\n// Import configuration and initialization modules.\nimport { PACKAGE_INFO, MQTT_UPDATE_INTERVAL } from \"./process-config.js\";\nimport { MqttTopicBuilder } from \"../uns-mqtt/mqtt-topic-builder.js\";\nimport { StatusMonitor } from \"./status-monitor.js\";\nimport { UnsPacket } from \"./uns-packet.js\";\n\n\n/**\n * UnsProxyProcess is responsible for managing the process lifecycle,\n * configuring MQTT (subscriptions and publishing for status updates), and\n * handling UNS proxy instances.\n *\n * It leverages HandoverManager for handover events and StatusMonitor for health reporting.\n */\nexport type UnsProxyProcessPluginMethod = (this: UnsProxyProcess, ...args: unknown[]) => unknown;\n\nexport type UnsProxyProcessPluginMethods = Record<string, UnsProxyProcessPluginMethod>;\n\nexport interface UnsProxyProcessPluginApi {\n version: number;\n define(methods: UnsProxyProcessPluginMethods): void;\n UnsProxyProcess: typeof UnsProxyProcess;\n}\n\nexport type UnsProxyProcessPlugin = (api: UnsProxyProcessPluginApi) => void;\n\nclass UnsProxyProcess {\n private active: boolean = false;\n private processStatusTopic: string;\n private processName: string;\n private processId: string;\n private unsMqttProxies: UnsMqttProxy[];\n private unsApiProxies: unknown[];\n private unsTemporalProxies: unknown[];\n private processMqttProxy: MqttProxy;\n private handoverManager: HandoverManager;\n private statusMonitor: StatusMonitor;\n\n // Plugin\n static pluginApiVersion = 1;\n private static registered = new Set<UnsProxyProcessPlugin>();\n private static registeredMethodNames = new Set<string>();\n private static applied = false;\n\n static use(plugin: UnsProxyProcessPlugin) {\n if (this.registered.has(plugin)) return this;\n this.registered.add(plugin);\n if (this.applied) this.applyPlugin(plugin);\n return this;\n }\n\n private static applyPlugin(plugin: UnsProxyProcessPlugin) {\n const define: UnsProxyProcessPluginApi[\"define\"] = (methods) => {\n for (const [name, fn] of Object.entries(methods)) {\n if (typeof fn !== \"function\") {\n throw new TypeError(`UnsProxyProcess plugin attempted to register non-function member \\\"${name}\\\".`);\n }\n if (this.registeredMethodNames.has(name) || Reflect.has(this.prototype, name)) {\n throw new Error(`UnsProxyProcess plugin attempted to overwrite existing member \\\"${name}\\\".`);\n }\n Object.defineProperty(this.prototype, name, {\n value: fn,\n writable: true,\n configurable: true,\n enumerable: false,\n });\n this.registeredMethodNames.add(name);\n }\n };\n\n plugin({\n define,\n version: this.pluginApiVersion,\n UnsProxyProcess: this,\n });\n }\n\n private static applyAll() {\n if (this.applied) return;\n this.applied = true;\n for (const p of this.registered) this.applyPlugin(p);\n }\n\n // References for cleanup.\n private mqttInputHandler: (event: any) => void;\n\n constructor(mqttHost: string, unsProxyProcessParameters: IUnsProcessParameters) {\n (this.constructor as typeof UnsProxyProcess).applyAll(); // Activate all the plugins\n\n this.unsMqttProxies = [];\n this.unsApiProxies = [];\n this.unsTemporalProxies = [];\n if (!unsProxyProcessParameters?.processName) {\n throw new Error(\"UnsProxyProcess requires a processName in configuration.\");\n }\n this.processName = unsProxyProcessParameters.processName;\n this.processId = randomBytes(16).toString(\"hex\");\n const { name: packageName, version } = PACKAGE_INFO;\n\n // Instantiate the topic builder.\n const topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageName)}/${MqttTopicBuilder.sanitizeTopicPart(version)}/${MqttTopicBuilder.sanitizeTopicPart(this.processName)}/`);\n\n // Generate topics.\n const processStatusTopic = topicBuilder.getProcessStatusTopic();\n const handoverTopic = topicBuilder.getHandoverTopic();\n const wildcardActiveTopic = topicBuilder.getWildcardActiveTopic();\n\n this.processStatusTopic = processStatusTopic;\n\n // Configure MQTT topics for subscription.\n const mqttSubToTopics = unsProxyProcessParameters?.mqttSubToTopics ?? [\n wildcardActiveTopic,\n handoverTopic,\n ];\n const mqttParameters: IMqttParameters = {\n mqttSubToTopics,\n username: unsProxyProcessParameters?.username ?? \"\",\n password: unsProxyProcessParameters?.password ?? \"\",\n mqttSSL: unsProxyProcessParameters?.mqttSSL ?? false,\n statusTopic: this.processStatusTopic,\n clientId: unsProxyProcessParameters?.clientId ?? `${this.processName}-${this.processId}`,\n hosts: unsProxyProcessParameters?.hosts,\n servers: unsProxyProcessParameters?.servers,\n port: unsProxyProcessParameters?.port,\n protocol: unsProxyProcessParameters?.protocol,\n keepalive: unsProxyProcessParameters?.keepalive,\n clean: unsProxyProcessParameters?.clean,\n connectTimeout: unsProxyProcessParameters?.connectTimeout,\n reconnectPeriod: unsProxyProcessParameters?.reconnectPeriod,\n reconnectOnConnackError: unsProxyProcessParameters?.reconnectOnConnackError,\n resubscribe: unsProxyProcessParameters?.resubscribe,\n queueQoSZero: unsProxyProcessParameters?.queueQoSZero,\n rejectUnauthorized: unsProxyProcessParameters?.rejectUnauthorized ?? false,\n properties: unsProxyProcessParameters?.properties,\n ca: unsProxyProcessParameters?.ca,\n cert: unsProxyProcessParameters?.cert,\n key: unsProxyProcessParameters?.key,\n servername: unsProxyProcessParameters?.servername,\n };\n\n // Initialize MQTT proxy and start connection.\n this.processMqttProxy = new MqttProxy(mqttHost, this.processName, mqttParameters);\n this.processMqttProxy.start();\n\n // Instantiate and start the StatusMonitor for memory and status updates.\n this.statusMonitor = new StatusMonitor(\n this.processMqttProxy,\n this.processStatusTopic,\n () => this.active,\n MQTT_UPDATE_INTERVAL,\n MQTT_UPDATE_INTERVAL,\n { processName: this.processName, processId: this.processId },\n );\n this.statusMonitor.start();\n }\n\n /**\n * Initializes the HandoverManager instance and sets up event listeners for handover and MQTT input events.\n * Determines handover and force start modes based on process arguments.\n */\n private initHandoverManager(instanceMode: string, handover: boolean) {\n\n const handoverRequestEnabled = instanceMode == \"handover\" ? true : false;\n const forceStartEnabled = instanceMode == \"force\" ? true : false;\n\n this.handoverManager = new HandoverManager(\n this.processName,\n this.processId,\n this.processMqttProxy,\n this.unsMqttProxies,\n handoverRequestEnabled,\n handover ?? true,\n forceStartEnabled\n );\n\n // Listen for handover events.\n this.handoverManager.event.on(\"handoverManager\", (event) => {\n this.active = event.active;\n });\n\n // Delegate MQTT events to the HandoverManager.\n this.mqttInputHandler = async (event: UnsEvents[\"input\"]) => {\n await this.handoverManager.handleMqttMessage(event);\n };\n this.processMqttProxy.event.on(\"input\", this.mqttInputHandler);\n }\n\n /**\n * Creates a new UNS proxy instance and stores it for future management.\n */\n public async createUnsMqttProxy(\n mqttHost: string, \n instanceName: string,\n instanceMode: string,\n handover: boolean,\n unsParameters?: IUnsParameters): Promise<UnsMqttProxy> {\n // Wait until the MQTT connection is established before proceeding.\n await this.waitForProcessConnection();\n\n // Currently handover manager can handle only mqtt events\n if (!this.handoverManager) {\n this.initHandoverManager(instanceMode, handover);\n }\n\n const resolvedUnsParameters: IUnsParameters = {\n ...(unsParameters ?? {}),\n clientId: unsParameters?.clientId ?? `${this.processName}-${instanceName}-${this.processId}`,\n };\n const unsMqttProxy = new UnsMqttProxy(mqttHost, this.processName, instanceName, resolvedUnsParameters);\n \n // Listen for UNS proxy producing topics and publish them via MQTT.\n unsMqttProxy.event.on(\"unsProxyProducedTopics\", (event) => {\n this.processMqttProxy.publish(\n event.statusTopic,\n JSON.stringify(event.producedTopics),\n );\n });\n\n // Listen for UNS proxy status events and publish them via MQTT.\n unsMqttProxy.event.on(\"mqttProxyStatus\", (event) => {\n const time = UnsPacket.formatToISO8601(new Date());\n const unsMessage: IUnsMessage = { data: { time, value: event.value, uom: event.uom } };\n UnsPacket.unsPacketFromUnsMessage(unsMessage).then((packet) => {\n this.processMqttProxy.publish(\n event.statusTopic,\n JSON.stringify(packet),\n );\n });\n });\n\n this.unsMqttProxies.push(unsMqttProxy);\n return unsMqttProxy;\n }\n\n public async waitForProcessConnection(): Promise<void> {\n while (!this.processMqttProxy?.isConnected) {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n\n /**\n * Shuts down the process by clearing intervals, timeouts, and removing\n * MQTT event listeners, and stopping the StatusMonitor.\n */\n public shutdown(): void {\n logger.info(`${this.processName} - Shutting down UnsProxyProcess...`);\n try {\n this.statusMonitor.stop();\n } catch (e: any) {\n logger.error(`${this.processName} - Error stopping StatusMonitor: ${e.message}`);\n }\n \n if (this.mqttInputHandler) {\n this.processMqttProxy.event.off(\"input\", this.mqttInputHandler);\n }\n \n try {\n if (typeof this.processMqttProxy.stop === \"function\") {\n this.processMqttProxy.stop();\n }\n } catch (e: any) {\n logger.error(`${this.processName} - Error stopping MQTT proxy: ${e.message}`);\n }\n \n logger.info(`${this.processName} - Shutdown complete.`);\n }\n \n}\n\ninterface UnsProxyProcess {}\n\nexport default UnsProxyProcess;\nexport { UnsProxyProcess };\n"]}
1
+ {"version":3,"file":"uns-proxy-process.js","sourceRoot":"","sources":["../../src/uns/uns-proxy-process.ts"],"names":[],"mappings":"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","sourcesContent":["import logger from \"../logger.js\";\r\nimport { randomBytes } from \"crypto\";\r\nimport { IUnsMessage, IUnsParameters, IUnsProcessParameters, UnsEvents } from \"./uns-interfaces.js\";\r\nimport { IMqttParameters } from \"../uns-mqtt/mqtt-interfaces.js\";\r\nimport MqttProxy from \"../uns-mqtt/mqtt-proxy.js\";\r\nimport UnsMqttProxy from \"../uns-mqtt/uns-mqtt-proxy.js\";\r\nimport { HandoverManager } from \"./handover-manager.js\";\r\n\r\n// Import configuration and initialization modules.\r\nimport { PACKAGE_INFO, MQTT_UPDATE_INTERVAL } from \"./process-config.js\";\r\nimport { MqttTopicBuilder } from \"../uns-mqtt/mqtt-topic-builder.js\";\r\nimport { StatusMonitor } from \"./status-monitor.js\";\r\nimport { UnsPacket } from \"./uns-packet.js\";\r\nimport {\r\n buildUnsServiceMetadata,\r\n type UnsServiceMetadata,\r\n type UnsServiceMetadataInput,\r\n} from \"./service-metadata.js\";\r\n\r\n\r\n/**\r\n * UnsProxyProcess is responsible for managing the process lifecycle,\r\n * configuring MQTT (subscriptions and publishing for status updates), and\r\n * handling UNS proxy instances.\r\n *\r\n * It leverages HandoverManager for handover events and StatusMonitor for health reporting.\r\n */\r\nexport type UnsProxyProcessPluginMethod = (this: UnsProxyProcess, ...args: unknown[]) => unknown;\r\n\r\nexport type UnsProxyProcessPluginMethods = Record<string, UnsProxyProcessPluginMethod>;\r\n\r\nexport interface UnsProxyProcessPluginApi {\r\n version: number;\r\n define(methods: UnsProxyProcessPluginMethods): void;\r\n UnsProxyProcess: typeof UnsProxyProcess;\r\n}\r\n\r\nexport type UnsProxyProcessPlugin = (api: UnsProxyProcessPluginApi) => void;\r\n\r\nclass UnsProxyProcess {\r\n private active: boolean = false;\r\n private processStatusTopic: string;\r\n private processName: string;\r\n private processId: string;\r\n private unsMqttProxies: UnsMqttProxy[];\r\n private unsApiProxies: unknown[];\r\n private unsTemporalProxies: unknown[];\r\n private processMqttProxy: MqttProxy;\r\n private handoverManager: HandoverManager;\r\n private statusMonitor: StatusMonitor;\r\n private serviceMetadataTopic: string;\r\n\r\n // Plugin\r\n static pluginApiVersion = 1;\r\n private static registered = new Set<UnsProxyProcessPlugin>();\r\n private static registeredMethodNames = new Set<string>();\r\n private static applied = false;\r\n\r\n static use(plugin: UnsProxyProcessPlugin) {\r\n if (this.registered.has(plugin)) return this;\r\n this.registered.add(plugin);\r\n if (this.applied) this.applyPlugin(plugin);\r\n return this;\r\n }\r\n\r\n private static applyPlugin(plugin: UnsProxyProcessPlugin) {\r\n const define: UnsProxyProcessPluginApi[\"define\"] = (methods) => {\r\n for (const [name, fn] of Object.entries(methods)) {\r\n if (typeof fn !== \"function\") {\r\n throw new TypeError(`UnsProxyProcess plugin attempted to register non-function member \\\"${name}\\\".`);\r\n }\r\n if (this.registeredMethodNames.has(name) || Reflect.has(this.prototype, name)) {\r\n throw new Error(`UnsProxyProcess plugin attempted to overwrite existing member \\\"${name}\\\".`);\r\n }\r\n Object.defineProperty(this.prototype, name, {\r\n value: fn,\r\n writable: true,\r\n configurable: true,\r\n enumerable: false,\r\n });\r\n this.registeredMethodNames.add(name);\r\n }\r\n };\r\n\r\n plugin({\r\n define,\r\n version: this.pluginApiVersion,\r\n UnsProxyProcess: this,\r\n });\r\n }\r\n\r\n private static applyAll() {\r\n if (this.applied) return;\r\n this.applied = true;\r\n for (const p of this.registered) this.applyPlugin(p);\r\n }\r\n\r\n // References for cleanup.\r\n private mqttInputHandler: (event: any) => void;\r\n\r\n constructor(mqttHost: string, unsProxyProcessParameters: IUnsProcessParameters) {\r\n (this.constructor as typeof UnsProxyProcess).applyAll(); // Activate all the plugins\r\n\r\n this.unsMqttProxies = [];\r\n this.unsApiProxies = [];\r\n this.unsTemporalProxies = [];\r\n if (!unsProxyProcessParameters?.processName) {\r\n throw new Error(\"UnsProxyProcess requires a processName in configuration.\");\r\n }\r\n this.processName = unsProxyProcessParameters.processName;\r\n this.processId = randomBytes(16).toString(\"hex\");\r\n const { name: packageName, version } = PACKAGE_INFO;\r\n\r\n // Instantiate the topic builder.\r\n const topicBuilder = new MqttTopicBuilder(`uns-infra/${MqttTopicBuilder.sanitizeTopicPart(packageName)}/${MqttTopicBuilder.sanitizeTopicPart(version)}/${MqttTopicBuilder.sanitizeTopicPart(this.processName)}/`);\r\n\r\n // Generate topics.\r\n const processStatusTopic = topicBuilder.getProcessStatusTopic();\r\n const handoverTopic = topicBuilder.getHandoverTopic();\r\n const wildcardActiveTopic = topicBuilder.getWildcardActiveTopic();\r\n const serviceMetadataTopic = topicBuilder.getServiceMetadataTopic();\r\n\r\n this.processStatusTopic = processStatusTopic;\r\n this.serviceMetadataTopic = serviceMetadataTopic;\r\n\r\n // Configure MQTT topics for subscription.\r\n const mqttSubToTopics = unsProxyProcessParameters?.mqttSubToTopics ?? [\r\n wildcardActiveTopic,\r\n handoverTopic,\r\n ];\r\n const mqttParameters: IMqttParameters = {\r\n mqttSubToTopics,\r\n username: unsProxyProcessParameters?.username ?? \"\",\r\n password: unsProxyProcessParameters?.password ?? \"\",\r\n mqttSSL: unsProxyProcessParameters?.mqttSSL ?? false,\r\n statusTopic: this.processStatusTopic,\r\n clientId: unsProxyProcessParameters?.clientId ?? `${this.processName}-${this.processId}`,\r\n hosts: unsProxyProcessParameters?.hosts,\r\n servers: unsProxyProcessParameters?.servers,\r\n port: unsProxyProcessParameters?.port,\r\n protocol: unsProxyProcessParameters?.protocol,\r\n keepalive: unsProxyProcessParameters?.keepalive,\r\n clean: unsProxyProcessParameters?.clean,\r\n connectTimeout: unsProxyProcessParameters?.connectTimeout,\r\n reconnectPeriod: unsProxyProcessParameters?.reconnectPeriod,\r\n reconnectOnConnackError: unsProxyProcessParameters?.reconnectOnConnackError,\r\n resubscribe: unsProxyProcessParameters?.resubscribe,\r\n queueQoSZero: unsProxyProcessParameters?.queueQoSZero,\r\n rejectUnauthorized: unsProxyProcessParameters?.rejectUnauthorized ?? false,\r\n properties: unsProxyProcessParameters?.properties,\r\n ca: unsProxyProcessParameters?.ca,\r\n cert: unsProxyProcessParameters?.cert,\r\n key: unsProxyProcessParameters?.key,\r\n servername: unsProxyProcessParameters?.servername,\r\n };\r\n\r\n // Initialize MQTT proxy and start connection.\r\n this.processMqttProxy = new MqttProxy(mqttHost, this.processName, mqttParameters);\r\n this.processMqttProxy.start();\r\n\r\n // Instantiate and start the StatusMonitor for memory and status updates.\r\n this.statusMonitor = new StatusMonitor(\r\n this.processMqttProxy,\r\n this.processStatusTopic,\r\n () => this.active,\r\n MQTT_UPDATE_INTERVAL,\r\n MQTT_UPDATE_INTERVAL,\r\n { processName: this.processName, processId: this.processId },\r\n );\r\n this.statusMonitor.start();\r\n }\r\n\r\n /**\r\n * Initializes the HandoverManager instance and sets up event listeners for handover and MQTT input events.\r\n * Determines handover and force start modes based on process arguments.\r\n */\r\n private initHandoverManager(instanceMode: string, handover: boolean) {\r\n\r\n const handoverRequestEnabled = instanceMode == \"handover\" ? true : false;\r\n const forceStartEnabled = instanceMode == \"force\" ? true : false;\r\n\r\n this.handoverManager = new HandoverManager(\r\n this.processName,\r\n this.processId,\r\n this.processMqttProxy,\r\n this.unsMqttProxies,\r\n handoverRequestEnabled,\r\n handover ?? true,\r\n forceStartEnabled\r\n );\r\n\r\n // Listen for handover events.\r\n this.handoverManager.event.on(\"handoverManager\", (event) => {\r\n this.active = event.active;\r\n });\r\n\r\n // Delegate MQTT events to the HandoverManager.\r\n this.mqttInputHandler = async (event: UnsEvents[\"input\"]) => {\r\n await this.handoverManager.handleMqttMessage(event);\r\n };\r\n this.processMqttProxy.event.on(\"input\", this.mqttInputHandler);\r\n }\r\n\r\n /**\r\n * Creates a new UNS proxy instance and stores it for future management.\r\n */\r\n public async createUnsMqttProxy(\r\n mqttHost: string, \r\n instanceName: string,\r\n instanceMode: string,\r\n handover: boolean,\r\n unsParameters?: IUnsParameters): Promise<UnsMqttProxy> {\r\n // Wait until the MQTT connection is established before proceeding.\r\n await this.waitForProcessConnection();\r\n\r\n // Currently handover manager can handle only mqtt events\r\n if (!this.handoverManager) {\r\n this.initHandoverManager(instanceMode, handover);\r\n }\r\n\r\n const resolvedUnsParameters: IUnsParameters = {\r\n ...(unsParameters ?? {}),\r\n clientId: unsParameters?.clientId ?? `${this.processName}-${instanceName}-${this.processId}`,\r\n };\r\n const unsMqttProxy = new UnsMqttProxy(mqttHost, this.processName, instanceName, resolvedUnsParameters);\r\n \r\n // Listen for UNS proxy producing topics and publish them via MQTT.\r\n unsMqttProxy.event.on(\"unsProxyProducedTopics\", (event) => {\r\n this.processMqttProxy.publish(\r\n event.statusTopic,\r\n JSON.stringify(event.producedTopics),\r\n );\r\n });\r\n\r\n // Listen for UNS proxy status events and publish them via MQTT.\r\n unsMqttProxy.event.on(\"mqttProxyStatus\", (event) => {\r\n const time = UnsPacket.formatToISO8601(new Date());\r\n const unsMessage: IUnsMessage = { data: { time, value: event.value, uom: event.uom } };\r\n UnsPacket.unsPacketFromUnsMessage(unsMessage).then((packet) => {\r\n this.processMqttProxy.publish(\r\n event.statusTopic,\r\n JSON.stringify(packet),\r\n );\r\n });\r\n });\r\n\r\n this.unsMqttProxies.push(unsMqttProxy);\r\n return unsMqttProxy;\r\n }\r\n\r\n public async waitForProcessConnection(): Promise<void> {\r\n while (!this.processMqttProxy?.isConnected) {\r\n await new Promise((resolve) => setTimeout(resolve, 100));\r\n }\r\n }\r\n\r\n /**\r\n * Publishes retained product/system service metadata for controller discovery.\r\n *\r\n * The payload is intentionally separate from the volatile active/alive status\r\n * topics. Controllers can combine this retained identity/capability metadata\r\n * with live process status to decide whether a service is currently healthy.\r\n */\r\n public async publishServiceMetadata(metadata: UnsServiceMetadataInput): Promise<UnsServiceMetadata> {\r\n await this.waitForProcessConnection();\r\n const resolved = buildUnsServiceMetadata({\r\n processName: this.processName,\r\n processId: this.processId,\r\n metadata,\r\n });\r\n await this.processMqttProxy.publish(\r\n this.serviceMetadataTopic,\r\n JSON.stringify(resolved),\r\n { retain: true },\r\n );\r\n return resolved;\r\n }\r\n\r\n /**\r\n * Shuts down the process by clearing intervals, timeouts, and removing\r\n * MQTT event listeners, and stopping the StatusMonitor.\r\n */\r\n public shutdown(): void {\r\n logger.info(`${this.processName} - Shutting down UnsProxyProcess...`);\r\n try {\r\n this.statusMonitor.stop();\r\n } catch (e: any) {\r\n logger.error(`${this.processName} - Error stopping StatusMonitor: ${e.message}`);\r\n }\r\n \r\n if (this.mqttInputHandler) {\r\n this.processMqttProxy.event.off(\"input\", this.mqttInputHandler);\r\n }\r\n \r\n try {\r\n if (typeof this.processMqttProxy.stop === \"function\") {\r\n this.processMqttProxy.stop();\r\n }\r\n } catch (e: any) {\r\n logger.error(`${this.processName} - Error stopping MQTT proxy: ${e.message}`);\r\n }\r\n \r\n logger.info(`${this.processName} - Shutdown complete.`);\r\n }\r\n \r\n}\r\n\r\ninterface UnsProxyProcess {}\r\n\r\nexport default UnsProxyProcess;\r\nexport type { UnsServiceMetadata, UnsServiceMetadataInput };\r\nexport { UnsProxyProcess };\r\n"]}