@sentry/replay 7.105.0 → 8.0.0-alpha.2

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.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/cjs/index.js +131 -286
  3. package/cjs/index.js.map +1 -1
  4. package/esm/index.js +133 -288
  5. package/esm/index.js.map +1 -1
  6. package/package.json +7 -7
  7. package/types/coreHandlers/handleAfterSendEvent.d.ts +1 -1
  8. package/types/coreHandlers/handleAfterSendEvent.d.ts.map +1 -1
  9. package/types/coreHandlers/handleBreadcrumbs.d.ts +14 -0
  10. package/types/coreHandlers/handleBreadcrumbs.d.ts.map +1 -0
  11. package/types/coreHandlers/handleGlobalEvent.d.ts +1 -1
  12. package/types/coreHandlers/handleGlobalEvent.d.ts.map +1 -1
  13. package/types/coreHandlers/handleNetworkBreadcrumbs.d.ts +1 -2
  14. package/types/coreHandlers/handleNetworkBreadcrumbs.d.ts.map +1 -1
  15. package/types/coreHandlers/util/fetchUtils.d.ts +3 -8
  16. package/types/coreHandlers/util/fetchUtils.d.ts.map +1 -1
  17. package/types/coreHandlers/util/networkUtils.d.ts +1 -2
  18. package/types/coreHandlers/util/networkUtils.d.ts.map +1 -1
  19. package/types/coreHandlers/util/xhrUtils.d.ts +2 -4
  20. package/types/coreHandlers/util/xhrUtils.d.ts.map +1 -1
  21. package/types/util/addGlobalListeners.d.ts.map +1 -1
  22. package/types/util/getReplay.d.ts.map +1 -1
  23. package/types/util/prepareReplayEvent.d.ts +2 -2
  24. package/types/util/prepareReplayEvent.d.ts.map +1 -1
  25. package/types/util/sendReplayRequest.d.ts +1 -1
  26. package/types/util/sendReplayRequest.d.ts.map +1 -1
  27. package/types-ts3.8/coreHandlers/handleAfterSendEvent.d.ts +1 -1
  28. package/types-ts3.8/coreHandlers/handleBreadcrumbs.d.ts +14 -0
  29. package/types-ts3.8/coreHandlers/handleGlobalEvent.d.ts +1 -1
  30. package/types-ts3.8/coreHandlers/handleNetworkBreadcrumbs.d.ts +1 -2
  31. package/types-ts3.8/coreHandlers/util/fetchUtils.d.ts +3 -8
  32. package/types-ts3.8/coreHandlers/util/networkUtils.d.ts +1 -2
  33. package/types-ts3.8/coreHandlers/util/xhrUtils.d.ts +2 -4
  34. package/types-ts3.8/util/prepareReplayEvent.d.ts +2 -2
  35. package/types-ts3.8/util/sendReplayRequest.d.ts +1 -1
  36. package/types/coreHandlers/handleFetch.d.ts +0 -9
  37. package/types/coreHandlers/handleFetch.d.ts.map +0 -1
  38. package/types/coreHandlers/handleScope.d.ts +0 -13
  39. package/types/coreHandlers/handleScope.d.ts.map +0 -1
  40. package/types/coreHandlers/handleXhr.d.ts +0 -9
  41. package/types/coreHandlers/handleXhr.d.ts.map +0 -1
  42. package/types-ts3.8/coreHandlers/handleFetch.d.ts +0 -9
  43. package/types-ts3.8/coreHandlers/handleScope.d.ts +0 -13
  44. package/types-ts3.8/coreHandlers/handleXhr.d.ts +0 -9
package/esm/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { _nullishCoalesce, _optionalChain } from '@sentry/utils';
2
- import { addBreadcrumb, getClient, isSentryRequestUrl, getCurrentScope, addEventProcessor, prepareEvent, getIsolationScope, setContext, captureException, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
3
- import { GLOBAL_OBJ, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, logger, uuid4, SENTRY_XHR_DATA_KEY, dropUndefinedKeys, stringMatchesSomePattern, addFetchInstrumentationHandler, addXhrInstrumentationHandler, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler, createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader, updateRateLimits, isRateLimited, consoleSandbox, isBrowser } from '@sentry/utils';
2
+ import { addBreadcrumb, getClient, isSentryRequestUrl, addEventProcessor, prepareEvent, getIsolationScope, getCurrentScope, setContext, captureException, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core';
3
+ import { GLOBAL_OBJ, normalize, fill, htmlTreeAsString, browserPerformanceTimeOrigin, logger, uuid4, dropUndefinedKeys, stringMatchesSomePattern, SENTRY_XHR_DATA_KEY, addClickKeypressInstrumentationHandler, addHistoryInstrumentationHandler, createEnvelope, createEventEnvelopeHeaders, getSdkMetadataForEnvelopeHeader, resolvedSyncPromise, updateRateLimits, isRateLimited, consoleSandbox, isBrowser } from '@sentry/utils';
4
4
  import { addPerformanceInstrumentationHandler, addLcpInstrumentationHandler } from '@sentry-internal/tracing';
5
5
 
6
6
  // exporting a separate copy of `WINDOW` rather than exporting the one from `@sentry/browser`
@@ -5708,10 +5708,6 @@ function isFeedbackEvent(event) {
5708
5708
  * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
5709
5709
  */
5710
5710
  function handleAfterSendEvent(replay) {
5711
- // Custom transports may still be returning `Promise<void>`, which means we cannot expect the status code to be available there
5712
- // TODO (v8): remove this check as it will no longer be necessary
5713
- const enforceStatusCode = isBaseTransportSend();
5714
-
5715
5711
  return (event, sendResponse) => {
5716
5712
  if (!replay.isEnabled() || (!isErrorEvent(event) && !isTransactionEvent(event))) {
5717
5713
  return;
@@ -5722,7 +5718,7 @@ function handleAfterSendEvent(replay) {
5722
5718
  // We only want to do stuff on successful error sending, otherwise you get error replays without errors attached
5723
5719
  // If not using the base transport, we allow `undefined` response (as a custom transport may not implement this correctly yet)
5724
5720
  // If we do use the base transport, we skip if we encountered an non-OK status code
5725
- if (enforceStatusCode && (!statusCode || statusCode < 200 || statusCode >= 300)) {
5721
+ if (!statusCode || statusCode < 200 || statusCode >= 300) {
5726
5722
  return;
5727
5723
  }
5728
5724
 
@@ -5778,22 +5774,6 @@ function handleErrorEvent(replay, event) {
5778
5774
  });
5779
5775
  }
5780
5776
 
5781
- function isBaseTransportSend() {
5782
- const client = getClient();
5783
- if (!client) {
5784
- return false;
5785
- }
5786
-
5787
- const transport = client.getTransport();
5788
- if (!transport) {
5789
- return false;
5790
- }
5791
-
5792
- return (
5793
- (transport.send ).__sentry__baseTransport__ || false
5794
- );
5795
- }
5796
-
5797
5777
  /**
5798
5778
  * Returns a listener to be added to `client.on('afterSendErrorEvent, listener)`.
5799
5779
  */
@@ -5829,6 +5809,112 @@ function handleHydrationError(replay, event) {
5829
5809
  }
5830
5810
  }
5831
5811
 
5812
+ /**
5813
+ * Handle breadcrumbs that Sentry captures, and make sure to capture relevant breadcrumbs to Replay as well.
5814
+ */
5815
+ function handleBreadcrumbs(replay) {
5816
+ const client = getClient();
5817
+
5818
+ if (!client) {
5819
+ return;
5820
+ }
5821
+
5822
+ client.on('beforeAddBreadcrumb', breadcrumb => beforeAddBreadcrumb(replay, breadcrumb));
5823
+ }
5824
+
5825
+ function beforeAddBreadcrumb(replay, breadcrumb) {
5826
+ if (!replay.isEnabled() || !isBreadcrumbWithCategory(breadcrumb)) {
5827
+ return;
5828
+ }
5829
+
5830
+ const result = normalizeBreadcrumb(breadcrumb);
5831
+ if (result) {
5832
+ addBreadcrumbEvent(replay, result);
5833
+ }
5834
+ }
5835
+
5836
+ /** Exported only for tests. */
5837
+ function normalizeBreadcrumb(breadcrumb) {
5838
+ if (
5839
+ !isBreadcrumbWithCategory(breadcrumb) ||
5840
+ [
5841
+ // fetch & xhr are handled separately,in handleNetworkBreadcrumbs
5842
+ 'fetch',
5843
+ 'xhr',
5844
+ // These two are breadcrumbs for emitted sentry events, we don't care about them
5845
+ 'sentry.event',
5846
+ 'sentry.transaction',
5847
+ ].includes(breadcrumb.category) ||
5848
+ // We capture UI breadcrumbs separately
5849
+ breadcrumb.category.startsWith('ui.')
5850
+ ) {
5851
+ return null;
5852
+ }
5853
+
5854
+ if (breadcrumb.category === 'console') {
5855
+ return normalizeConsoleBreadcrumb(breadcrumb);
5856
+ }
5857
+
5858
+ return createBreadcrumb(breadcrumb);
5859
+ }
5860
+
5861
+ /** exported for tests only */
5862
+ function normalizeConsoleBreadcrumb(
5863
+ breadcrumb,
5864
+ ) {
5865
+ const args = breadcrumb.data && breadcrumb.data.arguments;
5866
+
5867
+ if (!Array.isArray(args) || args.length === 0) {
5868
+ return createBreadcrumb(breadcrumb);
5869
+ }
5870
+
5871
+ let isTruncated = false;
5872
+
5873
+ // Avoid giant args captures
5874
+ const normalizedArgs = args.map(arg => {
5875
+ if (!arg) {
5876
+ return arg;
5877
+ }
5878
+ if (typeof arg === 'string') {
5879
+ if (arg.length > CONSOLE_ARG_MAX_SIZE) {
5880
+ isTruncated = true;
5881
+ return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
5882
+ }
5883
+
5884
+ return arg;
5885
+ }
5886
+ if (typeof arg === 'object') {
5887
+ try {
5888
+ const normalizedArg = normalize(arg, 7);
5889
+ const stringified = JSON.stringify(normalizedArg);
5890
+ if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
5891
+ isTruncated = true;
5892
+ // We use the pretty printed JSON string here as a base
5893
+ return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
5894
+ }
5895
+ return normalizedArg;
5896
+ } catch (e) {
5897
+ // fall back to default
5898
+ }
5899
+ }
5900
+
5901
+ return arg;
5902
+ });
5903
+
5904
+ return createBreadcrumb({
5905
+ ...breadcrumb,
5906
+ data: {
5907
+ ...breadcrumb.data,
5908
+ arguments: normalizedArgs,
5909
+ ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
5910
+ },
5911
+ });
5912
+ }
5913
+
5914
+ function isBreadcrumbWithCategory(breadcrumb) {
5915
+ return !!breadcrumb.category;
5916
+ }
5917
+
5832
5918
  /**
5833
5919
  * Returns true if we think the given event is an error originating inside of rrweb.
5834
5920
  */
@@ -5906,12 +5992,7 @@ function shouldSampleForBufferEvent(replay, event) {
5906
5992
  /**
5907
5993
  * Returns a listener to be added to `addEventProcessor(listener)`.
5908
5994
  */
5909
- function handleGlobalEventListener(
5910
- replay,
5911
- includeAfterSendEventHandling = false,
5912
- ) {
5913
- const afterSendHandler = includeAfterSendEventHandling ? handleAfterSendEvent(replay) : undefined;
5914
-
5995
+ function handleGlobalEventListener(replay) {
5915
5996
  return Object.assign(
5916
5997
  (event, hint) => {
5917
5998
  // Do nothing if replay has been disabled
@@ -5967,13 +6048,6 @@ function handleGlobalEventListener(
5967
6048
  event.tags = { ...event.tags, replayId: replay.getSessionId() };
5968
6049
  }
5969
6050
 
5970
- // In cases where a custom client is used that does not support the new hooks (yet),
5971
- // we manually call this hook method here
5972
- if (afterSendHandler) {
5973
- // Pretend the error had a 200 response so we always capture it
5974
- afterSendHandler(event, { statusCode: 200 });
5975
- }
5976
-
5977
6051
  return event;
5978
6052
  },
5979
6053
  { id: 'Replay' },
@@ -6090,97 +6164,14 @@ function addNetworkBreadcrumb(
6090
6164
  });
6091
6165
  }
6092
6166
 
6093
- /** only exported for tests */
6094
- function handleFetch(handlerData) {
6095
- const { startTimestamp, endTimestamp, fetchData, response } = handlerData;
6096
-
6097
- if (!endTimestamp) {
6098
- return null;
6099
- }
6100
-
6101
- // This is only used as a fallback, so we know the body sizes are never set here
6102
- const { method, url } = fetchData;
6103
-
6104
- return {
6105
- type: 'resource.fetch',
6106
- start: startTimestamp / 1000,
6107
- end: endTimestamp / 1000,
6108
- name: url,
6109
- data: {
6110
- method,
6111
- statusCode: response ? (response ).status : undefined,
6112
- },
6113
- };
6114
- }
6115
-
6116
- /**
6117
- * Returns a listener to be added to `addFetchInstrumentationHandler(listener)`.
6118
- */
6119
- function handleFetchSpanListener(replay) {
6120
- return (handlerData) => {
6121
- if (!replay.isEnabled()) {
6122
- return;
6123
- }
6124
-
6125
- const result = handleFetch(handlerData);
6126
-
6127
- addNetworkBreadcrumb(replay, result);
6128
- };
6129
- }
6130
-
6131
- /** only exported for tests */
6132
- function handleXhr(handlerData) {
6133
- const { startTimestamp, endTimestamp, xhr } = handlerData;
6134
-
6135
- const sentryXhrData = xhr[SENTRY_XHR_DATA_KEY];
6136
-
6137
- if (!startTimestamp || !endTimestamp || !sentryXhrData) {
6138
- return null;
6139
- }
6140
-
6141
- // This is only used as a fallback, so we know the body sizes are never set here
6142
- const { method, url, status_code: statusCode } = sentryXhrData;
6143
-
6144
- if (url === undefined) {
6145
- return null;
6146
- }
6147
-
6148
- return {
6149
- type: 'resource.xhr',
6150
- name: url,
6151
- start: startTimestamp / 1000,
6152
- end: endTimestamp / 1000,
6153
- data: {
6154
- method,
6155
- statusCode,
6156
- },
6157
- };
6158
- }
6159
-
6160
- /**
6161
- * Returns a listener to be added to `addXhrInstrumentationHandler(listener)`.
6162
- */
6163
- function handleXhrSpanListener(replay) {
6164
- return (handlerData) => {
6165
- if (!replay.isEnabled()) {
6166
- return;
6167
- }
6168
-
6169
- const result = handleXhr(handlerData);
6170
-
6171
- addNetworkBreadcrumb(replay, result);
6172
- };
6173
- }
6174
-
6175
6167
  /** Get the size of a body. */
6176
- function getBodySize(
6177
- body,
6178
- textEncoder,
6179
- ) {
6168
+ function getBodySize(body) {
6180
6169
  if (!body) {
6181
6170
  return undefined;
6182
6171
  }
6183
6172
 
6173
+ const textEncoder = new TextEncoder();
6174
+
6184
6175
  try {
6185
6176
  if (typeof body === 'string') {
6186
6177
  return textEncoder.encode(body).length;
@@ -6480,12 +6471,11 @@ async function captureFetchBreadcrumbToReplay(
6480
6471
  function enrichFetchBreadcrumb(
6481
6472
  breadcrumb,
6482
6473
  hint,
6483
- options,
6484
6474
  ) {
6485
6475
  const { input, response } = hint;
6486
6476
 
6487
6477
  const body = input ? _getFetchRequestArgBody(input) : undefined;
6488
- const reqSize = getBodySize(body, options.textEncoder);
6478
+ const reqSize = getBodySize(body);
6489
6479
 
6490
6480
  const resSize = response ? parseContentLengthHeader(response.headers.get('content-length')) : undefined;
6491
6481
 
@@ -6500,9 +6490,7 @@ function enrichFetchBreadcrumb(
6500
6490
  async function _prepareFetchData(
6501
6491
  breadcrumb,
6502
6492
  hint,
6503
- options
6504
-
6505
- ,
6493
+ options,
6506
6494
  ) {
6507
6495
  const now = Date.now();
6508
6496
  const { startTimestamp = now, endTimestamp = now } = hint;
@@ -6562,11 +6550,8 @@ async function _getResponseInfo(
6562
6550
  captureDetails,
6563
6551
  {
6564
6552
  networkCaptureBodies,
6565
- textEncoder,
6566
6553
  networkResponseHeaders,
6567
- }
6568
-
6569
- ,
6554
+ },
6570
6555
  response,
6571
6556
  responseBodySize,
6572
6557
  ) {
@@ -6583,7 +6568,7 @@ async function _getResponseInfo(
6583
6568
  const [bodyText, warning] = await _parseFetchResponseBody(response);
6584
6569
  const result = getResponseData(bodyText, {
6585
6570
  networkCaptureBodies,
6586
- textEncoder,
6571
+
6587
6572
  responseBodySize,
6588
6573
  captureDetails,
6589
6574
  headers,
@@ -6600,7 +6585,6 @@ function getResponseData(
6600
6585
  bodyText,
6601
6586
  {
6602
6587
  networkCaptureBodies,
6603
- textEncoder,
6604
6588
  responseBodySize,
6605
6589
  captureDetails,
6606
6590
  headers,
@@ -6610,9 +6594,7 @@ function getResponseData(
6610
6594
  ) {
6611
6595
  try {
6612
6596
  const size =
6613
- bodyText && bodyText.length && responseBodySize === undefined
6614
- ? getBodySize(bodyText, textEncoder)
6615
- : responseBodySize;
6597
+ bodyText && bodyText.length && responseBodySize === undefined ? getBodySize(bodyText) : responseBodySize;
6616
6598
 
6617
6599
  if (!captureDetails) {
6618
6600
  return buildSkippedNetworkRequestOrResponse(size);
@@ -6767,7 +6749,6 @@ async function captureXhrBreadcrumbToReplay(
6767
6749
  function enrichXhrBreadcrumb(
6768
6750
  breadcrumb,
6769
6751
  hint,
6770
- options,
6771
6752
  ) {
6772
6753
  const { xhr, input } = hint;
6773
6754
 
@@ -6775,10 +6756,10 @@ function enrichXhrBreadcrumb(
6775
6756
  return;
6776
6757
  }
6777
6758
 
6778
- const reqSize = getBodySize(input, options.textEncoder);
6759
+ const reqSize = getBodySize(input);
6779
6760
  const resSize = xhr.getResponseHeader('content-length')
6780
6761
  ? parseContentLengthHeader(xhr.getResponseHeader('content-length'))
6781
- : _getBodySize(xhr.response, xhr.responseType, options.textEncoder);
6762
+ : _getBodySize(xhr.response, xhr.responseType);
6782
6763
 
6783
6764
  if (reqSize !== undefined) {
6784
6765
  breadcrumb.data.request_body_size = reqSize;
@@ -6925,11 +6906,10 @@ function _parseXhrResponse(
6925
6906
  function _getBodySize(
6926
6907
  body,
6927
6908
  responseType,
6928
- textEncoder,
6929
6909
  ) {
6930
6910
  try {
6931
6911
  const bodyStr = responseType === 'json' && body && typeof body === 'object' ? JSON.stringify(body) : body;
6932
- return getBodySize(bodyStr, textEncoder);
6912
+ return getBodySize(bodyStr);
6933
6913
  } catch (e3) {
6934
6914
  return undefined;
6935
6915
  }
@@ -6945,8 +6925,6 @@ function handleNetworkBreadcrumbs(replay) {
6945
6925
  const client = getClient();
6946
6926
 
6947
6927
  try {
6948
- const textEncoder = new TextEncoder();
6949
-
6950
6928
  const {
6951
6929
  networkDetailAllowUrls,
6952
6930
  networkDetailDenyUrls,
@@ -6957,7 +6935,6 @@ function handleNetworkBreadcrumbs(replay) {
6957
6935
 
6958
6936
  const options = {
6959
6937
  replay,
6960
- textEncoder,
6961
6938
  networkDetailAllowUrls,
6962
6939
  networkDetailDenyUrls,
6963
6940
  networkCaptureBodies,
@@ -6965,12 +6942,8 @@ function handleNetworkBreadcrumbs(replay) {
6965
6942
  networkResponseHeaders,
6966
6943
  };
6967
6944
 
6968
- if (client && client.on) {
6945
+ if (client) {
6969
6946
  client.on('beforeAddBreadcrumb', (breadcrumb, hint) => beforeAddNetworkBreadcrumb(options, breadcrumb, hint));
6970
- } else {
6971
- // Fallback behavior
6972
- addFetchInstrumentationHandler(handleFetchSpanListener(replay));
6973
- addXhrInstrumentationHandler(handleXhrSpanListener(replay));
6974
6947
  }
6975
6948
  } catch (e2) {
6976
6949
  // Do nothing
@@ -6992,7 +6965,7 @@ function beforeAddNetworkBreadcrumb(
6992
6965
  // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
6993
6966
  // Because the hook runs synchronously, and the breadcrumb is afterwards passed on
6994
6967
  // So any async mutations to it will not be reflected in the final breadcrumb
6995
- enrichXhrBreadcrumb(breadcrumb, hint, options);
6968
+ enrichXhrBreadcrumb(breadcrumb, hint);
6996
6969
 
6997
6970
  // This call should not reject
6998
6971
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
@@ -7003,7 +6976,7 @@ function beforeAddNetworkBreadcrumb(
7003
6976
  // This has to be sync, as we need to ensure the breadcrumb is enriched in the same tick
7004
6977
  // Because the hook runs synchronously, and the breadcrumb is afterwards passed on
7005
6978
  // So any async mutations to it will not be reflected in the final breadcrumb
7006
- enrichFetchBreadcrumb(breadcrumb, hint, options);
6979
+ enrichFetchBreadcrumb(breadcrumb, hint);
7007
6980
 
7008
6981
  // This call should not reject
7009
6982
  // eslint-disable-next-line @typescript-eslint/no-floating-promises
@@ -7030,138 +7003,25 @@ function _isFetchHint(hint) {
7030
7003
  return hint && hint.response;
7031
7004
  }
7032
7005
 
7033
- let _LAST_BREADCRUMB = null;
7034
-
7035
- function isBreadcrumbWithCategory(breadcrumb) {
7036
- return !!breadcrumb.category;
7037
- }
7038
-
7039
- const handleScopeListener =
7040
- (replay) =>
7041
- (scope) => {
7042
- if (!replay.isEnabled()) {
7043
- return;
7044
- }
7045
-
7046
- const result = handleScope(scope);
7047
-
7048
- if (!result) {
7049
- return;
7050
- }
7051
-
7052
- addBreadcrumbEvent(replay, result);
7053
- };
7054
-
7055
- /**
7056
- * An event handler to handle scope changes.
7057
- */
7058
- function handleScope(scope) {
7059
- // TODO (v8): Remove this guard. This was put in place because we introduced
7060
- // Scope.getLastBreadcrumb mid-v7 which caused incompatibilities with older SDKs.
7061
- // For now, we'll just return null if the method doesn't exist but we should eventually
7062
- // get rid of this guard.
7063
- const newBreadcrumb = scope.getLastBreadcrumb && scope.getLastBreadcrumb();
7064
-
7065
- // Listener can be called when breadcrumbs have not changed, so we store the
7066
- // reference to the last crumb and only return a crumb if it has changed
7067
- if (_LAST_BREADCRUMB === newBreadcrumb || !newBreadcrumb) {
7068
- return null;
7069
- }
7070
-
7071
- _LAST_BREADCRUMB = newBreadcrumb;
7072
-
7073
- if (
7074
- !isBreadcrumbWithCategory(newBreadcrumb) ||
7075
- ['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(newBreadcrumb.category) ||
7076
- newBreadcrumb.category.startsWith('ui.')
7077
- ) {
7078
- return null;
7079
- }
7080
-
7081
- if (newBreadcrumb.category === 'console') {
7082
- return normalizeConsoleBreadcrumb(newBreadcrumb);
7083
- }
7084
-
7085
- return createBreadcrumb(newBreadcrumb);
7086
- }
7087
-
7088
- /** exported for tests only */
7089
- function normalizeConsoleBreadcrumb(
7090
- breadcrumb,
7091
- ) {
7092
- const args = breadcrumb.data && breadcrumb.data.arguments;
7093
-
7094
- if (!Array.isArray(args) || args.length === 0) {
7095
- return createBreadcrumb(breadcrumb);
7096
- }
7097
-
7098
- let isTruncated = false;
7099
-
7100
- // Avoid giant args captures
7101
- const normalizedArgs = args.map(arg => {
7102
- if (!arg) {
7103
- return arg;
7104
- }
7105
- if (typeof arg === 'string') {
7106
- if (arg.length > CONSOLE_ARG_MAX_SIZE) {
7107
- isTruncated = true;
7108
- return `${arg.slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
7109
- }
7110
-
7111
- return arg;
7112
- }
7113
- if (typeof arg === 'object') {
7114
- try {
7115
- const normalizedArg = normalize(arg, 7);
7116
- const stringified = JSON.stringify(normalizedArg);
7117
- if (stringified.length > CONSOLE_ARG_MAX_SIZE) {
7118
- isTruncated = true;
7119
- // We use the pretty printed JSON string here as a base
7120
- return `${JSON.stringify(normalizedArg, null, 2).slice(0, CONSOLE_ARG_MAX_SIZE)}…`;
7121
- }
7122
- return normalizedArg;
7123
- } catch (e) {
7124
- // fall back to default
7125
- }
7126
- }
7127
-
7128
- return arg;
7129
- });
7130
-
7131
- return createBreadcrumb({
7132
- ...breadcrumb,
7133
- data: {
7134
- ...breadcrumb.data,
7135
- arguments: normalizedArgs,
7136
- ...(isTruncated ? { _meta: { warnings: ['CONSOLE_ARG_TRUNCATED'] } } : {}),
7137
- },
7138
- });
7139
- }
7140
-
7141
7006
  /**
7142
7007
  * Add global listeners that cannot be removed.
7143
7008
  */
7144
7009
  function addGlobalListeners(replay) {
7145
7010
  // Listeners from core SDK //
7146
- const scope = getCurrentScope();
7147
7011
  const client = getClient();
7148
7012
 
7149
- scope.addScopeListener(handleScopeListener(replay));
7150
7013
  addClickKeypressInstrumentationHandler(handleDomListener(replay));
7151
7014
  addHistoryInstrumentationHandler(handleHistorySpanListener(replay));
7015
+ handleBreadcrumbs(replay);
7152
7016
  handleNetworkBreadcrumbs(replay);
7153
7017
 
7154
7018
  // Tag all (non replay) events that get sent to Sentry with the current
7155
7019
  // replay ID so that we can reference them later in the UI
7156
- const eventProcessor = handleGlobalEventListener(replay, !hasHooks(client));
7157
- if (client && client.addEventProcessor) {
7158
- client.addEventProcessor(eventProcessor);
7159
- } else {
7160
- addEventProcessor(eventProcessor);
7161
- }
7020
+ const eventProcessor = handleGlobalEventListener(replay);
7021
+ addEventProcessor(eventProcessor);
7162
7022
 
7163
7023
  // If a custom client has no hooks yet, we continue to use the "old" implementation
7164
- if (hasHooks(client)) {
7024
+ if (client) {
7165
7025
  client.on('beforeSendEvent', handleBeforeSendEvent(replay));
7166
7026
  client.on('afterSendEvent', handleAfterSendEvent(replay));
7167
7027
  client.on('createDsc', (dsc) => {
@@ -7199,11 +7059,6 @@ function addGlobalListeners(replay) {
7199
7059
  }
7200
7060
  }
7201
7061
 
7202
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
7203
- function hasHooks(client) {
7204
- return !!(client && client.on);
7205
- }
7206
-
7207
7062
  /**
7208
7063
  * Create a "span" for the total amount of memory being used by JS objects
7209
7064
  * (including v8 internal objects).
@@ -7525,9 +7380,7 @@ async function prepareReplayEvent({
7525
7380
 
7526
7381
  const eventHint = { event_id, integrations };
7527
7382
 
7528
- if (client.emit) {
7529
- client.emit('preprocessEvent', event, eventHint);
7530
- }
7383
+ client.emit('preprocessEvent', event, eventHint);
7531
7384
 
7532
7385
  const preparedEvent = (await prepareEvent(
7533
7386
  client.getOptions(),
@@ -7549,7 +7402,7 @@ async function prepareReplayEvent({
7549
7402
  preparedEvent.platform = preparedEvent.platform || 'javascript';
7550
7403
 
7551
7404
  // extract the SDK name because `client._prepareEvent` doesn't add it to the event
7552
- const metadata = client.getSdkMetadata && client.getSdkMetadata();
7405
+ const metadata = client.getSdkMetadata();
7553
7406
  const { name, version } = (metadata && metadata.sdk) || {};
7554
7407
 
7555
7408
  preparedEvent.sdk = {
@@ -7587,7 +7440,7 @@ async function sendReplayRequest({
7587
7440
  const dsn = client && client.getDsn();
7588
7441
 
7589
7442
  if (!client || !transport || !dsn || !session.sampled) {
7590
- return;
7443
+ return resolvedSyncPromise({});
7591
7444
  }
7592
7445
 
7593
7446
  const baseEvent = {
@@ -7608,7 +7461,7 @@ async function sendReplayRequest({
7608
7461
  // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
7609
7462
  client.recordDroppedEvent('event_processor', 'replay', baseEvent);
7610
7463
  logInfo('An event processor returned `null`, will not send event.');
7611
- return;
7464
+ return resolvedSyncPromise({});
7612
7465
  }
7613
7466
 
7614
7467
  /*
@@ -7670,11 +7523,6 @@ async function sendReplayRequest({
7670
7523
  throw error;
7671
7524
  }
7672
7525
 
7673
- // TODO (v8): we can remove this guard once transport.send's type signature doesn't include void anymore
7674
- if (!response) {
7675
- return response;
7676
- }
7677
-
7678
7526
  // If the status code is invalid, we want to immediately stop & not retry
7679
7527
  if (typeof response.statusCode === 'number' && (response.statusCode < 200 || response.statusCode >= 300)) {
7680
7528
  throw new TransportStatusCodeError(response.statusCode);
@@ -9533,12 +9381,9 @@ function _getMergedNetworkHeaders(headers) {
9533
9381
  /**
9534
9382
  * This is a small utility to get a type-safe instance of the Replay integration.
9535
9383
  */
9536
- // eslint-disable-next-line deprecation/deprecation
9537
9384
  function getReplay() {
9538
9385
  const client = getClient();
9539
- return (
9540
- client && client.getIntegrationByName && client.getIntegrationByName('Replay')
9541
- );
9386
+ return client && client.getIntegrationByName('Replay');
9542
9387
  }
9543
9388
 
9544
9389
  export { Replay, getReplay, replayIntegration };