@coralogix/browser 3.10.0 → 3.15.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/CHANGELOG.md CHANGED
@@ -1,3 +1,54 @@
1
+ ## 3.15.1 (2026-06-23)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - Improve user-interaction tracking accuracy
6
+
7
+ ## 3.15.0 (2026-06-22)
8
+
9
+ ### 🚀 Features
10
+
11
+ - Improved user-interaction tracking: smarter element fingerprinting and more accurate screenshot capture on clicks and navigation.
12
+
13
+
14
+ ## 3.14.0 (2026-06-14)
15
+
16
+ ### 🚀 Features
17
+
18
+ - Flush telemetry data on tab close with fetch keepalive support
19
+
20
+ ## 3.13.0 (2026-06-11)
21
+
22
+ ### 🚀 Features
23
+
24
+ - Improve user interaction with click and scroll coordinates, and viewport context
25
+
26
+
27
+ ## 3.12.0 (2026-06-09)
28
+
29
+ ### 🚀 Features
30
+
31
+ - Improve: capture screenshot on each unique view navigation
32
+
33
+ ## 3.11.1 (2026-06-08)
34
+
35
+ ### 🩹 Fixes
36
+
37
+ - SVG element support in session recording
38
+ - session recording after refreshing the page
39
+
40
+ ## 3.11.0 (2026-06-04)
41
+
42
+ ### 🚀 Features
43
+
44
+ - Add view number tracking for product analytics support
45
+
46
+ ## 3.10.1 (2026-06-02)
47
+
48
+ ### 🩹 Fixes
49
+
50
+ - Improve beforeSend to correctly reflect modifications in OpenTelemetry span attributes
51
+
1
52
  ## 3.10.0 (2026-05-25)
2
53
 
3
54
  ### 🚀 Features
package/index.esm2.js CHANGED
@@ -227,6 +227,7 @@ var SESSION_EXPIRATION_TIME = MILLISECONDS_PER_HOUR;
227
227
  var SESSION_MANAGER_KEY = 'rumSessionManager';
228
228
  var SESSION_RECORDER_KEY = 'rumSessionRecorder';
229
229
  var SESSION_RECORDER_SEGMENTS_MAP = 'rumSessionRecorderSegmentsMap';
230
+ var VIEW_NUMBER_KEY = 'rum_view_number';
230
231
 
231
232
  var SNAPSHOT_MANAGER_KEY = 'rumSnapshotManager';
232
233
  var INITIAL_SNAPSHOT_CONTEXT = {
@@ -264,6 +265,8 @@ function getCxGlobal() {
264
265
  }
265
266
  var CxGlobal = getCxGlobal();
266
267
 
268
+ var CLICK_SCREENSHOT_MANAGER_KEY = 'rumClickScreenshotManager';
269
+
267
270
  function getSnapshotManager() {
268
271
  return CxGlobal[SNAPSHOT_MANAGER_KEY];
269
272
  }
@@ -273,12 +276,28 @@ function getSessionManager() {
273
276
  function getSessionRecorder() {
274
277
  return CxGlobal[SESSION_RECORDER_KEY];
275
278
  }
279
+ function getClickScreenshotManager() {
280
+ return CxGlobal[CLICK_SCREENSHOT_MANAGER_KEY];
281
+ }
276
282
  function getSdkConfig() {
277
283
  return CxGlobal[SDK_CONFIG_KEY];
278
284
  }
279
285
  function getUserAgentData() {
280
286
  return CxGlobal[USER_AGENT_KEY];
281
287
  }
288
+ var TRACER_PROVIDER_KEY = '__cx_tracer_provider__';
289
+ function setTracerProvider(provider) {
290
+ CxGlobal[TRACER_PROVIDER_KEY] = provider;
291
+ }
292
+ function getTracerProvider() {
293
+ return CxGlobal[TRACER_PROVIDER_KEY];
294
+ }
295
+ function flush() {
296
+ var tracerProvider = getTracerProvider();
297
+ if (!tracerProvider)
298
+ return;
299
+ tracerProvider.forceFlush();
300
+ }
282
301
 
283
302
  var GLOBAL_SPAN_KEY = '__globalSpan__';
284
303
  var GLOBAL_SPAN_MAP_KEY = '__globalSpanMap__';
@@ -2122,6 +2141,11 @@ function addEventListeners(eventTarget, eventNames, listener, _a) {
2122
2141
  };
2123
2142
  }
2124
2143
 
2144
+ var CX_ACTION_NAME_ATTRIBUTE = 'data-cx-action-name';
2145
+ var DATA_TEST_ATTRIBUTE = 'data-test';
2146
+ var DATA_TESTID_ATTRIBUTE = 'data-testid';
2147
+ var DATA_TEST_ID_ATTRIBUTE = 'data-test-id';
2148
+
2125
2149
  var PARENT_SEARCH_DEPTH = 5;
2126
2150
  var CLICKABLE_ELEMENTS = ['BUTTON', 'LABEL', 'A', 'INPUT', 'OPTION'];
2127
2151
  function getAttributeFromAncestors(element, attr, depth) {
@@ -2159,7 +2183,12 @@ function getPlaceholder(element) {
2159
2183
  return '';
2160
2184
  }
2161
2185
  function getInnerText(element) {
2162
- return element instanceof HTMLElement ? element.innerText || '' : '';
2186
+ var clickableElement = findClickableElement(element, PARENT_SEARCH_DEPTH);
2187
+ if (!clickableElement)
2188
+ return '';
2189
+ return clickableElement instanceof HTMLElement
2190
+ ? clickableElement.innerText || ''
2191
+ : '';
2163
2192
  }
2164
2193
  function extractMaskedOrTextContent(element, config) {
2165
2194
  if (!element)
@@ -2238,6 +2267,177 @@ function findClickableElement(element, maxDepth) {
2238
2267
  return findClickableElement(element.parentElement, maxDepth - 1);
2239
2268
  }
2240
2269
 
2270
+ var SHADOW_DOM_MARKER = '::shadow ';
2271
+ var STABLE_ATTRIBUTES = [
2272
+ CX_ACTION_NAME_ATTRIBUTE,
2273
+ DATA_TEST_ATTRIBUTE,
2274
+ DATA_TESTID_ATTRIBUTE,
2275
+ DATA_TEST_ID_ATTRIBUTE,
2276
+ ];
2277
+ var ESCAPE_FREE_CLASS_NAME = /^[a-zA-Z_-][a-zA-Z0-9_-]*$/;
2278
+ var GENERATED_VALUE_PATTERNS = [
2279
+ /^\d/,
2280
+ /\d{3,}/,
2281
+ /__[a-zA-Z0-9]/,
2282
+ /(?:[a-z]\d|\d[a-z]){3,}/i,
2283
+ ];
2284
+ function getElementFingerprint(target) {
2285
+ try {
2286
+ if (!target.isConnected) {
2287
+ return undefined;
2288
+ }
2289
+ var selectors = [];
2290
+ var element = target;
2291
+ while (element) {
2292
+ var root = element.getRootNode();
2293
+ var selector = getSubtreeSelector(element, root);
2294
+ if (!selector) {
2295
+ return undefined;
2296
+ }
2297
+ selectors.unshift(selector);
2298
+ element = isShadowRoot(root) ? root.host : null;
2299
+ }
2300
+ return selectors.join(SHADOW_DOM_MARKER);
2301
+ }
2302
+ catch (_a) {
2303
+ return undefined;
2304
+ }
2305
+ }
2306
+ function isShadowRoot(node) {
2307
+ return (node.nodeType === Node.DOCUMENT_FRAGMENT_NODE && !!node.host);
2308
+ }
2309
+ function getSubtreeSelector(target, root) {
2310
+ var selector = '';
2311
+ for (var element = target; element && element.nodeName !== 'HTML'; element = element.parentElement) {
2312
+ var unique = getUniqueSegment(element, root, selector);
2313
+ if (unique) {
2314
+ return joinWithChild(unique, selector);
2315
+ }
2316
+ selector = joinWithChild(getLevelSegment(element, selector), selector);
2317
+ }
2318
+ return selector;
2319
+ }
2320
+ function getUniqueSegment(element, root, childSelector) {
2321
+ var e_1, _a;
2322
+ try {
2323
+ for (var _b = __values$1([getAttributeSegment(element), getIdSegment(element)]), _c = _b.next(); !_c.done; _c = _b.next()) {
2324
+ var segment = _c.value;
2325
+ if (segment && isUnique(root, joinWithChild(segment, childSelector))) {
2326
+ return segment;
2327
+ }
2328
+ }
2329
+ }
2330
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2331
+ finally {
2332
+ try {
2333
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2334
+ }
2335
+ finally { if (e_1) throw e_1.error; }
2336
+ }
2337
+ return undefined;
2338
+ }
2339
+ function getLevelSegment(element, childSelector) {
2340
+ var e_2, _a;
2341
+ var candidates = [
2342
+ getAttributeSegment(element),
2343
+ getStableClassSegment(element),
2344
+ element.tagName,
2345
+ ];
2346
+ try {
2347
+ for (var candidates_1 = __values$1(candidates), candidates_1_1 = candidates_1.next(); !candidates_1_1.done; candidates_1_1 = candidates_1.next()) {
2348
+ var segment = candidates_1_1.value;
2349
+ if (segment && isUniqueAmongSiblings(element, segment, childSelector)) {
2350
+ return segment;
2351
+ }
2352
+ }
2353
+ }
2354
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2355
+ finally {
2356
+ try {
2357
+ if (candidates_1_1 && !candidates_1_1.done && (_a = candidates_1.return)) _a.call(candidates_1);
2358
+ }
2359
+ finally { if (e_2) throw e_2.error; }
2360
+ }
2361
+ return "".concat(element.tagName, ":nth-of-type(").concat(nthOfTypeIndex(element), ")");
2362
+ }
2363
+ function getAttributeSegment(element) {
2364
+ var e_3, _a;
2365
+ try {
2366
+ for (var STABLE_ATTRIBUTES_1 = __values$1(STABLE_ATTRIBUTES), STABLE_ATTRIBUTES_1_1 = STABLE_ATTRIBUTES_1.next(); !STABLE_ATTRIBUTES_1_1.done; STABLE_ATTRIBUTES_1_1 = STABLE_ATTRIBUTES_1.next()) {
2367
+ var attribute = STABLE_ATTRIBUTES_1_1.value;
2368
+ var value = element.getAttribute(attribute);
2369
+ if (value) {
2370
+ return "".concat(element.tagName, "[").concat(attribute, "=\"").concat(CSS.escape(value), "\"]");
2371
+ }
2372
+ }
2373
+ }
2374
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
2375
+ finally {
2376
+ try {
2377
+ if (STABLE_ATTRIBUTES_1_1 && !STABLE_ATTRIBUTES_1_1.done && (_a = STABLE_ATTRIBUTES_1.return)) _a.call(STABLE_ATTRIBUTES_1);
2378
+ }
2379
+ finally { if (e_3) throw e_3.error; }
2380
+ }
2381
+ return undefined;
2382
+ }
2383
+ function getIdSegment(element) {
2384
+ return element.id && !isUnstableValue(element.id)
2385
+ ? "#".concat(CSS.escape(element.id))
2386
+ : undefined;
2387
+ }
2388
+ function getStableClassSegment(element) {
2389
+ var _a, _b;
2390
+ if (element.tagName === 'BODY') {
2391
+ return undefined;
2392
+ }
2393
+ var classNames = (_b = (_a = element.getAttribute('class')) === null || _a === void 0 ? void 0 : _a.split(/\s+/)) !== null && _b !== void 0 ? _b : [];
2394
+ var stable = classNames.find(function (name) { return name && !isUnstableValue(name) && ESCAPE_FREE_CLASS_NAME.test(name); });
2395
+ return stable ? "".concat(element.tagName, ".").concat(stable) : undefined;
2396
+ }
2397
+ function isUnstableValue(value) {
2398
+ return GENERATED_VALUE_PATTERNS.some(function (pattern) { return pattern.test(value); });
2399
+ }
2400
+ function isUnique(root, selector) {
2401
+ return root.querySelectorAll(selector).length === 1;
2402
+ }
2403
+ function isUniqueAmongSiblings(element, segment, childSelector) {
2404
+ var e_4, _a;
2405
+ var _b, _c;
2406
+ var siblings = (_c = (_b = element.parentElement) === null || _b === void 0 ? void 0 : _b.children) !== null && _c !== void 0 ? _c : [];
2407
+ try {
2408
+ for (var siblings_1 = __values$1(siblings), siblings_1_1 = siblings_1.next(); !siblings_1_1.done; siblings_1_1 = siblings_1.next()) {
2409
+ var sibling = siblings_1_1.value;
2410
+ if (sibling === element) {
2411
+ continue;
2412
+ }
2413
+ if (sibling.matches(segment) &&
2414
+ (!childSelector || sibling.querySelector(childSelector) !== null)) {
2415
+ return false;
2416
+ }
2417
+ }
2418
+ }
2419
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2420
+ finally {
2421
+ try {
2422
+ if (siblings_1_1 && !siblings_1_1.done && (_a = siblings_1.return)) _a.call(siblings_1);
2423
+ }
2424
+ finally { if (e_4) throw e_4.error; }
2425
+ }
2426
+ return true;
2427
+ }
2428
+ function nthOfTypeIndex(element) {
2429
+ var index = 1;
2430
+ for (var s = element.previousElementSibling; s; s = s.previousElementSibling) {
2431
+ if (s.tagName === element.tagName) {
2432
+ index += 1;
2433
+ }
2434
+ }
2435
+ return index;
2436
+ }
2437
+ function joinWithChild(parent, child) {
2438
+ return child ? "".concat(parent, ">").concat(child) : parent;
2439
+ }
2440
+
2241
2441
  var _a$3;
2242
2442
  var USER_INTERACTION_INSTRUMENTATION_NAME = 'interactions';
2243
2443
  var USER_INTERACTION_INSTRUMENTATION_VERSION = '1';
@@ -2256,6 +2456,7 @@ var CoralogixUserInteractionInstrumentation = (function (_super) {
2256
2456
  var _this = this;
2257
2457
  var _a;
2258
2458
  this.handler = function (e) {
2459
+ var _a;
2259
2460
  var span;
2260
2461
  if (shouldAttachSpanToGlobalSpan(CoralogixEventType.USER_INTERACTION)) {
2261
2462
  span = attachChildSpanToGlobalSpan(CoralogixEventType.USER_INTERACTION);
@@ -2266,8 +2467,16 @@ var CoralogixUserInteractionInstrumentation = (function (_super) {
2266
2467
  var eventTarget = e.target;
2267
2468
  var config = getSdkConfig();
2268
2469
  var id = eventTarget.id, type = eventTarget.type, className = eventTarget.className, nodeName = eventTarget.nodeName;
2470
+ var clickKey = generateUUID();
2269
2471
  span.setAttribute(CoralogixAttributes.EVENT_TYPE, CoralogixEventType.USER_INTERACTION);
2270
2472
  span.setAttribute(CoralogixAttributes.INTERACTION_EVENT_NAME, e.type);
2473
+ span.setAttribute(CoralogixAttributes.CX_ID, clickKey);
2474
+ if (e instanceof MouseEvent) {
2475
+ span.setAttribute(CoralogixAttributes.CLICK_X, e.clientX);
2476
+ span.setAttribute(CoralogixAttributes.CLICK_Y, e.clientY);
2477
+ span.setAttribute(CoralogixAttributes.ELEMENT_RELATIVE_X, e.offsetX);
2478
+ span.setAttribute(CoralogixAttributes.ELEMENT_RELATIVE_Y, e.offsetY);
2479
+ }
2271
2480
  if (eventTarget && eventTarget instanceof HTMLElement) {
2272
2481
  var elementText = extractMaskedOrTextContent(eventTarget, config);
2273
2482
  var cxActionName = extractActionName(eventTarget);
@@ -2279,6 +2488,13 @@ var CoralogixUserInteractionInstrumentation = (function (_super) {
2279
2488
  actionName: cxActionName,
2280
2489
  ariaLabel: ariaLabel,
2281
2490
  });
2491
+ var _b = eventTarget.getBoundingClientRect(), width = _b.width, height = _b.height;
2492
+ span.setAttribute(CoralogixAttributes.ELEMENT_WIDTH, width);
2493
+ span.setAttribute(CoralogixAttributes.ELEMENT_HEIGHT, height);
2494
+ var fingerprint = getElementFingerprint(eventTarget);
2495
+ if (fingerprint) {
2496
+ span.setAttribute(CoralogixAttributes.ELEMENT_FINGERPRINT, fingerprint);
2497
+ }
2282
2498
  [
2283
2499
  [CoralogixAttributes.ELEMENT_ID, id],
2284
2500
  [CoralogixAttributes.ELEMENT_CLASSES, className],
@@ -2301,6 +2517,7 @@ var CoralogixUserInteractionInstrumentation = (function (_super) {
2301
2517
  });
2302
2518
  }
2303
2519
  span.end();
2520
+ (_a = getClickScreenshotManager()) === null || _a === void 0 ? void 0 : _a.handleClick();
2304
2521
  };
2305
2522
  var eventsMap = __assign(__assign({}, DEFAULT_INSTRUMENTED_EVENTS), (_a = this._config) === null || _a === void 0 ? void 0 : _a['events']);
2306
2523
  var eventNames = Object.entries(eventsMap)
@@ -2598,13 +2815,20 @@ var CoralogixDOMInstrumentation = (function (_super) {
2598
2815
  var _this = _super.call(this, DOM_INSTRUMENTATION_NAME, DOM_INSTRUMENTATION_VERSION, config) || this;
2599
2816
  _this.visibilityChangeHandler = function () {
2600
2817
  if (document.hidden) {
2601
- var domSpan = _this.tracer.startSpan(DOM_INSTRUMENTATION_NAME);
2602
- domSpan.setAttribute(CoralogixAttributes.EVENT_TYPE, CoralogixEventType.DOM);
2603
- domSpan.end();
2818
+ _this.createDOMSpan();
2819
+ flush();
2604
2820
  }
2605
2821
  };
2606
2822
  return _this;
2607
2823
  }
2824
+ CoralogixDOMInstrumentation.prototype.createDOMSpan = function () {
2825
+ var domSpan = this.tracer.startSpan(DOM_INSTRUMENTATION_NAME);
2826
+ domSpan.setAttribute(CoralogixAttributes.EVENT_TYPE, CoralogixEventType.DOM);
2827
+ domSpan[CoralogixAttributes.DOM_CONTEXT] = {
2828
+ visibility_state: document.visibilityState,
2829
+ };
2830
+ domSpan.end();
2831
+ };
2608
2832
  CoralogixDOMInstrumentation.prototype.registerToDOMEvents = function () {
2609
2833
  var originalAddEventListener = getZoneJsOriginalDom(document, 'addEventListener');
2610
2834
  originalAddEventListener.call(document, 'visibilitychange', this.visibilityChangeHandler);
@@ -2713,9 +2937,8 @@ var NETWORK_URL_LABEL_PROVIDERS_KEY = 'NETWORK_URL_LABEL_PROVIDERS';
2713
2937
  var RUM_INTERNAL_DATA_KEY = 'rumInternalData';
2714
2938
  var MASKED_TEXT = '***';
2715
2939
  var MASK_CLASS_DEFAULT = 'cx-mask';
2716
- var CX_ACTION_NAME_ATTRIBUTE = 'data-cx-action-name';
2940
+ var CX_PREFIX = 'cx';
2717
2941
  var ARIA_LABEL_ATTRIBUTE = 'aria-label';
2718
- var DATA_TEST_ATTRIBUTE = 'data-test';
2719
2942
  var MASK_INPUT_TYPES_DEFAULT = [
2720
2943
  'password',
2721
2944
  'email',
@@ -2857,14 +3080,23 @@ var CoralogixAttributes = {
2857
3080
  TARGET_ELEMENT: 'target_element',
2858
3081
  TARGET_ELEMENT_TYPE: 'target_element_type',
2859
3082
  CX_ACTION_NAME: 'cx_action_name',
3083
+ CX_ID: 'cx_id',
2860
3084
  ARIA_LABEL: 'element_aria_label',
2861
3085
  TEST_ID: 'element_test_id',
2862
3086
  RESOLVED_NAME: 'element_resolved_name',
3087
+ CLICK_X: 'click_x',
3088
+ CLICK_Y: 'click_y',
3089
+ ELEMENT_RELATIVE_X: 'element_relative_x',
3090
+ ELEMENT_RELATIVE_Y: 'element_relative_y',
3091
+ ELEMENT_WIDTH: 'element_width',
3092
+ ELEMENT_HEIGHT: 'element_height',
3093
+ ELEMENT_FINGERPRINT: 'element_fingerprint',
2863
3094
  TIMESTAMP: 'timestamp',
2864
3095
  INTERNAL: 'internal',
2865
3096
  PAGE_CONTEXT: 'page_context',
2866
3097
  IS_NAVIGATION_EVENT: 'is_navigation_event',
2867
3098
  SCREENSHOT_CONTEXT: 'screenshot_context',
3099
+ DOM_CONTEXT: 'dom_context',
2868
3100
  };
2869
3101
  var CoralogixDomainsApiUrlMap = {
2870
3102
  EU1: 'https://ingress.eu1.rum-ingress-coralogix.com',
@@ -3520,6 +3752,8 @@ var DEFAULT_MS_RECORD_TIME = 10000;
3520
3752
  _a$1),
3521
3753
  });
3522
3754
 
3755
+ var KEEPALIVE_MAX_BYTES = 65536;
3756
+ var encoder = new TextEncoder();
3523
3757
  var Request = (function () {
3524
3758
  function Request(requestConfig) {
3525
3759
  this.requestConfig = requestConfig;
@@ -3550,14 +3784,19 @@ var Request = (function () {
3550
3784
  this.resolvedHeaders = headers;
3551
3785
  };
3552
3786
  Request.prototype.send = function (body) {
3787
+ var useKeepalive = document.hidden && this.isWithinKeepaliveQuota(body);
3553
3788
  return fetch(this.resolvedUrl, {
3554
3789
  method: 'POST',
3555
3790
  headers: this.resolvedHeaders,
3556
3791
  body: body,
3792
+ keepalive: useKeepalive,
3557
3793
  }).catch(function (e) {
3558
3794
  return e;
3559
3795
  });
3560
3796
  };
3797
+ Request.prototype.isWithinKeepaliveQuota = function (body) {
3798
+ return typeof body === 'string' && encoder.encode(body).length <= KEEPALIVE_MAX_BYTES;
3799
+ };
3561
3800
  return Request;
3562
3801
  }());
3563
3802
 
@@ -4033,7 +4272,7 @@ function isInstrumentationCompatible(confKey) {
4033
4272
  var SessionManager = (function (_super) {
4034
4273
  __extends(SessionManager, _super);
4035
4274
  function SessionManager(recordConfig) {
4036
- var _a;
4275
+ var _a, _b;
4037
4276
  var _this = _super.call(this, {
4038
4277
  timeoutDelay: SESSION_IDLE_TIME,
4039
4278
  onIdle: function () { return _this.clearSessionWhenIdle(); },
@@ -4043,6 +4282,7 @@ var SessionManager = (function (_super) {
4043
4282
  _this._sessionHasError = false;
4044
4283
  _this._cachedLogsSent = false;
4045
4284
  _this._currentPageTimestamp = getNowTime();
4285
+ _this._viewNumber = 0;
4046
4286
  _this.debugMode = !!((_a = getSdkConfig()) === null || _a === void 0 ? void 0 : _a.debug);
4047
4287
  _this.getPrevSession = function () {
4048
4288
  var _a;
@@ -4086,6 +4326,9 @@ var SessionManager = (function (_super) {
4086
4326
  return _this.activeSession;
4087
4327
  };
4088
4328
  _this.initializeSession(recordConfig);
4329
+ if ((_b = _this._sessionConfig) === null || _b === void 0 ? void 0 : _b.keepSessionAfterReload) {
4330
+ _this.loadViewNumber();
4331
+ }
4089
4332
  return _this;
4090
4333
  }
4091
4334
  Object.defineProperty(SessionManager.prototype, "currentPageTimestamp", {
@@ -4164,6 +4407,13 @@ var SessionManager = (function (_super) {
4164
4407
  enumerable: false,
4165
4408
  configurable: true
4166
4409
  });
4410
+ Object.defineProperty(SessionManager.prototype, "viewNumber", {
4411
+ get: function () {
4412
+ return this._viewNumber;
4413
+ },
4414
+ enumerable: false,
4415
+ configurable: true
4416
+ });
4167
4417
  SessionManager.prototype.updateCurrentPage = function (fragment) {
4168
4418
  if (this.isIdleActive) {
4169
4419
  this._currentPageFragment = undefined;
@@ -4172,6 +4422,26 @@ var SessionManager = (function (_super) {
4172
4422
  this._currentPageFragment = fragment;
4173
4423
  this._currentPageTimestamp = getNowTime();
4174
4424
  };
4425
+ SessionManager.prototype.incrementViewNumber = function () {
4426
+ this._viewNumber++;
4427
+ this.persistViewNumber();
4428
+ };
4429
+ SessionManager.prototype.persistViewNumber = function () {
4430
+ var _a, _b;
4431
+ if ((_a = this._sessionConfig) === null || _a === void 0 ? void 0 : _a.keepSessionAfterReload) {
4432
+ (_b = CxGlobal.sessionStorage) === null || _b === void 0 ? void 0 : _b.setItem(VIEW_NUMBER_KEY, String(this._viewNumber));
4433
+ }
4434
+ };
4435
+ SessionManager.prototype.loadViewNumber = function () {
4436
+ var _a;
4437
+ var storedViewNumber = (_a = CxGlobal.sessionStorage) === null || _a === void 0 ? void 0 : _a.getItem(VIEW_NUMBER_KEY);
4438
+ this._viewNumber = Number(storedViewNumber) || 0;
4439
+ };
4440
+ SessionManager.prototype.resetViewNumber = function () {
4441
+ var _a;
4442
+ this._viewNumber = 0;
4443
+ (_a = CxGlobal.sessionStorage) === null || _a === void 0 ? void 0 : _a.removeItem(VIEW_NUMBER_KEY);
4444
+ };
4175
4445
  SessionManager.prototype.getSessionKey = function () {
4176
4446
  return SESSION_KEY;
4177
4447
  };
@@ -4226,7 +4496,7 @@ var SessionManager = (function (_super) {
4226
4496
  (_a = CxGlobal.sessionStorage) === null || _a === void 0 ? void 0 : _a.removeItem(PREV_SESSION_KEY);
4227
4497
  };
4228
4498
  SessionManager.prototype.clearSession = function () {
4229
- var _a, _b, _c, _d, _e, _f;
4499
+ var _a, _b, _c, _d, _e, _f, _g;
4230
4500
  if (this.debugMode) {
4231
4501
  console.debug('Coralogix Browser SDK - Session expired, clearing session');
4232
4502
  }
@@ -4234,9 +4504,11 @@ var SessionManager = (function (_super) {
4234
4504
  this.clearGlobalSpans();
4235
4505
  this.clearSessionWithErrorMode();
4236
4506
  (_d = getSnapshotManager()) === null || _d === void 0 ? void 0 : _d.resetSnapshot();
4507
+ (_e = getClickScreenshotManager()) === null || _e === void 0 ? void 0 : _e.reset();
4237
4508
  this._currentPageFragment = undefined;
4238
- (_e = this.sessionRecorder) === null || _e === void 0 ? void 0 : _e.stopRecording();
4239
- (_f = CxGlobal.sessionStorage) === null || _f === void 0 ? void 0 : _f.removeItem(SESSION_KEY);
4509
+ this.resetViewNumber();
4510
+ (_f = this.sessionRecorder) === null || _f === void 0 ? void 0 : _f.stopRecording();
4511
+ (_g = CxGlobal.sessionStorage) === null || _g === void 0 ? void 0 : _g.removeItem(SESSION_KEY);
4240
4512
  };
4241
4513
  SessionManager.prototype.clearGlobalSpans = function () {
4242
4514
  var _a;
@@ -4249,13 +4521,8 @@ var SessionManager = (function (_super) {
4249
4521
  this.cachedLogsSent = false;
4250
4522
  };
4251
4523
  SessionManager.prototype.handleRefreshedSessions = function () {
4252
- var _a, _b;
4253
4524
  this.activeSession = this.getSession();
4254
- var recordingSegmentMapFromStorage = JSON.parse(((_a = CxGlobal.sessionStorage) === null || _a === void 0 ? void 0 : _a.getItem(SESSION_RECORDER_SEGMENTS_MAP)) || '{}');
4255
- if (this.activeSession) {
4256
- (_b = getSessionRecorder()) === null || _b === void 0 ? void 0 : _b.updateSegmentIndexCounter(recordingSegmentMapFromStorage);
4257
- }
4258
- else {
4525
+ if (!this.activeSession) {
4259
4526
  this.createNewSession();
4260
4527
  }
4261
4528
  };
@@ -4440,7 +4707,7 @@ function resolveUrlBlueprinters(urlBlueprinters) {
4440
4707
  return resolvedUrlBlueprinters;
4441
4708
  }
4442
4709
 
4443
- var SDK_VERSION = '3.10.0';
4710
+ var SDK_VERSION = '3.15.1';
4444
4711
 
4445
4712
  function shouldDropEvent(cxRumEvent, options) {
4446
4713
  if (isDocumentErrorWithoutMessage(cxRumEvent)) {
@@ -4578,6 +4845,9 @@ var CoralogixSpanMapProcessor = (function () {
4578
4845
  getSessionManager().sessionHasError = true;
4579
4846
  resolvedCxSpan.text.cx_rum.session_context.hasError = true;
4580
4847
  }
4848
+ if (shouldAddOtelAttr(span)) {
4849
+ this.addOtelInstrumentationData(span, resolvedCxSpan);
4850
+ }
4581
4851
  span[CX_MAPPED_SPAN] = resolvedCxSpan;
4582
4852
  }
4583
4853
  }
@@ -4591,21 +4861,19 @@ var CoralogixSpanMapProcessor = (function () {
4591
4861
  return Promise.resolve(undefined);
4592
4862
  };
4593
4863
  CoralogixSpanMapProcessor.prototype._mapToCxSpan = function (span, session, prevSession, sessionHasRecording, sessionHasScreenshot, onlySessionWithErrorMode) {
4594
- var _a, _b;
4595
- var _c = session || {}, sessionId = _c.sessionId, sessionCreationDate = _c.sessionCreationDate;
4596
- var _d = prevSession || {}, prevSessionId = _d.sessionId, prevSessionCreationDate = _d.sessionCreationDate, prevSessionHasRecording = _d.hasRecording, prevSessionHasScreenshot = _d.hasScreenshot;
4597
- var attributes = span.attributes, startTime = span.startTime, parentSpanId = span.parentSpanId, name = span.name, endTime = span.endTime, status = span.status, duration = span.duration, kind = span.kind;
4864
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4865
+ var _l = session || {}, sessionId = _l.sessionId, sessionCreationDate = _l.sessionCreationDate;
4866
+ var _m = prevSession || {}, prevSessionId = _m.sessionId, prevSessionCreationDate = _m.sessionCreationDate, prevSessionHasRecording = _m.hasRecording, prevSessionHasScreenshot = _m.hasScreenshot;
4867
+ var attributes = span.attributes;
4598
4868
  var user_context = JSON.parse(attributes[CoralogixAttributes.USER_CONTEXT]);
4599
4869
  var application_context = JSON.parse(attributes[CoralogixAttributes.APPLICATION_CONTEXT]);
4600
4870
  var application = application_context.application, version = application_context.version;
4601
4871
  var eventType = attributes[CoralogixAttributes.EVENT_TYPE] ||
4602
4872
  span[CoralogixAttributes.EVENT_TYPE];
4603
4873
  var eventTypeContext = this._getEventTypeContext(attributes, eventType, span);
4604
- var _e = span.spanContext(), spanId = _e.spanId, traceId = _e.traceId;
4605
- var resourceAttributes = __assign(__assign({}, (_a = span.resource) === null || _a === void 0 ? void 0 : _a.attributes), { 'service.name': application });
4606
4874
  var fingerPrint = getSessionManager().fingerPrint;
4607
4875
  var labels = JSON.parse(attributes[CoralogixAttributes.CUSTOM_LABELS]);
4608
- var isErrorWithStacktrace = !!((_b = eventTypeContext === null || eventTypeContext === void 0 ? void 0 : eventTypeContext.error_context) === null || _b === void 0 ? void 0 : _b.original_stacktrace);
4876
+ var isErrorWithStacktrace = !!((_a = eventTypeContext === null || eventTypeContext === void 0 ? void 0 : eventTypeContext.error_context) === null || _a === void 0 ? void 0 : _a.original_stacktrace);
4609
4877
  var version_metadata = {
4610
4878
  app_name: application,
4611
4879
  app_version: version,
@@ -4637,34 +4905,18 @@ var CoralogixSpanMapProcessor = (function () {
4637
4905
  type: eventType,
4638
4906
  source: attributes[CoralogixAttributes.SOURCE],
4639
4907
  severity: severity,
4640
- }, labels: labels, environment: attributes[CoralogixAttributes.ENVIRONMENT] || '' }),
4908
+ }, labels: labels, environment: attributes[CoralogixAttributes.ENVIRONMENT] || '', view_number: getSessionManager().viewNumber, layout_context: {
4909
+ viewport_width: (_b = window === null || window === void 0 ? void 0 : window.innerWidth) !== null && _b !== void 0 ? _b : 0,
4910
+ viewport_height: (_c = window === null || window === void 0 ? void 0 : window.innerHeight) !== null && _c !== void 0 ? _c : 0,
4911
+ view_width: (_e = (_d = document === null || document === void 0 ? void 0 : document.documentElement) === null || _d === void 0 ? void 0 : _d.scrollWidth) !== null && _e !== void 0 ? _e : 0,
4912
+ view_height: (_g = (_f = document === null || document === void 0 ? void 0 : document.documentElement) === null || _f === void 0 ? void 0 : _f.scrollHeight) !== null && _g !== void 0 ? _g : 0,
4913
+ device_pixel_ratio: (_h = window === null || window === void 0 ? void 0 : window.devicePixelRatio) !== null && _h !== void 0 ? _h : 1,
4914
+ scroll_x: (_j = window === null || window === void 0 ? void 0 : window.scrollX) !== null && _j !== void 0 ? _j : 0,
4915
+ scroll_y: (_k = window === null || window === void 0 ? void 0 : window.scrollY) !== null && _k !== void 0 ? _k : 0,
4916
+ } }),
4641
4917
  },
4642
4918
  };
4643
4919
  var resolvedLabels = this.resolveLabels(cxSpan.text.cx_rum);
4644
- if (shouldAddOtelAttr(span)) {
4645
- cxSpan.text.cx_rum.spanId = spanId;
4646
- cxSpan.text.cx_rum.traceId = traceId;
4647
- cxSpan.text.cx_rum.parentSpanId = parentSpanId;
4648
- cxSpan.instrumentation_data = {
4649
- otelSpan: {
4650
- spanId: spanId,
4651
- traceId: traceId,
4652
- parentSpanId: parentSpanId,
4653
- startTime: startTime,
4654
- endTime: endTime,
4655
- status: severity === CoralogixLogSeverity.Error
4656
- ? __assign(__assign({}, status), { code: SpanStatusCode.ERROR }) : status,
4657
- kind: kind,
4658
- duration: duration,
4659
- sessionId: sessionId,
4660
- name: name,
4661
- attributes: buildRumContextAttributes(cxSpan.text.cx_rum, resolvedLabels),
4662
- },
4663
- otelResource: {
4664
- attributes: resourceAttributes,
4665
- },
4666
- };
4667
- }
4668
4920
  this.resolveContextFromSpan(cxSpan, span, eventType);
4669
4921
  cxSpan.text.cx_rum.labels = resolvedLabels;
4670
4922
  return cxSpan;
@@ -4686,8 +4938,42 @@ var CoralogixSpanMapProcessor = (function () {
4686
4938
  span[CoralogixAttributes.SCREENSHOT_CONTEXT];
4687
4939
  break;
4688
4940
  }
4941
+ case CoralogixEventType.DOM: {
4942
+ cxSpan.text.cx_rum.dom_context = span[CoralogixAttributes.DOM_CONTEXT];
4943
+ break;
4944
+ }
4689
4945
  }
4690
4946
  };
4947
+ CoralogixSpanMapProcessor.prototype.addOtelInstrumentationData = function (span, cxSpan) {
4948
+ var _a;
4949
+ var _b = span.spanContext(), spanId = _b.spanId, traceId = _b.traceId;
4950
+ var parentSpanId = span.parentSpanId, startTime = span.startTime, endTime = span.endTime, status = span.status, kind = span.kind, duration = span.duration, name = span.name;
4951
+ var cxRum = cxSpan.text.cx_rum;
4952
+ var sessionId = cxRum.session_context.session_id;
4953
+ cxRum.spanId = spanId;
4954
+ cxRum.traceId = traceId;
4955
+ cxRum.parentSpanId = parentSpanId;
4956
+ var resourceAttributes = __assign(__assign({}, (_a = span.resource) === null || _a === void 0 ? void 0 : _a.attributes), { 'service.name': cxSpan.applicationName });
4957
+ cxSpan.instrumentation_data = {
4958
+ otelSpan: {
4959
+ spanId: spanId,
4960
+ traceId: traceId,
4961
+ parentSpanId: parentSpanId,
4962
+ startTime: startTime,
4963
+ endTime: endTime,
4964
+ status: cxSpan.severity === CoralogixLogSeverity.Error
4965
+ ? __assign(__assign({}, status), { code: SpanStatusCode.ERROR }) : status,
4966
+ kind: kind,
4967
+ duration: duration,
4968
+ sessionId: sessionId,
4969
+ name: name,
4970
+ attributes: buildRumContextAttributes(cxRum, cxRum.labels),
4971
+ },
4972
+ otelResource: {
4973
+ attributes: resourceAttributes,
4974
+ },
4975
+ };
4976
+ };
4691
4977
  CoralogixSpanMapProcessor.prototype._getEventTypeContext = function (spanAttributes, eventType, span) {
4692
4978
  var _a;
4693
4979
  switch (eventType) {
@@ -4761,6 +5047,7 @@ var CoralogixSpanMapProcessor = (function () {
4761
5047
  interaction_context: {
4762
5048
  target_element: spanAttributes[CoralogixAttributes.TARGET_ELEMENT],
4763
5049
  event_name: spanAttributes[CoralogixAttributes.INTERACTION_EVENT_NAME],
5050
+ cx_id: spanAttributes[CoralogixAttributes.CX_ID],
4764
5051
  target_element_inner_text: spanAttributes[CoralogixAttributes.ELEMENT_INNER_TEXT],
4765
5052
  element_id: spanAttributes[CoralogixAttributes.ELEMENT_ID],
4766
5053
  element_classes: spanAttributes[CoralogixAttributes.ELEMENT_CLASSES],
@@ -4769,6 +5056,13 @@ var CoralogixSpanMapProcessor = (function () {
4769
5056
  cx_action_name: spanAttributes[CoralogixAttributes.CX_ACTION_NAME],
4770
5057
  element_aria_label: spanAttributes[CoralogixAttributes.ARIA_LABEL],
4771
5058
  element_test_id: spanAttributes[CoralogixAttributes.TEST_ID],
5059
+ click_x: spanAttributes[CoralogixAttributes.CLICK_X],
5060
+ click_y: spanAttributes[CoralogixAttributes.CLICK_Y],
5061
+ element_relative_x: spanAttributes[CoralogixAttributes.ELEMENT_RELATIVE_X],
5062
+ element_relative_y: spanAttributes[CoralogixAttributes.ELEMENT_RELATIVE_Y],
5063
+ element_width: spanAttributes[CoralogixAttributes.ELEMENT_WIDTH],
5064
+ element_height: spanAttributes[CoralogixAttributes.ELEMENT_HEIGHT],
5065
+ element_fingerprint: spanAttributes[CoralogixAttributes.ELEMENT_FINGERPRINT],
4772
5066
  },
4773
5067
  };
4774
5068
  }
@@ -4976,6 +5270,7 @@ var CoralogixNavigationProcessor = (function () {
4976
5270
  };
4977
5271
  CoralogixNavigationProcessor.prototype.onEnd = function (span) { };
4978
5272
  CoralogixNavigationProcessor.prototype.onStart = function (span) {
5273
+ var _a;
4979
5274
  if (this.isResolving) {
4980
5275
  return;
4981
5276
  }
@@ -4989,6 +5284,8 @@ var CoralogixNavigationProcessor = (function () {
4989
5284
  if (currentPageFragment !== page_fragments) {
4990
5285
  getSessionManager().updateCurrentPage(page_fragments);
4991
5286
  span[CoralogixAttributes.IS_NAVIGATION_EVENT] = true;
5287
+ this.handlePageNavigation(currentPageFragment);
5288
+ (_a = getClickScreenshotManager()) === null || _a === void 0 ? void 0 : _a.onNavigation();
4992
5289
  }
4993
5290
  }
4994
5291
  }
@@ -4996,6 +5293,11 @@ var CoralogixNavigationProcessor = (function () {
4996
5293
  this.isResolving = false;
4997
5294
  }
4998
5295
  };
5296
+ CoralogixNavigationProcessor.prototype.handlePageNavigation = function (currentPageFragment) {
5297
+ if (currentPageFragment) {
5298
+ getSessionManager().incrementViewNumber();
5299
+ }
5300
+ };
4999
5301
  CoralogixNavigationProcessor.prototype.shutdown = function () {
5000
5302
  return Promise.resolve();
5001
5303
  };
@@ -5009,6 +5311,42 @@ function getTiming(duration) {
5009
5311
  return getNowTime() - getSessionManager().currentPageTimestamp;
5010
5312
  }
5011
5313
 
5314
+ var FIRST_CAPTURE_CLICK = 1;
5315
+ var MIN_SECOND_CAPTURE_CLICK = 2;
5316
+ var TOTAL_CAPTURE_OPTIONS = 9;
5317
+ function sampleSecondCaptureClick() {
5318
+ return (MIN_SECOND_CAPTURE_CLICK + Math.floor(Math.random() * TOTAL_CAPTURE_OPTIONS));
5319
+ }
5320
+ var ClickScreenshotManager = (function () {
5321
+ function ClickScreenshotManager() {
5322
+ var _this = this;
5323
+ this.secondCaptureClick = sampleSecondCaptureClick();
5324
+ this.clickCount = 0;
5325
+ this.reset = function () {
5326
+ _this.secondCaptureClick = sampleSecondCaptureClick();
5327
+ _this.clickCount = 0;
5328
+ };
5329
+ this.onNavigation = function () {
5330
+ _this.clickCount = 0;
5331
+ };
5332
+ this.handleClick = function () {
5333
+ if (!getSessionRecorder()) {
5334
+ return;
5335
+ }
5336
+ _this.clickCount += 1;
5337
+ if (_this.clickCount === FIRST_CAPTURE_CLICK ||
5338
+ _this.clickCount === _this.secondCaptureClick) {
5339
+ CoralogixRum.screenshot(CX_PREFIX);
5340
+ }
5341
+ };
5342
+ CxGlobal[CLICK_SCREENSHOT_MANAGER_KEY] = this;
5343
+ }
5344
+ ClickScreenshotManager.unregister = function () {
5345
+ CxGlobal[CLICK_SCREENSHOT_MANAGER_KEY] = undefined;
5346
+ };
5347
+ return ClickScreenshotManager;
5348
+ }());
5349
+
5012
5350
  if (supportedPerformanceTypes === null || supportedPerformanceTypes === void 0 ? void 0 : supportedPerformanceTypes.has(PerformanceTypes.LongTask)) {
5013
5351
  var ttiHandler_1 = (CxGlobal.__tti = {
5014
5352
  e: [],
@@ -5039,6 +5377,7 @@ var CoralogixRum = {
5039
5377
  init: function (options) {
5040
5378
  var _a, _b;
5041
5379
  var _this = this;
5380
+ var _c;
5042
5381
  try {
5043
5382
  if (isInited) {
5044
5383
  if (options === null || options === void 0 ? void 0 : options.debug) {
@@ -5070,6 +5409,7 @@ var CoralogixRum = {
5070
5409
  tracerProvider = new CoralogixWebTracerProvider({
5071
5410
  sampler: sampler,
5072
5411
  });
5412
+ setTracerProvider(tracerProvider);
5073
5413
  var pluginDefaults_1 = {};
5074
5414
  var instrumentations = INSTRUMENTATIONS.map(function (_a) {
5075
5415
  var _b, _c;
@@ -5155,6 +5495,9 @@ var CoralogixRum = {
5155
5495
  spanMapProcessor = new CoralogixSpanMapProcessor();
5156
5496
  tracerProvider.addSpanProcessor(spanMapProcessor);
5157
5497
  new SnapshotManager();
5498
+ if ((_c = resolvedOptions_1.sessionRecordingConfig) === null || _c === void 0 ? void 0 : _c.enable) {
5499
+ new ClickScreenshotManager();
5500
+ }
5158
5501
  snapshotProcessor = new CoralogixSnapshotSpanProcessor();
5159
5502
  tracerProvider.addSpanProcessor(snapshotProcessor);
5160
5503
  tracerProvider.addSpanProcessor(new BatchSpanProcessor((exporter = new CoralogixExporter()), {
@@ -5166,10 +5509,10 @@ var CoralogixRum = {
5166
5509
  tracerProvider: tracerProvider,
5167
5510
  instrumentations: instrumentations,
5168
5511
  });
5169
- var _c = __read$1(partition(resolvedOptions_1.labelProviders || [], function (_a) {
5512
+ var _d = __read$1(partition(resolvedOptions_1.labelProviders || [], function (_a) {
5170
5513
  var urlType = _a.urlType;
5171
5514
  return urlType === UrlType.PAGE || !urlType;
5172
- }), 2), pageUrlLabelProviders = _c[0], networkUrlLabelProviders = _c[1];
5515
+ }), 2), pageUrlLabelProviders = _d[0], networkUrlLabelProviders = _d[1];
5173
5516
  saveInternalRumData(PAGE_URL_LABEL_PROVIDERS_KEY, pageUrlLabelProviders);
5174
5517
  saveInternalRumData(NETWORK_URL_LABEL_PROVIDERS_KEY, networkUrlLabelProviders);
5175
5518
  isInited = true;
@@ -5255,6 +5598,7 @@ var CoralogixRum = {
5255
5598
  _deregisterInstrumentations = undefined;
5256
5599
  this.stopSessionRecording();
5257
5600
  (_a = getSessionManager()) === null || _a === void 0 ? void 0 : _a.stop();
5601
+ ClickScreenshotManager.unregister();
5258
5602
  attributesProcessor === null || attributesProcessor === void 0 ? void 0 : attributesProcessor.shutdown();
5259
5603
  navigationProcessor === null || navigationProcessor === void 0 ? void 0 : navigationProcessor.shutdown();
5260
5604
  spanMapProcessor === null || spanMapProcessor === void 0 ? void 0 : spanMapProcessor.shutdown();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralogix/browser",
3
- "version": "3.10.0",
3
+ "version": "3.15.1",
4
4
  "description": "Official Coralogix SDK for browsers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coralogix",
@@ -1,5 +1,5 @@
1
1
  import { __values, __spreadArray, __read, __assign, __awaiter, __generator, __rest } from 'tslib';
2
- import { c as cxSetTimeout, a as cxClearTimeout, g as getZoneJsOriginalDom, b as createCxMutationObserver, d as cxRequestAnimationFrame, e as cxCancelAnimationFrame, C as CxGlobal, f as getSdkConfig, h as cxClearInterval, S as SESSION_RECORDER_SEGMENTS_MAP, i as getNowTime, j as SESSION_RECORDING_NETWORK_ERR0R_MESSAGE, k as cxSetInterval, R as Request, l as SESSION_RECORDING_DEFAULT_HEADERS, m as SESSION_RECORDING_POSTFIX_URL, B as BATCH_TIME_DELAY, n as SESSION_RECORDER_KEY, o as SESSION_RECORDING_DEFAULT_ERROR_MESSAGE, M as MAX_BATCH_TIME_MS } from './index.esm2.js';
2
+ import { c as cxSetTimeout, a as cxClearTimeout, g as getZoneJsOriginalDom, b as createCxMutationObserver, d as cxRequestAnimationFrame, e as cxCancelAnimationFrame, C as CxGlobal, S as SESSION_RECORDER_SEGMENTS_MAP, f as getSdkConfig, h as cxClearInterval, i as getNowTime, j as SESSION_RECORDING_NETWORK_ERR0R_MESSAGE, k as cxSetInterval, R as Request, l as SESSION_RECORDING_DEFAULT_HEADERS, m as SESSION_RECORDING_POSTFIX_URL, B as BATCH_TIME_DELAY, n as SESSION_RECORDER_KEY, o as SESSION_RECORDING_DEFAULT_ERROR_MESSAGE, M as MAX_BATCH_TIME_MS } from './index.esm2.js';
3
3
  import '@opentelemetry/sdk-trace-base';
4
4
  import '@opentelemetry/sdk-trace-web';
5
5
  import '@opentelemetry/instrumentation';
@@ -492,6 +492,9 @@ function absolutifyURLs(cssText, href) {
492
492
  if (!filePath) {
493
493
  return origin;
494
494
  }
495
+ if (filePath[0] === '#') {
496
+ return "url(".concat(maybeQuote).concat(filePath).concat(maybeQuote, ")");
497
+ }
495
498
  if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
496
499
  return "url(".concat(maybeQuote).concat(filePath).concat(maybeQuote, ")");
497
500
  }
@@ -712,8 +715,11 @@ function absoluteToDoc(doc, attributeValue) {
712
715
  }
713
716
  return getHref(doc, attributeValue);
714
717
  }
718
+ var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
715
719
  function isSVGElement(el) {
716
- return Boolean(el.tagName === 'svg' || el.ownerSVGElement);
720
+ return Boolean(el.namespaceURI === SVG_NAMESPACE ||
721
+ el.tagName === 'svg' ||
722
+ el.ownerSVGElement);
717
723
  }
718
724
  function getHref(doc, customHref) {
719
725
  var a = cachedDocument.get(doc);
@@ -1166,12 +1172,13 @@ function serializeElementNode(n, options) {
1166
1172
  }
1167
1173
  catch (e) {
1168
1174
  }
1175
+ var isSVG = isSVGElement(n);
1169
1176
  return {
1170
1177
  type: NodeType.Element,
1171
- tagName: tagName,
1178
+ tagName: isSVG ? n.tagName : tagName,
1172
1179
  attributes: attributes,
1173
1180
  childNodes: [],
1174
- isSVG: isSVGElement(n) || undefined,
1181
+ isSVG: isSVG || undefined,
1175
1182
  needBlock: needBlock,
1176
1183
  rootId: rootId,
1177
1184
  isCustom: isCustomElement,
@@ -5710,7 +5717,7 @@ var WorkerManager = (function () {
5710
5717
  var SessionRecorder = (function () {
5711
5718
  function SessionRecorder(sessionManager, recordConfig) {
5712
5719
  var _this = this;
5713
- var _a;
5720
+ var _a, _b;
5714
5721
  this.isAutoStartRecording = false;
5715
5722
  this.onlySessionWithErrorMode = false;
5716
5723
  this.recordEvents = [];
@@ -5788,6 +5795,9 @@ var SessionRecorder = (function () {
5788
5795
  };
5789
5796
  CxGlobal[SESSION_RECORDER_KEY] = this;
5790
5797
  this.sessionManager = sessionManager;
5798
+ if ((_b = getSdkConfig().sessionConfig) === null || _b === void 0 ? void 0 : _b.keepSessionAfterReload) {
5799
+ this.restoreSegmentIndexCounter();
5800
+ }
5791
5801
  var onlySessionWithErrorMode = sessionManager.onlySessionWithErrorMode, maxRecordTimeForSessionWithError = sessionManager.maxRecordTimeForSessionWithError;
5792
5802
  var autoStartSessionRecording = recordConfig.autoStartSessionRecording, workerUrl = recordConfig.workerUrl;
5793
5803
  this.onlySessionWithErrorMode = onlySessionWithErrorMode;
@@ -5812,15 +5822,22 @@ var SessionRecorder = (function () {
5812
5822
  return (this.hasRecording &&
5813
5823
  !!this.segmentIndexCounter[(_a = this.sessionManager.getActiveSession()) === null || _a === void 0 ? void 0 : _a.sessionId]);
5814
5824
  };
5815
- SessionRecorder.prototype.updateSegmentIndexCounter = function (segmentIndexCounter) {
5816
- this.segmentIndexCounter = segmentIndexCounter;
5825
+ SessionRecorder.prototype.getSegmentIndexCounter = function () {
5826
+ return this.segmentIndexCounter;
5827
+ };
5828
+ SessionRecorder.prototype.restoreSegmentIndexCounter = function () {
5829
+ var stored = CxGlobal.sessionStorage.getItem(SESSION_RECORDER_SEGMENTS_MAP);
5830
+ if (stored) {
5831
+ this.segmentIndexCounter = JSON.parse(stored);
5832
+ }
5817
5833
  };
5818
5834
  SessionRecorder.prototype.getIsAutoStartRecording = function () {
5819
5835
  return this.isAutoStartRecording;
5820
5836
  };
5821
5837
  SessionRecorder.prototype.isConsoleRecordingActive = function () {
5822
5838
  var _a;
5823
- return !!this.recordRef && ((_a = getSdkConfig().sessionRecordingConfig) === null || _a === void 0 ? void 0 : _a.recordConsoleEvents) === true;
5839
+ return (!!this.recordRef &&
5840
+ ((_a = getSdkConfig().sessionRecordingConfig) === null || _a === void 0 ? void 0 : _a.recordConsoleEvents) === true);
5824
5841
  };
5825
5842
  Object.defineProperty(SessionRecorder.prototype, "recordingStopDueToTimeout", {
5826
5843
  get: function () {
package/src/Request.d.ts CHANGED
@@ -10,5 +10,6 @@ export declare class Request {
10
10
  private getResolvedUrl;
11
11
  private init;
12
12
  send(body: BodyInit): Promise<Response>;
13
+ private isWithinKeepaliveQuota;
13
14
  }
14
15
  export {};
@@ -16,9 +16,8 @@ export declare const NETWORK_URL_LABEL_PROVIDERS_KEY = "NETWORK_URL_LABEL_PROVID
16
16
  export declare const RUM_INTERNAL_DATA_KEY = "rumInternalData";
17
17
  export declare const MASKED_TEXT = "***";
18
18
  export declare const MASK_CLASS_DEFAULT = "cx-mask";
19
- export declare const CX_ACTION_NAME_ATTRIBUTE = "data-cx-action-name";
19
+ export declare const CX_PREFIX = "cx";
20
20
  export declare const ARIA_LABEL_ATTRIBUTE = "aria-label";
21
- export declare const DATA_TEST_ATTRIBUTE = "data-test";
22
21
  export declare const MASK_INPUT_TYPES_DEFAULT: InputType[];
23
22
  export declare const FINGER_PRINT_KEY = "cx-fingerprint";
24
23
  export declare const OPTIONS_DEFAULTS: Partial<CoralogixBrowserSdkConfig>;
@@ -47,14 +46,23 @@ export declare const CoralogixAttributes: {
47
46
  TARGET_ELEMENT: string;
48
47
  TARGET_ELEMENT_TYPE: string;
49
48
  CX_ACTION_NAME: string;
49
+ CX_ID: string;
50
50
  ARIA_LABEL: string;
51
51
  TEST_ID: string;
52
52
  RESOLVED_NAME: string;
53
+ CLICK_X: string;
54
+ CLICK_Y: string;
55
+ ELEMENT_RELATIVE_X: string;
56
+ ELEMENT_RELATIVE_Y: string;
57
+ ELEMENT_WIDTH: string;
58
+ ELEMENT_HEIGHT: string;
59
+ ELEMENT_FINGERPRINT: string;
53
60
  TIMESTAMP: string;
54
61
  INTERNAL: string;
55
62
  PAGE_CONTEXT: string;
56
63
  IS_NAVIGATION_EVENT: string;
57
64
  SCREENSHOT_CONTEXT: string;
65
+ DOM_CONTEXT: string;
58
66
  };
59
67
  export declare const CoralogixDomainsApiUrlMap: {
60
68
  EU1: string;
@@ -0,0 +1,4 @@
1
+ export declare const CX_ACTION_NAME_ATTRIBUTE = "data-cx-action-name";
2
+ export declare const DATA_TEST_ATTRIBUTE = "data-test";
3
+ export declare const DATA_TESTID_ATTRIBUTE = "data-testid";
4
+ export declare const DATA_TEST_ID_ATTRIBUTE = "data-test-id";
package/src/helpers.d.ts CHANGED
@@ -2,9 +2,15 @@ import { SessionManager } from './session/sessionManager';
2
2
  import { SessionRecorder } from './session/sessionRecorder';
3
3
  import { CoralogixBrowserSdkConfig, UserAgentData } from './types';
4
4
  import { SnapshotManager } from './snapshot/snapshotManager';
5
+ import { WebTracerProvider } from '@opentelemetry/sdk-trace-web';
6
+ import type { ClickScreenshotManager } from './instrumentations/screenshot/click-screenshot-manager';
5
7
  export declare function getSnapshotManager(): SnapshotManager;
6
8
  export declare function getSessionManager(): SessionManager;
7
9
  export declare function getSessionRecorder(): SessionRecorder | undefined;
10
+ export declare function getClickScreenshotManager(): ClickScreenshotManager | undefined;
8
11
  export declare function getSdkConfig(): CoralogixBrowserSdkConfig;
9
12
  export declare function getUserAgentData(): UserAgentData;
10
13
  export declare function clearMemoryFrom(keys: string[]): void;
14
+ export declare function setTracerProvider(provider: WebTracerProvider): void;
15
+ export declare function getTracerProvider(): WebTracerProvider | undefined;
16
+ export declare function flush(): void;
@@ -1,6 +1,7 @@
1
1
  import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
2
2
  export declare class CoralogixDOMInstrumentation extends InstrumentationBase {
3
3
  constructor(config: InstrumentationConfig);
4
+ private createDOMSpan;
4
5
  private visibilityChangeHandler;
5
6
  private registerToDOMEvents;
6
7
  private unregisterFromDOMEvents;
@@ -0,0 +1,9 @@
1
+ export declare class ClickScreenshotManager {
2
+ private secondCaptureClick;
3
+ private clickCount;
4
+ static unregister(): void;
5
+ constructor();
6
+ reset: () => void;
7
+ onNavigation: () => void;
8
+ handleClick: () => void;
9
+ }
@@ -0,0 +1 @@
1
+ export declare const CLICK_SCREENSHOT_MANAGER_KEY = "rumClickScreenshotManager";
@@ -0,0 +1,2 @@
1
+ export declare const SHADOW_DOM_MARKER = "::shadow ";
2
+ export declare function getElementFingerprint(target: Element): string | undefined;
@@ -4,5 +4,6 @@ export declare class CoralogixNavigationProcessor implements SpanProcessor {
4
4
  forceFlush(): Promise<void>;
5
5
  onEnd(span: ReadableSpan): void;
6
6
  onStart(span: Span): void;
7
+ private handlePageNavigation;
7
8
  shutdown(): Promise<void>;
8
9
  }
@@ -9,6 +9,7 @@ export declare class CoralogixSpanMapProcessor implements SpanProcessor, Process
9
9
  forceFlush(): Promise<void>;
10
10
  private _mapToCxSpan;
11
11
  private resolveContextFromSpan;
12
+ private addOtelInstrumentationData;
12
13
  private _getEventTypeContext;
13
14
  private resolveLabels;
14
15
  private getLabelsByLabelProviders;
@@ -16,3 +16,4 @@ export declare const SESSION_EXPIRATION_TIME: number;
16
16
  export declare const SESSION_MANAGER_KEY = "rumSessionManager";
17
17
  export declare const SESSION_RECORDER_KEY = "rumSessionRecorder";
18
18
  export declare const SESSION_RECORDER_SEGMENTS_MAP = "rumSessionRecorderSegmentsMap";
19
+ export declare const VIEW_NUMBER_KEY = "rum_view_number";
@@ -11,6 +11,7 @@ export declare class SessionManager extends SessionIdle {
11
11
  private _currentPageFragment;
12
12
  private _currentPageTimestamp;
13
13
  private _fingerPrint;
14
+ private _viewNumber;
14
15
  private debugMode;
15
16
  constructor(recordConfig?: SessionRecordingConfig);
16
17
  get currentPageTimestamp(): number;
@@ -23,9 +24,14 @@ export declare class SessionManager extends SessionIdle {
23
24
  get cachedLogsSent(): boolean;
24
25
  get sessionHasError(): boolean;
25
26
  get fingerPrint(): string | undefined;
27
+ get viewNumber(): number;
26
28
  set sessionHasError(value: boolean);
27
29
  set cachedLogsSent(val: boolean);
28
30
  updateCurrentPage(fragment: string): void;
31
+ incrementViewNumber(): void;
32
+ private persistViewNumber;
33
+ private loadViewNumber;
34
+ private resetViewNumber;
29
35
  getSessionKey(): string;
30
36
  getActiveSession(): Session;
31
37
  start(): void;
@@ -26,7 +26,8 @@ export declare class SessionRecorder {
26
26
  constructor(sessionManager: SessionManager, recordConfig: SessionRecordingConfig);
27
27
  getSessionHasScreenshot(): boolean;
28
28
  getSessionHasRecording(): boolean;
29
- updateSegmentIndexCounter(segmentIndexCounter: Record<string, number>): void;
29
+ getSegmentIndexCounter(): Record<string, number>;
30
+ private restoreSegmentIndexCounter;
30
31
  getIsAutoStartRecording(): boolean;
31
32
  isConsoleRecordingActive(): boolean;
32
33
  set recordingStopDueToTimeout(value: boolean);
package/src/types.d.ts CHANGED
@@ -75,6 +75,9 @@ export interface ScreenshotContext {
75
75
  id: string;
76
76
  description?: string;
77
77
  }
78
+ export interface DomContext {
79
+ visibility_state: DocumentVisibilityState;
80
+ }
78
81
  export interface ApplicationContextConfig {
79
82
  application: string;
80
83
  version: string;
@@ -221,12 +224,29 @@ export interface InteractionContext {
221
224
  target_element_inner_text: string;
222
225
  target_element_type: string;
223
226
  event_name: string;
227
+ cx_id: string;
224
228
  element_id: string;
225
229
  element_classes: string;
226
230
  cx_action_name?: string;
227
231
  element_aria_label?: string;
228
232
  element_test_id?: string;
229
233
  resolved_name: string;
234
+ click_x?: number;
235
+ click_y?: number;
236
+ element_relative_x?: number;
237
+ element_relative_y?: number;
238
+ element_width?: number;
239
+ element_height?: number;
240
+ element_fingerprint?: string;
241
+ }
242
+ export interface LayoutContext {
243
+ viewport_width: number;
244
+ viewport_height: number;
245
+ view_width: number;
246
+ view_height: number;
247
+ device_pixel_ratio: number;
248
+ scroll_x: number;
249
+ scroll_y: number;
230
250
  }
231
251
  export interface LongTaskContext extends Omit<PerformanceEntry, 'toJSON'> {
232
252
  id: string;
@@ -258,6 +278,7 @@ export interface EventTypeContext {
258
278
  custom_measurement_context?: CustomMeasurementContext;
259
279
  screenshot_context?: ScreenshotContext;
260
280
  memory_usage_context?: MemoryUsageContext;
281
+ dom_context?: DomContext;
261
282
  }
262
283
  export interface UserMetadata {
263
284
  user_id: string;
@@ -335,6 +356,8 @@ export interface CxRumEvent extends EventTypeContext {
335
356
  screenshot_context?: ScreenshotContext;
336
357
  screenshotId?: string;
337
358
  fingerPrint: string;
359
+ view_number: number;
360
+ layout_context: LayoutContext;
338
361
  }
339
362
  export interface CxSpan {
340
363
  version_metadata: VersionMetaData;
package/src/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "3.10.0";
1
+ export declare const SDK_VERSION = "3.15.1";