@whereby.com/browser-sdk 2.0.0-alpha17 → 2.0.0-alpha18

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/lib.esm.js CHANGED
@@ -1,9 +1,6 @@
1
1
  import { define, ref } from 'heresy';
2
2
  import { __rest, __awaiter } from 'tslib';
3
3
  import React, { useRef, useEffect, useState, useReducer } from 'react';
4
- import adapter from 'webrtc-adapter';
5
- import io from 'socket.io-client';
6
- import SDPUtils from 'sdp';
7
4
  import require$$0 from 'is-arguments';
8
5
  import require$$1 from 'is-generator-function';
9
6
  import require$$2 from 'which-typed-array';
@@ -12,6 +9,9 @@ import require$$2$1 from 'inherits';
12
9
  import require$$3$1 from 'es6-object-assign';
13
10
  import require$$0$1 from 'object-is';
14
11
  import require$$1$1 from 'is-nan';
12
+ import adapter from 'webrtc-adapter';
13
+ import io from 'socket.io-client';
14
+ import SDPUtils from 'sdp';
15
15
  import { detectDevice, Device } from 'mediasoup-client';
16
16
  import EventEmitter$1, { EventEmitter } from 'events';
17
17
  import { v4 } from 'uuid';
@@ -128,7 +128,7 @@ define("WherebyEmbed", {
128
128
  if (roomUrl.searchParams.get("roomKey")) {
129
129
  this.url.searchParams.append("roomKey", roomUrl.searchParams.get("roomKey"));
130
130
  }
131
- Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha17", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
131
+ Object.entries(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ jsApi: true, we: "2.0.0-alpha18", iframeSource: subdomain }, (displayName && { displayName })), (lang && { lang })), (metadata && { metadata })), (groups && { groups })), (virtualBackgroundUrl && { virtualBackgroundUrl })), (avatarUrl && { avatarUrl })), (minimal != null && { embed: minimal })), boolAttrs.reduce(
132
132
  // add to URL if set in any way
133
133
  (o, v) => (this[v.toLowerCase()] != null ? Object.assign(Object.assign({}, o), { [v]: this[v.toLowerCase()] }) : o), {}))).forEach(([k, v]) => {
134
134
  if (!this.url.searchParams.has(k) && typeof v === "string") {
@@ -144,2135 +144,1107 @@ define("WherebyEmbed", {
144
144
  },
145
145
  });
146
146
 
147
- var VideoView = (_a) => {
148
- var { muted, stream } = _a, rest = __rest(_a, ["muted", "stream"]);
149
- const videoEl = useRef(null);
150
- useEffect(() => {
151
- if (!videoEl.current) {
152
- return;
153
- }
154
- if (videoEl.current.srcObject !== stream) {
155
- videoEl.current.srcObject = stream;
156
- }
157
- // Handle muting programatically, not as video attribute
158
- // https://stackoverflow.com/questions/14111917/html5-video-muted-but-still-playing
159
- if (videoEl.current.muted !== muted) {
160
- videoEl.current.muted = Boolean(muted);
161
- }
162
- }, [muted, stream, videoEl]);
163
- return React.createElement("video", Object.assign({ ref: videoEl, autoPlay: true, playsInline: true }, rest));
147
+ function getDefaultExportFromCjs (x) {
148
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
149
+ }
150
+
151
+ var assertExports$1 = {};
152
+ var assert$1 = {
153
+ get exports(){ return assertExports$1; },
154
+ set exports(v){ assertExports$1 = v; },
164
155
  };
165
156
 
166
- const TypedLocalMediaEventTarget = EventTarget;
167
- class LocalMedia extends TypedLocalMediaEventTarget {
168
- constructor(constraints) {
169
- super();
170
- this._constraints = constraints;
171
- this.stream = new MediaStream();
172
- this._rtcManagers = [];
173
- navigator.mediaDevices.addEventListener("devicechange", this._updateDeviceList.bind(this));
174
- }
175
- addRtcManager(rtcManager) {
176
- this._rtcManagers.push(rtcManager);
177
- }
178
- removeRtcManager(rtcManager) {
179
- this._rtcManagers = this._rtcManagers.filter((r) => r !== rtcManager);
180
- }
181
- getCameraDeviceId() {
182
- var _a;
183
- return (_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
184
- }
185
- getMicrophoneDeviceId() {
186
- var _a;
187
- return (_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
188
- }
189
- isCameraEnabled() {
190
- var _a;
191
- return !!((_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
192
- }
193
- isMicrophoneEnabled() {
194
- var _a;
195
- return !!((_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
196
- }
197
- toggleCameraEnabled(enabled) {
198
- const videoTrack = this.stream.getVideoTracks()[0];
199
- if (!videoTrack) {
200
- return;
201
- }
202
- const newValue = enabled !== null && enabled !== void 0 ? enabled : !videoTrack.enabled;
203
- videoTrack.enabled = newValue;
204
- this.dispatchEvent(new CustomEvent("camera_enabled", { detail: { enabled: newValue } }));
205
- }
206
- toggleMichrophoneEnabled(enabled) {
207
- const audioTrack = this.stream.getAudioTracks()[0];
208
- if (!audioTrack) {
209
- return;
210
- }
211
- const newValue = enabled !== null && enabled !== void 0 ? enabled : !audioTrack.enabled;
212
- audioTrack.enabled = newValue;
213
- this.dispatchEvent(new CustomEvent("microphone_enabled", { detail: { enabled: newValue } }));
214
- }
215
- setCameraDevice(deviceId) {
216
- return __awaiter(this, void 0, void 0, function* () {
217
- const newStream = yield navigator.mediaDevices.getUserMedia({ video: { deviceId } });
218
- const newVideoTrack = newStream.getVideoTracks()[0];
219
- if (newVideoTrack) {
220
- const oldVideoTrack = this.stream.getVideoTracks()[0];
221
- newVideoTrack.enabled = oldVideoTrack.enabled;
222
- oldVideoTrack === null || oldVideoTrack === void 0 ? void 0 : oldVideoTrack.stop();
223
- this._rtcManagers.forEach((rtcManager) => {
224
- rtcManager.replaceTrack(oldVideoTrack, newVideoTrack);
225
- });
226
- this.stream.removeTrack(oldVideoTrack);
227
- this.stream.addTrack(newVideoTrack);
228
- }
229
- this.dispatchEvent(new CustomEvent("stream_updated", {
230
- detail: { stream: this.stream },
231
- }));
232
- });
233
- }
234
- setMicrophoneDevice(deviceId) {
235
- return __awaiter(this, void 0, void 0, function* () {
236
- const newStream = yield navigator.mediaDevices.getUserMedia({ audio: { deviceId } });
237
- const newAudioTrack = newStream.getAudioTracks()[0];
238
- const oldAudioTrack = this.stream.getAudioTracks()[0];
239
- if (oldAudioTrack) {
240
- newAudioTrack.enabled = oldAudioTrack.enabled;
241
- oldAudioTrack.stop();
242
- this.stream.removeTrack(oldAudioTrack);
243
- }
244
- this._rtcManagers.forEach((rtcManager) => {
245
- rtcManager.replaceTrack(oldAudioTrack, newAudioTrack);
246
- });
247
- this.stream.addTrack(newAudioTrack);
248
- this.dispatchEvent(new CustomEvent("stream_updated", {
249
- detail: { stream: this.stream },
250
- }));
251
- });
252
- }
253
- _updateDeviceList() {
254
- return __awaiter(this, void 0, void 0, function* () {
255
- try {
256
- const devices = yield navigator.mediaDevices.enumerateDevices();
257
- this.dispatchEvent(new CustomEvent("device_list_updated", {
258
- detail: {
259
- cameraDevices: devices.filter((d) => d.kind === "videoinput"),
260
- microphoneDevices: devices.filter((d) => d.kind === "audioinput"),
261
- speakerDevices: devices.filter((d) => d.kind === "audiooutput"),
262
- },
263
- }));
264
- }
265
- catch (error) {
266
- this.dispatchEvent(new CustomEvent("device_list_update_error", {
267
- detail: {
268
- error,
269
- },
270
- }));
271
- throw error;
272
- }
273
- });
274
- }
275
- start() {
276
- return __awaiter(this, void 0, void 0, function* () {
277
- const newStream = yield navigator.mediaDevices.getUserMedia(this._constraints);
278
- newStream.getTracks().forEach((t) => this.stream.addTrack(t));
279
- this._updateDeviceList();
280
- this.dispatchEvent(new CustomEvent("stream_updated", {
281
- detail: { stream: this.stream },
282
- }));
283
- return this.stream;
284
- });
285
- }
286
- stop() {
287
- var _a;
288
- (_a = this.stream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((t) => {
289
- t.stop();
290
- });
291
- }
292
- }
157
+ var errors = {};
293
158
 
294
- const initialState$1 = {
295
- cameraDeviceError: null,
296
- cameraDevices: [],
297
- isSettingCameraDevice: false,
298
- isSettingMicrophoneDevice: false,
299
- isStarting: false,
300
- microphoneDeviceError: null,
301
- microphoneDevices: [],
302
- speakerDevices: [],
303
- startError: null,
304
- };
305
- function reducer$1(state, action) {
306
- switch (action.type) {
307
- case "DEVICE_LIST_UPDATED":
308
- return Object.assign(Object.assign({}, state), action.payload);
309
- case "LOCAL_STREAM_UPDATED":
310
- return Object.assign(Object.assign({}, state), { currentCameraDeviceId: action.payload.currentCameraDeviceId, currentMicrophoneDeviceId: action.payload.currentMicrophoneDeviceId, localStream: action.payload.stream });
311
- case "SET_CAMERA_DEVICE":
312
- return Object.assign(Object.assign({}, state), { cameraDeviceError: null, isSettingCameraDevice: true });
313
- case "SET_CAMERA_DEVICE_COMPLETE":
314
- return Object.assign(Object.assign({}, state), { isSettingCameraDevice: false });
315
- case "SET_CAMERA_DEVICE_ERROR":
316
- return Object.assign(Object.assign({}, state), { cameraDeviceError: action.payload, isSettingCameraDevice: false });
317
- case "SET_MICROPHONE_DEVICE":
318
- return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: true, microphoneDeviceError: null });
319
- case "SET_MICROPHONE_DEVICE_COMPLETE":
320
- return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false });
321
- case "SET_MICROPHONE_DEVICE_ERROR":
322
- return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false, microphoneDeviceError: action.payload });
323
- case "START":
324
- return Object.assign(Object.assign({}, state), { isStarting: true, startError: null });
325
- case "START_COMPLETE":
326
- return Object.assign(Object.assign({}, state), { isStarting: false });
327
- case "START_ERROR":
328
- return Object.assign(Object.assign({}, state), { isStarting: false, startError: action.payload });
329
- default:
330
- return state;
331
- }
332
- }
333
- function useLocalMedia(constraints = { audio: true, video: true }) {
334
- const [localMedia] = useState(() => new LocalMedia(constraints));
335
- const [state, dispatch] = useReducer(reducer$1, initialState$1);
336
- useEffect(() => {
337
- localMedia.addEventListener("device_list_updated", (e) => {
338
- const { cameraDevices, microphoneDevices, speakerDevices } = e.detail;
339
- dispatch({ type: "DEVICE_LIST_UPDATED", payload: { cameraDevices, microphoneDevices, speakerDevices } });
340
- });
341
- localMedia.addEventListener("stream_updated", (e) => {
342
- const { stream } = e.detail;
343
- dispatch({
344
- type: "LOCAL_STREAM_UPDATED",
345
- payload: {
346
- stream,
347
- currentCameraDeviceId: localMedia.getCameraDeviceId(),
348
- currentMicrophoneDeviceId: localMedia.getMicrophoneDeviceId(),
349
- },
350
- });
351
- });
352
- const start = () => __awaiter(this, void 0, void 0, function* () {
353
- dispatch({ type: "START" });
354
- try {
355
- yield localMedia.start();
356
- dispatch({ type: "START_COMPLETE" });
357
- }
358
- catch (error) {
359
- dispatch({ type: "START_ERROR", payload: error });
360
- }
361
- });
362
- start();
363
- // Perform cleanup on unmount
364
- return () => {
365
- localMedia.stop();
366
- };
367
- }, []);
368
- return {
369
- state,
370
- actions: {
371
- setCameraDevice: (...args) => __awaiter(this, void 0, void 0, function* () {
372
- dispatch({ type: "SET_CAMERA_DEVICE" });
373
- try {
374
- yield localMedia.setCameraDevice(...args);
375
- dispatch({ type: "SET_CAMERA_DEVICE_COMPLETE" });
376
- }
377
- catch (error) {
378
- dispatch({ type: "SET_CAMERA_DEVICE_ERROR", payload: error });
379
- }
380
- }),
381
- setMicrophoneDevice: (...args) => __awaiter(this, void 0, void 0, function* () {
382
- dispatch({ type: "SET_MICROPHONE_DEVICE" });
383
- try {
384
- yield localMedia.setMicrophoneDevice(...args);
385
- dispatch({ type: "SET_MICROPHONE_DEVICE_COMPLETE" });
386
- }
387
- catch (error) {
388
- dispatch({ type: "SET_MICROPHONE_DEVICE_ERROR", payload: error });
389
- }
390
- }),
391
- toggleCameraEnabled: (...args) => {
392
- return localMedia.toggleCameraEnabled(...args);
393
- },
394
- toggleMicrophoneEnabled: (...args) => {
395
- return localMedia.toggleMichrophoneEnabled(...args);
396
- },
397
- },
398
- _ref: localMedia,
399
- };
400
- }
401
-
402
- const EVENTS = {
403
- CLIENT_CONNECTION_STATUS_CHANGED: "client_connection_status_changed",
404
- STREAM_ADDED: "stream_added",
405
- RTC_MANAGER_CREATED: "rtc_manager_created",
406
- RTC_MANAGER_DESTROYED: "rtc_manager_destroyed",
407
- LOCAL_STREAM_TRACK_ADDED: "local_stream_track_added",
408
- LOCAL_STREAM_TRACK_REMOVED: "local_stream_track_removed",
409
- REMOTE_STREAM_TRACK_ADDED: "remote_stream_track_added",
410
- REMOTE_STREAM_TRACK_REMOVED: "remote_stream_track_removed",
411
- };
159
+ var util = {};
412
160
 
413
- const TYPES = {
414
- CONNECTING: "connecting",
415
- CONNECTION_FAILED: "connection_failed",
416
- CONNECTION_SUCCESSFUL: "connection_successful",
417
- CONNECTION_DISCONNECTED: "connection_disconnected",
418
- };
161
+ var types = {};
419
162
 
420
- // Protocol enum used for the CLIENT (Make sure to keep it in sync with its server counterpart)
163
+ (function (exports) {
421
164
 
422
- // Requests: messages from the client to the server
423
- const PROTOCOL_REQUESTS = {
424
- BLOCK_CLIENT: "block_client",
425
- CLAIM_ROOM: "claim_room",
426
- CLEAR_CHAT_HISTORY: "clear_chat_history",
427
- ENABLE_AUDIO: "enable_audio",
428
- ENABLE_VIDEO: "enable_video",
429
- END_STREAM: "end_stream",
430
- FETCH_MEDIASERVER_CONFIG: "fetch_mediaserver_config",
431
- HANDLE_KNOCK: "handle_knock",
432
- IDENTIFY_DEVICE: "identify_device",
433
- INVITE_CLIENT_AS_MEMBER: "invite_client_as_member",
434
- JOIN_ROOM: "join_room",
435
- KICK_CLIENT: "kick_client",
436
- KNOCK_ROOM: "knock_room",
437
- LEAVE_ROOM: "leave_room",
438
- SEND_CLIENT_METADATA: "send_client_metadata",
439
- SET_LOCK: "set_lock",
440
- SHARE_MEDIA: "share_media",
441
- START_NEW_STREAM: "start_new_stream",
442
- START_SCREENSHARE: "start_screenshare",
443
- STOP_SCREENSHARE: "stop_screenshare",
444
- START_URL_EMBED: "start_url_embed",
445
- STOP_URL_EMBED: "stop_url_embed",
446
- START_RECORDING: "start_recording",
447
- STOP_RECORDING: "stop_recording",
448
- SFU_TOKEN: "sfu_token",
449
- };
165
+ var isArgumentsObject = require$$0;
166
+ var isGeneratorFunction = require$$1;
167
+ var whichTypedArray = require$$2;
168
+ var isTypedArray = require$$3;
450
169
 
451
- // Responses: messages from the server to the client, in response to requests
452
- const PROTOCOL_RESPONSES = {
453
- AUDIO_ENABLED: "audio_enabled",
454
- BACKGROUND_IMAGE_CHANGED: "background_image_changed",
455
- BLOCK_ADDED: "block_added",
456
- BLOCK_REMOVED: "block_removed",
457
- CHAT_HISTORY_CLEARED: "chat_history_cleared",
458
- CLIENT_BLOCKED: "client_blocked",
459
- CLIENT_INVITED_AS_MEMBER: "client_invited_as_member",
460
- CLIENT_KICKED: "client_kicked",
461
- CLIENT_LEFT: "client_left",
462
- CLIENT_METADATA_RECEIVED: "client_metadata_received",
463
- CLIENT_READY: "client_ready",
464
- CLIENT_ROLE_CHANGED: "client_role_changed",
465
- CLIENT_USER_ID_CHANGED: "client_user_id_changed",
466
- CONTACTS_UPDATED: "contacts_updated",
467
- DEVICE_IDENTIFIED: "device_identified",
468
- ROOM_ROLES_UPDATED: "room_roles_updated",
469
- KNOCK_HANDLED: "knock_handled",
470
- KNOCK_PAGE_BACKGROUND_CHANGED: "knock_page_background_changed",
471
- KNOCKER_LEFT: "knocker_left",
472
- MEDIASERVER_CONFIG: "mediaserver_config",
473
- MEDIA_SHARED: "media_shared",
474
- MEMBER_INVITE: "member_invite",
475
- NEW_CLIENT: "new_client",
476
- NEW_STREAM_STARTED: "new_stream_started",
477
- SCREENSHARE_STARTED: "screenshare_started",
478
- SCREENSHARE_STOPPED: "screenshare_stopped",
479
- OWNER_NOTIFIED: "owner_notified",
480
- OWNERS_CHANGED: "owners_changed",
481
- PLAY_CLIENT_STICKER: "play_client_sticker",
482
- ROOM_INTEGRATION_ENABLED: "room_integration_enabled",
483
- ROOM_INTEGRATION_DISABLED: "room_integration_disabled",
484
- ROOM_JOINED: "room_joined",
485
- ROOM_KNOCKED: "room_knocked",
486
- ROOM_LEFT: "room_left",
487
- ROOM_LOCKED: "room_locked",
488
- ROOM_PERMISSIONS_CHANGED: "room_permissions_changed",
489
- ROOM_LOGO_CHANGED: "room_logo_changed",
490
- ROOM_TYPE_CHANGED: "room_type_changed",
491
- ROOM_MODE_CHANGED: "room_mode_changed",
492
- SOCKET_USER_ID_CHANGED: "socket_user_id_changed",
493
- STICKERS_UNLOCKED: "stickers_unlocked",
494
- STREAM_ENDED: "stream_ended",
495
- URL_EMBED_STARTED: "url_embed_started",
496
- URL_EMBED_STOPPED: "url_embed_stopped",
497
- RECORDING_STARTED: "recording_started",
498
- RECORDING_STOPPED: "recording_stopped",
499
- USER_NOTIFIED: "user_notified",
500
- VIDEO_ENABLED: "video_enabled",
501
- CLIENT_UNABLE_TO_JOIN: "client_unable_to_join",
502
- };
170
+ function uncurryThis(f) {
171
+ return f.call.bind(f);
172
+ }
503
173
 
504
- // Relays: messages between clients, relayed through the server
505
- const RELAY_MESSAGES = {
506
- CHAT_MESSAGE: "chat_message",
507
- CHAT_READ_STATE: "chat_read_state",
508
- CHAT_STATE: "chat_state",
509
- ICE_CANDIDATE: "ice_candidate",
510
- ICE_END_OF_CANDIDATES: "ice_endofcandidates",
511
- READY_TO_RECEIVE_OFFER: "ready_to_receive_offer",
512
- REMOTE_CLIENT_MEDIA_REQUEST: "remote_client_media_request",
513
- SDP_ANSWER: "sdp_answer",
514
- SDP_OFFER: "sdp_offer",
515
- VIDEO_STICKER: "video_sticker",
516
- };
174
+ var BigIntSupported = typeof BigInt !== 'undefined';
175
+ var SymbolSupported = typeof Symbol !== 'undefined';
517
176
 
518
- /**
519
- * Wrapper class that extends the Socket.IO client library.
520
- */
521
- class ServerSocket {
522
- constructor(hostName, options) {
523
- // Prefer websockets but fallback to polling as recommended on
524
- // https://socket.io/docs/client-api/
525
- // with modifications to reconnect using WebSocket if we ever
526
- // connected with Websockets.
527
- if (options && !options.transports) {
528
- options.transports = ["websocket"];
529
- }
177
+ var ObjectToString = uncurryThis(Object.prototype.toString);
530
178
 
531
- this._socket = io(hostName, options);
532
- this._socket.io.on("reconnect", () => {
533
- this._socket.sendBuffer = [];
534
- });
535
- this._socket.io.on("reconnect_attempt", () => {
536
- if (this._wasConnectedUsingWebsocket) {
537
- this._socket.io.opts.transports = ["websocket"];
538
- // only fallback to polling if not safari
539
- // safari doesn't support cross doamin cookies making load-balancer stickiness not work
540
- // and if socket.io reconnects to another signal instance with polling it will fail
541
- // remove if we move signal to a whereby.com subdomain
542
- if (adapter.browserDetails.browser !== "safari") delete this._wasConnectedUsingWebsocket;
543
- } else {
544
- this._socket.io.opts.transports = ["polling", "websocket"];
545
- }
546
- });
547
- this._socket.on("connect", () => {
548
- const transport = this.getTransport();
549
- if (transport === "websocket") {
550
- this._wasConnectedUsingWebsocket = true;
551
- }
552
- });
553
- }
179
+ var numberValue = uncurryThis(Number.prototype.valueOf);
180
+ var stringValue = uncurryThis(String.prototype.valueOf);
181
+ var booleanValue = uncurryThis(Boolean.prototype.valueOf);
554
182
 
555
- connect() {
556
- if (this.isConnected() || this.isConnecting()) {
557
- return;
558
- }
559
- this._socket.open();
560
- }
183
+ if (BigIntSupported) {
184
+ var bigIntValue = uncurryThis(BigInt.prototype.valueOf);
185
+ }
561
186
 
562
- disconnect() {
563
- this._socket.disconnect();
564
- }
187
+ if (SymbolSupported) {
188
+ var symbolValue = uncurryThis(Symbol.prototype.valueOf);
189
+ }
565
190
 
566
- disconnectOnConnect() {
567
- this._socket.once("connect", () => {
568
- this._socket.disconnect();
569
- });
570
- }
191
+ function checkBoxedPrimitive(value, prototypeValueOf) {
192
+ if (typeof value !== 'object') {
193
+ return false;
194
+ }
195
+ try {
196
+ prototypeValueOf(value);
197
+ return true;
198
+ } catch(e) {
199
+ return false;
200
+ }
201
+ }
571
202
 
572
- emit() {
573
- this._socket.emit.apply(this._socket, arguments);
574
- }
203
+ exports.isArgumentsObject = isArgumentsObject;
204
+ exports.isGeneratorFunction = isGeneratorFunction;
205
+ exports.isTypedArray = isTypedArray;
575
206
 
576
- emitIfConnected(eventName, data) {
577
- if (!this.isConnected()) {
578
- return;
579
- }
580
- this.emit(eventName, data);
581
- }
207
+ // Taken from here and modified for better browser support
208
+ // https://github.com/sindresorhus/p-is-promise/blob/cda35a513bda03f977ad5cde3a079d237e82d7ef/index.js
209
+ function isPromise(input) {
210
+ return (
211
+ (
212
+ typeof Promise !== 'undefined' &&
213
+ input instanceof Promise
214
+ ) ||
215
+ (
216
+ input !== null &&
217
+ typeof input === 'object' &&
218
+ typeof input.then === 'function' &&
219
+ typeof input.catch === 'function'
220
+ )
221
+ );
222
+ }
223
+ exports.isPromise = isPromise;
582
224
 
583
- getTransport() {
584
- return (
585
- this._socket &&
586
- this._socket.io &&
587
- this._socket.io.engine &&
588
- this._socket.io.engine.transport &&
589
- this._socket.io.engine.transport.name
590
- );
591
- }
225
+ function isArrayBufferView(value) {
226
+ if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
227
+ return ArrayBuffer.isView(value);
228
+ }
592
229
 
593
- getManager() {
594
- return this._socket.io;
595
- }
230
+ return (
231
+ isTypedArray(value) ||
232
+ isDataView(value)
233
+ );
234
+ }
235
+ exports.isArrayBufferView = isArrayBufferView;
596
236
 
597
- isConnecting() {
598
- return this._socket && this._socket.connecting;
599
- }
600
237
 
601
- isConnected() {
602
- return this._socket && this._socket.connected;
603
- }
604
-
605
- /**
606
- * Register a new event handler.
607
- *
608
- * @param {string} eventName - Name of the event to listen for.
609
- * @param {function} handler - The callback function that should be called for the event.
610
- * @returns {function} Function to deregister the listener.
611
- */
612
- on(eventName, handler) {
613
- this._socket.on(eventName, handler);
238
+ function isUint8Array(value) {
239
+ return whichTypedArray(value) === 'Uint8Array';
240
+ }
241
+ exports.isUint8Array = isUint8Array;
614
242
 
615
- return () => {
616
- this._socket.off(eventName, handler);
617
- };
618
- }
243
+ function isUint8ClampedArray(value) {
244
+ return whichTypedArray(value) === 'Uint8ClampedArray';
245
+ }
246
+ exports.isUint8ClampedArray = isUint8ClampedArray;
619
247
 
620
- /**
621
- * Register a new event handler to be triggered only once.
622
- *
623
- * @param {string} eventName - Name of the event to listen for.
624
- * @param {function} handler - The function that should be called for the event.
625
- */
626
- once(eventName, handler) {
627
- this._socket.once(eventName, handler);
628
- }
248
+ function isUint16Array(value) {
249
+ return whichTypedArray(value) === 'Uint16Array';
250
+ }
251
+ exports.isUint16Array = isUint16Array;
629
252
 
630
- /**
631
- * Deregister an event handler.
632
- *
633
- * @param {string} eventName - Name of the event the handler is registered for.
634
- * @param {function} handler - The callback that will be deregistered.
635
- */
636
- off(eventName, handler) {
637
- this._socket.off(eventName, handler);
638
- }
639
- }
253
+ function isUint32Array(value) {
254
+ return whichTypedArray(value) === 'Uint32Array';
255
+ }
256
+ exports.isUint32Array = isUint32Array;
640
257
 
641
- var rtcManagerEvents = {
642
- CAMERA_NOT_WORKING: "camera_not_working",
643
- CONNECTION_BLOCKED_BY_NETWORK: "connection_blocked_by_network",
644
- MICROPHONE_NOT_WORKING: "microphone_not_working",
645
- MICROPHONE_STOPPED_WORKING: "microphone_stopped_working",
646
- SFU_CONNECTION_CLOSED: "sfu_connection_closed",
647
- COLOCATION_SPEAKER: "colocation_speaker",
648
- DOMINANT_SPEAKER: "dominant_speaker",
649
- };
258
+ function isInt8Array(value) {
259
+ return whichTypedArray(value) === 'Int8Array';
260
+ }
261
+ exports.isInt8Array = isInt8Array;
650
262
 
651
- const browserName$2 = adapter.browserDetails.browser;
652
- const browserVersion$1 = adapter.browserDetails.version;
263
+ function isInt16Array(value) {
264
+ return whichTypedArray(value) === 'Int16Array';
265
+ }
266
+ exports.isInt16Array = isInt16Array;
653
267
 
654
- // SDP mangling for deprioritizing H264
655
- function deprioritizeH264(sdp) {
656
- return SDPUtils.splitSections(sdp)
657
- .map(section => {
658
- // only modify video sections
659
- if (SDPUtils.getKind(section) !== "video") return section;
268
+ function isInt32Array(value) {
269
+ return whichTypedArray(value) === 'Int32Array';
270
+ }
271
+ exports.isInt32Array = isInt32Array;
660
272
 
661
- // list of payloadTypes used in this sdp/section
662
- const h264payloadTypes = SDPUtils.matchPrefix(section, "a=rtpmap:")
663
- .map(line => SDPUtils.parseRtpMap(line))
664
- .filter(codec => /h264/i.test(codec.name))
665
- .map(codec => "" + codec.payloadType);
273
+ function isFloat32Array(value) {
274
+ return whichTypedArray(value) === 'Float32Array';
275
+ }
276
+ exports.isFloat32Array = isFloat32Array;
666
277
 
667
- // return as is if no h264 found
668
- if (!h264payloadTypes.length) return section;
278
+ function isFloat64Array(value) {
279
+ return whichTypedArray(value) === 'Float64Array';
280
+ }
281
+ exports.isFloat64Array = isFloat64Array;
669
282
 
670
- // reorder and replace
671
- const mline = SDPUtils.matchPrefix(section, "m=video")[0];
672
- const mlinePayloadsSection = /(\s\d+)+$/i.exec(mline)[0];
673
- const mlinePayloadsNonH264 = mlinePayloadsSection
674
- .split(" ")
675
- .filter(payloadType => payloadType && !h264payloadTypes.includes(payloadType));
676
- const reorderedPayloads = [...mlinePayloadsNonH264, ...h264payloadTypes].join(" ");
677
- const newmline = mline.replace(mlinePayloadsSection, " " + reorderedPayloads);
678
- return section.replace(mline, newmline);
679
- })
680
- .join("");
681
- }
283
+ function isBigInt64Array(value) {
284
+ return whichTypedArray(value) === 'BigInt64Array';
285
+ }
286
+ exports.isBigInt64Array = isBigInt64Array;
682
287
 
683
- // TODO: currently assumes video, look at track.kind
684
- // ensures that SSRCs in new description match ssrcs in old description
685
- function replaceSSRCs(currentDescription, newDescription) {
686
- let ssrcs = currentDescription.match(/a=ssrc-group:FID (\d+) (\d+)\r\n/);
687
- let newssrcs = newDescription.match(/a=ssrc-group:FID (\d+) (\d+)\r\n/);
688
- // Firefox offers dont have a FID ssrc group (yet)
689
- if (!ssrcs) {
690
- ssrcs = currentDescription.match(/a=ssrc:(\d+) cname:(.*)\r\n/g)[1].match(/a=ssrc:(\d+)/);
691
- newssrcs = newDescription.match(/a=ssrc:(\d+) cname:(.*)\r\n/g)[1].match(/a=ssrc:(\d+)/);
692
- }
693
- for (let i = 1; i < ssrcs.length; i++) {
694
- newDescription = newDescription.replace(new RegExp(newssrcs[i], "g"), ssrcs[i]);
695
- }
696
- return newDescription;
697
- }
288
+ function isBigUint64Array(value) {
289
+ return whichTypedArray(value) === 'BigUint64Array';
290
+ }
291
+ exports.isBigUint64Array = isBigUint64Array;
698
292
 
699
- // Firefox < 63 (but not Firefox ESR 60) is affected by this:
700
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1478685
701
- // filter out the mid rtp header extension
702
- function filterMidExtension(sdp) {
703
- if (browserName$2 !== "safari" && (browserName$2 !== "firefox" || browserVersion$1 >= 63 || browserVersion$1 === 60)) {
704
- return sdp;
705
- }
706
- return (
707
- SDPUtils.splitLines(sdp.trim())
708
- .filter(line => {
709
- if (!line.startsWith("a=extmap:")) {
710
- return true;
711
- }
712
- const extmap = SDPUtils.parseExtmap(line);
713
- return extmap.uri !== "urn:ietf:params:rtp-hdrext:sdes:mid";
714
- })
715
- .join("\r\n") + "\r\n"
716
- );
717
- }
293
+ function isMapToString(value) {
294
+ return ObjectToString(value) === '[object Map]';
295
+ }
296
+ isMapToString.working = (
297
+ typeof Map !== 'undefined' &&
298
+ isMapToString(new Map())
299
+ );
718
300
 
719
- // Firefox < 68 (at least) is affected by this, although it is not
720
- // clear that FF is to blame:
721
- // https://bugzilla.mozilla.org/show_bug.cgi?id=1534673
722
- // Filter out a:msid-semantic header
723
- function filterMsidSemantic(sdp) {
724
- if (browserName$2 !== "firefox") {
725
- return sdp;
726
- }
727
- return (
728
- SDPUtils.splitLines(sdp.trim())
729
- .map(line => (line.startsWith("a=msid-semantic:") ? "a=msid-semantic: WMS *" : line))
730
- .join("\r\n") + "\r\n"
731
- );
732
- }
301
+ function isMap(value) {
302
+ if (typeof Map === 'undefined') {
303
+ return false;
304
+ }
733
305
 
734
- function isRelayed(pc) {
735
- return pc.getStats(null).then(result => {
736
- let localCandidateType;
737
- let remoteCandidateType;
738
- result.forEach(report => {
739
- // Chrome 58+ / spec
740
- if (report.type === "transport" && report.selectedCandidatePairId) {
741
- const transport = result.get(report.selectedCandidatePairId);
742
- if (!transport) {
743
- return;
744
- }
745
- localCandidateType = result.get(transport.localCandidateId).candidateType;
746
- remoteCandidateType = result.get(transport.remoteCandidateId).candidateType;
747
- return;
748
- }
749
- // Firefox (missing type=transport)
750
- if (report.type === "candidate-pair" && report.selected) {
751
- localCandidateType = result.get(report.localCandidateId).candidateType;
752
- remoteCandidateType = result.get(report.remoteCandidateId).candidateType;
753
- }
754
- });
755
- return (
756
- localCandidateType === "relay" ||
757
- localCandidateType === "relayed" || // relay: spec-stats; relayed: Firefox (bug)
758
- remoteCandidateType === "relay" ||
759
- remoteCandidateType === "relayed"
760
- );
761
- });
762
- }
306
+ return isMapToString.working
307
+ ? isMapToString(value)
308
+ : value instanceof Map;
309
+ }
310
+ exports.isMap = isMap;
763
311
 
764
- const logger$4 = console;
312
+ function isSetToString(value) {
313
+ return ObjectToString(value) === '[object Set]';
314
+ }
315
+ isSetToString.working = (
316
+ typeof Set !== 'undefined' &&
317
+ isSetToString(new Set())
318
+ );
319
+ function isSet(value) {
320
+ if (typeof Set === 'undefined') {
321
+ return false;
322
+ }
765
323
 
766
- // use https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters to change the video bandwidth.
767
- function setVideoBandwidthUsingSetParameters(pc, bandwidth) {
768
- const sender = pc.getSenders().find(s => s.track && s.track.kind === "video");
769
- if (!sender) {
770
- return Promise.resolve();
771
- }
324
+ return isSetToString.working
325
+ ? isSetToString(value)
326
+ : value instanceof Set;
327
+ }
328
+ exports.isSet = isSet;
772
329
 
773
- const parameters = sender.getParameters();
774
- if (parameters.encodings && parameters.encodings.length === 0) {
775
- return Promise.resolve();
776
- }
330
+ function isWeakMapToString(value) {
331
+ return ObjectToString(value) === '[object WeakMap]';
332
+ }
333
+ isWeakMapToString.working = (
334
+ typeof WeakMap !== 'undefined' &&
335
+ isWeakMapToString(new WeakMap())
336
+ );
337
+ function isWeakMap(value) {
338
+ if (typeof WeakMap === 'undefined') {
339
+ return false;
340
+ }
777
341
 
778
- if (!parameters.encodings) {
779
- // workaround for Firefox
780
- parameters.encodings = [{}];
781
- }
342
+ return isWeakMapToString.working
343
+ ? isWeakMapToString(value)
344
+ : value instanceof WeakMap;
345
+ }
346
+ exports.isWeakMap = isWeakMap;
782
347
 
783
- if (bandwidth === 0) {
784
- delete parameters.encodings[0].maxBitrate;
785
- } else {
786
- parameters.encodings[0].maxBitrate = bandwidth * 1000; // convert to bps
787
- }
788
-
789
- return sender.setParameters(parameters).catch(err => {
790
- logger$4.error("setParameters err: ", err);
791
- });
792
- }
348
+ function isWeakSetToString(value) {
349
+ return ObjectToString(value) === '[object WeakSet]';
350
+ }
351
+ isWeakSetToString.working = (
352
+ typeof WeakSet !== 'undefined' &&
353
+ isWeakSetToString(new WeakSet())
354
+ );
355
+ function isWeakSet(value) {
356
+ return isWeakSetToString(value);
357
+ }
358
+ exports.isWeakSet = isWeakSet;
793
359
 
794
- const logger$3 = console;
360
+ function isArrayBufferToString(value) {
361
+ return ObjectToString(value) === '[object ArrayBuffer]';
362
+ }
363
+ isArrayBufferToString.working = (
364
+ typeof ArrayBuffer !== 'undefined' &&
365
+ isArrayBufferToString(new ArrayBuffer())
366
+ );
367
+ function isArrayBuffer(value) {
368
+ if (typeof ArrayBuffer === 'undefined') {
369
+ return false;
370
+ }
795
371
 
796
- class Session {
797
- constructor({ peerConnectionId, bandwidth, maximumTurnBandwidth, deprioritizeH264Encoding }) {
798
- this.peerConnectionId = peerConnectionId;
799
- this.relayCandidateSeen = false;
800
- this.pc = null;
801
- this.wasEverConnected = false;
802
- this.connectionStatus = null;
803
- this.stats = {
804
- totalSent: 0,
805
- totalRecv: 0,
806
- };
807
- this.bandwidth = bandwidth || 0; // maximum bandwidth in kbps.
808
- this.maximumTurnBandwidth = maximumTurnBandwidth;
809
- this.pending = [];
810
- this.isOperationPending = false;
811
- this.streamIds = [];
812
- this.streams = [];
813
- this.earlyIceCandidates = [];
814
- this.afterConnected = new Promise(resolve => {
815
- this.registerConnected = resolve;
816
- });
817
- this.offerOptions = { offerToReceiveAudio: true, offerToReceiveVideo: true };
818
- this._deprioritizeH264Encoding = deprioritizeH264Encoding;
819
- }
372
+ return isArrayBufferToString.working
373
+ ? isArrayBufferToString(value)
374
+ : value instanceof ArrayBuffer;
375
+ }
376
+ exports.isArrayBuffer = isArrayBuffer;
820
377
 
821
- setAndGetPeerConnection({ clientId, constraints, peerConnectionConfig, shouldAddLocalVideo }) {
822
- this.peerConnectionConfig = peerConnectionConfig;
823
- this.shouldAddLocalVideo = shouldAddLocalVideo;
824
- this.clientId = clientId;
825
- this.pc = new RTCPeerConnection(peerConnectionConfig, constraints);
826
- this.signalingState = this.pc.signalingState;
378
+ function isDataViewToString(value) {
379
+ return ObjectToString(value) === '[object DataView]';
380
+ }
381
+ isDataViewToString.working = (
382
+ typeof ArrayBuffer !== 'undefined' &&
383
+ typeof DataView !== 'undefined' &&
384
+ isDataViewToString(new DataView(new ArrayBuffer(1), 0, 1))
385
+ );
386
+ function isDataView(value) {
387
+ if (typeof DataView === 'undefined') {
388
+ return false;
389
+ }
827
390
 
828
- this.pc.addEventListener("signalingstatechange", () => {
829
- if (this.signalingState === this.pc.signalingState) {
830
- return;
831
- }
832
- this.signalingState = this.pc.signalingState;
833
- // implements a simple queue of pending operations
834
- // like doing an ice restart or setting the bandwidth
835
- if (this.pc.signalingState === "stable") {
836
- this.isOperationPending = false;
837
- const action = this.pending.shift();
838
- if (action) {
839
- action.apply();
840
- }
841
- }
842
- });
391
+ return isDataViewToString.working
392
+ ? isDataViewToString(value)
393
+ : value instanceof DataView;
394
+ }
395
+ exports.isDataView = isDataView;
843
396
 
844
- return this.pc;
845
- }
397
+ // Store a copy of SharedArrayBuffer in case it's deleted elsewhere
398
+ var SharedArrayBufferCopy = typeof SharedArrayBuffer !== 'undefined' ? SharedArrayBuffer : undefined;
399
+ function isSharedArrayBufferToString(value) {
400
+ return ObjectToString(value) === '[object SharedArrayBuffer]';
401
+ }
402
+ function isSharedArrayBuffer(value) {
403
+ if (typeof SharedArrayBufferCopy === 'undefined') {
404
+ return false;
405
+ }
846
406
 
847
- addStream(stream) {
848
- this.streamIds.push(stream.id);
849
- this.streams.push(stream);
850
- if (RTCPeerConnection.prototype.addTrack) {
851
- stream.getAudioTracks().forEach(track => {
852
- this.pc.addTrack(track, stream);
853
- });
854
- stream.getVideoTracks().forEach(track => {
855
- this.pc.addTrack(track, stream);
856
- });
857
- } else {
858
- // legacy addStream fallback.
859
- this.pc.addStream(stream);
860
- }
861
- }
407
+ if (typeof isSharedArrayBufferToString.working === 'undefined') {
408
+ isSharedArrayBufferToString.working = isSharedArrayBufferToString(new SharedArrayBufferCopy());
409
+ }
862
410
 
863
- addTrack(track, stream) {
864
- if (!stream) {
865
- stream = this.streams[0];
866
- }
867
- stream.addTrack(track);
868
- this.pc.addTrack(track, stream);
869
- }
411
+ return isSharedArrayBufferToString.working
412
+ ? isSharedArrayBufferToString(value)
413
+ : value instanceof SharedArrayBufferCopy;
414
+ }
415
+ exports.isSharedArrayBuffer = isSharedArrayBuffer;
870
416
 
871
- removeTrack(track) {
872
- const stream = this.streams[0];
873
- stream.removeTrack(track);
874
- const sender = this.pc.getSenders().find(sender => sender.track === track);
875
- if (sender) {
876
- this.pc.removeTrack(sender);
877
- }
878
- }
417
+ function isAsyncFunction(value) {
418
+ return ObjectToString(value) === '[object AsyncFunction]';
419
+ }
420
+ exports.isAsyncFunction = isAsyncFunction;
879
421
 
880
- removeStream(stream) {
881
- for (let i = 0; i < this.streamIds.length; i++) {
882
- if (this.streamIds[i] === stream.id) {
883
- this.streamIds.splice(i, 1);
884
- this.streams.splice(i, 1);
885
- }
886
- }
422
+ function isMapIterator(value) {
423
+ return ObjectToString(value) === '[object Map Iterator]';
424
+ }
425
+ exports.isMapIterator = isMapIterator;
887
426
 
888
- if (this.pc) {
889
- if (this.pc.removeTrack) {
890
- stream.getTracks().forEach(track => {
891
- const sender = this.pc.getSenders().find(sender => sender.track === track);
892
- if (sender) {
893
- this.pc.removeTrack(sender);
894
- }
895
- });
896
- } else if (this.pc.removeStream) {
897
- this.pc.removeStream(stream);
898
- }
899
- }
900
- }
427
+ function isSetIterator(value) {
428
+ return ObjectToString(value) === '[object Set Iterator]';
429
+ }
430
+ exports.isSetIterator = isSetIterator;
901
431
 
902
- _setRemoteDescription(desc) {
903
- // deprioritize H264 Encoding if set by option/flag
904
- if (this._deprioritizeH264Encoding) desc.sdp = deprioritizeH264(desc.sdp);
432
+ function isGeneratorObject(value) {
433
+ return ObjectToString(value) === '[object Generator]';
434
+ }
435
+ exports.isGeneratorObject = isGeneratorObject;
905
436
 
906
- // wrapper around SRD which stores a promise
907
- this.srdComplete = this.pc.setRemoteDescription(desc);
908
- return this.srdComplete.then(() => {
909
- this.earlyIceCandidates.forEach(candidate => this.pc.addIceCandidate(candidate));
910
- this.earlyIceCandidates = [];
911
- });
912
- }
437
+ function isWebAssemblyCompiledModule(value) {
438
+ return ObjectToString(value) === '[object WebAssembly.Module]';
439
+ }
440
+ exports.isWebAssemblyCompiledModule = isWebAssemblyCompiledModule;
913
441
 
914
- handleOffer(message) {
915
- if (!this.canModifyPeerConnection()) {
916
- return new Promise(resolve => {
917
- this.pending.push(() => this.handleOffer(message).then(resolve));
918
- });
919
- }
920
- this.isOperationPending = true;
921
- let sdp = message.sdp;
442
+ function isNumberObject(value) {
443
+ return checkBoxedPrimitive(value, numberValue);
444
+ }
445
+ exports.isNumberObject = isNumberObject;
922
446
 
923
- sdp = filterMidExtension(sdp);
924
- sdp = filterMsidSemantic(sdp);
447
+ function isStringObject(value) {
448
+ return checkBoxedPrimitive(value, stringValue);
449
+ }
450
+ exports.isStringObject = isStringObject;
925
451
 
926
- const desc = { type: message.type, sdp };
927
- // Create an answer to send to the client that sent the offer
928
- let answerToSignal;
452
+ function isBooleanObject(value) {
453
+ return checkBoxedPrimitive(value, booleanValue);
454
+ }
455
+ exports.isBooleanObject = isBooleanObject;
929
456
 
930
- return this._setRemoteDescription(desc)
931
- .then(() => {
932
- return this.pc.createAnswer();
933
- })
934
- .then(answer => {
935
- answerToSignal = answer;
936
- return this.pc.setLocalDescription(answer);
937
- })
938
- .then(() => {
939
- return setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
940
- })
941
- .then(() => {
942
- return answerToSignal;
943
- });
944
- }
457
+ function isBigIntObject(value) {
458
+ return BigIntSupported && checkBoxedPrimitive(value, bigIntValue);
459
+ }
460
+ exports.isBigIntObject = isBigIntObject;
945
461
 
946
- handleAnswer(message) {
947
- // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1394602
948
- if (this.pendingOffer) {
949
- const pendingOffer = this.pendingOffer;
950
- delete this.pendingOffer;
951
- return this.pc.setLocalDescription(pendingOffer).then(() => this.handleAnswer(message));
952
- }
953
- let sdp = message.sdp;
462
+ function isSymbolObject(value) {
463
+ return SymbolSupported && checkBoxedPrimitive(value, symbolValue);
464
+ }
465
+ exports.isSymbolObject = isSymbolObject;
954
466
 
955
- sdp = filterMsidSemantic(sdp);
467
+ function isBoxedPrimitive(value) {
468
+ return (
469
+ isNumberObject(value) ||
470
+ isStringObject(value) ||
471
+ isBooleanObject(value) ||
472
+ isBigIntObject(value) ||
473
+ isSymbolObject(value)
474
+ );
475
+ }
476
+ exports.isBoxedPrimitive = isBoxedPrimitive;
956
477
 
957
- const desc = { type: message.type, sdp };
958
- return this._setRemoteDescription(desc).then(
959
- () => {
960
- return setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
961
- },
962
- e => {
963
- logger$3.warn("Could not set remote description from remote answer: ", e);
964
- }
965
- );
966
- }
478
+ function isAnyArrayBuffer(value) {
479
+ return typeof Uint8Array !== 'undefined' && (
480
+ isArrayBuffer(value) ||
481
+ isSharedArrayBuffer(value)
482
+ );
483
+ }
484
+ exports.isAnyArrayBuffer = isAnyArrayBuffer;
967
485
 
968
- addIceCandidate(candidate) {
969
- if (!this.srdComplete) {
970
- // In theory this is a protocol violation. However, our Javascript can signal an
971
- // answer after the first candidates.
972
- this.earlyIceCandidates.push(candidate);
973
- return;
974
- }
975
- this.srdComplete.then(() => {
976
- if (this.pc.signalingState === "closed") {
977
- return;
978
- }
979
- if (adapter.browserDetails.browser === "safari" && candidate && candidate.candidate === "") {
980
- // filter due to https://github.com/webrtcHacks/adapter/issues/863
981
- return;
982
- }
983
- this.pc.addIceCandidate(candidate).catch(e => {
984
- logger$3.warn("Failed to add ICE candidate ('%s'): %s", candidate ? candidate.candidate : null, e);
985
- });
986
- });
987
- }
486
+ ['isProxy', 'isExternal', 'isModuleNamespaceObject'].forEach(function(method) {
487
+ Object.defineProperty(exports, method, {
488
+ enumerable: false,
489
+ value: function() {
490
+ throw new Error(method + ' is not supported in userland');
491
+ }
492
+ });
493
+ });
494
+ } (types));
988
495
 
989
- canModifyPeerConnection() {
990
- return this.pc.signalingState === "stable" && !this.isOperationPending;
991
- }
496
+ var isBuffer = function isBuffer(arg) {
497
+ return arg instanceof Buffer;
498
+ };
992
499
 
993
- close() {
994
- const pc = this.pc;
995
- if (!pc) {
996
- return;
997
- }
500
+ (function (exports) {
501
+ // Copyright Joyent, Inc. and other Node contributors.
502
+ //
503
+ // Permission is hereby granted, free of charge, to any person obtaining a
504
+ // copy of this software and associated documentation files (the
505
+ // "Software"), to deal in the Software without restriction, including
506
+ // without limitation the rights to use, copy, modify, merge, publish,
507
+ // distribute, sublicense, and/or sell copies of the Software, and to permit
508
+ // persons to whom the Software is furnished to do so, subject to the
509
+ // following conditions:
510
+ //
511
+ // The above copyright notice and this permission notice shall be included
512
+ // in all copies or substantial portions of the Software.
513
+ //
514
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
515
+ // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
516
+ // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
517
+ // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
518
+ // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
519
+ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
520
+ // USE OR OTHER DEALINGS IN THE SOFTWARE.
998
521
 
999
- pc.oniceconnectionstatechange = null;
1000
- pc.onicecandidate = null;
1001
- pc.ontrack = null;
1002
- try {
1003
- // do not handle state change events when we close the connection explicitly
1004
- pc.close();
1005
- } catch (e) {
1006
- console.warn("failures during close of session", e);
1007
- // we're not interested in errors from RTCPeerConnection.close()
1008
- }
1009
- }
522
+ var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors ||
523
+ function getOwnPropertyDescriptors(obj) {
524
+ var keys = Object.keys(obj);
525
+ var descriptors = {};
526
+ for (var i = 0; i < keys.length; i++) {
527
+ descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]);
528
+ }
529
+ return descriptors;
530
+ };
1010
531
 
1011
- hasConnectedPeerConnection() {
1012
- return this.pc && this.pc.connectionState === "connected";
1013
- }
532
+ var formatRegExp = /%[sdj%]/g;
533
+ exports.format = function(f) {
534
+ if (!isString(f)) {
535
+ var objects = [];
536
+ for (var i = 0; i < arguments.length; i++) {
537
+ objects.push(inspect(arguments[i]));
538
+ }
539
+ return objects.join(' ');
540
+ }
1014
541
 
1015
- replaceTrack(oldTrack, newTrack) {
1016
- const pc = this.pc;
1017
- // This shouldn't really happen
1018
- if (!pc) return false;
1019
- const senders = pc.getSenders();
1020
- function dbg(msg) {
1021
- const tr = t => t && `id:${t.id},kind:${t.kind},state:${t.readyState}`;
1022
- logger$3.warn(
1023
- `${msg}. newTrack:${tr(newTrack)}, oldTrack:${tr(oldTrack)}, sender tracks: ${JSON.stringify(
1024
- senders.map(s => `s ${tr(s.track)}`)
1025
- )}, sender first codecs: ${JSON.stringify(senders.map(s => (s.getParameters().codecs || [])[0]))}`
1026
- );
1027
- }
1028
- if (!senders.length) {
1029
- dbg("No senders!");
1030
- }
1031
- // If we didn't specify oldTrack, replace with first of its kind
1032
- if (!oldTrack) {
1033
- oldTrack = (senders.find(s => s.track && s.track.kind === newTrack.kind) || {}).track;
1034
- if (!oldTrack) {
1035
- // odin: Temporary debug data, remove if you see after 2020-12-01
1036
- dbg("No sender with same kind! Add new track then.");
1037
- }
1038
- }
1039
- // Modern browsers makes things simple.
1040
- if (window.RTCRtpSender && window.RTCRtpSender.prototype.replaceTrack) {
1041
- if (oldTrack) {
1042
- const process = () => {
1043
- for (let i = 0; i < senders.length; i++) {
1044
- const sender = senders[i];
1045
- const track = sender.track;
1046
- if (!sender && !track) {
1047
- // odin: Temporary debug data, remove if you see after 2020-12-01
1048
- dbg("One of the tracks is null!");
1049
- }
1050
- if (track.id === newTrack.id) {
1051
- return Promise.resolve(newTrack);
1052
- }
1053
- if (track.id === oldTrack.id) {
1054
- return senders[i].replaceTrack(newTrack);
1055
- }
1056
- }
1057
- return null;
1058
- };
1059
- let result = process();
1060
- if (result) {
1061
- return result;
1062
- }
1063
- let resolve = null;
1064
- let reject = null;
1065
- result = new Promise((_resolve, _reject) => {
1066
- resolve = _resolve;
1067
- reject = _reject;
1068
- });
1069
- let retried = 0;
1070
- let timer = setInterval(async () => {
1071
- const trackReplacedPromise = process();
1072
- if (!trackReplacedPromise) {
1073
- if (3 < ++retried) {
1074
- clearInterval(timer);
1075
- timer = null;
1076
- dbg("No sender track to replace");
1077
- reject("No sender track to replace");
1078
- }
1079
- return;
1080
- }
1081
- clearInterval(timer);
1082
- timer = null;
1083
- const trackReplaced = await trackReplacedPromise;
1084
- resolve(trackReplaced);
1085
- }, 1000);
1086
- // if we have an oldtrack, we should not go forward, because
1087
- // we already know that the track has been added at least to the mediastream
1088
- return result;
1089
- }
1090
- const stream = this.streams.find(s => s.getTracks().find(t => t.id === newTrack.id)) || this.streams[0];
1091
- if (!stream) {
1092
- dbg("No stream?");
1093
- return Promise.reject(new Error("replaceTrack: No stream?"));
1094
- }
1095
- // Let's just add the track if we couldn't figure out a better way.
1096
- // We'll get here if you had no camera and plugged one in.
1097
- return pc.addTrack(newTrack, stream);
1098
- }
542
+ var i = 1;
543
+ var args = arguments;
544
+ var len = args.length;
545
+ var str = String(f).replace(formatRegExp, function(x) {
546
+ if (x === '%%') return '%';
547
+ if (i >= len) return x;
548
+ switch (x) {
549
+ case '%s': return String(args[i++]);
550
+ case '%d': return Number(args[i++]);
551
+ case '%j':
552
+ try {
553
+ return JSON.stringify(args[i++]);
554
+ } catch (_) {
555
+ return '[Circular]';
556
+ }
557
+ default:
558
+ return x;
559
+ }
560
+ });
561
+ for (var x = args[i]; i < len; x = args[++i]) {
562
+ if (isNull(x) || !isObject(x)) {
563
+ str += ' ' + x;
564
+ } else {
565
+ str += ' ' + inspect(x);
566
+ }
567
+ }
568
+ return str;
569
+ };
1099
570
 
1100
- if (!this.canModifyPeerConnection()) {
1101
- this.pending.push(() => {
1102
- this.replaceTrack(oldTrack, newTrack);
1103
- });
1104
- return;
1105
- }
1106
- this.isOperationPending = true;
1107
- const onn = pc.onnegotiationneeded;
1108
- pc.onnegotiationneeded = null;
1109
- this.removeTrack(oldTrack);
1110
- this.addTrack(newTrack);
1111
- setTimeout(() => {
1112
- // negotiationneeded is fired async, restore it async.
1113
- pc.onnegotiationneeded = onn;
1114
- }, 0);
1115
571
 
1116
- if (pc.localDescription.type === "offer") {
1117
- return pc
1118
- .createOffer()
1119
- .then(offer => {
1120
- offer.sdp = replaceSSRCs(pc.localDescription.sdp, offer.sdp);
1121
- return pc.setLocalDescription(offer);
1122
- })
1123
- .then(() => {
1124
- return this._setRemoteDescription(pc.remoteDescription);
1125
- });
1126
- } else {
1127
- return this._setRemoteDescription(pc.remoteDescription)
1128
- .then(() => {
1129
- return pc.createAnswer();
1130
- })
1131
- .then(answer => {
1132
- answer.sdp = replaceSSRCs(pc.localDescription.sdp, answer.sdp);
1133
- return pc.setLocalDescription(answer);
1134
- });
1135
- }
1136
- }
1137
-
1138
- // Restricts the bandwidth based on whether we are using a relayed connection.
1139
- // No signaling is required, this is done independently by both sides.
1140
- // Only applies to unrestricted connections, not affecting the bandwidth tables
1141
- // that depend on the number of participants.
1142
- maybeRestrictRelayBandwidth() {
1143
- if (!this.pc.getStats) {
1144
- return;
1145
- }
1146
- isRelayed(this.pc).then(isRelayed => {
1147
- if (isRelayed && this.bandwidth === 0) {
1148
- this.changeBandwidth(this.maximumTurnBandwidth);
1149
- }
1150
- });
1151
- }
1152
-
1153
- // no-signaling negotiation of bandwidth. Peer is NOT informed.
1154
- // Prefers using RTCRtpSender.setParameters if possible.
1155
- changeBandwidth(bandwidth) {
1156
- // don't renegotiate if bandwidth is already set.
1157
- if (bandwidth === this.bandwidth) {
1158
- return;
1159
- }
1160
-
1161
- if (!this.canModifyPeerConnection()) {
1162
- this.pending.push(() => this.changeBandwidth(bandwidth));
1163
- return;
1164
- }
1165
-
1166
- this.bandwidth = bandwidth;
1167
- if (!this.pc.localDescription || this.pc.localDescription.type === "") {
1168
- return;
1169
- }
1170
-
1171
- setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
1172
- }
1173
- }
1174
-
1175
- function getDefaultExportFromCjs (x) {
1176
- return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
1177
- }
572
+ // Mark that a method should not be used.
573
+ // Returns a modified function which warns once by default.
574
+ // If --no-deprecation is set, then it is a no-op.
575
+ exports.deprecate = function(fn, msg) {
576
+ if (typeof process !== 'undefined' && process.noDeprecation === true) {
577
+ return fn;
578
+ }
1178
579
 
1179
- var assertExports$1 = {};
1180
- var assert$1 = {
1181
- get exports(){ return assertExports$1; },
1182
- set exports(v){ assertExports$1 = v; },
1183
- };
580
+ // Allow for deprecating things in the process of starting up.
581
+ if (typeof process === 'undefined') {
582
+ return function() {
583
+ return exports.deprecate(fn, msg).apply(this, arguments);
584
+ };
585
+ }
1184
586
 
1185
- var errors = {};
587
+ var warned = false;
588
+ function deprecated() {
589
+ if (!warned) {
590
+ if (process.throwDeprecation) {
591
+ throw new Error(msg);
592
+ } else if (process.traceDeprecation) {
593
+ console.trace(msg);
594
+ } else {
595
+ console.error(msg);
596
+ }
597
+ warned = true;
598
+ }
599
+ return fn.apply(this, arguments);
600
+ }
1186
601
 
1187
- var util = {};
602
+ return deprecated;
603
+ };
1188
604
 
1189
- var types = {};
1190
605
 
1191
- (function (exports) {
606
+ var debugs = {};
607
+ var debugEnvRegex = /^$/;
608
+ exports.debuglog = function(set) {
609
+ set = set.toUpperCase();
610
+ if (!debugs[set]) {
611
+ if (debugEnvRegex.test(set)) {
612
+ var pid = process.pid;
613
+ debugs[set] = function() {
614
+ var msg = exports.format.apply(exports, arguments);
615
+ console.error('%s %d: %s', set, pid, msg);
616
+ };
617
+ } else {
618
+ debugs[set] = function() {};
619
+ }
620
+ }
621
+ return debugs[set];
622
+ };
1192
623
 
1193
- var isArgumentsObject = require$$0;
1194
- var isGeneratorFunction = require$$1;
1195
- var whichTypedArray = require$$2;
1196
- var isTypedArray = require$$3;
1197
624
 
1198
- function uncurryThis(f) {
1199
- return f.call.bind(f);
625
+ /**
626
+ * Echos the value of a value. Trys to print the value out
627
+ * in the best way possible given the different types.
628
+ *
629
+ * @param {Object} obj The object to print out.
630
+ * @param {Object} opts Optional options object that alters the output.
631
+ */
632
+ /* legacy: obj, showHidden, depth, colors*/
633
+ function inspect(obj, opts) {
634
+ // default options
635
+ var ctx = {
636
+ seen: [],
637
+ stylize: stylizeNoColor
638
+ };
639
+ // legacy...
640
+ if (arguments.length >= 3) ctx.depth = arguments[2];
641
+ if (arguments.length >= 4) ctx.colors = arguments[3];
642
+ if (isBoolean(opts)) {
643
+ // legacy...
644
+ ctx.showHidden = opts;
645
+ } else if (opts) {
646
+ // got an "options" object
647
+ exports._extend(ctx, opts);
648
+ }
649
+ // set default options
650
+ if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
651
+ if (isUndefined(ctx.depth)) ctx.depth = 2;
652
+ if (isUndefined(ctx.colors)) ctx.colors = false;
653
+ if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
654
+ if (ctx.colors) ctx.stylize = stylizeWithColor;
655
+ return formatValue(ctx, obj, ctx.depth);
1200
656
  }
657
+ exports.inspect = inspect;
1201
658
 
1202
- var BigIntSupported = typeof BigInt !== 'undefined';
1203
- var SymbolSupported = typeof Symbol !== 'undefined';
1204
659
 
1205
- var ObjectToString = uncurryThis(Object.prototype.toString);
660
+ // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
661
+ inspect.colors = {
662
+ 'bold' : [1, 22],
663
+ 'italic' : [3, 23],
664
+ 'underline' : [4, 24],
665
+ 'inverse' : [7, 27],
666
+ 'white' : [37, 39],
667
+ 'grey' : [90, 39],
668
+ 'black' : [30, 39],
669
+ 'blue' : [34, 39],
670
+ 'cyan' : [36, 39],
671
+ 'green' : [32, 39],
672
+ 'magenta' : [35, 39],
673
+ 'red' : [31, 39],
674
+ 'yellow' : [33, 39]
675
+ };
1206
676
 
1207
- var numberValue = uncurryThis(Number.prototype.valueOf);
1208
- var stringValue = uncurryThis(String.prototype.valueOf);
1209
- var booleanValue = uncurryThis(Boolean.prototype.valueOf);
677
+ // Don't use 'blue' not visible on cmd.exe
678
+ inspect.styles = {
679
+ 'special': 'cyan',
680
+ 'number': 'yellow',
681
+ 'boolean': 'yellow',
682
+ 'undefined': 'grey',
683
+ 'null': 'bold',
684
+ 'string': 'green',
685
+ 'date': 'magenta',
686
+ // "name": intentionally not styling
687
+ 'regexp': 'red'
688
+ };
1210
689
 
1211
- if (BigIntSupported) {
1212
- var bigIntValue = uncurryThis(BigInt.prototype.valueOf);
1213
- }
1214
690
 
1215
- if (SymbolSupported) {
1216
- var symbolValue = uncurryThis(Symbol.prototype.valueOf);
1217
- }
691
+ function stylizeWithColor(str, styleType) {
692
+ var style = inspect.styles[styleType];
1218
693
 
1219
- function checkBoxedPrimitive(value, prototypeValueOf) {
1220
- if (typeof value !== 'object') {
1221
- return false;
1222
- }
1223
- try {
1224
- prototypeValueOf(value);
1225
- return true;
1226
- } catch(e) {
1227
- return false;
694
+ if (style) {
695
+ return '\u001b[' + inspect.colors[style][0] + 'm' + str +
696
+ '\u001b[' + inspect.colors[style][1] + 'm';
697
+ } else {
698
+ return str;
1228
699
  }
1229
700
  }
1230
701
 
1231
- exports.isArgumentsObject = isArgumentsObject;
1232
- exports.isGeneratorFunction = isGeneratorFunction;
1233
- exports.isTypedArray = isTypedArray;
1234
-
1235
- // Taken from here and modified for better browser support
1236
- // https://github.com/sindresorhus/p-is-promise/blob/cda35a513bda03f977ad5cde3a079d237e82d7ef/index.js
1237
- function isPromise(input) {
1238
- return (
1239
- (
1240
- typeof Promise !== 'undefined' &&
1241
- input instanceof Promise
1242
- ) ||
1243
- (
1244
- input !== null &&
1245
- typeof input === 'object' &&
1246
- typeof input.then === 'function' &&
1247
- typeof input.catch === 'function'
1248
- )
1249
- );
1250
- }
1251
- exports.isPromise = isPromise;
1252
-
1253
- function isArrayBufferView(value) {
1254
- if (typeof ArrayBuffer !== 'undefined' && ArrayBuffer.isView) {
1255
- return ArrayBuffer.isView(value);
1256
- }
1257
702
 
1258
- return (
1259
- isTypedArray(value) ||
1260
- isDataView(value)
1261
- );
703
+ function stylizeNoColor(str, styleType) {
704
+ return str;
1262
705
  }
1263
- exports.isArrayBufferView = isArrayBufferView;
1264
706
 
1265
707
 
1266
- function isUint8Array(value) {
1267
- return whichTypedArray(value) === 'Uint8Array';
1268
- }
1269
- exports.isUint8Array = isUint8Array;
708
+ function arrayToHash(array) {
709
+ var hash = {};
1270
710
 
1271
- function isUint8ClampedArray(value) {
1272
- return whichTypedArray(value) === 'Uint8ClampedArray';
1273
- }
1274
- exports.isUint8ClampedArray = isUint8ClampedArray;
711
+ array.forEach(function(val, idx) {
712
+ hash[val] = true;
713
+ });
1275
714
 
1276
- function isUint16Array(value) {
1277
- return whichTypedArray(value) === 'Uint16Array';
715
+ return hash;
1278
716
  }
1279
- exports.isUint16Array = isUint16Array;
1280
717
 
1281
- function isUint32Array(value) {
1282
- return whichTypedArray(value) === 'Uint32Array';
1283
- }
1284
- exports.isUint32Array = isUint32Array;
1285
718
 
1286
- function isInt8Array(value) {
1287
- return whichTypedArray(value) === 'Int8Array';
1288
- }
1289
- exports.isInt8Array = isInt8Array;
1290
-
1291
- function isInt16Array(value) {
1292
- return whichTypedArray(value) === 'Int16Array';
1293
- }
1294
- exports.isInt16Array = isInt16Array;
1295
-
1296
- function isInt32Array(value) {
1297
- return whichTypedArray(value) === 'Int32Array';
1298
- }
1299
- exports.isInt32Array = isInt32Array;
1300
-
1301
- function isFloat32Array(value) {
1302
- return whichTypedArray(value) === 'Float32Array';
1303
- }
1304
- exports.isFloat32Array = isFloat32Array;
719
+ function formatValue(ctx, value, recurseTimes) {
720
+ // Provide a hook for user-specified inspect functions.
721
+ // Check that value is an object with an inspect function on it
722
+ if (ctx.customInspect &&
723
+ value &&
724
+ isFunction(value.inspect) &&
725
+ // Filter out the util module, it's inspect function is special
726
+ value.inspect !== exports.inspect &&
727
+ // Also filter out any prototype objects using the circular check.
728
+ !(value.constructor && value.constructor.prototype === value)) {
729
+ var ret = value.inspect(recurseTimes, ctx);
730
+ if (!isString(ret)) {
731
+ ret = formatValue(ctx, ret, recurseTimes);
732
+ }
733
+ return ret;
734
+ }
1305
735
 
1306
- function isFloat64Array(value) {
1307
- return whichTypedArray(value) === 'Float64Array';
1308
- }
1309
- exports.isFloat64Array = isFloat64Array;
736
+ // Primitive types cannot have properties
737
+ var primitive = formatPrimitive(ctx, value);
738
+ if (primitive) {
739
+ return primitive;
740
+ }
1310
741
 
1311
- function isBigInt64Array(value) {
1312
- return whichTypedArray(value) === 'BigInt64Array';
1313
- }
1314
- exports.isBigInt64Array = isBigInt64Array;
742
+ // Look up the keys of the object.
743
+ var keys = Object.keys(value);
744
+ var visibleKeys = arrayToHash(keys);
1315
745
 
1316
- function isBigUint64Array(value) {
1317
- return whichTypedArray(value) === 'BigUint64Array';
1318
- }
1319
- exports.isBigUint64Array = isBigUint64Array;
746
+ if (ctx.showHidden) {
747
+ keys = Object.getOwnPropertyNames(value);
748
+ }
1320
749
 
1321
- function isMapToString(value) {
1322
- return ObjectToString(value) === '[object Map]';
1323
- }
1324
- isMapToString.working = (
1325
- typeof Map !== 'undefined' &&
1326
- isMapToString(new Map())
1327
- );
750
+ // IE doesn't make error fields non-enumerable
751
+ // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
752
+ if (isError(value)
753
+ && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
754
+ return formatError(value);
755
+ }
1328
756
 
1329
- function isMap(value) {
1330
- if (typeof Map === 'undefined') {
1331
- return false;
757
+ // Some type of object without properties can be shortcutted.
758
+ if (keys.length === 0) {
759
+ if (isFunction(value)) {
760
+ var name = value.name ? ': ' + value.name : '';
761
+ return ctx.stylize('[Function' + name + ']', 'special');
762
+ }
763
+ if (isRegExp(value)) {
764
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
765
+ }
766
+ if (isDate(value)) {
767
+ return ctx.stylize(Date.prototype.toString.call(value), 'date');
768
+ }
769
+ if (isError(value)) {
770
+ return formatError(value);
771
+ }
1332
772
  }
1333
773
 
1334
- return isMapToString.working
1335
- ? isMapToString(value)
1336
- : value instanceof Map;
1337
- }
1338
- exports.isMap = isMap;
774
+ var base = '', array = false, braces = ['{', '}'];
1339
775
 
1340
- function isSetToString(value) {
1341
- return ObjectToString(value) === '[object Set]';
1342
- }
1343
- isSetToString.working = (
1344
- typeof Set !== 'undefined' &&
1345
- isSetToString(new Set())
1346
- );
1347
- function isSet(value) {
1348
- if (typeof Set === 'undefined') {
1349
- return false;
776
+ // Make Array say that they are Array
777
+ if (isArray(value)) {
778
+ array = true;
779
+ braces = ['[', ']'];
1350
780
  }
1351
781
 
1352
- return isSetToString.working
1353
- ? isSetToString(value)
1354
- : value instanceof Set;
1355
- }
1356
- exports.isSet = isSet;
1357
-
1358
- function isWeakMapToString(value) {
1359
- return ObjectToString(value) === '[object WeakMap]';
1360
- }
1361
- isWeakMapToString.working = (
1362
- typeof WeakMap !== 'undefined' &&
1363
- isWeakMapToString(new WeakMap())
1364
- );
1365
- function isWeakMap(value) {
1366
- if (typeof WeakMap === 'undefined') {
1367
- return false;
782
+ // Make functions say that they are functions
783
+ if (isFunction(value)) {
784
+ var n = value.name ? ': ' + value.name : '';
785
+ base = ' [Function' + n + ']';
1368
786
  }
1369
787
 
1370
- return isWeakMapToString.working
1371
- ? isWeakMapToString(value)
1372
- : value instanceof WeakMap;
1373
- }
1374
- exports.isWeakMap = isWeakMap;
788
+ // Make RegExps say that they are RegExps
789
+ if (isRegExp(value)) {
790
+ base = ' ' + RegExp.prototype.toString.call(value);
791
+ }
1375
792
 
1376
- function isWeakSetToString(value) {
1377
- return ObjectToString(value) === '[object WeakSet]';
1378
- }
1379
- isWeakSetToString.working = (
1380
- typeof WeakSet !== 'undefined' &&
1381
- isWeakSetToString(new WeakSet())
1382
- );
1383
- function isWeakSet(value) {
1384
- return isWeakSetToString(value);
1385
- }
1386
- exports.isWeakSet = isWeakSet;
793
+ // Make dates with properties first say the date
794
+ if (isDate(value)) {
795
+ base = ' ' + Date.prototype.toUTCString.call(value);
796
+ }
1387
797
 
1388
- function isArrayBufferToString(value) {
1389
- return ObjectToString(value) === '[object ArrayBuffer]';
1390
- }
1391
- isArrayBufferToString.working = (
1392
- typeof ArrayBuffer !== 'undefined' &&
1393
- isArrayBufferToString(new ArrayBuffer())
1394
- );
1395
- function isArrayBuffer(value) {
1396
- if (typeof ArrayBuffer === 'undefined') {
1397
- return false;
798
+ // Make error with message first say the error
799
+ if (isError(value)) {
800
+ base = ' ' + formatError(value);
1398
801
  }
1399
802
 
1400
- return isArrayBufferToString.working
1401
- ? isArrayBufferToString(value)
1402
- : value instanceof ArrayBuffer;
1403
- }
1404
- exports.isArrayBuffer = isArrayBuffer;
803
+ if (keys.length === 0 && (!array || value.length == 0)) {
804
+ return braces[0] + base + braces[1];
805
+ }
1405
806
 
1406
- function isDataViewToString(value) {
1407
- return ObjectToString(value) === '[object DataView]';
1408
- }
1409
- isDataViewToString.working = (
1410
- typeof ArrayBuffer !== 'undefined' &&
1411
- typeof DataView !== 'undefined' &&
1412
- isDataViewToString(new DataView(new ArrayBuffer(1), 0, 1))
1413
- );
1414
- function isDataView(value) {
1415
- if (typeof DataView === 'undefined') {
1416
- return false;
807
+ if (recurseTimes < 0) {
808
+ if (isRegExp(value)) {
809
+ return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
810
+ } else {
811
+ return ctx.stylize('[Object]', 'special');
812
+ }
1417
813
  }
1418
814
 
1419
- return isDataViewToString.working
1420
- ? isDataViewToString(value)
1421
- : value instanceof DataView;
1422
- }
1423
- exports.isDataView = isDataView;
815
+ ctx.seen.push(value);
1424
816
 
1425
- // Store a copy of SharedArrayBuffer in case it's deleted elsewhere
1426
- var SharedArrayBufferCopy = typeof SharedArrayBuffer !== 'undefined' ? SharedArrayBuffer : undefined;
1427
- function isSharedArrayBufferToString(value) {
1428
- return ObjectToString(value) === '[object SharedArrayBuffer]';
1429
- }
1430
- function isSharedArrayBuffer(value) {
1431
- if (typeof SharedArrayBufferCopy === 'undefined') {
1432
- return false;
817
+ var output;
818
+ if (array) {
819
+ output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
820
+ } else {
821
+ output = keys.map(function(key) {
822
+ return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
823
+ });
1433
824
  }
1434
825
 
1435
- if (typeof isSharedArrayBufferToString.working === 'undefined') {
1436
- isSharedArrayBufferToString.working = isSharedArrayBufferToString(new SharedArrayBufferCopy());
1437
- }
826
+ ctx.seen.pop();
1438
827
 
1439
- return isSharedArrayBufferToString.working
1440
- ? isSharedArrayBufferToString(value)
1441
- : value instanceof SharedArrayBufferCopy;
828
+ return reduceToSingleString(output, base, braces);
1442
829
  }
1443
- exports.isSharedArrayBuffer = isSharedArrayBuffer;
1444
830
 
1445
- function isAsyncFunction(value) {
1446
- return ObjectToString(value) === '[object AsyncFunction]';
1447
- }
1448
- exports.isAsyncFunction = isAsyncFunction;
1449
831
 
1450
- function isMapIterator(value) {
1451
- return ObjectToString(value) === '[object Map Iterator]';
832
+ function formatPrimitive(ctx, value) {
833
+ if (isUndefined(value))
834
+ return ctx.stylize('undefined', 'undefined');
835
+ if (isString(value)) {
836
+ var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
837
+ .replace(/'/g, "\\'")
838
+ .replace(/\\"/g, '"') + '\'';
839
+ return ctx.stylize(simple, 'string');
840
+ }
841
+ if (isNumber(value))
842
+ return ctx.stylize('' + value, 'number');
843
+ if (isBoolean(value))
844
+ return ctx.stylize('' + value, 'boolean');
845
+ // For some reason typeof null is "object", so special case here.
846
+ if (isNull(value))
847
+ return ctx.stylize('null', 'null');
1452
848
  }
1453
- exports.isMapIterator = isMapIterator;
1454
849
 
1455
- function isSetIterator(value) {
1456
- return ObjectToString(value) === '[object Set Iterator]';
1457
- }
1458
- exports.isSetIterator = isSetIterator;
1459
850
 
1460
- function isGeneratorObject(value) {
1461
- return ObjectToString(value) === '[object Generator]';
851
+ function formatError(value) {
852
+ return '[' + Error.prototype.toString.call(value) + ']';
1462
853
  }
1463
- exports.isGeneratorObject = isGeneratorObject;
1464
854
 
1465
- function isWebAssemblyCompiledModule(value) {
1466
- return ObjectToString(value) === '[object WebAssembly.Module]';
1467
- }
1468
- exports.isWebAssemblyCompiledModule = isWebAssemblyCompiledModule;
1469
-
1470
- function isNumberObject(value) {
1471
- return checkBoxedPrimitive(value, numberValue);
1472
- }
1473
- exports.isNumberObject = isNumberObject;
1474
-
1475
- function isStringObject(value) {
1476
- return checkBoxedPrimitive(value, stringValue);
1477
- }
1478
- exports.isStringObject = isStringObject;
1479
-
1480
- function isBooleanObject(value) {
1481
- return checkBoxedPrimitive(value, booleanValue);
1482
- }
1483
- exports.isBooleanObject = isBooleanObject;
1484
-
1485
- function isBigIntObject(value) {
1486
- return BigIntSupported && checkBoxedPrimitive(value, bigIntValue);
1487
- }
1488
- exports.isBigIntObject = isBigIntObject;
1489
-
1490
- function isSymbolObject(value) {
1491
- return SymbolSupported && checkBoxedPrimitive(value, symbolValue);
1492
- }
1493
- exports.isSymbolObject = isSymbolObject;
1494
-
1495
- function isBoxedPrimitive(value) {
1496
- return (
1497
- isNumberObject(value) ||
1498
- isStringObject(value) ||
1499
- isBooleanObject(value) ||
1500
- isBigIntObject(value) ||
1501
- isSymbolObject(value)
1502
- );
1503
- }
1504
- exports.isBoxedPrimitive = isBoxedPrimitive;
1505
-
1506
- function isAnyArrayBuffer(value) {
1507
- return typeof Uint8Array !== 'undefined' && (
1508
- isArrayBuffer(value) ||
1509
- isSharedArrayBuffer(value)
1510
- );
1511
- }
1512
- exports.isAnyArrayBuffer = isAnyArrayBuffer;
1513
855
 
1514
- ['isProxy', 'isExternal', 'isModuleNamespaceObject'].forEach(function(method) {
1515
- Object.defineProperty(exports, method, {
1516
- enumerable: false,
1517
- value: function() {
1518
- throw new Error(method + ' is not supported in userland');
856
+ function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
857
+ var output = [];
858
+ for (var i = 0, l = value.length; i < l; ++i) {
859
+ if (hasOwnProperty(value, String(i))) {
860
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
861
+ String(i), true));
862
+ } else {
863
+ output.push('');
864
+ }
865
+ }
866
+ keys.forEach(function(key) {
867
+ if (!key.match(/^\d+$/)) {
868
+ output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
869
+ key, true));
1519
870
  }
1520
871
  });
1521
- });
1522
- } (types));
1523
-
1524
- var isBuffer = function isBuffer(arg) {
1525
- return arg instanceof Buffer;
1526
- };
872
+ return output;
873
+ }
1527
874
 
1528
- (function (exports) {
1529
- // Copyright Joyent, Inc. and other Node contributors.
1530
- //
1531
- // Permission is hereby granted, free of charge, to any person obtaining a
1532
- // copy of this software and associated documentation files (the
1533
- // "Software"), to deal in the Software without restriction, including
1534
- // without limitation the rights to use, copy, modify, merge, publish,
1535
- // distribute, sublicense, and/or sell copies of the Software, and to permit
1536
- // persons to whom the Software is furnished to do so, subject to the
1537
- // following conditions:
1538
- //
1539
- // The above copyright notice and this permission notice shall be included
1540
- // in all copies or substantial portions of the Software.
1541
- //
1542
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1543
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1544
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
1545
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
1546
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
1547
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
1548
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
1549
875
 
1550
- var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors ||
1551
- function getOwnPropertyDescriptors(obj) {
1552
- var keys = Object.keys(obj);
1553
- var descriptors = {};
1554
- for (var i = 0; i < keys.length; i++) {
1555
- descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]);
876
+ function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
877
+ var name, str, desc;
878
+ desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
879
+ if (desc.get) {
880
+ if (desc.set) {
881
+ str = ctx.stylize('[Getter/Setter]', 'special');
882
+ } else {
883
+ str = ctx.stylize('[Getter]', 'special');
1556
884
  }
1557
- return descriptors;
1558
- };
1559
-
1560
- var formatRegExp = /%[sdj%]/g;
1561
- exports.format = function(f) {
1562
- if (!isString(f)) {
1563
- var objects = [];
1564
- for (var i = 0; i < arguments.length; i++) {
1565
- objects.push(inspect(arguments[i]));
885
+ } else {
886
+ if (desc.set) {
887
+ str = ctx.stylize('[Setter]', 'special');
1566
888
  }
1567
- return objects.join(' ');
1568
889
  }
1569
-
1570
- var i = 1;
1571
- var args = arguments;
1572
- var len = args.length;
1573
- var str = String(f).replace(formatRegExp, function(x) {
1574
- if (x === '%%') return '%';
1575
- if (i >= len) return x;
1576
- switch (x) {
1577
- case '%s': return String(args[i++]);
1578
- case '%d': return Number(args[i++]);
1579
- case '%j':
1580
- try {
1581
- return JSON.stringify(args[i++]);
1582
- } catch (_) {
1583
- return '[Circular]';
890
+ if (!hasOwnProperty(visibleKeys, key)) {
891
+ name = '[' + key + ']';
892
+ }
893
+ if (!str) {
894
+ if (ctx.seen.indexOf(desc.value) < 0) {
895
+ if (isNull(recurseTimes)) {
896
+ str = formatValue(ctx, desc.value, null);
897
+ } else {
898
+ str = formatValue(ctx, desc.value, recurseTimes - 1);
899
+ }
900
+ if (str.indexOf('\n') > -1) {
901
+ if (array) {
902
+ str = str.split('\n').map(function(line) {
903
+ return ' ' + line;
904
+ }).join('\n').slice(2);
905
+ } else {
906
+ str = '\n' + str.split('\n').map(function(line) {
907
+ return ' ' + line;
908
+ }).join('\n');
1584
909
  }
1585
- default:
1586
- return x;
910
+ }
911
+ } else {
912
+ str = ctx.stylize('[Circular]', 'special');
1587
913
  }
1588
- });
1589
- for (var x = args[i]; i < len; x = args[++i]) {
1590
- if (isNull(x) || !isObject(x)) {
1591
- str += ' ' + x;
914
+ }
915
+ if (isUndefined(name)) {
916
+ if (array && key.match(/^\d+$/)) {
917
+ return str;
918
+ }
919
+ name = JSON.stringify('' + key);
920
+ if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
921
+ name = name.slice(1, -1);
922
+ name = ctx.stylize(name, 'name');
1592
923
  } else {
1593
- str += ' ' + inspect(x);
924
+ name = name.replace(/'/g, "\\'")
925
+ .replace(/\\"/g, '"')
926
+ .replace(/(^"|"$)/g, "'");
927
+ name = ctx.stylize(name, 'string');
1594
928
  }
1595
929
  }
1596
- return str;
1597
- };
1598
930
 
931
+ return name + ': ' + str;
932
+ }
1599
933
 
1600
- // Mark that a method should not be used.
1601
- // Returns a modified function which warns once by default.
1602
- // If --no-deprecation is set, then it is a no-op.
1603
- exports.deprecate = function(fn, msg) {
1604
- if (typeof process !== 'undefined' && process.noDeprecation === true) {
1605
- return fn;
1606
- }
1607
934
 
1608
- // Allow for deprecating things in the process of starting up.
1609
- if (typeof process === 'undefined') {
1610
- return function() {
1611
- return exports.deprecate(fn, msg).apply(this, arguments);
1612
- };
1613
- }
935
+ function reduceToSingleString(output, base, braces) {
936
+ var length = output.reduce(function(prev, cur) {
937
+ if (cur.indexOf('\n') >= 0) ;
938
+ return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
939
+ }, 0);
1614
940
 
1615
- var warned = false;
1616
- function deprecated() {
1617
- if (!warned) {
1618
- if (process.throwDeprecation) {
1619
- throw new Error(msg);
1620
- } else if (process.traceDeprecation) {
1621
- console.trace(msg);
1622
- } else {
1623
- console.error(msg);
1624
- }
1625
- warned = true;
1626
- }
1627
- return fn.apply(this, arguments);
941
+ if (length > 60) {
942
+ return braces[0] +
943
+ (base === '' ? '' : base + '\n ') +
944
+ ' ' +
945
+ output.join(',\n ') +
946
+ ' ' +
947
+ braces[1];
1628
948
  }
1629
949
 
1630
- return deprecated;
1631
- };
950
+ return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
951
+ }
1632
952
 
1633
953
 
1634
- var debugs = {};
1635
- var debugEnvRegex = /^$/;
1636
- exports.debuglog = function(set) {
1637
- set = set.toUpperCase();
1638
- if (!debugs[set]) {
1639
- if (debugEnvRegex.test(set)) {
1640
- var pid = process.pid;
1641
- debugs[set] = function() {
1642
- var msg = exports.format.apply(exports, arguments);
1643
- console.error('%s %d: %s', set, pid, msg);
1644
- };
1645
- } else {
1646
- debugs[set] = function() {};
1647
- }
1648
- }
1649
- return debugs[set];
1650
- };
954
+ // NOTE: These type checking functions intentionally don't use `instanceof`
955
+ // because it is fragile and can be easily faked with `Object.create()`.
956
+ exports.types = types;
1651
957
 
958
+ function isArray(ar) {
959
+ return Array.isArray(ar);
960
+ }
961
+ exports.isArray = isArray;
1652
962
 
1653
- /**
1654
- * Echos the value of a value. Trys to print the value out
1655
- * in the best way possible given the different types.
1656
- *
1657
- * @param {Object} obj The object to print out.
1658
- * @param {Object} opts Optional options object that alters the output.
1659
- */
1660
- /* legacy: obj, showHidden, depth, colors*/
1661
- function inspect(obj, opts) {
1662
- // default options
1663
- var ctx = {
1664
- seen: [],
1665
- stylize: stylizeNoColor
1666
- };
1667
- // legacy...
1668
- if (arguments.length >= 3) ctx.depth = arguments[2];
1669
- if (arguments.length >= 4) ctx.colors = arguments[3];
1670
- if (isBoolean(opts)) {
1671
- // legacy...
1672
- ctx.showHidden = opts;
1673
- } else if (opts) {
1674
- // got an "options" object
1675
- exports._extend(ctx, opts);
1676
- }
1677
- // set default options
1678
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
1679
- if (isUndefined(ctx.depth)) ctx.depth = 2;
1680
- if (isUndefined(ctx.colors)) ctx.colors = false;
1681
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
1682
- if (ctx.colors) ctx.stylize = stylizeWithColor;
1683
- return formatValue(ctx, obj, ctx.depth);
963
+ function isBoolean(arg) {
964
+ return typeof arg === 'boolean';
1684
965
  }
1685
- exports.inspect = inspect;
1686
-
966
+ exports.isBoolean = isBoolean;
1687
967
 
1688
- // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
1689
- inspect.colors = {
1690
- 'bold' : [1, 22],
1691
- 'italic' : [3, 23],
1692
- 'underline' : [4, 24],
1693
- 'inverse' : [7, 27],
1694
- 'white' : [37, 39],
1695
- 'grey' : [90, 39],
1696
- 'black' : [30, 39],
1697
- 'blue' : [34, 39],
1698
- 'cyan' : [36, 39],
1699
- 'green' : [32, 39],
1700
- 'magenta' : [35, 39],
1701
- 'red' : [31, 39],
1702
- 'yellow' : [33, 39]
1703
- };
968
+ function isNull(arg) {
969
+ return arg === null;
970
+ }
971
+ exports.isNull = isNull;
1704
972
 
1705
- // Don't use 'blue' not visible on cmd.exe
1706
- inspect.styles = {
1707
- 'special': 'cyan',
1708
- 'number': 'yellow',
1709
- 'boolean': 'yellow',
1710
- 'undefined': 'grey',
1711
- 'null': 'bold',
1712
- 'string': 'green',
1713
- 'date': 'magenta',
1714
- // "name": intentionally not styling
1715
- 'regexp': 'red'
1716
- };
973
+ function isNullOrUndefined(arg) {
974
+ return arg == null;
975
+ }
976
+ exports.isNullOrUndefined = isNullOrUndefined;
1717
977
 
978
+ function isNumber(arg) {
979
+ return typeof arg === 'number';
980
+ }
981
+ exports.isNumber = isNumber;
1718
982
 
1719
- function stylizeWithColor(str, styleType) {
1720
- var style = inspect.styles[styleType];
983
+ function isString(arg) {
984
+ return typeof arg === 'string';
985
+ }
986
+ exports.isString = isString;
1721
987
 
1722
- if (style) {
1723
- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
1724
- '\u001b[' + inspect.colors[style][1] + 'm';
1725
- } else {
1726
- return str;
1727
- }
988
+ function isSymbol(arg) {
989
+ return typeof arg === 'symbol';
1728
990
  }
991
+ exports.isSymbol = isSymbol;
1729
992
 
993
+ function isUndefined(arg) {
994
+ return arg === void 0;
995
+ }
996
+ exports.isUndefined = isUndefined;
1730
997
 
1731
- function stylizeNoColor(str, styleType) {
1732
- return str;
998
+ function isRegExp(re) {
999
+ return isObject(re) && objectToString(re) === '[object RegExp]';
1733
1000
  }
1001
+ exports.isRegExp = isRegExp;
1002
+ exports.types.isRegExp = isRegExp;
1734
1003
 
1004
+ function isObject(arg) {
1005
+ return typeof arg === 'object' && arg !== null;
1006
+ }
1007
+ exports.isObject = isObject;
1735
1008
 
1736
- function arrayToHash(array) {
1737
- var hash = {};
1009
+ function isDate(d) {
1010
+ return isObject(d) && objectToString(d) === '[object Date]';
1011
+ }
1012
+ exports.isDate = isDate;
1013
+ exports.types.isDate = isDate;
1738
1014
 
1739
- array.forEach(function(val, idx) {
1740
- hash[val] = true;
1741
- });
1015
+ function isError(e) {
1016
+ return isObject(e) &&
1017
+ (objectToString(e) === '[object Error]' || e instanceof Error);
1018
+ }
1019
+ exports.isError = isError;
1020
+ exports.types.isNativeError = isError;
1742
1021
 
1743
- return hash;
1022
+ function isFunction(arg) {
1023
+ return typeof arg === 'function';
1744
1024
  }
1025
+ exports.isFunction = isFunction;
1745
1026
 
1027
+ function isPrimitive(arg) {
1028
+ return arg === null ||
1029
+ typeof arg === 'boolean' ||
1030
+ typeof arg === 'number' ||
1031
+ typeof arg === 'string' ||
1032
+ typeof arg === 'symbol' || // ES6 symbol
1033
+ typeof arg === 'undefined';
1034
+ }
1035
+ exports.isPrimitive = isPrimitive;
1746
1036
 
1747
- function formatValue(ctx, value, recurseTimes) {
1748
- // Provide a hook for user-specified inspect functions.
1749
- // Check that value is an object with an inspect function on it
1750
- if (ctx.customInspect &&
1751
- value &&
1752
- isFunction(value.inspect) &&
1753
- // Filter out the util module, it's inspect function is special
1754
- value.inspect !== exports.inspect &&
1755
- // Also filter out any prototype objects using the circular check.
1756
- !(value.constructor && value.constructor.prototype === value)) {
1757
- var ret = value.inspect(recurseTimes, ctx);
1758
- if (!isString(ret)) {
1759
- ret = formatValue(ctx, ret, recurseTimes);
1760
- }
1761
- return ret;
1762
- }
1037
+ exports.isBuffer = isBuffer;
1763
1038
 
1764
- // Primitive types cannot have properties
1765
- var primitive = formatPrimitive(ctx, value);
1766
- if (primitive) {
1767
- return primitive;
1768
- }
1039
+ function objectToString(o) {
1040
+ return Object.prototype.toString.call(o);
1041
+ }
1769
1042
 
1770
- // Look up the keys of the object.
1771
- var keys = Object.keys(value);
1772
- var visibleKeys = arrayToHash(keys);
1773
1043
 
1774
- if (ctx.showHidden) {
1775
- keys = Object.getOwnPropertyNames(value);
1776
- }
1044
+ function pad(n) {
1045
+ return n < 10 ? '0' + n.toString(10) : n.toString(10);
1046
+ }
1777
1047
 
1778
- // IE doesn't make error fields non-enumerable
1779
- // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
1780
- if (isError(value)
1781
- && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
1782
- return formatError(value);
1783
- }
1784
1048
 
1785
- // Some type of object without properties can be shortcutted.
1786
- if (keys.length === 0) {
1787
- if (isFunction(value)) {
1788
- var name = value.name ? ': ' + value.name : '';
1789
- return ctx.stylize('[Function' + name + ']', 'special');
1790
- }
1791
- if (isRegExp(value)) {
1792
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1793
- }
1794
- if (isDate(value)) {
1795
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
1796
- }
1797
- if (isError(value)) {
1798
- return formatError(value);
1799
- }
1800
- }
1049
+ var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
1050
+ 'Oct', 'Nov', 'Dec'];
1801
1051
 
1802
- var base = '', array = false, braces = ['{', '}'];
1052
+ // 26 Feb 16:19:34
1053
+ function timestamp() {
1054
+ var d = new Date();
1055
+ var time = [pad(d.getHours()),
1056
+ pad(d.getMinutes()),
1057
+ pad(d.getSeconds())].join(':');
1058
+ return [d.getDate(), months[d.getMonth()], time].join(' ');
1059
+ }
1803
1060
 
1804
- // Make Array say that they are Array
1805
- if (isArray(value)) {
1806
- array = true;
1807
- braces = ['[', ']'];
1808
- }
1809
1061
 
1810
- // Make functions say that they are functions
1811
- if (isFunction(value)) {
1812
- var n = value.name ? ': ' + value.name : '';
1813
- base = ' [Function' + n + ']';
1814
- }
1062
+ // log is just a thin wrapper to console.log that prepends a timestamp
1063
+ exports.log = function() {
1064
+ console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
1065
+ };
1815
1066
 
1816
- // Make RegExps say that they are RegExps
1817
- if (isRegExp(value)) {
1818
- base = ' ' + RegExp.prototype.toString.call(value);
1819
- }
1820
1067
 
1821
- // Make dates with properties first say the date
1822
- if (isDate(value)) {
1823
- base = ' ' + Date.prototype.toUTCString.call(value);
1824
- }
1068
+ /**
1069
+ * Inherit the prototype methods from one constructor into another.
1070
+ *
1071
+ * The Function.prototype.inherits from lang.js rewritten as a standalone
1072
+ * function (not on Function.prototype). NOTE: If this file is to be loaded
1073
+ * during bootstrapping this function needs to be rewritten using some native
1074
+ * functions as prototype setup using normal JavaScript does not work as
1075
+ * expected during bootstrapping (see mirror.js in r114903).
1076
+ *
1077
+ * @param {function} ctor Constructor function which needs to inherit the
1078
+ * prototype.
1079
+ * @param {function} superCtor Constructor function to inherit prototype from.
1080
+ */
1081
+ exports.inherits = require$$2$1;
1825
1082
 
1826
- // Make error with message first say the error
1827
- if (isError(value)) {
1828
- base = ' ' + formatError(value);
1829
- }
1083
+ exports._extend = function(origin, add) {
1084
+ // Don't do anything if add isn't an object
1085
+ if (!add || !isObject(add)) return origin;
1830
1086
 
1831
- if (keys.length === 0 && (!array || value.length == 0)) {
1832
- return braces[0] + base + braces[1];
1087
+ var keys = Object.keys(add);
1088
+ var i = keys.length;
1089
+ while (i--) {
1090
+ origin[keys[i]] = add[keys[i]];
1833
1091
  }
1092
+ return origin;
1093
+ };
1834
1094
 
1835
- if (recurseTimes < 0) {
1836
- if (isRegExp(value)) {
1837
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
1838
- } else {
1839
- return ctx.stylize('[Object]', 'special');
1840
- }
1841
- }
1095
+ function hasOwnProperty(obj, prop) {
1096
+ return Object.prototype.hasOwnProperty.call(obj, prop);
1097
+ }
1842
1098
 
1843
- ctx.seen.push(value);
1099
+ var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
1844
1100
 
1845
- var output;
1846
- if (array) {
1847
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
1848
- } else {
1849
- output = keys.map(function(key) {
1850
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
1101
+ exports.promisify = function promisify(original) {
1102
+ if (typeof original !== 'function')
1103
+ throw new TypeError('The "original" argument must be of type Function');
1104
+
1105
+ if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
1106
+ var fn = original[kCustomPromisifiedSymbol];
1107
+ if (typeof fn !== 'function') {
1108
+ throw new TypeError('The "util.promisify.custom" argument must be of type Function');
1109
+ }
1110
+ Object.defineProperty(fn, kCustomPromisifiedSymbol, {
1111
+ value: fn, enumerable: false, writable: false, configurable: true
1851
1112
  });
1113
+ return fn;
1852
1114
  }
1853
1115
 
1854
- ctx.seen.pop();
1116
+ function fn() {
1117
+ var promiseResolve, promiseReject;
1118
+ var promise = new Promise(function (resolve, reject) {
1119
+ promiseResolve = resolve;
1120
+ promiseReject = reject;
1121
+ });
1855
1122
 
1856
- return reduceToSingleString(output, base, braces);
1857
- }
1123
+ var args = [];
1124
+ for (var i = 0; i < arguments.length; i++) {
1125
+ args.push(arguments[i]);
1126
+ }
1127
+ args.push(function (err, value) {
1128
+ if (err) {
1129
+ promiseReject(err);
1130
+ } else {
1131
+ promiseResolve(value);
1132
+ }
1133
+ });
1858
1134
 
1135
+ try {
1136
+ original.apply(this, args);
1137
+ } catch (err) {
1138
+ promiseReject(err);
1139
+ }
1859
1140
 
1860
- function formatPrimitive(ctx, value) {
1861
- if (isUndefined(value))
1862
- return ctx.stylize('undefined', 'undefined');
1863
- if (isString(value)) {
1864
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
1865
- .replace(/'/g, "\\'")
1866
- .replace(/\\"/g, '"') + '\'';
1867
- return ctx.stylize(simple, 'string');
1141
+ return promise;
1868
1142
  }
1869
- if (isNumber(value))
1870
- return ctx.stylize('' + value, 'number');
1871
- if (isBoolean(value))
1872
- return ctx.stylize('' + value, 'boolean');
1873
- // For some reason typeof null is "object", so special case here.
1874
- if (isNull(value))
1875
- return ctx.stylize('null', 'null');
1876
- }
1877
1143
 
1144
+ Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
1878
1145
 
1879
- function formatError(value) {
1880
- return '[' + Error.prototype.toString.call(value) + ']';
1881
- }
1146
+ if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, {
1147
+ value: fn, enumerable: false, writable: false, configurable: true
1148
+ });
1149
+ return Object.defineProperties(
1150
+ fn,
1151
+ getOwnPropertyDescriptors(original)
1152
+ );
1153
+ };
1882
1154
 
1155
+ exports.promisify.custom = kCustomPromisifiedSymbol;
1883
1156
 
1884
- function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
1885
- var output = [];
1886
- for (var i = 0, l = value.length; i < l; ++i) {
1887
- if (hasOwnProperty(value, String(i))) {
1888
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1889
- String(i), true));
1890
- } else {
1891
- output.push('');
1892
- }
1157
+ function callbackifyOnRejected(reason, cb) {
1158
+ // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
1159
+ // Because `null` is a special error value in callbacks which means "no error
1160
+ // occurred", we error-wrap so the callback consumer can distinguish between
1161
+ // "the promise rejected with null" or "the promise fulfilled with undefined".
1162
+ if (!reason) {
1163
+ var newReason = new Error('Promise was rejected with a falsy value');
1164
+ newReason.reason = reason;
1165
+ reason = newReason;
1893
1166
  }
1894
- keys.forEach(function(key) {
1895
- if (!key.match(/^\d+$/)) {
1896
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
1897
- key, true));
1898
- }
1899
- });
1900
- return output;
1167
+ return cb(reason);
1901
1168
  }
1902
1169
 
1903
-
1904
- function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
1905
- var name, str, desc;
1906
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
1907
- if (desc.get) {
1908
- if (desc.set) {
1909
- str = ctx.stylize('[Getter/Setter]', 'special');
1910
- } else {
1911
- str = ctx.stylize('[Getter]', 'special');
1912
- }
1913
- } else {
1914
- if (desc.set) {
1915
- str = ctx.stylize('[Setter]', 'special');
1916
- }
1917
- }
1918
- if (!hasOwnProperty(visibleKeys, key)) {
1919
- name = '[' + key + ']';
1920
- }
1921
- if (!str) {
1922
- if (ctx.seen.indexOf(desc.value) < 0) {
1923
- if (isNull(recurseTimes)) {
1924
- str = formatValue(ctx, desc.value, null);
1925
- } else {
1926
- str = formatValue(ctx, desc.value, recurseTimes - 1);
1927
- }
1928
- if (str.indexOf('\n') > -1) {
1929
- if (array) {
1930
- str = str.split('\n').map(function(line) {
1931
- return ' ' + line;
1932
- }).join('\n').slice(2);
1933
- } else {
1934
- str = '\n' + str.split('\n').map(function(line) {
1935
- return ' ' + line;
1936
- }).join('\n');
1937
- }
1938
- }
1939
- } else {
1940
- str = ctx.stylize('[Circular]', 'special');
1941
- }
1170
+ function callbackify(original) {
1171
+ if (typeof original !== 'function') {
1172
+ throw new TypeError('The "original" argument must be of type Function');
1942
1173
  }
1943
- if (isUndefined(name)) {
1944
- if (array && key.match(/^\d+$/)) {
1945
- return str;
1174
+
1175
+ // We DO NOT return the promise as it gives the user a false sense that
1176
+ // the promise is actually somehow related to the callback's execution
1177
+ // and that the callback throwing will reject the promise.
1178
+ function callbackified() {
1179
+ var args = [];
1180
+ for (var i = 0; i < arguments.length; i++) {
1181
+ args.push(arguments[i]);
1946
1182
  }
1947
- name = JSON.stringify('' + key);
1948
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
1949
- name = name.slice(1, -1);
1950
- name = ctx.stylize(name, 'name');
1951
- } else {
1952
- name = name.replace(/'/g, "\\'")
1953
- .replace(/\\"/g, '"')
1954
- .replace(/(^"|"$)/g, "'");
1955
- name = ctx.stylize(name, 'string');
1183
+
1184
+ var maybeCb = args.pop();
1185
+ if (typeof maybeCb !== 'function') {
1186
+ throw new TypeError('The last argument must be of type Function');
1956
1187
  }
1188
+ var self = this;
1189
+ var cb = function() {
1190
+ return maybeCb.apply(self, arguments);
1191
+ };
1192
+ // In true node style we process the callback on `nextTick` with all the
1193
+ // implications (stack, `uncaughtException`, `async_hooks`)
1194
+ original.apply(this, args)
1195
+ .then(function(ret) { process.nextTick(cb.bind(null, null, ret)); },
1196
+ function(rej) { process.nextTick(callbackifyOnRejected.bind(null, rej, cb)); });
1957
1197
  }
1958
1198
 
1959
- return name + ': ' + str;
1199
+ Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));
1200
+ Object.defineProperties(callbackified,
1201
+ getOwnPropertyDescriptors(original));
1202
+ return callbackified;
1960
1203
  }
1204
+ exports.callbackify = callbackify;
1205
+ } (util));
1961
1206
 
1207
+ var hasRequiredErrors;
1962
1208
 
1963
- function reduceToSingleString(output, base, braces) {
1964
- var length = output.reduce(function(prev, cur) {
1965
- if (cur.indexOf('\n') >= 0) ;
1966
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
1967
- }, 0);
1209
+ function requireErrors () {
1210
+ if (hasRequiredErrors) return errors;
1211
+ hasRequiredErrors = 1;
1212
+ // longer be forced to treat every error message change as a semver-major
1213
+ // change. The NodeError classes here all expose a `code` property whose
1214
+ // value statically and permanently identifies the error. While the error
1215
+ // message may change, the code should not.
1968
1216
 
1969
- if (length > 60) {
1970
- return braces[0] +
1971
- (base === '' ? '' : base + '\n ') +
1972
- ' ' +
1973
- output.join(',\n ') +
1974
- ' ' +
1975
- braces[1];
1976
- }
1217
+ function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
1977
1218
 
1978
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
1979
- }
1219
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
1980
1220
 
1221
+ function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
1981
1222
 
1982
- // NOTE: These type checking functions intentionally don't use `instanceof`
1983
- // because it is fragile and can be easily faked with `Object.create()`.
1984
- exports.types = types;
1223
+ function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
1985
1224
 
1986
- function isArray(ar) {
1987
- return Array.isArray(ar);
1988
- }
1989
- exports.isArray = isArray;
1225
+ function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
1990
1226
 
1991
- function isBoolean(arg) {
1992
- return typeof arg === 'boolean';
1993
- }
1994
- exports.isBoolean = isBoolean;
1227
+ function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
1995
1228
 
1996
- function isNull(arg) {
1997
- return arg === null;
1998
- }
1999
- exports.isNull = isNull;
1229
+ function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
2000
1230
 
2001
- function isNullOrUndefined(arg) {
2002
- return arg == null;
2003
- }
2004
- exports.isNullOrUndefined = isNullOrUndefined;
1231
+ var codes = {}; // Lazy loaded
2005
1232
 
2006
- function isNumber(arg) {
2007
- return typeof arg === 'number';
2008
- }
2009
- exports.isNumber = isNumber;
1233
+ var assert;
1234
+ var util$1;
2010
1235
 
2011
- function isString(arg) {
2012
- return typeof arg === 'string';
2013
- }
2014
- exports.isString = isString;
1236
+ function createErrorType(code, message, Base) {
1237
+ if (!Base) {
1238
+ Base = Error;
1239
+ }
2015
1240
 
2016
- function isSymbol(arg) {
2017
- return typeof arg === 'symbol';
2018
- }
2019
- exports.isSymbol = isSymbol;
2020
-
2021
- function isUndefined(arg) {
2022
- return arg === void 0;
2023
- }
2024
- exports.isUndefined = isUndefined;
2025
-
2026
- function isRegExp(re) {
2027
- return isObject(re) && objectToString(re) === '[object RegExp]';
2028
- }
2029
- exports.isRegExp = isRegExp;
2030
- exports.types.isRegExp = isRegExp;
2031
-
2032
- function isObject(arg) {
2033
- return typeof arg === 'object' && arg !== null;
2034
- }
2035
- exports.isObject = isObject;
2036
-
2037
- function isDate(d) {
2038
- return isObject(d) && objectToString(d) === '[object Date]';
2039
- }
2040
- exports.isDate = isDate;
2041
- exports.types.isDate = isDate;
2042
-
2043
- function isError(e) {
2044
- return isObject(e) &&
2045
- (objectToString(e) === '[object Error]' || e instanceof Error);
2046
- }
2047
- exports.isError = isError;
2048
- exports.types.isNativeError = isError;
2049
-
2050
- function isFunction(arg) {
2051
- return typeof arg === 'function';
2052
- }
2053
- exports.isFunction = isFunction;
2054
-
2055
- function isPrimitive(arg) {
2056
- return arg === null ||
2057
- typeof arg === 'boolean' ||
2058
- typeof arg === 'number' ||
2059
- typeof arg === 'string' ||
2060
- typeof arg === 'symbol' || // ES6 symbol
2061
- typeof arg === 'undefined';
2062
- }
2063
- exports.isPrimitive = isPrimitive;
2064
-
2065
- exports.isBuffer = isBuffer;
2066
-
2067
- function objectToString(o) {
2068
- return Object.prototype.toString.call(o);
2069
- }
2070
-
2071
-
2072
- function pad(n) {
2073
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
2074
- }
2075
-
2076
-
2077
- var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
2078
- 'Oct', 'Nov', 'Dec'];
2079
-
2080
- // 26 Feb 16:19:34
2081
- function timestamp() {
2082
- var d = new Date();
2083
- var time = [pad(d.getHours()),
2084
- pad(d.getMinutes()),
2085
- pad(d.getSeconds())].join(':');
2086
- return [d.getDate(), months[d.getMonth()], time].join(' ');
2087
- }
2088
-
2089
-
2090
- // log is just a thin wrapper to console.log that prepends a timestamp
2091
- exports.log = function() {
2092
- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
2093
- };
2094
-
2095
-
2096
- /**
2097
- * Inherit the prototype methods from one constructor into another.
2098
- *
2099
- * The Function.prototype.inherits from lang.js rewritten as a standalone
2100
- * function (not on Function.prototype). NOTE: If this file is to be loaded
2101
- * during bootstrapping this function needs to be rewritten using some native
2102
- * functions as prototype setup using normal JavaScript does not work as
2103
- * expected during bootstrapping (see mirror.js in r114903).
2104
- *
2105
- * @param {function} ctor Constructor function which needs to inherit the
2106
- * prototype.
2107
- * @param {function} superCtor Constructor function to inherit prototype from.
2108
- */
2109
- exports.inherits = require$$2$1;
2110
-
2111
- exports._extend = function(origin, add) {
2112
- // Don't do anything if add isn't an object
2113
- if (!add || !isObject(add)) return origin;
2114
-
2115
- var keys = Object.keys(add);
2116
- var i = keys.length;
2117
- while (i--) {
2118
- origin[keys[i]] = add[keys[i]];
2119
- }
2120
- return origin;
2121
- };
2122
-
2123
- function hasOwnProperty(obj, prop) {
2124
- return Object.prototype.hasOwnProperty.call(obj, prop);
2125
- }
2126
-
2127
- var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined;
2128
-
2129
- exports.promisify = function promisify(original) {
2130
- if (typeof original !== 'function')
2131
- throw new TypeError('The "original" argument must be of type Function');
2132
-
2133
- if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) {
2134
- var fn = original[kCustomPromisifiedSymbol];
2135
- if (typeof fn !== 'function') {
2136
- throw new TypeError('The "util.promisify.custom" argument must be of type Function');
2137
- }
2138
- Object.defineProperty(fn, kCustomPromisifiedSymbol, {
2139
- value: fn, enumerable: false, writable: false, configurable: true
2140
- });
2141
- return fn;
2142
- }
2143
-
2144
- function fn() {
2145
- var promiseResolve, promiseReject;
2146
- var promise = new Promise(function (resolve, reject) {
2147
- promiseResolve = resolve;
2148
- promiseReject = reject;
2149
- });
2150
-
2151
- var args = [];
2152
- for (var i = 0; i < arguments.length; i++) {
2153
- args.push(arguments[i]);
2154
- }
2155
- args.push(function (err, value) {
2156
- if (err) {
2157
- promiseReject(err);
2158
- } else {
2159
- promiseResolve(value);
2160
- }
2161
- });
2162
-
2163
- try {
2164
- original.apply(this, args);
2165
- } catch (err) {
2166
- promiseReject(err);
2167
- }
2168
-
2169
- return promise;
2170
- }
2171
-
2172
- Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
2173
-
2174
- if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, {
2175
- value: fn, enumerable: false, writable: false, configurable: true
2176
- });
2177
- return Object.defineProperties(
2178
- fn,
2179
- getOwnPropertyDescriptors(original)
2180
- );
2181
- };
2182
-
2183
- exports.promisify.custom = kCustomPromisifiedSymbol;
2184
-
2185
- function callbackifyOnRejected(reason, cb) {
2186
- // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
2187
- // Because `null` is a special error value in callbacks which means "no error
2188
- // occurred", we error-wrap so the callback consumer can distinguish between
2189
- // "the promise rejected with null" or "the promise fulfilled with undefined".
2190
- if (!reason) {
2191
- var newReason = new Error('Promise was rejected with a falsy value');
2192
- newReason.reason = reason;
2193
- reason = newReason;
2194
- }
2195
- return cb(reason);
2196
- }
2197
-
2198
- function callbackify(original) {
2199
- if (typeof original !== 'function') {
2200
- throw new TypeError('The "original" argument must be of type Function');
2201
- }
2202
-
2203
- // We DO NOT return the promise as it gives the user a false sense that
2204
- // the promise is actually somehow related to the callback's execution
2205
- // and that the callback throwing will reject the promise.
2206
- function callbackified() {
2207
- var args = [];
2208
- for (var i = 0; i < arguments.length; i++) {
2209
- args.push(arguments[i]);
2210
- }
2211
-
2212
- var maybeCb = args.pop();
2213
- if (typeof maybeCb !== 'function') {
2214
- throw new TypeError('The last argument must be of type Function');
2215
- }
2216
- var self = this;
2217
- var cb = function() {
2218
- return maybeCb.apply(self, arguments);
2219
- };
2220
- // In true node style we process the callback on `nextTick` with all the
2221
- // implications (stack, `uncaughtException`, `async_hooks`)
2222
- original.apply(this, args)
2223
- .then(function(ret) { process.nextTick(cb.bind(null, null, ret)); },
2224
- function(rej) { process.nextTick(callbackifyOnRejected.bind(null, rej, cb)); });
2225
- }
2226
-
2227
- Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original));
2228
- Object.defineProperties(callbackified,
2229
- getOwnPropertyDescriptors(original));
2230
- return callbackified;
2231
- }
2232
- exports.callbackify = callbackify;
2233
- } (util));
2234
-
2235
- var hasRequiredErrors;
2236
-
2237
- function requireErrors () {
2238
- if (hasRequiredErrors) return errors;
2239
- hasRequiredErrors = 1;
2240
- // longer be forced to treat every error message change as a semver-major
2241
- // change. The NodeError classes here all expose a `code` property whose
2242
- // value statically and permanently identifies the error. While the error
2243
- // message may change, the code should not.
2244
-
2245
- function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
2246
-
2247
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
2248
-
2249
- function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
2250
-
2251
- function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
2252
-
2253
- function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
2254
-
2255
- function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
2256
-
2257
- function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
2258
-
2259
- var codes = {}; // Lazy loaded
2260
-
2261
- var assert;
2262
- var util$1;
2263
-
2264
- function createErrorType(code, message, Base) {
2265
- if (!Base) {
2266
- Base = Error;
2267
- }
2268
-
2269
- function getMessage(arg1, arg2, arg3) {
2270
- if (typeof message === 'string') {
2271
- return message;
2272
- } else {
2273
- return message(arg1, arg2, arg3);
2274
- }
2275
- }
1241
+ function getMessage(arg1, arg2, arg3) {
1242
+ if (typeof message === 'string') {
1243
+ return message;
1244
+ } else {
1245
+ return message(arg1, arg2, arg3);
1246
+ }
1247
+ }
2276
1248
 
2277
1249
  var NodeError =
2278
1250
  /*#__PURE__*/
@@ -3856,380 +2828,1456 @@ function requireAssert () {
3856
2828
  }
3857
2829
  };
3858
2830
 
3859
- assert.notDeepStrictEqual = notDeepStrictEqual;
2831
+ assert.notDeepStrictEqual = notDeepStrictEqual;
2832
+
2833
+ function notDeepStrictEqual(actual, expected, message) {
2834
+ if (arguments.length < 2) {
2835
+ throw new ERR_MISSING_ARGS('actual', 'expected');
2836
+ }
2837
+
2838
+ if (isDeepEqual === undefined) lazyLoadComparison();
2839
+
2840
+ if (isDeepStrictEqual(actual, expected)) {
2841
+ innerFail({
2842
+ actual: actual,
2843
+ expected: expected,
2844
+ message: message,
2845
+ operator: 'notDeepStrictEqual',
2846
+ stackStartFn: notDeepStrictEqual
2847
+ });
2848
+ }
2849
+ }
2850
+
2851
+ assert.strictEqual = function strictEqual(actual, expected, message) {
2852
+ if (arguments.length < 2) {
2853
+ throw new ERR_MISSING_ARGS('actual', 'expected');
2854
+ }
2855
+
2856
+ if (!objectIs(actual, expected)) {
2857
+ innerFail({
2858
+ actual: actual,
2859
+ expected: expected,
2860
+ message: message,
2861
+ operator: 'strictEqual',
2862
+ stackStartFn: strictEqual
2863
+ });
2864
+ }
2865
+ };
2866
+
2867
+ assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
2868
+ if (arguments.length < 2) {
2869
+ throw new ERR_MISSING_ARGS('actual', 'expected');
2870
+ }
2871
+
2872
+ if (objectIs(actual, expected)) {
2873
+ innerFail({
2874
+ actual: actual,
2875
+ expected: expected,
2876
+ message: message,
2877
+ operator: 'notStrictEqual',
2878
+ stackStartFn: notStrictEqual
2879
+ });
2880
+ }
2881
+ };
2882
+
2883
+ var Comparison = function Comparison(obj, keys, actual) {
2884
+ var _this = this;
2885
+
2886
+ _classCallCheck(this, Comparison);
2887
+
2888
+ keys.forEach(function (key) {
2889
+ if (key in obj) {
2890
+ if (actual !== undefined && typeof actual[key] === 'string' && isRegExp(obj[key]) && obj[key].test(actual[key])) {
2891
+ _this[key] = actual[key];
2892
+ } else {
2893
+ _this[key] = obj[key];
2894
+ }
2895
+ }
2896
+ });
2897
+ };
2898
+
2899
+ function compareExceptionKey(actual, expected, key, message, keys, fn) {
2900
+ if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) {
2901
+ if (!message) {
2902
+ // Create placeholder objects to create a nice output.
2903
+ var a = new Comparison(actual, keys);
2904
+ var b = new Comparison(expected, keys, actual);
2905
+ var err = new AssertionError({
2906
+ actual: a,
2907
+ expected: b,
2908
+ operator: 'deepStrictEqual',
2909
+ stackStartFn: fn
2910
+ });
2911
+ err.actual = actual;
2912
+ err.expected = expected;
2913
+ err.operator = fn.name;
2914
+ throw err;
2915
+ }
2916
+
2917
+ innerFail({
2918
+ actual: actual,
2919
+ expected: expected,
2920
+ message: message,
2921
+ operator: fn.name,
2922
+ stackStartFn: fn
2923
+ });
2924
+ }
2925
+ }
2926
+
2927
+ function expectedException(actual, expected, msg, fn) {
2928
+ if (typeof expected !== 'function') {
2929
+ if (isRegExp(expected)) return expected.test(actual); // assert.doesNotThrow does not accept objects.
2930
+
2931
+ if (arguments.length === 2) {
2932
+ throw new ERR_INVALID_ARG_TYPE('expected', ['Function', 'RegExp'], expected);
2933
+ } // Handle primitives properly.
2934
+
2935
+
2936
+ if (_typeof(actual) !== 'object' || actual === null) {
2937
+ var err = new AssertionError({
2938
+ actual: actual,
2939
+ expected: expected,
2940
+ message: msg,
2941
+ operator: 'deepStrictEqual',
2942
+ stackStartFn: fn
2943
+ });
2944
+ err.operator = fn.name;
2945
+ throw err;
2946
+ }
2947
+
2948
+ var keys = Object.keys(expected); // Special handle errors to make sure the name and the message are compared
2949
+ // as well.
2950
+
2951
+ if (expected instanceof Error) {
2952
+ keys.push('name', 'message');
2953
+ } else if (keys.length === 0) {
2954
+ throw new ERR_INVALID_ARG_VALUE('error', expected, 'may not be an empty object');
2955
+ }
2956
+
2957
+ if (isDeepEqual === undefined) lazyLoadComparison();
2958
+ keys.forEach(function (key) {
2959
+ if (typeof actual[key] === 'string' && isRegExp(expected[key]) && expected[key].test(actual[key])) {
2960
+ return;
2961
+ }
2962
+
2963
+ compareExceptionKey(actual, expected, key, msg, keys, fn);
2964
+ });
2965
+ return true;
2966
+ } // Guard instanceof against arrow functions as they don't have a prototype.
2967
+
2968
+
2969
+ if (expected.prototype !== undefined && actual instanceof expected) {
2970
+ return true;
2971
+ }
2972
+
2973
+ if (Error.isPrototypeOf(expected)) {
2974
+ return false;
2975
+ }
2976
+
2977
+ return expected.call({}, actual) === true;
2978
+ }
2979
+
2980
+ function getActual(fn) {
2981
+ if (typeof fn !== 'function') {
2982
+ throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
2983
+ }
2984
+
2985
+ try {
2986
+ fn();
2987
+ } catch (e) {
2988
+ return e;
2989
+ }
2990
+
2991
+ return NO_EXCEPTION_SENTINEL;
2992
+ }
2993
+
2994
+ function checkIsPromise(obj) {
2995
+ // Accept native ES6 promises and promises that are implemented in a similar
2996
+ // way. Do not accept thenables that use a function as `obj` and that have no
2997
+ // `catch` handler.
2998
+ // TODO: thenables are checked up until they have the correct methods,
2999
+ // but according to documentation, the `then` method should receive
3000
+ // the `fulfill` and `reject` arguments as well or it may be never resolved.
3001
+ return isPromise(obj) || obj !== null && _typeof(obj) === 'object' && typeof obj.then === 'function' && typeof obj.catch === 'function';
3002
+ }
3003
+
3004
+ function waitForActual(promiseFn) {
3005
+ return Promise.resolve().then(function () {
3006
+ var resultPromise;
3007
+
3008
+ if (typeof promiseFn === 'function') {
3009
+ // Return a rejected promise if `promiseFn` throws synchronously.
3010
+ resultPromise = promiseFn(); // Fail in case no promise is returned.
3011
+
3012
+ if (!checkIsPromise(resultPromise)) {
3013
+ throw new ERR_INVALID_RETURN_VALUE('instance of Promise', 'promiseFn', resultPromise);
3014
+ }
3015
+ } else if (checkIsPromise(promiseFn)) {
3016
+ resultPromise = promiseFn;
3017
+ } else {
3018
+ throw new ERR_INVALID_ARG_TYPE('promiseFn', ['Function', 'Promise'], promiseFn);
3019
+ }
3020
+
3021
+ return Promise.resolve().then(function () {
3022
+ return resultPromise;
3023
+ }).then(function () {
3024
+ return NO_EXCEPTION_SENTINEL;
3025
+ }).catch(function (e) {
3026
+ return e;
3027
+ });
3028
+ });
3029
+ }
3030
+
3031
+ function expectsError(stackStartFn, actual, error, message) {
3032
+ if (typeof error === 'string') {
3033
+ if (arguments.length === 4) {
3034
+ throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
3035
+ }
3036
+
3037
+ if (_typeof(actual) === 'object' && actual !== null) {
3038
+ if (actual.message === error) {
3039
+ throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error message \"".concat(actual.message, "\" is identical to the message."));
3040
+ }
3041
+ } else if (actual === error) {
3042
+ throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error \"".concat(actual, "\" is identical to the message."));
3043
+ }
3044
+
3045
+ message = error;
3046
+ error = undefined;
3047
+ } else if (error != null && _typeof(error) !== 'object' && typeof error !== 'function') {
3048
+ throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
3049
+ }
3050
+
3051
+ if (actual === NO_EXCEPTION_SENTINEL) {
3052
+ var details = '';
3053
+
3054
+ if (error && error.name) {
3055
+ details += " (".concat(error.name, ")");
3056
+ }
3057
+
3058
+ details += message ? ": ".concat(message) : '.';
3059
+ var fnType = stackStartFn.name === 'rejects' ? 'rejection' : 'exception';
3060
+ innerFail({
3061
+ actual: undefined,
3062
+ expected: error,
3063
+ operator: stackStartFn.name,
3064
+ message: "Missing expected ".concat(fnType).concat(details),
3065
+ stackStartFn: stackStartFn
3066
+ });
3067
+ }
3068
+
3069
+ if (error && !expectedException(actual, error, message, stackStartFn)) {
3070
+ throw actual;
3071
+ }
3072
+ }
3073
+
3074
+ function expectsNoError(stackStartFn, actual, error, message) {
3075
+ if (actual === NO_EXCEPTION_SENTINEL) return;
3076
+
3077
+ if (typeof error === 'string') {
3078
+ message = error;
3079
+ error = undefined;
3080
+ }
3081
+
3082
+ if (!error || expectedException(actual, error)) {
3083
+ var details = message ? ": ".concat(message) : '.';
3084
+ var fnType = stackStartFn.name === 'doesNotReject' ? 'rejection' : 'exception';
3085
+ innerFail({
3086
+ actual: actual,
3087
+ expected: error,
3088
+ operator: stackStartFn.name,
3089
+ message: "Got unwanted ".concat(fnType).concat(details, "\n") + "Actual message: \"".concat(actual && actual.message, "\""),
3090
+ stackStartFn: stackStartFn
3091
+ });
3092
+ }
3093
+
3094
+ throw actual;
3095
+ }
3096
+
3097
+ assert.throws = function throws(promiseFn) {
3098
+ for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
3099
+ args[_key2 - 1] = arguments[_key2];
3100
+ }
3101
+
3102
+ expectsError.apply(void 0, [throws, getActual(promiseFn)].concat(args));
3103
+ };
3104
+
3105
+ assert.rejects = function rejects(promiseFn) {
3106
+ for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
3107
+ args[_key3 - 1] = arguments[_key3];
3108
+ }
3109
+
3110
+ return waitForActual(promiseFn).then(function (result) {
3111
+ return expectsError.apply(void 0, [rejects, result].concat(args));
3112
+ });
3113
+ };
3114
+
3115
+ assert.doesNotThrow = function doesNotThrow(fn) {
3116
+ for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
3117
+ args[_key4 - 1] = arguments[_key4];
3118
+ }
3119
+
3120
+ expectsNoError.apply(void 0, [doesNotThrow, getActual(fn)].concat(args));
3121
+ };
3122
+
3123
+ assert.doesNotReject = function doesNotReject(fn) {
3124
+ for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
3125
+ args[_key5 - 1] = arguments[_key5];
3126
+ }
3127
+
3128
+ return waitForActual(fn).then(function (result) {
3129
+ return expectsNoError.apply(void 0, [doesNotReject, result].concat(args));
3130
+ });
3131
+ };
3132
+
3133
+ assert.ifError = function ifError(err) {
3134
+ if (err !== null && err !== undefined) {
3135
+ var message = 'ifError got unwanted exception: ';
3136
+
3137
+ if (_typeof(err) === 'object' && typeof err.message === 'string') {
3138
+ if (err.message.length === 0 && err.constructor) {
3139
+ message += err.constructor.name;
3140
+ } else {
3141
+ message += err.message;
3142
+ }
3143
+ } else {
3144
+ message += inspect(err);
3145
+ }
3146
+
3147
+ var newErr = new AssertionError({
3148
+ actual: err,
3149
+ expected: null,
3150
+ operator: 'ifError',
3151
+ message: message,
3152
+ stackStartFn: ifError
3153
+ }); // Make sure we actually have a stack trace!
3154
+
3155
+ var origStack = err.stack;
3156
+
3157
+ if (typeof origStack === 'string') {
3158
+ // This will remove any duplicated frames from the error frames taken
3159
+ // from within `ifError` and add the original error frames to the newly
3160
+ // created ones.
3161
+ var tmp2 = origStack.split('\n');
3162
+ tmp2.shift(); // Filter all frames existing in err.stack.
3163
+
3164
+ var tmp1 = newErr.stack.split('\n');
3165
+
3166
+ for (var i = 0; i < tmp2.length; i++) {
3167
+ // Find the first occurrence of the frame.
3168
+ var pos = tmp1.indexOf(tmp2[i]);
3169
+
3170
+ if (pos !== -1) {
3171
+ // Only keep new frames.
3172
+ tmp1 = tmp1.slice(0, pos);
3173
+ break;
3174
+ }
3175
+ }
3176
+
3177
+ newErr.stack = "".concat(tmp1.join('\n'), "\n").concat(tmp2.join('\n'));
3178
+ }
3179
+
3180
+ throw newErr;
3181
+ }
3182
+ }; // Expose a strict only variant of assert
3183
+
3184
+
3185
+ function strict() {
3186
+ for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
3187
+ args[_key6] = arguments[_key6];
3188
+ }
3189
+
3190
+ innerOk.apply(void 0, [strict, args.length].concat(args));
3191
+ }
3192
+
3193
+ assert.strict = objectAssign(strict, assert, {
3194
+ equal: assert.strictEqual,
3195
+ deepEqual: assert.deepStrictEqual,
3196
+ notEqual: assert.notStrictEqual,
3197
+ notDeepEqual: assert.notDeepStrictEqual
3198
+ });
3199
+ assert.strict.strict = assert.strict;
3200
+ return assertExports$1;
3201
+ }
3202
+
3203
+ var assertExports = requireAssert();
3204
+ var assert = /*@__PURE__*/getDefaultExportFromCjs(assertExports);
3205
+
3206
+ /**
3207
+ * Debounce function.
3208
+ *
3209
+ * @param {Function} fn - Function to debounce.
3210
+ * @param {Object} [options] - Options.
3211
+ * @param {number} [options.delay=500] - Delay in milliseconds.
3212
+ * @param {boolean} [options.edges=false] - Whether to call the function on the
3213
+ * leading and trailing edges of the wait timeout.
3214
+ * @returns {Function} Debounced function.
3215
+ */
3216
+ function debounce(fn, { delay = 500, edges } = {}) {
3217
+ assert.ok(typeof fn === "function", "fn<function> is required");
3218
+ let timeout;
3219
+ let nCalls = 0;
3220
+ return (...args) => {
3221
+ nCalls += 1;
3222
+ if (edges && nCalls === 1) {
3223
+ fn(...args);
3224
+ }
3225
+ clearTimeout(timeout);
3226
+ timeout = setTimeout(() => {
3227
+ if (!edges || nCalls > 1) {
3228
+ fn(...args);
3229
+ }
3230
+ timeout = undefined;
3231
+ nCalls = 0;
3232
+ }, delay);
3233
+ };
3234
+ }
3235
+
3236
+ var VideoView = (_a) => {
3237
+ var { muted, stream, onResize } = _a, rest = __rest(_a, ["muted", "stream", "onResize"]);
3238
+ const videoEl = useRef(null);
3239
+ useEffect(() => {
3240
+ if (!videoEl.current || !onResize) {
3241
+ return;
3242
+ }
3243
+ const resizeObserver = new ResizeObserver(debounce(() => {
3244
+ if (videoEl.current && (stream === null || stream === void 0 ? void 0 : stream.id)) {
3245
+ onResize({
3246
+ width: videoEl.current.clientWidth,
3247
+ height: videoEl.current.clientHeight,
3248
+ stream,
3249
+ });
3250
+ }
3251
+ }, { delay: 1000, edges: true }));
3252
+ resizeObserver.observe(videoEl.current);
3253
+ return () => {
3254
+ resizeObserver.disconnect();
3255
+ };
3256
+ }, [stream]);
3257
+ useEffect(() => {
3258
+ if (!videoEl.current) {
3259
+ return;
3260
+ }
3261
+ if (videoEl.current.srcObject !== stream) {
3262
+ videoEl.current.srcObject = stream;
3263
+ }
3264
+ // Handle muting programatically, not as video attribute
3265
+ // https://stackoverflow.com/questions/14111917/html5-video-muted-but-still-playing
3266
+ if (videoEl.current.muted !== muted) {
3267
+ videoEl.current.muted = Boolean(muted);
3268
+ }
3269
+ }, [muted, stream, videoEl]);
3270
+ return React.createElement("video", Object.assign({ ref: videoEl, autoPlay: true, playsInline: true }, rest));
3271
+ };
3272
+
3273
+ const TypedLocalMediaEventTarget = EventTarget;
3274
+ class LocalMedia extends TypedLocalMediaEventTarget {
3275
+ constructor(constraints) {
3276
+ super();
3277
+ this._constraints = constraints;
3278
+ this.stream = new MediaStream();
3279
+ this._rtcManagers = [];
3280
+ navigator.mediaDevices.addEventListener("devicechange", this._updateDeviceList.bind(this));
3281
+ }
3282
+ addRtcManager(rtcManager) {
3283
+ this._rtcManagers.push(rtcManager);
3284
+ }
3285
+ removeRtcManager(rtcManager) {
3286
+ this._rtcManagers = this._rtcManagers.filter((r) => r !== rtcManager);
3287
+ }
3288
+ getCameraDeviceId() {
3289
+ var _a;
3290
+ return (_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
3291
+ }
3292
+ getMicrophoneDeviceId() {
3293
+ var _a;
3294
+ return (_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.getSettings().deviceId;
3295
+ }
3296
+ isCameraEnabled() {
3297
+ var _a;
3298
+ return !!((_a = this.stream.getVideoTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
3299
+ }
3300
+ isMicrophoneEnabled() {
3301
+ var _a;
3302
+ return !!((_a = this.stream.getAudioTracks()[0]) === null || _a === void 0 ? void 0 : _a.enabled);
3303
+ }
3304
+ toggleCameraEnabled(enabled) {
3305
+ const videoTrack = this.stream.getVideoTracks()[0];
3306
+ if (!videoTrack) {
3307
+ return;
3308
+ }
3309
+ const newValue = enabled !== null && enabled !== void 0 ? enabled : !videoTrack.enabled;
3310
+ videoTrack.enabled = newValue;
3311
+ this.dispatchEvent(new CustomEvent("camera_enabled", { detail: { enabled: newValue } }));
3312
+ }
3313
+ toggleMichrophoneEnabled(enabled) {
3314
+ const audioTrack = this.stream.getAudioTracks()[0];
3315
+ if (!audioTrack) {
3316
+ return;
3317
+ }
3318
+ const newValue = enabled !== null && enabled !== void 0 ? enabled : !audioTrack.enabled;
3319
+ audioTrack.enabled = newValue;
3320
+ this.dispatchEvent(new CustomEvent("microphone_enabled", { detail: { enabled: newValue } }));
3321
+ }
3322
+ setCameraDevice(deviceId) {
3323
+ return __awaiter(this, void 0, void 0, function* () {
3324
+ const newStream = yield navigator.mediaDevices.getUserMedia({ video: { deviceId } });
3325
+ const newVideoTrack = newStream.getVideoTracks()[0];
3326
+ if (newVideoTrack) {
3327
+ const oldVideoTrack = this.stream.getVideoTracks()[0];
3328
+ newVideoTrack.enabled = oldVideoTrack.enabled;
3329
+ oldVideoTrack === null || oldVideoTrack === void 0 ? void 0 : oldVideoTrack.stop();
3330
+ this._rtcManagers.forEach((rtcManager) => {
3331
+ rtcManager.replaceTrack(oldVideoTrack, newVideoTrack);
3332
+ });
3333
+ this.stream.removeTrack(oldVideoTrack);
3334
+ this.stream.addTrack(newVideoTrack);
3335
+ }
3336
+ this.dispatchEvent(new CustomEvent("stream_updated", {
3337
+ detail: { stream: this.stream },
3338
+ }));
3339
+ });
3340
+ }
3341
+ setMicrophoneDevice(deviceId) {
3342
+ return __awaiter(this, void 0, void 0, function* () {
3343
+ const newStream = yield navigator.mediaDevices.getUserMedia({ audio: { deviceId } });
3344
+ const newAudioTrack = newStream.getAudioTracks()[0];
3345
+ const oldAudioTrack = this.stream.getAudioTracks()[0];
3346
+ if (oldAudioTrack) {
3347
+ newAudioTrack.enabled = oldAudioTrack.enabled;
3348
+ oldAudioTrack.stop();
3349
+ this.stream.removeTrack(oldAudioTrack);
3350
+ }
3351
+ this._rtcManagers.forEach((rtcManager) => {
3352
+ rtcManager.replaceTrack(oldAudioTrack, newAudioTrack);
3353
+ });
3354
+ this.stream.addTrack(newAudioTrack);
3355
+ this.dispatchEvent(new CustomEvent("stream_updated", {
3356
+ detail: { stream: this.stream },
3357
+ }));
3358
+ });
3359
+ }
3360
+ _updateDeviceList() {
3361
+ return __awaiter(this, void 0, void 0, function* () {
3362
+ try {
3363
+ const devices = yield navigator.mediaDevices.enumerateDevices();
3364
+ this.dispatchEvent(new CustomEvent("device_list_updated", {
3365
+ detail: {
3366
+ cameraDevices: devices.filter((d) => d.kind === "videoinput"),
3367
+ microphoneDevices: devices.filter((d) => d.kind === "audioinput"),
3368
+ speakerDevices: devices.filter((d) => d.kind === "audiooutput"),
3369
+ },
3370
+ }));
3371
+ }
3372
+ catch (error) {
3373
+ this.dispatchEvent(new CustomEvent("device_list_update_error", {
3374
+ detail: {
3375
+ error,
3376
+ },
3377
+ }));
3378
+ throw error;
3379
+ }
3380
+ });
3381
+ }
3382
+ start() {
3383
+ return __awaiter(this, void 0, void 0, function* () {
3384
+ const newStream = yield navigator.mediaDevices.getUserMedia(this._constraints);
3385
+ newStream.getTracks().forEach((t) => this.stream.addTrack(t));
3386
+ this._updateDeviceList();
3387
+ this.dispatchEvent(new CustomEvent("stream_updated", {
3388
+ detail: { stream: this.stream },
3389
+ }));
3390
+ return this.stream;
3391
+ });
3392
+ }
3393
+ stop() {
3394
+ var _a;
3395
+ (_a = this.stream) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((t) => {
3396
+ t.stop();
3397
+ });
3398
+ }
3399
+ }
3400
+
3401
+ const initialState$1 = {
3402
+ cameraDeviceError: null,
3403
+ cameraDevices: [],
3404
+ isSettingCameraDevice: false,
3405
+ isSettingMicrophoneDevice: false,
3406
+ isStarting: false,
3407
+ microphoneDeviceError: null,
3408
+ microphoneDevices: [],
3409
+ speakerDevices: [],
3410
+ startError: null,
3411
+ };
3412
+ function reducer$1(state, action) {
3413
+ switch (action.type) {
3414
+ case "DEVICE_LIST_UPDATED":
3415
+ return Object.assign(Object.assign({}, state), action.payload);
3416
+ case "LOCAL_STREAM_UPDATED":
3417
+ return Object.assign(Object.assign({}, state), { currentCameraDeviceId: action.payload.currentCameraDeviceId, currentMicrophoneDeviceId: action.payload.currentMicrophoneDeviceId, localStream: action.payload.stream });
3418
+ case "SET_CAMERA_DEVICE":
3419
+ return Object.assign(Object.assign({}, state), { cameraDeviceError: null, isSettingCameraDevice: true });
3420
+ case "SET_CAMERA_DEVICE_COMPLETE":
3421
+ return Object.assign(Object.assign({}, state), { isSettingCameraDevice: false });
3422
+ case "SET_CAMERA_DEVICE_ERROR":
3423
+ return Object.assign(Object.assign({}, state), { cameraDeviceError: action.payload, isSettingCameraDevice: false });
3424
+ case "SET_MICROPHONE_DEVICE":
3425
+ return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: true, microphoneDeviceError: null });
3426
+ case "SET_MICROPHONE_DEVICE_COMPLETE":
3427
+ return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false });
3428
+ case "SET_MICROPHONE_DEVICE_ERROR":
3429
+ return Object.assign(Object.assign({}, state), { isSettingMicrophoneDevice: false, microphoneDeviceError: action.payload });
3430
+ case "START":
3431
+ return Object.assign(Object.assign({}, state), { isStarting: true, startError: null });
3432
+ case "START_COMPLETE":
3433
+ return Object.assign(Object.assign({}, state), { isStarting: false });
3434
+ case "START_ERROR":
3435
+ return Object.assign(Object.assign({}, state), { isStarting: false, startError: action.payload });
3436
+ default:
3437
+ return state;
3438
+ }
3439
+ }
3440
+ function useLocalMedia(constraints = { audio: true, video: true }) {
3441
+ const [localMedia] = useState(() => new LocalMedia(constraints));
3442
+ const [state, dispatch] = useReducer(reducer$1, initialState$1);
3443
+ useEffect(() => {
3444
+ localMedia.addEventListener("device_list_updated", (e) => {
3445
+ const { cameraDevices, microphoneDevices, speakerDevices } = e.detail;
3446
+ dispatch({ type: "DEVICE_LIST_UPDATED", payload: { cameraDevices, microphoneDevices, speakerDevices } });
3447
+ });
3448
+ localMedia.addEventListener("stream_updated", (e) => {
3449
+ const { stream } = e.detail;
3450
+ dispatch({
3451
+ type: "LOCAL_STREAM_UPDATED",
3452
+ payload: {
3453
+ stream,
3454
+ currentCameraDeviceId: localMedia.getCameraDeviceId(),
3455
+ currentMicrophoneDeviceId: localMedia.getMicrophoneDeviceId(),
3456
+ },
3457
+ });
3458
+ });
3459
+ const start = () => __awaiter(this, void 0, void 0, function* () {
3460
+ dispatch({ type: "START" });
3461
+ try {
3462
+ yield localMedia.start();
3463
+ dispatch({ type: "START_COMPLETE" });
3464
+ }
3465
+ catch (error) {
3466
+ dispatch({ type: "START_ERROR", payload: error });
3467
+ }
3468
+ });
3469
+ start();
3470
+ // Perform cleanup on unmount
3471
+ return () => {
3472
+ localMedia.stop();
3473
+ };
3474
+ }, []);
3475
+ return {
3476
+ state,
3477
+ actions: {
3478
+ setCameraDevice: (...args) => __awaiter(this, void 0, void 0, function* () {
3479
+ dispatch({ type: "SET_CAMERA_DEVICE" });
3480
+ try {
3481
+ yield localMedia.setCameraDevice(...args);
3482
+ dispatch({ type: "SET_CAMERA_DEVICE_COMPLETE" });
3483
+ }
3484
+ catch (error) {
3485
+ dispatch({ type: "SET_CAMERA_DEVICE_ERROR", payload: error });
3486
+ }
3487
+ }),
3488
+ setMicrophoneDevice: (...args) => __awaiter(this, void 0, void 0, function* () {
3489
+ dispatch({ type: "SET_MICROPHONE_DEVICE" });
3490
+ try {
3491
+ yield localMedia.setMicrophoneDevice(...args);
3492
+ dispatch({ type: "SET_MICROPHONE_DEVICE_COMPLETE" });
3493
+ }
3494
+ catch (error) {
3495
+ dispatch({ type: "SET_MICROPHONE_DEVICE_ERROR", payload: error });
3496
+ }
3497
+ }),
3498
+ toggleCameraEnabled: (...args) => {
3499
+ return localMedia.toggleCameraEnabled(...args);
3500
+ },
3501
+ toggleMicrophoneEnabled: (...args) => {
3502
+ return localMedia.toggleMichrophoneEnabled(...args);
3503
+ },
3504
+ },
3505
+ _ref: localMedia,
3506
+ };
3507
+ }
3508
+
3509
+ const EVENTS = {
3510
+ CLIENT_CONNECTION_STATUS_CHANGED: "client_connection_status_changed",
3511
+ STREAM_ADDED: "stream_added",
3512
+ RTC_MANAGER_CREATED: "rtc_manager_created",
3513
+ RTC_MANAGER_DESTROYED: "rtc_manager_destroyed",
3514
+ LOCAL_STREAM_TRACK_ADDED: "local_stream_track_added",
3515
+ LOCAL_STREAM_TRACK_REMOVED: "local_stream_track_removed",
3516
+ REMOTE_STREAM_TRACK_ADDED: "remote_stream_track_added",
3517
+ REMOTE_STREAM_TRACK_REMOVED: "remote_stream_track_removed",
3518
+ };
3860
3519
 
3861
- function notDeepStrictEqual(actual, expected, message) {
3862
- if (arguments.length < 2) {
3863
- throw new ERR_MISSING_ARGS('actual', 'expected');
3864
- }
3520
+ const TYPES = {
3521
+ CONNECTING: "connecting",
3522
+ CONNECTION_FAILED: "connection_failed",
3523
+ CONNECTION_SUCCESSFUL: "connection_successful",
3524
+ CONNECTION_DISCONNECTED: "connection_disconnected",
3525
+ };
3865
3526
 
3866
- if (isDeepEqual === undefined) lazyLoadComparison();
3527
+ // Protocol enum used for the CLIENT (Make sure to keep it in sync with its server counterpart)
3867
3528
 
3868
- if (isDeepStrictEqual(actual, expected)) {
3869
- innerFail({
3870
- actual: actual,
3871
- expected: expected,
3872
- message: message,
3873
- operator: 'notDeepStrictEqual',
3874
- stackStartFn: notDeepStrictEqual
3875
- });
3876
- }
3877
- }
3529
+ // Requests: messages from the client to the server
3530
+ const PROTOCOL_REQUESTS = {
3531
+ BLOCK_CLIENT: "block_client",
3532
+ CLAIM_ROOM: "claim_room",
3533
+ CLEAR_CHAT_HISTORY: "clear_chat_history",
3534
+ ENABLE_AUDIO: "enable_audio",
3535
+ ENABLE_VIDEO: "enable_video",
3536
+ END_STREAM: "end_stream",
3537
+ FETCH_MEDIASERVER_CONFIG: "fetch_mediaserver_config",
3538
+ HANDLE_KNOCK: "handle_knock",
3539
+ IDENTIFY_DEVICE: "identify_device",
3540
+ INVITE_CLIENT_AS_MEMBER: "invite_client_as_member",
3541
+ JOIN_ROOM: "join_room",
3542
+ KICK_CLIENT: "kick_client",
3543
+ KNOCK_ROOM: "knock_room",
3544
+ LEAVE_ROOM: "leave_room",
3545
+ SEND_CLIENT_METADATA: "send_client_metadata",
3546
+ SET_LOCK: "set_lock",
3547
+ SHARE_MEDIA: "share_media",
3548
+ START_NEW_STREAM: "start_new_stream",
3549
+ START_SCREENSHARE: "start_screenshare",
3550
+ STOP_SCREENSHARE: "stop_screenshare",
3551
+ START_URL_EMBED: "start_url_embed",
3552
+ STOP_URL_EMBED: "stop_url_embed",
3553
+ START_RECORDING: "start_recording",
3554
+ STOP_RECORDING: "stop_recording",
3555
+ SFU_TOKEN: "sfu_token",
3556
+ };
3878
3557
 
3879
- assert.strictEqual = function strictEqual(actual, expected, message) {
3880
- if (arguments.length < 2) {
3881
- throw new ERR_MISSING_ARGS('actual', 'expected');
3882
- }
3558
+ // Responses: messages from the server to the client, in response to requests
3559
+ const PROTOCOL_RESPONSES = {
3560
+ AUDIO_ENABLED: "audio_enabled",
3561
+ BACKGROUND_IMAGE_CHANGED: "background_image_changed",
3562
+ BLOCK_ADDED: "block_added",
3563
+ BLOCK_REMOVED: "block_removed",
3564
+ CHAT_HISTORY_CLEARED: "chat_history_cleared",
3565
+ CLIENT_BLOCKED: "client_blocked",
3566
+ CLIENT_INVITED_AS_MEMBER: "client_invited_as_member",
3567
+ CLIENT_KICKED: "client_kicked",
3568
+ CLIENT_LEFT: "client_left",
3569
+ CLIENT_METADATA_RECEIVED: "client_metadata_received",
3570
+ CLIENT_READY: "client_ready",
3571
+ CLIENT_ROLE_CHANGED: "client_role_changed",
3572
+ CLIENT_USER_ID_CHANGED: "client_user_id_changed",
3573
+ CONTACTS_UPDATED: "contacts_updated",
3574
+ DEVICE_IDENTIFIED: "device_identified",
3575
+ ROOM_ROLES_UPDATED: "room_roles_updated",
3576
+ KNOCK_HANDLED: "knock_handled",
3577
+ KNOCK_PAGE_BACKGROUND_CHANGED: "knock_page_background_changed",
3578
+ KNOCKER_LEFT: "knocker_left",
3579
+ MEDIASERVER_CONFIG: "mediaserver_config",
3580
+ MEDIA_SHARED: "media_shared",
3581
+ MEMBER_INVITE: "member_invite",
3582
+ NEW_CLIENT: "new_client",
3583
+ NEW_STREAM_STARTED: "new_stream_started",
3584
+ SCREENSHARE_STARTED: "screenshare_started",
3585
+ SCREENSHARE_STOPPED: "screenshare_stopped",
3586
+ OWNER_NOTIFIED: "owner_notified",
3587
+ OWNERS_CHANGED: "owners_changed",
3588
+ PLAY_CLIENT_STICKER: "play_client_sticker",
3589
+ ROOM_INTEGRATION_ENABLED: "room_integration_enabled",
3590
+ ROOM_INTEGRATION_DISABLED: "room_integration_disabled",
3591
+ ROOM_JOINED: "room_joined",
3592
+ ROOM_KNOCKED: "room_knocked",
3593
+ ROOM_LEFT: "room_left",
3594
+ ROOM_LOCKED: "room_locked",
3595
+ ROOM_PERMISSIONS_CHANGED: "room_permissions_changed",
3596
+ ROOM_LOGO_CHANGED: "room_logo_changed",
3597
+ ROOM_TYPE_CHANGED: "room_type_changed",
3598
+ ROOM_MODE_CHANGED: "room_mode_changed",
3599
+ SOCKET_USER_ID_CHANGED: "socket_user_id_changed",
3600
+ STICKERS_UNLOCKED: "stickers_unlocked",
3601
+ STREAM_ENDED: "stream_ended",
3602
+ URL_EMBED_STARTED: "url_embed_started",
3603
+ URL_EMBED_STOPPED: "url_embed_stopped",
3604
+ RECORDING_STARTED: "recording_started",
3605
+ RECORDING_STOPPED: "recording_stopped",
3606
+ USER_NOTIFIED: "user_notified",
3607
+ VIDEO_ENABLED: "video_enabled",
3608
+ CLIENT_UNABLE_TO_JOIN: "client_unable_to_join",
3609
+ };
3883
3610
 
3884
- if (!objectIs(actual, expected)) {
3885
- innerFail({
3886
- actual: actual,
3887
- expected: expected,
3888
- message: message,
3889
- operator: 'strictEqual',
3890
- stackStartFn: strictEqual
3891
- });
3892
- }
3893
- };
3611
+ // Relays: messages between clients, relayed through the server
3612
+ const RELAY_MESSAGES = {
3613
+ CHAT_MESSAGE: "chat_message",
3614
+ CHAT_READ_STATE: "chat_read_state",
3615
+ CHAT_STATE: "chat_state",
3616
+ ICE_CANDIDATE: "ice_candidate",
3617
+ ICE_END_OF_CANDIDATES: "ice_endofcandidates",
3618
+ READY_TO_RECEIVE_OFFER: "ready_to_receive_offer",
3619
+ REMOTE_CLIENT_MEDIA_REQUEST: "remote_client_media_request",
3620
+ SDP_ANSWER: "sdp_answer",
3621
+ SDP_OFFER: "sdp_offer",
3622
+ VIDEO_STICKER: "video_sticker",
3623
+ };
3894
3624
 
3895
- assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
3896
- if (arguments.length < 2) {
3897
- throw new ERR_MISSING_ARGS('actual', 'expected');
3898
- }
3625
+ /**
3626
+ * Wrapper class that extends the Socket.IO client library.
3627
+ */
3628
+ class ServerSocket {
3629
+ constructor(hostName, options) {
3630
+ // Prefer websockets but fallback to polling as recommended on
3631
+ // https://socket.io/docs/client-api/
3632
+ // with modifications to reconnect using WebSocket if we ever
3633
+ // connected with Websockets.
3634
+ if (options && !options.transports) {
3635
+ options.transports = ["websocket"];
3636
+ }
3899
3637
 
3900
- if (objectIs(actual, expected)) {
3901
- innerFail({
3902
- actual: actual,
3903
- expected: expected,
3904
- message: message,
3905
- operator: 'notStrictEqual',
3906
- stackStartFn: notStrictEqual
3907
- });
3908
- }
3909
- };
3638
+ this._socket = io(hostName, options);
3639
+ this._socket.io.on("reconnect", () => {
3640
+ this._socket.sendBuffer = [];
3641
+ });
3642
+ this._socket.io.on("reconnect_attempt", () => {
3643
+ if (this._wasConnectedUsingWebsocket) {
3644
+ this._socket.io.opts.transports = ["websocket"];
3645
+ // only fallback to polling if not safari
3646
+ // safari doesn't support cross doamin cookies making load-balancer stickiness not work
3647
+ // and if socket.io reconnects to another signal instance with polling it will fail
3648
+ // remove if we move signal to a whereby.com subdomain
3649
+ if (adapter.browserDetails.browser !== "safari") delete this._wasConnectedUsingWebsocket;
3650
+ } else {
3651
+ this._socket.io.opts.transports = ["polling", "websocket"];
3652
+ }
3653
+ });
3654
+ this._socket.on("connect", () => {
3655
+ const transport = this.getTransport();
3656
+ if (transport === "websocket") {
3657
+ this._wasConnectedUsingWebsocket = true;
3658
+ }
3659
+ });
3660
+ }
3910
3661
 
3911
- var Comparison = function Comparison(obj, keys, actual) {
3912
- var _this = this;
3662
+ connect() {
3663
+ if (this.isConnected() || this.isConnecting()) {
3664
+ return;
3665
+ }
3666
+ this._socket.open();
3667
+ }
3913
3668
 
3914
- _classCallCheck(this, Comparison);
3669
+ disconnect() {
3670
+ this._socket.disconnect();
3671
+ }
3915
3672
 
3916
- keys.forEach(function (key) {
3917
- if (key in obj) {
3918
- if (actual !== undefined && typeof actual[key] === 'string' && isRegExp(obj[key]) && obj[key].test(actual[key])) {
3919
- _this[key] = actual[key];
3920
- } else {
3921
- _this[key] = obj[key];
3922
- }
3923
- }
3924
- });
3925
- };
3673
+ disconnectOnConnect() {
3674
+ this._socket.once("connect", () => {
3675
+ this._socket.disconnect();
3676
+ });
3677
+ }
3926
3678
 
3927
- function compareExceptionKey(actual, expected, key, message, keys, fn) {
3928
- if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) {
3929
- if (!message) {
3930
- // Create placeholder objects to create a nice output.
3931
- var a = new Comparison(actual, keys);
3932
- var b = new Comparison(expected, keys, actual);
3933
- var err = new AssertionError({
3934
- actual: a,
3935
- expected: b,
3936
- operator: 'deepStrictEqual',
3937
- stackStartFn: fn
3938
- });
3939
- err.actual = actual;
3940
- err.expected = expected;
3941
- err.operator = fn.name;
3942
- throw err;
3943
- }
3679
+ emit() {
3680
+ this._socket.emit.apply(this._socket, arguments);
3681
+ }
3944
3682
 
3945
- innerFail({
3946
- actual: actual,
3947
- expected: expected,
3948
- message: message,
3949
- operator: fn.name,
3950
- stackStartFn: fn
3951
- });
3952
- }
3953
- }
3683
+ emitIfConnected(eventName, data) {
3684
+ if (!this.isConnected()) {
3685
+ return;
3686
+ }
3687
+ this.emit(eventName, data);
3688
+ }
3689
+
3690
+ getTransport() {
3691
+ return (
3692
+ this._socket &&
3693
+ this._socket.io &&
3694
+ this._socket.io.engine &&
3695
+ this._socket.io.engine.transport &&
3696
+ this._socket.io.engine.transport.name
3697
+ );
3698
+ }
3954
3699
 
3955
- function expectedException(actual, expected, msg, fn) {
3956
- if (typeof expected !== 'function') {
3957
- if (isRegExp(expected)) return expected.test(actual); // assert.doesNotThrow does not accept objects.
3700
+ getManager() {
3701
+ return this._socket.io;
3702
+ }
3958
3703
 
3959
- if (arguments.length === 2) {
3960
- throw new ERR_INVALID_ARG_TYPE('expected', ['Function', 'RegExp'], expected);
3961
- } // Handle primitives properly.
3704
+ isConnecting() {
3705
+ return this._socket && this._socket.connecting;
3706
+ }
3962
3707
 
3708
+ isConnected() {
3709
+ return this._socket && this._socket.connected;
3710
+ }
3963
3711
 
3964
- if (_typeof(actual) !== 'object' || actual === null) {
3965
- var err = new AssertionError({
3966
- actual: actual,
3967
- expected: expected,
3968
- message: msg,
3969
- operator: 'deepStrictEqual',
3970
- stackStartFn: fn
3971
- });
3972
- err.operator = fn.name;
3973
- throw err;
3974
- }
3712
+ /**
3713
+ * Register a new event handler.
3714
+ *
3715
+ * @param {string} eventName - Name of the event to listen for.
3716
+ * @param {function} handler - The callback function that should be called for the event.
3717
+ * @returns {function} Function to deregister the listener.
3718
+ */
3719
+ on(eventName, handler) {
3720
+ this._socket.on(eventName, handler);
3975
3721
 
3976
- var keys = Object.keys(expected); // Special handle errors to make sure the name and the message are compared
3977
- // as well.
3722
+ return () => {
3723
+ this._socket.off(eventName, handler);
3724
+ };
3725
+ }
3978
3726
 
3979
- if (expected instanceof Error) {
3980
- keys.push('name', 'message');
3981
- } else if (keys.length === 0) {
3982
- throw new ERR_INVALID_ARG_VALUE('error', expected, 'may not be an empty object');
3983
- }
3727
+ /**
3728
+ * Register a new event handler to be triggered only once.
3729
+ *
3730
+ * @param {string} eventName - Name of the event to listen for.
3731
+ * @param {function} handler - The function that should be called for the event.
3732
+ */
3733
+ once(eventName, handler) {
3734
+ this._socket.once(eventName, handler);
3735
+ }
3984
3736
 
3985
- if (isDeepEqual === undefined) lazyLoadComparison();
3986
- keys.forEach(function (key) {
3987
- if (typeof actual[key] === 'string' && isRegExp(expected[key]) && expected[key].test(actual[key])) {
3988
- return;
3989
- }
3737
+ /**
3738
+ * Deregister an event handler.
3739
+ *
3740
+ * @param {string} eventName - Name of the event the handler is registered for.
3741
+ * @param {function} handler - The callback that will be deregistered.
3742
+ */
3743
+ off(eventName, handler) {
3744
+ this._socket.off(eventName, handler);
3745
+ }
3746
+ }
3990
3747
 
3991
- compareExceptionKey(actual, expected, key, msg, keys, fn);
3992
- });
3993
- return true;
3994
- } // Guard instanceof against arrow functions as they don't have a prototype.
3748
+ var rtcManagerEvents = {
3749
+ CAMERA_NOT_WORKING: "camera_not_working",
3750
+ CONNECTION_BLOCKED_BY_NETWORK: "connection_blocked_by_network",
3751
+ MICROPHONE_NOT_WORKING: "microphone_not_working",
3752
+ MICROPHONE_STOPPED_WORKING: "microphone_stopped_working",
3753
+ SFU_CONNECTION_CLOSED: "sfu_connection_closed",
3754
+ COLOCATION_SPEAKER: "colocation_speaker",
3755
+ DOMINANT_SPEAKER: "dominant_speaker",
3756
+ };
3995
3757
 
3758
+ const browserName$2 = adapter.browserDetails.browser;
3759
+ const browserVersion$1 = adapter.browserDetails.version;
3996
3760
 
3997
- if (expected.prototype !== undefined && actual instanceof expected) {
3998
- return true;
3999
- }
3761
+ // SDP mangling for deprioritizing H264
3762
+ function deprioritizeH264(sdp) {
3763
+ return SDPUtils.splitSections(sdp)
3764
+ .map(section => {
3765
+ // only modify video sections
3766
+ if (SDPUtils.getKind(section) !== "video") return section;
4000
3767
 
4001
- if (Error.isPrototypeOf(expected)) {
4002
- return false;
4003
- }
3768
+ // list of payloadTypes used in this sdp/section
3769
+ const h264payloadTypes = SDPUtils.matchPrefix(section, "a=rtpmap:")
3770
+ .map(line => SDPUtils.parseRtpMap(line))
3771
+ .filter(codec => /h264/i.test(codec.name))
3772
+ .map(codec => "" + codec.payloadType);
4004
3773
 
4005
- return expected.call({}, actual) === true;
4006
- }
3774
+ // return as is if no h264 found
3775
+ if (!h264payloadTypes.length) return section;
4007
3776
 
4008
- function getActual(fn) {
4009
- if (typeof fn !== 'function') {
4010
- throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
4011
- }
3777
+ // reorder and replace
3778
+ const mline = SDPUtils.matchPrefix(section, "m=video")[0];
3779
+ const mlinePayloadsSection = /(\s\d+)+$/i.exec(mline)[0];
3780
+ const mlinePayloadsNonH264 = mlinePayloadsSection
3781
+ .split(" ")
3782
+ .filter(payloadType => payloadType && !h264payloadTypes.includes(payloadType));
3783
+ const reorderedPayloads = [...mlinePayloadsNonH264, ...h264payloadTypes].join(" ");
3784
+ const newmline = mline.replace(mlinePayloadsSection, " " + reorderedPayloads);
3785
+ return section.replace(mline, newmline);
3786
+ })
3787
+ .join("");
3788
+ }
4012
3789
 
4013
- try {
4014
- fn();
4015
- } catch (e) {
4016
- return e;
4017
- }
3790
+ // TODO: currently assumes video, look at track.kind
3791
+ // ensures that SSRCs in new description match ssrcs in old description
3792
+ function replaceSSRCs(currentDescription, newDescription) {
3793
+ let ssrcs = currentDescription.match(/a=ssrc-group:FID (\d+) (\d+)\r\n/);
3794
+ let newssrcs = newDescription.match(/a=ssrc-group:FID (\d+) (\d+)\r\n/);
3795
+ // Firefox offers dont have a FID ssrc group (yet)
3796
+ if (!ssrcs) {
3797
+ ssrcs = currentDescription.match(/a=ssrc:(\d+) cname:(.*)\r\n/g)[1].match(/a=ssrc:(\d+)/);
3798
+ newssrcs = newDescription.match(/a=ssrc:(\d+) cname:(.*)\r\n/g)[1].match(/a=ssrc:(\d+)/);
3799
+ }
3800
+ for (let i = 1; i < ssrcs.length; i++) {
3801
+ newDescription = newDescription.replace(new RegExp(newssrcs[i], "g"), ssrcs[i]);
3802
+ }
3803
+ return newDescription;
3804
+ }
4018
3805
 
4019
- return NO_EXCEPTION_SENTINEL;
4020
- }
3806
+ // Firefox < 63 (but not Firefox ESR 60) is affected by this:
3807
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1478685
3808
+ // filter out the mid rtp header extension
3809
+ function filterMidExtension(sdp) {
3810
+ if (browserName$2 !== "safari" && (browserName$2 !== "firefox" || browserVersion$1 >= 63 || browserVersion$1 === 60)) {
3811
+ return sdp;
3812
+ }
3813
+ return (
3814
+ SDPUtils.splitLines(sdp.trim())
3815
+ .filter(line => {
3816
+ if (!line.startsWith("a=extmap:")) {
3817
+ return true;
3818
+ }
3819
+ const extmap = SDPUtils.parseExtmap(line);
3820
+ return extmap.uri !== "urn:ietf:params:rtp-hdrext:sdes:mid";
3821
+ })
3822
+ .join("\r\n") + "\r\n"
3823
+ );
3824
+ }
4021
3825
 
4022
- function checkIsPromise(obj) {
4023
- // Accept native ES6 promises and promises that are implemented in a similar
4024
- // way. Do not accept thenables that use a function as `obj` and that have no
4025
- // `catch` handler.
4026
- // TODO: thenables are checked up until they have the correct methods,
4027
- // but according to documentation, the `then` method should receive
4028
- // the `fulfill` and `reject` arguments as well or it may be never resolved.
4029
- return isPromise(obj) || obj !== null && _typeof(obj) === 'object' && typeof obj.then === 'function' && typeof obj.catch === 'function';
4030
- }
3826
+ // Firefox < 68 (at least) is affected by this, although it is not
3827
+ // clear that FF is to blame:
3828
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=1534673
3829
+ // Filter out a:msid-semantic header
3830
+ function filterMsidSemantic(sdp) {
3831
+ if (browserName$2 !== "firefox") {
3832
+ return sdp;
3833
+ }
3834
+ return (
3835
+ SDPUtils.splitLines(sdp.trim())
3836
+ .map(line => (line.startsWith("a=msid-semantic:") ? "a=msid-semantic: WMS *" : line))
3837
+ .join("\r\n") + "\r\n"
3838
+ );
3839
+ }
4031
3840
 
4032
- function waitForActual(promiseFn) {
4033
- return Promise.resolve().then(function () {
4034
- var resultPromise;
3841
+ function isRelayed(pc) {
3842
+ return pc.getStats(null).then(result => {
3843
+ let localCandidateType;
3844
+ let remoteCandidateType;
3845
+ result.forEach(report => {
3846
+ // Chrome 58+ / spec
3847
+ if (report.type === "transport" && report.selectedCandidatePairId) {
3848
+ const transport = result.get(report.selectedCandidatePairId);
3849
+ if (!transport) {
3850
+ return;
3851
+ }
3852
+ localCandidateType = result.get(transport.localCandidateId).candidateType;
3853
+ remoteCandidateType = result.get(transport.remoteCandidateId).candidateType;
3854
+ return;
3855
+ }
3856
+ // Firefox (missing type=transport)
3857
+ if (report.type === "candidate-pair" && report.selected) {
3858
+ localCandidateType = result.get(report.localCandidateId).candidateType;
3859
+ remoteCandidateType = result.get(report.remoteCandidateId).candidateType;
3860
+ }
3861
+ });
3862
+ return (
3863
+ localCandidateType === "relay" ||
3864
+ localCandidateType === "relayed" || // relay: spec-stats; relayed: Firefox (bug)
3865
+ remoteCandidateType === "relay" ||
3866
+ remoteCandidateType === "relayed"
3867
+ );
3868
+ });
3869
+ }
4035
3870
 
4036
- if (typeof promiseFn === 'function') {
4037
- // Return a rejected promise if `promiseFn` throws synchronously.
4038
- resultPromise = promiseFn(); // Fail in case no promise is returned.
3871
+ const logger$4 = console;
4039
3872
 
4040
- if (!checkIsPromise(resultPromise)) {
4041
- throw new ERR_INVALID_RETURN_VALUE('instance of Promise', 'promiseFn', resultPromise);
4042
- }
4043
- } else if (checkIsPromise(promiseFn)) {
4044
- resultPromise = promiseFn;
4045
- } else {
4046
- throw new ERR_INVALID_ARG_TYPE('promiseFn', ['Function', 'Promise'], promiseFn);
4047
- }
3873
+ // use https://w3c.github.io/webrtc-pc/#dom-rtcrtpsender-setparameters to change the video bandwidth.
3874
+ function setVideoBandwidthUsingSetParameters(pc, bandwidth) {
3875
+ const sender = pc.getSenders().find(s => s.track && s.track.kind === "video");
3876
+ if (!sender) {
3877
+ return Promise.resolve();
3878
+ }
4048
3879
 
4049
- return Promise.resolve().then(function () {
4050
- return resultPromise;
4051
- }).then(function () {
4052
- return NO_EXCEPTION_SENTINEL;
4053
- }).catch(function (e) {
4054
- return e;
4055
- });
4056
- });
4057
- }
3880
+ const parameters = sender.getParameters();
3881
+ if (parameters.encodings && parameters.encodings.length === 0) {
3882
+ return Promise.resolve();
3883
+ }
3884
+
3885
+ if (!parameters.encodings) {
3886
+ // workaround for Firefox
3887
+ parameters.encodings = [{}];
3888
+ }
4058
3889
 
4059
- function expectsError(stackStartFn, actual, error, message) {
4060
- if (typeof error === 'string') {
4061
- if (arguments.length === 4) {
4062
- throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
4063
- }
3890
+ if (bandwidth === 0) {
3891
+ delete parameters.encodings[0].maxBitrate;
3892
+ } else {
3893
+ parameters.encodings[0].maxBitrate = bandwidth * 1000; // convert to bps
3894
+ }
4064
3895
 
4065
- if (_typeof(actual) === 'object' && actual !== null) {
4066
- if (actual.message === error) {
4067
- throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error message \"".concat(actual.message, "\" is identical to the message."));
4068
- }
4069
- } else if (actual === error) {
4070
- throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error \"".concat(actual, "\" is identical to the message."));
4071
- }
3896
+ return sender.setParameters(parameters).catch(err => {
3897
+ logger$4.error("setParameters err: ", err);
3898
+ });
3899
+ }
4072
3900
 
4073
- message = error;
4074
- error = undefined;
4075
- } else if (error != null && _typeof(error) !== 'object' && typeof error !== 'function') {
4076
- throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
4077
- }
3901
+ const logger$3 = console;
4078
3902
 
4079
- if (actual === NO_EXCEPTION_SENTINEL) {
4080
- var details = '';
3903
+ class Session {
3904
+ constructor({ peerConnectionId, bandwidth, maximumTurnBandwidth, deprioritizeH264Encoding }) {
3905
+ this.peerConnectionId = peerConnectionId;
3906
+ this.relayCandidateSeen = false;
3907
+ this.pc = null;
3908
+ this.wasEverConnected = false;
3909
+ this.connectionStatus = null;
3910
+ this.stats = {
3911
+ totalSent: 0,
3912
+ totalRecv: 0,
3913
+ };
3914
+ this.bandwidth = bandwidth || 0; // maximum bandwidth in kbps.
3915
+ this.maximumTurnBandwidth = maximumTurnBandwidth;
3916
+ this.pending = [];
3917
+ this.isOperationPending = false;
3918
+ this.streamIds = [];
3919
+ this.streams = [];
3920
+ this.earlyIceCandidates = [];
3921
+ this.afterConnected = new Promise(resolve => {
3922
+ this.registerConnected = resolve;
3923
+ });
3924
+ this.offerOptions = { offerToReceiveAudio: true, offerToReceiveVideo: true };
3925
+ this._deprioritizeH264Encoding = deprioritizeH264Encoding;
3926
+ }
4081
3927
 
4082
- if (error && error.name) {
4083
- details += " (".concat(error.name, ")");
4084
- }
3928
+ setAndGetPeerConnection({ clientId, constraints, peerConnectionConfig, shouldAddLocalVideo }) {
3929
+ this.peerConnectionConfig = peerConnectionConfig;
3930
+ this.shouldAddLocalVideo = shouldAddLocalVideo;
3931
+ this.clientId = clientId;
3932
+ this.pc = new RTCPeerConnection(peerConnectionConfig, constraints);
3933
+ this.signalingState = this.pc.signalingState;
4085
3934
 
4086
- details += message ? ": ".concat(message) : '.';
4087
- var fnType = stackStartFn.name === 'rejects' ? 'rejection' : 'exception';
4088
- innerFail({
4089
- actual: undefined,
4090
- expected: error,
4091
- operator: stackStartFn.name,
4092
- message: "Missing expected ".concat(fnType).concat(details),
4093
- stackStartFn: stackStartFn
4094
- });
4095
- }
3935
+ this.pc.addEventListener("signalingstatechange", () => {
3936
+ if (this.signalingState === this.pc.signalingState) {
3937
+ return;
3938
+ }
3939
+ this.signalingState = this.pc.signalingState;
3940
+ // implements a simple queue of pending operations
3941
+ // like doing an ice restart or setting the bandwidth
3942
+ if (this.pc.signalingState === "stable") {
3943
+ this.isOperationPending = false;
3944
+ const action = this.pending.shift();
3945
+ if (action) {
3946
+ action.apply();
3947
+ }
3948
+ }
3949
+ });
4096
3950
 
4097
- if (error && !expectedException(actual, error, message, stackStartFn)) {
4098
- throw actual;
4099
- }
4100
- }
3951
+ return this.pc;
3952
+ }
4101
3953
 
4102
- function expectsNoError(stackStartFn, actual, error, message) {
4103
- if (actual === NO_EXCEPTION_SENTINEL) return;
3954
+ addStream(stream) {
3955
+ this.streamIds.push(stream.id);
3956
+ this.streams.push(stream);
3957
+ if (RTCPeerConnection.prototype.addTrack) {
3958
+ stream.getAudioTracks().forEach(track => {
3959
+ this.pc.addTrack(track, stream);
3960
+ });
3961
+ stream.getVideoTracks().forEach(track => {
3962
+ this.pc.addTrack(track, stream);
3963
+ });
3964
+ } else {
3965
+ // legacy addStream fallback.
3966
+ this.pc.addStream(stream);
3967
+ }
3968
+ }
4104
3969
 
4105
- if (typeof error === 'string') {
4106
- message = error;
4107
- error = undefined;
4108
- }
3970
+ addTrack(track, stream) {
3971
+ if (!stream) {
3972
+ stream = this.streams[0];
3973
+ }
3974
+ stream.addTrack(track);
3975
+ this.pc.addTrack(track, stream);
3976
+ }
4109
3977
 
4110
- if (!error || expectedException(actual, error)) {
4111
- var details = message ? ": ".concat(message) : '.';
4112
- var fnType = stackStartFn.name === 'doesNotReject' ? 'rejection' : 'exception';
4113
- innerFail({
4114
- actual: actual,
4115
- expected: error,
4116
- operator: stackStartFn.name,
4117
- message: "Got unwanted ".concat(fnType).concat(details, "\n") + "Actual message: \"".concat(actual && actual.message, "\""),
4118
- stackStartFn: stackStartFn
4119
- });
4120
- }
3978
+ removeTrack(track) {
3979
+ const stream = this.streams[0];
3980
+ stream.removeTrack(track);
3981
+ const sender = this.pc.getSenders().find(sender => sender.track === track);
3982
+ if (sender) {
3983
+ this.pc.removeTrack(sender);
3984
+ }
3985
+ }
4121
3986
 
4122
- throw actual;
4123
- }
3987
+ removeStream(stream) {
3988
+ for (let i = 0; i < this.streamIds.length; i++) {
3989
+ if (this.streamIds[i] === stream.id) {
3990
+ this.streamIds.splice(i, 1);
3991
+ this.streams.splice(i, 1);
3992
+ }
3993
+ }
4124
3994
 
4125
- assert.throws = function throws(promiseFn) {
4126
- for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
4127
- args[_key2 - 1] = arguments[_key2];
4128
- }
3995
+ if (this.pc) {
3996
+ if (this.pc.removeTrack) {
3997
+ stream.getTracks().forEach(track => {
3998
+ const sender = this.pc.getSenders().find(sender => sender.track === track);
3999
+ if (sender) {
4000
+ this.pc.removeTrack(sender);
4001
+ }
4002
+ });
4003
+ } else if (this.pc.removeStream) {
4004
+ this.pc.removeStream(stream);
4005
+ }
4006
+ }
4007
+ }
4129
4008
 
4130
- expectsError.apply(void 0, [throws, getActual(promiseFn)].concat(args));
4131
- };
4009
+ _setRemoteDescription(desc) {
4010
+ // deprioritize H264 Encoding if set by option/flag
4011
+ if (this._deprioritizeH264Encoding) desc.sdp = deprioritizeH264(desc.sdp);
4132
4012
 
4133
- assert.rejects = function rejects(promiseFn) {
4134
- for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
4135
- args[_key3 - 1] = arguments[_key3];
4136
- }
4013
+ // wrapper around SRD which stores a promise
4014
+ this.srdComplete = this.pc.setRemoteDescription(desc);
4015
+ return this.srdComplete.then(() => {
4016
+ this.earlyIceCandidates.forEach(candidate => this.pc.addIceCandidate(candidate));
4017
+ this.earlyIceCandidates = [];
4018
+ });
4019
+ }
4137
4020
 
4138
- return waitForActual(promiseFn).then(function (result) {
4139
- return expectsError.apply(void 0, [rejects, result].concat(args));
4140
- });
4141
- };
4021
+ handleOffer(message) {
4022
+ if (!this.canModifyPeerConnection()) {
4023
+ return new Promise(resolve => {
4024
+ this.pending.push(() => this.handleOffer(message).then(resolve));
4025
+ });
4026
+ }
4027
+ this.isOperationPending = true;
4028
+ let sdp = message.sdp;
4142
4029
 
4143
- assert.doesNotThrow = function doesNotThrow(fn) {
4144
- for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
4145
- args[_key4 - 1] = arguments[_key4];
4146
- }
4030
+ sdp = filterMidExtension(sdp);
4031
+ sdp = filterMsidSemantic(sdp);
4147
4032
 
4148
- expectsNoError.apply(void 0, [doesNotThrow, getActual(fn)].concat(args));
4149
- };
4033
+ const desc = { type: message.type, sdp };
4034
+ // Create an answer to send to the client that sent the offer
4035
+ let answerToSignal;
4150
4036
 
4151
- assert.doesNotReject = function doesNotReject(fn) {
4152
- for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
4153
- args[_key5 - 1] = arguments[_key5];
4154
- }
4037
+ return this._setRemoteDescription(desc)
4038
+ .then(() => {
4039
+ return this.pc.createAnswer();
4040
+ })
4041
+ .then(answer => {
4042
+ answerToSignal = answer;
4043
+ return this.pc.setLocalDescription(answer);
4044
+ })
4045
+ .then(() => {
4046
+ return setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
4047
+ })
4048
+ .then(() => {
4049
+ return answerToSignal;
4050
+ });
4051
+ }
4155
4052
 
4156
- return waitForActual(fn).then(function (result) {
4157
- return expectsNoError.apply(void 0, [doesNotReject, result].concat(args));
4158
- });
4159
- };
4053
+ handleAnswer(message) {
4054
+ // workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=1394602
4055
+ if (this.pendingOffer) {
4056
+ const pendingOffer = this.pendingOffer;
4057
+ delete this.pendingOffer;
4058
+ return this.pc.setLocalDescription(pendingOffer).then(() => this.handleAnswer(message));
4059
+ }
4060
+ let sdp = message.sdp;
4160
4061
 
4161
- assert.ifError = function ifError(err) {
4162
- if (err !== null && err !== undefined) {
4163
- var message = 'ifError got unwanted exception: ';
4062
+ sdp = filterMsidSemantic(sdp);
4164
4063
 
4165
- if (_typeof(err) === 'object' && typeof err.message === 'string') {
4166
- if (err.message.length === 0 && err.constructor) {
4167
- message += err.constructor.name;
4168
- } else {
4169
- message += err.message;
4170
- }
4171
- } else {
4172
- message += inspect(err);
4173
- }
4064
+ const desc = { type: message.type, sdp };
4065
+ return this._setRemoteDescription(desc).then(
4066
+ () => {
4067
+ return setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
4068
+ },
4069
+ e => {
4070
+ logger$3.warn("Could not set remote description from remote answer: ", e);
4071
+ }
4072
+ );
4073
+ }
4174
4074
 
4175
- var newErr = new AssertionError({
4176
- actual: err,
4177
- expected: null,
4178
- operator: 'ifError',
4179
- message: message,
4180
- stackStartFn: ifError
4181
- }); // Make sure we actually have a stack trace!
4075
+ addIceCandidate(candidate) {
4076
+ if (!this.srdComplete) {
4077
+ // In theory this is a protocol violation. However, our Javascript can signal an
4078
+ // answer after the first candidates.
4079
+ this.earlyIceCandidates.push(candidate);
4080
+ return;
4081
+ }
4082
+ this.srdComplete.then(() => {
4083
+ if (this.pc.signalingState === "closed") {
4084
+ return;
4085
+ }
4086
+ if (adapter.browserDetails.browser === "safari" && candidate && candidate.candidate === "") {
4087
+ // filter due to https://github.com/webrtcHacks/adapter/issues/863
4088
+ return;
4089
+ }
4090
+ this.pc.addIceCandidate(candidate).catch(e => {
4091
+ logger$3.warn("Failed to add ICE candidate ('%s'): %s", candidate ? candidate.candidate : null, e);
4092
+ });
4093
+ });
4094
+ }
4182
4095
 
4183
- var origStack = err.stack;
4096
+ canModifyPeerConnection() {
4097
+ return this.pc.signalingState === "stable" && !this.isOperationPending;
4098
+ }
4184
4099
 
4185
- if (typeof origStack === 'string') {
4186
- // This will remove any duplicated frames from the error frames taken
4187
- // from within `ifError` and add the original error frames to the newly
4188
- // created ones.
4189
- var tmp2 = origStack.split('\n');
4190
- tmp2.shift(); // Filter all frames existing in err.stack.
4100
+ close() {
4101
+ const pc = this.pc;
4102
+ if (!pc) {
4103
+ return;
4104
+ }
4191
4105
 
4192
- var tmp1 = newErr.stack.split('\n');
4106
+ pc.oniceconnectionstatechange = null;
4107
+ pc.onicecandidate = null;
4108
+ pc.ontrack = null;
4109
+ try {
4110
+ // do not handle state change events when we close the connection explicitly
4111
+ pc.close();
4112
+ } catch (e) {
4113
+ console.warn("failures during close of session", e);
4114
+ // we're not interested in errors from RTCPeerConnection.close()
4115
+ }
4116
+ }
4193
4117
 
4194
- for (var i = 0; i < tmp2.length; i++) {
4195
- // Find the first occurrence of the frame.
4196
- var pos = tmp1.indexOf(tmp2[i]);
4118
+ hasConnectedPeerConnection() {
4119
+ return this.pc && this.pc.connectionState === "connected";
4120
+ }
4197
4121
 
4198
- if (pos !== -1) {
4199
- // Only keep new frames.
4200
- tmp1 = tmp1.slice(0, pos);
4201
- break;
4202
- }
4203
- }
4122
+ replaceTrack(oldTrack, newTrack) {
4123
+ const pc = this.pc;
4124
+ // This shouldn't really happen
4125
+ if (!pc) return false;
4126
+ const senders = pc.getSenders();
4127
+ function dbg(msg) {
4128
+ const tr = t => t && `id:${t.id},kind:${t.kind},state:${t.readyState}`;
4129
+ logger$3.warn(
4130
+ `${msg}. newTrack:${tr(newTrack)}, oldTrack:${tr(oldTrack)}, sender tracks: ${JSON.stringify(
4131
+ senders.map(s => `s ${tr(s.track)}`)
4132
+ )}, sender first codecs: ${JSON.stringify(senders.map(s => (s.getParameters().codecs || [])[0]))}`
4133
+ );
4134
+ }
4135
+ if (!senders.length) {
4136
+ dbg("No senders!");
4137
+ }
4138
+ // If we didn't specify oldTrack, replace with first of its kind
4139
+ if (!oldTrack) {
4140
+ oldTrack = (senders.find(s => s.track && s.track.kind === newTrack.kind) || {}).track;
4141
+ if (!oldTrack) {
4142
+ // odin: Temporary debug data, remove if you see after 2020-12-01
4143
+ dbg("No sender with same kind! Add new track then.");
4144
+ }
4145
+ }
4146
+ // Modern browsers makes things simple.
4147
+ if (window.RTCRtpSender && window.RTCRtpSender.prototype.replaceTrack) {
4148
+ if (oldTrack) {
4149
+ const process = () => {
4150
+ for (let i = 0; i < senders.length; i++) {
4151
+ const sender = senders[i];
4152
+ const track = sender.track;
4153
+ if (!sender && !track) {
4154
+ // odin: Temporary debug data, remove if you see after 2020-12-01
4155
+ dbg("One of the tracks is null!");
4156
+ }
4157
+ if (track.id === newTrack.id) {
4158
+ return Promise.resolve(newTrack);
4159
+ }
4160
+ if (track.id === oldTrack.id) {
4161
+ return senders[i].replaceTrack(newTrack);
4162
+ }
4163
+ }
4164
+ return null;
4165
+ };
4166
+ let result = process();
4167
+ if (result) {
4168
+ return result;
4169
+ }
4170
+ let resolve = null;
4171
+ let reject = null;
4172
+ result = new Promise((_resolve, _reject) => {
4173
+ resolve = _resolve;
4174
+ reject = _reject;
4175
+ });
4176
+ let retried = 0;
4177
+ let timer = setInterval(async () => {
4178
+ const trackReplacedPromise = process();
4179
+ if (!trackReplacedPromise) {
4180
+ if (3 < ++retried) {
4181
+ clearInterval(timer);
4182
+ timer = null;
4183
+ dbg("No sender track to replace");
4184
+ reject("No sender track to replace");
4185
+ }
4186
+ return;
4187
+ }
4188
+ clearInterval(timer);
4189
+ timer = null;
4190
+ const trackReplaced = await trackReplacedPromise;
4191
+ resolve(trackReplaced);
4192
+ }, 1000);
4193
+ // if we have an oldtrack, we should not go forward, because
4194
+ // we already know that the track has been added at least to the mediastream
4195
+ return result;
4196
+ }
4197
+ const stream = this.streams.find(s => s.getTracks().find(t => t.id === newTrack.id)) || this.streams[0];
4198
+ if (!stream) {
4199
+ dbg("No stream?");
4200
+ return Promise.reject(new Error("replaceTrack: No stream?"));
4201
+ }
4202
+ // Let's just add the track if we couldn't figure out a better way.
4203
+ // We'll get here if you had no camera and plugged one in.
4204
+ return pc.addTrack(newTrack, stream);
4205
+ }
4204
4206
 
4205
- newErr.stack = "".concat(tmp1.join('\n'), "\n").concat(tmp2.join('\n'));
4206
- }
4207
+ if (!this.canModifyPeerConnection()) {
4208
+ this.pending.push(() => {
4209
+ this.replaceTrack(oldTrack, newTrack);
4210
+ });
4211
+ return;
4212
+ }
4213
+ this.isOperationPending = true;
4214
+ const onn = pc.onnegotiationneeded;
4215
+ pc.onnegotiationneeded = null;
4216
+ this.removeTrack(oldTrack);
4217
+ this.addTrack(newTrack);
4218
+ setTimeout(() => {
4219
+ // negotiationneeded is fired async, restore it async.
4220
+ pc.onnegotiationneeded = onn;
4221
+ }, 0);
4207
4222
 
4208
- throw newErr;
4209
- }
4210
- }; // Expose a strict only variant of assert
4223
+ if (pc.localDescription.type === "offer") {
4224
+ return pc
4225
+ .createOffer()
4226
+ .then(offer => {
4227
+ offer.sdp = replaceSSRCs(pc.localDescription.sdp, offer.sdp);
4228
+ return pc.setLocalDescription(offer);
4229
+ })
4230
+ .then(() => {
4231
+ return this._setRemoteDescription(pc.remoteDescription);
4232
+ });
4233
+ } else {
4234
+ return this._setRemoteDescription(pc.remoteDescription)
4235
+ .then(() => {
4236
+ return pc.createAnswer();
4237
+ })
4238
+ .then(answer => {
4239
+ answer.sdp = replaceSSRCs(pc.localDescription.sdp, answer.sdp);
4240
+ return pc.setLocalDescription(answer);
4241
+ });
4242
+ }
4243
+ }
4211
4244
 
4245
+ // Restricts the bandwidth based on whether we are using a relayed connection.
4246
+ // No signaling is required, this is done independently by both sides.
4247
+ // Only applies to unrestricted connections, not affecting the bandwidth tables
4248
+ // that depend on the number of participants.
4249
+ maybeRestrictRelayBandwidth() {
4250
+ if (!this.pc.getStats) {
4251
+ return;
4252
+ }
4253
+ isRelayed(this.pc).then(isRelayed => {
4254
+ if (isRelayed && this.bandwidth === 0) {
4255
+ this.changeBandwidth(this.maximumTurnBandwidth);
4256
+ }
4257
+ });
4258
+ }
4212
4259
 
4213
- function strict() {
4214
- for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
4215
- args[_key6] = arguments[_key6];
4216
- }
4260
+ // no-signaling negotiation of bandwidth. Peer is NOT informed.
4261
+ // Prefers using RTCRtpSender.setParameters if possible.
4262
+ changeBandwidth(bandwidth) {
4263
+ // don't renegotiate if bandwidth is already set.
4264
+ if (bandwidth === this.bandwidth) {
4265
+ return;
4266
+ }
4217
4267
 
4218
- innerOk.apply(void 0, [strict, args.length].concat(args));
4219
- }
4268
+ if (!this.canModifyPeerConnection()) {
4269
+ this.pending.push(() => this.changeBandwidth(bandwidth));
4270
+ return;
4271
+ }
4220
4272
 
4221
- assert.strict = objectAssign(strict, assert, {
4222
- equal: assert.strictEqual,
4223
- deepEqual: assert.deepStrictEqual,
4224
- notEqual: assert.notStrictEqual,
4225
- notDeepEqual: assert.notDeepStrictEqual
4226
- });
4227
- assert.strict.strict = assert.strict;
4228
- return assertExports$1;
4229
- }
4273
+ this.bandwidth = bandwidth;
4274
+ if (!this.pc.localDescription || this.pc.localDescription.type === "") {
4275
+ return;
4276
+ }
4230
4277
 
4231
- var assertExports = requireAssert();
4232
- var assert = /*@__PURE__*/getDefaultExportFromCjs(assertExports);
4278
+ setVideoBandwidthUsingSetParameters(this.pc, this.bandwidth);
4279
+ }
4280
+ }
4233
4281
 
4234
4282
  const MAXIMUM_TURN_BANDWIDTH = 512; // kbps;
4235
4283
  const MAXIMUM_TURN_BANDWIDTH_PREMIUM = 768; // kbps;
@@ -8296,6 +8344,8 @@ class LocalParticipant extends RoomParticipant {
8296
8344
  const API_BASE_URL = process.env["REACT_APP_API_BASE_URL"] || "https://api.whereby.dev";
8297
8345
  const SIGNAL_BASE_URL = process.env["REACT_APP_SIGNAL_BASE_URL"] || "wss://signal.appearin.net";
8298
8346
  const NON_PERSON_ROLES = ["recorder", "streamer"];
8347
+ // cache last reported stream resolutions
8348
+ const reportedStreamResolutions = new Map();
8299
8349
  function createSocket() {
8300
8350
  const parsedUrl = new URL(SIGNAL_BASE_URL);
8301
8351
  const path = `${parsedUrl.pathname.replace(/^\/$/, "")}/protocol/socket.io/v4`;
@@ -8834,6 +8884,21 @@ class RoomConnection extends TypedEventTarget {
8834
8884
  response: {},
8835
8885
  });
8836
8886
  }
8887
+ updateStreamResolution({ streamId, width, height }) {
8888
+ var _a, _b;
8889
+ if (!streamId || !this.rtcManager) {
8890
+ return;
8891
+ }
8892
+ // no need to report resolution for local participant
8893
+ if (((_b = (_a = this.localParticipant) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.id) === streamId) {
8894
+ return;
8895
+ }
8896
+ const old = reportedStreamResolutions.get(streamId);
8897
+ if (!old || old.width !== width || old.height !== height) {
8898
+ this.rtcManager.updateStreamResolution(streamId, null, { width: width || 1, height: height || 1 });
8899
+ }
8900
+ reportedStreamResolutions.set(streamId, { width, height });
8901
+ }
8837
8902
  }
8838
8903
 
8839
8904
  const initialState = {
@@ -9050,12 +9115,20 @@ function useRoomConnection(roomUrl, roomConnectionOptions) {
9050
9115
  },
9051
9116
  },
9052
9117
  components: {
9053
- VideoView,
9118
+ VideoView: (props) => React.createElement(VideoView, Object.assign({}, props, {
9119
+ onResize: ({ stream, width, height, }) => {
9120
+ roomConnection.updateStreamResolution({
9121
+ streamId: stream.id,
9122
+ width,
9123
+ height,
9124
+ });
9125
+ },
9126
+ })),
9054
9127
  },
9055
9128
  _ref: roomConnection,
9056
9129
  };
9057
9130
  }
9058
9131
 
9059
- const sdkVersion = "2.0.0-alpha17";
9132
+ const sdkVersion = "2.0.0-alpha18";
9060
9133
 
9061
9134
  export { VideoView, sdkVersion, useLocalMedia, useRoomConnection };