@uns-kit/core 2.0.69 → 2.0.71

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 (92) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +334 -312
  3. package/dist/base-path.js.map +1 -1
  4. package/dist/config/app-config.js.map +1 -1
  5. package/dist/config/project.config.extension.js.map +1 -1
  6. package/dist/config-file.js.map +1 -1
  7. package/dist/examples/datahub-client.js.map +1 -1
  8. package/dist/graphql/schema.js.map +1 -1
  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.js.map +1 -1
  17. package/dist/tools/generate-config-schema.js.map +1 -1
  18. package/dist/tools/generate-uns-dictionary.js +7 -7
  19. package/dist/tools/generate-uns-dictionary.js.map +1 -1
  20. package/dist/tools/generate-uns-measurements.js +7 -7
  21. package/dist/tools/generate-uns-measurements.js.map +1 -1
  22. package/dist/tools/generate-uns-reference.js +9 -9
  23. package/dist/tools/generate-uns-reference.js.map +1 -1
  24. package/dist/tools/pull-request.js.map +1 -1
  25. package/dist/tools/refresh-uns.js.map +1 -1
  26. package/dist/tools/schema.js.map +1 -1
  27. package/dist/tools/sync-uns-metadata.js +22 -22
  28. package/dist/tools/sync-uns-metadata.js.map +1 -1
  29. package/dist/tools/sync-uns-schema.js +17 -17
  30. package/dist/tools/sync-uns-schema.js.map +1 -1
  31. package/dist/uns/handover-manager-event-emitter.js.map +1 -1
  32. package/dist/uns/handover-manager.d.ts.map +1 -1
  33. package/dist/uns/handover-manager.js +1 -3
  34. package/dist/uns/handover-manager.js.map +1 -1
  35. package/dist/uns/process-config.js.map +1 -1
  36. package/dist/uns/service-metadata.js.map +1 -1
  37. package/dist/uns/status-monitor.js.map +1 -1
  38. package/dist/uns/uns-asset.js.map +1 -1
  39. package/dist/uns/uns-attributes.js.map +1 -1
  40. package/dist/uns/uns-dictionary-registry.js.map +1 -1
  41. package/dist/uns/uns-dictionary.generated.js.map +1 -1
  42. package/dist/uns/uns-event-emitter.js.map +1 -1
  43. package/dist/uns/uns-interfaces.d.ts +2 -0
  44. package/dist/uns/uns-interfaces.d.ts.map +1 -1
  45. package/dist/uns/uns-interfaces.js.map +1 -1
  46. package/dist/uns/uns-measurements.generated.js.map +1 -1
  47. package/dist/uns/uns-measurements.js.map +1 -1
  48. package/dist/uns/uns-object.js.map +1 -1
  49. package/dist/uns/uns-packet.js.map +1 -1
  50. package/dist/uns/uns-path.js.map +1 -1
  51. package/dist/uns/uns-proxy-process.d.ts +4 -1
  52. package/dist/uns/uns-proxy-process.d.ts.map +1 -1
  53. package/dist/uns/uns-proxy-process.js +36 -5
  54. package/dist/uns/uns-proxy-process.js.map +1 -1
  55. package/dist/uns/uns-proxy.js.map +1 -1
  56. package/dist/uns/uns-tags.js.map +1 -1
  57. package/dist/uns/uns-topic-matcher.js.map +1 -1
  58. package/dist/uns/uns-topics.js.map +1 -1
  59. package/dist/uns-config/config-schema.js.map +1 -1
  60. package/dist/uns-config/host-placeholders.js.map +1 -1
  61. package/dist/uns-config/schema-tolls.js.map +1 -1
  62. package/dist/uns-config/schema-tools.js.map +1 -1
  63. package/dist/uns-config/secret-placeholders.js.map +1 -1
  64. package/dist/uns-config/secret-resolver.js.map +1 -1
  65. package/dist/uns-config/uns-core-schema.js.map +1 -1
  66. package/dist/uns-grpc/uns-gateway-cli.js.map +1 -1
  67. package/dist/uns-grpc/uns-gateway-server.d.ts.map +1 -1
  68. package/dist/uns-grpc/uns-gateway-server.js +13 -4
  69. package/dist/uns-grpc/uns-gateway-server.js.map +1 -1
  70. package/dist/uns-grpc/uns-gateway.proto +107 -107
  71. package/dist/uns-mqtt/mqtt-interfaces.d.ts +2 -0
  72. package/dist/uns-mqtt/mqtt-interfaces.d.ts.map +1 -1
  73. package/dist/uns-mqtt/mqtt-interfaces.js.map +1 -1
  74. package/dist/uns-mqtt/mqtt-proxy.d.ts +1 -1
  75. package/dist/uns-mqtt/mqtt-proxy.d.ts.map +1 -1
  76. package/dist/uns-mqtt/mqtt-proxy.js +35 -38
  77. package/dist/uns-mqtt/mqtt-proxy.js.map +1 -1
  78. package/dist/uns-mqtt/mqtt-topic-builder.js.map +1 -1
  79. package/dist/uns-mqtt/mqtt-worker-init.js.map +1 -1
  80. package/dist/uns-mqtt/mqtt-worker.d.ts.map +1 -1
  81. package/dist/uns-mqtt/mqtt-worker.js +33 -17
  82. package/dist/uns-mqtt/mqtt-worker.js.map +1 -1
  83. package/dist/uns-mqtt/throttled-queue.d.ts +13 -2
  84. package/dist/uns-mqtt/throttled-queue.d.ts.map +1 -1
  85. package/dist/uns-mqtt/throttled-queue.js +85 -33
  86. package/dist/uns-mqtt/throttled-queue.js.map +1 -1
  87. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts +21 -3
  88. package/dist/uns-mqtt/uns-mqtt-proxy.d.ts.map +1 -1
  89. package/dist/uns-mqtt/uns-mqtt-proxy.js +162 -37
  90. package/dist/uns-mqtt/uns-mqtt-proxy.js.map +1 -1
  91. package/dist/uns-mqtt/ws-proxy.js.map +1 -1
  92. package/package.json +1 -1
@@ -1,107 +1,107 @@
1
- syntax = "proto3";
2
-
3
- package uns;
4
-
5
- service UnsGateway {
6
- rpc Publish (PublishRequest) returns (Ack);
7
- rpc Subscribe (SubscribeRequest) returns (stream MqttMessage);
8
- rpc RegisterApiGet (RegisterApiGetRequest) returns (Ack);
9
- rpc UnregisterApiGet (UnregisterApiGetRequest) returns (Ack);
10
- rpc ApiEventStream (stream ApiEventResponse) returns (stream ApiEvent);
11
- rpc Ready (ReadyRequest) returns (Ack);
12
- }
13
-
14
- message PublishRequest {
15
- string topic = 1;
16
- string attribute = 2;
17
- string description = 3;
18
- repeated string tags = 4;
19
- bool attribute_needs_persistence = 5;
20
- oneof content {
21
- Data data = 6;
22
- Table table = 7;
23
- }
24
- // Deprecated: producer-side delta calculation loses previous-value state
25
- // across service restarts. Publish raw cumulative counter values and request
26
- // delta/rate from Datahub history APIs.
27
- bool value_is_cumulative = 8;
28
- }
29
-
30
- message Data {
31
- string time = 1;
32
- double value_number = 2;
33
- string value_string = 3;
34
- string uom = 4;
35
- string data_group = 5;
36
- string foreign_event_key = 6;
37
- }
38
-
39
- message TableValue {
40
- string name = 1;
41
- string type = 2; // QuestDB column type (e.g., int, double, geohash(5c))
42
- string uom = 3; // Optional unit of measure
43
- double value_number = 4;
44
- string value_string = 5;
45
- }
46
-
47
- message Table {
48
- string time = 1;
49
- repeated TableValue columns = 2;
50
- string data_group = 3;
51
- }
52
-
53
- message SubscribeRequest {
54
- repeated string topics = 1;
55
- }
56
-
57
- message MqttMessage {
58
- string topic = 1;
59
- string payload = 2; // UNS packet JSON
60
- }
61
-
62
- message Ack {
63
- bool ok = 1;
64
- string error = 2;
65
- }
66
-
67
- message ReadyRequest {
68
- int32 timeout_ms = 1; // default 15000
69
- bool wait_output = 2; // wait for publisher active (output)
70
- bool wait_input = 3; // wait for subscriber active (input)
71
- bool wait_api = 4; // wait for API server (optional)
72
- }
73
-
74
- message ApiQueryParam {
75
- string name = 1;
76
- string type = 2; // string | number | boolean
77
- bool required = 3;
78
- string description = 4;
79
- }
80
-
81
- message RegisterApiGetRequest {
82
- string topic = 1;
83
- string attribute = 2;
84
- string api_description = 3;
85
- repeated string tags = 4;
86
- repeated ApiQueryParam query_params = 5;
87
- }
88
-
89
- message UnregisterApiGetRequest {
90
- string topic = 1;
91
- string attribute = 2;
92
- }
93
-
94
- message ApiEvent {
95
- string id = 1;
96
- string method = 2; // GET only for now
97
- string path = 3; // /{topic}{attribute}
98
- map<string, string> query = 4;
99
- string bearer = 5; // access token (optional)
100
- }
101
-
102
- message ApiEventResponse {
103
- string id = 1; // correlation
104
- int32 status = 2; // HTTP status
105
- string body = 3; // response body as string (JSON string if needed)
106
- map<string, string> headers = 4; // optional extra headers
107
- }
1
+ syntax = "proto3";
2
+
3
+ package uns;
4
+
5
+ service UnsGateway {
6
+ rpc Publish (PublishRequest) returns (Ack);
7
+ rpc Subscribe (SubscribeRequest) returns (stream MqttMessage);
8
+ rpc RegisterApiGet (RegisterApiGetRequest) returns (Ack);
9
+ rpc UnregisterApiGet (UnregisterApiGetRequest) returns (Ack);
10
+ rpc ApiEventStream (stream ApiEventResponse) returns (stream ApiEvent);
11
+ rpc Ready (ReadyRequest) returns (Ack);
12
+ }
13
+
14
+ message PublishRequest {
15
+ string topic = 1;
16
+ string attribute = 2;
17
+ string description = 3;
18
+ repeated string tags = 4;
19
+ bool attribute_needs_persistence = 5;
20
+ oneof content {
21
+ Data data = 6;
22
+ Table table = 7;
23
+ }
24
+ // Deprecated: producer-side delta calculation loses previous-value state
25
+ // across service restarts. Publish raw cumulative counter values and request
26
+ // delta/rate from Datahub history APIs.
27
+ bool value_is_cumulative = 8;
28
+ }
29
+
30
+ message Data {
31
+ string time = 1;
32
+ double value_number = 2;
33
+ string value_string = 3;
34
+ string uom = 4;
35
+ string data_group = 5;
36
+ string foreign_event_key = 6;
37
+ }
38
+
39
+ message TableValue {
40
+ string name = 1;
41
+ string type = 2; // QuestDB column type (e.g., int, double, geohash(5c))
42
+ string uom = 3; // Optional unit of measure
43
+ double value_number = 4;
44
+ string value_string = 5;
45
+ }
46
+
47
+ message Table {
48
+ string time = 1;
49
+ repeated TableValue columns = 2;
50
+ string data_group = 3;
51
+ }
52
+
53
+ message SubscribeRequest {
54
+ repeated string topics = 1;
55
+ }
56
+
57
+ message MqttMessage {
58
+ string topic = 1;
59
+ string payload = 2; // UNS packet JSON
60
+ }
61
+
62
+ message Ack {
63
+ bool ok = 1;
64
+ string error = 2;
65
+ }
66
+
67
+ message ReadyRequest {
68
+ int32 timeout_ms = 1; // default 15000
69
+ bool wait_output = 2; // wait for publisher active (output)
70
+ bool wait_input = 3; // wait for subscriber active (input)
71
+ bool wait_api = 4; // wait for API server (optional)
72
+ }
73
+
74
+ message ApiQueryParam {
75
+ string name = 1;
76
+ string type = 2; // string | number | boolean
77
+ bool required = 3;
78
+ string description = 4;
79
+ }
80
+
81
+ message RegisterApiGetRequest {
82
+ string topic = 1;
83
+ string attribute = 2;
84
+ string api_description = 3;
85
+ repeated string tags = 4;
86
+ repeated ApiQueryParam query_params = 5;
87
+ }
88
+
89
+ message UnregisterApiGetRequest {
90
+ string topic = 1;
91
+ string attribute = 2;
92
+ }
93
+
94
+ message ApiEvent {
95
+ string id = 1;
96
+ string method = 2; // GET only for now
97
+ string path = 3; // /{topic}{attribute}
98
+ map<string, string> query = 4;
99
+ string bearer = 5; // access token (optional)
100
+ }
101
+
102
+ message ApiEventResponse {
103
+ string id = 1; // correlation
104
+ int32 status = 2; // HTTP status
105
+ string body = 3; // response body as string (JSON string if needed)
106
+ map<string, string> headers = 4; // optional extra headers
107
+ }
@@ -47,6 +47,8 @@ export interface HandoverManagerEvents {
47
47
  }
48
48
  export interface IMqttWorkerData {
49
49
  publishThrottlingDelay?: number;
50
+ publishConcurrency?: number;
51
+ maxPendingPublishes?: number;
50
52
  subscribeThrottlingDelay?: number;
51
53
  persistToDisk?: boolean;
52
54
  mqttHost: string;
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-interfaces.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAGD,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;KAAE,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;CAC7C"}
1
+ {"version":3,"file":"mqtt-interfaces.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,MAAM,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,sBAAsB,CAAC;IACpC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAGD,MAAM,MAAM,mBAAmB,GAAG,qBAAqB,CAAC;AAExD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAE3E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,qBAAqB;IACpC,eAAe,EAAE;QAAE,MAAM,EAAE,OAAO,CAAC;KAAE,CAAC;CACvC;AAED,MAAM,WAAW,eAAe;IAC9B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,eAAe,CAAC;IACjC,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qBAAqB,CAAC,EAAE,mBAAmB,CAAC;CAC7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-interfaces.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import { IClientPublishOptions } from \"mqtt\";\r\n\r\nexport interface IMqttParameters {\r\n mqttSubToTopics?: string | string[];\r\n username?: string;\r\n password?: string;\r\n mqttSSL?: boolean;\r\n clientId?: string;\r\n hosts?: string[];\r\n servers?: IMqttServerConfig[];\r\n port?: number;\r\n protocol?: MqttProtocol;\r\n keepalive?: number;\r\n clean?: boolean;\r\n connectTimeout?: number;\r\n reconnectPeriod?: number;\r\n reconnectOnConnackError?: boolean;\r\n resubscribe?: boolean;\r\n queueQoSZero?: boolean;\r\n properties?: IMqttConnectProperties;\r\n ca?: string;\r\n cert?: string;\r\n key?: string;\r\n servername?: string;\r\n statusTopic?: string;\r\n rejectUnauthorized?: boolean;\r\n}\r\n\r\n// Narrow alias to avoid leaking mqtt dependency details elsewhere.\r\nexport type IMqttPublishOptions = IClientPublishOptions;\r\n\r\nexport type MqttProtocol = \"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\";\r\n\r\nexport interface IMqttServerConfig {\r\n host: string;\r\n port?: number;\r\n protocol?: MqttProtocol;\r\n}\r\n\r\nexport interface IMqttConnectProperties {\r\n sessionExpiryInterval?: number;\r\n receiveMaximum?: number;\r\n maximumPacketSize?: number;\r\n topicAliasMaximum?: number;\r\n requestResponseInformation?: boolean;\r\n requestProblemInformation?: boolean;\r\n userProperties?: Record<string, string>;\r\n}\r\n\r\nexport interface HandoverManagerEvents {\r\n handoverManager: { active: boolean; };\r\n}\r\n\r\nexport interface IMqttWorkerData {\r\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\r\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\r\n persistToDisk?: boolean; // Whether to persist the queue to disk; default is false\r\n mqttHost: string; // MQTT broker host\r\n instanceNameWithSuffix: string; // Unique instance name for logging\r\n mqttParameters?: IMqttParameters; // Additional parameters for the MQTT client \r\n publisherActive: boolean; // Whether the publisher is active\r\n subscriberActive: boolean; // Whether the subscriber is active\r\n defaultPublishOptions?: IMqttPublishOptions; // Default publish options (QoS/retain/etc.)\r\n}\r\n"]}
1
+ {"version":3,"file":"mqtt-interfaces.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-interfaces.ts"],"names":[],"mappings":"","sourcesContent":["import { IClientPublishOptions } from \"mqtt\";\n\nexport interface IMqttParameters {\n mqttSubToTopics?: string | string[];\n username?: string;\n password?: string;\n mqttSSL?: boolean;\n clientId?: string;\n hosts?: string[];\n servers?: IMqttServerConfig[];\n port?: number;\n protocol?: MqttProtocol;\n keepalive?: number;\n clean?: boolean;\n connectTimeout?: number;\n reconnectPeriod?: number;\n reconnectOnConnackError?: boolean;\n resubscribe?: boolean;\n queueQoSZero?: boolean;\n properties?: IMqttConnectProperties;\n ca?: string;\n cert?: string;\n key?: string;\n servername?: string;\n statusTopic?: string;\n rejectUnauthorized?: boolean;\n}\n\n// Narrow alias to avoid leaking mqtt dependency details elsewhere.\nexport type IMqttPublishOptions = IClientPublishOptions;\n\nexport type MqttProtocol = \"mqtt\" | \"mqtts\" | \"ws\" | \"wss\" | \"tcp\" | \"ssl\";\n\nexport interface IMqttServerConfig {\n host: string;\n port?: number;\n protocol?: MqttProtocol;\n}\n\nexport interface IMqttConnectProperties {\n sessionExpiryInterval?: number;\n receiveMaximum?: number;\n maximumPacketSize?: number;\n topicAliasMaximum?: number;\n requestResponseInformation?: boolean;\n requestProblemInformation?: boolean;\n userProperties?: Record<string, string>;\n}\n\nexport interface HandoverManagerEvents {\n handoverManager: { active: boolean; };\n}\n\nexport interface IMqttWorkerData {\n publishThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n publishConcurrency?: number; // Maximum concurrent outgoing publishes; default is 1\n maxPendingPublishes?: number; // Maximum accepted queued+in-flight publishes; default is unlimited\n subscribeThrottlingDelay?: number; // Delay in milliseconds; default is 1ms\n persistToDisk?: boolean; // Whether to persist the queue to disk; default is false\n mqttHost: string; // MQTT broker host\n instanceNameWithSuffix: string; // Unique instance name for logging\n mqttParameters?: IMqttParameters; // Additional parameters for the MQTT client \n publisherActive: boolean; // Whether the publisher is active\n subscriberActive: boolean; // Whether the subscriber is active\n defaultPublishOptions?: IMqttPublishOptions; // Default publish options (QoS/retain/etc.)\n}\n"]}
@@ -46,7 +46,7 @@ export default class MqttProxy {
46
46
  publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void>;
47
47
  subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]>;
48
48
  unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined>;
49
- stop(options?: MqttStopOptions): void;
49
+ stop(options?: MqttStopOptions): Promise<void>;
50
50
  private handleMqttConnect;
51
51
  private emitStatusUpdates;
52
52
  private updatePublishTransformationStats;
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,IAAoC,MAAM,MAAM,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC/B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,SAAS;IACrB,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAoC;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,OAAO,CAAC,2BAA2B,CAA+B;IAClE,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,UAAU,CAAa;IACxB,WAAW,UAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAU;IACpC,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,aAAa,CAA2C;gBAEpD,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU;IAY5G,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,0BAA0B;IAMlC,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;IA0CP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiHtB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BrG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAIpH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IASlF,IAAI,CAAC,OAAO,GAAE,eAAoB;IAkDzC,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,gCAAgC;IAKxC,OAAO,CAAC,kCAAkC;IAK1C,OAAO,CAAC,gBAAgB;YAsCV,4BAA4B;CAwC3C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAY7D"}
1
+ {"version":3,"file":"mqtt-proxy.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,IAAoC,MAAM,MAAM,CAAC;AAExD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,UAAU,CAAC;CAC/B,CAAC;AAEF,KAAK,aAAa,GAAG;IACnB,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,SAAS;IACrB,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAoC;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,oBAAoB,CAAiC;IAC7D,OAAO,CAAC,2BAA2B,CAA+B;IAClE,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,UAAU,CAAa;IACxB,WAAW,UAAS;IAC3B,OAAO,CAAC,kBAAkB,CAAU;IACpC,OAAO,CAAC,oBAAoB,CAA8B;IAC1D,OAAO,CAAC,wBAAwB,CAAS;IACzC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,aAAa,CAA2C;gBAEpD,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,UAAU;IAY5G,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,0BAA0B;IAMlC,OAAO,CAAC,iCAAiC;IAQzC,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;IA0CP,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAiHtB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BrG,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAIpH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IASlF,IAAI,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDzD,OAAO,CAAC,iBAAiB;IAoCzB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,gCAAgC;IAKxC,OAAO,CAAC,kCAAkC;IAK1C,OAAO,CAAC,gBAAgB;YAsCV,4BAA4B;CAwC3C;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CAY7D"}
@@ -220,16 +220,14 @@ export default class MqttProxy {
220
220
  this.updatePublishTransformationStats(JSON.stringify(message).length);
221
221
  const client = this.mqttClient;
222
222
  if (!client) {
223
- logger.warn(`${this.instanceName} - MQTT client missing; dropping publish to ${topic}`);
224
- return;
223
+ throw new Error(`${this.instanceName} - MQTT client missing; cannot publish to ${topic}`);
225
224
  }
226
225
  if (!client.connected) {
227
226
  // Wait briefly for reconnection before giving up.
228
227
  await this.waitForReconnect(client, 5000);
229
228
  }
230
229
  if (!client.connected) {
231
- logger.warn(`${this.instanceName} - MQTT client still disconnected; dropping publish to ${topic}`);
232
- return;
230
+ throw new Error(`${this.instanceName} - MQTT client still disconnected; publish failed for ${topic}`);
233
231
  }
234
232
  return new Promise((resolve, reject) => {
235
233
  client.publish(topic, message, options || {}, (err) => {
@@ -259,48 +257,47 @@ export default class MqttProxy {
259
257
  if (shouldLogDisconnect) {
260
258
  logger.debug(`${this.instanceName} - Disconnecting from MQTT broker...`);
261
259
  }
262
- try {
263
- if (this.statusUpdateInterval) {
264
- clearInterval(this.statusUpdateInterval);
265
- this.statusUpdateInterval = null;
266
- }
267
- if (this.transformationStatsInterval) {
268
- clearInterval(this.transformationStatsInterval);
269
- this.transformationStatsInterval = null;
270
- }
271
- if (this.mqttClient) {
272
- this.mqttClient.end(false, () => {
273
- this.isConnected = false;
274
- this.pendingReconnectWait = null;
275
- this.startupSettled = false;
276
- this.hasEstablishedConnection = false;
277
- this.startupResolve = null;
278
- this.startupReject = null;
279
- if (shouldLogDisconnect) {
280
- logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);
281
- }
282
- });
283
- }
284
- else {
260
+ return new Promise((resolve, reject) => {
261
+ const resetState = () => {
285
262
  this.isConnected = false;
286
263
  this.pendingReconnectWait = null;
287
264
  this.startupSettled = false;
288
265
  this.hasEstablishedConnection = false;
289
266
  this.startupResolve = null;
290
267
  this.startupReject = null;
268
+ };
269
+ try {
270
+ if (this.statusUpdateInterval) {
271
+ clearInterval(this.statusUpdateInterval);
272
+ this.statusUpdateInterval = null;
273
+ }
274
+ if (this.transformationStatsInterval) {
275
+ clearInterval(this.transformationStatsInterval);
276
+ this.transformationStatsInterval = null;
277
+ }
278
+ if (this.mqttClient) {
279
+ this.mqttClient.end(false, () => {
280
+ resetState();
281
+ if (shouldLogDisconnect) {
282
+ logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);
283
+ }
284
+ resolve();
285
+ });
286
+ }
287
+ else {
288
+ resetState();
289
+ resolve();
290
+ }
291
291
  }
292
- }
293
- catch (error) {
294
- if (!silent) {
295
- logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(error).message}`);
292
+ catch (error) {
293
+ resetState();
294
+ const reason = error instanceof Error ? error : new Error(String(error));
295
+ if (!silent) {
296
+ logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(reason).message}`);
297
+ }
298
+ reject(reason);
296
299
  }
297
- this.isConnected = false;
298
- this.pendingReconnectWait = null;
299
- this.startupSettled = false;
300
- this.hasEstablishedConnection = false;
301
- this.startupResolve = null;
302
- this.startupReject = null;
303
- }
300
+ });
304
301
  }
305
302
  handleMqttConnect() {
306
303
  const resolve = this.startupResolve;
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt, { IClientOptions, MqttClient } from \"mqtt\";\r\nimport logger from \"../logger.js\";\r\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\r\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\r\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\r\nimport { MqttWorker } from \"./mqtt-worker.js\";\r\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\r\n\r\nexport type MqttStopOptions = {\r\n silent?: boolean;\r\n reason?: \"retry\" | \"shutdown\";\r\n};\r\n\r\ntype MqttErrorInfo = {\r\n code: string | number;\r\n message: string;\r\n};\r\n\r\nexport default class MqttProxy {\r\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\r\n public statusTopic: string;\r\n public instanceName: string;\r\n private mqttHost: string;\r\n private mqttSubToTopics: string | string[];\r\n private mqttSSL: boolean;\r\n private mqttClient: MqttClient;\r\n private startDate: Date;\r\n private mqttParameters: IMqttParameters;\r\n private statusUpdateInterval: ReturnType<typeof setInterval>;\r\n private transformationStatsInterval: NodeJS.Timeout | null = null;\r\n private publishedMessageCount = 0;\r\n private publishedMessageBytes = 0;\r\n private subscribedMessageCount = 0;\r\n private subscribedMessageBytes = 0;\r\n private mqttWorker: MqttWorker;\r\n public isConnected = false;\r\n private rejectUnauthorized: boolean;\r\n private pendingReconnectWait: Promise<void> | null = null;\r\n private hasEstablishedConnection = false;\r\n private startupSettled = false;\r\n private startupResolve: (() => void) | null = null;\r\n private startupReject: ((error: unknown) => void) | null = null;\r\n\r\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\r\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\r\n this.rejectUnauthorized = mqttParameters.rejectUnauthorized ?? false;\r\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\r\n this.mqttHost = mqttHost;\r\n this.startDate = new Date();\r\n this.instanceName = instanceName ?? \"process\";\r\n this.statusTopic = `${mqttParameters?.statusTopic}`;\r\n this.mqttParameters = mqttParameters ?? {};\r\n this.mqttWorker = mqttWorker;\r\n }\r\n\r\n private resolveProtocol(): IMqttParameters[\"protocol\"] {\r\n return this.mqttParameters.protocol ?? (this.mqttSSL ? \"mqtts\" : \"mqtt\");\r\n }\r\n\r\n private resolveDefaultPort(protocol: IMqttParameters[\"protocol\"]): number {\r\n switch (protocol) {\r\n case \"mqtts\":\r\n case \"ssl\":\r\n return 8883;\r\n case \"wss\":\r\n return 443;\r\n case \"ws\":\r\n return 80;\r\n case \"tcp\":\r\n case \"mqtt\":\r\n default:\r\n return 1883;\r\n }\r\n }\r\n\r\n private ensureStatusUpdateInterval(): void {\r\n if (this.statusTopic && !this.statusUpdateInterval) {\r\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\r\n }\r\n }\r\n\r\n private ensureTransformationStatsInterval(): void {\r\n if (!this.transformationStatsInterval) {\r\n this.transformationStatsInterval = setInterval(() => {\r\n this.emitTransformationStatistics();\r\n }, 60000);\r\n }\r\n }\r\n\r\n private subscribeToTopics(): void {\r\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\r\n logger.debug(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\r\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\r\n }\r\n }\r\n\r\n private buildServers(defaultProtocol: IMqttParameters[\"protocol\"]): IClientOptions[\"servers\"] | undefined {\r\n const servers: IClientOptions[\"servers\"] = [];\r\n const { port } = this.mqttParameters;\r\n const protocol = this.mqttParameters.protocol ?? defaultProtocol;\r\n\r\n if (Array.isArray(this.mqttParameters.servers) && this.mqttParameters.servers.length > 0) {\r\n for (const server of this.mqttParameters.servers) {\r\n if (!server?.host) continue;\r\n const resolvedProtocol = server.protocol ?? protocol;\r\n const resolvedPort =\r\n typeof server.port === \"number\"\r\n ? server.port\r\n : typeof port === \"number\"\r\n ? port\r\n : this.resolveDefaultPort(resolvedProtocol);\r\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\r\n host: server.host,\r\n port: resolvedPort,\r\n };\r\n if (resolvedProtocol) {\r\n entry.protocol = resolvedProtocol;\r\n }\r\n servers.push(entry);\r\n }\r\n } else if (Array.isArray(this.mqttParameters.hosts) && this.mqttParameters.hosts.length > 0) {\r\n for (const host of this.mqttParameters.hosts) {\r\n if (!host) continue;\r\n const resolvedPort = typeof port === \"number\" ? port : this.resolveDefaultPort(protocol);\r\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\r\n host,\r\n port: resolvedPort,\r\n };\r\n if (protocol) {\r\n entry.protocol = protocol;\r\n }\r\n servers.push(entry);\r\n }\r\n }\r\n\r\n return servers.length > 0 ? servers : undefined;\r\n }\r\n\r\n public async start(): Promise<void> {\r\n logger.debug(`${this.instanceName} - Connecting to MQTT broker...`);\r\n this.startupSettled = false;\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n this.startupResolve = resolve;\r\n this.startupReject = reject;\r\n try {\r\n const username = this.mqttParameters.username;\r\n const password = this.mqttParameters.password;\r\n const clientId = this.mqttParameters.clientId ?? this.instanceName;\r\n const protocol = this.resolveProtocol();\r\n\r\n const options: IClientOptions = {\r\n username,\r\n password,\r\n protocolVersion: 5,\r\n rejectUnauthorized: this.rejectUnauthorized,\r\n keepalive: this.mqttParameters.keepalive,\r\n clean: this.mqttParameters.clean ?? true,\r\n connectTimeout: this.mqttParameters.connectTimeout,\r\n reconnectPeriod: this.mqttParameters.reconnectPeriod,\r\n reconnectOnConnackError: this.mqttParameters.reconnectOnConnackError,\r\n resubscribe: this.mqttParameters.resubscribe,\r\n queueQoSZero: this.mqttParameters.queueQoSZero,\r\n properties: this.mqttParameters.properties,\r\n ca: this.mqttParameters.ca,\r\n cert: this.mqttParameters.cert,\r\n key: this.mqttParameters.key,\r\n servername: this.mqttParameters.servername,\r\n \r\n will: {\r\n topic: `${this.statusTopic}alive`,\r\n payload: Buffer.from(\"\"),\r\n qos: 0,\r\n retain: true,\r\n properties: { messageExpiryInterval: 3600 },\r\n },\r\n clientId,\r\n };\r\n\r\n const servers = this.buildServers(protocol);\r\n if (servers) {\r\n options.servers = servers;\r\n options.protocol = protocol;\r\n this.mqttClient = mqtt.connect(options);\r\n } else {\r\n options.host = this.mqttHost;\r\n options.port = this.mqttParameters.port;\r\n options.protocol = protocol;\r\n this.mqttClient = mqtt.connect(options);\r\n }\r\n\r\n const onConnect = () => this.handleMqttConnect();\r\n\r\n this.mqttClient.on(\"connect\", onConnect);\r\n\r\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\r\n try {\r\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\r\n this.event.emit(\"input\", {\r\n message: message.toString(),\r\n topic: topic,\r\n packet: packet,\r\n });\r\n this.updateSubscribeTransformationStats(message.length);\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\r\n }\r\n });\r\n\r\n this.mqttClient.on(\"error\", (error) => {\r\n const errorInfo = formatMqttError(error);\r\n logger.error(`${this.instanceName} - MQTT client error: ${errorInfo.message}`);\r\n this.isConnected = false;\r\n this.event.emit(\"error\", {\r\n code: typeof errorInfo.code === \"number\" ? errorInfo.code : 0,\r\n message: errorInfo.message,\r\n });\r\n reject(error);\r\n });\r\n\r\n this.mqttClient.on(\"reconnect\", () => {\r\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\r\n });\r\n\r\n this.mqttClient.on(\"close\", () => {\r\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"offline\", () => {\r\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"end\", () => {\r\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\r\n this.isConnected = false;\r\n });\r\n\r\n this.mqttClient.on(\"disconnect\", (packet) => {\r\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\r\n this.isConnected = false;\r\n });\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${formatMqttError(error).message}`);\r\n this.isConnected = false;\r\n reject(error);\r\n }\r\n });\r\n }\r\n\r\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\r\n this.updatePublishTransformationStats(JSON.stringify(message).length);\r\n const client = this.mqttClient;\r\n if (!client) {\r\n logger.warn(`${this.instanceName} - MQTT client missing; dropping publish to ${topic}`);\r\n return;\r\n }\r\n\r\n if (!client.connected) {\r\n // Wait briefly for reconnection before giving up.\r\n await this.waitForReconnect(client, 5000);\r\n }\r\n\r\n if (!client.connected) {\r\n logger.warn(`${this.instanceName} - MQTT client still disconnected; dropping publish to ${topic}`);\r\n return;\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n client.publish(topic, message, options || {}, (err) => {\r\n if (err) {\r\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\r\n return reject(err);\r\n }\r\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\r\n resolve();\r\n });\r\n });\r\n }\r\n\r\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\r\n return this.mqttClient.subscribeAsync(topic, options);\r\n }\r\n\r\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\r\n const topics = Array.isArray(topic) ? topic.filter((t) => typeof t === \"string\" && t.length > 0) : [topic].filter((t): t is string => typeof t === \"string\" && t.length > 0);\r\n if (topics.length === 0) {\r\n logger.warn(`${this.instanceName} - unsubscribeAsync called with empty topic list; skipping.`);\r\n return Promise.resolve(undefined);\r\n }\r\n return this.mqttClient.unsubscribeAsync(topics);\r\n }\r\n\r\n public stop(options: MqttStopOptions = {}) {\r\n const silent = options.silent === true || options.reason === \"retry\";\r\n const shouldLogDisconnect = !silent && this.hasEstablishedConnection;\r\n\r\n if (shouldLogDisconnect) {\r\n logger.debug(`${this.instanceName} - Disconnecting from MQTT broker...`);\r\n }\r\n\r\n try {\r\n if (this.statusUpdateInterval) {\r\n clearInterval(this.statusUpdateInterval);\r\n this.statusUpdateInterval = null;\r\n }\r\n if (this.transformationStatsInterval) {\r\n clearInterval(this.transformationStatsInterval);\r\n this.transformationStatsInterval = null;\r\n }\r\n if (this.mqttClient) {\r\n this.mqttClient.end(false, () => {\r\n this.isConnected = false;\r\n this.pendingReconnectWait = null;\r\n this.startupSettled = false;\r\n this.hasEstablishedConnection = false;\r\n this.startupResolve = null;\r\n this.startupReject = null;\r\n if (shouldLogDisconnect) {\r\n logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);\r\n }\r\n });\r\n } else {\r\n this.isConnected = false;\r\n this.pendingReconnectWait = null;\r\n this.startupSettled = false;\r\n this.hasEstablishedConnection = false;\r\n this.startupResolve = null;\r\n this.startupReject = null;\r\n }\r\n } catch (error) {\r\n if (!silent) {\r\n logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(error).message}`);\r\n }\r\n this.isConnected = false;\r\n this.pendingReconnectWait = null;\r\n this.startupSettled = false;\r\n this.hasEstablishedConnection = false;\r\n this.startupResolve = null;\r\n this.startupReject = null;\r\n }\r\n }\r\n\r\n private handleMqttConnect(): void {\r\n const resolve = this.startupResolve;\r\n const reject = this.startupReject;\r\n if (!resolve || !reject) {\r\n return;\r\n }\r\n\r\n try {\r\n this.mqttClient.stream.setMaxListeners(0);\r\n const isFirstConnect = !this.startupSettled;\r\n this.startupSettled = true;\r\n this.hasEstablishedConnection = true;\r\n this.isConnected = true;\r\n\r\n if (isFirstConnect) {\r\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\r\n this.subscribeToTopics();\r\n this.ensureStatusUpdateInterval();\r\n this.ensureTransformationStatsInterval();\r\n resolve();\r\n return;\r\n }\r\n\r\n logger.info(`${this.instanceName} - Reconnected to MQTT broker at ${this.mqttHost}`);\r\n if (this.mqttParameters.resubscribe === false) {\r\n this.subscribeToTopics();\r\n }\r\n this.ensureStatusUpdateInterval();\r\n this.ensureTransformationStatsInterval();\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${formatMqttError(error).message}`);\r\n this.isConnected = false;\r\n reject(error);\r\n }\r\n }\r\n\r\n private emitStatusUpdates() {\r\n try {\r\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\r\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\r\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\r\n\r\n if (this.mqttWorker !== undefined) {\r\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\r\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\r\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\r\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\r\n }\r\n } catch (error) {\r\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\r\n }\r\n }\r\n\r\n private updatePublishTransformationStats(messageSizeOut: number): void {\r\n this.publishedMessageCount += 1;\r\n this.publishedMessageBytes += messageSizeOut;\r\n }\r\n\r\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\r\n this.subscribedMessageCount += 1;\r\n this.subscribedMessageBytes += messageSizeIn;\r\n }\r\n\r\n private waitForReconnect(client: mqtt.MqttClient, timeoutMs: number): Promise<void> {\r\n if (client.connected) {\r\n return Promise.resolve();\r\n }\r\n\r\n if (this.pendingReconnectWait) {\r\n return this.pendingReconnectWait;\r\n }\r\n\r\n this.pendingReconnectWait = new Promise<void>((resolve) => {\r\n if (client.connected) return resolve();\r\n\r\n const onConnect = () => {\r\n cleanup();\r\n resolve();\r\n };\r\n const onClose = () => {\r\n // stay waiting; close is expected during reconnect attempts\r\n };\r\n const cleanup = () => {\r\n client.off(\"connect\", onConnect);\r\n client.off(\"close\", onClose);\r\n };\r\n\r\n client.on(\"connect\", onConnect);\r\n client.on(\"close\", onClose);\r\n\r\n setTimeout(() => {\r\n cleanup();\r\n resolve();\r\n }, timeoutMs).unref?.();\r\n }).finally(() => {\r\n this.pendingReconnectWait = null;\r\n });\r\n\r\n return this.pendingReconnectWait;\r\n }\r\n\r\n private async emitTransformationStatistics(): Promise<void> {\r\n if (this.statusTopic !== \"\") {\r\n try {\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"published-message-count\",\r\n value: this.publishedMessageCount,\r\n uom: \"\",\r\n statusTopic: this.statusTopic + \"published-message-count\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"published-message-bytes\",\r\n value: Math.round(this.publishedMessageBytes / 1024),\r\n uom: DataSizeMeasurements.KiloByte,\r\n statusTopic: this.statusTopic + \"published-message-bytes\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"subscribed-message-count\",\r\n value: this.subscribedMessageCount,\r\n uom: \"\",\r\n statusTopic: this.statusTopic + \"subscribed-message-count\",\r\n });\r\n this.event.emit(\"mqttProxyStatus\", {\r\n event: \"subscribed-message-bytes\",\r\n value: Math.round(this.subscribedMessageBytes / 1024),\r\n uom: DataSizeMeasurements.KiloByte,\r\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\r\n });\r\n this.publishedMessageCount = 0;\r\n this.publishedMessageBytes = 0;\r\n this.subscribedMessageCount = 0;\r\n this.subscribedMessageBytes = 0;\r\n } catch (error: any) {\r\n this.publishedMessageCount = 0;\r\n this.publishedMessageBytes = 0;\r\n this.subscribedMessageCount = 0;\r\n this.subscribedMessageBytes = 0;\r\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport function formatMqttError(error: unknown): MqttErrorInfo {\r\n const parts: string[] = [];\r\n const codes: Array<string | number> = [];\r\n collectMqttErrorParts(error, parts, codes);\r\n\r\n const uniqueParts = Array.from(new Set(parts.map((part) => part.trim()).filter(Boolean)));\r\n const message = uniqueParts.join(\"; \") || \"Unknown MQTT error\";\r\n\r\n return {\r\n code: codes[0] ?? 0,\r\n message,\r\n };\r\n}\r\n\r\nfunction collectMqttErrorParts(\r\n error: unknown,\r\n parts: string[],\r\n codes: Array<string | number>,\r\n): void {\r\n if (error instanceof AggregateError) {\r\n if (typeof error.message === \"string\" && error.message.trim()) {\r\n parts.push(error.message.trim());\r\n }\r\n for (const nested of error.errors) {\r\n collectMqttErrorParts(nested, parts, codes);\r\n }\r\n return;\r\n }\r\n\r\n if (typeof error === \"string\") {\r\n if (error.trim()) {\r\n parts.push(error.trim());\r\n }\r\n return;\r\n }\r\n\r\n if (!error || typeof error !== \"object\") {\r\n return;\r\n }\r\n\r\n const record = error as {\r\n message?: unknown;\r\n name?: unknown;\r\n code?: unknown;\r\n address?: unknown;\r\n port?: unknown;\r\n cause?: unknown;\r\n };\r\n\r\n const code =\r\n typeof record.code === \"string\" || typeof record.code === \"number\"\r\n ? record.code\r\n : undefined;\r\n if (code !== undefined) {\r\n codes.push(code);\r\n }\r\n\r\n const message =\r\n typeof record.message === \"string\" && record.message.trim()\r\n ? record.message.trim()\r\n : undefined;\r\n const address =\r\n typeof record.address === \"string\" && record.address.trim()\r\n ? record.address.trim()\r\n : undefined;\r\n const port = typeof record.port === \"number\" ? record.port : undefined;\r\n const endpoint =\r\n address || port !== undefined\r\n ? `${address ?? \"\"}${address && port !== undefined ? \":\" : \"\"}${port ?? \"\"}`.trim()\r\n : undefined;\r\n\r\n const detailParts = [\r\n code !== undefined && !message?.includes(String(code)) ? String(code) : undefined,\r\n message,\r\n endpoint && !message?.includes(endpoint) ? endpoint : undefined,\r\n ].filter((part): part is string => typeof part === \"string\" && part.length > 0);\r\n\r\n if (detailParts.length > 0) {\r\n parts.push(detailParts.join(\" \"));\r\n } else if (typeof record.name === \"string\" && record.name.trim()) {\r\n parts.push(record.name.trim());\r\n }\r\n\r\n if (record.cause !== undefined) {\r\n collectMqttErrorParts(record.cause, parts, codes);\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"mqtt-proxy.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import mqtt, { IClientOptions, MqttClient } from \"mqtt\";\nimport logger from \"../logger.js\";\nimport { UnsEvents } from \"../uns/uns-interfaces.js\";\nimport { UnsEventEmitter } from \"../uns/uns-event-emitter.js\";\nimport { IMqttParameters } from \"./mqtt-interfaces.js\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\nimport { DataSizeMeasurements, PhysicalMeasurements } from \"../uns/uns-measurements.js\";\n\nexport type MqttStopOptions = {\n silent?: boolean;\n reason?: \"retry\" | \"shutdown\";\n};\n\ntype MqttErrorInfo = {\n code: string | number;\n message: string;\n};\n\nexport default class MqttProxy {\n public event: UnsEventEmitter<UnsEvents> = new UnsEventEmitter<UnsEvents>();\n public statusTopic: string;\n public instanceName: string;\n private mqttHost: string;\n private mqttSubToTopics: string | string[];\n private mqttSSL: boolean;\n private mqttClient: MqttClient;\n private startDate: Date;\n private mqttParameters: IMqttParameters;\n private statusUpdateInterval: ReturnType<typeof setInterval>;\n private transformationStatsInterval: NodeJS.Timeout | null = null;\n private publishedMessageCount = 0;\n private publishedMessageBytes = 0;\n private subscribedMessageCount = 0;\n private subscribedMessageBytes = 0;\n private mqttWorker: MqttWorker;\n public isConnected = false;\n private rejectUnauthorized: boolean;\n private pendingReconnectWait: Promise<void> | null = null;\n private hasEstablishedConnection = false;\n private startupSettled = false;\n private startupResolve: (() => void) | null = null;\n private startupReject: ((error: unknown) => void) | null = null;\n\n constructor(mqttHost: string, instanceName: string, mqttParameters: IMqttParameters, mqttWorker?: MqttWorker) {\n this.mqttSSL = mqttParameters?.mqttSSL ?? false;\n this.rejectUnauthorized = mqttParameters.rejectUnauthorized ?? false;\n this.mqttSubToTopics = mqttParameters?.mqttSubToTopics ?? [];\n this.mqttHost = mqttHost;\n this.startDate = new Date();\n this.instanceName = instanceName ?? \"process\";\n this.statusTopic = `${mqttParameters?.statusTopic}`;\n this.mqttParameters = mqttParameters ?? {};\n this.mqttWorker = mqttWorker;\n }\n\n private resolveProtocol(): IMqttParameters[\"protocol\"] {\n return this.mqttParameters.protocol ?? (this.mqttSSL ? \"mqtts\" : \"mqtt\");\n }\n\n private resolveDefaultPort(protocol: IMqttParameters[\"protocol\"]): number {\n switch (protocol) {\n case \"mqtts\":\n case \"ssl\":\n return 8883;\n case \"wss\":\n return 443;\n case \"ws\":\n return 80;\n case \"tcp\":\n case \"mqtt\":\n default:\n return 1883;\n }\n }\n\n private ensureStatusUpdateInterval(): void {\n if (this.statusTopic && !this.statusUpdateInterval) {\n this.statusUpdateInterval = setInterval(() => this.emitStatusUpdates(), 10000);\n }\n }\n\n private ensureTransformationStatsInterval(): void {\n if (!this.transformationStatsInterval) {\n this.transformationStatsInterval = setInterval(() => {\n this.emitTransformationStatistics();\n }, 60000);\n }\n }\n\n private subscribeToTopics(): void {\n if (this.mqttSubToTopics && this.mqttSubToTopics.length > 0) {\n logger.debug(`${this.instanceName} - Subscribed to ${this.mqttSubToTopics.length} topics.`);\n this.mqttClient.subscribe(this.mqttSubToTopics, { qos: 0 });\n }\n }\n\n private buildServers(defaultProtocol: IMqttParameters[\"protocol\"]): IClientOptions[\"servers\"] | undefined {\n const servers: IClientOptions[\"servers\"] = [];\n const { port } = this.mqttParameters;\n const protocol = this.mqttParameters.protocol ?? defaultProtocol;\n\n if (Array.isArray(this.mqttParameters.servers) && this.mqttParameters.servers.length > 0) {\n for (const server of this.mqttParameters.servers) {\n if (!server?.host) continue;\n const resolvedProtocol = server.protocol ?? protocol;\n const resolvedPort =\n typeof server.port === \"number\"\n ? server.port\n : typeof port === \"number\"\n ? port\n : this.resolveDefaultPort(resolvedProtocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host: server.host,\n port: resolvedPort,\n };\n if (resolvedProtocol) {\n entry.protocol = resolvedProtocol;\n }\n servers.push(entry);\n }\n } else if (Array.isArray(this.mqttParameters.hosts) && this.mqttParameters.hosts.length > 0) {\n for (const host of this.mqttParameters.hosts) {\n if (!host) continue;\n const resolvedPort = typeof port === \"number\" ? port : this.resolveDefaultPort(protocol);\n const entry: { host: string; port: number; protocol?: IMqttParameters[\"protocol\"] } = {\n host,\n port: resolvedPort,\n };\n if (protocol) {\n entry.protocol = protocol;\n }\n servers.push(entry);\n }\n }\n\n return servers.length > 0 ? servers : undefined;\n }\n\n public async start(): Promise<void> {\n logger.debug(`${this.instanceName} - Connecting to MQTT broker...`);\n this.startupSettled = false;\n\n return new Promise<void>((resolve, reject) => {\n this.startupResolve = resolve;\n this.startupReject = reject;\n try {\n const username = this.mqttParameters.username;\n const password = this.mqttParameters.password;\n const clientId = this.mqttParameters.clientId ?? this.instanceName;\n const protocol = this.resolveProtocol();\n\n const options: IClientOptions = {\n username,\n password,\n protocolVersion: 5,\n rejectUnauthorized: this.rejectUnauthorized,\n keepalive: this.mqttParameters.keepalive,\n clean: this.mqttParameters.clean ?? true,\n connectTimeout: this.mqttParameters.connectTimeout,\n reconnectPeriod: this.mqttParameters.reconnectPeriod,\n reconnectOnConnackError: this.mqttParameters.reconnectOnConnackError,\n resubscribe: this.mqttParameters.resubscribe,\n queueQoSZero: this.mqttParameters.queueQoSZero,\n properties: this.mqttParameters.properties,\n ca: this.mqttParameters.ca,\n cert: this.mqttParameters.cert,\n key: this.mqttParameters.key,\n servername: this.mqttParameters.servername,\n \n will: {\n topic: `${this.statusTopic}alive`,\n payload: Buffer.from(\"\"),\n qos: 0,\n retain: true,\n properties: { messageExpiryInterval: 3600 },\n },\n clientId,\n };\n\n const servers = this.buildServers(protocol);\n if (servers) {\n options.servers = servers;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n } else {\n options.host = this.mqttHost;\n options.port = this.mqttParameters.port;\n options.protocol = protocol;\n this.mqttClient = mqtt.connect(options);\n }\n\n const onConnect = () => this.handleMqttConnect();\n\n this.mqttClient.on(\"connect\", onConnect);\n\n this.mqttClient.on(\"message\", (topic: string, message: Buffer, packet: mqtt.IPublishPacket) => {\n try {\n logger.debug(`${this.instanceName} - Message received on topic ${topic}`);\n this.event.emit(\"input\", {\n message: message.toString(),\n topic: topic,\n packet: packet,\n });\n this.updateSubscribeTransformationStats(message.length);\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT message handler: ${error.message}`);\n }\n });\n\n this.mqttClient.on(\"error\", (error) => {\n const errorInfo = formatMqttError(error);\n logger.error(`${this.instanceName} - MQTT client error: ${errorInfo.message}`);\n this.isConnected = false;\n this.event.emit(\"error\", {\n code: typeof errorInfo.code === \"number\" ? errorInfo.code : 0,\n message: errorInfo.message,\n });\n reject(error);\n });\n\n this.mqttClient.on(\"reconnect\", () => {\n logger.debug(`${this.instanceName} - Attempting to reconnect to MQTT broker...`);\n });\n\n this.mqttClient.on(\"close\", () => {\n logger.debug(`${this.instanceName} - MQTT connection closed.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"offline\", () => {\n logger.debug(`${this.instanceName} - MQTT client is offline.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"end\", () => {\n logger.debug(`${this.instanceName} - MQTT client connection ended.`);\n this.isConnected = false;\n });\n\n this.mqttClient.on(\"disconnect\", (packet) => {\n logger.debug(`${this.instanceName} - MQTT client disconnected. Reason: ${packet?.reasonCode}`);\n this.isConnected = false;\n });\n } catch (error) {\n logger.error(`${this.instanceName} - Error starting MQTT proxy: ${formatMqttError(error).message}`);\n this.isConnected = false;\n reject(error);\n }\n });\n }\n\n public async publish(topic: string, message: string | Buffer, options?: mqtt.IClientPublishOptions): Promise<void> {\n this.updatePublishTransformationStats(JSON.stringify(message).length);\n const client = this.mqttClient;\n if (!client) {\n throw new Error(`${this.instanceName} - MQTT client missing; cannot publish to ${topic}`);\n }\n\n if (!client.connected) {\n // Wait briefly for reconnection before giving up.\n await this.waitForReconnect(client, 5000);\n }\n\n if (!client.connected) {\n throw new Error(`${this.instanceName} - MQTT client still disconnected; publish failed for ${topic}`);\n }\n\n return new Promise((resolve, reject) => {\n client.publish(topic, message, options || {}, (err) => {\n if (err) {\n logger.error(`${this.instanceName} - Error publishing to topic ${topic}: ${err.message}`);\n return reject(err);\n }\n logger.debug(`${this.instanceName} - Published message to topic ${topic}`);\n resolve();\n });\n });\n }\n\n public async subscribeAsync(topic: string | string[], options?: mqtt.IClientSubscribeOptions): Promise<mqtt.ISubscriptionGrant[]> {\n return this.mqttClient.subscribeAsync(topic, options);\n }\n\n public async unsubscribeAsync(topic: string | string[]): Promise<mqtt.Packet | undefined> {\n const topics = Array.isArray(topic) ? topic.filter((t) => typeof t === \"string\" && t.length > 0) : [topic].filter((t): t is string => typeof t === \"string\" && t.length > 0);\n if (topics.length === 0) {\n logger.warn(`${this.instanceName} - unsubscribeAsync called with empty topic list; skipping.`);\n return Promise.resolve(undefined);\n }\n return this.mqttClient.unsubscribeAsync(topics);\n }\n\n public stop(options: MqttStopOptions = {}): Promise<void> {\n const silent = options.silent === true || options.reason === \"retry\";\n const shouldLogDisconnect = !silent && this.hasEstablishedConnection;\n\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnecting from MQTT broker...`);\n }\n\n return new Promise((resolve, reject) => {\n const resetState = () => {\n this.isConnected = false;\n this.pendingReconnectWait = null;\n this.startupSettled = false;\n this.hasEstablishedConnection = false;\n this.startupResolve = null;\n this.startupReject = null;\n };\n\n try {\n if (this.statusUpdateInterval) {\n clearInterval(this.statusUpdateInterval);\n this.statusUpdateInterval = null;\n }\n if (this.transformationStatsInterval) {\n clearInterval(this.transformationStatsInterval);\n this.transformationStatsInterval = null;\n }\n if (this.mqttClient) {\n this.mqttClient.end(false, () => {\n resetState();\n if (shouldLogDisconnect) {\n logger.debug(`${this.instanceName} - Disconnected from MQTT broker.`);\n }\n resolve();\n });\n } else {\n resetState();\n resolve();\n }\n } catch (error) {\n resetState();\n const reason = error instanceof Error ? error : new Error(String(error));\n if (!silent) {\n logger.error(`${this.instanceName} - Error during stop: ${formatMqttError(reason).message}`);\n }\n reject(reason);\n }\n });\n }\n\n private handleMqttConnect(): void {\n const resolve = this.startupResolve;\n const reject = this.startupReject;\n if (!resolve || !reject) {\n return;\n }\n\n try {\n this.mqttClient.stream.setMaxListeners(0);\n const isFirstConnect = !this.startupSettled;\n this.startupSettled = true;\n this.hasEstablishedConnection = true;\n this.isConnected = true;\n\n if (isFirstConnect) {\n logger.info(`${this.instanceName} - Connected to MQTT broker at ${this.mqttHost}`);\n this.subscribeToTopics();\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n resolve();\n return;\n }\n\n logger.info(`${this.instanceName} - Reconnected to MQTT broker at ${this.mqttHost}`);\n if (this.mqttParameters.resubscribe === false) {\n this.subscribeToTopics();\n }\n this.ensureStatusUpdateInterval();\n this.ensureTransformationStatsInterval();\n } catch (error) {\n logger.error(`${this.instanceName} - Error in MQTT connect handler: ${formatMqttError(error).message}`);\n this.isConnected = false;\n reject(error);\n }\n }\n\n private emitStatusUpdates() {\n try {\n const uptime = Math.round((new Date().getTime() - this.startDate.getTime()) / 60000);\n this.event.emit(\"mqttProxyStatus\", { event: \"uptime\", value: uptime, uom: PhysicalMeasurements.Minute, statusTopic: this.statusTopic + \"uptime\" });\n this.event.emit(\"mqttProxyStatus\", { event: \"alive\", value: 1, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"alive\" });\n\n if (this.mqttWorker !== undefined) {\n const tpValue = this.mqttWorker.getPublisherState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-publisher-active\", value: tpValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-publisher-active\" });\n const tsValue = this.mqttWorker.getSubscriberState() ? 1 : 0;\n this.event.emit(\"mqttProxyStatus\", { event: \"t-subscriber-active\", value: tsValue, uom: DataSizeMeasurements.Bit, statusTopic: this.statusTopic + \"t-subscriber-active\" });\n }\n } catch (error) {\n logger.error(`${this.instanceName} - Error publishing MQTT status: ${error.message}`);\n }\n }\n\n private updatePublishTransformationStats(messageSizeOut: number): void {\n this.publishedMessageCount += 1;\n this.publishedMessageBytes += messageSizeOut;\n }\n\n private updateSubscribeTransformationStats(messageSizeIn: number): void {\n this.subscribedMessageCount += 1;\n this.subscribedMessageBytes += messageSizeIn;\n }\n\n private waitForReconnect(client: mqtt.MqttClient, timeoutMs: number): Promise<void> {\n if (client.connected) {\n return Promise.resolve();\n }\n\n if (this.pendingReconnectWait) {\n return this.pendingReconnectWait;\n }\n\n this.pendingReconnectWait = new Promise<void>((resolve) => {\n if (client.connected) return resolve();\n\n const onConnect = () => {\n cleanup();\n resolve();\n };\n const onClose = () => {\n // stay waiting; close is expected during reconnect attempts\n };\n const cleanup = () => {\n client.off(\"connect\", onConnect);\n client.off(\"close\", onClose);\n };\n\n client.on(\"connect\", onConnect);\n client.on(\"close\", onClose);\n\n setTimeout(() => {\n cleanup();\n resolve();\n }, timeoutMs).unref?.();\n }).finally(() => {\n this.pendingReconnectWait = null;\n });\n\n return this.pendingReconnectWait;\n }\n\n private async emitTransformationStatistics(): Promise<void> {\n if (this.statusTopic !== \"\") {\n try {\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-count\",\n value: this.publishedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"published-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"published-message-bytes\",\n value: Math.round(this.publishedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"published-message-bytes\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-count\",\n value: this.subscribedMessageCount,\n uom: \"\",\n statusTopic: this.statusTopic + \"subscribed-message-count\",\n });\n this.event.emit(\"mqttProxyStatus\", {\n event: \"subscribed-message-bytes\",\n value: Math.round(this.subscribedMessageBytes / 1024),\n uom: DataSizeMeasurements.KiloByte,\n statusTopic: this.statusTopic + \"subscribed-message-bytes\",\n });\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n } catch (error: any) {\n this.publishedMessageCount = 0;\n this.publishedMessageBytes = 0;\n this.subscribedMessageCount = 0;\n this.subscribedMessageBytes = 0;\n logger.error(`${this.instanceName} - Error emitting transformation statistics: ${error.message}`);\n }\n }\n }\n}\n\nexport function formatMqttError(error: unknown): MqttErrorInfo {\n const parts: string[] = [];\n const codes: Array<string | number> = [];\n collectMqttErrorParts(error, parts, codes);\n\n const uniqueParts = Array.from(new Set(parts.map((part) => part.trim()).filter(Boolean)));\n const message = uniqueParts.join(\"; \") || \"Unknown MQTT error\";\n\n return {\n code: codes[0] ?? 0,\n message,\n };\n}\n\nfunction collectMqttErrorParts(\n error: unknown,\n parts: string[],\n codes: Array<string | number>,\n): void {\n if (error instanceof AggregateError) {\n if (typeof error.message === \"string\" && error.message.trim()) {\n parts.push(error.message.trim());\n }\n for (const nested of error.errors) {\n collectMqttErrorParts(nested, parts, codes);\n }\n return;\n }\n\n if (typeof error === \"string\") {\n if (error.trim()) {\n parts.push(error.trim());\n }\n return;\n }\n\n if (!error || typeof error !== \"object\") {\n return;\n }\n\n const record = error as {\n message?: unknown;\n name?: unknown;\n code?: unknown;\n address?: unknown;\n port?: unknown;\n cause?: unknown;\n };\n\n const code =\n typeof record.code === \"string\" || typeof record.code === \"number\"\n ? record.code\n : undefined;\n if (code !== undefined) {\n codes.push(code);\n }\n\n const message =\n typeof record.message === \"string\" && record.message.trim()\n ? record.message.trim()\n : undefined;\n const address =\n typeof record.address === \"string\" && record.address.trim()\n ? record.address.trim()\n : undefined;\n const port = typeof record.port === \"number\" ? record.port : undefined;\n const endpoint =\n address || port !== undefined\n ? `${address ?? \"\"}${address && port !== undefined ? \":\" : \"\"}${port ?? \"\"}`.trim()\n : undefined;\n\n const detailParts = [\n code !== undefined && !message?.includes(String(code)) ? String(code) : undefined,\n message,\n endpoint && !message?.includes(endpoint) ? endpoint : undefined,\n ].filter((part): part is string => typeof part === \"string\" && part.length > 0);\n\n if (detailParts.length > 0) {\n parts.push(detailParts.join(\" \"));\n } else if (typeof record.name === \"string\" && record.name.trim()) {\n parts.push(record.name.trim());\n }\n\n if (record.cause !== undefined) {\n collectMqttErrorParts(record.cause, parts, codes);\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-topic-builder.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-topic-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACjB,kBAAkB,CAAS;IAEnC;;;;;OAKG;IACH,YAAY,kBAA0B;QAEpC,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,iBAAiB,CAAC,IAAY;QAC1C,MAAM,SAAS,GAAG,IAAI;aACnB,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;aAChC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAE3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1D,CAAC;IAAA,CAAC;IAEF;;;;OAIG;IACI,qBAAqB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,QAAQ,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACI,gBAAgB;QACrB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,UAAU,CAAC;IACnD,CAAC;IAED;;;;OAIG;IACI,uBAAuB;QAC5B,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,kBAAkB,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACI,sBAAsB;QAC3B,OAAO,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;IACvF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACxG,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;CACF","sourcesContent":["/**\r\n * MqttTopicBuilder is a utility class responsible for generating MQTT topics\r\n * based on a standardized pattern using the package name, version, and process name.\r\n *\r\n * This centralizes all MQTT topic definitions so that changes to topic structures\r\n * only need to be made in one place.\r\n */\r\nexport class MqttTopicBuilder {\r\n private processStatusTopic: string;\r\n\r\n /**\r\n * Constructor for MqttTopicBuilder.\r\n * It validates the provided process status topic and initializes the instance.\r\n * @param processStatusTopic The base topic for the process status.\r\n * Example: \"uns-infra/packageName/version/processName/\"\r\n */\r\n constructor(processStatusTopic: string) {\r\n \r\n if (!/^uns-infra\\/[^/]+\\/[^/]+\\/[^/]+\\/$/.test(processStatusTopic)) {\r\n throw new Error(\"processStatusTopic must follow the pattern 'uns-infra/<packageName>/<version>/<processName>/'\");\r\n }\r\n this.processStatusTopic = processStatusTopic;\r\n }\r\n\r\n /**\r\n * Sanitize topic\r\n * @param name \r\n * @returns \r\n */\r\n public static sanitizeTopicPart(name: string): string {\r\n const sanitized = name\r\n .replace(/[^a-zA-Z0-9_-]+/g, \"-\")\r\n .replace(/-{2,}/g, \"-\")\r\n .replace(/^-+|-+$/g, \"\");\r\n\r\n return sanitized.length > 0 ? sanitized : \"uns-process\";\r\n }; \r\n \r\n /**\r\n * Returns the process status topic.\r\n *\r\n * Example: \"uns-infra/packageName/version/processName\"\r\n */\r\n public getProcessStatusTopic(): string {\r\n return this.processStatusTopic;\r\n }\r\n \r\n /**\r\n * Returns the topic used for publishing the active state.\r\n *\r\n * Example: \"uns-infra/packageName/version/processName/active\"\r\n */\r\n public getActiveTopic(): string {\r\n return this.getProcessStatusTopic() + \"active\";\r\n }\r\n \r\n /**\r\n * Returns the topic used for handover requests.\r\n *\r\n * Example: \"uns-infra/packageName/version/processName/handover\"\r\n */\r\n public getHandoverTopic(): string {\r\n return this.getProcessStatusTopic() + \"handover\";\r\n }\r\n\r\n /**\r\n * Returns the retained metadata topic for product/system service discovery.\r\n *\r\n * Example: \"uns-infra/packageName/version/processName/service-metadata\"\r\n */\r\n public getServiceMetadataTopic(): string {\r\n return this.getProcessStatusTopic() + \"service-metadata\";\r\n }\r\n \r\n /**\r\n * Returns a wildcard topic for active status messages from any process.\r\n * Useful for subscriptions that must capture status from multiple processes.\r\n *\r\n * Example: \"uns-infra/packageName/+/+/active\"\r\n */\r\n public getWildcardActiveTopic(): string {\r\n return this.getProcessStatusTopic().split('/').slice(0, 2).join('/') + '/+/+/active';\r\n }\r\n\r\n /**\r\n * Extract base topic from a full topic string.\r\n * This is useful for creating a topic builder from an existing topic.\r\n * @param fullTopic The full topic string.\r\n * Example: \"uns-infra/packageName/version/processName/active\"\r\n * @returns The base topic string.\r\n * Example: \"uns-infra/packageName/version/processName/\"\r\n */\r\n public static extractBaseTopic(fullTopic: string): string {\r\n const parts = fullTopic.split('/');\r\n if (parts.length < 4) {\r\n throw new Error(\"Invalid topic format. Expected 'uns-infra/<packageName>/<version>/<processName>/'.\");\r\n }\r\n return parts.slice(0, 4).join('/') + '/';\r\n }\r\n }\r\n"]}
1
+ {"version":3,"file":"mqtt-topic-builder.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-topic-builder.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,OAAO,gBAAgB;IACjB,kBAAkB,CAAS;IAEnC;;;;;OAKG;IACH,YAAY,kBAA0B;QAEpC,IAAI,CAAC,oCAAoC,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC;YACnE,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;QACnH,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,iBAAiB,CAAC,IAAY;QAC1C,MAAM,SAAS,GAAG,IAAI;aACnB,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;aAChC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAE3B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;IAC1D,CAAC;IAAA,CAAC;IAEF;;;;OAIG;IACI,qBAAqB;QAC1B,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACI,cAAc;QACnB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,QAAQ,CAAC;IACjD,CAAC;IAED;;;;OAIG;IACI,gBAAgB;QACrB,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,UAAU,CAAC;IACnD,CAAC;IAED;;;;OAIG;IACI,uBAAuB;QAC5B,OAAO,IAAI,CAAC,qBAAqB,EAAE,GAAG,kBAAkB,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACI,sBAAsB;QAC3B,OAAO,IAAI,CAAC,qBAAqB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC;IACvF,CAAC;IAED;;;;;;;OAOG;IACI,MAAM,CAAC,gBAAgB,CAAC,SAAiB;QAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAC;QACxG,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC;CACF","sourcesContent":["/**\n * MqttTopicBuilder is a utility class responsible for generating MQTT topics\n * based on a standardized pattern using the package name, version, and process name.\n *\n * This centralizes all MQTT topic definitions so that changes to topic structures\n * only need to be made in one place.\n */\nexport class MqttTopicBuilder {\n private processStatusTopic: string;\n\n /**\n * Constructor for MqttTopicBuilder.\n * It validates the provided process status topic and initializes the instance.\n * @param processStatusTopic The base topic for the process status.\n * Example: \"uns-infra/packageName/version/processName/\"\n */\n constructor(processStatusTopic: string) {\n \n if (!/^uns-infra\\/[^/]+\\/[^/]+\\/[^/]+\\/$/.test(processStatusTopic)) {\n throw new Error(\"processStatusTopic must follow the pattern 'uns-infra/<packageName>/<version>/<processName>/'\");\n }\n this.processStatusTopic = processStatusTopic;\n }\n\n /**\n * Sanitize topic\n * @param name \n * @returns \n */\n public static sanitizeTopicPart(name: string): string {\n const sanitized = name\n .replace(/[^a-zA-Z0-9_-]+/g, \"-\")\n .replace(/-{2,}/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n\n return sanitized.length > 0 ? sanitized : \"uns-process\";\n }; \n \n /**\n * Returns the process status topic.\n *\n * Example: \"uns-infra/packageName/version/processName\"\n */\n public getProcessStatusTopic(): string {\n return this.processStatusTopic;\n }\n \n /**\n * Returns the topic used for publishing the active state.\n *\n * Example: \"uns-infra/packageName/version/processName/active\"\n */\n public getActiveTopic(): string {\n return this.getProcessStatusTopic() + \"active\";\n }\n \n /**\n * Returns the topic used for handover requests.\n *\n * Example: \"uns-infra/packageName/version/processName/handover\"\n */\n public getHandoverTopic(): string {\n return this.getProcessStatusTopic() + \"handover\";\n }\n\n /**\n * Returns the retained metadata topic for product/system service discovery.\n *\n * Example: \"uns-infra/packageName/version/processName/service-metadata\"\n */\n public getServiceMetadataTopic(): string {\n return this.getProcessStatusTopic() + \"service-metadata\";\n }\n \n /**\n * Returns a wildcard topic for active status messages from any process.\n * Useful for subscriptions that must capture status from multiple processes.\n *\n * Example: \"uns-infra/packageName/+/+/active\"\n */\n public getWildcardActiveTopic(): string {\n return this.getProcessStatusTopic().split('/').slice(0, 2).join('/') + '/+/+/active';\n }\n\n /**\n * Extract base topic from a full topic string.\n * This is useful for creating a topic builder from an existing topic.\n * @param fullTopic The full topic string.\n * Example: \"uns-infra/packageName/version/processName/active\"\n * @returns The base topic string.\n * Example: \"uns-infra/packageName/version/processName/\"\n */\n public static extractBaseTopic(fullTopic: string): string {\n const parts = fullTopic.split('/');\n if (parts.length < 4) {\n throw new Error(\"Invalid topic format. Expected 'uns-infra/<packageName>/<version>/<processName>/'.\");\n }\n return parts.slice(0, 4).join('/') + '/';\n }\n }\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-worker-init.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,IAAI,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { isMainThread, parentPort, workerData } from \"worker_threads\";\r\nimport { MqttWorker } from \"./mqtt-worker.js\";\r\n\r\nif (!isMainThread && parentPort) {\r\n new MqttWorker(workerData);\r\n}\r\n"]}
1
+ {"version":3,"file":"mqtt-worker-init.js","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker-init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,IAAI,CAAC,YAAY,IAAI,UAAU,EAAE,CAAC;IAChC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { isMainThread, parentPort, workerData } from \"worker_threads\";\nimport { MqttWorker } from \"./mqtt-worker.js\";\n\nif (!isMainThread && parentPort) {\n new MqttWorker(workerData);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"mqtt-worker.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE/E,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,SAAS,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACxC,SAAS,CAAC,UAAU,EAAE,mBAAmB,CAAC;gBAE9B,UAAU,EAAE,eAAe;IAyFvC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAgCjC;;OAEG;IACI,iBAAiB,IAAI,OAAO;IAGnC;;OAEG;IACI,kBAAkB,IAAI,OAAO;CAIrC"}
1
+ {"version":3,"file":"mqtt-worker.d.ts","sourceRoot":"","sources":["../../src/uns-mqtt/mqtt-worker.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE/E,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,SAAS,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACxC,SAAS,CAAC,UAAU,EAAE,mBAAmB,CAAC;gBAE9B,UAAU,EAAE,eAAe;IA+EvC;;OAEG;IACH,OAAO,CAAC,yBAAyB;IA4DjC;;OAEG;IACI,iBAAiB,IAAI,OAAO;IAGnC;;OAEG;IACI,kBAAkB,IAAI,OAAO;CAIrC"}