Skip to content

Commit 49fec35

Browse files
mydeabillyvg
authored andcommitted
feat: Refactor module scope vars & export mirror & takeFullSnapshot directly (#113)
Currently, we use these from `record.xx`, which is not ideal thinking about treeshaking and lazy loading. This moves these to be proper exports so we can use the in Replay without having to import `record` and everything that comes with it (=everything).
1 parent 3d91965 commit 49fec35

File tree

3 files changed

+33
-38
lines changed

3 files changed

+33
-38
lines changed

packages/rrweb/src/index.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import record from './record';
22
import { Replayer } from './replay';
33
import canvasMutation from './replay/canvas';
4-
import { _mirror } from './utils';
54
import * as utils from './utils';
65

76
export {
@@ -20,15 +19,6 @@ export type {
2019

2120
export type { recordOptions } from './types';
2221

23-
const { addCustomEvent } = record;
24-
const { freezePage } = record;
22+
export { canvasMutation, record, Replayer, utils };
2523

26-
export {
27-
record,
28-
addCustomEvent,
29-
freezePage,
30-
Replayer,
31-
canvasMutation,
32-
_mirror as mirror,
33-
utils,
34-
};
24+
export { takeFullSnapshot, mirror, freezePage, addCustomEvent } from './record';

packages/rrweb/src/record/index.ts

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,14 @@ declare global {
5858
const __RRWEB_EXCLUDE_IFRAME__: boolean;
5959
}
6060

61-
let wrappedEmit!: (e: eventWithTime, isCheckout?: boolean) => void;
61+
// These are stored in module scope because we access them in other exported methods
62+
let _wrappedEmit:
63+
| undefined
64+
| ((e: eventWithoutTime, isCheckout?: boolean) => void);
65+
let _takeFullSnapshot: undefined | ((isCheckout?: boolean) => void);
6266

63-
let takeFullSnapshot!: (isCheckout?: boolean) => void;
64-
let canvasManager: CanvasManagerInterface;
65-
let recording = false;
67+
export const mirror = createMirror();
6668

67-
const mirror = createMirror();
6869
function record<T = eventWithTime>(
6970
options: recordOptions<T> = {},
7071
): listenerHandler | undefined {
@@ -200,7 +201,7 @@ function record<T = eventWithTime>(
200201
}
201202
return e as unknown as T;
202203
};
203-
wrappedEmit = (r: eventWithoutTime, isCheckout?: boolean) => {
204+
const wrappedEmit = (r: eventWithoutTime, isCheckout?: boolean) => {
204205
const e = r as eventWithTime;
205206
e.timestamp = nowTimestamp();
206207
if (
@@ -251,6 +252,7 @@ function record<T = eventWithTime>(
251252
}
252253
}
253254
};
255+
_wrappedEmit = wrappedEmit;
254256

255257
const wrappedMutationEmit = (m: mutationCallbackParam) => {
256258
wrappedEmit({
@@ -310,7 +312,7 @@ function record<T = eventWithTime>(
310312

311313
const processedNodeManager = new ProcessedNodeManager();
312314

313-
canvasManager =
315+
const canvasManager: CanvasManagerInterface =
314316
typeof __RRWEB_EXCLUDE_CANVAS__ === 'boolean' && __RRWEB_EXCLUDE_CANVAS__
315317
? new CanvasManagerNoop()
316318
: new CanvasManager({
@@ -361,7 +363,7 @@ function record<T = eventWithTime>(
361363
mirror,
362364
});
363365

364-
takeFullSnapshot = (isCheckout = false) => {
366+
const takeFullSnapshot = (isCheckout = false) => {
365367
if (!recordDOM) {
366368
return;
367369
}
@@ -446,6 +448,7 @@ function record<T = eventWithTime>(
446448
mirror.getId(document),
447449
);
448450
};
451+
_takeFullSnapshot = takeFullSnapshot;
449452

450453
try {
451454
const handlers: listenerHandler[] = [];
@@ -589,7 +592,6 @@ function record<T = eventWithTime>(
589592
const init = () => {
590593
takeFullSnapshot();
591594
handlers.push(observe(document));
592-
recording = true;
593595
};
594596
if (
595597
document.readyState === 'interactive' ||
@@ -623,7 +625,7 @@ function record<T = eventWithTime>(
623625
return () => {
624626
handlers.forEach((h) => h());
625627
processedNodeManager.destroy();
626-
recording = false;
628+
_takeFullSnapshot = undefined;
627629
unregisterErrorHandler();
628630
};
629631
} catch (error) {
@@ -632,30 +634,35 @@ function record<T = eventWithTime>(
632634
}
633635
}
634636

635-
record.addCustomEvent = <T>(tag: string, payload: T) => {
636-
if (!recording) {
637+
export function addCustomEvent<T>(tag: string, payload: T) {
638+
if (!_wrappedEmit) {
637639
throw new Error('please add custom event after start recording');
638640
}
639-
wrappedEmit({
641+
_wrappedEmit({
640642
type: EventType.Custom,
641643
data: {
642644
tag,
643645
payload,
644646
},
645647
});
646-
};
648+
}
647649

648-
record.freezePage = () => {
650+
export function freezePage() {
649651
mutationBuffers.forEach((buf) => buf.freeze());
650-
};
652+
}
651653

652-
record.takeFullSnapshot = (isCheckout?: boolean) => {
653-
if (!recording) {
654+
export function takeFullSnapshot(isCheckout?: boolean) {
655+
if (!_takeFullSnapshot) {
654656
throw new Error('please take full snapshot after start recording');
655657
}
656-
takeFullSnapshot(isCheckout);
657-
};
658+
_takeFullSnapshot(isCheckout);
659+
}
660+
661+
// record.addCustomEvent is removed because Sentry Session Replay does not use it
662+
// record.freezePage is removed because Sentry Session Replay does not use it
658663

664+
// For backwards compatibility - we can eventually remove this when we migrated to using the exported `mirror` & `takeFullSnapshot`
659665
record.mirror = mirror;
666+
record.takeFullSnapshot = takeFullSnapshot;
660667

661668
export default record;

packages/rrweb/test/record.test.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,10 @@ interface ISuite {
2929

3030
interface IWindow extends Window {
3131
rrweb: {
32-
record: ((
32+
record: (
3333
options: recordOptions<eventWithTime>,
34-
) => listenerHandler | undefined) & {
35-
takeFullSnapshot: (isCheckout?: boolean | undefined) => void;
36-
};
37-
34+
) => listenerHandler | undefined;
35+
takeFullSnapshot: (isCheckout?: boolean | undefined) => void;
3836
freezePage(): void;
3937
addCustomEvent<T>(tag: string, payload: T): void;
4038
};
@@ -611,7 +609,7 @@ describe('record', function (this: ISuite) {
611609

612610
setTimeout(() => {
613611
// When a full snapshot is checked out manually, all adoptedStylesheets should also be captured.
614-
rrweb.record.takeFullSnapshot(true);
612+
rrweb.takeFullSnapshot(true);
615613
resolve(undefined);
616614
}, 10);
617615
});

0 commit comments

Comments
 (0)