@superatomai/sdk-node 0.0.29 → 0.0.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +17 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +66 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +66 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -9737,6 +9737,7 @@ init_logger();
|
|
|
9737
9737
|
var SDK_VERSION = "0.0.8";
|
|
9738
9738
|
var DEFAULT_WS_URL = "wss://ws.superatom.ai/websocket";
|
|
9739
9739
|
var SuperatomSDK = class {
|
|
9740
|
+
// 3.5 minutes (PING_INTERVAL + 30s grace)
|
|
9740
9741
|
constructor(config) {
|
|
9741
9742
|
this.ws = null;
|
|
9742
9743
|
this.messageHandlers = /* @__PURE__ */ new Map();
|
|
@@ -9747,6 +9748,12 @@ var SuperatomSDK = class {
|
|
|
9747
9748
|
this.collections = {};
|
|
9748
9749
|
this.components = [];
|
|
9749
9750
|
this.tools = [];
|
|
9751
|
+
// Heartbeat properties for keeping WebSocket connection alive
|
|
9752
|
+
this.pingInterval = null;
|
|
9753
|
+
this.lastPong = Date.now();
|
|
9754
|
+
this.PING_INTERVAL_MS = 18e4;
|
|
9755
|
+
// 3 minutes
|
|
9756
|
+
this.PONG_TIMEOUT_MS = 21e4;
|
|
9750
9757
|
if (config.logLevel) {
|
|
9751
9758
|
logger.setLogLevel(config.logLevel);
|
|
9752
9759
|
}
|
|
@@ -9860,6 +9867,7 @@ var SuperatomSDK = class {
|
|
|
9860
9867
|
this.connected = true;
|
|
9861
9868
|
this.reconnectAttempts = 0;
|
|
9862
9869
|
logger.info("WebSocket connected successfully");
|
|
9870
|
+
this.startHeartbeat();
|
|
9863
9871
|
resolve();
|
|
9864
9872
|
});
|
|
9865
9873
|
this.ws.addEventListener("message", (event) => {
|
|
@@ -9888,6 +9896,9 @@ var SuperatomSDK = class {
|
|
|
9888
9896
|
const message = IncomingMessageSchema.parse(parsed);
|
|
9889
9897
|
logger.debug("Received message:", message.type);
|
|
9890
9898
|
switch (message.type) {
|
|
9899
|
+
case "PONG":
|
|
9900
|
+
this.handlePong();
|
|
9901
|
+
break;
|
|
9891
9902
|
case "DATA_REQ":
|
|
9892
9903
|
handleDataRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
|
|
9893
9904
|
logger.error("Failed to handle data request:", error);
|
|
@@ -10010,6 +10021,7 @@ var SuperatomSDK = class {
|
|
|
10010
10021
|
* Disconnect from the WebSocket service
|
|
10011
10022
|
*/
|
|
10012
10023
|
disconnect() {
|
|
10024
|
+
this.stopHeartbeat();
|
|
10013
10025
|
if (this.ws) {
|
|
10014
10026
|
this.ws.close();
|
|
10015
10027
|
this.ws = null;
|
|
@@ -10020,6 +10032,7 @@ var SuperatomSDK = class {
|
|
|
10020
10032
|
* Cleanup and disconnect - stops reconnection attempts and closes the connection
|
|
10021
10033
|
*/
|
|
10022
10034
|
async destroy() {
|
|
10035
|
+
this.stopHeartbeat();
|
|
10023
10036
|
this.maxReconnectAttempts = 0;
|
|
10024
10037
|
this.reconnectAttempts = 0;
|
|
10025
10038
|
this.messageHandlers.clear();
|
|
@@ -10061,6 +10074,59 @@ var SuperatomSDK = class {
|
|
|
10061
10074
|
logger.error("Max reconnection attempts reached");
|
|
10062
10075
|
}
|
|
10063
10076
|
}
|
|
10077
|
+
/**
|
|
10078
|
+
* Start heartbeat to keep WebSocket connection alive
|
|
10079
|
+
* Sends PING every 3 minutes to prevent idle timeout from cloud infrastructure
|
|
10080
|
+
*/
|
|
10081
|
+
startHeartbeat() {
|
|
10082
|
+
this.stopHeartbeat();
|
|
10083
|
+
this.lastPong = Date.now();
|
|
10084
|
+
this.pingInterval = setInterval(() => {
|
|
10085
|
+
if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
|
|
10086
|
+
logger.warn("WebSocket not open during heartbeat check, stopping heartbeat");
|
|
10087
|
+
this.stopHeartbeat();
|
|
10088
|
+
return;
|
|
10089
|
+
}
|
|
10090
|
+
const timeSinceLastPong = Date.now() - this.lastPong;
|
|
10091
|
+
if (timeSinceLastPong > this.PONG_TIMEOUT_MS) {
|
|
10092
|
+
logger.warn(`No PONG received for ${timeSinceLastPong}ms, connection may be dead. Reconnecting...`);
|
|
10093
|
+
this.stopHeartbeat();
|
|
10094
|
+
this.ws.close();
|
|
10095
|
+
return;
|
|
10096
|
+
}
|
|
10097
|
+
try {
|
|
10098
|
+
const pingMessage = {
|
|
10099
|
+
type: "PING",
|
|
10100
|
+
from: { type: this.type },
|
|
10101
|
+
payload: { timestamp: Date.now() }
|
|
10102
|
+
};
|
|
10103
|
+
this.ws.send(JSON.stringify(pingMessage));
|
|
10104
|
+
logger.debug("Heartbeat PING sent");
|
|
10105
|
+
} catch (error) {
|
|
10106
|
+
logger.error("Failed to send PING:", error);
|
|
10107
|
+
this.stopHeartbeat();
|
|
10108
|
+
this.ws.close();
|
|
10109
|
+
}
|
|
10110
|
+
}, this.PING_INTERVAL_MS);
|
|
10111
|
+
logger.info(`Heartbeat started (PING every ${this.PING_INTERVAL_MS / 1e3}s)`);
|
|
10112
|
+
}
|
|
10113
|
+
/**
|
|
10114
|
+
* Stop the heartbeat interval
|
|
10115
|
+
*/
|
|
10116
|
+
stopHeartbeat() {
|
|
10117
|
+
if (this.pingInterval) {
|
|
10118
|
+
clearInterval(this.pingInterval);
|
|
10119
|
+
this.pingInterval = null;
|
|
10120
|
+
logger.debug("Heartbeat stopped");
|
|
10121
|
+
}
|
|
10122
|
+
}
|
|
10123
|
+
/**
|
|
10124
|
+
* Handle PONG response from server
|
|
10125
|
+
*/
|
|
10126
|
+
handlePong() {
|
|
10127
|
+
this.lastPong = Date.now();
|
|
10128
|
+
logger.debug("Heartbeat PONG received");
|
|
10129
|
+
}
|
|
10064
10130
|
storeComponents(components) {
|
|
10065
10131
|
this.components = components;
|
|
10066
10132
|
}
|