openkbs-pulse 1.0.16 → 1.0.18

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/pulse.js +11 -24
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openkbs-pulse",
3
- "version": "1.0.16",
3
+ "version": "1.0.18",
4
4
  "description": "Real-time WebSocket SDK for OpenKBS",
5
5
  "type": "module",
6
6
  "main": "pulse.js",
package/pulse.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * OpenKBS Pulse v1.0.12 - Real-time WebSocket SDK
2
+ * OpenKBS Pulse v1.0.18 - Real-time WebSocket SDK
3
3
  *
4
4
  * Usage:
5
5
  * const pulse = new Pulse({ kbId: 'your-kb-id', token: 'user-token' });
@@ -86,7 +86,6 @@
86
86
  */
87
87
  disconnect() {
88
88
  this._intentionalClose = true;
89
- this._stopHeartbeat();
90
89
  this._setConnectionState('disconnecting');
91
90
 
92
91
  if (this._ws) {
@@ -141,9 +140,6 @@
141
140
  this._reconnectAttempt = 0;
142
141
  this._setConnectionState('connected');
143
142
 
144
- // Start heartbeat to keep connection alive
145
- this._startHeartbeat();
146
-
147
143
  // Resubscribe to all channels
148
144
  Object.values(this._channels).forEach(channel => {
149
145
  channel._resubscribe();
@@ -155,7 +151,6 @@
155
151
 
156
152
  this._ws.onclose = (e) => {
157
153
  this._log('Disconnected:', e.code, e.reason);
158
- this._stopHeartbeat();
159
154
  this._setConnectionState('disconnected');
160
155
 
161
156
  if (!this._intentionalClose) {
@@ -239,22 +234,6 @@
239
234
  }, delay);
240
235
  }
241
236
 
242
- _startHeartbeat() {
243
- this._stopHeartbeat();
244
- this._heartbeatInterval = setInterval(() => {
245
- if (this._ws && this._ws.readyState === WebSocket.OPEN) {
246
- this._send({ action: 'ping' });
247
- }
248
- }, 25000); // Ping every 25 seconds
249
- }
250
-
251
- _stopHeartbeat() {
252
- if (this._heartbeatInterval) {
253
- clearInterval(this._heartbeatInterval);
254
- this._heartbeatInterval = null;
255
- }
256
- }
257
-
258
237
  _setConnectionState(state) {
259
238
  if (this._connectionState !== state) {
260
239
  this._connectionState = state;
@@ -486,8 +465,16 @@
486
465
  _handleMessage(msg) {
487
466
  // Handle sync (full member list) - can come from action='sync' or just type='presence'
488
467
  if (msg.action === 'sync' || (msg.type === 'presence' && msg.members)) {
489
- this._members = msg.members || [];
490
- this._count = msg.count !== undefined ? msg.count : this._members.length;
468
+ const newMembers = msg.members || [];
469
+ const newCount = msg.count !== undefined ? msg.count : newMembers.length;
470
+
471
+ // Ignore empty syncs if we already have members (race condition protection)
472
+ if (newCount === 0 && this._members.length > 0) {
473
+ return;
474
+ }
475
+
476
+ this._members = newMembers;
477
+ this._count = newCount;
491
478
  this._notifySubscribers();
492
479
  } else if (msg.action === 'enter') {
493
480
  this._members.push(msg.member);