@sentry/browser-utils 10.74.0 → 10.75.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.
@@ -16,7 +16,7 @@ function instrumentXHR() {
16
16
  const xhrproto = XMLHttpRequest.prototype;
17
17
  xhrproto.open = new Proxy(xhrproto.open, {
18
18
  apply(originalOpen, xhrOpenThisArg, xhrOpenArgArray) {
19
- const virtualError = new Error();
19
+ let virtualError = new Error();
20
20
  const startTimestamp = core.timestampInSeconds() * 1e3;
21
21
  const method = core.isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : void 0;
22
22
  const url = parseXhrUrlArg(xhrOpenArgArray[1]);
@@ -48,6 +48,7 @@ function instrumentXHR() {
48
48
  virtualError
49
49
  };
50
50
  core.triggerHandlers("xhr", handlerData);
51
+ virtualError = void 0;
51
52
  xhrOpenThisArg.removeEventListener("readystatechange", onreadystatechangeHandler);
52
53
  }
53
54
  };
@@ -1 +1 @@
1
- {"version":3,"file":"xhr.js","sources":["../../../src/instrument/xhr.ts"],"sourcesContent":["import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) => void): void {\n const type = 'xhr';\n addHandler(type, handler);\n maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n return;\n }\n\n const xhrproto = XMLHttpRequest.prototype;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.open = new Proxy(xhrproto.open, {\n apply(\n originalOpen,\n xhrOpenThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest,\n xhrOpenArgArray:\n | [method: string, url: string | URL]\n | [method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null],\n ) {\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your XHR call did not\n // have a stack trace. If you are using HttpClient integration,\n // this is the expected behavior, as we are using this virtual error to capture\n // the location of your XHR call, and group your HttpClient events accordingly.\n const virtualError = new Error();\n\n const startTimestamp = timestampInSeconds() * 1000;\n\n // open() should always be called with two or more arguments\n // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n const url = parseXhrUrlArg(xhrOpenArgArray[1]);\n\n if (!method || !url) {\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n }\n\n xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n method,\n url,\n request_headers: {},\n };\n\n // if Sentry key appears in URL, don't capture it as a request\n if (method === 'POST' && url.match(/sentry_key/)) {\n xhrOpenThisArg.__sentry_own_request__ = true;\n }\n\n const onreadystatechangeHandler: () => void = () => {\n // For whatever reason, this is not the same instance here as from the outer method\n const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!xhrInfo) {\n return;\n }\n\n if (xhrOpenThisArg.readyState === 4) {\n try {\n // touching statusCode in some platforms throws\n // an exception\n xhrInfo.status_code = xhrOpenThisArg.status;\n } catch {\n /* do nothing */\n }\n\n const handlerData: HandlerDataXhr = {\n endTimestamp: timestampInSeconds() * 1000,\n startTimestamp,\n xhr: xhrOpenThisArg,\n virtualError,\n };\n triggerHandlers('xhr', handlerData);\n\n // In the `addEventListener` branch below, this handler is the only\n // `readystatechange` listener we add, so detach it once the request is\n // done to avoid pinning the XMLHttpRequest and its captured\n // `virtualError` per HTTP call on long-lived pages. In the\n // `onreadystatechange` proxy branch the handler isn't registered via\n // `addEventListener`, so this is a harmless no-op there.\n xhrOpenThisArg.removeEventListener('readystatechange', onreadystatechangeHandler);\n }\n };\n\n if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n onreadystatechangeHandler();\n return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n },\n });\n } else {\n xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n }\n\n // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n apply(\n originalSetRequestHeader,\n setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n setRequestHeaderArgArray: unknown[],\n ) {\n const [header, value] = setRequestHeaderArgArray;\n\n const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n if (xhrInfo && isString(header) && isString(value)) {\n xhrInfo.request_headers[header.toLowerCase()] = value;\n }\n\n return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n },\n });\n\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.send = new Proxy(xhrproto.send, {\n apply(originalSend, sendThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return originalSend.apply(sendThisArg, sendArgArray);\n }\n\n if (sendArgArray[0] !== undefined) {\n sentryXhrData.body = sendArgArray[0];\n }\n\n const handlerData: HandlerDataXhr = {\n startTimestamp: timestampInSeconds() * 1000,\n xhr: sendThisArg,\n };\n triggerHandlers('xhr', handlerData);\n\n return originalSend.apply(sendThisArg, sendArgArray);\n },\n });\n}\n\n/**\n * Parses the URL argument of a XHR method to a string.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open#url\n * url: A string or any other object with a stringifier — including a URL object — that provides the URL of the resource to send the request to.\n *\n * @param url - The URL argument of an XHR method\n * @returns The parsed URL string or undefined if the URL is invalid\n */\nfunction parseXhrUrlArg(url: unknown): string | undefined {\n if (isString(url)) {\n return url;\n }\n\n try {\n // If the passed in argument is not a string, it should have a `toString` method as a stringifier.\n // If that fails, we just return undefined (like in IE11 where URL is not available)\n return (url as URL).toString();\n } catch {} // eslint-disable-line no-empty\n\n return undefined;\n}\n"],"names":["addHandler","maybeInstrument","WINDOW","timestampInSeconds","isString","triggerHandlers"],"mappings":"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"}
1
+ {"version":3,"file":"xhr.js","sources":["../../../src/instrument/xhr.ts"],"sourcesContent":["import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) => void): void {\n const type = 'xhr';\n addHandler(type, handler);\n maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n return;\n }\n\n const xhrproto = XMLHttpRequest.prototype;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.open = new Proxy(xhrproto.open, {\n apply(\n originalOpen,\n xhrOpenThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest,\n xhrOpenArgArray:\n | [method: string, url: string | URL]\n | [method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null],\n ) {\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your XHR call did not\n // have a stack trace. If you are using HttpClient integration,\n // this is the expected behavior, as we are using this virtual error to capture\n // the location of your XHR call, and group your HttpClient events accordingly.\n let virtualError: Error | undefined = new Error();\n\n const startTimestamp = timestampInSeconds() * 1000;\n\n // open() should always be called with two or more arguments\n // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n const url = parseXhrUrlArg(xhrOpenArgArray[1]);\n\n if (!method || !url) {\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n }\n\n xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n method,\n url,\n request_headers: {},\n };\n\n // if Sentry key appears in URL, don't capture it as a request\n if (method === 'POST' && url.match(/sentry_key/)) {\n xhrOpenThisArg.__sentry_own_request__ = true;\n }\n\n const onreadystatechangeHandler: () => void = () => {\n // For whatever reason, this is not the same instance here as from the outer method\n const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!xhrInfo) {\n return;\n }\n\n if (xhrOpenThisArg.readyState === 4) {\n try {\n // touching statusCode in some platforms throws\n // an exception\n xhrInfo.status_code = xhrOpenThisArg.status;\n } catch {\n /* do nothing */\n }\n\n const handlerData: HandlerDataXhr = {\n endTimestamp: timestampInSeconds() * 1000,\n startTimestamp,\n xhr: xhrOpenThisArg,\n virtualError,\n };\n triggerHandlers('xhr', handlerData);\n\n // An unformatted stack keeps its raw frames, and each frame keeps its receiver alive. For a request\n // opened from the previous one's `readystatechange` callback that receiver is the previous\n // XMLHttpRequest, so holding on would chain every completed request to the one still in flight.\n virtualError = undefined;\n\n // In the `addEventListener` branch below this is the only `readystatechange` listener we add, so\n // detach it once the request is done. It's a no-op in the `onreadystatechange` proxy branch.\n xhrOpenThisArg.removeEventListener('readystatechange', onreadystatechangeHandler);\n }\n };\n\n if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n onreadystatechangeHandler();\n return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n },\n });\n } else {\n xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n }\n\n // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n apply(\n originalSetRequestHeader,\n setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n setRequestHeaderArgArray: unknown[],\n ) {\n const [header, value] = setRequestHeaderArgArray;\n\n const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n if (xhrInfo && isString(header) && isString(value)) {\n xhrInfo.request_headers[header.toLowerCase()] = value;\n }\n\n return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n },\n });\n\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.send = new Proxy(xhrproto.send, {\n apply(originalSend, sendThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return originalSend.apply(sendThisArg, sendArgArray);\n }\n\n if (sendArgArray[0] !== undefined) {\n sentryXhrData.body = sendArgArray[0];\n }\n\n const handlerData: HandlerDataXhr = {\n startTimestamp: timestampInSeconds() * 1000,\n xhr: sendThisArg,\n };\n triggerHandlers('xhr', handlerData);\n\n return originalSend.apply(sendThisArg, sendArgArray);\n },\n });\n}\n\n/**\n * Parses the URL argument of a XHR method to a string.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open#url\n * url: A string or any other object with a stringifier — including a URL object — that provides the URL of the resource to send the request to.\n *\n * @param url - The URL argument of an XHR method\n * @returns The parsed URL string or undefined if the URL is invalid\n */\nfunction parseXhrUrlArg(url: unknown): string | undefined {\n if (isString(url)) {\n return url;\n }\n\n try {\n // If the passed in argument is not a string, it should have a `toString` method as a stringifier.\n // If that fails, we just return undefined (like in IE11 where URL is not available)\n return (url as URL).toString();\n } catch {} // eslint-disable-line no-empty\n\n return undefined;\n}\n"],"names":["addHandler","maybeInstrument","WINDOW","timestampInSeconds","isString","triggerHandlers"],"mappings":"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"}
@@ -24,6 +24,7 @@ const onLCP = (onReport, opts = {}) => {
24
24
  entries = entries.slice(-1);
25
25
  }
26
26
  for (const entry of entries) {
27
+ if (!entry) continue;
27
28
  lcpEntryManager._processEntry(entry);
28
29
  if (entry.startTime < visibilityWatcher.firstHiddenTime) {
29
30
  metric.value = Math.max(entry.startTime - getActivationStart.getActivationStart(), 0);
@@ -1 +1 @@
1
- {"version":3,"file":"getLCP.js","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"sourcesContent":["/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { addPageListener, removePageListener } from './lib/globalListeners';\nimport { initMetric } from './lib/initMetric';\nimport { initUnique } from './lib/initUnique';\nimport { LCPEntryManager } from './lib/LCPEntryManager';\nimport { observe } from './lib/observe';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('LCP');\n let report: ReturnType<typeof bindReporter>;\n\n const lcpEntryManager = initUnique(opts, LCPEntryManager);\n\n const handleEntries = (entries: LCPMetric['entries']) => {\n // If reportAllChanges is set then call this function for each entry,\n // otherwise only consider the last one.\n if (!opts.reportAllChanges) {\n // eslint-disable-next-line no-param-reassign\n entries = entries.slice(-1);\n }\n\n for (const entry of entries) {\n lcpEntryManager._processEntry(entry);\n\n // Only report if the page wasn't hidden prior to LCP.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries = [entry];\n report();\n }\n }\n };\n\n const po = observe('largest-contentful-paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n // Ensure this logic only runs once, since it can be triggered from\n // any of three different event listeners below.\n const stopListening = runOnce(() => {\n handleEntries(po.takeRecords() as LCPMetric['entries']);\n po.disconnect();\n report(true);\n });\n\n // Need a separate wrapper to ensure the `runOnce` function above is\n // common for all three functions\n const stopListeningWrapper = (event: Event) => {\n if (event.isTrusted) {\n // Wrap the listener in an idle callback so it's run in a separate\n // task to reduce potential INP impact.\n // https://github.com/GoogleChrome/web-vitals/issues/383\n whenIdleOrHidden(stopListening);\n removePageListener(event.type, stopListeningWrapper, {\n capture: true,\n });\n }\n };\n\n // Stop listening after input or visibilitychange.\n // Note: while scrolling is an input that stops LCP observation, it's\n // unreliable since it can be programmatically generated.\n // See: https://github.com/GoogleChrome/web-vitals/issues/75\n for (const type of ['keydown', 'click', 'visibilitychange']) {\n addPageListener(type, stopListeningWrapper, {\n capture: true,\n });\n }\n }\n });\n};\n"],"names":["whenActivated","getVisibilityWatcher","initMetric","initUnique","LCPEntryManager","getActivationStart","observe","bindReporter","runOnce","whenIdleOrHidden","removePageListener","addPageListener"],"mappings":";;;;;;;;;;;;;;AA8BO,MAAM,aAAA,GAAwC,CAAC,IAAA,EAAM,GAAI;AAazD,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAuC,IAAA,GAAmB,EAAC,KAAM;AACrF,EAAAA,2BAAA,CAAc,MAAM;AAClB,IAAA,MAAM,oBAAoBC,yCAAA,EAAqB;AAC/C,IAAA,MAAM,MAAA,GAASC,sBAAW,KAAK,CAAA;AAC/B,IAAA,IAAI,MAAA;AAEJ,IAAA,MAAM,eAAA,GAAkBC,qBAAA,CAAW,IAAA,EAAMC,+BAAe,CAAA;AAExD,IAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,KAAkC;AAGvD,MAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAE1B,QAAA,OAAA,GAAU,OAAA,CAAQ,MAAM,EAAE,CAAA;AAAA,MAC5B;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,eAAA,CAAgB,cAAc,KAAK,CAAA;AAGnC,QAAA,IAAI,KAAA,CAAM,SAAA,GAAY,iBAAA,CAAkB,eAAA,EAAiB;AAOvD,UAAA,MAAA,CAAO,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,SAAA,GAAYC,qCAAA,IAAsB,CAAC,CAAA;AACjE,UAAA,MAAA,CAAO,OAAA,GAAU,CAAC,KAAK,CAAA;AACvB,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,EAAA,GAAKC,eAAA,CAAQ,0BAAA,EAA4B,aAAa,CAAA;AAE5D,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,MAAA,GAASC,yBAAA,CAAa,QAAA,EAAU,MAAA,EAAQ,aAAA,EAAe,KAAK,gBAAgB,CAAA;AAI5E,MAAA,MAAM,aAAA,GAAgBC,gBAAQ,MAAM;AAClC,QAAA,aAAA,CAAc,EAAA,CAAG,aAAqC,CAAA;AACtD,QAAA,EAAA,CAAG,UAAA,EAAW;AACd,QAAA,MAAA,CAAO,IAAI,CAAA;AAAA,MACb,CAAC,CAAA;AAID,MAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAiB;AAC7C,QAAA,IAAI,MAAM,SAAA,EAAW;AAInB,UAAAC,iCAAA,CAAiB,aAAa,CAAA;AAC9B,UAAAC,kCAAA,CAAmB,KAAA,CAAM,MAAM,oBAAA,EAAsB;AAAA,YACnD,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAMA,MAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,SAAA,EAAW,OAAA,EAAS,kBAAkB,CAAA,EAAG;AAC3D,QAAAC,+BAAA,CAAgB,MAAM,oBAAA,EAAsB;AAAA,UAC1C,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;;;"}
1
+ {"version":3,"file":"getLCP.js","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"sourcesContent":["/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { addPageListener, removePageListener } from './lib/globalListeners';\nimport { initMetric } from './lib/initMetric';\nimport { initUnique } from './lib/initUnique';\nimport { LCPEntryManager } from './lib/LCPEntryManager';\nimport { observe } from './lib/observe';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('LCP');\n let report: ReturnType<typeof bindReporter>;\n\n const lcpEntryManager = initUnique(opts, LCPEntryManager);\n\n const handleEntries = (entries: LCPMetric['entries']) => {\n // If reportAllChanges is set then call this function for each entry,\n // otherwise only consider the last one.\n if (!opts.reportAllChanges) {\n // eslint-disable-next-line no-param-reassign\n entries = entries.slice(-1);\n }\n\n for (const entry of entries) {\n // Upstream has this guard too; a patched PerformanceObserver can yield nullish entries.\n if (!entry) continue;\n\n lcpEntryManager._processEntry(entry);\n\n // Only report if the page wasn't hidden prior to LCP.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries = [entry];\n report();\n }\n }\n };\n\n const po = observe('largest-contentful-paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n // Ensure this logic only runs once, since it can be triggered from\n // any of three different event listeners below.\n const stopListening = runOnce(() => {\n handleEntries(po.takeRecords() as LCPMetric['entries']);\n po.disconnect();\n report(true);\n });\n\n // Need a separate wrapper to ensure the `runOnce` function above is\n // common for all three functions\n const stopListeningWrapper = (event: Event) => {\n if (event.isTrusted) {\n // Wrap the listener in an idle callback so it's run in a separate\n // task to reduce potential INP impact.\n // https://github.com/GoogleChrome/web-vitals/issues/383\n whenIdleOrHidden(stopListening);\n removePageListener(event.type, stopListeningWrapper, {\n capture: true,\n });\n }\n };\n\n // Stop listening after input or visibilitychange.\n // Note: while scrolling is an input that stops LCP observation, it's\n // unreliable since it can be programmatically generated.\n // See: https://github.com/GoogleChrome/web-vitals/issues/75\n for (const type of ['keydown', 'click', 'visibilitychange']) {\n addPageListener(type, stopListeningWrapper, {\n capture: true,\n });\n }\n }\n });\n};\n"],"names":["whenActivated","getVisibilityWatcher","initMetric","initUnique","LCPEntryManager","getActivationStart","observe","bindReporter","runOnce","whenIdleOrHidden","removePageListener","addPageListener"],"mappings":";;;;;;;;;;;;;;AA8BO,MAAM,aAAA,GAAwC,CAAC,IAAA,EAAM,GAAI;AAazD,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAuC,IAAA,GAAmB,EAAC,KAAM;AACrF,EAAAA,2BAAA,CAAc,MAAM;AAClB,IAAA,MAAM,oBAAoBC,yCAAA,EAAqB;AAC/C,IAAA,MAAM,MAAA,GAASC,sBAAW,KAAK,CAAA;AAC/B,IAAA,IAAI,MAAA;AAEJ,IAAA,MAAM,eAAA,GAAkBC,qBAAA,CAAW,IAAA,EAAMC,+BAAe,CAAA;AAExD,IAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,KAAkC;AAGvD,MAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAE1B,QAAA,OAAA,GAAU,OAAA,CAAQ,MAAM,EAAE,CAAA;AAAA,MAC5B;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,QAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,QAAA,eAAA,CAAgB,cAAc,KAAK,CAAA;AAGnC,QAAA,IAAI,KAAA,CAAM,SAAA,GAAY,iBAAA,CAAkB,eAAA,EAAiB;AAOvD,UAAA,MAAA,CAAO,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,SAAA,GAAYC,qCAAA,IAAsB,CAAC,CAAA;AACjE,UAAA,MAAA,CAAO,OAAA,GAAU,CAAC,KAAK,CAAA;AACvB,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,EAAA,GAAKC,eAAA,CAAQ,0BAAA,EAA4B,aAAa,CAAA;AAE5D,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,MAAA,GAASC,yBAAA,CAAa,QAAA,EAAU,MAAA,EAAQ,aAAA,EAAe,KAAK,gBAAgB,CAAA;AAI5E,MAAA,MAAM,aAAA,GAAgBC,gBAAQ,MAAM;AAClC,QAAA,aAAA,CAAc,EAAA,CAAG,aAAqC,CAAA;AACtD,QAAA,EAAA,CAAG,UAAA,EAAW;AACd,QAAA,MAAA,CAAO,IAAI,CAAA;AAAA,MACb,CAAC,CAAA;AAID,MAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAiB;AAC7C,QAAA,IAAI,MAAM,SAAA,EAAW;AAInB,UAAAC,iCAAA,CAAiB,aAAa,CAAA;AAC9B,UAAAC,kCAAA,CAAmB,KAAA,CAAM,MAAM,oBAAA,EAAsB;AAAA,YACnD,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAMA,MAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,SAAA,EAAW,OAAA,EAAS,kBAAkB,CAAA,EAAG;AAC3D,QAAAC,+BAAA,CAAgB,MAAM,oBAAA,EAAsB;AAAA,UAC1C,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;;;"}
@@ -14,7 +14,7 @@ function instrumentXHR() {
14
14
  const xhrproto = XMLHttpRequest.prototype;
15
15
  xhrproto.open = new Proxy(xhrproto.open, {
16
16
  apply(originalOpen, xhrOpenThisArg, xhrOpenArgArray) {
17
- const virtualError = new Error();
17
+ let virtualError = new Error();
18
18
  const startTimestamp = timestampInSeconds() * 1e3;
19
19
  const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : void 0;
20
20
  const url = parseXhrUrlArg(xhrOpenArgArray[1]);
@@ -46,6 +46,7 @@ function instrumentXHR() {
46
46
  virtualError
47
47
  };
48
48
  triggerHandlers("xhr", handlerData);
49
+ virtualError = void 0;
49
50
  xhrOpenThisArg.removeEventListener("readystatechange", onreadystatechangeHandler);
50
51
  }
51
52
  };
@@ -1 +1 @@
1
- {"version":3,"file":"xhr.js","sources":["../../../src/instrument/xhr.ts"],"sourcesContent":["import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) => void): void {\n const type = 'xhr';\n addHandler(type, handler);\n maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n return;\n }\n\n const xhrproto = XMLHttpRequest.prototype;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.open = new Proxy(xhrproto.open, {\n apply(\n originalOpen,\n xhrOpenThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest,\n xhrOpenArgArray:\n | [method: string, url: string | URL]\n | [method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null],\n ) {\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your XHR call did not\n // have a stack trace. If you are using HttpClient integration,\n // this is the expected behavior, as we are using this virtual error to capture\n // the location of your XHR call, and group your HttpClient events accordingly.\n const virtualError = new Error();\n\n const startTimestamp = timestampInSeconds() * 1000;\n\n // open() should always be called with two or more arguments\n // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n const url = parseXhrUrlArg(xhrOpenArgArray[1]);\n\n if (!method || !url) {\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n }\n\n xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n method,\n url,\n request_headers: {},\n };\n\n // if Sentry key appears in URL, don't capture it as a request\n if (method === 'POST' && url.match(/sentry_key/)) {\n xhrOpenThisArg.__sentry_own_request__ = true;\n }\n\n const onreadystatechangeHandler: () => void = () => {\n // For whatever reason, this is not the same instance here as from the outer method\n const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!xhrInfo) {\n return;\n }\n\n if (xhrOpenThisArg.readyState === 4) {\n try {\n // touching statusCode in some platforms throws\n // an exception\n xhrInfo.status_code = xhrOpenThisArg.status;\n } catch {\n /* do nothing */\n }\n\n const handlerData: HandlerDataXhr = {\n endTimestamp: timestampInSeconds() * 1000,\n startTimestamp,\n xhr: xhrOpenThisArg,\n virtualError,\n };\n triggerHandlers('xhr', handlerData);\n\n // In the `addEventListener` branch below, this handler is the only\n // `readystatechange` listener we add, so detach it once the request is\n // done to avoid pinning the XMLHttpRequest and its captured\n // `virtualError` per HTTP call on long-lived pages. In the\n // `onreadystatechange` proxy branch the handler isn't registered via\n // `addEventListener`, so this is a harmless no-op there.\n xhrOpenThisArg.removeEventListener('readystatechange', onreadystatechangeHandler);\n }\n };\n\n if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n onreadystatechangeHandler();\n return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n },\n });\n } else {\n xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n }\n\n // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n apply(\n originalSetRequestHeader,\n setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n setRequestHeaderArgArray: unknown[],\n ) {\n const [header, value] = setRequestHeaderArgArray;\n\n const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n if (xhrInfo && isString(header) && isString(value)) {\n xhrInfo.request_headers[header.toLowerCase()] = value;\n }\n\n return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n },\n });\n\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.send = new Proxy(xhrproto.send, {\n apply(originalSend, sendThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return originalSend.apply(sendThisArg, sendArgArray);\n }\n\n if (sendArgArray[0] !== undefined) {\n sentryXhrData.body = sendArgArray[0];\n }\n\n const handlerData: HandlerDataXhr = {\n startTimestamp: timestampInSeconds() * 1000,\n xhr: sendThisArg,\n };\n triggerHandlers('xhr', handlerData);\n\n return originalSend.apply(sendThisArg, sendArgArray);\n },\n });\n}\n\n/**\n * Parses the URL argument of a XHR method to a string.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open#url\n * url: A string or any other object with a stringifier — including a URL object — that provides the URL of the resource to send the request to.\n *\n * @param url - The URL argument of an XHR method\n * @returns The parsed URL string or undefined if the URL is invalid\n */\nfunction parseXhrUrlArg(url: unknown): string | undefined {\n if (isString(url)) {\n return url;\n }\n\n try {\n // If the passed in argument is not a string, it should have a `toString` method as a stringifier.\n // If that fails, we just return undefined (like in IE11 where URL is not available)\n return (url as URL).toString();\n } catch {} // eslint-disable-line no-empty\n\n return undefined;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"xhr.js","sources":["../../../src/instrument/xhr.ts"],"sourcesContent":["import type { HandlerDataXhr, SentryWrappedXMLHttpRequest } from '@sentry/core';\nimport { addHandler, isString, maybeInstrument, timestampInSeconds, triggerHandlers } from '@sentry/core';\nimport { WINDOW } from '../types';\n\nexport const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';\n\ntype WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };\n\n/**\n * Add an instrumentation handler for when an XHR request happens.\n * The handler function is called once when the request starts and once when it ends,\n * which can be identified by checking if it has an `endTimestamp`.\n *\n * Use at your own risk, this might break without changelog notice, only used internally.\n * @hidden\n */\nexport function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) => void): void {\n const type = 'xhr';\n addHandler(type, handler);\n maybeInstrument(type, instrumentXHR);\n}\n\n/** Exported only for tests. */\nexport function instrumentXHR(): void {\n if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {\n return;\n }\n\n const xhrproto = XMLHttpRequest.prototype;\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.open = new Proxy(xhrproto.open, {\n apply(\n originalOpen,\n xhrOpenThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest,\n xhrOpenArgArray:\n | [method: string, url: string | URL]\n | [method: string, url: string | URL, async: boolean, username?: string | null, password?: string | null],\n ) {\n // NOTE: If you are a Sentry user, and you are seeing this stack frame,\n // it means the error, that was caused by your XHR call did not\n // have a stack trace. If you are using HttpClient integration,\n // this is the expected behavior, as we are using this virtual error to capture\n // the location of your XHR call, and group your HttpClient events accordingly.\n let virtualError: Error | undefined = new Error();\n\n const startTimestamp = timestampInSeconds() * 1000;\n\n // open() should always be called with two or more arguments\n // But to be on the safe side, we actually validate this and bail out if we don't have a method & url\n const method = isString(xhrOpenArgArray[0]) ? xhrOpenArgArray[0].toUpperCase() : undefined;\n const url = parseXhrUrlArg(xhrOpenArgArray[1]);\n\n if (!method || !url) {\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n }\n\n xhrOpenThisArg[SENTRY_XHR_DATA_KEY] = {\n method,\n url,\n request_headers: {},\n };\n\n // if Sentry key appears in URL, don't capture it as a request\n if (method === 'POST' && url.match(/sentry_key/)) {\n xhrOpenThisArg.__sentry_own_request__ = true;\n }\n\n const onreadystatechangeHandler: () => void = () => {\n // For whatever reason, this is not the same instance here as from the outer method\n const xhrInfo = xhrOpenThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!xhrInfo) {\n return;\n }\n\n if (xhrOpenThisArg.readyState === 4) {\n try {\n // touching statusCode in some platforms throws\n // an exception\n xhrInfo.status_code = xhrOpenThisArg.status;\n } catch {\n /* do nothing */\n }\n\n const handlerData: HandlerDataXhr = {\n endTimestamp: timestampInSeconds() * 1000,\n startTimestamp,\n xhr: xhrOpenThisArg,\n virtualError,\n };\n triggerHandlers('xhr', handlerData);\n\n // An unformatted stack keeps its raw frames, and each frame keeps its receiver alive. For a request\n // opened from the previous one's `readystatechange` callback that receiver is the previous\n // XMLHttpRequest, so holding on would chain every completed request to the one still in flight.\n virtualError = undefined;\n\n // In the `addEventListener` branch below this is the only `readystatechange` listener we add, so\n // detach it once the request is done. It's a no-op in the `onreadystatechange` proxy branch.\n xhrOpenThisArg.removeEventListener('readystatechange', onreadystatechangeHandler);\n }\n };\n\n if ('onreadystatechange' in xhrOpenThisArg && typeof xhrOpenThisArg.onreadystatechange === 'function') {\n xhrOpenThisArg.onreadystatechange = new Proxy(xhrOpenThisArg.onreadystatechange, {\n apply(originalOnreadystatechange, onreadystatechangeThisArg, onreadystatechangeArgArray: unknown[]) {\n onreadystatechangeHandler();\n return originalOnreadystatechange.apply(onreadystatechangeThisArg, onreadystatechangeArgArray);\n },\n });\n } else {\n xhrOpenThisArg.addEventListener('readystatechange', onreadystatechangeHandler);\n }\n\n // Intercepting `setRequestHeader` to access the request headers of XHR instance.\n // This will only work for user/library defined headers, not for the default/browser-assigned headers.\n // Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.\n xhrOpenThisArg.setRequestHeader = new Proxy(xhrOpenThisArg.setRequestHeader, {\n apply(\n originalSetRequestHeader,\n setRequestHeaderThisArg: SentryWrappedXMLHttpRequest,\n setRequestHeaderArgArray: unknown[],\n ) {\n const [header, value] = setRequestHeaderArgArray;\n\n const xhrInfo = setRequestHeaderThisArg[SENTRY_XHR_DATA_KEY];\n\n if (xhrInfo && isString(header) && isString(value)) {\n xhrInfo.request_headers[header.toLowerCase()] = value;\n }\n\n return originalSetRequestHeader.apply(setRequestHeaderThisArg, setRequestHeaderArgArray);\n },\n });\n\n return originalOpen.apply(xhrOpenThisArg, xhrOpenArgArray);\n },\n });\n\n // eslint-disable-next-line @typescript-eslint/unbound-method\n xhrproto.send = new Proxy(xhrproto.send, {\n apply(originalSend, sendThisArg: XMLHttpRequest & SentryWrappedXMLHttpRequest, sendArgArray: unknown[]) {\n const sentryXhrData = sendThisArg[SENTRY_XHR_DATA_KEY];\n\n if (!sentryXhrData) {\n return originalSend.apply(sendThisArg, sendArgArray);\n }\n\n if (sendArgArray[0] !== undefined) {\n sentryXhrData.body = sendArgArray[0];\n }\n\n const handlerData: HandlerDataXhr = {\n startTimestamp: timestampInSeconds() * 1000,\n xhr: sendThisArg,\n };\n triggerHandlers('xhr', handlerData);\n\n return originalSend.apply(sendThisArg, sendArgArray);\n },\n });\n}\n\n/**\n * Parses the URL argument of a XHR method to a string.\n *\n * See: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open#url\n * url: A string or any other object with a stringifier — including a URL object — that provides the URL of the resource to send the request to.\n *\n * @param url - The URL argument of an XHR method\n * @returns The parsed URL string or undefined if the URL is invalid\n */\nfunction parseXhrUrlArg(url: unknown): string | undefined {\n if (isString(url)) {\n return url;\n }\n\n try {\n // If the passed in argument is not a string, it should have a `toString` method as a stringifier.\n // If that fails, we just return undefined (like in IE11 where URL is not available)\n return (url as URL).toString();\n } catch {} // eslint-disable-line no-empty\n\n return undefined;\n}\n"],"names":[],"mappings":";;;AAIO,MAAM,mBAAA,GAAsB;AAY5B,SAAS,6BAA6B,OAAA,EAA+C;AAC1F,EAAA,MAAM,IAAA,GAAO,KAAA;AACb,EAAA,UAAA,CAAW,MAAM,OAAO,CAAA;AACxB,EAAA,eAAA,CAAgB,MAAM,aAAa,CAAA;AACrC;AAGO,SAAS,aAAA,GAAsB;AACpC,EAAA,IAAI,CAAE,OAAyB,cAAA,EAAgB;AAC7C,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,WAAW,cAAA,CAAe,SAAA;AAGhC,EAAA,QAAA,CAAS,IAAA,GAAO,IAAI,KAAA,CAAM,QAAA,CAAS,IAAA,EAAM;AAAA,IACvC,KAAA,CACE,YAAA,EACA,cAAA,EACA,eAAA,EAGA;AAMA,MAAA,IAAI,YAAA,GAAkC,IAAI,KAAA,EAAM;AAEhD,MAAA,MAAM,cAAA,GAAiB,oBAAmB,GAAI,GAAA;AAI9C,MAAA,MAAM,MAAA,GAAS,QAAA,CAAS,eAAA,CAAgB,CAAC,CAAC,IAAI,eAAA,CAAgB,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,MAAA;AACjF,MAAA,MAAM,GAAA,GAAM,cAAA,CAAe,eAAA,CAAgB,CAAC,CAAC,CAAA;AAE7C,MAAA,IAAI,CAAC,MAAA,IAAU,CAAC,GAAA,EAAK;AACnB,QAAA,OAAO,YAAA,CAAa,KAAA,CAAM,cAAA,EAAgB,eAAe,CAAA;AAAA,MAC3D;AAEA,MAAA,cAAA,CAAe,mBAAmB,CAAA,GAAI;AAAA,QACpC,MAAA;AAAA,QACA,GAAA;AAAA,QACA,iBAAiB;AAAC,OACpB;AAGA,MAAA,IAAI,MAAA,KAAW,MAAA,IAAU,GAAA,CAAI,KAAA,CAAM,YAAY,CAAA,EAAG;AAChD,QAAA,cAAA,CAAe,sBAAA,GAAyB,IAAA;AAAA,MAC1C;AAEA,MAAA,MAAM,4BAAwC,MAAM;AAElD,QAAA,MAAM,OAAA,GAAU,eAAe,mBAAmB,CAAA;AAElD,QAAA,IAAI,CAAC,OAAA,EAAS;AACZ,UAAA;AAAA,QACF;AAEA,QAAA,IAAI,cAAA,CAAe,eAAe,CAAA,EAAG;AACnC,UAAA,IAAI;AAGF,YAAA,OAAA,CAAQ,cAAc,cAAA,CAAe,MAAA;AAAA,UACvC,CAAA,CAAA,MAAQ;AAAA,UAER;AAEA,UAAA,MAAM,WAAA,GAA8B;AAAA,YAClC,YAAA,EAAc,oBAAmB,GAAI,GAAA;AAAA,YACrC,cAAA;AAAA,YACA,GAAA,EAAK,cAAA;AAAA,YACL;AAAA,WACF;AACA,UAAA,eAAA,CAAgB,OAAO,WAAW,CAAA;AAKlC,UAAA,YAAA,GAAe,MAAA;AAIf,UAAA,cAAA,CAAe,mBAAA,CAAoB,oBAAoB,yBAAyB,CAAA;AAAA,QAClF;AAAA,MACF,CAAA;AAEA,MAAA,IAAI,oBAAA,IAAwB,cAAA,IAAkB,OAAO,cAAA,CAAe,uBAAuB,UAAA,EAAY;AACrG,QAAA,cAAA,CAAe,kBAAA,GAAqB,IAAI,KAAA,CAAM,cAAA,CAAe,kBAAA,EAAoB;AAAA,UAC/E,KAAA,CAAM,0BAAA,EAA4B,yBAAA,EAA2B,0BAAA,EAAuC;AAClG,YAAA,yBAAA,EAA0B;AAC1B,YAAA,OAAO,0BAAA,CAA2B,KAAA,CAAM,yBAAA,EAA2B,0BAA0B,CAAA;AAAA,UAC/F;AAAA,SACD,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,cAAA,CAAe,gBAAA,CAAiB,oBAAoB,yBAAyB,CAAA;AAAA,MAC/E;AAKA,MAAA,cAAA,CAAe,gBAAA,GAAmB,IAAI,KAAA,CAAM,cAAA,CAAe,gBAAA,EAAkB;AAAA,QAC3E,KAAA,CACE,wBAAA,EACA,uBAAA,EACA,wBAAA,EACA;AACA,UAAA,MAAM,CAAC,MAAA,EAAQ,KAAK,CAAA,GAAI,wBAAA;AAExB,UAAA,MAAM,OAAA,GAAU,wBAAwB,mBAAmB,CAAA;AAE3D,UAAA,IAAI,WAAW,QAAA,CAAS,MAAM,CAAA,IAAK,QAAA,CAAS,KAAK,CAAA,EAAG;AAClD,YAAA,OAAA,CAAQ,eAAA,CAAgB,MAAA,CAAO,WAAA,EAAa,CAAA,GAAI,KAAA;AAAA,UAClD;AAEA,UAAA,OAAO,wBAAA,CAAyB,KAAA,CAAM,uBAAA,EAAyB,wBAAwB,CAAA;AAAA,QACzF;AAAA,OACD,CAAA;AAED,MAAA,OAAO,YAAA,CAAa,KAAA,CAAM,cAAA,EAAgB,eAAe,CAAA;AAAA,IAC3D;AAAA,GACD,CAAA;AAGD,EAAA,QAAA,CAAS,IAAA,GAAO,IAAI,KAAA,CAAM,QAAA,CAAS,IAAA,EAAM;AAAA,IACvC,KAAA,CAAM,YAAA,EAAc,WAAA,EAA2D,YAAA,EAAyB;AACtG,MAAA,MAAM,aAAA,GAAgB,YAAY,mBAAmB,CAAA;AAErD,MAAA,IAAI,CAAC,aAAA,EAAe;AAClB,QAAA,OAAO,YAAA,CAAa,KAAA,CAAM,WAAA,EAAa,YAAY,CAAA;AAAA,MACrD;AAEA,MAAA,IAAI,YAAA,CAAa,CAAC,CAAA,KAAM,MAAA,EAAW;AACjC,QAAA,aAAA,CAAc,IAAA,GAAO,aAAa,CAAC,CAAA;AAAA,MACrC;AAEA,MAAA,MAAM,WAAA,GAA8B;AAAA,QAClC,cAAA,EAAgB,oBAAmB,GAAI,GAAA;AAAA,QACvC,GAAA,EAAK;AAAA,OACP;AACA,MAAA,eAAA,CAAgB,OAAO,WAAW,CAAA;AAElC,MAAA,OAAO,YAAA,CAAa,KAAA,CAAM,WAAA,EAAa,YAAY,CAAA;AAAA,IACrD;AAAA,GACD,CAAA;AACH;AAWA,SAAS,eAAe,GAAA,EAAkC;AACxD,EAAA,IAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACjB,IAAA,OAAO,GAAA;AAAA,EACT;AAEA,EAAA,IAAI;AAGF,IAAA,OAAQ,IAAY,QAAA,EAAS;AAAA,EAC/B,CAAA,CAAA,MAAQ;AAAA,EAAC;AAET,EAAA,OAAO,MAAA;AACT;;;;"}
@@ -22,6 +22,7 @@ const onLCP = (onReport, opts = {}) => {
22
22
  entries = entries.slice(-1);
23
23
  }
24
24
  for (const entry of entries) {
25
+ if (!entry) continue;
25
26
  lcpEntryManager._processEntry(entry);
26
27
  if (entry.startTime < visibilityWatcher.firstHiddenTime) {
27
28
  metric.value = Math.max(entry.startTime - getActivationStart(), 0);
@@ -1 +1 @@
1
- {"version":3,"file":"getLCP.js","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"sourcesContent":["/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { addPageListener, removePageListener } from './lib/globalListeners';\nimport { initMetric } from './lib/initMetric';\nimport { initUnique } from './lib/initUnique';\nimport { LCPEntryManager } from './lib/LCPEntryManager';\nimport { observe } from './lib/observe';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('LCP');\n let report: ReturnType<typeof bindReporter>;\n\n const lcpEntryManager = initUnique(opts, LCPEntryManager);\n\n const handleEntries = (entries: LCPMetric['entries']) => {\n // If reportAllChanges is set then call this function for each entry,\n // otherwise only consider the last one.\n if (!opts.reportAllChanges) {\n // eslint-disable-next-line no-param-reassign\n entries = entries.slice(-1);\n }\n\n for (const entry of entries) {\n lcpEntryManager._processEntry(entry);\n\n // Only report if the page wasn't hidden prior to LCP.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries = [entry];\n report();\n }\n }\n };\n\n const po = observe('largest-contentful-paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n // Ensure this logic only runs once, since it can be triggered from\n // any of three different event listeners below.\n const stopListening = runOnce(() => {\n handleEntries(po.takeRecords() as LCPMetric['entries']);\n po.disconnect();\n report(true);\n });\n\n // Need a separate wrapper to ensure the `runOnce` function above is\n // common for all three functions\n const stopListeningWrapper = (event: Event) => {\n if (event.isTrusted) {\n // Wrap the listener in an idle callback so it's run in a separate\n // task to reduce potential INP impact.\n // https://github.com/GoogleChrome/web-vitals/issues/383\n whenIdleOrHidden(stopListening);\n removePageListener(event.type, stopListeningWrapper, {\n capture: true,\n });\n }\n };\n\n // Stop listening after input or visibilitychange.\n // Note: while scrolling is an input that stops LCP observation, it's\n // unreliable since it can be programmatically generated.\n // See: https://github.com/GoogleChrome/web-vitals/issues/75\n for (const type of ['keydown', 'click', 'visibilitychange']) {\n addPageListener(type, stopListeningWrapper, {\n capture: true,\n });\n }\n }\n });\n};\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BO,MAAM,aAAA,GAAwC,CAAC,IAAA,EAAM,GAAI;AAazD,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAuC,IAAA,GAAmB,EAAC,KAAM;AACrF,EAAA,aAAA,CAAc,MAAM;AAClB,IAAA,MAAM,oBAAoB,oBAAA,EAAqB;AAC/C,IAAA,MAAM,MAAA,GAAS,WAAW,KAAK,CAAA;AAC/B,IAAA,IAAI,MAAA;AAEJ,IAAA,MAAM,eAAA,GAAkB,UAAA,CAAW,IAAA,EAAM,eAAe,CAAA;AAExD,IAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,KAAkC;AAGvD,MAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAE1B,QAAA,OAAA,GAAU,OAAA,CAAQ,MAAM,EAAE,CAAA;AAAA,MAC5B;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAC3B,QAAA,eAAA,CAAgB,cAAc,KAAK,CAAA;AAGnC,QAAA,IAAI,KAAA,CAAM,SAAA,GAAY,iBAAA,CAAkB,eAAA,EAAiB;AAOvD,UAAA,MAAA,CAAO,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,SAAA,GAAY,kBAAA,IAAsB,CAAC,CAAA;AACjE,UAAA,MAAA,CAAO,OAAA,GAAU,CAAC,KAAK,CAAA;AACvB,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,0BAAA,EAA4B,aAAa,CAAA;AAE5D,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,MAAA,GAAS,YAAA,CAAa,QAAA,EAAU,MAAA,EAAQ,aAAA,EAAe,KAAK,gBAAgB,CAAA;AAI5E,MAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAClC,QAAA,aAAA,CAAc,EAAA,CAAG,aAAqC,CAAA;AACtD,QAAA,EAAA,CAAG,UAAA,EAAW;AACd,QAAA,MAAA,CAAO,IAAI,CAAA;AAAA,MACb,CAAC,CAAA;AAID,MAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAiB;AAC7C,QAAA,IAAI,MAAM,SAAA,EAAW;AAInB,UAAA,gBAAA,CAAiB,aAAa,CAAA;AAC9B,UAAA,kBAAA,CAAmB,KAAA,CAAM,MAAM,oBAAA,EAAsB;AAAA,YACnD,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAMA,MAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,SAAA,EAAW,OAAA,EAAS,kBAAkB,CAAA,EAAG;AAC3D,QAAA,eAAA,CAAgB,MAAM,oBAAA,EAAsB;AAAA,UAC1C,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"getLCP.js","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"sourcesContent":["/*\n * Copyright 2020 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { bindReporter } from './lib/bindReporter';\nimport { getActivationStart } from './lib/getActivationStart';\nimport { getVisibilityWatcher } from './lib/getVisibilityWatcher';\nimport { addPageListener, removePageListener } from './lib/globalListeners';\nimport { initMetric } from './lib/initMetric';\nimport { initUnique } from './lib/initUnique';\nimport { LCPEntryManager } from './lib/LCPEntryManager';\nimport { observe } from './lib/observe';\nimport { runOnce } from './lib/runOnce';\nimport { whenActivated } from './lib/whenActivated';\nimport { whenIdleOrHidden } from './lib/whenIdleOrHidden';\nimport type { LCPMetric, MetricRatingThresholds, ReportOpts } from './types';\n\n/** Thresholds for LCP. See https://web.dev/articles/lcp#what_is_a_good_lcp_score */\nexport const LCPThresholds: MetricRatingThresholds = [2500, 4000];\n\n/**\n * Calculates the [LCP](https://web.dev/articles/lcp) value for the current page and\n * calls the `callback` function once the value is ready (along with the\n * relevant `largest-contentful-paint` performance entry used to determine the\n * value). The reported value is a `DOMHighResTimeStamp`.\n *\n * If the `reportAllChanges` configuration option is set to `true`, the\n * `callback` function will be called any time a new `largest-contentful-paint`\n * performance entry is dispatched, or once the final value of the metric has\n * been determined.\n */\nexport const onLCP = (onReport: (metric: LCPMetric) => void, opts: ReportOpts = {}) => {\n whenActivated(() => {\n const visibilityWatcher = getVisibilityWatcher();\n const metric = initMetric('LCP');\n let report: ReturnType<typeof bindReporter>;\n\n const lcpEntryManager = initUnique(opts, LCPEntryManager);\n\n const handleEntries = (entries: LCPMetric['entries']) => {\n // If reportAllChanges is set then call this function for each entry,\n // otherwise only consider the last one.\n if (!opts.reportAllChanges) {\n // eslint-disable-next-line no-param-reassign\n entries = entries.slice(-1);\n }\n\n for (const entry of entries) {\n // Upstream has this guard too; a patched PerformanceObserver can yield nullish entries.\n if (!entry) continue;\n\n lcpEntryManager._processEntry(entry);\n\n // Only report if the page wasn't hidden prior to LCP.\n if (entry.startTime < visibilityWatcher.firstHiddenTime) {\n // The startTime attribute returns the value of the renderTime if it is\n // not 0, and the value of the loadTime otherwise. The activationStart\n // reference is used because LCP should be relative to page activation\n // rather than navigation start if the page was prerendered. But in cases\n // where `activationStart` occurs after the LCP, this time should be\n // clamped at 0.\n metric.value = Math.max(entry.startTime - getActivationStart(), 0);\n metric.entries = [entry];\n report();\n }\n }\n };\n\n const po = observe('largest-contentful-paint', handleEntries);\n\n if (po) {\n report = bindReporter(onReport, metric, LCPThresholds, opts.reportAllChanges);\n\n // Ensure this logic only runs once, since it can be triggered from\n // any of three different event listeners below.\n const stopListening = runOnce(() => {\n handleEntries(po.takeRecords() as LCPMetric['entries']);\n po.disconnect();\n report(true);\n });\n\n // Need a separate wrapper to ensure the `runOnce` function above is\n // common for all three functions\n const stopListeningWrapper = (event: Event) => {\n if (event.isTrusted) {\n // Wrap the listener in an idle callback so it's run in a separate\n // task to reduce potential INP impact.\n // https://github.com/GoogleChrome/web-vitals/issues/383\n whenIdleOrHidden(stopListening);\n removePageListener(event.type, stopListeningWrapper, {\n capture: true,\n });\n }\n };\n\n // Stop listening after input or visibilitychange.\n // Note: while scrolling is an input that stops LCP observation, it's\n // unreliable since it can be programmatically generated.\n // See: https://github.com/GoogleChrome/web-vitals/issues/75\n for (const type of ['keydown', 'click', 'visibilitychange']) {\n addPageListener(type, stopListeningWrapper, {\n capture: true,\n });\n }\n }\n });\n};\n"],"names":[],"mappings":";;;;;;;;;;;;AA8BO,MAAM,aAAA,GAAwC,CAAC,IAAA,EAAM,GAAI;AAazD,MAAM,KAAA,GAAQ,CAAC,QAAA,EAAuC,IAAA,GAAmB,EAAC,KAAM;AACrF,EAAA,aAAA,CAAc,MAAM;AAClB,IAAA,MAAM,oBAAoB,oBAAA,EAAqB;AAC/C,IAAA,MAAM,MAAA,GAAS,WAAW,KAAK,CAAA;AAC/B,IAAA,IAAI,MAAA;AAEJ,IAAA,MAAM,eAAA,GAAkB,UAAA,CAAW,IAAA,EAAM,eAAe,CAAA;AAExD,IAAA,MAAM,aAAA,GAAgB,CAAC,OAAA,KAAkC;AAGvD,MAAA,IAAI,CAAC,KAAK,gBAAA,EAAkB;AAE1B,QAAA,OAAA,GAAU,OAAA,CAAQ,MAAM,EAAE,CAAA;AAAA,MAC5B;AAEA,MAAA,KAAA,MAAW,SAAS,OAAA,EAAS;AAE3B,QAAA,IAAI,CAAC,KAAA,EAAO;AAEZ,QAAA,eAAA,CAAgB,cAAc,KAAK,CAAA;AAGnC,QAAA,IAAI,KAAA,CAAM,SAAA,GAAY,iBAAA,CAAkB,eAAA,EAAiB;AAOvD,UAAA,MAAA,CAAO,QAAQ,IAAA,CAAK,GAAA,CAAI,MAAM,SAAA,GAAY,kBAAA,IAAsB,CAAC,CAAA;AACjE,UAAA,MAAA,CAAO,OAAA,GAAU,CAAC,KAAK,CAAA;AACvB,UAAA,MAAA,EAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF,CAAA;AAEA,IAAA,MAAM,EAAA,GAAK,OAAA,CAAQ,0BAAA,EAA4B,aAAa,CAAA;AAE5D,IAAA,IAAI,EAAA,EAAI;AACN,MAAA,MAAA,GAAS,YAAA,CAAa,QAAA,EAAU,MAAA,EAAQ,aAAA,EAAe,KAAK,gBAAgB,CAAA;AAI5E,MAAA,MAAM,aAAA,GAAgB,QAAQ,MAAM;AAClC,QAAA,aAAA,CAAc,EAAA,CAAG,aAAqC,CAAA;AACtD,QAAA,EAAA,CAAG,UAAA,EAAW;AACd,QAAA,MAAA,CAAO,IAAI,CAAA;AAAA,MACb,CAAC,CAAA;AAID,MAAA,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAiB;AAC7C,QAAA,IAAI,MAAM,SAAA,EAAW;AAInB,UAAA,gBAAA,CAAiB,aAAa,CAAA;AAC9B,UAAA,kBAAA,CAAmB,KAAA,CAAM,MAAM,oBAAA,EAAsB;AAAA,YACnD,OAAA,EAAS;AAAA,WACV,CAAA;AAAA,QACH;AAAA,MACF,CAAA;AAMA,MAAA,KAAA,MAAW,IAAA,IAAQ,CAAC,SAAA,EAAW,OAAA,EAAS,kBAAkB,CAAA,EAAG;AAC3D,QAAA,eAAA,CAAgB,MAAM,oBAAA,EAAsB;AAAA,UAC1C,OAAA,EAAS;AAAA,SACV,CAAA;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AACH;;;;"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.74.0","sideEffects":false}
1
+ {"type":"module","version":"10.75.0","sideEffects":false}
@@ -1 +1 @@
1
- {"version":3,"file":"xhr.d.ts","sourceRoot":"","sources":["../../../src/instrument/xhr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA+B,MAAM,cAAc,CAAC;AAIhF,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAIvD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAI1F;AAED,+BAA+B;AAC/B,wBAAgB,aAAa,IAAI,IAAI,CA0IpC"}
1
+ {"version":3,"file":"xhr.d.ts","sourceRoot":"","sources":["../../../src/instrument/xhr.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAA+B,MAAM,cAAc,CAAC;AAIhF,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAIvD;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,IAAI,CAI1F;AAED,+BAA+B;AAC/B,wBAAgB,aAAa,IAAI,IAAI,CA2IpC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getLCP.d.ts","sourceRoot":"","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE7E,oFAAoF;AACpF,eAAO,MAAM,aAAa,EAAE,sBAAqC,CAAC;AAElE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,GAAI,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,EAAE,OAAM,UAAe,SAwEjF,CAAC"}
1
+ {"version":3,"file":"getLCP.d.ts","sourceRoot":"","sources":["../../../../src/metrics/web-vitals/getLCP.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,SAAS,EAAE,sBAAsB,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE7E,oFAAoF;AACpF,eAAO,MAAM,aAAa,EAAE,sBAAqC,CAAC;AAElE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,KAAK,GAAI,UAAU,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,EAAE,OAAM,UAAe,SA2EjF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/browser-utils",
3
- "version": "10.74.0",
3
+ "version": "10.75.0",
4
4
  "description": "Browser Utilities for all Sentry JavaScript SDKs",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser-utils",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@sentry/core": "10.74.0",
43
+ "@sentry/core": "10.75.0",
44
44
  "@sentry/conventions": "^0.16.0"
45
45
  },
46
46
  "scripts": {