diff --git a/.size-limit.js b/.size-limit.js index 4ae0dc49d8..164b3cc3d0 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -7,9 +7,9 @@ module.exports = [ gzip: true }, { - name: 'rrweb - record & getCanvasManager only (gzipped)', + name: 'rrweb - record & CanvasManager only (gzipped)', path: 'packages/rrweb/es/rrweb/packages/rrweb/src/entries/all.js', - import: '{ record, getCanvasManager }', + import: '{ record, CanvasManager }', gzip: true }, { diff --git a/packages/rrweb/src/index.ts b/packages/rrweb/src/index.ts index 3bdab596e8..9c65c6cdd9 100644 --- a/packages/rrweb/src/index.ts +++ b/packages/rrweb/src/index.ts @@ -27,9 +27,10 @@ export { record, Replayer, utils, canvasMutation }; export { deserializeArg } from './replay/canvas/deserialize-args'; export { + CanvasManager, takeFullSnapshot, mirror, freezePage, addCustomEvent, - getCanvasManager, } from './record'; +export type { CanvasManagerConstructorOptions } from './record'; diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index 359307ffc9..10b2aa594c 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -3,7 +3,6 @@ import { MaskInputOptions, SlimDOMOptions, createMirror, - DataURLOptions, } from '@sentry-internal/rrweb-snapshot'; import { initObservers, mutationBuffers } from './observer'; import { @@ -53,6 +52,7 @@ import { registerErrorHandler, unregisterErrorHandler, } from './error-handler'; +export type { CanvasManagerConstructorOptions } from './observers/canvas/canvas-manager'; function wrapEvent(e: event): eventWithTime { const eWithTime = e as eventWithTime; @@ -340,6 +340,18 @@ function record<T = eventWithTime>( const canvasManager: CanvasManagerInterface = _getCanvasManager( getCanvasManager, { + mirror, + win: window, + mutationCb: (p: canvasMutationParam) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.CanvasMutation, + ...p, + }, + }), + ), recordCanvas, blockClass, blockSelector, @@ -717,14 +729,6 @@ export function takeFullSnapshot(isCheckout?: boolean) { _takeFullSnapshot(isCheckout); } -function wrappedEmit(e: eventWithTime) { - if (!_wrappedEmit) { - return; - } - - _wrappedEmit(e); -} - // record.addCustomEvent is removed because Sentry Session Replay does not use it // record.freezePage is removed because Sentry Session Replay does not use it @@ -734,39 +738,17 @@ record.takeFullSnapshot = takeFullSnapshot; export default record; -type PrivateOptions = 'mutationCb' | 'win' | 'mirror'; -type PublicGetCanvasManagerOptions = Omit< - CanvasManagerConstructorOptions, - PrivateOptions ->; - -interface PrivateGetCanvasManagerOptions - extends PublicGetCanvasManagerOptions, - Pick<CanvasManagerConstructorOptions, PrivateOptions> {} - function _getCanvasManager( getCanvasManagerFn: | undefined - | ((options: PrivateGetCanvasManagerOptions) => CanvasManagerInterface), - options: PublicGetCanvasManagerOptions, + | (( + options: Partial<CanvasManagerConstructorOptions>, + ) => CanvasManagerInterface), + options: CanvasManagerConstructorOptions, ) { try { return getCanvasManagerFn - ? getCanvasManagerFn({ - ...options, - mirror, - win: window, - mutationCb: (p: canvasMutationParam) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.CanvasMutation, - ...p, - }, - }), - ), - }) + ? getCanvasManagerFn(options) : new CanvasManagerNoop(); } catch { console.warn('Unable to initialize CanvasManager'); @@ -774,8 +756,4 @@ function _getCanvasManager( } } -export function getCanvasManager( - options: PublicGetCanvasManagerOptions, -): CanvasManagerInterface { - return new CanvasManager(options as CanvasManagerConstructorOptions); -} +export { CanvasManager }; diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index fad5a2b77b..0eb4333199 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -84,10 +84,7 @@ export type recordOptions<T> = { errorHandler?: ErrorHandler; onMutation?: (mutations: MutationRecord[]) => boolean; getCanvasManager?: ( - options: Omit< - CanvasManagerConstructorOptions, - 'mutationCb' | 'win' | 'mirror' - >, + options: CanvasManagerConstructorOptions, ) => CanvasManagerInterface; }; diff --git a/packages/rrweb/test/record/cross-origin-iframes.test.ts b/packages/rrweb/test/record/cross-origin-iframes.test.ts index c48bd78368..1dba0cad98 100644 --- a/packages/rrweb/test/record/cross-origin-iframes.test.ts +++ b/packages/rrweb/test/record/cross-origin-iframes.test.ts @@ -17,7 +17,7 @@ import { } from '../utils'; import { unpack } from '../../src/packer/unpack'; import type * as http from 'http'; -import type { CanvasManagerInterface } from '../../src/record/observers/canvas/canvas-manager'; +import type { CanvasManager } from '../../src/record/observers/canvas/canvas-manager'; interface ISuite { code: string; @@ -35,7 +35,7 @@ interface IWindow extends Window { ) => listenerHandler | undefined; addCustomEvent<T>(tag: string, payload: T): void; pack: (e: eventWithTime) => string; - getCanvasManager: () => CanvasManagerInterface; + CanvasManager: typeof CanvasManager; }; emit: (e: eventWithTime) => undefined; snapshots: eventWithTime[]; @@ -54,12 +54,12 @@ async function injectRecordScript( options = options || {}; await frame.evaluate((options) => { (window as unknown as IWindow).snapshots = []; - const { record, pack, getCanvasManager } = (window as unknown as IWindow) + const { record, pack, CanvasManager } = (window as unknown as IWindow) .rrweb; const config: recordOptions<eventWithTime> = { recordCrossOriginIframes: true, recordCanvas: true, - getCanvasManager, + getCanvasManager: (options) => new CanvasManager(options), emit(event) { (window as unknown as IWindow).snapshots.push(event); (window as unknown as IWindow).emit(event); diff --git a/packages/rrweb/test/record/webgl.test.ts b/packages/rrweb/test/record/webgl.test.ts index d189e74256..1688cd6ecb 100644 --- a/packages/rrweb/test/record/webgl.test.ts +++ b/packages/rrweb/test/record/webgl.test.ts @@ -16,7 +16,7 @@ import { waitForRAF, } from '../utils'; import type { ICanvas } from '@sentry-internal/rrweb-snapshot'; -import type { CanvasManagerInterface } from '../../src/record/observers/canvas/canvas-manager'; +import type { CanvasManager } from '../../src/record/observers/canvas/canvas-manager'; interface ISuite { code: string; @@ -31,7 +31,7 @@ interface IWindow extends Window { options: recordOptions<eventWithTime>, ) => listenerHandler | undefined; addCustomEvent<T>(tag: string, payload: T): void; - getCanvasManager: () => CanvasManagerInterface; + CanvasManager: typeof CanvasManager; }; emit: (e: eventWithTime) => undefined; } @@ -66,10 +66,10 @@ const setup = function ( ctx.page.on('console', (msg) => console.log('PAGE LOG:', msg.text())); await ctx.page.evaluate((canvasSample) => { - const { record, getCanvasManager } = (window as unknown as IWindow).rrweb; + const { record, CanvasManager } = (window as unknown as IWindow).rrweb; record({ recordCanvas: true, - getCanvasManager, + getCanvasManager: (options) => new CanvasManager(options), sampling: { canvas: canvasSample, }, diff --git a/packages/rrweb/test/utils.ts b/packages/rrweb/test/utils.ts index 28e965834c..7f406ad239 100644 --- a/packages/rrweb/test/utils.ts +++ b/packages/rrweb/test/utils.ts @@ -712,7 +712,9 @@ export function generateRecordSnippet(options: recordOptions<eventWithTime>) { inlineImages: ${options.inlineImages}, plugins: ${options.plugins}, getCanvasManager: ${ - options.recordCanvas ? 'rrweb.getCanvasManager' : 'undefined' + options.recordCanvas + ? '(opts) => new rrweb.CanvasManager(opts)' + : 'undefined' } }); `;