@coralogix/browser 3.23.2 → 3.23.3

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,9 @@
1
+ ## 3.23.3 (2026-08-30)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - Stop the INP (Interaction to Next Paint) reporter throwing an uncaught `TypeError` after a back/forward navigation followed by a tab switch
6
+
1
7
  ## 3.23.2 (2026-08-20)
2
8
 
3
9
  ### 🩹 Fixes
package/README.md CHANGED
@@ -255,6 +255,23 @@ CoralogixRum.log(CoralogixLogSeverity.Info, 'this is a custom log message with i
255
255
  });
256
256
  ```
257
257
 
258
+ #### Stringifying custom log data
259
+
260
+ By default the `data` you pass to a custom log is sent as a nested structure. Set
261
+ `stringifyCustomLogData` at initialization to send it as a string instead, which is
262
+ useful when `data` holds nested objects or arrays. Circular references are handled
263
+ rather than throwing.
264
+
265
+ ```javascript
266
+ CoralogixRum.init({
267
+ // ...
268
+ stringifyCustomLogData: true,
269
+ });
270
+ ```
271
+
272
+ The SDK reads this option once, when it initializes, so it applies to every custom
273
+ log from that point on and cannot be changed per call.
274
+
258
275
  ### Instrumentation's
259
276
 
260
277
  Turn on/off specific instrumentation, default to all trues.
@@ -276,6 +293,11 @@ CoralogixRum.init({
276
293
  });
277
294
  ```
278
295
 
296
+ > [!NOTE]
297
+ > The `fetch` and `xhr` instrumentations also add the trace context headers to outgoing requests.
298
+ > Turning both off stops trace context propagation as well, even when `traceParentInHeader` is
299
+ > enabled.
300
+
279
301
  ##### Web Vitals: TBT metric
280
302
 
281
303
  By default, the **TBT** (Total Blocking Time) metric is disabled.
@@ -693,6 +715,11 @@ CoralogixRum.init({
693
715
  });
694
716
  ```
695
717
 
718
+ > [!NOTE]
719
+ > Trace headers are added by the `fetch` and `xhr` instrumentations, so this feature depends on them.
720
+ > If you set both `instrumentations.fetch` and `instrumentations.xhr` to `false`, no trace headers are
721
+ > sent even with `enabled: true`.
722
+
696
723
  #### propagateTraceHeaderCorsUrls
697
724
 
698
725
  When the backend domain is different from the app domain, specifying backend domains is necessary. <br>
@@ -983,6 +1010,13 @@ CoralogixRum.startTimeMeasure('login', {
983
1010
  CoralogixRum.endTimeMeasure('login');
984
1011
  ```
985
1012
 
1013
+ A few behaviours worth knowing:
1014
+
1015
+ - Starting a key while a measurement for it is still in progress does nothing, and neither does a blank key: `startTimeMeasure` returns and the running timer is left alone.
1016
+ - `endTimeMeasure` takes only the key, so there is no way to pass labels at the end. The object handed to `startTimeMeasure` is held by reference, and at the end it is merged over the SDK's global labels as they stand then - so a later `CoralogixRum.setLabels()` does affect the result.
1017
+ - Ending a measurement releases its key, so the same key can be measured again afterwards.
1018
+ - Open measurements are dropped the next time you start or end one while the session is idle. The check runs on those calls rather than on a timer, and activity clears the idle flag, so a measurement spanning a short idle gap may still report.
1019
+
986
1020
  ### Microfrontend support
987
1021
 
988
1022
  This feature allows you to track multiple applications on the same page.<br>
@@ -1039,15 +1073,57 @@ const customTracer = CoralogixRum.getCustomTracer({
1039
1073
  // ... your code
1040
1074
  ```
1041
1075
 
1076
+ #### When getCustomTracer returns nothing
1077
+
1078
+ `getCustomTracer` returns `undefined` rather than throwing, so a missing prerequisite
1079
+ shows up as a `TypeError` on the next line instead. It returns nothing when:
1080
+
1081
+ - the SDK has not been initialized yet
1082
+ - `traceParentInHeader` is not enabled - custom spans need it, and only a debug-level
1083
+ message says so
1084
+ - a custom tracer already exists, which logs `Custom tracer already exists`
1085
+
1086
+ `startGlobalSpan` behaves the same way: with a global span already open it warns
1087
+ `Global span already exists` and returns `undefined`, rather than replacing it.
1088
+
1089
+ A few more things worth knowing:
1090
+
1091
+ - Every span must be ended explicitly. `endSpan` ends the span and releases it, so a
1092
+ new global span can be started afterwards.
1093
+ - Labels are applied to the span they are passed with. A child span created by
1094
+ `startCustomSpan` does not inherit the global span's labels.
1095
+ - Open global spans are ended for you when the session resets, which happens after an
1096
+ hour of session time or 15 minutes of inactivity.
1097
+
1042
1098
  ### Traces Exporter
1043
1099
 
1044
1100
  The `tracesExporter` callback gives you full control over how collected trace events are handled.
1045
1101
  It receives a `TraceExporterData` object containing all trace data that the SDK has collected.
1046
1102
 
1103
+ Setting it redirects your traces rather than copying them. The span data is removed from
1104
+ what the SDK sends to Coralogix and delivered to your callback instead, so Coralogix stops
1105
+ receiving traces until you forward them yourself from inside the callback.
1106
+
1107
+ This happens per batch, and only for batches that carry OpenTelemetry span data. When
1108
+ one does, the strip applies to every log in it, not only to custom spans: views, errors
1109
+ and network events still reach Coralogix as RUM events, but without their
1110
+ `instrumentation_data`, the field holding request and response span detail. A batch with
1111
+ no span data at all is sent unchanged and your callback is not called for it.
1112
+
1113
+ Treat the payload as a subset rather than a mirror. A span missing its trace id, span id,
1114
+ name or timestamps is dropped from the conversion, as is one whose timestamps fall
1115
+ outside the accepted window - more than an hour ahead or a day behind. Those spans can
1116
+ still reach Coralogix inside the RUM payload without a matching entry in what your
1117
+ callback receives, so `resource_spans` can be shorter than you expect, or empty.
1118
+
1119
+ > [!WARNING]
1120
+ > The callback runs inline on the path that sends the RUM payload, and it is not wrapped.
1121
+ > An exception escaping your callback also stops that batch reaching Coralogix, so keep
1122
+ > your own work inside a `try`/`catch`.
1123
+
1047
1124
  ```ts
1048
1125
  CoralogixRum.init({
1049
1126
  tracesExporter: (data: TraceExporterData) => {
1050
- // Example: forward traces to your own backend endpoint
1051
1127
  fetch('https://api.mycompany.com/rum-traces', {
1052
1128
  method: 'POST',
1053
1129
  headers: {
@@ -1138,8 +1214,14 @@ CoralogixRum.init({
1138
1214
  const worker = new Worker('my-worker.js');
1139
1215
  ```
1140
1216
 
1217
+ The SDK also attaches a `CoralogixRum` handle to the worker object it returns, as a
1218
+ convenience for logging next to the code that created the worker. It is an alias to the
1219
+ same SDK instance, not a per-worker one, so it adds no worker attribution of its own -
1220
+ `worker.CoralogixRum.log(...)` and `CoralogixRum.log(...)` do the same thing. Pass a
1221
+ label yourself if you need to tell workers apart.
1222
+
1141
1223
  ```javascript
1142
- // Worker code
1224
+ // App code, on the main thread
1143
1225
 
1144
1226
  // Log a basic info log
1145
1227
  worker.CoralogixRum.log(CoralogixLogSeverity.Info, 'Test log from worker');
@@ -1151,12 +1233,17 @@ try {
1151
1233
  worker.CoralogixRum.captureError(error, { worker: 'analytics-worker' }, { label1: 'value1' });
1152
1234
  }
1153
1235
 
1154
- // Log messages received in the worker
1155
- self.onmessage = (message) => {
1156
- worker.CoralogixRum.log(CoralogixLogSeverity.Info, message);
1236
+ // Log messages the worker sends back
1237
+ worker.onmessage = (message) => {
1238
+ worker.CoralogixRum.log(CoralogixLogSeverity.Info, 'worker message', { data: message.data });
1157
1239
  };
1158
1240
  ```
1159
1241
 
1242
+ > [!NOTE]
1243
+ > `worker.CoralogixRum` lives on the worker object in the page, not inside the worker
1244
+ > script. Worker scope has no Coralogix global, so these calls only work on the main
1245
+ > thread.
1246
+
1160
1247
  ## Angular Zone.js Configuration
1161
1248
 
1162
1249
  By default, the SDK runs its internal timers outside Angular's Zone.js to prevent unnecessary change detection cycles. This improves performance by avoiding redundant UI updates triggered by the SDK's background operations.
@@ -1194,7 +1281,8 @@ If you are targeting legacy environments, make sure to use the ES5-compatible ve
1194
1281
 
1195
1282
  https://cdn.rum-ingress-coralogix.com/coralogix/browser/[version]/coralogix-browser-sdk.es5.js
1196
1283
 
1197
- > _**Note: CDN latest has no longer maintained, please use an explicit version instead.**_
1284
+ > [!NOTE]
1285
+ > The CDN `latest` tag is no longer maintained. Use an explicit version instead.
1198
1286
 
1199
1287
  ### Add the CDN script to your application
1200
1288
 
package/index.esm.js CHANGED
@@ -7,6 +7,7 @@ import 'error-stack-parser';
7
7
  import '@opentelemetry/instrumentation-fetch';
8
8
  import '@opentelemetry/instrumentation-xml-http-request';
9
9
  import 'web-vitals/attribution';
10
+ import 'web-vitals';
10
11
  import '@opentelemetry/api';
11
12
  import '@opentelemetry/propagator-b3';
12
13
  import '@opentelemetry/propagator-aws-xray';
package/index.esm2.js CHANGED
@@ -5,7 +5,8 @@ import { InstrumentationBase, registerInstrumentations } from '@opentelemetry/in
5
5
  import ErrorStackParser from 'error-stack-parser';
6
6
  import { FetchInstrumentation } from '@opentelemetry/instrumentation-fetch';
7
7
  import { XMLHttpRequestInstrumentation } from '@opentelemetry/instrumentation-xml-http-request';
8
- import { onFID, onCLS, onLCP, onFCP, onINP, onTTFB } from 'web-vitals/attribution';
8
+ import { onFID, onCLS, onLCP, onFCP, onTTFB } from 'web-vitals/attribution';
9
+ import { onINP } from 'web-vitals';
9
10
  import { createContextKey, baggageEntryMetadataFromString, propagation, diag, trace, isSpanContextValid, TraceFlags, context } from '@opentelemetry/api';
10
11
  import { B3Propagator, B3InjectEncoding } from '@opentelemetry/propagator-b3';
11
12
  import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray';
@@ -1442,7 +1443,7 @@ var attributionSanitizers = {
1442
1443
  return __assign(__assign({}, rest), { attribution: sanitizedAttribution });
1443
1444
  },
1444
1445
  INP: function (metric) {
1445
- metric.entries; metric.attribution; var rest = __rest(metric, ["entries", "attribution"]);
1446
+ metric.entries; var rest = __rest(metric, ["entries"]);
1446
1447
  return rest;
1447
1448
  },
1448
1449
  };
@@ -1831,6 +1832,9 @@ function isPerformanceObserverSupported() {
1831
1832
  }
1832
1833
 
1833
1834
  function sanitizeAttribution(metric) {
1835
+ if (metric.name === 'INP') {
1836
+ return attributionSanitizers.INP(metric);
1837
+ }
1834
1838
  if (!('attribution' in metric)) {
1835
1839
  metric.entries; var rest = __rest(metric, ["entries"]);
1836
1840
  return rest;
@@ -1846,8 +1850,6 @@ function sanitizeAttribution(metric) {
1846
1850
  return attributionSanitizers.FID(metric);
1847
1851
  case 'TTFB':
1848
1852
  return attributionSanitizers.TTFB(metric);
1849
- case 'INP':
1850
- return attributionSanitizers.INP(metric);
1851
1853
  }
1852
1854
  }
1853
1855
  var CoralogixWebVitalsInstrumentation = (function (_super) {
@@ -1856,6 +1858,13 @@ var CoralogixWebVitalsInstrumentation = (function (_super) {
1856
1858
  var _this = _super.call(this, WEB_VITALS_INSTRUMENTATION_NAME, WEB_VITALS_INSTRUMENTATION_VERSION, config) || this;
1857
1859
  _this.observers = [];
1858
1860
  _this.isSoftNavsEnabled = getSdkConfig().trackSoftNavigations;
1861
+ _this.onReportInp = function (metric) {
1862
+ var _a;
1863
+ if (!((_a = metric === null || metric === void 0 ? void 0 : metric.entries) === null || _a === void 0 ? void 0 : _a.length)) {
1864
+ return;
1865
+ }
1866
+ _this.onReport(metric);
1867
+ };
1859
1868
  _this.onReport = function (metric) {
1860
1869
  if (!metric) {
1861
1870
  return;
@@ -1900,7 +1909,7 @@ var CoralogixWebVitalsInstrumentation = (function (_super) {
1900
1909
  onFCP(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
1901
1910
  }
1902
1911
  if (this.metrics.inp) {
1903
- onINP(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
1912
+ onINP(this.onReportInp, { reportSoftNavs: shouldReportSoftNavs });
1904
1913
  }
1905
1914
  if (this.metrics.ttfb) {
1906
1915
  onTTFB(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
@@ -5206,7 +5215,7 @@ function resolveUrlBlueprinters(urlBlueprinters) {
5206
5215
  return resolvedUrlBlueprinters;
5207
5216
  }
5208
5217
 
5209
- var SDK_VERSION = '3.23.2';
5218
+ var SDK_VERSION = '3.23.3';
5210
5219
 
5211
5220
  function shouldDropEvent(cxRumEvent, options) {
5212
5221
  if (isDocumentErrorWithoutMessage(cxRumEvent)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralogix/browser",
3
- "version": "3.23.2",
3
+ "version": "3.23.3",
4
4
  "description": "Official Coralogix SDK for browsers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coralogix",
@@ -7,6 +7,7 @@ import 'error-stack-parser';
7
7
  import '@opentelemetry/instrumentation-fetch';
8
8
  import '@opentelemetry/instrumentation-xml-http-request';
9
9
  import 'web-vitals/attribution';
10
+ import 'web-vitals';
10
11
  import '@opentelemetry/api';
11
12
  import '@opentelemetry/propagator-b3';
12
13
  import '@opentelemetry/propagator-aws-xray';
@@ -8,6 +8,7 @@ export declare class CoralogixWebVitalsInstrumentation extends InstrumentationBa
8
8
  private registerToCoreWebVitalMetrics;
9
9
  private registerToSoftNavigations;
10
10
  private registerToCalculatedWebVitalMetrics;
11
+ private onReportInp;
11
12
  private onReport;
12
13
  private registerToTBTMetric;
13
14
  private calculateLoadingPageTime;
@@ -1,4 +1,5 @@
1
- import { CLSMetricWithAttribution, FCPMetricWithAttribution, FIDMetricWithAttribution, INPMetricWithAttribution, LCPMetricWithAttribution, Metric, TTFBMetricWithAttribution } from 'web-vitals/attribution';
1
+ import { CLSMetricWithAttribution, FCPMetricWithAttribution, FIDMetricWithAttribution, INPMetricWithAttribution, LCPMetricWithAttribution, Metric, MetricWithAttribution, TTFBMetricWithAttribution } from 'web-vitals/attribution';
2
+ import { INPMetric } from 'web-vitals';
2
3
  import { WebVitalsRating } from '../../types';
3
4
  export type CustomMetric = {
4
5
  name: 'SN' | 'LT' | 'TBT' | 'TTI';
@@ -36,7 +37,7 @@ type SanitizedFIDMetric = Omit<FIDMetricWithAttribution, 'entries' | 'attributio
36
37
  export type SanitizedTTFBMetric = Omit<TTFBMetricWithAttribution, 'entries' | 'attribution'> & {
37
38
  attribution: Omit<TTFBAttribution, 'navigationEntry'>;
38
39
  };
39
- type SanitizedINPMetric = Omit<INPMetricWithAttribution, 'entries' | 'attribution'>;
40
+ type SanitizedINPMetric = Omit<INPMetric, 'entries'>;
40
41
  export type SanitizedMetric = SanitizedLCPMetric | SanitizedFCPMetric | SanitizedCLSMetric | SanitizedFIDMetric | SanitizedTTFBMetric | SanitizedINPMetric | CustomMetric;
41
42
  export type SanitizerMap = {
42
43
  LCP: (m: LCPMetricWithAttribution) => SanitizedLCPMetric;
@@ -44,8 +45,9 @@ export type SanitizerMap = {
44
45
  CLS: (m: CLSMetricWithAttribution) => SanitizedCLSMetric;
45
46
  FID: (m: FIDMetricWithAttribution) => SanitizedFIDMetric;
46
47
  TTFB: (m: TTFBMetricWithAttribution) => SanitizedTTFBMetric;
47
- INP: (m: INPMetricWithAttribution) => SanitizedINPMetric;
48
+ INP: (m: INPMetric) => SanitizedINPMetric;
48
49
  };
50
+ export type ReportedMetric = Exclude<MetricWithAttribution, INPMetricWithAttribution> | INPMetric | CustomMetric;
49
51
  export interface CoralogixWebVitalsMetrics {
50
52
  lcp: boolean;
51
53
  fid: boolean;
package/src/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "3.23.2";
1
+ export declare const SDK_VERSION = "3.23.3";