summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm/time.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/utils/esm/time.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm/time.js')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/time.js183
1 files changed, 183 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/time.js b/shared/logger/node_modules/@sentry/utils/esm/time.js
new file mode 100644
index 0000000..2703ed2
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/time.js
@@ -0,0 +1,183 @@
+import { isNodeEnv, dynamicRequire } from './node.js';
+import { getGlobalObject } from './worldwide.js';
+
+// eslint-disable-next-line deprecation/deprecation
+const WINDOW = getGlobalObject();
+
+/**
+ * An object that can return the current timestamp in seconds since the UNIX epoch.
+ */
+
+/**
+ * A TimestampSource implementation for environments that do not support the Performance Web API natively.
+ *
+ * Note that this TimestampSource does not use a monotonic clock. A call to `nowSeconds` may return a timestamp earlier
+ * than a previously returned value. We do not try to emulate a monotonic behavior in order to facilitate debugging. It
+ * is more obvious to explain "why does my span have negative duration" than "why my spans have zero duration".
+ */
+const dateTimestampSource = {
+ nowSeconds: () => Date.now() / 1000,
+};
+
+/**
+ * A partial definition of the [Performance Web API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Performance}
+ * for accessing a high-resolution monotonic clock.
+ */
+
+/**
+ * Returns a wrapper around the native Performance API browser implementation, or undefined for browsers that do not
+ * support the API.
+ *
+ * Wrapping the native API works around differences in behavior from different browsers.
+ */
+function getBrowserPerformance() {
+ const { performance } = WINDOW;
+ if (!performance || !performance.now) {
+ return undefined;
+ }
+
+ // Replace performance.timeOrigin with our own timeOrigin based on Date.now().
+ //
+ // This is a partial workaround for browsers reporting performance.timeOrigin such that performance.timeOrigin +
+ // performance.now() gives a date arbitrarily in the past.
+ //
+ // Additionally, computing timeOrigin in this way fills the gap for browsers where performance.timeOrigin is
+ // undefined.
+ //
+ // The assumption that performance.timeOrigin + performance.now() ~= Date.now() is flawed, but we depend on it to
+ // interact with data coming out of performance entries.
+ //
+ // Note that despite recommendations against it in the spec, browsers implement the Performance API with a clock that
+ // might stop when the computer is asleep (and perhaps under other circumstances). Such behavior causes
+ // performance.timeOrigin + performance.now() to have an arbitrary skew over Date.now(). In laptop computers, we have
+ // observed skews that can be as long as days, weeks or months.
+ //
+ // See https://github.com/getsentry/sentry-javascript/issues/2590.
+ //
+ // BUG: despite our best intentions, this workaround has its limitations. It mostly addresses timings of pageload
+ // transactions, but ignores the skew built up over time that can aversely affect timestamps of navigation
+ // transactions of long-lived web pages.
+ const timeOrigin = Date.now() - performance.now();
+
+ return {
+ now: () => performance.now(),
+ timeOrigin,
+ };
+}
+
+/**
+ * Returns the native Performance API implementation from Node.js. Returns undefined in old Node.js versions that don't
+ * implement the API.
+ */
+function getNodePerformance() {
+ try {
+ const perfHooks = dynamicRequire(module, 'perf_hooks') ;
+ return perfHooks.performance;
+ } catch (_) {
+ return undefined;
+ }
+}
+
+/**
+ * The Performance API implementation for the current platform, if available.
+ */
+const platformPerformance = isNodeEnv() ? getNodePerformance() : getBrowserPerformance();
+
+const timestampSource =
+ platformPerformance === undefined
+ ? dateTimestampSource
+ : {
+ nowSeconds: () => (platformPerformance.timeOrigin + platformPerformance.now()) / 1000,
+ };
+
+/**
+ * Returns a timestamp in seconds since the UNIX epoch using the Date API.
+ */
+const dateTimestampInSeconds = dateTimestampSource.nowSeconds.bind(dateTimestampSource);
+
+/**
+ * Returns a timestamp in seconds since the UNIX epoch using either the Performance or Date APIs, depending on the
+ * availability of the Performance API.
+ *
+ * See `usingPerformanceAPI` to test whether the Performance API is used.
+ *
+ * BUG: Note that because of how browsers implement the Performance API, the clock might stop when the computer is
+ * asleep. This creates a skew between `dateTimestampInSeconds` and `timestampInSeconds`. The
+ * skew can grow to arbitrary amounts like days, weeks or months.
+ * See https://github.com/getsentry/sentry-javascript/issues/2590.
+ */
+const timestampInSeconds = timestampSource.nowSeconds.bind(timestampSource);
+
+/**
+ * Re-exported with an old name for backwards-compatibility.
+ * TODO (v8): Remove this
+ *
+ * @deprecated Use `timestampInSeconds` instead.
+ */
+const timestampWithMs = timestampInSeconds;
+
+/**
+ * A boolean that is true when timestampInSeconds uses the Performance API to produce monotonic timestamps.
+ */
+const usingPerformanceAPI = platformPerformance !== undefined;
+
+/**
+ * Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.
+ */
+let _browserPerformanceTimeOriginMode;
+
+/**
+ * The number of milliseconds since the UNIX epoch. This value is only usable in a browser, and only when the
+ * performance API is available.
+ */
+const browserPerformanceTimeOrigin = (() => {
+ // Unfortunately browsers may report an inaccurate time origin data, through either performance.timeOrigin or
+ // performance.timing.navigationStart, which results in poor results in performance data. We only treat time origin
+ // data as reliable if they are within a reasonable threshold of the current time.
+
+ const { performance } = WINDOW;
+ if (!performance || !performance.now) {
+ _browserPerformanceTimeOriginMode = 'none';
+ return undefined;
+ }
+
+ const threshold = 3600 * 1000;
+ const performanceNow = performance.now();
+ const dateNow = Date.now();
+
+ // if timeOrigin isn't available set delta to threshold so it isn't used
+ const timeOriginDelta = performance.timeOrigin
+ ? Math.abs(performance.timeOrigin + performanceNow - dateNow)
+ : threshold;
+ const timeOriginIsReliable = timeOriginDelta < threshold;
+
+ // While performance.timing.navigationStart is deprecated in favor of performance.timeOrigin, performance.timeOrigin
+ // is not as widely supported. Namely, performance.timeOrigin is undefined in Safari as of writing.
+ // Also as of writing, performance.timing is not available in Web Workers in mainstream browsers, so it is not always
+ // a valid fallback. In the absence of an initial time provided by the browser, fallback to the current time from the
+ // Date API.
+ // eslint-disable-next-line deprecation/deprecation
+ const navigationStart = performance.timing && performance.timing.navigationStart;
+ const hasNavigationStart = typeof navigationStart === 'number';
+ // if navigationStart isn't available set delta to threshold so it isn't used
+ const navigationStartDelta = hasNavigationStart ? Math.abs(navigationStart + performanceNow - dateNow) : threshold;
+ const navigationStartIsReliable = navigationStartDelta < threshold;
+
+ if (timeOriginIsReliable || navigationStartIsReliable) {
+ // Use the more reliable time origin
+ if (timeOriginDelta <= navigationStartDelta) {
+ _browserPerformanceTimeOriginMode = 'timeOrigin';
+ return performance.timeOrigin;
+ } else {
+ _browserPerformanceTimeOriginMode = 'navigationStart';
+ return navigationStart;
+ }
+ }
+
+ // Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.
+ _browserPerformanceTimeOriginMode = 'dateNow';
+ return dateNow;
+})();
+
+export { _browserPerformanceTimeOriginMode, browserPerformanceTimeOrigin, dateTimestampInSeconds, timestampInSeconds, timestampWithMs, usingPerformanceAPI };
+//# sourceMappingURL=time.js.map