From 88ea2d05c1869026111c91f7aa14ea7a7193fcd8 Mon Sep 17 00:00:00 2001 From: Paul D'Ambra Date: Thu, 6 Feb 2025 15:10:50 +0000 Subject: [PATCH] fix: move patch function into utils to improve bundling (#1631) * fix: move patch function into utils to improve bundling --------- Co-authored-by: pauldambra Co-authored-by: Justin Halsall --- .changeset/itchy-tables-compete.md | 8 ++++ .../rrweb-plugin-console-record/package.json | 3 +- .../rrweb-plugin-console-record/src/index.ts | 4 +- packages/record/package.json | 3 +- packages/record/tsconfig.json | 3 ++ packages/rrweb/src/record/observer.ts | 2 +- .../rrweb/src/record/observers/canvas/2d.ts | 3 +- .../src/record/observers/canvas/canvas.ts | 3 +- .../src/record/observers/canvas/webgl.ts | 3 +- .../rrweb/src/record/shadow-dom-manager.ts | 4 +- packages/rrweb/src/utils.ts | 43 ------------------ packages/utils/src/index.ts | 44 +++++++++++++++++++ yarn.lock | 2 +- 13 files changed, 71 insertions(+), 54 deletions(-) create mode 100644 .changeset/itchy-tables-compete.md diff --git a/.changeset/itchy-tables-compete.md b/.changeset/itchy-tables-compete.md new file mode 100644 index 0000000000..e545465949 --- /dev/null +++ b/.changeset/itchy-tables-compete.md @@ -0,0 +1,8 @@ +--- +"@rrweb/rrweb-plugin-console-record": patch +"@rrweb/record": patch +"rrweb": patch +"@rrweb/utils": patch +--- + +Move patch function into @rrweb/utils to improve bundling diff --git a/packages/plugins/rrweb-plugin-console-record/package.json b/packages/plugins/rrweb-plugin-console-record/package.json index c59352c02c..07897f39dd 100644 --- a/packages/plugins/rrweb-plugin-console-record/package.json +++ b/packages/plugins/rrweb-plugin-console-record/package.json @@ -53,6 +53,7 @@ "puppeteer": "^20.9.0" }, "peerDependencies": { - "rrweb": "^2.0.0-alpha.18" + "rrweb": "^2.0.0-alpha.18", + "@rrweb/utils": "^2.0.0-alpha.18" } } diff --git a/packages/plugins/rrweb-plugin-console-record/src/index.ts b/packages/plugins/rrweb-plugin-console-record/src/index.ts index d6c8416953..986d7115a6 100644 --- a/packages/plugins/rrweb-plugin-console-record/src/index.ts +++ b/packages/plugins/rrweb-plugin-console-record/src/index.ts @@ -1,5 +1,5 @@ import type { listenerHandler, RecordPlugin, IWindow } from '@rrweb/types'; -import { utils } from 'rrweb'; +import { patch } from '@rrweb/utils'; import { ErrorStackParser, StackFrame } from './error-stack-parser'; import { stringify } from './stringify'; @@ -183,7 +183,7 @@ function initLogObserver( }; } // replace the logger.{level}. return a restore function - return utils.patch( + return patch( _logger, level, (original: (...args: Array) => void) => { diff --git a/packages/record/package.json b/packages/record/package.json index 0e58cd5a59..6b1d244d6f 100644 --- a/packages/record/package.json +++ b/packages/record/package.json @@ -56,7 +56,8 @@ }, "dependencies": { "@rrweb/types": "^2.0.0-alpha.18", - "rrweb": "^2.0.0-alpha.18" + "rrweb": "^2.0.0-alpha.18", + "@rrweb/utils": "^2.0.0-alpha.18" }, "browserslist": [ "supports es6-class" diff --git a/packages/record/tsconfig.json b/packages/record/tsconfig.json index eb18687a7c..526faf2259 100644 --- a/packages/record/tsconfig.json +++ b/packages/record/tsconfig.json @@ -11,6 +11,9 @@ }, { "path": "../rrweb" + }, + { + "path": "../utils" } ] } diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index 7e3aab3fff..8326d79651 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -15,10 +15,10 @@ import { getWindowWidth, isBlocked, legacy_isTouchEvent, - patch, StyleSheetMirror, nowTimestamp, } from '../utils'; +import { patch } from '@rrweb/utils'; import type { observerParam, MutationBufferParam } from '../types'; import { IncrementalSource, diff --git a/packages/rrweb/src/record/observers/canvas/2d.ts b/packages/rrweb/src/record/observers/canvas/2d.ts index d6090a6728..ce1332a890 100644 --- a/packages/rrweb/src/record/observers/canvas/2d.ts +++ b/packages/rrweb/src/record/observers/canvas/2d.ts @@ -5,7 +5,8 @@ import { type IWindow, type listenerHandler, } from '@rrweb/types'; -import { hookSetter, isBlocked, patch } from '../../../utils'; +import { hookSetter, isBlocked } from '../../../utils'; +import { patch } from '@rrweb/utils'; import { serializeArgs } from './serialize-args'; export default function initCanvas2DMutationObserver( diff --git a/packages/rrweb/src/record/observers/canvas/canvas.ts b/packages/rrweb/src/record/observers/canvas/canvas.ts index 4f6b30fc36..aa9be94d51 100644 --- a/packages/rrweb/src/record/observers/canvas/canvas.ts +++ b/packages/rrweb/src/record/observers/canvas/canvas.ts @@ -1,6 +1,7 @@ import type { ICanvas } from 'rrweb-snapshot'; import type { blockClass, IWindow, listenerHandler } from '@rrweb/types'; -import { isBlocked, patch } from '../../../utils'; +import { isBlocked } from '../../../utils'; +import { patch } from '@rrweb/utils'; function getNormalizedContextName(contextType: string) { return contextType === 'experimental-webgl' ? 'webgl' : contextType; diff --git a/packages/rrweb/src/record/observers/canvas/webgl.ts b/packages/rrweb/src/record/observers/canvas/webgl.ts index 59218afb5c..3c51323b2d 100644 --- a/packages/rrweb/src/record/observers/canvas/webgl.ts +++ b/packages/rrweb/src/record/observers/canvas/webgl.ts @@ -6,7 +6,8 @@ import { type IWindow, type listenerHandler, } from '@rrweb/types'; -import { hookSetter, isBlocked, patch } from '../../../utils'; +import { hookSetter, isBlocked } from '../../../utils'; +import { patch } from '@rrweb/utils'; import { saveWebGLVar, serializeArgs } from './serialize-args'; function patchGLPrototype( diff --git a/packages/rrweb/src/record/shadow-dom-manager.ts b/packages/rrweb/src/record/shadow-dom-manager.ts index ab257e4003..35affb729b 100644 --- a/packages/rrweb/src/record/shadow-dom-manager.ts +++ b/packages/rrweb/src/record/shadow-dom-manager.ts @@ -9,10 +9,10 @@ import { initScrollObserver, initAdoptedStyleSheetObserver, } from './observer'; -import { patch, inDom } from '../utils'; +import { inDom } from '../utils'; import type { Mirror } from 'rrweb-snapshot'; import { isNativeShadowDom } from 'rrweb-snapshot'; -import dom from '@rrweb/utils'; +import dom, { patch } from '@rrweb/utils'; type BypassOptions = Omit< MutationBufferParam, diff --git a/packages/rrweb/src/utils.ts b/packages/rrweb/src/utils.ts index ecf72d05ea..13b15ec6c1 100644 --- a/packages/rrweb/src/utils.ts +++ b/packages/rrweb/src/utils.ts @@ -127,49 +127,6 @@ export function hookSetter( return () => hookSetter(target, key, original || {}, true); } -// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts -export function patch( - source: { [key: string]: any }, - name: string, - replacement: (...args: unknown[]) => unknown, -): () => void { - try { - 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" - if (typeof wrapped === 'function') { - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - wrapped.prototype = wrapped.prototype || {}; - Object.defineProperties(wrapped, { - __rrweb_original__: { - enumerable: false, - value: original, - }, - }); - } - - source[name] = wrapped; - - return () => { - source[name] = original; - }; - } catch { - return () => { - // - }; - // This can throw if multiple fill happens on a global object like XMLHttpRequest - // Fixes https://github.com/getsentry/sentry-javascript/issues/2043 - } -} - // guard against old third party libraries which redefine Date.now let nowTimestamp = Date.now; diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 1cd267c08f..94a8dc8394 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -222,6 +222,49 @@ export function mutationObserverCtor(): (typeof MutationObserver)['prototype'][' return getUntaintedPrototype('MutationObserver').constructor; } +// copy from https://github.com/getsentry/sentry-javascript/blob/b2109071975af8bf0316d3b5b38f519bdaf5dc15/packages/utils/src/object.ts +export function patch( + source: { [key: string]: any }, + name: string, + replacement: (...args: unknown[]) => unknown, +): () => void { + try { + 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" + if (typeof wrapped === 'function') { + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + wrapped.prototype = wrapped.prototype || {}; + Object.defineProperties(wrapped, { + __rrweb_original__: { + enumerable: false, + value: original, + }, + }); + } + + source[name] = wrapped; + + return () => { + source[name] = original; + }; + } catch { + return () => { + // + }; + // This can throw if multiple fill happens on a global object like XMLHttpRequest + // Fixes https://github.com/getsentry/sentry-javascript/issues/2043 + } +} + export default { childNodes, parentNode, @@ -235,4 +278,5 @@ export default { querySelector, querySelectorAll, mutationObserver: mutationObserverCtor, + patch, }; diff --git a/yarn.lock b/yarn.lock index 1c342df6ff..7d0b8c00de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1,5 +1,5 @@ # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 +# yarn lockfile v1 "@ampproject/remapping@^2.2.0", "@ampproject/remapping@^2.2.1":