@webex/internal-plugin-metrics 3.8.1 → 3.9.0-multipleLLM.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.
Files changed (35) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +92 -14
  2. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics.js +351 -48
  4. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +21 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  7. package/dist/call-diagnostic/config.js +3 -1
  8. package/dist/call-diagnostic/config.js.map +1 -1
  9. package/dist/index.js.map +1 -1
  10. package/dist/metrics.js +1 -1
  11. package/dist/metrics.types.js.map +1 -1
  12. package/dist/new-metrics.js +43 -1
  13. package/dist/new-metrics.js.map +1 -1
  14. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +23 -1
  15. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +177 -10
  16. package/dist/types/call-diagnostic/config.d.ts +2 -0
  17. package/dist/types/index.d.ts +2 -2
  18. package/dist/types/metrics.types.d.ts +19 -7
  19. package/dist/types/new-metrics.d.ts +19 -2
  20. package/package.json +11 -12
  21. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +104 -14
  22. package/src/call-diagnostic/call-diagnostic-metrics.ts +368 -25
  23. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +20 -0
  24. package/src/call-diagnostic/config.ts +3 -0
  25. package/src/index.ts +2 -0
  26. package/src/metrics.types.ts +26 -6
  27. package/src/new-metrics.ts +52 -1
  28. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +20 -1
  29. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +255 -0
  30. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +864 -39
  31. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +6 -0
  32. package/test/unit/spec/new-metrics.ts +67 -2
  33. package/test/unit/spec/prelogin-metrics-batcher.ts +72 -3
  34. package/dist/call-diagnostic-events-batcher.js +0 -60
  35. package/dist/call-diagnostic-events-batcher.js.map +0 -1
@@ -23,6 +23,7 @@ import {
23
23
  SubmitClientEventOptions,
24
24
  Table,
25
25
  DelayedClientEvent,
26
+ DelayedClientFeatureEvent,
26
27
  } from './metrics.types';
27
28
  import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
28
29
  import {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';
@@ -51,11 +52,18 @@ class Metrics extends WebexPlugin {
51
52
  */
52
53
  delaySubmitClientEvents = false;
53
54
 
55
+ /**
56
+ * Whether or not to delay the submission of feature events.
57
+ */
58
+ delaySubmitClientFeatureEvents = false;
59
+
54
60
  /**
55
61
  * Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
56
62
  */
57
63
  delayedClientEventsOverrides: Partial<DelayedClientEvent['options']> = {};
58
64
 
65
+ delayedClientFeatureEventsOverrides: Partial<DelayedClientFeatureEvent['options']> = {};
66
+
59
67
  /**
60
68
  * Constructor
61
69
  * @param args
@@ -275,7 +283,25 @@ class Metrics extends WebexPlugin {
275
283
  payload?: RecursivePartial<FeatureEvent['payload']>;
276
284
  options: any;
277
285
  }) {
278
- throw new Error('Not implemented.');
286
+ if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {
287
+ // @ts-ignore
288
+ this.webex.logger.log(
289
+ `NewMetrics: @submitFeatureEvent. Attempted to submit before webex.ready. Event name: ${name}`
290
+ );
291
+
292
+ return Promise.resolve();
293
+ }
294
+ this.callDiagnosticLatencies.saveTimestamp({
295
+ key: name,
296
+ options: {meetingId: options?.meetingId},
297
+ });
298
+
299
+ return this.callDiagnosticMetrics.submitFeatureEvent({
300
+ name,
301
+ payload,
302
+ options,
303
+ delaySubmitEvent: this.delaySubmitClientFeatureEvents,
304
+ });
279
305
  }
280
306
 
281
307
  /**
@@ -432,6 +458,31 @@ class Metrics extends WebexPlugin {
432
458
 
433
459
  return Promise.resolve();
434
460
  }
461
+
462
+ /**
463
+ * Sets the value of setDelaySubmitClientFeatureEvents.
464
+ * If set to true, feature events will be delayed until submitDelayedClientFeatureEvents is called.
465
+ * If set to false, delayed feature events will be submitted.
466
+ *
467
+ * @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of feature events,
468
+ * overrides: An object containing overrides for the feature events}
469
+ */
470
+ public setDelaySubmitClientFeatureEvents({
471
+ shouldDelay,
472
+ overrides,
473
+ }: {
474
+ shouldDelay: boolean;
475
+ overrides?: Partial<DelayedClientFeatureEvent['options']>;
476
+ }) {
477
+ this.delaySubmitClientFeatureEvents = shouldDelay;
478
+ this.delayedClientFeatureEventsOverrides = overrides || {};
479
+
480
+ if (this.isReady && !shouldDelay) {
481
+ return this.callDiagnosticMetrics.submitDelayedClientFeatureEvents(overrides);
482
+ }
483
+
484
+ return Promise.resolve();
485
+ }
435
486
  }
436
487
 
437
488
  export default Metrics;
@@ -108,6 +108,8 @@ describe('plugin-metrics', () => {
108
108
  .returns(10);
109
109
  webex.internal.newMetrics.callDiagnosticLatencies.getDownloadIntelligenceModelsReqResp =
110
110
  sinon.stub().returns(42);
111
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay =
112
+ sinon.stub().returns(12);
111
113
 
112
114
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
113
115
  //@ts-ignore
@@ -127,6 +129,7 @@ describe('plugin-metrics', () => {
127
129
  meetingInfoReqResp: 10,
128
130
  refreshCaptchaServiceReqResp: 10,
129
131
  downloadIntelligenceModelsReqResp: 42,
132
+ clickToInterstitialWithUserDelay: 12,
130
133
  },
131
134
  });
132
135
  assert.lengthOf(
@@ -183,9 +186,15 @@ describe('plugin-metrics', () => {
183
186
  webex.internal.newMetrics.callDiagnosticLatencies.getCallInitJoinReq = sinon
184
187
  .stub()
185
188
  .returns(10);
186
- webex.internal.newMetrics.callDiagnosticLatencies.getDownloadTimeJMT = sinon
189
+ webex.internal.newMetrics.callDiagnosticLatencies.getDownloadTimeJMT = sinon
187
190
  .stub()
188
191
  .returns(100);
192
+ webex.internal.newMetrics.callDiagnosticLatencies.getClickToInterstitialWithUserDelay = sinon
193
+ .stub()
194
+ .returns(43);
195
+ webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon
196
+ .stub()
197
+ .returns(64);
189
198
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
190
199
  //@ts-ignore
191
200
  {event: {name: 'client.locus.join.response'}}
@@ -209,6 +218,8 @@ describe('plugin-metrics', () => {
209
218
  totalJmt: 20,
210
219
  clientJmt: 5,
211
220
  downloadTime: 100,
221
+ clickToInterstitialWithUserDelay: 43,
222
+ totalJMTWithUserDelay: 64,
212
223
  },
213
224
  });
214
225
  assert.lengthOf(
@@ -338,6 +349,12 @@ describe('plugin-metrics', () => {
338
349
  webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTime = sinon
339
350
  .stub()
340
351
  .returns(1);
352
+ webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon
353
+ .stub()
354
+ .returns(43);
355
+ webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon
356
+ .stub()
357
+ .returns(64);
341
358
  const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
342
359
  //@ts-ignore
343
360
  {event: {name: 'client.media-engine.ready'}}
@@ -356,6 +373,8 @@ describe('plugin-metrics', () => {
356
373
  interstitialToMediaOKJMT: 22,
357
374
  callInitMediaEngineReady: 10,
358
375
  stayLobbyTime: 1,
376
+ totalMediaJMTWithUserDelay: 43,
377
+ totalJMTWithUserDelay: 64,
359
378
  },
360
379
  });
361
380
  assert.lengthOf(
@@ -130,6 +130,82 @@ describe('internal-plugin-metrics', () => {
130
130
  assert.deepEqual(res2, undefined);
131
131
  });
132
132
 
133
+ describe('getDiffBetweenTimestamps with clamping', () => {
134
+ it('should return diff without clamping when no clampValues provided', () => {
135
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
136
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
137
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed');
138
+ assert.deepEqual(res, 40);
139
+ });
140
+
141
+ it('should return diff without clamping when value is within range', () => {
142
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
143
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
144
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
145
+ minimum: 0,
146
+ maximum: 100
147
+ });
148
+ assert.deepEqual(res, 40);
149
+ });
150
+
151
+ it('should clamp to minimum when diff is below minimum', () => {
152
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
153
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
154
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
155
+ minimum: 10,
156
+ maximum: 100
157
+ });
158
+ assert.deepEqual(res, 10);
159
+ });
160
+
161
+ it('should clamp to maximum when diff is above maximum', () => {
162
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
163
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 210});
164
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
165
+ minimum: 0,
166
+ maximum: 100
167
+ });
168
+ assert.deepEqual(res, 100);
169
+ });
170
+
171
+ it('should use default minimum of 0 when only maximum is specified', () => {
172
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 50});
173
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 45});
174
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
175
+ maximum: 100
176
+ });
177
+ assert.deepEqual(res, 0);
178
+ });
179
+
180
+ it('should not clamp maximum when maximum is undefined', () => {
181
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
182
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 2000});
183
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
184
+ minimum: 5
185
+ });
186
+ assert.deepEqual(res, 1990);
187
+ });
188
+
189
+ it('should handle negative differences correctly with clamping', () => {
190
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 100});
191
+ cdl.saveTimestamp({key: 'client.alert.removed', value: 50});
192
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
193
+ minimum: 10,
194
+ maximum: 1000
195
+ });
196
+ assert.deepEqual(res, 10);
197
+ });
198
+
199
+ it('should return undefined when timestamps are missing even with clamping', () => {
200
+ cdl.saveTimestamp({key: 'client.alert.displayed', value: 10});
201
+ const res = cdl.getDiffBetweenTimestamps('client.alert.displayed', 'client.alert.removed', {
202
+ minimum: 0,
203
+ maximum: 100
204
+ });
205
+ assert.deepEqual(res, undefined);
206
+ });
207
+ });
208
+
133
209
  it('calculates getMeetingInfoReqResp correctly', () => {
134
210
  cdl.saveTimestamp({key: 'internal.client.meetinginfo.request', value: 10});
135
211
  cdl.saveTimestamp({key: 'internal.client.meetinginfo.response', value: 20});
@@ -446,6 +522,36 @@ describe('internal-plugin-metrics', () => {
446
522
  assert.deepEqual(cdl.getClickToInterstitial(), 0);
447
523
  });
448
524
 
525
+ it('calculates getClickToInterstitialWithUserDelay correctly', () => {
526
+ cdl.saveTimestamp({
527
+ key: 'internal.client.meeting.click.joinbutton',
528
+ value: 10,
529
+ });
530
+ cdl.saveTimestamp({
531
+ key: 'internal.client.meeting.interstitial-window.showed',
532
+ value: 20,
533
+ });
534
+ assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 10);
535
+ });
536
+
537
+ it('calculates getClickToInterstitialWithUserDelay without join button timestamp', () => {
538
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 5);
539
+ cdl.saveTimestamp({
540
+ key: 'internal.client.meeting.interstitial-window.showed',
541
+ value: 20,
542
+ });
543
+ assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 5);
544
+ });
545
+
546
+ it('calculates getClickToInterstitialWithUserDelay without join button timestamp when it is 0', () => {
547
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
548
+ cdl.saveTimestamp({
549
+ key: 'internal.client.meeting.interstitial-window.showed',
550
+ value: 20,
551
+ });
552
+ assert.deepEqual(cdl.getClickToInterstitialWithUserDelay(), 0);
553
+ });
554
+
449
555
  it('calculates getInterstitialToJoinOK correctly', () => {
450
556
  cdl.saveTimestamp({
451
557
  key: 'internal.client.interstitial-window.click.joinbutton',
@@ -554,6 +660,78 @@ describe('internal-plugin-metrics', () => {
554
660
  assert.deepEqual(cdl.getTotalJMT(), undefined);
555
661
  });
556
662
 
663
+ it('calculates getTotalJMTWithUserDelay correctly', () => {
664
+ cdl.saveTimestamp({
665
+ key: 'internal.client.interstitial-window.click.joinbutton',
666
+ value: 5,
667
+ });
668
+ cdl.saveTimestamp({
669
+ key: 'internal.client.meeting.click.joinbutton',
670
+ value: 10,
671
+ });
672
+ cdl.saveTimestamp({
673
+ key: 'internal.client.meeting.interstitial-window.showed',
674
+ value: 20,
675
+ });
676
+ cdl.saveTimestamp({
677
+ key: 'client.locus.join.response',
678
+ value: 40,
679
+ });
680
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 45);
681
+ });
682
+
683
+ it('calculates getTotalJMTWithUserDelay correctly when clickToInterstitialWithUserDelay is 0', () => {
684
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
685
+ cdl.saveTimestamp({
686
+ key: 'internal.client.interstitial-window.click.joinbutton',
687
+ value: 20,
688
+ });
689
+ cdl.saveTimestamp({
690
+ key: 'client.locus.join.response',
691
+ value: 40,
692
+ });
693
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 20);
694
+ });
695
+
696
+ it('calculates getTotalJMTWithUserDelay correctly when interstitialToJoinOk is 0', () => {
697
+ cdl.saveTimestamp({
698
+ key: 'internal.client.interstitial-window.click.joinbutton',
699
+ value: 40,
700
+ });
701
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 12);
702
+ cdl.saveTimestamp({
703
+ key: 'client.locus.join.response',
704
+ value: 40,
705
+ });
706
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 12);
707
+ });
708
+
709
+ it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay and interstitialToJoinOk are 0', () => {
710
+ cdl.saveTimestamp({
711
+ key: 'internal.client.interstitial-window.click.joinbutton',
712
+ value: 40,
713
+ });
714
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 0);
715
+ cdl.saveTimestamp({
716
+ key: 'client.locus.join.response',
717
+ value: 40,
718
+ });
719
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), 0);
720
+ });
721
+
722
+ it('calculates getTotalJMTWithUserDelay correctly when both clickToInterstitialWithUserDelay is not a number', () => {
723
+ cdl.saveTimestamp({
724
+ key: 'internal.client.interstitial-window.click.joinbutton',
725
+ value: 40,
726
+ });
727
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 'eleven' as unknown as number);
728
+ cdl.saveTimestamp({
729
+ key: 'client.locus.join.response',
730
+ value: 40,
731
+ });
732
+ assert.deepEqual(cdl.getTotalJMTWithUserDelay(), undefined);
733
+ });
734
+
557
735
  it('calculates getTotalMediaJMT correctly', () => {
558
736
  cdl.saveTimestamp({
559
737
  key: 'internal.client.meeting.click.joinbutton',
@@ -627,6 +805,71 @@ describe('internal-plugin-metrics', () => {
627
805
  assert.deepEqual(cdl.getTotalMediaJMT(), 31);
628
806
  });
629
807
 
808
+ it('calculates getTotalMediaJMTWithUserDelay correctly', () => {
809
+ cdl.saveLatency('internal.click.to.interstitial.with.user.delay', 7);
810
+ cdl.saveTimestamp({
811
+ key: 'internal.client.interstitial-window.click.joinbutton',
812
+ value: 10,
813
+ });
814
+ cdl.saveTimestamp({
815
+ key: 'client.locus.join.request',
816
+ value: 12,
817
+ });
818
+ cdl.saveTimestamp({
819
+ key: 'client.locus.join.response',
820
+ value: 20,
821
+ });
822
+ cdl.saveTimestamp({
823
+ key: 'internal.host.meeting.participant.admitted',
824
+ value: 24,
825
+ });
826
+ cdl.saveTimestamp({
827
+ key: 'client.ice.start',
828
+ value: 30,
829
+ });
830
+ cdl.saveTimestamp({
831
+ key: 'client.ice.end',
832
+ value: 40,
833
+ });
834
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 35);
835
+ });
836
+
837
+ it('calculates getTotalMediaJMTWithUserDelay correctly for guest join', () => {
838
+ cdl.saveTimestamp({
839
+ key: 'internal.client.meeting.click.joinbutton',
840
+ value: 5,
841
+ });
842
+ cdl.saveTimestamp({
843
+ key: 'internal.client.meeting.interstitial-window.showed',
844
+ value: 8,
845
+ });
846
+ cdl.saveTimestamp({
847
+ key: 'internal.client.interstitial-window.click.joinbutton',
848
+ value: 10,
849
+ });
850
+ cdl.saveTimestamp({
851
+ key: 'client.locus.join.request',
852
+ value: 12,
853
+ });
854
+ cdl.saveTimestamp({
855
+ key: 'client.locus.join.response',
856
+ value: 20,
857
+ });
858
+ cdl.saveTimestamp({
859
+ key: 'internal.host.meeting.participant.admitted',
860
+ value: 24,
861
+ });
862
+ cdl.saveTimestamp({
863
+ key: 'client.ice.start',
864
+ value: 30,
865
+ });
866
+ cdl.saveTimestamp({
867
+ key: 'client.ice.end',
868
+ value: 40,
869
+ });
870
+ assert.deepEqual(cdl.getTotalMediaJMTWithUserDelay(), 31);
871
+ });
872
+
630
873
  it('calculates getJoinConfJMT correctly', () => {
631
874
  cdl.saveTimestamp({
632
875
  key: 'client.locus.join.request',
@@ -751,6 +994,18 @@ describe('internal-plugin-metrics', () => {
751
994
  assert.deepEqual(cdl.getInterstitialToMediaOKJMT(), 10);
752
995
  });
753
996
 
997
+ it('calculates getShareDuration correctly', () => {
998
+ cdl.saveTimestamp({
999
+ key: 'internal.client.share.initiated',
1000
+ value: 5,
1001
+ });
1002
+ cdl.saveTimestamp({
1003
+ key: 'internal.client.share.stopped',
1004
+ value: 7,
1005
+ });
1006
+ assert.deepEqual(cdl.getShareDuration(), 2);
1007
+ });
1008
+
754
1009
  describe('calculates getU2CTime correctly', () => {
755
1010
  it('returns undefined when no precomputed value available', () => {
756
1011
  assert.deepEqual(cdl.getU2CTime(), undefined);