@fluxstack/live-client 0.5.1 → 0.6.1

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.cjs CHANGED
@@ -37,7 +37,7 @@ __export(index_exports, {
37
37
  module.exports = __toCommonJS(index_exports);
38
38
 
39
39
  // src/connection.ts
40
- var LiveConnection = class {
40
+ var LiveConnection = class _LiveConnection {
41
41
  ws = null;
42
42
  options;
43
43
  reconnectAttempts = 0;
@@ -199,18 +199,34 @@ var LiveConnection = class {
199
199
  this.setState({ error: "Max reconnection attempts reached" });
200
200
  }
201
201
  }
202
+ consecutiveHeartbeatFailures = 0;
203
+ static MAX_HEARTBEAT_FAILURES = 3;
202
204
  startHeartbeat() {
203
205
  this.stopHeartbeat();
206
+ this.consecutiveHeartbeatFailures = 0;
204
207
  this.heartbeatInterval = setInterval(() => {
205
208
  if (this.ws?.readyState === WebSocket.OPEN) {
209
+ let failed = false;
206
210
  for (const componentId of this.componentCallbacks.keys()) {
207
211
  this.sendMessage({
208
212
  type: "COMPONENT_PING",
209
213
  componentId,
210
214
  timestamp: Date.now()
211
215
  }).catch(() => {
216
+ failed = true;
212
217
  });
213
218
  }
219
+ if (failed) {
220
+ this.consecutiveHeartbeatFailures++;
221
+ this.log(`Heartbeat failed (${this.consecutiveHeartbeatFailures}/${_LiveConnection.MAX_HEARTBEAT_FAILURES})`);
222
+ if (this.consecutiveHeartbeatFailures >= _LiveConnection.MAX_HEARTBEAT_FAILURES) {
223
+ this.log("Too many heartbeat failures, reconnecting...");
224
+ this.setState({ error: "Heartbeat failed" });
225
+ this.reconnect();
226
+ }
227
+ } else {
228
+ this.consecutiveHeartbeatFailures = 0;
229
+ }
214
230
  }
215
231
  }, this.options.heartbeatInterval);
216
232
  }
@@ -438,6 +454,10 @@ function deepMerge(target, source, seen) {
438
454
  const result = { ...target };
439
455
  for (const key of Object.keys(source)) {
440
456
  const newVal = source[key];
457
+ if (newVal === null) {
458
+ delete result[key];
459
+ continue;
460
+ }
441
461
  const oldVal = result[key];
442
462
  if (isPlainObject(oldVal) && isPlainObject(newVal)) {
443
463
  result[key] = deepMerge(oldVal, newVal, seen);
@@ -718,6 +738,10 @@ function deepMerge2(target, source, seen) {
718
738
  const result = { ...target };
719
739
  for (const key of Object.keys(source)) {
720
740
  const newVal = source[key];
741
+ if (newVal === null) {
742
+ delete result[key];
743
+ continue;
744
+ }
721
745
  const oldVal = result[key];
722
746
  if (isPlainObject2(oldVal) && isPlainObject2(newVal)) {
723
747
  result[key] = deepMerge2(oldVal, newVal, seen);
@@ -1424,7 +1448,10 @@ function persistState(enabled, name, signedState, room, userId) {
1424
1448
  userId,
1425
1449
  lastUpdate: Date.now()
1426
1450
  }));
1427
- } catch {
1451
+ } catch (e) {
1452
+ if (typeof console !== "undefined") {
1453
+ console.warn(`[fluxstack] Failed to persist state for '${name}':`, e instanceof Error ? e.message : e);
1454
+ }
1428
1455
  }
1429
1456
  }
1430
1457
  function getPersistedState(enabled, name) {