From 708b839ee6bcec8bd9056316da657eb43c97b9aa Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 1 Dec 2023 13:30:16 -0500 Subject: [PATCH 01/15] add canvas to experiment --- packages/replay/src/replay.ts | 2 ++ packages/replay/src/types/replay.ts | 1 + 2 files changed, 3 insertions(+) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 5b46ac64e110..39e4440ed44b 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -339,6 +339,8 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, + recordCanvas: this._options._experiments.enableCanvas, + ...(this._options._experiments.enableCanvas && { sampling: { canvas: 4, }, dataURLOptions: { quality: 0.6, } }), }); } catch (err) { this._handleException(err); diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 38ca35ac8f0e..b88e045fb678 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -232,6 +232,7 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { _experiments: Partial<{ captureExceptions: boolean; traceInternals: boolean; + enableCanvas: boolean; }>; } From 083a5330c7613e464dea25af4c06d5c9b895f94d Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:05:09 -0500 Subject: [PATCH 02/15] update test --- packages/replay/test/integration/rrweb.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/replay/test/integration/rrweb.test.ts b/packages/replay/test/integration/rrweb.test.ts index 82dd18f2d6ec..4c5a3aac06f3 100644 --- a/packages/replay/test/integration/rrweb.test.ts +++ b/packages/replay/test/integration/rrweb.test.ts @@ -34,6 +34,7 @@ describe('Integration | rrweb', () => { "maskTextFn": undefined, "maskTextSelector": ".sentry-mask,[data-sentry-mask]", "onMutation": [Function], + "recordCanvas": undefined, "slimDOMOptions": "all", "unblockSelector": ".sentry-unblock,[data-sentry-unblock]", "unmaskTextSelector": ".sentry-unmask,[data-sentry-unmask]", From 8e228d43ff639c417326408fcf66c90f13c7c5ae Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:29:18 -0500 Subject: [PATCH 03/15] ref --- packages/replay/src/replay.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 39e4440ed44b..68f90b339854 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -339,8 +339,7 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, - recordCanvas: this._options._experiments.enableCanvas, - ...(this._options._experiments.enableCanvas && { sampling: { canvas: 4, }, dataURLOptions: { quality: 0.6, } }), + ...(this._options._experiments.enableCanvas && { recordCanvas: true, sampling: { canvas: 4 }, dataURLOptions: { quality: 0.6 } }), }); } catch (err) { this._handleException(err); From e9e09b6fbb3f4421443d9c4c6965eb5de6b6eac8 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:33:12 -0500 Subject: [PATCH 04/15] update test again --- packages/replay/test/integration/rrweb.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/replay/test/integration/rrweb.test.ts b/packages/replay/test/integration/rrweb.test.ts index 4c5a3aac06f3..82dd18f2d6ec 100644 --- a/packages/replay/test/integration/rrweb.test.ts +++ b/packages/replay/test/integration/rrweb.test.ts @@ -34,7 +34,6 @@ describe('Integration | rrweb', () => { "maskTextFn": undefined, "maskTextSelector": ".sentry-mask,[data-sentry-mask]", "onMutation": [Function], - "recordCanvas": undefined, "slimDOMOptions": "all", "unblockSelector": ".sentry-unblock,[data-sentry-unblock]", "unmaskTextSelector": ".sentry-unmask,[data-sentry-unmask]", From 9b806f32594bd1acb5db8f73c77e6cdcedcf3b41 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Fri, 1 Dec 2023 14:55:04 -0500 Subject: [PATCH 05/15] lint --- packages/replay/src/replay.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 68f90b339854..32bb1a99a1a5 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -339,7 +339,11 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, - ...(this._options._experiments.enableCanvas && { recordCanvas: true, sampling: { canvas: 4 }, dataURLOptions: { quality: 0.6 } }), + ...(this._options._experiments.enableCanvas && { + recordCanvas: true, + sampling: { canvas: 4 }, + dataURLOptions: { quality: 0.6 }, + }), }); } catch (err) { this._handleException(err); From c0baf3078fb672afedfa5455068891e54da2fbe5 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:37:13 -0500 Subject: [PATCH 06/15] configuration update --- packages/replay/src/replay.ts | 9 +++++---- packages/replay/src/types/replay.ts | 5 ++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 32bb1a99a1a5..17640fd2c471 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ // TODO: We might want to split this file up -import { EventType, record } from '@sentry-internal/rrweb'; +import { EventType, getCanvasManager, record } from '@sentry-internal/rrweb'; import { captureException, getClient, getCurrentHub } from '@sentry/core'; import type { ReplayRecordingMode, Transaction } from '@sentry/types'; import { logger } from '@sentry/utils'; @@ -339,10 +339,11 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, - ...(this._options._experiments.enableCanvas && { + ...(this._options._experiments.canvas && { recordCanvas: true, - sampling: { canvas: 4 }, - dataURLOptions: { quality: 0.6 }, + sampling: { canvas: this._options._experiments.canvas.fps }, + dataURLOptions: { quality: this._options._experiments.canvas.quality }, + getCanvasManager, }), }); } catch (err) { diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index b88e045fb678..4ae15f4c1995 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -232,7 +232,10 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { _experiments: Partial<{ captureExceptions: boolean; traceInternals: boolean; - enableCanvas: boolean; + canvas: { + fps: number, + quality: number + }; }>; } From 3b8a57f95345f1c580ab841174a67aa0a589c2fc Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 11:56:33 -0500 Subject: [PATCH 07/15] fix lint --- packages/replay/src/types/replay.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 4ae15f4c1995..3b15a451006c 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -233,8 +233,8 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { captureExceptions: boolean; traceInternals: boolean; canvas: { - fps: number, - quality: number + fps: number; + quality: number; }; }>; } From b17b4bcd12060516d03f8f2852e012bcc6b00734 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 14:25:36 -0500 Subject: [PATCH 08/15] reduce bundle size --- packages/replay/src/replay.ts | 2 +- packages/replay/src/types/replay.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 17640fd2c471..204ad7e77f18 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -343,7 +343,7 @@ export class ReplayContainer implements ReplayContainerInterface { recordCanvas: true, sampling: { canvas: this._options._experiments.canvas.fps }, dataURLOptions: { quality: this._options._experiments.canvas.quality }, - getCanvasManager, + ...this._options._experiments.canvas.manager, }), }); } catch (err) { diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 3b15a451006c..6d7b7e3e8acb 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -15,6 +15,7 @@ import type { AllPerformanceEntry, AllPerformanceEntryData, ReplayPerformanceEnt import type { ReplayFrameEvent } from './replayFrame'; import type { ReplayNetworkRequestOrResponse } from './request'; import type { ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; +import type { getCanvasManager } from '@sentry-internal/rrweb'; export type RecordingEvent = ReplayFrameEvent | ReplayEventWithTime; export type RecordingOptions = RrwebRecordOptions; @@ -235,6 +236,7 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { canvas: { fps: number; quality: number; + manager: typeof getCanvasManager; }; }>; } From ac14ad00370d6d6ba04d540bc3e17649a59da4a9 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:01:13 -0500 Subject: [PATCH 09/15] Update packages/replay/src/replay.ts Co-authored-by: Billy Vong --- packages/replay/src/replay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 204ad7e77f18..56dbcbff5a1c 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -343,7 +343,7 @@ export class ReplayContainer implements ReplayContainerInterface { recordCanvas: true, sampling: { canvas: this._options._experiments.canvas.fps }, dataURLOptions: { quality: this._options._experiments.canvas.quality }, - ...this._options._experiments.canvas.manager, + getCanvasManager: this._options._experiments.canvas.manager, }), }); } catch (err) { From 0ffa8fa0fb9d614f985c12a5a57533c6ce5a2c34 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 16:56:57 -0500 Subject: [PATCH 10/15] update import --- packages/replay/src/replay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 56dbcbff5a1c..7452b1d72bd4 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -1,5 +1,5 @@ /* eslint-disable max-lines */ // TODO: We might want to split this file up -import { EventType, getCanvasManager, record } from '@sentry-internal/rrweb'; +import { EventType, record } from '@sentry-internal/rrweb'; import { captureException, getClient, getCurrentHub } from '@sentry/core'; import type { ReplayRecordingMode, Transaction } from '@sentry/types'; import { logger } from '@sentry/utils'; From aab0c2ad53cbb37c5baf1e5613dfd1d550060d79 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:52:05 -0500 Subject: [PATCH 11/15] update types --- packages/replay/src/replay.ts | 9 +++++++++ packages/replay/src/types/replay.ts | 8 ++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 7452b1d72bd4..17b4f7d9f19a 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -331,6 +331,15 @@ export class ReplayContainer implements ReplayContainerInterface { */ public startRecording(): void { try { + // default canvas to 4 fps and quality of 0.6 + if (this._options._experiments.canvas) { + if (!this._options._experiments.canvas.fps) { + this._options._experiments.canvas.fps = 4; + } + if (!this._options._experiments.canvas.fps) { + this._options._experiments.canvas.fps = 0.6; + } + } this._stopRecording = record({ ...this._recordingOptions, // When running in error sampling mode, we need to overwrite `checkoutEveryNms` diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 6d7b7e3e8acb..5cf37bcdb623 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -15,7 +15,6 @@ import type { AllPerformanceEntry, AllPerformanceEntryData, ReplayPerformanceEnt import type { ReplayFrameEvent } from './replayFrame'; import type { ReplayNetworkRequestOrResponse } from './request'; import type { ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; -import type { getCanvasManager } from '@sentry-internal/rrweb'; export type RecordingEvent = ReplayFrameEvent | ReplayEventWithTime; export type RecordingOptions = RrwebRecordOptions; @@ -234,9 +233,10 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { captureExceptions: boolean; traceInternals: boolean; canvas: { - fps: number; - quality: number; - manager: typeof getCanvasManager; + fps?: number; + quality?: number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + manager: () => any; }; }>; } From fc94d449a47ab76a1bb7f22556d093c6896dc7f9 Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:21:24 -0500 Subject: [PATCH 12/15] fix default --- packages/replay/src/replay.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 17b4f7d9f19a..e178a941ac83 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -331,15 +331,6 @@ export class ReplayContainer implements ReplayContainerInterface { */ public startRecording(): void { try { - // default canvas to 4 fps and quality of 0.6 - if (this._options._experiments.canvas) { - if (!this._options._experiments.canvas.fps) { - this._options._experiments.canvas.fps = 4; - } - if (!this._options._experiments.canvas.fps) { - this._options._experiments.canvas.fps = 0.6; - } - } this._stopRecording = record({ ...this._recordingOptions, // When running in error sampling mode, we need to overwrite `checkoutEveryNms` @@ -350,8 +341,8 @@ export class ReplayContainer implements ReplayContainerInterface { onMutation: this._onMutationHandler, ...(this._options._experiments.canvas && { recordCanvas: true, - sampling: { canvas: this._options._experiments.canvas.fps }, - dataURLOptions: { quality: this._options._experiments.canvas.quality }, + sampling: { canvas: this._options._experiments.canvas.fps || 4}, + dataURLOptions: { quality: this._options._experiments.canvas.quality || 0.6}, getCanvasManager: this._options._experiments.canvas.manager, }), }); From 6b548268745a65a108f7175a3a2fb1b13c5dee84 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Wed, 6 Dec 2023 12:24:55 -0500 Subject: [PATCH 13/15] add types for canvas manager --- packages/replay/src/types/replay.ts | 5 ++--- packages/replay/src/types/rrweb.ts | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/packages/replay/src/types/replay.ts b/packages/replay/src/types/replay.ts index 5cf37bcdb623..d854f258c073 100644 --- a/packages/replay/src/types/replay.ts +++ b/packages/replay/src/types/replay.ts @@ -14,7 +14,7 @@ import type { SKIPPED, THROTTLED } from '../util/throttle'; import type { AllPerformanceEntry, AllPerformanceEntryData, ReplayPerformanceEntry } from './performance'; import type { ReplayFrameEvent } from './replayFrame'; import type { ReplayNetworkRequestOrResponse } from './request'; -import type { ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; +import type { CanvasManagerInterface, GetCanvasManagerOptions, ReplayEventWithTime, RrwebRecordOptions } from './rrweb'; export type RecordingEvent = ReplayFrameEvent | ReplayEventWithTime; export type RecordingOptions = RrwebRecordOptions; @@ -235,8 +235,7 @@ export interface ReplayPluginOptions extends ReplayNetworkOptions { canvas: { fps?: number; quality?: number; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - manager: () => any; + manager: (options: GetCanvasManagerOptions) => CanvasManagerInterface; }; }>; } diff --git a/packages/replay/src/types/rrweb.ts b/packages/replay/src/types/rrweb.ts index bc78c5811b12..bbef4f94903f 100644 --- a/packages/replay/src/types/rrweb.ts +++ b/packages/replay/src/types/rrweb.ts @@ -44,3 +44,23 @@ export type RrwebRecordOptions = { blockSelector?: string; maskInputOptions?: Record; } & Record; + +export interface CanvasManagerInterface { + reset(): void; + freeze(): void; + unfreeze(): void; + lock(): void; + unlock(): void; +} + +export interface GetCanvasManagerOptions { + recordCanvas: boolean; + blockClass: string | RegExp; + blockSelector: string | null; + unblockSelector: string | null; + sampling?: 'all' | number; + dataURLOptions: Partial<{ + type: string; + quality: number; + }>; +} From 67d7dd129759f51041ba38b0e05a243e46349bfc Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Wed, 6 Dec 2023 12:46:17 -0500 Subject: [PATCH 14/15] fix lint --- packages/replay/src/replay.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index e178a941ac83..21f3c124eba3 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -341,8 +341,8 @@ export class ReplayContainer implements ReplayContainerInterface { onMutation: this._onMutationHandler, ...(this._options._experiments.canvas && { recordCanvas: true, - sampling: { canvas: this._options._experiments.canvas.fps || 4}, - dataURLOptions: { quality: this._options._experiments.canvas.quality || 0.6}, + sampling: { canvas: this._options._experiments.canvas.fps || 4 }, + dataURLOptions: { quality: this._options._experiments.canvas.quality || 0.6 }, getCanvasManager: this._options._experiments.canvas.manager, }), }); From 3275143c47a0246ebd8d1bd64fd5c42e5af2b2fd Mon Sep 17 00:00:00 2001 From: Catherine Lee <55311782+c298lee@users.noreply.github.com> Date: Thu, 7 Dec 2023 11:20:19 -0500 Subject: [PATCH 15/15] styling --- packages/replay/src/replay.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/replay/src/replay.ts b/packages/replay/src/replay.ts index 21f3c124eba3..635db47245d6 100644 --- a/packages/replay/src/replay.ts +++ b/packages/replay/src/replay.ts @@ -331,6 +331,7 @@ export class ReplayContainer implements ReplayContainerInterface { */ public startRecording(): void { try { + const canvas = this._options._experiments.canvas; this._stopRecording = record({ ...this._recordingOptions, // When running in error sampling mode, we need to overwrite `checkoutEveryNms` @@ -339,11 +340,11 @@ export class ReplayContainer implements ReplayContainerInterface { ...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }), emit: getHandleRecordingEmit(this), onMutation: this._onMutationHandler, - ...(this._options._experiments.canvas && { + ...(canvas && { recordCanvas: true, - sampling: { canvas: this._options._experiments.canvas.fps || 4 }, - dataURLOptions: { quality: this._options._experiments.canvas.quality || 0.6 }, - getCanvasManager: this._options._experiments.canvas.manager, + sampling: { canvas: canvas.fps || 4 }, + dataURLOptions: { quality: canvas.quality || 0.6 }, + getCanvasManager: canvas.manager, }), }); } catch (err) {