From c69b1488d3209aa5d0dde342e7acafef081a7dd6 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 3 Jul 2026 18:06:36 +0200 Subject: [PATCH 1/3] =?UTF-8?q?=E2=9C=A8=20add=20Context=20type=20to=20@da?= =?UTF-8?q?tadog/js-core/assembly?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ports the Context/ContextValue/ContextArray types from browser-core's tools/serialisation/context.ts, closing the TODO in the js-core RFC for event/context payload typing used by electron-sdk and openfeature-js-client. --- packages/js-core/api/assembly.api.md | 13 +++++++++++++ packages/js-core/src/assembly/context.ts | 18 ++++++++++++++++++ packages/js-core/src/assembly/index.ts | 1 + 3 files changed, 32 insertions(+) create mode 100644 packages/js-core/src/assembly/context.ts diff --git a/packages/js-core/api/assembly.api.md b/packages/js-core/api/assembly.api.md index 498a6e46ee..47e5e82e8a 100644 --- a/packages/js-core/api/assembly.api.md +++ b/packages/js-core/api/assembly.api.md @@ -4,6 +4,19 @@ ```ts +// @public +export interface Context { + // (undocumented) + [x: string]: ContextValue; +} + +// @public +export interface ContextArray extends Array { +} + +// @public +export type ContextValue = string | number | boolean | Context | ContextArray | undefined | null; + // @public export function createHook(): Hook; diff --git a/packages/js-core/src/assembly/context.ts b/packages/js-core/src/assembly/context.ts new file mode 100644 index 0000000000..d043684322 --- /dev/null +++ b/packages/js-core/src/assembly/context.ts @@ -0,0 +1,18 @@ +/** + * A generic, JSON-serializable key/value bag used to type event and context payloads assembled by + * {@link Hook}. + */ +export interface Context { + [x: string]: ContextValue +} + +/** A value that can be stored in a {@link Context}: a JSON-serializable primitive, nested context, or array. */ +export type ContextValue = string | number | boolean | Context | ContextArray | undefined | null + +/** + * An array of {@link ContextValue}s, as found nested inside a {@link Context}. + * + * @hidden + */ +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface ContextArray extends Array {} diff --git a/packages/js-core/src/assembly/index.ts b/packages/js-core/src/assembly/index.ts index 516962b1ac..7a413204b5 100644 --- a/packages/js-core/src/assembly/index.ts +++ b/packages/js-core/src/assembly/index.ts @@ -1 +1,2 @@ export * from './hook' +export type * from './context' From 6f914c32c8c202c64ce53e101550cbd346598091 Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Fri, 3 Jul 2026 20:17:42 +0200 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9B=20fix=20TypeScript=204.1.6=20c?= =?UTF-8?q?ompatibility=20for=20Context=20type=20export?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 'export type * from' is only supported starting TypeScript 4.5; js-core targets TS 4.1.6 as its minimum supported version. Switch to named type exports, which are supported since TS 3.8. --- packages/js-core/src/assembly/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/js-core/src/assembly/index.ts b/packages/js-core/src/assembly/index.ts index 7a413204b5..9e46b4b4b3 100644 --- a/packages/js-core/src/assembly/index.ts +++ b/packages/js-core/src/assembly/index.ts @@ -1,2 +1,2 @@ export * from './hook' -export type * from './context' +export type { Context, ContextValue, ContextArray } from './context' From 63c4b148ca53012fe12fe11736edd2775e49b87f Mon Sep 17 00:00:00 2001 From: Thomas Lebeau Date: Wed, 8 Jul 2026 06:54:23 +0200 Subject: [PATCH 3/3] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20migrate=20browser-core?= =?UTF-8?q?=20to=20@datadog/js-core/assembly's=20Context=20type?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that Context/ContextValue/ContextArray live in @datadog/js-core/assembly, delete the duplicated browser-core/tools/serialisation/context.ts and point every internal consumer, plus browser-core's own public re-export in index.ts, at the js-core version instead. Downstream packages (browser-rum-core, browser-logs, browser-rum, ...) are unaffected: they still import Context from '@datadog/browser-core', which now just re-exports the js-core type under the hood. No behavior change: Context is a pure type, identical in both places. --- .../browser-core/src/domain/context/contextManager.ts | 2 +- .../src/domain/context/contextUtils.spec.ts | 2 +- .../browser-core/src/domain/context/contextUtils.ts | 2 +- .../src/domain/context/storeContextManager.spec.ts | 2 +- .../src/domain/context/storeContextManager.ts | 2 +- .../src/domain/contexts/rumInternalContext.type.ts | 2 +- .../src/domain/contexts/telemetrySessionContext.ts | 3 +-- packages/browser-core/src/domain/error/error.ts | 2 +- packages/browser-core/src/domain/error/error.types.ts | 2 +- .../src/domain/telemetry/telemetry.spec.ts | 2 +- .../browser-core/src/domain/telemetry/telemetry.ts | 3 +-- packages/browser-core/src/index.ts | 2 +- .../browser-core/src/tools/serialisation/context.ts | 11 ----------- .../browser-core/src/tools/serialisation/sanitize.ts | 2 +- packages/browser-core/src/transport/batch.ts | 2 +- packages/browser-core/src/transport/httpRequest.ts | 2 +- 16 files changed, 15 insertions(+), 28 deletions(-) delete mode 100644 packages/browser-core/src/tools/serialisation/context.ts diff --git a/packages/browser-core/src/domain/context/contextManager.ts b/packages/browser-core/src/domain/context/contextManager.ts index 0efa37f415..67ac7bef74 100644 --- a/packages/browser-core/src/domain/context/contextManager.ts +++ b/packages/browser-core/src/domain/context/contextManager.ts @@ -1,6 +1,6 @@ import { deepClone } from '@datadog/js-core/util' +import type { Context } from '@datadog/js-core/assembly' import { sanitize } from '../../tools/serialisation/sanitize' -import type { Context } from '../../tools/serialisation/context' import { Observable } from '../../tools/observable' import { display } from '../../tools/display' import { checkContext } from './contextUtils' diff --git a/packages/browser-core/src/domain/context/contextUtils.spec.ts b/packages/browser-core/src/domain/context/contextUtils.spec.ts index d2332f25dc..29d330e74d 100644 --- a/packages/browser-core/src/domain/context/contextUtils.spec.ts +++ b/packages/browser-core/src/domain/context/contextUtils.spec.ts @@ -1,5 +1,5 @@ +import type { Context } from '@datadog/js-core/assembly' import { display } from '../../tools/display' -import type { Context } from '../../tools/serialisation/context' import type { Account } from '../contexts/accountContext' import type { User } from '../contexts/userContext' import { checkContext } from './contextUtils' diff --git a/packages/browser-core/src/domain/context/contextUtils.ts b/packages/browser-core/src/domain/context/contextUtils.ts index 24ea8c8828..56b9887cf2 100644 --- a/packages/browser-core/src/domain/context/contextUtils.ts +++ b/packages/browser-core/src/domain/context/contextUtils.ts @@ -1,5 +1,5 @@ import { getType } from '@datadog/js-core/util' -import type { Context } from '../../tools/serialisation/context' +import type { Context } from '@datadog/js-core/assembly' import { display } from '../../tools/display' /** diff --git a/packages/browser-core/src/domain/context/storeContextManager.spec.ts b/packages/browser-core/src/domain/context/storeContextManager.spec.ts index f3e16ad362..e3c9804c21 100644 --- a/packages/browser-core/src/domain/context/storeContextManager.spec.ts +++ b/packages/browser-core/src/domain/context/storeContextManager.spec.ts @@ -1,6 +1,6 @@ +import type { Context } from '@datadog/js-core/assembly' import { createNewEvent } from '../../../test' import { DOM_EVENT } from '../../browser/addEventListener' -import type { Context } from '../../tools/serialisation/context' import { storeContextManager, buildStorageKey, removeStorageListeners } from './storeContextManager' import { CustomerDataType } from './contextConstants' import { createContextManager } from './contextManager' diff --git a/packages/browser-core/src/domain/context/storeContextManager.ts b/packages/browser-core/src/domain/context/storeContextManager.ts index bb9b237a96..eb2e35c1a3 100644 --- a/packages/browser-core/src/domain/context/storeContextManager.ts +++ b/packages/browser-core/src/domain/context/storeContextManager.ts @@ -1,6 +1,6 @@ import { combine } from '@datadog/js-core/util' +import type { Context } from '@datadog/js-core/assembly' import { addEventListener, DOM_EVENT } from '../../browser/addEventListener' -import type { Context } from '../../tools/serialisation/context' import { isEmptyObject, tryJsonParse } from '../../tools/utils/objectUtils' import type { ContextManager } from './contextManager' import type { CustomerDataType } from './contextConstants' diff --git a/packages/browser-core/src/domain/contexts/rumInternalContext.type.ts b/packages/browser-core/src/domain/contexts/rumInternalContext.type.ts index e555d23051..5afb736089 100644 --- a/packages/browser-core/src/domain/contexts/rumInternalContext.type.ts +++ b/packages/browser-core/src/domain/contexts/rumInternalContext.type.ts @@ -1,4 +1,4 @@ -import type { Context } from '../../tools/serialisation/context' +import type { Context } from '@datadog/js-core/assembly' export interface RumInternalContext extends Context { application_id: string diff --git a/packages/browser-core/src/domain/contexts/telemetrySessionContext.ts b/packages/browser-core/src/domain/contexts/telemetrySessionContext.ts index a9d11d8fe8..bf9e199b5b 100644 --- a/packages/browser-core/src/domain/contexts/telemetrySessionContext.ts +++ b/packages/browser-core/src/domain/contexts/telemetrySessionContext.ts @@ -1,7 +1,6 @@ -import type { Hook } from '@datadog/js-core/assembly' +import type { Context, Hook } from '@datadog/js-core/assembly' import { SKIPPED } from '@datadog/js-core/assembly' import type { SessionManager } from '../session/sessionManager' -import type { Context } from '../../tools/serialisation/context' export function startTelemetrySessionContext( assembleTelemetryHook: Hook, diff --git a/packages/browser-core/src/domain/error/error.ts b/packages/browser-core/src/domain/error/error.ts index 719bcfc84e..e54a258ab3 100644 --- a/packages/browser-core/src/domain/error/error.ts +++ b/packages/browser-core/src/domain/error/error.ts @@ -1,7 +1,7 @@ import type { ClocksState } from '@datadog/js-core/time' import { isIndexableObject } from '@datadog/js-core/util' +import type { Context } from '@datadog/js-core/assembly' import { sanitize } from '../../tools/serialisation/sanitize' -import type { Context } from '../../tools/serialisation/context' import { jsonStringify } from '../../tools/serialisation/jsonStringify' import type { StackTrace } from '../../tools/stackTrace/computeStackTrace' import { computeStackTrace } from '../../tools/stackTrace/computeStackTrace' diff --git a/packages/browser-core/src/domain/error/error.types.ts b/packages/browser-core/src/domain/error/error.types.ts index f9f670a2df..576809825a 100644 --- a/packages/browser-core/src/domain/error/error.types.ts +++ b/packages/browser-core/src/domain/error/error.types.ts @@ -1,5 +1,5 @@ import type { ClocksState } from '@datadog/js-core/time' -import type { Context } from '../../tools/serialisation/context' +import type { Context } from '@datadog/js-core/assembly' // TS v4.6 introduced Error.cause[1] typed as `Error`. TS v4.8 changed Error.cause to be // `unknown`[2]. diff --git a/packages/browser-core/src/domain/telemetry/telemetry.spec.ts b/packages/browser-core/src/domain/telemetry/telemetry.spec.ts index de7cbbb4bb..a6139bc35d 100644 --- a/packages/browser-core/src/domain/telemetry/telemetry.spec.ts +++ b/packages/browser-core/src/domain/telemetry/telemetry.spec.ts @@ -1,5 +1,6 @@ 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 type { Context } from '@datadog/js-core/assembly' import { NO_ERROR_STACK_PRESENT_MESSAGE } from '../error/error' import { callMonitored } from '../../tools/monitor' import type { ExperimentalFeature } from '../../tools/experimentalFeatures' @@ -13,7 +14,6 @@ import { registerCleanupTask, createNewEvent, } from '../../../test' -import type { Context } from '../../tools/serialisation/context' import { Observable } from '../../tools/observable' import type { StackTrace } from '../../tools/stackTrace/computeStackTrace' import { diff --git a/packages/browser-core/src/domain/telemetry/telemetry.ts b/packages/browser-core/src/domain/telemetry/telemetry.ts index a3c780d462..6d16639fc0 100644 --- a/packages/browser-core/src/domain/telemetry/telemetry.ts +++ b/packages/browser-core/src/domain/telemetry/telemetry.ts @@ -1,6 +1,6 @@ import { clocksNow } from '@datadog/js-core/time' import { getDebugMode, combine, globalObject, isWorkerEnvironment } from '@datadog/js-core/util' -import type { Hook } from '@datadog/js-core/assembly' +import type { Context, Hook } from '@datadog/js-core/assembly' import type { RecursivePartial } from '@datadog/js-core/util' import { DISCARDED } from '@datadog/js-core/assembly' import { @@ -10,7 +10,6 @@ import { 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/isError' import { toStackTraceString } from '../../tools/stackTrace/handlingStack' import { getExperimentalFeatures } from '../../tools/experimentalFeatures' diff --git a/packages/browser-core/src/index.ts b/packages/browser-core/src/index.ts index efead8da41..f6f229a5a9 100644 --- a/packages/browser-core/src/index.ts +++ b/packages/browser-core/src/index.ts @@ -101,7 +101,7 @@ export { } from './domain/error/error' export { NonErrorPrefix } from './domain/error/error.types' export { buildDebugIdByUrl, getSourceCodeContext } from './domain/sourceCodeContext' -export type { Context, ContextArray, ContextValue } from './tools/serialisation/context' +export type { Context, ContextArray, ContextValue } from '@datadog/js-core/assembly' export { getCookie, getInitCookie, setCookie, deleteCookie, resetInitCookies } from './browser/cookie' export { isCookieStoreSupported } from './browser/cookieAccess' export type { WeakRef, WeakRefConstructor } from './browser/browser.types' diff --git a/packages/browser-core/src/tools/serialisation/context.ts b/packages/browser-core/src/tools/serialisation/context.ts deleted file mode 100644 index 690eb66f12..0000000000 --- a/packages/browser-core/src/tools/serialisation/context.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface Context { - [x: string]: ContextValue -} - -export type ContextValue = string | number | boolean | Context | ContextArray | undefined | null - -/** - * @hidden - */ -// eslint-disable-next-line @typescript-eslint/no-empty-object-type -export interface ContextArray extends Array {} diff --git a/packages/browser-core/src/tools/serialisation/sanitize.ts b/packages/browser-core/src/tools/serialisation/sanitize.ts index ae83e39b4f..91c45f7cc6 100644 --- a/packages/browser-core/src/tools/serialisation/sanitize.ts +++ b/packages/browser-core/src/tools/serialisation/sanitize.ts @@ -1,6 +1,6 @@ +import type { Context, ContextArray, ContextValue } from '@datadog/js-core/assembly' import { display } from '../display' import { ONE_KIBI_BYTE } from '../utils/byteUtils' -import type { Context, ContextArray, ContextValue } from './context' import type { ObjectWithToJsonMethod } from './jsonStringify' import { detachToJsonMethod } from './jsonStringify' diff --git a/packages/browser-core/src/transport/batch.ts b/packages/browser-core/src/transport/batch.ts index 99a79cbdac..08ce12de70 100644 --- a/packages/browser-core/src/transport/batch.ts +++ b/packages/browser-core/src/transport/batch.ts @@ -1,6 +1,6 @@ import type { EndpointBuilder } from '@datadog/js-core/transport' +import type { Context } from '@datadog/js-core/assembly' import { DOCS_TROUBLESHOOTING, MORE_DETAILS, display } from '../tools/display' -import type { Context } from '../tools/serialisation/context' import { objectValues } from '../tools/utils/polyfills' import { isPageExitReason, createPageMayExitObservable } from '../browser/pageMayExitObservable' import { jsonStringify } from '../tools/serialisation/jsonStringify' diff --git a/packages/browser-core/src/transport/httpRequest.ts b/packages/browser-core/src/transport/httpRequest.ts index d7252b4091..1c0e663813 100644 --- a/packages/browser-core/src/transport/httpRequest.ts +++ b/packages/browser-core/src/transport/httpRequest.ts @@ -1,5 +1,5 @@ import type { EndpointBuilder, TransportRetryInfo } from '@datadog/js-core/transport' -import type { Context } from '../tools/serialisation/context' +import type { Context } from '@datadog/js-core/assembly' import { fetch } from '../browser/fetch' import { monitor, monitorError } from '../tools/monitor' import { Observable } from '../tools/observable'