vroom-web-sdk-beta
Version:
VROOM SDK (beta) by True Virtual World
1,540 lines (1,423 loc) • 152 kB
JavaScript
import { get, concat, isEmpty, flatten, findIndex } from 'lodash';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function(d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
}
/**
* @name sdkVersion
* @constant
* @type {string}
* @default
*/
var sdkVersion = '1.0.0';
/**
* @name sdkServer
* @constant
* @type {string}
* @default
* // wss://lb-janus-api-ts.truevirtualworld.com/vro/ws
* // wss://multistream-poc.truevirtualworld.com/ws1
*/
var sdkServer = 'wss://multistream-poc.truevirtualworld.com/ws1';
/**
* @name iceServer
* @constant
* @type {Array}
* @default
*/
var iceServer = [{ urls: 'stun:stun.l.google.com:19302' }];
/**
* @name sdkProtocol
* @constant
* @type {string}
* @default
*/
var sdkProtocol = 'janus-protocol';
/**
* @name WS_EVENT
* @constant
*/
var WS_EVENT = {
OPEN: 'open',
MESSAGE: 'message',
CLOSE: 'close',
ERROR: 'error',
};
/**
* @name STATUS
* @constant
*/
var STATUS = {
SUCCESS: 'success',
ACK: 'ack',
};
/**
* @name VROOM_COMMAND_STATUS
* @constant
*/
var VROOM_COMMAND_STATUS = {
SUCCESS: 'success',
ACK: 'ack',
TRICKLE: 'trickle',
EVENT: 'event',
MUTE_AUDIO: 'mute_audio',
MUTE_VIDEO: 'mute_video',
S_JOIN: 's-joined'
};
/**
* @name VROOM_PLUGIN_TYPE
* @constant
*/
var VROOM_PLUGIN_TYPE = {
EVENT: 'event',
MUTE_AUDIO: 'mute_audio',
MUTE_VIDEO: 'mute_video',
S_JOIN: 's-joined',
LEAVING: 'leaving',
UPDATED: 'updated',
UNKNOW: 'unknown'
};
/**
* @name VROOM_COMMAND
* @constant
*/
var VROOM_COMMAND = {
CREATE: 'create'
};
/**
* @name TRANSACTION_TYPE
* @constant
*/
var TRANSACTION_TYPE = {
SEND_CREATE: 'send-create'
};
/**
* @name keepAlivePeriod
* @constant
* @type {number}
*/
var keepAlivePeriod = 25000;
/**
* @name extensionId
* @constant
* @type {string}
* @default
*/
var extensionId = 'hapfgfdkleiggjjpfpenajgdnfckjpaj';
/**
* @name VROOM_COMMAND_STATUS
* @constant
*/
var VROOM_SDK_EVENT = {
BEFORE_CREATE: 'before_create',
CREATED: 'created',
AFTER_CREATE: 'after_create',
MUTE_AUDIO: 'mute_audio',
MUTE_VIDEO: 'mute_video',
JOIN: 'join',
INIT_SUB: 'init_sub',
UPDATE_SUB: 'update_sub',
UPDATE_TRACK: 'update-track',
LEAVE: 'leave',
MONITOR: 'monitor_update',
UPDATE_SUB_MEDIA_LIST: 'update_sub_media_list',
UPDATE_ATTENDEE: 'attendee_update',
JOIN_FAILURE: 'join_failure',
AFTER_HANGUP: 'AFTER_HANGUP',
LOCAL_STREAM_UPDATE: 'LOCAL_STREAM_UPDATE',
RECEIVED_PUBLISHER: 'RECEIVED_PUBLISHER',
};
/**
* @name MEDIA_TYPE
* @constant
*/
var MEDIA_TYPE = {
VIDEO: 'video',
AUDIO: 'audio',
};
/**
* @name BITRATE
*/
var BITRATE = 400000;
var events = {exports: {}};
var R = typeof Reflect === 'object' ? Reflect : null;
var ReflectApply = R && typeof R.apply === 'function'
? R.apply
: function ReflectApply(target, receiver, args) {
return Function.prototype.apply.call(target, receiver, args);
};
var ReflectOwnKeys;
if (R && typeof R.ownKeys === 'function') {
ReflectOwnKeys = R.ownKeys;
} else if (Object.getOwnPropertySymbols) {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target)
.concat(Object.getOwnPropertySymbols(target));
};
} else {
ReflectOwnKeys = function ReflectOwnKeys(target) {
return Object.getOwnPropertyNames(target);
};
}
function ProcessEmitWarning(warning) {
if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
return value !== value;
};
function EventEmitter() {
EventEmitter.init.call(this);
}
events.exports = EventEmitter;
events.exports.once = once;
// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;
// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
if (typeof listener !== 'function') {
throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
}
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
enumerable: true,
get: function() {
return defaultMaxListeners;
},
set: function(arg) {
if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
}
defaultMaxListeners = arg;
}
});
EventEmitter.init = function() {
if (this._events === undefined ||
this._events === Object.getPrototypeOf(this)._events) {
this._events = Object.create(null);
this._eventsCount = 0;
}
this._maxListeners = this._maxListeners || undefined;
};
// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
}
this._maxListeners = n;
return this;
};
function _getMaxListeners(that) {
if (that._maxListeners === undefined)
return EventEmitter.defaultMaxListeners;
return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
var args = [];
for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
var doError = (type === 'error');
var events = this._events;
if (events !== undefined)
doError = (doError && events.error === undefined);
else if (!doError)
return false;
// If there is no 'error' event listener then throw.
if (doError) {
var er;
if (args.length > 0)
er = args[0];
if (er instanceof Error) {
// Note: The comments on the `throw` lines are intentional, they show
// up in Node's output if this results in an unhandled exception.
throw er; // Unhandled 'error' event
}
// At least give some kind of context to the user
var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
err.context = er;
throw err; // Unhandled 'error' event
}
var handler = events[type];
if (handler === undefined)
return false;
if (typeof handler === 'function') {
ReflectApply(handler, this, args);
} else {
var len = handler.length;
var listeners = arrayClone(handler, len);
for (var i = 0; i < len; ++i)
ReflectApply(listeners[i], this, args);
}
return true;
};
function _addListener(target, type, listener, prepend) {
var m;
var events;
var existing;
checkListener(listener);
events = target._events;
if (events === undefined) {
events = target._events = Object.create(null);
target._eventsCount = 0;
} else {
// To avoid recursion in the case that type === "newListener"! Before
// adding it to the listeners, first emit "newListener".
if (events.newListener !== undefined) {
target.emit('newListener', type,
listener.listener ? listener.listener : listener);
// Re-assign `events` because a newListener handler could have caused the
// this._events to be assigned to a new object
events = target._events;
}
existing = events[type];
}
if (existing === undefined) {
// Optimize the case of one listener. Don't need the extra array object.
existing = events[type] = listener;
++target._eventsCount;
} else {
if (typeof existing === 'function') {
// Adding the second element, need to change to array.
existing = events[type] =
prepend ? [listener, existing] : [existing, listener];
// If we've already got an array, just append.
} else if (prepend) {
existing.unshift(listener);
} else {
existing.push(listener);
}
// Check for listener leak
m = _getMaxListeners(target);
if (m > 0 && existing.length > m && !existing.warned) {
existing.warned = true;
// No error code for this since it is a Warning
// eslint-disable-next-line no-restricted-syntax
var w = new Error('Possible EventEmitter memory leak detected. ' +
existing.length + ' ' + String(type) + ' listeners ' +
'added. Use emitter.setMaxListeners() to ' +
'increase limit');
w.name = 'MaxListenersExceededWarning';
w.emitter = target;
w.type = type;
w.count = existing.length;
ProcessEmitWarning(w);
}
}
return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener =
function prependListener(type, listener) {
return _addListener(this, type, listener, true);
};
function onceWrapper() {
if (!this.fired) {
this.target.removeListener(this.type, this.wrapFn);
this.fired = true;
if (arguments.length === 0)
return this.listener.call(this.target);
return this.listener.apply(this.target, arguments);
}
}
function _onceWrap(target, type, listener) {
var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener };
var wrapped = onceWrapper.bind(state);
wrapped.listener = listener;
state.wrapFn = wrapped;
return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
checkListener(listener);
this.on(type, _onceWrap(this, type, listener));
return this;
};
EventEmitter.prototype.prependOnceListener =
function prependOnceListener(type, listener) {
checkListener(listener);
this.prependListener(type, _onceWrap(this, type, listener));
return this;
};
// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener =
function removeListener(type, listener) {
var list, events, position, i, originalListener;
checkListener(listener);
events = this._events;
if (events === undefined)
return this;
list = events[type];
if (list === undefined)
return this;
if (list === listener || list.listener === listener) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else {
delete events[type];
if (events.removeListener)
this.emit('removeListener', type, list.listener || listener);
}
} else if (typeof list !== 'function') {
position = -1;
for (i = list.length - 1; i >= 0; i--) {
if (list[i] === listener || list[i].listener === listener) {
originalListener = list[i].listener;
position = i;
break;
}
}
if (position < 0)
return this;
if (position === 0)
list.shift();
else {
spliceOne(list, position);
}
if (list.length === 1)
events[type] = list[0];
if (events.removeListener !== undefined)
this.emit('removeListener', type, originalListener || listener);
}
return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners =
function removeAllListeners(type) {
var listeners, events, i;
events = this._events;
if (events === undefined)
return this;
// not listening for removeListener, no need to emit
if (events.removeListener === undefined) {
if (arguments.length === 0) {
this._events = Object.create(null);
this._eventsCount = 0;
} else if (events[type] !== undefined) {
if (--this._eventsCount === 0)
this._events = Object.create(null);
else
delete events[type];
}
return this;
}
// emit removeListener for all listeners on all events
if (arguments.length === 0) {
var keys = Object.keys(events);
var key;
for (i = 0; i < keys.length; ++i) {
key = keys[i];
if (key === 'removeListener') continue;
this.removeAllListeners(key);
}
this.removeAllListeners('removeListener');
this._events = Object.create(null);
this._eventsCount = 0;
return this;
}
listeners = events[type];
if (typeof listeners === 'function') {
this.removeListener(type, listeners);
} else if (listeners !== undefined) {
// LIFO order
for (i = listeners.length - 1; i >= 0; i--) {
this.removeListener(type, listeners[i]);
}
}
return this;
};
function _listeners(target, type, unwrap) {
var events = target._events;
if (events === undefined)
return [];
var evlistener = events[type];
if (evlistener === undefined)
return [];
if (typeof evlistener === 'function')
return unwrap ? [evlistener.listener || evlistener] : [evlistener];
return unwrap ?
unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
return _listeners(this, type, false);
};
EventEmitter.listenerCount = function(emitter, type) {
if (typeof emitter.listenerCount === 'function') {
return emitter.listenerCount(type);
} else {
return listenerCount.call(emitter, type);
}
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
var events = this._events;
if (events !== undefined) {
var evlistener = events[type];
if (typeof evlistener === 'function') {
return 1;
} else if (evlistener !== undefined) {
return evlistener.length;
}
}
return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
var copy = new Array(n);
for (var i = 0; i < n; ++i)
copy[i] = arr[i];
return copy;
}
function spliceOne(list, index) {
for (; index + 1 < list.length; index++)
list[index] = list[index + 1];
list.pop();
}
function unwrapListeners(arr) {
var ret = new Array(arr.length);
for (var i = 0; i < ret.length; ++i) {
ret[i] = arr[i].listener || arr[i];
}
return ret;
}
function once(emitter, name) {
return new Promise(function (resolve, reject) {
function errorListener(err) {
emitter.removeListener(name, resolver);
reject(err);
}
function resolver() {
if (typeof emitter.removeListener === 'function') {
emitter.removeListener('error', errorListener);
}
resolve([].slice.call(arguments));
}
eventTargetAgnosticAddListener(emitter, name, resolver, { once: true });
if (name !== 'error') {
addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true });
}
});
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
if (typeof emitter.on === 'function') {
eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
}
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
if (typeof emitter.on === 'function') {
if (flags.once) {
emitter.once(name, listener);
} else {
emitter.on(name, listener);
}
} else if (typeof emitter.addEventListener === 'function') {
// EventTarget does not have `error` event semantics like Node
// EventEmitters, we do not listen for `error` events here.
emitter.addEventListener(name, function wrapListener(arg) {
// IE does not have builtin `{ once: true }` support so we
// have to do it manually.
if (flags.once) {
emitter.removeEventListener(name, wrapListener);
}
listener(arg);
});
} else {
throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
}
}
var EventEmitter$1 = events.exports;
/**
* Utility function that works like `Object.apply`, but copies getters and setters properly as well. Additionally gives
* the option to exclude properties by name.
*/
const copyProps = (dest, src, exclude = []) => {
const props = Object.getOwnPropertyDescriptors(src);
for (let prop of exclude)
delete props[prop];
Object.defineProperties(dest, props);
};
/**
* Returns the full chain of prototypes up until Object.prototype given a starting object. The order of prototypes will
* be closest to farthest in the chain.
*/
const protoChain = (obj, currentChain = [obj]) => {
const proto = Object.getPrototypeOf(obj);
if (proto === null)
return currentChain;
return protoChain(proto, [...currentChain, proto]);
};
/**
* Identifies the nearest ancestor common to all the given objects in their prototype chains. For most unrelated
* objects, this function should return Object.prototype.
*/
const nearestCommonProto = (...objs) => {
if (objs.length === 0)
return undefined;
let commonProto = undefined;
const protoChains = objs.map(obj => protoChain(obj));
while (protoChains.every(protoChain => protoChain.length > 0)) {
const protos = protoChains.map(protoChain => protoChain.pop());
const potentialCommonProto = protos[0];
if (protos.every(proto => proto === potentialCommonProto))
commonProto = potentialCommonProto;
else
break;
}
return commonProto;
};
/**
* Creates a new prototype object that is a mixture of the given prototypes. The mixing is achieved by first
* identifying the nearest common ancestor and using it as the prototype for a new object. Then all properties/methods
* downstream of this prototype (ONLY downstream) are copied into the new object.
*
* The resulting prototype is more performant than softMixProtos(...), as well as ES5 compatible. However, it's not as
* flexible as updates to the source prototypes aren't captured by the mixed result. See softMixProtos for why you may
* want to use that instead.
*/
const hardMixProtos = (ingredients, constructor, exclude = []) => {
var _a;
const base = (_a = nearestCommonProto(...ingredients)) !== null && _a !== void 0 ? _a : Object.prototype;
const mixedProto = Object.create(base);
// Keeps track of prototypes we've already visited to avoid copying the same properties multiple times. We init the
// list with the proto chain below the nearest common ancestor because we don't want any of those methods mixed in
// when they will already be accessible via prototype access.
const visitedProtos = protoChain(base);
for (let prototype of ingredients) {
let protos = protoChain(prototype);
// Apply the prototype chain in reverse order so that old methods don't override newer ones.
for (let i = protos.length - 1; i >= 0; i--) {
let newProto = protos[i];
if (visitedProtos.indexOf(newProto) === -1) {
copyProps(mixedProto, newProto, ['constructor', ...exclude]);
visitedProtos.push(newProto);
}
}
}
mixedProto.constructor = constructor;
return mixedProto;
};
const unique = (arr) => arr.filter((e, i) => arr.indexOf(e) == i);
// Keeps track of constituent classes for every mixin class created by ts-mixer.
const mixins = new Map();
const getMixinsForClass = (clazz) => mixins.get(clazz);
const registerMixins = (mixedClass, constituents) => mixins.set(mixedClass, constituents);
const mergeObjectsOfDecorators = (o1, o2) => {
var _a, _b;
const allKeys = unique([...Object.getOwnPropertyNames(o1), ...Object.getOwnPropertyNames(o2)]);
const mergedObject = {};
for (let key of allKeys)
mergedObject[key] = unique([...((_a = o1 === null || o1 === void 0 ? void 0 : o1[key]) !== null && _a !== void 0 ? _a : []), ...((_b = o2 === null || o2 === void 0 ? void 0 : o2[key]) !== null && _b !== void 0 ? _b : [])]);
return mergedObject;
};
const mergePropertyAndMethodDecorators = (d1, d2) => {
var _a, _b, _c, _d;
return ({
property: mergeObjectsOfDecorators((_a = d1 === null || d1 === void 0 ? void 0 : d1.property) !== null && _a !== void 0 ? _a : {}, (_b = d2 === null || d2 === void 0 ? void 0 : d2.property) !== null && _b !== void 0 ? _b : {}),
method: mergeObjectsOfDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.method) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.method) !== null && _d !== void 0 ? _d : {}),
});
};
const mergeDecorators = (d1, d2) => {
var _a, _b, _c, _d, _e, _f;
return ({
class: unique([...(_a = d1 === null || d1 === void 0 ? void 0 : d1.class) !== null && _a !== void 0 ? _a : [], ...(_b = d2 === null || d2 === void 0 ? void 0 : d2.class) !== null && _b !== void 0 ? _b : []]),
static: mergePropertyAndMethodDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.static) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.static) !== null && _d !== void 0 ? _d : {}),
instance: mergePropertyAndMethodDecorators((_e = d1 === null || d1 === void 0 ? void 0 : d1.instance) !== null && _e !== void 0 ? _e : {}, (_f = d2 === null || d2 === void 0 ? void 0 : d2.instance) !== null && _f !== void 0 ? _f : {}),
});
};
const decorators = new Map();
const findAllConstituentClasses = (...classes) => {
var _a;
const allClasses = new Set();
const frontier = new Set([...classes]);
while (frontier.size > 0) {
for (let clazz of frontier) {
const protoChainClasses = protoChain(clazz.prototype).map(proto => proto.constructor);
const mixinClasses = (_a = getMixinsForClass(clazz)) !== null && _a !== void 0 ? _a : [];
const potentiallyNewClasses = [...protoChainClasses, ...mixinClasses];
const newClasses = potentiallyNewClasses.filter(c => !allClasses.has(c));
for (let newClass of newClasses)
frontier.add(newClass);
allClasses.add(clazz);
frontier.delete(clazz);
}
}
return [...allClasses];
};
const deepDecoratorSearch = (...classes) => {
const decoratorsForClassChain = findAllConstituentClasses(...classes)
.map(clazz => decorators.get(clazz))
.filter(decorators => !!decorators);
if (decoratorsForClassChain.length == 0)
return {};
if (decoratorsForClassChain.length == 1)
return decoratorsForClassChain[0];
return decoratorsForClassChain.reduce((d1, d2) => mergeDecorators(d1, d2));
};
function Mixin(...constructors) {
var _a, _b, _c;
const prototypes = constructors.map(constructor => constructor.prototype);
function MixedClass(...args) {
for (const constructor of constructors)
// @ts-ignore: potentially abstract class
copyProps(this, new constructor(...args));
}
MixedClass.prototype = hardMixProtos(prototypes, MixedClass)
;
Object.setPrototypeOf(MixedClass, hardMixProtos(constructors, null, ['prototype'])
);
let DecoratedMixedClass = MixedClass;
{
const classDecorators = deepDecoratorSearch(...constructors)
;
for (let decorator of (_a = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.class) !== null && _a !== void 0 ? _a : []) {
const result = decorator(DecoratedMixedClass);
if (result) {
DecoratedMixedClass = result;
}
}
applyPropAndMethodDecorators((_b = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.static) !== null && _b !== void 0 ? _b : {}, DecoratedMixedClass);
applyPropAndMethodDecorators((_c = classDecorators === null || classDecorators === void 0 ? void 0 : classDecorators.instance) !== null && _c !== void 0 ? _c : {}, DecoratedMixedClass.prototype);
}
registerMixins(DecoratedMixedClass, constructors);
return DecoratedMixedClass;
}
const applyPropAndMethodDecorators = (propAndMethodDecorators, target) => {
const propDecorators = propAndMethodDecorators.property;
const methodDecorators = propAndMethodDecorators.method;
if (propDecorators)
for (let key in propDecorators)
for (let decorator of propDecorators[key])
decorator(target, key);
if (methodDecorators)
for (let key in methodDecorators)
for (let decorator of methodDecorators[key])
decorator(target, key, Object.getOwnPropertyDescriptor(target, key));
};
/**
* @name invalidToken
* @constant
* @type {string}
* @default
*/
var invalidToken = 'Invalid token. Let\'s see https://developer.truevirtualworld.com/token';
/**
* @name invalidRoomId
* @constant
* @type {string}
* @default
*/
var invalidRoomId = 'Room not found. Let\'s see https://developer.truevirtualworld.com/room-id-format';
/**
* @name invalidDisplayName
* @constant
* @type {string}
* @default
*/
var invalidDisplayName = 'DisplayName is required. Let\'s see https://developer.truevirtualworld.com/participants';
/**
* @name connectionError
* @constant
* @type {string}
* @default
*/
var connectionError = 'connection error. Let\'s see https://developer.truevirtualworld.com/support';
var errorMessage = {
invalidToken: invalidToken,
invalidRoomId: invalidRoomId,
invalidDisplayName: invalidDisplayName,
connectionError: connectionError
};
var configValidation = function (config) {
var errorMsg = [];
if (!config.token)
errorMsg.push(errorMessage.invalidToken);
if (!config.displayName)
errorMsg.push(errorMessage.invalidDisplayName);
return errorMsg;
};
function getRoomFromUrlHelper(url) {
var match = url.indexOf('?') > -1 ? url.match(/\/(\d+)\?/) : url.split('https://')[1].split('/');
if (match) {
return +match[1];
}
else {
return null;
}
}
var ConfigurationBase = /** @class */ (function () {
function ConfigurationBase(config) {
this.config = __assign({}, config);
var hasError = configValidation(this.config);
if (hasError.length > 0) {
throw new Error(hasError[0]);
}
this.version = sdkVersion;
this.roomId = getRoomFromUrlHelper(this.config.endpoint) || 0;
this.displayName = config.displayName;
this.opaqueId = 'opaqueId-' + (Math.random() + 1).toString(36).substring(7);
}
return ConfigurationBase;
}());
var HelperFunction = /** @class */ (function () {
function HelperFunction() {
}
HelperFunction.prototype.randomString = function (len) {
var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.charAt(randomPoz);
}
return randomString;
};
HelperFunction.prototype.getRoomIdFromUrl = function (url) {
var match = url.indexOf('?') > -1 ? url.match(/\/(\d+)\?/) : url.split('https://')[1].split('/');
if (match) {
return +match[1];
}
else {
return null;
}
};
return HelperFunction;
}());
var SdkBase = /** @class */ (function (_super) {
__extends(SdkBase, _super);
function SdkBase(config) {
var _this = _super.call(this, config) || this;
_this.canJoin = false;
_this.streams = [];
_this.joined = false;
_this.attendees = [];
_this.roomId = 0;
_this.mapTransactions = new Map();
return _this;
}
SdkBase.prototype.joinStart = function (pub, sub, stream, audio, video, canJoin, config) {
return __awaiter(this, void 0, void 0, function () {
var roomId;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!canJoin)
return [2 /*return*/];
if (this.joined)
return [2 /*return*/];
pub.opaqueId = 'pub-' + this.opaqueId;
sub.opaqueId = 'sub-' + this.opaqueId;
return [4 /*yield*/, pub.attachPlugin()];
case 1:
_a.sent();
return [4 /*yield*/, sub.attachPlugin()];
case 2:
_a.sent();
roomId = this.getRoomIdFromUrl(config.endpoint);
if (!(roomId && config.displayName)) return [3 /*break*/, 4];
this.joined = true;
return [4 /*yield*/, pub.joinRoom(stream, roomId, config.displayName, !audio, !video)];
case 3: return [2 /*return*/, _a.sent()];
case 4: return [2 /*return*/];
}
});
});
};
SdkBase.prototype.receivePublisher = function (sub, publisher, privateId) {
return __awaiter(this, void 0, void 0, function () {
var e_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_a.trys.push([0, 2, , 3]);
return [4 /*yield*/, (sub === null || sub === void 0 ? void 0 : sub.receive(publisher, privateId))];
case 1:
_a.sent();
return [3 /*break*/, 3];
case 2:
e_1 = _a.sent();
console.error(e_1);
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
return SdkBase;
}(Mixin(EventEmitter$1, ConfigurationBase, HelperFunction)));
var Configs = {
// loadBalanceUrl: 'https://lb-janus-api-ts.truevirtualworld.com/api/v1/meeting/join',
// basicAuthLoadBalancer: 'Basic dnJvb20tY29uZmVyZW5jZTpzbXVeel07Yj99dzY+Rzh0'
loadBalanceUrl: 'https://newvroom-controller-api-sdk.truevirtualworld.com/api/v1/meeting/join',
basicAuthLoadBalancer: 'Basic dnJvb20tbGI6JnE1TjdAdG0leE1Kai9SSA=='
};
function handleCloseWs() {
console.log('WS on close');
}
function handleErrorWs() {
console.error('WS on error');
}
var wsEventFn = {
handleCloseWs: handleCloseWs,
handleErrorWs: handleErrorWs,
};
var randomString = function (len) {
var charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var randomString = '';
for (var i = 0; i < len; i++) {
var randomPoz = Math.floor(Math.random() * charSet.length);
randomString += charSet.charAt(randomPoz);
}
return randomString;
};
var TransactionEnum;
(function (TransactionEnum) {
TransactionEnum["create"] = "send-create";
TransactionEnum["attach"] = "send-attach-plugin";
})(TransactionEnum || (TransactionEnum = {}));
var BaseTransaction = /** @class */ (function () {
function BaseTransaction() {
}
return BaseTransaction;
}());
/** @class */ ((function (_super) {
__extends(CreateSession, _super);
function CreateSession() {
var _this = _super.call(this) || this;
_this.janus = 'create';
return _this;
}
return CreateSession;
})(BaseTransaction));
var DestroySession = /** @class */ (function (_super) {
__extends(DestroySession, _super);
function DestroySession(_a) {
var session_id = _a.session_id;
var _this = _super.call(this) || this;
_this.janus = 'destroy';
_this.session_id = session_id;
return _this;
}
return DestroySession;
}(BaseTransaction));
var AttachPluginMessage = /** @class */ (function (_super) {
__extends(AttachPluginMessage, _super);
function AttachPluginMessage(_a) {
var session_id = _a.session_id, opaque = _a.opaque;
var _this = _super.call(this) || this;
_this.janus = 'attach';
_this.plugin = 'janus.plugin.videoroom';
_this.opaque_id = opaque;
_this.session_id = session_id;
return _this;
}
return AttachPluginMessage;
}(BaseTransaction));
var TrickleMessage = /** @class */ (function (_super) {
__extends(TrickleMessage, _super);
function TrickleMessage(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, candidate = _a.candidate;
var _this = _super.call(this) || this;
_this.janus = 'trickle';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.candidate = candidate;
return _this;
}
return TrickleMessage;
}(BaseTransaction));
var StartRoomMessage = /** @class */ (function (_super) {
__extends(StartRoomMessage, _super);
function StartRoomMessage(data) {
var _this = _super.call(this) || this;
_this.janus = 'message';
var session_id = data.session_id, handle_id = data.handle_id, room = data.room, jsep = data.jsep;
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = {
request: 'start',
room: room
};
_this.jsep = jsep;
return _this;
}
return StartRoomMessage;
}(BaseTransaction));
var DetachPluginMessage = /** @class */ (function (_super) {
__extends(DetachPluginMessage, _super);
function DetachPluginMessage(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id;
var _this = _super.call(this) || this;
_this.janus = 'detach';
_this.session_id = session_id;
_this.handle_id = handle_id;
return _this;
}
return DetachPluginMessage;
}(BaseTransaction));
var JoinRoomAsPublisher = /** @class */ (function (_super) {
__extends(JoinRoomAsPublisher, _super);
function JoinRoomAsPublisher(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, room = _a.room, display = _a.display, audio = _a.audio, video = _a.video;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = {
request: 'join',
ptype: 'publisher',
room: room,
display: display,
mute_audio: audio,
mute_video: video,
//access_token:
};
return _this;
}
return JoinRoomAsPublisher;
}(BaseTransaction));
var JoinRoomAsSubscriber = /** @class */ (function (_super) {
__extends(JoinRoomAsSubscriber, _super);
function JoinRoomAsSubscriber(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, room = _a.room, streams = _a.streams, private_id = _a.private_id;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = {
request: 'join',
ptype: 'subscriber',
room: room,
streams: streams,
private_id: private_id
};
return _this;
}
return JoinRoomAsSubscriber;
}(BaseTransaction));
var UpdateSubscriber = /** @class */ (function (_super) {
__extends(UpdateSubscriber, _super);
function UpdateSubscriber(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, body = _a.body;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = body;
return _this;
}
return UpdateSubscriber;
}(BaseTransaction));
var HeartBeat = /** @class */ (function (_super) {
__extends(HeartBeat, _super);
function HeartBeat(_a) {
var session_id = _a.session_id;
var _this = _super.call(this) || this;
_this.janus = 'keepalive';
_this.session_id = session_id;
return _this;
}
return HeartBeat;
}(BaseTransaction));
var SendOffer = /** @class */ (function (_super) {
__extends(SendOffer, _super);
function SendOffer(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, body = _a.body, jsep = _a.jsep;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = body;
_this.jsep = jsep;
return _this;
}
return SendOffer;
}(BaseTransaction));
var MuteAudio = /** @class */ (function (_super) {
__extends(MuteAudio, _super);
function MuteAudio(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, mute = _a.mute, room = _a.room, id = _a.id;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = {
request: 'mute_audio',
mute_audio: mute,
room: room,
id: id
};
return _this;
}
return MuteAudio;
}(BaseTransaction));
var MuteVideo = /** @class */ (function (_super) {
__extends(MuteVideo, _super);
function MuteVideo(_a) {
var session_id = _a.session_id, handle_id = _a.handle_id, mute = _a.mute, room = _a.room, id = _a.id;
var _this = _super.call(this) || this;
_this.janus = 'message';
_this.session_id = session_id;
_this.handle_id = handle_id;
_this.body = {
request: 'mute_video',
mute_video: mute,
room: room,
id: id
};
return _this;
}
return MuteVideo;
}(BaseTransaction));
// NOTE: this list must be up-to-date with browsers listed in
// test/acceptance/useragentstrings.yml
const BROWSER_ALIASES_MAP = {
'Amazon Silk': 'amazon_silk',
'Android Browser': 'android',
Bada: 'bada',
BlackBerry: 'blackberry',
Chrome: 'chrome',
Chromium: 'chromium',
Electron: 'electron',
Epiphany: 'epiphany',
Firefox: 'firefox',
Focus: 'focus',
Generic: 'generic',
'Google Search': 'google_search',
Googlebot: 'googlebot',
'Internet Explorer': 'ie',
'K-Meleon': 'k_meleon',
Maxthon: 'maxthon',
'Microsoft Edge': 'edge',
'MZ Browser': 'mz',
'NAVER Whale Browser': 'naver',
Opera: 'opera',
'Opera Coast': 'opera_coast',
PhantomJS: 'phantomjs',
Puffin: 'puffin',
QupZilla: 'qupzilla',
QQ: 'qq',
QQLite: 'qqlite',
Safari: 'safari',
Sailfish: 'sailfish',
'Samsung Internet for Android': 'samsung_internet',
SeaMonkey: 'seamonkey',
Sleipnir: 'sleipnir',
Swing: 'swing',
Tizen: 'tizen',
'UC Browser': 'uc',
Vivaldi: 'vivaldi',
'WebOS Browser': 'webos',
WeChat: 'wechat',
'Yandex Browser': 'yandex',
Roku: 'roku',
};
const BROWSER_MAP = {
amazon_silk: 'Amazon Silk',
android: 'Android Browser',
bada: 'Bada',
blackberry: 'BlackBerry',
chrome: 'Chrome',
chromium: 'Chromium',
electron: 'Electron',
epiphany: 'Epiphany',
firefox: 'Firefox',
focus: 'Focus',
generic: 'Generic',
googlebot: 'Googlebot',
google_search: 'Google Search',
ie: 'Internet Explorer',
k_meleon: 'K-Meleon',
maxthon: 'Maxthon',
edge: 'Microsoft Edge',
mz: 'MZ Browser',
naver: 'NAVER Whale Browser',
opera: 'Opera',
opera_coast: 'Opera Coast',
phantomjs: 'PhantomJS',
puffin: 'Puffin',
qupzilla: 'QupZilla',
qq: 'QQ Browser',
qqlite: 'QQ Browser Lite',
safari: 'Safari',
sailfish: 'Sailfish',
samsung_internet: 'Samsung Internet for Android',
seamonkey: 'SeaMonkey',
sleipnir: 'Sleipnir',
swing: 'Swing',
tizen: 'Tizen',
uc: 'UC Browser',
vivaldi: 'Vivaldi',
webos: 'WebOS Browser',
wechat: 'WeChat',
yandex: 'Yandex Browser',
};
const PLATFORMS_MAP = {
tablet: 'tablet',
mobile: 'mobile',
desktop: 'desktop',
tv: 'tv',
};
const OS_MAP = {
WindowsPhone: 'Windows Phone',
Windows: 'Windows',
MacOS: 'macOS',
iOS: 'iOS',
Android: 'Android',
WebOS: 'WebOS',
BlackBerry: 'BlackBerry',
Bada: 'Bada',
Tizen: 'Tizen',
Linux: 'Linux',
ChromeOS: 'Chrome OS',
PlayStation4: 'PlayStation 4',
Roku: 'Roku',
};
const ENGINE_MAP = {
EdgeHTML: 'EdgeHTML',
Blink: 'Blink',
Trident: 'Trident',
Presto: 'Presto',
Gecko: 'Gecko',
WebKit: 'WebKit',
};
class Utils {
/**
* Get first matched item for a string
* @param {RegExp} regexp
* @param {String} ua
* @return {Array|{index: number, input: string}|*|boolean|string}
*/
static getFirstMatch(regexp, ua) {
const match = ua.match(regexp);
return (match && match.length > 0 && match[1]) || '';
}
/**
* Get second matched item for a string
* @param regexp
* @param {String} ua
* @return {Array|{index: number, input: string}|*|boolean|string}
*/
static getSecondMatch(regexp, ua) {
const match = ua.match(regexp);
return (match && match.length > 1 && match[2]) || '';
}
/**
* Match a regexp and return a constant or undefined
* @param {RegExp} regexp
* @param {String} ua
* @param {*} _const Any const that will be returned if regexp matches the string
* @return {*}
*/
static matchAndReturnConst(regexp, ua, _const) {
if (regexp.test(ua)) {
return _const;
}
return void (0);
}
static getWindowsVersionName(version) {
switch (version) {
case 'NT': return 'NT';
case 'XP': return 'XP';
case 'NT 5.0': return '2000';
case 'NT 5.1': return 'XP';
case 'NT 5.2': return '2003';
case 'NT 6.0': return 'Vista';
case 'NT 6.1': return '7';
case 'NT 6.2': return '8';
case 'NT 6.3': return '8.1';
case 'NT 10.0': return '10';
default: return undefined;
}
}
/**
* Get macOS version name
* 10.5 - Leopard
* 10.6 - Snow Leopard
* 10.7 - Lion
* 10.8 - Mountain Lion
* 10.9 - Mavericks
* 10.10 - Yosemite
* 10.11 - El Capitan
* 10.12 - Sierra
* 10.13 - High Sierra
* 10.14 - Mojave
* 10.15 - Catalina
*
* @example
* getMacOSVersionName("10.14") // 'Mojave'
*
* @param {string} version
* @return {string} versionName
*/
static getMacOSVersionName(version) {
const v = version.split('.').splice(0, 2).map(s => parseInt(s, 10) || 0);
v.push(0);
if (v[0] !== 10) return undefined;
switch (v[1]) {
case 5: return 'Leopard';
case 6: return 'Snow Leopard';
case 7: return 'Lion';
case 8: return 'Mountain Lion';
case 9: return 'Mavericks';
case 10: return 'Yosemite';
case 11: return 'El Capitan';
case 12: return 'Sierra';
case 13: return 'High Sierra';
case 14: return 'Mojave';
case 15: return 'Catalina';
default: return undefined;
}
}
/**
* Get Android version name
* 1.5 - Cupcake
* 1.6 - Donut
* 2.0 - Eclair
* 2.1 - Eclair
* 2.2 - Froyo
* 2.x - Gingerbread
* 3.x - Honeycomb
* 4.0 - Ice Cream Sandwich
* 4.1 - Jelly Bean
* 4.4 - KitKat
* 5.x - Lollipop
* 6.x - Marshmallow
* 7.x - Nougat
* 8.x - Oreo
* 9.x - Pie
*
* @example
* getAndroidVersionName("7.0") // 'Nougat'
*
* @param {string} version
* @return {string} versionName
*/
static getAndroidVersionName(version) {
const v = version.split('.').splice(0, 2).map(s => parseInt(s, 10) || 0);
v.push(0);
if (v[0] === 1 && v[1] < 5) return undefined;
if (v[0] === 1 && v[1] < 6) return 'Cupcake';
if (v[0] === 1 && v[1] >= 6) return 'Donut';
if (v[0] === 2 && v[1] < 2) return 'Eclair';
if (v[0] === 2 && v[1] === 2) return 'Froyo';
if (v[0] === 2 && v[1] > 2) return 'Gingerbread';
if (v[0] === 3) return 'Honeycomb';
if (v[0] === 4 && v[1] < 1) return 'Ice Cream Sandwich';
if (v[0] === 4 && v[1] < 4) return 'Jelly Bean';
if (v[0] === 4 && v[1] >= 4) return 'KitKat';
if (v[0] === 5) return 'Lollipop';
if (v[0] === 6) return 'Marshmallow';
if (v[0] === 7) return 'Nougat';
if (v[0] === 8) return 'Oreo';
if (v[0] === 9) return 'Pie';
return undefined;
}
/**
* Get version precisions count
*
* @example
* getVersionPrecision("1.10.3") // 3
*
* @param {string} version
* @return {number}
*/
static getVersionPrecision(version) {
return version.split('.').length;
}
/**
* Calculate browser version weight
*
* @example
* compareVersions('1.10.2.1', '1.8.2.1.90') // 1
* compareVersions('1.010.2.1', '1.09.2.1.90'); // 1
* compareVersions('1.10.2.1', '1.10.2.1'); // 0
* compareVersions('1.10.2.1', '1.0800.2'); // -1
* compareVersions('1.10.2.1', '1.10', true); // 0
*
* @param {String} versionA versions versions to compare
* @param {String} versionB versions versions to compare
* @param {boolean} [isLoose] enable loose comparison
* @return {Number} comparison result: -1 when versionA is lower,
* 1 when versionA is bigger, 0 when both equal
*/
/* eslin