diff --git a/packages/core/src/domain/telemetry/telemetryEvent.types.ts b/packages/core/src/domain/telemetry/telemetryEvent.types.ts index 574760c044..6e0dfcfd53 100644 --- a/packages/core/src/domain/telemetry/telemetryEvent.types.ts +++ b/packages/core/src/domain/telemetry/telemetryEvent.types.ts @@ -539,7 +539,7 @@ export type TelemetryBrowserFeaturesUsage = /** * Schema of mobile specific features usage */ -export type TelemetryMobileFeaturesUsage = AddViewLoadingTime +export type TelemetryMobileFeaturesUsage = AddViewLoadingTime | TrackWebView /** * Schema of common properties of Telemetry events @@ -640,6 +640,18 @@ export interface CommonTelemetryProperties { * Model of the device */ model?: string + /** + * Number of device processors + */ + readonly processor_count?: number + /** + * Total RAM in megabytes + */ + readonly total_ram?: number + /** + * Whether the device is considered a low RAM device (Android) + */ + readonly is_low_ram_device?: boolean [k: string]: unknown } /** @@ -905,3 +917,10 @@ export interface AddViewLoadingTime { overwritten: boolean [k: string]: unknown } +export interface TrackWebView { + /** + * trackWebView API + */ + feature: 'trackWebView' + [k: string]: unknown +} diff --git a/packages/rum-core/src/rumEvent.types.ts b/packages/rum-core/src/rumEvent.types.ts index 2f1ca40bd4..bec99ef31c 100644 --- a/packages/rum-core/src/rumEvent.types.ts +++ b/packages/rum-core/src/rumEvent.types.ts @@ -104,7 +104,7 @@ export type RumActionEvent = CommonProperties & /** * View properties */ - readonly view: { + readonly view?: { /** * Is the action starting in the foreground (focus in browser) */ @@ -175,9 +175,6 @@ export type RumTransitionEvent = CommonProperties & { * RUM event type */ readonly type: 'transition' - view: { - [k: string]: unknown - } /** * Stream properties */ @@ -482,7 +479,7 @@ export type RumErrorEvent = CommonProperties & /** * View properties */ - readonly view: { + readonly view?: { /** * Is the error starting in the foreground (focus in browser) */ @@ -507,9 +504,6 @@ export type RumLongTaskEvent = CommonProperties & * RUM event type */ readonly type: 'long_task' - view: { - [k: string]: unknown - } /** * Long Task properties */ @@ -634,9 +628,6 @@ export type RumResourceEvent = CommonProperties & * RUM event type */ readonly type: 'resource' - view: { - [k: string]: unknown - } /** * Resource properties */ @@ -841,7 +832,7 @@ export type RumResourceEvent = CommonProperties & /** * Type of the GraphQL operation */ - readonly operationType: 'query' | 'mutation' | 'subscription' + readonly operationType?: 'query' | 'mutation' | 'subscription' /** * Name of the GraphQL operation */ @@ -1329,13 +1320,10 @@ export type RumVitalEvent = RumVitalDurationEvent | RumVitalOperationStepEvent * Schema for a duration vital event. */ export type RumVitalDurationEvent = RumVitalEventCommonProperties & { - view: { - [k: string]: unknown - } /** * Vital properties */ - readonly vital: { + readonly vital?: { /** * Type of the vital. */ @@ -1381,13 +1369,10 @@ export type RumVitalEventCommonProperties = CommonProperties & * Schema for a vital operation step event. */ export type RumVitalOperationStepEvent = RumVitalEventCommonProperties & { - view: { - [k: string]: unknown - } /** * Vital properties */ - readonly vital: { + readonly vital?: { /** * Type of the vital. */ @@ -1484,7 +1469,7 @@ export interface CommonProperties { /** * View properties */ - readonly view?: { + readonly view: { /** * UUID of the view */ @@ -1699,6 +1684,18 @@ export interface CommonProperties { * Current screen brightness level (0.0 to 1.0). */ readonly brightness_level?: number + /** + * Number of device processors + */ + readonly processor_count?: number + /** + * Total RAM in megabytes + */ + readonly total_ram?: number + /** + * Whether the device is considered a low RAM device (Android) + */ + readonly is_low_ram_device?: boolean [k: string]: unknown } /** diff --git a/packages/rum/src/domain/profiling/profiler.spec.ts b/packages/rum/src/domain/profiling/profiler.spec.ts index 6cff19e348..b07e91ab55 100644 --- a/packages/rum/src/domain/profiling/profiler.spec.ts +++ b/packages/rum/src/domain/profiling/profiler.spec.ts @@ -19,9 +19,10 @@ import { mockViewHistory, } from '../../../../rum-core/test' import { mockProfiler } from '../../../test' +import type { BrowserProfilerTrace } from '../../types' import { mockedTrace } from './test-utils/mockedTrace' import { createRumProfiler } from './profiler' -import type { ProfilerTrace, RUMProfiler, RumProfilerTrace } from './types' +import type { ProfilerTrace, RUMProfiler } from './types' import type { ProfilingContextManager } from './profilingContext' import { startProfilingContext } from './profilingContext' import type { ProfileEventPayload } from './transport/assembly' @@ -48,7 +49,7 @@ describe('profiler', () => { profiler: RUMProfiler notifyPerformanceEntries: (entries: RumPerformanceEntry[]) => void profilingContextManager: ProfilingContextManager - mockedRumProfilerTrace: RumProfilerTrace + mockedRumProfilerTrace: BrowserProfilerTrace longTaskContexts: { findLongTasks: jasmine.Spy } } { const sessionManager = createRumSessionManagerMock().setId('session-id-1') @@ -59,7 +60,7 @@ describe('profiler', () => { const mockProfilerTrace: ProfilerTrace = deepClone(mockedTrace) - const mockedRumProfilerTrace: RumProfilerTrace = Object.assign(mockProfilerTrace, { + const mockedRumProfilerTrace: BrowserProfilerTrace = Object.assign(mockProfilerTrace, { startClocks: { relative: relativeNow(), timeStamp: timeStampNow(), diff --git a/packages/rum/src/domain/profiling/profiler.ts b/packages/rum/src/domain/profiling/profiler.ts index 2ab3c7a0a4..6d28d68406 100644 --- a/packages/rum/src/domain/profiling/profiler.ts +++ b/packages/rum/src/domain/profiling/profiler.ts @@ -22,14 +22,13 @@ import type { ViewHistory, } from '@datadog/browser-rum-core' import { createFormDataTransport, LifeCycleEventType } from '@datadog/browser-rum-core' +import type { BrowserProfilerTrace, RumViewEntry } from '../../types' import type { - RumProfilerTrace, RumProfilerInstance, Profiler, RUMProfiler, RUMProfilerConfiguration, RumProfilerStoppedInstance, - RumViewEntry, } from './types' import { getNumberOfSamples } from './utils/getNumberOfSamples' import type { ProfilingContextManager } from './profilingContext' @@ -290,7 +289,7 @@ export function createRumProfiler( instance.views.push(viewEntry) } - function handleProfilerTrace(trace: RumProfilerTrace): void { + function handleProfilerTrace(trace: BrowserProfilerTrace): void { // Find current session to assign it to the Profile. const sessionId = session.findTrackedSession()?.id const payload = assembleProfilingPayload(trace, configuration, sessionId) diff --git a/packages/rum/src/domain/profiling/transport/assembly.ts b/packages/rum/src/domain/profiling/transport/assembly.ts index 4aeeddb02e..723d20c486 100644 --- a/packages/rum/src/domain/profiling/transport/assembly.ts +++ b/packages/rum/src/domain/profiling/transport/assembly.ts @@ -1,30 +1,15 @@ import { buildTags, currentDrift } from '@datadog/browser-core' import type { RumConfiguration } from '@datadog/browser-rum-core' -import type { RumProfilerTrace } from '../types' +import type { BrowserProfileEvent, BrowserProfilerTrace } from '../../../types' import { buildProfileEventAttributes } from './buildProfileEventAttributes' -import type { ProfileEventAttributes } from './buildProfileEventAttributes' - -export interface ProfileEvent extends ProfileEventAttributes { - attachments: string[] - start: string // ISO date - end: string // ISO date - family: 'chrome' - runtime: 'chrome' - format: 'json' - version: 4 - tags_profiler: string - _dd: { - clock_drift: number - } -} export interface ProfileEventPayload { - event: ProfileEvent - 'wall-time.json': RumProfilerTrace + event: BrowserProfileEvent + 'wall-time.json': BrowserProfilerTrace } export function assembleProfilingPayload( - profilerTrace: RumProfilerTrace, + profilerTrace: BrowserProfilerTrace, configuration: RumConfiguration, sessionId: string | undefined ): ProfileEventPayload { @@ -37,15 +22,15 @@ export function assembleProfilingPayload( } function buildProfileEvent( - profilerTrace: RumProfilerTrace, + profilerTrace: BrowserProfilerTrace, configuration: RumConfiguration, sessionId: string | undefined -): ProfileEvent { +): ProfileEventPayload['event'] { const tags = buildTags(configuration) // TODO: get that from the tagContext hook const profileAttributes = buildProfileEventAttributes(profilerTrace, configuration.applicationId, sessionId) const profileEventTags = buildProfileEventTags(tags) - const profileEvent: ProfileEvent = { + const profileEvent: ProfileEventPayload['event'] = { ...profileAttributes, attachments: ['wall-time.json'], start: new Date(profilerTrace.startClocks.timeStamp).toISOString(), diff --git a/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.spec.ts b/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.spec.ts index 63a2fc7a17..b18f7e20e7 100644 --- a/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.spec.ts +++ b/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.spec.ts @@ -1,8 +1,8 @@ import { clocksOrigin } from '@datadog/browser-core' import { RumPerformanceEntryType } from '@datadog/browser-rum-core' import type { LongTaskContext } from '@datadog/browser-rum-core' -import type { RumProfilerTrace, RumViewEntry } from '../types' -import { buildProfileEventAttributes, type ProfileEventAttributes } from './buildProfileEventAttributes' +import type { BrowserProfilerTrace, RumViewEntry } from '../../../types' +import { buildProfileEventAttributes, ProfileEventAttributes } from './buildProfileEventAttributes' describe('buildProfileEventAttributes', () => { const applicationId = 'test-app-id' @@ -27,7 +27,7 @@ describe('buildProfileEventAttributes', () => { } } - function createMockProfilerTrace(overrides: Partial = {}): RumProfilerTrace { + function createMockProfilerTrace(overrides: Partial = {}): BrowserProfilerTrace { return { startClocks: clocksOrigin(), endClocks: clocksOrigin(), diff --git a/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.ts b/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.ts index 33836bd31e..4c9b84f82b 100644 --- a/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.ts +++ b/packages/rum/src/domain/profiling/transport/buildProfileEventAttributes.ts @@ -1,10 +1,20 @@ -import type { RumProfilerTrace, RumViewEntry } from '../types' +import type { BrowserProfilerTrace, RumViewEntry } from '../../../types' +// Type definition for the subset of BrowserProfileEvent properties that are built by this function export interface ProfileEventAttributes { - application: { id: string } - session?: { id: string } - view?: { id: string[]; name: string[] } - long_task?: { id: string[] } + application: { + id: string + } + session?: { + id: string + } + view?: { + id: string[] + name: string[] + } + long_task?: { + id: string[] + } } /** @@ -16,36 +26,36 @@ export interface ProfileEventAttributes { * @returns Additional attributes. */ export function buildProfileEventAttributes( - profilerTrace: RumProfilerTrace, + profilerTrace: BrowserProfilerTrace, applicationId: string, sessionId: string | undefined ): ProfileEventAttributes { - const attributes: ProfileEventAttributes = { - application: { - id: applicationId, - }, - } - if (sessionId) { - attributes.session = { - id: sessionId, - } - } - // Extract view ids and names from the profiler trace and add them as attributes of the profile event. // This will be used to filter the profiles by @view.id and/or @view.name. const { ids, names } = extractViewIdsAndNames(profilerTrace.views) - if (ids.length) { - attributes.view = { - id: ids, - name: names, - } - } const longTaskIds: string[] = profilerTrace.longTasks.map((longTask) => longTask.id).filter((id) => id !== undefined) - if (longTaskIds.length) { - attributes.long_task = { id: longTaskIds } + const attributes: ProfileEventAttributes = { + application: { + id: applicationId, + }, + ...(sessionId && { + session: { + id: sessionId, + }, + }), + ...(ids.length && { + view: { + id: ids, + name: names, + }, + }), + ...(longTaskIds.length && { + long_task: { id: longTaskIds }, + }), } + return attributes } diff --git a/packages/rum/src/domain/profiling/types/rumProfiler.types.ts b/packages/rum/src/domain/profiling/types/rumProfiler.types.ts index ac6210f5b4..77e02eedec 100644 --- a/packages/rum/src/domain/profiling/types/rumProfiler.types.ts +++ b/packages/rum/src/domain/profiling/types/rumProfiler.types.ts @@ -1,15 +1,7 @@ import type { TimeoutId, ClocksState } from '@datadog/browser-core' import type { LongTaskContext } from '@datadog/browser-rum-core' -import type { ProfilerTrace, Profiler } from './profilerApi.types' - -export interface RumViewEntry { - /** Detected start time of view */ - readonly startClocks: ClocksState - /** RUM view id */ - readonly viewId: string - /** RUM view name */ - readonly viewName: string | undefined -} +import type { RumViewEntry } from '../../../types' +import type { Profiler } from './profilerApi.types' /** * Additional data recorded during profiling session @@ -21,17 +13,6 @@ export interface RumProfilerEnrichmentData { readonly views: RumViewEntry[] } -export interface RumProfilerTrace extends ProfilerTrace, RumProfilerEnrichmentData { - /** High resolution time when profiler trace started, relative to the profiling session's time origin */ - readonly startClocks: ClocksState - /** High resolution time when profiler trace ended, relative to the profiling session's time origin */ - readonly endClocks: ClocksState - /** Time origin of the profiling session */ - readonly clocksOrigin: ClocksState - /** Sample interval in milliseconds */ - readonly sampleInterval: number -} - /** * Describes profiler session state when it's stopped */ diff --git a/packages/rum/src/types/index.ts b/packages/rum/src/types/index.ts index 411eab48a1..607c54e7ca 100644 --- a/packages/rum/src/types/index.ts +++ b/packages/rum/src/types/index.ts @@ -1,2 +1,3 @@ export type * from './sessionReplay' export * from './sessionReplayConstants' +export type * from './profiling' diff --git a/packages/rum/src/types/profiling.ts b/packages/rum/src/types/profiling.ts new file mode 100644 index 0000000000..bf751ccade --- /dev/null +++ b/packages/rum/src/types/profiling.ts @@ -0,0 +1,229 @@ +/* eslint-disable */ +/** + * DO NOT MODIFY IT BY HAND. Run `yarn json-schemas:sync` instead. + */ + +/** + * Schema of Browser SDK Profiling types. + */ +export type BrowserProfiling = BrowserProfileEvent | BrowserProfilerTrace +/** + * Schema of the Browser SDK Profile Event payload. + */ +export type BrowserProfileEvent = ProfileCommonProperties & { + /** + * Profile data format. + */ + readonly format: 'json' + /** + * Datadog internal metadata. + */ + readonly _dd: { + /** + * Clock drift value. Used by Browser SDK. + */ + readonly clock_drift: number + } +} + +/** + * Schema of a Profile Event metadata. Contains attributes shared by all profiles. + */ +export interface ProfileCommonProperties { + /** + * Application properties. + */ + readonly application: { + /** + * Application ID. + */ + readonly id: string + } + /** + * Session properties. + */ + readonly session?: { + /** + * Session ID. + */ + readonly id: string + } + /** + * View properties. + */ + readonly view?: { + /** + * Array of view IDs. + */ + readonly id: string[] + /** + * Array of view names. + */ + readonly name: string[] + } + /** + * Long task properties. + */ + readonly long_task?: { + /** + * Array of long task IDs. + */ + readonly id: string[] + } + /** + * List of attachment filenames. + */ + readonly attachments: string[] + /** + * Start time as ISO 8601 date string (yyyy-MM-dd'T'HH:mm:ss.SSS'Z'). + */ + readonly start: string + /** + * End time marking when the profile ended, as ISO 8601 date string (yyyy-MM-dd'T'HH:mm:ss.SSS'Z'). + */ + readonly end: string + /** + * Profiler family. + */ + readonly family: 'android' | 'chrome' | 'ios' + /** + * Runtime environment. + */ + readonly runtime: 'android' | 'chrome' | 'ios' + /** + * Profile ingestion event version. + */ + readonly version: number + /** + * Comma-separated profiler tags. + */ + readonly tags_profiler: string +} +/** + * Schema of a RUM profiler trace containing profiling data enriched with RUM context. + */ +export interface BrowserProfilerTrace { + /** + * An array of profiler resources. + */ + readonly resources: string[] + /** + * An array of profiler frames. + */ + readonly frames: ProfilerFrame[] + /** + * An array of profiler stacks. + */ + readonly stacks: ProfilerStack[] + /** + * An array of profiler samples. + */ + readonly samples: ProfilerSample[] + startClocks: ClocksState + endClocks: ClocksState + clocksOrigin: ClocksState + /** + * Sample interval in milliseconds. + */ + readonly sampleInterval: number + /** + * List of detected long tasks. + */ + readonly longTasks: RumProfilerLongTaskEntry[] + /** + * List of detected navigation entries. + */ + readonly views: RumViewEntry[] +} +/** + * Schema of a profiler frame from the JS Self-Profiling API. + */ +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 +} +/** + * Schema of a profiler stack from the JS Self-Profiling API. + */ +export interface ProfilerStack { + /** + * Index in the trace.stacks array. + */ + readonly parentId?: number + /** + * Index in the trace.frames array. + */ + readonly frameId: number +} +/** + * Schema of a profiler sample from the JS Self-Profiling API. + */ +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 +} +/** + * Schema of timing state with both relative and absolute timestamps. + */ +export interface ClocksState { + /** + * Time relative to navigation start in milliseconds. + */ + readonly relative: number + /** + * Epoch time in milliseconds. + */ + readonly timeStamp: number +} +/** + * Schema of a long task entry recorded during profiling. + */ +export interface RumProfilerLongTaskEntry { + /** + * RUM Long Task id. + */ + readonly id?: string + /** + * Duration in ns of the long task or long animation frame. + */ + readonly duration: number + /** + * Type of the event: long task or long animation frame + */ + readonly entryType: 'longtask' | 'long-animation-frame' + startClocks: ClocksState +} +/** + * Schema of a RUM view entry recorded during profiling. + */ +export interface RumViewEntry { + startClocks: ClocksState + /** + * RUM view id. + */ + readonly viewId: string + /** + * RUM view name. + */ + readonly viewName?: string +} diff --git a/packages/rum/src/types/sessionReplay.ts b/packages/rum/src/types/sessionReplay.ts index e01454c291..bceb0a14bf 100644 --- a/packages/rum/src/types/sessionReplay.ts +++ b/packages/rum/src/types/sessionReplay.ts @@ -45,6 +45,7 @@ export type BrowserRecord = | ViewEndRecord | VisualViewportRecord | FrustrationRecord + | BrowserChangeRecord /** * Browser-specific. Schema of a Record type which contains the full snapshot of a screen. */ @@ -333,6 +334,262 @@ export type FrustrationRecord = SlotSupportedCommonRecordSchema & { recordIds: number[] } } +/** + * Browser-specific. Schema of a record type which represents changes using a compact encoding. (Experimental; subject to change.) + */ +export type BrowserChangeRecord = SlotSupportedCommonRecordSchema & { + /** + * The type of this Record. + */ + readonly type: 12 + data: Change[] + id?: number +} +/** + * Browser-specific. Schema representing an individual change within a BrowserChangeData collection. + */ +export type Change = + | [0, ...AddStringChange[]] + | [1, ...AddNodeChange[]] + | [2, ...RemoveNodeChange[]] + | [3, ...AttributeChange[]] + | [4, ...TextChange[]] + | [5, ...SizeChange[]] + | [6, ...ScrollPositionChange[]] + | [7, ...AddStyleSheetChange[]] + | [8, ...AttachedStyleSheetsChange[]] + | [9, ...MediaPlaybackStateChange[]] + | [10, ...VisualViewportChange[]] +/** + * Browser-specific. Schema representing the addition of a string to the string table. + */ +export type AddStringChange = string +/** + * Browser-specific. Schema representing the addition of a new node to the document. + */ +export type AddNodeChange = + | AddCDataSectionNodeChange + | AddDocTypeNodeChange + | AddDocumentNodeChange + | AddDocumentFragmentNodeChange + | AddElementNodeChange + | AddShadowRootNodeChange + | AddTextNodeChange +/** + * Schema representing the addition of a new #cdata-section node. + * + * @minItems 2 + */ +export type AddCDataSectionNodeChange = [InsertionPoint, '#cdata-section' | StringReference] +/** + * Browser-specific. Schema representing the insertion point of a node which is being added to the document. + */ +export type InsertionPoint = + | AppendChildInsertionPoint + | InsertAfterPreviousInsertionPoint + | InsertBeforeInsertionPoint + | RootInsertionPoint +/** + * A positive integer insertion point. Inserting a node at positive integer N indicates that the new node's parent is the node with an id N lower than the new node, and that we should insert the new node at the end of its parent's child list, as if the DOM method appendChild() was being used. + */ +export type AppendChildInsertionPoint = number +/** + * A zero insertion point. Inserting a node at zero indicates that the new node should be inserted after the node with an id one lower than the new node, as if the DOM method after() is being used. Using a zero insertion point repeatedly is thus a quick way to insert a sequence of sibling elements. + */ +export type InsertAfterPreviousInsertionPoint = 0 +/** + * A negative integer insertion point. Inserting a node at negative integer -N indicates that the new node's next sibling is the node with an id N lower than the new node, and that we should insert the new node before its next sibling, as if the DOM method insertBefore() was being used. + */ +export type InsertBeforeInsertionPoint = number +/** + * A null insertion point, indicating that the node should be inserted at the root of the document. + */ +export type RootInsertionPoint = null +/** + * Browser-specific. Schema representing a string, expressed as an index into the string table. + */ +export type StringReference = number +/** + * Schema representing the addition of a new #doctype node, using the format [#doctype, name, public ID, system ID]. + * + * @minItems 5 + */ +export type AddDocTypeNodeChange = [ + InsertionPoint, + '#doctype' | StringReference, + StringOrStringReference, + StringOrStringReference, + StringOrStringReference +] +/** + * Browser-specific. Schema representing a string, either expressed as a literal or as an index into the string table. + */ +export type StringOrStringReference = string | StringReference +/** + * Schema representing the addition of a new #document node. + * + * @minItems 2 + */ +export type AddDocumentNodeChange = [InsertionPoint, '#document' | StringReference] +/** + * Schema representing the addition of a new #document-fragment node. + * + * @minItems 2 + */ +export type AddDocumentFragmentNodeChange = [InsertionPoint, '#document-fragment' | StringReference] +/** + * Schema representing the addition of a new element node. + * + * @minItems 2 + */ +export type AddElementNodeChange = [InsertionPoint, string | StringReference, ...AttributeAssignment[]] +/** + * Schema representing an assignment of a value to an attribute. The format is [name, value]. + * + * @minItems 2 + */ +export type AttributeAssignment = [StringOrStringReference, StringOrStringReference] +/** + * Schema representing the addition of a new #shadow-root node. + * + * @minItems 2 + */ +export type AddShadowRootNodeChange = [InsertionPoint, '#shadow-root' | StringReference] +/** + * Schema representing the addition of a new #text node. + * + * @minItems 3 + */ +export type AddTextNodeChange = [InsertionPoint, '#text' | StringReference, StringOrStringReference] +/** + * Browser-specific. Schema representing the removal of a node from the document. + */ +export type RemoveNodeChange = number +/** + * Browser-specific. Schema representing a change to an node's attributes. + * + * @minItems 1 + */ +export type AttributeChange = [NodeId, ...AttributeAssignmentOrDeletion[]] +/** + * Browser-specific. Schema representing the ID of a DOM node. + */ +export type NodeId = number +/** + * Schema representing a change to an attribute, either by assignment of a new value or by deletion of the attribute. + */ +export type AttributeAssignmentOrDeletion = AttributeAssignment | AttributeDeletion +/** + * Schema representing the deletion of an attribute. + * + * @minItems 1 + */ +export type AttributeDeletion = [StringOrStringReference] +/** + * Browser-specific. Schema representing a change to the text content of a #text node. + * + * @minItems 2 + */ +export type TextChange = [NodeId, StringOrStringReference] +/** + * Browser-specific. Schema representing a change in an element's size. + * + * @minItems 3 + */ +export type SizeChange = [NodeId, number, number] +/** + * Browser-specific. Schema representing a scroll position change. + * + * @minItems 3 + */ +export type ScrollPositionChange = [NodeId, number, number] +/** + * Browser-specific. Schema representing the addition of a new stylesheet to the document. + */ +export type AddStyleSheetChange = StyleSheetSnapshot +/** + * Schema representing a snapshot of a CSS stylesheet. + * + * @minItems 1 + */ +export type StyleSheetSnapshot = + | [StyleSheetRules] + | [StyleSheetRules, StyleSheetMediaList] + | [StyleSheetRules, StyleSheetMediaList, boolean] +/** + * Schema representing a CSS stylesheet's rules, encoded either as a single string or as an array containing a separate string for each rule. + */ +export type StyleSheetRules = StringOrStringReference | StringOrStringReference[] +/** + * If non-empty, the list of medias for which this stylesheet is active. Defaults to the empty list if not present. + */ +export type StyleSheetMediaList = StringOrStringReference[] +/** + * Browser-specific. Schema representing a change to the stylesheets attached to a DOM node. For or