@webex/internal-plugin-metrics 3.0.0-beta.371 → 3.0.0-beta.372

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.
@@ -182,6 +182,16 @@ var CallDiagnosticLatencies = /*#__PURE__*/function (_WebexPlugin) {
182
182
  return this.getDiffBetweenTimestamps('client.interstitial-window.start-launch', 'internal.client.interstitial-window.click.joinbutton');
183
183
  }
184
184
 
185
+ /**
186
+ * Device Register Time
187
+ * @returns - latency
188
+ */
189
+ }, {
190
+ key: "getRegisterWDMDeviceJMT",
191
+ value: function getRegisterWDMDeviceJMT() {
192
+ return this.getDiffBetweenTimestamps('internal.register.device.request', 'internal.register.device.response');
193
+ }
194
+
185
195
  /**
186
196
  * Call Init Join Request
187
197
  * @returns - latency
@@ -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","has","a","b","start","end","getDiffBetweenTimestamps","interstitialJoinClickTimestamp","connectedMedia","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","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} 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<string, 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 * @throws\n * @returns\n */\n public saveLatency(key: string, value: number) {\n this.precomputedLatencies.set(key, value);\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 * 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 * Locus Join Response Sent Received\n * @returns - latency\n */\n public getJoinRespSentReceived() {\n // TODO: not clear SPARK-440554\n return undefined;\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 * 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 * 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"],"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","has","a","b","start","end","getDiffBetweenTimestamps","interstitialJoinClickTimestamp","connectedMedia","lobbyTime","getStayLobbyTime","clickToInterstitial","getClickToInterstitial","interstitialToJoinOk","getInterstitialToJoinOK","joinReqResp","getJoinReqResp","ICESetupTime","getICESetupTime","joinConfJMT","getJoinConfJMT","totalMediaJMT","getMeeting","allowMediaInLobby","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} 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<string, 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 * @throws\n * @returns\n */\n public saveLatency(key: string, value: number) {\n this.precomputedLatencies.set(key, value);\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 * 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 * Locus Join Response Sent Received\n * @returns - latency\n */\n public getJoinRespSentReceived() {\n // TODO: not clear SPARK-440554\n return undefined;\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 * 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 * 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"],"mappings":"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"}
@@ -230,6 +230,7 @@ var prepareDiagnosticMetricItem = function prepareDiagnosticMetricItem(webex, it
230
230
  case 'client.call.initiated':
231
231
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
232
232
  joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();
233
+ joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
233
234
  break;
234
235
  case 'client.locus.join.response':
235
236
  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","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","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.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\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.joinReqSentReceived = cdl.getJoinRespSentReceived();\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 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","meetingInfoReqResp","getMeetingInfoReqResp","clickToInterstitial","getClickToInterstitial","showInterstitialTime","getShowInterstitialTime","registerWDMDeviceJMT","getRegisterWDMDeviceJMT","callInitJoinReq","getCallInitJoinReq","joinReqResp","getJoinReqResp","joinReqSentReceived","getJoinRespSentReceived","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.interstitial-window.launched':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.clickToInterstitial = cdl.getClickToInterstitial();\n break;\n\n case 'client.call.initiated':\n joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();\n joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();\n joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();\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.joinReqSentReceived = cdl.getJoinRespSentReceived();\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 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
@@ -161,7 +161,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
161
161
  });
162
162
  });
163
163
  },
164
- version: "3.0.0-beta.371"
164
+ version: "3.0.0-beta.372"
165
165
  });
166
166
  var _default = Metrics;
167
167
  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 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 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.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"],"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 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 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"],"mappings":""}
@@ -80,6 +80,11 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
80
80
  * @returns - latency
81
81
  */
82
82
  getShowInterstitialTime(): number;
83
+ /**
84
+ * Device Register Time
85
+ * @returns - latency
86
+ */
87
+ getRegisterWDMDeviceJMT(): number;
83
88
  /**
84
89
  * Call Init Join Request
85
90
  * @returns - latency
@@ -26,7 +26,7 @@ export type SubmitMQEOptions = {
26
26
  globalMeetingId?: string;
27
27
  };
28
28
  export type InternalEvent = {
29
- name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.reset.join.latencies' | 'internal.client.meeting.click.joinbutton' | 'internal.host.meeting.participant.admitted' | 'internal.client.meeting.interstitial-window.showed' | 'internal.client.interstitial-window.click.joinbutton' | 'internal.client.add-media.turn-discovery.start' | 'internal.client.add-media.turn-discovery.end';
29
+ name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.register.device.request' | 'internal.register.device.response' | 'internal.reset.join.latencies' | 'internal.client.meeting.click.joinbutton' | 'internal.host.meeting.participant.admitted' | 'internal.client.meeting.interstitial-window.showed' | 'internal.client.interstitial-window.click.joinbutton' | 'internal.client.add-media.turn-discovery.start' | 'internal.client.add-media.turn-discovery.end';
30
30
  payload?: never;
31
31
  options?: never;
32
32
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/internal-plugin-metrics",
3
- "version": "3.0.0-beta.371",
3
+ "version": "3.0.0-beta.372",
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.371",
32
- "@webex/common-timers": "3.0.0-beta.371",
31
+ "@webex/common": "3.0.0-beta.372",
32
+ "@webex/common-timers": "3.0.0-beta.372",
33
33
  "@webex/event-dictionary-ts": "^1.0.1329",
34
- "@webex/internal-plugin-device": "3.0.0-beta.371",
35
- "@webex/internal-plugin-metrics": "3.0.0-beta.371",
36
- "@webex/test-helper-chai": "3.0.0-beta.371",
37
- "@webex/test-helper-mock-webex": "3.0.0-beta.371",
38
- "@webex/webex-core": "3.0.0-beta.371",
34
+ "@webex/internal-plugin-device": "3.0.0-beta.372",
35
+ "@webex/internal-plugin-metrics": "3.0.0-beta.372",
36
+ "@webex/test-helper-chai": "3.0.0-beta.372",
37
+ "@webex/test-helper-mock-webex": "3.0.0-beta.372",
38
+ "@webex/webex-core": "3.0.0-beta.372",
39
39
  "ip-anonymize": "^0.1.0",
40
40
  "lodash": "^4.17.21",
41
41
  "uuid": "^3.3.2"
@@ -158,6 +158,17 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
158
158
  );
159
159
  }
160
160
 
161
+ /**
162
+ * Device Register Time
163
+ * @returns - latency
164
+ */
165
+ public getRegisterWDMDeviceJMT() {
166
+ return this.getDiffBetweenTimestamps(
167
+ 'internal.register.device.request',
168
+ 'internal.register.device.response'
169
+ );
170
+ }
171
+
161
172
  /**
162
173
  * Call Init Join Request
163
174
  * @returns - latency
@@ -249,6 +249,7 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
249
249
  case 'client.call.initiated':
250
250
  joinTimes.meetingInfoReqResp = cdl.getMeetingInfoReqResp();
251
251
  joinTimes.showInterstitialTime = cdl.getShowInterstitialTime();
252
+ joinTimes.registerWDMDeviceJMT = cdl.getRegisterWDMDeviceJMT();
252
253
  break;
253
254
 
254
255
  case 'client.locus.join.response':
@@ -41,6 +41,8 @@ export type InternalEvent = {
41
41
  name:
42
42
  | 'internal.client.meetinginfo.request'
43
43
  | 'internal.client.meetinginfo.response'
44
+ | 'internal.register.device.request'
45
+ | 'internal.register.device.response'
44
46
  | 'internal.reset.join.latencies'
45
47
  | 'internal.client.meeting.click.joinbutton'
46
48
  | 'internal.host.meeting.participant.admitted'
@@ -145,6 +145,7 @@ describe('plugin-metrics', () => {
145
145
  name: 'client.call.initiated',
146
146
  joinTimes: {
147
147
  meetingInfoReqResp: 10,
148
+ registerWDMDeviceJMT: 10,
148
149
  showInterstitialTime: 10,
149
150
  },
150
151
  });
@@ -143,6 +143,13 @@ describe('internal-plugin-metrics', () => {
143
143
  assert.deepEqual(cdl.getCallInitJoinReq(), 10);
144
144
  });
145
145
 
146
+
147
+ it('calculates getRegisterWDMDeviceJMT correctly', () => {
148
+ cdl.saveTimestamp({key: 'internal.register.device.request', value: 10});
149
+ cdl.saveTimestamp({key: 'internal.register.device.response', value: 20});
150
+ assert.deepEqual(cdl.getRegisterWDMDeviceJMT(), 10);
151
+ });
152
+
146
153
  it('calculates getJoinReqResp correctly', () => {
147
154
  cdl.saveTimestamp({
148
155
  key: 'client.locus.join.request',
@@ -317,6 +317,7 @@ describe('internal-plugin-metrics', () => {
317
317
  joinTimes: {
318
318
  showInterstitialTime: undefined,
319
319
  meetingInfoReqResp: undefined,
320
+ registerWDMDeviceJMT: undefined,
320
321
  },
321
322
  },
322
323
  ],