@webex/internal-plugin-metrics 3.12.0-next.1 → 3.12.0-next.11

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.
@@ -137,11 +137,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
137
137
  architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64" | "armv9" | "armv8" | "armv7" | "armv6" | "x86_64" | "x86_32";
138
138
  staticPerformance?: string;
139
139
  clockSpeedGigaHertz?: number;
140
- additionalProperties?: false;
140
+ additionalProperties?: never;
141
141
  };
142
142
  shareType?: "cb-normal-share" | "ce-airplay-share" | "ce-direct-share" | "ce-gui-loopback-share" | "ce-input-source-share" | "ce-input-source-share-hdmi" | "ce-input-source-share-usbc" | "ce-jpg-share" | "ce-miracast-share" | "mcs-normal-share" | "mcs-normal-audio-share" | "mcs-hfps-share" | "mcs-hfps-audio-share";
143
143
  videoDisplayMode?: "grid-view" | "active-speaker-view";
144
- videoLayoutType?: "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery";
144
+ videoLayoutType?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
145
145
  videoRenderType?: "wme" | "client_d3d" | "client_gdi";
146
146
  vdiInfo?: {};
147
147
  is64BitsClient?: boolean;
@@ -153,13 +153,16 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
153
153
  vendorId?: string;
154
154
  staticPerformanceLevel?: string;
155
155
  staticPerformanceScore?: number;
156
- additionalProperties?: false;
156
+ preInstalledTime?: string;
157
+ preInstalledType?: "installer" | "launcher" | "app";
158
+ preInstalledVersion?: string;
159
+ additionalProperties?: never;
157
160
  };
158
161
  emmVendorId?: string;
159
162
  isHybridMedia?: boolean;
160
163
  originData?: {};
161
164
  serviceVersion?: string;
162
- additionalProperties?: false;
165
+ additionalProperties?: never;
163
166
  };
164
167
  /**
165
168
  * Gather identifier details for call diagnostic payload.
@@ -183,7 +186,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
183
186
  imiAppId: string;
184
187
  sessionId: string;
185
188
  sessionInstanceId: string;
186
- additionalProperties?: false;
189
+ additionalProperties?: never;
187
190
  };
188
191
  csdmDeviceUrl?: string;
189
192
  destinationBreakoutSessionId?: string;
@@ -199,6 +202,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
199
202
  ivrId?: string;
200
203
  callId?: string;
201
204
  pairCallId?: string;
205
+ llmWebsocketUrl?: string;
202
206
  locusId?: string;
203
207
  locusJoinUrl?: string;
204
208
  locusSessionId?: string;
@@ -212,6 +216,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
212
216
  meetingLookupUrl?: string;
213
217
  meetingOrgId?: string;
214
218
  metricServiceUrl?: string;
219
+ mercuryWebsocketUrl?: string;
215
220
  msteamsTenantGuid?: string;
216
221
  msteamsConferenceId?: string;
217
222
  msteamsMeetingId?: string;
@@ -225,7 +230,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
225
230
  sipSessionId?: {
226
231
  local?: string;
227
232
  remote?: string;
228
- additionalProperties?: false;
233
+ additionalProperties?: never;
229
234
  };
230
235
  sipUri?: string;
231
236
  subConfId?: string;
@@ -253,7 +258,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
253
258
  idForEndpointAB?: string;
254
259
  customerOrgId?: string;
255
260
  correlationId: string;
256
- additionalProperties?: false;
261
+ additionalProperties?: never;
257
262
  } | {
258
263
  aggregatedBreakoutMoveId?: string;
259
264
  attendeeId?: string;
@@ -271,7 +276,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
271
276
  imiAppId: string;
272
277
  sessionId: string;
273
278
  sessionInstanceId: string;
274
- additionalProperties?: false;
279
+ additionalProperties?: never;
275
280
  };
276
281
  csdmDeviceUrl?: string;
277
282
  destinationBreakoutSessionId?: string;
@@ -287,6 +292,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
287
292
  ivrId?: string;
288
293
  callId?: string;
289
294
  pairCallId?: string;
295
+ llmWebsocketUrl?: string;
290
296
  locusId?: string;
291
297
  locusJoinUrl?: string;
292
298
  locusSessionId?: string;
@@ -300,6 +306,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
300
306
  meetingLookupUrl?: string;
301
307
  meetingOrgId?: string;
302
308
  metricServiceUrl?: string;
309
+ mercuryWebsocketUrl?: string;
303
310
  msteamsTenantGuid?: string;
304
311
  msteamsConferenceId?: string;
305
312
  msteamsMeetingId?: string;
@@ -313,7 +320,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
313
320
  sipSessionId?: {
314
321
  local?: string;
315
322
  remote?: string;
316
- additionalProperties?: false;
323
+ additionalProperties?: never;
317
324
  };
318
325
  sipUri?: string;
319
326
  subConfId?: string;
@@ -341,7 +348,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
341
348
  idForEndpointAB?: string;
342
349
  customerOrgId?: string;
343
350
  correlationId: string;
344
- additionalProperties?: false;
351
+ additionalProperties?: never;
345
352
  } | {
346
353
  aggregatedBreakoutMoveId?: string;
347
354
  attendeeId?: string;
@@ -359,7 +366,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
359
366
  imiAppId: string;
360
367
  sessionId: string;
361
368
  sessionInstanceId: string;
362
- additionalProperties?: false;
369
+ additionalProperties?: never;
363
370
  };
364
371
  csdmDeviceUrl?: string;
365
372
  destinationBreakoutSessionId?: string;
@@ -375,6 +382,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
375
382
  ivrId?: string;
376
383
  callId?: string;
377
384
  pairCallId?: string;
385
+ llmWebsocketUrl?: string;
378
386
  locusId?: string;
379
387
  locusJoinUrl?: string;
380
388
  locusSessionId?: string;
@@ -388,6 +396,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
388
396
  meetingLookupUrl?: string;
389
397
  meetingOrgId?: string;
390
398
  metricServiceUrl?: string;
399
+ mercuryWebsocketUrl?: string;
391
400
  msteamsTenantGuid?: string;
392
401
  msteamsConferenceId?: string;
393
402
  msteamsMeetingId?: string;
@@ -401,7 +410,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
401
410
  sipSessionId?: {
402
411
  local?: string;
403
412
  remote?: string;
404
- additionalProperties?: false;
413
+ additionalProperties?: never;
405
414
  };
406
415
  sipUri?: string;
407
416
  subConfId?: string;
@@ -429,7 +438,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
429
438
  idForEndpointAB?: string;
430
439
  customerOrgId?: string;
431
440
  correlationId: string;
432
- additionalProperties?: false;
441
+ additionalProperties?: never;
433
442
  };
434
443
  /**
435
444
  * Create diagnostic event, which can hold client event, feature event or MQE event data.
@@ -42,7 +42,7 @@ export type SubmitMQEOptions = {
42
42
  globalMeetingId?: string;
43
43
  };
44
44
  export type InternalEvent = {
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
+ name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.register.device.request' | 'internal.register.device.response' | 'internal.reset.join.latencies' | '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';
46
46
  payload?: never;
47
47
  options?: never;
48
48
  };
@@ -154,7 +154,7 @@ export type BuildClientEventFetchRequestOptions = (args: {
154
154
  payload?: RecursivePartial<ClientEvent['payload']>;
155
155
  options?: SubmitClientEventOptions;
156
156
  }) => Promise<any>;
157
- export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.click.to.interstitial.with.user.delay' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
157
+ export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.click.to.interstitial.with.user.delay' | 'internal.click.to.interstitial.for.client.jmt' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
158
158
  export interface IdType {
159
159
  meetingId?: string;
160
160
  callId?: string;
package/package.json CHANGED
@@ -24,7 +24,7 @@
24
24
  "@sinonjs/fake-timers": "^6.0.1",
25
25
  "@webex/babel-config-legacy": "0.0.0",
26
26
  "@webex/eslint-config-legacy": "0.0.0",
27
- "@webex/event-dictionary-ts": "^1.0.2073",
27
+ "@webex/event-dictionary-ts": "^1.0.2138",
28
28
  "@webex/jest-config-legacy": "0.0.0",
29
29
  "@webex/legacy-tools": "0.0.0",
30
30
  "@webex/test-helper-chai": "3.11.0-next.1",
@@ -40,7 +40,7 @@
40
40
  "@webex/common-timers": "3.11.0-next.1",
41
41
  "@webex/test-helper-chai": "3.11.0-next.1",
42
42
  "@webex/test-helper-mock-webex": "3.11.0-next.1",
43
- "@webex/webex-core": "3.12.0-next.1",
43
+ "@webex/webex-core": "3.12.0-next.11",
44
44
  "ip-anonymize": "^0.1.0",
45
45
  "lodash": "^4.17.21",
46
46
  "uuid": "^3.3.2"
@@ -53,5 +53,5 @@
53
53
  "test:style": "eslint ./src/**/*.*",
54
54
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
55
55
  },
56
- "version": "3.12.0-next.1"
56
+ "version": "3.12.0-next.11"
57
57
  }
@@ -193,7 +193,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
193
193
  */
194
194
  public getShowInterstitialTime() {
195
195
  return this.getDiffBetweenTimestamps(
196
- 'client.interstitial-window.start-launch',
196
+ 'internal.client.meeting.interstitial-window.showed',
197
197
  'internal.client.interstitial-window.click.joinbutton'
198
198
  );
199
199
  }
@@ -303,7 +303,39 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
303
303
  * @returns - latency
304
304
  */
305
305
  public getStayLobbyTime() {
306
- return this.getDiffBetweenTimestamps('client.locus.join.response', 'client.lobby.exited');
306
+ return this.getDiffBetweenTimestamps('client.lobby.entered', 'client.lobby.exited');
307
+ }
308
+
309
+ /**
310
+ * Stay lobby time capped by a certain timestamp.
311
+ * This is to handle the case where the target end timestamp could happen before the lobby is exited,
312
+ * for example media-engine.ready or client.ice.end
313
+ * This is supposed to be called AFTER the end timestamp happens
314
+ * @param endTimestampKey name of the target end event
315
+ * @returns - latency
316
+ */
317
+ public getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames) {
318
+ const lobbyStartTimestamp = this.latencyTimestamps.get('client.lobby.entered'); // might not exist (some meetings don't have lobby)
319
+
320
+ if (typeof lobbyStartTimestamp !== 'number') {
321
+ // no lobby in the meeting, stayLobbyTime is 0
322
+ return 0;
323
+ }
324
+
325
+ const lobbyEndTimestamp = this.latencyTimestamps.get('client.lobby.exited'); // might not exist (if user still in lobby at the time of measurement)
326
+ const maximumEndTimestamp = this.latencyTimestamps.get(endTimestampKey); // must exist
327
+
328
+ if (typeof maximumEndTimestamp !== 'number') {
329
+ // the provided timestamp to be used as a cap should exist, return undefined if it doesn't
330
+ return undefined;
331
+ }
332
+
333
+ const endTimestamp =
334
+ typeof lobbyEndTimestamp === 'number'
335
+ ? Math.min(lobbyEndTimestamp, maximumEndTimestamp)
336
+ : maximumEndTimestamp;
337
+
338
+ return clamp(endTimestamp - lobbyStartTimestamp, 0, this.MAX_INTEGER);
307
339
  }
308
340
 
309
341
  /**
@@ -331,14 +363,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
331
363
  * @returns - latency
332
364
  */
333
365
  public getClickToInterstitial() {
334
- // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
335
- if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
336
- return this.getDiffBetweenTimestamps(
337
- 'internal.client.meeting.click.joinbutton',
338
- 'internal.client.meeting.interstitial-window.showed'
339
- );
340
- }
341
-
342
366
  const clickToInterstitialLatency = this.precomputedLatencies.get(
343
367
  'internal.click.to.interstitial'
344
368
  );
@@ -355,14 +379,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
355
379
  * @returns - latency
356
380
  */
357
381
  public getClickToInterstitialWithUserDelay() {
358
- // for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
359
- if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
360
- return this.getDiffBetweenTimestamps(
361
- 'internal.client.meeting.click.joinbutton',
362
- 'internal.client.meeting.interstitial-window.showed'
363
- );
364
- }
365
-
366
382
  const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(
367
383
  'internal.click.to.interstitial.with.user.delay'
368
384
  );
@@ -390,11 +406,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
390
406
  * @returns - latency
391
407
  */
392
408
  public getCallInitMediaEngineReady() {
393
- return this.getDiffBetweenTimestamps(
394
- 'internal.client.interstitial-window.click.joinbutton',
395
- 'client.media-engine.ready',
396
- {maximum: 1200000}
397
- );
409
+ return this.getInterstitialToMediaOKJMT();
398
410
  }
399
411
 
400
412
  /**
@@ -402,20 +414,21 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
402
414
  * @returns - latency
403
415
  */
404
416
  public getInterstitialToMediaOKJMT() {
405
- const interstitialJoinClickTimestamp = this.latencyTimestamps.get(
406
- 'internal.client.interstitial-window.click.joinbutton'
417
+ const interstitialClickJoinToIceEnd = this.getDiffBetweenTimestamps(
418
+ 'internal.client.interstitial-window.click.joinbutton',
419
+ 'client.ice.end'
407
420
  );
421
+ const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');
408
422
 
409
- // get the first timestamp
410
- const connectedMedia = this.latencyTimestamps.get('client.ice.end');
411
-
412
- const lobbyTimeLatency = this.getStayLobbyTime();
413
- const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
414
-
415
- if (interstitialJoinClickTimestamp && connectedMedia) {
416
- const interstitialToMediaOKJmt = connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
417
-
418
- return clamp(interstitialToMediaOKJmt, 0, this.MAX_INTEGER);
423
+ if (
424
+ typeof interstitialClickJoinToIceEnd === 'number' &&
425
+ typeof stayLobbyTimeCappedByIceEnd === 'number'
426
+ ) {
427
+ return clamp(
428
+ interstitialClickJoinToIceEnd - stayLobbyTimeCappedByIceEnd,
429
+ 0,
430
+ this.MAX_INTEGER
431
+ );
419
432
  }
420
433
 
421
434
  return undefined;
@@ -427,10 +440,20 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
427
440
  */
428
441
  public getTotalJMT() {
429
442
  const clickToInterstitial = this.getClickToInterstitial();
430
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
443
+ const interstitialClickJoinToJoinLocusResponse = this.getDiffBetweenTimestamps(
444
+ 'internal.client.interstitial-window.click.joinbutton',
445
+ 'client.locus.join.response'
446
+ );
431
447
 
432
- if (typeof clickToInterstitial === 'number' && typeof interstitialToJoinOk === 'number') {
433
- return clamp(clickToInterstitial + interstitialToJoinOk, 0, this.MAX_INTEGER);
448
+ if (
449
+ typeof clickToInterstitial === 'number' &&
450
+ typeof interstitialClickJoinToJoinLocusResponse === 'number'
451
+ ) {
452
+ return clamp(
453
+ clickToInterstitial + interstitialClickJoinToJoinLocusResponse,
454
+ 0,
455
+ this.MAX_INTEGER
456
+ );
434
457
  }
435
458
 
436
459
  return undefined;
@@ -442,13 +465,20 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
442
465
  */
443
466
  public getTotalJMTWithUserDelay() {
444
467
  const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();
445
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
468
+ const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(
469
+ 'internal.client.meeting.interstitial-window.showed',
470
+ 'client.locus.join.response'
471
+ );
446
472
 
447
473
  if (
448
474
  typeof clickToInterstitialWithUserDelay === 'number' &&
449
- typeof interstitialToJoinOk === 'number'
475
+ typeof interstitialShowedToJoinLocusResponse === 'number'
450
476
  ) {
451
- return clamp(clickToInterstitialWithUserDelay + interstitialToJoinOk, 0, this.MAX_INTEGER);
477
+ return clamp(
478
+ clickToInterstitialWithUserDelay + interstitialShowedToJoinLocusResponse,
479
+ 0,
480
+ this.MAX_INTEGER
481
+ );
452
482
  }
453
483
 
454
484
  return undefined;
@@ -475,22 +505,26 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
475
505
  */
476
506
  public getTotalMediaJMT() {
477
507
  const clickToInterstitial = this.getClickToInterstitial();
478
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
479
- const joinConfJMT = this.getJoinConfJMT();
480
- const lobbyTimeLatency = this.getStayLobbyTime();
481
- const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
482
-
483
- if (clickToInterstitial && interstitialToJoinOk && joinConfJMT) {
484
- const totalMediaJMT = clamp(
485
- clickToInterstitial + interstitialToJoinOk + joinConfJMT,
508
+ const interstitialClickJoinToMediaEngineReady = this.getDiffBetweenTimestamps(
509
+ 'internal.client.interstitial-window.click.joinbutton',
510
+ 'client.media-engine.ready'
511
+ );
512
+ const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(
513
+ 'client.media-engine.ready'
514
+ );
515
+
516
+ if (
517
+ typeof clickToInterstitial === 'number' &&
518
+ typeof interstitialClickJoinToMediaEngineReady === 'number' &&
519
+ typeof stayLobbyTimeCappedByMediaEngineReady === 'number'
520
+ ) {
521
+ return clamp(
522
+ clickToInterstitial +
523
+ interstitialClickJoinToMediaEngineReady -
524
+ stayLobbyTimeCappedByMediaEngineReady,
486
525
  0,
487
- Infinity
526
+ this.MAX_INTEGER
488
527
  );
489
- if (this.getMeeting()?.allowMediaInLobby) {
490
- return clamp(totalMediaJMT, 0, this.MAX_INTEGER);
491
- }
492
-
493
- return clamp(totalMediaJMT - lobbyTime, 0, this.MAX_INTEGER);
494
528
  }
495
529
 
496
530
  return undefined;
@@ -502,12 +536,17 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
502
536
  */
503
537
  public getTotalMediaJMTWithUserDelay() {
504
538
  const clickToInterstitialWithUserDelay = this.getClickToInterstitialWithUserDelay();
505
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
506
- const joinConfJMT = this.getJoinConfJMT();
539
+ const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(
540
+ 'internal.client.meeting.interstitial-window.showed',
541
+ 'client.media-engine.ready'
542
+ );
507
543
 
508
- if (clickToInterstitialWithUserDelay && interstitialToJoinOk && joinConfJMT) {
544
+ if (
545
+ typeof clickToInterstitialWithUserDelay === 'number' &&
546
+ typeof interstitialShowedToMediaEngineReady === 'number'
547
+ ) {
509
548
  return clamp(
510
- clickToInterstitialWithUserDelay + interstitialToJoinOk + joinConfJMT,
549
+ clickToInterstitialWithUserDelay + interstitialShowedToMediaEngineReady,
511
550
  0,
512
551
  this.MAX_INTEGER
513
552
  );
@@ -521,11 +560,23 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
521
560
  * @returns - latency
522
561
  */
523
562
  public getClientJMT() {
524
- const interstitialToJoinOk = this.getInterstitialToJoinOK();
525
- const joinConfJMT = this.getJoinConfJMT();
563
+ const clickToInterstitialForClientJmt = this.precomputedLatencies.get(
564
+ 'internal.click.to.interstitial.for.client.jmt'
565
+ );
566
+ const interstitialJoinToLocusJoinRequest = this.getDiffBetweenTimestamps(
567
+ 'internal.client.interstitial-window.click.joinbutton',
568
+ 'client.locus.join.request'
569
+ );
526
570
 
527
- if (typeof interstitialToJoinOk === 'number' && typeof joinConfJMT === 'number') {
528
- return clamp(interstitialToJoinOk - joinConfJMT, 0, this.MAX_INTEGER);
571
+ if (
572
+ typeof clickToInterstitialForClientJmt === 'number' &&
573
+ typeof interstitialJoinToLocusJoinRequest === 'number'
574
+ ) {
575
+ return clamp(
576
+ clickToInterstitialForClientJmt + interstitialJoinToLocusJoinRequest,
577
+ 0,
578
+ this.MAX_INTEGER
579
+ );
529
580
  }
530
581
 
531
582
  return undefined;
@@ -190,6 +190,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
190
190
 
191
191
  // if ConvergedArchitecture enable and isConvergedWebinarWebcast -- then webcast
192
192
  if (meetingInfo?.enableConvergedArchitecture && meetingInfo?.enableEvent) {
193
+ // if enableConvergedWebinarLargeScale - then large scale webinar
194
+ if (meetingInfo?.enableConvergedWebinarLargeScale) {
195
+ return WEBEX_SUB_SERVICE_TYPES.LARGE_SCALE_WEBINAR;
196
+ }
197
+
193
198
  return meetingInfo?.isConvergedWebinarWebcast
194
199
  ? WEBEX_SUB_SERVICE_TYPES.WEBCAST
195
200
  : WEBEX_SUB_SERVICE_TYPES.WEBINAR;
@@ -284,7 +284,8 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
284
284
  devicePairingType: webex.devicemanager.getPairedMethod(),
285
285
  deviceURL: pairedDevice.url,
286
286
  isPersonalDevice: pairedDevice.mode === 'personal',
287
- productName: pairedDevice.devices[0]?.productName,
287
+ productName:
288
+ pairedDevice.devices?.length > 0 ? pairedDevice.devices[0]?.productName : undefined,
288
289
  };
289
290
  item.eventPayload.event.pairingState = 'paired';
290
291
  item.eventPayload.event.pairedDevice = devicePayload;
@@ -26,6 +26,7 @@ export const WEBEX_SUB_SERVICE_TYPES: Record<string, ClientSubServiceType> = {
26
26
  SCHEDULED_MEETING: 'ScheduledMeeting',
27
27
  WEBINAR: 'Webinar',
28
28
  WEBCAST: 'Webcast',
29
+ LARGE_SCALE_WEBINAR: 'LargeScaleWebinar',
29
30
  };
30
31
 
31
32
  // Found in https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
@@ -156,7 +156,6 @@ export type InternalEvent = {
156
156
  | 'internal.register.device.request'
157
157
  | 'internal.register.device.response'
158
158
  | 'internal.reset.join.latencies'
159
- | 'internal.client.meeting.click.joinbutton'
160
159
  | 'internal.host.meeting.participant.admitted'
161
160
  | 'internal.client.meeting.interstitial-window.showed'
162
161
  | 'internal.client.interstitial-window.click.joinbutton'
@@ -319,6 +318,7 @@ export type PreComputedLatencies =
319
318
  | 'internal.get.cluster.time'
320
319
  | 'internal.click.to.interstitial'
321
320
  | 'internal.click.to.interstitial.with.user.delay'
321
+ | 'internal.click.to.interstitial.for.client.jmt'
322
322
  | 'internal.refresh.captcha.time'
323
323
  | 'internal.exchange.ci.token.time'
324
324
  | 'internal.get.u2c.time'
@@ -346,6 +346,9 @@ describe('plugin-metrics', () => {
346
346
  webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon
347
347
  .stub()
348
348
  .returns(1);
349
+ webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTimeCappedBy = sinon
350
+ .stub()
351
+ .returns(1);
349
352
  webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon
350
353
  .stub()
351
354
  .returns(43);
@@ -366,9 +369,9 @@ describe('plugin-metrics', () => {
366
369
  assert.deepEqual(webex.request.getCalls()[0].args[0].body.metrics[0].eventPayload.event, {
367
370
  name: 'client.media-engine.ready',
368
371
  joinTimes: {
369
- totalMediaJMT: 61,
372
+ totalMediaJMT: 44,
370
373
  interstitialToMediaOKJMT: 22,
371
- callInitMediaEngineReady: 10,
374
+ callInitMediaEngineReady: 22,
372
375
  totalMediaJMTWithUserDelay: 43,
373
376
  totalJMTWithUserDelay: 64,
374
377
  },