@sentry/browser 9.8.0 → 9.9.0

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 (35) hide show
  1. package/build/npm/cjs/client.js +0 -3
  2. package/build/npm/cjs/client.js.map +1 -1
  3. package/build/npm/cjs/index.js +2 -0
  4. package/build/npm/cjs/index.js.map +1 -1
  5. package/build/npm/cjs/log.js +195 -0
  6. package/build/npm/cjs/log.js.map +1 -0
  7. package/build/npm/cjs/tracing/browserTracingIntegration.js +20 -0
  8. package/build/npm/cjs/tracing/browserTracingIntegration.js.map +1 -1
  9. package/build/npm/cjs/tracing/previousTrace.js +107 -0
  10. package/build/npm/cjs/tracing/previousTrace.js.map +1 -0
  11. package/build/npm/esm/client.js +1 -4
  12. package/build/npm/esm/client.js.map +1 -1
  13. package/build/npm/esm/index.js +2 -0
  14. package/build/npm/esm/index.js.map +1 -1
  15. package/build/npm/esm/log.js +187 -0
  16. package/build/npm/esm/log.js.map +1 -0
  17. package/build/npm/esm/package.json +1 -1
  18. package/build/npm/esm/tracing/browserTracingIntegration.js +21 -1
  19. package/build/npm/esm/tracing/browserTracingIntegration.js.map +1 -1
  20. package/build/npm/esm/tracing/previousTrace.js +101 -0
  21. package/build/npm/esm/tracing/previousTrace.js.map +1 -0
  22. package/build/npm/types/client.d.ts.map +1 -1
  23. package/build/npm/types/index.d.ts +2 -0
  24. package/build/npm/types/index.d.ts.map +1 -1
  25. package/build/npm/types/log.d.ts +93 -0
  26. package/build/npm/types/log.d.ts.map +1 -0
  27. package/build/npm/types/tracing/browserTracingIntegration.d.ts +22 -0
  28. package/build/npm/types/tracing/browserTracingIntegration.d.ts.map +1 -1
  29. package/build/npm/types/tracing/previousTrace.d.ts +31 -0
  30. package/build/npm/types/tracing/previousTrace.d.ts.map +1 -0
  31. package/build/npm/types-ts3.8/index.d.ts +2 -0
  32. package/build/npm/types-ts3.8/log.d.ts +93 -0
  33. package/build/npm/types-ts3.8/tracing/browserTracingIntegration.d.ts +22 -0
  34. package/build/npm/types-ts3.8/tracing/previousTrace.d.ts +31 -0
  35. package/package.json +7 -7
@@ -36,9 +36,6 @@ class BrowserClient extends core.Client {
36
36
  helpers.WINDOW.document.addEventListener('visibilitychange', () => {
37
37
  if (helpers.WINDOW.document.visibilityState === 'hidden') {
38
38
  this._flushOutcomes();
39
- if (this._options._experiments?.enableLogs) {
40
- core._INTERNAL_flushLogsBuffer(this);
41
- }
42
39
  }
43
40
  });
44
41
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n Client,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n getSDKSource,\n _INTERNAL_flushLogsBuffer,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /**\n * Important: Only set this option if you know what you are doing!\n *\n * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n * In case it is, it will stop initialization and log a warning\n * because browser extensions require a different Sentry initialization process:\n * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n *\n * Setting up the SDK in a browser extension with global error monitoring is not recommended\n * and will likely flood you with errors from other web sites or extensions. This can heavily\n * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n *\n * If this check wrongfully flags your setup as a browser extension, you can set this\n * option to `true` to skip the check.\n *\n * @default false\n */\n skipBrowserExtensionCheck?: boolean;\n };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /** If configured, this URL will be used as base URL for lazy loading integration. */\n cdnBaseUrl?: string;\n };\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends Client<BrowserClientOptions> {\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n public constructor(options: BrowserClientOptions) {\n const opts = {\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...options,\n };\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n if (opts.sendClientReports && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n this._flushOutcomes();\n if (this._options._experiments?.enableLogs) {\n _INTERNAL_flushLogsBuffer(this);\n }\n }\n });\n }\n\n if (this._options.sendDefaultPii) {\n this.on('postprocessEvent', addAutoIpAddressToUser);\n this.on('beforeSendSession', addAutoIpAddressToSession);\n }\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n event.platform = event.platform || 'javascript';\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n}\n"],"names":["Client","WINDOW","getSDKSource","applySdkMetadata","_INTERNAL_flushLogsBuffer","addAutoIpAddressToUser","addAutoIpAddressToSession","eventFromException","eventFromMessage"],"mappings":";;;;;;AAuBA;AACA;AACA;AACA;;AAmCA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,aAAA,SAAsBA,WAAM,CAAuB;AAChE;AACA;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAAwB;AACpD,IAAI,MAAM,OAAO;AACjB;AACA,MAAM,0BAA0B,EAAE,IAAI;AACtC,MAAM,GAAG,OAAO;AAChB,KAAK;AACL,IAAI,MAAM,YAAYC,cAAM,CAAC,iBAAkB,IAAGC,iBAAY,EAAE;AAChE,IAAIC,qBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;;AAE7D,IAAI,KAAK,CAAC,IAAI,CAAC;;AAEf,IAAI,IAAI,IAAI,CAAC,qBAAqBF,cAAM,CAAC,QAAQ,EAAE;AACnD,MAAMA,cAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM;AACjE,QAAQ,IAAIA,cAAM,CAAC,QAAQ,CAAC,eAAA,KAAoB,QAAQ,EAAE;AAC1D,UAAU,IAAI,CAAC,cAAc,EAAE;AAC/B,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE;AACtD,YAAYG,8BAAyB,CAAC,IAAI,CAAC;AAC3C;AACA;AACA,OAAO,CAAC;AACR;;AAEA,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;AACtC,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAEC,2BAAsB,CAAC;AACzD,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAEC,8BAAyB,CAAC;AAC7D;AACA;;AAEA;AACA;AACA;AACA,GAAS,kBAAkB,CAAC,SAAS,EAAW,IAAI,EAAkC;AACtF,IAAI,OAAOC,+BAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzG;;AAEA;AACA;AACA;AACA,GAAS,gBAAgB;AACzB,IAAI,OAAO;AACX,IAAI,KAAK,GAAkB,MAAM;AACjC,IAAI,IAAI;AACR,IAAwB;AACxB,IAAI,OAAOC,6BAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAC5G;;AAEA;AACA;AACA;AACA,GAAY,aAAa;AACzB,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,YAAY;AAChB,IAAI,cAAc;AAClB,IAA+B;AAC/B,IAAI,KAAK,CAAC,QAAS,GAAE,KAAK,CAAC,QAAA,IAAY,YAAY;;AAEnD,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC;AACzE;AACA;;;;"}
1
+ {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n Client,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n getSDKSource,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /**\n * Important: Only set this option if you know what you are doing!\n *\n * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n * In case it is, it will stop initialization and log a warning\n * because browser extensions require a different Sentry initialization process:\n * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n *\n * Setting up the SDK in a browser extension with global error monitoring is not recommended\n * and will likely flood you with errors from other web sites or extensions. This can heavily\n * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n *\n * If this check wrongfully flags your setup as a browser extension, you can set this\n * option to `true` to skip the check.\n *\n * @default false\n */\n skipBrowserExtensionCheck?: boolean;\n };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /** If configured, this URL will be used as base URL for lazy loading integration. */\n cdnBaseUrl?: string;\n };\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends Client<BrowserClientOptions> {\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n public constructor(options: BrowserClientOptions) {\n const opts = {\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...options,\n };\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n if (opts.sendClientReports && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n this._flushOutcomes();\n }\n });\n }\n\n if (this._options.sendDefaultPii) {\n this.on('postprocessEvent', addAutoIpAddressToUser);\n this.on('beforeSendSession', addAutoIpAddressToSession);\n }\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n event.platform = event.platform || 'javascript';\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n}\n"],"names":["Client","WINDOW","getSDKSource","applySdkMetadata","addAutoIpAddressToUser","addAutoIpAddressToSession","eventFromException","eventFromMessage"],"mappings":";;;;;;AAsBA;AACA;AACA;AACA;;AAmCA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,aAAA,SAAsBA,WAAM,CAAuB;AAChE;AACA;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAAwB;AACpD,IAAI,MAAM,OAAO;AACjB;AACA,MAAM,0BAA0B,EAAE,IAAI;AACtC,MAAM,GAAG,OAAO;AAChB,KAAK;AACL,IAAI,MAAM,YAAYC,cAAM,CAAC,iBAAkB,IAAGC,iBAAY,EAAE;AAChE,IAAIC,qBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;;AAE7D,IAAI,KAAK,CAAC,IAAI,CAAC;;AAEf,IAAI,IAAI,IAAI,CAAC,qBAAqBF,cAAM,CAAC,QAAQ,EAAE;AACnD,MAAMA,cAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM;AACjE,QAAQ,IAAIA,cAAM,CAAC,QAAQ,CAAC,eAAA,KAAoB,QAAQ,EAAE;AAC1D,UAAU,IAAI,CAAC,cAAc,EAAE;AAC/B;AACA,OAAO,CAAC;AACR;;AAEA,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;AACtC,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAEG,2BAAsB,CAAC;AACzD,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAEC,8BAAyB,CAAC;AAC7D;AACA;;AAEA;AACA;AACA;AACA,GAAS,kBAAkB,CAAC,SAAS,EAAW,IAAI,EAAkC;AACtF,IAAI,OAAOC,+BAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzG;;AAEA;AACA;AACA;AACA,GAAS,gBAAgB;AACzB,IAAI,OAAO;AACX,IAAI,KAAK,GAAkB,MAAM;AACjC,IAAI,IAAI;AACR,IAAwB;AACxB,IAAI,OAAOC,6BAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAC5G;;AAEA;AACA;AACA;AACA,GAAY,aAAa;AACzB,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,YAAY;AAChB,IAAI,cAAc;AAClB,IAA+B;AAC/B,IAAI,KAAK,CAAC,QAAS,GAAE,KAAK,CAAC,QAAA,IAAY,YAAY;;AAEnD,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC;AACzE;AACA;;;;"}
@@ -14,6 +14,7 @@ const httpcontext = require('./integrations/httpcontext.js');
14
14
  const linkederrors = require('./integrations/linkederrors.js');
15
15
  const browserapierrors = require('./integrations/browserapierrors.js');
16
16
  const lazyLoadIntegration = require('./utils/lazyLoadIntegration.js');
17
+ const log = require('./log.js');
17
18
  const reportingobserver = require('./integrations/reportingobserver.js');
18
19
  const httpclient = require('./integrations/httpclient.js');
19
20
  const contextlines = require('./integrations/contextlines.js');
@@ -126,6 +127,7 @@ exports.httpContextIntegration = httpcontext.httpContextIntegration;
126
127
  exports.linkedErrorsIntegration = linkederrors.linkedErrorsIntegration;
127
128
  exports.browserApiErrorsIntegration = browserapierrors.browserApiErrorsIntegration;
128
129
  exports.lazyLoadIntegration = lazyLoadIntegration.lazyLoadIntegration;
130
+ exports.logger = log;
129
131
  exports.reportingObserverIntegration = reportingobserver.reportingObserverIntegration;
130
132
  exports.httpClientIntegration = httpclient.httpClientIntegration;
131
133
  exports.contextLinesIntegration = contextlines.contextLinesIntegration;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,195 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const helpers = require('./helpers.js');
5
+
6
+ /**
7
+ * TODO: Make this configurable
8
+ */
9
+ const DEFAULT_FLUSH_INTERVAL = 5000;
10
+
11
+ let timeout;
12
+
13
+ /**
14
+ * This is a global timeout that is used to flush the logs buffer.
15
+ * It is used to ensure that logs are flushed even if the client is not flushed.
16
+ */
17
+ function startFlushTimeout(client) {
18
+ if (timeout) {
19
+ clearTimeout(timeout);
20
+ }
21
+
22
+ timeout = setTimeout(() => {
23
+ core._INTERNAL_flushLogsBuffer(client);
24
+ }, DEFAULT_FLUSH_INTERVAL);
25
+ }
26
+
27
+ let isClientListenerAdded = false;
28
+ /**
29
+ * This is a function that is used to add a flush listener to the client.
30
+ * It is used to ensure that the logger buffer is flushed when the client is flushed.
31
+ */
32
+ function addFlushingListeners(client) {
33
+ if (isClientListenerAdded || !client.getOptions()._experiments?.enableLogs) {
34
+ return;
35
+ }
36
+
37
+ isClientListenerAdded = true;
38
+
39
+ if (helpers.WINDOW.document) {
40
+ helpers.WINDOW.document.addEventListener('visibilitychange', () => {
41
+ if (helpers.WINDOW.document.visibilityState === 'hidden') {
42
+ core._INTERNAL_flushLogsBuffer(client);
43
+ }
44
+ });
45
+ }
46
+
47
+ client.on('flush', () => {
48
+ core._INTERNAL_flushLogsBuffer(client);
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Capture a log with the given level.
54
+ *
55
+ * @param level - The level of the log.
56
+ * @param message - The message to log.
57
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
58
+ * @param severityNumber - The severity number of the log.
59
+ */
60
+ function captureLog(
61
+ level,
62
+ message,
63
+ attributes,
64
+ severityNumber,
65
+ ) {
66
+ const client = core.getClient();
67
+ if (client) {
68
+ addFlushingListeners(client);
69
+
70
+ startFlushTimeout(client);
71
+ }
72
+
73
+ core._INTERNAL_captureLog({ level, message, attributes, severityNumber }, client, undefined);
74
+ }
75
+
76
+ /**
77
+ * @summary Capture a log with the `trace` level. Requires `_experiments.enableLogs` to be enabled.
78
+ *
79
+ * @param message - The message to log.
80
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
81
+ *
82
+ * @example
83
+ *
84
+ * ```
85
+ * Sentry.logger.trace('Hello world', { userId: 100 });
86
+ * ```
87
+ */
88
+ function trace(message, attributes) {
89
+ captureLog('trace', message, attributes);
90
+ }
91
+
92
+ /**
93
+ * @summary Capture a log with the `debug` level. Requires `_experiments.enableLogs` to be enabled.
94
+ *
95
+ * @param message - The message to log.
96
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
97
+ *
98
+ * @example
99
+ *
100
+ * ```
101
+ * Sentry.logger.debug('Hello world', { userId: 100 });
102
+ * ```
103
+ */
104
+ function debug(message, attributes) {
105
+ captureLog('debug', message, attributes);
106
+ }
107
+
108
+ /**
109
+ * @summary Capture a log with the `info` level. Requires `_experiments.enableLogs` to be enabled.
110
+ *
111
+ * @param message - The message to log.
112
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
113
+ *
114
+ * @example
115
+ *
116
+ * ```
117
+ * Sentry.logger.info('Hello world', { userId: 100 });
118
+ * ```
119
+ */
120
+ function info(message, attributes) {
121
+ captureLog('info', message, attributes);
122
+ }
123
+
124
+ /**
125
+ * @summary Capture a log with the `warn` level. Requires `_experiments.enableLogs` to be enabled.
126
+ *
127
+ * @param message - The message to log.
128
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
129
+ *
130
+ * @example
131
+ *
132
+ * ```
133
+ * Sentry.logger.warn('Hello world', { userId: 100 });
134
+ * ```
135
+ */
136
+ function warn(message, attributes) {
137
+ captureLog('warn', message, attributes);
138
+ }
139
+
140
+ /**
141
+ * @summary Capture a log with the `error` level. Requires `_experiments.enableLogs` to be enabled.
142
+ *
143
+ * @param message - The message to log.
144
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
145
+ *
146
+ * @example
147
+ *
148
+ * ```
149
+ * Sentry.logger.error('Hello world', { userId: 100 });
150
+ * ```
151
+ */
152
+ function error(message, attributes) {
153
+ captureLog('error', message, attributes);
154
+ }
155
+
156
+ /**
157
+ * @summary Capture a log with the `fatal` level. Requires `_experiments.enableLogs` to be enabled.
158
+ *
159
+ * @param message - The message to log.
160
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
161
+ *
162
+ * @example
163
+ *
164
+ * ```
165
+ * Sentry.logger.fatal('Hello world', { userId: 100 });
166
+ * ```
167
+ */
168
+ function fatal(message, attributes) {
169
+ captureLog('fatal', message, attributes);
170
+ }
171
+
172
+ /**
173
+ * @summary Capture a log with the `critical` level. Requires `_experiments.enableLogs` to be enabled.
174
+ *
175
+ * @param message - The message to log.
176
+ * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.
177
+ *
178
+ * @example
179
+ *
180
+ * ```
181
+ * Sentry.logger.critical('Hello world', { userId: 100 });
182
+ * ```
183
+ */
184
+ function critical(message, attributes) {
185
+ captureLog('critical', message, attributes);
186
+ }
187
+
188
+ exports.critical = critical;
189
+ exports.debug = debug;
190
+ exports.error = error;
191
+ exports.fatal = fatal;
192
+ exports.info = info;
193
+ exports.trace = trace;
194
+ exports.warn = warn;
195
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sources":["../../../src/log.ts"],"sourcesContent":["import type { LogSeverityLevel, Log, Client } from '@sentry/core';\nimport { getClient, _INTERNAL_captureLog, _INTERNAL_flushLogsBuffer } from '@sentry/core';\n\nimport { WINDOW } from './helpers';\n\n/**\n * TODO: Make this configurable\n */\nconst DEFAULT_FLUSH_INTERVAL = 5000;\n\nlet timeout: ReturnType<typeof setTimeout> | undefined;\n\n/**\n * This is a global timeout that is used to flush the logs buffer.\n * It is used to ensure that logs are flushed even if the client is not flushed.\n */\nfunction startFlushTimeout(client: Client): void {\n if (timeout) {\n clearTimeout(timeout);\n }\n\n timeout = setTimeout(() => {\n _INTERNAL_flushLogsBuffer(client);\n }, DEFAULT_FLUSH_INTERVAL);\n}\n\nlet isClientListenerAdded = false;\n/**\n * This is a function that is used to add a flush listener to the client.\n * It is used to ensure that the logger buffer is flushed when the client is flushed.\n */\nfunction addFlushingListeners(client: Client): void {\n if (isClientListenerAdded || !client.getOptions()._experiments?.enableLogs) {\n return;\n }\n\n isClientListenerAdded = true;\n\n if (WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n _INTERNAL_flushLogsBuffer(client);\n }\n });\n }\n\n client.on('flush', () => {\n _INTERNAL_flushLogsBuffer(client);\n });\n}\n\n/**\n * Capture a log with the given level.\n *\n * @param level - The level of the log.\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n * @param severityNumber - The severity number of the log.\n */\nfunction captureLog(\n level: LogSeverityLevel,\n message: string,\n attributes?: Log['attributes'],\n severityNumber?: Log['severityNumber'],\n): void {\n const client = getClient();\n if (client) {\n addFlushingListeners(client);\n\n startFlushTimeout(client);\n }\n\n _INTERNAL_captureLog({ level, message, attributes, severityNumber }, client, undefined);\n}\n\n/**\n * @summary Capture a log with the `trace` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.trace('Hello world', { userId: 100 });\n * ```\n */\nexport function trace(message: string, attributes?: Log['attributes']): void {\n captureLog('trace', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `debug` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.debug('Hello world', { userId: 100 });\n * ```\n */\nexport function debug(message: string, attributes?: Log['attributes']): void {\n captureLog('debug', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `info` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.info('Hello world', { userId: 100 });\n * ```\n */\nexport function info(message: string, attributes?: Log['attributes']): void {\n captureLog('info', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `warn` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.warn('Hello world', { userId: 100 });\n * ```\n */\nexport function warn(message: string, attributes?: Log['attributes']): void {\n captureLog('warn', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `error` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.error('Hello world', { userId: 100 });\n * ```\n */\nexport function error(message: string, attributes?: Log['attributes']): void {\n captureLog('error', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `fatal` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.fatal('Hello world', { userId: 100 });\n * ```\n */\nexport function fatal(message: string, attributes?: Log['attributes']): void {\n captureLog('fatal', message, attributes);\n}\n\n/**\n * @summary Capture a log with the `critical` level. Requires `_experiments.enableLogs` to be enabled.\n *\n * @param message - The message to log.\n * @param attributes - Arbitrary structured data that stores information about the log - e.g., userId: 100.\n *\n * @example\n *\n * ```\n * Sentry.logger.critical('Hello world', { userId: 100 });\n * ```\n */\nexport function critical(message: string, attributes?: Log['attributes']): void {\n captureLog('critical', message, attributes);\n}\n"],"names":["_INTERNAL_flushLogsBuffer","WINDOW","getClient","_INTERNAL_captureLog"],"mappings":";;;;;AAKA;AACA;AACA;AACA,MAAM,sBAAA,GAAyB,IAAI;;AAEnC,IAAI,OAAO;;AAEX;AACA;AACA;AACA;AACA,SAAS,iBAAiB,CAAC,MAAM,EAAgB;AACjD,EAAE,IAAI,OAAO,EAAE;AACf,IAAI,YAAY,CAAC,OAAO,CAAC;AACzB;;AAEA,EAAE,UAAU,UAAU,CAAC,MAAM;AAC7B,IAAIA,8BAAyB,CAAC,MAAM,CAAC;AACrC,GAAG,EAAE,sBAAsB,CAAC;AAC5B;;AAEA,IAAI,qBAAA,GAAwB,KAAK;AACjC;AACA;AACA;AACA;AACA,SAAS,oBAAoB,CAAC,MAAM,EAAgB;AACpD,EAAE,IAAI,qBAAsB,IAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,YAAY,EAAE,UAAU,EAAE;AAC9E,IAAI;AACJ;;AAEA,EAAE,qBAAA,GAAwB,IAAI;;AAE9B,EAAE,IAAIC,cAAM,CAAC,QAAQ,EAAE;AACvB,IAAIA,cAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM;AAC/D,MAAM,IAAIA,cAAM,CAAC,QAAQ,CAAC,eAAA,KAAoB,QAAQ,EAAE;AACxD,QAAQD,8BAAyB,CAAC,MAAM,CAAC;AACzC;AACA,KAAK,CAAC;AACN;;AAEA,EAAE,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM;AAC3B,IAAIA,8BAAyB,CAAC,MAAM,CAAC;AACrC,GAAG,CAAC;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,UAAU;AACnB,EAAE,KAAK;AACP,EAAE,OAAO;AACT,EAAE,UAAU;AACZ,EAAE,cAAc;AAChB,EAAQ;AACR,EAAE,MAAM,MAAA,GAASE,cAAS,EAAE;AAC5B,EAAE,IAAI,MAAM,EAAE;AACd,IAAI,oBAAoB,CAAC,MAAM,CAAC;;AAEhC,IAAI,iBAAiB,CAAC,MAAM,CAAC;AAC7B;;AAEA,EAAEC,yBAAoB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,CAAC;AACzF;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,KAAK,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC7E,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,KAAK,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC7E,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC5E,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC;AACzC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,IAAI,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC5E,EAAE,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,UAAU,CAAC;AACzC;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,KAAK,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC7E,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,KAAK,CAAC,OAAO,EAAU,UAAU,EAA4B;AAC7E,EAAE,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC;AAC1C;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,QAAQ,CAAC,OAAO,EAAU,UAAU,EAA4B;AAChF,EAAE,UAAU,CAAC,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC;AAC7C;;;;;;;;;;"}
@@ -6,6 +6,7 @@ const debugBuild = require('../debug-build.js');
6
6
  const helpers = require('../helpers.js');
7
7
  const backgroundtab = require('./backgroundtab.js');
8
8
  const request = require('./request.js');
9
+ const previousTrace = require('./previousTrace.js');
9
10
 
10
11
  /* eslint-disable max-lines */
11
12
 
@@ -19,6 +20,7 @@ const DEFAULT_BROWSER_TRACING_OPTIONS = {
19
20
  enableLongTask: true,
20
21
  enableLongAnimationFrame: true,
21
22
  enableInp: true,
23
+ linkPreviousTrace: 'in-memory',
22
24
  _experiments: {},
23
25
  ...request.defaultRequestInstrumentationOptions,
24
26
  };
@@ -58,6 +60,7 @@ const browserTracingIntegration = ((_options = {}) => {
58
60
  enableHTTPTimings,
59
61
  instrumentPageLoad,
60
62
  instrumentNavigation,
63
+ linkPreviousTrace,
61
64
  } = {
62
65
  ...DEFAULT_BROWSER_TRACING_OPTIONS,
63
66
  ..._options,
@@ -200,6 +203,23 @@ const browserTracingIntegration = ((_options = {}) => {
200
203
  });
201
204
  });
202
205
 
206
+ if (linkPreviousTrace !== 'off') {
207
+ let inMemoryPreviousTraceInfo = undefined;
208
+
209
+ client.on('spanStart', span => {
210
+ if (core.getRootSpan(span) !== span) {
211
+ return;
212
+ }
213
+
214
+ if (linkPreviousTrace === 'session-storage') {
215
+ const updatedPreviousTraceInfo = previousTrace.addPreviousTraceSpanLink(previousTrace.getPreviousTraceFromSessionStorage(), span);
216
+ previousTrace.storePreviousTraceInSessionStorage(updatedPreviousTraceInfo);
217
+ } else {
218
+ inMemoryPreviousTraceInfo = previousTrace.addPreviousTraceSpanLink(inMemoryPreviousTraceInfo, span);
219
+ }
220
+ });
221
+ }
222
+
203
223
  if (helpers.WINDOW.location) {
204
224
  if (instrumentPageLoad) {
205
225
  const origin = core.browserPerformanceTimeOrigin();
@@ -1 +1 @@
1
- {"version":3,"file":"browserTracingIntegration.js","sources":["../../../../src/tracing/browserTracingIntegration.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport {\n addHistoryInstrumentationHandler,\n addPerformanceEntries,\n registerInpInteractionListener,\n startTrackingINP,\n startTrackingInteractions,\n startTrackingLongAnimationFrames,\n startTrackingLongTasks,\n startTrackingWebVitals,\n} from '@sentry-internal/browser-utils';\nimport type { Client, IntegrationFn, Span, StartSpanOptions, TransactionSource } from '@sentry/core';\nimport {\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n TRACING_DEFAULTS,\n addNonEnumerableProperty,\n browserPerformanceTimeOrigin,\n generateTraceId,\n getClient,\n getCurrentScope,\n getDynamicSamplingContextFromSpan,\n getIsolationScope,\n getLocationHref,\n logger,\n propagationContextFromHeaders,\n registerSpanErrorInstrumentation,\n spanIsSampled,\n spanToJSON,\n startIdleSpan,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { registerBackgroundTabDetection } from './backgroundtab';\nimport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request';\n\nexport const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\ninterface RouteInfo {\n name: string | undefined;\n source: TransactionSource | undefined;\n}\n\n/** Options for Browser Tracing integration */\nexport interface BrowserTracingOptions {\n /**\n * The time that has to pass without any span being created.\n * If this time is exceeded, the idle span will finish.\n *\n * Default: 1000 (ms)\n */\n idleTimeout: number;\n\n /**\n * The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 30000 (ms)\n */\n finalTimeout: number;\n\n /**\n The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 15000 (ms)\n */\n childSpanTimeout: number;\n\n /**\n * If a span should be created on page load.\n * If this is set to `false`, this integration will not start the default page load span.\n * Default: true\n */\n instrumentPageLoad: boolean;\n\n /**\n * If a span should be created on navigation (history change).\n * If this is set to `false`, this integration will not start the default navigation spans.\n * Default: true\n */\n instrumentNavigation: boolean;\n\n /**\n * Flag spans where tabs moved to background with \"cancelled\". Browser background tab timing is\n * not suited towards doing precise measurements of operations. By default, we recommend that this option\n * be enabled as background transactions can mess up your statistics in nondeterministic ways.\n *\n * Default: true\n */\n markBackgroundSpan: boolean;\n\n /**\n * If true, Sentry will capture long tasks and add them to the corresponding transaction.\n *\n * Default: true\n */\n enableLongTask: boolean;\n\n /**\n * If true, Sentry will capture long animation frames and add them to the corresponding transaction.\n *\n * Default: false\n */\n enableLongAnimationFrame: boolean;\n\n /**\n * If true, Sentry will capture first input delay and add it to the corresponding transaction.\n *\n * Default: true\n */\n enableInp: boolean;\n\n /**\n * Flag to disable patching all together for fetch requests.\n *\n * Default: true\n */\n traceFetch: boolean;\n\n /**\n * Flag to disable patching all together for xhr requests.\n *\n * Default: true\n */\n traceXHR: boolean;\n\n /**\n * Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.\n * Do not enable this in case you have live streams or very long running streams.\n *\n * Default: false\n */\n trackFetchStreamPerformance: boolean;\n\n /**\n * If true, Sentry will capture http timings and add them to the corresponding http spans.\n *\n * Default: true\n */\n enableHTTPTimings: boolean;\n\n /**\n * _experiments allows the user to send options to define how this integration works.\n *\n * Default: undefined\n */\n _experiments: Partial<{\n enableInteractions: boolean;\n enableStandaloneClsSpans: boolean;\n }>;\n\n /**\n * A callback which is called before a span for a pageload or navigation is started.\n * It receives the options passed to `startSpan`, and expects to return an updated options object.\n */\n beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n /**\n * This function will be called before creating a span for a request with the given url.\n * Return false if you don't want a span for the given url.\n *\n * Default: (url: string) => true\n */\n shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nconst DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = {\n ...TRACING_DEFAULTS,\n instrumentNavigation: true,\n instrumentPageLoad: true,\n markBackgroundSpan: true,\n enableLongTask: true,\n enableLongAnimationFrame: true,\n enableInp: true,\n _experiments: {},\n ...defaultRequestInstrumentationOptions,\n};\n\n/**\n * The Browser Tracing integration automatically instruments browser pageload/navigation\n * actions as transactions, and captures requests, metrics and errors as spans.\n *\n * The integration can be configured with a variety of options, and can be extended to use\n * any routing library.\n *\n * We explicitly export the proper type here, as this has to be extended in some cases.\n */\nexport const browserTracingIntegration = ((_options: Partial<BrowserTracingOptions> = {}) => {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n registerSpanErrorInstrumentation();\n\n const {\n enableInp,\n enableLongTask,\n enableLongAnimationFrame,\n _experiments: { enableInteractions, enableStandaloneClsSpans },\n beforeStartSpan,\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n markBackgroundSpan,\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n instrumentPageLoad,\n instrumentNavigation,\n } = {\n ...DEFAULT_BROWSER_TRACING_OPTIONS,\n ..._options,\n };\n\n const _collectWebVitals = startTrackingWebVitals({ recordClsStandaloneSpans: enableStandaloneClsSpans || false });\n\n if (enableInp) {\n startTrackingINP();\n }\n\n if (\n enableLongAnimationFrame &&\n GLOBAL_OBJ.PerformanceObserver &&\n PerformanceObserver.supportedEntryTypes &&\n PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n ) {\n startTrackingLongAnimationFrames();\n } else if (enableLongTask) {\n startTrackingLongTasks();\n }\n\n if (enableInteractions) {\n startTrackingInteractions();\n }\n\n const latestRoute: RouteInfo = {\n name: undefined,\n source: undefined,\n };\n\n /** Create routing idle transaction. */\n function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions): void {\n const isPageloadTransaction = startSpanOptions.op === 'pageload';\n\n const finalStartSpanOptions: StartSpanOptions = beforeStartSpan\n ? beforeStartSpan(startSpanOptions)\n : startSpanOptions;\n\n const attributes = finalStartSpanOptions.attributes || {};\n\n // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`\n // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.\n if (startSpanOptions.name !== finalStartSpanOptions.name) {\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'custom';\n finalStartSpanOptions.attributes = attributes;\n }\n\n latestRoute.name = finalStartSpanOptions.name;\n latestRoute.source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n const idleSpan = startIdleSpan(finalStartSpanOptions, {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n // should wait for finish signal if it's a pageload transaction\n disableAutoFinish: isPageloadTransaction,\n beforeSpanEnd: span => {\n _collectWebVitals();\n addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans });\n setActiveIdleSpan(client, undefined);\n\n // A trace should stay consistent over the entire timespan of one route - even after the pageload/navigation ended.\n // Only when another navigation happens, we want to create a new trace.\n // This way, e.g. errors that occur after the pageload span ended are still associated to the pageload trace.\n const scope = getCurrentScope();\n const oldPropagationContext = scope.getPropagationContext();\n\n scope.setPropagationContext({\n ...oldPropagationContext,\n traceId: idleSpan.spanContext().traceId,\n sampled: spanIsSampled(idleSpan),\n dsc: getDynamicSamplingContextFromSpan(span),\n });\n },\n });\n setActiveIdleSpan(client, idleSpan);\n\n function emitFinish(): void {\n if (optionalWindowDocument && ['interactive', 'complete'].includes(optionalWindowDocument.readyState)) {\n client.emit('idleSpanEnableAutoFinish', idleSpan);\n }\n }\n\n if (isPageloadTransaction && optionalWindowDocument) {\n optionalWindowDocument.addEventListener('readystatechange', () => {\n emitFinish();\n });\n\n emitFinish();\n }\n }\n\n return {\n name: BROWSER_TRACING_INTEGRATION_ID,\n afterAllSetup(client) {\n let startingUrl: string | undefined = getLocationHref();\n\n function maybeEndActiveSpan(): void {\n const activeSpan = getActiveIdleSpan(client);\n\n if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n DEBUG_BUILD && logger.log(`[Tracing] Finishing current active span with op: ${spanToJSON(activeSpan).op}`);\n // If there's an open active span, we need to finish it before creating an new one.\n activeSpan.end();\n }\n }\n\n client.on('startNavigationSpan', startSpanOptions => {\n if (getClient() !== client) {\n return;\n }\n\n maybeEndActiveSpan();\n\n getIsolationScope().setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() });\n getCurrentScope().setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() });\n\n _createRouteSpan(client, {\n op: 'navigation',\n ...startSpanOptions,\n });\n });\n\n client.on('startPageLoadSpan', (startSpanOptions, traceOptions = {}) => {\n if (getClient() !== client) {\n return;\n }\n maybeEndActiveSpan();\n\n const sentryTrace = traceOptions.sentryTrace || getMetaContent('sentry-trace');\n const baggage = traceOptions.baggage || getMetaContent('baggage');\n\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n getCurrentScope().setPropagationContext(propagationContext);\n\n _createRouteSpan(client, {\n op: 'pageload',\n ...startSpanOptions,\n });\n });\n\n if (WINDOW.location) {\n if (instrumentPageLoad) {\n const origin = browserPerformanceTimeOrigin();\n startBrowserTracingPageLoadSpan(client, {\n name: WINDOW.location.pathname,\n // pageload should always start at timeOrigin (and needs to be in s, not ms)\n startTime: origin ? origin / 1000 : undefined,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',\n },\n });\n }\n\n if (instrumentNavigation) {\n addHistoryInstrumentationHandler(({ to, from }) => {\n /**\n * This early return is there to account for some cases where a navigation transaction starts right after\n * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't\n * create an uneccessary navigation transaction.\n *\n * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also\n * only be caused in certain development environments where the usage of a hot module reloader is causing\n * errors.\n */\n if (from === undefined && startingUrl?.indexOf(to) !== -1) {\n startingUrl = undefined;\n return;\n }\n\n if (from !== to) {\n startingUrl = undefined;\n startBrowserTracingNavigationSpan(client, {\n name: WINDOW.location.pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',\n },\n });\n }\n });\n }\n }\n\n if (markBackgroundSpan) {\n registerBackgroundTabDetection();\n }\n\n if (enableInteractions) {\n registerInteractionListener(client, idleTimeout, finalTimeout, childSpanTimeout, latestRoute);\n }\n\n if (enableInp) {\n registerInpInteractionListener();\n }\n\n instrumentOutgoingRequests(client, {\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n tracePropagationTargets: client.getOptions().tracePropagationTargets,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Manually start a page load span.\n * This will only do something if a browser tracing integration integration has been setup.\n *\n * If you provide a custom `traceOptions` object, it will be used to continue the trace\n * instead of the default behavior, which is to look it up on the <meta> tags.\n */\nexport function startBrowserTracingPageLoadSpan(\n client: Client,\n spanOptions: StartSpanOptions,\n traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n): Span | undefined {\n client.emit('startPageLoadSpan', spanOptions, traceOptions);\n getCurrentScope().setTransactionName(spanOptions.name);\n\n return getActiveIdleSpan(client);\n}\n\n/**\n * Manually start a navigation span.\n * This will only do something if a browser tracing integration has been setup.\n */\nexport function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined {\n client.emit('startNavigationSpan', spanOptions);\n\n getCurrentScope().setTransactionName(spanOptions.name);\n\n return getActiveIdleSpan(client);\n}\n\n/** Returns the value of a meta tag */\nexport function getMetaContent(metaName: string): string | undefined {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n const metaTag = optionalWindowDocument?.querySelector(`meta[name=${metaName}]`);\n return metaTag?.getAttribute('content') || undefined;\n}\n\n/** Start listener for interaction transactions */\nfunction registerInteractionListener(\n client: Client,\n idleTimeout: BrowserTracingOptions['idleTimeout'],\n finalTimeout: BrowserTracingOptions['finalTimeout'],\n childSpanTimeout: BrowserTracingOptions['childSpanTimeout'],\n latestRoute: RouteInfo,\n): void {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n let inflightInteractionSpan: Span | undefined;\n const registerInteractionTransaction = (): void => {\n const op = 'ui.action.click';\n\n const activeIdleSpan = getActiveIdleSpan(client);\n if (activeIdleSpan) {\n const currentRootSpanOp = spanToJSON(activeIdleSpan).op;\n if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) {\n DEBUG_BUILD &&\n logger.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`);\n return undefined;\n }\n }\n\n if (inflightInteractionSpan) {\n inflightInteractionSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'interactionInterrupted');\n inflightInteractionSpan.end();\n inflightInteractionSpan = undefined;\n }\n\n if (!latestRoute.name) {\n DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);\n return undefined;\n }\n\n inflightInteractionSpan = startIdleSpan(\n {\n name: latestRoute.name,\n op,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.source || 'url',\n },\n },\n {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n },\n );\n };\n\n if (optionalWindowDocument) {\n addEventListener('click', registerInteractionTransaction, { once: false, capture: true });\n }\n}\n\n// We store the active idle span on the client object, so we can access it from exported functions\nconst ACTIVE_IDLE_SPAN_PROPERTY = '_sentry_idleSpan';\nfunction getActiveIdleSpan(client: Client): Span | undefined {\n return (client as { [ACTIVE_IDLE_SPAN_PROPERTY]?: Span })[ACTIVE_IDLE_SPAN_PROPERTY];\n}\n\nfunction setActiveIdleSpan(client: Client, span: Span | undefined): void {\n addNonEnumerableProperty(client, ACTIVE_IDLE_SPAN_PROPERTY, span);\n}\n"],"names":["TRACING_DEFAULTS","defaultRequestInstrumentationOptions","WINDOW","registerSpanErrorInstrumentation","startTrackingWebVitals","startTrackingINP","GLOBAL_OBJ","startTrackingLongAnimationFrames","startTrackingLongTasks","startTrackingInteractions","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","startIdleSpan","addPerformanceEntries","getCurrentScope","spanIsSampled","getDynamicSamplingContextFromSpan","getLocationHref","spanToJSON","DEBUG_BUILD","logger","getClient","getIsolationScope","generateTraceId","propagationContextFromHeaders","browserPerformanceTimeOrigin","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","addHistoryInstrumentationHandler","registerBackgroundTabDetection","registerInpInteractionListener","instrumentOutgoingRequests","SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON","addNonEnumerableProperty"],"mappings":"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"}
1
+ {"version":3,"file":"browserTracingIntegration.js","sources":["../../../../src/tracing/browserTracingIntegration.ts"],"sourcesContent":["/* eslint-disable max-lines */\nimport {\n addHistoryInstrumentationHandler,\n addPerformanceEntries,\n registerInpInteractionListener,\n startTrackingINP,\n startTrackingInteractions,\n startTrackingLongAnimationFrames,\n startTrackingLongTasks,\n startTrackingWebVitals,\n} from '@sentry-internal/browser-utils';\nimport type { Client, IntegrationFn, Span, StartSpanOptions, TransactionSource } from '@sentry/core';\nimport {\n GLOBAL_OBJ,\n SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n TRACING_DEFAULTS,\n addNonEnumerableProperty,\n browserPerformanceTimeOrigin,\n generateTraceId,\n getClient,\n getCurrentScope,\n getDynamicSamplingContextFromSpan,\n getIsolationScope,\n getLocationHref,\n getRootSpan,\n logger,\n propagationContextFromHeaders,\n registerSpanErrorInstrumentation,\n spanIsSampled,\n spanToJSON,\n startIdleSpan,\n} from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\nimport { WINDOW } from '../helpers';\nimport { registerBackgroundTabDetection } from './backgroundtab';\nimport { defaultRequestInstrumentationOptions, instrumentOutgoingRequests } from './request';\nimport type { PreviousTraceInfo } from './previousTrace';\nimport {\n addPreviousTraceSpanLink,\n getPreviousTraceFromSessionStorage,\n storePreviousTraceInSessionStorage,\n} from './previousTrace';\n\nexport const BROWSER_TRACING_INTEGRATION_ID = 'BrowserTracing';\n\ninterface RouteInfo {\n name: string | undefined;\n source: TransactionSource | undefined;\n}\n\n/** Options for Browser Tracing integration */\nexport interface BrowserTracingOptions {\n /**\n * The time that has to pass without any span being created.\n * If this time is exceeded, the idle span will finish.\n *\n * Default: 1000 (ms)\n */\n idleTimeout: number;\n\n /**\n * The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 30000 (ms)\n */\n finalTimeout: number;\n\n /**\n The max. time an idle span may run.\n * If this time is exceeded, the idle span will finish no matter what.\n *\n * Default: 15000 (ms)\n */\n childSpanTimeout: number;\n\n /**\n * If a span should be created on page load.\n * If this is set to `false`, this integration will not start the default page load span.\n * Default: true\n */\n instrumentPageLoad: boolean;\n\n /**\n * If a span should be created on navigation (history change).\n * If this is set to `false`, this integration will not start the default navigation spans.\n * Default: true\n */\n instrumentNavigation: boolean;\n\n /**\n * Flag spans where tabs moved to background with \"cancelled\". Browser background tab timing is\n * not suited towards doing precise measurements of operations. By default, we recommend that this option\n * be enabled as background transactions can mess up your statistics in nondeterministic ways.\n *\n * Default: true\n */\n markBackgroundSpan: boolean;\n\n /**\n * If true, Sentry will capture long tasks and add them to the corresponding transaction.\n *\n * Default: true\n */\n enableLongTask: boolean;\n\n /**\n * If true, Sentry will capture long animation frames and add them to the corresponding transaction.\n *\n * Default: false\n */\n enableLongAnimationFrame: boolean;\n\n /**\n * If true, Sentry will capture first input delay and add it to the corresponding transaction.\n *\n * Default: true\n */\n enableInp: boolean;\n\n /**\n * Flag to disable patching all together for fetch requests.\n *\n * Default: true\n */\n traceFetch: boolean;\n\n /**\n * Flag to disable patching all together for xhr requests.\n *\n * Default: true\n */\n traceXHR: boolean;\n\n /**\n * Flag to disable tracking of long-lived streams, like server-sent events (SSE) via fetch.\n * Do not enable this in case you have live streams or very long running streams.\n *\n * Default: false\n */\n trackFetchStreamPerformance: boolean;\n\n /**\n * If true, Sentry will capture http timings and add them to the corresponding http spans.\n *\n * Default: true\n */\n enableHTTPTimings: boolean;\n\n /**\n * Link the currently started trace to a previous trace (e.g. a prior pageload, navigation or\n * manually started span). When enabled, this option will allow you to navigate between traces\n * in the Sentry UI.\n *\n * You can set this option to the following values:\n *\n * - `'in-memory'`: The previous trace data will be stored in memory.\n * This is useful for single-page applications and enabled by default.\n *\n * - `'session-storage'`: The previous trace data will be stored in the `sessionStorage`.\n * This is useful for multi-page applications or static sites but it means that the\n * Sentry SDK writes to the browser's `sessionStorage`.\n *\n * - `'off'`: The previous trace data will not be stored or linked.\n *\n * Note that your `tracesSampleRate` or `tracesSampler` config significantly influences\n * how often traces will be linked.\n *\n * @default 'in-memory' - see explanation above\n */\n linkPreviousTrace: 'in-memory' | 'session-storage' | 'off';\n\n /**\n * _experiments allows the user to send options to define how this integration works.\n *\n * Default: undefined\n */\n _experiments: Partial<{\n enableInteractions: boolean;\n enableStandaloneClsSpans: boolean;\n }>;\n\n /**\n * A callback which is called before a span for a pageload or navigation is started.\n * It receives the options passed to `startSpan`, and expects to return an updated options object.\n */\n beforeStartSpan?: (options: StartSpanOptions) => StartSpanOptions;\n\n /**\n * This function will be called before creating a span for a request with the given url.\n * Return false if you don't want a span for the given url.\n *\n * Default: (url: string) => true\n */\n shouldCreateSpanForRequest?(this: void, url: string): boolean;\n}\n\nconst DEFAULT_BROWSER_TRACING_OPTIONS: BrowserTracingOptions = {\n ...TRACING_DEFAULTS,\n instrumentNavigation: true,\n instrumentPageLoad: true,\n markBackgroundSpan: true,\n enableLongTask: true,\n enableLongAnimationFrame: true,\n enableInp: true,\n linkPreviousTrace: 'in-memory',\n _experiments: {},\n ...defaultRequestInstrumentationOptions,\n};\n\n/**\n * The Browser Tracing integration automatically instruments browser pageload/navigation\n * actions as transactions, and captures requests, metrics and errors as spans.\n *\n * The integration can be configured with a variety of options, and can be extended to use\n * any routing library.\n *\n * We explicitly export the proper type here, as this has to be extended in some cases.\n */\nexport const browserTracingIntegration = ((_options: Partial<BrowserTracingOptions> = {}) => {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n registerSpanErrorInstrumentation();\n\n const {\n enableInp,\n enableLongTask,\n enableLongAnimationFrame,\n _experiments: { enableInteractions, enableStandaloneClsSpans },\n beforeStartSpan,\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n markBackgroundSpan,\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n instrumentPageLoad,\n instrumentNavigation,\n linkPreviousTrace,\n } = {\n ...DEFAULT_BROWSER_TRACING_OPTIONS,\n ..._options,\n };\n\n const _collectWebVitals = startTrackingWebVitals({ recordClsStandaloneSpans: enableStandaloneClsSpans || false });\n\n if (enableInp) {\n startTrackingINP();\n }\n\n if (\n enableLongAnimationFrame &&\n GLOBAL_OBJ.PerformanceObserver &&\n PerformanceObserver.supportedEntryTypes &&\n PerformanceObserver.supportedEntryTypes.includes('long-animation-frame')\n ) {\n startTrackingLongAnimationFrames();\n } else if (enableLongTask) {\n startTrackingLongTasks();\n }\n\n if (enableInteractions) {\n startTrackingInteractions();\n }\n\n const latestRoute: RouteInfo = {\n name: undefined,\n source: undefined,\n };\n\n /** Create routing idle transaction. */\n function _createRouteSpan(client: Client, startSpanOptions: StartSpanOptions): void {\n const isPageloadTransaction = startSpanOptions.op === 'pageload';\n\n const finalStartSpanOptions: StartSpanOptions = beforeStartSpan\n ? beforeStartSpan(startSpanOptions)\n : startSpanOptions;\n\n const attributes = finalStartSpanOptions.attributes || {};\n\n // If `finalStartSpanOptions.name` is different than `startSpanOptions.name`\n // it is because `beforeStartSpan` set a custom name. Therefore we set the source to 'custom'.\n if (startSpanOptions.name !== finalStartSpanOptions.name) {\n attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] = 'custom';\n finalStartSpanOptions.attributes = attributes;\n }\n\n latestRoute.name = finalStartSpanOptions.name;\n latestRoute.source = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE];\n\n const idleSpan = startIdleSpan(finalStartSpanOptions, {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n // should wait for finish signal if it's a pageload transaction\n disableAutoFinish: isPageloadTransaction,\n beforeSpanEnd: span => {\n _collectWebVitals();\n addPerformanceEntries(span, { recordClsOnPageloadSpan: !enableStandaloneClsSpans });\n setActiveIdleSpan(client, undefined);\n\n // A trace should stay consistent over the entire timespan of one route - even after the pageload/navigation ended.\n // Only when another navigation happens, we want to create a new trace.\n // This way, e.g. errors that occur after the pageload span ended are still associated to the pageload trace.\n const scope = getCurrentScope();\n const oldPropagationContext = scope.getPropagationContext();\n\n scope.setPropagationContext({\n ...oldPropagationContext,\n traceId: idleSpan.spanContext().traceId,\n sampled: spanIsSampled(idleSpan),\n dsc: getDynamicSamplingContextFromSpan(span),\n });\n },\n });\n setActiveIdleSpan(client, idleSpan);\n\n function emitFinish(): void {\n if (optionalWindowDocument && ['interactive', 'complete'].includes(optionalWindowDocument.readyState)) {\n client.emit('idleSpanEnableAutoFinish', idleSpan);\n }\n }\n\n if (isPageloadTransaction && optionalWindowDocument) {\n optionalWindowDocument.addEventListener('readystatechange', () => {\n emitFinish();\n });\n\n emitFinish();\n }\n }\n\n return {\n name: BROWSER_TRACING_INTEGRATION_ID,\n afterAllSetup(client) {\n let startingUrl: string | undefined = getLocationHref();\n\n function maybeEndActiveSpan(): void {\n const activeSpan = getActiveIdleSpan(client);\n\n if (activeSpan && !spanToJSON(activeSpan).timestamp) {\n DEBUG_BUILD && logger.log(`[Tracing] Finishing current active span with op: ${spanToJSON(activeSpan).op}`);\n // If there's an open active span, we need to finish it before creating an new one.\n activeSpan.end();\n }\n }\n\n client.on('startNavigationSpan', startSpanOptions => {\n if (getClient() !== client) {\n return;\n }\n\n maybeEndActiveSpan();\n\n getIsolationScope().setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() });\n getCurrentScope().setPropagationContext({ traceId: generateTraceId(), sampleRand: Math.random() });\n\n _createRouteSpan(client, {\n op: 'navigation',\n ...startSpanOptions,\n });\n });\n\n client.on('startPageLoadSpan', (startSpanOptions, traceOptions = {}) => {\n if (getClient() !== client) {\n return;\n }\n maybeEndActiveSpan();\n\n const sentryTrace = traceOptions.sentryTrace || getMetaContent('sentry-trace');\n const baggage = traceOptions.baggage || getMetaContent('baggage');\n\n const propagationContext = propagationContextFromHeaders(sentryTrace, baggage);\n getCurrentScope().setPropagationContext(propagationContext);\n\n _createRouteSpan(client, {\n op: 'pageload',\n ...startSpanOptions,\n });\n });\n\n if (linkPreviousTrace !== 'off') {\n let inMemoryPreviousTraceInfo: PreviousTraceInfo | undefined = undefined;\n\n client.on('spanStart', span => {\n if (getRootSpan(span) !== span) {\n return;\n }\n\n if (linkPreviousTrace === 'session-storage') {\n const updatedPreviousTraceInfo = addPreviousTraceSpanLink(getPreviousTraceFromSessionStorage(), span);\n storePreviousTraceInSessionStorage(updatedPreviousTraceInfo);\n } else {\n inMemoryPreviousTraceInfo = addPreviousTraceSpanLink(inMemoryPreviousTraceInfo, span);\n }\n });\n }\n\n if (WINDOW.location) {\n if (instrumentPageLoad) {\n const origin = browserPerformanceTimeOrigin();\n startBrowserTracingPageLoadSpan(client, {\n name: WINDOW.location.pathname,\n // pageload should always start at timeOrigin (and needs to be in s, not ms)\n startTime: origin ? origin / 1000 : undefined,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser',\n },\n });\n }\n\n if (instrumentNavigation) {\n addHistoryInstrumentationHandler(({ to, from }) => {\n /**\n * This early return is there to account for some cases where a navigation transaction starts right after\n * long-running pageload. We make sure that if `from` is undefined and a valid `startingURL` exists, we don't\n * create an uneccessary navigation transaction.\n *\n * This was hard to duplicate, but this behavior stopped as soon as this fix was applied. This issue might also\n * only be caused in certain development environments where the usage of a hot module reloader is causing\n * errors.\n */\n if (from === undefined && startingUrl?.indexOf(to) !== -1) {\n startingUrl = undefined;\n return;\n }\n\n if (from !== to) {\n startingUrl = undefined;\n startBrowserTracingNavigationSpan(client, {\n name: WINDOW.location.pathname,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url',\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.navigation.browser',\n },\n });\n }\n });\n }\n }\n\n if (markBackgroundSpan) {\n registerBackgroundTabDetection();\n }\n\n if (enableInteractions) {\n registerInteractionListener(client, idleTimeout, finalTimeout, childSpanTimeout, latestRoute);\n }\n\n if (enableInp) {\n registerInpInteractionListener();\n }\n\n instrumentOutgoingRequests(client, {\n traceFetch,\n traceXHR,\n trackFetchStreamPerformance,\n tracePropagationTargets: client.getOptions().tracePropagationTargets,\n shouldCreateSpanForRequest,\n enableHTTPTimings,\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Manually start a page load span.\n * This will only do something if a browser tracing integration integration has been setup.\n *\n * If you provide a custom `traceOptions` object, it will be used to continue the trace\n * instead of the default behavior, which is to look it up on the <meta> tags.\n */\nexport function startBrowserTracingPageLoadSpan(\n client: Client,\n spanOptions: StartSpanOptions,\n traceOptions?: { sentryTrace?: string | undefined; baggage?: string | undefined },\n): Span | undefined {\n client.emit('startPageLoadSpan', spanOptions, traceOptions);\n getCurrentScope().setTransactionName(spanOptions.name);\n\n return getActiveIdleSpan(client);\n}\n\n/**\n * Manually start a navigation span.\n * This will only do something if a browser tracing integration has been setup.\n */\nexport function startBrowserTracingNavigationSpan(client: Client, spanOptions: StartSpanOptions): Span | undefined {\n client.emit('startNavigationSpan', spanOptions);\n\n getCurrentScope().setTransactionName(spanOptions.name);\n\n return getActiveIdleSpan(client);\n}\n\n/** Returns the value of a meta tag */\nexport function getMetaContent(metaName: string): string | undefined {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n const metaTag = optionalWindowDocument?.querySelector(`meta[name=${metaName}]`);\n return metaTag?.getAttribute('content') || undefined;\n}\n\n/** Start listener for interaction transactions */\nfunction registerInteractionListener(\n client: Client,\n idleTimeout: BrowserTracingOptions['idleTimeout'],\n finalTimeout: BrowserTracingOptions['finalTimeout'],\n childSpanTimeout: BrowserTracingOptions['childSpanTimeout'],\n latestRoute: RouteInfo,\n): void {\n /**\n * This is just a small wrapper that makes `document` optional.\n * We want to be extra-safe and always check that this exists, to ensure weird environments do not blow up.\n */\n const optionalWindowDocument = WINDOW.document as (typeof WINDOW)['document'] | undefined;\n\n let inflightInteractionSpan: Span | undefined;\n const registerInteractionTransaction = (): void => {\n const op = 'ui.action.click';\n\n const activeIdleSpan = getActiveIdleSpan(client);\n if (activeIdleSpan) {\n const currentRootSpanOp = spanToJSON(activeIdleSpan).op;\n if (['navigation', 'pageload'].includes(currentRootSpanOp as string)) {\n DEBUG_BUILD &&\n logger.warn(`[Tracing] Did not create ${op} span because a pageload or navigation span is in progress.`);\n return undefined;\n }\n }\n\n if (inflightInteractionSpan) {\n inflightInteractionSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON, 'interactionInterrupted');\n inflightInteractionSpan.end();\n inflightInteractionSpan = undefined;\n }\n\n if (!latestRoute.name) {\n DEBUG_BUILD && logger.warn(`[Tracing] Did not create ${op} transaction because _latestRouteName is missing.`);\n return undefined;\n }\n\n inflightInteractionSpan = startIdleSpan(\n {\n name: latestRoute.name,\n op,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: latestRoute.source || 'url',\n },\n },\n {\n idleTimeout,\n finalTimeout,\n childSpanTimeout,\n },\n );\n };\n\n if (optionalWindowDocument) {\n addEventListener('click', registerInteractionTransaction, { once: false, capture: true });\n }\n}\n\n// We store the active idle span on the client object, so we can access it from exported functions\nconst ACTIVE_IDLE_SPAN_PROPERTY = '_sentry_idleSpan';\nfunction getActiveIdleSpan(client: Client): Span | undefined {\n return (client as { [ACTIVE_IDLE_SPAN_PROPERTY]?: Span })[ACTIVE_IDLE_SPAN_PROPERTY];\n}\n\nfunction setActiveIdleSpan(client: Client, span: Span | undefined): void {\n addNonEnumerableProperty(client, ACTIVE_IDLE_SPAN_PROPERTY, span);\n}\n"],"names":["TRACING_DEFAULTS","defaultRequestInstrumentationOptions","WINDOW","registerSpanErrorInstrumentation","startTrackingWebVitals","startTrackingINP","GLOBAL_OBJ","startTrackingLongAnimationFrames","startTrackingLongTasks","startTrackingInteractions","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","startIdleSpan","addPerformanceEntries","getCurrentScope","spanIsSampled","getDynamicSamplingContextFromSpan","getLocationHref","spanToJSON","DEBUG_BUILD","logger","getClient","getIsolationScope","generateTraceId","propagationContextFromHeaders","getRootSpan","addPreviousTraceSpanLink","getPreviousTraceFromSessionStorage","storePreviousTraceInSessionStorage","browserPerformanceTimeOrigin","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","addHistoryInstrumentationHandler","registerBackgroundTabDetection","registerInpInteractionListener","instrumentOutgoingRequests","SEMANTIC_ATTRIBUTE_SENTRY_IDLE_SPAN_FINISH_REASON","addNonEnumerableProperty"],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+
3
+ const core = require('@sentry/core');
4
+ const helpers = require('../helpers.js');
5
+ require('@sentry-internal/browser-utils');
6
+ require('../stack-parsers.js');
7
+ const debugBuild = require('../debug-build.js');
8
+ require('../integrations/breadcrumbs.js');
9
+ require('../integrations/browserapierrors.js');
10
+ require('../integrations/browsersession.js');
11
+ require('../integrations/globalhandlers.js');
12
+ require('../integrations/httpcontext.js');
13
+ require('../integrations/linkederrors.js');
14
+
15
+ // 1h in seconds
16
+ const PREVIOUS_TRACE_MAX_DURATION = 3600;
17
+
18
+ // session storage key
19
+ const PREVIOUS_TRACE_KEY = 'sentry_previous_trace';
20
+
21
+ /**
22
+ * Adds a previous_trace span link to the passed span if the passed
23
+ * previousTraceInfo is still valid.
24
+ *
25
+ * @returns the updated previous trace info (based on the current span/trace) to
26
+ * be used on the next call
27
+ */
28
+ function addPreviousTraceSpanLink(
29
+ previousTraceInfo,
30
+ span,
31
+ ) {
32
+ const spanJson = core.spanToJSON(span);
33
+
34
+ if (!previousTraceInfo) {
35
+ return {
36
+ spanContext: span.spanContext(),
37
+ startTimestamp: spanJson.start_timestamp,
38
+ };
39
+ }
40
+
41
+ if (previousTraceInfo.spanContext.traceId === spanJson.trace_id) {
42
+ // This means, we're still in the same trace so let's not update the previous trace info
43
+ // or add a link to the current span.
44
+ // Once we move away from the long-lived, route-based trace model, we can remove this cases
45
+ return previousTraceInfo;
46
+ }
47
+
48
+ // Only add the link if the startTimeStamp of the previous trace's root span is within
49
+ // PREVIOUS_TRACE_MAX_DURATION (1h) of the current root span's startTimestamp
50
+ // This is done to
51
+ // - avoid adding links to "stale" traces
52
+ // - enable more efficient querying for previous/next traces in Sentry
53
+ if (Date.now() / 1000 - previousTraceInfo.startTimestamp <= PREVIOUS_TRACE_MAX_DURATION) {
54
+ if (debugBuild.DEBUG_BUILD) {
55
+ core.logger.info(
56
+ `Adding previous_trace ${previousTraceInfo.spanContext} link to span ${{
57
+ op: spanJson.op,
58
+ ...span.spanContext(),
59
+ }}`,
60
+ );
61
+ }
62
+
63
+ span.addLink({
64
+ context: previousTraceInfo.spanContext,
65
+ attributes: {
66
+ [core.SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: 'previous_trace',
67
+ },
68
+ });
69
+ }
70
+
71
+ return {
72
+ spanContext: span.spanContext(),
73
+ startTimestamp: core.spanToJSON(span).start_timestamp,
74
+ };
75
+ }
76
+
77
+ /**
78
+ * Stores @param previousTraceInfo in sessionStorage.
79
+ */
80
+ function storePreviousTraceInSessionStorage(previousTraceInfo) {
81
+ try {
82
+ helpers.WINDOW.sessionStorage.setItem(PREVIOUS_TRACE_KEY, JSON.stringify(previousTraceInfo));
83
+ } catch (e) {
84
+ // Ignore potential errors (e.g. if sessionStorage is not available)
85
+ debugBuild.DEBUG_BUILD && core.logger.warn('Could not store previous trace in sessionStorage', e);
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Retrieves the previous trace from sessionStorage if available.
91
+ */
92
+ function getPreviousTraceFromSessionStorage() {
93
+ try {
94
+ const previousTraceInfo = helpers.WINDOW.sessionStorage?.getItem(PREVIOUS_TRACE_KEY);
95
+ // @ts-expect-error - intentionally risking JSON.parse throwing when previousTraceInfo is null to save bundle size
96
+ return JSON.parse(previousTraceInfo);
97
+ } catch (e) {
98
+ return undefined;
99
+ }
100
+ }
101
+
102
+ exports.PREVIOUS_TRACE_KEY = PREVIOUS_TRACE_KEY;
103
+ exports.PREVIOUS_TRACE_MAX_DURATION = PREVIOUS_TRACE_MAX_DURATION;
104
+ exports.addPreviousTraceSpanLink = addPreviousTraceSpanLink;
105
+ exports.getPreviousTraceFromSessionStorage = getPreviousTraceFromSessionStorage;
106
+ exports.storePreviousTraceInSessionStorage = storePreviousTraceInSessionStorage;
107
+ //# sourceMappingURL=previousTrace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previousTrace.js","sources":["../../../../src/tracing/previousTrace.ts"],"sourcesContent":["import type { Span } from '@sentry/core';\nimport { logger, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE, spanToJSON, type SpanContextData } from '@sentry/core';\nimport { WINDOW } from '../exports';\nimport { DEBUG_BUILD } from '../debug-build';\n\nexport interface PreviousTraceInfo {\n /**\n * Span context of the previous trace's local root span\n */\n spanContext: SpanContextData;\n\n /**\n * Timestamp in seconds when the previous trace was started\n */\n startTimestamp: number;\n}\n\n// 1h in seconds\nexport const PREVIOUS_TRACE_MAX_DURATION = 3600;\n\n// session storage key\nexport const PREVIOUS_TRACE_KEY = 'sentry_previous_trace';\n\n/**\n * Adds a previous_trace span link to the passed span if the passed\n * previousTraceInfo is still valid.\n *\n * @returns the updated previous trace info (based on the current span/trace) to\n * be used on the next call\n */\nexport function addPreviousTraceSpanLink(\n previousTraceInfo: PreviousTraceInfo | undefined,\n span: Span,\n): PreviousTraceInfo {\n const spanJson = spanToJSON(span);\n\n if (!previousTraceInfo) {\n return {\n spanContext: span.spanContext(),\n startTimestamp: spanJson.start_timestamp,\n };\n }\n\n if (previousTraceInfo.spanContext.traceId === spanJson.trace_id) {\n // This means, we're still in the same trace so let's not update the previous trace info\n // or add a link to the current span.\n // Once we move away from the long-lived, route-based trace model, we can remove this cases\n return previousTraceInfo;\n }\n\n // Only add the link if the startTimeStamp of the previous trace's root span is within\n // PREVIOUS_TRACE_MAX_DURATION (1h) of the current root span's startTimestamp\n // This is done to\n // - avoid adding links to \"stale\" traces\n // - enable more efficient querying for previous/next traces in Sentry\n if (Date.now() / 1000 - previousTraceInfo.startTimestamp <= PREVIOUS_TRACE_MAX_DURATION) {\n if (DEBUG_BUILD) {\n logger.info(\n `Adding previous_trace ${previousTraceInfo.spanContext} link to span ${{\n op: spanJson.op,\n ...span.spanContext(),\n }}`,\n );\n }\n\n span.addLink({\n context: previousTraceInfo.spanContext,\n attributes: {\n [SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: 'previous_trace',\n },\n });\n }\n\n return {\n spanContext: span.spanContext(),\n startTimestamp: spanToJSON(span).start_timestamp,\n };\n}\n\n/**\n * Stores @param previousTraceInfo in sessionStorage.\n */\nexport function storePreviousTraceInSessionStorage(previousTraceInfo: PreviousTraceInfo): void {\n try {\n WINDOW.sessionStorage.setItem(PREVIOUS_TRACE_KEY, JSON.stringify(previousTraceInfo));\n } catch (e) {\n // Ignore potential errors (e.g. if sessionStorage is not available)\n DEBUG_BUILD && logger.warn('Could not store previous trace in sessionStorage', e);\n }\n}\n\n/**\n * Retrieves the previous trace from sessionStorage if available.\n */\nexport function getPreviousTraceFromSessionStorage(): PreviousTraceInfo | undefined {\n try {\n const previousTraceInfo = WINDOW.sessionStorage?.getItem(PREVIOUS_TRACE_KEY);\n // @ts-expect-error - intentionally risking JSON.parse throwing when previousTraceInfo is null to save bundle size\n return JSON.parse(previousTraceInfo);\n } catch (e) {\n return undefined;\n }\n}\n"],"names":["spanToJSON","DEBUG_BUILD","logger","SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE","WINDOW"],"mappings":";;;;;;;;;;;;;;AAiBA;AACO,MAAM,2BAA4B,GAAE;;AAE3C;AACO,MAAM,kBAAmB,GAAE;;AAElC;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,wBAAwB;AACxC,EAAE,iBAAiB;AACnB,EAAE,IAAI;AACN,EAAqB;AACrB,EAAE,MAAM,QAAS,GAAEA,eAAU,CAAC,IAAI,CAAC;;AAEnC,EAAE,IAAI,CAAC,iBAAiB,EAAE;AAC1B,IAAI,OAAO;AACX,MAAM,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE;AACrC,MAAM,cAAc,EAAE,QAAQ,CAAC,eAAe;AAC9C,KAAK;AACL;;AAEA,EAAE,IAAI,iBAAiB,CAAC,WAAW,CAAC,OAAA,KAAY,QAAQ,CAAC,QAAQ,EAAE;AACnE;AACA;AACA;AACA,IAAI,OAAO,iBAAiB;AAC5B;;AAEA;AACA;AACA;AACA;AACA;AACA,EAAE,IAAI,IAAI,CAAC,GAAG,EAAC,GAAI,IAAA,GAAO,iBAAiB,CAAC,cAAe,IAAG,2BAA2B,EAAE;AAC3F,IAAI,IAAIC,sBAAW,EAAE;AACrB,MAAMC,WAAM,CAAC,IAAI;AACjB,QAAQ,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,WAAW,CAAC,cAAc,EAAE;AAC/E,UAAU,EAAE,EAAE,QAAQ,CAAC,EAAE;AACzB,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE;AAC/B,SAAS,CAAC,CAAA;AACA,OAAA;AACA;;AAEA,IAAA,IAAA,CAAA,OAAA,CAAA;AACA,MAAA,OAAA,EAAA,iBAAA,CAAA,WAAA;AACA,MAAA,UAAA,EAAA;AACA,QAAA,CAAAC,sCAAA,GAAA,gBAAA;AACA,OAAA;AACA,KAAA,CAAA;AACA;;AAEA,EAAA,OAAA;AACA,IAAA,WAAA,EAAA,IAAA,CAAA,WAAA,EAAA;AACA,IAAA,cAAA,EAAAH,eAAA,CAAA,IAAA,CAAA,CAAA,eAAA;AACA,GAAA;AACA;;AAEA;AACA;AACA;AACA,SAAA,kCAAA,CAAA,iBAAA,EAAA;AACA,EAAA,IAAA;AACA,IAAAI,cAAA,CAAA,cAAA,CAAA,OAAA,CAAA,kBAAA,EAAA,IAAA,CAAA,SAAA,CAAA,iBAAA,CAAA,CAAA;AACA,GAAA,CAAA,OAAA,CAAA,EAAA;AACA;AACA,IAAAH,sBAAA,IAAAC,WAAA,CAAA,IAAA,CAAA,kDAAA,EAAA,CAAA,CAAA;AACA;AACA;;AAEA;AACA;AACA;AACA,SAAA,kCAAA,GAAA;AACA,EAAA,IAAA;AACA,IAAA,MAAA,iBAAA,GAAAE,cAAA,CAAA,cAAA,EAAA,OAAA,CAAA,kBAAA,CAAA;AACA;AACA,IAAA,OAAA,IAAA,CAAA,KAAA,CAAA,iBAAA,CAAA;AACA,GAAA,CAAA,OAAA,CAAA,EAAA;AACA,IAAA,OAAA,SAAA;AACA;AACA;;;;;;;;"}
@@ -1,4 +1,4 @@
1
- import { Client, getSDKSource, applySdkMetadata, _INTERNAL_flushLogsBuffer, addAutoIpAddressToUser, addAutoIpAddressToSession } from '@sentry/core';
1
+ import { Client, getSDKSource, applySdkMetadata, addAutoIpAddressToUser, addAutoIpAddressToSession } from '@sentry/core';
2
2
  import { eventFromException, eventFromMessage } from './eventbuilder.js';
3
3
  import { WINDOW } from './helpers.js';
4
4
 
@@ -34,9 +34,6 @@ class BrowserClient extends Client {
34
34
  WINDOW.document.addEventListener('visibilitychange', () => {
35
35
  if (WINDOW.document.visibilityState === 'hidden') {
36
36
  this._flushOutcomes();
37
- if (this._options._experiments?.enableLogs) {
38
- _INTERNAL_flushLogsBuffer(this);
39
- }
40
37
  }
41
38
  });
42
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n Client,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n getSDKSource,\n _INTERNAL_flushLogsBuffer,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /**\n * Important: Only set this option if you know what you are doing!\n *\n * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n * In case it is, it will stop initialization and log a warning\n * because browser extensions require a different Sentry initialization process:\n * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n *\n * Setting up the SDK in a browser extension with global error monitoring is not recommended\n * and will likely flood you with errors from other web sites or extensions. This can heavily\n * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n *\n * If this check wrongfully flags your setup as a browser extension, you can set this\n * option to `true` to skip the check.\n *\n * @default false\n */\n skipBrowserExtensionCheck?: boolean;\n };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /** If configured, this URL will be used as base URL for lazy loading integration. */\n cdnBaseUrl?: string;\n };\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends Client<BrowserClientOptions> {\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n public constructor(options: BrowserClientOptions) {\n const opts = {\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...options,\n };\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n if (opts.sendClientReports && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n this._flushOutcomes();\n if (this._options._experiments?.enableLogs) {\n _INTERNAL_flushLogsBuffer(this);\n }\n }\n });\n }\n\n if (this._options.sendDefaultPii) {\n this.on('postprocessEvent', addAutoIpAddressToUser);\n this.on('beforeSendSession', addAutoIpAddressToSession);\n }\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n event.platform = event.platform || 'javascript';\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n}\n"],"names":[],"mappings":";;;;AAuBA;AACA;AACA;AACA;;AAmCA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,aAAA,SAAsB,MAAM,CAAuB;AAChE;AACA;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAAwB;AACpD,IAAI,MAAM,OAAO;AACjB;AACA,MAAM,0BAA0B,EAAE,IAAI;AACtC,MAAM,GAAG,OAAO;AAChB,KAAK;AACL,IAAI,MAAM,YAAY,MAAM,CAAC,iBAAkB,IAAG,YAAY,EAAE;AAChE,IAAI,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;;AAE7D,IAAI,KAAK,CAAC,IAAI,CAAC;;AAEf,IAAI,IAAI,IAAI,CAAC,qBAAqB,MAAM,CAAC,QAAQ,EAAE;AACnD,MAAM,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM;AACjE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAA,KAAoB,QAAQ,EAAE;AAC1D,UAAU,IAAI,CAAC,cAAc,EAAE;AAC/B,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,EAAE;AACtD,YAAY,yBAAyB,CAAC,IAAI,CAAC;AAC3C;AACA;AACA,OAAO,CAAC;AACR;;AAEA,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;AACtC,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;AACzD,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AAC7D;AACA;;AAEA;AACA;AACA;AACA,GAAS,kBAAkB,CAAC,SAAS,EAAW,IAAI,EAAkC;AACtF,IAAI,OAAO,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzG;;AAEA;AACA;AACA;AACA,GAAS,gBAAgB;AACzB,IAAI,OAAO;AACX,IAAI,KAAK,GAAkB,MAAM;AACjC,IAAI,IAAI;AACR,IAAwB;AACxB,IAAI,OAAO,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAC5G;;AAEA;AACA;AACA;AACA,GAAY,aAAa;AACzB,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,YAAY;AAChB,IAAI,cAAc;AAClB,IAA+B;AAC/B,IAAI,KAAK,CAAC,QAAS,GAAE,KAAK,CAAC,QAAA,IAAY,YAAY;;AAEnD,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC;AACzE;AACA;;;;"}
1
+ {"version":3,"file":"client.js","sources":["../../../src/client.ts"],"sourcesContent":["import type {\n BrowserClientProfilingOptions,\n BrowserClientReplayOptions,\n ClientOptions,\n Event,\n EventHint,\n Options,\n ParameterizedString,\n Scope,\n SeverityLevel,\n} from '@sentry/core';\nimport {\n Client,\n addAutoIpAddressToSession,\n addAutoIpAddressToUser,\n applySdkMetadata,\n getSDKSource,\n} from '@sentry/core';\nimport { eventFromException, eventFromMessage } from './eventbuilder';\nimport { WINDOW } from './helpers';\nimport type { BrowserTransportOptions } from './transports/types';\n\n/**\n * Configuration options for the Sentry Browser SDK.\n * @see @sentry/core Options for more information.\n */\nexport type BrowserOptions = Options<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /**\n * Important: Only set this option if you know what you are doing!\n *\n * By default, the SDK will check if `Sentry.init` is called in a browser extension.\n * In case it is, it will stop initialization and log a warning\n * because browser extensions require a different Sentry initialization process:\n * https://docs.sentry.io/platforms/javascript/best-practices/shared-environments/\n *\n * Setting up the SDK in a browser extension with global error monitoring is not recommended\n * and will likely flood you with errors from other web sites or extensions. This can heavily\n * impact your quota and cause interference with your and other Sentry SDKs in shared environments.\n *\n * If this check wrongfully flags your setup as a browser extension, you can set this\n * option to `true` to skip the check.\n *\n * @default false\n */\n skipBrowserExtensionCheck?: boolean;\n };\n\n/**\n * Configuration options for the Sentry Browser SDK Client class\n * @see BrowserClient for more information.\n */\nexport type BrowserClientOptions = ClientOptions<BrowserTransportOptions> &\n BrowserClientReplayOptions &\n BrowserClientProfilingOptions & {\n /** If configured, this URL will be used as base URL for lazy loading integration. */\n cdnBaseUrl?: string;\n };\n\n/**\n * The Sentry Browser SDK Client.\n *\n * @see BrowserOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class BrowserClient extends Client<BrowserClientOptions> {\n /**\n * Creates a new Browser SDK instance.\n *\n * @param options Configuration options for this SDK.\n */\n public constructor(options: BrowserClientOptions) {\n const opts = {\n // We default this to true, as it is the safer scenario\n parentSpanIsAlwaysRootSpan: true,\n ...options,\n };\n const sdkSource = WINDOW.SENTRY_SDK_SOURCE || getSDKSource();\n applySdkMetadata(opts, 'browser', ['browser'], sdkSource);\n\n super(opts);\n\n if (opts.sendClientReports && WINDOW.document) {\n WINDOW.document.addEventListener('visibilitychange', () => {\n if (WINDOW.document.visibilityState === 'hidden') {\n this._flushOutcomes();\n }\n });\n }\n\n if (this._options.sendDefaultPii) {\n this.on('postprocessEvent', addAutoIpAddressToUser);\n this.on('beforeSendSession', addAutoIpAddressToSession);\n }\n }\n\n /**\n * @inheritDoc\n */\n public eventFromException(exception: unknown, hint?: EventHint): PromiseLike<Event> {\n return eventFromException(this._options.stackParser, exception, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n public eventFromMessage(\n message: ParameterizedString,\n level: SeverityLevel = 'info',\n hint?: EventHint,\n ): PromiseLike<Event> {\n return eventFromMessage(this._options.stackParser, message, level, hint, this._options.attachStacktrace);\n }\n\n /**\n * @inheritDoc\n */\n protected _prepareEvent(\n event: Event,\n hint: EventHint,\n currentScope: Scope,\n isolationScope: Scope,\n ): PromiseLike<Event | null> {\n event.platform = event.platform || 'javascript';\n\n return super._prepareEvent(event, hint, currentScope, isolationScope);\n }\n}\n"],"names":[],"mappings":";;;;AAsBA;AACA;AACA;AACA;;AAmCA;AACA;AACA;AACA;AACA;AACA;AACO,MAAM,aAAA,SAAsB,MAAM,CAAuB;AAChE;AACA;AACA;AACA;AACA;AACA,GAAS,WAAW,CAAC,OAAO,EAAwB;AACpD,IAAI,MAAM,OAAO;AACjB;AACA,MAAM,0BAA0B,EAAE,IAAI;AACtC,MAAM,GAAG,OAAO;AAChB,KAAK;AACL,IAAI,MAAM,YAAY,MAAM,CAAC,iBAAkB,IAAG,YAAY,EAAE;AAChE,IAAI,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;;AAE7D,IAAI,KAAK,CAAC,IAAI,CAAC;;AAEf,IAAI,IAAI,IAAI,CAAC,qBAAqB,MAAM,CAAC,QAAQ,EAAE;AACnD,MAAM,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM;AACjE,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAA,KAAoB,QAAQ,EAAE;AAC1D,UAAU,IAAI,CAAC,cAAc,EAAE;AAC/B;AACA,OAAO,CAAC;AACR;;AAEA,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;AACtC,MAAM,IAAI,CAAC,EAAE,CAAC,kBAAkB,EAAE,sBAAsB,CAAC;AACzD,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AAC7D;AACA;;AAEA;AACA;AACA;AACA,GAAS,kBAAkB,CAAC,SAAS,EAAW,IAAI,EAAkC;AACtF,IAAI,OAAO,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzG;;AAEA;AACA;AACA;AACA,GAAS,gBAAgB;AACzB,IAAI,OAAO;AACX,IAAI,KAAK,GAAkB,MAAM;AACjC,IAAI,IAAI;AACR,IAAwB;AACxB,IAAI,OAAO,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AAC5G;;AAEA;AACA;AACA;AACA,GAAY,aAAa;AACzB,IAAI,KAAK;AACT,IAAI,IAAI;AACR,IAAI,YAAY;AAChB,IAAI,cAAc;AAClB,IAA+B;AAC/B,IAAI,KAAK,CAAC,QAAS,GAAE,KAAK,CAAC,QAAA,IAAY,YAAY;;AAEnD,IAAI,OAAO,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC;AACzE;AACA;;;;"}