@coralogix/browser 3.23.2 → 3.23.5

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,23 @@
1
+ ## 3.23.5 (2026-09-02)
2
+
3
+ ### 🩹 Fixes
4
+
5
+ - Make a single `cx-metadata.json` request per microfrontend when several errors are reported at once, instead of one request per error (microfrontend support, `supportMfe`)
6
+ - Stop reporting the SDK's own `cx-metadata.json` lookups as network requests in your RUM data
7
+ - Ignore a `cx-metadata.json` served with an error status instead of reading it as metadata, which could label an error with an empty microfrontend name and version
8
+
9
+ ## 3.23.4 (2026-08-31)
10
+
11
+ ### 🩹 Fixes
12
+
13
+ - Restore canvas capture in session recording: with `recordCanvas` enabled and a numeric `sampling.canvas`, snapshots stopped after the first frame and the recording worker reported an uncaught `__awaiter is not defined` error
14
+
15
+ ## 3.23.3 (2026-08-30)
16
+
17
+ ### 🩹 Fixes
18
+
19
+ - Stop the INP (Interaction to Next Paint) reporter throwing an uncaught `TypeError` after a back/forward navigation followed by a tab switch
20
+
1
21
  ## 3.23.2 (2026-08-20)
2
22
 
3
23
  ### 🩹 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';
@@ -535,49 +536,55 @@ function addLabelForMFE(span, lastFrame) {
535
536
  setCustomLabelsForSpan(span, { mfeApp: app, mfeVersion: version });
536
537
  }
537
538
  }
538
- function extractMetadataFromMfeStacktrace() {
539
- return __awaiter(this, arguments, void 0, function (fileName) {
540
- var metadata, cachedMetadata, MFE_METADATA_KEY, mfePath, response, _a, e_1;
541
- if (fileName === void 0) { fileName = ''; }
542
- return __generator(this, function (_b) {
543
- switch (_b.label) {
539
+ function fetchMfeMetadata(mfePath) {
540
+ return __awaiter(this, void 0, void 0, function () {
541
+ var response, _a, e_1;
542
+ var _b;
543
+ return __generator(this, function (_c) {
544
+ switch (_c.label) {
544
545
  case 0:
545
- cachedMetadata = CxGlobal[CACHED_METADATA_KEY];
546
- MFE_METADATA_KEY = 'cx-metadata.json';
547
- mfePath = extractMfePath(fileName);
548
- if (!mfePath) return [3, 7];
549
- response = void 0;
550
- if (!!(cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.has(mfePath))) return [3, 6];
551
- _b.label = 1;
552
- case 1:
553
- _b.trys.push([1, 4, , 5]);
554
- return [4, fetch("".concat(mfePath).concat(MFE_METADATA_KEY), {
546
+ _c.trys.push([0, 3, , 4]);
547
+ return [4, fetch("".concat(mfePath).concat(MFE_METADATA_FILE), {
555
548
  cache: 'no-cache',
556
549
  })];
557
- case 2:
558
- response = _b.sent();
550
+ case 1:
551
+ response = _c.sent();
552
+ if (!response.ok) {
553
+ return [2, undefined];
554
+ }
559
555
  _a = [{}];
560
556
  return [4, response.json()];
557
+ case 2: return [2, __assign.apply(void 0, [__assign.apply(void 0, _a.concat([(_c.sent())])), { mfePath: mfePath }])];
561
558
  case 3:
562
- metadata = __assign.apply(void 0, [__assign.apply(void 0, _a.concat([(_b.sent())])), { mfePath: mfePath }]);
563
- return [3, 5];
564
- case 4:
565
- e_1 = _b.sent();
566
- if (getSdkConfig().debug) {
559
+ e_1 = _c.sent();
560
+ if ((_b = getSdkConfig()) === null || _b === void 0 ? void 0 : _b.debug) {
567
561
  console.warn('Coralogix Browser SDK - Error fetching metadata', e_1);
568
562
  }
569
- return [3, 5];
570
- case 5:
571
- CxGlobal[CACHED_METADATA_KEY] = cachedMetadata.set(mfePath, metadata);
572
- return [3, 7];
573
- case 6:
574
- metadata = cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.get(mfePath);
575
- _b.label = 7;
576
- case 7: return [2, metadata];
563
+ return [2, undefined];
564
+ case 4: return [2];
577
565
  }
578
566
  });
579
567
  });
580
568
  }
569
+ function extractMetadataFromMfeStacktrace() {
570
+ return __awaiter(this, arguments, void 0, function (fileName) {
571
+ var cachedMetadata, mfePath, pending;
572
+ if (fileName === void 0) { fileName = ''; }
573
+ return __generator(this, function (_a) {
574
+ cachedMetadata = CxGlobal[CACHED_METADATA_KEY];
575
+ mfePath = extractMfePath(fileName);
576
+ if (mfePath) {
577
+ pending = cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.get(mfePath);
578
+ if (!pending) {
579
+ pending = fetchMfeMetadata(mfePath);
580
+ cachedMetadata === null || cachedMetadata === void 0 ? void 0 : cachedMetadata.set(mfePath, pending);
581
+ }
582
+ return [2, pending];
583
+ }
584
+ return [2, undefined];
585
+ });
586
+ });
587
+ }
581
588
  var _consoleErrorHandler = function (errorInstrumentation) {
582
589
  return function (original) {
583
590
  return function () {
@@ -1442,7 +1449,7 @@ var attributionSanitizers = {
1442
1449
  return __assign(__assign({}, rest), { attribution: sanitizedAttribution });
1443
1450
  },
1444
1451
  INP: function (metric) {
1445
- metric.entries; metric.attribution; var rest = __rest(metric, ["entries", "attribution"]);
1452
+ metric.entries; var rest = __rest(metric, ["entries"]);
1446
1453
  return rest;
1447
1454
  },
1448
1455
  };
@@ -1831,6 +1838,9 @@ function isPerformanceObserverSupported() {
1831
1838
  }
1832
1839
 
1833
1840
  function sanitizeAttribution(metric) {
1841
+ if (metric.name === 'INP') {
1842
+ return attributionSanitizers.INP(metric);
1843
+ }
1834
1844
  if (!('attribution' in metric)) {
1835
1845
  metric.entries; var rest = __rest(metric, ["entries"]);
1836
1846
  return rest;
@@ -1846,8 +1856,6 @@ function sanitizeAttribution(metric) {
1846
1856
  return attributionSanitizers.FID(metric);
1847
1857
  case 'TTFB':
1848
1858
  return attributionSanitizers.TTFB(metric);
1849
- case 'INP':
1850
- return attributionSanitizers.INP(metric);
1851
1859
  }
1852
1860
  }
1853
1861
  var CoralogixWebVitalsInstrumentation = (function (_super) {
@@ -1856,6 +1864,13 @@ var CoralogixWebVitalsInstrumentation = (function (_super) {
1856
1864
  var _this = _super.call(this, WEB_VITALS_INSTRUMENTATION_NAME, WEB_VITALS_INSTRUMENTATION_VERSION, config) || this;
1857
1865
  _this.observers = [];
1858
1866
  _this.isSoftNavsEnabled = getSdkConfig().trackSoftNavigations;
1867
+ _this.onReportInp = function (metric) {
1868
+ var _a;
1869
+ if (!((_a = metric === null || metric === void 0 ? void 0 : metric.entries) === null || _a === void 0 ? void 0 : _a.length)) {
1870
+ return;
1871
+ }
1872
+ _this.onReport(metric);
1873
+ };
1859
1874
  _this.onReport = function (metric) {
1860
1875
  if (!metric) {
1861
1876
  return;
@@ -1900,7 +1915,7 @@ var CoralogixWebVitalsInstrumentation = (function (_super) {
1900
1915
  onFCP(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
1901
1916
  }
1902
1917
  if (this.metrics.inp) {
1903
- onINP(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
1918
+ onINP(this.onReportInp, { reportSoftNavs: shouldReportSoftNavs });
1904
1919
  }
1905
1920
  if (this.metrics.ttfb) {
1906
1921
  onTTFB(this.onReport, { reportSoftNavs: shouldReportSoftNavs });
@@ -3142,6 +3157,8 @@ var CoralogixWorkerInstrumentation = (function (_super) {
3142
3157
 
3143
3158
  var CORALOGIX_LOGS_URL_SUFFIX = '/browser/v1beta/logs';
3144
3159
  var CORALOGIX_RECORDING_URL_SUFFIX = '/sessionrecording';
3160
+ var MFE_METADATA_FILE = 'cx-metadata.json';
3161
+ var MFE_METADATA_URL_PATTERN = /cx-metadata\.json$/;
3145
3162
  var MAX_INTERACTION_ELEMENT_SIZE = 1024;
3146
3163
  var MAX_CHARACTERS = 1024;
3147
3164
  var REQUIRED_CONFIG_KEYS = [
@@ -3198,6 +3215,7 @@ var OPTIONS_DEFAULTS = {
3198
3215
  ignoreUrls: [
3199
3216
  new RegExp(CORALOGIX_LOGS_URL_SUFFIX),
3200
3217
  new RegExp(CORALOGIX_RECORDING_URL_SUFFIX),
3218
+ MFE_METADATA_URL_PATTERN,
3201
3219
  ],
3202
3220
  user_context: {
3203
3221
  user_id: '',
@@ -5206,7 +5224,7 @@ function resolveUrlBlueprinters(urlBlueprinters) {
5206
5224
  return resolvedUrlBlueprinters;
5207
5225
  }
5208
5226
 
5209
- var SDK_VERSION = '3.23.2';
5227
+ var SDK_VERSION = '3.23.5';
5210
5228
 
5211
5229
  function shouldDropEvent(cxRumEvent, options) {
5212
5230
  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.5",
4
4
  "description": "Official Coralogix SDK for browsers",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coralogix",
@@ -1,4 +1,4 @@
1
- import { __values, __spreadArray, __read, __assign, __awaiter, __generator, __rest } from 'tslib';
1
+ import { __values, __spreadArray, __read, __assign, __rest, __awaiter, __generator } from 'tslib';
2
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';
@@ -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';
@@ -4229,78 +4230,69 @@ function getImageBitmapWorkerString() {
4229
4230
  var lastBlobMap = new Map();
4230
4231
  var transparentBlobMap = new Map();
4231
4232
  function getTransparentBlobFor(width, height, dataURLOptions) {
4232
- return __awaiter(this, void 0, void 0, function () {
4233
- var id, offscreen, blob, arrayBuffer, base64;
4234
- return __generator(this, function (_a) {
4235
- switch (_a.label) {
4236
- case 0:
4237
- id = width + '-' + height;
4238
- if (!('OffscreenCanvas' in globalThis)) return [3, 3];
4239
- if (transparentBlobMap.has(id))
4240
- return [2, transparentBlobMap.get(id)];
4241
- offscreen = new OffscreenCanvas(width, height);
4242
- offscreen.getContext('2d');
4243
- return [4, offscreen.convertToBlob(dataURLOptions)];
4244
- case 1:
4245
- blob = _a.sent();
4246
- return [4, blob.arrayBuffer()];
4247
- case 2:
4248
- arrayBuffer = _a.sent();
4249
- base64 = encode(arrayBuffer);
4250
- transparentBlobMap.set(id, base64);
4251
- return [2, base64];
4252
- case 3: return [2, ''];
4253
- }
4233
+ var id = width + '-' + height;
4234
+ if ('OffscreenCanvas' in globalThis) {
4235
+ var cached = transparentBlobMap.get(id);
4236
+ if (cached !== undefined)
4237
+ return Promise.resolve(cached);
4238
+ var offscreen = new OffscreenCanvas(width, height);
4239
+ offscreen.getContext('2d');
4240
+ return offscreen
4241
+ .convertToBlob(dataURLOptions)
4242
+ .then(function (blob) {
4243
+ return blob.arrayBuffer();
4244
+ })
4245
+ .then(function (arrayBuffer) {
4246
+ var base64 = encode(arrayBuffer);
4247
+ transparentBlobMap.set(id, base64);
4248
+ return base64;
4254
4249
  });
4250
+ }
4251
+ else {
4252
+ return Promise.resolve('');
4253
+ }
4254
+ }
4255
+ function sendSnapshot(id, type, base64, width, height) {
4256
+ if (lastBlobMap.get(id) === base64)
4257
+ return self.postMessage({ id: id });
4258
+ self.postMessage({
4259
+ id: id,
4260
+ type: type,
4261
+ base64: base64,
4262
+ width: width,
4263
+ height: height,
4255
4264
  });
4265
+ lastBlobMap.set(id, base64);
4256
4266
  }
4257
4267
  self.onmessage = function (e) {
4258
- return __awaiter(this, void 0, void 0, function () {
4259
- var _a, id, bitmap, width, height, dataURLOptions, transparentBase64, offscreen, ctx, blob, type, arrayBuffer, base64, _b;
4260
- return __generator(this, function (_c) {
4261
- switch (_c.label) {
4262
- case 0:
4263
- if (!('OffscreenCanvas' in globalThis)) return [3, 5];
4264
- _a = e.data, id = _a.id, bitmap = _a.bitmap, width = _a.width, height = _a.height, dataURLOptions = _a.dataURLOptions;
4265
- transparentBase64 = getTransparentBlobFor(width, height, dataURLOptions);
4266
- offscreen = new OffscreenCanvas(width, height);
4267
- ctx = offscreen.getContext('2d');
4268
- ctx.drawImage(bitmap, 0, 0);
4269
- bitmap.close();
4270
- return [4, offscreen.convertToBlob(dataURLOptions)];
4271
- case 1:
4272
- blob = _c.sent();
4273
- type = blob.type;
4274
- return [4, blob.arrayBuffer()];
4275
- case 2:
4276
- arrayBuffer = _c.sent();
4277
- base64 = encode(arrayBuffer);
4278
- _b = !lastBlobMap.has(id);
4279
- if (!_b) return [3, 4];
4280
- return [4, transparentBase64];
4281
- case 3:
4282
- _b = (_c.sent()) === base64;
4283
- _c.label = 4;
4284
- case 4:
4285
- if (_b) {
4286
- lastBlobMap.set(id, base64);
4287
- return [2, self.postMessage({ id: id })];
4288
- }
4289
- if (lastBlobMap.get(id) === base64)
4290
- return [2, self.postMessage({ id: id })];
4291
- self.postMessage({
4292
- id: id,
4293
- type: type,
4294
- base64: base64,
4295
- width: width,
4296
- height: height,
4297
- });
4268
+ if (!('OffscreenCanvas' in globalThis)) {
4269
+ return self.postMessage({ id: e.data.id });
4270
+ }
4271
+ var _a = e.data, id = _a.id, bitmap = _a.bitmap, width = _a.width, height = _a.height, dataURLOptions = _a.dataURLOptions;
4272
+ var transparentBase64 = getTransparentBlobFor(width, height, dataURLOptions);
4273
+ var offscreen = new OffscreenCanvas(width, height);
4274
+ var ctx = offscreen.getContext('2d');
4275
+ ctx.drawImage(bitmap, 0, 0);
4276
+ bitmap.close();
4277
+ var type = '';
4278
+ return offscreen
4279
+ .convertToBlob(dataURLOptions)
4280
+ .then(function (blob) {
4281
+ type = blob.type;
4282
+ return blob.arrayBuffer();
4283
+ })
4284
+ .then(function (arrayBuffer) {
4285
+ var base64 = encode(arrayBuffer);
4286
+ if (!lastBlobMap.has(id)) {
4287
+ return transparentBase64.then(function (transparent) {
4288
+ if (transparent === base64) {
4298
4289
  lastBlobMap.set(id, base64);
4299
- return [3, 6];
4300
- case 5: return [2, self.postMessage({ id: e.data.id })];
4301
- case 6: return [2];
4302
- }
4303
- });
4290
+ return self.postMessage({ id: id });
4291
+ }
4292
+ return sendSnapshot(id, type, base64, width, height);
4293
+ });
4294
+ }
4295
+ return sendSnapshot(id, type, base64, width, height);
4304
4296
  });
4305
4297
  };
4306
4298
  }
@@ -2,6 +2,8 @@ import { CoralogixBrowserSdkConfig, InputType } from './types';
2
2
  import { InternalInstrumentationConfig } from './instrumentations/instrumentation.model';
3
3
  export declare const CORALOGIX_LOGS_URL_SUFFIX = "/browser/v1beta/logs";
4
4
  export declare const CORALOGIX_RECORDING_URL_SUFFIX = "/sessionrecording";
5
+ export declare const MFE_METADATA_FILE = "cx-metadata.json";
6
+ export declare const MFE_METADATA_URL_PATTERN: RegExp;
5
7
  export declare const MAX_INTERACTION_ELEMENT_SIZE = 1024;
6
8
  export declare const MAX_CHARACTERS = 1024;
7
9
  export declare const REQUIRED_CONFIG_KEYS: Array<keyof CoralogixBrowserSdkConfig>;
@@ -1,6 +1,8 @@
1
1
  import { InstrumentationBase, InstrumentationConfig } from '@opentelemetry/instrumentation';
2
2
  import { CoralogixRumLabels, CxStackFrame } from '../types';
3
+ import { MFEMetadata } from '../mfe/mfe.types';
3
4
  import { ErrorSource } from './instrumentation.model';
5
+ export declare const CACHED_METADATA_KEY = "__cx_metadata__";
4
6
  export declare const STACK_FRAME_LIMIT = 50;
5
7
  export declare const STACK_LINE_LIMIT = 1024;
6
8
  export declare function sanitizeConsoleErrorStack(stack: string | undefined): string | undefined;
@@ -16,6 +18,7 @@ interface CoralogixErrorInstrumentationConfig extends InstrumentationConfig {
16
18
  ignoreErrors?: Array<string | RegExp>;
17
19
  }
18
20
  export declare function parseStackFrames(err: Error): CxStackFrame[];
21
+ export declare function extractMetadataFromMfeStacktrace(fileName?: string): Promise<MFEMetadata | undefined>;
19
22
  export declare class CoralogixErrorInstrumentation extends InstrumentationBase {
20
23
  constructor(config: CoralogixErrorInstrumentationConfig);
21
24
  protected init(): void;
@@ -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.5";