versacall-core-library-react 2.0.85-dev → 2.0.87-dev

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.
@@ -172,8 +172,6 @@ function initWorkerPort(host, secure, log) {
172
172
  type
173
173
  } = ev.data;
174
174
  if (type === 'MESSAGE') {
175
- // ev.data.channel is the raw MQTT topic "{channelKey}/{channelName}/"
176
- // — identical to what emitter-io exposed as msg.channel.
177
175
  processMessage(ev.data.channel, ev.data.data);
178
176
  } else if (type === 'CONNECTION_CHANGED') {
179
177
  log('system', namespace, 'workerPort.onmessage', ev.data.connected ? 'Emitter Connect' : 'Emitter Disconnect');
@@ -39,7 +39,7 @@ let packetIdCounter = 0;
39
39
  * topic string → { channelKey, channelName }
40
40
  * Maintained across reconnects so we can resubscribe automatically.
41
41
  */
42
- const activeSubscriptions = new Map();
42
+ const activeSubscriptions = new Map(); // lookupKey → {channelKey, channelName, ports: Set}
43
43
 
44
44
  // ─── Helpers ─────────────────────────────────────────────────────────────────
45
45
 
@@ -57,6 +57,18 @@ function concat(a, b) {
57
57
  out.set(b, a.length);
58
58
  return out;
59
59
  }
60
+ function cleanupPortSubscriptions(port) {
61
+ for (const [lookupKey, sub] of activeSubscriptions) {
62
+ sub.ports.delete(port);
63
+ if (sub.ports.size === 0) {
64
+ activeSubscriptions.delete(lookupKey);
65
+ const mqttTopic = "".concat(sub.channelKey, "/").concat(sub.channelName, "/");
66
+ if (mqttConnected) {
67
+ wsSend(buildUnsubscribe(nextPacketId(), mqttTopic));
68
+ }
69
+ }
70
+ }
71
+ }
60
72
 
61
73
  // ─── MQTT encoding ───────────────────────────────────────────────────────────
62
74
 
@@ -166,7 +178,6 @@ function decodeVarInt(buf, offset) {
166
178
  * Leaves any trailing incomplete bytes in receiveBuffer.
167
179
  */
168
180
  function drainBuffer() {
169
- console.log('[vc-worker] drainBuffer called, buffer length:', receiveBuffer.length);
170
181
  let offset = 0;
171
182
  while (offset < receiveBuffer.length) {
172
183
  const firstByte = receiveBuffer[offset];
@@ -187,7 +198,6 @@ function drainBuffer() {
187
198
 
188
199
  /** Route a decoded MQTT packet to the appropriate handler. */
189
200
  function dispatchMqttPacket(type, flags, body) {
190
- console.log('[vc-worker] dispatchMqttPacket type:', type, 'body length:', body.length);
191
201
  switch (type) {
192
202
  case 2:
193
203
  return onConnack(body);
@@ -228,27 +238,13 @@ function onConnack(body) {
228
238
  * forward it unchanged — ChannelsConsumer handlers will match as before.
229
239
  */
230
240
  function onPublish(flags, body) {
231
- console.log('[vc-worker] onPublish called, body length:', body.length);
232
241
  if (body.length < 2) return;
233
242
  const topicLen = body[0] << 8 | body[1];
234
243
  if (2 + topicLen > body.length) return;
235
244
  const topic = textDecoder.decode(body.slice(2, 2 + topicLen));
236
- console.log('[vc-worker] topic:', topic);
237
245
  const qos = flags >> 1 & 0x03;
238
- console.log('[vc-worker] qos:', qos);
239
246
  const payloadStart = 2 + topicLen + (qos > 0 ? 2 : 0);
240
247
  const payloadStr = textDecoder.decode(body.slice(payloadStart));
241
- console.log('[vc-worker] payload first 200 chars:', payloadStr.substring(0, 200));
242
-
243
- // TEMPORARY DEBUG - remove after diagnosis
244
- ports.forEach(port => {
245
- try {
246
- port.postMessage({
247
- type: 'LOG',
248
- message: 'RAW TOPIC: ' + topic + ' | QOS: ' + qos + ' | PAYLOAD: ' + payloadStr.substring(0, 200)
249
- });
250
- } catch (_) {}
251
- });
252
248
  let data;
253
249
  try {
254
250
  data = JSON.parse(payloadStr);
@@ -308,7 +304,6 @@ function openWebSocket(config) {
308
304
  pingIntervalId = setInterval(() => wsSend(PINGREQ), 25000);
309
305
  };
310
306
  ws.onmessage = ev => {
311
- console.log('[vc-worker] WebSocket data received, bytes:', ev.data.byteLength);
312
307
  receiveBuffer = concat(receiveBuffer, new Uint8Array(ev.data));
313
308
  drainBuffer();
314
309
  };
@@ -369,10 +364,6 @@ function handlePortMessage(port, msg) {
369
364
  // First INIT — record config and open the connection.
370
365
  wsConfig = config;
371
366
  openWebSocket(config);
372
- port.postMessage({
373
- type: 'LOG',
374
- message: 'Worker: first INIT, opening WebSocket'
375
- });
376
367
  } else if (mqttConnected) {
377
368
  // Subsequent INIT from a later iframe — we're already live.
378
369
  // Immediately tell the new port so it can update connection-state UI.
@@ -380,10 +371,6 @@ function handlePortMessage(port, msg) {
380
371
  type: 'CONNECTION_CHANGED',
381
372
  connected: true
382
373
  });
383
- port.postMessage({
384
- type: 'LOG',
385
- message: 'Worker: subsequent INIT, reusing existing connection. Total ports: ' + ports.size
386
- });
387
374
  }
388
375
  // If !mqttConnected and wsConfig is already set we're in the middle of
389
376
  // connecting; the CONNACK broadcast will reach the new port once ready.
@@ -393,22 +380,34 @@ function handlePortMessage(port, msg) {
393
380
  {
394
381
  const mqttTopic = "".concat(msg.channelKey, "/").concat(msg.channelName, "/");
395
382
  const lookupKey = "".concat(msg.channelName, "/");
396
- activeSubscriptions.set(lookupKey, {
397
- channelKey: msg.channelKey,
398
- channelName: msg.channelName
399
- });
400
- if (mqttConnected) {
401
- wsSend(buildSubscribe(nextPacketId(), mqttTopic));
383
+ const existing = activeSubscriptions.get(lookupKey);
384
+ if (existing) {
385
+ existing.ports.add(port);
386
+ } else {
387
+ activeSubscriptions.set(lookupKey, {
388
+ channelKey: msg.channelKey,
389
+ channelName: msg.channelName,
390
+ ports: new Set([port])
391
+ });
392
+ if (mqttConnected) {
393
+ wsSend(buildSubscribe(nextPacketId(), mqttTopic));
394
+ }
402
395
  }
403
396
  break;
404
397
  }
405
398
  case 'UNSUBSCRIBE':
406
399
  {
407
400
  const lookupKey = "".concat(msg.channelName, "/");
408
- activeSubscriptions.delete(lookupKey);
409
- const mqttTopic = "".concat(msg.channelKey, "/").concat(msg.channelName, "/");
410
- if (mqttConnected) {
411
- wsSend(buildUnsubscribe(nextPacketId(), mqttTopic));
401
+ const existing = activeSubscriptions.get(lookupKey);
402
+ if (existing) {
403
+ existing.ports.delete(port);
404
+ if (existing.ports.size === 0) {
405
+ activeSubscriptions.delete(lookupKey);
406
+ const mqttTopic = "".concat(msg.channelKey, "/").concat(msg.channelName, "/");
407
+ if (mqttConnected) {
408
+ wsSend(buildUnsubscribe(nextPacketId(), mqttTopic));
409
+ }
410
+ }
412
411
  }
413
412
  break;
414
413
  }
@@ -427,9 +426,9 @@ self.onconnect = event => {
427
426
  const port = event.ports[0];
428
427
  ports.add(port);
429
428
  port.onmessage = ev => handlePortMessage(port, ev.data);
430
- port.onmessageerror = () => ports.delete(port);
431
-
432
- // start() is required when the port was not started implicitly via
433
- // addEventListener — calling it on an already-started port is harmless.
429
+ port.onmessageerror = () => {
430
+ ports.delete(port);
431
+ cleanupPortSubscriptions(port);
432
+ };
434
433
  port.start();
435
434
  };
package/package.json CHANGED
@@ -2,10 +2,10 @@
2
2
  "versacall": {
3
3
  "title": "Versacall Core Library React",
4
4
  "applicationType": "react-library",
5
- "build": 85
5
+ "build": 87
6
6
  },
7
7
  "name": "versacall-core-library-react",
8
- "version": "2.0.85-dev",
8
+ "version": "2.0.87-dev",
9
9
  "description": "Versacall Core Library",
10
10
  "main": "dist/index.js",
11
11
  "module": "dist/index.js",