@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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/connection.ts
2
- var LiveConnection = class {
2
+ var LiveConnection = class _LiveConnection {
3
3
  ws = null;
4
4
  options;
5
5
  reconnectAttempts = 0;
@@ -161,18 +161,34 @@ var LiveConnection = class {
161
161
  this.setState({ error: "Max reconnection attempts reached" });
162
162
  }
163
163
  }
164
+ consecutiveHeartbeatFailures = 0;
165
+ static MAX_HEARTBEAT_FAILURES = 3;
164
166
  startHeartbeat() {
165
167
  this.stopHeartbeat();
168
+ this.consecutiveHeartbeatFailures = 0;
166
169
  this.heartbeatInterval = setInterval(() => {
167
170
  if (this.ws?.readyState === WebSocket.OPEN) {
171
+ let failed = false;
168
172
  for (const componentId of this.componentCallbacks.keys()) {
169
173
  this.sendMessage({
170
174
  type: "COMPONENT_PING",
171
175
  componentId,
172
176
  timestamp: Date.now()
173
177
  }).catch(() => {
178
+ failed = true;
174
179
  });
175
180
  }
181
+ if (failed) {
182
+ this.consecutiveHeartbeatFailures++;
183
+ this.log(`Heartbeat failed (${this.consecutiveHeartbeatFailures}/${_LiveConnection.MAX_HEARTBEAT_FAILURES})`);
184
+ if (this.consecutiveHeartbeatFailures >= _LiveConnection.MAX_HEARTBEAT_FAILURES) {
185
+ this.log("Too many heartbeat failures, reconnecting...");
186
+ this.setState({ error: "Heartbeat failed" });
187
+ this.reconnect();
188
+ }
189
+ } else {
190
+ this.consecutiveHeartbeatFailures = 0;
191
+ }
176
192
  }
177
193
  }, this.options.heartbeatInterval);
178
194
  }
@@ -400,6 +416,10 @@ function deepMerge(target, source, seen) {
400
416
  const result = { ...target };
401
417
  for (const key of Object.keys(source)) {
402
418
  const newVal = source[key];
419
+ if (newVal === null) {
420
+ delete result[key];
421
+ continue;
422
+ }
403
423
  const oldVal = result[key];
404
424
  if (isPlainObject(oldVal) && isPlainObject(newVal)) {
405
425
  result[key] = deepMerge(oldVal, newVal, seen);
@@ -680,6 +700,10 @@ function deepMerge2(target, source, seen) {
680
700
  const result = { ...target };
681
701
  for (const key of Object.keys(source)) {
682
702
  const newVal = source[key];
703
+ if (newVal === null) {
704
+ delete result[key];
705
+ continue;
706
+ }
683
707
  const oldVal = result[key];
684
708
  if (isPlainObject2(oldVal) && isPlainObject2(newVal)) {
685
709
  result[key] = deepMerge2(oldVal, newVal, seen);
@@ -1386,7 +1410,10 @@ function persistState(enabled, name, signedState, room, userId) {
1386
1410
  userId,
1387
1411
  lastUpdate: Date.now()
1388
1412
  }));
1389
- } catch {
1413
+ } catch (e) {
1414
+ if (typeof console !== "undefined") {
1415
+ console.warn(`[fluxstack] Failed to persist state for '${name}':`, e instanceof Error ? e.message : e);
1416
+ }
1390
1417
  }
1391
1418
  }
1392
1419
  function getPersistedState(enabled, name) {