Skip to content

Commit 8aca02d

Browse files
authored
ref(browser): Move utils to @sentry-internal/browser-utils (#11451)
ref #9832 Building off #11381, this moves browser related utils into the browser utils package. Next step is to move `browserTracingIntegration` into browser!
1 parent a1e4efe commit 8aca02d

34 files changed

+105
-114
lines changed

packages/browser-utils/.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module.exports = {
22
extends: ['../../.eslintrc.js'],
3+
env: {
4+
browser: true,
5+
},
36
overrides: [
47
{
58
files: ['src/**'],

packages/browser-utils/src/browser/backgroundtab.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { SPAN_STATUS_ERROR, getActiveSpan, getRootSpan } from '@sentry/core';
22
import { spanToJSON } from '@sentry/core';
33
import { logger } from '@sentry/utils';
44

5-
import { DEBUG_BUILD } from '../common/debug-build';
5+
import { DEBUG_BUILD } from '../debug-build';
66
import { WINDOW } from './types';
77

88
/**

packages/browser-utils/src/browser/browserTracingIntegration.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,10 @@ import {
1616
} from '@sentry/core';
1717
import type { Client, IntegrationFn, StartSpanOptions, TransactionSource } from '@sentry/types';
1818
import type { Span } from '@sentry/types';
19-
import {
20-
addHistoryInstrumentationHandler,
21-
browserPerformanceTimeOrigin,
22-
getDomElement,
23-
logger,
24-
uuid4,
25-
} from '@sentry/utils';
26-
27-
import { DEBUG_BUILD } from '../common/debug-build';
19+
import { browserPerformanceTimeOrigin, getDomElement, logger, uuid4 } from '@sentry/utils';
20+
21+
import { DEBUG_BUILD } from '../debug-build';
22+
import { addHistoryInstrumentationHandler } from '../instrument/history';
2823
import { registerBackgroundTabDetection } from './backgroundtab';
2924
import {
3025
addPerformanceEntries,

packages/browser-utils/src/browser/instrument.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { getFunctionName, logger } from '@sentry/utils';
22

3-
import { DEBUG_BUILD } from '../common/debug-build';
3+
import { DEBUG_BUILD } from '../debug-build';
44
import { onCLS } from './web-vitals/getCLS';
55
import { onFID } from './web-vitals/getFID';
66
import { onLCP } from './web-vitals/getLCP';

packages/browser-utils/src/browser/metrics/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sent
55
import { browserPerformanceTimeOrigin, getComponentName, htmlTreeAsString, logger, parseUrl } from '@sentry/utils';
66

77
import { spanToJSON } from '@sentry/core';
8-
import { DEBUG_BUILD } from '../../common/debug-build';
8+
import { DEBUG_BUILD } from '../../debug-build';
99
import {
1010
addClsInstrumentationHandler,
1111
addFidInstrumentationHandler,

packages/browser-utils/src/browser/request.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,13 @@ import {
1616
import type { HandlerDataXhr, SentryWrappedXMLHttpRequest, Span } from '@sentry/types';
1717
import {
1818
BAGGAGE_HEADER_NAME,
19-
SENTRY_XHR_DATA_KEY,
2019
addFetchInstrumentationHandler,
21-
addXhrInstrumentationHandler,
2220
browserPerformanceTimeOrigin,
2321
dynamicSamplingContextToSentryBaggageHeader,
2422
generateSentryTraceHeader,
2523
stringMatchesSomePattern,
2624
} from '@sentry/utils';
25+
import { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler } from '../instrument/xhr';
2726

2827
import { addPerformanceInstrumentationHandler } from './instrument';
2928
import { WINDOW } from './types';

packages/browser-utils/src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,13 @@ export {
1212
addLcpInstrumentationHandler,
1313
} from './browser';
1414

15+
export { addClickKeypressInstrumentationHandler } from './instrument/dom';
16+
17+
export { addHistoryInstrumentationHandler } from './instrument/history';
18+
19+
export {
20+
addXhrInstrumentationHandler,
21+
SENTRY_XHR_DATA_KEY,
22+
} from './instrument/xhr';
23+
1524
export type { RequestInstrumentationOptions } from './browser';

packages/utils/src/instrument/dom.ts renamed to packages/browser-utils/src/instrument/dom.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
1-
// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages.
2-
3-
/* eslint-disable @typescript-eslint/no-explicit-any */
4-
/* eslint-disable @typescript-eslint/ban-types */
51
import type { HandlerDataDom } from '@sentry/types';
62

7-
import { uuid4 } from '../misc';
8-
import { addNonEnumerableProperty, fill } from '../object';
9-
import { GLOBAL_OBJ } from '../worldwide';
10-
import { addHandler, maybeInstrument, triggerHandlers } from './_handlers';
3+
import { addHandler, addNonEnumerableProperty, fill, maybeInstrument, triggerHandlers, uuid4 } from '@sentry/utils';
4+
import { WINDOW } from '../browser/types';
115

126
type SentryWrappedTarget = HTMLElement & { _sentryId?: string };
137

@@ -25,14 +19,13 @@ type RemoveEventListener = (
2519
type InstrumentedElement = Element & {
2620
__sentry_instrumentation_handlers__?: {
2721
[key in 'click' | 'keypress']?: {
28-
handler?: Function;
22+
handler?: unknown;
2923
/** The number of custom listeners attached to this element */
3024
refCount: number;
3125
};
3226
};
3327
};
3428

35-
const WINDOW = GLOBAL_OBJ as unknown as Window;
3629
const DEBOUNCE_DURATION = 1000;
3730

3831
let debounceTimerID: number | undefined;
@@ -71,7 +64,7 @@ export function instrumentDOM(): void {
7164
// could potentially prevent the event from bubbling up to our global listeners. This way, our handler are still
7265
// guaranteed to fire at least once.)
7366
['EventTarget', 'Node'].forEach((target: string) => {
74-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
67+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
7568
const proto = (WINDOW as any)[target] && (WINDOW as any)[target].prototype;
7669
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, no-prototype-builtins
7770
if (!proto || !proto.hasOwnProperty || !proto.hasOwnProperty('addEventListener')) {

packages/utils/src/instrument/history.ts renamed to packages/browser-utils/src/instrument/history.ts

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,6 @@
1-
// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages.
2-
3-
/* eslint-disable @typescript-eslint/no-explicit-any */
4-
/* eslint-disable @typescript-eslint/ban-types */
51
import type { HandlerDataHistory } from '@sentry/types';
6-
7-
import { fill } from '../object';
8-
import { supportsHistory } from '../supports';
9-
import { GLOBAL_OBJ } from '../worldwide';
10-
import { addHandler, maybeInstrument, triggerHandlers } from './_handlers';
11-
12-
const WINDOW = GLOBAL_OBJ as unknown as Window;
2+
import { addHandler, fill, maybeInstrument, supportsHistory, triggerHandlers } from '@sentry/utils';
3+
import { WINDOW } from '../browser/types';
134

145
let lastHref: string | undefined;
156

@@ -33,7 +24,7 @@ function instrumentHistory(): void {
3324
}
3425

3526
const oldOnPopState = WINDOW.onpopstate;
36-
WINDOW.onpopstate = function (this: WindowEventHandlers, ...args: any[]): any {
27+
WINDOW.onpopstate = function (this: WindowEventHandlers, ...args: unknown[]) {
3728
const to = WINDOW.location.href;
3829
// keep track of the current URL state, as we always receive only the updated state
3930
const from = lastHref;
@@ -53,7 +44,7 @@ function instrumentHistory(): void {
5344
};
5445

5546
function historyReplacementFunction(originalHistoryFunction: () => void): () => void {
56-
return function (this: History, ...args: any[]): void {
47+
return function (this: History, ...args: unknown[]): void {
5748
const url = args.length > 2 ? args[2] : undefined;
5849
if (url) {
5950
// coerce to string (this is what pushState does)

packages/utils/src/instrument/xhr.ts renamed to packages/browser-utils/src/instrument/xhr.ts

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
1-
// TODO(v8): Move everything in this file into the browser package. Nothing here is generic and we run risk of leaking browser types into non-browser packages.
2-
3-
/* eslint-disable @typescript-eslint/no-explicit-any */
4-
/* eslint-disable @typescript-eslint/ban-types */
51
import type { HandlerDataXhr, SentryWrappedXMLHttpRequest, WrappedFunction } from '@sentry/types';
62

7-
import { isString } from '../is';
8-
import { fill } from '../object';
9-
import { GLOBAL_OBJ } from '../worldwide';
10-
import { addHandler, maybeInstrument, triggerHandlers } from './_handlers';
11-
12-
const WINDOW = GLOBAL_OBJ as unknown as Window;
3+
import { addHandler, fill, isString, maybeInstrument, triggerHandlers } from '@sentry/utils';
4+
import { WINDOW } from '../browser/types';
135

146
export const SENTRY_XHR_DATA_KEY = '__sentry_xhr_v3__';
157

8+
type WindowWithXhr = Window & { XMLHttpRequest?: typeof XMLHttpRequest };
9+
1610
/**
1711
* Add an instrumentation handler for when an XHR request happens.
1812
* The handler function is called once when the request starts and once when it ends,
@@ -29,15 +23,14 @@ export function addXhrInstrumentationHandler(handler: (data: HandlerDataXhr) =>
2923

3024
/** Exported only for tests. */
3125
export function instrumentXHR(): void {
32-
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
33-
if (!(WINDOW as any).XMLHttpRequest) {
26+
if (!(WINDOW as WindowWithXhr).XMLHttpRequest) {
3427
return;
3528
}
3629

3730
const xhrproto = XMLHttpRequest.prototype;
3831

3932
fill(xhrproto, 'open', function (originalOpen: () => void): () => void {
40-
return function (this: XMLHttpRequest & SentryWrappedXMLHttpRequest, ...args: any[]): void {
33+
return function (this: XMLHttpRequest & SentryWrappedXMLHttpRequest, ...args: unknown[]): void {
4134
const startTimestamp = Date.now();
4235

4336
// open() should always be called with two or more arguments
@@ -87,8 +80,8 @@ export function instrumentXHR(): void {
8780
};
8881

8982
if ('onreadystatechange' in this && typeof this.onreadystatechange === 'function') {
90-
fill(this, 'onreadystatechange', function (original: WrappedFunction): Function {
91-
return function (this: SentryWrappedXMLHttpRequest, ...readyStateArgs: any[]): void {
83+
fill(this, 'onreadystatechange', function (original: WrappedFunction) {
84+
return function (this: SentryWrappedXMLHttpRequest, ...readyStateArgs: unknown[]): void {
9285
onreadystatechangeHandler();
9386
return original.apply(this, readyStateArgs);
9487
};
@@ -100,7 +93,7 @@ export function instrumentXHR(): void {
10093
// Intercepting `setRequestHeader` to access the request headers of XHR instance.
10194
// This will only work for user/library defined headers, not for the default/browser-assigned headers.
10295
// Request cookies are also unavailable for XHR, as `Cookie` header can't be defined by `setRequestHeader`.
103-
fill(this, 'setRequestHeader', function (original: WrappedFunction): Function {
96+
fill(this, 'setRequestHeader', function (original: WrappedFunction) {
10497
return function (this: SentryWrappedXMLHttpRequest, ...setRequestHeaderArgs: unknown[]): void {
10598
const [header, value] = setRequestHeaderArgs;
10699

@@ -119,7 +112,7 @@ export function instrumentXHR(): void {
119112
});
120113

121114
fill(xhrproto, 'send', function (originalSend: () => void): () => void {
122-
return function (this: XMLHttpRequest & SentryWrappedXMLHttpRequest, ...args: any[]): void {
115+
return function (this: XMLHttpRequest & SentryWrappedXMLHttpRequest, ...args: unknown[]): void {
123116
const sentryXhrData = this[SENTRY_XHR_DATA_KEY];
124117

125118
if (!sentryXhrData) {

packages/browser-utils/test/browser/request.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
/* eslint-disable deprecation/deprecation */
21
import * as utils from '@sentry/utils';
32

3+
import * as xhrInstrumentation from '../../src/instrument/xhr';
4+
45
import { extractNetworkProtocol, instrumentOutgoingRequests, shouldAttachHeaders } from '../../src/browser/request';
56
import { WINDOW } from '../../src/browser/types';
67

@@ -17,7 +18,7 @@ describe('instrumentOutgoingRequests', () => {
1718

1819
it('instruments fetch and xhr requests', () => {
1920
const addFetchSpy = jest.spyOn(utils, 'addFetchInstrumentationHandler');
20-
const addXhrSpy = jest.spyOn(utils, 'addXhrInstrumentationHandler');
21+
const addXhrSpy = jest.spyOn(xhrInstrumentation, 'addXhrInstrumentationHandler');
2122

2223
instrumentOutgoingRequests();
2324

@@ -34,7 +35,7 @@ describe('instrumentOutgoingRequests', () => {
3435
});
3536

3637
it('does not instrument xhr requests if traceXHR is false', () => {
37-
const addXhrSpy = jest.spyOn(utils, 'addXhrInstrumentationHandler');
38+
const addXhrSpy = jest.spyOn(xhrInstrumentation, 'addXhrInstrumentationHandler');
3839

3940
instrumentOutgoingRequests({ traceXHR: false });
4041

packages/utils/test/instrument/dom.test.ts renamed to packages/browser-utils/test/instrument/dom.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { instrumentDOM } from '../../src/instrument/dom';
22

3-
jest.mock('../../src/worldwide', () => {
4-
const original = jest.requireActual('../../src/worldwide');
3+
jest.mock('@sentry/utils', () => {
4+
const original = jest.requireActual('@sentry/utils');
55

66
return {
77
...original,

packages/utils/test/instrument/xhr.test.ts renamed to packages/browser-utils/test/instrument/xhr.test.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { instrumentXHR } from '../../src/instrument/xhr';
22

3-
jest.mock('../../src/worldwide', () => {
4-
const original = jest.requireActual('../../src/worldwide');
5-
3+
jest.mock('@sentry/utils', () => {
4+
const original = jest.requireActual('@sentry/utils');
65
return {
76
...original,
87
GLOBAL_OBJ: {

packages/browser/src/integrations/breadcrumbs.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
1+
import {
2+
SENTRY_XHR_DATA_KEY,
3+
addClickKeypressInstrumentationHandler,
4+
addHistoryInstrumentationHandler,
5+
addXhrInstrumentationHandler,
6+
} from '@sentry-internal/browser-utils';
17
import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core';
28
import type {
9+
Breadcrumb,
310
Client,
411
Event as SentryEvent,
12+
FetchBreadcrumbData,
13+
FetchBreadcrumbHint,
514
HandlerDataConsole,
615
HandlerDataDom,
716
HandlerDataFetch,
817
HandlerDataHistory,
918
HandlerDataXhr,
1019
IntegrationFn,
11-
} from '@sentry/types';
12-
import type {
13-
Breadcrumb,
14-
FetchBreadcrumbData,
15-
FetchBreadcrumbHint,
1620
XhrBreadcrumbData,
1721
XhrBreadcrumbHint,
18-
} from '@sentry/types/build/types/breadcrumb';
22+
} from '@sentry/types';
1923
import {
20-
SENTRY_XHR_DATA_KEY,
21-
addClickKeypressInstrumentationHandler,
2224
addConsoleInstrumentationHandler,
2325
addFetchInstrumentationHandler,
24-
addHistoryInstrumentationHandler,
25-
addXhrInstrumentationHandler,
2626
getComponentName,
2727
getEventDescription,
2828
htmlTreeAsString,

packages/browser/src/integrations/httpclient.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1+
import { SENTRY_XHR_DATA_KEY, addXhrInstrumentationHandler } from '@sentry-internal/browser-utils';
12
import { captureEvent, defineIntegration, getClient, isSentryRequestUrl } from '@sentry/core';
23
import type { Client, Event as SentryEvent, IntegrationFn, SentryWrappedXMLHttpRequest } from '@sentry/types';
34
import {
45
GLOBAL_OBJ,
5-
SENTRY_XHR_DATA_KEY,
66
addExceptionMechanism,
77
addFetchInstrumentationHandler,
8-
addXhrInstrumentationHandler,
98
logger,
109
supportsNativeFetch,
1110
} from '@sentry/utils';

packages/browser/src/profiling/integration.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { defineIntegration, getActiveSpan, getRootSpan } from '@sentry/core';
2-
import type { EventEnvelope, IntegrationFn, Span } from '@sentry/types';
3-
import type { Profile } from '@sentry/types/src/profiling';
2+
import type { EventEnvelope, IntegrationFn, Profile, Span } from '@sentry/types';
43
import { logger } from '@sentry/utils';
54

65
import { DEBUG_BUILD } from '../debug-build';

packages/browser/src/profiling/utils.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
/* eslint-disable max-lines */
22

33
import { DEFAULT_ENVIRONMENT, getClient, spanToJSON } from '@sentry/core';
4-
import type { DebugImage, Envelope, Event, EventEnvelope, Span, StackFrame, StackParser } from '@sentry/types';
5-
import type { Profile, ThreadCpuProfile } from '@sentry/types/src/profiling';
4+
import type {
5+
DebugImage,
6+
Envelope,
7+
Event,
8+
EventEnvelope,
9+
Profile,
10+
Span,
11+
StackFrame,
12+
StackParser,
13+
ThreadCpuProfile,
14+
} from '@sentry/types';
615
import { GLOBAL_OBJ, browserPerformanceTimeOrigin, forEachEnvelopeItem, logger, uuid4 } from '@sentry/utils';
716

817
import { DEBUG_BUILD } from '../debug-build';

packages/browser/src/sdk.ts

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,9 @@ import {
99
startSession,
1010
} from '@sentry/core';
1111
import type { DsnLike, Integration, Options, UserFeedback } from '@sentry/types';
12-
import {
13-
addHistoryInstrumentationHandler,
14-
consoleSandbox,
15-
logger,
16-
stackParserFromStackParserOptions,
17-
supportsFetch,
18-
} from '@sentry/utils';
12+
import { consoleSandbox, logger, stackParserFromStackParserOptions, supportsFetch } from '@sentry/utils';
1913

14+
import { addHistoryInstrumentationHandler } from '@sentry-internal/browser-utils';
2015
import { dedupeIntegration } from '@sentry/core';
2116
import type { BrowserClientOptions, BrowserOptions } from './client';
2217
import { BrowserClient } from './client';

packages/deno/src/integrations/breadcrumbs.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core';
2-
import type { Client, Event as SentryEvent, HandlerDataConsole, HandlerDataFetch, IntegrationFn } from '@sentry/types';
3-
import type { FetchBreadcrumbData, FetchBreadcrumbHint } from '@sentry/types/build/types/breadcrumb';
2+
import type {
3+
Client,
4+
Event as SentryEvent,
5+
FetchBreadcrumbData,
6+
FetchBreadcrumbHint,
7+
HandlerDataConsole,
8+
HandlerDataFetch,
9+
IntegrationFn,
10+
} from '@sentry/types';
411
import {
512
addConsoleInstrumentationHandler,
613
addFetchInstrumentationHandler,

0 commit comments

Comments
 (0)