Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@sentry-internal/browser-utils

Package Overview
Dependencies
Maintainers
9
Versions
63
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sentry-internal/browser-utils - npm Package Compare versions

Comparing version 8.17.0 to 8.18.0

1

build/cjs/index.js

@@ -21,2 +21,3 @@ Object.defineProperty(exports, '__esModule', { value: true });

exports.startTrackingInteractions = browserMetrics.startTrackingInteractions;
exports.startTrackingLongAnimationFrames = browserMetrics.startTrackingLongAnimationFrames;
exports.startTrackingLongTasks = browserMetrics.startTrackingLongTasks;

@@ -23,0 +24,0 @@ exports.startTrackingWebVitals = browserMetrics.startTrackingWebVitals;

@@ -79,2 +79,55 @@ Object.defineProperty(exports, '__esModule', { value: true });

/**
* Start tracking long animation frames.
*/
function startTrackingLongAnimationFrames() {
// NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so
// we directly observe `long-animation-frame` events instead of through the web-vitals
// `observe` helper function.
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries() ) {
if (!core.getActiveSpan()) {
return;
}
if (!entry.scripts[0]) {
return;
}
const startTime = utils.msToSec((utils$1.browserPerformanceTimeOrigin ) + entry.startTime);
const duration = utils.msToSec(entry.duration);
const attributes = {
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',
};
const initialScript = entry.scripts[0];
if (initialScript) {
const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;
attributes['browser.script.invoker'] = invoker;
attributes['browser.script.invoker_type'] = invokerType;
if (sourceURL) {
attributes['code.filepath'] = sourceURL;
}
if (sourceFunctionName) {
attributes['code.function'] = sourceFunctionName;
}
if (sourceCharPosition !== -1) {
attributes['browser.script.source_char_position'] = sourceCharPosition;
}
}
const span = core.startInactiveSpan({
name: 'Main UI thread blocked',
op: 'ui.long-animation-frame',
startTime,
attributes,
});
if (span) {
span.end(startTime + duration);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
}
/**
* Start tracking interaction events.

@@ -547,4 +600,5 @@ */

exports.startTrackingInteractions = startTrackingInteractions;
exports.startTrackingLongAnimationFrames = startTrackingLongAnimationFrames;
exports.startTrackingLongTasks = startTrackingLongTasks;
exports.startTrackingWebVitals = startTrackingWebVitals;
//# sourceMappingURL=browserMetrics.js.map

38

build/cjs/metrics/inp.js

@@ -5,9 +5,8 @@ Object.defineProperty(exports, '__esModule', { value: true });

const utils$1 = require('@sentry/utils');
const types = require('../types.js');
const instrument = require('./instrument.js');
const utils = require('./utils.js');
// We only care about name here
const LAST_INTERACTIONS = [];
const INTERACTIONS_ROUTE_MAP = new Map();
const INTERACTIONS_SPAN_MAP = new Map();

@@ -84,10 +83,11 @@ /**

// We first try to lookup the route name from our INTERACTIONS_ROUTE_MAP,
// We first try to lookup the span from our INTERACTIONS_SPAN_MAP,
// where we cache the route per interactionId
const cachedRouteName = interactionId != null ? INTERACTIONS_ROUTE_MAP.get(interactionId) : undefined;
const cachedSpan = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;
const spanToUse = cachedSpan || rootSpan;
// Else, we try to use the active span.
// Finally, we fall back to look at the transactionName on the scope
const routeName =
cachedRouteName || (rootSpan ? core.spanToJSON(rootSpan).description : scope.getScopeData().transactionName);
const routeName = spanToUse ? core.spanToJSON(spanToUse).description : scope.getScopeData().transactionName;

@@ -121,2 +121,5 @@ const user = scope.getUser();

replay_id: replayId || undefined,
// INP score calculation in the sentry backend relies on the user agent
// to account for different INP values being reported from different browsers
'user_agent.original': types.WINDOW.navigator && types.WINDOW.navigator.userAgent,
});

@@ -143,7 +146,13 @@

/** Register a listener to cache route information for INP interactions. */
function registerInpInteractionListener(latestRoute) {
/**
* Register a listener to cache route information for INP interactions.
* TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.
*/
function registerInpInteractionListener(_latestRoute) {
const handleEntries = ({ entries }) => {
const activeSpan = core.getActiveSpan();
const activeRootSpan = activeSpan && core.getRootSpan(activeSpan);
entries.forEach(entry => {
if (!instrument.isPerformanceEventTiming(entry) || !latestRoute.name) {
if (!instrument.isPerformanceEventTiming(entry) || !activeRootSpan) {
return;

@@ -158,3 +167,3 @@ }

// If the interaction was already recorded before, nothing more to do
if (INTERACTIONS_ROUTE_MAP.has(interactionId)) {
if (INTERACTIONS_SPAN_MAP.has(interactionId)) {
return;

@@ -166,10 +175,9 @@ }

const last = LAST_INTERACTIONS.shift() ;
INTERACTIONS_ROUTE_MAP.delete(last);
INTERACTIONS_SPAN_MAP.delete(last);
}
// We add the interaction to the list of recorded interactions
// and store the route information for this interaction
// (we clone the object because it is mutated when it changes)
// and store the span for this interaction
LAST_INTERACTIONS.push(interactionId);
INTERACTIONS_ROUTE_MAP.set(interactionId, latestRoute.name);
INTERACTIONS_SPAN_MAP.set(interactionId, activeRootSpan);
});

@@ -176,0 +184,0 @@ };

export { addClsInstrumentationHandler, addFidInstrumentationHandler, addInpInstrumentationHandler, addLcpInstrumentationHandler, addPerformanceInstrumentationHandler, addTtfbInstrumentationHandler } from './metrics/instrument.js';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingWebVitals } from './metrics/browserMetrics.js';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongAnimationFrames, startTrackingLongTasks, startTrackingWebVitals } from './metrics/browserMetrics.js';
export { addClickKeypressInstrumentationHandler } from './instrument/dom.js';

@@ -4,0 +4,0 @@ export { addHistoryInstrumentationHandler } from './instrument/history.js';

@@ -1,2 +0,2 @@

import { spanToJSON, setMeasurement, getActiveSpan, startInactiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
import { getActiveSpan, startInactiveSpan, spanToJSON, setMeasurement, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
import { browserPerformanceTimeOrigin, logger, parseUrl, htmlTreeAsString, getComponentName } from '@sentry/utils';

@@ -77,2 +77,55 @@ import { DEBUG_BUILD } from '../debug-build.js';

/**
* Start tracking long animation frames.
*/
function startTrackingLongAnimationFrames() {
// NOTE: the current web-vitals version (3.5.2) does not support long-animation-frame, so
// we directly observe `long-animation-frame` events instead of through the web-vitals
// `observe` helper function.
const observer = new PerformanceObserver(list => {
for (const entry of list.getEntries() ) {
if (!getActiveSpan()) {
return;
}
if (!entry.scripts[0]) {
return;
}
const startTime = msToSec((browserPerformanceTimeOrigin ) + entry.startTime);
const duration = msToSec(entry.duration);
const attributes = {
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.browser.metrics',
};
const initialScript = entry.scripts[0];
if (initialScript) {
const { invoker, invokerType, sourceURL, sourceFunctionName, sourceCharPosition } = initialScript;
attributes['browser.script.invoker'] = invoker;
attributes['browser.script.invoker_type'] = invokerType;
if (sourceURL) {
attributes['code.filepath'] = sourceURL;
}
if (sourceFunctionName) {
attributes['code.function'] = sourceFunctionName;
}
if (sourceCharPosition !== -1) {
attributes['browser.script.source_char_position'] = sourceCharPosition;
}
}
const span = startInactiveSpan({
name: 'Main UI thread blocked',
op: 'ui.long-animation-frame',
startTime,
attributes,
});
if (span) {
span.end(startTime + duration);
}
}
});
observer.observe({ type: 'long-animation-frame', buffered: true });
}
/**
* Start tracking interaction events.

@@ -541,3 +594,3 @@ */

export { _addMeasureSpans, _addResourceSpans, addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingWebVitals };
export { _addMeasureSpans, _addResourceSpans, addPerformanceEntries, startTrackingInteractions, startTrackingLongAnimationFrames, startTrackingLongTasks, startTrackingWebVitals };
//# sourceMappingURL=browserMetrics.js.map
import { getClient, getCurrentScope, getActiveSpan, getRootSpan, spanToJSON, SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startInactiveSpan, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT, SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE } from '@sentry/core';
import { browserPerformanceTimeOrigin, htmlTreeAsString, dropUndefinedKeys } from '@sentry/utils';
import { WINDOW } from '../types.js';
import { addInpInstrumentationHandler, addPerformanceInstrumentationHandler, isPerformanceEventTiming } from './instrument.js';
import { getBrowserPerformanceAPI, msToSec } from './utils.js';
// We only care about name here
const LAST_INTERACTIONS = [];
const INTERACTIONS_ROUTE_MAP = new Map();
const INTERACTIONS_SPAN_MAP = new Map();

@@ -81,10 +80,11 @@ /**

// We first try to lookup the route name from our INTERACTIONS_ROUTE_MAP,
// We first try to lookup the span from our INTERACTIONS_SPAN_MAP,
// where we cache the route per interactionId
const cachedRouteName = interactionId != null ? INTERACTIONS_ROUTE_MAP.get(interactionId) : undefined;
const cachedSpan = interactionId != null ? INTERACTIONS_SPAN_MAP.get(interactionId) : undefined;
const spanToUse = cachedSpan || rootSpan;
// Else, we try to use the active span.
// Finally, we fall back to look at the transactionName on the scope
const routeName =
cachedRouteName || (rootSpan ? spanToJSON(rootSpan).description : scope.getScopeData().transactionName);
const routeName = spanToUse ? spanToJSON(spanToUse).description : scope.getScopeData().transactionName;

@@ -118,2 +118,5 @@ const user = scope.getUser();

replay_id: replayId || undefined,
// INP score calculation in the sentry backend relies on the user agent
// to account for different INP values being reported from different browsers
'user_agent.original': WINDOW.navigator && WINDOW.navigator.userAgent,
});

@@ -140,7 +143,13 @@

/** Register a listener to cache route information for INP interactions. */
function registerInpInteractionListener(latestRoute) {
/**
* Register a listener to cache route information for INP interactions.
* TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.
*/
function registerInpInteractionListener(_latestRoute) {
const handleEntries = ({ entries }) => {
const activeSpan = getActiveSpan();
const activeRootSpan = activeSpan && getRootSpan(activeSpan);
entries.forEach(entry => {
if (!isPerformanceEventTiming(entry) || !latestRoute.name) {
if (!isPerformanceEventTiming(entry) || !activeRootSpan) {
return;

@@ -155,3 +164,3 @@ }

// If the interaction was already recorded before, nothing more to do
if (INTERACTIONS_ROUTE_MAP.has(interactionId)) {
if (INTERACTIONS_SPAN_MAP.has(interactionId)) {
return;

@@ -163,10 +172,9 @@ }

const last = LAST_INTERACTIONS.shift() ;
INTERACTIONS_ROUTE_MAP.delete(last);
INTERACTIONS_SPAN_MAP.delete(last);
}
// We add the interaction to the list of recorded interactions
// and store the route information for this interaction
// (we clone the object because it is mutated when it changes)
// and store the span for this interaction
LAST_INTERACTIONS.push(interactionId);
INTERACTIONS_ROUTE_MAP.set(interactionId, latestRoute.name);
INTERACTIONS_SPAN_MAP.set(interactionId, activeRootSpan);
});

@@ -173,0 +181,0 @@ };

export { addPerformanceInstrumentationHandler, addClsInstrumentationHandler, addFidInstrumentationHandler, addTtfbInstrumentationHandler, addLcpInstrumentationHandler, addInpInstrumentationHandler, } from './metrics/instrument';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingWebVitals, startTrackingINP, registerInpInteractionListener, } from './metrics/browserMetrics';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingLongAnimationFrames, startTrackingWebVitals, startTrackingINP, registerInpInteractionListener, } from './metrics/browserMetrics';
export { addClickKeypressInstrumentationHandler } from './instrument/dom';

@@ -4,0 +4,0 @@ export { addHistoryInstrumentationHandler } from './instrument/history';

@@ -14,2 +14,6 @@ import { Span } from '@sentry/types';

/**
* Start tracking long animation frames.
*/
export declare function startTrackingLongAnimationFrames(): void;
/**
* Start tracking interaction events.

@@ -16,0 +20,0 @@ */

@@ -1,4 +0,1 @@

interface PartialRouteInfo {
name: string | undefined;
}
/**

@@ -8,5 +5,7 @@ * Start tracking INP webvital events.

export declare function startTrackingINP(): () => void;
/** Register a listener to cache route information for INP interactions. */
export declare function registerInpInteractionListener(latestRoute: PartialRouteInfo): void;
export {};
/**
* Register a listener to cache route information for INP interactions.
* TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.
*/
export declare function registerInpInteractionListener(_latestRoute?: unknown): void;
//# sourceMappingURL=inp.d.ts.map

@@ -17,2 +17,12 @@ type InstrumentHandlerTypePerformanceObserver = 'longtask' | 'event' | 'navigation' | 'paint' | 'resource' | 'first-input';

}
interface PerformanceScriptTiming extends PerformanceEntry {
sourceURL: string;
sourceFunctionName: string;
sourceCharPosition: number;
invoker: string;
invokerType: string;
}
export interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
scripts: PerformanceScriptTiming[];
}
interface Metric {

@@ -19,0 +29,0 @@ /**

export { addPerformanceInstrumentationHandler, addClsInstrumentationHandler, addFidInstrumentationHandler, addTtfbInstrumentationHandler, addLcpInstrumentationHandler, addInpInstrumentationHandler, } from './metrics/instrument';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingWebVitals, startTrackingINP, registerInpInteractionListener, } from './metrics/browserMetrics';
export { addPerformanceEntries, startTrackingInteractions, startTrackingLongTasks, startTrackingLongAnimationFrames, startTrackingWebVitals, startTrackingINP, registerInpInteractionListener, } from './metrics/browserMetrics';
export { addClickKeypressInstrumentationHandler } from './instrument/dom';

@@ -4,0 +4,0 @@ export { addHistoryInstrumentationHandler } from './instrument/history';

@@ -14,2 +14,6 @@ import type { Span } from '@sentry/types';

/**
* Start tracking long animation frames.
*/
export declare function startTrackingLongAnimationFrames(): void;
/**
* Start tracking interaction events.

@@ -16,0 +20,0 @@ */

@@ -1,4 +0,1 @@

interface PartialRouteInfo {
name: string | undefined;
}
/**

@@ -8,5 +5,7 @@ * Start tracking INP webvital events.

export declare function startTrackingINP(): () => void;
/** Register a listener to cache route information for INP interactions. */
export declare function registerInpInteractionListener(latestRoute: PartialRouteInfo): void;
export {};
/**
* Register a listener to cache route information for INP interactions.
* TODO(v9): `latestRoute` no longer needs to be passed in and will be removed in v9.
*/
export declare function registerInpInteractionListener(_latestRoute?: unknown): void;
//# sourceMappingURL=inp.d.ts.map

@@ -17,2 +17,12 @@ type InstrumentHandlerTypePerformanceObserver = 'longtask' | 'event' | 'navigation' | 'paint' | 'resource' | 'first-input';

}
interface PerformanceScriptTiming extends PerformanceEntry {
sourceURL: string;
sourceFunctionName: string;
sourceCharPosition: number;
invoker: string;
invokerType: string;
}
export interface PerformanceLongAnimationFrameTiming extends PerformanceEntry {
scripts: PerformanceScriptTiming[];
}
interface Metric {

@@ -19,0 +29,0 @@ /**

{
"name": "@sentry-internal/browser-utils",
"version": "8.17.0",
"version": "8.18.0",
"description": "Browser Utilities for all Sentry JavaScript SDKs",

@@ -42,5 +42,5 @@ "repository": "git://github.com/getsentry/sentry-javascript.git",

"dependencies": {
"@sentry/core": "8.17.0",
"@sentry/types": "8.17.0",
"@sentry/utils": "8.17.0"
"@sentry/core": "8.18.0",
"@sentry/types": "8.18.0",
"@sentry/utils": "8.18.0"
},

@@ -47,0 +47,0 @@ "scripts": {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc