Skip to content

Commit 2b34955

Browse files
committed
change to not use _experiments for canvas
1 parent 5465347 commit 2b34955

File tree

5 files changed

+70
-64
lines changed

5 files changed

+70
-64
lines changed

packages/replay-canvas/src/canvas.ts

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,53 @@
1-
import { getCanvasManager } from '@sentry-internal/rrweb';
2-
import type { ReplayConfiguration } from '@sentry/replay';
1+
import { CanvasManager } from '@sentry-internal/rrweb';
2+
import type { CanvasManagerInterface } from '@sentry/replay';
33
import type { Integration } from '@sentry/types';
44

55
interface ReplayCanvasOptions {
66
quality: 'low' | 'medium' | 'high';
77
}
88

9+
interface ReplayCanvasIntegrationOptions {
10+
recordCanvas: true;
11+
getCanvasManager: (options: ConstructorParameters<typeof CanvasManager>[0]) => CanvasManagerInterface;
12+
sampling: {
13+
canvas: number;
14+
};
15+
dataURLOptions: {
16+
type: string;
17+
quality: number;
18+
};
19+
}
20+
21+
const CANVAS_QUALITY = {
22+
low: {
23+
sampling: {
24+
canvas: 1,
25+
},
26+
dataURLOptions: {
27+
type: 'image/webp',
28+
quality: 0.25,
29+
},
30+
},
31+
medium: {
32+
sampling: {
33+
canvas: 2,
34+
},
35+
dataURLOptions: {
36+
type: 'image/webp',
37+
quality: 0.4,
38+
},
39+
},
40+
high: {
41+
sampling: {
42+
canvas: 4,
43+
},
44+
dataURLOptions: {
45+
type: 'image/webp',
46+
quality: 0.5,
47+
},
48+
},
49+
};
50+
951
/** An integration to add canvas recording to replay. */
1052
export class ReplayCanvas implements Integration {
1153
/**
@@ -20,10 +62,10 @@ export class ReplayCanvas implements Integration {
2062

2163
private _canvasOptions: ReplayCanvasOptions;
2264

23-
public constructor(options?: Partial<ReplayCanvasOptions>) {
65+
public constructor(options: Partial<ReplayCanvasOptions> = {}) {
2466
this.name = ReplayCanvas.id;
2567
this._canvasOptions = {
26-
quality: (options && options.quality) || 'medium',
68+
quality: options.quality || 'medium',
2769
};
2870
}
2971

@@ -36,15 +78,13 @@ export class ReplayCanvas implements Integration {
3678
* Get the options that should be merged into replay options.
3779
* This is what is actually called by the Replay integration to setup canvas.
3880
*/
39-
public getOptions(): Partial<ReplayConfiguration> {
81+
public getOptions(): ReplayCanvasIntegrationOptions {
82+
const { quality } = this._canvasOptions;
83+
4084
return {
41-
_experiments: {
42-
canvas: {
43-
...this._canvasOptions,
44-
manager: getCanvasManager,
45-
quality: this._canvasOptions.quality,
46-
},
47-
},
85+
recordCanvas: true,
86+
getCanvasManager: (options: ConstructorParameters<typeof CanvasManager>[0]) => new CanvasManager(options),
87+
...(CANVAS_QUALITY[quality || 'medium'] || CANVAS_QUALITY.medium),
4888
};
4989
}
5090
}

packages/replay/src/constants.ts

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -53,33 +53,3 @@ export const MAX_REPLAY_DURATION = 3_600_000; // 60 minutes in ms;
5353

5454
/** Default attributes to be ignored when `maskAllText` is enabled */
5555
export const DEFAULT_IGNORED_ATTRIBUTES = ['title', 'placeholder'];
56-
57-
export const CANVAS_QUALITY = {
58-
low: {
59-
sampling: {
60-
canvas: 1,
61-
},
62-
dataURLOptions: {
63-
type: 'image/webp',
64-
quality: 0.25,
65-
},
66-
},
67-
medium: {
68-
sampling: {
69-
canvas: 2,
70-
},
71-
dataURLOptions: {
72-
type: 'image/webp',
73-
quality: 0.4,
74-
},
75-
},
76-
high: {
77-
sampling: {
78-
canvas: 4,
79-
},
80-
dataURLOptions: {
81-
type: 'image/webp',
82-
quality: 0.5,
83-
},
84-
},
85-
};

packages/replay/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export type {
1111
ReplayFrameEvent,
1212
ReplaySpanFrame,
1313
ReplaySpanFrameEvent,
14+
CanvasManagerInterface,
1415
} from './types';
1516

1617
// TODO (v8): Remove deprecated types

packages/replay/src/integration.ts

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -349,11 +349,6 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
349349

350350
/** Get canvas options from ReplayCanvas integration, if it is also added. */
351351
private _maybeLoadFromReplayCanvasIntegration(): void {
352-
// If already defined, skip this...
353-
if (this._initialOptions._experiments.canvas) {
354-
return;
355-
}
356-
357352
// To save bundle size, we skip checking for stuff here
358353
// and instead just try-catch everything - as generally this should all be defined
359354
/* eslint-disable @typescript-eslint/no-non-null-assertion */
@@ -365,16 +360,8 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,
365360
if (!canvasIntegration) {
366361
return;
367362
}
368-
const additionalOptions = canvasIntegration.getOptions();
369-
370-
const mergedExperimentsOptions = {
371-
...this._initialOptions._experiments,
372-
...additionalOptions._experiments,
373-
};
374-
375-
this._initialOptions._experiments = mergedExperimentsOptions;
376363

377-
this._replay!.getOptions()._experiments = mergedExperimentsOptions;
364+
this._replay!.addIntegration('canvas', canvasIntegration.getOptions());
378365
} catch {
379366
// ignore errors here
380367
}

packages/replay/src/replay.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import { logger } from '@sentry/utils';
1212

1313
import {
1414
BUFFER_CHECKOUT_TIME,
15-
CANVAS_QUALITY,
1615
SESSION_IDLE_EXPIRE_DURATION,
1716
SESSION_IDLE_PAUSE_DURATION,
1817
SLOW_CLICK_SCROLL_TIMEOUT,
@@ -145,6 +144,11 @@ export class ReplayContainer implements ReplayContainerInterface {
145144

146145
private _context: InternalEventContext;
147146

147+
/**
148+
* Internal integrations (e.g. canvas)
149+
*/
150+
private _integrations: Record<string, Record<string, unknown>>;
151+
148152
public constructor({
149153
options,
150154
recordingOptions,
@@ -163,6 +167,7 @@ export class ReplayContainer implements ReplayContainerInterface {
163167
this._lastActivity = Date.now();
164168
this._isEnabled = false;
165169
this._isPaused = false;
170+
this._integrations = {};
166171
this._hasInitializedCoreListeners = false;
167172
this._context = {
168173
errorIds: new Set(),
@@ -338,7 +343,8 @@ export class ReplayContainer implements ReplayContainerInterface {
338343
*/
339344
public startRecording(): void {
340345
try {
341-
const canvas = this._options._experiments.canvas;
346+
const { canvas } = this._integrations;
347+
342348
this._stopRecording = record({
343349
...this._recordingOptions,
344350
// When running in error sampling mode, we need to overwrite `checkoutEveryNms`
@@ -347,12 +353,7 @@ export class ReplayContainer implements ReplayContainerInterface {
347353
...(this.recordingMode === 'buffer' && { checkoutEveryNms: BUFFER_CHECKOUT_TIME }),
348354
emit: getHandleRecordingEmit(this),
349355
onMutation: this._onMutationHandler,
350-
...(canvas &&
351-
canvas.manager && {
352-
recordCanvas: true,
353-
getCanvasManager: canvas.manager,
354-
...(CANVAS_QUALITY[canvas.quality || 'medium'] || CANVAS_QUALITY.medium),
355-
}),
356+
...canvas,
356357
});
357358
} catch (err) {
358359
this._handleException(err);
@@ -717,6 +718,13 @@ export class ReplayContainer implements ReplayContainerInterface {
717718
return spanToJSON(lastTransaction).description;
718719
}
719720

721+
/**
722+
* Internal integration use only, should not be public
723+
*/
724+
public addIntegration(name: string, options: Record<string, unknown>): void {
725+
this._integrations[name] = options;
726+
}
727+
720728
/**
721729
* Initialize and start all listeners to varying events (DOM,
722730
* Performance Observer, Recording, Sentry SDK, etc)

0 commit comments

Comments
 (0)