@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 CHANGED
@@ -1650,6 +1650,10 @@ declare class SuperatomSDK {
1650
1650
  private userManager;
1651
1651
  private dashboardManager;
1652
1652
  private reportManager;
1653
+ private pingInterval;
1654
+ private lastPong;
1655
+ private readonly PING_INTERVAL_MS;
1656
+ private readonly PONG_TIMEOUT_MS;
1653
1657
  constructor(config: SuperatomSDKConfig);
1654
1658
  /**
1655
1659
  * Initialize PromptLoader and load prompts into memory
@@ -1717,6 +1721,19 @@ declare class SuperatomSDK {
1717
1721
  */
1718
1722
  addCollection<TParams = any, TResult = any>(collectionName: string, operation: CollectionOperation | string, handler: CollectionHandler<TParams, TResult>): void;
1719
1723
  private handleReconnect;
1724
+ /**
1725
+ * Start heartbeat to keep WebSocket connection alive
1726
+ * Sends PING every 3 minutes to prevent idle timeout from cloud infrastructure
1727
+ */
1728
+ private startHeartbeat;
1729
+ /**
1730
+ * Stop the heartbeat interval
1731
+ */
1732
+ private stopHeartbeat;
1733
+ /**
1734
+ * Handle PONG response from server
1735
+ */
1736
+ private handlePong;
1720
1737
  private storeComponents;
1721
1738
  /**
1722
1739
  * Set tools for the SDK instance
package/dist/index.d.ts CHANGED
@@ -1650,6 +1650,10 @@ declare class SuperatomSDK {
1650
1650
  private userManager;
1651
1651
  private dashboardManager;
1652
1652
  private reportManager;
1653
+ private pingInterval;
1654
+ private lastPong;
1655
+ private readonly PING_INTERVAL_MS;
1656
+ private readonly PONG_TIMEOUT_MS;
1653
1657
  constructor(config: SuperatomSDKConfig);
1654
1658
  /**
1655
1659
  * Initialize PromptLoader and load prompts into memory
@@ -1717,6 +1721,19 @@ declare class SuperatomSDK {
1717
1721
  */
1718
1722
  addCollection<TParams = any, TResult = any>(collectionName: string, operation: CollectionOperation | string, handler: CollectionHandler<TParams, TResult>): void;
1719
1723
  private handleReconnect;
1724
+ /**
1725
+ * Start heartbeat to keep WebSocket connection alive
1726
+ * Sends PING every 3 minutes to prevent idle timeout from cloud infrastructure
1727
+ */
1728
+ private startHeartbeat;
1729
+ /**
1730
+ * Stop the heartbeat interval
1731
+ */
1732
+ private stopHeartbeat;
1733
+ /**
1734
+ * Handle PONG response from server
1735
+ */
1736
+ private handlePong;
1720
1737
  private storeComponents;
1721
1738
  /**
1722
1739
  * Set tools for the SDK instance
package/dist/index.js CHANGED
@@ -9781,6 +9781,7 @@ init_logger();
9781
9781
  var SDK_VERSION = "0.0.8";
9782
9782
  var DEFAULT_WS_URL = "wss://ws.superatom.ai/websocket";
9783
9783
  var SuperatomSDK = class {
9784
+ // 3.5 minutes (PING_INTERVAL + 30s grace)
9784
9785
  constructor(config) {
9785
9786
  this.ws = null;
9786
9787
  this.messageHandlers = /* @__PURE__ */ new Map();
@@ -9791,6 +9792,12 @@ var SuperatomSDK = class {
9791
9792
  this.collections = {};
9792
9793
  this.components = [];
9793
9794
  this.tools = [];
9795
+ // Heartbeat properties for keeping WebSocket connection alive
9796
+ this.pingInterval = null;
9797
+ this.lastPong = Date.now();
9798
+ this.PING_INTERVAL_MS = 18e4;
9799
+ // 3 minutes
9800
+ this.PONG_TIMEOUT_MS = 21e4;
9794
9801
  if (config.logLevel) {
9795
9802
  logger.setLogLevel(config.logLevel);
9796
9803
  }
@@ -9904,6 +9911,7 @@ var SuperatomSDK = class {
9904
9911
  this.connected = true;
9905
9912
  this.reconnectAttempts = 0;
9906
9913
  logger.info("WebSocket connected successfully");
9914
+ this.startHeartbeat();
9907
9915
  resolve();
9908
9916
  });
9909
9917
  this.ws.addEventListener("message", (event) => {
@@ -9932,6 +9940,9 @@ var SuperatomSDK = class {
9932
9940
  const message = IncomingMessageSchema.parse(parsed);
9933
9941
  logger.debug("Received message:", message.type);
9934
9942
  switch (message.type) {
9943
+ case "PONG":
9944
+ this.handlePong();
9945
+ break;
9935
9946
  case "DATA_REQ":
9936
9947
  handleDataRequest(parsed, this.collections, (msg) => this.send(msg)).catch((error) => {
9937
9948
  logger.error("Failed to handle data request:", error);
@@ -10054,6 +10065,7 @@ var SuperatomSDK = class {
10054
10065
  * Disconnect from the WebSocket service
10055
10066
  */
10056
10067
  disconnect() {
10068
+ this.stopHeartbeat();
10057
10069
  if (this.ws) {
10058
10070
  this.ws.close();
10059
10071
  this.ws = null;
@@ -10064,6 +10076,7 @@ var SuperatomSDK = class {
10064
10076
  * Cleanup and disconnect - stops reconnection attempts and closes the connection
10065
10077
  */
10066
10078
  async destroy() {
10079
+ this.stopHeartbeat();
10067
10080
  this.maxReconnectAttempts = 0;
10068
10081
  this.reconnectAttempts = 0;
10069
10082
  this.messageHandlers.clear();
@@ -10105,6 +10118,59 @@ var SuperatomSDK = class {
10105
10118
  logger.error("Max reconnection attempts reached");
10106
10119
  }
10107
10120
  }
10121
+ /**
10122
+ * Start heartbeat to keep WebSocket connection alive
10123
+ * Sends PING every 3 minutes to prevent idle timeout from cloud infrastructure
10124
+ */
10125
+ startHeartbeat() {
10126
+ this.stopHeartbeat();
10127
+ this.lastPong = Date.now();
10128
+ this.pingInterval = setInterval(() => {
10129
+ if (!this.ws || this.ws.readyState !== this.ws.OPEN) {
10130
+ logger.warn("WebSocket not open during heartbeat check, stopping heartbeat");
10131
+ this.stopHeartbeat();
10132
+ return;
10133
+ }
10134
+ const timeSinceLastPong = Date.now() - this.lastPong;
10135
+ if (timeSinceLastPong > this.PONG_TIMEOUT_MS) {
10136
+ logger.warn(`No PONG received for ${timeSinceLastPong}ms, connection may be dead. Reconnecting...`);
10137
+ this.stopHeartbeat();
10138
+ this.ws.close();
10139
+ return;
10140
+ }
10141
+ try {
10142
+ const pingMessage = {
10143
+ type: "PING",
10144
+ from: { type: this.type },
10145
+ payload: { timestamp: Date.now() }
10146
+ };
10147
+ this.ws.send(JSON.stringify(pingMessage));
10148
+ logger.debug("Heartbeat PING sent");
10149
+ } catch (error) {
10150
+ logger.error("Failed to send PING:", error);
10151
+ this.stopHeartbeat();
10152
+ this.ws.close();
10153
+ }
10154
+ }, this.PING_INTERVAL_MS);
10155
+ logger.info(`Heartbeat started (PING every ${this.PING_INTERVAL_MS / 1e3}s)`);
10156
+ }
10157
+ /**
10158
+ * Stop the heartbeat interval
10159
+ */
10160
+ stopHeartbeat() {
10161
+ if (this.pingInterval) {
10162
+ clearInterval(this.pingInterval);
10163
+ this.pingInterval = null;
10164
+ logger.debug("Heartbeat stopped");
10165
+ }
10166
+ }
10167
+ /**
10168
+ * Handle PONG response from server
10169
+ */
10170
+ handlePong() {
10171
+ this.lastPong = Date.now();
10172
+ logger.debug("Heartbeat PONG received");
10173
+ }
10108
10174
  storeComponents(components) {
10109
10175
  this.components = components;
10110
10176
  }