@coralogix/browser 3.2.0 → 3.4.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,22 @@
1
+ ## 3.4.1 (2026-03-25)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - Improve MFE stacktrace metadata extraction stability
6
+ - Fix potential infinite loop in navigation tracking
7
+
8
+ ## 3.4.0 (2026-02-26)
9
+
10
+ ### 🚀 Features
11
+
12
+ - add numeric ID grouping to default URL blueprinter
13
+
14
+ ## 3.3.0 (2026-02-24)
15
+
16
+ ### 🚀 Features
17
+
18
+ - Enrich spans with RUM context (cx_rum) to improve RUM–Tracing correlation.
19
+
1
20
  ## 3.2.0 (2026-02-05)
2
21
 
3
22
  - Create new zoneless CDN for Angular consumers
package/index.esm2.js CHANGED
@@ -369,6 +369,12 @@ var CACHED_METADATA_KEY = '__cx_metadata__';
369
369
  var ERROR_INSTRUMENTATION_VERSION = '1';
370
370
  var STACK_LIMIT = 4096;
371
371
  var MESSAGE_LIMIT = 1024;
372
+ var MFE_PATH_PATTERN = /https?:\/\/.*\//;
373
+ function extractMfePath(fileName) {
374
+ var _a;
375
+ var _b = __read$1((_a = fileName.match(MFE_PATH_PATTERN)) !== null && _a !== void 0 ? _a : [], 1), mfePath = _b[0];
376
+ return mfePath;
377
+ }
372
378
  var ERROR_INSTRUMENTATION_NAME = 'errors';
373
379
  var ErrorAttributes = {
374
380
  TYPE: 'error_type',
@@ -455,32 +461,32 @@ function addLabelForMFE(span, lastFrame) {
455
461
  }
456
462
  function extractMetadataFromMfeStacktrace() {
457
463
  return __awaiter(this, arguments, void 0, function (fileName) {
458
- var metadata, cachedMetadata, MFE_METADATA_KEY, _a, mfePath, response, _b, e_1;
464
+ var metadata, cachedMetadata, MFE_METADATA_KEY, mfePath, response, _a, e_1;
459
465
  if (fileName === void 0) { fileName = ''; }
460
- return __generator(this, function (_c) {
461
- switch (_c.label) {
466
+ return __generator(this, function (_b) {
467
+ switch (_b.label) {
462
468
  case 0:
463
469
  cachedMetadata = CxGlobal[CACHED_METADATA_KEY];
464
470
  MFE_METADATA_KEY = 'cx-metadata.json';
465
- _a = __read$1(fileName.match(/https?:\/\/.*\//), 1), mfePath = _a[0];
471
+ mfePath = extractMfePath(fileName);
466
472
  if (!mfePath) return [3, 7];
467
473
  response = void 0;
468
474
  if (!!(cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.has(mfePath))) return [3, 6];
469
- _c.label = 1;
475
+ _b.label = 1;
470
476
  case 1:
471
- _c.trys.push([1, 4, , 5]);
477
+ _b.trys.push([1, 4, , 5]);
472
478
  return [4, fetch("".concat(mfePath).concat(MFE_METADATA_KEY), {
473
479
  cache: 'no-cache',
474
480
  })];
475
481
  case 2:
476
- response = _c.sent();
477
- _b = [{}];
482
+ response = _b.sent();
483
+ _a = [{}];
478
484
  return [4, response.json()];
479
485
  case 3:
480
- metadata = __assign.apply(void 0, [__assign.apply(void 0, _b.concat([(_c.sent())])), { mfePath: mfePath }]);
486
+ metadata = __assign.apply(void 0, [__assign.apply(void 0, _a.concat([(_b.sent())])), { mfePath: mfePath }]);
481
487
  return [3, 5];
482
488
  case 4:
483
- e_1 = _c.sent();
489
+ e_1 = _b.sent();
484
490
  if (getSdkConfig().debug) {
485
491
  console.warn('Coralogix Browser SDK - Error fetching metadata', e_1);
486
492
  }
@@ -490,7 +496,7 @@ function extractMetadataFromMfeStacktrace() {
490
496
  return [3, 7];
491
497
  case 6:
492
498
  metadata = cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.get(mfePath);
493
- _c.label = 7;
499
+ _b.label = 7;
494
500
  case 7: return [2, metadata];
495
501
  }
496
502
  });
@@ -2490,9 +2496,25 @@ var idPatterns = [
2490
2496
  replacement: ID_MASK_KEY,
2491
2497
  },
2492
2498
  ];
2499
+ var PATH_ID_PLACEHOLDER = '/{id}';
2500
+ var NUMERIC_PATH_SEGMENT_REGEX = /\/(?![vV]\d{1,2}\/)([^/\d?]*\d+[^/?]*)/g;
2501
+ function replaceNumericPathSegments(url) {
2502
+ var replacePath = function (s) { return s.replace(NUMERIC_PATH_SEGMENT_REGEX, PATH_ID_PLACEHOLDER); };
2503
+ try {
2504
+ var origin_1 = new URL(url).origin;
2505
+ if (origin_1 === 'null' || !url.startsWith(origin_1))
2506
+ return url;
2507
+ return origin_1 + replacePath(url.slice(origin_1.length));
2508
+ }
2509
+ catch (_a) {
2510
+ return replacePath(url);
2511
+ }
2512
+ }
2493
2513
  var defaultUrlBlueprinters = {
2494
2514
  pageUrlBlueprinters: [
2495
- function (url) { return replacePatternsInUrl({ patterns: idPatterns, url: url }); },
2515
+ function (url) {
2516
+ return replaceNumericPathSegments(replacePatternsInUrl({ patterns: idPatterns, url: url }));
2517
+ },
2496
2518
  ],
2497
2519
  };
2498
2520
  var OPTIONS_DEFAULTS = {
@@ -2794,26 +2816,6 @@ function rateForTBTMetricValue(value) {
2794
2816
  return 'good';
2795
2817
  }
2796
2818
  }
2797
- function flattenAttributes(attributes) {
2798
- var e_4, _a;
2799
- var customLabels = JSON.parse(attributes[CoralogixAttributes.CUSTOM_LABELS]);
2800
- var flatAttributes = omit(attributes, CoralogixAttributes.CUSTOM_LABELS);
2801
- try {
2802
- for (var _b = __values$1(Object.entries(customLabels)), _c = _b.next(); !_c.done; _c = _b.next()) {
2803
- var _d = __read$1(_c.value, 2), key = _d[0], value = _d[1];
2804
- flatAttributes[key] =
2805
- typeof value !== 'string' ? JSON.stringify(value) : value;
2806
- }
2807
- }
2808
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
2809
- finally {
2810
- try {
2811
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2812
- }
2813
- finally { if (e_4) throw e_4.error; }
2814
- }
2815
- return flatAttributes;
2816
- }
2817
2819
  var getCircularReplacer = function () {
2818
2820
  var seen = new WeakSet();
2819
2821
  return function (key, value) {
@@ -4152,7 +4154,7 @@ function resolveUrlBlueprinters(urlBlueprinters) {
4152
4154
  return resolvedUrlBlueprinters;
4153
4155
  }
4154
4156
 
4155
- var SDK_VERSION = '3.2.0';
4157
+ var SDK_VERSION = '3.4.1';
4156
4158
 
4157
4159
  function shouldDropEvent(cxRumEvent, options) {
4158
4160
  if (isDocumentErrorWithoutMessage(cxRumEvent)) {
@@ -4218,6 +4220,54 @@ function editableToCxRumEvent(editable, cxRumEvent) {
4218
4220
  return __assign(__assign(__assign({}, cxRumEvent), editable), { session_context: __assign(__assign({}, cxRumEvent.session_context), editable.session_context) });
4219
4221
  }
4220
4222
 
4223
+ function buildCxRumSpanAttributes(attrs) {
4224
+ var e_1, _a;
4225
+ var result = {};
4226
+ try {
4227
+ for (var _b = __values$1(Object.entries(attrs)), _c = _b.next(); !_c.done; _c = _b.next()) {
4228
+ var _d = __read$1(_c.value, 2), key = _d[0], value = _d[1];
4229
+ if (value !== undefined && value !== null) {
4230
+ result[key] = value;
4231
+ }
4232
+ }
4233
+ }
4234
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
4235
+ finally {
4236
+ try {
4237
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4238
+ }
4239
+ finally { if (e_1) throw e_1.error; }
4240
+ }
4241
+ return result;
4242
+ }
4243
+ function flattenToAttributes(obj, prefix) {
4244
+ var e_2, _a;
4245
+ var result = {};
4246
+ if (!obj)
4247
+ return result;
4248
+ try {
4249
+ for (var _b = __values$1(Object.entries(obj)), _c = _b.next(); !_c.done; _c = _b.next()) {
4250
+ var _d = __read$1(_c.value, 2), key = _d[0], value = _d[1];
4251
+ if (value != null) {
4252
+ result["".concat(prefix).concat(key)] = typeof value === 'string' ? value : JSON.stringify(value);
4253
+ }
4254
+ }
4255
+ }
4256
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
4257
+ finally {
4258
+ try {
4259
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4260
+ }
4261
+ finally { if (e_2) throw e_2.error; }
4262
+ }
4263
+ return result;
4264
+ }
4265
+ function buildRumContextAttributes(cxRumEvent, resolvedLabels) {
4266
+ var session_context = cxRumEvent.session_context, page_context = cxRumEvent.page_context, event_context = cxRumEvent.event_context, error_context = cxRumEvent.error_context, network_request_context = cxRumEvent.network_request_context;
4267
+ var prefixedLabels = flattenToAttributes(resolvedLabels, 'cx_rum.labels.');
4268
+ return buildCxRumSpanAttributes(__assign(__assign({ 'cx_rum.browser_sdk.version': cxRumEvent.browser_sdk.version, 'cx_rum.platform': cxRumEvent.platform, 'cx_rum.environment': cxRumEvent.environment, 'cx_rum.version_metadata.app_name': cxRumEvent.version_metadata.app_name, 'cx_rum.version_metadata.app_version': cxRumEvent.version_metadata.app_version }, prefixedLabels), { 'cx_rum.session_context.os': session_context === null || session_context === void 0 ? void 0 : session_context.os, 'cx_rum.session_context.osVersion': session_context === null || session_context === void 0 ? void 0 : session_context.osVersion, 'cx_rum.session_context.browser': session_context === null || session_context === void 0 ? void 0 : session_context.browser, 'cx_rum.session_context.browserVersion': session_context === null || session_context === void 0 ? void 0 : session_context.browserVersion, 'cx_rum.session_context.device': session_context === null || session_context === void 0 ? void 0 : session_context.device, 'cx_rum.session_context.user_agent': session_context === null || session_context === void 0 ? void 0 : session_context.user_agent, 'cx_rum.session_context.user_email': session_context === null || session_context === void 0 ? void 0 : session_context.user_email, 'cx_rum.session_context.user_id': session_context === null || session_context === void 0 ? void 0 : session_context.user_id, 'cx_rum.session_context.user_name': session_context === null || session_context === void 0 ? void 0 : session_context.user_name, 'cx_rum.page_context.page_fragments': page_context === null || page_context === void 0 ? void 0 : page_context.page_fragments, 'cx_rum.page_context.page_url_blueprint': page_context === null || page_context === void 0 ? void 0 : page_context.page_url_blueprint, 'cx_rum.event_context.type': event_context === null || event_context === void 0 ? void 0 : event_context.type, 'cx_rum.event_context.severity': event_context === null || event_context === void 0 ? void 0 : event_context.severity, 'cx_rum.error_context.error_type': error_context === null || error_context === void 0 ? void 0 : error_context.error_type, 'cx_rum.error_context.error_message': error_context === null || error_context === void 0 ? void 0 : error_context.error_message, 'cx_rum.network_request_context.fragments': network_request_context === null || network_request_context === void 0 ? void 0 : network_request_context.fragments, 'cx_rum.network_request_context.url': network_request_context === null || network_request_context === void 0 ? void 0 : network_request_context.url, 'cx_rum.network_request_context.status_code': network_request_context === null || network_request_context === void 0 ? void 0 : network_request_context.status_code, 'cx_rum.network_request_context.method': network_request_context === null || network_request_context === void 0 ? void 0 : network_request_context.method }));
4269
+ }
4270
+
4221
4271
  var CoralogixSpanMapProcessor = (function () {
4222
4272
  function CoralogixSpanMapProcessor() {
4223
4273
  this.sdkConfig = getSdkConfig();
@@ -4304,6 +4354,7 @@ var CoralogixSpanMapProcessor = (function () {
4304
4354
  }, labels: labels, environment: attributes[CoralogixAttributes.ENVIRONMENT] || '' }),
4305
4355
  },
4306
4356
  };
4357
+ var resolvedLabels = this.resolveLabels(cxSpan.text.cx_rum);
4307
4358
  if (shouldAddOtelAttr(span)) {
4308
4359
  cxSpan.text.cx_rum.spanId = spanId;
4309
4360
  cxSpan.text.cx_rum.traceId = traceId;
@@ -4313,8 +4364,6 @@ var CoralogixSpanMapProcessor = (function () {
4313
4364
  spanId: spanId,
4314
4365
  traceId: traceId,
4315
4366
  parentSpanId: parentSpanId,
4316
- name: name,
4317
- attributes: __assign(__assign(__assign({}, flattenAttributes(attributes)), this.resolveLabels(cxSpan.text.cx_rum)), { sessionId: sessionId }),
4318
4367
  startTime: startTime,
4319
4368
  endTime: endTime,
4320
4369
  status: severity === CoralogixLogSeverity.Error
@@ -4322,6 +4371,8 @@ var CoralogixSpanMapProcessor = (function () {
4322
4371
  kind: kind,
4323
4372
  duration: duration,
4324
4373
  sessionId: sessionId,
4374
+ name: name,
4375
+ attributes: buildRumContextAttributes(cxSpan.text.cx_rum, resolvedLabels),
4325
4376
  },
4326
4377
  otelResource: {
4327
4378
  attributes: resourceAttributes,
@@ -4329,7 +4380,7 @@ var CoralogixSpanMapProcessor = (function () {
4329
4380
  };
4330
4381
  }
4331
4382
  this.resolveContextFromSpan(cxSpan, span, eventType);
4332
- cxSpan.text.cx_rum.labels = this.resolveLabels(cxSpan.text.cx_rum);
4383
+ cxSpan.text.cx_rum.labels = resolvedLabels;
4333
4384
  return cxSpan;
4334
4385
  };
4335
4386
  CoralogixSpanMapProcessor.prototype.resolveContextFromSpan = function (cxSpan, span, eventType) {
@@ -4454,14 +4505,17 @@ var CoralogixSpanMapProcessor = (function () {
4454
4505
  return {};
4455
4506
  };
4456
4507
  CoralogixSpanMapProcessor.prototype.resolveLabels = function (cxRumEvent) {
4457
- var _a, _b;
4508
+ var _a, _b, _c;
4458
4509
  var allLabels = cxRumEvent.labels;
4459
4510
  var labelProviders = (_a = this.sdkConfig) === null || _a === void 0 ? void 0 : _a.labelProviders;
4460
4511
  if (labelProviders === null || labelProviders === void 0 ? void 0 : labelProviders.length) {
4461
4512
  var pageUrlLabelProviders = getInternalRumData(PAGE_URL_LABEL_PROVIDERS_KEY);
4462
4513
  var networkUrlLabelProviders = getInternalRumData(NETWORK_URL_LABEL_PROVIDERS_KEY);
4463
4514
  var networkRequestFragment = (_b = cxRumEvent.network_request_context) === null || _b === void 0 ? void 0 : _b.fragments;
4464
- var labelsFromProviders = __assign(__assign({}, this.getLabelsByLabelProviders(pageUrlLabelProviders, cxRumEvent, cxRumEvent.page_context.page_fragments)), (networkRequestFragment
4515
+ var pageFragment = (_c = cxRumEvent.page_context) === null || _c === void 0 ? void 0 : _c.page_fragments;
4516
+ var labelsFromProviders = __assign(__assign({}, (pageFragment
4517
+ ? this.getLabelsByLabelProviders(pageUrlLabelProviders, cxRumEvent, pageFragment)
4518
+ : {})), (networkRequestFragment
4465
4519
  ? this.getLabelsByLabelProviders(networkUrlLabelProviders, cxRumEvent, networkRequestFragment)
4466
4520
  : {}));
4467
4521
  allLabels = __assign(__assign({}, allLabels), labelsFromProviders);
@@ -4625,22 +4679,32 @@ var SnapshotManager = (function () {
4625
4679
 
4626
4680
  var CoralogixNavigationProcessor = (function () {
4627
4681
  function CoralogixNavigationProcessor() {
4682
+ this.isResolving = false;
4628
4683
  }
4629
4684
  CoralogixNavigationProcessor.prototype.forceFlush = function () {
4630
4685
  return Promise.resolve();
4631
4686
  };
4632
4687
  CoralogixNavigationProcessor.prototype.onEnd = function (span) { };
4633
4688
  CoralogixNavigationProcessor.prototype.onStart = function (span) {
4634
- var pageContext = resolvePageContext(location.href);
4635
- if (pageContext) {
4636
- span[CoralogixAttributes.PAGE_CONTEXT] = pageContext;
4637
- var currentPageFragment = getSessionManager().currentPageFragment;
4638
- var page_fragments = pageContext.page_fragments;
4639
- if (currentPageFragment !== page_fragments) {
4640
- getSessionManager().updateCurrentPage(page_fragments);
4641
- span[CoralogixAttributes.IS_NAVIGATION_EVENT] = true;
4689
+ if (this.isResolving) {
4690
+ return;
4691
+ }
4692
+ this.isResolving = true;
4693
+ try {
4694
+ var pageContext = resolvePageContext(location.href);
4695
+ if (pageContext) {
4696
+ span[CoralogixAttributes.PAGE_CONTEXT] = pageContext;
4697
+ var currentPageFragment = getSessionManager().currentPageFragment;
4698
+ var page_fragments = pageContext.page_fragments;
4699
+ if (currentPageFragment !== page_fragments) {
4700
+ getSessionManager().updateCurrentPage(page_fragments);
4701
+ span[CoralogixAttributes.IS_NAVIGATION_EVENT] = true;
4702
+ }
4642
4703
  }
4643
4704
  }
4705
+ finally {
4706
+ this.isResolving = false;
4707
+ }
4644
4708
  };
4645
4709
  CoralogixNavigationProcessor.prototype.shutdown = function () {
4646
4710
  return Promise.resolve();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralogix/browser",
3
- "version": "3.2.0",
3
+ "version": "3.4.1",
4
4
  "description": "Official Coralogix SDK for browsers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coralogix",
@@ -1,5 +1,6 @@
1
1
  import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
2
2
  import { CoralogixRumLabels } from '../types';
3
+ export declare function extractMfePath(fileName: string): string | undefined;
3
4
  export declare const ERROR_INSTRUMENTATION_NAME = "errors";
4
5
  export declare const ErrorAttributes: {
5
6
  TYPE: string;
@@ -0,0 +1,30 @@
1
+ import type { Attributes } from '@opentelemetry/api';
2
+ import type { CoralogixRumLabels, CxRumEvent } from '../types';
3
+ export interface CxRumSpanAttributes extends Attributes {
4
+ 'cx_rum.browser_sdk.version'?: string;
5
+ 'cx_rum.platform'?: string;
6
+ 'cx_rum.environment'?: string;
7
+ 'cx_rum.version_metadata.app_name'?: string;
8
+ 'cx_rum.version_metadata.app_version'?: string;
9
+ 'cx_rum.session_context.os'?: string;
10
+ 'cx_rum.session_context.osVersion'?: string;
11
+ 'cx_rum.session_context.browser'?: string;
12
+ 'cx_rum.session_context.browserVersion'?: string;
13
+ 'cx_rum.session_context.device'?: string;
14
+ 'cx_rum.session_context.user_agent'?: string;
15
+ 'cx_rum.session_context.user_email'?: string;
16
+ 'cx_rum.session_context.user_id'?: string;
17
+ 'cx_rum.session_context.user_name'?: string;
18
+ 'cx_rum.page_context.page_fragments'?: string;
19
+ 'cx_rum.page_context.page_url_blueprint'?: string;
20
+ 'cx_rum.event_context.type'?: string;
21
+ 'cx_rum.event_context.severity'?: number;
22
+ 'cx_rum.error_context.error_type'?: string;
23
+ 'cx_rum.error_context.error_message'?: string;
24
+ 'cx_rum.network_request_context.fragments'?: string;
25
+ 'cx_rum.network_request_context.url'?: string;
26
+ 'cx_rum.network_request_context.status_code'?: number;
27
+ 'cx_rum.network_request_context.method'?: string;
28
+ }
29
+ export declare function buildCxRumSpanAttributes(attrs: CxRumSpanAttributes): Attributes;
30
+ export declare function buildRumContextAttributes(cxRumEvent: CxRumEvent, resolvedLabels: CoralogixRumLabels): Attributes;
@@ -1,5 +1,6 @@
1
1
  import { ReadableSpan, Span, SpanProcessor } from '@opentelemetry/sdk-trace-base';
2
2
  export declare class CoralogixNavigationProcessor implements SpanProcessor {
3
+ private isResolving;
3
4
  forceFlush(): Promise<void>;
4
5
  onEnd(span: ReadableSpan): void;
5
6
  onStart(span: Span): void;
package/src/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "3.2.0";
1
+ export declare const SDK_VERSION = "3.4.1";