add the patch function to utils

This commit is contained in:
Yanzhen Yu
2020-07-18 16:42:11 +08:00
parent c5580f97f4
commit 6f08ec3ca7
6 changed files with 101 additions and 10 deletions

View File

@@ -116,6 +116,46 @@ export function hookSetter<T>(
return () => hookSetter(target, key, original || {}, true);
}
// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts
export function patch(
// tslint:disable-next-line:no-any
source: { [key: string]: any },
name: string,
// tslint:disable-next-line:no-any
replacement: (...args: any[]) => any,
): () => void {
if (!(name in source)) {
return () => {};
}
const original = source[name] as () => unknown;
const wrapped = replacement(original);
// Make sure it's a function first, as we need to attach an empty prototype for `defineProperties` to work
// otherwise it'll throw "TypeError: Object.defineProperties called on non-object"
// tslint:disable-next-line:strict-type-predicates
if (typeof wrapped === 'function') {
try {
wrapped.prototype = wrapped.prototype || {};
Object.defineProperties(wrapped, {
__rrweb_original__: {
enumerable: false,
value: original,
},
});
} catch {
// This can throw if multiple fill happens on a global object like XMLHttpRequest
// Fixes https://github.com/getsentry/sentry-javascript/issues/2043
}
}
source[name] = wrapped;
return () => {
source[name] = original;
};
}
export function getWindowHeight(): number {
return (
window.innerHeight ||

View File

@@ -1,3 +1,4 @@
import { MaskInputOptions } from 'rrweb-snapshot';
import { mutationRecord, blockClass, mutationCallBack } from '../types';
export default class MutationBuffer {
private texts;
@@ -11,10 +12,10 @@ export default class MutationBuffer {
private emissionCallback;
private blockClass;
private inlineStylesheet;
private maskAllInputs;
constructor(cb: mutationCallBack, blockClass: blockClass, inlineStylesheet: boolean, maskAllInputs: boolean);
private maskInputOptions;
constructor(cb: mutationCallBack, blockClass: blockClass, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions);
processMutations: (mutations: mutationRecord[]) => void;
emit: () => void;
private processMutation;
private genAdds;
emit: () => void;
}

View File

@@ -1,4 +1,3 @@
import { observerParam, listenerHandler, hooksParam } from '../types';
export declare const INPUT_TAGS: string[];
export declare const MASK_TYPES: string[];
export default function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;

View File

@@ -12,6 +12,8 @@ export declare class Replayer {
private noramlSpeed;
private legacy_missingNodeRetryMap;
private service;
private treeIndex;
private fragmentParentMap;
constructor(events: Array<eventWithTime | string>, config?: Partial<playerConfig>);
on(event: string, handler: Handler): void;
setConfig(config: Partial<playerConfig>): void;
@@ -31,6 +33,9 @@ export declare class Replayer {
private rebuildFullSnapshot;
private waitForStylesheetLoad;
private applyIncremental;
private applyMutation;
private applyScroll;
private applyInput;
private legacy_resolveMissingNode;
private moveAndHover;
private hoverElements;

21
typings/types.d.ts vendored
View File

@@ -1,4 +1,4 @@
import { serializedNodeWithId, idNodeMap, INode } from 'rrweb-snapshot';
import { serializedNodeWithId, idNodeMap, INode, MaskInputOptions } from 'rrweb-snapshot';
import { PackFn, UnpackFn } from './packer/base';
export declare enum EventType {
DomContentLoaded = 0,
@@ -90,6 +90,12 @@ export declare type eventWithTime = event & {
delay?: number;
};
export declare type blockClass = string | RegExp;
export declare type SamplingStrategy = Partial<{
mousemove: boolean | number;
mouseInteraction: boolean | Record<string, boolean | undefined>;
scroll: number;
input: 'all' | 'last';
}>;
export declare type recordOptions<T> = {
emit?: (e: T, isCheckout?: boolean) => void;
checkoutEveryNth?: number;
@@ -97,10 +103,12 @@ export declare type recordOptions<T> = {
blockClass?: blockClass;
ignoreClass?: string;
maskAllInputs?: boolean;
maskInputOptions?: MaskInputOptions;
inlineStylesheet?: boolean;
hooks?: hooksParam;
mousemoveWait?: number;
packFn?: PackFn;
sampling?: SamplingStrategy;
mousemoveWait?: number;
};
export declare type observerParam = {
mutationCb: mutationCallBack;
@@ -112,10 +120,10 @@ export declare type observerParam = {
mediaInteractionCb: mediaInteractionCallback;
blockClass: blockClass;
ignoreClass: string;
maskAllInputs: boolean;
maskInputOptions: MaskInputOptions;
inlineStylesheet: boolean;
styleSheetRuleCb: styleSheetRuleCallback;
mousemoveWait: number;
sampling: SamplingStrategy;
};
export declare type hooksParam = {
mutation?: mutationCallBack;
@@ -265,6 +273,8 @@ export declare type playerConfig = {
unpackFn?: UnpackFn;
};
export declare type playerMetaData = {
startTime: number;
endTime: number;
totalTime: number;
};
export declare type missingNode = {
@@ -297,6 +307,7 @@ export declare enum ReplayerEvents {
SkipEnd = "skip-end",
MouseInteraction = "mouse-interaction",
EventCast = "event-cast",
CustomEvent = "custom-event"
CustomEvent = "custom-event",
Flush = "flush"
}
export {};

37
typings/utils.d.ts vendored
View File

@@ -1,12 +1,47 @@
import { Mirror, throttleOptions, listenerHandler, hookResetter, blockClass } from './types';
import { Mirror, throttleOptions, listenerHandler, hookResetter, blockClass, eventWithTime, addedNodeMutation, removedNodeMutation, textMutation, attributeMutation, mutationData, scrollData, inputData } from './types';
import { INode } from 'rrweb-snapshot';
export declare function on(type: string, fn: EventListenerOrEventListenerObject, target?: Document | Window): listenerHandler;
export declare const mirror: Mirror;
export declare function throttle<T>(func: (arg: T) => void, wait: number, options?: throttleOptions): (arg: T) => void;
export declare function hookSetter<T>(target: T, key: string | number | symbol, d: PropertyDescriptor, isRevoked?: boolean, win?: Window & typeof globalThis): hookResetter;
export declare function patch(source: {
[key: string]: any;
}, name: string, replacement: (...args: any[]) => any): () => void;
export declare function getWindowHeight(): number;
export declare function getWindowWidth(): number;
export declare function isBlocked(node: Node | null, blockClass: blockClass): boolean;
export declare function isAncestorRemoved(target: INode): boolean;
export declare function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent;
export declare function polyfill(): void;
export declare function needCastInSyncMode(event: eventWithTime): boolean;
export declare type TreeNode = {
id: number;
mutation: addedNodeMutation;
parent?: TreeNode;
children: Record<number, TreeNode>;
texts: textMutation[];
attributes: attributeMutation[];
};
export declare class TreeIndex {
tree: Record<number, TreeNode>;
private removeNodeMutations;
private textMutations;
private attributeMutations;
private indexes;
private removeIdSet;
private scrollMap;
private inputMap;
constructor();
add(mutation: addedNodeMutation): void;
remove(mutation: removedNodeMutation): void;
text(mutation: textMutation): void;
attribute(mutation: attributeMutation): void;
scroll(d: scrollData): void;
input(d: inputData): void;
flush(): {
mutationData: mutationData;
scrollMap: TreeIndex['scrollMap'];
inputMap: TreeIndex['inputMap'];
};
private reset;
}