twilio-video 2.17.0 → 2.18.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.
Files changed (56) hide show
  1. package/CHANGELOG.md +39 -2
  2. package/COMMON_ISSUES.md +130 -0
  3. package/README.md +24 -15
  4. package/dist/twilio-video.js +361 -220
  5. package/dist/twilio-video.min.js +22 -21
  6. package/es5/connect.js +13 -2
  7. package/es5/connect.js.map +1 -1
  8. package/es5/media/track/localmediatrack.js +2 -0
  9. package/es5/media/track/localmediatrack.js.map +1 -1
  10. package/es5/media/track/remotevideotrack.js +68 -14
  11. package/es5/media/track/remotevideotrack.js.map +1 -1
  12. package/es5/preflight/getCombinedConnectionStats.js +0 -1
  13. package/es5/preflight/getCombinedConnectionStats.js.map +1 -1
  14. package/es5/preflight/getturncredentials.js +2 -16
  15. package/es5/preflight/getturncredentials.js.map +1 -1
  16. package/es5/preflight/makestat.js +1 -1
  17. package/es5/preflight/makestat.js.map +1 -1
  18. package/es5/preflight/preflighttest.js +83 -11
  19. package/es5/preflight/preflighttest.js.map +1 -1
  20. package/es5/signaling/v2/cancelableroomsignalingpromise.js +2 -9
  21. package/es5/signaling/v2/cancelableroomsignalingpromise.js.map +1 -1
  22. package/es5/signaling/v2/mediasignaling.js +2 -4
  23. package/es5/signaling/v2/mediasignaling.js.map +1 -1
  24. package/es5/signaling/v2/peerconnection.js +4 -2
  25. package/es5/signaling/v2/peerconnection.js.map +1 -1
  26. package/es5/signaling/v2/twilioconnectiontransport.js +3 -27
  27. package/es5/signaling/v2/twilioconnectiontransport.js.map +1 -1
  28. package/es5/util/constants.js +3 -0
  29. package/es5/util/constants.js.map +1 -1
  30. package/es5/util/eventobserver.js +9 -19
  31. package/es5/util/eventobserver.js.map +1 -1
  32. package/es5/util/index.js +2 -0
  33. package/es5/util/index.js.map +1 -1
  34. package/es5/util/sid.js +18 -0
  35. package/es5/util/sid.js.map +1 -0
  36. package/es5/util/twilio-video-errors.js +38 -5
  37. package/es5/util/twilio-video-errors.js.map +1 -1
  38. package/lib/connect.js +21 -2
  39. package/lib/media/track/localmediatrack.js +2 -0
  40. package/lib/media/track/remotevideotrack.js +74 -14
  41. package/lib/preflight/getCombinedConnectionStats.ts +0 -1
  42. package/lib/preflight/getturncredentials.ts +2 -12
  43. package/lib/preflight/makestat.ts +2 -2
  44. package/lib/preflight/preflighttest.ts +107 -13
  45. package/lib/signaling/v2/cancelableroomsignalingpromise.js +1 -12
  46. package/lib/signaling/v2/mediasignaling.js +2 -5
  47. package/lib/signaling/v2/peerconnection.js +4 -2
  48. package/lib/signaling/v2/twilioconnectiontransport.js +1 -31
  49. package/lib/util/constants.js +3 -0
  50. package/lib/util/eventobserver.js +10 -22
  51. package/lib/util/index.js +3 -0
  52. package/lib/util/sid.js +20 -0
  53. package/lib/util/twilio-video-errors.js +37 -5
  54. package/package.json +4 -3
  55. package/tsconfig.json +1 -1
  56. package/tsdef/PreflightTypes.d.ts +1 -2
@@ -1,5 +1,5 @@
1
- import { DEFAULT_LOGGER_NAME, DEFAULT_LOG_LEVEL } from '../util/constants';
2
- import { PreflightOptions, PreflightTestReport, RTCIceCandidateStats, SelectedIceCandidatePairStats } from '../../tsdef/PreflightTypes';
1
+ import { DEFAULT_ENVIRONMENT, DEFAULT_LOGGER_NAME, DEFAULT_LOG_LEVEL, DEFAULT_REALM, SDK_NAME, SDK_VERSION } from '../util/constants';
2
+ import { PreflightOptions, PreflightTestReport, RTCIceCandidateStats, SelectedIceCandidatePairStats, Stats } from '../../tsdef/PreflightTypes';
3
3
  import { StatsReport } from '../../tsdef/types';
4
4
  import { Timer } from './timer';
5
5
  import { calculateMOS } from './mos';
@@ -10,9 +10,13 @@ import { syntheticAudio } from './syntheticaudio';
10
10
  import { syntheticVideo } from './syntheticvideo';
11
11
  import { waitForSometime } from '../util';
12
12
 
13
+ const { WS_SERVER } = require('../util/constants');
13
14
  const Log = require('../util/log');
14
15
  const EventEmitter = require('../eventemitter');
15
16
  const MovingAverageDelta = require('../util/movingaveragedelta');
17
+ const EventObserver = require('../util/eventobserver');
18
+ const InsightsPublisher = require('../util/insightspublisher');
19
+ const { createSID, sessionSID } = require('../util/sid');
16
20
 
17
21
  const SECOND = 1000;
18
22
  const DEFAULT_TEST_DURATION = 10 * SECOND;
@@ -71,6 +75,16 @@ declare interface PreflightStats {
71
75
  iceCandidateStats: RTCIceCandidateStats[],
72
76
  }
73
77
 
78
+ declare interface PreflightTestReportInternal extends PreflightTestReport {
79
+ error?: string,
80
+ mos?: Stats|null
81
+ }
82
+
83
+ declare interface PreflightOptionsInternal extends PreflightOptions {
84
+ environment?: string;
85
+ wsServer?: string;
86
+ }
87
+
74
88
  function notEmpty<TValue>(value: TValue | null | undefined): value is TValue {
75
89
  return value !== null && typeof value !== 'undefined';
76
90
  }
@@ -108,12 +122,16 @@ export class PreflightTest extends EventEmitter {
108
122
  */
109
123
  constructor(token: string, options: PreflightOptions) {
110
124
  super();
125
+ const internalOptions = options as PreflightOptionsInternal;
126
+ const { environment = 'prod', region = 'gll', duration = DEFAULT_TEST_DURATION } = internalOptions;
127
+ // eslint-disable-next-line new-cap
128
+ const wsServer = internalOptions.wsServer || WS_SERVER(environment, region);
129
+
111
130
  this._log = new Log('default', this, DEFAULT_LOG_LEVEL, DEFAULT_LOGGER_NAME);
112
- this._testDuration = options.duration || DEFAULT_TEST_DURATION;
131
+ this._testDuration = duration;
113
132
  this._instanceId = nInstances++;
114
-
115
133
  this._testTiming.start();
116
- this._runPreflightTest(token, options);
134
+ this._runPreflightTest(token, environment, wsServer);
117
135
  }
118
136
 
119
137
  toString(): string {
@@ -127,7 +145,7 @@ export class PreflightTest extends EventEmitter {
127
145
  this._stopped = true;
128
146
  }
129
147
 
130
- private _generatePreflightReport(collectedStats: PreflightStats) : PreflightTestReport {
148
+ private _generatePreflightReport(collectedStats?: PreflightStats, error? : Error) : PreflightTestReportInternal {
131
149
  this._testTiming.stop();
132
150
  return {
133
151
  testTiming: this._testTiming.getTimeMeasurement(),
@@ -139,12 +157,15 @@ export class PreflightTest extends EventEmitter {
139
157
  media: this._mediaTiming.getTimeMeasurement()
140
158
  },
141
159
  stats: {
142
- jitter: makeStat(collectedStats.jitter),
143
- rtt: makeStat(collectedStats.rtt),
144
- packetLoss: makeStat(collectedStats.packetLoss),
160
+ jitter: makeStat(collectedStats?.jitter),
161
+ rtt: makeStat(collectedStats?.rtt),
162
+ packetLoss: makeStat(collectedStats?.packetLoss),
145
163
  },
146
- selectedIceCandidatePairStats: collectedStats.selectedIceCandidatePairStats,
147
- iceCandidateStats: collectedStats.iceCandidateStats
164
+ selectedIceCandidatePairStats: collectedStats ? collectedStats.selectedIceCandidatePairStats : null,
165
+ iceCandidateStats: collectedStats ? collectedStats.iceCandidateStats : [],
166
+ // NOTE(mpatwardhan): internal properties.
167
+ error: error?.toString(),
168
+ mos: makeStat(collectedStats?.mos),
148
169
  };
149
170
  }
150
171
 
@@ -211,9 +232,79 @@ export class PreflightTest extends EventEmitter {
211
232
  }
212
233
  }
213
234
 
214
- private async _runPreflightTest(token: string, options: PreflightOptions) {
235
+ private _setupInsights({ token, environment = DEFAULT_ENVIRONMENT, realm = DEFAULT_REALM } : {
236
+ token: string,
237
+ environment?: string,
238
+ realm?: string
239
+ }) {
240
+ const eventPublisherOptions = {};
241
+ const eventPublisher = new InsightsPublisher(
242
+ token,
243
+ SDK_NAME,
244
+ SDK_VERSION,
245
+ environment,
246
+ realm,
247
+ eventPublisherOptions);
248
+
249
+ // event publisher requires room sid/participant sid. supply fake ones.
250
+ eventPublisher.connect('PREFLIGHT_ROOM_SID', 'PREFLIGHT_PARTICIPANT');
251
+ const eventObserver = new EventObserver(eventPublisher, Date.now(), this._log);
252
+
253
+ // eslint-disable-next-line no-undefined
254
+ const undefinedValue = undefined;
255
+ return {
256
+ reportToInsights: ({ report }: { report: PreflightTestReportInternal }) => {
257
+ const jitterStats = report.stats.jitter || undefinedValue;
258
+ const rttStats = report.stats.rtt || undefinedValue;
259
+ const packetLossStats = report.stats.packetLoss || undefinedValue;
260
+ const mosStats = report.mos || undefinedValue;
261
+
262
+ // stringify important info from ice candidates.
263
+ const candidateTypeToProtocols = new Map<string, string[]>();
264
+ report.iceCandidateStats.forEach(candidateStats => {
265
+ if (candidateStats.candidateType && candidateStats.protocol) {
266
+ let protocols = candidateTypeToProtocols.get(candidateStats.candidateType) || [];
267
+ if (protocols.indexOf(candidateStats.protocol) < 0) {
268
+ protocols.push(candidateStats.protocol);
269
+ }
270
+ candidateTypeToProtocols.set(candidateStats.candidateType, protocols);
271
+ }
272
+ });
273
+ const iceCandidateStats = JSON.stringify(Object.fromEntries(candidateTypeToProtocols));
274
+
275
+ const insightsReport = {
276
+ name: 'report',
277
+ group: 'preflight',
278
+ level: report.error ? 'error' : 'info',
279
+ payload: {
280
+ sessionSID,
281
+ preflightSID: createSID('PF'),
282
+ testTiming: report.testTiming,
283
+ dtlsTiming: report.networkTiming.dtls,
284
+ iceTiming: report.networkTiming.ice,
285
+ peerConnectionTiming: report.networkTiming.peerConnection,
286
+ connectTiming: report.networkTiming.connect,
287
+ mediaTiming: report.networkTiming.media,
288
+ selectedLocalCandidate: report.selectedIceCandidatePairStats?.localCandidate,
289
+ selectedRemoteCandidate: report.selectedIceCandidatePairStats?.remoteCandidate,
290
+ iceCandidateStats,
291
+ jitterStats,
292
+ rttStats,
293
+ packetLossStats,
294
+ mosStats,
295
+ error: report.error
296
+ }
297
+ };
298
+ eventObserver.emit('event', insightsReport);
299
+ setTimeout(() => eventPublisher.disconnect(), 2000);
300
+ }
301
+ };
302
+ }
303
+
304
+ private async _runPreflightTest(token: string, environment: string, wsServer: string) {
215
305
  let localTracks: MediaStreamTrack[] = [];
216
306
  let pcs: RTCPeerConnection[] = [];
307
+ const { reportToInsights } = this._setupInsights({ token, environment });
217
308
  try {
218
309
  let elements = [];
219
310
  localTracks = await this._executePreflightStep('Acquire media', () => [syntheticAudio(), syntheticVideo({ width: 640, height: 480 })]);
@@ -221,7 +312,7 @@ export class PreflightTest extends EventEmitter {
221
312
  this.emit('debug', { localTracks });
222
313
 
223
314
  this._connectTiming.start();
224
- let iceServers = await this._executePreflightStep('Get turn credentials', () => getTurnCredentials(token, options));
315
+ let iceServers = await this._executePreflightStep('Get turn credentials', () => getTurnCredentials(token, wsServer));
225
316
  this._connectTiming.stop();
226
317
  this.emit('progress', PreflightProgress.connected);
227
318
 
@@ -287,9 +378,12 @@ export class PreflightTest extends EventEmitter {
287
378
  () => this._collectRTCStatsForDuration(this._testDuration, initCollectedStats(), senderPC, receiverPC));
288
379
 
289
380
  const report = await this._executePreflightStep('generate report', () => this._generatePreflightReport(collectedStats));
381
+ reportToInsights({ report });
290
382
  this.emit('completed', report);
291
383
 
292
384
  } catch (error) {
385
+ // eslint-disable-next-line no-undefined
386
+ reportToInsights({ report: this._generatePreflightReport(undefined, error) });
293
387
  this.emit('failed', error);
294
388
  } finally {
295
389
  pcs.forEach(pc => pc.close());
@@ -57,8 +57,6 @@ function createCancelableRoomSignalingPromise(token, wsServer, localParticipant,
57
57
  };
58
58
 
59
59
  const {
60
- InsightsPublisher,
61
- NullInsightsPublisher,
62
60
  automaticSubscription,
63
61
  bandwidthProfile,
64
62
  dominantSpeaker,
@@ -69,10 +67,8 @@ function createCancelableRoomSignalingPromise(token, wsServer, localParticipant,
69
67
  name,
70
68
  networkMonitor,
71
69
  networkQuality,
72
- insights,
73
70
  realm,
74
71
  sdpSemantics,
75
- wsServerInsights
76
72
  } = options;
77
73
 
78
74
  // decide which msp channels to request
@@ -92,20 +88,13 @@ function createCancelableRoomSignalingPromise(token, wsServer, localParticipant,
92
88
  networkMonitor,
93
89
  networkQuality,
94
90
  iceServers,
95
- insights,
96
91
  onIced,
97
92
  realm,
98
93
  renderHints,
99
94
  sdpSemantics,
100
95
  trackPriority,
101
96
  trackSwitchOff
102
- }, typeof wsServerInsights === 'string' ? {
103
- wsServerInsights
104
- } : {}, InsightsPublisher ? {
105
- InsightsPublisher
106
- } : {}, NullInsightsPublisher ? {
107
- NullInsightsPublisher
108
- } : {}, bandwidthProfile ? {
97
+ }, bandwidthProfile ? {
109
98
  bandwidthProfile
110
99
  } : {});
111
100
 
@@ -50,19 +50,16 @@ class MediaSignaling extends EventEmitter {
50
50
  const receiverPromise = this._getReceiver(id).then(receiver => {
51
51
  if (receiver.kind !== 'data') {
52
52
  this._log.error('Expected a DataTrackReceiver');
53
- throw new Error('Expected a DataTrackReceiver');
54
53
  } if (this._receiverPromise !== receiverPromise) {
55
54
  return;
56
55
  }
57
56
 
58
57
  try {
59
58
  this._transport = receiver.toDataTransport();
59
+ this.emit('ready', this._transport);
60
60
  } catch (ex) {
61
- this._log.error('Failed to toDataTransport');
62
- throw new Error('Failed to toDataTransport');
61
+ this._log.error(`Failed to toDataTransport: ${ex.message}`);
63
62
  }
64
- this.emit('ready', this._transport);
65
-
66
63
  receiver.once('close', () => this._teardown());
67
64
  });
68
65
  this._receiverPromise = receiverPromise;
@@ -904,7 +904,9 @@ class PeerConnectionV2 extends StateMachine {
904
904
  log.debug(`Starting ICE reconnect timeout: ${delay}`);
905
905
  this._iceReconnectTimeout.start();
906
906
  }
907
- this.offer();
907
+ this.offer().catch(ex => {
908
+ log.error(`offer failed in _initiateIceRestart with: ${ex.message}`);
909
+ });
908
910
  }
909
911
 
910
912
  /**
@@ -1747,7 +1749,7 @@ function updateEncodingParameters(pcv2) {
1747
1749
  params.encodings[0].networkPriority = 'high';
1748
1750
  }
1749
1751
 
1750
- if (!isFirefox && sender.track.kind === 'video') {
1752
+ if (isSafari && sender.track.kind === 'video') {
1751
1753
  const { width, height } = sender.track.getSettings();
1752
1754
  pcv2._updateEncodings(width, height, params.encodings);
1753
1755
  }
@@ -1,14 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  const { getSdpFormat } = require('@twilio/webrtc/lib/util/sdp');
4
- const packageInfo = require('../../../package.json');
5
- const InsightsPublisher = require('../../util/insightspublisher');
6
- const NullInsightsPublisher = require('../../util/insightspublisher/null');
7
4
  const StateMachine = require('../../statemachine');
8
5
  const TwilioConnection = require('../../twilioconnection');
9
6
  const DefaultBackoff = require('backoff');
10
7
  const { reconnectBackoffConfig } = require('../../util/constants');
11
8
  const Timeout = require('../../util/timeout');
9
+ const { SDK_NAME, SDK_VERSION } = require('../../util/constants');
12
10
 
13
11
  const {
14
12
  createBandwidthProfilePayload,
@@ -27,8 +25,6 @@ const {
27
25
 
28
26
  const ICE_VERSION = 1;
29
27
  const RSP_VERSION = 2;
30
- const SDK_NAME = `${packageInfo.name}.js`;
31
- const SDK_VERSION = packageInfo.version;
32
28
 
33
29
  /*
34
30
  TwilioConnectionTransport States
@@ -90,8 +86,6 @@ class TwilioConnectionTransport extends StateMachine {
90
86
  constructor(name, accessToken, localParticipant, peerConnectionManager, wsServer, options) {
91
87
  options = Object.assign({
92
88
  Backoff: DefaultBackoff,
93
- InsightsPublisher,
94
- NullInsightsPublisher,
95
89
  TwilioConnection,
96
90
  iceServers: null,
97
91
  sdpFormat: getSdpFormat(options.sdpSemantics),
@@ -102,19 +96,6 @@ class TwilioConnectionTransport extends StateMachine {
102
96
  }, options);
103
97
  super('connecting', states);
104
98
 
105
- const eventPublisherOptions = {};
106
- if (options.wsServerInsights) {
107
- eventPublisherOptions.gateway = options.wsServerInsights;
108
- }
109
-
110
- const EventPublisher = options.insights ? options.InsightsPublisher : options.NullInsightsPublisher;
111
- const eventPublisher = new EventPublisher(
112
- accessToken,
113
- SDK_NAME,
114
- SDK_VERSION,
115
- options.environment,
116
- options.realm,
117
- eventPublisherOptions);
118
99
 
119
100
  Object.defineProperties(this, {
120
101
  _accessToken: {
@@ -126,9 +107,6 @@ class TwilioConnectionTransport extends StateMachine {
126
107
  _bandwidthProfile: {
127
108
  value: options.bandwidthProfile
128
109
  },
129
- _disconnectEventPublisher: {
130
- value: () => eventPublisher.disconnect()
131
- },
132
110
  _dominantSpeaker: {
133
111
  value: options.dominantSpeaker
134
112
  },
@@ -198,16 +176,9 @@ class TwilioConnectionTransport extends StateMachine {
198
176
  }
199
177
  });
200
178
 
201
- // eslint-disable-next-line no-warning-comments
202
- // TODO(mmalavalli): Create and set EventPublisher outside this class, so
203
- // that the EventPublisher constructor is no longer a dependency.
204
- this._eventObserver.setPublisher(eventPublisher);
205
179
 
206
180
  setupTransport(this);
207
181
 
208
- this.once('connected', ({ sid, participant }) => {
209
- eventPublisher.connect(sid, participant.sid);
210
- });
211
182
  }
212
183
 
213
184
  /**
@@ -315,7 +286,6 @@ class TwilioConnectionTransport extends StateMachine {
315
286
  this.preempt('disconnected', null, [error]);
316
287
  this._sendConnectOrSyncOrDisconnectMessage();
317
288
  this._twilioConnection.close();
318
- this._disconnectEventPublisher();
319
289
  return true;
320
290
  }
321
291
  return false;
@@ -1,4 +1,7 @@
1
1
  'use strict';
2
+ const packageInfo = require('../../package.json');
3
+ module.exports.SDK_NAME = `${packageInfo.name}.js`;
4
+ module.exports.SDK_VERSION = packageInfo.version;
2
5
 
3
6
  module.exports.DEFAULT_ENVIRONMENT = 'prod';
4
7
  module.exports.DEFAULT_REALM = 'us1';
@@ -8,7 +8,8 @@ const VALID_GROUPS = [
8
8
  'room',
9
9
  'media',
10
10
  'quality',
11
- 'video-processor'
11
+ 'video-processor',
12
+ 'preflight'
12
13
  ];
13
14
 
14
15
  const VALID_LEVELS = [
@@ -27,40 +28,35 @@ const VALID_LEVELS = [
27
28
  class EventObserver extends EventEmitter {
28
29
  /**
29
30
  * Constructor.
31
+ * @param {InsightsPublisher} publisher
30
32
  * @param {number} connectTimestamp
31
33
  * @param {Log} log
32
34
  * @param {EventListener} [eventListener]
33
35
  */
34
- constructor(connectTimestamp, log, eventListener = null) {
36
+ constructor(publisher, connectTimestamp, log, eventListener = null) {
35
37
  super();
36
-
37
- Object.defineProperties(this, {
38
- _publisher: {
39
- value: null,
40
- writable: true
41
- }
42
- });
43
-
44
38
  this.on('event', ({ name, group, level, payload }) => {
45
39
  if (typeof name !== 'string') {
40
+ log.error('Unexpected name: ', name);
46
41
  throw new Error('Unexpected name: ', name);
47
42
  }
48
43
 
49
44
  if (!VALID_GROUPS.includes(group)) {
45
+ log.error('Unexpected group: ', group);
50
46
  throw new Error('Unexpected group: ', group);
51
47
  }
52
48
 
53
49
  if (!VALID_LEVELS.includes(level)) {
50
+ log.error('Unexpected level: ', level);
54
51
  throw new Error('Unexpected level: ', level);
55
52
  }
56
53
 
57
54
  const timestamp = Date.now();
58
55
  const elapsedTime = timestamp - connectTimestamp;
59
56
 
60
- if (this._publisher) {
61
- const publisherPayload = Object.assign({ elapsedTime, level }, payload ? payload : {});
62
- this._publisher.publish(group, name, publisherPayload);
63
- }
57
+ const publisherPayload = Object.assign({ elapsedTime, level }, payload ? payload : {});
58
+ publisher.publish(group, name, publisherPayload);
59
+
64
60
  const event = Object.assign({
65
61
  elapsedTime,
66
62
  group,
@@ -82,14 +78,6 @@ class EventObserver extends EventEmitter {
82
78
  }
83
79
  });
84
80
  }
85
-
86
- /**
87
- * sets the publisher object. Once set events will be sent to publisher.
88
- * @param {InsightsPublisher} publisher
89
- */
90
- setPublisher(publisher) {
91
- this._publisher = publisher;
92
- }
93
81
  }
94
82
 
95
83
  /**
package/lib/util/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  const constants = require('./constants');
4
4
  const { typeErrors: E, trackPriority } = constants;
5
5
  const util = require('@twilio/webrtc/lib/util');
6
+ const { sessionSID } = require('./sid');
6
7
 
7
8
  /**
8
9
  * Return the given {@link LocalTrack} or a new {@link LocalTrack} for the
@@ -572,6 +573,8 @@ function createRoomConnectEventPayload(connectOptions) {
572
573
  return val ? 'true' : 'false';
573
574
  }
574
575
  const payload = {
576
+ sessionSID,
577
+
575
578
  // arrays props converted to lengths.
576
579
  iceServers: (connectOptions.iceServers || []).length,
577
580
  audioTracks: (connectOptions.tracks || []).filter(track => track.kind === 'audio').length,
@@ -0,0 +1,20 @@
1
+ const SID_CHARS = '1234567890abcdef';
2
+ const SID_CHAR_LENGTH = 32;
3
+ // copied from: https://code.hq.twilio.com/flex/monkey/blob/0fdce2b6c52d6be0b17a5cdb92f0c54f119b8ea8/src/client/lib/sid.ts#L39
4
+
5
+ /**
6
+ * Generates a random sid using given prefix.
7
+ * @param {string} prefix
8
+ * @returns string
9
+ */
10
+ function createSID(prefix) {
11
+ let result = '';
12
+ for (let i = 0; i < SID_CHAR_LENGTH; i++) {
13
+ result += SID_CHARS.charAt(Math.floor(Math.random() * SID_CHARS.length));
14
+ }
15
+ return `${prefix}${result}`;
16
+ }
17
+
18
+ exports.sessionSID = createSID('SS');
19
+ exports.createSID = createSID;
20
+
@@ -19,9 +19,6 @@ exports.createTwilioError = function createTwilioError(code, message) {
19
19
  return TwilioErrorByCode[code] ? new TwilioErrorByCode[code]() : new TwilioError(code, message);
20
20
  };
21
21
 
22
- // Note(mpatwardhan): We derive twilio specific errors here. After typescript compiles to es5 `instanceof` does not work
23
- // on objects that derive from Error/Array types. To workaround we call setPrototypeOf after calling super()
24
- // more on this at: https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
25
22
  /**
26
23
  * @class AccessTokenInvalidError
27
24
  * @classdesc Raised whenever the AccessToken used for connecting to a Room is invalid.
@@ -239,6 +236,7 @@ class SignalingServerBusyError extends TwilioError {
239
236
  Object.setPrototypeOf(this, SignalingServerBusyError.prototype);
240
237
  }
241
238
  }
239
+
242
240
  exports.SignalingServerBusyError = SignalingServerBusyError;
243
241
  Object.defineProperty(TwilioErrorByCode, 53006, { value: SignalingServerBusyError });
244
242
 
@@ -388,7 +386,7 @@ Object.defineProperty(TwilioErrorByCode, 53107, { value: RoomMaxParticipantsOutO
388
386
  class RoomTypeInvalidError extends TwilioError {
389
387
  constructor() {
390
388
  super(53108, 'RoomType is not valid');
391
- Object.setPrototypeOf(this, RoomMaxParticipantsOutOfRangeError.prototype);
389
+ Object.setPrototypeOf(this, RoomTypeInvalidError.prototype);
392
390
  }
393
391
  }
394
392
 
@@ -565,6 +563,40 @@ class RoomCompletedError extends TwilioError {
565
563
  exports.RoomCompletedError = RoomCompletedError;
566
564
  Object.defineProperty(TwilioErrorByCode, 53118, { value: RoomCompletedError });
567
565
 
566
+ /**
567
+ * @class RoomAudioOnlyFlagNotSupportedError
568
+ * @classdesc Raised whenever a participant tries to set the AudioOnly flag for a Room type other than Group Rooms.
569
+ * @extends TwilioError
570
+ * @property {number} code - 53124
571
+ * @property {string} message - 'The AudioOnly flag is not supported for the Room type'
572
+ */
573
+ class RoomAudioOnlyFlagNotSupportedError extends TwilioError {
574
+ constructor() {
575
+ super(53124, 'The AudioOnly flag is not supported for the Room type');
576
+ Object.setPrototypeOf(this, RoomAudioOnlyFlagNotSupportedError.prototype);
577
+ }
578
+ }
579
+
580
+ exports.RoomAudioOnlyFlagNotSupportedError = RoomAudioOnlyFlagNotSupportedError;
581
+ Object.defineProperty(TwilioErrorByCode, 53124, { value: RoomAudioOnlyFlagNotSupportedError });
582
+
583
+ /**
584
+ * @class RoomTrackKindNotSupportedError
585
+ * @classdesc Raised whenever a participant tries to publish a track or connects with a track that is not supported by the group room.
586
+ * @extends TwilioError
587
+ * @property {number} code - 53125
588
+ * @property {string} message - 'The track kind is not supported by the Room'
589
+ */
590
+ class RoomTrackKindNotSupportedError extends TwilioError {
591
+ constructor() {
592
+ super(53125, 'The track kind is not supported by the Room');
593
+ Object.setPrototypeOf(this, RoomTrackKindNotSupportedError.prototype);
594
+ }
595
+ }
596
+
597
+ exports.RoomTrackKindNotSupportedError = RoomTrackKindNotSupportedError;
598
+ Object.defineProperty(TwilioErrorByCode, 53125, { value: RoomTrackKindNotSupportedError });
599
+
568
600
  /**
569
601
  * @class ParticipantIdentityInvalidError
570
602
  * @classdesc Raised whenever a Participant identity is invalid, and the scenario is not covered by a more specific error code.
@@ -618,7 +650,7 @@ Object.defineProperty(TwilioErrorByCode, 53202, { value: ParticipantIdentityChar
618
650
 
619
651
  /**
620
652
  * @class ParticipantMaxTracksExceededError
621
- * @classdesc Raised when the Room limit for published tracks has been reached and a Participant tries to publish a track to the Room.
653
+ * @classdesc Raised whenever a Participant tries to publish a Track and the maximum number of published tracks allowed in the Room at the same time has been reached
622
654
  * @extends TwilioError
623
655
  * @property {number} code - 53203
624
656
  * @property {string} message - 'The maximum number of published tracks allowed in the Room at the same time has been reached'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "twilio-video",
3
3
  "title": "Twilio Video",
4
4
  "description": "Twilio Video JavaScript Library",
5
- "version": "2.17.0",
5
+ "version": "2.18.2",
6
6
  "homepage": "https://twilio.com",
7
7
  "author": "Mark Andrus Roberts <mroberts@twilio.com>",
8
8
  "contributors": [
@@ -85,7 +85,7 @@
85
85
  "vinyl-fs": "^2.4.4",
86
86
  "vinyl-source-stream": "^1.1.0",
87
87
  "watchify": "^3.11.1",
88
- "webrtc-adapter": "^4.1.1"
88
+ "webrtc-adapter": "^7.7.1"
89
89
  },
90
90
  "engines": {
91
91
  "node": ">=0.12"
@@ -97,7 +97,8 @@
97
97
  "lint:js": "eslint ./lib ./test/*.js ./docker/**/*.js ./test/framework/*.js ./test/lib/*.js ./test/integration/** ./test/unit/** ",
98
98
  "lint:ts": "eslint ./tsdef/*.ts ./lib/**/*.ts",
99
99
  "lint": "npm-run-all lint:js lint:ts",
100
- "test:unit": "npm-run-all build:es5 test:unit:js test:unit:ts",
100
+ "printVersion": "node --version && npm --version",
101
+ "test:unit": "npm-run-all printVersion build:es5 test:unit:js test:unit:ts",
101
102
  "test:unit:js": "nyc --report-dir=./coverage/js --extension=.js --include=lib/**/* --reporter=html --reporter=lcov --reporter=text mocha ./test/unit/index.js",
102
103
  "test:unit:ts": "nyc --report-dir=./coverage/ts --extension=.ts --include=lib/**/* --reporter=html --reporter=lcov --reporter=text mocha -r ts-node/register ./test/unit/index.ts",
103
104
  "test:serversiderender": "mocha ./test/serversiderender/index.js",
package/tsconfig.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "checkJs": false,
5
5
  "declaration": false,
6
6
  "target": "es5",
7
- "lib": ["es5", "es6", "es2016", "es2017.object", "es2018.promise", "dom"],
7
+ "lib": ["es5", "es6", "es2016", "es2019", "es2018.promise", "dom"],
8
8
  "downlevelIteration": true,
9
9
  "module": "commonjs",
10
10
  "noImplicitAny": true,
@@ -1,6 +1,5 @@
1
1
  export interface PreflightOptions {
2
2
  duration?: number;
3
- environment?: string;
4
3
  region?: string;
5
4
  }
6
5
 
@@ -26,7 +25,7 @@ export interface RTCIceCandidateStats {
26
25
  candidateType?: string;
27
26
  priority?: number;
28
27
  url?: string;
29
- relayProtocol?: number;
28
+ relayProtocol?: string;
30
29
  }
31
30
 
32
31
  export interface SelectedIceCandidatePairStats {