@defcomm/meetingsdk 0.3.1 → 0.3.2

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.mjs CHANGED
@@ -1326,11 +1326,14 @@ var SFUClient = class {
1326
1326
  sdp: answer.sdp
1327
1327
  }
1328
1328
  });
1329
- const waiters = this.subscriptionWaiters.splice(0);
1330
- waiters.forEach((w) => w.resolve());
1329
+ const waiter = this.subscriptionWaiters.shift();
1330
+ waiter?.resolve();
1331
1331
  } catch (error) {
1332
- const waiters = this.subscriptionWaiters.splice(0);
1333
- waiters.forEach((w) => w.reject(error));
1332
+ const waiter = this.subscriptionWaiters.shift();
1333
+ if (waiter) {
1334
+ waiter.trackIds.forEach((id) => this.subscribedTracks.delete(id));
1335
+ waiter.reject(error);
1336
+ }
1334
1337
  this.onError(
1335
1338
  new Error(`Failed to process subscriber offer: ${String(error)}`)
1336
1339
  );
@@ -1352,11 +1355,20 @@ var SFUClient = class {
1352
1355
  if (!uniqueIds.length || !this.isSocketOpen()) return;
1353
1356
  uniqueIds.forEach((id) => this.subscribedTracks.add(id));
1354
1357
  return new Promise((resolve, reject) => {
1355
- this.subscriptionWaiters.push({ resolve, reject });
1356
- this.send({
1358
+ const sent = this.send({
1357
1359
  type: "subscribe",
1358
1360
  payload: { track_ids: uniqueIds }
1359
1361
  });
1362
+ if (!sent) {
1363
+ uniqueIds.forEach((id) => this.subscribedTracks.delete(id));
1364
+ reject(new Error("Signaling socket is not open"));
1365
+ return;
1366
+ }
1367
+ this.subscriptionWaiters.push({
1368
+ trackIds: uniqueIds,
1369
+ resolve,
1370
+ reject
1371
+ });
1360
1372
  });
1361
1373
  }
1362
1374
  async processSubscriptionQueue() {
@@ -1369,11 +1381,20 @@ var SFUClient = class {
1369
1381
  continue;
1370
1382
  }
1371
1383
  await new Promise((resolve, reject) => {
1372
- this.subscriptionWaiters.push({ resolve, reject });
1373
- this.send({
1384
+ const sent = this.send({
1374
1385
  type: "subscribe",
1375
1386
  payload: { track_ids: [trackId] }
1376
1387
  });
1388
+ if (!sent) {
1389
+ this.subscribedTracks.delete(trackId);
1390
+ reject(new Error("Signaling socket is not open"));
1391
+ return;
1392
+ }
1393
+ this.subscriptionWaiters.push({
1394
+ trackIds: [trackId],
1395
+ resolve,
1396
+ reject
1397
+ });
1377
1398
  });
1378
1399
  }
1379
1400
  } finally {
@@ -1431,9 +1452,16 @@ var SFUClient = class {
1431
1452
  if (!this.screenTransceiver || !this.screenSender) {
1432
1453
  throw new Error("Screen transceiver is not initialized");
1433
1454
  }
1434
- if (this.screenStream) {
1435
- return this.screenStream;
1455
+ const existing = this.screenStream;
1456
+ const existingTrack = this.screenSender.track;
1457
+ if (existing || existingTrack && existingTrack.readyState === "live") {
1458
+ return existing;
1436
1459
  }
1460
+ try {
1461
+ await this.screenSender.replaceTrack(null);
1462
+ } catch {
1463
+ }
1464
+ this.screenTransceiver.direction = "inactive";
1437
1465
  const screenStream = await navigator.mediaDevices.getDisplayMedia({
1438
1466
  video: true,
1439
1467
  audio: false
@@ -1443,29 +1471,33 @@ var SFUClient = class {
1443
1471
  screenStream.getTracks().forEach((track) => track.stop());
1444
1472
  throw new Error("Screen share returned no video track");
1445
1473
  }
1474
+ const generation = ++this.screenShareGeneration;
1446
1475
  this.screenStream = screenStream;
1447
1476
  try {
1448
1477
  await this.screenSender.replaceTrack(screenTrack);
1449
1478
  this.screenTransceiver.direction = "sendonly";
1479
+ this.send({
1480
+ type: "start_screen_share"
1481
+ });
1450
1482
  const offer = await this.publisher.createOffer();
1451
1483
  await this.publisher.setLocalDescription(offer);
1484
+ const localDescription = this.publisher.localDescription;
1485
+ if (!localDescription?.sdp) {
1486
+ throw new Error("Publisher did not produce a valid screen-share SDP");
1487
+ }
1452
1488
  this.send({
1453
1489
  type: "publish_offer",
1454
1490
  payload: {
1455
1491
  revision: ++this.publisherRevision,
1456
- sdp: offer.sdp
1492
+ sdp: localDescription.sdp
1457
1493
  }
1458
1494
  });
1459
- this.send({ type: "start_screen_share" });
1460
1495
  screenTrack.onended = () => {
1496
+ if (generation !== this.screenShareGeneration) {
1497
+ return;
1498
+ }
1461
1499
  void this.stopScreenShare();
1462
1500
  };
1463
- console.info("[publisher] Screen track attached", {
1464
- screenTrackId: screenTrack.id,
1465
- cameraTrackId: this.videoSender?.track?.id,
1466
- screenMid: this.screenTransceiver.mid,
1467
- cameraMid: this.cameraTransceiver?.mid
1468
- });
1469
1501
  return this.screenStream;
1470
1502
  } catch (error) {
1471
1503
  try {
@@ -1473,19 +1505,33 @@ var SFUClient = class {
1473
1505
  } catch {
1474
1506
  }
1475
1507
  this.screenTransceiver.direction = "inactive";
1476
- screenStream.getTracks().forEach((track) => track.stop());
1508
+ screenTrack.onended = null;
1509
+ screenStream.getTracks().forEach((track) => {
1510
+ try {
1511
+ track.stop();
1512
+ } catch {
1513
+ }
1514
+ });
1477
1515
  this.screenStream = null;
1478
1516
  try {
1479
- this.send({ type: "stop_screen_share" });
1517
+ this.send({
1518
+ type: "stop_screen_share"
1519
+ });
1480
1520
  } catch {
1481
1521
  }
1482
1522
  throw error;
1483
1523
  }
1484
1524
  }
1485
1525
  async stopScreenShare() {
1486
- if (!this.screenStream && !this.screenSender?.track) return;
1487
- const screenTrack = this.screenSender?.track || null;
1488
- if (screenTrack) screenTrack.onended = null;
1526
+ const stream = this.screenStream;
1527
+ const senderTrack = this.screenSender?.track || null;
1528
+ if (!stream && !senderTrack) {
1529
+ return;
1530
+ }
1531
+ ++this.screenShareGeneration;
1532
+ if (senderTrack) {
1533
+ senderTrack.onended = null;
1534
+ }
1489
1535
  try {
1490
1536
  await this.screenSender?.replaceTrack(null);
1491
1537
  } catch (error) {
@@ -1494,23 +1540,33 @@ var SFUClient = class {
1494
1540
  if (this.screenTransceiver) {
1495
1541
  this.screenTransceiver.direction = "inactive";
1496
1542
  }
1497
- this.send({ type: "stop_screen_share" });
1498
1543
  try {
1499
- const offer = await this.publisher?.createOffer();
1500
- if (offer && this.publisher) {
1544
+ if (this.publisher) {
1545
+ const offer = await this.publisher.createOffer();
1501
1546
  await this.publisher.setLocalDescription(offer);
1502
- this.send({
1503
- type: "publish_offer",
1504
- payload: {
1505
- revision: ++this.publisherRevision,
1506
- sdp: offer.sdp
1507
- }
1508
- });
1547
+ const localDescription = this.publisher.localDescription;
1548
+ if (localDescription?.sdp) {
1549
+ this.send({
1550
+ type: "publish_offer",
1551
+ payload: {
1552
+ revision: ++this.publisherRevision,
1553
+ sdp: localDescription.sdp
1554
+ }
1555
+ });
1556
+ }
1509
1557
  }
1510
1558
  } catch (error) {
1511
1559
  this.onError(error);
1512
1560
  }
1513
- this.screenStream?.getTracks().forEach((track) => track.stop());
1561
+ this.send({
1562
+ type: "stop_screen_share"
1563
+ });
1564
+ stream?.getTracks().forEach((track) => {
1565
+ try {
1566
+ track.stop();
1567
+ } catch {
1568
+ }
1569
+ });
1514
1570
  this.screenStream = null;
1515
1571
  if (this.currentParticipantId) {
1516
1572
  this.onScreenShareStopped(this.currentParticipantId);