@machhub-dev/sdk-ts 1.0.4 → 1.0.5
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.
- package/dist/cjs/sdk-ts.d.ts +0 -4
- package/dist/cjs/sdk-ts.js +2 -45
- package/dist/sdk-ts.d.ts +0 -4
- package/dist/sdk-ts.js +2 -45
- package/package.json +1 -3
- package/src/sdk-ts.ts +6 -58
- package/src/classes/function.ts +0 -34
- package/src/example/functions.ts +0 -21
- package/src/services/nats.service.ts +0 -293
package/dist/cjs/sdk-ts.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Collection } from "./classes/collection.js";
|
|
2
2
|
import { Historian } from "./classes/historian.js";
|
|
3
3
|
import { Tag } from "./classes/tag.js";
|
|
4
|
-
import { Function } from "./classes/function.js";
|
|
5
4
|
import { Flow } from "./classes/flow.js";
|
|
6
5
|
import { Auth } from "./classes/auth.js";
|
|
7
6
|
export interface SDKConfig {
|
|
@@ -9,12 +8,10 @@ export interface SDKConfig {
|
|
|
9
8
|
developer_key?: string;
|
|
10
9
|
httpUrl?: string;
|
|
11
10
|
mqttUrl?: string;
|
|
12
|
-
natsUrl?: string;
|
|
13
11
|
}
|
|
14
12
|
export declare class SDK {
|
|
15
13
|
private http;
|
|
16
14
|
private mqtt;
|
|
17
|
-
private nats;
|
|
18
15
|
private _historian;
|
|
19
16
|
private _tag;
|
|
20
17
|
private _function;
|
|
@@ -39,7 +36,6 @@ export declare class SDK {
|
|
|
39
36
|
* application_id: 'your-app-id',
|
|
40
37
|
* httpUrl: 'http://localhost:6188', // optional (default = http://localhost:6188)
|
|
41
38
|
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
42
|
-
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
43
39
|
* };
|
|
44
40
|
*
|
|
45
41
|
* const sdk = new SDK();
|
package/dist/cjs/sdk-ts.js
CHANGED
|
@@ -3,11 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SDK = void 0;
|
|
4
4
|
const http_service_js_1 = require("./services/http.service.js");
|
|
5
5
|
const mqtt_service_js_1 = require("./services/mqtt.service.js");
|
|
6
|
-
const nats_service_js_1 = require("./services/nats.service.js");
|
|
7
6
|
const collection_js_1 = require("./classes/collection.js");
|
|
8
7
|
const historian_js_1 = require("./classes/historian.js");
|
|
9
8
|
const tag_js_1 = require("./classes/tag.js");
|
|
10
|
-
const function_js_1 = require("./classes/function.js");
|
|
11
9
|
const flow_js_1 = require("./classes/flow.js");
|
|
12
10
|
const auth_js_1 = require("./classes/auth.js");
|
|
13
11
|
const MACHHUB_SDK_PATH = "machhub";
|
|
@@ -68,46 +66,11 @@ class MQTTClient {
|
|
|
68
66
|
return this.mqttService.publish(topic, data);
|
|
69
67
|
}
|
|
70
68
|
}
|
|
71
|
-
// Core NATS client class
|
|
72
|
-
class NATSClient {
|
|
73
|
-
constructor(natsService) {
|
|
74
|
-
this.natsService = natsService;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Creates a new NATSClient instance
|
|
78
|
-
* @param applicationID The ID for your application
|
|
79
|
-
* @param natsUrl The base URL for NATS connection (default = ws://localhost:7500)
|
|
80
|
-
*/
|
|
81
|
-
static async getInstance(applicationID, natsUrl = "ws://localhost:7500") {
|
|
82
|
-
if (!this.instance) {
|
|
83
|
-
const natsService = await nats_service_js_1.NATSService.getInstance(natsUrl);
|
|
84
|
-
this.instance = new NATSClient(natsService);
|
|
85
|
-
}
|
|
86
|
-
return this.instance;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Subscribes to subject updates
|
|
90
|
-
* @param subject The subject to subscribe to
|
|
91
|
-
* @param callback The callback function for data updates
|
|
92
|
-
*/
|
|
93
|
-
async subscribe(subject, callback) {
|
|
94
|
-
return this.natsService.addSubjectHandler(subject, callback);
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Publishes a message to a specific subject
|
|
98
|
-
* @param subject The subject to publish to
|
|
99
|
-
* @param data The data to publish
|
|
100
|
-
*/
|
|
101
|
-
async publish(subject, data) {
|
|
102
|
-
return this.natsService.publish(subject, data);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
69
|
// SDK Class
|
|
106
70
|
class SDK {
|
|
107
71
|
constructor() {
|
|
108
72
|
this.http = null;
|
|
109
73
|
this.mqtt = null;
|
|
110
|
-
this.nats = null;
|
|
111
74
|
this._historian = null;
|
|
112
75
|
this._tag = null;
|
|
113
76
|
this._function = null;
|
|
@@ -138,7 +101,6 @@ class SDK {
|
|
|
138
101
|
* application_id: 'your-app-id',
|
|
139
102
|
* httpUrl: 'http://localhost:6188', // optional (default = http://localhost:6188)
|
|
140
103
|
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
141
|
-
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
142
104
|
* };
|
|
143
105
|
*
|
|
144
106
|
* const sdk = new SDK();
|
|
@@ -180,17 +142,12 @@ class SDK {
|
|
|
180
142
|
if (!config.mqttUrl) {
|
|
181
143
|
config.mqttUrl = `${secured ? 'wss' : 'ws'}://${host}/mqtt`;
|
|
182
144
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
const { httpUrl, mqttUrl, natsUrl } = config;
|
|
187
|
-
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl, natsUrl, developer_key: config.developer_key?.split('').map((_, i) => i < config.developer_key.length - 4 ? '*' : config.developer_key[i]).join('') });
|
|
145
|
+
const { httpUrl, mqttUrl } = config;
|
|
146
|
+
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl, developer_key: config.developer_key?.split('').map((_, i) => i < config.developer_key.length - 4 ? '*' : config.developer_key[i]).join('') });
|
|
188
147
|
this.http = new HTTPClient(this.applicationID, httpUrl, config.developer_key, envCfg.runtimeID);
|
|
189
148
|
this.mqtt = await MQTTClient.getInstance(this.applicationID, mqttUrl, config.developer_key);
|
|
190
|
-
this.nats = await NATSClient.getInstance(this.applicationID, natsUrl);
|
|
191
149
|
this._historian = new historian_js_1.Historian(this.http["httpService"], this.mqtt["mqttService"]);
|
|
192
150
|
this._tag = new tag_js_1.Tag(this.http["httpService"], this.mqtt["mqttService"]);
|
|
193
|
-
this._function = new function_js_1.Function(this.http["httpService"], this.nats["natsService"]);
|
|
194
151
|
this._flow = new flow_js_1.Flow(this.http["httpService"]);
|
|
195
152
|
this._auth = new auth_js_1.Auth(this.http["httpService"], this.applicationID);
|
|
196
153
|
}
|
package/dist/sdk-ts.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Collection } from "./classes/collection.js";
|
|
2
2
|
import { Historian } from "./classes/historian.js";
|
|
3
3
|
import { Tag } from "./classes/tag.js";
|
|
4
|
-
import { Function } from "./classes/function.js";
|
|
5
4
|
import { Flow } from "./classes/flow.js";
|
|
6
5
|
import { Auth } from "./classes/auth.js";
|
|
7
6
|
export interface SDKConfig {
|
|
@@ -9,12 +8,10 @@ export interface SDKConfig {
|
|
|
9
8
|
developer_key?: string;
|
|
10
9
|
httpUrl?: string;
|
|
11
10
|
mqttUrl?: string;
|
|
12
|
-
natsUrl?: string;
|
|
13
11
|
}
|
|
14
12
|
export declare class SDK {
|
|
15
13
|
private http;
|
|
16
14
|
private mqtt;
|
|
17
|
-
private nats;
|
|
18
15
|
private _historian;
|
|
19
16
|
private _tag;
|
|
20
17
|
private _function;
|
|
@@ -39,7 +36,6 @@ export declare class SDK {
|
|
|
39
36
|
* application_id: 'your-app-id',
|
|
40
37
|
* httpUrl: 'http://localhost:6188', // optional (default = http://localhost:6188)
|
|
41
38
|
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
42
|
-
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
43
39
|
* };
|
|
44
40
|
*
|
|
45
41
|
* const sdk = new SDK();
|
package/dist/sdk-ts.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { HTTPService } from "./services/http.service.js";
|
|
2
2
|
import { MQTTService } from "./services/mqtt.service.js";
|
|
3
|
-
import { NATSService } from "./services/nats.service.js";
|
|
4
3
|
import { Collection } from "./classes/collection.js";
|
|
5
4
|
import { Historian } from "./classes/historian.js";
|
|
6
5
|
import { Tag } from "./classes/tag.js";
|
|
7
|
-
import { Function } from "./classes/function.js";
|
|
8
6
|
import { Flow } from "./classes/flow.js";
|
|
9
7
|
import { Auth } from "./classes/auth.js";
|
|
10
8
|
const MACHHUB_SDK_PATH = "machhub";
|
|
@@ -65,46 +63,11 @@ class MQTTClient {
|
|
|
65
63
|
return this.mqttService.publish(topic, data);
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
|
-
// Core NATS client class
|
|
69
|
-
class NATSClient {
|
|
70
|
-
constructor(natsService) {
|
|
71
|
-
this.natsService = natsService;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Creates a new NATSClient instance
|
|
75
|
-
* @param applicationID The ID for your application
|
|
76
|
-
* @param natsUrl The base URL for NATS connection (default = ws://localhost:7500)
|
|
77
|
-
*/
|
|
78
|
-
static async getInstance(applicationID, natsUrl = "ws://localhost:7500") {
|
|
79
|
-
if (!this.instance) {
|
|
80
|
-
const natsService = await NATSService.getInstance(natsUrl);
|
|
81
|
-
this.instance = new NATSClient(natsService);
|
|
82
|
-
}
|
|
83
|
-
return this.instance;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Subscribes to subject updates
|
|
87
|
-
* @param subject The subject to subscribe to
|
|
88
|
-
* @param callback The callback function for data updates
|
|
89
|
-
*/
|
|
90
|
-
async subscribe(subject, callback) {
|
|
91
|
-
return this.natsService.addSubjectHandler(subject, callback);
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Publishes a message to a specific subject
|
|
95
|
-
* @param subject The subject to publish to
|
|
96
|
-
* @param data The data to publish
|
|
97
|
-
*/
|
|
98
|
-
async publish(subject, data) {
|
|
99
|
-
return this.natsService.publish(subject, data);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
66
|
// SDK Class
|
|
103
67
|
export class SDK {
|
|
104
68
|
constructor() {
|
|
105
69
|
this.http = null;
|
|
106
70
|
this.mqtt = null;
|
|
107
|
-
this.nats = null;
|
|
108
71
|
this._historian = null;
|
|
109
72
|
this._tag = null;
|
|
110
73
|
this._function = null;
|
|
@@ -135,7 +98,6 @@ export class SDK {
|
|
|
135
98
|
* application_id: 'your-app-id',
|
|
136
99
|
* httpUrl: 'http://localhost:6188', // optional (default = http://localhost:6188)
|
|
137
100
|
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
138
|
-
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
139
101
|
* };
|
|
140
102
|
*
|
|
141
103
|
* const sdk = new SDK();
|
|
@@ -177,17 +139,12 @@ export class SDK {
|
|
|
177
139
|
if (!config.mqttUrl) {
|
|
178
140
|
config.mqttUrl = `${secured ? 'wss' : 'ws'}://${host}/mqtt`;
|
|
179
141
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
}
|
|
183
|
-
const { httpUrl, mqttUrl, natsUrl } = config;
|
|
184
|
-
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl, natsUrl, developer_key: config.developer_key?.split('').map((_, i) => i < config.developer_key.length - 4 ? '*' : config.developer_key[i]).join('') });
|
|
142
|
+
const { httpUrl, mqttUrl } = config;
|
|
143
|
+
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl, developer_key: config.developer_key?.split('').map((_, i) => i < config.developer_key.length - 4 ? '*' : config.developer_key[i]).join('') });
|
|
185
144
|
this.http = new HTTPClient(this.applicationID, httpUrl, config.developer_key, envCfg.runtimeID);
|
|
186
145
|
this.mqtt = await MQTTClient.getInstance(this.applicationID, mqttUrl, config.developer_key);
|
|
187
|
-
this.nats = await NATSClient.getInstance(this.applicationID, natsUrl);
|
|
188
146
|
this._historian = new Historian(this.http["httpService"], this.mqtt["mqttService"]);
|
|
189
147
|
this._tag = new Tag(this.http["httpService"], this.mqtt["mqttService"]);
|
|
190
|
-
this._function = new Function(this.http["httpService"], this.nats["natsService"]);
|
|
191
148
|
this._flow = new Flow(this.http["httpService"]);
|
|
192
149
|
this._auth = new Auth(this.http["httpService"], this.applicationID);
|
|
193
150
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@machhub-dev/sdk-ts",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "MACHHUB TYPESCRIPT SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"machhub",
|
|
@@ -20,8 +20,6 @@
|
|
|
20
20
|
"build": "npx tsc && npx tsc --module CommonJS --outDir dist/cjs"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@nats-io/nats-core": "^3.0.2",
|
|
24
|
-
"@nats-io/transport-node": "^3.0.2",
|
|
25
23
|
"jwt-decode": "^4.0.0",
|
|
26
24
|
"mqtt": "^5.10.4",
|
|
27
25
|
"safe-buffer": "^5.2.1",
|
package/src/sdk-ts.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { HTTPService } from "./services/http.service.js";
|
|
2
2
|
import { MQTTService } from "./services/mqtt.service.js";
|
|
3
|
-
import { NATSService } from "./services/nats.service.js";
|
|
4
3
|
import { Collection } from "./classes/collection.js";
|
|
5
4
|
import { Historian } from "./classes/historian.js";
|
|
6
5
|
import { Tag } from "./classes/tag.js";
|
|
7
|
-
import { Function } from "./classes/function.js";
|
|
8
6
|
import { Flow } from "./classes/flow.js";
|
|
9
7
|
import { Auth } from "./classes/auth.js";
|
|
10
8
|
|
|
@@ -78,60 +76,17 @@ class MQTTClient {
|
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
// Core NATS client class
|
|
82
|
-
class NATSClient {
|
|
83
|
-
private natsService: NATSService;
|
|
84
|
-
private static instance: NATSClient | undefined;
|
|
85
|
-
|
|
86
|
-
private constructor(natsService: NATSService) {
|
|
87
|
-
this.natsService = natsService;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Creates a new NATSClient instance
|
|
92
|
-
* @param applicationID The ID for your application
|
|
93
|
-
* @param natsUrl The base URL for NATS connection (default = ws://localhost:7500)
|
|
94
|
-
*/
|
|
95
|
-
static async getInstance(applicationID?: string, natsUrl: string = "ws://localhost:7500"): Promise<NATSClient> {
|
|
96
|
-
if (!this.instance) {
|
|
97
|
-
const natsService = await NATSService.getInstance(natsUrl);
|
|
98
|
-
this.instance = new NATSClient(natsService);
|
|
99
|
-
}
|
|
100
|
-
return this.instance;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Subscribes to subject updates
|
|
105
|
-
* @param subject The subject to subscribe to
|
|
106
|
-
* @param callback The callback function for data updates
|
|
107
|
-
*/
|
|
108
|
-
async subscribe(subject: string, callback: (data: any) => void): Promise<any> {
|
|
109
|
-
return this.natsService.addSubjectHandler(subject, callback);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Publishes a message to a specific subject
|
|
114
|
-
* @param subject The subject to publish to
|
|
115
|
-
* @param data The data to publish
|
|
116
|
-
*/
|
|
117
|
-
async publish(subject: string, data: any): Promise<any> {
|
|
118
|
-
return this.natsService.publish(subject, data);
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
79
|
export interface SDKConfig {
|
|
123
80
|
application_id: string;
|
|
124
81
|
developer_key?: string;
|
|
125
82
|
httpUrl?: string;
|
|
126
83
|
mqttUrl?: string;
|
|
127
|
-
natsUrl?: string;
|
|
128
84
|
}
|
|
129
85
|
|
|
130
86
|
// SDK Class
|
|
131
87
|
export class SDK {
|
|
132
88
|
private http: HTTPClient | null = null;
|
|
133
89
|
private mqtt: MQTTClient | null = null;
|
|
134
|
-
private nats: NATSClient | null = null;
|
|
135
90
|
private _historian: Historian | null = null;
|
|
136
91
|
private _tag: Tag | null = null;
|
|
137
92
|
private _function: Function | null = null;
|
|
@@ -162,7 +117,6 @@ export class SDK {
|
|
|
162
117
|
* application_id: 'your-app-id',
|
|
163
118
|
* httpUrl: 'http://localhost:6188', // optional (default = http://localhost:6188)
|
|
164
119
|
* mqttUrl: 'ws://localhost:180', // optional (default = ws://localhost:180)
|
|
165
|
-
* natsUrl: 'ws://localhost:7500', // optional (default = ws://localhost:7500)
|
|
166
120
|
* };
|
|
167
121
|
*
|
|
168
122
|
* const sdk = new SDK();
|
|
@@ -186,9 +140,9 @@ export class SDK {
|
|
|
186
140
|
const envCfg = await getEnvConfig();
|
|
187
141
|
|
|
188
142
|
// Extract application_id from runtimeID if not provided in config
|
|
189
|
-
const application_id = config.application_id ||
|
|
190
|
-
|
|
191
|
-
|
|
143
|
+
const application_id = config.application_id ||
|
|
144
|
+
this.extractApplicationIDFromRuntimeID(envCfg.runtimeID);
|
|
145
|
+
|
|
192
146
|
this.applicationID = application_id;
|
|
193
147
|
|
|
194
148
|
// Determine the hostname - use window.location.hostname in browser, otherwise fallback to localhost
|
|
@@ -210,21 +164,15 @@ export class SDK {
|
|
|
210
164
|
config.mqttUrl = `${secured ? 'wss' : 'ws'}://${host}/mqtt`;
|
|
211
165
|
}
|
|
212
166
|
|
|
213
|
-
|
|
214
|
-
config.natsUrl = `${secured ? 'wss' : 'ws'}://${host}/nats`;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const { httpUrl, mqttUrl, natsUrl } = config;
|
|
167
|
+
const { httpUrl, mqttUrl } = config;
|
|
218
168
|
|
|
219
|
-
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl,
|
|
169
|
+
console.log("SDK Config:", { application_id: this.applicationID, httpUrl, mqttUrl, developer_key: config.developer_key?.split('').map((_, i) => i < config!.developer_key!.length - 4 ? '*' : config!.developer_key![i]).join('') });
|
|
220
170
|
|
|
221
171
|
this.http = new HTTPClient(this.applicationID, httpUrl, config.developer_key, envCfg.runtimeID);
|
|
222
172
|
this.mqtt = await MQTTClient.getInstance(this.applicationID, mqttUrl, config.developer_key);
|
|
223
|
-
this.nats = await NATSClient.getInstance(this.applicationID, natsUrl);
|
|
224
173
|
|
|
225
174
|
this._historian = new Historian(this.http["httpService"], this.mqtt["mqttService"]);
|
|
226
175
|
this._tag = new Tag(this.http["httpService"], this.mqtt["mqttService"]);
|
|
227
|
-
this._function = new Function(this.http["httpService"], this.nats["natsService"]);
|
|
228
176
|
this._flow = new Flow(this.http["httpService"]);
|
|
229
177
|
this._auth = new Auth(this.http["httpService"], this.applicationID);
|
|
230
178
|
} catch (error: any) {
|
|
@@ -355,7 +303,7 @@ async function findConfigEndpoint(): Promise<string> {
|
|
|
355
303
|
'Accept': 'application/json',
|
|
356
304
|
},
|
|
357
305
|
signal: AbortSignal.timeout(2000)
|
|
358
|
-
}).catch(() => {console.log("ERR"); return null}); // Catch fetch errors silently
|
|
306
|
+
}).catch(() => { console.log("ERR"); return null }); // Catch fetch errors silently
|
|
359
307
|
|
|
360
308
|
if (!testResponse || !testResponse.ok) {
|
|
361
309
|
continue; // Skip to next candidate
|
package/src/classes/function.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { HTTPService } from "../services/http.service.js";
|
|
2
|
-
import { NATSService } from "../services/nats.service.js";
|
|
3
|
-
|
|
4
|
-
export class Function {
|
|
5
|
-
private httpService: HTTPService;
|
|
6
|
-
private natsService: NATSService | null;
|
|
7
|
-
|
|
8
|
-
constructor(httpService: HTTPService, natsService: NATSService) {
|
|
9
|
-
this.httpService = httpService;
|
|
10
|
-
this.natsService = natsService;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public async executeFunction(function_type: string, function_name: string, payload: any): Promise<any> {
|
|
14
|
-
return await this.httpService.request.withJSON({
|
|
15
|
-
function_type: function_type,
|
|
16
|
-
function_name: function_name,
|
|
17
|
-
payload: payload,
|
|
18
|
-
}).post("function/execute");
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
public async addFunction(name: string, func: (data: Record<string,any>) => Record<string,any>): Promise<any> {
|
|
22
|
-
if (!this.natsService) {
|
|
23
|
-
throw new Error("NATS service not connected");
|
|
24
|
-
}
|
|
25
|
-
return this.natsService.addFunction(name, func);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
public async initializeFunctions(): Promise<any> {
|
|
29
|
-
if (!this.natsService) {
|
|
30
|
-
throw new Error("NATS service not connected");
|
|
31
|
-
}
|
|
32
|
-
return this.natsService.initializeFunctions();
|
|
33
|
-
}
|
|
34
|
-
}
|
package/src/example/functions.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { SDK, SDKConfig } from "../index.js";
|
|
2
|
-
|
|
3
|
-
let sdk = new SDK();
|
|
4
|
-
let config: SDKConfig = {
|
|
5
|
-
application_id: "machhub_admin",
|
|
6
|
-
natsUrl: "nats://localhost:4222",
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
(async () => {
|
|
10
|
-
await sdk.Initialize(config);
|
|
11
|
-
|
|
12
|
-
function add10(data: Record<string,any>): Record<string,any>{
|
|
13
|
-
data.result = data.a + 10;
|
|
14
|
-
console.log("Function add executed with data:", data);
|
|
15
|
-
return data
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
sdk.function.addFunction("add", add10);
|
|
19
|
-
|
|
20
|
-
await sdk.function.initializeFunctions();
|
|
21
|
-
})();
|
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import { NatsConnection, Subscription, wsconnect } from "@nats-io/nats-core";
|
|
2
|
-
import { connect } from "@nats-io/transport-node";
|
|
3
|
-
|
|
4
|
-
const HEALTH_SUBJECT = "runtime.typescript.health";
|
|
5
|
-
|
|
6
|
-
interface SubscribedSubject {
|
|
7
|
-
subject: string;
|
|
8
|
-
handler: (message: unknown) => void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export class NATSService {
|
|
12
|
-
private url!: string;
|
|
13
|
-
private functions: Record<string, (data: Record<string, any>) => Promise<Record<string, any>> | Record<string, any>> = {};
|
|
14
|
-
private connection: NatsConnection | null = null;
|
|
15
|
-
private static instance: NATSService | undefined;
|
|
16
|
-
private subscribedSubjects: SubscribedSubject[] = [];
|
|
17
|
-
private subscriptions: Subscription[] = [];
|
|
18
|
-
private readonly EXEC_FUNCTION_SUBJECT = "runtime.exec.typescript.*";
|
|
19
|
-
|
|
20
|
-
constructor(url: string) {
|
|
21
|
-
this.url = url;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Returns a singleton instance of NATSService.
|
|
26
|
-
*/
|
|
27
|
-
static async getInstance(url: string = "ws://localhost:7500"): Promise<NATSService> {
|
|
28
|
-
if (!this.instance || !this.instance.connection) {
|
|
29
|
-
this.instance = new NATSService(url);
|
|
30
|
-
await this.instance.connect();
|
|
31
|
-
}
|
|
32
|
-
return this.instance;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Resets the singleton instance.
|
|
37
|
-
*/
|
|
38
|
-
public static resetInstance(): void {
|
|
39
|
-
if (this.instance) {
|
|
40
|
-
this.instance.connection?.close();
|
|
41
|
-
this.instance = undefined;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Connects to the NATS broker.
|
|
47
|
-
*/
|
|
48
|
-
private async connect(): Promise<void> {
|
|
49
|
-
let retries = 0;
|
|
50
|
-
const maxRetries = 10;
|
|
51
|
-
|
|
52
|
-
while (!this.connection && retries < maxRetries) {
|
|
53
|
-
try {
|
|
54
|
-
// NATSService.log(`Connecting to NATS server (${this.url})...`);
|
|
55
|
-
if (this.url.startsWith("nats")) {
|
|
56
|
-
this.connection = await connect({ servers: this.url });
|
|
57
|
-
} else if (this.url.startsWith("ws")) {
|
|
58
|
-
this.connection = await wsconnect({ servers: this.url });
|
|
59
|
-
} else {
|
|
60
|
-
NATSService.log("ERROR - Unsupported protocol : ", this.url.split("://")[0]);
|
|
61
|
-
}
|
|
62
|
-
this.connection?.publish(HEALTH_SUBJECT, JSON.stringify(true));
|
|
63
|
-
// NATSService.log(`Published message: true to ${HEALTH_SUBJECT}`);
|
|
64
|
-
// NATSService.log("Connected to NATS server");
|
|
65
|
-
} catch (err: any) {
|
|
66
|
-
NATSService.log("Caught an error during connection attempt:", err); // Debugging log
|
|
67
|
-
retries++;
|
|
68
|
-
console.error(`Failed to connect to NATS server. Retrying (${retries}/${maxRetries})...`, err);
|
|
69
|
-
if (retries >= maxRetries) {
|
|
70
|
-
throw new Error("Max retries reached. Unable to connect to NATS server.");
|
|
71
|
-
}
|
|
72
|
-
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (!this.connection) {
|
|
77
|
-
throw new Error("Failed to establish a connection to the NATS server.");
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Adds a subject and handler to the subscribed list.
|
|
83
|
-
* @param subject {string} The subject to subscribe to.
|
|
84
|
-
* @param handler {(message: unknown) => void} The handler function for incoming messages.
|
|
85
|
-
*/
|
|
86
|
-
public addSubjectHandler(subject: string, handler: (message: unknown) => void): void {
|
|
87
|
-
try {
|
|
88
|
-
this.subscribedSubjects.push({ subject, handler });
|
|
89
|
-
NATSService.log("New Subscription Handler:", subject);
|
|
90
|
-
|
|
91
|
-
const sub = this.connection?.subscribe(subject, {
|
|
92
|
-
callback: (err, msg) => {
|
|
93
|
-
if (err) {
|
|
94
|
-
console.error(`Error handling message for subject ${subject}:`, err);
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
const parsedMessage = this.parseMessage(msg.data);
|
|
98
|
-
handler(parsedMessage);
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
if (sub) this.subscriptions.push(sub);
|
|
102
|
-
} catch (e) {
|
|
103
|
-
console.error(`Failed to subscribe to subject ${subject}:`, e);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Subscribes to the EXEC_FUNCTION_SUBJECT and executes registered functions.
|
|
109
|
-
*/
|
|
110
|
-
public initializeFunctions(): boolean {
|
|
111
|
-
if (!this.connection) {
|
|
112
|
-
throw new Error("No active connection. Please connect to the NATS server first.");
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const sub = this.connection.subscribe(this.EXEC_FUNCTION_SUBJECT, {
|
|
116
|
-
callback: (err, msg) => {
|
|
117
|
-
if (err) {
|
|
118
|
-
console.error("Error handling message:", err);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
const dataStr = Buffer.from(msg.data).toString('utf-8');
|
|
124
|
-
const data = JSON.parse(dataStr) as Record<string, any>;
|
|
125
|
-
const subjectParts = msg.subject.split(".");
|
|
126
|
-
if (subjectParts.length !== 4) {
|
|
127
|
-
msg.respond(JSON.stringify({ error: "Invalid subject format" }));
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
const functionName = subjectParts[3];
|
|
132
|
-
this.executeFunction(functionName, data)
|
|
133
|
-
.then((result) => {
|
|
134
|
-
msg.respond(JSON.stringify(result));
|
|
135
|
-
})
|
|
136
|
-
.catch((e: any) => {
|
|
137
|
-
console.log("Error executing function '" + functionName + "': ", e);
|
|
138
|
-
msg.respond(JSON.stringify({ status: "failed", error: e.message }));
|
|
139
|
-
});
|
|
140
|
-
} catch (parseError: any) {
|
|
141
|
-
console.error("Error parsing function execution message:", parseError);
|
|
142
|
-
msg.respond(JSON.stringify({
|
|
143
|
-
status: "failed",
|
|
144
|
-
error: `Failed to parse message: ${parseError.message}`
|
|
145
|
-
}));
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
if (sub) this.subscriptions.push(sub);
|
|
150
|
-
|
|
151
|
-
NATSService.log(`Subscribed to '${this.EXEC_FUNCTION_SUBJECT}'`);
|
|
152
|
-
return true;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* Adds a new function to the registry.
|
|
157
|
-
* @param functionName {string} The name of the function to add.
|
|
158
|
-
* @param func {(data: Record<string, any>) => Promise<Record<string, any>> | Record<string, any>} The function implementation.
|
|
159
|
-
* @throws TypeError if the provided argument is not a function.
|
|
160
|
-
*/
|
|
161
|
-
public addFunction(
|
|
162
|
-
functionName: string,
|
|
163
|
-
func: (data: Record<string, any>) => Promise<Record<string, any>> | Record<string, any>
|
|
164
|
-
): void {
|
|
165
|
-
if (typeof func !== "function") {
|
|
166
|
-
throw new TypeError(`The provided argument '${functionName}' is not a function.`);
|
|
167
|
-
}
|
|
168
|
-
this.functions[functionName] = func;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Executes a registered function by name with the provided arguments.
|
|
173
|
-
* @param functionName {string} The name of the function to execute.
|
|
174
|
-
* @param arg {Record<string, any>} The arguments to pass to the function. (JSON)
|
|
175
|
-
* @returns {Promise<Record<string, any>>} The result of the function execution. (JSON)
|
|
176
|
-
* @throws Error if the function is not found.
|
|
177
|
-
*/
|
|
178
|
-
public async executeFunction(
|
|
179
|
-
functionName: string,
|
|
180
|
-
arg: Record<string, any>
|
|
181
|
-
): Promise<Record<string, any>> {
|
|
182
|
-
const func = this.functions[functionName];
|
|
183
|
-
if (!func) {
|
|
184
|
-
throw new Error(`Function '${functionName}' not found`);
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
return await func(arg);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Clears all subscribed subjects.
|
|
192
|
-
*/
|
|
193
|
-
public clearSubjects(): void {
|
|
194
|
-
this.subscribedSubjects = [];
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Publishes a message to a specific subject.
|
|
199
|
-
* @param subject {string} The subject to publish to.
|
|
200
|
-
* @param message {unknown} The message to publish.
|
|
201
|
-
* @returns {boolean} True if the message was published successfully.
|
|
202
|
-
*/
|
|
203
|
-
public publish(subject: string, message: unknown): boolean {
|
|
204
|
-
try {
|
|
205
|
-
const payload = JSON.stringify(message);
|
|
206
|
-
NATSService.log("Publishing to", subject, "with payload:", payload);
|
|
207
|
-
|
|
208
|
-
this.connection?.publish(subject, payload);
|
|
209
|
-
} catch (e) {
|
|
210
|
-
console.error(`Failed to publish to subject ${subject}:`, e);
|
|
211
|
-
throw e;
|
|
212
|
-
}
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Retrieves all registered functions.
|
|
218
|
-
* @returns {Record<string, (data: Record<string, any>) => Record<string, any>} An object containing all registered functions.
|
|
219
|
-
*/
|
|
220
|
-
public getAllFunctions(): Record<string, (data: Record<string, any>) => Record<string, any>> {
|
|
221
|
-
return this.functions;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
public static log(message?: any, ...optionalParams: any[]) {
|
|
225
|
-
console.log("[TYPESCRIPT] >", message, ...optionalParams);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Prints the names of all available functions to the console.
|
|
230
|
-
*/
|
|
231
|
-
public printFunctions(): void {
|
|
232
|
-
NATSService.log("Available functions: ", Object.keys(this.functions).join(", "));
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Parses a message buffer into a JSON object or returns raw data.
|
|
237
|
-
* @param message {Uint8Array} The message buffer.
|
|
238
|
-
* @returns {unknown} The parsed message (JSON object) or the raw string if parsing fails.
|
|
239
|
-
*/
|
|
240
|
-
private parseMessage(message: Uint8Array): unknown {
|
|
241
|
-
try {
|
|
242
|
-
const messageStr = Buffer.from(message).toString('utf-8');
|
|
243
|
-
// Check if the message is empty
|
|
244
|
-
if (!messageStr || messageStr.trim().length === 0) {
|
|
245
|
-
NATSService.log("Received empty message");
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// Try to parse as JSON
|
|
250
|
-
return JSON.parse(messageStr);
|
|
251
|
-
} catch (error) {
|
|
252
|
-
// If JSON parsing fails, check if it's binary data or non-JSON content
|
|
253
|
-
const messageStr = Buffer.from(message).toString('utf-8');
|
|
254
|
-
|
|
255
|
-
// Check if it looks like binary data (contains non-printable characters)
|
|
256
|
-
const isBinary = message.some(byte => byte < 32 && byte !== 9 && byte !== 10 && byte !== 13);
|
|
257
|
-
|
|
258
|
-
if (isBinary) {
|
|
259
|
-
NATSService.log("Received binary data, returning as Uint8Array");
|
|
260
|
-
return message; // Return raw binary data
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// If it's a plain string (not JSON), return as is
|
|
264
|
-
NATSService.log("Failed to parse message as JSON, returning as string:", messageStr.substring(0, 100));
|
|
265
|
-
console.error("Error parsing message:", error);
|
|
266
|
-
return messageStr;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Gracefully unsubscribes from all NATS subscriptions and closes the connection.
|
|
272
|
-
*/
|
|
273
|
-
public async shutdown(): Promise<void> {
|
|
274
|
-
NATSService.log("Shutting down NATSService...");
|
|
275
|
-
for (const sub of this.subscriptions) {
|
|
276
|
-
try {
|
|
277
|
-
sub.unsubscribe();
|
|
278
|
-
} catch (e) {
|
|
279
|
-
NATSService.log("Error unsubscribing:", e);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
this.subscriptions = [];
|
|
283
|
-
if (this.connection) {
|
|
284
|
-
try {
|
|
285
|
-
await this.connection.drain();
|
|
286
|
-
await this.connection.close();
|
|
287
|
-
} catch (e) {
|
|
288
|
-
NATSService.log("Error closing NATS connection:", e);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
NATSService.log("NATSService shutdown complete.");
|
|
292
|
-
}
|
|
293
|
-
}
|