163 lines
3.8 KiB
TypeScript
163 lines
3.8 KiB
TypeScript
import { snapshot } from 'rrweb-snapshot';
|
|
import initObservers from './observer';
|
|
import { mirror, on, getWindowWidth, getWindowHeight } from '../utils';
|
|
import {
|
|
EventType,
|
|
event,
|
|
eventWithTime,
|
|
recordOptions,
|
|
IncrementalSource,
|
|
listenerHandler,
|
|
} from '../types';
|
|
|
|
function wrapEvent(e: event): eventWithTime {
|
|
return {
|
|
...e,
|
|
timestamp: Date.now(),
|
|
};
|
|
}
|
|
|
|
function record(options: recordOptions = {}): listenerHandler | undefined {
|
|
const { emit } = options;
|
|
// runtime checks for user options
|
|
if (!emit) {
|
|
throw new Error('emit function is required');
|
|
}
|
|
try {
|
|
const handlers: listenerHandler[] = [];
|
|
handlers.push(
|
|
on('DOMContentLoaded', () => {
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.DomContentLoaded,
|
|
data: {},
|
|
}),
|
|
);
|
|
}),
|
|
);
|
|
const init = () => {
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.Meta,
|
|
data: {
|
|
href: window.location.href,
|
|
width: getWindowWidth(),
|
|
height: getWindowHeight(),
|
|
},
|
|
}),
|
|
);
|
|
const [node, idNodeMap] = snapshot(document);
|
|
if (!node) {
|
|
return console.warn('Failed to snapshot the document');
|
|
}
|
|
mirror.map = idNodeMap;
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.FullSnapshot,
|
|
data: {
|
|
node,
|
|
initialOffset: {
|
|
left: document.documentElement!.scrollLeft,
|
|
top: document.documentElement!.scrollTop,
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
handlers.push(
|
|
initObservers({
|
|
mutationCb: m =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.Mutation,
|
|
...m,
|
|
},
|
|
}),
|
|
),
|
|
mousemoveCb: positions =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.MouseMove,
|
|
positions,
|
|
},
|
|
}),
|
|
),
|
|
mouseInteractionCb: d =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.MouseInteraction,
|
|
...d,
|
|
},
|
|
}),
|
|
),
|
|
scrollCb: p =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.Scroll,
|
|
...p,
|
|
},
|
|
}),
|
|
),
|
|
viewportResizeCb: d =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.ViewportResize,
|
|
...d,
|
|
},
|
|
}),
|
|
),
|
|
inputCb: v =>
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.IncrementalSnapshot,
|
|
data: {
|
|
source: IncrementalSource.Input,
|
|
...v,
|
|
},
|
|
}),
|
|
),
|
|
}),
|
|
);
|
|
};
|
|
if (
|
|
document.readyState === 'interactive' ||
|
|
document.readyState === 'complete'
|
|
) {
|
|
init();
|
|
} else {
|
|
handlers.push(
|
|
on(
|
|
'load',
|
|
() => {
|
|
emit(
|
|
wrapEvent({
|
|
type: EventType.Load,
|
|
data: {},
|
|
}),
|
|
);
|
|
init();
|
|
},
|
|
window,
|
|
),
|
|
);
|
|
}
|
|
return () => {
|
|
handlers.forEach(h => h());
|
|
};
|
|
} catch (error) {
|
|
// TODO: handle internal error
|
|
console.warn(error);
|
|
}
|
|
}
|
|
|
|
export default record;
|