@reactoo/watchtogether-sdk-js 2.8.9 → 2.8.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactoo/watchtogether-sdk-js",
3
- "version": "2.8.9",
3
+ "version": "2.8.11",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "dist/watchtogether-sdk.min.js",
6
6
  "module": "dist/watchtogether-sdk.min.js",
@@ -114,14 +114,14 @@ let asset = function() {
114
114
 
115
115
  createHighlightAsset: (id, title, roomIds, highlight = {}) => {
116
116
  return this.__privates.auth.__client
117
- .then(client => client.apis.asset.publishAsset({id}, {requestBody: {assetType: 'highlight',...(roomIds ? {roomIds} : {}), title, highlight}}));
117
+ .then(client => client.apis.asset.publishAsset({id}, {requestBody: {assetType: 'highlight',...(roomIds ? {roomIds} : {}), title, customAttributes: {highlight}}}));
118
118
  },
119
119
 
120
120
  createHighlightAssetWithThumbnail: (file, id, title, roomIds, highlight = {}, initiationData = null) => {
121
121
  return this.__privates.auth.__client
122
122
  .then(client => Promise.all([client, initiationData ? Promise.resolve(initiationData) : client.apis.asset.initiateAssetUpload({id: id || generateUUID()})]))
123
123
  .then(([client, response]) => Promise.all([client, client.http({url: response.data.signedUrl, method: response.data.httpMethod, headers: {"Content-Type":file.type}, body:file}), response.data.id]))
124
- .then(([client, response, idn]) => Promise.all([client.apis.asset.publishAsset({id:idn}, {requestBody: {assetType: 'highlight', title: title, ...(roomIds ? {roomIds} : {}), highlight}}), idn]))
124
+ .then(([client, response, idn]) => Promise.all([client.apis.asset.publishAsset({id:idn}, {requestBody: {assetType: 'highlight', title: title, ...(roomIds ? {roomIds} : {}), customAttributes: {highlight}}}), idn]))
125
125
  ;
126
126
  },
127
127
  }
@@ -234,6 +234,7 @@ class RoomSession {
234
234
  this.enableDtx = false;
235
235
  this.simulcast = false;
236
236
 
237
+
237
238
  this.defaultSimulcastSettings = {
238
239
  "default" : {
239
240
  mode: "controlled", // controlled, manual, browserControlled
@@ -274,6 +275,7 @@ class RoomSession {
274
275
  this.sessionId = null;
275
276
  this.apisecret = null;
276
277
  this.ws = null;
278
+ this.wsOpen = false;
277
279
 
278
280
  // helper flags
279
281
 
@@ -291,6 +293,7 @@ class RoomSession {
291
293
  this.requestMuteStatusTimeout = 100;
292
294
  this._statsInterval = 3000;
293
295
  this._statsIntervalId = null;
296
+ this._sendMessageWebsocketTimeout = 30000;
294
297
  this._sendMessageTimeout = 10000;
295
298
  this._keepAlivePeriod = 25000;
296
299
  this._longPollTimeout = 60000;
@@ -502,6 +505,7 @@ class RoomSession {
502
505
  id,
503
506
  userId,
504
507
  role,
508
+ mid,
505
509
  fullUserId: display,
506
510
  constructId: this.constructId,
507
511
  track: track,
@@ -541,6 +545,7 @@ class RoomSession {
541
545
  role,
542
546
  fullUserId: display,
543
547
  constructId: this.constructId,
548
+ mid: null,
544
549
  track: null,
545
550
  source: null,
546
551
  adding: false,
@@ -957,21 +962,36 @@ class RoomSession {
957
962
  };
958
963
  this._log(requestData);
959
964
  const op = () => new Promise((resolve, reject) => {
965
+
960
966
  let messageTimeoutId = null;
961
- let abortResponse = () => {
962
- this._abortController.signal.removeEventListener('abort', abortResponse);
967
+
968
+ let cleanup = () => {
963
969
  clearTimeout(messageTimeoutId);
970
+ this._abortController.signal.removeEventListener('abort', abortResponse);
964
971
  this.ws.removeEventListener('message', parseResponse);
972
+ };
973
+
974
+ let abortResponse = () => {
975
+ cleanup();
965
976
  reject({type: 'warning', id: 4, message: 'connection cancelled'})
966
977
  };
967
978
 
979
+ // we may get multiple responses from parallel requests, so we need to make sure we only resolve the one we sent
980
+
968
981
  let parseResponse = (event) => {
969
- let json = JSON.parse(event.data);
982
+ let json;
983
+ try {
984
+ json = JSON.parse(event.data);
985
+ }
986
+ catch (e) {}
987
+
988
+ if(!json) {
989
+ return;
990
+ }
991
+
970
992
  let r_transaction = json['transaction'];
971
993
  if (r_transaction === transaction && (!dontResolveOnAck || json['janus'] !== 'ack')) {
972
- clearTimeout(messageTimeoutId);
973
- this._abortController.signal.removeEventListener('abort', abortResponse);
974
- this.ws.removeEventListener('message', parseResponse);
994
+ cleanup();
975
995
  if (json['janus'] === 'error') {
976
996
  if (json?.error?.code == 403) {
977
997
  this.disconnect();
@@ -988,17 +1008,23 @@ class RoomSession {
988
1008
  this.ws.send(JSON.stringify(requestData));
989
1009
  }
990
1010
  resolve();
991
- } else {
1011
+ }
1012
+ else {
992
1013
  if (this.ws && this.ws.readyState === 1) {
1014
+
993
1015
  this.ws.addEventListener('message', parseResponse);
1016
+
994
1017
  messageTimeoutId = setTimeout(() => {
995
- this.ws.removeEventListener('message', parseResponse);
996
- this._abortController.signal.removeEventListener('abort', abortResponse);
1018
+ cleanup();
997
1019
  reject({type: 'warning', id: 6, message: 'send timeout', data: requestData});
998
1020
  }, this._sendMessageTimeout);
1021
+
999
1022
  this._abortController.signal.addEventListener('abort', abortResponse);
1023
+
1000
1024
  this.ws.send(JSON.stringify(requestData));
1001
- } else {
1025
+ }
1026
+ else {
1027
+ cleanup();
1002
1028
  reject({type: 'warning', id: 7, message: 'No connection to WebSockets', data: requestData});
1003
1029
  }
1004
1030
  }
@@ -1008,11 +1034,52 @@ class RoomSession {
1008
1034
  if (e.id === 4 ) {
1009
1035
  return Promise.reject(e);
1010
1036
  }
1011
- else if(e.id === 7 && retry > 0) {
1012
- return wait(this._sendMessageTimeout).then(() => this.#send(request, ignoreResponse, dontResolveOnAck, retry - 1));
1037
+ else if(e.id === 7 && this.isSupposeToBeConnected) {
1038
+
1039
+ return new Promise((resolve, reject) => {
1040
+
1041
+ let establishConnectionTimeoutId = null;
1042
+
1043
+ const cleanup = () => {
1044
+ clearTimeout(establishConnectionTimeoutId);
1045
+ this._abortController.signal.removeEventListener('abort', abort);
1046
+ this.off('webSocketsConnectionOpened', connection);
1047
+ };
1048
+
1049
+ const connection = () => {
1050
+ cleanup();
1051
+ resolve(this.#sendWebsockets(request, ignoreResponse, dontResolveOnAck, retry - 1));
1052
+ };
1053
+ const timeout = () => {
1054
+ cleanup();
1055
+ reject({type: 'warning', id: 46, message: 'WebSocket connection did not open during wait period', data: requestData});
1056
+ };
1057
+ const abort = () => {
1058
+ cleanup();
1059
+ reject({type: 'warning', id: 47, message: 'WebSocket connection was aborted', data: requestData});
1060
+ };
1061
+
1062
+
1063
+ if(this.wsOpen) {
1064
+
1065
+ this._log('Retrying failed WebSocket request', requestData);
1066
+
1067
+ resolve(this.#sendWebsockets(request, ignoreResponse, dontResolveOnAck, retry - 1));
1068
+ }
1069
+ else {
1070
+
1071
+ this._log('Waiting for WebSocket connection to open before sending request', requestData);
1072
+
1073
+ this._abortController.signal.addEventListener('abort', abort);
1074
+ establishConnectionTimeoutId = setTimeout(timeout, this._sendMessageWebsocketTimeout);
1075
+ this.once('webSocketsConnectionOpened', connection);
1076
+ }
1077
+
1078
+ })
1079
+
1013
1080
  }
1014
- else if(retry > 0) {
1015
- return this.#send(request, ignoreResponse, dontResolveOnAck, retry - 1);
1081
+ else if(retry > 0 && this.isSupposeToBeConnected) {
1082
+ return this.#sendWebsockets(request, ignoreResponse, dontResolveOnAck, retry - 1);
1016
1083
  }
1017
1084
  else {
1018
1085
  return Promise.reject(e);
@@ -1055,6 +1122,9 @@ class RoomSession {
1055
1122
 
1056
1123
  #connectionClosed() {
1057
1124
 
1125
+ this.wsOpen = false;
1126
+ this.emit('webSocketsConnectionClosed');
1127
+
1058
1128
  if (!this.isConnected || this.isConnecting || this.isDisconnecting) {
1059
1129
  return;
1060
1130
  }
@@ -1133,7 +1203,12 @@ class RoomSession {
1133
1203
  if (type === "trickle") {
1134
1204
  let candidate = json["candidate"];
1135
1205
  let config = handle.webrtcStuff;
1136
- if (config.pc && config.remoteSdp) {
1206
+ if (config.pc &&
1207
+ config.remoteSdp &&
1208
+ !config.isIceRestarting &&
1209
+ config.pc.iceConnectionState !== 'closed' &&
1210
+ config.pc.iceConnectionState !== 'failed' &&
1211
+ config.pc.iceConnectionState !== 'disconnected') {
1137
1212
 
1138
1213
  if (!candidate || candidate.completed === true) {
1139
1214
  config.pc.addIceCandidate(null).catch((e) => {
@@ -1731,6 +1806,10 @@ class RoomSession {
1731
1806
  this.ws.addEventListener('message', this.__handleWsEventsBoundFn);
1732
1807
 
1733
1808
  this.ws.onopen = () => {
1809
+
1810
+ this.wsOpen = true;
1811
+ this.emit('webSocketsConnectionOpened');
1812
+
1734
1813
  this._abortController.signal.removeEventListener('abort', abortConnect);
1735
1814
  if(!reclaim) {
1736
1815
  this.#send({"janus": "create"})
@@ -1895,8 +1974,6 @@ class RoomSession {
1895
1974
  enableDtx = false
1896
1975
  ) {
1897
1976
 
1898
- this.isSupposeToBeConnected = true;
1899
-
1900
1977
  if (this.isConnecting) {
1901
1978
  this.emit('error', {type: 'warning', id: 23, message: 'connection already in progress'});
1902
1979
  return
@@ -1906,6 +1983,8 @@ class RoomSession {
1906
1983
  await this.disconnect();
1907
1984
  }
1908
1985
 
1986
+ this.isSupposeToBeConnected = true;
1987
+
1909
1988
  this._abortController = new AbortController();
1910
1989
 
1911
1990
  this.sessionId = null;
@@ -2025,6 +2104,7 @@ class RoomSession {
2025
2104
  this.userId = null;
2026
2105
 
2027
2106
  this.isPublished = false;
2107
+ this.isConnecting = false;
2028
2108
  this.isConnected = false;
2029
2109
  this.isDisconnecting = false;
2030
2110
  this.emit('publishing', false);
@@ -2199,6 +2279,7 @@ class RoomSession {
2199
2279
  }
2200
2280
  this.emit('iceState', [handleId, handleId === this.#publisherHandle?.handleId, config.pc.iceConnectionState]);
2201
2281
  };
2282
+
2202
2283
  config.pc.onicecandidate = (event) => {
2203
2284
  if (event.candidate == null || (adapter.browserDetails.browser === 'edge' && event.candidate.candidate.indexOf('endOfCandidates') > 0)) {
2204
2285
  config.iceDone = true;
@@ -2451,8 +2532,8 @@ class RoomSession {
2451
2532
 
2452
2533
  config.isIceRestarting = true;
2453
2534
 
2454
- // removing this so we can cache ice candidates again
2455
- config.remoteSdp = null;
2535
+ // // removing this so we can cache ice candidates again
2536
+ // config.remoteSdp = null;
2456
2537
 
2457
2538
  if (this.handleId === handleId) {
2458
2539
  this._log('Performing local ICE restart');
@@ -2646,6 +2727,9 @@ class RoomSession {
2646
2727
  }
2647
2728
 
2648
2729
  #publishRemote(handleId, jsep) {
2730
+
2731
+ console.log('picaaaa');
2732
+
2649
2733
  let handle = this.#getHandle(handleId);
2650
2734
  if (!handle) {
2651
2735
  return Promise.reject({
@@ -2794,7 +2878,7 @@ class RoomSession {
2794
2878
  let existingTracks = [...(config.streamMap?.[this.id]?.[source] || [])];
2795
2879
 
2796
2880
  if(stream?.getTracks().length) {
2797
- if(!config.streamMap[this.id]) {
2881
+ if(!config.streamMap?.[this.id]) {
2798
2882
  config.streamMap[this.id] = {};
2799
2883
  }
2800
2884
  config.streamMap[this.id][source] = stream?.getTracks()?.map(track => track.id) || [];
@@ -2814,8 +2898,8 @@ class RoomSession {
2814
2898
  } catch (e) {
2815
2899
  this._log(e);
2816
2900
  }
2817
- config.stream.removeTrack(oldAudioStream);
2818
- config?.tracks.splice(oldAudioStreamIndex, 1);
2901
+ config?.stream?.removeTrack(oldAudioStream);
2902
+ config?.tracks?.splice(oldAudioStreamIndex, 1);
2819
2903
  }
2820
2904
 
2821
2905
  // remove old video track related to this source