@webex/internal-plugin-metrics 3.12.0-webex-services-ready.2 → 3.12.0-webex-services-ready.4

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.
Files changed (38) hide show
  1. package/dist/automated-user.js +19 -0
  2. package/dist/automated-user.js.map +1 -0
  3. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +0 -23
  4. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +571 -15
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics.js +51 -26
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  9. package/dist/index.js +15 -0
  10. package/dist/index.js.map +1 -1
  11. package/dist/metrics.js +1 -1
  12. package/dist/metrics.types.js +4 -0
  13. package/dist/metrics.types.js.map +1 -1
  14. package/dist/new-metrics.js +16 -6
  15. package/dist/new-metrics.js.map +1 -1
  16. package/dist/prelogin-metrics-batcher.js +0 -23
  17. package/dist/prelogin-metrics-batcher.js.map +1 -1
  18. package/dist/types/automated-user.d.ts +2 -0
  19. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +199 -5
  20. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +27 -2
  21. package/dist/types/index.d.ts +5 -3
  22. package/dist/types/metrics.types.d.ts +4 -2
  23. package/dist/types/new-metrics.d.ts +4 -0
  24. package/package.json +12 -11
  25. package/src/automated-user.ts +16 -0
  26. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +0 -26
  27. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +661 -5
  28. package/src/call-diagnostic/call-diagnostic-metrics.ts +40 -18
  29. package/src/index.ts +5 -0
  30. package/src/metrics.types.ts +15 -2
  31. package/src/new-metrics.ts +12 -4
  32. package/src/prelogin-metrics-batcher.ts +0 -26
  33. package/test/unit/spec/automated-user.ts +43 -0
  34. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +0 -136
  35. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1192 -16
  36. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +75 -11
  37. package/test/unit/spec/new-metrics.ts +13 -2
  38. package/test/unit/spec/prelogin-metrics-batcher.ts +1 -120
@@ -1 +1 @@
1
- {"version":3,"names":["_webexCore","require","_lodash","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","CallDiagnosticLatencies","exports","_WebexPlugin","_this","_classCallCheck2","_len","arguments","length","args","Array","_key","concat","_defineProperty2","latencyTimestamps","_map","precomputedLatencies","_inherits2","_createClass2","key","value","clearTimestamps","clear","setMeetingId","meetingId","getMeeting","webex","meetings","getBasicMeetingInformation","undefined","saveTimestamp","_ref","_ref$value","Date","getTime","_ref$options","options","saveFirstTimestampOnly","set","delete","saveLatency","accumulate","existingValue","get","measureLatency","callback","_this2","start","performance","now","finally","has","getDiffBetweenTimestamps","a","b","clampValues","end","diff","_ref2","_ref2$minimum","minimum","_ref2$maximum","maximum","MAX_INTEGER","clamp","getMeetingInfoReqResp","getShowInterstitialTime","getU2CTime","u2cLatency","Math","floor","getRegisterWDMDeviceJMT","getCallInitJoinReq","interstitialShowedToJoinReq","showInterstitialTime","getJoinReqResp","getTurnDiscoveryTime","getLocalSDPGenRemoteSDPRecv","getICESetupTime","getAudioICESetupTime","getVideoICESetupTime","getShareICESetupTime","getStayLobbyTime","getStayLobbyTimeCappedBy","endTimestampKey","lobbyStartTimestamp","lobbyEndTimestamp","maximumEndTimestamp","endTimestamp","min","getPageJMT","latency","getDownloadTimeJMT","getClickToInterstitial","clickToInterstitialLatency","getClickToInterstitialWithUserDelay","clickToInterstitialWithUserDelayLatency","getInterstitialToJoinOK","interstitialShowedToJoinResp","getCallInitMediaEngineReady","getInterstitialToMediaOKJMT","interstitialShowedToIceEnd","stayLobbyTimeCappedByIceEnd","getTotalJMT","clickToInterstitial","interstitialShowedToJoinLocusResponse","getTotalJMTWithUserDelay","clickToInterstitialWithUserDelay","getJoinConfJMT","joinReqResp","ICESetupTime","getTotalMediaJMT","interstitialShowedToMediaEngineReady","stayLobbyTimeCappedByMediaEngineReady","getTotalMediaJMTWithUserDelay","getClientJMT","clickToInterstitialForClientJmt","interstitialShowedToLocusJoinRequest","getAudioJoinRespRxStart","getVideoJoinRespRxStart","getReachabilityClustersReqResp","reachablityClusterReqResp","getAudioJoinRespTxStart","getVideoJoinRespTxStart","getShareDuration","getExchangeCITokenJMT","exchangeCITokenJMT","getRefreshCaptchaReqResp","refreshCaptchaReqResp","getDownloadIntelligenceModelsReqResp","downloadIntelligenceModelsReqResp","getOtherAppApiReqResp","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';\nimport {clamp} from 'lodash';\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 private MAX_INTEGER = 2147483647;\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.getBasicMeetingInformation(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 key === 'client.media-engine.remote-sdp-received'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n // new offer/answer so reset the remote SDP timestamp\n if (key === 'client.media-engine.local-sdp-generated') {\n this.latencyTimestamps.delete('client.media-engine.remote-sdp-received');\n }\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(\n a: MetricEventNames,\n b: MetricEventNames,\n clampValues?: {minimum?: number; maximum?: number}\n ) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n\n if (typeof start !== 'number' || typeof end !== 'number') {\n return undefined;\n }\n\n const diff = end - start;\n\n const {minimum = 0, maximum = this.MAX_INTEGER} = clampValues || {};\n\n return clamp(diff, minimum, maximum);\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 {maximum: 1200000}\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\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 typeof u2cLatency === 'number' ? 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 const interstitialShowedToJoinReq = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.request'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (typeof interstitialShowedToJoinReq !== 'number') {\n return undefined;\n }\n\n return clamp(interstitialShowedToJoinReq - showInterstitialTime, 0, 1200000);\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.request',\n 'client.locus.join.response',\n {maximum: 1200000}\n );\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 {maximum: 1200000}\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', {maximum: 1200000});\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('client.lobby.entered', 'client.lobby.exited');\n }\n\n /**\n * Stay lobby time capped by a certain timestamp.\n * This is to handle the case where the target end timestamp could happen before the lobby is exited,\n * for example media-engine.ready or client.ice.end\n * This is supposed to be called AFTER the end timestamp happens\n * @param endTimestampKey name of the target end event\n * @returns - latency\n */\n public getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames) {\n const lobbyStartTimestamp = this.latencyTimestamps.get('client.lobby.entered'); // might not exist (some meetings don't have lobby)\n\n if (typeof lobbyStartTimestamp !== 'number') {\n // no lobby in the meeting, stayLobbyTime is 0\n return 0;\n }\n\n const lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist (if user still in lobby at the time of measurement)\n const maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist\n\n if (typeof maximumEndTimestamp !== 'number') {\n // the provided timestamp to be used as a cap should exist, return undefined if it doesn't\n return undefined;\n }\n\n const endTimestamp =\n typeof lobbyEndTimestamp === 'number'\n ? Math.min(lobbyEndTimestamp, maximumEndTimestamp)\n : maximumEndTimestamp;\n\n return clamp(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n const latency = this.precomputedLatencies.get('internal.client.pageJMT');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n const latency = this.precomputedLatencies.get('internal.download.time');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n const clickToInterstitialLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial'\n );\n\n if (typeof clickToInterstitialLatency === 'number') {\n return clamp(clickToInterstitialLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Click To Interstitial With User Delay\n * @returns - latency\n */\n public getClickToInterstitialWithUserDelay() {\n const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.with.user.delay'\n );\n\n if (typeof clickToInterstitialWithUserDelayLatency === 'number') {\n return clamp(clickToInterstitialWithUserDelayLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n const interstitialShowedToJoinResp = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (typeof interstitialShowedToJoinResp !== 'number') {\n return undefined;\n }\n\n return clamp(interstitialShowedToJoinResp - showInterstitialTime, 0, this.MAX_INTEGER);\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getInterstitialToMediaOKJMT();\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialShowedToIceEnd = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.ice.end'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');\n\n if (\n typeof interstitialShowedToIceEnd === 'number' &&\n typeof stayLobbyTimeCappedByIceEnd === 'number'\n ) {\n return clamp(\n interstitialShowedToIceEnd - showInterstitialTime - stayLobbyTimeCappedByIceEnd,\n 0,\n this.MAX_INTEGER\n );\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 interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitial + interstitialShowedToJoinLocusResponse - showInterstitialTime,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total JMT With User Delay\n * @returns - latency\n */\n public getTotalJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\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 clamp(joinReqResp + ICESetupTime, 0, this.MAX_INTEGER);\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 interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.media-engine.ready'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialShowedToMediaEngineReady === 'number' &&\n typeof stayLobbyTimeCappedByMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitial +\n interstitialShowedToMediaEngineReady -\n showInterstitialTime -\n stayLobbyTimeCappedByMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT With User Delay\n * @returns - latency\n */\n public getTotalMediaJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const clickToInterstitialForClientJmt = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.for.client.jmt'\n );\n const interstitialShowedToLocusJoinRequest = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.request'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (\n typeof clickToInterstitialForClientJmt === 'number' &&\n typeof interstitialShowedToLocusJoinRequest === 'number'\n ) {\n return clamp(\n clickToInterstitialForClientJmt +\n interstitialShowedToLocusJoinRequest -\n showInterstitialTime,\n 0,\n this.MAX_INTEGER\n );\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 typeof reachablityClusterReqResp === 'number'\n ? clamp(Math.floor(reachablityClusterReqResp), 0, this.MAX_INTEGER)\n : 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 * Time from share initiation to share stop (ms).\n */\n public getShareDuration() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.share.initiated',\n 'internal.client.share.stopped'\n );\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 typeof exchangeCITokenJMT === 'number'\n ? clamp(Math.floor(exchangeCITokenJMT), 0, this.MAX_INTEGER)\n : 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 typeof refreshCaptchaReqResp === 'number'\n ? clamp(Math.floor(refreshCaptchaReqResp), 0, this.MAX_INTEGER)\n : 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 typeof downloadIntelligenceModelsReqResp === 'number'\n ? clamp(Math.floor(downloadIntelligenceModelsReqResp), 0, this.MAX_INTEGER)\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 ? clamp(Math.floor(otherAppApiJMT), 0, this.MAX_INTEGER) : undefined;\n }\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_webexCore","require","_lodash","_metrics","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_callSuper","_getPrototypeOf2","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","Boolean","prototype","valueOf","call","CallDiagnosticLatencies","exports","_WebexPlugin","_this","_classCallCheck2","_len","args","Array","_key","concat","latencyTimestamps","_map","precomputedLatencies","meetingLatencies","_inherits2","_createClass2","key","value","clearTimestamps","clear","clearLocusSyncLatency","dataSetName","meetingId","trackingId","records","get","remainingRecords","record","locusSync","setMeetingLatencyRecords","getLocusSyncLatency","_this$getDiffBetweenL","_this$getDiffBetweenL2","_this2","undefined","getLocusSyncLatencyRecord","hashtreePrepTime","getDiffBetweenLocusSyncTimestamps","hashtreeResponseTime","syncPrepStart","getLocusSyncPrepStart","syncPrepTime","syncResponseTime","syncMessageReceiveTime","totalTimeFromMessageReceived","totalTimeFromSyncResponse","totalTime","Math","max","skewedSegment","randomBackoffTime","some","segment","LOCUS_SYNC_SKEW_THRESHOLD_MS","hasMeaningfulSegment","getClampedLocusSyncLatency","recordLocusSyncMessageReceived","messageReceived","Date","getTime","changedRecord","completeLocusSyncLatency","hasMessageReceived","hasSyncResponse","syncResponse","syncLatency","removeLocusSyncLatencyRecord","completed","dataSet","a","b","start","end","hashTreeResponse","latency","round","clamp","MAX_INTEGER","findLocusSyncRecord","predicate","_orderedRecords$find","_ref","_ref$searchFromLatest","searchFromLatest","orderedRecords","_toConsumableArray2","reverse","find","_ref2","pruneStaleLocusSyncLatencyRecords","_this3","currentTimestamp","getLatestLocusSyncTimestamp","isPrunableCandidate","hasCompleted","recordsAfterTtl","_ref3","lastTimestamp","LOCUS_SYNC_PENDING_RECORD_TTL_MS","overflowCount","_ref4","LOCUS_SYNC_MAX_RECORDS_PER_DATASET","_ref5","_ref6","_ref7","_ref8","_ref9","_record$messageReceiv","syncRequest","hashTreeRequest","syncStart","pruneOptions","recordsToSave","set","delete","getLatestPendingLocusSyncLatencyRecord","saveLocusSyncBackoffLatency","_ref0","_this$meetingLatencie","pendingRecord","isLocusSyncLatencyEvent","LOCUS_SYNC_LATENCY_EVENT_NAMES","includes","saveLocusSyncLatencyTimestamp","_ref1","_this$meetingLatencie4","webex","logger","warn","_this$meetingLatencie3","_this$meetingLatencie2","setMeetingId","getMeeting","meetings","getBasicMeetingInformation","saveTimestamp","_ref10","_ref10$value","_ref10$options","options","saveFirstTimestampOnly","saveLatency","normalizedOptions","accumulate","_normalizedOptions$ac","existingValue","measureLatency","callback","_this4","performance","now","finally","has","getDiffBetweenTimestamps","clampValues","diff","_ref11","_ref11$minimum","minimum","_ref11$maximum","maximum","getMeetingInfoReqResp","getShowInterstitialTime","getU2CTime","u2cLatency","floor","getRegisterWDMDeviceJMT","getCallInitJoinReq","interstitialShowedToJoinReq","showInterstitialTime","getJoinReqResp","getTurnDiscoveryTime","getLocalSDPGenRemoteSDPRecv","getICESetupTime","getAudioICESetupTime","getVideoICESetupTime","getShareICESetupTime","getStayLobbyTime","getStayLobbyTimeCappedBy","endTimestampKey","lobbyStartTimestamp","lobbyEndTimestamp","maximumEndTimestamp","endTimestamp","min","getPageJMT","getDownloadTimeJMT","getClickToInterstitial","clickToInterstitialLatency","getClickToInterstitialWithUserDelay","clickToInterstitialWithUserDelayLatency","getInterstitialToJoinOK","interstitialShowedToJoinResp","getCallInitMediaEngineReady","getInterstitialToMediaOKJMT","interstitialShowedToIceEnd","stayLobbyTimeCappedByIceEnd","getTotalJMT","clickToInterstitial","interstitialShowedToJoinLocusResponse","getTotalJMTWithUserDelay","clickToInterstitialWithUserDelay","getJoinConfJMT","joinReqResp","ICESetupTime","getTotalMediaJMT","interstitialShowedToMediaEngineReady","stayLobbyTimeCappedByMediaEngineReady","getTotalMediaJMTWithUserDelay","getClientJMT","clickToInterstitialForClientJmt","interstitialShowedToLocusJoinRequest","getAudioJoinRespRxStart","getVideoJoinRespRxStart","getReachabilityClustersReqResp","reachablityClusterReqResp","getAudioJoinRespTxStart","getVideoJoinRespTxStart","getShareDuration","getExchangeCITokenJMT","exchangeCITokenJMT","getRefreshCaptchaReqResp","refreshCaptchaReqResp","getDownloadIntelligenceModelsReqResp","downloadIntelligenceModelsReqResp","getOtherAppApiReqResp","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';\nimport {clamp} from 'lodash';\n\nimport {\n LOCUS_SYNC_LATENCY_EVENT_NAMES,\n MetricEventNames,\n PreComputedLatencies,\n} from '../metrics.types';\n\n// we only care about client event and feature event for now\n\ntype LocusSyncLatencyMilestone = {\n meetingId: string;\n dataSetName: string;\n key: MetricEventNames;\n value: number;\n trackingId?: string;\n};\n\ntype SaveTimestampOptions = {\n meetingId?: string;\n dataSetName?: string;\n trackingId?: string;\n};\n\ntype SaveLatencyOptions = {\n accumulate?: boolean;\n meetingId?: string;\n dataSetName?: string;\n};\n\ntype LocusSyncLatencyRecord = {\n meetingId: string;\n dataSetName: string;\n randomBackoffTime: number;\n trackingId?: string;\n syncStart?: number;\n hashTreeRequest?: number;\n hashTreeResponse?: number;\n syncRequest?: number;\n syncResponse?: number;\n messageReceived?: number;\n};\n\ntype LocusSyncLatencyTimestampKey = Exclude<keyof LocusSyncLatencyRecord, 'randomBackoffTime'>;\n\n/**\n * Container for the latencies tracked for a single meeting. Locus sync is currently the only\n * meeting-specific latency we track, but this wrapper lets us add other latency records in the\n * future without changing the shape of `meetingLatencies`.\n */\ntype MeetingLatencyRecord = {\n locusSync: LocusSyncLatencyRecord;\n};\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 meetingLatencies: Map<string, MeetingLatencyRecord[]>;\n // meetingId that the current latencies are for\n private meetingId?: string;\n private MAX_INTEGER = 2147483647;\n\n // Aligned with UCF desktop (MekleFlowSyncMetricsTracker::kSleepWakeSkewThresholdMs): if any\n // measured Locus sync segment exceeds this threshold the record is assumed to be corrupted by a\n // clock jump (sleep/wake) and is discarded instead of being reported.\n private LOCUS_SYNC_SKEW_THRESHOLD_MS = 10 * 60 * 1000;\n\n // Incomplete Locus sync records (missing the /sync response and/or the LLM message) are kept for\n // this long so a late milestone can still complete them, then pruned as stale.\n private LOCUS_SYNC_PENDING_RECORD_TTL_MS = 5 * 60 * 1000;\n\n // Safety cap on the number of records kept per meeting + dataset, to bound memory if syncs churn\n // faster than the TTL can clean them up.\n private LOCUS_SYNC_MAX_RECORDS_PER_DATASET = 20;\n\n /**\n * @constructor\n */\n constructor(...args) {\n super(...args);\n this.latencyTimestamps = new Map();\n this.precomputedLatencies = new Map();\n this.meetingLatencies = new Map();\n }\n\n /**\n * Clear timestamps\n */\n public clearTimestamps() {\n this.latencyTimestamps.clear();\n this.precomputedLatencies.clear();\n this.meetingLatencies.clear();\n }\n\n /**\n * Clear tracked Locus sync latency state for a dataset.\n *\n * When a `trackingId` is supplied only the single record matching it is dropped, mirroring the\n * native client which discards the individual in-progress record on a sync error (by syncId).\n * When no `trackingId` is supplied every record for the dataset is dropped (legacy behavior).\n *\n * @param dataSetName dataset name\n * @param meetingId meeting id\n * @param trackingId optional sync tracking id to drop a single record instead of the whole dataset\n */\n public clearLocusSyncLatency(dataSetName: string, meetingId: string, trackingId?: string) {\n const records = this.meetingLatencies.get(meetingId);\n\n if (!records) {\n return;\n }\n\n const remainingRecords = trackingId\n ? records.filter((record) => record.locusSync.trackingId !== trackingId)\n : records.filter((record) => record.locusSync.dataSetName !== dataSetName);\n\n this.setMeetingLatencyRecords(meetingId, remainingRecords);\n }\n\n /**\n * Calculates Locus sync latency values from stored milestone timestamps.\n * @param meetingId meeting id\n * @param trackingId sync tracking id used to match the record\n * @returns sync latency metrics\n */\n public getLocusSyncLatency(meetingId: string, trackingId: string) {\n if (!trackingId) {\n return undefined;\n }\n\n const record = this.getLocusSyncLatencyRecord(meetingId, trackingId);\n\n if (!record) {\n return undefined;\n }\n\n // Some sync flows skip the /hashtree request, for example single-leaf data sets or cases\n // where we already know which leaves to sync. Treat the missing hashtree segment as 0,\n // while still requiring the sync request/response/message milestones below.\n const hashtreePrepTime =\n this.getDiffBetweenLocusSyncTimestamps(record, 'syncStart', 'hashTreeRequest') ?? 0;\n const hashtreeResponseTime =\n this.getDiffBetweenLocusSyncTimestamps(record, 'hashTreeRequest', 'hashTreeResponse') ?? 0;\n const syncPrepStart = this.getLocusSyncPrepStart(record);\n const syncPrepTime = this.getDiffBetweenLocusSyncTimestamps(\n record,\n syncPrepStart,\n 'syncRequest'\n );\n const syncResponseTime = this.getDiffBetweenLocusSyncTimestamps(\n record,\n 'syncRequest',\n 'syncResponse'\n );\n // Aligned with UCF: syncMessageReceiveTime is measured from the sync request start (not the\n // sync response), i.e. how long after we asked Locus to sync the resulting state update arrived.\n const syncMessageReceiveTime = this.getDiffBetweenLocusSyncTimestamps(\n record,\n 'syncRequest',\n 'messageReceived'\n );\n const totalTimeFromMessageReceived = this.getDiffBetweenLocusSyncTimestamps(\n record,\n 'syncStart',\n 'messageReceived'\n );\n const totalTimeFromSyncResponse = this.getDiffBetweenLocusSyncTimestamps(\n record,\n 'syncStart',\n 'syncResponse'\n );\n\n // messageReceived can occasionally be out of order due to race conditions relative to the\n // /sync response. Use the larger of the two so totalTime is never less than syncStart->syncResponse.\n const totalTime =\n typeof totalTimeFromMessageReceived === 'number' &&\n typeof totalTimeFromSyncResponse === 'number'\n ? Math.max(totalTimeFromMessageReceived, totalTimeFromSyncResponse)\n : totalTimeFromMessageReceived ?? totalTimeFromSyncResponse;\n\n if (typeof syncPrepTime !== 'number' || typeof totalTime !== 'number') {\n return undefined;\n }\n\n // Aligned with UCF desktop (MekleFlowSyncMetricsTracker kSleepWakeSkewThresholdMs): if any\n // individual segment is larger than the skew threshold the timestamps were almost certainly\n // distorted by a clock jump (device sleep/wake), so discard the whole record.\n const skewedSegment = [\n record.randomBackoffTime,\n hashtreePrepTime,\n hashtreeResponseTime,\n syncPrepTime,\n syncResponseTime,\n syncMessageReceiveTime,\n totalTime,\n ].some((segment) => typeof segment === 'number' && segment > this.LOCUS_SYNC_SKEW_THRESHOLD_MS);\n\n if (skewedSegment) {\n return undefined;\n }\n\n // Emit whenever at least one measured segment is non-zero. The LLM broadcast itself is gated\n // in completeLocusSyncLatency(); this only guards against an all-zero (unmeasurable) record.\n const hasMeaningfulSegment =\n hashtreeResponseTime > 0 ||\n (typeof syncResponseTime === 'number' && syncResponseTime > 0) ||\n (typeof syncMessageReceiveTime === 'number' && syncMessageReceiveTime > 0);\n\n if (!hasMeaningfulSegment) {\n return undefined;\n }\n\n return {\n randomBackoffTime: this.getClampedLocusSyncLatency(record.randomBackoffTime),\n hashtreePrepTime,\n hashtreeResponseTime,\n syncPrepTime,\n ...(typeof syncResponseTime === 'number' ? {syncResponseTime} : {}),\n ...(typeof syncMessageReceiveTime === 'number' ? {syncMessageReceiveTime} : {}),\n totalTime,\n };\n }\n\n /**\n * Records the time the LLM state-update message for a Locus sync arrived. This is the milestone\n * that gates the client.locus.sync.complete metric: the metric is emitted only for flows where\n * the update came over LLM (aligned with the agreed requirement that body/http-only syncs do not\n * emit). The record is matched by meeting id + tracking id, regardless of which other milestones\n * are present yet, so the real arrival time is captured even if the /sync response has not landed.\n * @param meetingId meeting id\n * @param trackingId sync tracking id used to match the pending record\n * @returns void\n */\n public recordLocusSyncMessageReceived(meetingId: string, trackingId: string) {\n if (!trackingId) {\n return;\n }\n\n const record = this.getLocusSyncLatencyRecord(meetingId, trackingId);\n\n if (record && typeof record.messageReceived !== 'number') {\n record.messageReceived = new Date().getTime();\n const records = this.meetingLatencies.get(meetingId);\n\n if (records) {\n this.setMeetingLatencyRecords(meetingId, records, {\n changedRecord: record,\n });\n }\n }\n }\n\n /**\n * Complete and remove the Locus sync latency record for a meeting + tracking id.\n *\n * Both milestones are required, in any arrival order: the metric is emitted only once BOTH the\n * matching LLM broadcast (messageReceived) AND the /sync response have arrived. The LLM broadcast\n * confirms the client that issued the /sync received the resulting state update for its tracking\n * id (so sync cancel, or a sync storm where the final broadcast echoed another client's tracking\n * id, never emit); the /sync response is always waited for too, since the LLM message can arrive\n * before the HTTP response. If either milestone is missing the record is kept so the other can\n * still arrive; it is only consumed when the metric is actually emitted.\n * @param meetingId meeting id\n * @param trackingId sync tracking id used to match the pending record\n * @returns completed sync latency metric payload, or undefined when not completed\n */\n public completeLocusSyncLatency(meetingId: string, trackingId: string) {\n if (!trackingId) {\n return undefined;\n }\n\n const record = this.getLocusSyncLatencyRecord(meetingId, trackingId);\n\n if (!record) {\n return undefined;\n }\n\n const hasMessageReceived = typeof record.messageReceived === 'number';\n const hasSyncResponse = typeof record.syncResponse === 'number';\n\n // Wait until both milestones are present before emitting. The LLM broadcast and the /sync\n // response can arrive in either order, so we keep the record until the second one lands.\n if (!hasMessageReceived || !hasSyncResponse) {\n return undefined;\n }\n\n const syncLatency = this.getLocusSyncLatency(meetingId, trackingId);\n\n this.removeLocusSyncLatencyRecord(meetingId, trackingId);\n\n if (!syncLatency) {\n return undefined;\n }\n\n const completed = {\n dataSet: record.dataSetName,\n syncLatency,\n };\n\n return completed;\n }\n\n /**\n * Helper to calculate end - start for Locus sync milestones.\n * @param record tracked milestone timestamps\n * @param a start milestone\n * @param b end milestone\n * @returns latency\n */\n private getDiffBetweenLocusSyncTimestamps(\n record: LocusSyncLatencyRecord,\n a: LocusSyncLatencyTimestampKey,\n b: LocusSyncLatencyTimestampKey\n ) {\n const start = record[a];\n const end = record[b];\n\n if (typeof start !== 'number' || typeof end !== 'number') {\n return undefined;\n }\n\n return this.getClampedLocusSyncLatency(end - start);\n }\n\n /**\n * Get the timestamp that starts the sync prep segment.\n * @param record tracked milestone timestamps\n * @returns sync prep start milestone\n */\n private getLocusSyncPrepStart(record: LocusSyncLatencyRecord): LocusSyncLatencyTimestampKey {\n return typeof record.hashTreeResponse === 'number' ? 'hashTreeResponse' : 'syncStart';\n }\n\n /**\n * Round and clamp Locus sync latency values.\n * @param latency latency value\n * @returns rounded latency\n */\n private getClampedLocusSyncLatency(latency: number) {\n return Math.round(clamp(latency, 0, this.MAX_INTEGER));\n }\n\n /**\n * Finds a Locus sync latency record for a meeting using a predicate run against each stored\n * locusSync record.\n * @param meetingId meeting id\n * @param predicate matcher run against each locusSync record\n * @param options.searchFromLatest when true, iterate from the most recently added record first\n * @returns matching Locus sync latency record\n */\n private findLocusSyncRecord(\n meetingId: string,\n predicate: (locusSync: LocusSyncLatencyRecord) => boolean,\n {searchFromLatest = false}: {searchFromLatest?: boolean} = {}\n ) {\n const records = this.meetingLatencies.get(meetingId);\n\n if (!records) {\n return undefined;\n }\n\n const orderedRecords = searchFromLatest ? [...records].reverse() : records;\n\n return orderedRecords.find((record) => predicate(record.locusSync))?.locusSync;\n }\n\n /**\n * Get the Locus sync latency record for a meeting and tracking id.\n * @param meetingId meeting id\n * @param trackingId /sync response tracking id\n * @returns matching Locus sync latency record\n */\n private getLocusSyncLatencyRecord(meetingId: string, trackingId: string) {\n return this.findLocusSyncRecord(meetingId, (locusSync) => locusSync.trackingId === trackingId);\n }\n\n /**\n * Remove the Locus sync latency record for a meeting and tracking id.\n * @param meetingId meeting id\n * @param trackingId sync tracking id used to match the record\n * @returns void\n */\n private removeLocusSyncLatencyRecord(meetingId: string, trackingId: string) {\n const records = this.meetingLatencies.get(meetingId);\n\n if (!records) {\n return;\n }\n\n const remainingRecords = records.filter(({locusSync}) => locusSync.trackingId !== trackingId);\n\n this.setMeetingLatencyRecords(meetingId, remainingRecords);\n }\n\n /**\n * Prune stale never-completed Locus sync latency records for the same dataset as the record that\n * just changed. Records are dropped when they have been pending longer than the TTL, or to keep\n * the number of records per dataset under the safety cap (oldest pending candidates first).\n * @param records current records for the meeting\n * @param changedRecord the record that was just updated, used as the reference point\n * @returns the records to keep\n */\n private pruneStaleLocusSyncLatencyRecords(\n records: MeetingLatencyRecord[],\n changedRecord: LocusSyncLatencyRecord\n ) {\n const currentTimestamp = this.getLatestLocusSyncTimestamp(changedRecord);\n\n if (typeof currentTimestamp !== 'number') {\n return records;\n }\n\n // A record is only a cleanup candidate when it belongs to the same dataset as the record that\n // just changed, is not that record itself, and has never completed. Everything else is kept.\n const isPrunableCandidate = (locusSync: LocusSyncLatencyRecord) => {\n if (locusSync.dataSetName !== changedRecord.dataSetName) {\n return false;\n }\n\n if (changedRecord.trackingId && locusSync.trackingId === changedRecord.trackingId) {\n return false;\n }\n\n const hasCompleted =\n typeof locusSync.syncResponse === 'number' && typeof locusSync.messageReceived === 'number';\n\n return !hasCompleted;\n };\n\n // 1) Drop candidates that have been pending longer than the TTL.\n const recordsAfterTtl = records.filter(({locusSync}) => {\n if (!isPrunableCandidate(locusSync)) {\n return true;\n }\n\n const lastTimestamp = this.getLatestLocusSyncTimestamp(locusSync);\n\n if (typeof lastTimestamp !== 'number') {\n return true;\n }\n\n return currentTimestamp - lastTimestamp < this.LOCUS_SYNC_PENDING_RECORD_TTL_MS;\n });\n\n // 2) Cap the number of records kept per dataset, dropping the oldest pending candidates first.\n let overflowCount = Math.max(\n 0,\n recordsAfterTtl.filter(({locusSync}) => locusSync.dataSetName === changedRecord.dataSetName)\n .length - this.LOCUS_SYNC_MAX_RECORDS_PER_DATASET\n );\n\n if (overflowCount === 0) {\n return recordsAfterTtl;\n }\n\n return recordsAfterTtl.filter(({locusSync}) => {\n if (overflowCount <= 0 || !isPrunableCandidate(locusSync)) {\n return true;\n }\n\n overflowCount -= 1;\n\n return false;\n });\n }\n\n /**\n * Get the most recent milestone timestamp stored on a Locus sync latency record, checking\n * milestones from latest to earliest so the newest available one is returned.\n * @param record tracked milestone timestamps\n * @returns latest milestone timestamp, or undefined when none are set\n */\n private getLatestLocusSyncTimestamp(record: LocusSyncLatencyRecord) {\n return (\n record.messageReceived ??\n record.syncResponse ??\n record.syncRequest ??\n record.hashTreeResponse ??\n record.hashTreeRequest ??\n record.syncStart\n );\n }\n\n /**\n * Persist the Locus sync latency records for a meeting, deleting the meeting entry when no\n * records remain. When pruneOptions is provided, stale records are pruned before saving.\n * @param meetingId meeting id\n * @param records records to save\n * @param pruneOptions when provided, triggers stale record pruning relative to changedRecord\n * @returns void\n */\n private setMeetingLatencyRecords(\n meetingId: string,\n records: MeetingLatencyRecord[],\n pruneOptions?: {\n changedRecord: LocusSyncLatencyRecord;\n }\n ) {\n const recordsToSave = pruneOptions\n ? this.pruneStaleLocusSyncLatencyRecords(records, pruneOptions.changedRecord)\n : records;\n\n if (recordsToSave.length > 0) {\n this.meetingLatencies.set(meetingId, recordsToSave);\n } else {\n this.meetingLatencies.delete(meetingId);\n }\n }\n\n /**\n * Get the latest Locus sync latency record waiting for sync.start.\n * @param meetingId meeting id\n * @param dataSetName dataset name\n * @returns latest pending Locus sync latency record\n */\n private getLatestPendingLocusSyncLatencyRecord(meetingId: string, dataSetName: string) {\n return this.findLocusSyncRecord(\n meetingId,\n (locusSync) => locusSync.dataSetName === dataSetName && locusSync.syncStart === undefined,\n {searchFromLatest: true}\n );\n }\n\n /**\n * Store random backoff latency for the current or next Locus sync latency record.\n * @param meetingId meeting id\n * @param dataSetName dataset name\n * @param randomBackoffTime random backoff latency value\n * @returns void\n */\n private saveLocusSyncBackoffLatency({\n meetingId,\n dataSetName,\n randomBackoffTime,\n }: {\n meetingId: string;\n dataSetName: string;\n randomBackoffTime: number;\n }) {\n const pendingRecord = this.getLatestPendingLocusSyncLatencyRecord(meetingId, dataSetName);\n\n if (pendingRecord) {\n pendingRecord.randomBackoffTime = randomBackoffTime;\n\n return;\n }\n\n const records = this.meetingLatencies.get(meetingId) ?? [];\n\n records.push({\n locusSync: {\n meetingId,\n dataSetName,\n randomBackoffTime,\n },\n });\n this.meetingLatencies.set(meetingId, records);\n }\n\n /**\n * Checks if metric event name is a Locus sync latency milestone.\n * @param key event name\n * @returns whether event is Locus sync latency milestone\n */\n private isLocusSyncLatencyEvent(key: MetricEventNames) {\n return LOCUS_SYNC_LATENCY_EVENT_NAMES.includes(key as any);\n }\n\n /**\n * Stores a Locus sync latency milestone timestamp.\n * @param options options\n */\n private saveLocusSyncLatencyTimestamp({\n meetingId,\n dataSetName,\n key,\n value,\n trackingId,\n }: LocusSyncLatencyMilestone) {\n if (!trackingId) {\n // @ts-ignore\n this.webex.logger.warn(\n `CallDiagnosticLatencies: saveLocusSyncLatencyTimestamp called without a trackingId for key \"${key}\"; skipping Locus sync milestone`\n );\n\n return;\n }\n\n if (key === 'internal.client.locus.sync.start') {\n const pendingRecord = this.getLatestPendingLocusSyncLatencyRecord(meetingId, dataSetName);\n\n if (pendingRecord) {\n pendingRecord.trackingId = trackingId;\n pendingRecord.syncStart = value;\n this.setMeetingLatencyRecords(meetingId, this.meetingLatencies.get(meetingId) ?? [], {\n changedRecord: pendingRecord,\n });\n\n return;\n }\n\n const records = this.meetingLatencies.get(meetingId) ?? [];\n\n records.push({\n locusSync: {\n meetingId,\n dataSetName,\n randomBackoffTime: 0,\n trackingId,\n syncStart: value,\n },\n });\n this.setMeetingLatencyRecords(meetingId, records, {\n changedRecord: records[records.length - 1].locusSync,\n });\n\n return;\n }\n\n // Every sync milestone after sync.start is stamped with the same tracking id that was\n // generated up-front and forced onto the /sync request, so the record is located by\n // meeting id + tracking id.\n const record = this.getLocusSyncLatencyRecord(meetingId, trackingId);\n\n if (!record) {\n return;\n }\n\n switch (key) {\n case 'internal.client.locus.hashtree.request':\n record.hashTreeRequest = value;\n break;\n case 'internal.client.locus.hashtree.response':\n record.hashTreeResponse = value;\n break;\n case 'internal.client.locus.sync.request':\n record.syncRequest = value;\n break;\n case 'internal.client.locus.sync.response':\n record.syncResponse = value;\n break;\n case 'internal.client.locus.sync.message.received':\n record.messageReceived = value;\n break;\n default:\n break;\n }\n\n this.setMeetingLatencyRecords(meetingId, this.meetingLatencies.get(meetingId) ?? [], {\n changedRecord: record,\n });\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.getBasicMeetingInformation(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?: SaveTimestampOptions;\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\n if (this.isLocusSyncLatencyEvent(key) && options.dataSetName && options.meetingId) {\n this.saveLocusSyncLatencyTimestamp({\n meetingId: options.meetingId,\n dataSetName: options.dataSetName,\n key,\n value,\n trackingId: options.trackingId,\n });\n\n return;\n }\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 key === 'client.media-engine.remote-sdp-received'\n ) {\n this.saveFirstTimestampOnly(key, value);\n } else {\n this.latencyTimestamps.set(key, value);\n // new offer/answer so reset the remote SDP timestamp\n if (key === 'client.media-engine.local-sdp-generated') {\n this.latencyTimestamps.delete('client.media-engine.remote-sdp-received');\n }\n }\n }\n\n /**\n * Store precomputed latency value\n * @param key - key\n * @param value - value\n * @param options - store options (a legacy boolean `accumulate` flag is also accepted)\n * @param options.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 * @param options.meetingId - meeting id, only used for Locus sync latency records\n * @param options.dataSetName - dataset name, only used for Locus sync latency records\n * @throws\n * @returns\n */\n public saveLatency(key: PreComputedLatencies, value: number, options: SaveLatencyOptions = {}) {\n // Older (untyped) callers may still pass a boolean `accumulate` as the third argument\n // (saveLatency(key, value, true)). Normalize it to the options object before destructuring,\n // otherwise accumulation is silently lost and legacy SDK/plugin consumers underreport latencies.\n const normalizedOptions: SaveLatencyOptions =\n typeof options === 'boolean' ? {accumulate: options} : options;\n const {accumulate = false, meetingId, dataSetName} = normalizedOptions;\n\n if (key === 'internal.client.locus.sync.random.backoff' && meetingId && dataSetName) {\n this.saveLocusSyncBackoffLatency({\n meetingId,\n dataSetName,\n randomBackoffTime: value,\n });\n\n return;\n }\n\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(\n a: MetricEventNames,\n b: MetricEventNames,\n clampValues?: {minimum?: number; maximum?: number}\n ) {\n const start = this.latencyTimestamps.get(a);\n const end = this.latencyTimestamps.get(b);\n\n if (typeof start !== 'number' || typeof end !== 'number') {\n return undefined;\n }\n\n const diff = end - start;\n\n const {minimum = 0, maximum = this.MAX_INTEGER} = clampValues || {};\n\n return clamp(diff, minimum, maximum);\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 {maximum: 1200000}\n );\n }\n\n /**\n * Interstitial Time\n * @returns - latency\n */\n public getShowInterstitialTime() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\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 typeof u2cLatency === 'number' ? 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 const interstitialShowedToJoinReq = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.request'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (typeof interstitialShowedToJoinReq !== 'number') {\n return undefined;\n }\n\n return clamp(interstitialShowedToJoinReq - showInterstitialTime, 0, 1200000);\n }\n\n /**\n * Locus Join Request\n * @returns - latency\n */\n public getJoinReqResp() {\n return this.getDiffBetweenTimestamps(\n 'client.locus.join.request',\n 'client.locus.join.response',\n {maximum: 1200000}\n );\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 {maximum: 1200000}\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', {maximum: 1200000});\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('client.lobby.entered', 'client.lobby.exited');\n }\n\n /**\n * Stay lobby time capped by a certain timestamp.\n * This is to handle the case where the target end timestamp could happen before the lobby is exited,\n * for example media-engine.ready or client.ice.end\n * This is supposed to be called AFTER the end timestamp happens\n * @param endTimestampKey name of the target end event\n * @returns - latency\n */\n public getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames) {\n const lobbyStartTimestamp = this.latencyTimestamps.get('client.lobby.entered'); // might not exist (some meetings don't have lobby)\n\n if (typeof lobbyStartTimestamp !== 'number') {\n // no lobby in the meeting, stayLobbyTime is 0\n return 0;\n }\n\n const lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist (if user still in lobby at the time of measurement)\n const maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist\n\n if (typeof maximumEndTimestamp !== 'number') {\n // the provided timestamp to be used as a cap should exist, return undefined if it doesn't\n return undefined;\n }\n\n const endTimestamp =\n typeof lobbyEndTimestamp === 'number'\n ? Math.min(lobbyEndTimestamp, maximumEndTimestamp)\n : maximumEndTimestamp;\n\n return clamp(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);\n }\n\n /**\n * Page JMT\n * @returns - latency\n */\n public getPageJMT() {\n const latency = this.precomputedLatencies.get('internal.client.pageJMT');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Download Time JMT\n * @returns - latency\n */\n public getDownloadTimeJMT() {\n const latency = this.precomputedLatencies.get('internal.download.time');\n\n return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;\n }\n\n /**\n * Click To Interstitial\n * @returns - latency\n */\n public getClickToInterstitial() {\n const clickToInterstitialLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial'\n );\n\n if (typeof clickToInterstitialLatency === 'number') {\n return clamp(clickToInterstitialLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Click To Interstitial With User Delay\n * @returns - latency\n */\n public getClickToInterstitialWithUserDelay() {\n const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.with.user.delay'\n );\n\n if (typeof clickToInterstitialWithUserDelayLatency === 'number') {\n return clamp(clickToInterstitialWithUserDelayLatency, 0, this.MAX_INTEGER);\n }\n\n return undefined;\n }\n\n /**\n * Interstitial To Join Ok\n * @returns - latency\n */\n public getInterstitialToJoinOK() {\n const interstitialShowedToJoinResp = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (typeof interstitialShowedToJoinResp !== 'number') {\n return undefined;\n }\n\n return clamp(interstitialShowedToJoinResp - showInterstitialTime, 0, this.MAX_INTEGER);\n }\n\n /**\n * Call Init To MediaEngineReady\n * @returns - latency\n */\n public getCallInitMediaEngineReady() {\n return this.getInterstitialToMediaOKJMT();\n }\n\n /**\n * Interstitial To Media Ok\n * @returns - latency\n */\n public getInterstitialToMediaOKJMT() {\n const interstitialShowedToIceEnd = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.ice.end'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');\n\n if (\n typeof interstitialShowedToIceEnd === 'number' &&\n typeof stayLobbyTimeCappedByIceEnd === 'number'\n ) {\n return clamp(\n interstitialShowedToIceEnd - showInterstitialTime - stayLobbyTimeCappedByIceEnd,\n 0,\n this.MAX_INTEGER\n );\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 interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitial + interstitialShowedToJoinLocusResponse - showInterstitialTime,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total JMT With User Delay\n * @returns - latency\n */\n public getTotalJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.response'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToJoinLocusResponse === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToJoinLocusResponse,\n 0,\n this.MAX_INTEGER\n );\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 clamp(joinReqResp + ICESetupTime, 0, this.MAX_INTEGER);\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 interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.media-engine.ready'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitial === 'number' &&\n typeof interstitialShowedToMediaEngineReady === 'number' &&\n typeof stayLobbyTimeCappedByMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitial +\n interstitialShowedToMediaEngineReady -\n showInterstitialTime -\n stayLobbyTimeCappedByMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Total Media JMT With User Delay\n * @returns - latency\n */\n public getTotalMediaJMTWithUserDelay() {\n const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();\n const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.media-engine.ready'\n );\n\n if (\n typeof clickToInterstitialWithUserDelay === 'number' &&\n typeof interstitialShowedToMediaEngineReady === 'number'\n ) {\n return clamp(\n clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady,\n 0,\n this.MAX_INTEGER\n );\n }\n\n return undefined;\n }\n\n /**\n * Client JMT\n * @returns - latency\n */\n public getClientJMT() {\n const clickToInterstitialForClientJmt = this.precomputedLatencies.get(\n 'internal.click.to.interstitial.for.client.jmt'\n );\n const interstitialShowedToLocusJoinRequest = this.getDiffBetweenTimestamps(\n 'internal.client.meeting.interstitial-window.showed',\n 'client.locus.join.request'\n );\n const showInterstitialTime = this.getShowInterstitialTime() || 0;\n\n if (\n typeof clickToInterstitialForClientJmt === 'number' &&\n typeof interstitialShowedToLocusJoinRequest === 'number'\n ) {\n return clamp(\n clickToInterstitialForClientJmt +\n interstitialShowedToLocusJoinRequest -\n showInterstitialTime,\n 0,\n this.MAX_INTEGER\n );\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 typeof reachablityClusterReqResp === 'number'\n ? clamp(Math.floor(reachablityClusterReqResp), 0, this.MAX_INTEGER)\n : 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 * Time from share initiation to share stop (ms).\n */\n public getShareDuration() {\n return this.getDiffBetweenTimestamps(\n 'internal.client.share.initiated',\n 'internal.client.share.stopped'\n );\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 typeof exchangeCITokenJMT === 'number'\n ? clamp(Math.floor(exchangeCITokenJMT), 0, this.MAX_INTEGER)\n : 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 typeof refreshCaptchaReqResp === 'number'\n ? clamp(Math.floor(refreshCaptchaReqResp), 0, this.MAX_INTEGER)\n : 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 typeof downloadIntelligenceModelsReqResp === 'number'\n ? clamp(Math.floor(downloadIntelligenceModelsReqResp), 0, this.MAX_INTEGER)\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 ? clamp(Math.floor(otherAppApiJMT), 0, this.MAX_INTEGER) : undefined;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
 
3
+ var _typeof = require("@babel/runtime-corejs2/helpers/typeof");
3
4
  var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
4
5
  var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
5
6
  var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
@@ -7,6 +8,7 @@ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/o
7
8
  var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
8
9
  var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
9
10
  var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
11
+ var _WeakMap2 = require("@babel/runtime-corejs2/core-js/weak-map");
10
12
  var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
11
13
  _Object$defineProperty(exports, "__esModule", {
12
14
  value: true
@@ -32,11 +34,13 @@ var _uuid = _interopRequireDefault(require("uuid"));
32
34
  var _lodash = require("lodash");
33
35
  var _webexCore = require("@webex/webex-core");
34
36
  var _metrics = require("../metrics");
37
+ var AutomatedUserUtils = _interopRequireWildcard(require("../automated-user"));
35
38
  var _callDiagnosticMetrics = require("./call-diagnostic-metrics.util");
36
39
  var _config = require("../config");
37
40
  var _callDiagnosticMetricsBatcher = _interopRequireDefault(require("./call-diagnostic-metrics-batcher"));
38
41
  var _preloginMetricsBatcher = _interopRequireDefault(require("../prelogin-metrics-batcher"));
39
42
  var _config2 = require("./config");
43
+ function _interopRequireWildcard(e, t) { if ("function" == typeof _WeakMap2) var r = new _WeakMap2(), n = new _WeakMap2(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = _Object$defineProperty) && _Object$getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
40
44
  function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
41
45
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; }
42
46
  function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
@@ -67,8 +71,6 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
67
71
  (0, _defineProperty2.default)(_this, "callDiagnosticEventsBatcher", void 0);
68
72
  // @ts-ignore
69
73
  (0, _defineProperty2.default)(_this, "preLoginMetricsBatcher", void 0);
70
- (0, _defineProperty2.default)(_this, "logger", void 0);
71
- // to avoid adding @ts-ignore everywhere
72
74
  (0, _defineProperty2.default)(_this, "hasLoggedBrowserSerial", void 0);
73
75
  (0, _defineProperty2.default)(_this, "device", void 0);
74
76
  (0, _defineProperty2.default)(_this, "delayedClientEvents", []);
@@ -91,21 +93,17 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
91
93
  * Prepare the event and send the request to metrics-a service, pre login.
92
94
  * @param event
93
95
  * @param preLoginId
94
- * @param markTelemetryOptOutOnResponse
95
96
  * @returns
96
97
  */
97
98
  (0, _defineProperty2.default)(_this, "submitToCallDiagnosticsPreLogin", function (event, preLoginId) {
98
99
  // build metrics-a event type
99
100
  var finalEvent = {
100
101
  eventPayload: event,
101
- type: ['diagnostic-event'],
102
- markTelemetryOptOutOnResponse: true
102
+ type: ['diagnostic-event']
103
103
  };
104
104
  _this.preLoginMetricsBatcher.savePreLoginId(preLoginId);
105
105
  return _this.preLoginMetricsBatcher.request(finalEvent);
106
106
  });
107
- _this.logger = _this.webex.logger;
108
- // @ts-ignore
109
107
  _this.callDiagnosticEventsBatcher = new _callDiagnosticMetricsBatcher.default({}, {
110
108
  parent: _this.webex
111
109
  });
@@ -122,6 +120,14 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
122
120
  */
123
121
  (0, _inherits2.default)(CallDiagnosticMetrics, _StatelessWebexPlugin);
124
122
  return (0, _createClass2.default)(CallDiagnosticMetrics, [{
123
+ key: "logger",
124
+ get:
125
+ // lazy getter to avoid @ts-ignore on every call site
126
+ function get() {
127
+ // @ts-ignore
128
+ return this.webex.logger;
129
+ }
130
+ }, {
125
131
  key: "getCurLoginType",
126
132
  value: function getCurLoginType() {
127
133
  // @ts-ignore
@@ -132,6 +138,23 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
132
138
  return null;
133
139
  }
134
140
 
141
+ /**
142
+ * Returns the user activation state reported from the browser's navigator.userActivation API
143
+ * @returns object with hasBeenActive and isActive booleans, or undefined if unavailable
144
+ */
145
+ }, {
146
+ key: "getUserActivation",
147
+ value: function getUserActivation() {
148
+ var userActivation = typeof navigator !== 'undefined' ? navigator.userActivation : undefined;
149
+ if (userActivation) {
150
+ return {
151
+ hasBeenActive: userActivation.hasBeenActive,
152
+ isActive: userActivation.isActive
153
+ };
154
+ }
155
+ return undefined;
156
+ }
157
+
135
158
  /**
136
159
  * Returns the telemetryOptOut value of the current user
137
160
  * @returns one of 'manual', 'automatic', undefined
@@ -243,13 +266,13 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
243
266
  }, {
244
267
  key: "getOrigin",
245
268
  value: function getOrigin(options, meetingId) {
246
- var _this$webex$meetings$, _this$webex$meetings$2, _this$webex$meetings$3, _this$webex$meetings$4, _this$webex$meetings$5, _this$webex$meetings$6;
269
+ var _this$webex$meetings, _this$webex$meetings$, _this$webex$meetings$2, _this$webex$meetings2, _this$webex$meetings3, _this$webex$meetings4, _this$webex$meetings5, _this$webex$meetings6, _this$webex$meetings7;
247
270
  var defaultClientType = // @ts-ignore
248
- (_this$webex$meetings$ = this.webex.meetings.config) === null || _this$webex$meetings$ === void 0 ? void 0 : (_this$webex$meetings$2 = _this$webex$meetings$.metrics) === null || _this$webex$meetings$2 === void 0 ? void 0 : _this$webex$meetings$2.clientType;
271
+ (_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$ = _this$webex$meetings.config) === null || _this$webex$meetings$ === void 0 ? void 0 : (_this$webex$meetings$2 = _this$webex$meetings$.metrics) === null || _this$webex$meetings$2 === void 0 ? void 0 : _this$webex$meetings$2.clientType;
249
272
  var defaultSubClientType = // @ts-ignore
250
- (_this$webex$meetings$3 = this.webex.meetings.config) === null || _this$webex$meetings$3 === void 0 ? void 0 : (_this$webex$meetings$4 = _this$webex$meetings$3.metrics) === null || _this$webex$meetings$4 === void 0 ? void 0 : _this$webex$meetings$4.subClientType;
273
+ (_this$webex$meetings2 = this.webex.meetings) === null || _this$webex$meetings2 === void 0 ? void 0 : (_this$webex$meetings3 = _this$webex$meetings2.config) === null || _this$webex$meetings3 === void 0 ? void 0 : (_this$webex$meetings4 = _this$webex$meetings3.metrics) === null || _this$webex$meetings4 === void 0 ? void 0 : _this$webex$meetings4.subClientType;
251
274
  // @ts-ignore
252
- var providedClientVersion = (_this$webex$meetings$5 = this.webex.meetings.config) === null || _this$webex$meetings$5 === void 0 ? void 0 : (_this$webex$meetings$6 = _this$webex$meetings$5.metrics) === null || _this$webex$meetings$6 === void 0 ? void 0 : _this$webex$meetings$6.clientVersion;
275
+ var providedClientVersion = (_this$webex$meetings5 = this.webex.meetings) === null || _this$webex$meetings5 === void 0 ? void 0 : (_this$webex$meetings6 = _this$webex$meetings5.config) === null || _this$webex$meetings6 === void 0 ? void 0 : (_this$webex$meetings7 = _this$webex$meetings6.metrics) === null || _this$webex$meetings7 === void 0 ? void 0 : _this$webex$meetings7.clientVersion;
253
276
  // @ts-ignore
254
277
  var defaultSDKClientVersion = "".concat(_config.CLIENT_NAME, "/").concat(this.webex.version);
255
278
  var versionMetadata = {};
@@ -263,13 +286,13 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
263
286
  this.hasLoggedBrowserSerial = true;
264
287
  }
265
288
  if (defaultClientType && defaultSubClientType || options.clientType && options.subClientType) {
266
- var _this$webex$meetings, _this$webex$meetings$7, _this$webex$meetings$8, _this$webex$meetings$9, _this$webex$meetings$0, _this$webex$meetings$1;
289
+ var _this$webex$meetings8, _this$webex$meetings9, _this$webex$meetings0, _this$webex$meetings1, _this$webex$meetings10, _this$webex$meetings11, _this$webex$meetings12, _this$webex$meetings13, _this$webex$meetings14;
267
290
  var origin = {
268
291
  name: 'endpoint',
269
292
  networkType: (options === null || options === void 0 ? void 0 : options.networkType) || 'unknown',
270
293
  userAgent: (0, _callDiagnosticMetrics.userAgentToString)({
271
294
  // @ts-ignore
272
- clientName: (_this$webex$meetings = this.webex.meetings) === null || _this$webex$meetings === void 0 ? void 0 : (_this$webex$meetings$7 = _this$webex$meetings.config) === null || _this$webex$meetings$7 === void 0 ? void 0 : (_this$webex$meetings$8 = _this$webex$meetings$7.metrics) === null || _this$webex$meetings$8 === void 0 ? void 0 : _this$webex$meetings$8.clientName,
295
+ clientName: (_this$webex$meetings8 = this.webex.meetings) === null || _this$webex$meetings8 === void 0 ? void 0 : (_this$webex$meetings9 = _this$webex$meetings8.config) === null || _this$webex$meetings9 === void 0 ? void 0 : (_this$webex$meetings0 = _this$webex$meetings9.metrics) === null || _this$webex$meetings0 === void 0 ? void 0 : _this$webex$meetings0.clientName,
273
296
  // @ts-ignore
274
297
  webexVersion: this.webex.version
275
298
  }),
@@ -279,9 +302,9 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
279
302
  }, versionMetadata), {}, {
280
303
  publicNetworkPrefix:
281
304
  // @ts-ignore
282
- (0, _callDiagnosticMetrics.anonymizeIPAddress)((_this$webex$meetings$9 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$9 === void 0 ? void 0 : _this$webex$meetings$9.clientAddress) || undefined,
305
+ (0, _callDiagnosticMetrics.anonymizeIPAddress)((_this$webex$meetings1 = this.webex.meetings) === null || _this$webex$meetings1 === void 0 ? void 0 : (_this$webex$meetings10 = _this$webex$meetings1.geoHintInfo) === null || _this$webex$meetings10 === void 0 ? void 0 : _this$webex$meetings10.clientAddress) || undefined,
283
306
  localNetworkPrefix: (0, _callDiagnosticMetrics.anonymizeIPAddress)(// @ts-ignore
284
- (_this$webex$meetings$0 = this.webex.meetings.meetingCollection.get(meetingId)) === null || _this$webex$meetings$0 === void 0 ? void 0 : (_this$webex$meetings$1 = _this$webex$meetings$0.statsAnalyzer) === null || _this$webex$meetings$1 === void 0 ? void 0 : _this$webex$meetings$1.getLocalIpAddress()) || undefined,
307
+ (_this$webex$meetings11 = this.webex.meetings) === null || _this$webex$meetings11 === void 0 ? void 0 : (_this$webex$meetings12 = _this$webex$meetings11.meetingCollection) === null || _this$webex$meetings12 === void 0 ? void 0 : (_this$webex$meetings13 = _this$webex$meetings12.get(meetingId)) === null || _this$webex$meetings13 === void 0 ? void 0 : (_this$webex$meetings14 = _this$webex$meetings13.statsAnalyzer) === null || _this$webex$meetings14 === void 0 ? void 0 : _this$webex$meetings14.getLocalIpAddress()) || undefined,
285
308
  osVersion: getOSVersion() || 'unknown',
286
309
  subClientType: (options === null || options === void 0 ? void 0 : options.subClientType) || defaultSubClientType,
287
310
  os: (0, _metrics.getOSNameInternal)(),
@@ -411,7 +434,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
411
434
  }, {
412
435
  key: "prepareDiagnosticEvent",
413
436
  value: function prepareDiagnosticEvent(eventData, options) {
414
- var _this$webex$meetings$10;
437
+ var _this$webex$meetings15, _this$webex$meetings16;
415
438
  var meetingId = options.meetingId,
416
439
  triggeredTime = options.triggeredTime;
417
440
  var origin = this.getOrigin(options, meetingId);
@@ -425,7 +448,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
425
448
  sent: 'not_defined_yet'
426
449
  },
427
450
  // @ts-ignore
428
- senderCountryCode: (_this$webex$meetings$10 = this.webex.meetings.geoHintInfo) === null || _this$webex$meetings$10 === void 0 ? void 0 : _this$webex$meetings$10.countryCode,
451
+ senderCountryCode: (_this$webex$meetings15 = this.webex.meetings) === null || _this$webex$meetings15 === void 0 ? void 0 : (_this$webex$meetings16 = _this$webex$meetings15.geoHintInfo) === null || _this$webex$meetings16 === void 0 ? void 0 : _this$webex$meetings16.countryCode,
429
452
  event: eventData
430
453
  };
431
454
 
@@ -899,7 +922,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
899
922
  }, {
900
923
  key: "createCommonEventObjectInMeeting",
901
924
  value: function createCommonEventObjectInMeeting(_ref8) {
902
- var _this$webex$meetings2, _this$webex$meetings3, _this$webex$meetings4, _meeting$meetingInfo0, _navigator, _options$joinFlowVers, _meeting$callStateFor;
925
+ var _this$webex$meetings17, _this$webex$meetings18, _this$webex$meetings19, _meeting$meetingInfo0, _options$joinFlowVers, _meeting$callStateFor;
903
926
  var name = _ref8.name,
904
927
  options = _ref8.options,
905
928
  _ref8$eventType = _ref8.eventType,
@@ -954,9 +977,10 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
954
977
  }), {}, {
955
978
  webexSubServiceType: this.getSubServiceType(meeting),
956
979
  // @ts-ignore
957
- webClientPreload: (_this$webex$meetings2 = this.webex.meetings) === null || _this$webex$meetings2 === void 0 ? void 0 : (_this$webex$meetings3 = _this$webex$meetings2.config) === null || _this$webex$meetings3 === void 0 ? void 0 : (_this$webex$meetings4 = _this$webex$meetings3.metrics) === null || _this$webex$meetings4 === void 0 ? void 0 : _this$webex$meetings4.webClientPreload,
980
+ webClientPreload: (_this$webex$meetings17 = this.webex.meetings) === null || _this$webex$meetings17 === void 0 ? void 0 : (_this$webex$meetings18 = _this$webex$meetings17.config) === null || _this$webex$meetings18 === void 0 ? void 0 : (_this$webex$meetings19 = _this$webex$meetings18.metrics) === null || _this$webex$meetings19 === void 0 ? void 0 : _this$webex$meetings19.webClientPreload,
958
981
  isVipMeeting: (meeting === null || meeting === void 0 ? void 0 : (_meeting$meetingInfo0 = meeting.meetingInfo) === null || _meeting$meetingInfo0 === void 0 ? void 0 : _meeting$meetingInfo0.vipmeeting) || false,
959
- isAutomatedUser: typeof window !== 'undefined' && typeof navigator !== 'undefined' && !!((_navigator = navigator) !== null && _navigator !== void 0 && _navigator.webdriver) // if webdriver is true, it's most likely in a test environment
982
+ isAutomatedUser: AutomatedUserUtils.isAutomatedUser(),
983
+ userActivation: this.getUserActivation()
960
984
  });
961
985
  var joinFlowVersion = (_options$joinFlowVers = options.joinFlowVersion) !== null && _options$joinFlowVers !== void 0 ? _options$joinFlowVers : (_meeting$callStateFor = meeting.callStateForMetrics) === null || _meeting$callStateFor === void 0 ? void 0 : _meeting$callStateFor.joinFlowVersion;
962
986
  if (joinFlowVersion) {
@@ -1034,7 +1058,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
1034
1058
  }, {
1035
1059
  key: "createClientEventObjectPreMeeting",
1036
1060
  value: function createClientEventObjectPreMeeting(_ref1) {
1037
- var _this$webex$meetings5, _this$webex$meetings6, _this$webex$meetings7, _navigator2;
1061
+ var _this$webex$meetings20, _this$webex$meetings21, _this$webex$meetings22;
1038
1062
  var name = _ref1.name,
1039
1063
  options = _ref1.options,
1040
1064
  errors = _ref1.errors;
@@ -1066,8 +1090,9 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
1066
1090
  loginType: this.getCurLoginType(),
1067
1091
  telemetryOptOut: this.getTelemetryOptOut(),
1068
1092
  // @ts-ignore
1069
- webClientPreload: (_this$webex$meetings5 = this.webex.meetings) === null || _this$webex$meetings5 === void 0 ? void 0 : (_this$webex$meetings6 = _this$webex$meetings5.config) === null || _this$webex$meetings6 === void 0 ? void 0 : (_this$webex$meetings7 = _this$webex$meetings6.metrics) === null || _this$webex$meetings7 === void 0 ? void 0 : _this$webex$meetings7.webClientPreload,
1070
- isAutomatedUser: typeof window !== 'undefined' && typeof navigator !== 'undefined' && !!((_navigator2 = navigator) !== null && _navigator2 !== void 0 && _navigator2.webdriver) // if webdriver is true, it's most likely in a test environment
1093
+ webClientPreload: (_this$webex$meetings20 = this.webex.meetings) === null || _this$webex$meetings20 === void 0 ? void 0 : (_this$webex$meetings21 = _this$webex$meetings20.config) === null || _this$webex$meetings21 === void 0 ? void 0 : (_this$webex$meetings22 = _this$webex$meetings21.metrics) === null || _this$webex$meetings22 === void 0 ? void 0 : _this$webex$meetings22.webClientPreload,
1094
+ isAutomatedUser: AutomatedUserUtils.isAutomatedUser(),
1095
+ userActivation: this.getUserActivation()
1071
1096
  };
1072
1097
  if (options.joinFlowVersion) {
1073
1098
  clientEventObject.joinFlowVersion = options.joinFlowVersion;
@@ -1253,8 +1278,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
1253
1278
  // build metrics-a event type
1254
1279
  var finalEvent = {
1255
1280
  eventPayload: event,
1256
- type: ['diagnostic-event'],
1257
- markTelemetryOptOutOnResponse: true
1281
+ type: ['diagnostic-event']
1258
1282
  };
1259
1283
  return this.callDiagnosticEventsBatcher.request(finalEvent);
1260
1284
  }
@@ -1272,6 +1296,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
1272
1296
  */
1273
1297
  function () {
1274
1298
  var _buildClientEventFetchRequestOptions = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee(_ref12) {
1299
+ var _this$webex$internal$, _this$webex$internal$2;
1275
1300
  var name, payload, options, clientEvent, diagnosticEvent, request;
1276
1301
  return _regenerator.default.wrap(function (_context) {
1277
1302
  while (1) switch (_context.prev = _context.next) {
@@ -1297,7 +1322,7 @@ var CallDiagnosticMetrics = exports.default = /*#__PURE__*/function (_StatelessW
1297
1322
  },
1298
1323
  headers: {},
1299
1324
  // @ts-ignore
1300
- waitForServiceTimeout: this.webex.internal.metrics.config.waitForServiceTimeout
1325
+ waitForServiceTimeout: (_this$webex$internal$ = this.webex.internal.metrics) === null || _this$webex$internal$ === void 0 ? void 0 : (_this$webex$internal$2 = _this$webex$internal$.config) === null || _this$webex$internal$2 === void 0 ? void 0 : _this$webex$internal$2.waitForServiceTimeout
1301
1326
  };
1302
1327
  if (options.preLoginId) {
1303
1328
  request.headers = {