add hooks API (#132)

This commit is contained in:
yz-yu
2026-04-01 12:00:00 +08:00
committed by GitHub
parent a91399046b
commit 1afc0b7527
5 changed files with 150 additions and 69 deletions

View File

@@ -34,6 +34,7 @@ function record(options: recordOptions = {}): listenerHandler | undefined {
ignoreClass = 'rr-ignore',
inlineStylesheet = true,
maskAllInputs = false,
hooks,
} = options;
// runtime checks for user options
if (!emit) {
@@ -114,72 +115,75 @@ function record(options: recordOptions = {}): listenerHandler | undefined {
takeFullSnapshot();
handlers.push(
initObservers({
mutationCb: m =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Mutation,
...m,
},
}),
),
mousemoveCb: (positions, source) =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source,
positions,
},
}),
),
mouseInteractionCb: d =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.MouseInteraction,
...d,
},
}),
),
scrollCb: p =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Scroll,
...p,
},
}),
),
viewportResizeCb: d =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.ViewportResize,
...d,
},
}),
),
inputCb: v =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Input,
...v,
},
}),
),
blockClass,
ignoreClass,
maskAllInputs,
inlineStylesheet,
}),
initObservers(
{
mutationCb: m =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Mutation,
...m,
},
}),
),
mousemoveCb: (positions, source) =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source,
positions,
},
}),
),
mouseInteractionCb: d =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.MouseInteraction,
...d,
},
}),
),
scrollCb: p =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Scroll,
...p,
},
}),
),
viewportResizeCb: d =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.ViewportResize,
...d,
},
}),
),
inputCb: v =>
wrappedEmit(
wrapEvent({
type: EventType.IncrementalSnapshot,
data: {
source: IncrementalSource.Input,
...v,
},
}),
),
blockClass,
ignoreClass,
maskAllInputs,
inlineStylesheet,
},
hooks,
),
);
};
if (

View File

@@ -29,6 +29,8 @@ import {
attributeCursor,
blockClass,
IncrementalSource,
hooksParam,
Arguments,
} from '../types';
import { deepDelete, isParentRemoved, isAncestorInSet } from './collection';
@@ -506,7 +508,58 @@ function initInputObserver(
};
}
export default function initObservers(o: observerParam): listenerHandler {
function mergeHooks(o: observerParam, hooks: hooksParam) {
const {
mutationCb,
mousemoveCb,
mouseInteractionCb,
scrollCb,
viewportResizeCb,
inputCb,
} = o;
o.mutationCb = (...p: Arguments<mutationCallBack>) => {
if (hooks.mutation) {
hooks.mutation(...p);
}
mutationCb(...p);
};
o.mousemoveCb = (...p: Arguments<mousemoveCallBack>) => {
if (hooks.mousemove) {
hooks.mousemove(...p);
}
mousemoveCb(...p);
};
o.mouseInteractionCb = (...p: Arguments<mouseInteractionCallBack>) => {
if (hooks.mouseInteraction) {
hooks.mouseInteraction(...p);
}
mouseInteractionCb(...p);
};
o.scrollCb = (...p: Arguments<scrollCallback>) => {
if (hooks.scroll) {
hooks.scroll(...p);
}
scrollCb(...p);
};
o.viewportResizeCb = (...p: Arguments<viewportResizeCallback>) => {
if (hooks.viewportResize) {
hooks.viewportResize(...p);
}
viewportResizeCb(...p);
};
o.inputCb = (...p: Arguments<inputCallback>) => {
if (hooks.input) {
hooks.input(...p);
}
inputCb(...p);
};
}
export default function initObservers(
o: observerParam,
hooks: hooksParam = {},
): listenerHandler {
mergeHooks(o, hooks);
const mutationObserver = initMutationObserver(
o.mutationCb,
o.blockClass,

View File

@@ -119,6 +119,7 @@ export type recordOptions = {
ignoreClass?: string;
maskAllInputs?: boolean;
inlineStylesheet?: boolean;
hooks?: hooksParam;
};
export type observerParam = {
@@ -134,6 +135,15 @@ export type observerParam = {
inlineStylesheet: boolean;
};
export type hooksParam = {
mutation?: mutationCallBack;
mousemove?: mousemoveCallBack;
mouseInteraction?: mouseInteractionCallBack;
scroll?: scrollCallback;
viewportResize?: viewportResizeCallback;
input?: inputCallback;
};
export type textCursor = {
node: Node;
value: string | null;
@@ -285,6 +295,10 @@ export type Emitter = {
emit(type: string, event?: unknown): void;
};
export type Arguments<T> = T extends (...payload: infer U) => unknown
? U
: unknown;
export enum ReplayerEvents {
Start = 'start',
Pause = 'pause',

View File

@@ -1,2 +1,2 @@
import { observerParam, listenerHandler } from '../types';
export default function initObservers(o: observerParam): listenerHandler;
import { observerParam, listenerHandler, hooksParam } from '../types';
export default function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;

10
typings/types.d.ts vendored
View File

@@ -88,6 +88,7 @@ export declare type recordOptions = {
ignoreClass?: string;
maskAllInputs?: boolean;
inlineStylesheet?: boolean;
hooks?: hooksParam;
};
export declare type observerParam = {
mutationCb: mutationCallBack;
@@ -101,6 +102,14 @@ export declare type observerParam = {
maskAllInputs: boolean;
inlineStylesheet: boolean;
};
export declare type hooksParam = {
mutation?: mutationCallBack;
mousemove?: mousemoveCallBack;
mouseInteraction?: mouseInteractionCallBack;
scroll?: scrollCallback;
viewportResize?: viewportResizeCallback;
input?: inputCallback;
};
export declare type textCursor = {
node: Node;
value: string | null;
@@ -225,6 +234,7 @@ export declare type Emitter = {
on(type: string, handler: Handler): void;
emit(type: string, event?: unknown): void;
};
export declare type Arguments<T> = T extends (...payload: infer U) => unknown ? U : unknown;
export declare enum ReplayerEvents {
Start = "start",
Pause = "pause",