@webex/internal-plugin-metrics 3.0.0-beta.417 → 3.0.0-beta.418

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.
@@ -54,6 +54,7 @@ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
54
54
  key: "clearTimestamps",
55
55
  value: function clearTimestamps() {
56
56
  this.latencyTimestamps.clear();
57
+ this.precomputedLatencies.clear();
57
58
  }
58
59
 
59
60
  /**
@@ -83,7 +84,8 @@ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
83
84
  /**
84
85
  * Store timestamp value
85
86
  * @param key - key
86
- * @param value -value
87
+ * @param value - value
88
+ * @param options - store options
87
89
  * @throws
88
90
  * @returns
89
91
  */
@@ -113,33 +115,33 @@ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
113
115
  * Store precomputed latency value
114
116
  * @param key - key
115
117
  * @param value - value
116
- * @param overwrite - overwrite existing value or add it
118
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
117
119
  * @throws
118
120
  * @returns
119
121
  */
120
122
  }, {
121
123
  key: "saveLatency",
122
124
  value: function saveLatency(key, value) {
123
- var overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
124
- var existingValue = overwrite ? 0 : this.precomputedLatencies.get(key) || 0;
125
+ var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
126
+ var existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;
125
127
  this.precomputedLatencies.set(key, value + existingValue);
126
128
  }
127
129
 
128
130
  /**
129
131
  * Measure latency for a request
130
- * @param key - key
131
132
  * @param callback - callback for which you would like to measure latency
132
- * @param overwrite - overwite existing value or add to it
133
+ * @param key - key
134
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
133
135
  * @returns
134
136
  */
135
137
  }, {
136
138
  key: "measureLatency",
137
139
  value: function measureLatency(callback, key) {
138
140
  var _this2 = this;
139
- var overwrite = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
141
+ var accumulate = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
140
142
  var start = performance.now();
141
143
  return callback().finally(function () {
142
- _this2.saveLatency(key, performance.now() - start, overwrite);
144
+ _this2.saveLatency(key, performance.now() - start, accumulate);
143
145
  });
144
146
  }
145
147
 
@@ -522,8 +524,20 @@ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
522
524
  }
523
525
 
524
526
  /**
525
- * Total latency for all other app api requests.
527
+ * Get the latency for downloading intelligence models.
528
+ * @returns - latency
529
+ */
530
+ }, {
531
+ key: "getDownloadIntelligenceModelsReqResp",
532
+ value: function getDownloadIntelligenceModelsReqResp() {
533
+ var downloadIntelligenceModelsReqResp = this.precomputedLatencies.get('internal.api.fetch.intelligence.models');
534
+ return downloadIntelligenceModelsReqResp ? Math.floor(downloadIntelligenceModelsReqResp) : undefined;
535
+ }
536
+
537
+ /**
538
+ * Get the total latency for all other app API requests.
526
539
  * Excludes meeting info, because it's measured separately.
540
+ * @returns - latency
527
541
  */
528
542
  }, {
529
543
  key: "getOtherAppApiReqResp",
@@ -1 +1 @@
1
- {"version":3,"names":["CallDiagnosticLatencies","args","latencyTimestamps","precomputedLatencies","clear","meetingId","webex","meetings","meetingCollection","get","undefined","key","value","Date","getTime","options","setMeetingId","saveFirstTimestampOnly","set","overwrite","existingValue","callback","start","performance","now","finally","saveLatency","has","a","b","end","getDiffBetweenTimestamps","u2cLatency","Math","floor","interstitialJoinClickTimestamp","connectedMedia","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","reachablityClusterReqResp","exchangeCITokenJMT","refreshCaptchaReqResp","otherAppApiJMT","WebexPlugin"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport {MetricEventNames, PreComputedLatencies} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\n/**\n * @description Helper class to store latencies timestamp and to calculate various latencies for CA.\n * @exports\n * @class CallDiagnosticLatencies\n */\nexport default class CallDiagnosticLatencies extends WebexPlugin {\n latencyTimestamps: Map<MetricEventNames, number>;\n precomputedLatencies: Map<PreComputedLatencies, number>;\n // meetingId that the current latencies are for\n private meetingId?: string;\n\n /**\n * @constructor\n */\n constructor(...args) {\n super(...args);\n this.latencyTimestamps = new Map();\n this.precomputedLatencies = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n }\n\n /**\n * Associate current latencies with a meeting id\n * @param meetingId\n */\n private setMeetingId(meetingId: string) {\n this.meetingId = meetingId;\n }\n\n /**\n * Returns the meeting object associated with current latencies\n * @returns meeting object\n */\n private getMeeting() {\n if (this.meetingId) {\n // @ts-ignore\n return this.webex.meetings.meetingCollection.get(this.meetingId);\n }\n\n return undefined;\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n public saveTimestamp({\n key,\n value = new Date().getTime(),\n options = {},\n }: {\n key: MetricEventNames;\n value?: number;\n options?: {meetingId?: string};\n }) {\n // save the meetingId so we can use the meeting object in latency calculations if needed\n const {meetingId} = options;\n if (meetingId) {\n this.setMeetingId(meetingId);\n }\n // for some events we're only interested in the first timestamp not last\n // as these events can happen multiple times\n if (\n key === 'client.media.rx.start' ||\n key === 'client.media.tx.start' ||\n key === 'internal.client.meetinginfo.request' ||\n key === 'internal.client.meetinginfo.response'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n }\n }\n\n /**\n * Store precomputed latency value\n * @param key - key\n * @param value - value\n * @param overwrite - overwrite existing value or add it\n * @throws\n * @returns\n */\n public saveLatency(key: PreComputedLatencies, value: number, overwrite = true) {\n const existingValue = overwrite ? 0 : this.precomputedLatencies.get(key) || 0;\n this.precomputedLatencies.set(key, value + existingValue);\n }\n\n /**\n * Measure latency for a request\n * @param key - key\n * @param callback - callback for which you would like to measure latency\n * @param overwrite - overwite existing value or add to it\n * @returns\n */\n public measureLatency(\n callback: () => Promise<any>,\n key: PreComputedLatencies,\n overwrite = false\n ) {\n const start = performance.now();\n\n return callback().finally(() => {\n this.saveLatency(key, performance.now() - start, overwrite);\n });\n }\n\n /**\n * Store only the first timestamp value for the given key\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {\n if (this.latencyTimestamps.has(key)) {\n return;\n }\n this.latencyTimestamps.set(key, value);\n }\n\n /**\n * Helper to calculate end - start\n * @param a start\n * @param b end\n * @returns latency\n */\n public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n if (start && end) {\n return end - start;\n }\n\n return undefined;\n }\n\n /**\n * Meeting Info Request\n * @note Meeting Info request happen not just in the join phase. CA requires\n * metrics around meeting info request that are only part of join phase.\n * This internal.* event is used to track the real timestamps\n * (when the actual request/response happen). This is because the actual CA event is\n * sent inside the join method on the meeting object based on some logic, but that's not exactly when\n * those events are actually fired. The logic only confirms that they have happened, and we send them over.\n * @returns - latency\n */\n public getMeetingInfoReqResp() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meetinginfo.request',\n 'internal.client.meetinginfo.response'\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'client.interstitial-window.start-launch',\n 'internal.client.interstitial-window.click.joinbutton'\n );\n }\n\n /**\n * getU2CTime\n * @returns - latency\n */\n public getU2CTime() {\n const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');\n\n return u2cLatency ? Math.floor(u2cLatency) : undefined;\n }\n\n /**\n * Device Register Time\n * @returns - latency\n */\n public getRegisterWDMDeviceJMT() {\n return this.getDiffBetweenTimestamps(\n 'internal.register.device.request',\n 'internal.register.device.response'\n );\n }\n\n /**\n * Call Init Join Request\n * @returns - latency\n */\n public getCallInitJoinReq() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.request'\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');\n }\n\n /**\n * Time taken to do turn discovery\n * @returns - latency\n */\n public getTurnDiscoveryTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.add-media.turn-discovery.start',\n 'internal.client.add-media.turn-discovery.end'\n );\n }\n\n /**\n * Local SDP Generated Remote SDP REceived\n * @returns - latency\n */\n public getLocalSDPGenRemoteSDPRecv() {\n return this.getDiffBetweenTimestamps(\n 'client.media-engine.local-sdp-generated',\n 'client.media-engine.remote-sdp-received'\n );\n }\n\n /**\n * ICE Setup Time\n * @returns - latency\n */\n public getICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Audio ICE time\n * @returns - latency\n */\n public getAudioICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Video ICE Time\n * @returns - latency\n */\n public getVideoICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Share ICE Time\n * @returns - latency\n */\n public getShareICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Stay Lobby Time\n * @returns - latency\n */\n public getStayLobbyTime() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.response',\n 'internal.host.meeting.participant.admitted'\n );\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n return this.precomputedLatencies.get('internal.download.time') || undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)\n if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'internal.client.meeting.interstitial-window.showed'\n );\n }\n\n // for cross launch and guest flows\n return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialJoinClickTimestamp = this.latencyTimestamps.get(\n 'internal.client.interstitial-window.click.joinbutton'\n );\n\n // get the first timestamp\n const connectedMedia = this.latencyTimestamps.get('client.ice.end');\n\n const lobbyTime = this.getStayLobbyTime() || 0;\n\n if (interstitialJoinClickTimestamp && connectedMedia) {\n return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Total JMT\n * @returns - latency\n */\n public getTotalJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n\n if (clickToInterstitial && interstitialToJoinOk) {\n return clickToInterstitial + interstitialToJoinOk;\n }\n\n return undefined;\n }\n\n /**\n * Join Conf JMT\n * @returns - latency\n */\n public getJoinConfJMT() {\n const joinReqResp = this.getJoinReqResp();\n const ICESetupTime = this.getICESetupTime();\n\n if (joinReqResp && ICESetupTime) {\n return joinReqResp + ICESetupTime;\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT\n * @returns - latency\n */\n public getTotalMediaJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n const lobbyTime = this.getStayLobbyTime();\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;\n if (this.getMeeting()?.allowMediaInLobby) {\n return totalMediaJMT;\n }\n\n return totalMediaJMT - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (interstitialToJoinOk && joinConfJMT) {\n return interstitialToJoinOk - joinConfJMT;\n }\n\n return undefined;\n }\n\n /**\n * Audio setup delay receive\n */\n public getAudioJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Video setup delay receive\n */\n public getVideoJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Total latency for all get cluster request.\n */\n public getReachabilityClustersReqResp() {\n const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');\n\n return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;\n }\n\n /**\n * Audio setup delay transmit\n */\n public getAudioJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Video setup delay transmit\n */\n public getVideoJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Total latency for all exchange ci token.\n */\n public getExchangeCITokenJMT() {\n const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');\n\n return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;\n }\n\n /**\n * Total latency for all refresh captcha requests.\n */\n public getRefreshCaptchaReqResp() {\n const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');\n\n return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;\n }\n\n /**\n * Total latency for all other app api requests.\n * Excludes meeting info, because it's measured separately.\n */\n public getOtherAppApiReqResp() {\n const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');\n\n return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["CallDiagnosticLatencies","args","latencyTimestamps","precomputedLatencies","clear","meetingId","webex","meetings","meetingCollection","get","undefined","key","value","Date","getTime","options","setMeetingId","saveFirstTimestampOnly","set","accumulate","existingValue","callback","start","performance","now","finally","saveLatency","has","a","b","end","getDiffBetweenTimestamps","u2cLatency","Math","floor","interstitialJoinClickTimestamp","connectedMedia","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","reachablityClusterReqResp","exchangeCITokenJMT","refreshCaptchaReqResp","downloadIntelligenceModelsReqResp","otherAppApiJMT","WebexPlugin"],"sources":["call-diagnostic-metrics-latencies.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport {MetricEventNames, PreComputedLatencies} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\n/**\n * @description Helper class to store latencies timestamp and to calculate various latencies for CA.\n * @exports\n * @class CallDiagnosticLatencies\n */\nexport default class CallDiagnosticLatencies extends WebexPlugin {\n latencyTimestamps: Map<MetricEventNames, number>;\n precomputedLatencies: Map<PreComputedLatencies, number>;\n // meetingId that the current latencies are for\n private meetingId?: string;\n\n /**\n * @constructor\n */\n constructor(...args) {\n super(...args);\n this.latencyTimestamps = new Map();\n this.precomputedLatencies = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n this.precomputedLatencies.clear();\n }\n\n /**\n * Associate current latencies with a meeting id\n * @param meetingId\n */\n private setMeetingId(meetingId: string) {\n this.meetingId = meetingId;\n }\n\n /**\n * Returns the meeting object associated with current latencies\n * @returns meeting object\n */\n private getMeeting() {\n if (this.meetingId) {\n // @ts-ignore\n return this.webex.meetings.meetingCollection.get(this.meetingId);\n }\n\n return undefined;\n }\n\n /**\n * Store timestamp value\n * @param key - key\n * @param value - value\n * @param options - store options\n * @throws\n * @returns\n */\n public saveTimestamp({\n key,\n value = new Date().getTime(),\n options = {},\n }: {\n key: MetricEventNames;\n value?: number;\n options?: {meetingId?: string};\n }) {\n // save the meetingId so we can use the meeting object in latency calculations if needed\n const {meetingId} = options;\n if (meetingId) {\n this.setMeetingId(meetingId);\n }\n // for some events we're only interested in the first timestamp not last\n // as these events can happen multiple times\n if (\n key === 'client.media.rx.start' ||\n key === 'client.media.tx.start' ||\n key === 'internal.client.meetinginfo.request' ||\n key === 'internal.client.meetinginfo.response'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n }\n }\n\n /**\n * Store precomputed latency value\n * @param key - key\n * @param value - value\n * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement\n * @throws\n * @returns\n */\n public saveLatency(key: PreComputedLatencies, value: number, accumulate = false) {\n const existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;\n this.precomputedLatencies.set(key, value + existingValue);\n }\n\n /**\n * Measure latency for a request\n * @param callback - callback for which you would like to measure latency\n * @param key - key\n * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement\n * @returns\n */\n public measureLatency(\n callback: () => Promise<unknown>,\n key: PreComputedLatencies,\n accumulate = false\n ) {\n const start = performance.now();\n\n return callback().finally(() => {\n this.saveLatency(key, performance.now() - start, accumulate);\n });\n }\n\n /**\n * Store only the first timestamp value for the given key\n * @param key - key\n * @param value -value\n * @throws\n * @returns\n */\n saveFirstTimestampOnly(key: MetricEventNames, value: number = new Date().getTime()) {\n if (this.latencyTimestamps.has(key)) {\n return;\n }\n this.latencyTimestamps.set(key, value);\n }\n\n /**\n * Helper to calculate end - start\n * @param a start\n * @param b end\n * @returns latency\n */\n public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n if (start && end) {\n return end - start;\n }\n\n return undefined;\n }\n\n /**\n * Meeting Info Request\n * @note Meeting Info request happen not just in the join phase. CA requires\n * metrics around meeting info request that are only part of join phase.\n * This internal.* event is used to track the real timestamps\n * (when the actual request/response happen). This is because the actual CA event is\n * sent inside the join method on the meeting object based on some logic, but that's not exactly when\n * those events are actually fired. The logic only confirms that they have happened, and we send them over.\n * @returns - latency\n */\n public getMeetingInfoReqResp() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meetinginfo.request',\n 'internal.client.meetinginfo.response'\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'client.interstitial-window.start-launch',\n 'internal.client.interstitial-window.click.joinbutton'\n );\n }\n\n /**\n * getU2CTime\n * @returns - latency\n */\n public getU2CTime() {\n const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');\n\n return u2cLatency ? Math.floor(u2cLatency) : undefined;\n }\n\n /**\n * Device Register Time\n * @returns - latency\n */\n public getRegisterWDMDeviceJMT() {\n return this.getDiffBetweenTimestamps(\n 'internal.register.device.request',\n 'internal.register.device.response'\n );\n }\n\n /**\n * Call Init Join Request\n * @returns - latency\n */\n public getCallInitJoinReq() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.request'\n );\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');\n }\n\n /**\n * Time taken to do turn discovery\n * @returns - latency\n */\n public getTurnDiscoveryTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.add-media.turn-discovery.start',\n 'internal.client.add-media.turn-discovery.end'\n );\n }\n\n /**\n * Local SDP Generated Remote SDP REceived\n * @returns - latency\n */\n public getLocalSDPGenRemoteSDPRecv() {\n return this.getDiffBetweenTimestamps(\n 'client.media-engine.local-sdp-generated',\n 'client.media-engine.remote-sdp-received'\n );\n }\n\n /**\n * ICE Setup Time\n * @returns - latency\n */\n public getICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Audio ICE time\n * @returns - latency\n */\n public getAudioICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Video ICE Time\n * @returns - latency\n */\n public getVideoICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Share ICE Time\n * @returns - latency\n */\n public getShareICESetupTime() {\n return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');\n }\n\n /**\n * Stay Lobby Time\n * @returns - latency\n */\n public getStayLobbyTime() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.response',\n 'internal.host.meeting.participant.admitted'\n );\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n return this.precomputedLatencies.get('internal.download.time') || undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)\n if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.click.joinbutton',\n 'internal.client.meeting.interstitial-window.showed'\n );\n }\n\n // for cross launch and guest flows\n return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.locus.join.response'\n );\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.interstitial-window.click.joinbutton',\n 'client.media-engine.ready'\n );\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialJoinClickTimestamp = this.latencyTimestamps.get(\n 'internal.client.interstitial-window.click.joinbutton'\n );\n\n // get the first timestamp\n const connectedMedia = this.latencyTimestamps.get('client.ice.end');\n\n const lobbyTime = this.getStayLobbyTime() || 0;\n\n if (interstitialJoinClickTimestamp && connectedMedia) {\n return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Total JMT\n * @returns - latency\n */\n public getTotalJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n\n if (clickToInterstitial && interstitialToJoinOk) {\n return clickToInterstitial + interstitialToJoinOk;\n }\n\n return undefined;\n }\n\n /**\n * Join Conf JMT\n * @returns - latency\n */\n public getJoinConfJMT() {\n const joinReqResp = this.getJoinReqResp();\n const ICESetupTime = this.getICESetupTime();\n\n if (joinReqResp && ICESetupTime) {\n return joinReqResp + ICESetupTime;\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT\n * @returns - latency\n */\n public getTotalMediaJMT() {\n const clickToInterstitial = this.getClickToInterstitial();\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n const lobbyTime = this.getStayLobbyTime();\n\n if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {\n const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;\n if (this.getMeeting()?.allowMediaInLobby) {\n return totalMediaJMT;\n }\n\n return totalMediaJMT - lobbyTime;\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const interstitialToJoinOk = this.getInterstitialToJoinOK();\n const joinConfJMT = this.getJoinConfJMT();\n\n if (interstitialToJoinOk && joinConfJMT) {\n return interstitialToJoinOk - joinConfJMT;\n }\n\n return undefined;\n }\n\n /**\n * Audio setup delay receive\n */\n public getAudioJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Video setup delay receive\n */\n public getVideoJoinRespRxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.rx.start');\n }\n\n /**\n * Total latency for all get cluster request.\n */\n public getReachabilityClustersReqResp() {\n const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');\n\n return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;\n }\n\n /**\n * Audio setup delay transmit\n */\n public getAudioJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Video setup delay transmit\n */\n public getVideoJoinRespTxStart() {\n return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');\n }\n\n /**\n * Total latency for all exchange ci token.\n */\n public getExchangeCITokenJMT() {\n const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');\n\n return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;\n }\n\n /**\n * Total latency for all refresh captcha requests.\n */\n public getRefreshCaptchaReqResp() {\n const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');\n\n return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;\n }\n\n /**\n * Get the latency for downloading intelligence models.\n * @returns - latency\n */\n public getDownloadIntelligenceModelsReqResp() {\n const downloadIntelligenceModelsReqResp = this.precomputedLatencies.get(\n 'internal.api.fetch.intelligence.models'\n );\n\n return downloadIntelligenceModelsReqResp\n ? Math.floor(downloadIntelligenceModelsReqResp)\n : undefined;\n }\n\n /**\n * Get the total latency for all other app API requests.\n * Excludes meeting info, because it's measured separately.\n * @returns - latency\n */\n public getOtherAppApiReqResp() {\n const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');\n\n return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;\n }\n}\n"],"mappings":"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"}
@@ -234,6 +234,7 @@ var prepareDiagnosticMetricItem = function prepareDiagnosticMetricItem(webex, it
234
234
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
235
235
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
236
236
  joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
237
+ joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
237
238
  break;
238
239
  case 'client.call.initiated':
239
240
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","isMeetingInfoServiceError","rawError","body","data","meetingInfo","url","includes","WBX_APP_API_URL","isNetworkError","WebexHttpError","NetworkOrCORSError","isUnauthorizedError","Unauthorized","isSdpOfferCreationError","name","ERROR_DESCRIPTIONS","SDP_OFFER_CREATION_ERROR","isBrowserMediaErrorName","errorName","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","getBuildType","webClientDomain","markAsTestEvent","prepareDiagnosticMetricItem","webex","item","origin","buildType","exports","eventPayload","event","eventData","networkType","eventName","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","downloadTime","getDownloadTimeJMT","otherAppApiReqResp","getOtherAppApiReqResp","exchangeCITokenJMT","getExchangeCITokenJMT","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","refreshCaptchaServiceReqResp","getRefreshCaptchaReqResp","showInterstitialTime","getShowInterstitialTime","registerWDMDeviceJMT","getRegisterWDMDeviceJMT","getU2CTime","getReachabilityClustersReqResp","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","logger","log","latencies","Object","fromEntries","latencyTimestamps","setMetricTimings","options","json","JSON","parse","now","Date","toISOString","metrics","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion","generateClientErrorCodeForIceFailure","signalingState","iceConnectionState","turnServerUsed","ICE_FAILURE_CLIENT_CODE","MISSING_ROAP_ANSWER_CLIENT_CODE","DTLS_HANDSHAKE_FAILED_CLIENT_CODE","ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE","ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {WebexHttpError} from '@webex/webex-core';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\nimport {\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n DTLS_HANDSHAKE_FAILED_CLIENT_CODE,\n ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,\n ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,\n ICE_FAILURE_CLIENT_CODE,\n MISSING_ROAP_ANSWER_CLIENT_CODE,\n WBX_APP_API_URL,\n ERROR_DESCRIPTIONS,\n} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns {boolean}\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * MeetingInfo errors sometimes has body.data.meetingInfo object\n * MeetingInfo errors come with a wbxappapi url\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isMeetingInfoServiceError = (rawError: any) => {\n if (rawError.body?.data?.meetingInfo || rawError.body?.url?.includes(WBX_APP_API_URL)) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the raw error is a network related error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isNetworkError = (rawError: any) => {\n if (rawError instanceof WebexHttpError.NetworkOrCORSError) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the error is an unauthorized error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isUnauthorizedError = (rawError: any) => {\n if (rawError instanceof WebexHttpError.Unauthorized) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the error is an SdpOfferCreation error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isSdpOfferCreationError = (rawError: any) => {\n // would LIKE to do rawError instanceof Errors.SdpOfferCreationError\n // but including internal-media-core in plugin-metrics breaks meetings and metrics unit tests\n if (rawError.name === ERROR_DESCRIPTIONS.SDP_OFFER_CREATION_ERROR) {\n return true;\n }\n\n return false;\n};\n\n/**\n * MDN Media Devices getUserMedia() method returns a name if it errs\n * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n *\n * @param errorCode\n * @returns\n */\nexport const isBrowserMediaErrorName = (errorName: any) => {\n if (BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[errorName]) {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (\n webClientDomain,\n markAsTestEvent = false\n): Event['origin']['buildType'] => {\n // used temporary to test pre join in production without creating noise data, SPARK-468456\n if (markAsTestEvent) {\n return 'test';\n }\n\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: exports.getBuildType(\n item.eventPayload?.event?.eventData?.webClientDomain,\n item.eventPayload?.event?.eventData?.markAsTestEvent\n ),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.webexapp.launched':\n joinTimes.downloadTime = cdl.getDownloadTimeJMT();\n break;\n case 'client.login.end':\n joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();\n joinTimes.exchangeCITokenJMT = cdl.getExchangeCITokenJMT();\n break;\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();\n joinTimes.getU2CTime = cdl.getU2CTime();\n joinTimes.getReachabilityClustersReqResp = cdl.getReachabilityClustersReqResp();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n joinTimes.downloadTime = cdl.getDownloadTimeJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n // @ts-ignore\n webex.logger.log(\n `CallDiagnosticLatencies,prepareDiagnosticMetricItem: ${JSON.stringify({\n latencies: Object.fromEntries(cdl.latencyTimestamps),\n event: item,\n })}`\n );\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body && options.json) {\n const body = JSON.parse(options.body);\n\n const now = new Date().toISOString();\n body.metrics?.forEach((metric) => {\n if (metric.eventPayload) {\n // The event will effectively be triggered and sent at the same time.\n // The existing triggered time is from when the options were built.\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n options.body = JSON.stringify(body);\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n\n/**\n * Generates client error codes for specific ice failures\n * that happen when trying to add media in a meeting.\n */\nexport const generateClientErrorCodeForIceFailure = ({\n signalingState,\n iceConnectionState,\n turnServerUsed,\n}: {\n signalingState: RTCPeerConnection['signalingState'];\n iceConnectionState: RTCPeerConnection['iceConnectionState'];\n turnServerUsed: boolean;\n}) => {\n let errorCode = ICE_FAILURE_CLIENT_CODE; // default;\n\n if (signalingState === 'have-local-offer') {\n errorCode = MISSING_ROAP_ANSWER_CLIENT_CODE;\n }\n\n if (signalingState === 'stable' && iceConnectionState === 'connected') {\n errorCode = DTLS_HANDSHAKE_FAILED_CLIENT_CODE;\n }\n\n if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected') {\n if (turnServerUsed) {\n errorCode = ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE;\n } else {\n errorCode = ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE;\n }\n }\n\n return errorCode;\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","userAgentToString","clientName","webexVersion","userAgentOption","browserInfo","clientInfo","util","format","indexOf","toLowerCase","split","osInfo","process","env","NODE_ENV","clearEmptyKeysRecursively","obj","length","forEach","key","filter","x","isLocusServiceErrorCode","errorCode","code","charAt","isMeetingInfoServiceError","rawError","body","data","meetingInfo","url","includes","WBX_APP_API_URL","isNetworkError","WebexHttpError","NetworkOrCORSError","isUnauthorizedError","Unauthorized","isSdpOfferCreationError","name","ERROR_DESCRIPTIONS","SDP_OFFER_CREATION_ERROR","isBrowserMediaErrorName","errorName","BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP","getBuildType","webClientDomain","markAsTestEvent","prepareDiagnosticMetricItem","webex","item","origin","buildType","exports","eventPayload","event","eventData","networkType","eventName","joinTimes","audioSetupDelay","videoSetupDelay","cdl","internal","newMetrics","callDiagnosticLatencies","downloadTime","getDownloadTimeJMT","otherAppApiReqResp","getOtherAppApiReqResp","exchangeCITokenJMT","getExchangeCITokenJMT","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","refreshCaptchaServiceReqResp","getRefreshCaptchaReqResp","downloadIntelligenceModelsReqResp","getDownloadIntelligenceModelsReqResp","showInterstitialTime","getShowInterstitialTime","registerWDMDeviceJMT","getRegisterWDMDeviceJMT","getU2CTime","getReachabilityClustersReqResp","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","pageJmt","getPageJMT","interstitialToJoinOK","getInterstitialToJoinOK","totalJmt","getTotalJMT","clientJmt","getClientJMT","ICESetupTime","getICESetupTime","audioICESetupTime","getAudioICESetupTime","videoICESetupTime","getVideoICESetupTime","shareICESetupTime","getShareICESetupTime","localSDPGenRemoteSDPRecv","getLocalSDPGenRemoteSDPRecv","totalMediaJMT","getTotalMediaJMT","interstitialToMediaOKJMT","getInterstitialToMediaOKJMT","callInitMediaEngineReady","getCallInitMediaEngineReady","stayLobbyTime","getStayLobbyTime","joinRespRxStart","getAudioJoinRespRxStart","joinRespTxStart","getAudioJoinRespTxStart","getVideoJoinRespRxStart","getVideoJoinRespTxStart","logger","log","latencies","Object","fromEntries","latencyTimestamps","setMetricTimings","options","json","JSON","parse","now","Date","toISOString","metrics","metric","originTime","triggered","sent","extractVersionMetadata","version","majorVersion","minorVersion","generateClientErrorCodeForIceFailure","signalingState","iceConnectionState","turnServerUsed","ICE_FAILURE_CLIENT_CODE","MISSING_ROAP_ANSWER_CLIENT_CODE","DTLS_HANDSHAKE_FAILED_CLIENT_CODE","ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE","ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE"],"sources":["call-diagnostic-metrics.util.ts"],"sourcesContent":["/* eslint-disable valid-jsdoc */\nimport anonymize from 'ip-anonymize';\nimport util from 'util';\n\nimport {BrowserDetection} from '@webex/common';\nimport {WebexHttpError} from '@webex/webex-core';\nimport {isEmpty, merge} from 'lodash';\nimport {\n ClientEvent,\n Event,\n MediaQualityEventAudioSetupDelayPayload,\n MediaQualityEventVideoSetupDelayPayload,\n MetricEventNames,\n} from '../metrics.types';\nimport {\n BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,\n DTLS_HANDSHAKE_FAILED_CLIENT_CODE,\n ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE,\n ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,\n ICE_FAILURE_CLIENT_CODE,\n MISSING_ROAP_ANSWER_CLIENT_CODE,\n WBX_APP_API_URL,\n ERROR_DESCRIPTIONS,\n} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport const anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\n/**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\nexport const userAgentToString = ({clientName, webexVersion}) => {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !== -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${webexVersion}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${webexVersion}`);\n};\n\n/**\n * Iterates object recursively and removes any\n * property that returns isEmpty for it's associated value\n * isEmpty = implementation from Lodash.\n *\n * It modifies the object in place (mutable)\n *\n * @param obj - input\n * @returns\n */\nexport const clearEmptyKeysRecursively = (obj: any) => {\n // Check if the object is empty\n if (Object.keys(obj).length === 0) {\n return;\n }\n\n Object.keys(obj).forEach((key) => {\n if (\n (typeof obj[key] === 'object' || typeof obj[key] === 'string' || Array.isArray(obj[key])) &&\n isEmpty(obj[key])\n ) {\n delete obj[key];\n }\n if (Array.isArray(obj[key])) {\n obj[key] = [...obj[key].filter((x) => !!x)];\n }\n if (typeof obj[key] === 'object') {\n clearEmptyKeysRecursively(obj[key]);\n }\n });\n};\n\n/**\n * Locus error codes start with 2. The next three digits are the\n * HTTP status code related to the error code (like 400, 403, 502, etc.)\n * The remaining three digits are just an increasing integer.\n * If it is 7 digits and starts with a 2, it is locus.\n *\n * @param errorCode\n * @returns {boolean}\n */\nexport const isLocusServiceErrorCode = (errorCode: string | number) => {\n const code = `${errorCode}`;\n\n if (code.length === 7 && code.charAt(0) === '2') {\n return true;\n }\n\n return false;\n};\n\n/**\n * MeetingInfo errors sometimes has body.data.meetingInfo object\n * MeetingInfo errors come with a wbxappapi url\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isMeetingInfoServiceError = (rawError: any) => {\n if (rawError.body?.data?.meetingInfo || rawError.body?.url?.includes(WBX_APP_API_URL)) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the raw error is a network related error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isNetworkError = (rawError: any) => {\n if (rawError instanceof WebexHttpError.NetworkOrCORSError) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the error is an unauthorized error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isUnauthorizedError = (rawError: any) => {\n if (rawError instanceof WebexHttpError.Unauthorized) {\n return true;\n }\n\n return false;\n};\n\n/**\n * Returns true if the error is an SdpOfferCreation error\n *\n * @param {Object} rawError\n * @returns {boolean}\n */\nexport const isSdpOfferCreationError = (rawError: any) => {\n // would LIKE to do rawError instanceof Errors.SdpOfferCreationError\n // but including internal-media-core in plugin-metrics breaks meetings and metrics unit tests\n if (rawError.name === ERROR_DESCRIPTIONS.SDP_OFFER_CREATION_ERROR) {\n return true;\n }\n\n return false;\n};\n\n/**\n * MDN Media Devices getUserMedia() method returns a name if it errs\n * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia\n *\n * @param errorCode\n * @returns\n */\nexport const isBrowserMediaErrorName = (errorName: any) => {\n if (BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[errorName]) {\n return true;\n }\n\n return false;\n};\n\n/**\n * @param webClientDomain\n * @returns\n */\nexport const getBuildType = (\n webClientDomain,\n markAsTestEvent = false\n): Event['origin']['buildType'] => {\n // used temporary to test pre join in production without creating noise data, SPARK-468456\n if (markAsTestEvent) {\n return 'test';\n }\n\n if (\n webClientDomain?.includes('localhost') ||\n webClientDomain?.includes('127.0.0.1') ||\n process.env.NODE_ENV !== 'production'\n ) {\n return 'test';\n }\n\n return 'prod';\n};\n\n/**\n * Prepare metric item for submission.\n * @param {Object} webex sdk instance\n * @param {Object} item\n * @returns {Object} prepared item\n */\nexport const prepareDiagnosticMetricItem = (webex: any, item: any) => {\n const origin: Partial<Event['origin']> = {\n buildType: exports.getBuildType(\n item.eventPayload?.event?.eventData?.webClientDomain,\n item.eventPayload?.event?.eventData?.markAsTestEvent\n ),\n networkType: 'unknown',\n };\n\n // check event names and append latencies?\n const eventName = item.eventPayload?.event?.name as MetricEventNames;\n const joinTimes: ClientEvent['payload']['joinTimes'] = {};\n const audioSetupDelay: MediaQualityEventAudioSetupDelayPayload = {};\n const videoSetupDelay: MediaQualityEventVideoSetupDelayPayload = {};\n\n const cdl = webex.internal.newMetrics.callDiagnosticLatencies;\n\n switch (eventName) {\n case 'client.webexapp.launched':\n joinTimes.downloadTime = cdl.getDownloadTimeJMT();\n break;\n case 'client.login.end':\n joinTimes.otherAppApiReqResp = cdl.getOtherAppApiReqResp();\n joinTimes.exchangeCITokenJMT = cdl.getExchangeCITokenJMT();\n break;\n case 'client.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();\n joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();\n joinTimes.getU2CTime = cdl.getU2CTime();\n joinTimes.getReachabilityClustersReqResp = cdl.getReachabilityClustersReqResp();\n break;\n\n case 'client.locus.join.response':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.callInitJoinReq = cdl.getCallInitJoinReq();\n joinTimes.joinReqResp = cdl.getJoinReqResp();\n joinTimes.pageJmt = cdl.getPageJMT();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n joinTimes.interstitialToJoinOK = cdl.getInterstitialToJoinOK();\n joinTimes.totalJmt = cdl.getTotalJMT();\n joinTimes.clientJmt = cdl.getClientJMT();\n joinTimes.downloadTime = cdl.getDownloadTimeJMT();\n break;\n\n case 'client.ice.end':\n joinTimes.ICESetupTime = cdl.getICESetupTime();\n joinTimes.audioICESetupTime = cdl.getAudioICESetupTime();\n joinTimes.videoICESetupTime = cdl.getVideoICESetupTime();\n joinTimes.shareICESetupTime = cdl.getShareICESetupTime();\n break;\n\n case 'client.media.rx.start':\n joinTimes.localSDPGenRemoteSDPRecv = cdl.getLocalSDPGenRemoteSDPRecv();\n break;\n\n case 'client.media-engine.ready':\n joinTimes.totalMediaJMT = cdl.getTotalMediaJMT();\n joinTimes.interstitialToMediaOKJMT = cdl.getInterstitialToMediaOKJMT();\n joinTimes.callInitMediaEngineReady = cdl.getCallInitMediaEngineReady();\n joinTimes.stayLobbyTime = cdl.getStayLobbyTime();\n break;\n\n case 'client.mediaquality.event':\n audioSetupDelay.joinRespRxStart = cdl.getAudioJoinRespRxStart();\n audioSetupDelay.joinRespTxStart = cdl.getAudioJoinRespTxStart();\n videoSetupDelay.joinRespRxStart = cdl.getVideoJoinRespRxStart();\n videoSetupDelay.joinRespTxStart = cdl.getVideoJoinRespTxStart();\n }\n\n if (!isEmpty(joinTimes)) {\n item.eventPayload.event = merge(item.eventPayload.event, {joinTimes});\n }\n\n if (!isEmpty(audioSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {audioSetupDelay});\n }\n\n if (!isEmpty(videoSetupDelay)) {\n item.eventPayload.event = merge(item.eventPayload.event, {videoSetupDelay});\n }\n\n item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);\n\n // @ts-ignore\n webex.logger.log(\n `CallDiagnosticLatencies,prepareDiagnosticMetricItem: ${JSON.stringify({\n latencies: Object.fromEntries(cdl.latencyTimestamps),\n event: item,\n })}`\n );\n\n return item;\n};\n\n/**\n * Sets the originTime value(s) before the request/fetch.\n * This function is only useful if you are about to submit a metrics\n * request using pre-built fetch options;\n *\n * @param {any} options\n * @returns {any} the updated options object\n */\nexport const setMetricTimings = (options) => {\n if (options.body && options.json) {\n const body = JSON.parse(options.body);\n\n const now = new Date().toISOString();\n body.metrics?.forEach((metric) => {\n if (metric.eventPayload) {\n // The event will effectively be triggered and sent at the same time.\n // The existing triggered time is from when the options were built.\n metric.eventPayload.originTime = {\n triggered: now,\n sent: now,\n };\n }\n });\n options.body = JSON.stringify(body);\n }\n\n return options;\n};\n\nexport const extractVersionMetadata = (version: string) => {\n // extract major and minor version\n const [majorVersion, minorVersion] = version.split('.');\n\n return {\n majorVersion: parseInt(majorVersion, 10),\n minorVersion: parseInt(minorVersion, 10),\n };\n};\n\n/**\n * Generates client error codes for specific ice failures\n * that happen when trying to add media in a meeting.\n */\nexport const generateClientErrorCodeForIceFailure = ({\n signalingState,\n iceConnectionState,\n turnServerUsed,\n}: {\n signalingState: RTCPeerConnection['signalingState'];\n iceConnectionState: RTCPeerConnection['iceConnectionState'];\n turnServerUsed: boolean;\n}) => {\n let errorCode = ICE_FAILURE_CLIENT_CODE; // default;\n\n if (signalingState === 'have-local-offer') {\n errorCode = MISSING_ROAP_ANSWER_CLIENT_CODE;\n }\n\n if (signalingState === 'stable' && iceConnectionState === 'connected') {\n errorCode = DTLS_HANDSHAKE_FAILED_CLIENT_CODE;\n }\n\n if (signalingState !== 'have-local-offer' && iceConnectionState !== 'connected') {\n if (turnServerUsed) {\n errorCode = ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE;\n } else {\n errorCode = ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE;\n }\n }\n\n return errorCode;\n};\n"],"mappings":"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"}
package/dist/metrics.js CHANGED
@@ -165,7 +165,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
165
165
  });
166
166
  });
167
167
  },
168
- version: "3.0.0-beta.417"
168
+ version: "3.0.0-beta.418"
169
169
  });
170
170
  var _default = Metrics;
171
171
  exports.default = _default;
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {\n ClientEvent as RawClientEvent,\n Event as RawEvent,\n MediaQualityEvent as RawMediaQualityEvent,\n} from '@webex/event-dictionary-ts';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type EnvironmentType = NonNullable<RawEvent['origin']['environment']>;\n\nexport type NewEnvironmentType = NonNullable<RawEvent['origin']['newEnvironment']>;\n\nexport type ClientLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['clientLaunchMethod'];\n\nexport type BrowserLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['browserLaunchMethod'];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n correlationId?: string;\n preLoginId?: string;\n environment?: EnvironmentType;\n newEnvironmentType?: NewEnvironmentType;\n clientLaunchMethod?: ClientLaunchMethodType;\n browserLaunchMethod?: BrowserLaunchMethodType;\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.register.device.request'\n | 'internal.register.device.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton'\n | 'internal.client.add-media.turn-discovery.start'\n | 'internal.client.add-media.turn-discovery.end';\n\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientSubServiceType = ClientEvent['payload']['webexSubServiceType'];\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\nexport type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];\nexport type ClientEventPayloadError = ClientEvent['payload']['errors'];\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type PreComputedLatencies =\n | 'internal.client.pageJMT'\n | 'internal.download.time'\n | 'internal.get.cluster.time'\n | 'internal.click.to.interstitial'\n | 'internal.refresh.captcha.time'\n | 'internal.exchange.ci.token.time'\n | 'internal.get.u2c.time'\n | 'internal.call.init.join.req'\n | 'internal.other.app.api.time';\n"],"mappings":""}
1
+ {"version":3,"names":[],"sources":["metrics.types.ts"],"sourcesContent":["import {\n ClientEvent as RawClientEvent,\n Event as RawEvent,\n MediaQualityEvent as RawMediaQualityEvent,\n} from '@webex/event-dictionary-ts';\n\nexport type Event = Omit<RawEvent, 'event'> & {event: RawClientEvent | RawMediaQualityEvent};\n\nexport type ClientEventError = NonNullable<RawClientEvent['errors']>[0];\n\nexport type EnvironmentType = NonNullable<RawEvent['origin']['environment']>;\n\nexport type NewEnvironmentType = NonNullable<RawEvent['origin']['newEnvironment']>;\n\nexport type ClientLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['clientLaunchMethod'];\n\nexport type BrowserLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['browserLaunchMethod'];\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n correlationId?: string;\n preLoginId?: string;\n environment?: EnvironmentType;\n newEnvironmentType?: NewEnvironmentType;\n clientLaunchMethod?: ClientLaunchMethodType;\n browserLaunchMethod?: BrowserLaunchMethodType;\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n};\n\nexport type SubmitMQEOptions = {\n meetingId: string;\n mediaConnections?: any[];\n networkType?: Event['origin']['networkType'];\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n};\n\nexport type InternalEvent = {\n name:\n | 'internal.client.meetinginfo.request'\n | 'internal.client.meetinginfo.response'\n | 'internal.register.device.request'\n | 'internal.register.device.response'\n | 'internal.reset.join.latencies'\n | 'internal.client.meeting.click.joinbutton'\n | 'internal.host.meeting.participant.admitted'\n | 'internal.client.meeting.interstitial-window.showed'\n | 'internal.client.interstitial-window.click.joinbutton'\n | 'internal.client.add-media.turn-discovery.start'\n | 'internal.client.add-media.turn-discovery.end';\n\n payload?: never;\n options?: never;\n};\n\nexport interface ClientEvent {\n name: RawClientEvent['name'];\n payload?: RawClientEvent;\n options?: SubmitClientEventOptions;\n}\n\nexport interface BehavioralEvent {\n // TODO: not implemented\n name: 'host.meeting.participant.admitted' | 'sdk.media-flow.started';\n payload?: never;\n options?: never;\n}\n\nexport interface OperationalEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface FeatureEvent {\n // TODO: not implemented\n name: never;\n payload?: never;\n options?: never;\n}\n\nexport interface MediaQualityEvent {\n name: RawMediaQualityEvent['name'];\n payload?: RawMediaQualityEvent;\n options: SubmitMQEOptions;\n}\n\nexport type RecursivePartial<T> = {\n [P in keyof T]?: T[P] extends (infer U)[]\n ? RecursivePartial<U>[]\n : T[P] extends object\n ? RecursivePartial<T[P]>\n : T[P];\n};\n\nexport type MetricEventNames =\n | InternalEvent['name']\n | ClientEvent['name']\n | BehavioralEvent['name']\n | OperationalEvent['name']\n | FeatureEvent['name']\n | MediaQualityEvent['name'];\n\nexport type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;\nexport type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];\nexport type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];\nexport type NetworkType = NonNullable<RawEvent['origin']>['networkType'];\n\nexport type ClientSubServiceType = ClientEvent['payload']['webexSubServiceType'];\nexport type ClientEventPayload = RecursivePartial<ClientEvent['payload']>;\nexport type ClientEventLeaveReason = ClientEvent['payload']['leaveReason'];\nexport type ClientEventPayloadError = ClientEvent['payload']['errors'];\n\nexport type MediaQualityEventAudioSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['audioSetupDelay'];\nexport type MediaQualityEventVideoSetupDelayPayload = NonNullable<\n MediaQualityEvent['payload']\n>['videoSetupDelay'];\n\nexport type SubmitMQEPayload = RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: NonNullable<MediaQualityEvent['payload']>['intervals'];\n};\n\nexport type SubmitInternalEvent = (args: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitBehavioralEvent = (args: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitClientEvent = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type SubmitOperationalEvent = (args: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type PreComputedLatencies =\n | 'internal.client.pageJMT'\n | 'internal.download.time'\n | 'internal.get.cluster.time'\n | 'internal.click.to.interstitial'\n | 'internal.refresh.captcha.time'\n | 'internal.exchange.ci.token.time'\n | 'internal.get.u2c.time'\n | 'internal.call.init.join.req'\n | 'internal.other.app.api.time'\n | 'internal.api.fetch.intelligence.models';\n"],"mappings":""}
@@ -30,7 +30,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
30
30
  /**
31
31
  * Store timestamp value
32
32
  * @param key - key
33
- * @param value -value
33
+ * @param value - value
34
+ * @param options - store options
34
35
  * @throws
35
36
  * @returns
36
37
  */
@@ -45,19 +46,19 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
45
46
  * Store precomputed latency value
46
47
  * @param key - key
47
48
  * @param value - value
48
- * @param overwrite - overwrite existing value or add it
49
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
49
50
  * @throws
50
51
  * @returns
51
52
  */
52
- saveLatency(key: PreComputedLatencies, value: number, overwrite?: boolean): void;
53
+ saveLatency(key: PreComputedLatencies, value: number, accumulate?: boolean): void;
53
54
  /**
54
55
  * Measure latency for a request
55
- * @param key - key
56
56
  * @param callback - callback for which you would like to measure latency
57
- * @param overwrite - overwite existing value or add to it
57
+ * @param key - key
58
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
58
59
  * @returns
59
60
  */
60
- measureLatency(callback: () => Promise<any>, key: PreComputedLatencies, overwrite?: boolean): Promise<any>;
61
+ measureLatency(callback: () => Promise<unknown>, key: PreComputedLatencies, accumulate?: boolean): Promise<unknown>;
61
62
  /**
62
63
  * Store only the first timestamp value for the given key
63
64
  * @param key - key
@@ -223,8 +224,14 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
223
224
  */
224
225
  getRefreshCaptchaReqResp(): number;
225
226
  /**
226
- * Total latency for all other app api requests.
227
+ * Get the latency for downloading intelligence models.
228
+ * @returns - latency
229
+ */
230
+ getDownloadIntelligenceModelsReqResp(): number;
231
+ /**
232
+ * Get the total latency for all other app API requests.
227
233
  * Excludes meeting info, because it's measured separately.
234
+ * @returns - latency
228
235
  */
229
236
  getOtherAppApiReqResp(): number;
230
237
  }
@@ -104,4 +104,4 @@ export type BuildClientEventFetchRequestOptions = (args: {
104
104
  payload?: RecursivePartial<ClientEvent['payload']>;
105
105
  options?: SubmitClientEventOptions;
106
106
  }) => Promise<any>;
107
- export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time';
107
+ export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.417",
3
+ "version": "3.0.0-beta.418",
4
4
  "description": "",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -28,14 +28,14 @@
28
28
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
29
29
  },
30
30
  "dependencies": {
31
- "@webex/common": "3.0.0-beta.417",
32
- "@webex/common-timers": "3.0.0-beta.417",
31
+ "@webex/common": "3.0.0-beta.418",
32
+ "@webex/common-timers": "3.0.0-beta.418",
33
33
  "@webex/event-dictionary-ts": "^1.0.1406",
34
- "@webex/internal-plugin-device": "3.0.0-beta.417",
35
- "@webex/internal-plugin-metrics": "3.0.0-beta.417",
36
- "@webex/test-helper-chai": "3.0.0-beta.417",
37
- "@webex/test-helper-mock-webex": "3.0.0-beta.417",
38
- "@webex/webex-core": "3.0.0-beta.417",
34
+ "@webex/internal-plugin-device": "3.0.0-beta.418",
35
+ "@webex/internal-plugin-metrics": "3.0.0-beta.418",
36
+ "@webex/test-helper-chai": "3.0.0-beta.418",
37
+ "@webex/test-helper-mock-webex": "3.0.0-beta.418",
38
+ "@webex/webex-core": "3.0.0-beta.418",
39
39
  "ip-anonymize": "^0.1.0",
40
40
  "lodash": "^4.17.21",
41
41
  "uuid": "^3.3.2"
@@ -31,6 +31,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
31
31
  */
32
32
  public clearTimestamps() {
33
33
  this.latencyTimestamps.clear();
34
+ this.precomputedLatencies.clear();
34
35
  }
35
36
 
36
37
  /**
@@ -57,7 +58,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
57
58
  /**
58
59
  * Store timestamp value
59
60
  * @param key - key
60
- * @param value -value
61
+ * @param value - value
62
+ * @param options - store options
61
63
  * @throws
62
64
  * @returns
63
65
  */
@@ -93,31 +95,31 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
93
95
  * Store precomputed latency value
94
96
  * @param key - key
95
97
  * @param value - value
96
- * @param overwrite - overwrite existing value or add it
98
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
97
99
  * @throws
98
100
  * @returns
99
101
  */
100
- public saveLatency(key: PreComputedLatencies, value: number, overwrite = true) {
101
- const existingValue = overwrite ? 0 : this.precomputedLatencies.get(key) || 0;
102
+ public saveLatency(key: PreComputedLatencies, value: number, accumulate = false) {
103
+ const existingValue = accumulate ? this.precomputedLatencies.get(key) || 0 : 0;
102
104
  this.precomputedLatencies.set(key, value + existingValue);
103
105
  }
104
106
 
105
107
  /**
106
108
  * Measure latency for a request
107
- * @param key - key
108
109
  * @param callback - callback for which you would like to measure latency
109
- * @param overwrite - overwite existing value or add to it
110
+ * @param key - key
111
+ * @param accumulate - when it is true, it overwrites existing value with sum of the current value and the new measurement otherwise just store the new measurement
110
112
  * @returns
111
113
  */
112
114
  public measureLatency(
113
- callback: () => Promise<any>,
115
+ callback: () => Promise<unknown>,
114
116
  key: PreComputedLatencies,
115
- overwrite = false
117
+ accumulate = false
116
118
  ) {
117
119
  const start = performance.now();
118
120
 
119
121
  return callback().finally(() => {
120
- this.saveLatency(key, performance.now() - start, overwrite);
122
+ this.saveLatency(key, performance.now() - start, accumulate);
121
123
  });
122
124
  }
123
125
 
@@ -483,8 +485,23 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
483
485
  }
484
486
 
485
487
  /**
486
- * Total latency for all other app api requests.
488
+ * Get the latency for downloading intelligence models.
489
+ * @returns - latency
490
+ */
491
+ public getDownloadIntelligenceModelsReqResp() {
492
+ const downloadIntelligenceModelsReqResp = this.precomputedLatencies.get(
493
+ 'internal.api.fetch.intelligence.models'
494
+ );
495
+
496
+ return downloadIntelligenceModelsReqResp
497
+ ? Math.floor(downloadIntelligenceModelsReqResp)
498
+ : undefined;
499
+ }
500
+
501
+ /**
502
+ * Get the total latency for all other app API requests.
487
503
  * Excludes meeting info, because it's measured separately.
504
+ * @returns - latency
488
505
  */
489
506
  public getOtherAppApiReqResp() {
490
507
  const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
@@ -252,6 +252,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
252
252
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
253
253
  joinTimes.clickToInterstitial = cdl.getClickToInterstitial();
254
254
  joinTimes.refreshCaptchaServiceReqResp = cdl.getRefreshCaptchaReqResp();
255
+ joinTimes.downloadIntelligenceModelsReqResp = cdl.getDownloadIntelligenceModelsReqResp();
255
256
  break;
256
257
 
257
258
  case 'client.call.initiated':
@@ -175,4 +175,5 @@ export type PreComputedLatencies =
175
175
  | 'internal.exchange.ci.token.time'
176
176
  | 'internal.get.u2c.time'
177
177
  | 'internal.call.init.join.req'
178
- | 'internal.other.app.api.time';
178
+ | 'internal.other.app.api.time'
179
+ | 'internal.api.fetch.intelligence.models';
@@ -106,6 +106,9 @@ describe('plugin-metrics', () => {
106
106
  webex.internal.newMetrics.callDiagnosticLatencies.getRefreshCaptchaReqResp = sinon
107
107
  .stub()
108
108
  .returns(10);
109
+ webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
110
+ sinon.stub().returns(42);
111
+
109
112
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
110
113
  //@ts-ignore
111
114
  {event: {name: 'client.interstitial-window.launched'}}
@@ -123,6 +126,7 @@ describe('plugin-metrics', () => {
123
126
  clickToInterstitial: 10,
124
127
  meetingInfoReqResp: 10,
125
128
  refreshCaptchaServiceReqResp: 10,
129
+ downloadIntelligenceModelsReqResp: 42,
126
130
  },
127
131
  });
128
132
  assert.lengthOf(
@@ -51,29 +51,29 @@ describe('internal-plugin-metrics', () => {
51
51
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
52
52
  });
53
53
 
54
- it('should overwrite latency when overwrite is true', () => {
54
+ it('should overwrite latency when accumulate is false', () => {
55
55
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
56
- cdl.saveLatency('internal.client.pageJMT', 10, true);
56
+ cdl.saveLatency('internal.client.pageJMT', 10, false);
57
57
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
58
58
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
59
- cdl.saveLatency('internal.client.pageJMT', 20, true);
59
+ cdl.saveLatency('internal.client.pageJMT', 20, false);
60
60
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
61
61
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
62
62
  });
63
63
 
64
- it('should save latency correctly when overwrite is false', () => {
64
+ it('should save latency correctly when accumulate is true', () => {
65
65
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
66
- cdl.saveLatency('internal.client.pageJMT', 10, false);
66
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
67
67
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
68
68
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
69
69
  });
70
70
 
71
- it('should save latency correctly when overwrite is false and there is existing value', () => {
71
+ it('should save latency correctly when accumulate is true and there is existing value', () => {
72
72
  assert.deepEqual(cdl.precomputedLatencies.size, 0);
73
73
  cdl.saveLatency('internal.client.pageJMT', 10);
74
74
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
75
75
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 10);
76
- cdl.saveLatency('internal.client.pageJMT', 10, false);
76
+ cdl.saveLatency('internal.client.pageJMT', 10, true);
77
77
  assert.deepEqual(cdl.precomputedLatencies.size, 1);
78
78
  assert.deepEqual(cdl.precomputedLatencies.get('internal.client.pageJMT'), 20);
79
79
  });
@@ -108,8 +108,13 @@ describe('internal-plugin-metrics', () => {
108
108
  cdl.saveTimestamp({key: 'client.alert.displayed'});
109
109
  cdl.saveTimestamp({key: 'client.alert.removed'});
110
110
  assert.deepEqual(cdl.latencyTimestamps.size, 2);
111
+ cdl.saveLatency('internal.api.fetch.intelligence.models', 42);
112
+ assert.deepEqual(cdl.precomputedLatencies.size, 1);
113
+
111
114
  cdl.clearTimestamps();
115
+
112
116
  assert.deepEqual(cdl.latencyTimestamps.size, 0);
117
+ assert.deepEqual(cdl.precomputedLatencies.size, 0);
113
118
  });
114
119
 
115
120
  it('should calculate diff between timestamps correctly', () => {
@@ -145,9 +150,9 @@ describe('internal-plugin-metrics', () => {
145
150
  let clock;
146
151
  let saveLatencySpy;
147
152
 
148
- beforeEach(() => {
149
- clock = sinon.useFakeTimers();
150
-
153
+ beforeEach(() => {
154
+ clock = sinon.useFakeTimers();
155
+
151
156
  saveLatencySpy = sinon.stub(cdl, 'saveLatency');
152
157
  });
153
158
 
@@ -155,54 +160,56 @@ describe('internal-plugin-metrics', () => {
155
160
  clock.restore();
156
161
  sinon.restore();
157
162
  });
158
-
159
- it('checks measureLatency with overwrite false', async () => {
163
+
164
+ it('checks measureLatency with accumulate false', async () => {
160
165
  const key = 'internal.client.pageJMT';
161
- const overwrite = false;
166
+ const accumulate = false;
167
+
162
168
  const callbackStub = sinon.stub().callsFake(() => {
163
169
  clock.tick(50);
164
170
  return Promise.resolve('test');
165
171
  });
166
172
 
167
- const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
173
+ // accumulate should be false by default
174
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT');
168
175
 
169
176
  const resolvedValue = await promise;
170
177
  assert.deepEqual(resolvedValue, 'test');
171
178
  assert.calledOnceWithExactly(callbackStub);
172
- assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
179
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
173
180
  });
174
181
 
175
- it('checks measureLatency with overwrite true', async () => {
182
+ it('checks measureLatency with accumulate true', async () => {
176
183
  const key = 'internal.download.time';
177
- const overwrite = true;
184
+ const accumulate = true;
178
185
  const callbackStub = sinon.stub().callsFake(() => {
179
186
  clock.tick(20);
180
187
  return Promise.resolve('test123');
181
188
  });
182
189
 
183
- const promise = cdl.measureLatency(callbackStub, 'internal.download.time', overwrite);
190
+ const promise = cdl.measureLatency(callbackStub, 'internal.download.time', accumulate);
184
191
 
185
192
  const resolvedValue = await promise;
186
193
  assert.deepEqual(resolvedValue, 'test123');
187
194
  assert.calledOnceWithExactly(callbackStub);
188
- assert.calledOnceWithExactly(saveLatencySpy, key, 20, overwrite)
195
+ assert.calledOnceWithExactly(saveLatencySpy, key, 20, accumulate);
189
196
  });
190
197
 
191
198
  it('checks measureLatency when callBack rejects', async () => {
192
199
  const key = 'internal.client.pageJMT';
193
- const overwrite = true;
200
+ const accumulate = false;
194
201
  const error = new Error('some error');
195
202
  const callbackStub = sinon.stub().callsFake(() => {
196
203
  clock.tick(50);
197
204
  return Promise.reject(error);
198
205
  });
199
206
 
200
- const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', overwrite);
207
+ const promise = cdl.measureLatency(callbackStub, 'internal.client.pageJMT', accumulate);
201
208
 
202
209
  const rejectedValue = await assert.isRejected(promise);
203
210
  assert.deepEqual(rejectedValue, error);
204
211
  assert.calledOnceWithExactly(callbackStub);
205
- assert.calledOnceWithExactly(saveLatencySpy, key, 50, overwrite)
212
+ assert.calledOnceWithExactly(saveLatencySpy, key, 50, accumulate);
206
213
  });
207
214
  });
208
215
 
@@ -541,7 +541,10 @@ describe('internal-plugin-metrics', () => {
541
541
  it('should prepare diagnostic event successfully', () => {
542
542
  const options = {meetingId: fakeMeeting.id};
543
543
  const getOriginStub = sinon.stub(cd, 'getOrigin').returns({origin: 'fake-origin'});
544
- const clearEmptyKeysRecursivelyStub = sinon.stub(CallDiagnosticUtils, 'clearEmptyKeysRecursively');
544
+ const clearEmptyKeysRecursivelyStub = sinon.stub(
545
+ CallDiagnosticUtils,
546
+ 'clearEmptyKeysRecursively'
547
+ );
545
548
 
546
549
  const res = cd.prepareDiagnosticEvent(
547
550
  {
@@ -896,11 +899,13 @@ describe('internal-plugin-metrics', () => {
896
899
  options
897
900
  );
898
901
  assert.notCalled(submitToCallDiagnosticsSpy);
899
- assert.calledWith(submitToCallDiagnosticsPreLoginSpy, {
902
+ assert.calledWith(
903
+ submitToCallDiagnosticsPreLoginSpy,
904
+ {
900
905
  eventId: 'my-fake-id',
901
906
  version: 1,
902
- origin: { origin: 'fake-origin' },
903
- originTime: { triggered: now.toISOString(), sent: 'not_defined_yet' },
907
+ origin: {origin: 'fake-origin'},
908
+ originTime: {triggered: now.toISOString(), sent: 'not_defined_yet'},
904
909
  senderCountryCode: 'UK',
905
910
  event: {
906
911
  name: 'client.alert.displayed',
@@ -912,12 +917,14 @@ describe('internal-plugin-metrics', () => {
912
917
  orgId: 'orgId',
913
918
  locusUrl: 'locus-url',
914
919
  webexConferenceIdStr: 'webexConferenceIdStr1',
915
- globalMeetingId: 'globalMeetingId1'
920
+ globalMeetingId: 'globalMeetingId1',
916
921
  },
917
- eventData: { webClientDomain: 'whatever' },
918
- loginType: 'login-ci'
922
+ eventData: {webClientDomain: 'whatever'},
923
+ loginType: 'login-ci',
919
924
  },
920
- }, options.preLoginId);
925
+ },
926
+ options.preLoginId
927
+ );
921
928
  });
922
929
 
923
930
  it('should use meeting loginType if present and meetingId provided', () => {
@@ -1382,7 +1389,7 @@ describe('internal-plugin-metrics', () => {
1382
1389
  });
1383
1390
  });
1384
1391
 
1385
- describe("#submitToCallDiagnostics", () => {
1392
+ describe('#submitToCallDiagnostics', () => {
1386
1393
  it('should send request to call diagnostic batcher', () => {
1387
1394
  const requestStub = sinon.stub();
1388
1395
  //@ts-ignore
@@ -1391,7 +1398,7 @@ describe('internal-plugin-metrics', () => {
1391
1398
  cd.submitToCallDiagnostics({event: 'test'});
1392
1399
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
1393
1400
  });
1394
- })
1401
+ });
1395
1402
 
1396
1403
  describe('#submitMQE', () => {
1397
1404
  it('submits the event correctly', () => {
@@ -2006,12 +2013,16 @@ describe('internal-plugin-metrics', () => {
2006
2013
 
2007
2014
  describe('httpStatusCode', () => {
2008
2015
  it('should include httpStatusCode for browser media errors', () => {
2009
- const res = cd.generateClientEventErrorPayload({name: 'PermissionDeniedError', message: 'bad times', statusCode: 401});
2016
+ const res = cd.generateClientEventErrorPayload({
2017
+ name: 'PermissionDeniedError',
2018
+ message: 'bad times',
2019
+ statusCode: 401,
2020
+ });
2010
2021
  assert.deepEqual(res, {
2011
2022
  category: 'expected',
2012
2023
  errorCode: 4032,
2013
2024
  errorData: {
2014
- errorName: 'PermissionDeniedError'
2025
+ errorName: 'PermissionDeniedError',
2015
2026
  },
2016
2027
  errorDescription: 'CameraPermissionDenied',
2017
2028
  fatal: true,
@@ -2024,12 +2035,16 @@ describe('internal-plugin-metrics', () => {
2024
2035
  });
2025
2036
 
2026
2037
  it('should include httpStatusCode for SdpOfferCreationErrors', () => {
2027
- const res = cd.generateClientEventErrorPayload({name: 'SdpOfferCreationError', message: 'bad times', statusCode: 404});
2038
+ const res = cd.generateClientEventErrorPayload({
2039
+ name: 'SdpOfferCreationError',
2040
+ message: 'bad times',
2041
+ statusCode: 404,
2042
+ });
2028
2043
  assert.deepEqual(res, {
2029
2044
  category: 'media',
2030
2045
  errorCode: 2050,
2031
2046
  errorData: {
2032
- errorName: 'SdpOfferCreationError'
2047
+ errorName: 'SdpOfferCreationError',
2033
2048
  },
2034
2049
  errorDescription: 'SdpOfferCreationError',
2035
2050
  fatal: true,
@@ -2042,7 +2057,11 @@ describe('internal-plugin-metrics', () => {
2042
2057
  });
2043
2058
 
2044
2059
  it('should include httpStatusCode for service error codes', () => {
2045
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 58400}, message: 'bad times', statusCode: 400});
2060
+ const res = cd.generateClientEventErrorPayload({
2061
+ body: {errorCode: 58400},
2062
+ message: 'bad times',
2063
+ statusCode: 400,
2064
+ });
2046
2065
  assert.deepEqual(res, {
2047
2066
  category: 'signaling',
2048
2067
  errorCode: 4100,
@@ -2057,7 +2076,11 @@ describe('internal-plugin-metrics', () => {
2057
2076
  });
2058
2077
 
2059
2078
  it('should include httpStatusCode for locus service error codes', () => {
2060
- const res = cd.generateClientEventErrorPayload({body: {errorCode: 2403001}, message: 'bad times', statusCode: 400});
2079
+ const res = cd.generateClientEventErrorPayload({
2080
+ body: {errorCode: 2403001},
2081
+ message: 'bad times',
2082
+ statusCode: 400,
2083
+ });
2061
2084
  assert.deepEqual(res, {
2062
2085
  category: 'expected',
2063
2086
  errorCode: 3007,
@@ -2072,7 +2095,11 @@ describe('internal-plugin-metrics', () => {
2072
2095
  });
2073
2096
 
2074
2097
  it('should include httpStatusCode for meetingInfo service error codes', () => {
2075
- const res = cd.generateClientEventErrorPayload({body: {data: {meetingInfo: {}}}, message: 'bad times', statusCode: 400});
2098
+ const res = cd.generateClientEventErrorPayload({
2099
+ body: {data: {meetingInfo: {}}},
2100
+ message: 'bad times',
2101
+ statusCode: 400,
2102
+ });
2076
2103
  assert.deepEqual(res, {
2077
2104
  category: 'signaling',
2078
2105
  errorCode: 4100,
@@ -2087,8 +2114,10 @@ describe('internal-plugin-metrics', () => {
2087
2114
  });
2088
2115
 
2089
2116
  it('should include httpStatusCode for network errors', () => {
2090
- const error = new WebexHttpError.NetworkOrCORSError(
2091
- {statusCode: 400, options: {service: '', headers: {}}});
2117
+ const error = new WebexHttpError.NetworkOrCORSError({
2118
+ statusCode: 400,
2119
+ options: {service: '', headers: {}},
2120
+ });
2092
2121
  const res = cd.generateClientEventErrorPayload(error);
2093
2122
  assert.deepEqual(res, {
2094
2123
  category: 'network',
@@ -2104,8 +2133,10 @@ describe('internal-plugin-metrics', () => {
2104
2133
  });
2105
2134
 
2106
2135
  it('should include httpStatusCode for unauthorized errors', () => {
2107
- const error = new WebexHttpError.Unauthorized(
2108
- {statusCode: 401, options: {service: '', headers: {}}});
2136
+ const error = new WebexHttpError.Unauthorized({
2137
+ statusCode: 401,
2138
+ options: {service: '', headers: {}},
2139
+ });
2109
2140
  const res = cd.generateClientEventErrorPayload(error);
2110
2141
  assert.deepEqual(res, {
2111
2142
  category: 'network',
@@ -2308,7 +2339,7 @@ describe('internal-plugin-metrics', () => {
2308
2339
  });
2309
2340
  });
2310
2341
 
2311
- describe("#submitToCallDiagnosticsPreLogin", () => {
2342
+ describe('#submitToCallDiagnosticsPreLogin', () => {
2312
2343
  it('should send request to call diagnostic batcher and saves preLoginId', () => {
2313
2344
  const requestStub = sinon.stub();
2314
2345
  //@ts-ignore
@@ -2321,7 +2352,7 @@ describe('internal-plugin-metrics', () => {
2321
2352
  assert.calledWith(cd.preLoginMetricsBatcher.savePreLoginId, preLoginId);
2322
2353
  assert.calledWith(requestStub, {eventPayload: {event: 'test'}, type: ['diagnostic-event']});
2323
2354
  });
2324
- })
2355
+ });
2325
2356
 
2326
2357
  describe('#isServiceErrorExpected', () => {
2327
2358
  it('returns true for code mapped to "expected"', () => {
@@ -319,6 +319,7 @@ describe('internal-plugin-metrics', () => {
319
319
  clickToInterstitial: undefined,
320
320
  meetingInfoReqResp: undefined,
321
321
  refreshCaptchaServiceReqResp: undefined,
322
+ downloadIntelligenceModelsReqResp: undefined,
322
323
  },
323
324
  },
324
325
  ],
@@ -346,7 +347,7 @@ describe('internal-plugin-metrics', () => {
346
347
  interstitialToJoinOK: undefined,
347
348
  totalJmt: undefined,
348
349
  clientJmt: undefined,
349
- downloadTime: undefined
350
+ downloadTime: undefined,
350
351
  },
351
352
  },
352
353
  ],
@@ -75,6 +75,7 @@ describe('internal-plugin-metrics', () => {
75
75
  meetingInfoReqResp: undefined,
76
76
  clickToInterstitial: undefined,
77
77
  refreshCaptchaServiceReqResp: undefined,
78
+ downloadIntelligenceModelsReqResp: undefined,
78
79
  },
79
80
  name: 'client.interstitial-window.launched',
80
81
  },
@@ -149,7 +150,8 @@ describe('internal-plugin-metrics', () => {
149
150
  });
150
151
 
151
152
  it('fails if preLoinId is not set', async () => {
152
- webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.preLoginId = undefined;
153
+ webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.preLoginId =
154
+ undefined;
153
155
 
154
156
  const promise =
155
157
  webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnosticsPreLogin(
@@ -177,7 +179,7 @@ describe('internal-plugin-metrics', () => {
177
179
 
178
180
  describe('prepareItem', () => {
179
181
  it('calls prepareDiagnosticMetricItem correctly', async () => {
180
- // avoid setting .sent timestamp
182
+ // avoid setting .sent timestamp
181
183
  webex.internal.newMetrics.callDiagnosticMetrics.preLoginMetricsBatcher.prepareRequest = (q) =>
182
184
  Promise.resolve(q);
183
185