From 8408b1885ac3fb0bc9146713d9882d2db876a716 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Thu, 23 Jan 2025 14:28:16 -0500 Subject: [PATCH] fix(rrweb): WIP: refactor sideeffects from rrweb/record --- packages/rrweb/package.json | 4 ++- packages/rrweb/src/record/clean-array-from.ts | 15 +++++++++++ packages/rrweb/src/record/index.ts | 25 +++++++------------ 3 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 packages/rrweb/src/record/clean-array-from.ts diff --git a/packages/rrweb/package.json b/packages/rrweb/package.json index d21864c36f..b9a97424e8 100644 --- a/packages/rrweb/package.json +++ b/packages/rrweb/package.json @@ -58,7 +58,9 @@ "dist", "package.json" ], - "sideEffects": false, + "sideEffects": [ + "./src/record/clean-array-from.ts" + ], "author": "yanzhen@smartx.com", "license": "MIT", "bugs": { diff --git a/packages/rrweb/src/record/clean-array-from.ts b/packages/rrweb/src/record/clean-array-from.ts new file mode 100644 index 0000000000..962d1b4929 --- /dev/null +++ b/packages/rrweb/src/record/clean-array-from.ts @@ -0,0 +1,15 @@ +// Multiple tools (i.e. MooTools, Prototype.js) override Array.from and drop support for the 2nd parameter +// Try to pull a clean implementation from a newly created iframe +try { + if (Array.from([1], (x) => x * 2)[0] !== 2) { + const cleanFrame = document.createElement('iframe'); + document.body.appendChild(cleanFrame); + // eslint-disable-next-line @typescript-eslint/unbound-method -- Array.from is static and doesn't rely on binding + Array.from = cleanFrame.contentWindow?.Array.from || Array.from; + document.body.removeChild(cleanFrame); + } +} catch (err) { + console.debug('Unable to override Array.from', err); +} + +export {}; diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index 65accaaaec..4fe65e6b0e 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -3,6 +3,7 @@ import { MaskInputOptions, SlimDOMOptions, createMirror, + type Mirror, } from '@sentry-internal/rrweb-snapshot'; import { initObservers, mutationBuffers } from './observer'; import { @@ -52,6 +53,8 @@ import { registerErrorHandler, unregisterErrorHandler, } from './error-handler'; +import './clean-array-from'; + export type { CanvasManagerConstructorOptions } from './observers/canvas/canvas-manager'; declare global { @@ -67,21 +70,6 @@ let _wrappedEmit: | ((e: eventWithTime, isCheckout?: boolean) => void); let _takeFullSnapshot: undefined | ((isCheckout?: boolean) => void); -// Multiple tools (i.e. MooTools, Prototype.js) override Array.from and drop support for the 2nd parameter -// Try to pull a clean implementation from a newly created iframe -try { - if (Array.from([1], (x) => x * 2)[0] !== 2) { - const cleanFrame = document.createElement('iframe'); - document.body.appendChild(cleanFrame); - // eslint-disable-next-line @typescript-eslint/unbound-method -- Array.from is static and doesn't rely on binding - Array.from = cleanFrame.contentWindow?.Array.from || Array.from; - document.body.removeChild(cleanFrame); - } -} catch (err) { - console.debug('Unable to override Array.from', err); -} - -const mirror = createMirror(); function record( options: recordOptions = {}, ): listenerHandler | undefined { @@ -129,6 +117,7 @@ function record( } = options; registerErrorHandler(errorHandler); + const mirror = createMirror(); const inEmittingFrame = recordCrossOriginIframes ? window.parent === window @@ -721,9 +710,13 @@ export function takeFullSnapshot(isCheckout?: boolean) { // record.freezePage is removed because Sentry Session Replay does not use it // For backwards compatibility - we can eventually remove this when we migrated to using the exported `mirror` & `takeFullSnapshot` -record.mirror = mirror; +// record.mirror = mirror; record.takeFullSnapshot = takeFullSnapshot; +namespace record { + export var mirror: Mirror; +} + export default record; function _getCanvasManager(