@webex/plugin-meetings 2.18.0 → 2.19.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -300
- package/dist/constants.js +3 -206
- package/dist/constants.js.map +1 -1
- package/dist/meeting/effectsState.js +1 -2
- package/dist/meeting/effectsState.js.map +1 -1
- package/dist/meeting/index.js +366 -496
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/util.js +4 -213
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +0 -28
- package/dist/meetings/index.js.map +1 -1
- package/dist/statsAnalyzer/index.js +145 -86
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/package.json +6 -8
- package/src/constants.ts +1 -214
- package/src/meeting/effectsState.js +1 -2
- package/src/meeting/index.js +120 -213
- package/src/meeting/util.js +4 -252
- package/src/meetings/index.js +0 -22
- package/src/statsAnalyzer/index.js +164 -99
- package/test/integration/spec/journey.js +2 -67
- package/test/unit/spec/meeting/effectsState.js +2 -1
- package/test/unit/spec/meeting/index.js +88 -29
- package/test/unit/spec/meeting/utils.js +0 -2
- package/test/unit/spec/stats-analyzer/index.js +209 -1
- package/dist/analyzer/analyzer.js +0 -113
- package/dist/analyzer/analyzer.js.map +0 -1
- package/dist/analyzer/calculator.js +0 -87
- package/dist/analyzer/calculator.js.map +0 -1
- package/dist/metrics/mqa-processor.js +0 -170
- package/dist/metrics/mqa-processor.js.map +0 -1
- package/dist/stats/data.js +0 -93
- package/dist/stats/data.js.map +0 -1
- package/dist/stats/events.js +0 -222
- package/dist/stats/events.js.map +0 -1
- package/dist/stats/filter.js +0 -84
- package/dist/stats/filter.js.map +0 -1
- package/dist/stats/history.js +0 -147
- package/dist/stats/history.js.map +0 -1
- package/dist/stats/index.js +0 -425
- package/dist/stats/index.js.map +0 -1
- package/dist/stats/metrics.js +0 -112
- package/dist/stats/metrics.js.map +0 -1
- package/dist/stats/stats.js +0 -592
- package/dist/stats/stats.js.map +0 -1
- package/dist/stats/stream.js +0 -156
- package/dist/stats/stream.js.map +0 -1
- package/dist/stats/transformer.js +0 -126
- package/dist/stats/transformer.js.map +0 -1
- package/dist/stats/util.js +0 -64
- package/dist/stats/util.js.map +0 -1
- package/src/analyzer/analyzer.js +0 -78
- package/src/analyzer/calculator.js +0 -77
- package/src/metrics/mqa-processor.js +0 -118
- package/src/stats/data.js +0 -56
- package/src/stats/events.js +0 -185
- package/src/stats/filter.js +0 -40
- package/src/stats/history.js +0 -107
- package/src/stats/index.js +0 -320
- package/src/stats/metrics.js +0 -95
- package/src/stats/stats.js +0 -477
- package/src/stats/stream.js +0 -108
- package/src/stats/transformer.js +0 -109
- package/src/stats/util.js +0 -44
package/dist/stats/stats.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["MeetingStats","attrs","options","optionalCreateOptions","MEETINGS","peerConnection","RTCRtpDirection","history","mqa","stream","filter","events","id","populate","withHistory","withMQA","media","withFilter","withStream","withId","onClose","TypeError","onEvent","withEventsHistory","withEvents","onData","data","add","isEmpty","omit","event","cbFn","on","STATS","DATA","filtered","doHistory","doMQA","doEvents","END","err","StatsError","cb","StatsEvents","setEvents","StatsHistory","config","stats","historyMax","setHistory","MQA_STATS","MQA_SIZE","setMQA","transceiverDirection","StatsStream","rTCRtpDirection","interval","setStream","setFilter","StatsFilter","getStream","pipe","getFilter","setId","uuid","v4","StatelessWebexPlugin"],"sources":["stats.js"],"sourcesContent":["import {StatelessWebexPlugin} from '@webex/webex-core';\nimport {isFunction} from 'lodash';\nimport {uuid} from 'uuid';\n\nimport {\n MEETINGS,\n STATS,\n MQA_STATS\n} from '../constants';\nimport StatsHistory from '../stats/history';\nimport StatsStream from '../stats/stream';\nimport StatsFilter from '../stats/filter';\nimport StatsEvents from '../stats/events';\nimport StatsError from '../common/errors/stats';\n\n/**\n * @class MeetingStats\n */\nexport default class MeetingStats extends StatelessWebexPlugin {\n namespace = MEETINGS;\n\n /**\n * @param {Object} attrs\n * @param {Object} options\n * @param {Object} [optionalCreateOptions]\n * @param {Boolean} optionalCreateOptions.history\n * @param {Boolean} optionalCreateOptions.mqa\n * @param {RTCRtpSender|RTCRtpReceiver} optionalCreateOptions.stream\n * @param {RTCRtpSender|RTCRtpReceiver} optionalCreateOptions.filter\n * @param {RTCPeerConnection} optionalCreateOptions.media\n * @param {String} optionalCreateOptions.id\n * @param {Function} optionalCreateOptions.onClose\n * @param {Function} optionalCreateOptions.onEvent\n * @param {Function} optionalCreateOptions.onData\n * if using filter or stream, media must also exist\n */\n constructor(attrs, options, optionalCreateOptions) {\n super({}, options);\n this.attrs = attrs;\n this.options = options;\n // what this stats object is configured to work with\n /**\n * @instance\n * @type {RTCPeerConnection}\n * @private\n * @memberof MeetingStats\n */\n this.peerConnection = null;\n /**\n * @instance\n * @type {RTCRtpSender|RTCRtpReceiver}\n * @private\n * @memberof MeetingStats\n */\n this.RTCRtpDirection = null;\n // usable values\n /**\n * @instance\n * @type {StatsHistory}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.history = null;\n /**\n * @instance\n * @type {StatsHistory}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.mqa = null;\n /**\n * @instance\n * @type {ReadableStream}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.stream = null;\n /**\n * @instance\n * @type {TransformStream}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.filter = null;\n /**\n * @instance\n * @type {StatsEvents}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.events = null;\n /**\n * @instance\n * @type {String}\n * @readonly\n * @private\n * @memberof MeetingStats\n */\n this.id = null;\n this.populate(optionalCreateOptions);\n }\n\n /**\n * @param {Object} [optionalCreateOptions]\n * @returns {undefined}\n * @private\n * @memberof MeetingStats\n */\n populate(optionalCreateOptions) {\n if (optionalCreateOptions) {\n if (optionalCreateOptions.history) {\n this.withHistory();\n }\n if (optionalCreateOptions.mqa) {\n this.withMQA();\n }\n if (optionalCreateOptions.filter && !optionalCreateOptions.stream && optionalCreateOptions.media) {\n this.withFilter(optionalCreateOptions.filter, optionalCreateOptions.media);\n }\n if (optionalCreateOptions.stream && !optionalCreateOptions.filter && optionalCreateOptions.media) {\n this.withStream(optionalCreateOptions.stream, optionalCreateOptions.media);\n }\n if (optionalCreateOptions.id) {\n this.withId(optionalCreateOptions.id);\n }\n if (optionalCreateOptions.onClose) {\n if (!isFunction(optionalCreateOptions.onClose)) {\n throw new TypeError('stats->populate#onClose must be a callback function for filtered data.');\n }\n this.onClose(optionalCreateOptions.onClose);\n }\n if (optionalCreateOptions.onEvent) {\n if (!isFunction(optionalCreateOptions.onEvent)) {\n throw new TypeError('stats->populate#onEvent must be a callback function for filtered data.');\n }\n if (this.history) {\n this.withEventsHistory(this.history, optionalCreateOptions.onEvent);\n }\n else {\n this.withEvents(optionalCreateOptions.onEvent);\n }\n }\n if (optionalCreateOptions.onData) {\n if (!isFunction(optionalCreateOptions.onData)) {\n throw new TypeError('stats->populate#onData must be a callback function for filtered data.');\n }\n this.onData(optionalCreateOptions.onData);\n }\n }\n\n return this;\n }\n\n /**\n * @param {WebRTCData} data\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n doHistory(data) {\n if (this.history) {\n this.history.add(data);\n }\n }\n\n /**\n * @param {WebRTCData} data\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n doMQA(data) {\n if (this.mqa && data.data) {\n if (!data.data.isEmpty()) {\n this.mqa.add(data.data.omit());\n }\n }\n }\n\n /**\n * @param {WebRTCData} data\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n doEvents(data) {\n if (this.events) {\n this.events.event(data);\n }\n }\n\n /**\n * does all the work for the built properties\n * calls back a function with data from piped stream filter\n * @param {Function} cbFn\n * @returns {undefined}\n * @throws {Error} if the filter stream does not exist\n * @private\n * @memberof MeetingStats\n */\n onData(cbFn) {\n if (!this.filter) {\n throw new TypeError('The stats sender/receiver filter must be set up before data can be processed.');\n }\n this.filter.on(STATS.DATA, (filtered) => {\n this.doHistory(filtered);\n this.doMQA(filtered);\n this.doEvents(filtered);\n cbFn(filtered);\n });\n\n return this;\n }\n\n /**\n * triggered if the data stream closes\n * calls back a function with error\n * @param {Function} cbFn\n * @returns {undefined}\n * @private\n * @memberof MeetingStats\n */\n onClose(cbFn) {\n if (!this.filter) {\n throw new TypeError('the stats sender/receiver filter must be set up before data can be closed.');\n }\n this.stream.on(STATS.END, (err) => {\n if (!err) {\n err = new StatsError(`The stats stream for id: ${this.id} ended.`);\n }\n cbFn(err);\n });\n\n return this;\n }\n\n /**\n * constructs an event object on this instance\n * @param {StatsHistory} history\n * @param {Function} cb\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withEventsHistory(history, cb) {\n const events = new StatsEvents(history, cb);\n\n this.setEvents(events);\n\n return this;\n }\n\n /**\n * constructs an event object on this instance\n * @param {Function} cb\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withEvents(cb) {\n const events = new StatsEvents(null, cb);\n\n this.setEvents(events);\n\n return this;\n }\n\n /**\n * constructs a history object on this instance\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withHistory() {\n const history = new StatsHistory(this.config.stats.historyMax);\n\n this.setHistory(history);\n\n return this;\n }\n\n /**\n * constructs a history object on this instance\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withMQA() {\n const mqa = new StatsHistory(MQA_STATS.MQA_SIZE);\n\n this.setMQA(mqa);\n\n return this;\n }\n\n /**\n * constructs a readable stream object on this instance\n * @param {RTCRtpReceiver|RTCRtpSender} transceiverDirection\n * @param {RTCPeerConnection} peerConnection\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withStream(transceiverDirection, peerConnection) {\n const stream = new StatsStream({\n rTCRtpDirection: transceiverDirection,\n peerConnection,\n interval: this.config.stats.interval\n });\n\n this.setStream(stream);\n\n return this;\n }\n\n /**\n * @param {RTCRtpReceiver|RTCRtpSender} transceiverDirection\n * @param {RTCPeerConnection} peerConnection\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withFilter(transceiverDirection, peerConnection) {\n this.withStream(transceiverDirection, peerConnection);\n this.setFilter(new StatsFilter());\n this.getStream().pipe(this.getFilter());\n\n return this;\n }\n\n /**\n * constructs an id to match this stats object\n * takes params as precedence\n * @param {String} id\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n withId(id) {\n if (id) {\n this.setId(id);\n }\n else {\n this.setId(uuid.v4());\n }\n\n return this;\n }\n\n /**\n * @returns {MeetingStats}\n * @public\n * @memberof MeetingStats\n */\n build() {\n return this;\n }\n\n /**\n * @param {String} id\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setId(id) {\n this.id = id;\n }\n\n /**\n * @param {StatsHistory} history\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setHistory(history) {\n this.history = history;\n }\n\n /**\n * @param {StatsHistory} mqa\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setMQA(mqa) {\n this.mqa = mqa;\n }\n\n /**\n * @param {StatsEvent} events\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setEvents(events) {\n this.events = events;\n }\n\n /**\n * @param {Readable} stream\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setStream(stream) {\n this.stream = stream;\n }\n\n /**\n * @param {Transform} filter\n * @returns {undefined}\n * @public\n * @memberof MeetingStats\n */\n setFilter(filter) {\n this.filter = filter;\n }\n\n /**\n * @returns {String}\n * @public\n * @memberof MeetingStats\n */\n getId() {\n return this.id;\n }\n\n /**\n * @returns {StatsHistory}\n * @public\n * @memberof MeetingStats\n */\n getHistory() {\n return this.history;\n }\n\n /**\n * @returns {StatsHistory}\n * @public\n * @memberof MeetingStats\n */\n getMQA() {\n return this.mqa;\n }\n\n /**\n * @returns {StatsEvents}\n * @public\n * @memberof MeetingStats\n */\n getEvents() {\n return this.events;\n }\n\n /**\n * @returns {Readable}\n * @public\n * @memberof MeetingStats\n */\n getStream() {\n return this.stream;\n }\n\n /**\n * @returns {Transform}\n * @public\n * @memberof MeetingStats\n */\n getFilter() {\n return this.filter;\n }\n}\n"],"mappings":"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AAQ;QACN,KAAKmD,KAAL,CAAWnD,EAAX;MACD,CAFD,MAGK;QACH,KAAKmD,KAAL,CAAWC,UAAA,CAAKC,EAAL,EAAX;MACD;;MAED,OAAO,IAAP;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,iBAAQ;MACN,OAAO,IAAP;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,eAAMrD,EAAN,EAAU;MACR,KAAKA,EAAL,GAAUA,EAAV;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,oBAAWL,OAAX,EAAoB;MAClB,KAAKA,OAAL,GAAeA,OAAf;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,gBAAOC,GAAP,EAAY;MACV,KAAKA,GAAL,GAAWA,GAAX;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,mBAAUG,MAAV,EAAkB;MAChB,KAAKA,MAAL,GAAcA,MAAd;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,mBAAUF,MAAV,EAAkB;MAChB,KAAKA,MAAL,GAAcA,MAAd;IACD;IAED;AACF;AACA;AACA;AACA;AACA;;;;WACE,mBAAUC,MAAV,EAAkB;MAChB,KAAKA,MAAL,GAAcA,MAAd;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,iBAAQ;MACN,OAAO,KAAKE,EAAZ;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,sBAAa;MACX,OAAO,KAAKL,OAAZ;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,kBAAS;MACP,OAAO,KAAKC,GAAZ;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,qBAAY;MACV,OAAO,KAAKG,MAAZ;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,qBAAY;MACV,OAAO,KAAKF,MAAZ;IACD;IAED;AACF;AACA;AACA;AACA;;;;WACE,qBAAY;MACV,OAAO,KAAKC,MAAZ;IACD;;;EAzcuCwD,+B"}
|
package/dist/stats/stream.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
|
|
4
|
-
|
|
5
|
-
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
6
|
-
|
|
7
|
-
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
8
|
-
|
|
9
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
10
|
-
value: true
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
exports.default = void 0;
|
|
14
|
-
|
|
15
|
-
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
16
|
-
|
|
17
|
-
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
18
|
-
|
|
19
|
-
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
|
|
20
|
-
|
|
21
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
22
|
-
|
|
23
|
-
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
|
|
24
|
-
|
|
25
|
-
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
26
|
-
|
|
27
|
-
var _weakMap = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/weak-map"));
|
|
28
|
-
|
|
29
|
-
var _events = require("events");
|
|
30
|
-
|
|
31
|
-
var _readableStream = require("readable-stream");
|
|
32
|
-
|
|
33
|
-
var _commonTimers = require("@webex/common-timers");
|
|
34
|
-
|
|
35
|
-
var _constants = require("../constants");
|
|
36
|
-
|
|
37
|
-
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = _Reflect$construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
|
|
38
|
-
|
|
39
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
40
|
-
|
|
41
|
-
var pcsByRTCRtpDirection = new _weakMap.default();
|
|
42
|
-
var emittersByRTCRtpDirection = new _weakMap.default();
|
|
43
|
-
var RTCRtpDirectionByEmitter = new _weakMap.default();
|
|
44
|
-
var emittersByStream = new _weakMap.default();
|
|
45
|
-
var timersByEmitter = new _weakMap.default();
|
|
46
|
-
/**
|
|
47
|
-
* Helper function that ensures no matter how many stats streams we create, we
|
|
48
|
-
* don't poll the PeerConnection more than once per interval.
|
|
49
|
-
* @param {EventEmitter} emitter
|
|
50
|
-
* @param {Number} interval
|
|
51
|
-
* @private
|
|
52
|
-
* @returns {undefined}
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
var schedule = function schedule(emitter, interval) {
|
|
56
|
-
var timer = (0, _commonTimers.safeSetTimeout)(function () {
|
|
57
|
-
var direction = RTCRtpDirectionByEmitter.get(emitter);
|
|
58
|
-
var pc = pcsByRTCRtpDirection.get(direction);
|
|
59
|
-
|
|
60
|
-
if (direction) {
|
|
61
|
-
direction.getStats().then(function (stats) {
|
|
62
|
-
emitter.emit(_constants.STATS.DATA, stats); // TODO: Remove on 1.0 spec adoption
|
|
63
|
-
// "closed" is supposed to be part of the {@link RTCPeerConnectionState}
|
|
64
|
-
// enum according to spec, but at time of writing, was still implemented
|
|
65
|
-
// in the {@link RTCSignalingState} enum.
|
|
66
|
-
|
|
67
|
-
if (!(pc.signalingState === _constants.STATS.CLOSED || pc.connectionState === _constants.STATS.CLOSED)) {
|
|
68
|
-
schedule(emitter, interval);
|
|
69
|
-
}
|
|
70
|
-
}).catch(function (err) {
|
|
71
|
-
emitter.emit(_constants.ERROR, err);
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
}, interval);
|
|
75
|
-
timersByEmitter.set(emitter, timer);
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Polls an {@link RTCPeerConnection} once per second and emits its {@link RTCStatsReport}
|
|
79
|
-
* {@link RTCStatsReport}
|
|
80
|
-
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
var StatsStream = /*#__PURE__*/function (_Readable) {
|
|
84
|
-
(0, _inherits2.default)(StatsStream, _Readable);
|
|
85
|
-
|
|
86
|
-
var _super = _createSuper(StatsStream);
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @private
|
|
90
|
-
* @param {Object} config
|
|
91
|
-
* @param {RTCRtpSender|RTCRtpReceiver} config.rTCRtpDirection
|
|
92
|
-
* @param {RTCPeerConnection} config.peerConnection
|
|
93
|
-
* @param {Number} config.interval
|
|
94
|
-
*/
|
|
95
|
-
function StatsStream() {
|
|
96
|
-
var _this;
|
|
97
|
-
|
|
98
|
-
var config = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
99
|
-
(0, _classCallCheck2.default)(this, StatsStream);
|
|
100
|
-
_this = _super.call(this, {
|
|
101
|
-
objectMode: true
|
|
102
|
-
});
|
|
103
|
-
_this.interval = config.interval;
|
|
104
|
-
|
|
105
|
-
if (!emittersByRTCRtpDirection.has(config.rTCRtpDirection)) {
|
|
106
|
-
emittersByRTCRtpDirection.set(config.rTCRtpDirection, new _events.EventEmitter());
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
var emitter = emittersByRTCRtpDirection.get(config.rTCRtpDirection);
|
|
110
|
-
|
|
111
|
-
if (!emittersByStream.has((0, _assertThisInitialized2.default)(_this))) {
|
|
112
|
-
emittersByStream.set((0, _assertThisInitialized2.default)(_this), emitter);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (!RTCRtpDirectionByEmitter.has(emitter)) {
|
|
116
|
-
RTCRtpDirectionByEmitter.set(emitter, config.rTCRtpDirection);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (!pcsByRTCRtpDirection.has(config.rTCRtpDirection)) {
|
|
120
|
-
pcsByRTCRtpDirection.set(config.rTCRtpDirection, config.peerConnection);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
emitter.once(_constants.ERROR, function (err) {
|
|
124
|
-
_this.emit(_constants.ERROR, err);
|
|
125
|
-
});
|
|
126
|
-
return _this;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* See NodeJS Docs
|
|
130
|
-
* @private
|
|
131
|
-
* @returns {undefined}
|
|
132
|
-
*/
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
(0, _createClass2.default)(StatsStream, [{
|
|
136
|
-
key: "_read",
|
|
137
|
-
value: function _read() {
|
|
138
|
-
var _this2 = this;
|
|
139
|
-
|
|
140
|
-
var emitter = emittersByStream.get(this);
|
|
141
|
-
emitter.once(_constants.STATS.DATA, function (data) {
|
|
142
|
-
if (!_this2.isPaused()) {
|
|
143
|
-
_this2.push(data);
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
if (!timersByEmitter.has(emitter)) {
|
|
148
|
-
schedule(emitter, this.interval);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}]);
|
|
152
|
-
return StatsStream;
|
|
153
|
-
}(_readableStream.Readable);
|
|
154
|
-
|
|
155
|
-
exports.default = StatsStream;
|
|
156
|
-
//# sourceMappingURL=stream.js.map
|
package/dist/stats/stream.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["pcsByRTCRtpDirection","emittersByRTCRtpDirection","RTCRtpDirectionByEmitter","emittersByStream","timersByEmitter","schedule","emitter","interval","timer","safeSetTimeout","direction","get","pc","getStats","then","stats","emit","STATS","DATA","signalingState","CLOSED","connectionState","catch","err","ERROR","set","StatsStream","config","objectMode","has","rTCRtpDirection","EventEmitter","peerConnection","once","data","isPaused","push","Readable"],"sources":["stream.js"],"sourcesContent":["import {EventEmitter} from 'events';\n\nimport {Readable} from 'readable-stream';\nimport {safeSetTimeout} from '@webex/common-timers';\n\nimport {\n ERROR,\n STATS\n} from '../constants';\n\nconst pcsByRTCRtpDirection = new WeakMap();\nconst emittersByRTCRtpDirection = new WeakMap();\nconst RTCRtpDirectionByEmitter = new WeakMap();\nconst emittersByStream = new WeakMap();\nconst timersByEmitter = new WeakMap();\n\n/**\n * Helper function that ensures no matter how many stats streams we create, we\n * don't poll the PeerConnection more than once per interval.\n * @param {EventEmitter} emitter\n * @param {Number} interval\n * @private\n * @returns {undefined}\n */\nconst schedule = (emitter, interval) => {\n const timer = safeSetTimeout(() => {\n const direction = RTCRtpDirectionByEmitter.get(emitter);\n const pc = pcsByRTCRtpDirection.get(direction);\n\n if (direction) {\n direction.getStats()\n .then((stats) => {\n emitter.emit(STATS.DATA, stats);\n // TODO: Remove on 1.0 spec adoption\n // \"closed\" is supposed to be part of the {@link RTCPeerConnectionState}\n // enum according to spec, but at time of writing, was still implemented\n // in the {@link RTCSignalingState} enum.\n if (!(pc.signalingState === STATS.CLOSED || pc.connectionState === STATS.CLOSED)) {\n schedule(emitter, interval);\n }\n })\n .catch((err) => {\n emitter.emit(ERROR, err);\n });\n }\n }, interval);\n\n timersByEmitter.set(emitter, timer);\n};\n\n/**\n * Polls an {@link RTCPeerConnection} once per second and emits its {@link RTCStatsReport}\n * {@link RTCStatsReport}\n */\nexport default class StatsStream extends Readable {\n /**\n * @private\n * @param {Object} config\n * @param {RTCRtpSender|RTCRtpReceiver} config.rTCRtpDirection\n * @param {RTCPeerConnection} config.peerConnection\n * @param {Number} config.interval\n */\n constructor(config = {}) {\n super({objectMode: true});\n\n this.interval = config.interval;\n\n if (!emittersByRTCRtpDirection.has(config.rTCRtpDirection)) {\n emittersByRTCRtpDirection.set(config.rTCRtpDirection, new EventEmitter());\n }\n const emitter = emittersByRTCRtpDirection.get(config.rTCRtpDirection);\n\n if (!emittersByStream.has(this)) {\n emittersByStream.set(this, emitter);\n }\n if (!RTCRtpDirectionByEmitter.has(emitter)) {\n RTCRtpDirectionByEmitter.set(emitter, config.rTCRtpDirection);\n }\n\n if (!pcsByRTCRtpDirection.has(config.rTCRtpDirection)) {\n pcsByRTCRtpDirection.set(config.rTCRtpDirection, config.peerConnection);\n }\n\n emitter.once(ERROR, (err) => {\n this.emit(ERROR, err);\n });\n }\n\n /**\n * See NodeJS Docs\n * @private\n * @returns {undefined}\n */\n _read() {\n const emitter = emittersByStream.get(this);\n\n emitter.once(STATS.DATA, (data) => {\n if (!this.isPaused()) {\n this.push(data);\n }\n });\n\n if (!timersByEmitter.has(emitter)) {\n schedule(emitter, this.interval);\n }\n }\n}\n\n"],"mappings":"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"}
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
|
-
|
|
5
|
-
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
6
|
-
|
|
7
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
8
|
-
value: true
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
exports.default = void 0;
|
|
12
|
-
|
|
13
|
-
var _forEach2 = _interopRequireDefault(require("lodash/forEach"));
|
|
14
|
-
|
|
15
|
-
var _find2 = _interopRequireDefault(require("lodash/find"));
|
|
16
|
-
|
|
17
|
-
var _keys2 = _interopRequireDefault(require("lodash/keys"));
|
|
18
|
-
|
|
19
|
-
var _constants = require("../constants");
|
|
20
|
-
|
|
21
|
-
var _browserDetection = _interopRequireDefault(require("../common/browser-detection"));
|
|
22
|
-
|
|
23
|
-
var _BrowserDetection = (0, _browserDetection.default)(),
|
|
24
|
-
isBrowser = _BrowserDetection.isBrowser;
|
|
25
|
-
|
|
26
|
-
var StatsTransformer = {
|
|
27
|
-
isFF: isBrowser('firefox')
|
|
28
|
-
}; // convert the ids from the parsed stats objects into understandable keys
|
|
29
|
-
|
|
30
|
-
StatsTransformer.simplify = function (stat) {
|
|
31
|
-
return (0, _find2.default)((0, _keys2.default)(StatsTransformer.isFF ? _constants.DEFAULT_FF_TRANSFORM_REGEX : _constants.DEFAULT_TRANSFORM_REGEX), function (key) {
|
|
32
|
-
var value;
|
|
33
|
-
|
|
34
|
-
if (StatsTransformer.isFF) {
|
|
35
|
-
// FF stats are formatted poorly so we have to take what we can get
|
|
36
|
-
value = _constants.DEFAULT_FF_TRANSFORM_REGEX[key].regex.test("".concat(stat.type).concat(stat.kind ? "_".concat(stat.kind) : '', "_").concat(stat.id)) ? key : false;
|
|
37
|
-
} else {
|
|
38
|
-
// no other parameters necessary besides id
|
|
39
|
-
value = _constants.DEFAULT_TRANSFORM_REGEX[key].regex.test(stat.id) ? key : false;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
if (value) {
|
|
43
|
-
// others were included but have a value that exclude them from the list because of duplicates that weren't chosen
|
|
44
|
-
if (_constants.DEFAULT_TRANSFORM_REGEX[value].decider) {
|
|
45
|
-
if (stat[_constants.DEFAULT_TRANSFORM_REGEX[value].decider] !== _constants.DEFAULT_TRANSFORM_REGEX[value].selector) {
|
|
46
|
-
value = false;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return value;
|
|
50
|
-
} // // some types need to check against a type field as well
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (_constants.DEFAULT_TRANSFORM_REGEX[value].profiler) {
|
|
54
|
-
var mapStatToReadableType = stat[_constants.DEFAULT_TRANSFORM_REGEX[value].profiler.type];
|
|
55
|
-
|
|
56
|
-
if (!(mapStatToReadableType && mapStatToReadableType.includes(_constants.DEFAULT_TRANSFORM_REGEX[value].profiler.value) && value.toLowerCase().includes(_constants.DEFAULT_TRANSFORM_REGEX[value].profiler.value))) {
|
|
57
|
-
value = false;
|
|
58
|
-
return value;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return value;
|
|
64
|
-
});
|
|
65
|
-
}; // parse the RTCStatsReport, extracting only the data we care about
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
StatsTransformer.parse = function (report) {
|
|
69
|
-
var target = {}; // from the stats object
|
|
70
|
-
// get the rtc stats report
|
|
71
|
-
|
|
72
|
-
if (report && report.forEach && report.size > 0) {
|
|
73
|
-
report.forEach(function (stat) {
|
|
74
|
-
// each report has internal data
|
|
75
|
-
if (stat && stat.type) {
|
|
76
|
-
// pull only certain types
|
|
77
|
-
if (_constants.DEFAULT_GET_STATS_FILTER.types.includes(stat.type)) {
|
|
78
|
-
// insert into the target the statistic mapped to it's statical id
|
|
79
|
-
target[stat.id] = stat;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
return target;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
StatsTransformer.convert = function (parsed, options) {
|
|
89
|
-
// supply your own simplification function (rather than id as the key)
|
|
90
|
-
if (options.simplifyFn) {
|
|
91
|
-
return options.simplifyFn(parsed);
|
|
92
|
-
} // else use ours that stores things like rtcOutAudio, rtpInVideo, etc
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
var target = {};
|
|
96
|
-
(0, _forEach2.default)(parsed, function (stat) {
|
|
97
|
-
var key = StatsTransformer.simplify(stat);
|
|
98
|
-
|
|
99
|
-
if (key) {
|
|
100
|
-
target[key] = stat;
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
return target;
|
|
104
|
-
}; // transform the RTCStatsReport into a much more readable, processable format
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
StatsTransformer.transform = function (report) {
|
|
108
|
-
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
|
|
109
|
-
simplifyFn: undefined
|
|
110
|
-
};
|
|
111
|
-
var data; // first parse it and cut out not necessary data
|
|
112
|
-
|
|
113
|
-
var parsed = StatsTransformer.parse(report); // either convert the data or store each stat with it's id mapped as the key to the stat object itself
|
|
114
|
-
|
|
115
|
-
if (_constants.DEFAULT_TRANSFORM_REGEX) {
|
|
116
|
-
data = StatsTransformer.convert(parsed, options);
|
|
117
|
-
} else {
|
|
118
|
-
data = parsed;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return data;
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
var _default = StatsTransformer;
|
|
125
|
-
exports.default = _default;
|
|
126
|
-
//# sourceMappingURL=transformer.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["BrowserDetection","isBrowser","StatsTransformer","isFF","simplify","stat","DEFAULT_FF_TRANSFORM_REGEX","DEFAULT_TRANSFORM_REGEX","key","value","regex","test","type","kind","id","decider","selector","profiler","mapStatToReadableType","includes","toLowerCase","parse","report","target","forEach","size","DEFAULT_GET_STATS_FILTER","types","convert","parsed","options","simplifyFn","transform","undefined","data"],"sources":["transformer.js"],"sourcesContent":["import {keys, find, forEach} from 'lodash';\n\nimport {\n DEFAULT_TRANSFORM_REGEX, DEFAULT_FF_TRANSFORM_REGEX, DEFAULT_GET_STATS_FILTER\n} from '../constants';\nimport BrowserDetection from '../common/browser-detection';\n\nconst {isBrowser} = BrowserDetection();\n\nconst StatsTransformer = {\n isFF: isBrowser('firefox')\n};\n\n// convert the ids from the parsed stats objects into understandable keys\nStatsTransformer.simplify = (stat) => find(keys(StatsTransformer.isFF ? DEFAULT_FF_TRANSFORM_REGEX : DEFAULT_TRANSFORM_REGEX), (key) => {\n let value;\n\n if (StatsTransformer.isFF) {\n // FF stats are formatted poorly so we have to take what we can get\n value = (DEFAULT_FF_TRANSFORM_REGEX[key].regex.test(`${stat.type}${stat.kind ? `_${stat.kind}` : ''}_${stat.id}`) ? key : false);\n }\n else {\n // no other parameters necessary besides id\n value = (DEFAULT_TRANSFORM_REGEX[key].regex.test(stat.id) ? key : false);\n }\n\n if (value) {\n // others were included but have a value that exclude them from the list because of duplicates that weren't chosen\n if (DEFAULT_TRANSFORM_REGEX[value].decider) {\n if (stat[DEFAULT_TRANSFORM_REGEX[value].decider] !== DEFAULT_TRANSFORM_REGEX[value].selector) {\n value = false;\n }\n\n return value;\n }\n // // some types need to check against a type field as well\n if (DEFAULT_TRANSFORM_REGEX[value].profiler) {\n const mapStatToReadableType = stat[DEFAULT_TRANSFORM_REGEX[value].profiler.type];\n\n if (!((mapStatToReadableType && mapStatToReadableType.includes(DEFAULT_TRANSFORM_REGEX[value].profiler.value)) &&\n (value.toLowerCase().includes(DEFAULT_TRANSFORM_REGEX[value].profiler.value)))) {\n value = false;\n\n return value;\n }\n }\n }\n\n return value;\n});\n\n// parse the RTCStatsReport, extracting only the data we care about\nStatsTransformer.parse = (report) => {\n const target = {};\n\n // from the stats object\n // get the rtc stats report\n if (report && report.forEach && report.size > 0) {\n report.forEach((stat) => {\n // each report has internal data\n if (stat && stat.type) {\n // pull only certain types\n if (DEFAULT_GET_STATS_FILTER.types.includes(stat.type)) {\n // insert into the target the statistic mapped to it's statical id\n target[stat.id] = stat;\n }\n }\n });\n }\n\n return target;\n};\n\nStatsTransformer.convert = (parsed, options) => {\n // supply your own simplification function (rather than id as the key)\n if (options.simplifyFn) {\n return options.simplifyFn(parsed);\n }\n // else use ours that stores things like rtcOutAudio, rtpInVideo, etc\n const target = {};\n\n forEach(parsed, (stat) => {\n const key = StatsTransformer.simplify(stat);\n\n if (key) {\n target[key] = stat;\n }\n });\n\n return target;\n};\n\n// transform the RTCStatsReport into a much more readable, processable format\nStatsTransformer.transform = (report, options = {simplifyFn: undefined}) => {\n let data;\n // first parse it and cut out not necessary data\n const parsed = StatsTransformer.parse(report);\n\n // either convert the data or store each stat with it's id mapped as the key to the stat object itself\n if (DEFAULT_TRANSFORM_REGEX) {\n data = StatsTransformer.convert(parsed, options);\n }\n else {\n data = parsed;\n }\n\n return data;\n};\nexport default StatsTransformer;\n"],"mappings":"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"}
|
package/dist/stats/util.js
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
|
-
|
|
5
|
-
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
6
|
-
|
|
7
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
8
|
-
value: true
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
exports.default = void 0;
|
|
12
|
-
|
|
13
|
-
var _assign = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/assign"));
|
|
14
|
-
|
|
15
|
-
var _forEach2 = _interopRequireDefault(require("lodash/forEach"));
|
|
16
|
-
|
|
17
|
-
var _constants = require("../constants");
|
|
18
|
-
|
|
19
|
-
var _parameter = _interopRequireDefault(require("../common/errors/parameter"));
|
|
20
|
-
|
|
21
|
-
var StatsUtil = {};
|
|
22
|
-
|
|
23
|
-
StatsUtil.generateSingularOptions = function (senderReceiver, config, meeting, name) {
|
|
24
|
-
var options = {};
|
|
25
|
-
options[name] = {};
|
|
26
|
-
options[name][senderReceiver.correlate] = senderReceiver;
|
|
27
|
-
StatsUtil.generateOptions(options, config, meeting);
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
StatsUtil.generateOptions = function (options, config, meeting) {
|
|
31
|
-
if (!options || !config || !meeting) {
|
|
32
|
-
throw new _parameter.default('stats/util->validateInitialization#options, config, and meeting must be provided to execute getStats');
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
StatsUtil.configOptions(meeting, config, options, _constants.STATS.SENDERS);
|
|
36
|
-
StatsUtil.configOptions(meeting, config, options, _constants.STATS.RECEIVERS);
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
StatsUtil.configOptions = function (meeting, config, options, name) {
|
|
40
|
-
if (options[name]) {
|
|
41
|
-
(0, _forEach2.default)(options[name], function (type) {
|
|
42
|
-
if (!type.correlate) {
|
|
43
|
-
throw new _parameter.default("stats/util->validateInitialization#each ".concat(type, " must be provided with a correlate as audio OR video OR share."));
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (!config[name][type.correlate]) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
var typeConfig = config[name][type.correlate];
|
|
51
|
-
var media = meeting[typeConfig.parent][typeConfig.peerConnection];
|
|
52
|
-
var filter = media[typeConfig.transceiver][typeConfig.child];
|
|
53
|
-
(0, _assign.default)(type, {
|
|
54
|
-
media: media,
|
|
55
|
-
filter: filter,
|
|
56
|
-
name: typeConfig.name
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
var _default = StatsUtil;
|
|
63
|
-
exports.default = _default;
|
|
64
|
-
//# sourceMappingURL=util.js.map
|
package/dist/stats/util.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["StatsUtil","generateSingularOptions","senderReceiver","config","meeting","name","options","correlate","generateOptions","ParameterError","configOptions","STATS","SENDERS","RECEIVERS","type","typeConfig","media","parent","peerConnection","filter","transceiver","child"],"sources":["util.js"],"sourcesContent":["import {forEach} from 'lodash';\n\nimport {\n STATS\n} from '../constants';\nimport ParameterError from '../common/errors/parameter';\n\nconst StatsUtil = {};\n\nStatsUtil.generateSingularOptions = (senderReceiver, config, meeting, name) => {\n const options = {};\n\n options[name] = {};\n options[name][senderReceiver.correlate] = senderReceiver;\n StatsUtil.generateOptions(options, config, meeting);\n};\n\nStatsUtil.generateOptions = (options, config, meeting) => {\n if (!options || !config || !meeting) {\n throw new ParameterError('stats/util->validateInitialization#options, config, and meeting must be provided to execute getStats');\n }\n StatsUtil.configOptions(meeting, config, options, STATS.SENDERS);\n StatsUtil.configOptions(meeting, config, options, STATS.RECEIVERS);\n};\n\nStatsUtil.configOptions = (meeting, config, options, name) => {\n if (options[name]) {\n forEach(options[name], (type) => {\n if (!type.correlate) {\n throw new ParameterError(`stats/util->validateInitialization#each ${type} must be provided with a correlate as audio OR video OR share.`);\n }\n if (!config[name][type.correlate]) {\n return;\n }\n const typeConfig = config[name][type.correlate];\n const media = meeting[typeConfig.parent][typeConfig.peerConnection];\n const filter = media[typeConfig.transceiver][typeConfig.child];\n\n Object.assign(type, {media, filter, name: typeConfig.name});\n });\n }\n};\n\nexport default StatsUtil;\n"],"mappings":";;;;;;;;;;;;;;;;AAEA;;AAGA;;AAEA,IAAMA,SAAS,GAAG,EAAlB;;AAEAA,SAAS,CAACC,uBAAV,GAAoC,UAACC,cAAD,EAAiBC,MAAjB,EAAyBC,OAAzB,EAAkCC,IAAlC,EAA2C;EAC7E,IAAMC,OAAO,GAAG,EAAhB;EAEAA,OAAO,CAACD,IAAD,CAAP,GAAgB,EAAhB;EACAC,OAAO,CAACD,IAAD,CAAP,CAAcH,cAAc,CAACK,SAA7B,IAA0CL,cAA1C;EACAF,SAAS,CAACQ,eAAV,CAA0BF,OAA1B,EAAmCH,MAAnC,EAA2CC,OAA3C;AACD,CAND;;AAQAJ,SAAS,CAACQ,eAAV,GAA4B,UAACF,OAAD,EAAUH,MAAV,EAAkBC,OAAlB,EAA8B;EACxD,IAAI,CAACE,OAAD,IAAY,CAACH,MAAb,IAAuB,CAACC,OAA5B,EAAqC;IACnC,MAAM,IAAIK,kBAAJ,CAAmB,sGAAnB,CAAN;EACD;;EACDT,SAAS,CAACU,aAAV,CAAwBN,OAAxB,EAAiCD,MAAjC,EAAyCG,OAAzC,EAAkDK,gBAAA,CAAMC,OAAxD;EACAZ,SAAS,CAACU,aAAV,CAAwBN,OAAxB,EAAiCD,MAAjC,EAAyCG,OAAzC,EAAkDK,gBAAA,CAAME,SAAxD;AACD,CAND;;AAQAb,SAAS,CAACU,aAAV,GAA0B,UAACN,OAAD,EAAUD,MAAV,EAAkBG,OAAlB,EAA2BD,IAA3B,EAAoC;EAC5D,IAAIC,OAAO,CAACD,IAAD,CAAX,EAAmB;IACjB,uBAAQC,OAAO,CAACD,IAAD,CAAf,EAAuB,UAACS,IAAD,EAAU;MAC/B,IAAI,CAACA,IAAI,CAACP,SAAV,EAAqB;QACnB,MAAM,IAAIE,kBAAJ,mDAA8DK,IAA9D,oEAAN;MACD;;MACD,IAAI,CAACX,MAAM,CAACE,IAAD,CAAN,CAAaS,IAAI,CAACP,SAAlB,CAAL,EAAmC;QACjC;MACD;;MACD,IAAMQ,UAAU,GAAGZ,MAAM,CAACE,IAAD,CAAN,CAAaS,IAAI,CAACP,SAAlB,CAAnB;MACA,IAAMS,KAAK,GAAGZ,OAAO,CAACW,UAAU,CAACE,MAAZ,CAAP,CAA2BF,UAAU,CAACG,cAAtC,CAAd;MACA,IAAMC,MAAM,GAAGH,KAAK,CAACD,UAAU,CAACK,WAAZ,CAAL,CAA8BL,UAAU,CAACM,KAAzC,CAAf;MAEA,qBAAcP,IAAd,EAAoB;QAACE,KAAK,EAALA,KAAD;QAAQG,MAAM,EAANA,MAAR;QAAgBd,IAAI,EAAEU,UAAU,CAACV;MAAjC,CAApB;IACD,CAZD;EAaD;AACF,CAhBD;;eAkBeL,S"}
|
package/src/analyzer/analyzer.js
DELETED
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import {forEach, isFinite, isArray} from 'lodash';
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ANALYSIS_STATS,
|
|
5
|
-
ANALYSIS_CHECKS
|
|
6
|
-
} from '../constants';
|
|
7
|
-
import ParameterError from '../common/errors/parameter';
|
|
8
|
-
|
|
9
|
-
const StatsAnalyzer = {};
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Can involve changing of the default plugin-meetings sdk for deeper results
|
|
13
|
-
* @param {Array} series of WebRTCData
|
|
14
|
-
* @param {Object} options
|
|
15
|
-
* @param {Array} options.analysisKeys [{key: 'bytesSent', check: 'increasing'}, {key: 'bytesReceived', check: 'increasing'}]
|
|
16
|
-
* @returns {Object} analysis {valid: true/false, failed: { key: [number] }, data: { webRtcKeyToAnalyze: { valid: true/false, reports: [ { value: number, valid: true/false, difference: number } ] } } }
|
|
17
|
-
* @public
|
|
18
|
-
*/
|
|
19
|
-
StatsAnalyzer.analyze = (series, options = {analysisKeys: ANALYSIS_STATS.DEFAULT_KEYS}) => {
|
|
20
|
-
if (!isArray(series) || !series.length || !options || !isArray(options.analysisKeys) || !options.analysisKeys.length) {
|
|
21
|
-
throw new ParameterError('analyzer->analyze#series must be defined as a nonempty array of WebRTCData objects, and options.analysisKeys must be a nonempty array of strings, representing the properties to analyze.');
|
|
22
|
-
}
|
|
23
|
-
const properties = new Set(options.analysisKeys);
|
|
24
|
-
const analysis = {valid: true, failed: {}, data: {}};
|
|
25
|
-
|
|
26
|
-
properties.forEach((config) => {
|
|
27
|
-
const property = config.key;
|
|
28
|
-
|
|
29
|
-
analysis.data[property] = {valid: true, reports: []};
|
|
30
|
-
analysis.failed[property] = [];
|
|
31
|
-
let previous = {value: 0};
|
|
32
|
-
let index = 0;
|
|
33
|
-
|
|
34
|
-
for (let i = series.length - 1; i > 0; i -= 1) {
|
|
35
|
-
const singular = {};
|
|
36
|
-
|
|
37
|
-
forEach(series[i].data.getData()[config.prop], (webrtcData) => { // eslint-disable-line
|
|
38
|
-
const value = webrtcData[property];
|
|
39
|
-
|
|
40
|
-
if (!value || !isFinite(value)) {
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
singular.value = value;
|
|
44
|
-
singular.difference = 0;
|
|
45
|
-
singular.valid = false;
|
|
46
|
-
singular.index = index;
|
|
47
|
-
singular.difference = singular.value - previous.value;
|
|
48
|
-
if (config.check === ANALYSIS_CHECKS.INCREASING && singular.difference > 0) {
|
|
49
|
-
singular.valid = true;
|
|
50
|
-
}
|
|
51
|
-
else if (config.check === ANALYSIS_CHECKS.DECREASING && singular.difference < 0) {
|
|
52
|
-
singular.valid = true;
|
|
53
|
-
}
|
|
54
|
-
else if (config.check === ANALYSIS_CHECKS.CONSTANT) {
|
|
55
|
-
singular.valid = true;
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
singular.valid = false;
|
|
59
|
-
}
|
|
60
|
-
if (!singular.valid) {
|
|
61
|
-
analysis.data[property].valid = false;
|
|
62
|
-
analysis.valid = false;
|
|
63
|
-
analysis.failed[property].push(i);
|
|
64
|
-
}
|
|
65
|
-
previous = singular;
|
|
66
|
-
analysis.data[property].reports.push(singular);
|
|
67
|
-
});
|
|
68
|
-
index += 1;
|
|
69
|
-
}
|
|
70
|
-
if (!analysis.data[property].valid) {
|
|
71
|
-
analysis.valid = false;
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
return analysis;
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export default StatsAnalyzer;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import {keys, isFinite} from 'lodash';
|
|
2
|
-
|
|
3
|
-
import {DEFAULT_EXCLUDED_STATS} from '../constants';
|
|
4
|
-
|
|
5
|
-
const StatsCalculator = {};
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Calculate an interval of values between 2 data points, using updated as the "latest" so updated - previous = interval
|
|
9
|
-
* @param {WebRTCData} previous
|
|
10
|
-
* @param {WebRTCData} updated
|
|
11
|
-
* @returns {Object} interval: {StringKey: IntervalValue, ..., n}
|
|
12
|
-
* @public
|
|
13
|
-
*/
|
|
14
|
-
StatsCalculator.difference = (previous, updated) => {
|
|
15
|
-
// if there was no previous, just take the updated
|
|
16
|
-
if (!previous || !previous.data || !previous.data.getData || keys(previous.data.getData()).length === 0) {
|
|
17
|
-
return updated;
|
|
18
|
-
}
|
|
19
|
-
const interval = {};
|
|
20
|
-
|
|
21
|
-
// get inside the data from the filtered report
|
|
22
|
-
keys(updated.data.getData()).forEach((key) => {
|
|
23
|
-
interval[key] = interval[key] ? interval[key] : {};
|
|
24
|
-
keys(updated.data.getData()[key]).forEach((stat) => {
|
|
25
|
-
let value = updated.data.getData()[key][stat];
|
|
26
|
-
|
|
27
|
-
// only use some simple data points that are numbers and aren't silly things like timestamp
|
|
28
|
-
if (isFinite(value) && !(DEFAULT_EXCLUDED_STATS.includes(stat) && value !== 0)) {
|
|
29
|
-
// if there was nothing there before, just return the updated data
|
|
30
|
-
if (!previous.data.getData()[key] || !previous.data.getData()[key][stat]) {
|
|
31
|
-
interval[key][stat] = value;
|
|
32
|
-
}
|
|
33
|
-
// subract and store
|
|
34
|
-
else {
|
|
35
|
-
value -= previous.data.getData()[key][stat];
|
|
36
|
-
interval[key][stat] = value;
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
return interval;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Calculate an aggregate of values between an old summary and a new data point, using summary as the base to add to so aggregate = summary + data
|
|
47
|
-
* @param {WebRTCData} data
|
|
48
|
-
* @param {Object} summary
|
|
49
|
-
* @returns {Object} aggregate {StringKey: SummedValue, ..., n}
|
|
50
|
-
* @public
|
|
51
|
-
*/
|
|
52
|
-
StatsCalculator.sum = (data, summary) => {
|
|
53
|
-
const aggregate = summary;
|
|
54
|
-
|
|
55
|
-
// get inside the data from the filtered report
|
|
56
|
-
keys(data.data.getData()).forEach((key) => {
|
|
57
|
-
keys(data.data.getData()[key]).forEach((stat) => {
|
|
58
|
-
const value = data.data.getData()[key][stat];
|
|
59
|
-
|
|
60
|
-
// only use some simple data points that are numbers and aren't silly things like timestamp
|
|
61
|
-
if (isFinite(value) && !(DEFAULT_EXCLUDED_STATS.includes(stat) && value !== 0)) {
|
|
62
|
-
// if there was something there before, add to that value
|
|
63
|
-
if (aggregate[key][stat]) {
|
|
64
|
-
aggregate[key][stat] += value;
|
|
65
|
-
}
|
|
66
|
-
// set up the value as the new data point
|
|
67
|
-
else {
|
|
68
|
-
aggregate[key][stat] = value;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
return aggregate;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export default StatsCalculator;
|