Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/browser-core/src/browser/addEventListener.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { CookieStore, CookieStoreEventMap } from '@datadog/js-core/util'
import { monitor } from '../tools/monitor'
import { monitor } from '@datadog/js-core/monitor'
import { getZoneJsOriginalValue } from '../tools/getZoneJsOriginalValue'
import { noop } from '../tools/utils/functionUtils'
import type { VisualViewport, VisualViewportEventMap } from './browser.types'
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-core/src/browser/fetchObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { ClocksState } from '@datadog/js-core/time'
import { clocksNow } from '@datadog/js-core/time'
import { normalizeUrl, globalObject } from '@datadog/js-core/util'
import type { GlobalObject } from '@datadog/js-core/util'
import { monitorError } from '@datadog/js-core/monitor'
import type { InstrumentedMethodCall } from '../tools/instrumentMethod'
import { instrumentMethod } from '../tools/instrumentMethod'
import { monitorError } from '../tools/monitor'
import { Observable } from '../tools/observable'
import { readBytesFromStream } from '../tools/readBytesFromStream'
import { tryToClone } from '../tools/utils/responseUtils'
Expand Down
21 changes: 4 additions & 17 deletions packages/browser-core/src/browser/pageMayExitObservable.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
import { globalObject } from '@datadog/js-core/util'
import { PageExitReason } from '@datadog/js-core/transport'
import type { PageMayExitEvent } from '@datadog/js-core/transport'
import { Observable } from '../tools/observable'
import { objectValues } from '../tools/utils/polyfills'
import { addEventListeners, addEventListener, DOM_EVENT } from './addEventListener'

export const PageExitReason = {
HIDDEN: 'visibility_hidden',
UNLOADING: 'before_unload',
PAGEHIDE: 'page_hide',
FROZEN: 'page_frozen',
} as const

export type PageExitReason = (typeof PageExitReason)[keyof typeof PageExitReason]

export interface PageMayExitEvent {
reason: PageExitReason
}
export { PageExitReason, isPageExitReason } from '@datadog/js-core/transport'
export type { PageMayExitEvent } from '@datadog/js-core/transport'

export function createPageMayExitObservable(): Observable<PageMayExitEvent> {
return new Observable<PageMayExitEvent>((observable) => {
Expand Down Expand Up @@ -54,7 +45,3 @@ export function createPageMayExitObservable(): Observable<PageMayExitEvent> {
}
})
}

export function isPageExitReason(reason: string): reason is PageExitReason {
return objectValues(PageExitReason).includes(reason as PageExitReason)
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { clocksNow } from '@datadog/js-core/time'
import { ConsoleApiName, globalConsole } from '@datadog/js-core/util'
import { callMonitored } from '@datadog/js-core/monitor'
import { isError, computeRawError } from '../error/error'
import { Observable, mergeObservables } from '../../tools/observable'
import { callMonitored } from '../../tools/monitor'
import { sanitize } from '../../tools/serialisation/sanitize'
import { jsonStringify } from '../../tools/serialisation/jsonStringify'
import type { RawError } from '../error/error.types'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { monitor } from '@datadog/js-core/monitor'
import type { RawTelemetryUsage, RawTelemetryUsageFeature } from '../telemetry'
import { addTelemetryUsage } from '../telemetry'
import { monitor } from '../../tools/monitor'
import type { BufferedObservable } from '../../tools/observable'
import type { ContextManager } from './contextManager'
import type { ContextManagerMethod, CustomerContextKey } from './contextConstants'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { clocksNow } from '@datadog/js-core/time'
import { monitor } from '@datadog/js-core/monitor'
import { toStackTraceString } from '../../tools/stackTrace/handlingStack'
import { monitor } from '../../tools/monitor'
import { mergeObservables, Observable } from '../../tools/observable'
import { addEventListener, DOM_EVENT, isEventSupported } from '../../browser/addEventListener'
import { safeTruncate } from '../../tools/utils/stringUtils'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
} from '@datadog/js-core/time'
import type { TimeStamp, RelativeTime } from '@datadog/js-core/time'
import { isWorkerEnvironment } from '@datadog/js-core/util'
import { monitorError } from '@datadog/js-core/monitor'
import { Observable } from '../../tools/observable'
import { createValueHistory } from '../../tools/valueHistory'
import { addEventListener, addEventListeners, DOM_EVENT } from '../../browser/addEventListener'
Expand All @@ -22,7 +23,6 @@ import type { TrackingConsentState } from '../trackingConsent'
import { display } from '../../tools/display'
import { isSampled } from '../sampler'
import { TelemetryMetrics, addTelemetryMetrics } from '../telemetry'
import { monitorError } from '../../tools/monitor'
import type { SessionState } from './sessionState'
import {
expandOnly,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { monitorError } from '@datadog/js-core/monitor'
import { isEmptyObject } from '../../../tools/utils/objectUtils'
import type { CookieOptions } from '../../../browser/cookie'
import { getCookies } from '../../../browser/cookie'
Expand All @@ -8,7 +9,6 @@ import type { SessionState } from '../sessionState'
import { toSessionString, toSessionState } from '../sessionState'
import { Observable } from '../../../tools/observable'
import { mockable } from '../../../tools/mockable'
import { monitorError } from '../../../tools/monitor'
import type { CookieAccess } from '../../../browser/cookieAccess'
import {
areCookiesAuthorized,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createHook } from '@datadog/js-core/assembly'
import { INTAKE_SITE_US1_FED, INTAKE_SITE_US2_FED, INTAKE_SITE_US1 } from '@datadog/js-core/transport'
import { callMonitored } from '@datadog/js-core/monitor'
import { NO_ERROR_STACK_PRESENT_MESSAGE } from '../error/error'
import { callMonitored } from '../../tools/monitor'
import type { ExperimentalFeature } from '../../tools/experimentalFeatures'
import { addExperimentalFeatures } from '../../tools/experimentalFeatures'
import { type Configuration } from '../configuration'
Expand Down
2 changes: 1 addition & 1 deletion packages/browser-core/src/domain/telemetry/telemetry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import {
INTAKE_SITE_US1_FED,
INTAKE_SITE_US2_FED,
} from '@datadog/js-core/transport'
import { startMonitorErrorCollection } from '@datadog/js-core/monitor'
import type { Context } from '../../tools/serialisation/context'
import { NO_ERROR_STACK_PRESENT_MESSAGE, isError } from '../error/isError'
import { toStackTraceString } from '../../tools/stackTrace/handlingStack'
import { getExperimentalFeatures } from '../../tools/experimentalFeatures'
import type { Configuration } from '../configuration'
import { buildTags } from '../tags'
import { BufferedObservable, Observable } from '../../tools/observable'
import { startMonitorErrorCollection } from '../../tools/monitor'
import { display } from '../../tools/display'
import { sendToExtension } from '../../tools/sendToExtension'
import { jsonStringify } from '../../tools/serialisation/jsonStringify'
Expand Down
2 changes: 0 additions & 2 deletions packages/browser-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export {
addTelemetryUsage,
addTelemetryMetrics,
} from './domain/telemetry'
export { monitored, monitor, callMonitored, monitorError } from './tools/monitor'
export type { Subscription } from './tools/observable'
export { Observable, BufferedObservable } from './tools/observable'
export type { SessionManager, SessionContext } from './domain/session/sessionManager'
Expand Down Expand Up @@ -72,7 +71,6 @@ export {
bridgeSupports,
BridgeCapability,
createBatch,
createFlushController,
FLUSH_DURATION_LIMIT,
} from './transport'
export * from './tools/display'
Expand Down
105 changes: 2 additions & 103 deletions packages/browser-core/src/tools/encoder.ts
Original file line number Diff line number Diff line change
@@ -1,103 +1,2 @@
import type { Uint8ArrayBuffer } from './utils/byteUtils'
import { computeBytesCount } from './utils/byteUtils'

export interface Encoder<Output extends string | Uint8ArrayBuffer = string | Uint8ArrayBuffer> {
/**
* Whether this encoder might call the provided callbacks asynchronously
*/
isAsync: boolean

/**
* Whether some data has been written since the last finish() or finishSync() call
*/
isEmpty: boolean

/**
* Write a string to be encoded.
*
* This operation can be synchronous or asynchronous depending on the encoder implementation.
*
* If specified, the callback will be invoked when the operation finishes, unless the operation is
* asynchronous and finish() or finishSync() is called in the meantime.
*/
write(data: string, callback?: (additionalEncodedBytesCount: number) => void): void

/**
* Waits for pending data to be encoded and resets the encoder state.
*
* This operation can be synchronous or asynchronous depending on the encoder implementation.
*
* The callback will be invoked when the operation finishes, unless the operation is asynchronous
* and another call to finish() or finishSync() occurs in the meantime.
*/
finish(callback: (result: EncoderResult<Output>) => void): void

/**
* Resets the encoder state then returns the encoded data and any potential pending data directly,
* discarding all pending write operations and finish() callbacks.
*/
finishSync(): EncoderResult<Output> & { pendingData: string }

/**
* Returns a rough estimation of the bytes count if the data was encoded.
*/
estimateEncodedBytesCount(data: string): number
}

export interface EncoderResult<Output extends string | Uint8ArrayBuffer = string | Uint8ArrayBuffer> {
output: Output
outputBytesCount: number

/**
* An encoding type supported by HTTP Content-Encoding, if applicable.
* See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding#directives
*/
encoding?: 'deflate'

/**
* Total bytes count of the input strings encoded to UTF-8.
*/
rawBytesCount: number
}

export function createIdentityEncoder(): Encoder<string> {
let output = ''
let outputBytesCount = 0

return {
isAsync: false,

get isEmpty() {
return !output
},

write(data, callback) {
const additionalEncodedBytesCount = computeBytesCount(data)
outputBytesCount += additionalEncodedBytesCount
output += data
if (callback) {
callback(additionalEncodedBytesCount)
}
},

finish(callback) {
callback(this.finishSync())
},

finishSync() {
const result = {
output,
outputBytesCount,
rawBytesCount: outputBytesCount,
pendingData: '',
}
output = ''
outputBytesCount = 0
return result
},

estimateEncodedBytesCount(data) {
return data.length
},
}
}
export type { Encoder, EncoderResult } from '@datadog/js-core/transport'
export { createIdentityEncoder } from '@datadog/js-core/transport'
40 changes: 2 additions & 38 deletions packages/browser-core/src/tools/getZoneJsOriginalValue.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,2 @@
import { globalObject } from '@datadog/js-core/util'

export interface BrowserWindowWithZoneJs {
Zone?: {
// All Zone.js versions expose the __symbol__ method, but we observed that some website have a
// 'Zone' global variable unrelated to Zone.js, so let's consider this method optional
// nonetheless.
__symbol__?: (name: string) => string
}
}

/**
* Gets the original value for a DOM API that was potentially patched by Zone.js.
*
* Zone.js[1] is a library that patches a bunch of JS and DOM APIs. It usually stores the original
* value of the patched functions/constructors/methods in a hidden property prefixed by
* __zone_symbol__.
*
* In multiple occasions, we observed that Zone.js is the culprit of important issues leading to
* browser resource exhaustion (memory leak, high CPU usage). This method is used as a workaround to
* use the original DOM API instead of the one patched by Zone.js.
*
* [1]: https://github.com/angular/angular/tree/main/packages/zone.js
*/
export function getZoneJsOriginalValue<Target, Name extends keyof Target & string>(
target: Target,
name: Name
): Target[Name] {
const browserWindow = globalObject as BrowserWindowWithZoneJs
let original: Target[Name] | undefined
if (browserWindow.Zone && typeof browserWindow.Zone.__symbol__ === 'function') {
original = (target as any)[browserWindow.Zone.__symbol__(name)]
}
if (!original) {
original = target[name]
}
return original
}
export type { BrowserWindowWithZoneJs } from '@datadog/js-core/util'
export { getZoneJsOriginalValue } from '@datadog/js-core/util'
2 changes: 1 addition & 1 deletion packages/browser-core/src/tools/instrumentMethod.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { callMonitored } from '@datadog/js-core/monitor'
import { setTimeout } from './timer'
import { callMonitored } from './monitor'
import { noop } from './utils/functionUtils'
import { createHandlingStack } from './stackTrace/handlingStack'

Expand Down
33 changes: 1 addition & 32 deletions packages/browser-core/src/tools/mockable.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1 @@
declare const __BUILD_ENV__SDK_VERSION__: string

export const mockableReplacements = new Map<unknown, unknown>()

/**
* Wraps a value to make it mockable in tests. In production builds, this is a no-op
* that returns the value as-is. In test builds, it checks if a mock replacement has
* been registered and returns that instead.
*
* @example
* // In source file:
* import { mockable } from '../tools/mockable'
* export function formatNavigationEntry(): string {
* const navigationEntry = mockable(getNavigationEntry)()
* ...
* }
*
* // In test file:
* import { replaceMockable } from '@datadog/browser-core/test'
* it('...', () => {
* replaceMockable(getNavigationEntry, () => FAKE_NAVIGATION_ENTRY)
* expect(formatNavigationEntry()).toEqual(...)
* })
*/
export function mockable<T>(value: T): T {
// In test builds, return a wrapper that checks for mocks at call time
if (__BUILD_ENV__SDK_VERSION__ === 'test' && mockableReplacements.has(value)) {
return mockableReplacements.get(value)! as T
}
// In production, return the value as-is
return value
}
export { mockable, mockableReplacements } from '@datadog/js-core/util'
29 changes: 0 additions & 29 deletions packages/browser-core/src/tools/monitor.spec.ts

This file was deleted.

24 changes: 0 additions & 24 deletions packages/browser-core/src/tools/monitor.ts

This file was deleted.

Loading
Loading