@webex/internal-plugin-metrics 3.9.0-webinar5k.1 → 3.10.0-multi-llms.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/metrics.js CHANGED
@@ -148,7 +148,7 @@ var Metrics = _webexCore.WebexPlugin.extend({
148
148
  }
149
149
  });
150
150
  },
151
- version: "3.9.0-webinar5k.1"
151
+ version: "3.10.0-multi-llms.1"
152
152
  });
153
153
  var _default = exports.default = Metrics;
154
154
  //# sourceMappingURL=metrics.js.map
@@ -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 FeatureEvent as RawFeatureEvent,\n} from '@webex/event-dictionary-ts';\n\nexport type Event = Omit<RawEvent, 'event'> & {\n event: RawClientEvent | RawMediaQualityEvent | RawFeatureEvent;\n};\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 ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;\n\nexport type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;\n\nexport type BrowserLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['browserLaunchMethod'];\n\nexport type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';\n\nexport type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';\n\nexport type MetricEventVerb =\n | 'abort'\n | 'accept'\n | 'activate'\n | 'apply'\n | 'answer'\n | 'authorize'\n | 'build'\n | 'cancel'\n | 'change'\n | 'click'\n | 'close'\n | 'complete'\n | 'connect'\n | 'create'\n | 'deactivate'\n | 'decrypt'\n | 'delete'\n | 'deliver'\n | 'destroy'\n | 'disable'\n | 'disconnect'\n | 'dismiss'\n | 'display'\n | 'download'\n | 'edit'\n | 'enable'\n | 'encrypt'\n | 'end'\n | 'expire'\n | 'fail'\n | 'fetch'\n | 'fire'\n | 'generate'\n | 'get'\n | 'hide'\n | 'hover'\n | 'ignore'\n | 'initialize'\n | 'initiate'\n | 'invalidate'\n | 'join'\n | 'list'\n | 'load'\n | 'login'\n | 'logout'\n | 'notify'\n | 'offer'\n | 'open'\n | 'press'\n | 'receive'\n | 'refer'\n | 'refresh'\n | 'register'\n | 'release'\n | 'reload'\n | 'reject'\n | 'request'\n | 'reset'\n | 'resize'\n | 'respond'\n | 'retry'\n | 'revoke'\n | 'save'\n | 'search'\n | 'select'\n | 'send'\n | 'set'\n | 'sign'\n | 'start'\n | 'submit'\n | 'switch'\n | 'sync'\n | 'toggle'\n | 'transfer'\n | 'unregister'\n | 'update'\n | 'upload'\n | 'use'\n | 'validate'\n | 'view'\n | 'visit'\n | 'wait'\n | 'warn'\n | 'exit';\n\nexport type MetricEventJoinFlowVersion = 'Other' | 'NewFTE';\nexport type MetricEventMeetingJoinPhase = 'pre-join' | 'join' | 'in-meeting';\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n correlationId?: string;\n sessionCorrelationId?: string;\n preLoginId?: string;\n environment?: EnvironmentType;\n newEnvironmentType?: NewEnvironmentType;\n clientLaunchMethod?: ClientLaunchMethodType;\n browserLaunchMethod?: BrowserLaunchMethodType;\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n joinFlowVersion?: MetricEventJoinFlowVersion;\n meetingJoinPhase?: MetricEventMeetingJoinPhase;\n triggeredTime?: string;\n emailInput?: ClientEmailInput;\n userNameInput?: ClientUserNameInput;\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 DeviceContext {\n app: {version: string};\n device: {id: string};\n locale: string;\n os: {\n name: string;\n version: string;\n };\n}\n\nexport type MetricType = 'behavioral' | 'operational' | 'business';\n\nexport type Table = 'wbxapp_callend_metrics' | 'business_metrics' | 'business_ucf' | 'default';\n\ntype InternalEventPayload = string | number | boolean;\nexport type EventPayload = Record<string, InternalEventPayload>;\nexport type BehavioralEventPayload = EventPayload; // for compatibilty, can be remove after wxcc-desktop did change their imports.\n\nexport interface BusinessEventPayload {\n metricName: string;\n timestamp: number;\n context: DeviceContext;\n browserDetails: EventPayload;\n value: EventPayload;\n}\n\nexport interface BusinessEvent {\n type: string[];\n eventPayload: BusinessEventPayload;\n}\n\nexport interface TaggedEvent {\n context: DeviceContext;\n metricName: string;\n tags: EventPayload;\n timestamp: number;\n type: [MetricType];\n}\n\nexport type BehavioralEvent = TaggedEvent;\nexport type OperationalEvent = TaggedEvent;\n\nexport interface FeatureEvent {\n name: RawFeatureEvent['name'];\n payload?: RawFeatureEvent;\n options?: SubmitClientEventOptions;\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['metricName']\n | OperationalEvent['metricName']\n | BusinessEvent['eventPayload']['metricName']\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 ClientFeatureEventPayload = RecursivePartial<FeatureEvent['payload']>;\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 product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: EventPayload;\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['metricName'];\n payload: EventPayload;\n}) => void;\n\nexport type SubmitBusinessEvent = (args: {\n name: OperationalEvent['metricName'];\n payload: EventPayload;\n metadata?: EventPayload;\n table?: Table;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type PreComputedLatencies =\n | 'internal.client.pageJMT'\n | 'internal.download.time'\n | 'internal.get.cluster.time'\n | 'internal.click.to.interstitial'\n | 'internal.click.to.interstitial.with.user.delay'\n | 'internal.refresh.captcha.time'\n | 'internal.exchange.ci.token.time'\n | 'internal.get.u2c.time'\n | 'internal.call.init.join.req'\n | 'internal.other.app.api.time'\n | 'internal.api.fetch.intelligence.models';\n\nexport interface IdType {\n meetingId?: string;\n callId?: string;\n}\n\nexport interface IMetricsAttributes {\n type: string;\n version: string;\n userId: string;\n correlationId: string;\n connectionId: string;\n data: any[];\n meetingId?: string;\n callId?: string;\n}\n\nexport interface DelayedClientEvent {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}\n\nexport type SubmitFeatureEvent = (args: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport interface DelayedClientFeatureEvent {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options?: SubmitClientEventOptions;\n}\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 FeatureEvent as RawFeatureEvent,\n} from '@webex/event-dictionary-ts';\n\nexport type Event = Omit<RawEvent, 'event'> & {\n event: RawClientEvent | RawMediaQualityEvent | RawFeatureEvent;\n};\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 ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;\n\nexport type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;\n\nexport type BrowserLaunchMethodType = NonNullable<\n RawEvent['origin']['clientInfo']\n>['browserLaunchMethod'];\n\nexport type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';\n\nexport type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';\n\nexport type MetricEventVerb =\n | 'abort'\n | 'accept'\n | 'activate'\n | 'apply'\n | 'answer'\n | 'authorize'\n | 'build'\n | 'cancel'\n | 'change'\n | 'click'\n | 'close'\n | 'complete'\n | 'connect'\n | 'create'\n | 'deactivate'\n | 'decrypt'\n | 'delete'\n | 'deliver'\n | 'destroy'\n | 'disable'\n | 'disconnect'\n | 'dismiss'\n | 'display'\n | 'download'\n | 'edit'\n | 'enable'\n | 'encrypt'\n | 'end'\n | 'expire'\n | 'fail'\n | 'fetch'\n | 'fire'\n | 'generate'\n | 'get'\n | 'hide'\n | 'hover'\n | 'ignore'\n | 'initialize'\n | 'initiate'\n | 'invalidate'\n | 'join'\n | 'list'\n | 'load'\n | 'login'\n | 'logout'\n | 'notify'\n | 'offer'\n | 'open'\n | 'press'\n | 'receive'\n | 'refer'\n | 'refresh'\n | 'register'\n | 'release'\n | 'reload'\n | 'reject'\n | 'request'\n | 'reset'\n | 'resize'\n | 'respond'\n | 'retry'\n | 'revoke'\n | 'save'\n | 'search'\n | 'select'\n | 'send'\n | 'set'\n | 'sign'\n | 'start'\n | 'submit'\n | 'switch'\n | 'sync'\n | 'toggle'\n | 'transfer'\n | 'unregister'\n | 'update'\n | 'upload'\n | 'use'\n | 'validate'\n | 'view'\n | 'visit'\n | 'wait'\n | 'warn'\n | 'exit';\n\nexport type MetricEventJoinFlowVersion = 'Other' | 'NewFTE';\nexport type MetricEventMeetingJoinPhase = 'pre-join' | 'join' | 'in-meeting';\n\nexport type SubmitClientEventOptions = {\n meetingId?: string;\n mediaConnections?: any[];\n rawError?: any;\n correlationId?: string;\n sessionCorrelationId?: string;\n preLoginId?: string;\n environment?: EnvironmentType;\n newEnvironmentType?: NewEnvironmentType;\n clientLaunchMethod?: ClientLaunchMethodType;\n browserLaunchMethod?: BrowserLaunchMethodType;\n webexConferenceIdStr?: string;\n globalMeetingId?: string;\n joinFlowVersion?: MetricEventJoinFlowVersion;\n meetingJoinPhase?: MetricEventMeetingJoinPhase;\n triggeredTime?: string;\n emailInput?: ClientEmailInput;\n userNameInput?: ClientUserNameInput;\n vendorId?: 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 | 'internal.client.share.initiated'\n | 'internal.client.share.stopped';\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 DeviceContext {\n app: {version: string};\n device: {id: string};\n locale: string;\n os: {\n name: string;\n version: string;\n };\n}\n\nexport type MetricType = 'behavioral' | 'operational' | 'business';\n\nexport type Table = 'wbxapp_callend_metrics' | 'business_metrics' | 'business_ucf' | 'default';\n\ntype InternalEventPayload = string | number | boolean;\nexport type EventPayload = Record<string, InternalEventPayload>;\nexport type BehavioralEventPayload = EventPayload; // for compatibilty, can be remove after wxcc-desktop did change their imports.\n\nexport interface BusinessEventPayload {\n metricName: string;\n timestamp: number;\n context: DeviceContext;\n browserDetails: EventPayload;\n value: EventPayload;\n}\n\nexport interface BusinessEvent {\n type: string[];\n eventPayload: BusinessEventPayload;\n}\n\nexport interface TaggedEvent {\n context: DeviceContext;\n metricName: string;\n tags: EventPayload;\n timestamp: number;\n type: [MetricType];\n}\n\nexport type BehavioralEvent = TaggedEvent;\nexport type OperationalEvent = TaggedEvent;\n\nexport interface FeatureEvent {\n name: RawFeatureEvent['name'];\n payload?: RawFeatureEvent;\n options?: SubmitClientEventOptions;\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['metricName']\n | OperationalEvent['metricName']\n | BusinessEvent['eventPayload']['metricName']\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 ClientFeatureEventPayload = RecursivePartial<FeatureEvent['payload']>;\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 product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: EventPayload;\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['metricName'];\n payload: EventPayload;\n}) => void;\n\nexport type SubmitBusinessEvent = (args: {\n name: OperationalEvent['metricName'];\n payload: EventPayload;\n metadata?: EventPayload;\n table?: Table;\n}) => void;\n\nexport type SubmitMQE = (args: {\n name: MediaQualityEvent['name'];\n payload: SubmitMQEPayload;\n options: any;\n}) => void;\n\nexport type BuildClientEventFetchRequestOptions = (args: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport type PreComputedLatencies =\n | 'internal.client.pageJMT'\n | 'internal.download.time'\n | 'internal.get.cluster.time'\n | 'internal.click.to.interstitial'\n | 'internal.click.to.interstitial.with.user.delay'\n | 'internal.refresh.captcha.time'\n | 'internal.exchange.ci.token.time'\n | 'internal.get.u2c.time'\n | 'internal.call.init.join.req'\n | 'internal.other.app.api.time'\n | 'internal.api.fetch.intelligence.models';\n\nexport interface IdType {\n meetingId?: string;\n callId?: string;\n}\n\nexport interface IMetricsAttributes {\n type: string;\n version: string;\n userId: string;\n correlationId: string;\n connectionId: string;\n data: any[];\n meetingId?: string;\n callId?: string;\n}\n\nexport interface DelayedClientEvent {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n}\n\nexport type SubmitFeatureEvent = (args: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options?: SubmitClientEventOptions;\n}) => Promise<any>;\n\nexport interface DelayedClientFeatureEvent {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options?: SubmitClientEventOptions;\n}\n"],"mappings":""}
@@ -9,6 +9,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
9
9
  latencyTimestamps: Map<MetricEventNames, number>;
10
10
  precomputedLatencies: Map<PreComputedLatencies, number>;
11
11
  private meetingId?;
12
+ private MAX_INTEGER;
12
13
  /**
13
14
  * @constructor
14
15
  */
@@ -73,7 +74,10 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
73
74
  * @param b end
74
75
  * @returns latency
75
76
  */
76
- getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames): number;
77
+ getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames, clampValues?: {
78
+ minimum?: number;
79
+ maximum?: number;
80
+ }): number;
77
81
  /**
78
82
  * Meeting Info Request
79
83
  * @note Meeting Info request happen not just in the join phase. CA requires
@@ -230,6 +234,10 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
230
234
  * Video setup delay transmit
231
235
  */
232
236
  getVideoJoinRespTxStart(): number;
237
+ /**
238
+ * Time from share initiation to share stop (ms).
239
+ */
240
+ getShareDuration(): number;
233
241
  /**
234
242
  * Total latency for all exchange ci token.
235
243
  */
@@ -8,6 +8,7 @@ type GetOriginOptions = {
8
8
  browserLaunchMethod?: BrowserLaunchMethodType;
9
9
  environment?: EnvironmentType;
10
10
  newEnvironment?: NewEnvironmentType;
11
+ vendorId?: string;
11
12
  };
12
13
  type GetIdentifiersOptions = {
13
14
  meeting?: any;
@@ -33,6 +34,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
33
34
  private delayedClientFeatureEvents;
34
35
  private eventErrorCache;
35
36
  private isMercuryConnected;
37
+ private eventLimitTracker;
38
+ private eventLimitWarningsLogged;
36
39
  validator: (options: {
37
40
  type: 'mqe' | 'ce';
38
41
  event: Event;
@@ -77,7 +80,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
77
80
  * @returns
78
81
  */
79
82
  getOrigin(options: GetOriginOptions, meetingId?: string): {
80
- name: "endpoint" | "addin" | "antares" | "appapi" | "beech" | "breakout" | "calendar" | "cb" | "cca" | "ccc" | "cloudproxy" | "crc" | "edonus" | "givr" | "hecate" | "hedge" | "hesiod" | "homer" | "idbroker" | "superhomer" | "l2sip" | "linus" | "locus" | "mbs" | "mcc" | "mcs" | "mercury" | "mes" | "mjs" | "mmp" | "mrs" | "mygdon" | "ngpage" | "ngservice" | "oauth" | "orpheus" | "page" | "poros" | "publicapi" | "rhesos" | "terminus" | "tpgw" | "ucc" | "wdm" | "webexivr" | "meetingcontainer";
83
+ name: "endpoint" | "addin" | "antares" | "appapi" | "beech" | "breakout" | "calendar" | "cb" | "cca" | "ccc" | "cloudproxy" | "crc" | "edonus" | "givr" | "hecate" | "hedge" | "hesiod" | "homer" | "idbroker" | "superhomer" | "l2sip" | "linus" | "locus" | "mbs" | "mcc" | "mcs" | "mercury" | "mes" | "mjs" | "mmp" | "mrs" | "mygdon" | "ngpage" | "ngservice" | "oauth" | "orpheus" | "page" | "poros" | "publicapi" | "rhesos" | "sbs" | "terminus" | "tpgw" | "ucc" | "wdm" | "webexivr" | "meetingcontainer";
81
84
  userAgent: string;
82
85
  buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
83
86
  upgradeChannel?: string;
@@ -98,10 +101,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
98
101
  publicNetworkPrefix?: string;
99
102
  browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient" | "switch-to-web" | "switch-to-native";
100
103
  clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch" | "cws" | "installer" | "installer-launcher" | "launcher" | "cws-launcher";
104
+ urlProtocolLaunchMethod?: "manual" | "auto" | "extension-fallback";
101
105
  browser?: string;
102
106
  browserVersion?: string;
103
- clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC" | "TEAMS_PHONE";
104
- subClientType?: "TEAMS_DEVICE" | "AUTOMOTIVE_APP" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP" | "PHONE_NOVUM" | "PHONE_ESPRESSO" | "PHONE_BUMBLEBEE";
107
+ clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC" | "TEAMS_PHONE" | "WEBEX_RELAY";
108
+ subClientType?: "TEAMS_DEVICE" | "SIP" | "AUTOMOTIVE_APP" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP" | "PHONE_NOVUM" | "PHONE_ESPRESSO" | "PHONE_BUMBLEBEE" | "SIP_PSTN";
105
109
  schedulingClientType?: "TEAMS_CLIENT" | "GOOGLE_ADDON" | "PT" | "PUBLIC_API" | "UNIFIED_PAGE" | "WEBEX_PAGE" | "GOOGLE_NOTIFICATION_CALENDAR" | "MSFT_NOTIFICATION_ADDIN" | "MSFT_NOTIFICATION_CALENDAR" | "OUTLOOK_ADDIN";
106
110
  clientVersion?: string;
107
111
  clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
@@ -144,6 +148,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
144
148
  inMeetingUpdate?: boolean;
145
149
  mtaVersion?: string;
146
150
  isWarholOpening?: boolean;
151
+ vendorId?: string;
147
152
  additionalProperties?: false;
148
153
  };
149
154
  emmVendorId?: string;
@@ -241,6 +246,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
241
246
  recordingId?: string;
242
247
  clientCorrelationId?: string;
243
248
  idForEndpointAB?: string;
249
+ customerOrgId?: string;
244
250
  correlationId: string;
245
251
  additionalProperties?: false;
246
252
  } | {
@@ -327,6 +333,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
327
333
  recordingId?: string;
328
334
  clientCorrelationId?: string;
329
335
  idForEndpointAB?: string;
336
+ customerOrgId?: string;
330
337
  correlationId: string;
331
338
  additionalProperties?: false;
332
339
  } | {
@@ -413,6 +420,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
413
420
  recordingId?: string;
414
421
  clientCorrelationId?: string;
415
422
  idForEndpointAB?: string;
423
+ customerOrgId?: string;
416
424
  correlationId: string;
417
425
  additionalProperties?: false;
418
426
  };
@@ -482,6 +490,30 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
482
490
  * Clear the error cache
483
491
  */
484
492
  clearErrorCache(): void;
493
+ /**
494
+ * Checks if an event should be limited based on criteria defined in the event dictionary.
495
+ * Returns true if the event should be sent, false if it has reached its limit.
496
+ * @param event - The diagnostic event object
497
+ * @returns boolean indicating whether the event should be sent
498
+ */
499
+ private shouldSendEvent;
500
+ /**
501
+ * Checks the current count for a limit key and increments if under limit.
502
+ * @param limitKey - The unique key for this limit combination
503
+ * @param maxCount - Maximum allowed count
504
+ * @param eventDescription - Description for logging
505
+ * @returns true if under limit and incremented, false if at/over limit
506
+ */
507
+ private checkAndIncrementEventCount;
508
+ /**
509
+ * Clears event limit tracking
510
+ */
511
+ clearEventLimits(): void;
512
+ /**
513
+ * Clears event limit tracking for a specific correlationId only.
514
+ * Keeps limits for other meetings intact.
515
+ */
516
+ clearEventLimitsForCorrelationId(correlationId: string): void;
485
517
  /**
486
518
  * Generate error payload for Client Event
487
519
  * @param rawError
@@ -32,6 +32,7 @@ export type SubmitClientEventOptions = {
32
32
  triggeredTime?: string;
33
33
  emailInput?: ClientEmailInput;
34
34
  userNameInput?: ClientUserNameInput;
35
+ vendorId?: string;
35
36
  };
36
37
  export type SubmitMQEOptions = {
37
38
  meetingId: string;
@@ -41,7 +42,7 @@ export type SubmitMQEOptions = {
41
42
  globalMeetingId?: string;
42
43
  };
43
44
  export type InternalEvent = {
44
- 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';
45
+ 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' | 'internal.client.share.initiated' | 'internal.client.share.stopped';
45
46
  payload?: never;
46
47
  options?: never;
47
48
  };
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "directory": "packages/@webex/internal-plugin-metrics"
12
12
  },
13
13
  "engines": {
14
- "node": ">=16"
14
+ "node": ">=18"
15
15
  },
16
16
  "browserify": {
17
17
  "transform": [
@@ -26,22 +26,21 @@
26
26
  "@webex/eslint-config-legacy": "0.0.0",
27
27
  "@webex/jest-config-legacy": "0.0.0",
28
28
  "@webex/legacy-tools": "0.0.0",
29
- "@webex/test-helper-chai": "3.9.0-webinar5k.1",
30
- "@webex/test-helper-mocha": "3.9.0-webinar5k.1",
31
- "@webex/test-helper-mock-webex": "3.9.0-webinar5k.1",
32
- "@webex/test-helper-test-users": "3.9.0-webinar5k.1",
29
+ "@webex/test-helper-chai": "3.9.0-multi-llms.1",
30
+ "@webex/test-helper-mocha": "3.9.0-multi-llms.1",
31
+ "@webex/test-helper-mock-webex": "3.9.0-multi-llms.1",
32
+ "@webex/test-helper-test-users": "3.9.0-multi-llms.1",
33
33
  "eslint": "^8.24.0",
34
34
  "prettier": "^2.7.1",
35
35
  "sinon": "^9.2.4"
36
36
  },
37
37
  "dependencies": {
38
- "@webex/common": "3.9.0-webinar5k.1",
39
- "@webex/common-timers": "3.9.0-webinar5k.1",
40
- "@webex/event-dictionary-ts": "^1.0.1819",
41
- "@webex/internal-plugin-metrics": "3.9.0-webinar5k.1",
42
- "@webex/test-helper-chai": "3.9.0-webinar5k.1",
43
- "@webex/test-helper-mock-webex": "3.9.0-webinar5k.1",
44
- "@webex/webex-core": "3.9.0-webinar5k.1",
38
+ "@webex/common": "3.9.0-multi-llms.1",
39
+ "@webex/common-timers": "3.9.0-multi-llms.1",
40
+ "@webex/event-dictionary-ts": "^1.0.1930",
41
+ "@webex/test-helper-chai": "3.9.0-multi-llms.1",
42
+ "@webex/test-helper-mock-webex": "3.9.0-multi-llms.1",
43
+ "@webex/webex-core": "3.10.0-multi-llms.1",
45
44
  "ip-anonymize": "^0.1.0",
46
45
  "lodash": "^4.17.21",
47
46
  "uuid": "^3.3.2"
@@ -54,5 +53,5 @@
54
53
  "test:style": "eslint ./src/**/*.*",
55
54
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
56
55
  },
57
- "version": "3.9.0-webinar5k.1"
56
+ "version": "3.10.0-multi-llms.1"
58
57
  }
@@ -1,6 +1,7 @@
1
1
  /* eslint-disable class-methods-use-this */
2
2
  /* eslint-disable valid-jsdoc */
3
3
  import {WebexPlugin} from '@webex/webex-core';
4
+ import {clamp} from 'lodash';
4
5
 
5
6
  import {MetricEventNames, PreComputedLatencies} from '../metrics.types';
6
7
 
@@ -16,6 +17,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
16
17
  precomputedLatencies: Map<PreComputedLatencies, number>;
17
18
  // meetingId that the current latencies are for
18
19
  private meetingId?: string;
20
+ private MAX_INTEGER = 2147483647;
19
21
 
20
22
  /**
21
23
  * @constructor
@@ -148,15 +150,23 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
148
150
  * @param b end
149
151
  * @returns latency
150
152
  */
151
- public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {
153
+ public getDiffBetweenTimestamps(
154
+ a: MetricEventNames,
155
+ b: MetricEventNames,
156
+ clampValues?: {minimum?: number; maximum?: number}
157
+ ) {
152
158
  const start = this.latencyTimestamps.get(a);
153
159
  const end = this.latencyTimestamps.get(b);
154
160
 
155
- if (typeof start === 'number' && typeof end === 'number') {
156
- return end - start;
161
+ if (typeof start !== 'number' || typeof end !== 'number') {
162
+ return undefined;
157
163
  }
158
164
 
159
- return undefined;
165
+ const diff = end - start;
166
+
167
+ const {minimum = 0, maximum = this.MAX_INTEGER} = clampValues || {};
168
+
169
+ return clamp(diff, minimum, maximum);
160
170
  }
161
171
 
162
172
  /**
@@ -172,7 +182,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
172
182
  public getMeetingInfoReqResp() {
173
183
  return this.getDiffBetweenTimestamps(
174
184
  'internal.client.meetinginfo.request',
175
- 'internal.client.meetinginfo.response'
185
+ 'internal.client.meetinginfo.response',
186
+ {maximum: 1200000}
176
187
  );
177
188
  }
178
189
 
@@ -215,7 +226,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
215
226
  public getCallInitJoinReq() {
216
227
  return this.getDiffBetweenTimestamps(
217
228
  'internal.client.interstitial-window.click.joinbutton',
218
- 'client.locus.join.request'
229
+ 'client.locus.join.request',
230
+ {maximum: 1200000}
219
231
  );
220
232
  }
221
233
 
@@ -224,7 +236,11 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
224
236
  * @returns - latency
225
237
  */
226
238
  public getJoinReqResp() {
227
- return this.getDiffBetweenTimestamps('client.locus.join.request', 'client.locus.join.response');
239
+ return this.getDiffBetweenTimestamps(
240
+ 'client.locus.join.request',
241
+ 'client.locus.join.response',
242
+ {maximum: 1200000}
243
+ );
228
244
  }
229
245
 
230
246
  /**
@@ -245,7 +261,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
245
261
  public getLocalSDPGenRemoteSDPRecv() {
246
262
  return this.getDiffBetweenTimestamps(
247
263
  'client.media-engine.local-sdp-generated',
248
- 'client.media-engine.remote-sdp-received'
264
+ 'client.media-engine.remote-sdp-received',
265
+ {maximum: 1200000}
249
266
  );
250
267
  }
251
268
 
@@ -254,7 +271,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
254
271
  * @returns - latency
255
272
  */
256
273
  public getICESetupTime() {
257
- return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end');
274
+ return this.getDiffBetweenTimestamps('client.ice.start', 'client.ice.end', {maximum: 1200000});
258
275
  }
259
276
 
260
277
  /**
@@ -299,7 +316,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
299
316
  public getPageJMT() {
300
317
  const latency = this.precomputedLatencies.get('internal.client.pageJMT');
301
318
 
302
- return typeof latency === 'number' ? latency : undefined;
319
+ return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;
303
320
  }
304
321
 
305
322
  /**
@@ -309,7 +326,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
309
326
  public getDownloadTimeJMT() {
310
327
  const latency = this.precomputedLatencies.get('internal.download.time');
311
328
 
312
- return typeof latency === 'number' ? latency : undefined;
329
+ return typeof latency === 'number' ? clamp(latency, 0, this.MAX_INTEGER) : undefined;
313
330
  }
314
331
 
315
332
  /**
@@ -330,7 +347,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
330
347
  );
331
348
 
332
349
  if (typeof clickToInterstitialLatency === 'number') {
333
- return clickToInterstitialLatency;
350
+ return clamp(clickToInterstitialLatency, 0, this.MAX_INTEGER);
334
351
  }
335
352
 
336
353
  return undefined;
@@ -354,7 +371,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
354
371
  );
355
372
 
356
373
  if (typeof clickToInterstitialWithUserDelayLatency === 'number') {
357
- return clickToInterstitialWithUserDelayLatency;
374
+ return clamp(clickToInterstitialWithUserDelayLatency, 0, this.MAX_INTEGER);
358
375
  }
359
376
 
360
377
  return undefined;
@@ -378,7 +395,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
378
395
  public getCallInitMediaEngineReady() {
379
396
  return this.getDiffBetweenTimestamps(
380
397
  'internal.client.interstitial-window.click.joinbutton',
381
- 'client.media-engine.ready'
398
+ 'client.media-engine.ready',
399
+ {maximum: 1200000}
382
400
  );
383
401
  }
384
402
 
@@ -398,7 +416,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
398
416
  const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
399
417
 
400
418
  if (interstitialJoinClickTimestamp && connectedMedia) {
401
- return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
419
+ const interstitialToMediaOKJmt = connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
420
+
421
+ return clamp(interstitialToMediaOKJmt, 0, this.MAX_INTEGER);
402
422
  }
403
423
 
404
424
  return undefined;
@@ -413,7 +433,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
413
433
  const interstitialToJoinOk = this.getInterstitialToJoinOK();
414
434
 
415
435
  if (typeof clickToInterstitial === 'number' && typeof interstitialToJoinOk === 'number') {
416
- return clickToInterstitial + interstitialToJoinOk;
436
+ return clamp(clickToInterstitial + interstitialToJoinOk, 0, this.MAX_INTEGER);
417
437
  }
418
438
 
419
439
  return undefined;
@@ -431,7 +451,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
431
451
  typeof clickToInterstitialWithUserDelay === 'number' &&
432
452
  typeof interstitialToJoinOk === 'number'
433
453
  ) {
434
- return clickToInterstitialWithUserDelay + interstitialToJoinOk;
454
+ return clamp(clickToInterstitialWithUserDelay + interstitialToJoinOk, 0, this.MAX_INTEGER);
435
455
  }
436
456
 
437
457
  return undefined;
@@ -446,7 +466,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
446
466
  const ICESetupTime = this.getICESetupTime();
447
467
 
448
468
  if (joinReqResp && ICESetupTime) {
449
- return joinReqResp + ICESetupTime;
469
+ return clamp(joinReqResp + ICESetupTime, 0, this.MAX_INTEGER);
450
470
  }
451
471
 
452
472
  return undefined;
@@ -463,12 +483,16 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
463
483
  const lobbyTime = this.getStayLobbyTime();
464
484
 
465
485
  if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
466
- const totalMediaJMT = clickToInterstitial + interstitialToJoinOk + joinConfJMT;
486
+ const totalMediaJMT = clamp(
487
+ clickToInterstitial + interstitialToJoinOk + joinConfJMT,
488
+ 0,
489
+ Infinity
490
+ );
467
491
  if (this.getMeeting()?.allowMediaInLobby) {
468
- return totalMediaJMT;
492
+ return clamp(totalMediaJMT, 0, this.MAX_INTEGER);
469
493
  }
470
494
 
471
- return totalMediaJMT - lobbyTime;
495
+ return clamp(totalMediaJMT - lobbyTime, 0, this.MAX_INTEGER);
472
496
  }
473
497
 
474
498
  return undefined;
@@ -484,7 +508,11 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
484
508
  const joinConfJMT = this.getJoinConfJMT();
485
509
 
486
510
  if (clickToInterstitialWithUserDelay && interstitialToJoinOk && joinConfJMT) {
487
- return clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT;
511
+ return clamp(
512
+ clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT,
513
+ 0,
514
+ this.MAX_INTEGER
515
+ );
488
516
  }
489
517
 
490
518
  return undefined;
@@ -499,7 +527,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
499
527
  const joinConfJMT = this.getJoinConfJMT();
500
528
 
501
529
  if (typeof interstitialToJoinOk === 'number' && typeof joinConfJMT === 'number') {
502
- return interstitialToJoinOk - joinConfJMT;
530
+ return clamp(interstitialToJoinOk - joinConfJMT, 0, this.MAX_INTEGER);
503
531
  }
504
532
 
505
533
  return undefined;
@@ -526,7 +554,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
526
554
  const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');
527
555
 
528
556
  return typeof reachablityClusterReqResp === 'number'
529
- ? Math.floor(reachablityClusterReqResp)
557
+ ? clamp(Math.floor(reachablityClusterReqResp), 0, this.MAX_INTEGER)
530
558
  : undefined;
531
559
  }
532
560
 
@@ -544,13 +572,25 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
544
572
  return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.media.tx.start');
545
573
  }
546
574
 
575
+ /**
576
+ * Time from share initiation to share stop (ms).
577
+ */
578
+ public getShareDuration() {
579
+ return this.getDiffBetweenTimestamps(
580
+ 'internal.client.share.initiated',
581
+ 'internal.client.share.stopped'
582
+ );
583
+ }
584
+
547
585
  /**
548
586
  * Total latency for all exchange ci token.
549
587
  */
550
588
  public getExchangeCITokenJMT() {
551
589
  const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');
552
590
 
553
- return typeof exchangeCITokenJMT === 'number' ? Math.floor(exchangeCITokenJMT) : undefined;
591
+ return typeof exchangeCITokenJMT === 'number'
592
+ ? clamp(Math.floor(exchangeCITokenJMT), 0, this.MAX_INTEGER)
593
+ : undefined;
554
594
  }
555
595
 
556
596
  /**
@@ -560,7 +600,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
560
600
  const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');
561
601
 
562
602
  return typeof refreshCaptchaReqResp === 'number'
563
- ? Math.floor(refreshCaptchaReqResp)
603
+ ? clamp(Math.floor(refreshCaptchaReqResp), 0, this.MAX_INTEGER)
564
604
  : undefined;
565
605
  }
566
606
 
@@ -574,7 +614,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
574
614
  );
575
615
 
576
616
  return typeof downloadIntelligenceModelsReqResp === 'number'
577
- ? Math.floor(downloadIntelligenceModelsReqResp)
617
+ ? clamp(Math.floor(downloadIntelligenceModelsReqResp), 0, this.MAX_INTEGER)
578
618
  : undefined;
579
619
  }
580
620
 
@@ -586,6 +626,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
586
626
  public getOtherAppApiReqResp() {
587
627
  const otherAppApiJMT = this.precomputedLatencies.get('internal.other.app.api.time');
588
628
 
589
- return otherAppApiJMT > 0 ? Math.floor(otherAppApiJMT) : undefined;
629
+ return otherAppApiJMT > 0 ? clamp(Math.floor(otherAppApiJMT), 0, this.MAX_INTEGER) : undefined;
590
630
  }
591
631
  }