diff --git a/developer-extension/package.json b/developer-extension/package.json index 52765b79b9..067033950b 100644 --- a/developer-extension/package.json +++ b/developer-extension/package.json @@ -19,6 +19,7 @@ "@datadog/browser-logs": "workspace:*", "@datadog/browser-rum": "workspace:*", "@datadog/browser-rum-core": "workspace:*", + "@datadog/js-core": "workspace:*", "@mantine/core": "9.3.2", "@mantine/hooks": "9.3.2", "@tabler/icons-react": "3.44.0", diff --git a/developer-extension/src/panel/components/tabs/eventsTab/copyEvent.ts b/developer-extension/src/panel/components/tabs/eventsTab/copyEvent.ts index 16cf10efca..1790122135 100644 --- a/developer-extension/src/panel/components/tabs/eventsTab/copyEvent.ts +++ b/developer-extension/src/panel/components/tabs/eventsTab/copyEvent.ts @@ -1,5 +1,5 @@ -import type { EndpointBuilder } from '@datadog/browser-core' -import { createEndpointBuilder } from '../../../../../../packages/browser-core/src/domain/configuration' +import type { EndpointBuilder } from '@datadog/js-core/transport' +import { createEndpointBuilder } from '@datadog/js-core/transport' import { copy } from '../../../copy' import type { SdkInfos } from '../../../hooks/useSdkInfos' import type { SdkEvent } from '../../../sdkEvent' @@ -89,6 +89,6 @@ export function getIntakeUrlForEvent(sdkInfos: SdkInfos, event: SdkEvent) { } return builder - .build('manual', { data: 'a', bytesCount: 1 }) + .build('manual', {}) .replace(/dd-evp-origin-version=[^&]+/g, `dd-evp-origin-version=${encodeURIComponent(version)}`) } diff --git a/eslint-local-rules/disallowSideEffects.ts b/eslint-local-rules/disallowSideEffects.ts index 659c16b9d9..720442324d 100644 --- a/eslint-local-rules/disallowSideEffects.ts +++ b/eslint-local-rules/disallowSideEffects.ts @@ -49,6 +49,7 @@ const packagesWithoutSideEffect = new Set([ '@datadog/js-core/time', '@datadog/js-core/util', '@datadog/js-core/monitor', + '@datadog/js-core/transport', '@datadog/browser-core', '@datadog/browser-rum-core', '@datadog/browser-rum-react/internal', diff --git a/eslint-local-rules/disallowUrlConstructorPatchValues.ts b/eslint-local-rules/disallowUrlConstructorPatchValues.ts index 911cfdd7d5..f33abf2b81 100644 --- a/eslint-local-rules/disallowUrlConstructorPatchValues.ts +++ b/eslint-local-rules/disallowUrlConstructorPatchValues.ts @@ -8,7 +8,7 @@ export default RuleCreator.withoutDocs({ }, schema: [], messages: { - patchedUrlConstructor: 'This value might be patched. Use `buildUrl` from @datadog/browser-core instead', + patchedUrlConstructor: 'This value might be patched. Use `buildUrl` from @datadog/js-core/util instead', }, type: 'suggestion', }, diff --git a/eslint.config.ts b/eslint.config.ts index 61566234f5..146b6948b2 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -22,7 +22,7 @@ const MONITOR_UNTIL_COMMENT_EXPIRED_LEVEL = const PACKAGES_NO_RESTRICTED_SYNTAX_RULES = [ { selector: 'Identifier[name="globalThis"]', - message: 'Use `globalObject` from @datadog/browser-core instead of `globalThis`.', + message: 'Use `globalObject` from @datadog/js-core/util instead of `globalThis`.', }, ] diff --git a/packages/browser-core/src/browser/addEventListener.ts b/packages/browser-core/src/browser/addEventListener.ts index 1fca98d267..6c0b9481fd 100644 --- a/packages/browser-core/src/browser/addEventListener.ts +++ b/packages/browser-core/src/browser/addEventListener.ts @@ -1,7 +1,8 @@ +import type { CookieStore, CookieStoreEventMap } from '@datadog/js-core/util' import { monitor } from '../tools/monitor' import { getZoneJsOriginalValue } from '../tools/getZoneJsOriginalValue' import { noop } from '../tools/utils/functionUtils' -import type { CookieStore, CookieStoreEventMap, VisualViewport, VisualViewportEventMap } from './browser.types' +import type { VisualViewport, VisualViewportEventMap } from './browser.types' export type TrustableEvent = E & { __ddIsTrusted?: boolean } diff --git a/packages/browser-core/src/browser/browser.types.ts b/packages/browser-core/src/browser/browser.types.ts index bfca38839e..45a076d3d5 100644 --- a/packages/browser-core/src/browser/browser.types.ts +++ b/packages/browser-core/src/browser/browser.types.ts @@ -50,147 +50,3 @@ export interface WeakRefConstructor { new (target: T): WeakRef } - -export interface CookieStoreItem { - name: string - value: string - domain?: string - path?: string - expires?: number - secure?: boolean - sameSite?: 'strict' | 'lax' | 'none' - partitioned?: boolean -} - -export interface CookieStore extends EventTarget { - get(name: string): Promise - getAll(name?: string): Promise - set(options: { - name: string - value: string - expires?: number | Date - domain?: string - path?: string - secure?: boolean - sameSite?: 'strict' | 'lax' | 'none' - partitioned?: boolean - }): Promise - delete(options: { name: string; domain?: string; path?: string; partitioned?: boolean }): Promise -} - -export interface CookieStoreEventMap { - change: CookieChangeEvent -} - -export interface CookieChangeItem { - name: string - value: string | undefined -} - -export type CookieChangeEvent = Event & { - changed: CookieChangeItem[] - deleted: CookieChangeItem[] -} - -export type NetworkInterface = 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown' -export type EffectiveType = 'slow-2g' | '2g' | '3g' | '4g' - -export interface BrowserNavigator extends Navigator { - connection?: NetworkInformation -} - -export interface NetworkInformation { - type?: NetworkInterface - effectiveType?: EffectiveType - saveData: boolean -} - -// Types for the JS Self-Profiling API -// https://wicg.github.io/js-self-profiling/ - -export interface ProfilerFrame { - /** A function instance name. */ - readonly name: string - /** Index in the trace.resources array. */ - readonly resourceId?: number - /** 1-based index of the line. */ - readonly line?: number - /** 1-based index of the column. */ - readonly column?: number -} - -export interface ProfilerStack { - /** Index in the trace.stacks array. */ - readonly parentId?: number - /** Index in the trace.frames array. */ - readonly frameId: number -} - -export interface ProfilerSample { - /** High resolution time relative to the profiling session's time origin. */ - readonly timestamp: number - /** Index in the trace.stacks array. */ - readonly stackId?: number -} - -export type ProfilerResource = string - -export interface ProfilerTrace { - /** An array of profiler resources. */ - readonly resources: ProfilerResource[] - /** An array of profiler frames. */ - readonly frames: ProfilerFrame[] - /** An array of profiler stacks. */ - readonly stacks: ProfilerStack[] - /** An array of profiler samples. */ - readonly samples: ProfilerSample[] -} - -export interface ProfilerInitOptions { - /** Sample interval in ms. */ - readonly sampleInterval: number - /** Max buffer size in number of samples. */ - readonly maxBufferSize: number -} - -export interface ProfilerConstructor { - new (options: ProfilerInitOptions): Profiler -} - -export interface Profiler extends EventTarget { - /** Sample interval in ms. */ - readonly sampleInterval: number - /** True if profiler is stopped. */ - readonly stopped: boolean - - stop(): Promise - - addEventListener( - type: K, - listener: (ev: ProfilerEventMap[K]) => any, - options?: boolean | AddEventListenerOptions - ): void - addEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | AddEventListenerOptions - ): void - removeEventListener( - type: K, - listener: (ev: ProfilerEventMap[K]) => any, - options?: boolean | EventListenerOptions - ): void - removeEventListener( - type: string, - listener: EventListenerOrEventListenerObject, - options?: boolean | EventListenerOptions - ): void -} - -interface ProfilerEventMap { - samplebufferfull: SampleBufferFullEvent -} - -export interface SampleBufferFullEvent extends Event { - readonly target: Profiler -} diff --git a/packages/browser-core/src/browser/cookie.ts b/packages/browser-core/src/browser/cookie.ts index a9e6392791..3851782b36 100644 --- a/packages/browser-core/src/browser/cookie.ts +++ b/packages/browser-core/src/browser/cookie.ts @@ -1,12 +1,11 @@ import { ONE_SECOND } from '@datadog/js-core/time' +import { buildUrl, globalObject } from '@datadog/js-core/util' import { findAllCommaSeparatedValues, findCommaSeparatedValue, findCommaSeparatedValues, generateUUID, } from '../tools/utils/stringUtils' -import { buildUrl } from '../tools/utils/urlPolyfill' -import { globalObject } from '../tools/globalObject' export interface CookieOptions { secure?: boolean diff --git a/packages/browser-core/src/browser/cookieAccess.spec.ts b/packages/browser-core/src/browser/cookieAccess.spec.ts index f05c080b63..7d508994bc 100644 --- a/packages/browser-core/src/browser/cookieAccess.spec.ts +++ b/packages/browser-core/src/browser/cookieAccess.spec.ts @@ -1,8 +1,8 @@ import { ONE_MINUTE, dateNow } from '@datadog/js-core/time' +import { globalObject } from '@datadog/js-core/util' import type { Clock } from '../../test' import { collectAsyncCalls, mockClock, registerCleanupTask, replaceMockable } from '../../test' import { display } from '../tools/display' -import { globalObject } from '../tools/globalObject' import { detectVersion, isChromium } from '../tools/utils/browserDetection' import type { CookieOptions } from './cookie' import { deleteCookie, getCookie, setCookie } from './cookie' diff --git a/packages/browser-core/src/browser/cookieAccess.ts b/packages/browser-core/src/browser/cookieAccess.ts index 492151f63e..6b64f48443 100644 --- a/packages/browser-core/src/browser/cookieAccess.ts +++ b/packages/browser-core/src/browser/cookieAccess.ts @@ -1,11 +1,11 @@ import { ONE_MINUTE, ONE_SECOND, dateNow } from '@datadog/js-core/time' +import { globalObject } from '@datadog/js-core/util' import { setInterval, clearInterval } from '../tools/timer' import { Observable } from '../tools/observable' import { mockable } from '../tools/mockable' import { display } from '../tools/display' import { generateUUID } from '../tools/utils/stringUtils' import { addTelemetryDebug } from '../domain/telemetry' -import { globalObject } from '../tools/globalObject' import { addEventListener, DOM_EVENT, isEventSupported } from './addEventListener' import { getCookies, setCookie } from './cookie' import type { CookieOptions } from './cookie' diff --git a/packages/browser-core/src/browser/fetch.ts b/packages/browser-core/src/browser/fetch.ts index f344110529..614be626ef 100644 --- a/packages/browser-core/src/browser/fetch.ts +++ b/packages/browser-core/src/browser/fetch.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { getZoneJsOriginalValue } from '../tools/getZoneJsOriginalValue' -import { globalObject } from '../tools/globalObject' /** * Make a fetch request using the native implementation, bypassing Zone.js patching. diff --git a/packages/browser-core/src/browser/fetchObservable.ts b/packages/browser-core/src/browser/fetchObservable.ts index 79efde55da..15d5514e50 100644 --- a/packages/browser-core/src/browser/fetchObservable.ts +++ b/packages/browser-core/src/browser/fetchObservable.ts @@ -1,12 +1,11 @@ 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 type { InstrumentedMethodCall } from '../tools/instrumentMethod' import { instrumentMethod } from '../tools/instrumentMethod' import { monitorError } from '../tools/monitor' import { Observable } from '../tools/observable' -import { normalizeUrl } from '../tools/utils/urlPolyfill' -import type { GlobalObject } from '../tools/globalObject' -import { globalObject } from '../tools/globalObject' import { readBytesFromStream } from '../tools/readBytesFromStream' import { tryToClone } from '../tools/utils/responseUtils' diff --git a/packages/browser-core/src/browser/pageMayExitObservable.ts b/packages/browser-core/src/browser/pageMayExitObservable.ts index baae5e163c..b59682b182 100644 --- a/packages/browser-core/src/browser/pageMayExitObservable.ts +++ b/packages/browser-core/src/browser/pageMayExitObservable.ts @@ -1,6 +1,6 @@ +import { globalObject } from '@datadog/js-core/util' import { Observable } from '../tools/observable' import { objectValues } from '../tools/utils/polyfills' -import { globalObject } from '../tools/globalObject' import { addEventListeners, addEventListener, DOM_EVENT } from './addEventListener' export const PageExitReason = { diff --git a/packages/browser-core/src/browser/xhrObservable.ts b/packages/browser-core/src/browser/xhrObservable.ts index 6d66cbf45a..9fcf38bf55 100644 --- a/packages/browser-core/src/browser/xhrObservable.ts +++ b/packages/browser-core/src/browser/xhrObservable.ts @@ -1,10 +1,9 @@ import { elapsed, timeStampNow, clocksNow } from '@datadog/js-core/time' import type { Duration, ClocksState } from '@datadog/js-core/time' +import { normalizeUrl, globalObject } from '@datadog/js-core/util' import type { InstrumentedMethodCall } from '../tools/instrumentMethod' import { instrumentMethod } from '../tools/instrumentMethod' import { Observable } from '../tools/observable' -import { normalizeUrl } from '../tools/utils/urlPolyfill' -import { globalObject } from '../tools/globalObject' import { addEventListener } from './addEventListener' export interface XhrOpenContext { diff --git a/packages/browser-core/src/domain/allowedTrackingOrigins.ts b/packages/browser-core/src/domain/allowedTrackingOrigins.ts index 7328f07fe7..fa286d893d 100644 --- a/packages/browser-core/src/domain/allowedTrackingOrigins.ts +++ b/packages/browser-core/src/domain/allowedTrackingOrigins.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { display } from '../tools/display' -import { globalObject } from '../tools/globalObject' import { matchList } from '../tools/matchOption' import { mockable } from '../tools/mockable' import type { InitConfiguration } from './configuration' diff --git a/packages/browser-core/src/domain/configuration/configuration.ts b/packages/browser-core/src/domain/configuration/configuration.ts index 096595f444..a23370eb82 100644 --- a/packages/browser-core/src/domain/configuration/configuration.ts +++ b/packages/browser-core/src/domain/configuration/configuration.ts @@ -1,3 +1,5 @@ +import type { ProxyFn, Site } from '@datadog/js-core/transport' +import { INTAKE_SITE_US1 } from '@datadog/js-core/transport' import { catchUserErrors } from '../../tools/catchUserErrors' import { DOCS_ORIGIN, MORE_DETAILS, display } from '../../tools/display' import type { RawTelemetryConfiguration } from '../telemetry' @@ -9,8 +11,6 @@ import { TrackingConsent } from '../trackingConsent' import type { SessionPersistence } from '../session/sessionConstants' import type { MatchOption } from '../../tools/matchOption' import { isAllowedTrackingOrigins } from '../allowedTrackingOrigins' -import { INTAKE_SITE_US1 } from '../intakeSites' -import type { Site } from '../intakeSites' /** * Default privacy level for the browser SDK. @@ -267,12 +267,6 @@ export interface InitConfiguration { // for this option. type GenericBeforeSendCallback = (event: any, context?: any) => unknown -/** - * path: /api/vX/product - * parameters: xxx=yyy&zzz=aaa - */ -export type ProxyFn = (options: { path: string; parameters: string; subdomain?: string }) => string - /** * @internal */ diff --git a/packages/browser-core/src/domain/configuration/endpointBuilder.spec.ts b/packages/browser-core/src/domain/configuration/endpointBuilder.spec.ts index f75e42ed32..031f74794c 100644 --- a/packages/browser-core/src/domain/configuration/endpointBuilder.spec.ts +++ b/packages/browser-core/src/domain/configuration/endpointBuilder.spec.ts @@ -1,9 +1,9 @@ -import type { Payload } from '../../transport' +import type { EndpointPayload } from '@datadog/js-core/transport' +import { buildEndpointUrl, createEndpointBuilder, createReplicaEndpointBuilder } from '@datadog/js-core/transport' import type { InitConfiguration } from './configuration' import { validateAndBuildConfiguration } from './configuration' -import { buildEndpointUrl, createEndpointBuilder, createReplicaEndpointBuilder } from './endpointBuilder' -const DEFAULT_PAYLOAD = {} as Payload +const DEFAULT_PAYLOAD = {} as EndpointPayload describe('endpointBuilder', () => { const clientToken = 'some_client_token' diff --git a/packages/browser-core/src/domain/configuration/index.ts b/packages/browser-core/src/domain/configuration/index.ts index b73e9d35d0..aed2b7099d 100644 --- a/packages/browser-core/src/domain/configuration/index.ts +++ b/packages/browser-core/src/domain/configuration/index.ts @@ -1,4 +1,4 @@ -export type { Configuration, InitConfiguration, ProxyFn } from './configuration' +export type { Configuration, InitConfiguration } from './configuration' export { DefaultPrivacyLevel, TraceContextInjection, @@ -7,5 +7,3 @@ export { serializeConfiguration, buildCookieOptions, } from './configuration' -export type { EndpointBuilder, TrackType } from './endpointBuilder' -export { createEndpointBuilder, createReplicaEndpointBuilder, buildEndpointUrl } from './endpointBuilder' diff --git a/packages/browser-core/src/domain/connectivity/connectivity.ts b/packages/browser-core/src/domain/connectivity/connectivity.ts index 5657530635..3b1876f881 100644 --- a/packages/browser-core/src/domain/connectivity/connectivity.ts +++ b/packages/browser-core/src/domain/connectivity/connectivity.ts @@ -1,19 +1,19 @@ -import type { EffectiveType, NetworkInterface } from '../../browser/browser.types' -import { globalObject } from '../../tools/globalObject' +import type { NetworkEffectiveType, NetworkInterface } from '@datadog/js-core/util' +import { globalObject } from '@datadog/js-core/util' export interface Connectivity { status: 'connected' | 'not_connected' interfaces?: NetworkInterface[] - effective_type?: EffectiveType + effective_type?: NetworkEffectiveType [key: string]: unknown } export function getConnectivity(): Connectivity { - const navigator = globalObject.navigator + const { navigator } = globalObject return { - status: navigator.onLine ? 'connected' : 'not_connected', - interfaces: navigator.connection?.type ? [navigator.connection.type] : undefined, - effective_type: navigator.connection?.effectiveType, + status: navigator?.onLine ? 'connected' : 'not_connected', + interfaces: navigator?.connection?.type ? [navigator.connection.type] : undefined, + effective_type: navigator?.connection?.effectiveType, } } diff --git a/packages/browser-core/src/domain/error/trackRuntimeError.ts b/packages/browser-core/src/domain/error/trackRuntimeError.ts index 1995a9a417..f736860dd0 100644 --- a/packages/browser-core/src/domain/error/trackRuntimeError.ts +++ b/packages/browser-core/src/domain/error/trackRuntimeError.ts @@ -1,9 +1,9 @@ import { clocksNow } from '@datadog/js-core/time' +import { globalObject } from '@datadog/js-core/util' import { instrumentMethod } from '../../tools/instrumentMethod' import { Observable } from '../../tools/observable' import type { StackTrace } from '../../tools/stackTrace/computeStackTrace' import { computeStackTraceFromOnErrorMessage } from '../../tools/stackTrace/computeStackTrace' -import { globalObject } from '../../tools/globalObject' import { DOM_EVENT, isEventSupported } from '../../browser/addEventListener' import { noop } from '../../tools/utils/functionUtils' import { computeRawError, isError } from './error' diff --git a/packages/browser-core/src/domain/intakeSites.spec.ts b/packages/browser-core/src/domain/intakeSites.spec.ts index 40c2b669a8..222e77f610 100644 --- a/packages/browser-core/src/domain/intakeSites.spec.ts +++ b/packages/browser-core/src/domain/intakeSites.spec.ts @@ -1,4 +1,4 @@ -import { isIntakeUrl } from './intakeSites' +import { isIntakeUrl } from '@datadog/js-core/transport' describe('intakeSites', () => { const clientToken = 'some_client_token' diff --git a/packages/browser-core/src/domain/session/sessionManager.ts b/packages/browser-core/src/domain/session/sessionManager.ts index cc22daedb3..f8fd877c0d 100644 --- a/packages/browser-core/src/domain/session/sessionManager.ts +++ b/packages/browser-core/src/domain/session/sessionManager.ts @@ -9,6 +9,7 @@ import { relativeNow, } from '@datadog/js-core/time' import type { TimeStamp, RelativeTime } from '@datadog/js-core/time' +import { isWorkerEnvironment } from '@datadog/js-core/util' import { Observable } from '../../tools/observable' import { createValueHistory } from '../../tools/valueHistory' import { addEventListener, addEventListeners, DOM_EVENT } from '../../browser/addEventListener' @@ -18,7 +19,6 @@ import { noop, throttle } from '../../tools/utils/functionUtils' import { generateUUID } from '../../tools/utils/stringUtils' import type { Configuration } from '../configuration' import type { TrackingConsentState } from '../trackingConsent' -import { isWorkerEnvironment } from '../../tools/globalObject' import { display } from '../../tools/display' import { isSampled } from '../sampler' import { TelemetryMetrics, addTelemetryMetrics } from '../telemetry' diff --git a/packages/browser-core/src/domain/session/sessionStore.spec.ts b/packages/browser-core/src/domain/session/sessionStore.spec.ts index 4131013f55..2941c8b626 100644 --- a/packages/browser-core/src/domain/session/sessionStore.spec.ts +++ b/packages/browser-core/src/domain/session/sessionStore.spec.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { replaceMockable } from '../../../test' -import { globalObject } from '../../tools/globalObject' import type { Configuration, InitConfiguration } from '../configuration' import { buildCookieOptions } from '../configuration' import { display } from '../../tools/display' diff --git a/packages/browser-core/src/domain/session/sessionStore.ts b/packages/browser-core/src/domain/session/sessionStore.ts index b8a4dffe06..e942355333 100644 --- a/packages/browser-core/src/domain/session/sessionStore.ts +++ b/packages/browser-core/src/domain/session/sessionStore.ts @@ -1,5 +1,5 @@ +import { isWorkerEnvironment } from '@datadog/js-core/util' import type { Configuration } from '../configuration' -import { isWorkerEnvironment } from '../../tools/globalObject' import { display } from '../../tools/display' import { SessionPersistence } from './sessionConstants' import type { SessionStoreStrategy, SessionStoreStrategyType } from './storeStrategies/sessionStoreStrategy' diff --git a/packages/browser-core/src/domain/session/storeStrategies/sessionInCookie.spec.ts b/packages/browser-core/src/domain/session/storeStrategies/sessionInCookie.spec.ts index ca3431647c..1bb72770f9 100644 --- a/packages/browser-core/src/domain/session/storeStrategies/sessionInCookie.spec.ts +++ b/packages/browser-core/src/domain/session/storeStrategies/sessionInCookie.spec.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { registerCleanupTask, replaceMockable, mockCookies, collectAsyncCalls } from '../../../../test' -import { globalObject } from '../../../tools/globalObject' import { Observable } from '../../../tools/observable' import type { SessionState } from '../sessionState' import type { Configuration, InitConfiguration } from '../../configuration' diff --git a/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.spec.ts b/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.spec.ts index f260e35f37..653d187edf 100644 --- a/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.spec.ts +++ b/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.spec.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { registerCleanupTask } from '../../../../test' -import { globalObject } from '../../../tools/globalObject' import type { SessionState } from '../sessionState' import type { GlobalObjectWithSession } from './sessionInMemory' import { initMemorySessionStoreStrategy, MEMORY_SESSION_STORE_KEY } from './sessionInMemory' diff --git a/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.ts b/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.ts index 3f48d8944e..b4cfe78239 100644 --- a/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.ts +++ b/packages/browser-core/src/domain/session/storeStrategies/sessionInMemory.ts @@ -1,4 +1,4 @@ -import { globalObject } from '../../../tools/globalObject' +import { globalObject } from '@datadog/js-core/util' import { Observable } from '../../../tools/observable' import { shallowClone } from '../../../tools/utils/objectUtils' import { SessionPersistence } from '../sessionConstants' diff --git a/packages/browser-core/src/domain/synthetics/syntheticsWorkerValues.ts b/packages/browser-core/src/domain/synthetics/syntheticsWorkerValues.ts index 906bfcb4ff..a76809ef1b 100644 --- a/packages/browser-core/src/domain/synthetics/syntheticsWorkerValues.ts +++ b/packages/browser-core/src/domain/synthetics/syntheticsWorkerValues.ts @@ -1,5 +1,5 @@ +import { globalObject, isWorkerEnvironment } from '@datadog/js-core/util' import { getInitCookie } from '../../browser/cookie' -import { globalObject, isWorkerEnvironment } from '../../tools/globalObject' import { tryJsonParse } from '../../tools/utils/objectUtils' const cookieNamePrefix = 'datadog-synthetics-' diff --git a/packages/browser-core/src/domain/telemetry/telemetry.spec.ts b/packages/browser-core/src/domain/telemetry/telemetry.spec.ts index 74cb4b01fa..de7cbbb4bb 100644 --- a/packages/browser-core/src/domain/telemetry/telemetry.spec.ts +++ b/packages/browser-core/src/domain/telemetry/telemetry.spec.ts @@ -1,10 +1,10 @@ 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 { 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 { validateAndBuildConfiguration, type Configuration } from '../configuration' -import { INTAKE_SITE_US1_FED, INTAKE_SITE_US2_FED, INTAKE_SITE_US1 } from '../intakeSites' import { setNavigatorOnLine, setNavigatorConnection, diff --git a/packages/browser-core/src/domain/telemetry/telemetry.ts b/packages/browser-core/src/domain/telemetry/telemetry.ts index 8cdfa32d6c..1025d81d4e 100644 --- a/packages/browser-core/src/domain/telemetry/telemetry.ts +++ b/packages/browser-core/src/domain/telemetry/telemetry.ts @@ -1,16 +1,21 @@ import { clocksNow } from '@datadog/js-core/time' -import { getDebugMode, combine } from '@datadog/js-core/util' +import { getDebugMode, combine, globalObject, isWorkerEnvironment } from '@datadog/js-core/util' import type { Hook } from '@datadog/js-core/assembly' import type { RecursivePartial } from '@datadog/js-core/util' import { DISCARDED } from '@datadog/js-core/assembly' +import { + createEndpointBuilder, + createReplicaEndpointBuilder, + INTAKE_SITE_STAGING, + INTAKE_SITE_US1_FED, + INTAKE_SITE_US2_FED, +} from '@datadog/js-core/transport' import type { Context } from '../../tools/serialisation/context' import { NO_ERROR_STACK_PRESENT_MESSAGE, isError } from '../error/error' import { toStackTraceString } from '../../tools/stackTrace/handlingStack' import { getExperimentalFeatures } from '../../tools/experimentalFeatures' -import { createEndpointBuilder, createReplicaEndpointBuilder } from '../configuration' import type { Configuration } from '../configuration' import { buildTags } from '../tags' -import { INTAKE_SITE_STAGING, INTAKE_SITE_US1_FED, INTAKE_SITE_US2_FED } from '../intakeSites' import { BufferedObservable, Observable } from '../../tools/observable' import { startMonitorErrorCollection } from '../../tools/monitor' import { display } from '../../tools/display' @@ -22,7 +27,6 @@ import type { StackTrace } from '../../tools/stackTrace/computeStackTrace' import { computeStackTrace } from '../../tools/stackTrace/computeStackTrace' import { getConnectivity } from '../connectivity' import { canUseEventBridge, getEventBridge, createBatch } from '../../transport' -import { globalObject, isWorkerEnvironment } from '../../tools/globalObject' import { noop } from '../../tools/utils/functionUtils' import type { TelemetryEvent } from './telemetryEvent.types' import type { diff --git a/packages/browser-core/src/index.ts b/packages/browser-core/src/index.ts index f3a5e61eb1..02befa70e1 100644 --- a/packages/browser-core/src/index.ts +++ b/packages/browser-core/src/index.ts @@ -1,15 +1,11 @@ -export type { Configuration, InitConfiguration, EndpointBuilder, ProxyFn } from './domain/configuration' +export type { Configuration, InitConfiguration } from './domain/configuration' export { validateAndBuildConfiguration, DefaultPrivacyLevel, TraceContextInjection, serializeConfiguration, isSampleRate, - buildEndpointUrl, - createEndpointBuilder, - createReplicaEndpointBuilder, } from './domain/configuration' -export * from './domain/intakeSites' export type { TrackingConsentState } from './domain/trackingConsent' export { TrackingConsent, createTrackingConsentState } from './domain/trackingConsent' export { @@ -81,11 +77,12 @@ export { export * from './tools/display' export type { Encoder, EncoderResult } from './tools/encoder' export { createIdentityEncoder } from './tools/encoder' -export * from './tools/utils/urlPolyfill' +export { normalizeUrl, isValidUrl, getPathName, buildUrl, getPristineWindow } from '@datadog/js-core/util' export * from './tools/utils/arrayUtils' export * from './tools/serialisation/sanitize' -export * from './tools/globalObject' +export { globalObject, isWorkerEnvironment } from '@datadog/js-core/util' +export type { GlobalObject } from '@datadog/js-core/util' export { AbstractLifeCycle } from './tools/abstractLifeCycle' export * from './domain/eventRateLimiter/createEventRateLimiter' export * from './tools/utils/browserDetection' @@ -105,14 +102,13 @@ export { NonErrorPrefix } from './domain/error/error.types' export type { Context, ContextArray, ContextValue } from './tools/serialisation/context' export { getCookie, getInitCookie, setCookie, deleteCookie, resetInitCookies } from './browser/cookie' export { isCookieStoreSupported } from './browser/cookieAccess' +export type { WeakRef, WeakRefConstructor } from './browser/browser.types' export type { CookieStore, - WeakRef, - WeakRefConstructor, NetworkInformation, - BrowserNavigator, + Navigator, NetworkInterface, - EffectiveType, + NetworkEffectiveType, Profiler, ProfilerConstructor, ProfilerTrace, @@ -122,7 +118,7 @@ export type { ProfilerSample, ProfilerResource, SampleBufferFullEvent, -} from './browser/browser.types' +} from '@datadog/js-core/util' export type { XhrCompleteContext, XhrStartContext, XhrContext } from './browser/xhrObservable' export { initXhrObservable } from './browser/xhrObservable' export type { FetchResolveContext, FetchStartContext, FetchContext } from './browser/fetchObservable' diff --git a/packages/browser-core/src/tools/getZoneJsOriginalValue.ts b/packages/browser-core/src/tools/getZoneJsOriginalValue.ts index 71efe4e8ea..ca8b4a8e50 100644 --- a/packages/browser-core/src/tools/getZoneJsOriginalValue.ts +++ b/packages/browser-core/src/tools/getZoneJsOriginalValue.ts @@ -1,4 +1,4 @@ -import { globalObject } from './globalObject' +import { globalObject } from '@datadog/js-core/util' export interface BrowserWindowWithZoneJs { Zone?: { diff --git a/packages/browser-core/src/tools/globalObject.ts b/packages/browser-core/src/tools/globalObject.ts deleted file mode 100644 index dd7e38f9cf..0000000000 --- a/packages/browser-core/src/tools/globalObject.ts +++ /dev/null @@ -1,37 +0,0 @@ -// eslint-disable-next-line no-restricted-imports -import type { BrowserNavigator, CookieStore, ProfilerConstructor } from '../browser/browser.types' - -/** - * Reflects values available in the global object (e.g. window or self). We use our own type to - * adjust the expectations across the codebase when the native types offered by TypeScript aren't - * sufficient. - * - * For example, we can mark a property as optional when it is not available in all browsers, or add - * new browser APIs that are not yet typed properly in the typescript lib. - * - * Feel free to add more properties as needed, or mark some properties as optional when they are. - */ -export interface GlobalObject extends Omit< - // eslint-disable-next-line no-restricted-syntax - typeof globalThis, - 'queueMicrotask' | 'cookieStore' | 'Profiler' | 'window' -> { - navigator: BrowserNavigator - - // cookieStore is not available in all browsers yet - cookieStore?: CookieStore - - // queueMicrotask is not available in all browsers yet - queueMicrotask?: typeof queueMicrotask - - // Profiler is not available in all browsers yet - Profiler?: ProfilerConstructor - - // window is not available in SSR environments - window?: Window -} - -// eslint-disable-next-line no-restricted-syntax -export const globalObject = globalThis as GlobalObject - -export const isWorkerEnvironment = 'WorkerGlobalScope' in globalObject diff --git a/packages/browser-core/src/tools/queueMicrotask.ts b/packages/browser-core/src/tools/queueMicrotask.ts index 60efde99a9..5a929ebfcb 100644 --- a/packages/browser-core/src/tools/queueMicrotask.ts +++ b/packages/browser-core/src/tools/queueMicrotask.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { monitor } from './monitor' -import { globalObject } from './globalObject' export function queueMicrotask(callback: () => void) { // Intentionally avoid .bind(globalObject): in some environments (e.g. Selenium GeckoDriver's diff --git a/packages/browser-core/src/tools/sendToExtension.ts b/packages/browser-core/src/tools/sendToExtension.ts index 350545d7d0..b9aea874d3 100644 --- a/packages/browser-core/src/tools/sendToExtension.ts +++ b/packages/browser-core/src/tools/sendToExtension.ts @@ -1,4 +1,4 @@ -import { globalObject } from './globalObject' +import { globalObject } from '@datadog/js-core/util' interface BrowserWindow { __ddBrowserSdkExtensionCallback?: (message: unknown) => void diff --git a/packages/browser-core/src/tools/timer.ts b/packages/browser-core/src/tools/timer.ts index 88b6796607..13efb473ce 100644 --- a/packages/browser-core/src/tools/timer.ts +++ b/packages/browser-core/src/tools/timer.ts @@ -1,7 +1,7 @@ +import type { GlobalObject } from '@datadog/js-core/util' +import { globalObject } from '@datadog/js-core/util' import { getZoneJsOriginalValue } from './getZoneJsOriginalValue' import { monitor } from './monitor' -import type { GlobalObject } from './globalObject' -import { globalObject } from './globalObject' export type TimeoutId = ReturnType diff --git a/packages/browser-core/src/tools/utils/urlPolyfill.spec.ts b/packages/browser-core/src/tools/utils/urlPolyfill.spec.ts index 803f693f22..4ca746ffb5 100644 --- a/packages/browser-core/src/tools/utils/urlPolyfill.spec.ts +++ b/packages/browser-core/src/tools/utils/urlPolyfill.spec.ts @@ -1,4 +1,4 @@ -import { buildUrl, getPathName, isValidUrl, normalizeUrl, getPristineWindow } from './urlPolyfill' +import { buildUrl, getPathName, isValidUrl, normalizeUrl, getPristineWindow } from '@datadog/js-core/util' describe('normalize url', () => { it('should resolve absolute paths', () => { diff --git a/packages/browser-core/src/transport/batch.ts b/packages/browser-core/src/transport/batch.ts index ecb00298b1..99a79cbdac 100644 --- a/packages/browser-core/src/transport/batch.ts +++ b/packages/browser-core/src/transport/batch.ts @@ -1,3 +1,4 @@ +import type { EndpointBuilder } from '@datadog/js-core/transport' import { DOCS_TROUBLESHOOTING, MORE_DETAILS, display } from '../tools/display' import type { Context } from '../tools/serialisation/context' import { objectValues } from '../tools/utils/polyfills' @@ -7,7 +8,6 @@ import { createIdentityEncoder } from '../tools/encoder' import type { Encoder, EncoderResult } from '../tools/encoder' import { computeBytesCount, ONE_KIBI_BYTE } from '../tools/utils/byteUtils' import { mockable } from '../tools/mockable' -import type { EndpointBuilder } from '../domain/configuration' import type { Observable } from '../tools/observable' import { createHttpRequest } from './httpRequest' import type { Payload } from './httpRequest' diff --git a/packages/browser-core/src/transport/eventBridge.ts b/packages/browser-core/src/transport/eventBridge.ts index e2a4070841..60e2ea7afd 100644 --- a/packages/browser-core/src/transport/eventBridge.ts +++ b/packages/browser-core/src/transport/eventBridge.ts @@ -1,5 +1,5 @@ +import { globalObject } from '@datadog/js-core/util' import { display } from '../tools/display' -import { globalObject } from '../tools/globalObject' import type { DefaultPrivacyLevel } from '../domain/configuration' export interface BrowserWindowWithEventBridge { diff --git a/packages/browser-core/src/transport/flushController.ts b/packages/browser-core/src/transport/flushController.ts index 7f6846f74f..a408366ab2 100644 --- a/packages/browser-core/src/transport/flushController.ts +++ b/packages/browser-core/src/transport/flushController.ts @@ -1,7 +1,7 @@ import { ONE_SECOND } from '@datadog/js-core/time' import type { Duration } from '@datadog/js-core/time' +import { isWorkerEnvironment } from '@datadog/js-core/util' import type { PageMayExitEvent, PageExitReason } from '../browser/pageMayExitObservable' -import { isWorkerEnvironment } from '../tools/globalObject' import { Observable } from '../tools/observable' import type { TimeoutId } from '../tools/timer' import { clearTimeout, setTimeout } from '../tools/timer' diff --git a/packages/browser-core/src/transport/httpRequest.spec.ts b/packages/browser-core/src/transport/httpRequest.spec.ts index b7175f49ff..0f1efd1bb2 100644 --- a/packages/browser-core/src/transport/httpRequest.spec.ts +++ b/packages/browser-core/src/transport/httpRequest.spec.ts @@ -1,3 +1,5 @@ +import type { EndpointBuilder } from '@datadog/js-core/transport' +import { createEndpointBuilder } from '@datadog/js-core/transport' import type { Request } from '../../test' import { collectAsyncCalls, @@ -8,8 +10,6 @@ import { NETWORK_ERROR_FETCH_MOCK, wait, } from '../../test' -import type { EndpointBuilder } from '../domain/configuration' -import { createEndpointBuilder } from '../domain/configuration' import { noop } from '../tools/utils/functionUtils' import type { HttpRequest, HttpRequestEvent } from './httpRequest' import { createHttpRequest, fetchStrategy, RECOMMENDED_REQUEST_BYTES_LIMIT } from './httpRequest' diff --git a/packages/browser-core/src/transport/httpRequest.ts b/packages/browser-core/src/transport/httpRequest.ts index 13b4fbb273..d7252b4091 100644 --- a/packages/browser-core/src/transport/httpRequest.ts +++ b/packages/browser-core/src/transport/httpRequest.ts @@ -1,4 +1,4 @@ -import type { EndpointBuilder } from '../domain/configuration' +import type { EndpointBuilder, TransportRetryInfo } from '@datadog/js-core/transport' import type { Context } from '../tools/serialisation/context' import { fetch } from '../browser/fetch' import { monitor, monitorError } from '../tools/monitor' @@ -60,15 +60,10 @@ export type HttpRequestEvent = export interface Payload { data: string | FormData | Blob bytesCount: number - retry?: RetryInfo + retry?: TransportRetryInfo encoding?: 'deflate' } -export interface RetryInfo { - count: number - lastFailureStatus: number -} - export function createHttpRequest( endpointBuilders: EndpointBuilder[], reportError: (message: string) => void, diff --git a/packages/browser-core/src/transport/index.ts b/packages/browser-core/src/transport/index.ts index 21e43adbb8..5cdccd6b6f 100644 --- a/packages/browser-core/src/transport/index.ts +++ b/packages/browser-core/src/transport/index.ts @@ -1,4 +1,4 @@ -export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload, RetryInfo } from './httpRequest' +export type { BandwidthStats, HttpRequest, HttpRequestEvent, Payload } from './httpRequest' export { createHttpRequest } from './httpRequest' export type { BrowserWindowWithEventBridge, DatadogEventBridge } from './eventBridge' export { canUseEventBridge, bridgeSupports, getEventBridge, BridgeCapability } from './eventBridge' diff --git a/packages/browser-core/src/transport/sendWithRetryStrategy.ts b/packages/browser-core/src/transport/sendWithRetryStrategy.ts index 1c04de6716..70488b29f3 100644 --- a/packages/browser-core/src/transport/sendWithRetryStrategy.ts +++ b/packages/browser-core/src/transport/sendWithRetryStrategy.ts @@ -1,5 +1,5 @@ import { ONE_MINUTE, ONE_SECOND } from '@datadog/js-core/time' -import type { TrackType } from '../domain/configuration' +import type { TrackType } from '@datadog/js-core/transport' import { setTimeout } from '../tools/timer' import { ONE_MEBI_BYTE, ONE_KIBI_BYTE } from '../tools/utils/byteUtils' import { isServerError } from '../tools/utils/responseUtils' diff --git a/packages/browser-core/test/interceptRequests.ts b/packages/browser-core/test/interceptRequests.ts index a893a5fd96..6963329b62 100644 --- a/packages/browser-core/test/interceptRequests.ts +++ b/packages/browser-core/test/interceptRequests.ts @@ -1,4 +1,4 @@ -import type { EndpointBuilder } from '../src' +import type { EndpointBuilder } from '@datadog/js-core/transport' import { noop } from '../src' import { mockXhr, MockXhr } from './emulate/mockXhr' import { readFormData } from './readFormData' diff --git a/packages/browser-debugger/src/domain/deliveryApi.ts b/packages/browser-debugger/src/domain/deliveryApi.ts index 5a3a996619..1fe3983c2f 100644 --- a/packages/browser-debugger/src/domain/deliveryApi.ts +++ b/packages/browser-debugger/src/domain/deliveryApi.ts @@ -1,4 +1,4 @@ -import type { TimeoutId, Site } from '@datadog/browser-core' +import type { TimeoutId } from '@datadog/browser-core' import { dateNow } from '@datadog/js-core/time' import { addTelemetryDebug, @@ -8,8 +8,9 @@ import { mockable, setInterval, clearInterval, - INTAKE_SITE_US1, } from '@datadog/browser-core' +import { INTAKE_SITE_US1 } from '@datadog/js-core/transport' +import type { Site } from '@datadog/js-core/transport' import { display } from './display' import { addProbe, clearProbes, removeProbe } from './probes' import type { Probe } from './probes' diff --git a/packages/browser-debugger/src/entries/main.ts b/packages/browser-debugger/src/entries/main.ts index 04a3df2914..49f8182326 100644 --- a/packages/browser-debugger/src/entries/main.ts +++ b/packages/browser-debugger/src/entries/main.ts @@ -7,7 +7,8 @@ */ import { defineGlobal, globalObject, makePublicApi, mockable } from '@datadog/browser-core' -import type { PublicApi, Site } from '@datadog/browser-core' +import type { PublicApi } from '@datadog/browser-core' +import type { Site } from '@datadog/js-core/transport' import { initDebuggerTransport, onEntry, onReturn, onThrow } from '../domain/api' import { startDeliveryApiPolling } from '../domain/deliveryApi' import { display } from '../domain/display' diff --git a/packages/browser-debugger/src/transport/startDebuggerBatch.ts b/packages/browser-debugger/src/transport/startDebuggerBatch.ts index 46d0283625..95cc287223 100644 --- a/packages/browser-debugger/src/transport/startDebuggerBatch.ts +++ b/packages/browser-debugger/src/transport/startDebuggerBatch.ts @@ -1,5 +1,6 @@ import type { InitConfiguration, Batch } from '@datadog/browser-core' -import { createBatch, createEndpointBuilder } from '@datadog/browser-core' +import { createBatch } from '@datadog/browser-core' +import { createEndpointBuilder } from '@datadog/js-core/transport' import { display } from '../domain/display' export function startDebuggerBatch(initConfiguration: InitConfiguration): Batch { diff --git a/packages/browser-logs/src/domain/networkError/networkErrorCollection.ts b/packages/browser-logs/src/domain/networkError/networkErrorCollection.ts index b2f2145144..534c0c82e7 100644 --- a/packages/browser-logs/src/domain/networkError/networkErrorCollection.ts +++ b/packages/browser-logs/src/domain/networkError/networkErrorCollection.ts @@ -8,10 +8,10 @@ import { toStackTraceString, noop, isServerError, - isIntakeUrl, ResponseBodyAction, safeTruncate, } from '@datadog/browser-core' +import { isIntakeUrl } from '@datadog/js-core/transport' import type { LogsConfiguration } from '../configuration' import type { LifeCycle } from '../lifeCycle' import type { LogsEventDomainContext } from '../../domainContext.types' diff --git a/packages/browser-logs/src/entries/main.ts b/packages/browser-logs/src/entries/main.ts index b1abf685cb..b9e798d878 100644 --- a/packages/browser-logs/src/entries/main.ts +++ b/packages/browser-logs/src/entries/main.ts @@ -42,11 +42,10 @@ export type { SessionPersistence, TrackingConsent, MatchOption, - ProxyFn, - Site, RawReportType, ErrorSource, } from '@datadog/browser-core' +export type { ProxyFn, Site } from '@datadog/js-core/transport' export type { ConsoleApiName } from '@datadog/js-core/util' /** diff --git a/packages/browser-logs/src/transport/startLogsBatch.ts b/packages/browser-logs/src/transport/startLogsBatch.ts index 7dec993057..c0ee09779d 100644 --- a/packages/browser-logs/src/transport/startLogsBatch.ts +++ b/packages/browser-logs/src/transport/startLogsBatch.ts @@ -1,5 +1,6 @@ import type { Context, SessionManager } from '@datadog/browser-core' -import { createBatch, createEndpointBuilder, createReplicaEndpointBuilder } from '@datadog/browser-core' +import { createBatch } from '@datadog/browser-core' +import { createEndpointBuilder, createReplicaEndpointBuilder } from '@datadog/js-core/transport' import type { LogsConfiguration } from '../domain/configuration' import type { LifeCycle } from '../domain/lifeCycle' import { LifeCycleEventType } from '../domain/lifeCycle' diff --git a/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.spec.ts b/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.spec.ts index 5155fb0f18..005602126c 100644 --- a/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.spec.ts +++ b/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.spec.ts @@ -1,12 +1,6 @@ import { ONE_MINUTE } from '@datadog/js-core/time' -import { - DefaultPrivacyLevel, - INTAKE_SITE_US1, - display, - setCookie, - deleteCookie, - createContextManager, -} from '@datadog/browser-core' +import { DefaultPrivacyLevel, display, setCookie, deleteCookie, createContextManager } from '@datadog/browser-core' +import { INTAKE_SITE_US1 } from '@datadog/js-core/transport' import { interceptRequests, registerCleanupTask } from '@datadog/browser-core/test' import { appendElement } from '../../../test' import type { RumInitConfiguration } from './configuration' diff --git a/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.ts b/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.ts index 5c5859834f..824524b1b0 100644 --- a/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.ts +++ b/packages/browser-rum-core/src/domain/configuration/remoteConfiguration.ts @@ -7,9 +7,9 @@ import { TelemetryMetrics, monitorError, fetch, - buildEndpointUrl, } from '@datadog/browser-core' import { isIndexableObject } from '@datadog/js-core/util' +import { buildEndpointUrl } from '@datadog/js-core/transport' import { extractRegexMatch } from '../extractRegexMatch' import type { RumInitConfiguration } from './configuration' import type { RumSdkConfig, DynamicOption, ContextItem } from './remoteConfiguration.types' diff --git a/packages/browser-rum-core/src/domain/contexts/urlContexts.ts b/packages/browser-rum-core/src/domain/contexts/urlContexts.ts index cf5ae225e2..88088660c5 100644 --- a/packages/browser-rum-core/src/domain/contexts/urlContexts.ts +++ b/packages/browser-rum-core/src/domain/contexts/urlContexts.ts @@ -1,7 +1,8 @@ import type { RelativeTime } from '@datadog/js-core/time' import type { Observable } from '@datadog/browser-core' import { relativeNow } from '@datadog/js-core/time' -import { SESSION_TIME_OUT_DELAY, createValueHistory, mockable, buildUrl, globalObject } from '@datadog/browser-core' +import { SESSION_TIME_OUT_DELAY, createValueHistory, mockable, globalObject } from '@datadog/browser-core' +import { buildUrl } from '@datadog/js-core/util' import { DISCARDED } from '@datadog/js-core/assembly' import type { LocationChange } from '../../browser/locationChangeObservable' import type { LifeCycle } from '../lifeCycle' diff --git a/packages/browser-rum-core/src/domain/getSessionReplayUrl.ts b/packages/browser-rum-core/src/domain/getSessionReplayUrl.ts index 900b3ce59e..6ae2e6ed85 100644 --- a/packages/browser-rum-core/src/domain/getSessionReplayUrl.ts +++ b/packages/browser-rum-core/src/domain/getSessionReplayUrl.ts @@ -1,5 +1,5 @@ -import { INTAKE_SITE_STAGING, INTAKE_SITE_US1, INTAKE_SITE_EU1 } from '@datadog/browser-core' import type { SessionContext } from '@datadog/browser-core' +import { INTAKE_SITE_STAGING, INTAKE_SITE_US1, INTAKE_SITE_EU1 } from '@datadog/js-core/transport' import type { RumConfiguration } from './configuration' import type { ViewHistoryEntry } from './contexts/viewHistory' diff --git a/packages/browser-rum-core/src/domain/requestCollection.spec.ts b/packages/browser-rum-core/src/domain/requestCollection.spec.ts index ad32e17352..a8c9a4f27c 100644 --- a/packages/browser-rum-core/src/domain/requestCollection.spec.ts +++ b/packages/browser-rum-core/src/domain/requestCollection.spec.ts @@ -1,5 +1,5 @@ -import type { Payload } from '@datadog/browser-core' -import { createEndpointBuilder, RequestType, startBufferingData } from '@datadog/browser-core' +import { RequestType, startBufferingData } from '@datadog/browser-core' +import { createEndpointBuilder, type EndpointPayload } from '@datadog/js-core/transport' import type { MockFetch, MockFetchManager } from '@datadog/browser-core/test' import { registerCleanupTask, mockFetch, mockXhr, withXhr } from '@datadog/browser-core/test' import { mockRumConfiguration } from '../../test' @@ -10,7 +10,7 @@ import type { Tracer } from './tracing/tracer' import { clearTracingIfNeeded } from './tracing/tracer' import { createSpanIdentifier, createTraceIdentifier } from './tracing/identifier' -const DEFAULT_PAYLOAD = {} as Payload +const DEFAULT_PAYLOAD = {} as EndpointPayload describe('collect fetch', () => { const FAKE_URL = 'http://fake-url/' diff --git a/packages/browser-rum-core/src/domain/resource/graphql.ts b/packages/browser-rum-core/src/domain/resource/graphql.ts index c2200cae22..7642e354ff 100644 --- a/packages/browser-rum-core/src/domain/resource/graphql.ts +++ b/packages/browser-rum-core/src/domain/resource/graphql.ts @@ -1,4 +1,5 @@ -import { buildUrl, isNonEmptyArray, matchList, ONE_KIBI_BYTE, safeTruncate, tryJsonParse } from '@datadog/browser-core' +import { isNonEmptyArray, matchList, ONE_KIBI_BYTE, safeTruncate, tryJsonParse } from '@datadog/browser-core' +import { buildUrl } from '@datadog/js-core/util' import type { RumConfiguration, GraphQlUrlOption } from '../configuration' import type { RequestCompleteEvent } from '../requestCollection' diff --git a/packages/browser-rum-core/src/domain/resource/resourceUtils.ts b/packages/browser-rum-core/src/domain/resource/resourceUtils.ts index 3b314efb13..932301608c 100644 --- a/packages/browser-rum-core/src/domain/resource/resourceUtils.ts +++ b/packages/browser-rum-core/src/domain/resource/resourceUtils.ts @@ -1,13 +1,8 @@ import { elapsed, toServerDuration } from '@datadog/js-core/time' import type { Duration, RelativeTime } from '@datadog/js-core/time' -import { - getPathName, - isValidUrl, - ResourceType, - isIntakeUrl, - isExperimentalFeatureEnabled, - ExperimentalFeature, -} from '@datadog/browser-core' +import { ResourceType, isExperimentalFeatureEnabled, ExperimentalFeature } from '@datadog/browser-core' +import { getPathName, isValidUrl } from '@datadog/js-core/util' +import { isIntakeUrl } from '@datadog/js-core/transport' import type { RumPerformanceNavigationTiming, RumPerformanceResourceTiming } from '../../browser/performanceObservable' diff --git a/packages/browser-rum-core/src/transport/formDataTransport.ts b/packages/browser-rum-core/src/transport/formDataTransport.ts index 3b8948e913..d58cef96cd 100644 --- a/packages/browser-rum-core/src/transport/formDataTransport.ts +++ b/packages/browser-rum-core/src/transport/formDataTransport.ts @@ -1,13 +1,7 @@ import type { Uint8ArrayBuffer, Encoder, EncoderResult, DeflateEncoderStreamId, Context } from '@datadog/browser-core' -import { - addTelemetryDebug, - createEndpointBuilder, - createHttpRequest, - jsonStringify, - objectEntries, - ErrorSource, -} from '@datadog/browser-core' +import { addTelemetryDebug, createHttpRequest, jsonStringify, objectEntries, ErrorSource } from '@datadog/browser-core' import { clocksNow } from '@datadog/js-core/time' +import { createEndpointBuilder } from '@datadog/js-core/transport' import type { RumConfiguration } from '../domain/configuration' import type { LifeCycle } from '../domain/lifeCycle' import { LifeCycleEventType } from '../domain/lifeCycle' diff --git a/packages/browser-rum-core/src/transport/startRumBatch.ts b/packages/browser-rum-core/src/transport/startRumBatch.ts index 049934a0e4..7831424c71 100644 --- a/packages/browser-rum-core/src/transport/startRumBatch.ts +++ b/packages/browser-rum-core/src/transport/startRumBatch.ts @@ -5,10 +5,9 @@ import { isExperimentalFeatureEnabled, ExperimentalFeature, sendToExtension, - createEndpointBuilder, - createReplicaEndpointBuilder, } from '@datadog/browser-core' import { combine } from '@datadog/js-core/util' +import { createEndpointBuilder, createReplicaEndpointBuilder } from '@datadog/js-core/transport' import type { RumConfiguration } from '../domain/configuration' import type { LifeCycle } from '../domain/lifeCycle' import { LifeCycleEventType } from '../domain/lifeCycle' diff --git a/packages/browser-rum-nextjs/src/domain/nextjsPlugin.ts b/packages/browser-rum-nextjs/src/domain/nextjsPlugin.ts index 8f8d21dc82..6e4f554328 100644 --- a/packages/browser-rum-nextjs/src/domain/nextjsPlugin.ts +++ b/packages/browser-rum-nextjs/src/domain/nextjsPlugin.ts @@ -1,4 +1,4 @@ -import { buildUrl } from '@datadog/browser-core' +import { buildUrl } from '@datadog/js-core/util' import type { RumPlugin, RumPublicApi, StartRumResult } from '@datadog/browser-rum-core' export type NextjsPlugin = Pick, 'name' | 'onInit' | 'onRumStart'> diff --git a/packages/browser-rum-slim/package.json b/packages/browser-rum-slim/package.json index a5b63fcb9c..c937bd8dc6 100644 --- a/packages/browser-rum-slim/package.json +++ b/packages/browser-rum-slim/package.json @@ -20,7 +20,8 @@ }, "dependencies": { "@datadog/browser-core": "7.4.0", - "@datadog/browser-rum-core": "7.4.0" + "@datadog/browser-rum-core": "7.4.0", + "@datadog/js-core": "0.0.4" }, "peerDependencies": { "@datadog/browser-logs": "7.4.0" diff --git a/packages/browser-rum-slim/src/entries/main.ts b/packages/browser-rum-slim/src/entries/main.ts index aaf34ff570..da3daa5ca1 100644 --- a/packages/browser-rum-slim/src/entries/main.ts +++ b/packages/browser-rum-slim/src/entries/main.ts @@ -12,13 +12,12 @@ export type { SessionPersistence, TrackingConsent, MatchOption, - ProxyFn, - Site, Context, ContextValue, ContextArray, RumInternalContext, } from '@datadog/browser-core' +export type { ProxyFn, Site } from '@datadog/js-core/transport' /** * @deprecated Use {@link DatadogRum} instead diff --git a/packages/browser-rum/src/boot/datadogRecorder.ts b/packages/browser-rum/src/boot/datadogRecorder.ts index 199b2238e1..5486955c38 100644 --- a/packages/browser-rum/src/boot/datadogRecorder.ts +++ b/packages/browser-rum/src/boot/datadogRecorder.ts @@ -1,13 +1,7 @@ import type { HttpRequest, DeflateEncoder, Telemetry, SessionManager } from '@datadog/browser-core' -import { - createHttpRequest, - addTelemetryDebug, - canUseEventBridge, - noop, - createEndpointBuilder, - ErrorSource, -} from '@datadog/browser-core' +import { createHttpRequest, addTelemetryDebug, canUseEventBridge, noop, ErrorSource } from '@datadog/browser-core' import { clocksNow } from '@datadog/js-core/time' +import { createEndpointBuilder } from '@datadog/js-core/transport' import type { LifeCycle, ViewHistory, RumConfiguration } from '@datadog/browser-rum-core' import { LifeCycleEventType } from '@datadog/browser-rum-core' diff --git a/packages/browser-rum/src/domain/profiling/datadogProfiler.ts b/packages/browser-rum/src/domain/profiling/datadogProfiler.ts index 5b19f2e22c..8c00bcbfad 100644 --- a/packages/browser-rum/src/domain/profiling/datadogProfiler.ts +++ b/packages/browser-rum/src/domain/profiling/datadogProfiler.ts @@ -259,12 +259,14 @@ export function createRumProfiler( collectViewEntry(lastViewEntry) // Add event handler case we overflow the buffer + // eslint-disable-next-line local-rules/disallow-zone-js-patched-values -- FIXME use the `addEventListener` helper profiler.addEventListener('samplebufferfull', handleSampleBufferFull) } function collectProfilerInstance(runningInstance: RumProfilerRunningInstance) { // Cleanup instance clearTimeout(runningInstance.timeoutId) + // eslint-disable-next-line local-rules/disallow-zone-js-patched-values -- FIXME use the `addEventListener` helper runningInstance.profiler.removeEventListener('samplebufferfull', handleSampleBufferFull) // Store instance data snapshot in local variables to use in async callback @@ -336,6 +338,7 @@ export function createRumProfiler( if (stateReason === 'quota_ko') { // Discard data — quota denied means we should not send anything clearTimeout(runningInstance.timeoutId) + // eslint-disable-next-line local-rules/disallow-zone-js-patched-values -- FIXME use the `addEventListener` helper runningInstance.profiler.removeEventListener('samplebufferfull', handleSampleBufferFull) void runningInstance.profiler.stop().catch(monitorError) } else { diff --git a/packages/browser-rum/src/domain/profiling/quotaCheck.ts b/packages/browser-rum/src/domain/profiling/quotaCheck.ts index a7790b29e9..ae7d7c74a4 100644 --- a/packages/browser-rum/src/domain/profiling/quotaCheck.ts +++ b/packages/browser-rum/src/domain/profiling/quotaCheck.ts @@ -1,4 +1,5 @@ -import { fetch, setTimeout, clearTimeout, buildEndpointUrl } from '@datadog/browser-core' +import { fetch, setTimeout, clearTimeout } from '@datadog/browser-core' +import { buildEndpointUrl } from '@datadog/js-core/transport' import type { RumConfiguration } from '@datadog/browser-rum-core' // Reason strings surfaced on RUM events. Backend reasons backend_unavailable and diff --git a/packages/browser-rum/src/domain/record/serialization/serializationUtils.ts b/packages/browser-rum/src/domain/record/serialization/serializationUtils.ts index d594b529e1..7a51c37c8c 100644 --- a/packages/browser-rum/src/domain/record/serialization/serializationUtils.ts +++ b/packages/browser-rum/src/domain/record/serialization/serializationUtils.ts @@ -1,4 +1,4 @@ -import { buildUrl } from '@datadog/browser-core' +import { buildUrl } from '@datadog/js-core/util' import { CENSORED_STRING_MARK, shouldMaskNode } from '@datadog/browser-rum-core' import type { NodePrivacyLevel } from '@datadog/browser-rum-core' diff --git a/packages/browser-rum/src/entries/main.ts b/packages/browser-rum/src/entries/main.ts index 3edd00e786..99ff0005f1 100644 --- a/packages/browser-rum/src/entries/main.ts +++ b/packages/browser-rum/src/entries/main.ts @@ -21,14 +21,13 @@ export type { SessionPersistence, TrackingConsent, MatchOption, - ProxyFn, - Site, Context, ContextValue, ContextArray, RumInternalContext, } from '@datadog/browser-core' export { DefaultPrivacyLevel } from '@datadog/browser-core' +export type { ProxyFn, Site } from '@datadog/js-core/transport' /** * @deprecated Use {@link DatadogRum} instead diff --git a/packages/js-core/api/transport.api.md b/packages/js-core/api/transport.api.md new file mode 100644 index 0000000000..c474c34374 --- /dev/null +++ b/packages/js-core/api/transport.api.md @@ -0,0 +1,85 @@ +## API Report File for "@datadog/js-core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public +export function buildEndpointUrl(input: BuildEndpointUrlOptions): string; + +// @public +export interface BuildEndpointUrlOptions { + parameters?: string; + path: string; + proxy?: string | ProxyFn; + site: Site | undefined; + subdomain?: string; +} + +// @public +export function createEndpointBuilder(configuration: EndpointBuilderConfiguration, trackType: TrackType, extraParameters?: string[]): EndpointBuilder; + +// @public +export function createReplicaEndpointBuilder(input: ConfigurationWithReplica, trackType: TrackType): EndpointBuilder | undefined; + +// @public +export interface EndpointBuilder { + build(api: TransportApiType, payload: EndpointPayload): string; + trackType: TrackType; +} + +// @public +export interface EndpointPayload { + encoding?: 'deflate'; + retry?: TransportRetryInfo; +} + +// @public +export const INTAKE_SITE_EU1: Site; + +// @public +export const INTAKE_SITE_STAGING: Site; + +// @public +export const INTAKE_SITE_US1: Site; + +// @public +export const INTAKE_SITE_US1_FED: Site; + +// @public +export const INTAKE_SITE_US2_FED: Site; + +// @public +export const INTAKE_URL_PARAMETERS: string[]; + +// @public +export function isIntakeUrl(url: string): boolean; + +// @public +export type ProxyFn = (options: { + path: string; + parameters: string; + subdomain?: string; +}) => string; + +// @public +export type Site = 'datadoghq.com' | 'us3.datadoghq.com' | 'us5.datadoghq.com' | 'datadoghq.eu' | 'ddog-gov.com' | 'us2.ddog-gov.com' | 'ap1.datadoghq.com' | 'ap2.datadoghq.com' | (string & {}); + +// @public +export type TrackType = 'logs' | 'rum' | 'replay' | 'profile' | 'exposures' | 'flagevaluation' | 'debugger'; + +// @public +export type TransportApiType = 'fetch' | 'beacon' | 'manual'; + +// @public +export interface TransportRetryInfo { + count: number; + lastFailureStatus: number; +} + +// @public +export type TransportSource = 'browser' | 'flutter' | 'unity' | 'dd_debugger'; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/js-core/api/util.api.md b/packages/js-core/api/util.api.md index 93beb61940..32e2528ad6 100644 --- a/packages/js-core/api/util.api.md +++ b/packages/js-core/api/util.api.md @@ -1,88 +1,255 @@ -## API Report File for "@datadog/js-core" - -> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). - -```ts - -// @public -export function combine(a: A, b: B): Combined; - -// @public (undocumented) -export function combine(a: A, b: B, c: C): Combined, C>; - -// @public (undocumented) -export function combine(a: A, b: B, c: C, d: D): Combined, C>, D>; - -// @public (undocumented) -export function combine(a: A, b: B, c: C, d: D, e: E): Combined, C>, D>, E>; - -// @public (undocumented) -export function combine(a: A, b: B, c: C, d: D, e: E, f: F): Combined, C>, D>, E>, F>; - -// @public (undocumented) -export function combine(a: A, b: B, c: C, d: D, e: E, f: F, g: G): Combined, C>, D>, E>, F>, G>; - -// @public (undocumented) -export function combine(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H): Combined, C>, D>, E>, F>, G>, H>; - -// @public -export const ConsoleApiName: { - readonly log: "log"; - readonly debug: "debug"; - readonly info: "info"; - readonly warn: "warn"; - readonly error: "error"; -}; - -// @public -export type ConsoleApiName = (typeof ConsoleApiName)[keyof typeof ConsoleApiName]; - -// @public -export function createDisplay(prefix: string): Display; - -// @public -export function deepClone(value: T): T; - -// @public -export interface Display { - // (undocumented) - debug: typeof console.debug; - // (undocumented) - error: typeof console.error; - // (undocumented) - info: typeof console.info; - // (undocumented) - log: typeof console.log; - // (undocumented) - warn: typeof console.warn; -} - -// @public -export function getDebugMode(): boolean; - -// @public -export function getType(value: unknown): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null" | "array"; - -// @public -export const globalConsole: Console; - -// @public -export function isIndexableObject(value: unknown): value is Record; - -// @public -export function mergeInto(destination: D, source: S): Merged; - -// @public -export const originalConsoleMethods: Display; - -// @public -export type RecursivePartial = { - [P in keyof T]?: T[P] extends Array ? Array> : T[P] extends object | undefined ? RecursivePartial : T[P]; -}; - -// @public -export function setDebugMode(newDebugMode: boolean): void; - -// (No @packageDocumentation comment for this package) - -``` +## API Report File for "@datadog/js-core" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts + +// @public +export function buildUrl(url: string, base?: string): URL; + +// @public +export function combine(a: A, b: B): Combined; + +// @public (undocumented) +export function combine(a: A, b: B, c: C): Combined, C>; + +// @public (undocumented) +export function combine(a: A, b: B, c: C, d: D): Combined, C>, D>; + +// @public (undocumented) +export function combine(a: A, b: B, c: C, d: D, e: E): Combined, C>, D>, E>; + +// @public (undocumented) +export function combine(a: A, b: B, c: C, d: D, e: E, f: F): Combined, C>, D>, E>, F>; + +// @public (undocumented) +export function combine(a: A, b: B, c: C, d: D, e: E, f: F, g: G): Combined, C>, D>, E>, F>, G>; + +// @public (undocumented) +export function combine(a: A, b: B, c: C, d: D, e: E, f: F, g: G, h: H): Combined, C>, D>, E>, F>, G>, H>; + +// @public +export const ConsoleApiName: { + readonly log: "log"; + readonly debug: "debug"; + readonly info: "info"; + readonly warn: "warn"; + readonly error: "error"; +}; + +// @public +export type ConsoleApiName = (typeof ConsoleApiName)[keyof typeof ConsoleApiName]; + +// @public +type CookieChangeEvent_2 = Event & { + changed: CookieChangeItem[]; + deleted: CookieChangeItem[]; +}; +export { CookieChangeEvent_2 as CookieChangeEvent } + +// @public +export interface CookieChangeItem { + name: string; + value: string | undefined; +} + +// @public +interface CookieStore_2 extends EventTarget { + addEventListener(type: K, listener: (ev: CookieStoreEventMap_2[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + delete(options: { + name: string; + domain?: string; + path?: string; + partitioned?: boolean; + }): Promise; + get(name: string): Promise; + getAll(name?: string): Promise; + removeEventListener(type: K, listener: (ev: CookieStoreEventMap_2[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + set(options: { + name: string; + value: string; + expires?: number | Date; + domain?: string; + path?: string; + secure?: boolean; + sameSite?: 'strict' | 'lax' | 'none'; + partitioned?: boolean; + }): Promise; +} +export { CookieStore_2 as CookieStore } + +// @internal (undocumented) +interface CookieStoreEventMap_2 { + // (undocumented) + change: CookieChangeEvent_2; +} +export { CookieStoreEventMap_2 as CookieStoreEventMap } + +// @public +export interface CookieStoreItem { + domain?: string; + expires?: number; + name: string; + partitioned?: boolean; + path?: string; + sameSite?: 'strict' | 'lax' | 'none'; + secure?: boolean; + value: string; +} + +// @public +export function createDisplay(prefix: string): Display; + +// @public +export function deepClone(value: T): T; + +// @public +export interface Display { + // (undocumented) + debug: typeof console.debug; + // (undocumented) + error: typeof console.error; + // (undocumented) + info: typeof console.info; + // (undocumented) + log: typeof console.log; + // (undocumented) + warn: typeof console.warn; +} + +// @public +export function getDebugMode(): boolean; + +// @public +export function getPathName(url: string): string; + +// @public +export function getPristineWindow(): Pick; + +// @public +export function getType(value: unknown): "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function" | "null" | "array"; + +// @public +export const globalConsole: Console; + +// @public +export interface GlobalObject extends Omit { + cookieStore?: CookieStore_2; + navigator?: Navigator_2; + Profiler?: ProfilerConstructor; + queueMicrotask?: typeof queueMicrotask; + window?: Window; +} + +// @public +export const globalObject: GlobalObject; + +// @public +export function isIndexableObject(value: unknown): value is Record; + +// @public +export function isValidUrl(url: string): boolean; + +// @public +export const isWorkerEnvironment: boolean; + +// @public +export function mergeInto(destination: D, source: S): Merged; + +// @public +interface Navigator_2 { + connection?: NetworkInformation; + onLine: boolean; +} +export { Navigator_2 as Navigator } + +// @public +export type NetworkEffectiveType = 'slow-2g' | '2g' | '3g' | '4g'; + +// @public +export interface NetworkInformation { + effectiveType?: NetworkEffectiveType; + saveData: boolean; + type?: NetworkInterface; +} + +// @public +export type NetworkInterface = 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown'; + +// @public +export function normalizeUrl(url: string): string; + +// @public +export const originalConsoleMethods: Display; + +// @public +export interface Profiler extends EventTarget { + addEventListener(type: K, listener: (ev: ProfilerEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; + addEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | AddEventListenerOptions): void; + removeEventListener(type: K, listener: (ev: ProfilerEventMap[K]) => any, options?: boolean | EventListenerOptions): void; + removeEventListener(type: string, listener: EventListenerOrEventListenerObject, options?: boolean | EventListenerOptions): void; + readonly sampleInterval: number; + stop(): Promise; + readonly stopped: boolean; +} + +// @public +export interface ProfilerConstructor { + new (options: ProfilerInitOptions): Profiler; +} + +// @public +export interface ProfilerFrame { + readonly column?: number; + readonly line?: number; + readonly name: string; + readonly resourceId?: number; +} + +// @public +export interface ProfilerInitOptions { + readonly maxBufferSize: number; + readonly sampleInterval: number; +} + +// @public +export type ProfilerResource = string; + +// @public +export interface ProfilerSample { + readonly stackId?: number; + readonly timestamp: number; +} + +// @public +export interface ProfilerStack { + readonly frameId: number; + readonly parentId?: number; +} + +// @public +export interface ProfilerTrace { + readonly frames: ProfilerFrame[]; + readonly resources: ProfilerResource[]; + readonly samples: ProfilerSample[]; + readonly stacks: ProfilerStack[]; +} + +// @public +export type RecursivePartial = { + [P in keyof T]?: T[P] extends Array ? Array> : T[P] extends object | undefined ? RecursivePartial : T[P]; +}; + +// @public +export interface SampleBufferFullEvent extends Event { + readonly target: Profiler; +} + +// @public +export function setDebugMode(newDebugMode: boolean): void; + +// (No @packageDocumentation comment for this package) + +``` diff --git a/packages/js-core/package.json b/packages/js-core/package.json index b7c1c6cf1e..53bd600e86 100644 --- a/packages/js-core/package.json +++ b/packages/js-core/package.json @@ -23,6 +23,11 @@ "import": "./esm/entries/util.mjs", "require": "./cjs/entries/util.js", "types": "./cjs/entries/util.d.ts" + }, + "./transport": { + "import": "./esm/entries/transport.mjs", + "require": "./cjs/entries/transport.js", + "types": "./cjs/entries/transport.d.ts" } }, "files": [ @@ -33,6 +38,7 @@ "time", "monitor", "util", + "transport", "!src/**/*.spec.ts", "!src/**/*.specHelper.ts" ], diff --git a/packages/js-core/src/entries/transport.ts b/packages/js-core/src/entries/transport.ts new file mode 100644 index 0000000000..c5454735a3 --- /dev/null +++ b/packages/js-core/src/entries/transport.ts @@ -0,0 +1,21 @@ +export type { + TrackType, + TransportApiType, + TransportSource, + EndpointBuilder, + BuildEndpointUrlOptions, + ProxyFn, + TransportRetryInfo, + EndpointPayload, +} from '../transport/endpointBuilder' +export { createEndpointBuilder, createReplicaEndpointBuilder, buildEndpointUrl } from '../transport/endpointBuilder' +export type { Site } from '../transport/intakeSites' +export { + INTAKE_SITE_STAGING, + INTAKE_SITE_US1, + INTAKE_SITE_EU1, + INTAKE_SITE_US1_FED, + INTAKE_SITE_US2_FED, + INTAKE_URL_PARAMETERS, + isIntakeUrl, +} from '../transport/intakeSites' diff --git a/packages/js-core/src/entries/util.ts b/packages/js-core/src/entries/util.ts index a8060ccb7a..f5446dc452 100644 --- a/packages/js-core/src/entries/util.ts +++ b/packages/js-core/src/entries/util.ts @@ -3,3 +3,26 @@ export type { Display } from '../util/display' export { setDebugMode, getDebugMode } from '../util/debug' export * from '../util/mergeInto' export * from '../util/typeUtils' +export { globalObject, isWorkerEnvironment } from '../util/globalObject' +export type { + GlobalObject, + Navigator, + NetworkInformation, + NetworkInterface, + NetworkEffectiveType, + CookieStoreItem, + CookieStore, + CookieChangeItem, + CookieChangeEvent, + CookieStoreEventMap, + ProfilerFrame, + ProfilerStack, + ProfilerSample, + ProfilerResource, + ProfilerTrace, + ProfilerInitOptions, + SampleBufferFullEvent, + Profiler, + ProfilerConstructor, +} from '../util/globalObject' +export { normalizeUrl, isValidUrl, getPathName, buildUrl, getPristineWindow } from '../util/urlPolyfill' diff --git a/packages/browser-core/src/domain/configuration/endpointBuilder.ts b/packages/js-core/src/transport/endpointBuilder.ts similarity index 57% rename from packages/browser-core/src/domain/configuration/endpointBuilder.ts rename to packages/js-core/src/transport/endpointBuilder.ts index 33b6eb9d01..1c27f59086 100644 --- a/packages/browser-core/src/domain/configuration/endpointBuilder.ts +++ b/packages/js-core/src/transport/endpointBuilder.ts @@ -1,16 +1,16 @@ -import { timeStampNow } from '@datadog/js-core/time' -import type { Payload } from '../../transport' -import { normalizeUrl } from '../../tools/utils/urlPolyfill' -import { generateUUID } from '../../tools/utils/stringUtils' -import type { Site } from '../intakeSites' -import { INTAKE_SITE_US1 } from '../intakeSites' -import type { Configuration, ProxyFn } from './configuration' +import { timeStampNow } from '../entries/time' +import { normalizeUrl } from '../entries/util' +import type { Site } from './intakeSites' +import { INTAKE_SITE_US1 } from './intakeSites' // replaced at build time declare const __BUILD_ENV__SDK_VERSION__: string +/** The Datadog backend track a request is being sent to. */ export type TrackType = 'logs' | 'rum' | 'replay' | 'profile' | 'exposures' | 'flagevaluation' | 'debugger' -export type ApiType = + +/** The mechanism used to send a request to an intake endpoint. */ +export type TransportApiType = | 'fetch' | 'beacon' // 'manual' reflects that the request have been sent manually, outside of the SDK (ex: via curl or @@ -26,6 +26,25 @@ export type ApiType = */ export type TransportSource = 'browser' | 'flutter' | 'unity' | 'dd_debugger' +/** A function that builds a proxy URL for an intake request. */ +export type ProxyFn = (options: { path: string; parameters: string; subdomain?: string }) => string + +/** Metadata about a request retry attempt. */ +export interface TransportRetryInfo { + /** Number of retry attempts so far. */ + count: number + /** HTTP status code of the last failed attempt. */ + lastFailureStatus: number +} + +/** The data and metadata associated with a single intake request. */ +export interface EndpointPayload { + /** Present when this is a retry; carries the previous attempt's metadata. */ + retry?: TransportRetryInfo + /** Compression applied to the payload body, if any. */ + encoding?: 'deflate' +} + interface EndpointBuilderConfiguration { clientToken: string proxy?: string | ProxyFn @@ -33,15 +52,33 @@ interface EndpointBuilderConfiguration { source?: TransportSource } -export type EndpointBuilder = ReturnType +interface ReplicaConfiguration { + clientToken: string + applicationId?: string +} +interface ConfigurationWithReplica { + replica?: ReplicaConfiguration + proxy?: string | ProxyFn + source?: TransportSource +} + +/** Builds intake URLs for a specific track. */ +export interface EndpointBuilder { + /** Builds the intake URL for the given API type and payload metadata. */ + build(api: TransportApiType, payload: EndpointPayload): string + /** The track this builder targets. */ + trackType: TrackType +} + +/** Creates an {@link EndpointBuilder} for the given track type. */ export function createEndpointBuilder( configuration: EndpointBuilderConfiguration, trackType: TrackType, extraParameters?: string[] -) { +): EndpointBuilder { return { - build(api: ApiType, payload: Payload) { + build(api: TransportApiType, payload: EndpointPayload) { return buildEndpointUrl({ proxy: configuration.proxy, site: configuration.site, @@ -59,7 +96,10 @@ export function createEndpointBuilder( * The replica always targets the US1 site but keeps the `proxy` and `source` of the main * configuration. The RUM track additionally carries the replica `application.id`. */ -export function createReplicaEndpointBuilder({ replica, proxy, source }: Configuration, trackType: TrackType) { +export function createReplicaEndpointBuilder( + { replica, proxy, source }: ConfigurationWithReplica, + trackType: TrackType +): EndpointBuilder | undefined { if (!replica) { return } @@ -75,14 +115,21 @@ export function createReplicaEndpointBuilder({ replica, proxy, source }: Configu ) } +/** Options for building a Datadog intake URL. */ export interface BuildEndpointUrlOptions { + /** Optional proxy URL or function to route intake requests through. */ proxy?: string | ProxyFn + /** Target Datadog site. Defaults to `INTAKE_SITE_US1` when undefined. */ site: Site | undefined + /** Optional subdomain prepended to the intake domain (e.g. `'sdk-configuration'`). */ subdomain?: string + /** The API path (e.g. `/api/v2/rum`). */ path: string + /** Pre-built query string appended to the URL, without a leading `?`. */ parameters?: string } +/** Builds a Datadog intake URL from the given options. */ export function buildEndpointUrl({ proxy, site = INTAKE_SITE_US1, @@ -124,8 +171,8 @@ export function buildEndpointUrl({ function buildEndpointParameters( { clientToken, source = 'browser' }: EndpointBuilderConfiguration, trackType: TrackType, - api: ApiType, - { retry, encoding }: Payload, + api: TransportApiType, + { retry, encoding }: EndpointPayload, extraParameters: string[] = [] ) { const parameters = [ @@ -150,3 +197,14 @@ function buildEndpointParameters( return parameters.join('&') } + +/** + * UUID v4 + * from https://gist.github.com/jed/982883 + */ +function generateUUID(placeholder?: string): string { + return placeholder + ? // eslint-disable-next-line no-bitwise + (parseInt(placeholder, 10) ^ ((Math.random() * 16) >> (parseInt(placeholder, 10) / 4))).toString(16) + : `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, generateUUID) +} diff --git a/packages/browser-core/src/domain/intakeSites.ts b/packages/js-core/src/transport/intakeSites.ts similarity index 64% rename from packages/browser-core/src/domain/intakeSites.ts rename to packages/js-core/src/transport/intakeSites.ts index d94773b9cf..24d6243f30 100644 --- a/packages/browser-core/src/domain/intakeSites.ts +++ b/packages/js-core/src/transport/intakeSites.ts @@ -1,3 +1,4 @@ +/** A Datadog intake site hostname. Extensible with custom string values for internal use. */ export type Site = | 'datadoghq.com' | 'us3.datadoghq.com' @@ -9,14 +10,21 @@ export type Site = | 'ap2.datadoghq.com' | (string & {}) +/** Datadog staging environment (internal use). */ export const INTAKE_SITE_STAGING: Site = 'datad0g.com' +/** Datadog US1 site (default). */ export const INTAKE_SITE_US1: Site = 'datadoghq.com' +/** Datadog EU1 site. */ export const INTAKE_SITE_EU1: Site = 'datadoghq.eu' +/** Datadog US1 FedRAMP site. */ export const INTAKE_SITE_US1_FED: Site = 'ddog-gov.com' +/** Datadog US2 FedRAMP site. */ export const INTAKE_SITE_US2_FED: Site = 'us2.ddog-gov.com' +/** URL query parameters that identify a Datadog intake request. */ export const INTAKE_URL_PARAMETERS = ['ddsource', 'dd-api-key', 'dd-request-id'] +/** Returns true if the URL targets a Datadog intake endpoint. */ export function isIntakeUrl(url: string): boolean { // check if tags is present in the query string return INTAKE_URL_PARAMETERS.every((param) => url.includes(param)) diff --git a/packages/js-core/src/util/globalObject.ts b/packages/js-core/src/util/globalObject.ts new file mode 100644 index 0000000000..82f5c90899 --- /dev/null +++ b/packages/js-core/src/util/globalObject.ts @@ -0,0 +1,265 @@ +/** + * Represents the global object across JS environments (browser window, Web Worker, Node.js, ...). + * + * We extend `typeof globalThis` to inherit all standard globals, but override specific browser + * APIs with our own definitions and make them optional so the type is valid in non-browser + * environments where those APIs may not exist. + * + * The overridden types are either more accurate than what TypeScript's DOM lib provides, or not + * yet available in the TypeScript version we currently support or require as minimum. + * Only the properties actually used by the SDK are included. + */ +export interface GlobalObject extends Omit< + // eslint-disable-next-line no-restricted-syntax + typeof globalThis, + 'navigator' | 'queueMicrotask' | 'cookieStore' | 'Profiler' | 'window' +> { + /** Not available in Node.js. https://developer.mozilla.org/en-US/docs/Web/API/Navigator */ + navigator?: Navigator + + /** Not available in all browsers yet. https://developer.mozilla.org/en-US/docs/Web/API/CookieStore */ + cookieStore?: CookieStore + + /** Not available in all browsers yet. https://developer.mozilla.org/en-US/docs/Web/API/queueMicrotask */ + queueMicrotask?: typeof queueMicrotask + + /** Not available in all browsers yet. https://developer.mozilla.org/en-US/docs/Web/API/Profiler */ + Profiler?: ProfilerConstructor + + /** Not available in workers or SSR environments. https://developer.mozilla.org/en-US/docs/Web/API/Window */ + window?: Window +} + +/** The global object for the current JS environment. */ +// eslint-disable-next-line no-restricted-syntax +export const globalObject = globalThis as GlobalObject + +/** True when the SDK is running inside a Web Worker. */ +export const isWorkerEnvironment = 'WorkerGlobalScope' in globalObject + +/** + * The types below are either more accurate than what TypeScript's DOM lib provides, or not yet + * available in the TypeScript version we currently support or require as minimum. + * Only the properties actually used by the SDK are included. + */ + +// Network Information API +// https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation + +/** The physical type of the network connection. */ +export type NetworkInterface = 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown' + +/** The effective bandwidth class of the network connection. */ +export type NetworkEffectiveType = 'slow-2g' | '2g' | '3g' | '4g' + +/** Provides information about the device's network connection. */ +export interface NetworkInformation { + /** The physical connection type. */ + type?: NetworkInterface + /** The effective connection type based on observed bandwidth. */ + effectiveType?: NetworkEffectiveType + /** Whether the user has requested a reduced data usage mode. */ + saveData: boolean +} + +/** Extends the standard Navigator with the Network Information API. */ +export interface Navigator { + /** Whether the browser is online. */ + onLine: boolean + /** Network connection info; may be absent in some browsers. */ + connection?: NetworkInformation +} + +// CookieStore API +// https://developer.mozilla.org/en-US/docs/Web/API/CookieStore + +/** A single cookie's attributes. */ +export interface CookieStoreItem { + /** Cookie name. */ + name: string + /** Cookie value. */ + value: string + /** Restricts the cookie to the given domain. */ + domain?: string + /** Restricts the cookie to the given path. */ + path?: string + /** Expiry time as a Unix timestamp in milliseconds. */ + expires?: number + /** Whether the cookie is restricted to HTTPS. */ + secure?: boolean + /** Same-site policy. */ + sameSite?: 'strict' | 'lax' | 'none' + /** Whether the cookie is partitioned (CHIPS). */ + partitioned?: boolean +} + +/** Describes a cookie that was changed or deleted in a `CookieChangeEvent`. */ +export interface CookieChangeItem { + /** Cookie name. */ + name: string + /** New value, or `undefined` if the cookie was deleted. */ + value: string | undefined +} + +/** Fired when cookies are added, modified, or removed. */ +export type CookieChangeEvent = Event & { + /** Cookies that were added or modified. */ + changed: CookieChangeItem[] + /** Cookies that were deleted. */ + deleted: CookieChangeItem[] +} + +/** @internal */ +export interface CookieStoreEventMap { + change: CookieChangeEvent +} + +/** Async, event-driven API for reading and writing cookies. */ +export interface CookieStore extends EventTarget { + /** Retrieves the cookie with the given name. */ + get(name: string): Promise + /** Retrieves all cookies matching the given name, or all cookies if omitted. */ + getAll(name?: string): Promise + /** Sets a cookie with the given attributes. */ + set(options: { + name: string + value: string + expires?: number | Date + domain?: string + path?: string + secure?: boolean + sameSite?: 'strict' | 'lax' | 'none' + partitioned?: boolean + }): Promise + /** Deletes a cookie matching the given attributes. */ + delete(options: { name: string; domain?: string; path?: string; partitioned?: boolean }): Promise + /** Adds a typed listener for the given cookie store event. */ + addEventListener( + type: K, + listener: (ev: CookieStoreEventMap[K]) => any, + options?: boolean | AddEventListenerOptions + ): void + /** @inheritdoc EventTarget.addEventListener */ + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions + ): void + /** Removes a typed listener for the given cookie store event. */ + removeEventListener( + type: K, + listener: (ev: CookieStoreEventMap[K]) => any, + options?: boolean | EventListenerOptions + ): void + /** @inheritdoc EventTarget.removeEventListener */ + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void +} + +// JS Self-Profiling API +// https://wicg.github.io/js-self-profiling/ + +/** A single frame (function call) captured in a profiler trace. */ +export interface ProfilerFrame { + /** Function name. */ + readonly name: string + /** Index into `ProfilerTrace.resources`. */ + readonly resourceId?: number + /** 1-based source line number. */ + readonly line?: number + /** 1-based source column number. */ + readonly column?: number +} + +/** A node in the profiler's call-stack tree. */ +export interface ProfilerStack { + /** Index of the parent stack node, if any. */ + readonly parentId?: number + /** Index into `ProfilerTrace.frames`. */ + readonly frameId: number +} + +/** A single time-stamped sample captured by the profiler. */ +export interface ProfilerSample { + /** Time in ms relative to the profiling session's time origin. */ + readonly timestamp: number + /** Index into `ProfilerTrace.stacks`, if a stack was captured. */ + readonly stackId?: number +} + +/** A script URL referenced by a profiler frame. */ +export type ProfilerResource = string + +/** The complete output of a profiling session. */ +export interface ProfilerTrace { + /** Script URLs referenced by frames. */ + readonly resources: ProfilerResource[] + /** Function call frames. */ + readonly frames: ProfilerFrame[] + /** Call-stack tree nodes. */ + readonly stacks: ProfilerStack[] + /** Time-stamped samples. */ + readonly samples: ProfilerSample[] +} + +/** Options passed when starting a profiler session. */ +export interface ProfilerInitOptions { + /** How often to sample, in ms. */ + readonly sampleInterval: number + /** Maximum number of samples before the buffer-full event fires. */ + readonly maxBufferSize: number +} + +/** Fired when the profiler's sample buffer is full. */ +export interface SampleBufferFullEvent extends Event { + /** The profiler that fired the event. */ + readonly target: Profiler +} + +/** @internal */ +interface ProfilerEventMap { + samplebufferfull: SampleBufferFullEvent +} + +/** A running JS Self-Profiling session. */ +export interface Profiler extends EventTarget { + /** The actual sample interval in ms (may differ from the requested value). */ + readonly sampleInterval: number + /** Whether the profiler has been stopped. */ + readonly stopped: boolean + /** Stops the profiler and returns the collected trace. */ + stop(): Promise + /** Adds a typed listener for the given profiler event. */ + addEventListener( + type: K, + listener: (ev: ProfilerEventMap[K]) => any, + options?: boolean | AddEventListenerOptions + ): void + /** @inheritdoc EventTarget.addEventListener */ + addEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | AddEventListenerOptions + ): void + /** Removes a typed listener for the given profiler event. */ + removeEventListener( + type: K, + listener: (ev: ProfilerEventMap[K]) => any, + options?: boolean | EventListenerOptions + ): void + /** @inheritdoc EventTarget.removeEventListener */ + removeEventListener( + type: string, + listener: EventListenerOrEventListenerObject, + options?: boolean | EventListenerOptions + ): void +} + +/** Constructor for a JS Self-Profiling session. */ +export interface ProfilerConstructor { + /** Starts a new profiling session with the given options. */ + new (options: ProfilerInitOptions): Profiler +} diff --git a/packages/browser-core/src/tools/utils/urlPolyfill.ts b/packages/js-core/src/util/urlPolyfill.ts similarity index 67% rename from packages/browser-core/src/tools/utils/urlPolyfill.ts rename to packages/js-core/src/util/urlPolyfill.ts index ae39e169be..e30d87b177 100644 --- a/packages/browser-core/src/tools/utils/urlPolyfill.ts +++ b/packages/js-core/src/util/urlPolyfill.ts @@ -1,10 +1,12 @@ -import type { GlobalObject } from '../globalObject' -import { globalObject } from '../globalObject' +import type { GlobalObject } from './globalObject' +import { globalObject } from './globalObject' +/** Resolves a URL against the current page location, returning a normalized absolute URL string. */ export function normalizeUrl(url: string) { return buildUrl(url, globalObject.location?.href).href } +/** Returns true if the given string is a valid URL. */ export function isValidUrl(url: string) { try { return !!buildUrl(url) @@ -13,11 +15,13 @@ export function isValidUrl(url: string) { } } +/** Extracts the pathname from a URL, ensuring it starts with `/`. */ export function getPathName(url: string) { const pathname = buildUrl(url).pathname return pathname[0] === '/' ? pathname : `/${pathname}` } +/** Constructs a URL object, using the native URL constructor from a pristine iframe to avoid polyfill interference. */ export function buildUrl(url: string, base?: string) { const { URL } = getPristineWindow() @@ -28,13 +32,12 @@ export function buildUrl(url: string, base?: string) { } } -/** - * Get native URL constructor from a clean iframe - * This avoids polyfill issues by getting the native implementation from a fresh iframe context - * Falls back to the original URL constructor if iframe approach fails - */ let getPristineGlobalObjectCache: Pick | undefined +/** + * Returns a `{ URL }` object sourced from a pristine iframe, bypassing any patched URL constructor. + * Falls back to the current global if iframe creation fails. + */ export function getPristineWindow() { if (!getPristineGlobalObjectCache) { let iframe: HTMLIFrameElement | undefined diff --git a/packages/js-core/transport/package.json b/packages/js-core/transport/package.json new file mode 100644 index 0000000000..64d8aef662 --- /dev/null +++ b/packages/js-core/transport/package.json @@ -0,0 +1,6 @@ +{ + "private": true, + "main": "../cjs/entries/transport.js", + "module": "../esm/entries/transport.mjs", + "types": "../cjs/entries/transport.d.ts" +} diff --git a/scripts/build/build-test-apps.ts b/scripts/build/build-test-apps.ts index f9cf85ca5e..05fdc55522 100644 --- a/scripts/build/build-test-apps.ts +++ b/scripts/build/build-test-apps.ts @@ -130,31 +130,35 @@ function showHelpAndExit() { } async function buildApp(appName: string) { - const appPath = `test/apps/${appName}` - printLog(`Building app at ${appPath}...`) - await command`yarn install --no-immutable`.withCurrentWorkingDirectory(appPath).runAsync() - - // install peer dependencies if any - // intent: renovate does not allow to generate local packages before install - // so local packages are marked as optional peer dependencies and only installed when we build the test apps - const packageJson = JSON.parse(fs.readFileSync(path.join(appPath, 'package.json'), 'utf-8')) - if (packageJson.peerDependencies) { - // For each peer dependency, install it - for (const [name] of Object.entries(packageJson.peerDependencies)) { - const resolution = packageJson.resolutions?.[name] - const specifier = resolution ? `${name}@${resolution}` : name - await command`yarn add -D ${specifier}`.withCurrentWorkingDirectory(appPath).runAsync() - } - // revert package.json & yarn.lock changes if they are versioned - const areFilesVersioned = await command`git ls-files package.json yarn.lock` - .withCurrentWorkingDirectory(appPath) - .runAsync() - if (areFilesVersioned) { - await command`git checkout package.json yarn.lock`.withCurrentWorkingDirectory(appPath).runAsync() + try { + const appPath = `test/apps/${appName}` + printLog(`Building app at ${appPath}...`) + await command`yarn install --no-immutable`.withCurrentWorkingDirectory(appPath).runAsync() + + // install peer dependencies if any + // intent: renovate does not allow to generate local packages before install + // so local packages are marked as optional peer dependencies and only installed when we build the test apps + const packageJson = JSON.parse(fs.readFileSync(path.join(appPath, 'package.json'), 'utf-8')) + if (packageJson.peerDependencies) { + // For each peer dependency, install it + for (const [name] of Object.entries(packageJson.peerDependencies)) { + const resolution = packageJson.resolutions?.[name] + const specifier = resolution ? `${name}@${resolution}` : name + await command`yarn add -D ${specifier}`.withCurrentWorkingDirectory(appPath).runAsync() + } + // revert package.json & yarn.lock changes if they are versioned + const areFilesVersioned = await command`git ls-files package.json yarn.lock` + .withCurrentWorkingDirectory(appPath) + .runAsync() + if (areFilesVersioned) { + await command`git checkout package.json yarn.lock`.withCurrentWorkingDirectory(appPath).runAsync() + } } - } - await command`yarn build`.withCurrentWorkingDirectory(appPath).runAsync() + await command`yarn build`.withCurrentWorkingDirectory(appPath).runAsync() + } catch (error) { + throw new Error(`Failed to build app '${appName}'`, { cause: error }) + } } async function buildReactRouterV6App() { diff --git a/test/e2e/lib/framework/pageSetups.ts b/test/e2e/lib/framework/pageSetups.ts index ea7c667660..abff651c19 100644 --- a/test/e2e/lib/framework/pageSetups.ts +++ b/test/e2e/lib/framework/pageSetups.ts @@ -1,4 +1,5 @@ -import { generateUUID, INTAKE_URL_PARAMETERS } from '@datadog/browser-core' +import { generateUUID } from '@datadog/browser-core' +import { INTAKE_URL_PARAMETERS } from '@datadog/js-core/transport' import type { LogsInitConfiguration } from '@datadog/browser-logs' import type { RumInitConfiguration, RemoteConfiguration } from '@datadog/browser-rum-core' import type { DebuggerInitConfiguration } from '@datadog/browser-debugger' diff --git a/tsconfig.base.json b/tsconfig.base.json index bddeee91ba..b201f80876 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -49,7 +49,8 @@ "@datadog/js-core/assembly": ["./packages/js-core/src/entries/assembly"], "@datadog/js-core/time": ["./packages/js-core/src/entries/time"], "@datadog/js-core/monitor": ["./packages/js-core/src/entries/monitor"], - "@datadog/js-core/util": ["./packages/js-core/src/entries/util"] + "@datadog/js-core/util": ["./packages/js-core/src/entries/util"], + "@datadog/js-core/transport": ["./packages/js-core/src/entries/transport"] } } } diff --git a/yarn.lock b/yarn.lock index 0409b06f86..203e5c5d46 100644 --- a/yarn.lock +++ b/yarn.lock @@ -508,6 +508,7 @@ __metadata: dependencies: "@datadog/browser-core": "npm:7.4.0" "@datadog/browser-rum-core": "npm:7.4.0" + "@datadog/js-core": "npm:0.0.4" peerDependencies: "@datadog/browser-logs": 7.4.0 peerDependenciesMeta: @@ -568,6 +569,7 @@ __metadata: "@datadog/browser-logs": "workspace:*" "@datadog/browser-rum": "workspace:*" "@datadog/browser-rum-core": "workspace:*" + "@datadog/js-core": "workspace:*" "@mantine/core": "npm:9.3.2" "@mantine/hooks": "npm:9.3.2" "@tabler/icons-react": "npm:3.44.0" @@ -593,7 +595,7 @@ __metadata: languageName: unknown linkType: soft -"@datadog/js-core@npm:0.0.4, @datadog/js-core@workspace:packages/js-core": +"@datadog/js-core@npm:0.0.4, @datadog/js-core@workspace:*, @datadog/js-core@workspace:packages/js-core": version: 0.0.0-use.local resolution: "@datadog/js-core@workspace:packages/js-core" languageName: unknown