@webex/internal-plugin-metrics 3.12.0-next.5 → 3.12.0-next.50

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 (84) hide show
  1. package/README.md +274 -0
  2. package/dist/automated-user.js +19 -0
  3. package/dist/automated-user.js.map +1 -0
  4. package/dist/batcher.js +3 -0
  5. package/dist/batcher.js.map +1 -1
  6. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +635 -62
  7. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  8. package/dist/call-diagnostic/call-diagnostic-metrics.js +188 -78
  9. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  10. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
  11. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  12. package/dist/call-diagnostic/config.js +16 -3
  13. package/dist/call-diagnostic/config.js.map +1 -1
  14. package/dist/config.js +8 -0
  15. package/dist/config.js.map +1 -1
  16. package/dist/index.js +25 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/metrics.js +118 -5
  19. package/dist/metrics.js.map +1 -1
  20. package/dist/metrics.types.js +4 -0
  21. package/dist/metrics.types.js.map +1 -1
  22. package/dist/network-telemetry.js +610 -0
  23. package/dist/network-telemetry.js.map +1 -0
  24. package/dist/new-metrics.js +63 -17
  25. package/dist/new-metrics.js.map +1 -1
  26. package/dist/privacy-and-security-permission-enricher/constants.js +18 -0
  27. package/dist/privacy-and-security-permission-enricher/constants.js.map +1 -0
  28. package/dist/privacy-and-security-permission-enricher/index.js +143 -0
  29. package/dist/privacy-and-security-permission-enricher/index.js.map +1 -0
  30. package/dist/privacy-and-security-permission-enricher/types.js +7 -0
  31. package/dist/privacy-and-security-permission-enricher/types.js.map +1 -0
  32. package/dist/privacy-and-security-permission-enricher/utils.js +71 -0
  33. package/dist/privacy-and-security-permission-enricher/utils.js.map +1 -0
  34. package/dist/types/automated-user.d.ts +2 -0
  35. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +208 -5
  36. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +73 -14
  37. package/dist/types/call-diagnostic/config.d.ts +4 -0
  38. package/dist/types/config.d.ts +9 -0
  39. package/dist/types/index.d.ts +5 -3
  40. package/dist/types/metrics.types.d.ts +7 -2
  41. package/dist/types/network-telemetry.d.ts +108 -0
  42. package/dist/types/new-metrics.d.ts +17 -1
  43. package/dist/types/privacy-and-security-permission-enricher/constants.d.ts +6 -0
  44. package/dist/types/privacy-and-security-permission-enricher/index.d.ts +40 -0
  45. package/dist/types/privacy-and-security-permission-enricher/types.d.ts +14 -0
  46. package/dist/types/privacy-and-security-permission-enricher/utils.d.ts +5 -0
  47. package/dist/types/unhandled-exception-telemetry/index.d.ts +60 -0
  48. package/dist/types/unhandled-exception-telemetry/utils.d.ts +6 -0
  49. package/dist/unhandled-exception-telemetry/index.js +330 -0
  50. package/dist/unhandled-exception-telemetry/index.js.map +1 -0
  51. package/dist/unhandled-exception-telemetry/utils.js +105 -0
  52. package/dist/unhandled-exception-telemetry/utils.js.map +1 -0
  53. package/package.json +12 -11
  54. package/src/automated-user.ts +16 -0
  55. package/src/batcher.js +4 -0
  56. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +781 -71
  57. package/src/call-diagnostic/call-diagnostic-metrics.ts +119 -16
  58. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
  59. package/src/call-diagnostic/config.ts +14 -0
  60. package/src/config.js +8 -0
  61. package/src/index.ts +16 -0
  62. package/src/metrics.js +123 -5
  63. package/src/metrics.types.ts +25 -3
  64. package/src/network-telemetry.ts +757 -0
  65. package/src/new-metrics.ts +56 -6
  66. package/src/privacy-and-security-permission-enricher/constants.ts +33 -0
  67. package/src/privacy-and-security-permission-enricher/index.ts +142 -0
  68. package/src/privacy-and-security-permission-enricher/types.ts +21 -0
  69. package/src/privacy-and-security-permission-enricher/utils.ts +82 -0
  70. package/src/unhandled-exception-telemetry/index.ts +403 -0
  71. package/src/unhandled-exception-telemetry/utils.ts +101 -0
  72. package/test/unit/spec/automated-user.ts +43 -0
  73. package/test/unit/spec/batcher.js +43 -0
  74. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +14 -2
  75. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +1424 -293
  76. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +906 -159
  77. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
  78. package/test/unit/spec/metrics.js +14 -5
  79. package/test/unit/spec/network-telemetry.ts +610 -0
  80. package/test/unit/spec/new-metrics.ts +203 -50
  81. package/test/unit/spec/prelogin-metrics-batcher.ts +71 -36
  82. package/test/unit/spec/privacy-and-security-permission-enricher.ts +318 -0
  83. package/test/unit/spec/unhandled-exception-telemetry/utils.ts +109 -0
  84. package/test/unit/spec/unhandled-exception-telemetry.ts +688 -0
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_constants","require","_utils","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","PERMISSION_ENRICHMENT_RULES","exports","events","CAMERA_AND_MICROPHONE_PERMISSION_EVENTS","resolve","resources","terminal","MEDIA_TX_PERMISSION_EVENTS","payload","resolveMediaResources","CONTENT_SHARE_PERMISSION_EVENTS","resolveContentShareResources","FINAL_PERMISSION_EVENTS","resolvePermissionEnrichmentPolicy","name","_PERMISSION_ENRICHMEN","_PERMISSION_ENRICHMEN2","find","_ref","has","NO_PERMISSION_ENRICHMENT","PrivacyAndSecurityPermissionEnricher","onEnrichmentError","_classCallCheck2","_map","_createClass2","key","value","setPermission","permission","projectPrivacyAndSecurityPermission","enrich","_ref2","scope","policy","_this$lastReported$ge","privacyAndSecurityPermission","undefined","lastReported","set","get","projectedPermission","changedPermission","getChangedPermission","error","delete"],"sources":["index.ts"],"sourcesContent":["import type {ClientEventPayload, PrivacyAndSecurityPermission} from '../metrics.types';\nimport {\n CAMERA_AND_MICROPHONE_PERMISSION_EVENTS,\n CONTENT_SHARE_PERMISSION_EVENTS,\n FINAL_PERMISSION_EVENTS,\n MEDIA_TX_PERMISSION_EVENTS,\n NO_PERMISSION_ENRICHMENT,\n} from './constants';\nimport type {\n PermissionEnrichmentContext,\n PermissionEnrichmentPolicy,\n PermissionEnrichmentRule,\n} from './types';\nimport {\n getChangedPermission,\n projectPrivacyAndSecurityPermission,\n resolveContentShareResources,\n resolveMediaResources,\n} from './utils';\n\nexport const PERMISSION_ENRICHMENT_RULES = [\n {\n events: CAMERA_AND_MICROPHONE_PERMISSION_EVENTS,\n resolve: () => ({resources: ['camera', 'microphone'], terminal: false}),\n },\n {\n events: MEDIA_TX_PERMISSION_EVENTS,\n resolve: (payload) => ({resources: resolveMediaResources(payload), terminal: false}),\n },\n {\n events: CONTENT_SHARE_PERMISSION_EVENTS,\n resolve: (payload) => ({\n resources: resolveContentShareResources(payload),\n terminal: false,\n }),\n },\n {\n events: FINAL_PERMISSION_EVENTS,\n resolve: () => ({resources: ['camera', 'microphone', 'contentShare'], terminal: true}),\n },\n] satisfies readonly PermissionEnrichmentRule[];\n\nconst resolvePermissionEnrichmentPolicy = (\n name: PermissionEnrichmentContext['name'],\n payload?: ClientEventPayload\n): PermissionEnrichmentPolicy =>\n PERMISSION_ENRICHMENT_RULES.find(({events}) => events.has(name))?.resolve(payload) ??\n NO_PERMISSION_ENRICHMENT;\n\n/**\n * Enriches eligible client events with relevant browser permission changes.\n */\nexport default class PrivacyAndSecurityPermissionEnricher {\n private permission?: PrivacyAndSecurityPermission;\n\n private lastReported = new Map<string, PrivacyAndSecurityPermission>();\n\n private readonly onEnrichmentError: (error: unknown) => void;\n\n /**\n * Creates a permission enricher.\n * @param {Function} onEnrichmentError permission enrichment error handler\n */\n constructor(onEnrichmentError: (error: unknown) => void) {\n this.onEnrichmentError = onEnrichmentError;\n }\n\n /**\n * Stores the latest normalized browser permission state.\n * @param {PrivacyAndSecurityPermission} permission permission snapshot\n * @returns {void}\n */\n public setPermission(permission: PrivacyAndSecurityPermission): void {\n this.permission = projectPrivacyAndSecurityPermission(permission, [\n 'camera',\n 'microphone',\n 'contentShare',\n ]);\n }\n\n /**\n * Returns the original payload or a copy enriched with relevant permission changes.\n * @param {PermissionEnrichmentContext} context event context and permission history scope\n * @returns {ClientEventPayload | undefined}\n */\n public enrich({\n name,\n payload,\n scope,\n }: PermissionEnrichmentContext): ClientEventPayload | undefined {\n const policy = resolvePermissionEnrichmentPolicy(name, payload);\n\n try {\n if (payload?.privacyAndSecurityPermission !== undefined) {\n // An explicitly supplied permission payload is authoritative for this event.\n if (!policy.terminal) {\n this.lastReported.set(scope, {\n ...this.lastReported.get(scope),\n ...(payload.privacyAndSecurityPermission as PrivacyAndSecurityPermission),\n });\n }\n\n return payload;\n }\n\n if (policy.resources.length === 0) {\n return payload;\n }\n\n const projectedPermission = this.permission\n ? projectPrivacyAndSecurityPermission(this.permission, policy.resources)\n : undefined;\n\n if (!projectedPermission) {\n return payload;\n }\n\n if (policy.terminal) {\n return {...payload, privacyAndSecurityPermission: projectedPermission};\n }\n\n const lastReported = this.lastReported.get(scope) ?? {};\n const changedPermission = getChangedPermission(projectedPermission, lastReported);\n\n if (!changedPermission) {\n return payload;\n }\n\n this.lastReported.set(scope, {...lastReported, ...changedPermission});\n\n return {...payload, privacyAndSecurityPermission: changedPermission};\n } catch (error) {\n this.onEnrichmentError(error);\n\n return payload;\n } finally {\n if (policy.terminal) {\n this.lastReported.delete(scope);\n }\n }\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+
3
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
4
+ _Object$defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["types.ts"],"sourcesContent":["import type {\n ClientEvent,\n ClientEventPayload,\n PrivacyAndSecurityPermissionResource,\n} from '../metrics.types';\n\nexport type PermissionEnrichmentPolicy = {\n resources: readonly PrivacyAndSecurityPermissionResource[];\n terminal: boolean;\n};\n\nexport type PermissionEnrichmentRule = {\n events: ReadonlySet<ClientEvent['name']>;\n resolve: (payload?: ClientEventPayload) => PermissionEnrichmentPolicy;\n};\n\nexport type PermissionEnrichmentContext = {\n name: ClientEvent['name'];\n payload?: ClientEventPayload;\n scope: string;\n};\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+
3
+ var _Object$keys2 = require("@babel/runtime-corejs2/core-js/object/keys");
4
+ var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
5
+ var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
6
+ var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
7
+ var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
8
+ var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
9
+ var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
10
+ _Object$defineProperty(exports, "__esModule", {
11
+ value: true
12
+ });
13
+ exports.resolveMediaResources = exports.resolveContentShareResources = exports.projectPrivacyAndSecurityPermission = exports.getChangedPermission = void 0;
14
+ var _keys = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/keys"));
15
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
16
+ var _lodash = require("lodash");
17
+ function ownKeys(e, r) { var t = _Object$keys2(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; }
18
+ 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; }
19
+ var resolveMediaResources = exports.resolveMediaResources = function resolveMediaResources(payload) {
20
+ switch (payload === null || payload === void 0 ? void 0 : payload.mediaType) {
21
+ case 'audio':
22
+ return ['microphone'];
23
+ case 'video':
24
+ return ['camera'];
25
+ case 'share':
26
+ return ['contentShare'];
27
+ default:
28
+ return [];
29
+ }
30
+ };
31
+ var resolveContentShareResources = exports.resolveContentShareResources = function resolveContentShareResources(payload) {
32
+ if ((payload === null || payload === void 0 ? void 0 : payload.mediaType) !== 'share') {
33
+ return [];
34
+ }
35
+ return ['contentShare'];
36
+ };
37
+ var copyPermissionState = function copyPermissionState(source, target, resource) {
38
+ switch (resource) {
39
+ case 'camera':
40
+ if (source.camera) {
41
+ target.camera = _objectSpread({}, source.camera);
42
+ }
43
+ break;
44
+ case 'microphone':
45
+ if (source.microphone) {
46
+ target.microphone = _objectSpread({}, source.microphone);
47
+ }
48
+ break;
49
+ case 'contentShare':
50
+ if (source.contentShare) {
51
+ target.contentShare = _objectSpread({}, source.contentShare);
52
+ }
53
+ break;
54
+ default:
55
+ break;
56
+ }
57
+ };
58
+ var projectPrivacyAndSecurityPermission = exports.projectPrivacyAndSecurityPermission = function projectPrivacyAndSecurityPermission(permission, resources) {
59
+ var projectedPermission = {};
60
+ resources.forEach(function (resource) {
61
+ copyPermissionState(permission, projectedPermission, resource);
62
+ });
63
+ return (0, _keys.default)(projectedPermission).length > 0 ? projectedPermission : undefined;
64
+ };
65
+ var getChangedPermission = exports.getChangedPermission = function getChangedPermission(current, previous) {
66
+ var changedResources = (0, _keys.default)(current).filter(function (resource) {
67
+ return !(0, _lodash.isEqual)(current[resource], previous[resource]);
68
+ });
69
+ return projectPrivacyAndSecurityPermission(current, changedResources);
70
+ };
71
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_lodash","require","ownKeys","e","r","t","_Object$keys2","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","resolveMediaResources","exports","payload","mediaType","resolveContentShareResources","copyPermissionState","source","target","resource","camera","microphone","contentShare","projectPrivacyAndSecurityPermission","permission","resources","projectedPermission","_keys","undefined","getChangedPermission","current","previous","changedResources","isEqual"],"sources":["utils.ts"],"sourcesContent":["import {isEqual} from 'lodash';\n\nimport type {\n ClientEventPayload,\n PrivacyAndSecurityPermission,\n PrivacyAndSecurityPermissionResource,\n} from '../metrics.types';\n\nexport const resolveMediaResources = (\n payload?: ClientEventPayload\n): PrivacyAndSecurityPermissionResource[] => {\n switch (payload?.mediaType) {\n case 'audio':\n return ['microphone'];\n case 'video':\n return ['camera'];\n case 'share':\n return ['contentShare'];\n default:\n return [];\n }\n};\n\nexport const resolveContentShareResources = (\n payload?: ClientEventPayload\n): PrivacyAndSecurityPermissionResource[] => {\n if (payload?.mediaType !== 'share') {\n return [];\n }\n\n return ['contentShare'];\n};\n\nconst copyPermissionState = (\n source: PrivacyAndSecurityPermission,\n target: PrivacyAndSecurityPermission,\n resource: PrivacyAndSecurityPermissionResource\n): void => {\n switch (resource) {\n case 'camera':\n if (source.camera) {\n target.camera = {...source.camera};\n }\n break;\n case 'microphone':\n if (source.microphone) {\n target.microphone = {...source.microphone};\n }\n break;\n case 'contentShare':\n if (source.contentShare) {\n target.contentShare = {...source.contentShare};\n }\n break;\n default:\n break;\n }\n};\n\nexport const projectPrivacyAndSecurityPermission = (\n permission: PrivacyAndSecurityPermission,\n resources: readonly PrivacyAndSecurityPermissionResource[]\n): PrivacyAndSecurityPermission | undefined => {\n const projectedPermission: PrivacyAndSecurityPermission = {};\n\n resources.forEach((resource) => {\n copyPermissionState(permission, projectedPermission, resource);\n });\n\n return Object.keys(projectedPermission).length > 0 ? projectedPermission : undefined;\n};\n\nexport const getChangedPermission = (\n current: PrivacyAndSecurityPermission,\n previous: PrivacyAndSecurityPermission\n): PrivacyAndSecurityPermission | undefined => {\n const changedResources = (Object.keys(current) as PrivacyAndSecurityPermissionResource[]).filter(\n (resource) => !isEqual(current[resource], previous[resource])\n );\n\n return projectPrivacyAndSecurityPermission(current, changedResources);\n};\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ export declare const isAutomatedUserAgent: (userAgent?: string | null) => boolean;
2
+ export declare const isAutomatedUser: () => boolean;
@@ -1,5 +1,35 @@
1
1
  import { WebexPlugin } from '@webex/webex-core';
2
2
  import { MetricEventNames, PreComputedLatencies } from '../metrics.types';
3
+ type SaveTimestampOptions = {
4
+ meetingId?: string;
5
+ dataSetName?: string;
6
+ trackingId?: string;
7
+ };
8
+ type SaveLatencyOptions = {
9
+ accumulate?: boolean;
10
+ meetingId?: string;
11
+ dataSetName?: string;
12
+ };
13
+ type LocusSyncLatencyRecord = {
14
+ meetingId: string;
15
+ dataSetName: string;
16
+ randomBackoffTime: number;
17
+ trackingId?: string;
18
+ syncStart?: number;
19
+ hashTreeRequest?: number;
20
+ hashTreeResponse?: number;
21
+ syncRequest?: number;
22
+ syncResponse?: number;
23
+ messageReceived?: number;
24
+ };
25
+ /**
26
+ * Container for the latencies tracked for a single meeting. Locus sync is currently the only
27
+ * meeting-specific latency we track, but this wrapper lets us add other latency records in the
28
+ * future without changing the shape of `meetingLatencies`.
29
+ */
30
+ type MeetingLatencyRecord = {
31
+ locusSync: LocusSyncLatencyRecord;
32
+ };
3
33
  /**
4
34
  * @description Helper class to store latencies timestamp and to calculate various latencies for CA.
5
35
  * @exports
@@ -8,8 +38,12 @@ import { MetricEventNames, PreComputedLatencies } from '../metrics.types';
8
38
  export default class CallDiagnosticLatencies extends WebexPlugin {
9
39
  latencyTimestamps: Map<MetricEventNames, number>;
10
40
  precomputedLatencies: Map<PreComputedLatencies, number>;
41
+ meetingLatencies: Map<string, MeetingLatencyRecord[]>;
11
42
  private meetingId?;
12
43
  private MAX_INTEGER;
44
+ private LOCUS_SYNC_SKEW_THRESHOLD_MS;
45
+ private LOCUS_SYNC_PENDING_RECORD_TTL_MS;
46
+ private LOCUS_SYNC_MAX_RECORDS_PER_DATASET;
13
47
  /**
14
48
  * @constructor
15
49
  */
@@ -18,6 +52,164 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
18
52
  * Clear timestamps
19
53
  */
20
54
  clearTimestamps(): void;
55
+ /**
56
+ * Clear tracked Locus sync latency state for a dataset.
57
+ *
58
+ * When a `trackingId` is supplied only the single record matching it is dropped, mirroring the
59
+ * native client which discards the individual in-progress record on a sync error (by syncId).
60
+ * When no `trackingId` is supplied every record for the dataset is dropped (legacy behavior).
61
+ *
62
+ * @param dataSetName dataset name
63
+ * @param meetingId meeting id
64
+ * @param trackingId optional sync tracking id to drop a single record instead of the whole dataset
65
+ */
66
+ clearLocusSyncLatency(dataSetName: string, meetingId: string, trackingId?: string): void;
67
+ /**
68
+ * Calculates Locus sync latency values from stored milestone timestamps.
69
+ * @param meetingId meeting id
70
+ * @param trackingId sync tracking id used to match the record
71
+ * @returns sync latency metrics
72
+ */
73
+ getLocusSyncLatency(meetingId: string, trackingId: string): {
74
+ totalTime: number;
75
+ syncMessageReceiveTime?: number;
76
+ syncResponseTime?: number;
77
+ randomBackoffTime: number;
78
+ hashtreePrepTime: number;
79
+ hashtreeResponseTime: number;
80
+ syncPrepTime: number;
81
+ };
82
+ /**
83
+ * Records the time the LLM state-update message for a Locus sync arrived. This is the milestone
84
+ * that gates the client.locus.sync.complete metric: the metric is emitted only for flows where
85
+ * the update came over LLM (aligned with the agreed requirement that body/http-only syncs do not
86
+ * emit). The record is matched by meeting id + tracking id, regardless of which other milestones
87
+ * are present yet, so the real arrival time is captured even if the /sync response has not landed.
88
+ * @param meetingId meeting id
89
+ * @param trackingId sync tracking id used to match the pending record
90
+ * @returns void
91
+ */
92
+ recordLocusSyncMessageReceived(meetingId: string, trackingId: string): void;
93
+ /**
94
+ * Complete and remove the Locus sync latency record for a meeting + tracking id.
95
+ *
96
+ * Both milestones are required, in any arrival order: the metric is emitted only once BOTH the
97
+ * matching LLM broadcast (messageReceived) AND the /sync response have arrived. The LLM broadcast
98
+ * confirms the client that issued the /sync received the resulting state update for its tracking
99
+ * id (so sync cancel, or a sync storm where the final broadcast echoed another client's tracking
100
+ * id, never emit); the /sync response is always waited for too, since the LLM message can arrive
101
+ * before the HTTP response. If either milestone is missing the record is kept so the other can
102
+ * still arrive; it is only consumed when the metric is actually emitted.
103
+ * @param meetingId meeting id
104
+ * @param trackingId sync tracking id used to match the pending record
105
+ * @returns completed sync latency metric payload, or undefined when not completed
106
+ */
107
+ completeLocusSyncLatency(meetingId: string, trackingId: string): {
108
+ dataSet: string;
109
+ syncLatency: {
110
+ totalTime: number;
111
+ syncMessageReceiveTime?: number;
112
+ syncResponseTime?: number;
113
+ randomBackoffTime: number;
114
+ hashtreePrepTime: number;
115
+ hashtreeResponseTime: number;
116
+ syncPrepTime: number;
117
+ };
118
+ };
119
+ /**
120
+ * Helper to calculate end - start for Locus sync milestones.
121
+ * @param record tracked milestone timestamps
122
+ * @param a start milestone
123
+ * @param b end milestone
124
+ * @returns latency
125
+ */
126
+ private getDiffBetweenLocusSyncTimestamps;
127
+ /**
128
+ * Get the timestamp that starts the sync prep segment.
129
+ * @param record tracked milestone timestamps
130
+ * @returns sync prep start milestone
131
+ */
132
+ private getLocusSyncPrepStart;
133
+ /**
134
+ * Round and clamp Locus sync latency values.
135
+ * @param latency latency value
136
+ * @returns rounded latency
137
+ */
138
+ private getClampedLocusSyncLatency;
139
+ /**
140
+ * Finds a Locus sync latency record for a meeting using a predicate run against each stored
141
+ * locusSync record.
142
+ * @param meetingId meeting id
143
+ * @param predicate matcher run against each locusSync record
144
+ * @param options.searchFromLatest when true, iterate from the most recently added record first
145
+ * @returns matching Locus sync latency record
146
+ */
147
+ private findLocusSyncRecord;
148
+ /**
149
+ * Get the Locus sync latency record for a meeting and tracking id.
150
+ * @param meetingId meeting id
151
+ * @param trackingId /sync response tracking id
152
+ * @returns matching Locus sync latency record
153
+ */
154
+ private getLocusSyncLatencyRecord;
155
+ /**
156
+ * Remove the Locus sync latency record for a meeting and tracking id.
157
+ * @param meetingId meeting id
158
+ * @param trackingId sync tracking id used to match the record
159
+ * @returns void
160
+ */
161
+ private removeLocusSyncLatencyRecord;
162
+ /**
163
+ * Prune stale never-completed Locus sync latency records for the same dataset as the record that
164
+ * just changed. Records are dropped when they have been pending longer than the TTL, or to keep
165
+ * the number of records per dataset under the safety cap (oldest pending candidates first).
166
+ * @param records current records for the meeting
167
+ * @param changedRecord the record that was just updated, used as the reference point
168
+ * @returns the records to keep
169
+ */
170
+ private pruneStaleLocusSyncLatencyRecords;
171
+ /**
172
+ * Get the most recent milestone timestamp stored on a Locus sync latency record, checking
173
+ * milestones from latest to earliest so the newest available one is returned.
174
+ * @param record tracked milestone timestamps
175
+ * @returns latest milestone timestamp, or undefined when none are set
176
+ */
177
+ private getLatestLocusSyncTimestamp;
178
+ /**
179
+ * Persist the Locus sync latency records for a meeting, deleting the meeting entry when no
180
+ * records remain. When pruneOptions is provided, stale records are pruned before saving.
181
+ * @param meetingId meeting id
182
+ * @param records records to save
183
+ * @param pruneOptions when provided, triggers stale record pruning relative to changedRecord
184
+ * @returns void
185
+ */
186
+ private setMeetingLatencyRecords;
187
+ /**
188
+ * Get the latest Locus sync latency record waiting for sync.start.
189
+ * @param meetingId meeting id
190
+ * @param dataSetName dataset name
191
+ * @returns latest pending Locus sync latency record
192
+ */
193
+ private getLatestPendingLocusSyncLatencyRecord;
194
+ /**
195
+ * Store random backoff latency for the current or next Locus sync latency record.
196
+ * @param meetingId meeting id
197
+ * @param dataSetName dataset name
198
+ * @param randomBackoffTime random backoff latency value
199
+ * @returns void
200
+ */
201
+ private saveLocusSyncBackoffLatency;
202
+ /**
203
+ * Checks if metric event name is a Locus sync latency milestone.
204
+ * @param key event name
205
+ * @returns whether event is Locus sync latency milestone
206
+ */
207
+ private isLocusSyncLatencyEvent;
208
+ /**
209
+ * Stores a Locus sync latency milestone timestamp.
210
+ * @param options options
211
+ */
212
+ private saveLocusSyncLatencyTimestamp;
21
213
  /**
22
214
  * Associate current latencies with a meeting id
23
215
  * @param meetingId
@@ -39,19 +231,20 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
39
231
  saveTimestamp({ key, value, options, }: {
40
232
  key: MetricEventNames;
41
233
  value?: number;
42
- options?: {
43
- meetingId?: string;
44
- };
234
+ options?: SaveTimestampOptions;
45
235
  }): void;
46
236
  /**
47
237
  * Store precomputed latency value
48
238
  * @param key - key
49
239
  * @param value - value
50
- * @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
240
+ * @param options - store options (a legacy boolean `accumulate` flag is also accepted)
241
+ * @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
242
+ * @param options.meetingId - meeting id, only used for Locus sync latency records
243
+ * @param options.dataSetName - dataset name, only used for Locus sync latency records
51
244
  * @throws
52
245
  * @returns
53
246
  */
54
- saveLatency(key: PreComputedLatencies, value: number, accumulate?: boolean): void;
247
+ saveLatency(key: PreComputedLatencies, value: number, options?: SaveLatencyOptions): void;
55
248
  /**
56
249
  * Measure latency for a request
57
250
  * @param callback - callback for which you would like to measure latency
@@ -149,6 +342,15 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
149
342
  * @returns - latency
150
343
  */
151
344
  getStayLobbyTime(): number;
345
+ /**
346
+ * Stay lobby time capped by a certain timestamp.
347
+ * This is to handle the case where the target end timestamp could happen before the lobby is exited,
348
+ * for example media-engine.ready or client.ice.end
349
+ * This is supposed to be called AFTER the end timestamp happens
350
+ * @param endTimestampKey name of the target end event
351
+ * @returns - latency
352
+ */
353
+ getStayLobbyTimeCappedBy(endTimestampKey: MetricEventNames): number;
152
354
  /**
153
355
  * Page JMT
154
356
  * @returns - latency
@@ -258,3 +460,4 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
258
460
  */
259
461
  getOtherAppApiReqResp(): number;
260
462
  }
463
+ export {};
@@ -27,7 +27,7 @@ type GetIdentifiersOptions = {
27
27
  export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
28
28
  private callDiagnosticEventsBatcher;
29
29
  private preLoginMetricsBatcher;
30
- private logger;
30
+ private get logger();
31
31
  private hasLoggedBrowserSerial;
32
32
  private device;
33
33
  private delayedClientEvents;
@@ -36,6 +36,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
36
36
  private isMercuryConnected;
37
37
  private eventLimitTracker;
38
38
  private eventLimitWarningsLogged;
39
+ private isTelemetryOptOutManual;
40
+ private isTelemetryOptOutAutomatic;
39
41
  validator: (options: {
40
42
  type: 'mqe' | 'ce';
41
43
  event: Event;
@@ -53,6 +55,29 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
53
55
  * @returns one of 'login-ci','unverified-guest', null
54
56
  */
55
57
  getCurLoginType(): "unverified-guest" | "login-ci";
58
+ /**
59
+ * Returns the user activation state reported from the browser's navigator.userActivation API
60
+ * @returns object with hasBeenActive and isActive booleans, or undefined if unavailable
61
+ */
62
+ getUserActivation(): {
63
+ hasBeenActive: boolean;
64
+ isActive: boolean;
65
+ } | undefined;
66
+ /**
67
+ * Returns the telemetryOptOut value of the current user
68
+ * @returns one of 'manual', 'automatic', undefined
69
+ */
70
+ getTelemetryOptOut(): "manual" | "automatic";
71
+ /**
72
+ * Sets the manual telemetry opt-out status for the current user
73
+ * @param value - boolean value indicating manual telemetry opt-out status
74
+ */
75
+ setIsTelemetryOptOutManual(value: boolean): void;
76
+ /**
77
+ * Sets the automatic telemetry opt-out status for the current user
78
+ * @param value - boolean value indicating automatic telemetry opt-out status
79
+ */
80
+ setIsTelemetryOptOutAutomatic(value: boolean): void;
56
81
  /**
57
82
  * Returns if the meeting has converged architecture enabled
58
83
  * @param options.meetingId
@@ -84,6 +109,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
84
109
  userAgent: string;
85
110
  buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
86
111
  upgradeChannel?: string;
112
+ upgradeSource?: string;
87
113
  instanceId?: string;
88
114
  networkType: "wifi" | "ethernet" | "cellular" | "unknown";
89
115
  localIP?: string;
@@ -106,6 +132,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
106
132
  urlProtocolLaunchMethod?: "manual" | "auto" | "extension-fallback";
107
133
  browser?: string;
108
134
  browserVersion?: string;
135
+ isSupportedBrowserFamily?: boolean;
136
+ isOutdatedBrowserVersion?: boolean;
109
137
  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";
110
138
  subClientType?: "TEAMS_DEVICE" | "SIP" | "AUTOMOTIVE_APP" | "BROWSER_EXTENSION" | "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";
111
139
  schedulingClientType?: "TEAMS_CLIENT" | "GOOGLE_ADDON" | "PT" | "PUBLIC_API" | "UNIFIED_PAGE" | "WEBEX_PAGE" | "GOOGLE_NOTIFICATION_CALENDAR" | "MSFT_NOTIFICATION_ADDIN" | "MSFT_NOTIFICATION_CALENDAR" | "OUTLOOK_ADDIN";
@@ -113,6 +141,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
113
141
  clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
114
142
  localClientVersion?: string;
115
143
  launcherVersion?: string;
144
+ installerVersion?: string;
145
+ installerMajorVersion?: number;
146
+ installerMinorVersion?: number;
147
+ installerRevision?: number;
116
148
  modelNumber?: string;
117
149
  joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
118
150
  standbyUsed?: boolean;
@@ -137,11 +169,12 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
137
169
  architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64" | "armv9" | "armv8" | "armv7" | "armv6" | "x86_64" | "x86_32";
138
170
  staticPerformance?: string;
139
171
  clockSpeedGigaHertz?: number;
140
- additionalProperties?: false;
172
+ additionalProperties?: never;
141
173
  };
142
174
  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
175
  videoDisplayMode?: "grid-view" | "active-speaker-view";
144
- videoLayoutType?: "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery";
176
+ videoLayoutType?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
177
+ appliedLayout?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
145
178
  videoRenderType?: "wme" | "client_d3d" | "client_gdi";
146
179
  vdiInfo?: {};
147
180
  is64BitsClient?: boolean;
@@ -153,14 +186,31 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
153
186
  vendorId?: string;
154
187
  staticPerformanceLevel?: string;
155
188
  staticPerformanceScore?: number;
156
- additionalProperties?: false;
189
+ preInstalledTime?: string;
190
+ preInstalledType?: "installer" | "launcher" | "app";
191
+ preInstalledVersion?: string;
192
+ additionalProperties?: never;
193
+ };
194
+ installerInfo?: {
195
+ packageSuffix?: string;
196
+ packageArch?: string;
197
+ launchId?: string;
198
+ packageCount?: number;
199
+ totalSize?: number;
200
+ additionalProperties?: never;
157
201
  };
158
202
  emmVendorId?: string;
159
203
  isHybridMedia?: boolean;
160
204
  originData?: {};
161
205
  serviceVersion?: string;
162
- additionalProperties?: false;
206
+ additionalProperties?: never;
163
207
  };
208
+ /**
209
+ * Returns the signed-in user's CI ID derived from credentials tokens.
210
+ * Used as a fallback when no device is registered.
211
+ * @returns the userId, or undefined if it can't be determined
212
+ */
213
+ private getUserIdFromCredentials;
164
214
  /**
165
215
  * Gather identifier details for call diagnostic payload.
166
216
  * @throws Error if initialization fails.
@@ -172,6 +222,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
172
222
  participantId?: string;
173
223
  breakoutGroupId?: string;
174
224
  breakoutMoveId?: string;
225
+ breakoutTrackingId?: string;
175
226
  breakoutSessionId?: string;
176
227
  browserId?: string;
177
228
  ciExchangeTokenUrl?: string;
@@ -183,7 +234,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
183
234
  imiAppId: string;
184
235
  sessionId: string;
185
236
  sessionInstanceId: string;
186
- additionalProperties?: false;
237
+ additionalProperties?: never;
187
238
  };
188
239
  csdmDeviceUrl?: string;
189
240
  destinationBreakoutSessionId?: string;
@@ -200,6 +251,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
200
251
  callId?: string;
201
252
  pairCallId?: string;
202
253
  llmWebsocketUrl?: string;
254
+ locusCluster?: string;
203
255
  locusId?: string;
204
256
  locusJoinUrl?: string;
205
257
  locusSessionId?: string;
@@ -217,6 +269,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
217
269
  msteamsTenantGuid?: string;
218
270
  msteamsConferenceId?: string;
219
271
  msteamsMeetingId?: string;
272
+ mtid?: string;
220
273
  oauth2ClientId?: string;
221
274
  orgId?: string;
222
275
  provisionalCorrelationId?: string;
@@ -227,7 +280,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
227
280
  sipSessionId?: {
228
281
  local?: string;
229
282
  remote?: string;
230
- additionalProperties?: false;
283
+ additionalProperties?: never;
231
284
  };
232
285
  sipUri?: string;
233
286
  subConfId?: string;
@@ -255,13 +308,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
255
308
  idForEndpointAB?: string;
256
309
  customerOrgId?: string;
257
310
  correlationId: string;
258
- additionalProperties?: false;
311
+ additionalProperties?: never;
259
312
  } | {
260
313
  aggregatedBreakoutMoveId?: string;
261
314
  attendeeId?: string;
262
315
  participantId?: string;
263
316
  breakoutGroupId?: string;
264
317
  breakoutMoveId?: string;
318
+ breakoutTrackingId?: string;
265
319
  breakoutSessionId?: string;
266
320
  browserId?: string;
267
321
  ciExchangeTokenUrl?: string;
@@ -273,7 +327,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
273
327
  imiAppId: string;
274
328
  sessionId: string;
275
329
  sessionInstanceId: string;
276
- additionalProperties?: false;
330
+ additionalProperties?: never;
277
331
  };
278
332
  csdmDeviceUrl?: string;
279
333
  destinationBreakoutSessionId?: string;
@@ -290,6 +344,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
290
344
  callId?: string;
291
345
  pairCallId?: string;
292
346
  llmWebsocketUrl?: string;
347
+ locusCluster?: string;
293
348
  locusId?: string;
294
349
  locusJoinUrl?: string;
295
350
  locusSessionId?: string;
@@ -307,6 +362,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
307
362
  msteamsTenantGuid?: string;
308
363
  msteamsConferenceId?: string;
309
364
  msteamsMeetingId?: string;
365
+ mtid?: string;
310
366
  oauth2ClientId?: string;
311
367
  orgId?: string;
312
368
  provisionalCorrelationId?: string;
@@ -317,7 +373,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
317
373
  sipSessionId?: {
318
374
  local?: string;
319
375
  remote?: string;
320
- additionalProperties?: false;
376
+ additionalProperties?: never;
321
377
  };
322
378
  sipUri?: string;
323
379
  subConfId?: string;
@@ -345,13 +401,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
345
401
  idForEndpointAB?: string;
346
402
  customerOrgId?: string;
347
403
  correlationId: string;
348
- additionalProperties?: false;
404
+ additionalProperties?: never;
349
405
  } | {
350
406
  aggregatedBreakoutMoveId?: string;
351
407
  attendeeId?: string;
352
408
  participantId?: string;
353
409
  breakoutGroupId?: string;
354
410
  breakoutMoveId?: string;
411
+ breakoutTrackingId?: string;
355
412
  breakoutSessionId?: string;
356
413
  browserId?: string;
357
414
  ciExchangeTokenUrl?: string;
@@ -363,7 +420,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
363
420
  imiAppId: string;
364
421
  sessionId: string;
365
422
  sessionInstanceId: string;
366
- additionalProperties?: false;
423
+ additionalProperties?: never;
367
424
  };
368
425
  csdmDeviceUrl?: string;
369
426
  destinationBreakoutSessionId?: string;
@@ -380,6 +437,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
380
437
  callId?: string;
381
438
  pairCallId?: string;
382
439
  llmWebsocketUrl?: string;
440
+ locusCluster?: string;
383
441
  locusId?: string;
384
442
  locusJoinUrl?: string;
385
443
  locusSessionId?: string;
@@ -397,6 +455,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
397
455
  msteamsTenantGuid?: string;
398
456
  msteamsConferenceId?: string;
399
457
  msteamsMeetingId?: string;
458
+ mtid?: string;
400
459
  oauth2ClientId?: string;
401
460
  orgId?: string;
402
461
  provisionalCorrelationId?: string;
@@ -407,7 +466,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
407
466
  sipSessionId?: {
408
467
  local?: string;
409
468
  remote?: string;
410
- additionalProperties?: false;
469
+ additionalProperties?: never;
411
470
  };
412
471
  sipUri?: string;
413
472
  subConfId?: string;
@@ -435,7 +494,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
435
494
  idForEndpointAB?: string;
436
495
  customerOrgId?: string;
437
496
  correlationId: string;
438
- additionalProperties?: false;
497
+ additionalProperties?: never;
439
498
  };
440
499
  /**
441
500
  * Create diagnostic event, which can hold client event, feature event or MQE event data.