chore: abstract types to shared package (#1593)

* chore: update types

* small typing change

* fix typing issue

* typed node

* add extra lint skip

* add changeset

---------

Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
This commit is contained in:
David Newell
2026-04-01 12:00:00 +08:00
committed by GitHub
parent 97c93a171d
commit 8d634cba97
36 changed files with 256 additions and 250 deletions

View File

@@ -0,0 +1,11 @@
---
"@rrweb/all": patch
"rrdom-nodejs": patch
"rrdom": patch
"rrweb-snapshot": major
"rrweb": patch
"@rrweb/rrweb-plugin-canvas-webrtc-record": patch
---
`NodeType` enum was moved from rrweb-snapshot to @rrweb/types
The following types where moved from rrweb-snapshot to @rrweb/types: `documentNode`, `documentTypeNode`, `legacyAttributes`, `textNode`, `cdataNode`, `commentNode`, `elementNode`, `serializedNode`, `serializedNodeWithId`, `serializedElementNodeWithId`, `serializedTextNodeWithId`, `IMirror`, `INode`, `mediaAttributes`, `attributes` and `DataURLOptions`

View File

@@ -1,6 +1,6 @@
import { NodeType } from 'rrweb-snapshot';
import { expect } from 'vitest'; import { expect } from 'vitest';
import { import {
NodeType,
EventType, EventType,
IncrementalSource, IncrementalSource,
eventWithTime, eventWithTime,

View File

@@ -1,6 +1,9 @@
import type { Mirror } from 'rrweb-snapshot';
import SimplePeer from 'simple-peer-light'; import SimplePeer from 'simple-peer-light';
import type { RecordPlugin, ICrossOriginIframeMirror } from '@rrweb/types'; import type {
RecordPlugin,
ICrossOriginIframeMirror,
IMirror,
} from '@rrweb/types';
import type { WebRTCDataChannel } from './types'; import type { WebRTCDataChannel } from './types';
export const PLUGIN_NAME = 'rrweb/canvas-webrtc@1'; export const PLUGIN_NAME = 'rrweb/canvas-webrtc@1';
@@ -25,7 +28,7 @@ export type CrossOriginIframeMessageEventContent = {
export class RRWebPluginCanvasWebRTCRecord { export class RRWebPluginCanvasWebRTCRecord {
private peer: SimplePeer.Instance | null = null; private peer: SimplePeer.Instance | null = null;
private mirror: Mirror | undefined; private mirror: IMirror<Node> | undefined;
private crossOriginIframeMirror: ICrossOriginIframeMirror | undefined; private crossOriginIframeMirror: ICrossOriginIframeMirror | undefined;
private streamMap: Map<number, MediaStream> = new Map(); private streamMap: Map<number, MediaStream> = new Map();
private incomingStreams = new Set<MediaStream>(); private incomingStreams = new Set<MediaStream>();

View File

@@ -56,6 +56,6 @@
"cssstyle": "^2.3.0", "cssstyle": "^2.3.0",
"nwsapi": "2.2.0", "nwsapi": "2.2.0",
"rrdom": "^2.0.0-alpha.17", "rrdom": "^2.0.0-alpha.17",
"rrweb-snapshot": "^2.0.0-alpha.17" "@rrweb/types": "^2.0.0-alpha.17"
} }
} }

View File

@@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { NodeType as RRNodeType } from '@rrweb/types';
import { NodeType as RRNodeType } from 'rrweb-snapshot';
import type { NWSAPI } from 'nwsapi'; import type { NWSAPI } from 'nwsapi';
import type { CSSStyleDeclaration as CSSStyleDeclarationType } from 'cssstyle'; import type { CSSStyleDeclaration as CSSStyleDeclarationType } from 'cssstyle';
import { import {
@@ -345,7 +344,7 @@ export class RRStyleElement extends RRElement {
for (const child of this.childNodes) for (const child of this.childNodes)
if (child.RRNodeType === RRNodeType.Text) if (child.RRNodeType === RRNodeType.Text)
result += (child as RRText).textContent; result += (child as RRText).textContent;
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment
this._sheet = cssom.parse(result); this._sheet = cssom.parse(result);
} }
return this._sheet; return this._sheet;

View File

@@ -4,7 +4,7 @@
import { describe, it, expect, beforeAll } from 'vitest'; import { describe, it, expect, beforeAll } from 'vitest';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import { NodeType as RRNodeType } from 'rrweb-snapshot'; import { NodeType as RRNodeType } from '@rrweb/types';
import { import {
RRCanvasElement, RRCanvasElement,
RRCDATASection, RRCDATASection,

View File

@@ -10,7 +10,7 @@
"path": "../rrdom" "path": "../rrdom"
}, },
{ {
"path": "../rrweb-snapshot" "path": "../types"
} }
] ]
} }

View File

@@ -1,11 +1,9 @@
import { import { type Mirror as NodeMirror } from 'rrweb-snapshot';
NodeType as RRNodeType, import { NodeType as RRNodeType } from '@rrweb/types';
Mirror as NodeMirror,
type elementNode,
} from 'rrweb-snapshot';
import type { import type {
canvasMutationData, canvasMutationData,
canvasEventWithTime, canvasEventWithTime,
elementNode,
inputData, inputData,
scrollData, scrollData,
styleDeclarationData, styleDeclarationData,

View File

@@ -1,4 +1,4 @@
import { NodeType as RRNodeType } from 'rrweb-snapshot'; import { NodeType as RRNodeType } from '@rrweb/types';
import { parseCSSText, camelize, toCSSText } from './style'; import { parseCSSText, camelize, toCSSText } from './style';
export interface IRRNode { export interface IRRNode {
parentElement: IRRNode | null; parentElement: IRRNode | null;

View File

@@ -1,13 +1,9 @@
import { import { createMirror as createNodeMirror } from 'rrweb-snapshot';
NodeType as RRNodeType, import type { Mirror as NodeMirror } from 'rrweb-snapshot';
createMirror as createNodeMirror, import { NodeType as RRNodeType } from '@rrweb/types';
} from 'rrweb-snapshot';
import type { import type {
Mirror as NodeMirror,
IMirror, IMirror,
serializedNodeWithId, serializedNodeWithId,
} from 'rrweb-snapshot';
import type {
canvasMutationData, canvasMutationData,
canvasEventWithTime, canvasEventWithTime,
inputData, inputData,

View File

@@ -5,12 +5,7 @@ import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as puppeteer from 'puppeteer'; import * as puppeteer from 'puppeteer';
import { vi, MockInstance } from 'vitest'; import { vi, MockInstance } from 'vitest';
import { import { createMirror, Mirror as NodeMirror } from 'rrweb-snapshot';
NodeType as RRNodeType,
createMirror,
Mirror as NodeMirror,
serializedNodeWithId,
} from 'rrweb-snapshot';
import { import {
buildFromDom, buildFromDom,
getDefaultSN, getDefaultSN,
@@ -27,8 +22,16 @@ import {
sameNodeType, sameNodeType,
} from '../src/diff'; } from '../src/diff';
import type { IRRElement, IRRNode } from '../src/document'; import type { IRRElement, IRRNode } from '../src/document';
import type { canvasMutationData, styleSheetRuleData } from '@rrweb/types'; import type {
import { EventType, IncrementalSource } from '@rrweb/types'; serializedNodeWithId,
canvasMutationData,
styleSheetRuleData,
} from '@rrweb/types';
import {
NodeType as RRNodeType,
EventType,
IncrementalSource,
} from '@rrweb/types';
const elementSn = { const elementSn = {
type: RRNodeType.Element, type: RRNodeType.Element,

View File

@@ -3,11 +3,11 @@
*/ */
import { vi, MockInstance } from 'vitest'; import { vi, MockInstance } from 'vitest';
import { import {
NodeType as RRNodeType,
createMirror, createMirror,
Mirror as NodeMirror, Mirror as NodeMirror,
serializedNodeWithId, serializedNodeWithId,
} from 'rrweb-snapshot'; } from 'rrweb-snapshot';
import { NodeType as RRNodeType } from '@rrweb/types';
import { RRDocument } from '../../src'; import { RRDocument } from '../../src';
import { diff, ReplayerHandler } from '../../src/diff'; import { diff, ReplayerHandler } from '../../src/diff';

View File

@@ -1,7 +1,7 @@
/** /**
* @jest-environment jsdom * @jest-environment jsdom
*/ */
import { NodeType as RRNodeType } from 'rrweb-snapshot'; import { NodeType as RRNodeType } from '@rrweb/types';
import { import {
BaseRRDocument, BaseRRDocument,
BaseRRDocumentType, BaseRRDocumentType,

View File

@@ -6,18 +6,17 @@ import * as path from 'path';
import * as puppeteer from 'puppeteer'; import * as puppeteer from 'puppeteer';
import { vi } from 'vitest'; import { vi } from 'vitest';
import { JSDOM } from 'jsdom'; import { JSDOM } from 'jsdom';
import { buildNodeWithSN, Mirror } from 'rrweb-snapshot';
import { import {
buildNodeWithSN,
cdataNode, cdataNode,
commentNode, commentNode,
documentNode, documentNode,
documentTypeNode, documentTypeNode,
elementNode, elementNode,
Mirror,
NodeType, NodeType,
NodeType as RRNodeType, NodeType as RRNodeType,
textNode, textNode,
} from 'rrweb-snapshot'; } from '@rrweb/types';
import { import {
buildFromDom, buildFromDom,
buildFromNode, buildFromNode,

View File

@@ -54,6 +54,7 @@
}, },
"homepage": "https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-snapshot#readme", "homepage": "https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-snapshot#readme",
"devDependencies": { "devDependencies": {
"@rrweb/types": "^2.0.0-alpha.17",
"@rrweb/utils": "^2.0.0-alpha.17", "@rrweb/utils": "^2.0.0-alpha.17",
"@types/jsdom": "^20.0.0", "@types/jsdom": "^20.0.0",
"@types/node": "^18.15.11", "@types/node": "^18.15.11",

View File

@@ -2,13 +2,11 @@ import { mediaSelectorPlugin, pseudoClassPlugin } from './css';
import { import {
type serializedNodeWithId, type serializedNodeWithId,
type serializedElementNodeWithId, type serializedElementNodeWithId,
type serializedTextNodeWithId,
NodeType, NodeType,
type tagMap,
type elementNode, type elementNode,
type BuildCache,
type legacyAttributes, type legacyAttributes,
} from './types'; } from '@rrweb/types';
import { type tagMap, type BuildCache } from './types';
import { isElement, Mirror, isNodeMetaEqual } from './utils'; import { isElement, Mirror, isNodeMetaEqual } from './utils';
import postcss from 'postcss'; import postcss from 'postcss';
@@ -90,7 +88,7 @@ export function applyCssSplits(
hackCss: boolean, hackCss: boolean,
cache: BuildCache, cache: BuildCache,
): void { ): void {
const childTextNodes: serializedTextNodeWithId[] = []; const childTextNodes = [];
for (const scn of n.childNodes) { for (const scn of n.childNodes) {
if (scn.type === NodeType.Text) { if (scn.type === NodeType.Text) {
childTextNodes.push(scn); childTextNodes.push(scn);

View File

@@ -1,20 +1,22 @@
import { import type {
type serializedNode, MaskInputOptions,
type serializedNodeWithId, SlimDOMOptions,
NodeType, MaskTextFn,
type attributes, MaskInputFn,
type MaskInputOptions, KeepIframeSrcFn,
type SlimDOMOptions, ICanvas,
type DataURLOptions, DialogAttributes,
type DialogAttributes,
type MaskTextFn,
type MaskInputFn,
type KeepIframeSrcFn,
type ICanvas,
type elementNode,
type serializedElementNodeWithId,
type mediaAttributes,
} from './types'; } from './types';
import { NodeType } from '@rrweb/types';
import type {
serializedNode,
serializedNodeWithId,
serializedElementNodeWithId,
elementNode,
attributes,
mediaAttributes,
DataURLOptions,
} from '@rrweb/types';
import { import {
Mirror, Mirror,
is2DCanvasBlank, is2DCanvasBlank,

View File

@@ -1,126 +1,9 @@
export enum NodeType { import type { serializedNodeWithId } from '@rrweb/types';
Document,
DocumentType,
Element,
Text,
CDATA,
Comment,
}
export type documentNode = {
type: NodeType.Document;
childNodes: serializedNodeWithId[];
compatMode?: string;
};
export type documentTypeNode = {
type: NodeType.DocumentType;
name: string;
publicId: string;
systemId: string;
};
type cssTextKeyAttr = {
_cssText?: string;
};
export type attributes = cssTextKeyAttr & {
[key: string]:
| string
| number // properties e.g. rr_scrollLeft or rr_mediaCurrentTime
| true // e.g. checked on <input type="radio">
| null; // an indication that an attribute was removed (during a mutation)
};
export type legacyAttributes = {
/**
* @deprecated old bug in rrweb was causing these to always be set
* @see https://github.com/rrweb-io/rrweb/pull/651
*/
selected: false;
};
export type elementNode = {
type: NodeType.Element;
tagName: string;
attributes: attributes;
childNodes: serializedNodeWithId[];
isSVG?: true;
needBlock?: boolean;
// This is a custom element or not.
isCustom?: true;
};
export type textNode = {
type: NodeType.Text;
textContent: string;
/**
* @deprecated styles are now always snapshotted against parent <style> element
* style mutations can still happen via an added textNode, but they don't need this attribute for correct replay
*/
isStyle?: true;
};
export type cdataNode = {
type: NodeType.CDATA;
textContent: '';
};
export type commentNode = {
type: NodeType.Comment;
textContent: string;
};
export type serializedNode = (
| documentNode
| documentTypeNode
| elementNode
| textNode
| cdataNode
| commentNode
) & {
rootId?: number;
isShadowHost?: boolean;
isShadow?: boolean;
};
export type serializedNodeWithId = serializedNode & { id: number };
export type serializedElementNodeWithId = Extract<
serializedNodeWithId,
Record<'type', NodeType.Element>
>;
export type serializedTextNodeWithId = Extract<
serializedNodeWithId,
Record<'type', NodeType.Text>
>;
export type tagMap = { export type tagMap = {
[key: string]: string; [key: string]: string;
}; };
export type mediaAttributes = {
rr_mediaState: 'played' | 'paused';
rr_mediaCurrentTime: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaPlaybackRate?: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaMuted?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaLoop?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaVolume?: number;
};
export type DialogAttributes = { export type DialogAttributes = {
open: string; open: string;
/** /**
@@ -138,37 +21,10 @@ export type DialogAttributes = {
// rr_open_mode_index?: number; // rr_open_mode_index?: number;
}; };
// @deprecated
export interface INode extends Node {
__sn: serializedNodeWithId;
}
export interface ICanvas extends HTMLCanvasElement { export interface ICanvas extends HTMLCanvasElement {
__context: string; __context: string;
} }
export interface IMirror<TNode> {
getId(n: TNode | undefined | null): number;
getNode(id: number): TNode | null;
getIds(): number[];
getMeta(n: TNode): serializedNodeWithId | null;
removeNodeFromMap(n: TNode): void;
has(id: number): boolean;
hasNode(node: TNode): boolean;
add(n: TNode, meta: serializedNodeWithId): void;
replace(id: number, n: TNode): void;
reset(): void;
}
export type idNodeMap = Map<number, Node>; export type idNodeMap = Map<number, Node>;
export type nodeMetaMap = WeakMap<Node, serializedNodeWithId>; export type nodeMetaMap = WeakMap<Node, serializedNodeWithId>;
@@ -210,11 +66,6 @@ export type SlimDOMOptions = Partial<{
headTitleMutations: boolean; headTitleMutations: boolean;
}>; }>;
export type DataURLOptions = Partial<{
type: string;
quality: number;
}>;
export type MaskTextFn = (text: string, element: HTMLElement | null) => string; export type MaskTextFn = (text: string, element: HTMLElement | null) => string;
export type MaskInputFn = (text: string, element: HTMLElement) => string; export type MaskInputFn = (text: string, element: HTMLElement) => string;

View File

@@ -3,6 +3,10 @@ import type {
MaskInputFn, MaskInputFn,
MaskInputOptions, MaskInputOptions,
nodeMetaMap, nodeMetaMap,
} from './types';
import { NodeType } from '@rrweb/types';
import type {
IMirror, IMirror,
serializedNodeWithId, serializedNodeWithId,
serializedNode, serializedNode,
@@ -10,9 +14,8 @@ import type {
documentTypeNode, documentTypeNode,
textNode, textNode,
elementNode, elementNode,
} from './types'; } from '@rrweb/types';
import dom from '@rrweb/utils'; import dom from '@rrweb/utils';
import { NodeType } from './types';
export function isElement(n: Node): n is Element { export function isElement(n: Node): n is Element {
return n.nodeType === n.ELEMENT_NODE; return n.nodeType === n.ELEMENT_NODE;

View File

@@ -7,12 +7,12 @@ import postcss, { type AcceptedPlugin } from 'postcss';
import { JSDOM } from 'jsdom'; import { JSDOM } from 'jsdom';
import { splitCssText, stringifyStylesheet } from './../src/utils'; import { splitCssText, stringifyStylesheet } from './../src/utils';
import { applyCssSplits } from './../src/rebuild'; import { applyCssSplits } from './../src/rebuild';
import { import type {
NodeType, serializedElementNodeWithId,
type serializedElementNodeWithId, BuildCache,
type BuildCache, textNode,
type textNode,
} from '../src/types'; } from '../src/types';
import { NodeType } from '@rrweb/types';
import { Window } from 'happy-dom'; import { Window } from 'happy-dom';
describe('css parser', () => { describe('css parser', () => {

View File

@@ -9,7 +9,7 @@ import {
buildNodeWithSN, buildNodeWithSN,
createCache, createCache,
} from '../src/rebuild'; } from '../src/rebuild';
import { NodeType } from '../src/types'; import { NodeType } from '@rrweb/types';
import { createMirror, Mirror, normalizeCssString } from '../src/utils'; import { createMirror, Mirror, normalizeCssString } from '../src/utils';
const expect = _expect as unknown as { const expect = _expect as unknown as {

View File

@@ -2,14 +2,14 @@
* @vitest-environment jsdom * @vitest-environment jsdom
*/ */
import { describe, it, test, expect } from 'vitest'; import { describe, it, test, expect } from 'vitest';
import { NodeType, serializedNode } from '../src/types';
import { import {
escapeImportStatement, escapeImportStatement,
extractFileExtension, extractFileExtension,
fixSafariColons, fixSafariColons,
isNodeMetaEqual, isNodeMetaEqual,
} from '../src/utils'; } from '../src/utils';
import type { serializedNodeWithId } from 'rrweb-snapshot'; import { NodeType } from '@rrweb/types';
import type { serializedNode, serializedNodeWithId } from '@rrweb/types';
describe('utils', () => { describe('utils', () => {
describe('isNodeMetaEqual()', () => { describe('isNodeMetaEqual()', () => {

View File

@@ -7,6 +7,9 @@
"tsBuildInfoFile": "./tsconfig.tsbuildinfo" "tsBuildInfoFile": "./tsconfig.tsbuildinfo"
}, },
"references": [ "references": [
{
"path": "../types"
},
{ {
"path": "../utils" "path": "../utils"
} }

View File

@@ -1,11 +1,12 @@
import type { Mirror, serializedNodeWithId } from 'rrweb-snapshot'; import type { Mirror } from 'rrweb-snapshot';
import { genId, NodeType } from 'rrweb-snapshot'; import { genId } from 'rrweb-snapshot';
import type { CrossOriginIframeMessageEvent } from '../types'; import type { CrossOriginIframeMessageEvent } from '../types';
import CrossOriginIframeMirror from './cross-origin-iframe-mirror'; import CrossOriginIframeMirror from './cross-origin-iframe-mirror';
import { EventType, IncrementalSource } from '@rrweb/types'; import { EventType, NodeType, IncrementalSource } from '@rrweb/types';
import type { import type {
eventWithTime, eventWithTime,
eventWithoutTime, eventWithoutTime,
serializedNodeWithId,
mutationCallBack, mutationCallBack,
} from '@rrweb/types'; } from '@rrweb/types';
import type { StylesheetManager } from './stylesheet-manager'; import type { StylesheetManager } from './stylesheet-manager';

View File

@@ -1,4 +1,4 @@
import type { ICanvas, Mirror, DataURLOptions } from 'rrweb-snapshot'; import type { ICanvas, Mirror } from 'rrweb-snapshot';
import type { import type {
blockClass, blockClass,
canvasManagerMutationCallback, canvasManagerMutationCallback,
@@ -8,6 +8,7 @@ import type {
IWindow, IWindow,
listenerHandler, listenerHandler,
CanvasArg, CanvasArg,
DataURLOptions,
} from '@rrweb/types'; } from '@rrweb/types';
import { isBlocked } from '../../../utils'; import { isBlocked } from '../../../utils';
import { CanvasContext } from '@rrweb/types'; import { CanvasContext } from '@rrweb/types';

View File

@@ -1,6 +1,7 @@
import type { elementNode, serializedNodeWithId } from 'rrweb-snapshot';
import { stringifyRule } from 'rrweb-snapshot'; import { stringifyRule } from 'rrweb-snapshot';
import type { import type {
elementNode,
serializedNodeWithId,
adoptedStyleSheetCallback, adoptedStyleSheetCallback,
adoptedStyleSheetParam, adoptedStyleSheetParam,
attributeMutation, attributeMutation,

View File

@@ -1,6 +1,6 @@
import { encode } from 'base64-arraybuffer'; import { encode } from 'base64-arraybuffer';
import type { DataURLOptions } from 'rrweb-snapshot';
import type { import type {
DataURLOptions,
ImageBitmapDataURLWorkerParams, ImageBitmapDataURLWorkerParams,
ImageBitmapDataURLWorkerResponse, ImageBitmapDataURLWorkerResponse,
} from '@rrweb/types'; } from '@rrweb/types';

View File

@@ -2,13 +2,10 @@ import {
rebuild, rebuild,
adaptCssForReplay, adaptCssForReplay,
buildNodeWithSN, buildNodeWithSN,
NodeType,
type BuildCache, type BuildCache,
createCache, createCache,
Mirror, Mirror,
createMirror, createMirror,
type attributes,
type serializedElementNodeWithId,
toLowerCase, toLowerCase,
} from 'rrweb-snapshot'; } from 'rrweb-snapshot';
import { import {
@@ -40,12 +37,14 @@ import {
} from './machine'; } from './machine';
import type { playerConfig, missingNodeMap } from '../types'; import type { playerConfig, missingNodeMap } from '../types';
import { import {
NodeType,
EventType, EventType,
IncrementalSource, IncrementalSource,
MouseInteractions, MouseInteractions,
ReplayerEvents, ReplayerEvents,
} from '@rrweb/types'; } from '@rrweb/types';
import type { import type {
attributes,
fullSnapshotEvent, fullSnapshotEvent,
eventWithTime, eventWithTime,
playerMetaData, playerMetaData,
@@ -70,6 +69,7 @@ import type {
styleSheetRuleData, styleSheetRuleData,
styleDeclarationData, styleDeclarationData,
adoptedStyleSheetData, adoptedStyleSheetData,
serializedElementNodeWithId,
} from '@rrweb/types'; } from '@rrweb/types';
import { import {
polyfill, polyfill,

View File

@@ -1,8 +1,9 @@
import { type Emitter, MediaInteractions, ReplayerEvents } from '@rrweb/types'; import type { Emitter } from '@rrweb/types';
import { MediaInteractions, ReplayerEvents } from '@rrweb/types';
import type { RRMediaElement } from 'rrdom'; import type { RRMediaElement } from 'rrdom';
import type { createPlayerService, createSpeedService } from '../machine'; import type { createPlayerService, createSpeedService } from '../machine';
import type { Mirror, mediaAttributes } from 'rrweb-snapshot'; import type { Mirror } from 'rrweb-snapshot';
import type { mediaInteractionData } from '@rrweb/types'; import type { mediaInteractionData, mediaAttributes } from '@rrweb/types';
type MediaState = { type MediaState = {
isPlaying: boolean; isPlaying: boolean;

View File

@@ -4,7 +4,6 @@ import type {
SlimDOMOptions, SlimDOMOptions,
MaskInputFn, MaskInputFn,
MaskTextFn, MaskTextFn,
DataURLOptions,
} from 'rrweb-snapshot'; } from 'rrweb-snapshot';
import type { IframeManager } from './record/iframe-manager'; import type { IframeManager } from './record/iframe-manager';
import type { ShadowDomManager } from './record/shadow-dom-manager'; import type { ShadowDomManager } from './record/shadow-dom-manager';
@@ -13,6 +12,7 @@ import type { RRNode } from 'rrdom';
import type { CanvasManager } from './record/observers/canvas/canvas-manager'; import type { CanvasManager } from './record/observers/canvas/canvas-manager';
import type { StylesheetManager } from './record/stylesheet-manager'; import type { StylesheetManager } from './record/stylesheet-manager';
import type { import type {
DataURLOptions,
addedNodeMutation, addedNodeMutation,
blockClass, blockClass,
canvasMutationCallback, canvasMutationCallback,

View File

@@ -8,8 +8,9 @@ import type {
IWindow, IWindow,
DeprecatedMirror, DeprecatedMirror,
textMutation, textMutation,
IMirror,
} from '@rrweb/types'; } from '@rrweb/types';
import type { IMirror, Mirror, SlimDOMOptions } from 'rrweb-snapshot'; import type { Mirror, SlimDOMOptions } from 'rrweb-snapshot';
import { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot'; import { isShadowRoot, IGNORED_NODE, classMatchesRegex } from 'rrweb-snapshot';
import { RRNode, RRIFrameElement, BaseRRNode } from 'rrdom'; import { RRNode, RRIFrameElement, BaseRRNode } from 'rrdom';
import dom from '@rrweb/utils'; import dom from '@rrweb/utils';

View File

@@ -14,8 +14,8 @@ import {
ISuite, ISuite,
} from './utils'; } from './utils';
import type { recordOptions } from '../src/types'; import type { recordOptions } from '../src/types';
import { eventWithTime, EventType, RecordPlugin } from '@rrweb/types'; import { eventWithTime, NodeType, EventType } from '@rrweb/types';
import { visitSnapshot, NodeType } from 'rrweb-snapshot'; import { visitSnapshot } from 'rrweb-snapshot';
describe('record integration tests', function (this: ISuite) { describe('record integration tests', function (this: ISuite) {
vi.setConfig({ testTimeout: 10_000 }); vi.setConfig({ testTimeout: 10_000 });

View File

@@ -1,5 +1,5 @@
import { NodeType } from 'rrweb-snapshot';
import { import {
NodeType,
EventType, EventType,
IncrementalSource, IncrementalSource,
eventWithTime, eventWithTime,

View File

@@ -49,9 +49,6 @@
"vite": "^5.3.1", "vite": "^5.3.1",
"vite-plugin-dts": "^3.9.1" "vite-plugin-dts": "^3.9.1"
}, },
"dependencies": {
"rrweb-snapshot": "^2.0.0-alpha.17"
},
"browserslist": [ "browserslist": [
"supports es6-class" "supports es6-class"
] ]

View File

@@ -1,10 +1,3 @@
import type {
serializedNodeWithId,
Mirror,
INode,
DataURLOptions,
} from 'rrweb-snapshot';
export enum EventType { export enum EventType {
DomContentLoaded, DomContentLoaded,
Load, Load,
@@ -254,7 +247,7 @@ export type RecordPlugin<TOptions = unknown> = {
) => listenerHandler; ) => listenerHandler;
eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend; eventProcessor?: <TExtend>(event: eventWithTime) => eventWithTime & TExtend;
getMirror?: (mirrors: { getMirror?: (mirrors: {
nodeMirror: Mirror; nodeMirror: IMirror<Node>;
crossOriginIframeMirror: ICrossOriginIframeMirror; crossOriginIframeMirror: ICrossOriginIframeMirror;
crossOriginIframeStyleMirror: ICrossOriginIframeMirror; crossOriginIframeStyleMirror: ICrossOriginIframeMirror;
}) => void; }) => void;
@@ -615,6 +608,13 @@ export type customElementParam = {
export type customElementCallback = (c: customElementParam) => void; export type customElementCallback = (c: customElementParam) => void;
/**
* @deprecated
*/
interface INode extends Node {
__sn: serializedNodeWithId;
}
export type DeprecatedMirror = { export type DeprecatedMirror = {
map: { map: {
[key: number]: INode; [key: number]: INode;
@@ -705,6 +705,147 @@ export type TakeTypedKeyValues<Obj extends object, Type> = Pick<
TakeTypeHelper<Obj, Type>[keyof TakeTypeHelper<Obj, Type>] TakeTypeHelper<Obj, Type>[keyof TakeTypeHelper<Obj, Type>]
>; >;
export enum NodeType {
Document,
DocumentType,
Element,
Text,
CDATA,
Comment,
}
export type documentNode = {
type: NodeType.Document;
childNodes: serializedNodeWithId[];
compatMode?: string;
};
export type documentTypeNode = {
type: NodeType.DocumentType;
name: string;
publicId: string;
systemId: string;
};
type cssTextKeyAttr = {
_cssText?: string;
};
export type attributes = cssTextKeyAttr & {
[key: string]:
| string
| number // properties e.g. rr_scrollLeft or rr_mediaCurrentTime
| true // e.g. checked on <input type="radio">
| null; // an indication that an attribute was removed (during a mutation)
};
export type legacyAttributes = {
/**
* @deprecated old bug in rrweb was causing these to always be set
* @see https://github.com/rrweb-io/rrweb/pull/651
*/
selected: false;
};
export type mediaAttributes = {
rr_mediaState: 'played' | 'paused';
rr_mediaCurrentTime: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaPlaybackRate?: number;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaMuted?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaLoop?: boolean;
/**
* for backwards compatibility this is optional but should always be set
*/
rr_mediaVolume?: number;
};
export type elementNode = {
type: NodeType.Element;
tagName: string;
attributes: attributes;
childNodes: serializedNodeWithId[];
isSVG?: true;
needBlock?: boolean;
// This is a custom element or not.
isCustom?: true;
};
export type textNode = {
type: NodeType.Text;
textContent: string;
/**
* @deprecated styles are now always snapshotted against parent <style> element
* style mutations can still happen via an added textNode, but they don't need this attribute for correct replay
*/
isStyle?: true;
};
export type cdataNode = {
type: NodeType.CDATA;
textContent: '';
};
export type commentNode = {
type: NodeType.Comment;
textContent: string;
};
export type serializedNode = (
| documentNode
| documentTypeNode
| elementNode
| textNode
| cdataNode
| commentNode
) & {
rootId?: number;
isShadowHost?: boolean;
isShadow?: boolean;
};
export type serializedNodeWithId = serializedNode & { id: number };
export type serializedElementNodeWithId = Extract<
serializedNodeWithId,
Record<'type', NodeType.Element>
>;
export interface IMirror<TNode> {
getId(n: TNode | undefined | null): number;
getNode(id: number): TNode | null;
getIds(): number[];
getMeta(n: TNode): serializedNodeWithId | null;
removeNodeFromMap(n: TNode): void;
has(id: number): boolean;
hasNode(node: TNode): boolean;
add(n: TNode, meta: serializedNodeWithId): void;
replace(id: number, n: TNode): void;
reset(): void;
}
export type DataURLOptions = Partial<{
type: string;
quality: number;
}>;
// Types for @rrweb/packer // Types for @rrweb/packer
export type PackFn = (event: eventWithTime) => string; export type PackFn = (event: eventWithTime) => string;
export type UnpackFn = (raw: string) => eventWithTime; export type UnpackFn = (raw: string) => eventWithTime;

View File

@@ -6,9 +6,5 @@
"rootDir": "src", "rootDir": "src",
"tsBuildInfoFile": "./tsconfig.tsbuildinfo" "tsBuildInfoFile": "./tsconfig.tsbuildinfo"
}, },
"references": [ "references": []
{
"path": "../rrweb-snapshot"
}
]
} }