@myinterview/widget-react 1.1.23-beta-78ffddc → 1.1.23-binary-001

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/dist/esm/index.js CHANGED
@@ -2,6 +2,31 @@ import * as React from 'react';
2
2
  import React__default, { createContext, forwardRef, useRef, useEffect, useState, useLayoutEffect, useImperativeHandle, useDebugValue, useContext, createElement, useCallback, useMemo } from 'react';
3
3
  import { createPortal } from 'react-dom';
4
4
 
5
+ /*! *****************************************************************************
6
+ Copyright (c) Microsoft Corporation.
7
+
8
+ Permission to use, copy, modify, and/or distribute this software for any
9
+ purpose with or without fee is hereby granted.
10
+
11
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
12
+ REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13
+ AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
14
+ INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15
+ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
16
+ OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17
+ PERFORMANCE OF THIS SOFTWARE.
18
+ ***************************************************************************** */
19
+
20
+ function __awaiter(thisArg, _arguments, P, generator) {
21
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
22
+ return new (P || (P = Promise))(function (resolve, reject) {
23
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
24
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
25
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
26
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
27
+ });
28
+ }
29
+
5
30
  // eslint-disable-next-line @typescript-eslint/unbound-method
6
31
  const objectToString = Object.prototype.toString;
7
32
 
@@ -922,12 +947,6 @@ function createStackParser(...parsers) {
922
947
  // Remove webpack (error: *) wrappers
923
948
  const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, '$1') : line;
924
949
 
925
- // https://github.com/getsentry/sentry-javascript/issues/7813
926
- // Skip Error: lines
927
- if (cleanedLine.match(/\S*Error: /)) {
928
- continue;
929
- }
930
-
931
950
  for (const parser of sortedParsers) {
932
951
  const frame = parser(cleanedLine);
933
952
 
@@ -1112,8 +1131,6 @@ function supportsHistory() {
1112
1131
  // eslint-disable-next-line deprecation/deprecation
1113
1132
  const WINDOW$3 = getGlobalObject();
1114
1133
 
1115
- const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v2__';
1116
-
1117
1134
  /**
1118
1135
  * Instrument native APIs to call handlers that can be used to create breadcrumbs, APM spans etc.
1119
1136
  * - Console API
@@ -1226,13 +1243,11 @@ function instrumentFetch() {
1226
1243
 
1227
1244
  fill(WINDOW$3, 'fetch', function (originalFetch) {
1228
1245
  return function (...args) {
1229
- const { method, url } = parseFetchArgs(args);
1230
-
1231
1246
  const handlerData = {
1232
1247
  args,
1233
1248
  fetchData: {
1234
- method,
1235
- url,
1249
+ method: getFetchMethod(args),
1250
+ url: getFetchUrl(args),
1236
1251
  },
1237
1252
  startTimestamp: Date.now(),
1238
1253
  };
@@ -1267,53 +1282,29 @@ function instrumentFetch() {
1267
1282
  });
1268
1283
  }
1269
1284
 
1270
- function hasProp(obj, prop) {
1271
- return !!obj && typeof obj === 'object' && !!(obj )[prop];
1272
- }
1273
-
1274
- function getUrlFromResource(resource) {
1275
- if (typeof resource === 'string') {
1276
- return resource;
1277
- }
1278
-
1279
- if (!resource) {
1280
- return '';
1281
- }
1282
-
1283
- if (hasProp(resource, 'url')) {
1284
- return resource.url;
1285
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access */
1286
+ /** Extract `method` from fetch call arguments */
1287
+ function getFetchMethod(fetchArgs = []) {
1288
+ if ('Request' in WINDOW$3 && isInstanceOf(fetchArgs[0], Request) && fetchArgs[0].method) {
1289
+ return String(fetchArgs[0].method).toUpperCase();
1285
1290
  }
1286
-
1287
- if (resource.toString) {
1288
- return resource.toString();
1291
+ if (fetchArgs[1] && fetchArgs[1].method) {
1292
+ return String(fetchArgs[1].method).toUpperCase();
1289
1293
  }
1290
-
1291
- return '';
1294
+ return 'GET';
1292
1295
  }
1293
1296
 
1294
- /**
1295
- * Parses the fetch arguments to find the used Http method and the url of the request
1296
- */
1297
- function parseFetchArgs(fetchArgs) {
1298
- if (fetchArgs.length === 0) {
1299
- return { method: 'GET', url: '' };
1297
+ /** Extract `url` from fetch call arguments */
1298
+ function getFetchUrl(fetchArgs = []) {
1299
+ if (typeof fetchArgs[0] === 'string') {
1300
+ return fetchArgs[0];
1300
1301
  }
1301
-
1302
- if (fetchArgs.length === 2) {
1303
- const [url, options] = fetchArgs ;
1304
-
1305
- return {
1306
- url: getUrlFromResource(url),
1307
- method: hasProp(options, 'method') ? String(options.method).toUpperCase() : 'GET',
1308
- };
1302
+ if ('Request' in WINDOW$3 && isInstanceOf(fetchArgs[0], Request)) {
1303
+ return fetchArgs[0].url;
1309
1304
  }
1310
-
1311
- const arg = fetchArgs[0];
1312
- return {
1313
- url: getUrlFromResource(arg ),
1314
- method: hasProp(arg, 'method') ? String(arg.method).toUpperCase() : 'GET',
1315
- };
1305
+ return String(fetchArgs[0]);
1316
1306
  }
1307
+ /* eslint-enable @typescript-eslint/no-unsafe-member-access */
1317
1308
 
1318
1309
  /** JSDoc */
1319
1310
  function instrumentXHR() {
@@ -1326,11 +1317,10 @@ function instrumentXHR() {
1326
1317
  fill(xhrproto, 'open', function (originalOpen) {
1327
1318
  return function ( ...args) {
1328
1319
  const url = args[1];
1329
- const xhrInfo = (this[SENTRY_XHR_DATA_KEY] = {
1320
+ const xhrInfo = (this.__sentry_xhr__ = {
1330
1321
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
1331
1322
  method: isString$2(args[0]) ? args[0].toUpperCase() : args[0],
1332
1323
  url: args[1],
1333
- request_headers: {},
1334
1324
  });
1335
1325
 
1336
1326
  // if Sentry key appears in URL, don't capture it as a request
@@ -1341,7 +1331,7 @@ function instrumentXHR() {
1341
1331
 
1342
1332
  const onreadystatechangeHandler = () => {
1343
1333
  // For whatever reason, this is not the same instance here as from the outer method
1344
- const xhrInfo = this[SENTRY_XHR_DATA_KEY];
1334
+ const xhrInfo = this.__sentry_xhr__;
1345
1335
 
1346
1336
  if (!xhrInfo) {
1347
1337
  return;
@@ -1376,32 +1366,14 @@ function instrumentXHR() {
1376
1366
  this.addEventListener('readystatechange', onreadystatechangeHandler);
1377
1367
  }
1378
1368
 
1379
- // Intercepting `setRequestHeader` to access the request headers of XHR instance.
1380
- // This will only work for user/library defined headers, not for the default/browser-assigned headers.
1381
- // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.
1382
- fill(this, 'setRequestHeader', function (original) {
1383
- return function ( ...setRequestHeaderArgs) {
1384
- const [header, value] = setRequestHeaderArgs ;
1385
-
1386
- const xhrInfo = this[SENTRY_XHR_DATA_KEY];
1387
-
1388
- if (xhrInfo) {
1389
- xhrInfo.request_headers[header.toLowerCase()] = value;
1390
- }
1391
-
1392
- return original.apply(this, setRequestHeaderArgs);
1393
- };
1394
- });
1395
-
1396
1369
  return originalOpen.apply(this, args);
1397
1370
  };
1398
1371
  });
1399
1372
 
1400
1373
  fill(xhrproto, 'send', function (originalSend) {
1401
1374
  return function ( ...args) {
1402
- const sentryXhrData = this[SENTRY_XHR_DATA_KEY];
1403
- if (sentryXhrData && args[0] !== undefined) {
1404
- sentryXhrData.body = args[0];
1375
+ if (this.__sentry_xhr__ && args[0] !== undefined) {
1376
+ this.__sentry_xhr__.body = args[0];
1405
1377
  }
1406
1378
 
1407
1379
  triggerHandlers('xhr', {
@@ -1700,15 +1672,13 @@ function instrumentError() {
1700
1672
  url,
1701
1673
  });
1702
1674
 
1703
- if (_oldOnErrorHandler && !_oldOnErrorHandler.__SENTRY_LOADER__) {
1675
+ if (_oldOnErrorHandler) {
1704
1676
  // eslint-disable-next-line prefer-rest-params
1705
1677
  return _oldOnErrorHandler.apply(this, arguments);
1706
1678
  }
1707
1679
 
1708
1680
  return false;
1709
1681
  };
1710
-
1711
- WINDOW$3.onerror.__SENTRY_INSTRUMENTED__ = true;
1712
1682
  }
1713
1683
 
1714
1684
  let _oldOnUnhandledRejectionHandler = null;
@@ -1719,15 +1689,13 @@ function instrumentUnhandledRejection() {
1719
1689
  WINDOW$3.onunhandledrejection = function (e) {
1720
1690
  triggerHandlers('unhandledrejection', e);
1721
1691
 
1722
- if (_oldOnUnhandledRejectionHandler && !_oldOnUnhandledRejectionHandler.__SENTRY_LOADER__) {
1692
+ if (_oldOnUnhandledRejectionHandler) {
1723
1693
  // eslint-disable-next-line prefer-rest-params
1724
1694
  return _oldOnUnhandledRejectionHandler.apply(this, arguments);
1725
1695
  }
1726
1696
 
1727
1697
  return true;
1728
1698
  };
1729
-
1730
- WINDOW$3.onunhandledrejection.__SENTRY_INSTRUMENTED__ = true;
1731
1699
  }
1732
1700
 
1733
1701
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
@@ -2025,7 +1993,7 @@ function loadModule(moduleName) {
2025
1993
  * @returns A normalized version of the object, or `"**non-serializable**"` if any errors are thrown during normalization.
2026
1994
  */
2027
1995
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2028
- function normalize(input, depth = 100, maxProperties = +Infinity) {
1996
+ function normalize(input, depth = +Infinity, maxProperties = +Infinity) {
2029
1997
  try {
2030
1998
  // since we're at the outermost level, we don't provide a key
2031
1999
  return visit('', input, depth, maxProperties);
@@ -2071,10 +2039,7 @@ function visit(
2071
2039
  const [memoize, unmemoize] = memo;
2072
2040
 
2073
2041
  // Get the simple cases out of the way first
2074
- if (
2075
- value == null || // this matches null and undefined -> eqeq not eqeqeq
2076
- (['number', 'boolean', 'string'].includes(typeof value) && !isNaN$1(value))
2077
- ) {
2042
+ if (value === null || (['number', 'boolean', 'string'].includes(typeof value) && !isNaN$1(value))) {
2078
2043
  return value ;
2079
2044
  }
2080
2045
 
@@ -2095,16 +2060,17 @@ function visit(
2095
2060
  return value ;
2096
2061
  }
2097
2062
 
2098
- // We can set `__sentry_override_normalization_depth__` on an object to ensure that from there
2099
- // We keep a certain amount of depth.
2100
- // This should be used sparingly, e.g. we use it for the redux integration to ensure we get a certain amount of state.
2101
- const remainingDepth =
2102
- typeof (value )['__sentry_override_normalization_depth__'] === 'number'
2103
- ? ((value )['__sentry_override_normalization_depth__'] )
2104
- : depth;
2063
+ // Do not normalize objects that we know have already been normalized. As a general rule, the
2064
+ // "__sentry_skip_normalization__" property should only be used sparingly and only should only be set on objects that
2065
+ // have already been normalized.
2066
+ let overriddenDepth = depth;
2067
+
2068
+ if (typeof (value )['__sentry_override_normalization_depth__'] === 'number') {
2069
+ overriddenDepth = (value )['__sentry_override_normalization_depth__'] ;
2070
+ }
2105
2071
 
2106
2072
  // We're also done if we've reached the max depth
2107
- if (remainingDepth === 0) {
2073
+ if (overriddenDepth === 0) {
2108
2074
  // At this point we know `serialized` is a string of the form `"[object XXXX]"`. Clean it up so it's just `"[XXXX]"`.
2109
2075
  return stringified.replace('object ', '');
2110
2076
  }
@@ -2120,7 +2086,7 @@ function visit(
2120
2086
  try {
2121
2087
  const jsonValue = valueWithToJSON.toJSON();
2122
2088
  // We need to normalize the return value of `.toJSON()` in case it has circular references
2123
- return visit('', jsonValue, remainingDepth - 1, maxProperties, memo);
2089
+ return visit('', jsonValue, overriddenDepth - 1, maxProperties, memo);
2124
2090
  } catch (err) {
2125
2091
  // pass (The built-in `toJSON` failed, but we can still try to do it ourselves)
2126
2092
  }
@@ -2149,7 +2115,7 @@ function visit(
2149
2115
 
2150
2116
  // Recursively visit all the child nodes
2151
2117
  const visitValue = visitable[visitKey];
2152
- normalized[visitKey] = visit(visitKey, visitValue, remainingDepth - 1, maxProperties, memo);
2118
+ normalized[visitKey] = visit(visitKey, visitValue, overriddenDepth - 1, maxProperties, memo);
2153
2119
 
2154
2120
  numAdded++;
2155
2121
  }
@@ -2161,7 +2127,6 @@ function visit(
2161
2127
  return normalized;
2162
2128
  }
2163
2129
 
2164
- /* eslint-disable complexity */
2165
2130
  /**
2166
2131
  * Stringify the given value. Handles various known special values and types.
2167
2132
  *
@@ -2212,6 +2177,11 @@ function stringifyValue(
2212
2177
  return '[NaN]';
2213
2178
  }
2214
2179
 
2180
+ // this catches `undefined` (but not `null`, which is a primitive and can be serialized on its own)
2181
+ if (value === void 0) {
2182
+ return '[undefined]';
2183
+ }
2184
+
2215
2185
  if (typeof value === 'function') {
2216
2186
  return `[Function: ${getFunctionName(value)}]`;
2217
2187
  }
@@ -2229,19 +2199,11 @@ function stringifyValue(
2229
2199
  // them to strings means that instances of classes which haven't defined their `toStringTag` will just come out as
2230
2200
  // `"[object Object]"`. If we instead look at the constructor's name (which is the same as the name of the class),
2231
2201
  // we can make sure that only plain objects come out that way.
2232
- const objName = getConstructorName(value);
2233
-
2234
- // Handle HTML Elements
2235
- if (/^HTML(\w*)Element$/.test(objName)) {
2236
- return `[HTMLElement: ${objName}]`;
2237
- }
2238
-
2239
- return `[object ${objName}]`;
2202
+ return `[object ${getConstructorName(value)}]`;
2240
2203
  } catch (err) {
2241
2204
  return `**non-serializable** (${err})`;
2242
2205
  }
2243
2206
  }
2244
- /* eslint-enable complexity */
2245
2207
 
2246
2208
  function getConstructorName(value) {
2247
2209
  const prototype = Object.getPrototypeOf(value);
@@ -2552,7 +2514,9 @@ function makePromiseBuffer(limit) {
2552
2514
  * // environments where DOM might not be available
2553
2515
  * @returns parsed URL object
2554
2516
  */
2555
- function parseUrl(url) {
2517
+ function parseUrl(url)
2518
+
2519
+ {
2556
2520
  if (!url) {
2557
2521
  return {};
2558
2522
  }
@@ -2570,8 +2534,6 @@ function parseUrl(url) {
2570
2534
  host: match[4],
2571
2535
  path: match[5],
2572
2536
  protocol: match[2],
2573
- search: query,
2574
- hash: fragment,
2575
2537
  relative: match[5] + query + fragment, // everything minus origin
2576
2538
  };
2577
2539
  }
@@ -2956,7 +2918,6 @@ const ITEM_TYPE_TO_DATA_CATEGORY_MAP = {
2956
2918
  profile: 'profile',
2957
2919
  replay_event: 'replay',
2958
2920
  replay_recording: 'replay',
2959
- check_in: 'monitor',
2960
2921
  };
2961
2922
 
2962
2923
  /**
@@ -2986,14 +2947,16 @@ function createEventEnvelopeHeaders(
2986
2947
  dsn,
2987
2948
  ) {
2988
2949
  const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;
2950
+
2989
2951
  return {
2990
2952
  event_id: event.event_id ,
2991
2953
  sent_at: new Date().toISOString(),
2992
2954
  ...(sdkInfo && { sdk: sdkInfo }),
2993
2955
  ...(!!tunnel && { dsn: dsnToString(dsn) }),
2994
- ...(dynamicSamplingContext && {
2995
- trace: dropUndefinedKeys({ ...dynamicSamplingContext }),
2996
- }),
2956
+ ...(event.type === 'transaction' &&
2957
+ dynamicSamplingContext && {
2958
+ trace: dropUndefinedKeys({ ...dynamicSamplingContext }),
2959
+ }),
2997
2960
  };
2998
2961
  }
2999
2962
 
@@ -3698,16 +3661,9 @@ class Scope {
3698
3661
  // errors with transaction and it relies on that.
3699
3662
  if (this._span) {
3700
3663
  event.contexts = { trace: this._span.getTraceContext(), ...event.contexts };
3701
- const transaction = this._span.transaction;
3702
- if (transaction) {
3703
- event.sdkProcessingMetadata = {
3704
- dynamicSamplingContext: transaction.getDynamicSamplingContext(),
3705
- ...event.sdkProcessingMetadata,
3706
- };
3707
- const transactionName = transaction.name;
3708
- if (transactionName) {
3709
- event.tags = { transaction: transactionName, ...event.tags };
3710
- }
3664
+ const transactionName = this._span.transaction && this._span.transaction.name;
3665
+ if (transactionName) {
3666
+ event.tags = { transaction: transactionName, ...event.tags };
3711
3667
  }
3712
3668
  }
3713
3669
 
@@ -3831,6 +3787,11 @@ const API_VERSION = 4;
3831
3787
  */
3832
3788
  const DEFAULT_BREADCRUMBS = 100;
3833
3789
 
3790
+ /**
3791
+ * A layer in the process stack.
3792
+ * @hidden
3793
+ */
3794
+
3834
3795
  /**
3835
3796
  * @inheritDoc
3836
3797
  */
@@ -4108,17 +4069,7 @@ class Hub {
4108
4069
  * @inheritDoc
4109
4070
  */
4110
4071
  startTransaction(context, customSamplingContext) {
4111
- const result = this._callExtensionMethod('startTransaction', context, customSamplingContext);
4112
-
4113
- if ((typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && !result) {
4114
- // eslint-disable-next-line no-console
4115
- console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
4116
- Sentry.addTracingExtensions();
4117
- Sentry.init({...});
4118
- `);
4119
- }
4120
-
4121
- return result;
4072
+ return this._callExtensionMethod('startTransaction', context, customSamplingContext);
4122
4073
  }
4123
4074
 
4124
4075
  /**
@@ -4203,10 +4154,13 @@ Sentry.init({...});
4203
4154
  */
4204
4155
  _sendSessionUpdate() {
4205
4156
  const { scope, client } = this.getStackTop();
4157
+ if (!scope) return;
4206
4158
 
4207
4159
  const session = scope.getSession();
4208
- if (session && client && client.captureSession) {
4209
- client.captureSession(session);
4160
+ if (session) {
4161
+ if (client && client.captureSession) {
4162
+ client.captureSession(session);
4163
+ }
4210
4164
  }
4211
4165
  }
4212
4166
 
@@ -4276,28 +4230,47 @@ function getCurrentHub() {
4276
4230
  // Get main carrier (global for every environment)
4277
4231
  const registry = getMainCarrier();
4278
4232
 
4279
- if (registry.__SENTRY__ && registry.__SENTRY__.acs) {
4280
- const hub = registry.__SENTRY__.acs.getCurrentHub();
4281
-
4282
- if (hub) {
4283
- return hub;
4284
- }
4285
- }
4286
-
4287
- // Return hub that lives on a global object
4288
- return getGlobalHub(registry);
4289
- }
4290
-
4291
- function getGlobalHub(registry = getMainCarrier()) {
4292
4233
  // If there's no hub, or its an old API, assign a new one
4293
4234
  if (!hasHubOnCarrier(registry) || getHubFromCarrier(registry).isOlderThan(API_VERSION)) {
4294
4235
  setHubOnCarrier(registry, new Hub());
4295
4236
  }
4296
4237
 
4238
+ // Prefer domains over global if they are there (applicable only to Node environment)
4239
+ if (isNodeEnv()) {
4240
+ return getHubFromActiveDomain(registry);
4241
+ }
4297
4242
  // Return hub that lives on a global object
4298
4243
  return getHubFromCarrier(registry);
4299
4244
  }
4300
4245
 
4246
+ /**
4247
+ * Try to read the hub from an active domain, and fallback to the registry if one doesn't exist
4248
+ * @returns discovered hub
4249
+ */
4250
+ function getHubFromActiveDomain(registry) {
4251
+ try {
4252
+ const sentry = getMainCarrier().__SENTRY__;
4253
+ const activeDomain = sentry && sentry.extensions && sentry.extensions.domain && sentry.extensions.domain.active;
4254
+
4255
+ // If there's no active domain, just return global hub
4256
+ if (!activeDomain) {
4257
+ return getHubFromCarrier(registry);
4258
+ }
4259
+
4260
+ // If there's no hub on current domain, or it's an old API, assign a new one
4261
+ if (!hasHubOnCarrier(activeDomain) || getHubFromCarrier(activeDomain).isOlderThan(API_VERSION)) {
4262
+ const registryHubTopStack = getHubFromCarrier(registry).getStackTop();
4263
+ setHubOnCarrier(activeDomain, new Hub(registryHubTopStack.client, Scope.clone(registryHubTopStack.scope)));
4264
+ }
4265
+
4266
+ // Return hub that lives on a domain
4267
+ return getHubFromCarrier(activeDomain);
4268
+ } catch (_Oo) {
4269
+ // Return hub that lives on a global object
4270
+ return getHubFromCarrier(registry);
4271
+ }
4272
+ }
4273
+
4301
4274
  /**
4302
4275
  * This will tell whether a carrier has a hub on it or not
4303
4276
  * @param carrier object
@@ -4371,69 +4344,6 @@ var SpanStatus; (function (SpanStatus) {
4371
4344
  const DataLoss = 'data_loss'; SpanStatus["DataLoss"] = DataLoss;
4372
4345
  })(SpanStatus || (SpanStatus = {}));
4373
4346
 
4374
- /**
4375
- * Wraps a function with a transaction/span and finishes the span after the function is done.
4376
- *
4377
- * Note that if you have not enabled tracing extensions via `addTracingExtensions`, this function
4378
- * will not generate spans, and the `span` returned from the callback may be undefined.
4379
- *
4380
- * This function is meant to be used internally and may break at any time. Use at your own risk.
4381
- *
4382
- * @internal
4383
- * @private
4384
- */
4385
- function trace(
4386
- context,
4387
- callback,
4388
- // eslint-disable-next-line @typescript-eslint/no-empty-function
4389
- onError = () => {},
4390
- ) {
4391
- const ctx = { ...context };
4392
- // If a name is set and a description is not, set the description to the name.
4393
- if (ctx.name !== undefined && ctx.description === undefined) {
4394
- ctx.description = ctx.name;
4395
- }
4396
-
4397
- const hub = getCurrentHub();
4398
- const scope = hub.getScope();
4399
-
4400
- const parentSpan = scope.getSpan();
4401
- const activeSpan = parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx);
4402
- scope.setSpan(activeSpan);
4403
-
4404
- function finishAndSetSpan() {
4405
- activeSpan && activeSpan.finish();
4406
- hub.getScope().setSpan(parentSpan);
4407
- }
4408
-
4409
- let maybePromiseResult;
4410
- try {
4411
- maybePromiseResult = callback(activeSpan);
4412
- } catch (e) {
4413
- activeSpan && activeSpan.setStatus('internal_error');
4414
- onError(e);
4415
- finishAndSetSpan();
4416
- throw e;
4417
- }
4418
-
4419
- if (isThenable(maybePromiseResult)) {
4420
- Promise.resolve(maybePromiseResult).then(
4421
- () => {
4422
- finishAndSetSpan();
4423
- },
4424
- e => {
4425
- activeSpan && activeSpan.setStatus('internal_error');
4426
- onError(e);
4427
- finishAndSetSpan();
4428
- },
4429
- );
4430
- } else {
4431
- finishAndSetSpan();
4432
- }
4433
-
4434
- return maybePromiseResult;
4435
- }
4436
-
4437
4347
  // Note: All functions in this file are typed with a return value of `ReturnType<Hub[HUB_FUNCTION]>`,
4438
4348
  // where HUB_FUNCTION is some method on the Hub class.
4439
4349
  //
@@ -4775,11 +4685,7 @@ function prepareEvent(
4775
4685
 
4776
4686
  applyClientOptions(prepared, options);
4777
4687
  applyIntegrationsMetadata(prepared, integrations);
4778
-
4779
- // Only apply debug metadata to error events.
4780
- if (event.type === undefined) {
4781
- applyDebugMetadata(prepared, options.stackParser);
4782
- }
4688
+ applyDebugMetadata(prepared, options.stackParser);
4783
4689
 
4784
4690
  // If we have scope given to us, use it as the base for further modifications.
4785
4691
  // This allows us to prevent unnecessary copying of data if `captureContext` is not provided.
@@ -4856,8 +4762,6 @@ function applyClientOptions(event, options) {
4856
4762
  }
4857
4763
  }
4858
4764
 
4859
- const debugIdStackParserCache = new WeakMap();
4860
-
4861
4765
  /**
4862
4766
  * Applies debug metadata images to the event in order to apply source maps by looking up their debug ID.
4863
4767
  */
@@ -4868,28 +4772,10 @@ function applyDebugMetadata(event, stackParser) {
4868
4772
  return;
4869
4773
  }
4870
4774
 
4871
- let debugIdStackFramesCache;
4872
- const cachedDebugIdStackFrameCache = debugIdStackParserCache.get(stackParser);
4873
- if (cachedDebugIdStackFrameCache) {
4874
- debugIdStackFramesCache = cachedDebugIdStackFrameCache;
4875
- } else {
4876
- debugIdStackFramesCache = new Map();
4877
- debugIdStackParserCache.set(stackParser, debugIdStackFramesCache);
4878
- }
4879
-
4880
4775
  // Build a map of filename -> debug_id
4881
4776
  const filenameDebugIdMap = Object.keys(debugIdMap).reduce((acc, debugIdStackTrace) => {
4882
- let parsedStack;
4883
- const cachedParsedStack = debugIdStackFramesCache.get(debugIdStackTrace);
4884
- if (cachedParsedStack) {
4885
- parsedStack = cachedParsedStack;
4886
- } else {
4887
- parsedStack = stackParser(debugIdStackTrace);
4888
- debugIdStackFramesCache.set(debugIdStackTrace, parsedStack);
4889
- }
4890
-
4891
- for (let i = parsedStack.length - 1; i >= 0; i--) {
4892
- const stackFrame = parsedStack[i];
4777
+ const parsedStack = stackParser(debugIdStackTrace);
4778
+ for (const stackFrame of parsedStack) {
4893
4779
  if (stackFrame.filename) {
4894
4780
  acc[stackFrame.filename] = debugIdMap[debugIdStackTrace];
4895
4781
  break;
@@ -5794,7 +5680,7 @@ function getEventForEnvelopeItem(item, type) {
5794
5680
  return Array.isArray(item) ? (item )[1] : undefined;
5795
5681
  }
5796
5682
 
5797
- const SDK_VERSION = '7.52.1';
5683
+ const SDK_VERSION = '7.46.0';
5798
5684
 
5799
5685
  let originalFunctionToString;
5800
5686
 
@@ -5817,17 +5703,11 @@ class FunctionToString {constructor() { FunctionToString.prototype.__init.call(
5817
5703
  // eslint-disable-next-line @typescript-eslint/unbound-method
5818
5704
  originalFunctionToString = Function.prototype.toString;
5819
5705
 
5820
- // intrinsics (like Function.prototype) might be immutable in some environments
5821
- // e.g. Node with --frozen-intrinsics, XS (an embedded JavaScript engine) or SES (a JavaScript proposal)
5822
- try {
5823
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
5824
- Function.prototype.toString = function ( ...args) {
5825
- const context = getOriginalFunction(this) || this;
5826
- return originalFunctionToString.apply(context, args);
5827
- };
5828
- } catch (e) {
5829
- // ignore errors here, just don't patch this
5830
- }
5706
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5707
+ Function.prototype.toString = function ( ...args) {
5708
+ const context = getOriginalFunction(this) || this;
5709
+ return originalFunctionToString.apply(context, args);
5710
+ };
5831
5711
  }
5832
5712
  } FunctionToString.__initStatic();
5833
5713
 
@@ -5975,9 +5855,8 @@ function _getPossibleEventMessages(event) {
5975
5855
  return [event.message];
5976
5856
  }
5977
5857
  if (event.exception) {
5978
- const { values } = event.exception;
5979
5858
  try {
5980
- const { type = '', value = '' } = (values && values[values.length - 1]) || {};
5859
+ const { type = '', value = '' } = (event.exception.values && event.exception.values[0]) || {};
5981
5860
  return [`${value}`, `${type}: ${value}`];
5982
5861
  } catch (oO) {
5983
5862
  (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(`Cannot extract message for event ${getEventDescription(event)}`);
@@ -6027,9 +5906,9 @@ function _getEventFilterUrl(event) {
6027
5906
  }
6028
5907
 
6029
5908
  var Integrations = /*#__PURE__*/Object.freeze({
6030
- __proto__: null,
6031
- FunctionToString: FunctionToString,
6032
- InboundFilters: InboundFilters
5909
+ __proto__: null,
5910
+ FunctionToString: FunctionToString,
5911
+ InboundFilters: InboundFilters
6033
5912
  });
6034
5913
 
6035
5914
  const WINDOW$1 = GLOBAL_OBJ ;
@@ -6636,14 +6515,12 @@ function _consoleBreadcrumb(handlerData) {
6636
6515
  function _xhrBreadcrumb(handlerData) {
6637
6516
  const { startTimestamp, endTimestamp } = handlerData;
6638
6517
 
6639
- const sentryXhrData = handlerData.xhr[SENTRY_XHR_DATA_KEY];
6640
-
6641
6518
  // We only capture complete, non-sentry requests
6642
- if (!startTimestamp || !endTimestamp || !sentryXhrData) {
6519
+ if (!startTimestamp || !endTimestamp || !handlerData.xhr.__sentry_xhr__) {
6643
6520
  return;
6644
6521
  }
6645
6522
 
6646
- const { method, url, status_code, body } = sentryXhrData;
6523
+ const { method, url, status_code, body } = handlerData.xhr.__sentry_xhr__;
6647
6524
 
6648
6525
  const data = {
6649
6526
  method,
@@ -6761,43 +6638,6 @@ function _isEvent(event) {
6761
6638
  return event && !!(event ).target;
6762
6639
  }
6763
6640
 
6764
- /**
6765
- * Creates an envelope from a user feedback.
6766
- */
6767
- function createUserFeedbackEnvelope(
6768
- feedback,
6769
- {
6770
- metadata,
6771
- tunnel,
6772
- dsn,
6773
- }
6774
-
6775
- ,
6776
- ) {
6777
- const headers = {
6778
- event_id: feedback.event_id,
6779
- sent_at: new Date().toISOString(),
6780
- ...(metadata &&
6781
- metadata.sdk && {
6782
- sdk: {
6783
- name: metadata.sdk.name,
6784
- version: metadata.sdk.version,
6785
- },
6786
- }),
6787
- ...(!!tunnel && !!dsn && { dsn: dsnToString(dsn) }),
6788
- };
6789
- const item = createUserFeedbackEnvelopeItem(feedback);
6790
-
6791
- return createEnvelope(headers, [item]);
6792
- }
6793
-
6794
- function createUserFeedbackEnvelopeItem(feedback) {
6795
- const feedbackHeaders = {
6796
- type: 'user_report',
6797
- };
6798
- return [feedbackHeaders, feedback];
6799
- }
6800
-
6801
6641
  /**
6802
6642
  * Configuration options for the Sentry Browser SDK.
6803
6643
  * @see @sentry/types Options for more information.
@@ -6880,23 +6720,6 @@ class BrowserClient extends BaseClient {
6880
6720
  super.sendEvent(event, hint);
6881
6721
  }
6882
6722
 
6883
- /**
6884
- * Sends user feedback to Sentry.
6885
- */
6886
- captureUserFeedback(feedback) {
6887
- if (!this._isEnabled()) {
6888
- (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.warn('SDK not enabled, will not capture user feedback.');
6889
- return;
6890
- }
6891
-
6892
- const envelope = createUserFeedbackEnvelope(feedback, {
6893
- metadata: this.getSdkMetadata(),
6894
- dsn: this.getDsn(),
6895
- tunnel: this.getOptions().tunnel,
6896
- });
6897
- void this._sendEnvelope(envelope);
6898
- }
6899
-
6900
6723
  /**
6901
6724
  * @inheritDoc
6902
6725
  */
@@ -7139,7 +6962,7 @@ function createFrame(filename, func, lineno, colno) {
7139
6962
 
7140
6963
  // Chromium based browsers: Chrome, Brave, new Opera, new Edge
7141
6964
  const chromeRegex =
7142
- /^\s*at (?:(.+?\)(?: \[.+\])?|.*?) ?\((?:address at )?)?(?:async )?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
6965
+ /^\s*at (?:(.*\).*?|.*?) ?\((?:address at )?)?(?:async )?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
7143
6966
  const chromeEvalRegex = /\((\S*)(?::(\d+))(?::(\d+))\)/;
7144
6967
 
7145
6968
  const chrome = line => {
@@ -7175,7 +6998,7 @@ const chromeStackLineParser = [CHROME_PRIORITY, chrome];
7175
6998
  // generates filenames without a prefix like `file://` the filenames in the stacktrace are just 42.js
7176
6999
  // We need this specific case for now because we want no other regex to match.
7177
7000
  const geckoREgex =
7178
- /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
7001
+ /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension|safari-extension|safari-web-extension|capacitor)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. /=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
7179
7002
  const geckoEvalRegex = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
7180
7003
 
7181
7004
  const gecko = line => {
@@ -7207,7 +7030,8 @@ const gecko = line => {
7207
7030
 
7208
7031
  const geckoStackLineParser = [GECKO_PRIORITY, gecko];
7209
7032
 
7210
- const winjsRegex = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:[-a-z]+):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
7033
+ const winjsRegex =
7034
+ /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
7211
7035
 
7212
7036
  const winjs = line => {
7213
7037
  const parts = winjsRegex.exec(line);
@@ -8253,13 +8077,13 @@ function startSessionTracking() {
8253
8077
  }
8254
8078
 
8255
8079
  var index$1 = /*#__PURE__*/Object.freeze({
8256
- __proto__: null,
8257
- GlobalHandlers: GlobalHandlers,
8258
- TryCatch: TryCatch,
8259
- Breadcrumbs: Breadcrumbs,
8260
- LinkedErrors: LinkedErrors,
8261
- HttpContext: HttpContext,
8262
- Dedupe: Dedupe
8080
+ __proto__: null,
8081
+ GlobalHandlers: GlobalHandlers,
8082
+ TryCatch: TryCatch,
8083
+ Breadcrumbs: Breadcrumbs,
8084
+ LinkedErrors: LinkedErrors,
8085
+ HttpContext: HttpContext,
8086
+ Dedupe: Dedupe
8263
8087
  });
8264
8088
 
8265
8089
  // exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`
@@ -8272,14 +8096,11 @@ const REPLAY_SESSION_KEY = 'sentryReplaySession';
8272
8096
  const REPLAY_EVENT_NAME = 'replay_event';
8273
8097
  const UNABLE_TO_SEND_REPLAY = 'Unable to send Replay';
8274
8098
 
8275
- // The idle limit for a session after which recording is paused.
8276
- const SESSION_IDLE_PAUSE_DURATION = 300000; // 5 minutes in ms
8277
-
8278
- // The idle limit for a session after which the session expires.
8279
- const SESSION_IDLE_EXPIRE_DURATION = 900000; // 15 minutes in ms
8099
+ // The idle limit for a session
8100
+ const SESSION_IDLE_DURATION = 300000; // 5 minutes in ms
8280
8101
 
8281
8102
  // The maximum length of a session
8282
- const MAX_SESSION_LIFE = 3600000; // 60 minutes in ms
8103
+ const MAX_SESSION_LIFE = 3600000; // 60 minutes
8283
8104
 
8284
8105
  /** Default flush delays */
8285
8106
  const DEFAULT_FLUSH_MIN_DELAY = 5000;
@@ -8288,16 +8109,13 @@ const DEFAULT_FLUSH_MIN_DELAY = 5000;
8288
8109
  const DEFAULT_FLUSH_MAX_DELAY = 5500;
8289
8110
 
8290
8111
  /* How long to wait for error checkouts */
8291
- const BUFFER_CHECKOUT_TIME = 60000;
8112
+ const ERROR_CHECKOUT_TIME = 60000;
8292
8113
 
8293
8114
  const RETRY_BASE_INTERVAL = 5000;
8294
8115
  const RETRY_MAX_COUNT = 3;
8295
8116
 
8296
- /* The max (uncompressed) size in bytes of a network body. Any body larger than this will be truncated. */
8297
- const NETWORK_BODY_MAX_SIZE = 150000;
8298
-
8299
- /* The max size of a single console arg that is captured. Any arg larger than this will be truncated. */
8300
- const CONSOLE_ARG_MAX_SIZE = 5000;
8117
+ /* The max (uncompressed) size in bytes of a network body. Any body larger than this will be dropped. */
8118
+ const NETWORK_BODY_MAX_SIZE = 300000;
8301
8119
 
8302
8120
  var NodeType$1;
8303
8121
  (function (NodeType) {
@@ -8334,7 +8152,7 @@ function maskInputValue({ input, maskInputSelector, unmaskInputSelector, maskInp
8334
8152
  if (unmaskInputSelector && input.matches(unmaskInputSelector)) {
8335
8153
  return text;
8336
8154
  }
8337
- if (input.hasAttribute('data-rr-is-password')) {
8155
+ if (input.hasAttribute('rr_is_password')) {
8338
8156
  type = 'password';
8339
8157
  }
8340
8158
  if (isInputTypeMasked({ maskInputOptions, tagName, type }) ||
@@ -8367,21 +8185,6 @@ function is2DCanvasBlank(canvas) {
8367
8185
  }
8368
8186
  return true;
8369
8187
  }
8370
- function getInputType(element) {
8371
- const type = element.type;
8372
- return element.hasAttribute('data-rr-is-password')
8373
- ? 'password'
8374
- : type
8375
- ? type.toLowerCase()
8376
- : null;
8377
- }
8378
- function getInputValue(el, tagName, type) {
8379
- typeof type === 'string' ? type.toLowerCase() : '';
8380
- if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {
8381
- return el.getAttribute('value') || '';
8382
- }
8383
- return el.value;
8384
- }
8385
8188
 
8386
8189
  let _id = 1;
8387
8190
  const tagNameRegex = new RegExp('[^a-z0-9-_:]');
@@ -8420,13 +8223,6 @@ function getCssRuleString(rule) {
8420
8223
  catch (_a) {
8421
8224
  }
8422
8225
  }
8423
- return validateStringifiedCssRule(cssStringified);
8424
- }
8425
- function validateStringifiedCssRule(cssStringified) {
8426
- if (cssStringified.indexOf(':') > -1) {
8427
- const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
8428
- return cssStringified.replace(regex, '$1\\$2');
8429
- }
8430
8226
  return cssStringified;
8431
8227
  }
8432
8228
  function isCSSImportRule(rule) {
@@ -8435,7 +8231,7 @@ function isCSSImportRule(rule) {
8435
8231
  function stringifyStyleSheet(sheet) {
8436
8232
  return sheet.cssRules
8437
8233
  ? Array.from(sheet.cssRules)
8438
- .map((rule) => rule.cssText ? validateStringifiedCssRule(rule.cssText) : '')
8234
+ .map((rule) => rule.cssText || '')
8439
8235
  .join('')
8440
8236
  : '';
8441
8237
  }
@@ -8770,15 +8566,14 @@ function serializeNode(n, options) {
8770
8566
  tagName === 'select' ||
8771
8567
  tagName === 'option') {
8772
8568
  const el = n;
8773
- const type = getInputType(el);
8774
- const value = getInputValue(el, tagName.toUpperCase(), type);
8569
+ const value = getInputValue(tagName, el, attributes);
8775
8570
  const checked = n.checked;
8776
- if (type !== 'submit' &&
8777
- type !== 'button' &&
8571
+ if (attributes.type !== 'submit' &&
8572
+ attributes.type !== 'button' &&
8778
8573
  value) {
8779
8574
  attributes.value = maskInputValue({
8780
8575
  input: el,
8781
- type,
8576
+ type: attributes.type,
8782
8577
  tagName,
8783
8578
  value,
8784
8579
  maskInputSelector,
@@ -9251,8 +9046,15 @@ function snapshot(n, options) {
9251
9046
  function skipAttribute(tagName, attributeName, value) {
9252
9047
  return ((tagName === 'video' || tagName === 'audio') && attributeName === 'autoplay');
9253
9048
  }
9049
+ function getInputValue(tagName, el, attributes) {
9050
+ if (tagName === 'input' &&
9051
+ (attributes.type === 'radio' || attributes.type === 'checkbox')) {
9052
+ return el.getAttribute('value') || '';
9053
+ }
9054
+ return el.value;
9055
+ }
9254
9056
 
9255
- var EventType$1;
9057
+ var EventType;
9256
9058
  (function (EventType) {
9257
9059
  EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
9258
9060
  EventType[EventType["Load"] = 1] = "Load";
@@ -9261,7 +9063,7 @@ var EventType$1;
9261
9063
  EventType[EventType["Meta"] = 4] = "Meta";
9262
9064
  EventType[EventType["Custom"] = 5] = "Custom";
9263
9065
  EventType[EventType["Plugin"] = 6] = "Plugin";
9264
- })(EventType$1 || (EventType$1 = {}));
9066
+ })(EventType || (EventType = {}));
9265
9067
  var IncrementalSource;
9266
9068
  (function (IncrementalSource) {
9267
9069
  IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
@@ -9876,9 +9678,9 @@ class MutationBuffer {
9876
9678
  this.attributes.push(item);
9877
9679
  }
9878
9680
  if (m.attributeName === 'type' &&
9879
- target.tagName === 'INPUT' &&
9681
+ m.target.tagName === 'INPUT' &&
9880
9682
  (m.oldValue || '').toLowerCase() === 'password') {
9881
- target.setAttribute('data-rr-is-password', 'true');
9683
+ m.target.setAttribute('rr_is_password', 'true');
9882
9684
  }
9883
9685
  if (m.attributeName === 'style') {
9884
9686
  const old = this.doc.createElement('span');
@@ -10275,25 +10077,27 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
10275
10077
  isBlocked(target, blockClass, blockSelector, unblockSelector)) {
10276
10078
  return;
10277
10079
  }
10278
- const el = target;
10279
- const type = getInputType(el);
10280
- if (el.classList.contains(ignoreClass) ||
10281
- (ignoreSelector && el.matches(ignoreSelector))) {
10080
+ let type = target.type;
10081
+ if (target.classList.contains(ignoreClass) ||
10082
+ (ignoreSelector && target.matches(ignoreSelector))) {
10282
10083
  return;
10283
10084
  }
10284
- let text = getInputValue(el, tagName, type);
10085
+ let text = target.value;
10285
10086
  let isChecked = false;
10087
+ if (target.hasAttribute('rr_is_password')) {
10088
+ type = 'password';
10089
+ }
10286
10090
  if (type === 'radio' || type === 'checkbox') {
10287
10091
  isChecked = target.checked;
10288
10092
  }
10289
- if (hasInputMaskOptions({
10093
+ else if (hasInputMaskOptions({
10290
10094
  maskInputOptions,
10291
10095
  maskInputSelector,
10292
10096
  tagName,
10293
10097
  type,
10294
10098
  })) {
10295
10099
  text = maskInputValue({
10296
- input: el,
10100
+ input: target,
10297
10101
  maskInputOptions,
10298
10102
  maskInputSelector,
10299
10103
  unmaskInputSelector,
@@ -10310,18 +10114,8 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
10310
10114
  .querySelectorAll(`input[type="radio"][name="${name}"]`)
10311
10115
  .forEach((el) => {
10312
10116
  if (el !== target) {
10313
- const text = maskInputValue({
10314
- input: el,
10315
- maskInputOptions,
10316
- maskInputSelector,
10317
- unmaskInputSelector,
10318
- tagName,
10319
- type,
10320
- value: getInputValue(el, tagName, type),
10321
- maskInputFn,
10322
- });
10323
10117
  cbWithDedup(el, callbackWrapper(wrapEventWithUserTriggeredFlag)({
10324
- text,
10118
+ text: el.value,
10325
10119
  isChecked: !isChecked,
10326
10120
  userTriggered: false,
10327
10121
  }, userTriggeredOnInput));
@@ -11234,17 +11028,17 @@ function record(options = {}) {
11234
11028
  wrappedEmit = (e, isCheckout) => {
11235
11029
  var _a;
11236
11030
  if (((_a = mutationBuffers[0]) === null || _a === void 0 ? void 0 : _a.isFrozen()) &&
11237
- e.type !== EventType$1.FullSnapshot &&
11238
- !(e.type === EventType$1.IncrementalSnapshot &&
11031
+ e.type !== EventType.FullSnapshot &&
11032
+ !(e.type === EventType.IncrementalSnapshot &&
11239
11033
  e.data.source === IncrementalSource.Mutation)) {
11240
11034
  mutationBuffers.forEach((buf) => buf.unfreeze());
11241
11035
  }
11242
11036
  emit(eventProcessor(e), isCheckout);
11243
- if (e.type === EventType$1.FullSnapshot) {
11037
+ if (e.type === EventType.FullSnapshot) {
11244
11038
  lastFullSnapshotEvent = e;
11245
11039
  incrementalSnapshotCount = 0;
11246
11040
  }
11247
- else if (e.type === EventType$1.IncrementalSnapshot) {
11041
+ else if (e.type === EventType.IncrementalSnapshot) {
11248
11042
  if (e.data.source === IncrementalSource.Mutation &&
11249
11043
  e.data.isAttachIframe) {
11250
11044
  return;
@@ -11260,16 +11054,16 @@ function record(options = {}) {
11260
11054
  };
11261
11055
  const wrappedMutationEmit = (m) => {
11262
11056
  wrappedEmit(wrapEvent({
11263
- type: EventType$1.IncrementalSnapshot,
11057
+ type: EventType.IncrementalSnapshot,
11264
11058
  data: Object.assign({ source: IncrementalSource.Mutation }, m),
11265
11059
  }));
11266
11060
  };
11267
11061
  const wrappedScrollEmit = (p) => wrappedEmit(wrapEvent({
11268
- type: EventType$1.IncrementalSnapshot,
11062
+ type: EventType.IncrementalSnapshot,
11269
11063
  data: Object.assign({ source: IncrementalSource.Scroll }, p),
11270
11064
  }));
11271
11065
  const wrappedCanvasMutationEmit = (p) => wrappedEmit(wrapEvent({
11272
- type: EventType$1.IncrementalSnapshot,
11066
+ type: EventType.IncrementalSnapshot,
11273
11067
  data: Object.assign({ source: IncrementalSource.CanvasMutation }, p),
11274
11068
  }));
11275
11069
  const iframeManager = new IframeManager({
@@ -11314,7 +11108,7 @@ function record(options = {}) {
11314
11108
  takeFullSnapshot = (isCheckout = false) => {
11315
11109
  var _a, _b, _c, _d;
11316
11110
  wrappedEmit(wrapEvent({
11317
- type: EventType$1.Meta,
11111
+ type: EventType.Meta,
11318
11112
  data: {
11319
11113
  href: window.location.href,
11320
11114
  width: getWindowWidth(),
@@ -11357,7 +11151,7 @@ function record(options = {}) {
11357
11151
  }
11358
11152
  mirror.map = idNodeMap;
11359
11153
  wrappedEmit(wrapEvent({
11360
- type: EventType$1.FullSnapshot,
11154
+ type: EventType.FullSnapshot,
11361
11155
  data: {
11362
11156
  node,
11363
11157
  initialOffset: {
@@ -11382,7 +11176,7 @@ function record(options = {}) {
11382
11176
  const handlers = [];
11383
11177
  handlers.push(on$1('DOMContentLoaded', () => {
11384
11178
  wrappedEmit(wrapEvent({
11385
- type: EventType$1.DomContentLoaded,
11179
+ type: EventType.DomContentLoaded,
11386
11180
  data: {},
11387
11181
  }));
11388
11182
  }));
@@ -11392,40 +11186,40 @@ function record(options = {}) {
11392
11186
  onMutation,
11393
11187
  mutationCb: wrappedMutationEmit,
11394
11188
  mousemoveCb: (positions, source) => wrappedEmit(wrapEvent({
11395
- type: EventType$1.IncrementalSnapshot,
11189
+ type: EventType.IncrementalSnapshot,
11396
11190
  data: {
11397
11191
  source,
11398
11192
  positions,
11399
11193
  },
11400
11194
  })),
11401
11195
  mouseInteractionCb: (d) => wrappedEmit(wrapEvent({
11402
- type: EventType$1.IncrementalSnapshot,
11196
+ type: EventType.IncrementalSnapshot,
11403
11197
  data: Object.assign({ source: IncrementalSource.MouseInteraction }, d),
11404
11198
  })),
11405
11199
  scrollCb: wrappedScrollEmit,
11406
11200
  viewportResizeCb: (d) => wrappedEmit(wrapEvent({
11407
- type: EventType$1.IncrementalSnapshot,
11201
+ type: EventType.IncrementalSnapshot,
11408
11202
  data: Object.assign({ source: IncrementalSource.ViewportResize }, d),
11409
11203
  })),
11410
11204
  inputCb: (v) => wrappedEmit(wrapEvent({
11411
- type: EventType$1.IncrementalSnapshot,
11205
+ type: EventType.IncrementalSnapshot,
11412
11206
  data: Object.assign({ source: IncrementalSource.Input }, v),
11413
11207
  })),
11414
11208
  mediaInteractionCb: (p) => wrappedEmit(wrapEvent({
11415
- type: EventType$1.IncrementalSnapshot,
11209
+ type: EventType.IncrementalSnapshot,
11416
11210
  data: Object.assign({ source: IncrementalSource.MediaInteraction }, p),
11417
11211
  })),
11418
11212
  styleSheetRuleCb: (r) => wrappedEmit(wrapEvent({
11419
- type: EventType$1.IncrementalSnapshot,
11213
+ type: EventType.IncrementalSnapshot,
11420
11214
  data: Object.assign({ source: IncrementalSource.StyleSheetRule }, r),
11421
11215
  })),
11422
11216
  styleDeclarationCb: (r) => wrappedEmit(wrapEvent({
11423
- type: EventType$1.IncrementalSnapshot,
11217
+ type: EventType.IncrementalSnapshot,
11424
11218
  data: Object.assign({ source: IncrementalSource.StyleDeclaration }, r),
11425
11219
  })),
11426
11220
  canvasMutationCb: wrappedCanvasMutationEmit,
11427
11221
  fontCb: (p) => wrappedEmit(wrapEvent({
11428
- type: EventType$1.IncrementalSnapshot,
11222
+ type: EventType.IncrementalSnapshot,
11429
11223
  data: Object.assign({ source: IncrementalSource.Font }, p),
11430
11224
  })),
11431
11225
  blockClass,
@@ -11458,7 +11252,7 @@ function record(options = {}) {
11458
11252
  observer: p.observer,
11459
11253
  options: p.options,
11460
11254
  callback: (payload) => wrappedEmit(wrapEvent({
11461
- type: EventType$1.Plugin,
11255
+ type: EventType.Plugin,
11462
11256
  data: {
11463
11257
  plugin: p.name,
11464
11258
  payload,
@@ -11486,7 +11280,7 @@ function record(options = {}) {
11486
11280
  else {
11487
11281
  handlers.push(on$1('load', () => {
11488
11282
  wrappedEmit(wrapEvent({
11489
- type: EventType$1.Load,
11283
+ type: EventType.Load,
11490
11284
  data: {},
11491
11285
  }));
11492
11286
  init();
@@ -11505,7 +11299,7 @@ record.addCustomEvent = (tag, payload) => {
11505
11299
  throw new Error('please add custom event after start recording');
11506
11300
  }
11507
11301
  wrappedEmit(wrapEvent({
11508
- type: EventType$1.Custom,
11302
+ type: EventType.Custom,
11509
11303
  data: {
11510
11304
  tag,
11511
11305
  payload,
@@ -11523,475 +11317,6 @@ record.takeFullSnapshot = (isCheckout) => {
11523
11317
  };
11524
11318
  record.mirror = mirror;
11525
11319
 
11526
- /**
11527
- * Create a breadcrumb for a replay.
11528
- */
11529
- function createBreadcrumb(
11530
- breadcrumb,
11531
- ) {
11532
- return {
11533
- timestamp: Date.now() / 1000,
11534
- type: 'default',
11535
- ...breadcrumb,
11536
- };
11537
- }
11538
-
11539
- var NodeType;
11540
- (function (NodeType) {
11541
- NodeType[NodeType["Document"] = 0] = "Document";
11542
- NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
11543
- NodeType[NodeType["Element"] = 2] = "Element";
11544
- NodeType[NodeType["Text"] = 3] = "Text";
11545
- NodeType[NodeType["CDATA"] = 4] = "CDATA";
11546
- NodeType[NodeType["Comment"] = 5] = "Comment";
11547
- })(NodeType || (NodeType = {}));
11548
-
11549
- /**
11550
- * Converts a timestamp to ms, if it was in s, or keeps it as ms.
11551
- */
11552
- function timestampToMs(timestamp) {
11553
- const isMs = timestamp > 9999999999;
11554
- return isMs ? timestamp : timestamp * 1000;
11555
- }
11556
-
11557
- /**
11558
- * Add an event to the event buffer.
11559
- * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
11560
- */
11561
- async function addEvent(
11562
- replay,
11563
- event,
11564
- isCheckout,
11565
- ) {
11566
- if (!replay.eventBuffer) {
11567
- // This implies that `_isEnabled` is false
11568
- return null;
11569
- }
11570
-
11571
- if (replay.isPaused()) {
11572
- // Do not add to event buffer when recording is paused
11573
- return null;
11574
- }
11575
-
11576
- const timestampInMs = timestampToMs(event.timestamp);
11577
-
11578
- // Throw out events that happen more than 5 minutes ago. This can happen if
11579
- // page has been left open and idle for a long period of time and user
11580
- // comes back to trigger a new session. The performance entries rely on
11581
- // `performance.timeOrigin`, which is when the page first opened.
11582
- if (timestampInMs + replay.timeouts.sessionIdlePause < Date.now()) {
11583
- return null;
11584
- }
11585
-
11586
- try {
11587
- if (isCheckout) {
11588
- replay.eventBuffer.clear();
11589
- }
11590
-
11591
- return await replay.eventBuffer.addEvent(event);
11592
- } catch (error) {
11593
- (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(error);
11594
- await replay.stop('addEvent');
11595
-
11596
- const client = getCurrentHub().getClient();
11597
-
11598
- if (client) {
11599
- client.recordDroppedEvent('internal_sdk_error', 'replay');
11600
- }
11601
- }
11602
- }
11603
-
11604
- /**
11605
- * Add a breadcrumb event to replay.
11606
- */
11607
- function addBreadcrumbEvent(replay, breadcrumb) {
11608
- if (breadcrumb.category === 'sentry.transaction') {
11609
- return;
11610
- }
11611
-
11612
- if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {
11613
- replay.triggerUserActivity();
11614
- } else {
11615
- replay.checkAndHandleExpiredSession();
11616
- }
11617
-
11618
- replay.addUpdate(() => {
11619
- void addEvent(replay, {
11620
- type: EventType$1.Custom,
11621
- // TODO: We were converting from ms to seconds for breadcrumbs, spans,
11622
- // but maybe we should just keep them as milliseconds
11623
- timestamp: (breadcrumb.timestamp || 0) * 1000,
11624
- data: {
11625
- tag: 'breadcrumb',
11626
- // normalize to max. 10 depth and 1_000 properties per object
11627
- payload: normalize(breadcrumb, 10, 1000),
11628
- },
11629
- });
11630
-
11631
- // Do not flush after console log messages
11632
- return breadcrumb.category === 'console';
11633
- });
11634
- }
11635
-
11636
- /**
11637
- * Detect a slow click on a button/a tag,
11638
- * and potentially create a corresponding breadcrumb.
11639
- */
11640
- function detectSlowClick(
11641
- replay,
11642
- config,
11643
- clickBreadcrumb,
11644
- node,
11645
- ) {
11646
- if (ignoreElement(node, config)) {
11647
- return;
11648
- }
11649
-
11650
- /*
11651
- We consider a slow click a click on a button/a, which does not trigger one of:
11652
- - DOM mutation
11653
- - Scroll (within 100ms)
11654
- Within the given threshold time.
11655
- After time timeout time, we stop listening and mark it as a slow click anyhow.
11656
- */
11657
-
11658
- let cleanup = () => {
11659
- // replaced further down
11660
- };
11661
-
11662
- // After timeout time, def. consider this a slow click, and stop watching for mutations
11663
- const timeout = setTimeout(() => {
11664
- handleSlowClick(replay, clickBreadcrumb, config.timeout, 'timeout');
11665
- cleanup();
11666
- }, config.timeout);
11667
-
11668
- const mutationHandler = () => {
11669
- maybeHandleSlowClick(replay, clickBreadcrumb, config.threshold, config.timeout, 'mutation');
11670
- cleanup();
11671
- };
11672
-
11673
- const scrollHandler = () => {
11674
- maybeHandleSlowClick(replay, clickBreadcrumb, config.scrollTimeout, config.timeout, 'scroll');
11675
- cleanup();
11676
- };
11677
-
11678
- const obs = new MutationObserver(mutationHandler);
11679
-
11680
- obs.observe(WINDOW.document.documentElement, {
11681
- attributes: true,
11682
- characterData: true,
11683
- childList: true,
11684
- subtree: true,
11685
- });
11686
-
11687
- WINDOW.addEventListener('scroll', scrollHandler);
11688
-
11689
- // Stop listening to scroll timeouts early
11690
- const scrollTimeout = setTimeout(() => {
11691
- WINDOW.removeEventListener('scroll', scrollHandler);
11692
- }, config.scrollTimeout);
11693
-
11694
- cleanup = () => {
11695
- clearTimeout(timeout);
11696
- clearTimeout(scrollTimeout);
11697
- obs.disconnect();
11698
- WINDOW.removeEventListener('scroll', scrollHandler);
11699
- };
11700
- }
11701
-
11702
- function maybeHandleSlowClick(
11703
- replay,
11704
- clickBreadcrumb,
11705
- threshold,
11706
- timeout,
11707
- endReason,
11708
- ) {
11709
- const now = Date.now();
11710
- const timeAfterClickMs = now - clickBreadcrumb.timestamp * 1000;
11711
-
11712
- if (timeAfterClickMs > threshold) {
11713
- handleSlowClick(replay, clickBreadcrumb, Math.min(timeAfterClickMs, timeout), endReason);
11714
- return true;
11715
- }
11716
-
11717
- return false;
11718
- }
11719
-
11720
- function handleSlowClick(
11721
- replay,
11722
- clickBreadcrumb,
11723
- timeAfterClickMs,
11724
- endReason,
11725
- ) {
11726
- const breadcrumb = {
11727
- message: clickBreadcrumb.message,
11728
- timestamp: clickBreadcrumb.timestamp,
11729
- category: 'ui.slowClickDetected',
11730
- data: {
11731
- ...clickBreadcrumb.data,
11732
- url: WINDOW.location.href,
11733
- // TODO FN: add parametrized route, when possible
11734
- timeAfterClickMs,
11735
- endReason,
11736
- },
11737
- };
11738
-
11739
- addBreadcrumbEvent(replay, breadcrumb);
11740
- }
11741
-
11742
- const SLOW_CLICK_IGNORE_TAGS = ['SELECT', 'OPTION'];
11743
-
11744
- function ignoreElement(node, config) {
11745
- // If <input> tag, we only want to consider input[type='submit'] & input[type='button']
11746
- if (node.tagName === 'INPUT' && !['submit', 'button'].includes(node.getAttribute('type') || '')) {
11747
- return true;
11748
- }
11749
-
11750
- if (SLOW_CLICK_IGNORE_TAGS.includes(node.tagName)) {
11751
- return true;
11752
- }
11753
-
11754
- // If <a> tag, detect special variants that may not lead to an action
11755
- // If target !== _self, we may open the link somewhere else, which would lead to no action
11756
- // Also, when downloading a file, we may not leave the page, but still not trigger an action
11757
- if (
11758
- node.tagName === 'A' &&
11759
- (node.hasAttribute('download') || (node.hasAttribute('target') && node.getAttribute('target') !== '_self'))
11760
- ) {
11761
- return true;
11762
- }
11763
-
11764
- if (config.ignoreSelector && node.matches(config.ignoreSelector)) {
11765
- return true;
11766
- }
11767
-
11768
- return false;
11769
- }
11770
-
11771
- // Note that these are the serialized attributes and not attributes directly on
11772
- // the DOM Node. Attributes we are interested in:
11773
- const ATTRIBUTES_TO_RECORD = new Set([
11774
- 'id',
11775
- 'class',
11776
- 'aria-label',
11777
- 'role',
11778
- 'name',
11779
- 'alt',
11780
- 'title',
11781
- 'data-test-id',
11782
- 'data-testid',
11783
- ]);
11784
-
11785
- /**
11786
- * Inclusion list of attributes that we want to record from the DOM element
11787
- */
11788
- function getAttributesToRecord(attributes) {
11789
- const obj = {};
11790
- for (const key in attributes) {
11791
- if (ATTRIBUTES_TO_RECORD.has(key)) {
11792
- let normalizedKey = key;
11793
-
11794
- if (key === 'data-testid' || key === 'data-test-id') {
11795
- normalizedKey = 'testId';
11796
- }
11797
-
11798
- obj[normalizedKey] = attributes[key];
11799
- }
11800
- }
11801
-
11802
- return obj;
11803
- }
11804
-
11805
- const handleDomListener = (
11806
- replay,
11807
- ) => {
11808
- const slowClickExperiment = replay.getOptions()._experiments.slowClicks;
11809
-
11810
- const slowClickConfig = slowClickExperiment
11811
- ? {
11812
- threshold: slowClickExperiment.threshold,
11813
- timeout: slowClickExperiment.timeout,
11814
- scrollTimeout: slowClickExperiment.scrollTimeout,
11815
- ignoreSelector: slowClickExperiment.ignoreSelectors ? slowClickExperiment.ignoreSelectors.join(',') : '',
11816
- }
11817
- : undefined;
11818
-
11819
- return (handlerData) => {
11820
- if (!replay.isEnabled()) {
11821
- return;
11822
- }
11823
-
11824
- const result = handleDom(handlerData);
11825
-
11826
- if (!result) {
11827
- return;
11828
- }
11829
-
11830
- const isClick = handlerData.name === 'click';
11831
- const event = isClick && (handlerData.event );
11832
- // Ignore clicks if ctrl/alt/meta keys are held down as they alter behavior of clicks (e.g. open in new tab)
11833
- if (isClick && slowClickConfig && event && !event.altKey && !event.metaKey && !event.ctrlKey) {
11834
- detectSlowClick(
11835
- replay,
11836
- slowClickConfig,
11837
- result ,
11838
- getClickTargetNode(handlerData.event) ,
11839
- );
11840
- }
11841
-
11842
- addBreadcrumbEvent(replay, result);
11843
- };
11844
- };
11845
-
11846
- /** Get the base DOM breadcrumb. */
11847
- function getBaseDomBreadcrumb(target, message) {
11848
- // `__sn` property is the serialized node created by rrweb
11849
- const serializedNode = target && isRrwebNode(target) && target.__sn.type === NodeType.Element ? target.__sn : null;
11850
-
11851
- return {
11852
- message,
11853
- data: serializedNode
11854
- ? {
11855
- nodeId: serializedNode.id,
11856
- node: {
11857
- id: serializedNode.id,
11858
- tagName: serializedNode.tagName,
11859
- textContent: target
11860
- ? Array.from(target.childNodes)
11861
- .map(
11862
- (node) => '__sn' in node && node.__sn.type === NodeType.Text && node.__sn.textContent,
11863
- )
11864
- .filter(Boolean) // filter out empty values
11865
- .map(text => (text ).trim())
11866
- .join('')
11867
- : '',
11868
- attributes: getAttributesToRecord(serializedNode.attributes),
11869
- },
11870
- }
11871
- : {},
11872
- };
11873
- }
11874
-
11875
- /**
11876
- * An event handler to react to DOM events.
11877
- * Exported for tests.
11878
- */
11879
- function handleDom(handlerData) {
11880
- const { target, message } = getDomTarget(handlerData);
11881
-
11882
- return createBreadcrumb({
11883
- category: `ui.${handlerData.name}`,
11884
- ...getBaseDomBreadcrumb(target, message),
11885
- });
11886
- }
11887
-
11888
- function getDomTarget(handlerData) {
11889
- const isClick = handlerData.name === 'click';
11890
-
11891
- let message;
11892
- let target = null;
11893
-
11894
- // Accessing event.target can throw (see getsentry/raven-js#838, #768)
11895
- try {
11896
- target = isClick ? getClickTargetNode(handlerData.event) : getTargetNode(handlerData.event);
11897
- message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
11898
- } catch (e) {
11899
- message = '<unknown>';
11900
- }
11901
-
11902
- return { target, message };
11903
- }
11904
-
11905
- function isRrwebNode(node) {
11906
- return '__sn' in node;
11907
- }
11908
-
11909
- function getTargetNode(event) {
11910
- if (isEventWithTarget(event)) {
11911
- return event.target ;
11912
- }
11913
-
11914
- return event;
11915
- }
11916
-
11917
- const INTERACTIVE_SELECTOR = 'button,a';
11918
-
11919
- // For clicks, we check if the target is inside of a button or link
11920
- // If so, we use this as the target instead
11921
- // This is useful because if you click on the image in <button><img></button>,
11922
- // The target will be the image, not the button, which we don't want here
11923
- function getClickTargetNode(event) {
11924
- const target = getTargetNode(event);
11925
-
11926
- if (!target || !(target instanceof Element)) {
11927
- return target;
11928
- }
11929
-
11930
- const closestInteractive = target.closest(INTERACTIVE_SELECTOR);
11931
- return closestInteractive || target;
11932
- }
11933
-
11934
- function isEventWithTarget(event) {
11935
- return typeof event === 'object' && !!event && 'target' in event;
11936
- }
11937
-
11938
- /** Handle keyboard events & create breadcrumbs. */
11939
- function handleKeyboardEvent(replay, event) {
11940
- if (!replay.isEnabled()) {
11941
- return;
11942
- }
11943
-
11944
- replay.triggerUserActivity();
11945
-
11946
- const breadcrumb = getKeyboardBreadcrumb(event);
11947
-
11948
- if (!breadcrumb) {
11949
- return;
11950
- }
11951
-
11952
- addBreadcrumbEvent(replay, breadcrumb);
11953
- }
11954
-
11955
- /** exported only for tests */
11956
- function getKeyboardBreadcrumb(event) {
11957
- const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;
11958
-
11959
- // never capture for input fields
11960
- if (!target || isInputElement(target )) {
11961
- return null;
11962
- }
11963
-
11964
- // Note: We do not consider shift here, as that means "uppercase"
11965
- const hasModifierKey = metaKey || ctrlKey || altKey;
11966
- const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length
11967
-
11968
- // Do not capture breadcrumb if only a word key is pressed
11969
- // This could leak e.g. user input
11970
- if (!hasModifierKey && isCharacterKey) {
11971
- return null;
11972
- }
11973
-
11974
- const message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
11975
- const baseBreadcrumb = getBaseDomBreadcrumb(target , message);
11976
-
11977
- return createBreadcrumb({
11978
- category: 'ui.keyDown',
11979
- message,
11980
- data: {
11981
- ...baseBreadcrumb.data,
11982
- metaKey,
11983
- shiftKey,
11984
- ctrlKey,
11985
- altKey,
11986
- key,
11987
- },
11988
- });
11989
- }
11990
-
11991
- function isInputElement(target) {
11992
- return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
11993
- }
11994
-
11995
11320
  const NAVIGATION_ENTRY_KEYS = [
11996
11321
  'name',
11997
11322
  'type',
@@ -12145,19 +11470,20 @@ class EventBufferArray {
12145
11470
  return this.events.length > 0;
12146
11471
  }
12147
11472
 
12148
- /** @inheritdoc */
12149
- get type() {
12150
- return 'sync';
12151
- }
12152
-
12153
11473
  /** @inheritdoc */
12154
11474
  destroy() {
12155
11475
  this.events = [];
12156
11476
  }
12157
11477
 
12158
11478
  /** @inheritdoc */
12159
- async addEvent(event) {
11479
+ async addEvent(event, isCheckout) {
11480
+ if (isCheckout) {
11481
+ this.events = [event];
11482
+ return;
11483
+ }
11484
+
12160
11485
  this.events.push(event);
11486
+ return;
12161
11487
  }
12162
11488
 
12163
11489
  /** @inheritdoc */
@@ -12171,22 +11497,6 @@ class EventBufferArray {
12171
11497
  resolve(JSON.stringify(eventsRet));
12172
11498
  });
12173
11499
  }
12174
-
12175
- /** @inheritdoc */
12176
- clear() {
12177
- this.events = [];
12178
- }
12179
-
12180
- /** @inheritdoc */
12181
- getEarliestTimestamp() {
12182
- const timestamp = this.events.map(event => event.timestamp).sort()[0];
12183
-
12184
- if (!timestamp) {
12185
- return null;
12186
- }
12187
-
12188
- return timestampToMs(timestamp);
12189
- }
12190
11500
  }
12191
11501
 
12192
11502
  /**
@@ -12294,20 +11604,11 @@ class WorkerHandler {
12294
11604
  * Exported only for testing.
12295
11605
  */
12296
11606
  class EventBufferCompressionWorker {
11607
+ /** @inheritdoc */
12297
11608
 
12298
11609
  constructor(worker) {
12299
11610
  this._worker = new WorkerHandler(worker);
12300
- this._earliestTimestamp = null;
12301
- }
12302
-
12303
- /** @inheritdoc */
12304
- get hasEvents() {
12305
- return !!this._earliestTimestamp;
12306
- }
12307
-
12308
- /** @inheritdoc */
12309
- get type() {
12310
- return 'worker';
11611
+ this.hasEvents = false;
12311
11612
  }
12312
11613
 
12313
11614
  /**
@@ -12330,10 +11631,13 @@ class EventBufferCompressionWorker {
12330
11631
  *
12331
11632
  * Returns true if event was successfuly received and processed by worker.
12332
11633
  */
12333
- addEvent(event) {
12334
- const timestamp = timestampToMs(event.timestamp);
12335
- if (!this._earliestTimestamp || timestamp < this._earliestTimestamp) {
12336
- this._earliestTimestamp = timestamp;
11634
+ async addEvent(event, isCheckout) {
11635
+ this.hasEvents = true;
11636
+
11637
+ if (isCheckout) {
11638
+ // This event is a checkout, make sure worker buffer is cleared before
11639
+ // proceeding.
11640
+ await this._clear();
12337
11641
  }
12338
11642
 
12339
11643
  return this._sendEventToWorker(event);
@@ -12346,18 +11650,6 @@ class EventBufferCompressionWorker {
12346
11650
  return this._finishRequest();
12347
11651
  }
12348
11652
 
12349
- /** @inheritdoc */
12350
- clear() {
12351
- this._earliestTimestamp = null;
12352
- // We do not wait on this, as we assume the order of messages is consistent for the worker
12353
- void this._worker.postMessage('clear');
12354
- }
12355
-
12356
- /** @inheritdoc */
12357
- getEarliestTimestamp() {
12358
- return this._earliestTimestamp;
12359
- }
12360
-
12361
11653
  /**
12362
11654
  * Send the event to the worker.
12363
11655
  */
@@ -12371,10 +11663,15 @@ class EventBufferCompressionWorker {
12371
11663
  async _finishRequest() {
12372
11664
  const response = await this._worker.postMessage('finish');
12373
11665
 
12374
- this._earliestTimestamp = null;
11666
+ this.hasEvents = false;
12375
11667
 
12376
11668
  return response;
12377
11669
  }
11670
+
11671
+ /** Clear any pending events from the worker. */
11672
+ _clear() {
11673
+ return this._worker.postMessage('clear');
11674
+ }
12378
11675
  }
12379
11676
 
12380
11677
  /**
@@ -12392,11 +11689,6 @@ class EventBufferProxy {
12392
11689
  this._ensureWorkerIsLoadedPromise = this._ensureWorkerIsLoaded();
12393
11690
  }
12394
11691
 
12395
- /** @inheritdoc */
12396
- get type() {
12397
- return this._used.type;
12398
- }
12399
-
12400
11692
  /** @inheritDoc */
12401
11693
  get hasEvents() {
12402
11694
  return this._used.hasEvents;
@@ -12408,23 +11700,13 @@ class EventBufferProxy {
12408
11700
  this._compression.destroy();
12409
11701
  }
12410
11702
 
12411
- /** @inheritdoc */
12412
- clear() {
12413
- return this._used.clear();
12414
- }
12415
-
12416
- /** @inheritdoc */
12417
- getEarliestTimestamp() {
12418
- return this._used.getEarliestTimestamp();
12419
- }
12420
-
12421
11703
  /**
12422
11704
  * Add an event to the event buffer.
12423
11705
  *
12424
11706
  * Returns true if event was successfully added.
12425
11707
  */
12426
- addEvent(event) {
12427
- return this._used.addEvent(event);
11708
+ addEvent(event, isCheckout) {
11709
+ return this._used.addEvent(event, isCheckout);
12428
11710
  }
12429
11711
 
12430
11712
  /** @inheritDoc */
@@ -12499,31 +11781,6 @@ function createEventBuffer({ useCompression }) {
12499
11781
  return new EventBufferArray();
12500
11782
  }
12501
11783
 
12502
- /**
12503
- * Removes the session from Session Storage and unsets session in replay instance
12504
- */
12505
- function clearSession(replay) {
12506
- deleteSession();
12507
- replay.session = undefined;
12508
- }
12509
-
12510
- /**
12511
- * Deletes a session from storage
12512
- */
12513
- function deleteSession() {
12514
- const hasSessionStorage = 'sessionStorage' in WINDOW;
12515
-
12516
- if (!hasSessionStorage) {
12517
- return;
12518
- }
12519
-
12520
- try {
12521
- WINDOW.sessionStorage.removeItem(REPLAY_SESSION_KEY);
12522
- } catch (e) {
12523
- // Ignore potential SecurityError exceptions
12524
- }
12525
- }
12526
-
12527
11784
  /**
12528
11785
  * Given an initial timestamp and an expiry duration, checks to see if current
12529
11786
  * time should be considered as expired.
@@ -12554,26 +11811,11 @@ function isSessionExpired(session, timeouts, targetTime = +new Date()) {
12554
11811
  // First, check that maximum session length has not been exceeded
12555
11812
  isExpired(session.started, timeouts.maxSessionLife, targetTime) ||
12556
11813
  // check that the idle timeout has not been exceeded (i.e. user has
12557
- // performed an action within the last `sessionIdleExpire` ms)
12558
- isExpired(session.lastActivity, timeouts.sessionIdleExpire, targetTime)
11814
+ // performed an action within the last `idleTimeout` ms)
11815
+ isExpired(session.lastActivity, timeouts.sessionIdle, targetTime)
12559
11816
  );
12560
11817
  }
12561
11818
 
12562
- /**
12563
- * Given a sample rate, returns true if replay should be sampled.
12564
- *
12565
- * 1.0 = 100% sampling
12566
- * 0.0 = 0% sampling
12567
- */
12568
- function isSampled(sampleRate) {
12569
- if (sampleRate === undefined) {
12570
- return false;
12571
- }
12572
-
12573
- // Math.random() returns a number in range of 0 to 1 (inclusive of 0, but not 1)
12574
- return Math.random() < sampleRate;
12575
- }
12576
-
12577
11819
  /**
12578
11820
  * Save a session to session storage.
12579
11821
  */
@@ -12590,6 +11832,21 @@ function saveSession(session) {
12590
11832
  }
12591
11833
  }
12592
11834
 
11835
+ /**
11836
+ * Given a sample rate, returns true if replay should be sampled.
11837
+ *
11838
+ * 1.0 = 100% sampling
11839
+ * 0.0 = 0% sampling
11840
+ */
11841
+ function isSampled(sampleRate) {
11842
+ if (sampleRate === undefined) {
11843
+ return false;
11844
+ }
11845
+
11846
+ // Math.random() returns a number in range of 0 to 1 (inclusive of 0, but not 1)
11847
+ return Math.random() < sampleRate;
11848
+ }
11849
+
12593
11850
  /**
12594
11851
  * Get a session with defaults & applied sampling.
12595
11852
  */
@@ -12608,15 +11865,14 @@ function makeSession(session) {
12608
11865
  lastActivity,
12609
11866
  segmentId,
12610
11867
  sampled,
12611
- shouldRefresh: true,
12612
11868
  };
12613
11869
  }
12614
11870
 
12615
11871
  /**
12616
11872
  * Get the sampled status for a session based on sample rates & current sampled status.
12617
11873
  */
12618
- function getSessionSampleType(sessionSampleRate, allowBuffering) {
12619
- return isSampled(sessionSampleRate) ? 'session' : allowBuffering ? 'buffer' : false;
11874
+ function getSessionSampleType(sessionSampleRate, errorSampleRate) {
11875
+ return isSampled(sessionSampleRate) ? 'session' : isSampled(errorSampleRate) ? 'error' : false;
12620
11876
  }
12621
11877
 
12622
11878
  /**
@@ -12624,8 +11880,8 @@ function getSessionSampleType(sessionSampleRate, allowBuffering) {
12624
11880
  * that all replays will be saved to as attachments. Currently, we only expect
12625
11881
  * one of these Sentry events per "replay session".
12626
11882
  */
12627
- function createSession({ sessionSampleRate, allowBuffering, stickySession = false }) {
12628
- const sampled = getSessionSampleType(sessionSampleRate, allowBuffering);
11883
+ function createSession({ sessionSampleRate, errorSampleRate, stickySession = false }) {
11884
+ const sampled = getSessionSampleType(sessionSampleRate, errorSampleRate);
12629
11885
  const session = makeSession({
12630
11886
  sampled,
12631
11887
  });
@@ -12673,7 +11929,7 @@ function getSession({
12673
11929
  currentSession,
12674
11930
  stickySession,
12675
11931
  sessionSampleRate,
12676
- allowBuffering,
11932
+ errorSampleRate,
12677
11933
  }) {
12678
11934
  // If session exists and is passed, use it instead of always hitting session storage
12679
11935
  const session = currentSession || (stickySession && fetchSession());
@@ -12686,9 +11942,8 @@ function getSession({
12686
11942
 
12687
11943
  if (!isExpired) {
12688
11944
  return { type: 'saved', session };
12689
- } else if (!session.shouldRefresh) {
12690
- // In this case, stop
12691
- // This is the case if we have an error session that is completed (=triggered an error)
11945
+ } else if (session.sampled === 'error') {
11946
+ // Error samples should not be re-created when expired, but instead we stop when the replay is done
12692
11947
  const discardedSession = makeSession({ sampled: false });
12693
11948
  return { type: 'new', session: discardedSession };
12694
11949
  } else {
@@ -12700,12 +11955,65 @@ function getSession({
12700
11955
  const newSession = createSession({
12701
11956
  stickySession,
12702
11957
  sessionSampleRate,
12703
- allowBuffering,
11958
+ errorSampleRate,
12704
11959
  });
12705
11960
 
12706
11961
  return { type: 'new', session: newSession };
12707
11962
  }
12708
11963
 
11964
+ /**
11965
+ * Add an event to the event buffer.
11966
+ * `isCheckout` is true if this is either the very first event, or an event triggered by `checkoutEveryNms`.
11967
+ */
11968
+ async function addEvent(
11969
+ replay,
11970
+ event,
11971
+ isCheckout,
11972
+ ) {
11973
+ if (!replay.eventBuffer) {
11974
+ // This implies that `_isEnabled` is false
11975
+ return null;
11976
+ }
11977
+
11978
+ if (replay.isPaused()) {
11979
+ // Do not add to event buffer when recording is paused
11980
+ return null;
11981
+ }
11982
+
11983
+ // TODO: sadness -- we will want to normalize timestamps to be in ms -
11984
+ // requires coordination with frontend
11985
+ const isMs = event.timestamp > 9999999999;
11986
+ const timestampInMs = isMs ? event.timestamp : event.timestamp * 1000;
11987
+
11988
+ // Throw out events that happen more than 5 minutes ago. This can happen if
11989
+ // page has been left open and idle for a long period of time and user
11990
+ // comes back to trigger a new session. The performance entries rely on
11991
+ // `performance.timeOrigin`, which is when the page first opened.
11992
+ if (timestampInMs + replay.timeouts.sessionIdle < Date.now()) {
11993
+ return null;
11994
+ }
11995
+
11996
+ // Only record earliest event if a new session was created, otherwise it
11997
+ // shouldn't be relevant
11998
+ const earliestEvent = replay.getContext().earliestEvent;
11999
+ if (replay.session && replay.session.segmentId === 0 && (!earliestEvent || timestampInMs < earliestEvent)) {
12000
+ replay.getContext().earliestEvent = timestampInMs;
12001
+ }
12002
+
12003
+ try {
12004
+ return await replay.eventBuffer.addEvent(event, isCheckout);
12005
+ } catch (error) {
12006
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error(error);
12007
+ replay.stop('addEvent');
12008
+
12009
+ const client = getCurrentHub().getClient();
12010
+
12011
+ if (client) {
12012
+ client.recordDroppedEvent('internal_sdk_error', 'replay');
12013
+ }
12014
+ }
12015
+ }
12016
+
12709
12017
  /** If the event is an error event */
12710
12018
  function isErrorEvent(event) {
12711
12019
  return !event.type;
@@ -12755,21 +12063,31 @@ function handleAfterSendEvent(replay) {
12755
12063
  return;
12756
12064
  }
12757
12065
 
12758
- // Add error to list of errorIds of replay. This is ok to do even if not
12759
- // sampled because context will get reset at next checkout.
12760
- // XXX: There is also a race condition where it's possible to capture an
12761
- // error to Sentry before Replay SDK has loaded, but response returns after
12762
- // it was loaded, and this gets called.
12066
+ // Add error to list of errorIds of replay
12763
12067
  if (event.event_id) {
12764
12068
  replay.getContext().errorIds.add(event.event_id);
12765
12069
  }
12766
12070
 
12767
- // If error event is tagged with replay id it means it was sampled (when in buffer mode)
12071
+ // Trigger error recording
12768
12072
  // Need to be very careful that this does not cause an infinite loop
12769
- if (replay.recordingMode === 'buffer' && event.tags && event.tags.replayId) {
12770
- setTimeout(() => {
12771
- // Capture current event buffer as new replay
12772
- void replay.sendBufferedReplayOrFlush();
12073
+ if (
12074
+ replay.recordingMode === 'error' &&
12075
+ event.exception &&
12076
+ event.message !== UNABLE_TO_SEND_REPLAY // ignore this error because otherwise we could loop indefinitely with trying to capture replay and failing
12077
+ ) {
12078
+ setTimeout(async () => {
12079
+ // Allow flush to complete before resuming as a session recording, otherwise
12080
+ // the checkout from `startRecording` may be included in the payload.
12081
+ // Prefer to keep the error replay as a separate (and smaller) segment
12082
+ // than the session replay.
12083
+ await replay.flushImmediate();
12084
+
12085
+ if (replay.stopRecording()) {
12086
+ // Reset all "capture on error" configuration before
12087
+ // starting a new recording
12088
+ replay.recordingMode = 'session';
12089
+ replay.startRecording();
12090
+ }
12773
12091
  });
12774
12092
  }
12775
12093
  };
@@ -12791,6 +12109,166 @@ function isBaseTransportSend() {
12791
12109
  );
12792
12110
  }
12793
12111
 
12112
+ var NodeType;
12113
+ (function (NodeType) {
12114
+ NodeType[NodeType["Document"] = 0] = "Document";
12115
+ NodeType[NodeType["DocumentType"] = 1] = "DocumentType";
12116
+ NodeType[NodeType["Element"] = 2] = "Element";
12117
+ NodeType[NodeType["Text"] = 3] = "Text";
12118
+ NodeType[NodeType["CDATA"] = 4] = "CDATA";
12119
+ NodeType[NodeType["Comment"] = 5] = "Comment";
12120
+ })(NodeType || (NodeType = {}));
12121
+
12122
+ /**
12123
+ * Create a breadcrumb for a replay.
12124
+ */
12125
+ function createBreadcrumb(
12126
+ breadcrumb,
12127
+ ) {
12128
+ return {
12129
+ timestamp: Date.now() / 1000,
12130
+ type: 'default',
12131
+ ...breadcrumb,
12132
+ };
12133
+ }
12134
+
12135
+ /**
12136
+ * Add a breadcrumb event to replay.
12137
+ */
12138
+ function addBreadcrumbEvent(replay, breadcrumb) {
12139
+ if (breadcrumb.category === 'sentry.transaction') {
12140
+ return;
12141
+ }
12142
+
12143
+ if (['ui.click', 'ui.input'].includes(breadcrumb.category )) {
12144
+ replay.triggerUserActivity();
12145
+ } else {
12146
+ replay.checkAndHandleExpiredSession();
12147
+ }
12148
+
12149
+ replay.addUpdate(() => {
12150
+ void addEvent(replay, {
12151
+ type: EventType.Custom,
12152
+ // TODO: We were converting from ms to seconds for breadcrumbs, spans,
12153
+ // but maybe we should just keep them as milliseconds
12154
+ timestamp: (breadcrumb.timestamp || 0) * 1000,
12155
+ data: {
12156
+ tag: 'breadcrumb',
12157
+ payload: breadcrumb,
12158
+ },
12159
+ });
12160
+
12161
+ // Do not flush after console log messages
12162
+ return breadcrumb.category === 'console';
12163
+ });
12164
+ }
12165
+
12166
+ // Note that these are the serialized attributes and not attributes directly on
12167
+ // the DOM Node. Attributes we are interested in:
12168
+ const ATTRIBUTES_TO_RECORD = new Set([
12169
+ 'id',
12170
+ 'class',
12171
+ 'aria-label',
12172
+ 'role',
12173
+ 'name',
12174
+ 'alt',
12175
+ 'title',
12176
+ 'data-test-id',
12177
+ 'data-testid',
12178
+ ]);
12179
+
12180
+ /**
12181
+ * Inclusion list of attributes that we want to record from the DOM element
12182
+ */
12183
+ function getAttributesToRecord(attributes) {
12184
+ const obj = {};
12185
+ for (const key in attributes) {
12186
+ if (ATTRIBUTES_TO_RECORD.has(key)) {
12187
+ let normalizedKey = key;
12188
+
12189
+ if (key === 'data-testid' || key === 'data-test-id') {
12190
+ normalizedKey = 'testId';
12191
+ }
12192
+
12193
+ obj[normalizedKey] = attributes[key];
12194
+ }
12195
+ }
12196
+
12197
+ return obj;
12198
+ }
12199
+
12200
+ const handleDomListener =
12201
+ (replay) =>
12202
+ (handlerData) => {
12203
+ if (!replay.isEnabled()) {
12204
+ return;
12205
+ }
12206
+
12207
+ const result = handleDom(handlerData);
12208
+
12209
+ if (!result) {
12210
+ return;
12211
+ }
12212
+
12213
+ addBreadcrumbEvent(replay, result);
12214
+ };
12215
+
12216
+ /**
12217
+ * An event handler to react to DOM events.
12218
+ */
12219
+ function handleDom(handlerData) {
12220
+ let target;
12221
+ let targetNode;
12222
+
12223
+ // Accessing event.target can throw (see getsentry/raven-js#838, #768)
12224
+ try {
12225
+ targetNode = getTargetNode(handlerData);
12226
+ target = htmlTreeAsString(targetNode);
12227
+ } catch (e) {
12228
+ target = '<unknown>';
12229
+ }
12230
+
12231
+ // `__sn` property is the serialized node created by rrweb
12232
+ const serializedNode =
12233
+ targetNode && '__sn' in targetNode && targetNode.__sn.type === NodeType.Element ? targetNode.__sn : null;
12234
+
12235
+ return createBreadcrumb({
12236
+ category: `ui.${handlerData.name}`,
12237
+ message: target,
12238
+ data: serializedNode
12239
+ ? {
12240
+ nodeId: serializedNode.id,
12241
+ node: {
12242
+ id: serializedNode.id,
12243
+ tagName: serializedNode.tagName,
12244
+ textContent: targetNode
12245
+ ? Array.from(targetNode.childNodes)
12246
+ .map(
12247
+ (node) => '__sn' in node && node.__sn.type === NodeType.Text && node.__sn.textContent,
12248
+ )
12249
+ .filter(Boolean) // filter out empty values
12250
+ .map(text => (text ).trim())
12251
+ .join('')
12252
+ : '',
12253
+ attributes: getAttributesToRecord(serializedNode.attributes),
12254
+ },
12255
+ }
12256
+ : {},
12257
+ });
12258
+ }
12259
+
12260
+ function getTargetNode(handlerData) {
12261
+ if (isEventWithTarget(handlerData.event)) {
12262
+ return handlerData.event.target;
12263
+ }
12264
+
12265
+ return handlerData.event;
12266
+ }
12267
+
12268
+ function isEventWithTarget(event) {
12269
+ return !!(event ).target;
12270
+ }
12271
+
12794
12272
  /**
12795
12273
  * Returns true if we think the given event is an error originating inside of rrweb.
12796
12274
  */
@@ -12814,30 +12292,6 @@ function isRrwebError(event, hint) {
12814
12292
  });
12815
12293
  }
12816
12294
 
12817
- /**
12818
- * Determine if event should be sampled (only applies in buffer mode).
12819
- * When an event is captured by `hanldleGlobalEvent`, when in buffer mode
12820
- * we determine if we want to sample the error or not.
12821
- */
12822
- function shouldSampleForBufferEvent(replay, event) {
12823
- if (replay.recordingMode !== 'buffer') {
12824
- return false;
12825
- }
12826
-
12827
- // ignore this error because otherwise we could loop indefinitely with
12828
- // trying to capture replay and failing
12829
- if (event.message === UNABLE_TO_SEND_REPLAY) {
12830
- return false;
12831
- }
12832
-
12833
- // Require the event to be an error event & to have an exception
12834
- if (!event.exception || event.type) {
12835
- return false;
12836
- }
12837
-
12838
- return isSampled(replay.getOptions().errorSampleRate);
12839
- }
12840
-
12841
12295
  /**
12842
12296
  * Returns a listener to be added to `addGlobalEventProcessor(listener)`.
12843
12297
  */
@@ -12867,16 +12321,8 @@ function handleGlobalEventListener(
12867
12321
  return null;
12868
12322
  }
12869
12323
 
12870
- // When in buffer mode, we decide to sample here.
12871
- // Later, in `handleAfterSendEvent`, if the replayId is set, we know that we sampled
12872
- // And convert the buffer session to a full session
12873
- const isErrorEventSampled = shouldSampleForBufferEvent(replay, event);
12874
-
12875
- // Tag errors if it has been sampled in buffer mode, or if it is session mode
12876
- // Only tag transactions if in session mode
12877
- const shouldTagReplayId = isErrorEventSampled || replay.recordingMode === 'session';
12878
-
12879
- if (shouldTagReplayId) {
12324
+ // Only tag transactions with replayId if not waiting for an error
12325
+ if (isErrorEvent(event) || (isTransactionEvent(event) && replay.recordingMode === 'session')) {
12880
12326
  event.tags = { ...event.tags, replayId: replay.getSessionId() };
12881
12327
  }
12882
12328
 
@@ -12926,7 +12372,7 @@ function createPerformanceSpans(
12926
12372
  ) {
12927
12373
  return entries.map(({ type, start, end, name, data }) =>
12928
12374
  addEvent(replay, {
12929
- type: EventType$1.Custom,
12375
+ type: EventType.Custom,
12930
12376
  timestamp: start,
12931
12377
  data: {
12932
12378
  tag: 'performanceSpan',
@@ -13075,14 +12521,12 @@ function handleFetchSpanListener(replay) {
13075
12521
  function handleXhr(handlerData) {
13076
12522
  const { startTimestamp, endTimestamp, xhr } = handlerData;
13077
12523
 
13078
- const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];
13079
-
13080
- if (!startTimestamp || !endTimestamp || !sentryXhrData) {
12524
+ if (!startTimestamp || !endTimestamp || !xhr.__sentry_xhr__) {
13081
12525
  return null;
13082
12526
  }
13083
12527
 
13084
12528
  // This is only used as a fallback, so we know the body sizes are never set here
13085
- const { method, url, status_code: statusCode } = sentryXhrData;
12529
+ const { method, url, status_code: statusCode } = xhr.__sentry_xhr__;
13086
12530
 
13087
12531
  if (url === undefined) {
13088
12532
  return null;
@@ -13115,393 +12559,6 @@ function handleXhrSpanListener(replay) {
13115
12559
  };
13116
12560
  }
13117
12561
 
13118
- const OBJ = 10;
13119
- const OBJ_KEY = 11;
13120
- const OBJ_KEY_STR = 12;
13121
- const OBJ_VAL = 13;
13122
- const OBJ_VAL_STR = 14;
13123
- const OBJ_VAL_COMPLETED = 15;
13124
-
13125
- const ARR = 20;
13126
- const ARR_VAL = 21;
13127
- const ARR_VAL_STR = 22;
13128
- const ARR_VAL_COMPLETED = 23;
13129
-
13130
- const ALLOWED_PRIMITIVES = ['true', 'false', 'null'];
13131
-
13132
- /**
13133
- * Complete an incomplete JSON string.
13134
- * This will ensure that the last element always has a `"~~"` to indicate it was truncated.
13135
- * For example, `[1,2,` will be completed to `[1,2,"~~"]`
13136
- * and `{"aa":"b` will be completed to `{"aa":"b~~"}`
13137
- */
13138
- function completeJson(incompleteJson, stack) {
13139
- if (!stack.length) {
13140
- return incompleteJson;
13141
- }
13142
-
13143
- let json = incompleteJson;
13144
-
13145
- // Most checks are only needed for the last step in the stack
13146
- const lastPos = stack.length - 1;
13147
- const lastStep = stack[lastPos];
13148
-
13149
- json = _fixLastStep(json, lastStep);
13150
-
13151
- // Complete remaining steps - just add closing brackets
13152
- for (let i = lastPos; i >= 0; i--) {
13153
- const step = stack[i];
13154
-
13155
- switch (step) {
13156
- case OBJ:
13157
- json = `${json}}`;
13158
- break;
13159
- case ARR:
13160
- json = `${json}]`;
13161
- break;
13162
- }
13163
- }
13164
-
13165
- return json;
13166
- }
13167
-
13168
- function _fixLastStep(json, lastStep) {
13169
- switch (lastStep) {
13170
- // Object cases
13171
- case OBJ:
13172
- return `${json}"~~":"~~"`;
13173
- case OBJ_KEY:
13174
- return `${json}:"~~"`;
13175
- case OBJ_KEY_STR:
13176
- return `${json}~~":"~~"`;
13177
- case OBJ_VAL:
13178
- return _maybeFixIncompleteObjValue(json);
13179
- case OBJ_VAL_STR:
13180
- return `${json}~~"`;
13181
- case OBJ_VAL_COMPLETED:
13182
- return `${json},"~~":"~~"`;
13183
-
13184
- // Array cases
13185
- case ARR:
13186
- return `${json}"~~"`;
13187
- case ARR_VAL:
13188
- return _maybeFixIncompleteArrValue(json);
13189
- case ARR_VAL_STR:
13190
- return `${json}~~"`;
13191
- case ARR_VAL_COMPLETED:
13192
- return `${json},"~~"`;
13193
- }
13194
-
13195
- return json;
13196
- }
13197
-
13198
- function _maybeFixIncompleteArrValue(json) {
13199
- const pos = _findLastArrayDelimiter(json);
13200
-
13201
- if (pos > -1) {
13202
- const part = json.slice(pos + 1);
13203
-
13204
- if (ALLOWED_PRIMITIVES.includes(part.trim())) {
13205
- return `${json},"~~"`;
13206
- }
13207
-
13208
- // Everything else is replaced with `"~~"`
13209
- return `${json.slice(0, pos + 1)}"~~"`;
13210
- }
13211
-
13212
- // fallback, this shouldn't happen, to be save
13213
- return json;
13214
- }
13215
-
13216
- function _findLastArrayDelimiter(json) {
13217
- for (let i = json.length - 1; i >= 0; i--) {
13218
- const char = json[i];
13219
-
13220
- if (char === ',' || char === '[') {
13221
- return i;
13222
- }
13223
- }
13224
-
13225
- return -1;
13226
- }
13227
-
13228
- function _maybeFixIncompleteObjValue(json) {
13229
- const startPos = json.lastIndexOf(':');
13230
-
13231
- const part = json.slice(startPos + 1);
13232
-
13233
- if (ALLOWED_PRIMITIVES.includes(part.trim())) {
13234
- return `${json},"~~":"~~"`;
13235
- }
13236
-
13237
- // Everything else is replaced with `"~~"`
13238
- // This also means we do not have incomplete numbers, e.g `[1` is replaced with `["~~"]`
13239
- return `${json.slice(0, startPos + 1)}"~~"`;
13240
- }
13241
-
13242
- /**
13243
- * Evaluate an (incomplete) JSON string.
13244
- */
13245
- function evaluateJson(json) {
13246
- const stack = [];
13247
-
13248
- for (let pos = 0; pos < json.length; pos++) {
13249
- _evaluateJsonPos(stack, json, pos);
13250
- }
13251
-
13252
- return stack;
13253
- }
13254
-
13255
- function _evaluateJsonPos(stack, json, pos) {
13256
- const curStep = stack[stack.length - 1];
13257
-
13258
- const char = json[pos];
13259
-
13260
- const whitespaceRegex = /\s/;
13261
-
13262
- if (whitespaceRegex.test(char)) {
13263
- return;
13264
- }
13265
-
13266
- if (char === '"' && !_isEscaped(json, pos)) {
13267
- _handleQuote(stack, curStep);
13268
- return;
13269
- }
13270
-
13271
- switch (char) {
13272
- case '{':
13273
- _handleObj(stack, curStep);
13274
- break;
13275
- case '[':
13276
- _handleArr(stack, curStep);
13277
- break;
13278
- case ':':
13279
- _handleColon(stack, curStep);
13280
- break;
13281
- case ',':
13282
- _handleComma(stack, curStep);
13283
- break;
13284
- case '}':
13285
- _handleObjClose(stack, curStep);
13286
- break;
13287
- case ']':
13288
- _handleArrClose(stack, curStep);
13289
- break;
13290
- }
13291
- }
13292
-
13293
- function _handleQuote(stack, curStep) {
13294
- // End of obj value
13295
- if (curStep === OBJ_VAL_STR) {
13296
- stack.pop();
13297
- stack.push(OBJ_VAL_COMPLETED);
13298
- return;
13299
- }
13300
-
13301
- // End of arr value
13302
- if (curStep === ARR_VAL_STR) {
13303
- stack.pop();
13304
- stack.push(ARR_VAL_COMPLETED);
13305
- return;
13306
- }
13307
-
13308
- // Start of obj value
13309
- if (curStep === OBJ_VAL) {
13310
- stack.push(OBJ_VAL_STR);
13311
- return;
13312
- }
13313
-
13314
- // Start of arr value
13315
- if (curStep === ARR_VAL) {
13316
- stack.push(ARR_VAL_STR);
13317
- return;
13318
- }
13319
-
13320
- // Start of obj key
13321
- if (curStep === OBJ) {
13322
- stack.push(OBJ_KEY_STR);
13323
- return;
13324
- }
13325
-
13326
- // End of obj key
13327
- if (curStep === OBJ_KEY_STR) {
13328
- stack.pop();
13329
- stack.push(OBJ_KEY);
13330
- return;
13331
- }
13332
- }
13333
-
13334
- function _handleObj(stack, curStep) {
13335
- // Initial object
13336
- if (!curStep) {
13337
- stack.push(OBJ);
13338
- return;
13339
- }
13340
-
13341
- // New object as obj value
13342
- if (curStep === OBJ_VAL) {
13343
- stack.push(OBJ);
13344
- return;
13345
- }
13346
-
13347
- // New object as array element
13348
- if (curStep === ARR_VAL) {
13349
- stack.push(OBJ);
13350
- }
13351
-
13352
- // New object as first array element
13353
- if (curStep === ARR) {
13354
- stack.push(OBJ);
13355
- return;
13356
- }
13357
- }
13358
-
13359
- function _handleArr(stack, curStep) {
13360
- // Initial array
13361
- if (!curStep) {
13362
- stack.push(ARR);
13363
- stack.push(ARR_VAL);
13364
- return;
13365
- }
13366
-
13367
- // New array as obj value
13368
- if (curStep === OBJ_VAL) {
13369
- stack.push(ARR);
13370
- stack.push(ARR_VAL);
13371
- return;
13372
- }
13373
-
13374
- // New array as array element
13375
- if (curStep === ARR_VAL) {
13376
- stack.push(ARR);
13377
- stack.push(ARR_VAL);
13378
- }
13379
-
13380
- // New array as first array element
13381
- if (curStep === ARR) {
13382
- stack.push(ARR);
13383
- stack.push(ARR_VAL);
13384
- return;
13385
- }
13386
- }
13387
-
13388
- function _handleColon(stack, curStep) {
13389
- if (curStep === OBJ_KEY) {
13390
- stack.pop();
13391
- stack.push(OBJ_VAL);
13392
- }
13393
- }
13394
-
13395
- function _handleComma(stack, curStep) {
13396
- // Comma after obj value
13397
- if (curStep === OBJ_VAL) {
13398
- stack.pop();
13399
- return;
13400
- }
13401
- if (curStep === OBJ_VAL_COMPLETED) {
13402
- // Pop OBJ_VAL_COMPLETED & OBJ_VAL
13403
- stack.pop();
13404
- stack.pop();
13405
- return;
13406
- }
13407
-
13408
- // Comma after arr value
13409
- if (curStep === ARR_VAL) {
13410
- // do nothing - basically we'd pop ARR_VAL but add it right back
13411
- return;
13412
- }
13413
-
13414
- if (curStep === ARR_VAL_COMPLETED) {
13415
- // Pop ARR_VAL_COMPLETED
13416
- stack.pop();
13417
-
13418
- // basically we'd pop ARR_VAL but add it right back
13419
- return;
13420
- }
13421
- }
13422
-
13423
- function _handleObjClose(stack, curStep) {
13424
- // Empty object {}
13425
- if (curStep === OBJ) {
13426
- stack.pop();
13427
- }
13428
-
13429
- // Object with element
13430
- if (curStep === OBJ_VAL) {
13431
- // Pop OBJ_VAL, OBJ
13432
- stack.pop();
13433
- stack.pop();
13434
- }
13435
-
13436
- // Obj with element
13437
- if (curStep === OBJ_VAL_COMPLETED) {
13438
- // Pop OBJ_VAL_COMPLETED, OBJ_VAL, OBJ
13439
- stack.pop();
13440
- stack.pop();
13441
- stack.pop();
13442
- }
13443
-
13444
- // if was obj value, complete it
13445
- if (stack[stack.length - 1] === OBJ_VAL) {
13446
- stack.push(OBJ_VAL_COMPLETED);
13447
- }
13448
-
13449
- // if was arr value, complete it
13450
- if (stack[stack.length - 1] === ARR_VAL) {
13451
- stack.push(ARR_VAL_COMPLETED);
13452
- }
13453
- }
13454
-
13455
- function _handleArrClose(stack, curStep) {
13456
- // Empty array []
13457
- if (curStep === ARR) {
13458
- stack.pop();
13459
- }
13460
-
13461
- // Array with element
13462
- if (curStep === ARR_VAL) {
13463
- // Pop ARR_VAL, ARR
13464
- stack.pop();
13465
- stack.pop();
13466
- }
13467
-
13468
- // Array with element
13469
- if (curStep === ARR_VAL_COMPLETED) {
13470
- // Pop ARR_VAL_COMPLETED, ARR_VAL, ARR
13471
- stack.pop();
13472
- stack.pop();
13473
- stack.pop();
13474
- }
13475
-
13476
- // if was obj value, complete it
13477
- if (stack[stack.length - 1] === OBJ_VAL) {
13478
- stack.push(OBJ_VAL_COMPLETED);
13479
- }
13480
-
13481
- // if was arr value, complete it
13482
- if (stack[stack.length - 1] === ARR_VAL) {
13483
- stack.push(ARR_VAL_COMPLETED);
13484
- }
13485
- }
13486
-
13487
- function _isEscaped(str, pos) {
13488
- const previousChar = str[pos - 1];
13489
-
13490
- return previousChar === '\\' && !_isEscaped(str, pos - 1);
13491
- }
13492
-
13493
- /* eslint-disable max-lines */
13494
-
13495
- /**
13496
- * Takes an incomplete JSON string, and returns a hopefully valid JSON string.
13497
- * Note that this _can_ fail, so you should check the return value is valid JSON.
13498
- */
13499
- function fixJson(incompleteJson) {
13500
- const stack = evaluateJson(incompleteJson);
13501
-
13502
- return completeJson(incompleteJson, stack);
13503
- }
13504
-
13505
12562
  /** Get the size of a body. */
13506
12563
  function getBodySize(
13507
12564
  body,
@@ -13595,68 +12652,51 @@ function makeNetworkReplayBreadcrumb(
13595
12652
  return result;
13596
12653
  }
13597
12654
 
13598
- /** Build the request or response part of a replay network breadcrumb that was skipped. */
13599
- function buildSkippedNetworkRequestOrResponse(bodySize) {
13600
- return {
13601
- headers: {},
13602
- size: bodySize,
13603
- _meta: {
13604
- warnings: ['URL_SKIPPED'],
13605
- },
13606
- };
12655
+ /** Get either a JSON network body, or a text representation. */
12656
+ function getNetworkBody(bodyText) {
12657
+ if (!bodyText) {
12658
+ return;
12659
+ }
12660
+
12661
+ try {
12662
+ return JSON.parse(bodyText);
12663
+ } catch (e2) {
12664
+ // return text
12665
+ }
12666
+
12667
+ return bodyText;
13607
12668
  }
13608
12669
 
13609
12670
  /** Build the request or response part of a replay network breadcrumb. */
13610
12671
  function buildNetworkRequestOrResponse(
13611
- headers,
13612
12672
  bodySize,
13613
12673
  body,
13614
12674
  ) {
13615
- if (!bodySize && Object.keys(headers).length === 0) {
13616
- return undefined;
13617
- }
13618
-
13619
12675
  if (!bodySize) {
13620
- return {
13621
- headers,
13622
- };
12676
+ return undefined;
13623
12677
  }
13624
12678
 
13625
12679
  if (!body) {
13626
12680
  return {
13627
- headers,
13628
12681
  size: bodySize,
13629
12682
  };
13630
12683
  }
13631
12684
 
13632
12685
  const info = {
13633
- headers,
13634
12686
  size: bodySize,
13635
12687
  };
13636
12688
 
13637
- const { body: normalizedBody, warnings } = normalizeNetworkBody(body);
13638
- info.body = normalizedBody;
13639
- if (warnings.length > 0) {
12689
+ if (bodySize < NETWORK_BODY_MAX_SIZE) {
12690
+ info.body = body;
12691
+ } else {
13640
12692
  info._meta = {
13641
- warnings,
12693
+ errors: ['MAX_BODY_SIZE_EXCEEDED'],
13642
12694
  };
13643
12695
  }
13644
12696
 
13645
12697
  return info;
13646
12698
  }
13647
12699
 
13648
- /** Filter a set of headers */
13649
- function getAllowedHeaders(headers, allowedHeaders) {
13650
- return Object.keys(headers).reduce((filteredHeaders, key) => {
13651
- const normalizedKey = key.toLowerCase();
13652
- // Avoid putting empty strings into the headers
13653
- if (allowedHeaders.includes(normalizedKey) && headers[key]) {
13654
- filteredHeaders[normalizedKey] = headers[key];
13655
- }
13656
- return filteredHeaders;
13657
- }, {});
13658
- }
13659
-
13660
12700
  function _serializeFormData(formData) {
13661
12701
  // This is a bit simplified, but gives us a decent estimate
13662
12702
  // This converts e.g. { name: 'Anne Smith', age: 13 } to 'name=Anne+Smith&age=13'
@@ -13664,78 +12704,6 @@ function _serializeFormData(formData) {
13664
12704
  return new URLSearchParams(formData).toString();
13665
12705
  }
13666
12706
 
13667
- function normalizeNetworkBody(body)
13668
-
13669
- {
13670
- if (!body || typeof body !== 'string') {
13671
- return {
13672
- body,
13673
- warnings: [],
13674
- };
13675
- }
13676
-
13677
- const exceedsSizeLimit = body.length > NETWORK_BODY_MAX_SIZE;
13678
-
13679
- if (_strIsProbablyJson(body)) {
13680
- try {
13681
- const json = exceedsSizeLimit ? fixJson(body.slice(0, NETWORK_BODY_MAX_SIZE)) : body;
13682
- const normalizedBody = JSON.parse(json);
13683
- return {
13684
- body: normalizedBody,
13685
- warnings: exceedsSizeLimit ? ['JSON_TRUNCATED'] : [],
13686
- };
13687
- } catch (e3) {
13688
- return {
13689
- body: exceedsSizeLimit ? `${body.slice(0, NETWORK_BODY_MAX_SIZE)}…` : body,
13690
- warnings: exceedsSizeLimit ? ['INVALID_JSON', 'TEXT_TRUNCATED'] : ['INVALID_JSON'],
13691
- };
13692
- }
13693
- }
13694
-
13695
- return {
13696
- body: exceedsSizeLimit ? `${body.slice(0, NETWORK_BODY_MAX_SIZE)}…` : body,
13697
- warnings: exceedsSizeLimit ? ['TEXT_TRUNCATED'] : [],
13698
- };
13699
- }
13700
-
13701
- function _strIsProbablyJson(str) {
13702
- const first = str[0];
13703
- const last = str[str.length - 1];
13704
-
13705
- // Simple check: If this does not start & end with {} or [], it's not JSON
13706
- return (first === '[' && last === ']') || (first === '{' && last === '}');
13707
- }
13708
-
13709
- /** Match an URL against a list of strings/Regex. */
13710
- function urlMatches(url, urls) {
13711
- const fullUrl = getFullUrl(url);
13712
-
13713
- return stringMatchesSomePattern(fullUrl, urls);
13714
- }
13715
-
13716
- /** exported for tests */
13717
- function getFullUrl(url, baseURI = WINDOW.document.baseURI) {
13718
- // Short circuit for common cases:
13719
- if (url.startsWith('http://') || url.startsWith('https://') || url.startsWith(WINDOW.location.origin)) {
13720
- return url;
13721
- }
13722
- const fixedUrl = new URL(url, baseURI);
13723
-
13724
- // If these do not match, we are not dealing with a relative URL, so just return it
13725
- if (fixedUrl.origin !== new URL(baseURI).origin) {
13726
- return url;
13727
- }
13728
-
13729
- const fullUrl = fixedUrl.href;
13730
-
13731
- // Remove trailing slashes, if they don't match the original URL
13732
- if (!url.endsWith('/') && fullUrl.endsWith('/')) {
13733
- return fullUrl.slice(0, -1);
13734
- }
13735
-
13736
- return fullUrl;
13737
- }
13738
-
13739
12707
  /**
13740
12708
  * Capture a fetch breadcrumb to a replay.
13741
12709
  * This adds additional data (where approriate).
@@ -13743,9 +12711,7 @@ function getFullUrl(url, baseURI = WINDOW.document.baseURI) {
13743
12711
  async function captureFetchBreadcrumbToReplay(
13744
12712
  breadcrumb,
13745
12713
  hint,
13746
- options
13747
-
13748
- ,
12714
+ options,
13749
12715
  ) {
13750
12716
  try {
13751
12717
  const data = await _prepareFetchData(breadcrumb, hint, options);
@@ -13772,7 +12738,6 @@ function enrichFetchBreadcrumb(
13772
12738
 
13773
12739
  const body = _getFetchRequestArgBody(input);
13774
12740
  const reqSize = getBodySize(body, options.textEncoder);
13775
-
13776
12741
  const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
13777
12742
 
13778
12743
  if (reqSize !== undefined) {
@@ -13786,109 +12751,97 @@ function enrichFetchBreadcrumb(
13786
12751
  async function _prepareFetchData(
13787
12752
  breadcrumb,
13788
12753
  hint,
13789
- options
13790
-
13791
- ,
12754
+ options,
13792
12755
  ) {
13793
12756
  const { startTimestamp, endTimestamp } = hint;
13794
12757
 
13795
12758
  const {
13796
12759
  url,
13797
12760
  method,
13798
- status_code: statusCode = 0,
12761
+ status_code: statusCode,
13799
12762
  request_body_size: requestBodySize,
13800
12763
  response_body_size: responseBodySize,
13801
12764
  } = breadcrumb.data;
13802
12765
 
13803
- const captureDetails = urlMatches(url, options.networkDetailAllowUrls);
13804
-
13805
- const request = captureDetails
13806
- ? _getRequestInfo(options, hint.input, requestBodySize)
13807
- : buildSkippedNetworkRequestOrResponse(requestBodySize);
13808
- const response = await _getResponseInfo(captureDetails, options, hint.response, responseBodySize);
12766
+ const request = _getRequestInfo(options, hint.input, requestBodySize);
12767
+ const response = await _getResponseInfo(options, hint.response, responseBodySize);
13809
12768
 
13810
12769
  return {
13811
12770
  startTimestamp,
13812
12771
  endTimestamp,
13813
12772
  url,
13814
12773
  method,
13815
- statusCode,
12774
+ statusCode: statusCode || 0,
13816
12775
  request,
13817
12776
  response,
13818
12777
  };
13819
12778
  }
13820
12779
 
13821
12780
  function _getRequestInfo(
13822
- { networkCaptureBodies, networkRequestHeaders },
12781
+ { captureBodies },
13823
12782
  input,
13824
12783
  requestBodySize,
13825
12784
  ) {
13826
- const headers = getRequestHeaders(input, networkRequestHeaders);
13827
-
13828
- if (!networkCaptureBodies) {
13829
- return buildNetworkRequestOrResponse(headers, requestBodySize, undefined);
12785
+ if (!captureBodies) {
12786
+ return buildNetworkRequestOrResponse(requestBodySize, undefined);
13830
12787
  }
13831
12788
 
13832
12789
  // We only want to transmit string or string-like bodies
13833
12790
  const requestBody = _getFetchRequestArgBody(input);
13834
- const bodyStr = getBodyString(requestBody);
13835
- return buildNetworkRequestOrResponse(headers, requestBodySize, bodyStr);
12791
+ const body = getNetworkBody(getBodyString(requestBody));
12792
+ return buildNetworkRequestOrResponse(requestBodySize, body);
13836
12793
  }
13837
12794
 
13838
12795
  async function _getResponseInfo(
13839
- captureDetails,
13840
- {
13841
- networkCaptureBodies,
13842
- textEncoder,
13843
- networkResponseHeaders,
13844
- }
13845
-
13846
- ,
12796
+ { captureBodies, textEncoder },
13847
12797
  response,
13848
12798
  responseBodySize,
13849
12799
  ) {
13850
- if (!captureDetails && responseBodySize !== undefined) {
13851
- return buildSkippedNetworkRequestOrResponse(responseBodySize);
13852
- }
13853
-
13854
- const headers = getAllHeaders(response.headers, networkResponseHeaders);
13855
-
13856
- if (!networkCaptureBodies && responseBodySize !== undefined) {
13857
- return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
12800
+ if (!captureBodies && responseBodySize !== undefined) {
12801
+ return buildNetworkRequestOrResponse(responseBodySize, undefined);
13858
12802
  }
13859
12803
 
13860
12804
  // Only clone the response if we need to
13861
12805
  try {
13862
12806
  // We have to clone this, as the body can only be read once
13863
12807
  const res = response.clone();
13864
- const bodyText = await _parseFetchBody(res);
12808
+ const { body, bodyText } = await _parseFetchBody(res);
13865
12809
 
13866
12810
  const size =
13867
12811
  bodyText && bodyText.length && responseBodySize === undefined
13868
12812
  ? getBodySize(bodyText, textEncoder)
13869
12813
  : responseBodySize;
13870
12814
 
13871
- if (!captureDetails) {
13872
- return buildSkippedNetworkRequestOrResponse(size);
12815
+ if (captureBodies) {
12816
+ return buildNetworkRequestOrResponse(size, body);
13873
12817
  }
13874
12818
 
13875
- if (networkCaptureBodies) {
13876
- return buildNetworkRequestOrResponse(headers, size, bodyText);
13877
- }
13878
-
13879
- return buildNetworkRequestOrResponse(headers, size, undefined);
12819
+ return buildNetworkRequestOrResponse(size, undefined);
13880
12820
  } catch (e) {
13881
12821
  // fallback
13882
- return buildNetworkRequestOrResponse(headers, responseBodySize, undefined);
12822
+ return buildNetworkRequestOrResponse(responseBodySize, undefined);
13883
12823
  }
13884
12824
  }
13885
12825
 
13886
- async function _parseFetchBody(response) {
12826
+ async function _parseFetchBody(
12827
+ response,
12828
+ ) {
12829
+ let bodyText;
12830
+
13887
12831
  try {
13888
- return await response.text();
12832
+ bodyText = await response.text();
13889
12833
  } catch (e2) {
13890
- return undefined;
12834
+ return {};
12835
+ }
12836
+
12837
+ try {
12838
+ const body = JSON.parse(bodyText);
12839
+ return { body, bodyText };
12840
+ } catch (e3) {
12841
+ // just send bodyText
13891
12842
  }
12843
+
12844
+ return { bodyText, body: bodyText };
13892
12845
  }
13893
12846
 
13894
12847
  function _getFetchRequestArgBody(fetchArgs = []) {
@@ -13900,56 +12853,6 @@ function _getFetchRequestArgBody(fetchArgs = []) {
13900
12853
  return (fetchArgs[1] ).body;
13901
12854
  }
13902
12855
 
13903
- function getAllHeaders(headers, allowedHeaders) {
13904
- const allHeaders = {};
13905
-
13906
- allowedHeaders.forEach(header => {
13907
- if (headers.get(header)) {
13908
- allHeaders[header] = headers.get(header) ;
13909
- }
13910
- });
13911
-
13912
- return allHeaders;
13913
- }
13914
-
13915
- function getRequestHeaders(fetchArgs, allowedHeaders) {
13916
- if (fetchArgs.length === 1 && typeof fetchArgs[0] !== 'string') {
13917
- return getHeadersFromOptions(fetchArgs[0] , allowedHeaders);
13918
- }
13919
-
13920
- if (fetchArgs.length === 2) {
13921
- return getHeadersFromOptions(fetchArgs[1] , allowedHeaders);
13922
- }
13923
-
13924
- return {};
13925
- }
13926
-
13927
- function getHeadersFromOptions(
13928
- input,
13929
- allowedHeaders,
13930
- ) {
13931
- if (!input) {
13932
- return {};
13933
- }
13934
-
13935
- const headers = input.headers;
13936
-
13937
- if (!headers) {
13938
- return {};
13939
- }
13940
-
13941
- if (headers instanceof Headers) {
13942
- return getAllHeaders(headers, allowedHeaders);
13943
- }
13944
-
13945
- // We do not support this, as it is not really documented (anymore?)
13946
- if (Array.isArray(headers)) {
13947
- return {};
13948
- }
13949
-
13950
- return getAllowedHeaders(headers, allowedHeaders);
13951
- }
13952
-
13953
12856
  /**
13954
12857
  * Capture an XHR breadcrumb to a replay.
13955
12858
  * This adds additional data (where approriate).
@@ -14000,12 +12903,12 @@ function _prepareXhrData(
14000
12903
  hint,
14001
12904
  options,
14002
12905
  ) {
14003
- const { startTimestamp, endTimestamp, input, xhr } = hint;
12906
+ const { startTimestamp, endTimestamp, input } = hint;
14004
12907
 
14005
12908
  const {
14006
12909
  url,
14007
12910
  method,
14008
- status_code: statusCode = 0,
12911
+ status_code: statusCode,
14009
12912
  request_body_size: requestBodySize,
14010
12913
  response_body_size: responseBodySize,
14011
12914
  } = breadcrumb.data;
@@ -14014,35 +12917,13 @@ function _prepareXhrData(
14014
12917
  return null;
14015
12918
  }
14016
12919
 
14017
- if (!urlMatches(url, options.networkDetailAllowUrls)) {
14018
- const request = buildSkippedNetworkRequestOrResponse(requestBodySize);
14019
- const response = buildSkippedNetworkRequestOrResponse(responseBodySize);
14020
- return {
14021
- startTimestamp,
14022
- endTimestamp,
14023
- url,
14024
- method,
14025
- statusCode,
14026
- request,
14027
- response,
14028
- };
14029
- }
14030
-
14031
- const xhrInfo = xhr[SENTRY_XHR_DATA_KEY];
14032
- const networkRequestHeaders = xhrInfo
14033
- ? getAllowedHeaders(xhrInfo.request_headers, options.networkRequestHeaders)
14034
- : {};
14035
- const networkResponseHeaders = getAllowedHeaders(getResponseHeaders(xhr), options.networkResponseHeaders);
14036
-
14037
12920
  const request = buildNetworkRequestOrResponse(
14038
- networkRequestHeaders,
14039
12921
  requestBodySize,
14040
- options.networkCaptureBodies ? getBodyString(input) : undefined,
12922
+ options.captureBodies ? getNetworkBody(getBodyString(input)) : undefined,
14041
12923
  );
14042
12924
  const response = buildNetworkRequestOrResponse(
14043
- networkResponseHeaders,
14044
12925
  responseBodySize,
14045
- options.networkCaptureBodies ? hint.xhr.responseText : undefined,
12926
+ options.captureBodies ? getNetworkBody(hint.xhr.responseText) : undefined,
14046
12927
  );
14047
12928
 
14048
12929
  return {
@@ -14050,26 +12931,12 @@ function _prepareXhrData(
14050
12931
  endTimestamp,
14051
12932
  url,
14052
12933
  method,
14053
- statusCode,
12934
+ statusCode: statusCode || 0,
14054
12935
  request,
14055
12936
  response,
14056
12937
  };
14057
12938
  }
14058
12939
 
14059
- function getResponseHeaders(xhr) {
14060
- const headers = xhr.getAllResponseHeaders();
14061
-
14062
- if (!headers) {
14063
- return {};
14064
- }
14065
-
14066
- return headers.split('\r\n').reduce((acc, line) => {
14067
- const [key, value] = line.split(': ');
14068
- acc[key.toLowerCase()] = value;
14069
- return acc;
14070
- }, {});
14071
- }
14072
-
14073
12940
  /**
14074
12941
  * This method does two things:
14075
12942
  * - It enriches the regular XHR/fetch breadcrumbs with request/response size data
@@ -14082,16 +12949,10 @@ function handleNetworkBreadcrumbs(replay) {
14082
12949
  try {
14083
12950
  const textEncoder = new TextEncoder();
14084
12951
 
14085
- const { networkDetailAllowUrls, networkCaptureBodies, networkRequestHeaders, networkResponseHeaders } =
14086
- replay.getOptions();
14087
-
14088
12952
  const options = {
14089
12953
  replay,
14090
12954
  textEncoder,
14091
- networkDetailAllowUrls,
14092
- networkCaptureBodies,
14093
- networkRequestHeaders,
14094
- networkResponseHeaders,
12955
+ captureBodies: replay.getOptions()._experiments.captureNetworkBodies || false,
14095
12956
  };
14096
12957
 
14097
12958
  if (client && client.on) {
@@ -14199,66 +13060,9 @@ function handleScope(scope) {
14199
13060
  return null;
14200
13061
  }
14201
13062
 
14202
- if (newBreadcrumb.category === 'console') {
14203
- return normalizeConsoleBreadcrumb(newBreadcrumb);
14204
- }
14205
-
14206
13063
  return createBreadcrumb(newBreadcrumb);
14207
13064
  }
14208
13065
 
14209
- /** exported for tests only */
14210
- function normalizeConsoleBreadcrumb(breadcrumb) {
14211
- const args = breadcrumb.data && breadcrumb.data.arguments;
14212
-
14213
- if (!Array.isArray(args) || args.length === 0) {
14214
- return createBreadcrumb(breadcrumb);
14215
- }
14216
-
14217
- let isTruncated = false;
14218
-
14219
- // Avoid giant args captures
14220
- const normalizedArgs = args.map(arg => {
14221
- if (!arg) {
14222
- return arg;
14223
- }
14224
- if (typeof arg === 'string') {
14225
- if (arg.length > CONSOLE_ARG_MAX_SIZE) {
14226
- isTruncated = true;
14227
- return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
14228
- }
14229
-
14230
- return arg;
14231
- }
14232
- if (typeof arg === 'object') {
14233
- try {
14234
- const normalizedArg = normalize(arg, 7);
14235
- const stringified = JSON.stringify(normalizedArg);
14236
- if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
14237
- const fixedJson = fixJson(stringified.slice(0, CONSOLE_ARG_MAX_SIZE));
14238
- const json = JSON.parse(fixedJson);
14239
- // We only set this after JSON.parse() was successfull, so we know we didn't run into `catch`
14240
- isTruncated = true;
14241
- return json;
14242
- }
14243
- return normalizedArg;
14244
- } catch (e) {
14245
- // fall back to default
14246
- }
14247
- }
14248
-
14249
- return arg;
14250
- });
14251
-
14252
- return createBreadcrumb({
14253
- ...breadcrumb,
14254
- data: {
14255
- ...breadcrumb.data,
14256
- arguments: normalizedArgs,
14257
- ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
14258
- },
14259
- });
14260
- }
14261
-
14262
13066
  /**
14263
13067
  * Add global listeners that cannot be removed.
14264
13068
  */
@@ -14283,8 +13087,7 @@ function addGlobalListeners(replay) {
14283
13087
  client.on('afterSendEvent', handleAfterSendEvent(replay));
14284
13088
  client.on('createDsc', (dsc) => {
14285
13089
  const replayId = replay.getSessionId();
14286
- // We do not want to set the DSC when in buffer mode, as that means the replay has not been sent (yet)
14287
- if (replayId && replay.isEnabled() && replay.recordingMode === 'session') {
13090
+ if (replayId) {
14288
13091
  dsc.replay_id = replayId;
14289
13092
  }
14290
13093
  });
@@ -14564,23 +13367,6 @@ function debounce(func, wait, options) {
14564
13367
  return debounced;
14565
13368
  }
14566
13369
 
14567
- /* eslint-disable @typescript-eslint/naming-convention */
14568
-
14569
- var EventType; (function (EventType) {
14570
- const DomContentLoaded = 0; EventType[EventType["DomContentLoaded"] = DomContentLoaded] = "DomContentLoaded";
14571
- const Load = 1; EventType[EventType["Load"] = Load] = "Load";
14572
- const FullSnapshot = 2; EventType[EventType["FullSnapshot"] = FullSnapshot] = "FullSnapshot";
14573
- const IncrementalSnapshot = 3; EventType[EventType["IncrementalSnapshot"] = IncrementalSnapshot] = "IncrementalSnapshot";
14574
- const Meta = 4; EventType[EventType["Meta"] = Meta] = "Meta";
14575
- const Custom = 5; EventType[EventType["Custom"] = Custom] = "Custom";
14576
- const Plugin = 6; EventType[EventType["Plugin"] = Plugin] = "Plugin";
14577
- })(EventType || (EventType = {}));
14578
-
14579
- /**
14580
- * This is a partial copy of rrweb's eventWithTime type which only contains the properties
14581
- * we specifcally need in the SDK.
14582
- */
14583
-
14584
13370
  /**
14585
13371
  * Handler for recording events.
14586
13372
  *
@@ -14609,7 +13395,7 @@ function getHandleRecordingEmit(replay) {
14609
13395
  // when an error occurs. Clear any state that happens before this current
14610
13396
  // checkout. This needs to happen before `addEvent()` which updates state
14611
13397
  // dependent on this reset.
14612
- if (replay.recordingMode === 'buffer' && isCheckout) {
13398
+ if (replay.recordingMode === 'error' && isCheckout) {
14613
13399
  replay.setInitialState();
14614
13400
  }
14615
13401
 
@@ -14623,14 +13409,6 @@ function getHandleRecordingEmit(replay) {
14623
13409
  return false;
14624
13410
  }
14625
13411
 
14626
- // Additionally, create a meta event that will capture certain SDK settings.
14627
- // In order to handle buffer mode, this needs to either be done when we
14628
- // receive checkout events or at flush time.
14629
- //
14630
- // `isCheckout` is always true, but want to be explicit that it should
14631
- // only be added for checkouts
14632
- void addSettingsEvent(replay, isCheckout);
14633
-
14634
13412
  // If there is a previousSessionId after a full snapshot occurs, then
14635
13413
  // the replay session was started due to session expiration. The new session
14636
13414
  // is started before triggering a new checkout and contains the id
@@ -14641,10 +13419,10 @@ function getHandleRecordingEmit(replay) {
14641
13419
  return true;
14642
13420
  }
14643
13421
 
14644
- // When in buffer mode, make sure we adjust the session started date to the current earliest event of the buffer
14645
- // this should usually be the timestamp of the checkout event, but to be safe...
14646
- if (replay.recordingMode === 'buffer' && replay.session && replay.eventBuffer) {
14647
- const earliestEvent = replay.eventBuffer.getEarliestTimestamp();
13422
+ // See note above re: session start needs to reflect the most recent
13423
+ // checkout.
13424
+ if (replay.recordingMode === 'error' && replay.session) {
13425
+ const { earliestEvent } = replay.getContext();
14648
13426
  if (earliestEvent) {
14649
13427
  replay.session.started = earliestEvent;
14650
13428
 
@@ -14668,46 +13446,6 @@ function getHandleRecordingEmit(replay) {
14668
13446
  };
14669
13447
  }
14670
13448
 
14671
- /**
14672
- * Exported for tests
14673
- */
14674
- function createOptionsEvent(replay) {
14675
- const options = replay.getOptions();
14676
- return {
14677
- type: EventType.Custom,
14678
- timestamp: Date.now(),
14679
- data: {
14680
- tag: 'options',
14681
- payload: {
14682
- sessionSampleRate: options.sessionSampleRate,
14683
- errorSampleRate: options.errorSampleRate,
14684
- useCompressionOption: options.useCompression,
14685
- blockAllMedia: options.blockAllMedia,
14686
- maskAllText: options.maskAllText,
14687
- maskAllInputs: options.maskAllInputs,
14688
- useCompression: replay.eventBuffer ? replay.eventBuffer.type === 'worker' : false,
14689
- networkDetailHasUrls: options.networkDetailAllowUrls.length > 0,
14690
- networkCaptureBodies: options.networkCaptureBodies,
14691
- networkRequestHasHeaders: options.networkRequestHeaders.length > 0,
14692
- networkResponseHasHeaders: options.networkResponseHeaders.length > 0,
14693
- },
14694
- },
14695
- };
14696
- }
14697
-
14698
- /**
14699
- * Add a "meta" event that contains a simplified view on current configuration
14700
- * options. This should only be included on the first segment of a recording.
14701
- */
14702
- function addSettingsEvent(replay, isCheckout) {
14703
- // Only need to add this event when sending the first segment
14704
- if (!isCheckout || !replay.session || replay.session.segmentId !== 0) {
14705
- return Promise.resolve(null);
14706
- }
14707
-
14708
- return addEvent(replay, createOptionsEvent(replay), false);
14709
- }
14710
-
14711
13449
  /**
14712
13450
  * Create a replay envelope ready to be sent.
14713
13451
  * This includes both the replay event, as well as the recording data.
@@ -14819,9 +13557,11 @@ async function sendReplayRequest({
14819
13557
  recordingData,
14820
13558
  replayId,
14821
13559
  segmentId: segment_id,
13560
+ includeReplayStartTimestamp,
14822
13561
  eventContext,
14823
13562
  timestamp,
14824
13563
  session,
13564
+ options,
14825
13565
  }) {
14826
13566
  const preparedRecordingData = prepareRecordingData({
14827
13567
  recordingData,
@@ -14843,8 +13583,9 @@ async function sendReplayRequest({
14843
13583
  }
14844
13584
 
14845
13585
  const baseEvent = {
13586
+ // @ts-ignore private api
14846
13587
  type: REPLAY_EVENT_NAME,
14847
- replay_start_timestamp: initialTimestamp / 1000,
13588
+ ...(includeReplayStartTimestamp ? { replay_start_timestamp: initialTimestamp / 1000 } : {}),
14848
13589
  timestamp: timestamp / 1000,
14849
13590
  error_ids: errorIds,
14850
13591
  trace_ids: traceIds,
@@ -14863,6 +13604,15 @@ async function sendReplayRequest({
14863
13604
  return;
14864
13605
  }
14865
13606
 
13607
+ replayEvent.contexts = {
13608
+ ...replayEvent.contexts,
13609
+ replay: {
13610
+ ...(replayEvent.contexts && replayEvent.contexts.replay),
13611
+ session_sample_rate: options.sessionSampleRate,
13612
+ error_sample_rate: options.errorSampleRate,
13613
+ },
13614
+ };
13615
+
14866
13616
  /*
14867
13617
  For reference, the fully built event looks something like this:
14868
13618
  {
@@ -14893,6 +13643,10 @@ async function sendReplayRequest({
14893
13643
  },
14894
13644
  "sdkProcessingMetadata": {},
14895
13645
  "contexts": {
13646
+ "replay": {
13647
+ "session_sample_rate": 1,
13648
+ "error_sample_rate": 0,
13649
+ },
14896
13650
  },
14897
13651
  }
14898
13652
  */
@@ -15018,11 +13772,9 @@ class ReplayContainer {
15018
13772
  __init2() {this.performanceEvents = [];}
15019
13773
 
15020
13774
  /**
15021
- * Recording can happen in one of three modes:
15022
- * - session: Record the whole session, sending it continuously
15023
- * - buffer: Always keep the last 60s of recording, requires:
15024
- * - having replaysOnErrorSampleRate > 0 to capture replay when an error occurs
15025
- * - or calling `flush()` to send the replay
13775
+ * Recording can happen in one of two modes:
13776
+ * * session: Record the whole session, sending it continuously
13777
+ * * error: Always keep the last 60s of recording, and when an error occurs, send it immediately
15026
13778
  */
15027
13779
  __init3() {this.recordingMode = 'session';}
15028
13780
 
@@ -15031,8 +13783,7 @@ class ReplayContainer {
15031
13783
  * @hidden
15032
13784
  */
15033
13785
  __init4() {this.timeouts = {
15034
- sessionIdlePause: SESSION_IDLE_PAUSE_DURATION,
15035
- sessionIdleExpire: SESSION_IDLE_EXPIRE_DURATION,
13786
+ sessionIdle: SESSION_IDLE_DURATION,
15036
13787
  maxSessionLife: MAX_SESSION_LIFE,
15037
13788
  }; }
15038
13789
 
@@ -15076,6 +13827,7 @@ class ReplayContainer {
15076
13827
  errorIds: new Set(),
15077
13828
  traceIds: new Set(),
15078
13829
  urls: [],
13830
+ earliestEvent: null,
15079
13831
  initialTimestamp: Date.now(),
15080
13832
  initialUrl: '',
15081
13833
  };}
@@ -15085,7 +13837,7 @@ class ReplayContainer {
15085
13837
  recordingOptions,
15086
13838
  }
15087
13839
 
15088
- ) {ReplayContainer.prototype.__init.call(this);ReplayContainer.prototype.__init2.call(this);ReplayContainer.prototype.__init3.call(this);ReplayContainer.prototype.__init4.call(this);ReplayContainer.prototype.__init5.call(this);ReplayContainer.prototype.__init6.call(this);ReplayContainer.prototype.__init7.call(this);ReplayContainer.prototype.__init8.call(this);ReplayContainer.prototype.__init9.call(this);ReplayContainer.prototype.__init10.call(this);ReplayContainer.prototype.__init11.call(this);ReplayContainer.prototype.__init12.call(this);ReplayContainer.prototype.__init13.call(this);ReplayContainer.prototype.__init14.call(this);ReplayContainer.prototype.__init15.call(this);ReplayContainer.prototype.__init16.call(this);ReplayContainer.prototype.__init17.call(this);ReplayContainer.prototype.__init18.call(this);
13840
+ ) {ReplayContainer.prototype.__init.call(this);ReplayContainer.prototype.__init2.call(this);ReplayContainer.prototype.__init3.call(this);ReplayContainer.prototype.__init4.call(this);ReplayContainer.prototype.__init5.call(this);ReplayContainer.prototype.__init6.call(this);ReplayContainer.prototype.__init7.call(this);ReplayContainer.prototype.__init8.call(this);ReplayContainer.prototype.__init9.call(this);ReplayContainer.prototype.__init10.call(this);ReplayContainer.prototype.__init11.call(this);ReplayContainer.prototype.__init12.call(this);ReplayContainer.prototype.__init13.call(this);ReplayContainer.prototype.__init14.call(this);ReplayContainer.prototype.__init15.call(this);ReplayContainer.prototype.__init16.call(this);ReplayContainer.prototype.__init17.call(this);
15089
13841
  this._recordingOptions = recordingOptions;
15090
13842
  this._options = options;
15091
13843
 
@@ -15115,102 +13867,49 @@ class ReplayContainer {
15115
13867
  }
15116
13868
 
15117
13869
  /**
15118
- * Initializes the plugin based on sampling configuration. Should not be
15119
- * called outside of constructor.
13870
+ * Initializes the plugin.
13871
+ *
13872
+ * Creates or loads a session, attaches listeners to varying events (DOM,
13873
+ * _performanceObserver, Recording, Sentry SDK, etc)
15120
13874
  */
15121
- initializeSampling() {
15122
- const { errorSampleRate, sessionSampleRate } = this._options;
15123
-
15124
- // If neither sample rate is > 0, then do nothing - user will need to call one of
15125
- // `start()` or `startBuffering` themselves.
15126
- if (errorSampleRate <= 0 && sessionSampleRate <= 0) {
15127
- return;
15128
- }
15129
-
15130
- // Otherwise if there is _any_ sample rate set, try to load an existing
15131
- // session, or create a new one.
15132
- const isSessionSampled = this._loadAndCheckSession();
13875
+ start() {
13876
+ this.setInitialState();
15133
13877
 
15134
- if (!isSessionSampled) {
15135
- // This should only occur if `errorSampleRate` is 0 and was unsampled for
15136
- // session-based replay. In this case there is nothing to do.
13878
+ if (!this._loadAndCheckSession()) {
15137
13879
  return;
15138
13880
  }
15139
13881
 
13882
+ // If there is no session, then something bad has happened - can't continue
15140
13883
  if (!this.session) {
15141
- // This should not happen, something wrong has occurred
15142
- this._handleException(new Error('Unable to initialize and create session'));
13884
+ this._handleException(new Error('No session found'));
15143
13885
  return;
15144
13886
  }
15145
13887
 
15146
- if (this.session.sampled && this.session.sampled !== 'session') {
15147
- // If not sampled as session-based, then recording mode will be `buffer`
15148
- // Note that we don't explicitly check if `sampled === 'buffer'` because we
15149
- // could have sessions from Session storage that are still `error` from
15150
- // prior SDK version.
15151
- this.recordingMode = 'buffer';
15152
- }
15153
-
15154
- this._initializeRecording();
15155
- }
15156
-
15157
- /**
15158
- * Start a replay regardless of sampling rate. Calling this will always
15159
- * create a new session. Will throw an error if replay is already in progress.
15160
- *
15161
- * Creates or loads a session, attaches listeners to varying events (DOM,
15162
- * _performanceObserver, Recording, Sentry SDK, etc)
15163
- */
15164
- start() {
15165
- if (this._isEnabled && this.recordingMode === 'session') {
15166
- throw new Error('Replay recording is already in progress');
13888
+ if (!this.session.sampled) {
13889
+ // If session was not sampled, then we do not initialize the integration at all.
13890
+ return;
15167
13891
  }
15168
13892
 
15169
- if (this._isEnabled && this.recordingMode === 'buffer') {
15170
- throw new Error('Replay buffering is in progress, call `flush()` to save the replay');
13893
+ // If session is sampled for errors, then we need to set the recordingMode
13894
+ // to 'error', which will configure recording with different options.
13895
+ if (this.session.sampled === 'error') {
13896
+ this.recordingMode = 'error';
15171
13897
  }
15172
13898
 
15173
- const previousSessionId = this.session && this.session.id;
13899
+ // setup() is generally called on page load or manually - in both cases we
13900
+ // should treat it as an activity
13901
+ this._updateSessionActivity();
15174
13902
 
15175
- const { session } = getSession({
15176
- timeouts: this.timeouts,
15177
- stickySession: Boolean(this._options.stickySession),
15178
- currentSession: this.session,
15179
- // This is intentional: create a new session-based replay when calling `start()`
15180
- sessionSampleRate: 1,
15181
- allowBuffering: false,
13903
+ this.eventBuffer = createEventBuffer({
13904
+ useCompression: this._options.useCompression,
15182
13905
  });
15183
13906
 
15184
- session.previousSessionId = previousSessionId;
15185
- this.session = session;
15186
-
15187
- this._initializeRecording();
15188
- }
15189
-
15190
- /**
15191
- * Start replay buffering. Buffers until `flush()` is called or, if
15192
- * `replaysOnErrorSampleRate` > 0, an error occurs.
15193
- */
15194
- startBuffering() {
15195
- if (this._isEnabled) {
15196
- throw new Error('Replay recording is already in progress');
15197
- }
15198
-
15199
- const previousSessionId = this.session && this.session.id;
15200
-
15201
- const { session } = getSession({
15202
- timeouts: this.timeouts,
15203
- stickySession: Boolean(this._options.stickySession),
15204
- currentSession: this.session,
15205
- sessionSampleRate: 0,
15206
- allowBuffering: true,
15207
- });
13907
+ this._addListeners();
15208
13908
 
15209
- session.previousSessionId = previousSessionId;
15210
- this.session = session;
13909
+ // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout
13910
+ this._isEnabled = true;
15211
13911
 
15212
- this.recordingMode = 'buffer';
15213
- this._initializeRecording();
13912
+ this.startRecording();
15214
13913
  }
15215
13914
 
15216
13915
  /**
@@ -15225,7 +13924,7 @@ class ReplayContainer {
15225
13924
  // When running in error sampling mode, we need to overwrite `checkoutEveryNms`
15226
13925
  // Without this, it would record forever, until an error happens, which we don't want
15227
13926
  // instead, we'll always keep the last 60 seconds of replay before an error happened
15228
- ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }),
13927
+ ...(this.recordingMode === 'error' && { checkoutEveryNms: ERROR_CHECKOUT_TIME }),
15229
13928
  emit: getHandleRecordingEmit(this),
15230
13929
  onMutation: this._onMutationHandler,
15231
13930
  });
@@ -15236,18 +13935,17 @@ class ReplayContainer {
15236
13935
 
15237
13936
  /**
15238
13937
  * Stops the recording, if it was running.
15239
- *
15240
- * Returns true if it was previously stopped, or is now stopped,
15241
- * otherwise false.
13938
+ * Returns true if it was stopped, else false.
15242
13939
  */
15243
13940
  stopRecording() {
15244
13941
  try {
15245
13942
  if (this._stopRecording) {
15246
13943
  this._stopRecording();
15247
13944
  this._stopRecording = undefined;
13945
+ return true;
15248
13946
  }
15249
13947
 
15250
- return true;
13948
+ return false;
15251
13949
  } catch (err) {
15252
13950
  this._handleException(err);
15253
13951
  return false;
@@ -15258,7 +13956,7 @@ class ReplayContainer {
15258
13956
  * Currently, this needs to be manually called (e.g. for tests). Sentry SDK
15259
13957
  * does not support a teardown
15260
13958
  */
15261
- async stop(reason) {
13959
+ stop(reason) {
15262
13960
  if (!this._isEnabled) {
15263
13961
  return;
15264
13962
  }
@@ -15274,24 +13972,12 @@ class ReplayContainer {
15274
13972
  log(msg);
15275
13973
  }
15276
13974
 
15277
- // We can't move `_isEnabled` after awaiting a flush, otherwise we can
15278
- // enter into an infinite loop when `stop()` is called while flushing.
15279
13975
  this._isEnabled = false;
15280
13976
  this._removeListeners();
15281
13977
  this.stopRecording();
15282
-
15283
- this._debouncedFlush.cancel();
15284
- // See comment above re: `_isEnabled`, we "force" a flush, ignoring the
15285
- // `_isEnabled` state of the plugin since it was disabled above.
15286
- await this._flush({ force: true });
15287
-
15288
- // After flush, destroy event buffer
15289
13978
  this.eventBuffer && this.eventBuffer.destroy();
15290
13979
  this.eventBuffer = null;
15291
-
15292
- // Clear session from session storage, note this means if a new session
15293
- // is started after, it will not have `previousSessionId`
15294
- clearSession(this);
13980
+ this._debouncedFlush.cancel();
15295
13981
  } catch (err) {
15296
13982
  this._handleException(err);
15297
13983
  }
@@ -15322,45 +14008,6 @@ class ReplayContainer {
15322
14008
  this.startRecording();
15323
14009
  }
15324
14010
 
15325
- /**
15326
- * If not in "session" recording mode, flush event buffer which will create a new replay.
15327
- * Unless `continueRecording` is false, the replay will continue to record and
15328
- * behave as a "session"-based replay.
15329
- *
15330
- * Otherwise, queue up a flush.
15331
- */
15332
- async sendBufferedReplayOrFlush({ continueRecording = true } = {}) {
15333
- if (this.recordingMode === 'session') {
15334
- return this.flushImmediate();
15335
- }
15336
-
15337
- // Allow flush to complete before resuming as a session recording, otherwise
15338
- // the checkout from `startRecording` may be included in the payload.
15339
- // Prefer to keep the error replay as a separate (and smaller) segment
15340
- // than the session replay.
15341
- await this.flushImmediate();
15342
-
15343
- const hasStoppedRecording = this.stopRecording();
15344
-
15345
- if (!continueRecording || !hasStoppedRecording) {
15346
- return;
15347
- }
15348
-
15349
- // Re-start recording, but in "session" recording mode
15350
-
15351
- // Reset all "capture on error" configuration before
15352
- // starting a new recording
15353
- this.recordingMode = 'session';
15354
-
15355
- // Once this session ends, we do not want to refresh it
15356
- if (this.session) {
15357
- this.session.shouldRefresh = false;
15358
- this._maybeSaveSession();
15359
- }
15360
-
15361
- this.startRecording();
15362
- }
15363
-
15364
14011
  /**
15365
14012
  * We want to batch uploads of replay events. Save events only if
15366
14013
  * `<flushMinDelay>` milliseconds have elapsed since the last event
@@ -15370,12 +14017,12 @@ class ReplayContainer {
15370
14017
  * processing and hand back control to caller.
15371
14018
  */
15372
14019
  addUpdate(cb) {
15373
- // We need to always run `cb` (e.g. in the case of `this.recordingMode == 'buffer'`)
14020
+ // We need to always run `cb` (e.g. in the case of `this.recordingMode == 'error'`)
15374
14021
  const cbResult = cb();
15375
14022
 
15376
14023
  // If this option is turned on then we will only want to call `flush`
15377
14024
  // explicitly
15378
- if (this.recordingMode === 'buffer') {
14025
+ if (this.recordingMode === 'error') {
15379
14026
  return;
15380
14027
  }
15381
14028
 
@@ -15447,12 +14094,12 @@ class ReplayContainer {
15447
14094
  const oldSessionId = this.getSessionId();
15448
14095
 
15449
14096
  // Prevent starting a new session if the last user activity is older than
15450
- // SESSION_IDLE_PAUSE_DURATION. Otherwise non-user activity can trigger a new
14097
+ // SESSION_IDLE_DURATION. Otherwise non-user activity can trigger a new
15451
14098
  // session+recording. This creates noisy replays that do not have much
15452
14099
  // content in them.
15453
14100
  if (
15454
14101
  this._lastActivity &&
15455
- isExpired(this._lastActivity, this.timeouts.sessionIdlePause) &&
14102
+ isExpired(this._lastActivity, this.timeouts.sessionIdle) &&
15456
14103
  this.session &&
15457
14104
  this.session.sampled === 'session'
15458
14105
  ) {
@@ -15502,30 +14149,6 @@ class ReplayContainer {
15502
14149
  this._context.urls.push(url);
15503
14150
  }
15504
14151
 
15505
- /**
15506
- * Initialize and start all listeners to varying events (DOM,
15507
- * Performance Observer, Recording, Sentry SDK, etc)
15508
- */
15509
- _initializeRecording() {
15510
- this.setInitialState();
15511
-
15512
- // this method is generally called on page load or manually - in both cases
15513
- // we should treat it as an activity
15514
- this._updateSessionActivity();
15515
-
15516
- this.eventBuffer = createEventBuffer({
15517
- useCompression: this._options.useCompression,
15518
- });
15519
-
15520
- this._removeListeners();
15521
- this._addListeners();
15522
-
15523
- // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout
15524
- this._isEnabled = true;
15525
-
15526
- this.startRecording();
15527
- }
15528
-
15529
14152
  /** A wrapper to conditionally capture exceptions. */
15530
14153
  _handleException(error) {
15531
14154
  (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('[Replay]', error);
@@ -15545,7 +14168,7 @@ class ReplayContainer {
15545
14168
  stickySession: Boolean(this._options.stickySession),
15546
14169
  currentSession: this.session,
15547
14170
  sessionSampleRate: this._options.sessionSampleRate,
15548
- allowBuffering: this._options.errorSampleRate > 0,
14171
+ errorSampleRate: this._options.errorSampleRate,
15549
14172
  });
15550
14173
 
15551
14174
  // If session was newly created (i.e. was not loaded from storage), then
@@ -15562,7 +14185,7 @@ class ReplayContainer {
15562
14185
  this.session = session;
15563
14186
 
15564
14187
  if (!this.session.sampled) {
15565
- void this.stop('session unsampled');
14188
+ this.stop('session unsampled');
15566
14189
  return false;
15567
14190
  }
15568
14191
 
@@ -15577,7 +14200,6 @@ class ReplayContainer {
15577
14200
  WINDOW.document.addEventListener('visibilitychange', this._handleVisibilityChange);
15578
14201
  WINDOW.addEventListener('blur', this._handleWindowBlur);
15579
14202
  WINDOW.addEventListener('focus', this._handleWindowFocus);
15580
- WINDOW.addEventListener('keydown', this._handleKeyboardEvent);
15581
14203
 
15582
14204
  // There is no way to remove these listeners, so ensure they are only added once
15583
14205
  if (!this._hasInitializedCoreListeners) {
@@ -15606,7 +14228,6 @@ class ReplayContainer {
15606
14228
 
15607
14229
  WINDOW.removeEventListener('blur', this._handleWindowBlur);
15608
14230
  WINDOW.removeEventListener('focus', this._handleWindowFocus);
15609
- WINDOW.removeEventListener('keydown', this._handleKeyboardEvent);
15610
14231
 
15611
14232
  if (this._performanceObserver) {
15612
14233
  this._performanceObserver.disconnect();
@@ -15657,11 +14278,6 @@ class ReplayContainer {
15657
14278
  this._doChangeToForegroundTasks(breadcrumb);
15658
14279
  };}
15659
14280
 
15660
- /** Ensure page remains active when a key is pressed. */
15661
- __init16() {this._handleKeyboardEvent = (event) => {
15662
- handleKeyboardEvent(this, event);
15663
- };}
15664
-
15665
14281
  /**
15666
14282
  * Tasks to run when we consider a page to be hidden (via blurring and/or visibility)
15667
14283
  */
@@ -15693,7 +14309,7 @@ class ReplayContainer {
15693
14309
  const isSessionActive = this.checkAndHandleExpiredSession();
15694
14310
 
15695
14311
  if (!isSessionActive) {
15696
- // If the user has come back to the page within SESSION_IDLE_PAUSE_DURATION
14312
+ // If the user has come back to the page within SESSION_IDLE_DURATION
15697
14313
  // ms, we will re-use the existing session, otherwise create a new
15698
14314
  // session
15699
14315
  (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.log('[Replay] Document has become active, but session has expired');
@@ -15741,7 +14357,7 @@ class ReplayContainer {
15741
14357
  _createCustomBreadcrumb(breadcrumb) {
15742
14358
  this.addUpdate(() => {
15743
14359
  void addEvent(this, {
15744
- type: EventType$1.Custom,
14360
+ type: EventType.Custom,
15745
14361
  timestamp: breadcrumb.timestamp || 0,
15746
14362
  data: {
15747
14363
  tag: 'breadcrumb',
@@ -15767,7 +14383,7 @@ class ReplayContainer {
15767
14383
  * Only flush if `this.recordingMode === 'session'`
15768
14384
  */
15769
14385
  _conditionalFlush() {
15770
- if (this.recordingMode === 'buffer') {
14386
+ if (this.recordingMode === 'error') {
15771
14387
  return;
15772
14388
  }
15773
14389
 
@@ -15782,35 +14398,22 @@ class ReplayContainer {
15782
14398
  this._context.errorIds.clear();
15783
14399
  this._context.traceIds.clear();
15784
14400
  this._context.urls = [];
15785
- }
15786
-
15787
- /** Update the initial timestamp based on the buffer content. */
15788
- _updateInitialTimestampFromEventBuffer() {
15789
- const { session, eventBuffer } = this;
15790
- if (!session || !eventBuffer) {
15791
- return;
15792
- }
15793
-
15794
- // we only ever update this on the initial segment
15795
- if (session.segmentId) {
15796
- return;
15797
- }
15798
-
15799
- const earliestEvent = eventBuffer.getEarliestTimestamp();
15800
- if (earliestEvent && earliestEvent < this._context.initialTimestamp) {
15801
- this._context.initialTimestamp = earliestEvent;
15802
- }
14401
+ this._context.earliestEvent = null;
15803
14402
  }
15804
14403
 
15805
14404
  /**
15806
14405
  * Return and clear _context
15807
14406
  */
15808
14407
  _popEventContext() {
14408
+ if (this._context.earliestEvent && this._context.earliestEvent < this._context.initialTimestamp) {
14409
+ this._context.initialTimestamp = this._context.earliestEvent;
14410
+ }
14411
+
15809
14412
  const _context = {
15810
14413
  initialTimestamp: this._context.initialTimestamp,
15811
14414
  initialUrl: this._context.initialUrl,
15812
- errorIds: Array.from(this._context.errorIds),
15813
- traceIds: Array.from(this._context.traceIds),
14415
+ errorIds: Array.from(this._context.errorIds).filter(Boolean),
14416
+ traceIds: Array.from(this._context.traceIds).filter(Boolean),
15814
14417
  urls: this._context.urls,
15815
14418
  };
15816
14419
 
@@ -15849,9 +14452,6 @@ class ReplayContainer {
15849
14452
  }
15850
14453
 
15851
14454
  try {
15852
- // This uses the data from the eventBuffer, so we need to call this before `finish()
15853
- this._updateInitialTimestampFromEventBuffer();
15854
-
15855
14455
  // Note this empties the event buffer regardless of outcome of sending replay
15856
14456
  const recordingData = await this.eventBuffer.finish();
15857
14457
 
@@ -15867,6 +14467,7 @@ class ReplayContainer {
15867
14467
  replayId,
15868
14468
  recordingData,
15869
14469
  segmentId,
14470
+ includeReplayStartTimestamp: segmentId === 0,
15870
14471
  eventContext,
15871
14472
  session: this.session,
15872
14473
  options: this.getOptions(),
@@ -15878,7 +14479,7 @@ class ReplayContainer {
15878
14479
  // This means we retried 3 times and all of them failed,
15879
14480
  // or we ran into a problem we don't want to retry, like rate limiting.
15880
14481
  // In this case, we want to completely stop the replay - otherwise, we may get inconsistent segments
15881
- void this.stop('sendReplay');
14482
+ this.stop('sendReplay');
15882
14483
 
15883
14484
  const client = getCurrentHub().getClient();
15884
14485
 
@@ -15892,12 +14493,8 @@ class ReplayContainer {
15892
14493
  * Flush recording data to Sentry. Creates a lock so that only a single flush
15893
14494
  * can be active at a time. Do not call this directly.
15894
14495
  */
15895
- __init17() {this._flush = async ({
15896
- force = false,
15897
- }
15898
-
15899
- = {}) => {
15900
- if (!this._isEnabled && !force) {
14496
+ __init16() {this._flush = async () => {
14497
+ if (!this._isEnabled) {
15901
14498
  // This can happen if e.g. the replay was stopped because of exceeding the retry limit
15902
14499
  return;
15903
14500
  }
@@ -15947,7 +14544,7 @@ class ReplayContainer {
15947
14544
  }
15948
14545
 
15949
14546
  /** Handler for rrweb.record.onMutation */
15950
- __init18() {this._onMutationHandler = (mutations) => {
14547
+ __init17() {this._onMutationHandler = (mutations) => {
15951
14548
  const count = mutations.length;
15952
14549
 
15953
14550
  const mutationLimit = this._options._experiments.mutationLimit || 0;
@@ -16081,8 +14678,6 @@ function isElectronNodeRenderer() {
16081
14678
  const MEDIA_SELECTORS =
16082
14679
  'img,image,svg,video,object,picture,embed,map,audio,link[rel="icon"],link[rel="apple-touch-icon"]';
16083
14680
 
16084
- const DEFAULT_NETWORK_HEADERS = ['content-length', 'content-type', 'accept'];
16085
-
16086
14681
  let _initialized = false;
16087
14682
 
16088
14683
  /**
@@ -16123,11 +14718,6 @@ class Replay {
16123
14718
  maskAllInputs = true,
16124
14719
  blockAllMedia = true,
16125
14720
 
16126
- networkDetailAllowUrls = [],
16127
- networkCaptureBodies = true,
16128
- networkRequestHeaders = [],
16129
- networkResponseHeaders = [],
16130
-
16131
14721
  mask = [],
16132
14722
  unmask = [],
16133
14723
  block = [],
@@ -16186,13 +14776,6 @@ class Replay {
16186
14776
  errorSampleRate,
16187
14777
  useCompression,
16188
14778
  blockAllMedia,
16189
- maskAllInputs,
16190
- maskAllText,
16191
- networkDetailAllowUrls,
16192
- networkCaptureBodies,
16193
- networkRequestHeaders: _getMergedNetworkHeaders(networkRequestHeaders),
16194
- networkResponseHeaders: _getMergedNetworkHeaders(networkResponseHeaders),
16195
-
16196
14779
  _experiments,
16197
14780
  };
16198
14781
 
@@ -16246,7 +14829,14 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
16246
14829
  }
16247
14830
 
16248
14831
  /**
16249
- * Setup and initialize replay container
14832
+ * We previously used to create a transaction in `setupOnce` and it would
14833
+ * potentially create a transaction before some native SDK integrations have run
14834
+ * and applied their own global event processor. An example is:
14835
+ * https://github.com/getsentry/sentry-javascript/blob/b47ceafbdac7f8b99093ce6023726ad4687edc48/packages/browser/src/integrations/useragent.ts
14836
+ *
14837
+ * So we call `replay.setup` in next event loop as a workaround to wait for other
14838
+ * global event processors to finish. This is no longer needed, but keeping it
14839
+ * here to avoid any future issues.
16250
14840
  */
16251
14841
  setupOnce() {
16252
14842
  if (!isBrowser()) {
@@ -16255,20 +14845,12 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
16255
14845
 
16256
14846
  this._setup();
16257
14847
 
16258
- // Once upon a time, we tried to create a transaction in `setupOnce` and it would
16259
- // potentially create a transaction before some native SDK integrations have run
16260
- // and applied their own global event processor. An example is:
16261
- // https://github.com/getsentry/sentry-javascript/blob/b47ceafbdac7f8b99093ce6023726ad4687edc48/packages/browser/src/integrations/useragent.ts
16262
- //
16263
- // So we call `this._initialize()` in next event loop as a workaround to wait for other
16264
- // global event processors to finish. This is no longer needed, but keeping it
16265
- // here to avoid any future issues.
16266
- setTimeout(() => this._initialize());
14848
+ // XXX: See method comments above
14849
+ setTimeout(() => this.start());
16267
14850
  }
16268
14851
 
16269
14852
  /**
16270
- * Start a replay regardless of sampling rate. Calling this will always
16271
- * create a new session. Will throw an error if replay is already in progress.
14853
+ * Initializes the plugin.
16272
14854
  *
16273
14855
  * Creates or loads a session, attaches listeners to varying events (DOM,
16274
14856
  * PerformanceObserver, Recording, Sentry SDK, etc)
@@ -16281,64 +14863,27 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
16281
14863
  this._replay.start();
16282
14864
  }
16283
14865
 
16284
- /**
16285
- * Start replay buffering. Buffers until `flush()` is called or, if
16286
- * `replaysOnErrorSampleRate` > 0, until an error occurs.
16287
- */
16288
- startBuffering() {
16289
- if (!this._replay) {
16290
- return;
16291
- }
16292
-
16293
- this._replay.startBuffering();
16294
- }
16295
-
16296
14866
  /**
16297
14867
  * Currently, this needs to be manually called (e.g. for tests). Sentry SDK
16298
14868
  * does not support a teardown
16299
14869
  */
16300
14870
  stop() {
16301
14871
  if (!this._replay) {
16302
- return Promise.resolve();
16303
- }
16304
-
16305
- return this._replay.stop();
16306
- }
16307
-
16308
- /**
16309
- * If not in "session" recording mode, flush event buffer which will create a new replay.
16310
- * Unless `continueRecording` is false, the replay will continue to record and
16311
- * behave as a "session"-based replay.
16312
- *
16313
- * Otherwise, queue up a flush.
16314
- */
16315
- flush(options) {
16316
- if (!this._replay || !this._replay.isEnabled()) {
16317
- return Promise.resolve();
14872
+ return;
16318
14873
  }
16319
14874
 
16320
- return this._replay.sendBufferedReplayOrFlush(options);
14875
+ this._replay.stop();
16321
14876
  }
16322
14877
 
16323
14878
  /**
16324
- * Get the current session ID.
14879
+ * Immediately send all pending events.
16325
14880
  */
16326
- getReplayId() {
14881
+ flush() {
16327
14882
  if (!this._replay || !this._replay.isEnabled()) {
16328
14883
  return;
16329
14884
  }
16330
14885
 
16331
- return this._replay.getSessionId();
16332
- }
16333
- /**
16334
- * Initializes replay.
16335
- */
16336
- _initialize() {
16337
- if (!this._replay) {
16338
- return;
16339
- }
16340
-
16341
- this._replay.initializeSampling();
14886
+ return this._replay.flushImmediate();
16342
14887
  }
16343
14888
 
16344
14889
  /** Setup the integration. */
@@ -16389,10 +14934,6 @@ function loadReplayOptionsFromClient(initialOptions) {
16389
14934
  return finalOptions;
16390
14935
  }
16391
14936
 
16392
- function _getMergedNetworkHeaders(headers) {
16393
- return [...DEFAULT_NETWORK_HEADERS, ...headers.map(header => header.toLowerCase())];
16394
- }
16395
-
16396
14937
  /**
16397
14938
  * Polyfill for the optional chain operator, `?.`, given previous conversion of the expression into an array of values,
16398
14939
  * descriptors, and functions.
@@ -16830,9 +15371,6 @@ class Postgres {
16830
15371
  const span = _optionalChain([parentSpan, 'optionalAccess', _6 => _6.startChild, 'call', _7 => _7({
16831
15372
  description: typeof config === 'string' ? config : (config ).text,
16832
15373
  op: 'db',
16833
- data: {
16834
- 'db.system': 'postgresql',
16835
- },
16836
15374
  })]);
16837
15375
 
16838
15376
  if (typeof callback === 'function') {
@@ -16909,9 +15447,6 @@ class Mysql {constructor() { Mysql.prototype.__init.call(this); }
16909
15447
  const span = _optionalChain([parentSpan, 'optionalAccess', _4 => _4.startChild, 'call', _5 => _5({
16910
15448
  description: typeof options === 'string' ? options : (options ).sql,
16911
15449
  op: 'db',
16912
- data: {
16913
- 'db.system': 'mysql',
16914
- },
16915
15450
  })]);
16916
15451
 
16917
15452
  if (typeof callback === 'function') {
@@ -17133,7 +15668,6 @@ class Mongo {
17133
15668
  collectionName: collection.collectionName,
17134
15669
  dbName: collection.dbName,
17135
15670
  namespace: collection.namespace,
17136
- 'db.system': 'mongodb',
17137
15671
  };
17138
15672
  const spanContext = {
17139
15673
  op: 'db',
@@ -17220,15 +15754,31 @@ class Prisma {
17220
15754
  }
17221
15755
 
17222
15756
  this._client.$use((params, next) => {
15757
+ const scope = getCurrentHub().getScope();
15758
+ const parentSpan = _optionalChain([scope, 'optionalAccess', _2 => _2.getSpan, 'call', _3 => _3()]);
15759
+
17223
15760
  const action = params.action;
17224
15761
  const model = params.model;
17225
- return trace(
17226
- { name: model ? `${model} ${action}` : action, op: 'db.sql.prisma', data: { 'db.system': 'prisma' } },
17227
- () => next(params),
17228
- );
15762
+
15763
+ const span = _optionalChain([parentSpan, 'optionalAccess', _4 => _4.startChild, 'call', _5 => _5({
15764
+ description: model ? `${model} ${action}` : action,
15765
+ op: 'db.sql.prisma',
15766
+ })]);
15767
+
15768
+ const rv = next(params);
15769
+
15770
+ if (isThenable(rv)) {
15771
+ return rv.then((res) => {
15772
+ _optionalChain([span, 'optionalAccess', _6 => _6.finish, 'call', _7 => _7()]);
15773
+ return res;
15774
+ });
15775
+ }
15776
+
15777
+ _optionalChain([span, 'optionalAccess', _8 => _8.finish, 'call', _9 => _9()]);
15778
+ return rv;
17229
15779
  });
17230
15780
  }
17231
- } Prisma.__initStatic();
15781
+ }Prisma.__initStatic();
17232
15782
 
17233
15783
  /** Tracing integration for graphql package */
17234
15784
  class GraphQL {constructor() { GraphQL.prototype.__init.call(this); }
@@ -25560,6 +24110,7 @@ var STATES$5;
25560
24110
  STATES["RE_INIT_RECORDER__NEXT_QUESTION"] = "reInitRecorderNextQuestion";
25561
24111
  STATES["UPLOADING"] = "uploading";
25562
24112
  STATES["CONFIRM"] = "confirm";
24113
+ STATES["CONFIRM_WATING"] = "confirmWaiting";
25563
24114
  STATES["FINISHED"] = "finished";
25564
24115
  STATES["ERROR"] = "error";
25565
24116
  })(STATES$5 || (STATES$5 = {}));
@@ -25613,6 +24164,7 @@ var ACTIONS$6;
25613
24164
  ACTIONS["RESET_FAILED_RECORDING_ATTEMPTS"] = "resetFailedRecordingAttempts";
25614
24165
  ACTIONS["CLEAR_VIDEO_ERROR"] = "clearVideoError";
25615
24166
  ACTIONS["UPDATE_VIDEO_DIMENSIONS"] = "updateVideoDimensions";
24167
+ ACTIONS["UPDATE_UPLOADED_FALSE_COUNT"] = "updateUploadedFalseCount";
25616
24168
  })(ACTIONS$6 || (ACTIONS$6 = {}));
25617
24169
  var EVENTS$5;
25618
24170
  (function (EVENTS) {
@@ -25668,6 +24220,7 @@ var GUARDS$3;
25668
24220
  GUARDS["IS_RECORDER_READY"] = "isRecorderReady";
25669
24221
  GUARDS["IS_ASSESSMENT_QUESTION"] = "isAssessmentQuestion";
25670
24222
  GUARDS["IS_TIMES_UP"] = "isTimesUp";
24223
+ GUARDS["SHOULD_TRY_TO_CONFIRM"] = "shouldTryToConfirm";
25671
24224
  })(GUARDS$3 || (GUARDS$3 = {}));
25672
24225
  var TAGS;
25673
24226
  (function (TAGS) {
@@ -25677,6 +24230,7 @@ var TAGS;
25677
24230
  TAGS["DISPLAY_OUTER_VIEW"] = "displayOuterView";
25678
24231
  TAGS["DISPLAY_QUESTION"] = "displayQuestion";
25679
24232
  TAGS["DISPLAY_QUESTIONS_LIST"] = "displayQuestionsList";
24233
+ TAGS["DISPLAY_UPLOAD"] = "displayUpload";
25680
24234
  TAGS["LOADING"] = "loading";
25681
24235
  })(TAGS || (TAGS = {}));
25682
24236
 
@@ -30398,7 +28952,7 @@ const configGenerator = () => {
30398
28952
  let release;
30399
28953
  try {
30400
28954
  environment !== null && environment !== void 0 ? environment : (environment = "staging");
30401
- release !== null && release !== void 0 ? release : (release = "1.1.23");
28955
+ release !== null && release !== void 0 ? release : (release = "1.1.23-binary-001");
30402
28956
  }
30403
28957
  catch (_a) {
30404
28958
  console.error('sentry configGenerator error');
@@ -30871,6 +29425,7 @@ const SECONDS_LEFT_HIGHLIGHT = 10;
30871
29425
  const DEFAULT_ASSESSMENT_MAX_CHARS = 300;
30872
29426
  const DEFAULT_ASSESSMENT_DURATION = 0;
30873
29427
  const DEFAULT_VIDEO_DIMENSIONS = { width: 1280, height: 720 }; // Transcoder default dimensions (720p)
29428
+ const MAX_CONFIRM_ATTEMPTS = 5;
30874
29429
  // Font
30875
29430
  const FONT_URL = 'https://fonts.googleapis.com/css2?family=Nunito+Sans:wght@400;600;700&display=swap';
30876
29431
  var RETAKE_SPEED;
@@ -35031,8 +33586,8 @@ function memoizeOne(resultFn, isEqual) {
35031
33586
  }
35032
33587
 
35033
33588
  var memoizeOne_esm = /*#__PURE__*/Object.freeze({
35034
- __proto__: null,
35035
- 'default': memoizeOne
33589
+ __proto__: null,
33590
+ 'default': memoizeOne
35036
33591
  });
35037
33592
 
35038
33593
  var require$$2 = /*@__PURE__*/getAugmentedNamespace(memoizeOne_esm);
@@ -38992,6 +37547,11 @@ var EVENT_TYPES;
38992
37547
  EVENT_TYPES["SOUND_RESTORED"] = "soundRestored";
38993
37548
  EVENT_TYPES["TIMES_UP"] = "timesUp";
38994
37549
  EVENT_TYPES["COMPLETED_INTERVIEW"] = "completedInterview";
37550
+ EVENT_TYPES["RECONNECTED"] = "reconnected";
37551
+ EVENT_TYPES["CONFIRM_UPLOADED_FAILED"] = "confirmUploadedFailed";
37552
+ EVENT_TYPES["FINISHED"] = "finished";
37553
+ EVENT_TYPES["ON_FINISH_SUCCEED"] = "onFinishSucceed";
37554
+ EVENT_TYPES["ON_FINISH_FAILED"] = "onFinishFailed";
38995
37555
  })(EVENT_TYPES || (EVENT_TYPES = {}));
38996
37556
  let event_id;
38997
37557
  const updateEventId = (eventId) => { event_id = eventId; };
@@ -39541,31 +38101,6 @@ const Setup = ({ widgetMachine, sendToWidget, isPracticeDisabled, recordWithoutV
39541
38101
  React__default.createElement(C, { className: startButtonClassNames, color: "special", backgroundColor: "white", onClick: () => sendToWidget(EVENTS$5.QUESTION_MODE), disabled: !canStartInterview }, t(isResumed ? 'welcome.resumeInterview' : 'buttons.btn_start').toUpperCase()))));
39542
38102
  };
39543
38103
 
39544
- /*! *****************************************************************************
39545
- Copyright (c) Microsoft Corporation.
39546
-
39547
- Permission to use, copy, modify, and/or distribute this software for any
39548
- purpose with or without fee is hereby granted.
39549
-
39550
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
39551
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39552
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
39553
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
39554
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
39555
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
39556
- PERFORMANCE OF THIS SOFTWARE.
39557
- ***************************************************************************** */
39558
-
39559
- function __awaiter(thisArg, _arguments, P, generator) {
39560
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
39561
- return new (P || (P = Promise))(function (resolve, reject) {
39562
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
39563
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
39564
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
39565
- step((generator = generator.apply(thisArg, _arguments || [])).next());
39566
- });
39567
- }
39568
-
39569
38104
  const uploadToS3 = (url, data, onProgress, timeout = 0) => s3AxiosInstance.put(url, data, {
39570
38105
  headers: { 'Content-Type': 'video/webm' }, onUploadProgress: onProgress, timeout,
39571
38106
  });
@@ -39636,8 +38171,8 @@ const OuterView = ({ widgetMachine, sendToWidget, recorderRef }) => {
39636
38171
  const isQuestionDisplayed = widgetMachine.hasTag(TAGS.DISPLAY_QUESTION) || (isVideoQuestionState && !currentQuestionObj.thinkingTime);
39637
38172
  const isPreviewState = widgetMachine.matches(STATES$5.PREVIEW);
39638
38173
  const isUploadingState = widgetMachine.matches(STATES$5.UPLOADING);
39639
- const isConfirmState = widgetMachine.matches(STATES$5.CONFIRM);
39640
38174
  const isQuestionsListDisplayed = widgetMachine.hasTag(TAGS.DISPLAY_QUESTIONS_LIST);
38175
+ const isUploadDisplayed = widgetMachine.hasTag(TAGS.DISPLAY_UPLOAD);
39641
38176
  const isRecording = recorderMachine.matches({ [STATES$6.RECORDING]: STATES$6.COLLECTING_BLOBS });
39642
38177
  const isCountDown = recorderMachine.matches({ [STATES$6.RECORDING]: STATES$6.COUNT_DOWN });
39643
38178
  const isPracticeMode = recordingType === TAKE_TYPES.PRACTICE;
@@ -39655,7 +38190,7 @@ const OuterView = ({ widgetMachine, sendToWidget, recorderRef }) => {
39655
38190
  isSetupState && React__default.createElement(Setup, { recordWithoutVideo: recordWithoutVideo, widgetMachine: widgetMachine, sendToWidget: sendToWidget, isPracticeDisabled: !!config.disablePractice }),
39656
38191
  isQuestionsListDisplayed && React__default.createElement(QuestionsList, { questions: questions, currentQuestion: currentQuestion, isPracticeMode: isPracticeMode, questionsStatus: questionsStatus }),
39657
38192
  isQuestionDisplayed && React__default.createElement(Question, { questionObj: currentQuestionObj }),
39658
- (isUploadingState || isConfirmState) && (React__default.createElement(Upload, { isConnected: isConnected, totalFileSize: totalFileSize, totalUploadedFilesSize: totalUploadedFilesSize, totalUploadSpeed: totalUploadSpeed }))));
38193
+ isUploadDisplayed && (React__default.createElement(Upload, { isConnected: isConnected, totalFileSize: totalFileSize, totalUploadedFilesSize: totalUploadedFilesSize, totalUploadSpeed: totalUploadSpeed }))));
39659
38194
  };
39660
38195
 
39661
38196
  var actions = {};
@@ -43484,9 +42019,7 @@ var AsapAction = (function (_super) {
43484
42019
  var actions = scheduler.actions;
43485
42020
  if (id != null && ((_a = actions[actions.length - 1]) === null || _a === void 0 ? void 0 : _a.id) !== id) {
43486
42021
  immediateProvider.clearImmediate(id);
43487
- if (scheduler._scheduled === id) {
43488
- scheduler._scheduled = undefined;
43489
- }
42022
+ scheduler._scheduled = undefined;
43490
42023
  }
43491
42024
  return undefined;
43492
42025
  };
@@ -44752,7 +43285,7 @@ const accUploaderMachine = createMachine({
44752
43285
  actions: [ACTIONS$2.SENTRY],
44753
43286
  },
44754
43287
  {
44755
- actions: [ACTIONS$2.SET_UPLOADED, ACTIONS$2.SENTRY],
43288
+ actions: [ACTIONS$2.SENTRY],
44756
43289
  target: `#uploader.${STATES$2.UPLOADED}`, // In case the video already uploaded
44757
43290
  },
44758
43291
  ],
@@ -44769,7 +43302,6 @@ const accUploaderMachine = createMachine({
44769
43302
  id: 'uploadToS3',
44770
43303
  src: ({ signedUrl, file }) => (callback) => uploadToS3(signedUrl, file, callback),
44771
43304
  onDone: {
44772
- // actions: [ACTIONS.SET_UPLOADED],
44773
43305
  target: `#uploader.${STATES$2.UPLOADED}`,
44774
43306
  },
44775
43307
  onError: {
@@ -45125,10 +43657,14 @@ const accWidgetMachine = createMachine({
45125
43657
  failedRecordingMessage: VIDEO_CORRUPTED_STATES.NO_ERROR,
45126
43658
  isResumed: false,
45127
43659
  videoDimensions: DEFAULT_VIDEO_DIMENSIONS,
43660
+ confirmUploadedFalseCount: 0,
45128
43661
  },
45129
43662
  on: {
45130
43663
  [EVENTS$1.CONNECTION_CHANGED]: {
45131
- actions: [ACTIONS$6.SET_CONNECTION],
43664
+ actions: [
43665
+ ACTIONS$6.SET_CONNECTION,
43666
+ { type: ACTIONS$6.EMIT_TRACKING_EVENT, data: { eventType: EVENT_TYPES.RECONNECTED } },
43667
+ ],
45132
43668
  },
45133
43669
  [EVENTS$5.UPLOADER_PROGRESS]: {
45134
43670
  actions: [ACTIONS$6.UPDATE_TOTAL_UPLOADED_FILES_SIZE],
@@ -45655,7 +44191,7 @@ const accWidgetMachine = createMachine({
45655
44191
  },
45656
44192
  },
45657
44193
  [STATES$5.UPLOADING]: {
45658
- tags: [TAGS.DISPLAY_OUTER_VIEW],
44194
+ tags: [TAGS.DISPLAY_OUTER_VIEW, TAGS.DISPLAY_UPLOAD],
45659
44195
  entry: [
45660
44196
  { type: ACTIONS$6.SESSION_EVENT, data: { event: 'widget_completed', type: 'date' } },
45661
44197
  { type: ACTIONS$6.CONSOLE_DEBUG, data: { message: DEBUG.UPLOADING_STATE } },
@@ -45669,30 +44205,57 @@ const accWidgetMachine = createMachine({
45669
44205
  },
45670
44206
  },
45671
44207
  },
44208
+ [STATES$5.CONFIRM_WATING]: {
44209
+ tags: [TAGS.DISPLAY_OUTER_VIEW, TAGS.DISPLAY_UPLOAD],
44210
+ always: {
44211
+ target: STATES$5.CONFIRM,
44212
+ cond: GUARDS$3.IS_CONNECTED,
44213
+ },
44214
+ },
45672
44215
  [STATES$5.CONFIRM]: {
45673
- tags: [TAGS.DISPLAY_OUTER_VIEW],
44216
+ tags: [TAGS.DISPLAY_OUTER_VIEW, TAGS.DISPLAY_UPLOAD],
45674
44217
  invoke: {
45675
44218
  id: 'getVideo',
45676
44219
  src: (context) => { var _a; return getVideo(((_a = context.widgetConfig.video) === null || _a === void 0 ? void 0 : _a.video_id) || ''); },
45677
- onDone: {
45678
- target: STATES$5.FINISHED,
45679
- cond: (_, event) => !!event.data.data.data.video.uploaded,
45680
- },
44220
+ onDone: [
44221
+ {
44222
+ target: STATES$5.FINISHED,
44223
+ cond: (_, event) => !!event.data.data.data.video.uploaded,
44224
+ },
44225
+ {
44226
+ actions: [
44227
+ ACTIONS$6.UPDATE_UPLOADED_FALSE_COUNT,
44228
+ { type: ACTIONS$6.SENTRY, data: { eventName: 'CONFIRM::UPLOADED_FALSE' } },
44229
+ ],
44230
+ target: STATES$5.CONFIRM_WATING,
44231
+ cond: GUARDS$3.SHOULD_TRY_TO_CONFIRM,
44232
+ },
44233
+ {
44234
+ actions: [
44235
+ { type: ACTIONS$6.SET_VIDEO_ERROR, data: { errorMessage: 'Error, Please contact support' } },
44236
+ { type: ACTIONS$6.EMIT_TRACKING_EVENT, data: { eventType: EVENT_TYPES.CONFIRM_UPLOADED_FAILED } },
44237
+ ],
44238
+ target: STATES$5.ERROR,
44239
+ },
44240
+ ],
45681
44241
  onError: [
45682
44242
  {
45683
- actions: [() => console.error('UPDATE_VIDEO_UPLADED_ERROR:'), console.error, ACTIONS$6.SENTRY],
44243
+ actions: [() => console.error('UPDATE_VIDEO_UPLADED_ERROR:'), console.error, { type: ACTIONS$6.SENTRY, data: { eventName: 'CONFIRM::ERROR__NOT_FOUND' } }],
45684
44244
  target: STATES$5.FINISHED,
45685
44245
  cond: (_, event) => event.data.response.status === STATUS_CODES.NOT_FOUND,
45686
44246
  },
45687
44247
  {
45688
- actions: [ACTIONS$6.SENTRY],
45689
- target: STATES$5.CONFIRM,
44248
+ actions: [() => console.error('UPDATE_VIDEO_UPLADED_ERROR:'), console.error, { type: ACTIONS$6.SENTRY, data: { eventName: 'CONFIRM::ERROR' } }],
44249
+ target: STATES$5.CONFIRM_WATING,
45690
44250
  },
45691
44251
  ],
45692
44252
  },
45693
44253
  },
45694
44254
  [STATES$5.FINISHED]: {
45695
- entry: [{ type: ACTIONS$6.CONSOLE_DEBUG, data: { message: DEBUG.INTERVIEW_SUBMITTED } }],
44255
+ entry: [
44256
+ { type: ACTIONS$6.CONSOLE_DEBUG, data: { message: DEBUG.INTERVIEW_SUBMITTED } },
44257
+ { type: ACTIONS$6.EMIT_TRACKING_EVENT, data: { eventType: EVENT_TYPES.FINISHED } },
44258
+ ],
45696
44259
  type: 'final',
45697
44260
  },
45698
44261
  [STATES$5.ERROR]: {
@@ -45888,9 +44451,12 @@ const accWidgetMachine = createMachine({
45888
44451
  widgetConfig: Object.assign(Object.assign({}, widgetConfig), { video: Object.assign(Object.assign({}, widgetConfig.video), { videos: (_b = (_a = widgetConfig.video) === null || _a === void 0 ? void 0 : _a.videos) === null || _b === void 0 ? void 0 : _b.map((video, idx) => ((idx !== questionNumber - 1) ? video : videoFile)) }) }),
45889
44452
  });
45890
44453
  }),
45891
- [ACTIONS$6.SET_VIDEO_ERROR]: assign$2((_, event) => ({
45892
- error: event.data.response.data || { errorMessage: event.data.message },
45893
- })),
44454
+ [ACTIONS$6.SET_VIDEO_ERROR]: assign$2((_, event, meta) => {
44455
+ var _a, _b, _c, _d;
44456
+ return ({
44457
+ error: ((_b = (_a = event.data) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.data) || { errorMessage: ((_c = event.data) === null || _c === void 0 ? void 0 : _c.message) || ((_d = meta.action.data) === null || _d === void 0 ? void 0 : _d.errorMessage) },
44458
+ });
44459
+ }),
45894
44460
  [ACTIONS$6.REVOKE_MEMORY]: send$2((_, event) => ({ type: EVENTS$4.REMOVE_TAKES, data: { questionToRemove: event.data.questionNumber } }), { to: ({ storageRef }) => storageRef }),
45895
44461
  [ACTIONS$6.UPDATE_VIDEO_OBJECT]: assign$2(({ widgetConfig, recordingType }) => {
45896
44462
  var _a, _b;
@@ -45924,6 +44490,9 @@ const accWidgetMachine = createMachine({
45924
44490
  height: event.data.height,
45925
44491
  },
45926
44492
  })),
44493
+ [ACTIONS$6.UPDATE_UPLOADED_FALSE_COUNT]: assign$2(({ confirmUploadedFalseCount }) => ({
44494
+ confirmUploadedFalseCount: confirmUploadedFalseCount + 1,
44495
+ })),
45927
44496
  },
45928
44497
  services: {
45929
44498
  [SERVICES$1.UPDATE_VIDEO_OBJECT_CALL]: ({ widgetConfig: { video }, recordingType, speedTestResult }, event, meta) => (callback, onReceive) => {
@@ -45967,6 +44536,7 @@ const accWidgetMachine = createMachine({
45967
44536
  [GUARDS$3.IS_RECORDER_READY]: ({ recorderRef }) => (recorderRef === null || recorderRef === void 0 ? void 0 : recorderRef.getSnapshot().value) === STATES$6.IDLE,
45968
44537
  [GUARDS$3.IS_ASSESSMENT_QUESTION]: ({ questions, currentQuestion }) => !!questions[currentQuestion - 1].answerType && questions[currentQuestion - 1].answerType !== ANSWER_TYPES.VIDEO,
45969
44538
  [GUARDS$3.IS_TIMES_UP]: (_, event) => !!event.data.isTimesUp,
44539
+ [GUARDS$3.SHOULD_TRY_TO_CONFIRM]: ({ confirmUploadedFalseCount }) => confirmUploadedFalseCount <= MAX_CONFIRM_ATTEMPTS,
45970
44540
  },
45971
44541
  });
45972
44542
 
@@ -48489,10 +47059,25 @@ const Main = ({ widgetConfig, setShouldShowWaterMark, myinterviewRef, isWidgetMi
48489
47059
  useEffect(() => {
48490
47060
  setShouldShowWaterMark(!!(company === null || company === void 0 ? void 0 : company.shouldShowWaterMark));
48491
47061
  }, [company === null || company === void 0 ? void 0 : company.shouldShowWaterMark]);
47062
+ const _onFinish = () => __awaiter(void 0, void 0, void 0, function* () { var _a, _b; return (_b = (_a = widgetConfig.config).onFinish) === null || _b === void 0 ? void 0 : _b.call(_a, { redirectUrl: candidate.redirectUrl, video_id: (video === null || video === void 0 ? void 0 : video.video_id) || '' }); });
48492
47063
  useEffect(() => {
48493
- var _a, _b;
48494
47064
  if (machine.done) {
48495
- (_b = (_a = widgetConfig.config).onFinish) === null || _b === void 0 ? void 0 : _b.call(_a, { redirectUrl: candidate.redirectUrl, video_id: (video === null || video === void 0 ? void 0 : video.video_id) || '' });
47065
+ if (widgetConfig.config.onFinish) {
47066
+ _onFinish().then(() => {
47067
+ emitTrackEvent({ eventType: EVENT_TYPES.ON_FINISH_SUCCEED });
47068
+ }).catch((err) => {
47069
+ var _a;
47070
+ let errorMessage = '';
47071
+ try {
47072
+ errorMessage = (err === null || err === void 0 ? void 0 : err.message) || (err === null || err === void 0 ? void 0 : err.msg) || ((_a = err === null || err === void 0 ? void 0 : err.data) === null || _a === void 0 ? void 0 : _a.message);
47073
+ }
47074
+ catch (_b) {
47075
+ //
47076
+ }
47077
+ emitTrackEvent({ eventType: EVENT_TYPES.ON_FINISH_FAILED, extraData: { errorMessage } });
47078
+ throw err;
47079
+ });
47080
+ }
48496
47081
  }
48497
47082
  }, [machine.done]);
48498
47083
  useEffect(() => {
@@ -48508,11 +47093,16 @@ const Main = ({ widgetConfig, setShouldShowWaterMark, myinterviewRef, isWidgetMi
48508
47093
  });
48509
47094
  }
48510
47095
  }, [candidate, job === null || job === void 0 ? void 0 : job.language]);
47096
+ const setBackgroundOpacity = () => {
47097
+ var _a;
47098
+ (_a = myinterviewRef === null || myinterviewRef === void 0 ? void 0 : myinterviewRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty('--myinterview-background-opacity', isLoading || isErrorState ? '0' : '1');
47099
+ };
48511
47100
  useEffect(() => {
48512
47101
  var _a, _b;
48513
47102
  if (isErrorState && (error === null || error === void 0 ? void 0 : error.statusCode) === 400) {
48514
47103
  (_b = (_a = widgetConfig.config).onError) === null || _b === void 0 ? void 0 : _b.call(_a, { messageType: 'applied' });
48515
47104
  }
47105
+ setBackgroundOpacity();
48516
47106
  }, [isErrorState]);
48517
47107
  const isResumed = useMemo(() => { var _a, _b; return !!((_b = (_a = widgetConfig.video) === null || _a === void 0 ? void 0 : _a.videos) === null || _b === void 0 ? void 0 : _b.some((v) => v.uploaded)); }, [widgetConfig.video]);
48518
47108
  const handleScroll = (e) => {
@@ -48522,8 +47112,7 @@ const Main = ({ widgetConfig, setShouldShowWaterMark, myinterviewRef, isWidgetMi
48522
47112
  (_b = viewsRef === null || viewsRef === void 0 ? void 0 : viewsRef.current) === null || _b === void 0 ? void 0 : _b.style.setProperty('--myinterview-widget-practice-opacity', scrollTop > 10 ? '0' : '1');
48523
47113
  };
48524
47114
  useEffect(() => {
48525
- var _a;
48526
- (_a = myinterviewRef === null || myinterviewRef === void 0 ? void 0 : myinterviewRef.current) === null || _a === void 0 ? void 0 : _a.style.setProperty('--myinterview-background-opacity', isLoading || isErrorState ? '0' : '1');
47115
+ setBackgroundOpacity();
48527
47116
  }, [isLoading]);
48528
47117
  const onRetry = () => {
48529
47118
  send(EVENTS$5.RETRY);
@@ -48721,15 +47310,15 @@ const Widget = ({ candidate, job, video, config, disabled = false, buttonText =
48721
47310
  revertBodyStyling();
48722
47311
  setIsWidgetOpen(false);
48723
47312
  };
48724
- const onInterviewCompleted = (data) => {
47313
+ const onInterviewCompleted = (data) => __awaiter(void 0, void 0, void 0, function* () {
48725
47314
  var _a;
48726
- (_a = config.onFinish) === null || _a === void 0 ? void 0 : _a.call(config, data);
48727
47315
  onCloseWidget();
48728
- };
47316
+ yield ((_a = config.onFinish) === null || _a === void 0 ? void 0 : _a.call(config, data));
47317
+ });
48729
47318
  const onError = (data) => {
48730
47319
  var _a;
48731
- (_a = config.onError) === null || _a === void 0 ? void 0 : _a.call(config, data);
48732
47320
  onCloseWidget();
47321
+ (_a = config.onError) === null || _a === void 0 ? void 0 : _a.call(config, data);
48733
47322
  };
48734
47323
  const openWidget = () => {
48735
47324
  var _a;