@reactoo/watchtogether-sdk-js 2.8.60 → 2.8.62

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.60",
3
+ "version": "2.8.62",
4
4
  "description": "Javascript SDK for Reactoo",
5
5
  "main": "dist/watchtogether-sdk.min.js",
6
6
  "module": "dist/watchtogether-sdk.min.js",
@@ -124,6 +124,48 @@ let liveBarn = function() {
124
124
  return this.__privates.auth.__client
125
125
  .then(client => client.apis.livebarn.publishTeamLogo({id: fileId, teamId}));
126
126
  },
127
+
128
+ getLiveBarnLeagueList: ({instanceType, fulltextPhrase, sports, type, ids, size, startKey, sort} = {}) => {
129
+ return chunkArray(ids, 30)
130
+ .reduce((promiseChain, idsChunk) => {
131
+ return promiseChain.then(chainResponse => {
132
+ const apiParams = {
133
+ operation: 'listLeagues',
134
+ ...(fulltextPhrase && {fulltextPhrase}),
135
+ ...(sports?.length && {sports}),
136
+ ...(type && {type}),
137
+ ...(idsChunk?.length && {ids: idsChunk}),
138
+ ...(size && !ids?.length && {size}),
139
+ ...(startKey && {startKey}),
140
+ ...(sort && {sort}),
141
+ };
142
+ return this.system.getIntegrationPublic(instanceType, apiParams)
143
+ .then(response => ids?.length ? ({
144
+ data: {
145
+ items: [...chainResponse.data.items, ...response.data.items],
146
+ size: chainResponse.data.size + response.data.size,
147
+ startKey: null,
148
+ },
149
+ }) : response);
150
+ });
151
+ }, Promise.resolve({data: {items: [], size: 0, startKey: null}}));
152
+ },
153
+ getLiveBarnLeagueById: ({type, id} = {}) => {
154
+ const apiParams = {
155
+ operation: 'getLeague',
156
+ id,
157
+ };
158
+ return this.system.getIntegrationPublic(type, apiParams);
159
+ },
160
+ uploadLeagueLogo: (file, leagueId) => {
161
+ return this.__privates.auth.__client
162
+ .then(client => Promise.all([client, client.apis.livebarn.initiateLeagueLogoUpload({id: generateUUID(), leagueId})]))
163
+ .then(([client, response]) => Promise.all([client.http({url: response.data.signedUrl, method: response.data.httpMethod, headers: {"Content-Type": file.type}, body: file}), response.data.id]));
164
+ },
165
+ publishLeagueLogo: (fileId, leagueId) => {
166
+ return this.__privates.auth.__client
167
+ .then(client => client.apis.livebarn.publishLeagueLogo({id: fileId, leagueId}));
168
+ },
127
169
  };
128
170
  };
129
171
 
@@ -442,7 +442,7 @@ class RoomSession {
442
442
  }
443
443
 
444
444
  #getDisplayById(id) {
445
- return this.#subscriberHandle.webrtcStuff.userIdToDisplay[id];
445
+ return this.#subscriberHandle?.webrtcStuff?.userIdToDisplay?.[id];
446
446
  }
447
447
 
448
448
  #emitLocalFeedUpdate({feedRemoval = false, addingTrack = false, removingTrack = false, track = null, source = null, mid = null} = {}) {
@@ -1050,7 +1050,7 @@ class RoomSession {
1050
1050
  let cleanup = () => {
1051
1051
  clearTimeout(messageTimeoutId);
1052
1052
  this._abortController?.signal?.removeEventListener('abort', abortResponse);
1053
- this.ws.removeEventListener('message', parseResponse);
1053
+ this.ws?.removeEventListener('message', parseResponse);
1054
1054
  };
1055
1055
 
1056
1056
  let abortResponse = () => {
@@ -1261,13 +1261,17 @@ class RoomSession {
1261
1261
  this.#connectionClosed();
1262
1262
  });
1263
1263
 
1264
- this._keepAliveId = setTimeout(() => {
1265
- this.#startKeepAlive();
1266
- }, this._keepAlivePeriod);
1264
+ if(!this._keepAliveId) {
1265
+ this._keepAliveId = setTimeout(() => {
1266
+ this._keepAliveId = null;
1267
+ this.#startKeepAlive();
1268
+ }, this._keepAlivePeriod);
1269
+ }
1267
1270
  }
1268
1271
 
1269
1272
  #stopKeepAlive() {
1270
1273
  clearTimeout(this._keepAliveId);
1274
+ this._keepAliveId = null;
1271
1275
  }
1272
1276
 
1273
1277
  #handleWsEvents(event, skipPoll = false) {
@@ -1344,7 +1348,7 @@ class RoomSession {
1344
1348
  //none universal
1345
1349
  } else if (type === 'timeout') {
1346
1350
  this._log('WebSockets Gateway timeout', json);
1347
- this.ws.close(3504, "Gateway timeout");
1351
+ this.ws?.close?.(3504, "Gateway timeout");
1348
1352
  } else if (type === 'success' || type === 'error') {
1349
1353
  // we're capturing those elsewhere
1350
1354
  } else {
@@ -3093,16 +3097,33 @@ class RoomSession {
3093
3097
  let replaceAudio = stream?.getAudioTracks()?.length;
3094
3098
  let replaceVideo = stream?.getVideoTracks()?.length;
3095
3099
 
3096
- for(const transceiver of transceivers) {
3097
- if(['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && transceiver.sender?.track?.kind === 'audio' && existingTracks.includes(transceiver.sender?.track?.id)) {
3098
- audioTransceiver = transceiver;
3099
- }
3100
- else if(['sendonly', 'sendrecv'].includes(transceiver.currentDirection) && transceiver.sender?.track?.kind === 'video' && existingTracks.includes(transceiver.sender?.track?.id)) {
3101
- videoTransceiver = transceiver;
3100
+
3101
+ for (const transceiver of transceivers) {
3102
+
3103
+ const kind = transceiver.receiver.track.kind;
3104
+ const isActive = ['sendonly', 'sendrecv'].includes(transceiver.currentDirection);
3105
+
3106
+ // Check if the current transceiver's ID is the one we are replacing/resuming
3107
+ const isMyTrack = existingTracks.includes(transceiver.sender?.track?.id);
3108
+ // Check if the slot is currently active but sending nothing (i.e., replaceTrack(null) was called)
3109
+ const isEmptySlot = transceiver.sender.track === null;
3110
+
3111
+
3112
+ // 1. Audio Transceiver (Check Active or Empty Slot)
3113
+ if (isActive && kind === 'audio') {
3114
+ // If it's already my track OR if it is an empty slot that belonged to an existing source
3115
+ if (isMyTrack || (isEmptySlot && replaceAudio && !audioTransceiver)) {
3116
+ audioTransceiver = transceiver;
3117
+ }
3102
3118
  }
3103
3119
 
3104
- // Reusing existing transceivers
3105
- // TODO: if we start using different codecs for different sources, we need to check for that here
3120
+ // 2. Video Transceiver (Check Active or Empty Slot)
3121
+ else if (isActive && kind === 'video') {
3122
+ // If it's already my track OR if it is an empty slot that belonged to an existing source
3123
+ if (isMyTrack || (isEmptySlot && replaceVideo && !videoTransceiver)) {
3124
+ videoTransceiver = transceiver;
3125
+ }
3126
+ }
3106
3127
 
3107
3128
  else if(transceiver.currentDirection === 'inactive' && transceiver.sender?.getParameters()?.codecs?.find(c => c.mimeType.indexOf('audio') > -1) && replaceAudio && !audioTransceiver) {
3108
3129
  audioTransceiver = transceiver;
@@ -3112,6 +3133,7 @@ class RoomSession {
3112
3133
  }
3113
3134
  }
3114
3135
 
3136
+
3115
3137
  if (replaceAudio) {
3116
3138
  config.stream.addTrack(stream.getAudioTracks()[0]);
3117
3139
  config.tracks.push(stream.getAudioTracks()[0]);