From 7c0de6d653dfe9e9a8b2f3b2266f949ff4f8cd05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Mon, 30 May 2022 18:29:32 +0200 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=90=9B=20[RUMF-1267]=20remove=20depen?= =?UTF-8?q?dency=20loop=20from=20eventBridge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/src/transport/eventBridge.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/transport/eventBridge.ts b/packages/core/src/transport/eventBridge.ts index 25da490bb4..224e22cf6b 100644 --- a/packages/core/src/transport/eventBridge.ts +++ b/packages/core/src/transport/eventBridge.ts @@ -1,4 +1,4 @@ -import { getGlobalObject } from '..' +import { getGlobalObject } from '../tools/utils' export interface BrowserWindowWithEventBridge extends Window { DatadogEventBridge?: DatadogEventBridge From 39cbb6fb09112b686a144f0d6651995405d9fd56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Mon, 30 May 2022 18:37:13 +0200 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=F0=9F=90=9B=20[RUMF-1?= =?UTF-8?q?267]=20remove=20dependency=20loop=20in=20recorder=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit reorganize recorder types moving most of the src/domain/record/types in src/types. I wanted to do this for a long time, because I'm always confused when looking for a specific type of the recorder. Now everything is at the same level. --- .../domain/record/mutationObserver.spec.ts | 5 +- .../rum/src/domain/record/mutationObserver.ts | 5 +- packages/rum/src/domain/record/observer.ts | 6 +- packages/rum/src/domain/record/record.ts | 14 +- .../rum/src/domain/record/serialize.spec.ts | 4 +- packages/rum/src/domain/record/serialize.ts | 18 +- packages/rum/src/domain/record/types.ts | 223 ++--------------- packages/rum/src/entries/internal.ts | 16 -- packages/rum/src/types.ts | 105 -------- packages/rum/src/types/index.ts | 3 + packages/rum/src/types/record.ts | 236 ++++++++++++++++++ packages/rum/src/types/segment.ts | 28 +++ packages/rum/src/types/serializedNode.ts | 47 ++++ packages/rum/test/htmlAst.ts | 2 +- packages/rum/test/utils.ts | 5 +- .../scenario/recorder/recorder.scenario.ts | 6 +- 16 files changed, 355 insertions(+), 368 deletions(-) delete mode 100644 packages/rum/src/types.ts create mode 100644 packages/rum/src/types/index.ts create mode 100644 packages/rum/src/types/record.ts create mode 100644 packages/rum/src/types/segment.ts create mode 100644 packages/rum/src/types/serializedNode.ts diff --git a/packages/rum/src/domain/record/mutationObserver.spec.ts b/packages/rum/src/domain/record/mutationObserver.spec.ts index 3458917c70..33fba728df 100644 --- a/packages/rum/src/domain/record/mutationObserver.spec.ts +++ b/packages/rum/src/domain/record/mutationObserver.spec.ts @@ -7,10 +7,11 @@ import { PRIVACY_ATTR_VALUE_MASK, PRIVACY_ATTR_VALUE_MASK_USER_INPUT, } from '../../constants' +import type { AttributeMutation, Attributes } from '../../types' +import { NodeType } from '../../types' import { serializeDocument } from './serialize' import { sortAddedAndMovedNodes, startMutationObserver, MutationController } from './mutationObserver' -import type { AttributeMutation, Attributes, MutationCallBack } from './types' -import { NodeType } from './types' +import type { MutationCallBack } from './types' describe('startMutationCollection', () => { let sandbox: HTMLElement diff --git a/packages/rum/src/domain/record/mutationObserver.ts b/packages/rum/src/domain/record/mutationObserver.ts index dbda47eff0..a7d481adbb 100644 --- a/packages/rum/src/domain/record/mutationObserver.ts +++ b/packages/rum/src/domain/record/mutationObserver.ts @@ -2,6 +2,7 @@ import type { DefaultPrivacyLevel } from '@datadog/browser-core' import { monitor, noop } from '@datadog/browser-core' import { getMutationObserverConstructor } from '@datadog/browser-rum-core' import { NodePrivacyLevel } from '../../constants' +import type { AddedNodeMutation, AttributeMutation, RemovedNodeMutation, TextMutation } from '../../types' import { getNodePrivacyLevel, getTextContent } from './privacy' import type { NodeWithSerializedNode } from './serializationUtils' import { @@ -12,15 +13,11 @@ import { } from './serializationUtils' import { serializeNodeWithId, serializeAttribute } from './serialize' import type { - AddedNodeMutation, - AttributeMutation, RumAttributesMutationRecord, RumCharacterDataMutationRecord, RumChildListMutationRecord, MutationCallBack, RumMutationRecord, - RemovedNodeMutation, - TextMutation, } from './types' import { forEach } from './utils' import { createMutationBatch } from './mutationBatch' diff --git a/packages/rum/src/domain/record/observer.ts b/packages/rum/src/domain/record/observer.ts index 9dcc18bfa0..c626d64c3b 100644 --- a/packages/rum/src/domain/record/observer.ts +++ b/packages/rum/src/domain/record/observer.ts @@ -11,12 +11,13 @@ import { noop, } from '@datadog/browser-core' import { NodePrivacyLevel } from '../../constants' +import type { InputState, MousePosition, MouseInteractionParam } from '../../types' +import { IncrementalSource, MediaInteractions, MouseInteractions } from '../../types' import { getNodePrivacyLevel, shouldMaskNode } from './privacy' import { getElementInputValue, getSerializedNodeId, hasSerializedNode } from './serializationUtils' import type { FocusCallback, InputCallback, - InputState, ListenerHandler, MediaInteractionCallback, MouseInteractionCallBack, @@ -27,10 +28,7 @@ import type { StyleSheetRuleCallback, ViewportResizeCallback, VisualViewportResizeCallback, - MousePosition, - MouseInteractionParam, } from './types' -import { IncrementalSource, MediaInteractions, MouseInteractions } from './types' import { forEach, isTouchEvent } from './utils' import type { MutationController } from './mutationObserver' import { startMutationObserver } from './mutationObserver' diff --git a/packages/rum/src/domain/record/record.ts b/packages/rum/src/domain/record/record.ts index b35b37e5ad..2f45bf536e 100644 --- a/packages/rum/src/domain/record/record.ts +++ b/packages/rum/src/domain/record/record.ts @@ -1,14 +1,8 @@ import { assign, timeStampNow } from '@datadog/browser-core' -import type { IncrementalSnapshotRecord } from '../../types' -import { RecordType } from '../../types' -import { serializeDocument } from './serialize' -import { initObservers } from './observer' -import { IncrementalSource } from './types' import type { + IncrementalSnapshotRecord, IncrementalData, InputData, - RecordAPI, - RecordOptions, MediaInteractionData, MouseInteractionData, MousemoveData, @@ -16,7 +10,11 @@ import type { ScrollData, StyleSheetRuleData, ViewportResizeData, -} from './types' +} from '../../types' +import { RecordType, IncrementalSource } from '../../types' +import { serializeDocument } from './serialize' +import { initObservers } from './observer' +import type { RecordAPI, RecordOptions } from './types' import { MutationController } from './mutationObserver' import { getVisualViewport, getScrollX, getScrollY, getWindowHeight, getWindowWidth } from './viewports' diff --git a/packages/rum/src/domain/record/serialize.spec.ts b/packages/rum/src/domain/record/serialize.spec.ts index 0938b3b175..541987d0e3 100644 --- a/packages/rum/src/domain/record/serialize.spec.ts +++ b/packages/rum/src/domain/record/serialize.spec.ts @@ -14,6 +14,8 @@ import { AST_MASK_USER_INPUT, generateLeanSerializedDoc, } from '../../../test/htmlAst' +import type { ElementNode, SerializedNodeWithId, TextNode } from '../../types' +import { NodeType } from '../../types' import { hasSerializedNode } from './serializationUtils' import type { SerializeOptions } from './serialize' import { @@ -24,8 +26,6 @@ import { serializeAttribute, } from './serialize' import { MAX_ATTRIBUTE_VALUE_CHAR_LENGTH } from './privacy' -import type { ElementNode, SerializedNodeWithId, TextNode } from './types' -import { NodeType } from './types' const DEFAULT_OPTIONS: SerializeOptions = { document, diff --git a/packages/rum/src/domain/record/serialize.ts b/packages/rum/src/domain/record/serialize.ts index 707d99bd0b..1bc6d80ce8 100644 --- a/packages/rum/src/domain/record/serialize.ts +++ b/packages/rum/src/domain/record/serialize.ts @@ -6,13 +6,6 @@ import { CENSORED_STRING_MARK, CENSORED_IMG_MARK, } from '../../constants' -import { - getTextContent, - shouldMaskNode, - reducePrivacyLevel, - getNodeSelfPrivacyLevel, - MAX_ATTRIBUTE_VALUE_CHAR_LENGTH, -} from './privacy' import type { SerializedNode, SerializedNodeWithId, @@ -21,8 +14,15 @@ import type { ElementNode, TextNode, CDataNode, -} from './types' -import { NodeType } from './types' +} from '../../types' +import { NodeType } from '../../types' +import { + getTextContent, + shouldMaskNode, + reducePrivacyLevel, + getNodeSelfPrivacyLevel, + MAX_ATTRIBUTE_VALUE_CHAR_LENGTH, +} from './privacy' import { getSerializedNodeId, setSerializedNodeId, getElementInputValue } from './serializationUtils' import { forEach } from './utils' diff --git a/packages/rum/src/domain/record/types.ts b/packages/rum/src/domain/record/types.ts index b64550044d..f584c4e7d4 100644 --- a/packages/rum/src/domain/record/types.ts +++ b/packages/rum/src/domain/record/types.ts @@ -1,67 +1,20 @@ import type { DefaultPrivacyLevel, TimeStamp } from '@datadog/browser-core' -import type { FocusRecord, VisualViewportRecord, Record } from '../../types' +import type { + FocusRecord, + VisualViewportRecord, + Record, + MousePosition, + IncrementalSource, + MouseInteractionParam, + ScrollPosition, + StyleSheetRuleParam, + ViewportResizeDimention, + MediaInteractionParam, + MutationPayload, + InputState, +} from '../../types' import type { MutationController } from './mutationObserver' -export const IncrementalSource = { - Mutation: 0, - MouseMove: 1, - MouseInteraction: 2, - Scroll: 3, - ViewportResize: 4, - Input: 5, - TouchMove: 6, - MediaInteraction: 7, - StyleSheetRule: 8, - // CanvasMutation : 9, - // Font : 10, -} as const - -export type IncrementalSource = typeof IncrementalSource[keyof typeof IncrementalSource] - -export type MutationData = { - source: typeof IncrementalSource.Mutation -} & MutationPayload - -export interface MousemoveData { - source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove - positions: MousePosition[] -} - -export type MouseInteractionData = { - source: typeof IncrementalSource.MouseInteraction -} & MouseInteractionParam - -export type ScrollData = { - source: typeof IncrementalSource.Scroll -} & ScrollPosition - -export type ViewportResizeData = { - source: typeof IncrementalSource.ViewportResize -} & ViewportResizeDimention - -export type InputData = { - source: typeof IncrementalSource.Input - id: number -} & InputState - -export type MediaInteractionData = { - source: typeof IncrementalSource.MediaInteraction -} & MediaInteractionParam - -export type StyleSheetRuleData = { - source: typeof IncrementalSource.StyleSheetRule -} & StyleSheetRuleParam - -export type IncrementalData = - | MutationData - | MousemoveData - | MouseInteractionData - | ScrollData - | ViewportResizeData - | InputData - | MediaInteractionData - | StyleSheetRuleData - export interface RecordOptions { emit?: (record: Record) => void defaultPrivacyLevel: DefaultPrivacyLevel @@ -118,44 +71,12 @@ export interface TextCursor { node: Node value: string | null } -export interface TextMutation { - id: number - value: string | null -} - export interface AttributeCursor { node: Node attributes: { [key: string]: string | null } } -export interface AttributeMutation { - id: number - attributes: { - [key: string]: string | null - } -} - -export interface RemovedNodeMutation { - parentId: number - id: number -} - -export interface AddedNodeMutation { - parentId: number - // Newly recorded mutations will not have previousId any more, just for compatibility - previousId?: number | null - nextId: number | null - node: SerializedNodeWithId -} - -export interface MutationPayload { - texts: TextMutation[] - attributes: AttributeMutation[] - removes: RemovedNodeMutation[] - adds: AddedNodeMutation[] -} - export type MutationCallBack = (m: MutationPayload) => void export type MousemoveCallBack = ( @@ -163,84 +84,16 @@ export type MousemoveCallBack = ( source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove ) => void -export interface MousePosition { - x: number - y: number - id: number - timeOffset: number -} - -export const MouseInteractions = { - MouseUp: 0, - MouseDown: 1, - Click: 2, - ContextMenu: 3, - DblClick: 4, - Focus: 5, - Blur: 6, - TouchStart: 7, - TouchEnd: 9, -} as const - -export type MouseInteractions = typeof MouseInteractions[keyof typeof MouseInteractions] - -export interface MouseInteractionParam { - type: MouseInteractions - id: number - x: number - y: number -} - export type MouseInteractionCallBack = (d: MouseInteractionParam) => void -export interface ScrollPosition { - id: number - x: number - y: number -} - export type ScrollCallback = (p: ScrollPosition) => void -export interface StyleSheetAddRule { - rule: string - index?: number | number[] -} - -export interface StyleSheetDeleteRule { - index: number | number[] -} - -export interface StyleSheetRuleParam { - id: number - removes?: StyleSheetDeleteRule[] - adds?: StyleSheetAddRule[] -} - export type StyleSheetRuleCallback = (s: StyleSheetRuleParam) => void -export interface ViewportResizeDimention { - width: number - height: number -} - export type ViewportResizeCallback = (d: ViewportResizeDimention) => void -export type InputState = { text: string } | { isChecked: boolean } - export type InputCallback = (v: InputState & { id: number }) => void -export const MediaInteractions = { - Play: 0, - Pause: 1, -} as const - -export type MediaInteractions = typeof MediaInteractions[keyof typeof MediaInteractions] - -export interface MediaInteractionParam { - type: MediaInteractions - id: number -} - export type MediaInteractionCallback = (p: MediaInteractionParam) => void export type FocusCallback = (data: FocusRecord['data']) => void @@ -248,51 +101,3 @@ export type FocusCallback = (data: FocusRecord['data']) => void export type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void export type ListenerHandler = () => void - -export const enum NodeType { - Document, - DocumentType, - Element, - Text, - CDATA, - Comment, -} - -export type DocumentNode = { - type: NodeType.Document - childNodes: SerializedNodeWithId[] -} - -export type DocumentTypeNode = { - type: NodeType.DocumentType - name: string - publicId: string - systemId: string -} - -export type Attributes = { - [key: string]: string | number | boolean -} - -export type ElementNode = { - type: NodeType.Element - tagName: string - attributes: Attributes - childNodes: SerializedNodeWithId[] - isSVG?: true -} - -export type TextNode = { - type: NodeType.Text - textContent: string - isStyle?: true -} - -export type CDataNode = { - type: NodeType.CDATA - textContent: '' -} - -export type SerializedNode = DocumentNode | DocumentTypeNode | ElementNode | TextNode | CDataNode - -export type SerializedNodeWithId = SerializedNode & { id: number } diff --git a/packages/rum/src/entries/internal.ts b/packages/rum/src/entries/internal.ts index cabc56a84e..c08a2b80e4 100644 --- a/packages/rum/src/entries/internal.ts +++ b/packages/rum/src/entries/internal.ts @@ -5,22 +5,6 @@ * WARNING: this module is not intended for public usages, and won't follow semver for breaking * changes. */ -export { - MutationData, - MousemoveData, - MouseInteractionData, - ScrollData, - ViewportResizeData, - InputData, - MediaInteractionData, - StyleSheetRuleData, - MediaInteractions, - MouseInteractions, - AddedNodeMutation, - MousePosition, - RemovedNodeMutation, -} from '../domain/record' - export { PRIVACY_ATTR_NAME, PRIVACY_ATTR_VALUE_HIDDEN, PRIVACY_CLASS_HIDDEN, NodePrivacyLevel } from '../constants' export * from '../types' diff --git a/packages/rum/src/types.ts b/packages/rum/src/types.ts deleted file mode 100644 index 51f04b0753..0000000000 --- a/packages/rum/src/types.ts +++ /dev/null @@ -1,105 +0,0 @@ -import type { TimeStamp } from '@datadog/browser-core' -import type { IncrementalData, SerializedNodeWithId } from './domain/record' - -export { IncrementalSource, MutationData, ViewportResizeData, ScrollData } from './domain/record' - -export interface Segment extends SegmentMetadata { - records: Record[] -} - -export interface SegmentMetadata extends SegmentContext { - start: number - end: number - has_full_snapshot: boolean - records_count: number - creation_reason: CreationReason - index_in_view: number -} - -export interface SegmentContext { - application: { id: string } - session: { id: string } - view: { id: string } -} - -export type CreationReason = - | 'init' - | 'segment_duration_limit' - | 'segment_bytes_limit' - | 'view_change' - | 'before_unload' - | 'visibility_hidden' - -export type Record = - | FullSnapshotRecord - | IncrementalSnapshotRecord - | MetaRecord - | FocusRecord - | ViewEndRecord - | VisualViewportRecord - -export const RecordType = { - FullSnapshot: 2, - IncrementalSnapshot: 3, - Meta: 4, - Focus: 6, - ViewEnd: 7, - VisualViewport: 8, -} as const - -export type RecordType = typeof RecordType[keyof typeof RecordType] - -export interface FullSnapshotRecord { - type: typeof RecordType.FullSnapshot - timestamp: TimeStamp - data: { - node: SerializedNodeWithId - initialOffset: { - top: number - left: number - } - } -} - -export interface IncrementalSnapshotRecord { - type: typeof RecordType.IncrementalSnapshot - timestamp: TimeStamp - data: IncrementalData -} - -export interface MetaRecord { - type: typeof RecordType.Meta - timestamp: TimeStamp - data: { - href: string - width: number - height: number - } -} - -export interface FocusRecord { - type: typeof RecordType.Focus - timestamp: TimeStamp - data: { - has_focus: boolean - } -} - -export interface ViewEndRecord { - type: typeof RecordType.ViewEnd - timestamp: TimeStamp -} - -export interface VisualViewportRecord { - type: typeof RecordType.VisualViewport - timestamp: TimeStamp - data: { - scale: number - offsetLeft: number - offsetTop: number - pageLeft: number - pageTop: number - height: number - width: number - } -} diff --git a/packages/rum/src/types/index.ts b/packages/rum/src/types/index.ts new file mode 100644 index 0000000000..9a04a42150 --- /dev/null +++ b/packages/rum/src/types/index.ts @@ -0,0 +1,3 @@ +export * from './segment' +export * from './record' +export * from './serializedNode' diff --git a/packages/rum/src/types/record.ts b/packages/rum/src/types/record.ts new file mode 100644 index 0000000000..7f133bd710 --- /dev/null +++ b/packages/rum/src/types/record.ts @@ -0,0 +1,236 @@ +import type { TimeStamp } from '@datadog/browser-core' +import type { SerializedNodeWithId } from './serializedNode' + +export type Record = + | FullSnapshotRecord + | IncrementalSnapshotRecord + | MetaRecord + | FocusRecord + | ViewEndRecord + | VisualViewportRecord + +export const RecordType = { + FullSnapshot: 2, + IncrementalSnapshot: 3, + Meta: 4, + Focus: 6, + ViewEnd: 7, + VisualViewport: 8, +} as const + +export type RecordType = typeof RecordType[keyof typeof RecordType] + +export interface FullSnapshotRecord { + type: typeof RecordType.FullSnapshot + timestamp: TimeStamp + data: { + node: SerializedNodeWithId + initialOffset: { + top: number + left: number + } + } +} + +export interface IncrementalSnapshotRecord { + type: typeof RecordType.IncrementalSnapshot + timestamp: TimeStamp + data: IncrementalData +} + +export interface MetaRecord { + type: typeof RecordType.Meta + timestamp: TimeStamp + data: { + href: string + width: number + height: number + } +} + +export interface FocusRecord { + type: typeof RecordType.Focus + timestamp: TimeStamp + data: { + has_focus: boolean + } +} + +export interface ViewEndRecord { + type: typeof RecordType.ViewEnd + timestamp: TimeStamp +} + +export interface VisualViewportRecord { + type: typeof RecordType.VisualViewport + timestamp: TimeStamp + data: { + scale: number + offsetLeft: number + offsetTop: number + pageLeft: number + pageTop: number + height: number + width: number + } +} + +export const IncrementalSource = { + Mutation: 0, + MouseMove: 1, + MouseInteraction: 2, + Scroll: 3, + ViewportResize: 4, + Input: 5, + TouchMove: 6, + MediaInteraction: 7, + StyleSheetRule: 8, + // CanvasMutation : 9, + // Font : 10, +} as const + +export type IncrementalSource = typeof IncrementalSource[keyof typeof IncrementalSource] + +export type MutationData = { + source: typeof IncrementalSource.Mutation +} & MutationPayload + +export interface MousemoveData { + source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove + positions: MousePosition[] +} + +export type MouseInteractionData = { + source: typeof IncrementalSource.MouseInteraction +} & MouseInteractionParam + +export type ScrollData = { + source: typeof IncrementalSource.Scroll +} & ScrollPosition + +export type ViewportResizeData = { + source: typeof IncrementalSource.ViewportResize +} & ViewportResizeDimention + +export type InputData = { + source: typeof IncrementalSource.Input + id: number +} & InputState + +export type MediaInteractionData = { + source: typeof IncrementalSource.MediaInteraction +} & MediaInteractionParam + +export type StyleSheetRuleData = { + source: typeof IncrementalSource.StyleSheetRule +} & StyleSheetRuleParam + +export type IncrementalData = + | MutationData + | MousemoveData + | MouseInteractionData + | ScrollData + | ViewportResizeData + | InputData + | MediaInteractionData + | StyleSheetRuleData + +export interface MutationPayload { + texts: TextMutation[] + attributes: AttributeMutation[] + removes: RemovedNodeMutation[] + adds: AddedNodeMutation[] +} + +export interface TextMutation { + id: number + value: string | null +} + +export interface AttributeMutation { + id: number + attributes: { + [key: string]: string | null + } +} + +export interface RemovedNodeMutation { + parentId: number + id: number +} + +export interface AddedNodeMutation { + parentId: number + // Newly recorded mutations will not have previousId any more, just for compatibility + previousId?: number | null + nextId: number | null + node: SerializedNodeWithId +} + +export interface MousePosition { + x: number + y: number + id: number + timeOffset: number +} + +export interface MouseInteractionParam { + type: MouseInteractions + id: number + x: number + y: number +} + +export const MouseInteractions = { + MouseUp: 0, + MouseDown: 1, + Click: 2, + ContextMenu: 3, + DblClick: 4, + Focus: 5, + Blur: 6, + TouchStart: 7, + TouchEnd: 9, +} as const + +export type MouseInteractions = typeof MouseInteractions[keyof typeof MouseInteractions] + +export interface ScrollPosition { + id: number + x: number + y: number +} + +export interface ViewportResizeDimention { + width: number + height: number +} + +export type InputState = { text: string } | { isChecked: boolean } + +export const MediaInteractions = { + Play: 0, + Pause: 1, +} as const + +export type MediaInteractions = typeof MediaInteractions[keyof typeof MediaInteractions] + +export interface MediaInteractionParam { + type: MediaInteractions + id: number +} + +export interface StyleSheetAddRule { + rule: string + index?: number | number[] +} + +export interface StyleSheetDeleteRule { + index: number | number[] +} + +export interface StyleSheetRuleParam { + id: number + removes?: StyleSheetDeleteRule[] + adds?: StyleSheetAddRule[] +} diff --git a/packages/rum/src/types/segment.ts b/packages/rum/src/types/segment.ts new file mode 100644 index 0000000000..83911f332a --- /dev/null +++ b/packages/rum/src/types/segment.ts @@ -0,0 +1,28 @@ +import type { Record } from './record' + +export interface Segment extends SegmentMetadata { + records: Record[] +} + +export interface SegmentMetadata extends SegmentContext { + start: number + end: number + has_full_snapshot: boolean + records_count: number + creation_reason: CreationReason + index_in_view: number +} + +export interface SegmentContext { + application: { id: string } + session: { id: string } + view: { id: string } +} + +export type CreationReason = + | 'init' + | 'segment_duration_limit' + | 'segment_bytes_limit' + | 'view_change' + | 'before_unload' + | 'visibility_hidden' diff --git a/packages/rum/src/types/serializedNode.ts b/packages/rum/src/types/serializedNode.ts new file mode 100644 index 0000000000..5ef6101661 --- /dev/null +++ b/packages/rum/src/types/serializedNode.ts @@ -0,0 +1,47 @@ +export const enum NodeType { + Document, + DocumentType, + Element, + Text, + CDATA, + Comment, +} + +export type DocumentNode = { + type: NodeType.Document + childNodes: SerializedNodeWithId[] +} + +export type DocumentTypeNode = { + type: NodeType.DocumentType + name: string + publicId: string + systemId: string +} + +export type Attributes = { + [key: string]: string | number | boolean +} + +export type ElementNode = { + type: NodeType.Element + tagName: string + attributes: Attributes + childNodes: SerializedNodeWithId[] + isSVG?: true +} + +export type TextNode = { + type: NodeType.Text + textContent: string + isStyle?: true +} + +export type CDataNode = { + type: NodeType.CDATA + textContent: '' +} + +export type SerializedNode = DocumentNode | DocumentTypeNode | ElementNode | TextNode | CDataNode + +export type SerializedNodeWithId = SerializedNode & { id: number } diff --git a/packages/rum/test/htmlAst.ts b/packages/rum/test/htmlAst.ts index 0a461b9e9d..c98c7ee78b 100644 --- a/packages/rum/test/htmlAst.ts +++ b/packages/rum/test/htmlAst.ts @@ -1,5 +1,5 @@ import { objectValues } from '../../core/src' -import type { SerializedNodeWithId } from '../src/domain/record' +import type { SerializedNodeWithId } from '../src/types' import { serializeNodeWithId } from '../src/domain/record' import { NodePrivacyLevel, PRIVACY_ATTR_NAME } from '../src/constants' diff --git a/packages/rum/test/utils.ts b/packages/rum/test/utils.ts index 84d390dcb7..494e1453b4 100644 --- a/packages/rum/test/utils.ts +++ b/packages/rum/test/utils.ts @@ -6,16 +6,13 @@ import type { SerializedNode, SerializedNodeWithId, TextNode, -} from '../src/domain/record' -import { IncrementalSource, NodeType } from '../src/domain/record' -import type { FullSnapshotRecord, IncrementalSnapshotRecord, MetaRecord, VisualViewportRecord, Segment, } from '../src/types' -import { RecordType } from '../src/types' +import { RecordType, IncrementalSource, NodeType } from '../src/types' export class MockWorker implements DeflateWorker { readonly pendingMessages: DeflateWorkerAction[] = [] diff --git a/test/e2e/scenario/recorder/recorder.scenario.ts b/test/e2e/scenario/recorder/recorder.scenario.ts index 84f9067edb..834994d390 100644 --- a/test/e2e/scenario/recorder/recorder.scenario.ts +++ b/test/e2e/scenario/recorder/recorder.scenario.ts @@ -1,7 +1,5 @@ -import type { CreationReason, Segment } from '@datadog/browser-rum/src/types' -import { IncrementalSource, RecordType } from '@datadog/browser-rum/src/types' -import type { InputData, StyleSheetRuleData } from '@datadog/browser-rum/src/domain/record/types' -import { NodeType } from '@datadog/browser-rum/src/domain/record/types' +import type { InputData, StyleSheetRuleData, CreationReason, Segment } from '@datadog/browser-rum/src/types' +import { NodeType, IncrementalSource, RecordType } from '@datadog/browser-rum/src/types' import type { RumInitConfiguration } from '@datadog/browser-rum-core' import { DefaultPrivacyLevel } from '@datadog/browser-rum' From 96d5f3688e3b9ab1c51609386d7d78618a7b3a0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Mon, 30 May 2022 18:42:24 +0200 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=9A=A8=F0=9F=8F=B7=EF=B8=8F=20[RUMF-1?= =?UTF-8?q?267]=20make=20sure=20we=20don't=20export=20an=20enum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/rum/src/types/serializedNode.ts | 28 +++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/packages/rum/src/types/serializedNode.ts b/packages/rum/src/types/serializedNode.ts index 5ef6101661..a4270ab189 100644 --- a/packages/rum/src/types/serializedNode.ts +++ b/packages/rum/src/types/serializedNode.ts @@ -1,19 +1,21 @@ -export const enum NodeType { - Document, - DocumentType, - Element, - Text, - CDATA, - Comment, -} +export const NodeType = { + Document: 0, + DocumentType: 1, + Element: 2, + Text: 3, + CDATA: 4, + Comment: 5, +} as const + +export type NodeType = typeof NodeType[keyof typeof NodeType] export type DocumentNode = { - type: NodeType.Document + type: typeof NodeType.Document childNodes: SerializedNodeWithId[] } export type DocumentTypeNode = { - type: NodeType.DocumentType + type: typeof NodeType.DocumentType name: string publicId: string systemId: string @@ -24,7 +26,7 @@ export type Attributes = { } export type ElementNode = { - type: NodeType.Element + type: typeof NodeType.Element tagName: string attributes: Attributes childNodes: SerializedNodeWithId[] @@ -32,13 +34,13 @@ export type ElementNode = { } export type TextNode = { - type: NodeType.Text + type: typeof NodeType.Text textContent: string isStyle?: true } export type CDataNode = { - type: NodeType.CDATA + type: typeof NodeType.CDATA textContent: '' } From 2b97076d73d0bebaad1a6501df4d88a386c36b42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Mon, 30 May 2022 18:54:24 +0200 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=8F=B7=EF=B8=8F=20[RUMF-1267]=20renam?= =?UTF-8?q?e=20a=20few=20Record-related=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * It is a bit unusual to have *Param types. Those suffixes have been removed * MouseInteractions and MediaInteractions enums have been renamed to MouseInteractionType and MediaInteractionType to be a bit more conventional. * ViewportResizeDimention have been renamed to ViewportResizeDimension --- packages/rum/src/domain/record/observer.ts | 26 ++++++++++---------- packages/rum/src/domain/record/types.ts | 16 ++++++------- packages/rum/src/types/record.ts | 28 +++++++++++----------- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/packages/rum/src/domain/record/observer.ts b/packages/rum/src/domain/record/observer.ts index c626d64c3b..c9373b0fc0 100644 --- a/packages/rum/src/domain/record/observer.ts +++ b/packages/rum/src/domain/record/observer.ts @@ -11,8 +11,8 @@ import { noop, } from '@datadog/browser-core' import { NodePrivacyLevel } from '../../constants' -import type { InputState, MousePosition, MouseInteractionParam } from '../../types' -import { IncrementalSource, MediaInteractions, MouseInteractions } from '../../types' +import type { InputState, MousePosition, MouseInteraction } from '../../types' +import { IncrementalSource, MediaInteractionType, MouseInteractionType } from '../../types' import { getNodePrivacyLevel, shouldMaskNode } from './privacy' import { getElementInputValue, getSerializedNodeId, hasSerializedNode } from './serializationUtils' import type { @@ -113,15 +113,15 @@ function initMoveObserver(cb: MousemoveCallBack): ListenerHandler { } const eventTypeToMouseInteraction = { - [DOM_EVENT.MOUSE_UP]: MouseInteractions.MouseUp, - [DOM_EVENT.MOUSE_DOWN]: MouseInteractions.MouseDown, - [DOM_EVENT.CLICK]: MouseInteractions.Click, - [DOM_EVENT.CONTEXT_MENU]: MouseInteractions.ContextMenu, - [DOM_EVENT.DBL_CLICK]: MouseInteractions.DblClick, - [DOM_EVENT.FOCUS]: MouseInteractions.Focus, - [DOM_EVENT.BLUR]: MouseInteractions.Blur, - [DOM_EVENT.TOUCH_START]: MouseInteractions.TouchStart, - [DOM_EVENT.TOUCH_END]: MouseInteractions.TouchEnd, + [DOM_EVENT.MOUSE_UP]: MouseInteractionType.MouseUp, + [DOM_EVENT.MOUSE_DOWN]: MouseInteractionType.MouseDown, + [DOM_EVENT.CLICK]: MouseInteractionType.Click, + [DOM_EVENT.CONTEXT_MENU]: MouseInteractionType.ContextMenu, + [DOM_EVENT.DBL_CLICK]: MouseInteractionType.DblClick, + [DOM_EVENT.FOCUS]: MouseInteractionType.Focus, + [DOM_EVENT.BLUR]: MouseInteractionType.Blur, + [DOM_EVENT.TOUCH_START]: MouseInteractionType.TouchStart, + [DOM_EVENT.TOUCH_END]: MouseInteractionType.TouchEnd, } function initMouseInteractionObserver( cb: MouseInteractionCallBack, @@ -133,7 +133,7 @@ function initMouseInteractionObserver( return } const { clientX, clientY } = isTouchEvent(event) ? event.changedTouches[0] : event - const position: MouseInteractionParam = { + const position: MouseInteraction = { id: getSerializedNodeId(target), type: eventTypeToMouseInteraction[event.type as keyof typeof eventTypeToMouseInteraction], x: clientX, @@ -339,7 +339,7 @@ function initMediaInteractionObserver( } mediaInteractionCb({ id: getSerializedNodeId(target), - type: event.type === DOM_EVENT.PLAY ? MediaInteractions.Play : MediaInteractions.Pause, + type: event.type === DOM_EVENT.PLAY ? MediaInteractionType.Play : MediaInteractionType.Pause, }) } return addEventListeners(document, [DOM_EVENT.PLAY, DOM_EVENT.PAUSE], handler, { capture: true, passive: true }).stop diff --git a/packages/rum/src/domain/record/types.ts b/packages/rum/src/domain/record/types.ts index f584c4e7d4..4b83cf46a8 100644 --- a/packages/rum/src/domain/record/types.ts +++ b/packages/rum/src/domain/record/types.ts @@ -5,11 +5,11 @@ import type { Record, MousePosition, IncrementalSource, - MouseInteractionParam, + MouseInteraction, ScrollPosition, - StyleSheetRuleParam, - ViewportResizeDimention, - MediaInteractionParam, + StyleSheetRule, + ViewportResizeDimension, + MediaInteraction, MutationPayload, InputState, } from '../../types' @@ -84,17 +84,17 @@ export type MousemoveCallBack = ( source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove ) => void -export type MouseInteractionCallBack = (d: MouseInteractionParam) => void +export type MouseInteractionCallBack = (d: MouseInteraction) => void export type ScrollCallback = (p: ScrollPosition) => void -export type StyleSheetRuleCallback = (s: StyleSheetRuleParam) => void +export type StyleSheetRuleCallback = (s: StyleSheetRule) => void -export type ViewportResizeCallback = (d: ViewportResizeDimention) => void +export type ViewportResizeCallback = (d: ViewportResizeDimension) => void export type InputCallback = (v: InputState & { id: number }) => void -export type MediaInteractionCallback = (p: MediaInteractionParam) => void +export type MediaInteractionCallback = (p: MediaInteraction) => void export type FocusCallback = (data: FocusRecord['data']) => void diff --git a/packages/rum/src/types/record.ts b/packages/rum/src/types/record.ts index 7f133bd710..e6c050457a 100644 --- a/packages/rum/src/types/record.ts +++ b/packages/rum/src/types/record.ts @@ -102,7 +102,7 @@ export interface MousemoveData { export type MouseInteractionData = { source: typeof IncrementalSource.MouseInteraction -} & MouseInteractionParam +} & MouseInteraction export type ScrollData = { source: typeof IncrementalSource.Scroll @@ -110,7 +110,7 @@ export type ScrollData = { export type ViewportResizeData = { source: typeof IncrementalSource.ViewportResize -} & ViewportResizeDimention +} & ViewportResizeDimension export type InputData = { source: typeof IncrementalSource.Input @@ -119,11 +119,11 @@ export type InputData = { export type MediaInteractionData = { source: typeof IncrementalSource.MediaInteraction -} & MediaInteractionParam +} & MediaInteraction export type StyleSheetRuleData = { source: typeof IncrementalSource.StyleSheetRule -} & StyleSheetRuleParam +} & StyleSheetRule export type IncrementalData = | MutationData @@ -174,14 +174,14 @@ export interface MousePosition { timeOffset: number } -export interface MouseInteractionParam { - type: MouseInteractions +export interface MouseInteraction { + type: MouseInteractionType id: number x: number y: number } -export const MouseInteractions = { +export const MouseInteractionType = { MouseUp: 0, MouseDown: 1, Click: 2, @@ -193,7 +193,7 @@ export const MouseInteractions = { TouchEnd: 9, } as const -export type MouseInteractions = typeof MouseInteractions[keyof typeof MouseInteractions] +export type MouseInteractionType = typeof MouseInteractionType[keyof typeof MouseInteractionType] export interface ScrollPosition { id: number @@ -201,22 +201,22 @@ export interface ScrollPosition { y: number } -export interface ViewportResizeDimention { +export interface ViewportResizeDimension { width: number height: number } export type InputState = { text: string } | { isChecked: boolean } -export const MediaInteractions = { +export const MediaInteractionType = { Play: 0, Pause: 1, } as const -export type MediaInteractions = typeof MediaInteractions[keyof typeof MediaInteractions] +export type MediaInteractionType = typeof MediaInteractionType[keyof typeof MediaInteractionType] -export interface MediaInteractionParam { - type: MediaInteractions +export interface MediaInteraction { + type: MediaInteractionType id: number } @@ -229,7 +229,7 @@ export interface StyleSheetDeleteRule { index: number | number[] } -export interface StyleSheetRuleParam { +export interface StyleSheetRule { id: number removes?: StyleSheetDeleteRule[] adds?: StyleSheetAddRule[] From 6e6ac03e00d40e7bfe87ad537f5e58b5b020fc47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Zugmeyer?= Date: Tue, 31 May 2022 10:20:10 +0200 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=91=8C=20[RUMF-1267]=20collocate=20re?= =?UTF-8?q?maining=20types=20from=20domain/record/types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/rum/src/domain/record/index.ts | 1 - .../src/domain/record/mutationBatch.spec.ts | 2 +- .../rum/src/domain/record/mutationBatch.ts | 2 +- .../domain/record/mutationObserver.spec.ts | 2 +- .../rum/src/domain/record/mutationObserver.ts | 34 ++++-- .../rum/src/domain/record/observer.spec.ts | 2 +- packages/rum/src/domain/record/observer.ts | 67 +++++++++--- packages/rum/src/domain/record/record.spec.ts | 2 +- packages/rum/src/domain/record/record.ts | 14 ++- packages/rum/src/domain/record/types.ts | 103 ------------------ 10 files changed, 97 insertions(+), 132 deletions(-) diff --git a/packages/rum/src/domain/record/index.ts b/packages/rum/src/domain/record/index.ts index b8f887f4a6..c6e610d4a0 100644 --- a/packages/rum/src/domain/record/index.ts +++ b/packages/rum/src/domain/record/index.ts @@ -1,3 +1,2 @@ export { record } from './record' export { serializeNodeWithId, serializeDocument } from './serialize' -export * from './types' diff --git a/packages/rum/src/domain/record/mutationBatch.spec.ts b/packages/rum/src/domain/record/mutationBatch.spec.ts index e6ca4213ed..38322d0499 100644 --- a/packages/rum/src/domain/record/mutationBatch.spec.ts +++ b/packages/rum/src/domain/record/mutationBatch.spec.ts @@ -1,6 +1,6 @@ import { collectAsyncCalls } from '../../../test/utils' import { createMutationBatch } from './mutationBatch' -import type { RumMutationRecord } from './types' +import type { RumMutationRecord } from './mutationObserver' describe('createMutationBatch', () => { let mutationBatch: ReturnType diff --git a/packages/rum/src/domain/record/mutationBatch.ts b/packages/rum/src/domain/record/mutationBatch.ts index 384900c90e..ea473d44a6 100644 --- a/packages/rum/src/domain/record/mutationBatch.ts +++ b/packages/rum/src/domain/record/mutationBatch.ts @@ -1,5 +1,5 @@ import { noop, requestIdleCallback } from '@datadog/browser-core' -import type { RumMutationRecord } from './types' +import type { RumMutationRecord } from './mutationObserver' /** * Maximum duration to wait before processing mutations. If the browser is idle, mutations will be diff --git a/packages/rum/src/domain/record/mutationObserver.spec.ts b/packages/rum/src/domain/record/mutationObserver.spec.ts index 33fba728df..f7cb80d00c 100644 --- a/packages/rum/src/domain/record/mutationObserver.spec.ts +++ b/packages/rum/src/domain/record/mutationObserver.spec.ts @@ -11,7 +11,7 @@ import type { AttributeMutation, Attributes } from '../../types' import { NodeType } from '../../types' import { serializeDocument } from './serialize' import { sortAddedAndMovedNodes, startMutationObserver, MutationController } from './mutationObserver' -import type { MutationCallBack } from './types' +import type { MutationCallBack } from './observer' describe('startMutationCollection', () => { let sandbox: HTMLElement diff --git a/packages/rum/src/domain/record/mutationObserver.ts b/packages/rum/src/domain/record/mutationObserver.ts index a7d481adbb..d3ff3acda3 100644 --- a/packages/rum/src/domain/record/mutationObserver.ts +++ b/packages/rum/src/domain/record/mutationObserver.ts @@ -12,18 +12,38 @@ import { nodeAndAncestorsHaveSerializedNode, } from './serializationUtils' import { serializeNodeWithId, serializeAttribute } from './serialize' -import type { - RumAttributesMutationRecord, - RumCharacterDataMutationRecord, - RumChildListMutationRecord, - MutationCallBack, - RumMutationRecord, -} from './types' import { forEach } from './utils' import { createMutationBatch } from './mutationBatch' +import type { MutationCallBack } from './observer' type WithSerializedTarget = T & { target: NodeWithSerializedNode } +// https://dom.spec.whatwg.org/#interface-mutationrecord +interface RumCharacterDataMutationRecord { + type: 'characterData' + target: Node + oldValue: string | null +} + +interface RumAttributesMutationRecord { + type: 'attributes' + target: Element + oldValue: string | null + attributeName: string | null +} + +interface RumChildListMutationRecord { + type: 'childList' + target: Node + addedNodes: NodeList + removedNodes: NodeList +} + +export type RumMutationRecord = + | RumCharacterDataMutationRecord + | RumAttributesMutationRecord + | RumChildListMutationRecord + /** * Buffers and aggregate mutations generated by a MutationObserver into MutationPayload */ diff --git a/packages/rum/src/domain/record/observer.spec.ts b/packages/rum/src/domain/record/observer.spec.ts index 625e299f6b..f6f24a1105 100644 --- a/packages/rum/src/domain/record/observer.spec.ts +++ b/packages/rum/src/domain/record/observer.spec.ts @@ -1,9 +1,9 @@ import { DefaultPrivacyLevel, isIE } from '@datadog/browser-core' import { createNewEvent } from '../../../../core/test/specHelper' import { NodePrivacyLevel, PRIVACY_ATTR_NAME, PRIVACY_ATTR_VALUE_MASK_USER_INPUT } from '../../constants' +import type { InputCallback } from './observer' import { initInputObserver } from './observer' import { serializeDocument } from './serialize' -import type { InputCallback } from './types' describe('initInputObserver', () => { let stopInputObserver: () => void diff --git a/packages/rum/src/domain/record/observer.ts b/packages/rum/src/domain/record/observer.ts index c9373b0fc0..f0c1cdb678 100644 --- a/packages/rum/src/domain/record/observer.ts +++ b/packages/rum/src/domain/record/observer.ts @@ -11,24 +11,21 @@ import { noop, } from '@datadog/browser-core' import { NodePrivacyLevel } from '../../constants' -import type { InputState, MousePosition, MouseInteraction } from '../../types' +import type { + InputState, + MousePosition, + MouseInteraction, + MutationPayload, + ScrollPosition, + StyleSheetRule, + ViewportResizeDimension, + MediaInteraction, + FocusRecord, + VisualViewportRecord, +} from '../../types' import { IncrementalSource, MediaInteractionType, MouseInteractionType } from '../../types' import { getNodePrivacyLevel, shouldMaskNode } from './privacy' import { getElementInputValue, getSerializedNodeId, hasSerializedNode } from './serializationUtils' -import type { - FocusCallback, - InputCallback, - ListenerHandler, - MediaInteractionCallback, - MouseInteractionCallBack, - MousemoveCallBack, - MutationCallBack, - ObserverParam, - ScrollCallback, - StyleSheetRuleCallback, - ViewportResizeCallback, - VisualViewportResizeCallback, -} from './types' import { forEach, isTouchEvent } from './utils' import type { MutationController } from './mutationObserver' import { startMutationObserver } from './mutationObserver' @@ -46,6 +43,46 @@ const MOUSE_MOVE_OBSERVER_THRESHOLD = 50 const SCROLL_OBSERVER_THRESHOLD = 100 const VISUAL_VIEWPORT_OBSERVER_THRESHOLD = 200 +type ListenerHandler = () => void + +type MousemoveCallBack = ( + p: MousePosition[], + source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove +) => void + +export type MutationCallBack = (m: MutationPayload) => void + +type MouseInteractionCallBack = (d: MouseInteraction) => void + +type ScrollCallback = (p: ScrollPosition) => void + +type StyleSheetRuleCallback = (s: StyleSheetRule) => void + +type ViewportResizeCallback = (d: ViewportResizeDimension) => void + +export type InputCallback = (v: InputState & { id: number }) => void + +type MediaInteractionCallback = (p: MediaInteraction) => void + +type FocusCallback = (data: FocusRecord['data']) => void + +type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void + +interface ObserverParam { + defaultPrivacyLevel: DefaultPrivacyLevel + mutationController: MutationController + mutationCb: MutationCallBack + mousemoveCb: MousemoveCallBack + mouseInteractionCb: MouseInteractionCallBack + scrollCb: ScrollCallback + viewportResizeCb: ViewportResizeCallback + visualViewportResizeCb: VisualViewportResizeCallback + inputCb: InputCallback + mediaInteractionCb: MediaInteractionCallback + styleSheetRuleCb: StyleSheetRuleCallback + focusCb: FocusCallback +} + export function initObservers(o: ObserverParam): ListenerHandler { const mutationHandler = initMutationObserver(o.mutationController, o.mutationCb, o.defaultPrivacyLevel) const mousemoveHandler = initMoveObserver(o.mousemoveCb) diff --git a/packages/rum/src/domain/record/record.spec.ts b/packages/rum/src/domain/record/record.spec.ts index ec713080a7..e37546be97 100644 --- a/packages/rum/src/domain/record/record.spec.ts +++ b/packages/rum/src/domain/record/record.spec.ts @@ -4,8 +4,8 @@ import { createNewEvent } from '../../../../core/test/specHelper' import { collectAsyncCalls, recordsPerFullSnapshot } from '../../../test/utils' import type { IncrementalSnapshotRecord, FocusRecord, Record } from '../../types' import { RecordType, IncrementalSource } from '../../types' +import type { RecordAPI } from './record' import { record } from './record' -import type { RecordAPI } from './types' describe('record', () => { let sandbox: HTMLElement diff --git a/packages/rum/src/domain/record/record.ts b/packages/rum/src/domain/record/record.ts index 2f45bf536e..9726d556a8 100644 --- a/packages/rum/src/domain/record/record.ts +++ b/packages/rum/src/domain/record/record.ts @@ -1,4 +1,5 @@ import { assign, timeStampNow } from '@datadog/browser-core' +import type { DefaultPrivacyLevel, TimeStamp } from '@datadog/browser-core' import type { IncrementalSnapshotRecord, IncrementalData, @@ -10,15 +11,26 @@ import type { ScrollData, StyleSheetRuleData, ViewportResizeData, + Record, } from '../../types' import { RecordType, IncrementalSource } from '../../types' import { serializeDocument } from './serialize' import { initObservers } from './observer' -import type { RecordAPI, RecordOptions } from './types' import { MutationController } from './mutationObserver' import { getVisualViewport, getScrollX, getScrollY, getWindowHeight, getWindowWidth } from './viewports' +export interface RecordOptions { + emit?: (record: Record) => void + defaultPrivacyLevel: DefaultPrivacyLevel +} + +export interface RecordAPI { + stop: () => void + takeFullSnapshot: (timestamp?: TimeStamp) => void + flushMutations: () => void +} + export function record(options: RecordOptions): RecordAPI { const { emit } = options // runtime checks for user options diff --git a/packages/rum/src/domain/record/types.ts b/packages/rum/src/domain/record/types.ts index 4b83cf46a8..e69de29bb2 100644 --- a/packages/rum/src/domain/record/types.ts +++ b/packages/rum/src/domain/record/types.ts @@ -1,103 +0,0 @@ -import type { DefaultPrivacyLevel, TimeStamp } from '@datadog/browser-core' -import type { - FocusRecord, - VisualViewportRecord, - Record, - MousePosition, - IncrementalSource, - MouseInteraction, - ScrollPosition, - StyleSheetRule, - ViewportResizeDimension, - MediaInteraction, - MutationPayload, - InputState, -} from '../../types' -import type { MutationController } from './mutationObserver' - -export interface RecordOptions { - emit?: (record: Record) => void - defaultPrivacyLevel: DefaultPrivacyLevel -} - -export interface RecordAPI { - stop: ListenerHandler - takeFullSnapshot: (timestamp?: TimeStamp) => void - flushMutations: () => void -} - -export interface ObserverParam { - defaultPrivacyLevel: DefaultPrivacyLevel - mutationController: MutationController - mutationCb: MutationCallBack - mousemoveCb: MousemoveCallBack - mouseInteractionCb: MouseInteractionCallBack - scrollCb: ScrollCallback - viewportResizeCb: ViewportResizeCallback - visualViewportResizeCb: VisualViewportResizeCallback - inputCb: InputCallback - mediaInteractionCb: MediaInteractionCallback - styleSheetRuleCb: StyleSheetRuleCallback - focusCb: FocusCallback -} - -// https://dom.spec.whatwg.org/#interface-mutationrecord -export interface RumCharacterDataMutationRecord { - type: 'characterData' - target: Node - oldValue: string | null -} - -export interface RumAttributesMutationRecord { - type: 'attributes' - target: Element - oldValue: string | null - attributeName: string | null -} - -export interface RumChildListMutationRecord { - type: 'childList' - target: Node - addedNodes: NodeList - removedNodes: NodeList -} - -export type RumMutationRecord = - | RumCharacterDataMutationRecord - | RumAttributesMutationRecord - | RumChildListMutationRecord - -export interface TextCursor { - node: Node - value: string | null -} -export interface AttributeCursor { - node: Node - attributes: { - [key: string]: string | null - } -} -export type MutationCallBack = (m: MutationPayload) => void - -export type MousemoveCallBack = ( - p: MousePosition[], - source: typeof IncrementalSource.MouseMove | typeof IncrementalSource.TouchMove -) => void - -export type MouseInteractionCallBack = (d: MouseInteraction) => void - -export type ScrollCallback = (p: ScrollPosition) => void - -export type StyleSheetRuleCallback = (s: StyleSheetRule) => void - -export type ViewportResizeCallback = (d: ViewportResizeDimension) => void - -export type InputCallback = (v: InputState & { id: number }) => void - -export type MediaInteractionCallback = (p: MediaInteraction) => void - -export type FocusCallback = (data: FocusRecord['data']) => void - -export type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void - -export type ListenerHandler = () => void