Skip to content

Commit d05f037

Browse files
mydearamchaik
authored andcommitted
ref(replay): Extract worker into dedicated package (getsentry#7139)
1 parent 77bad3c commit d05f037

26 files changed

+226
-50
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"packages/react",
5353
"packages/remix",
5454
"packages/replay",
55+
"packages/replay-worker",
5556
"packages/serverless",
5657
"packages/svelte",
5758
"packages/tracing",

packages/replay-worker/.eslintignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vendor

packages/replay-worker/.eslintrc.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Note: All paths are relative to the directory in which eslint is being run, rather than the directory where this file
2+
// lives
3+
4+
// ESLint config docs: https://eslint.org/docs/user-guide/configuring/
5+
6+
module.exports = {
7+
extends: ['../../.eslintrc.js'],
8+
overrides: [
9+
{
10+
files: ['src/**/*.ts'],
11+
rules: {
12+
// We cannot use backticks, as that conflicts with the stringified worker
13+
'prefer-template': 'off',
14+
},
15+
},
16+
],
17+
};

packages/replay-worker/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
/*.tgz
3+
.eslintcache
4+
build
5+
!vendor/*.d.ts

packages/replay-worker/LICENSE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6+
persons to whom the Software is furnished to do so, subject to the following conditions:
7+
8+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9+
Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

packages/replay-worker/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<p align="center">
2+
<a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-wordmark-dark-280x84.png" alt="Sentry" width="280" height="84">
4+
</a>
5+
</p>
6+
7+
# Sentry Session Replay Worker
8+
9+
This is an internal package that is used by @sentry/replay.
10+
It generates a web worker and converts it to a string, so that we can process it easier in replay.
11+
12+
By extracting this into a dedicated (private, internal) package, we can streamline the build of replay.

packages/replay-worker/jest.config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../jest/jest.config.js');

packages/replay-worker/package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"name": "@sentry-internal/replay-worker",
3+
"version": "7.37.2",
4+
"description": "Worker for @sentry/replay",
5+
"main": "build/index.js",
6+
"module": "build/index.js",
7+
"sideEffects": false,
8+
"private": true,
9+
"scripts": {
10+
"build": "yarn build:transpile",
11+
"build:transpile": "rollup -c rollup.worker.config.js",
12+
"build:types": "yarn build:transpile",
13+
"build:dev": "yarn build",
14+
"build:watch": "run-p build:transpile:watch",
15+
"build:dev:watch": "run-p build:watch",
16+
"build:transpile:watch": "yarn build:rollup --watch",
17+
"clean": "rimraf build",
18+
"fix": "run-s fix:eslint fix:prettier",
19+
"fix:eslint": "eslint . --format stylish --fix",
20+
"fix:prettier": "prettier --write \"{src,test}/**/*.ts\"",
21+
"lint": "run-s lint:prettier lint:eslint",
22+
"lint:eslint": "eslint . --format stylish",
23+
"lint:prettier": "prettier --check \"{src,test}/**/*.ts\"",
24+
"test": "jest",
25+
"test:watch": "jest --watch"
26+
},
27+
"repository": {
28+
"type": "git",
29+
"url": "git+https://github.com/getsentry/sentry-javascript.git"
30+
},
31+
"author": "Sentry",
32+
"license": "MIT",
33+
"bugs": {
34+
"url": "https://github.com/getsentry/sentry-javascript/issues"
35+
},
36+
"homepage": "https://docs.sentry.io/platforms/javascript/session-replay/",
37+
"devDependencies": {
38+
"@types/pako": "^2.0.0",
39+
"rollup-plugin-copy": "~3.4.0",
40+
"tslib": "^1.9.3"
41+
},
42+
"dependencies": {
43+
"pako": "^2.1.0"
44+
},
45+
"engines": {
46+
"node": ">=12"
47+
},
48+
"volta": {
49+
"extends": "../../package.json"
50+
}
51+
}

packages/replay/rollup.config.worker.js renamed to packages/replay-worker/rollup.worker.config.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import resolve from '@rollup/plugin-node-resolve';
44
import typescript from '@rollup/plugin-typescript';
55
import { defineConfig } from 'rollup';
66
import { terser } from 'rollup-plugin-terser';
7+
import copy from 'rollup-plugin-copy';
78

89
const config = defineConfig({
9-
input: ['./worker/src/worker.ts'],
10+
input: ['./src/worker.ts'],
1011
output: {
11-
dir: './src/worker/',
12+
dir: './build/',
1213
format: 'esm',
1314
},
1415
plugins: [
15-
typescript({ tsconfig: './tsconfig.worker.json' }),
16+
typescript({ tsconfig: './tsconfig.json', inlineSourceMap: false, sourceMap: false, inlineSources: false }),
1617
resolve(),
1718
terser({
1819
mangle: {
@@ -25,6 +26,9 @@ const config = defineConfig({
2526
return `export default \`${code}\`;`;
2627
},
2728
},
29+
copy({
30+
targets: [{ src: 'vendor/*', dest: 'build' }],
31+
}),
2832
],
2933
});
3034

packages/replay/worker/src/Compressor.ts renamed to packages/replay-worker/src/Compressor.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
import { constants, Deflate } from 'pako';
1+
import { constants, Deflate, deflate } from 'pako';
22

3+
/**
4+
* A stateful compressor that can be used to batch compress events.
5+
*/
36
export class Compressor {
47
/**
58
* pako deflator instance
@@ -15,10 +18,16 @@ export class Compressor {
1518
this._init();
1619
}
1720

21+
/**
22+
* Clear the compressor buffer.
23+
*/
1824
public clear(): void {
1925
this._init();
2026
}
2127

28+
/**
29+
* Add an event to the compressor buffer.
30+
*/
2231
public addEvent(data: string): void {
2332
if (!data) {
2433
throw new Error('Adding invalid event');
@@ -34,6 +43,9 @@ export class Compressor {
3443
this._hasEvents = true;
3544
}
3645

46+
/**
47+
* Finish compression of the current buffer.
48+
*/
3749
public finish(): Uint8Array {
3850
// We should always have a list, it can be empty
3951
this.deflate.push(']', constants.Z_FINISH);
@@ -51,6 +63,9 @@ export class Compressor {
5163
return result;
5264
}
5365

66+
/**
67+
* Re-initialize the compressor buffer.
68+
*/
5469
private _init(): void {
5570
this._hasEvents = false;
5671
this.deflate = new Deflate();
@@ -59,3 +74,10 @@ export class Compressor {
5974
this.deflate.push('[', constants.Z_NO_FLUSH);
6075
}
6176
}
77+
78+
/**
79+
* Compress a string.
80+
*/
81+
export function compress(data: string): Uint8Array {
82+
return deflate(data);
83+
}

packages/replay/worker/src/handleMessage.ts renamed to packages/replay-worker/src/handleMessage.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
2-
import { Compressor } from './Compressor';
2+
import { compress, Compressor } from './Compressor';
33

44
const compressor = new Compressor();
55

66
interface Handlers {
77
clear: () => void;
88
addEvent: (data: string) => void;
9-
finish: () => void;
9+
finish: () => Uint8Array;
10+
compress: (data: string) => Uint8Array;
1011
}
1112

1213
const handlers: Handlers = {
1314
clear: () => {
1415
compressor.clear();
15-
return '';
1616
},
1717

1818
addEvent: (data: string) => {
@@ -22,8 +22,15 @@ const handlers: Handlers = {
2222
finish: () => {
2323
return compressor.finish();
2424
},
25+
26+
compress: (data: string) => {
27+
return compress(data);
28+
},
2529
};
2630

31+
/**
32+
* Handler for worker messages.
33+
*/
2734
export function handleMessage(e: MessageEvent): void {
2835
const method = e.data.method as string;
2936
const id = e.data.id as number;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// TODO Once https://github.com/microsoft/TypeScript/issues/33094 is done (if it ever is), this file can disappear, as
2+
// it's purely a placeholder to satisfy VSCode.
3+
{
4+
"extends": "../tsconfig.test.json",
5+
6+
"include": ["./**/*"]
7+
}

packages/replay/test/unit/worker/Compressor.test.ts renamed to packages/replay-worker/test/unit/Compressor.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import pako from 'pako';
22

3-
import { Compressor } from '../../../worker/src/Compressor';
3+
import { Compressor } from '../../src/Compressor';
44

5-
describe('Unit | worker | Compressor', () => {
5+
describe('Compressor', () => {
66
it('compresses multiple events', () => {
77
const compressor = new Compressor();
88

packages/replay-worker/tsconfig.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"module": "esnext",
5+
"lib": ["webworker", "scripthost"],
6+
"esModuleInterop": true,
7+
"target": "es6",
8+
"strictPropertyInitialization": false
9+
},
10+
"include": ["src/**/*.ts"]
11+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.json",
3+
"include": ["test/**/*.ts"],
4+
"compilerOptions": {
5+
"types": ["node", "jest"]
6+
}
7+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export function getWorkerURL(): string;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import workerString from './worker';
2+
3+
export function getWorkerURL() {
4+
const workerBlob = new Blob([workerString]);
5+
return URL.createObjectURL(workerBlob);
6+
}

packages/replay/.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
module.exports = {
77
extends: ['../../.eslintrc.js'],
8-
ignorePatterns: ['rollup.config.worker.js'],
98
overrides: [
109
{
1110
files: ['worker/**/*.ts'],

packages/replay/package.json

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,22 @@
77
"types": "build/npm/types/index.d.ts",
88
"sideEffects": false,
99
"scripts": {
10-
"build": "run-s build:worker && run-p build:core build:types build:bundle",
11-
"build:transpile": "run-s build:worker build:core",
10+
"build": "run-p build:transpile build:types build:bundle",
11+
"build:transpile": "rollup -c rollup.npm.config.js",
1212
"build:bundle": "rollup -c rollup.bundle.config.js",
13-
"build:dev": "run-p build:worker build:transpile build:types",
14-
"build:worker": "rollup -c rollup.config.worker.js",
15-
"build:core": "rollup -c rollup.npm.config.js",
13+
"build:dev": "run-p build:transpile build:types",
1614
"build:types": "tsc -p tsconfig.types.json",
17-
"build:watch": "run-p build:worker:watch build:core:watch build:bundle:watch build:types:watch",
18-
"build:dev:watch": "run-p build:core:watch build:types:watch",
19-
"build:core:watch": "yarn build:core --watch",
20-
"build:worker:watch": "yarn build:worker --watch",
15+
"build:watch": "run-p build:transpile:watch build:bundle:watch build:types:watch",
16+
"build:dev:watch": "run-p build:transpile:watch build:types:watch",
17+
"build:transpile:watch": "yarn build:transpile --watch",
2118
"build:bundle:watch": "yarn build:bundle --watch",
2219
"build:types:watch": "tsc -p tsconfig.types.json --watch",
2320
"build:tarball": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm",
2421
"circularDepCheck": "madge --circular src/index.ts",
2522
"clean": "rimraf build sentry-replay-*.tgz",
2623
"fix": "run-s fix:eslint fix:prettier",
2724
"fix:eslint": "eslint . --format stylish --fix",
28-
"fix:prettier": "prettier --write \"{src,test,scripts,worker}/**/*.ts\"",
25+
"fix:prettier": "prettier --write \"{src,test,scripts}/**/*.ts\"",
2926
"lint": "run-s lint:prettier lint:eslint",
3027
"lint:eslint": "eslint . --format stylish",
3128
"lint:prettier": "prettier --check \"{src,test,scripts,worker}/**/*.ts\"",
@@ -46,10 +43,9 @@
4643
"homepage": "https://docs.sentry.io/platforms/javascript/session-replay/",
4744
"devDependencies": {
4845
"@babel/core": "^7.17.5",
46+
"@sentry-internal/replay-worker": "7.37.2",
4947
"@sentry-internal/rrweb": "1.103.0",
50-
"@types/pako": "^2.0.0",
5148
"jsdom-worker": "^0.2.1",
52-
"pako": "^2.0.4",
5349
"tslib": "^1.9.3"
5450
},
5551
"dependencies": {

packages/replay/rollup.npm.config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ export default makeNPMConfigVariants(
55
hasBundles: true,
66
packageSpecificConfig: {
77
output: {
8-
// set exports to 'named' or 'auto' so that rollup doesn't warn about
9-
// the default export in `worker/worker.js`
8+
// set exports to 'named' or 'auto' so that rollup doesn't warn
109
exports: 'named',
1110
// set preserveModules to false because for Replay we actually want
1211
// to bundle everything into one file.

packages/replay/src/eventBuffer/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1+
import { getWorkerURL } from '@sentry-internal/replay-worker';
12
import { logger } from '@sentry/utils';
23

34
import type { EventBuffer } from '../types';
4-
import workerString from '../worker/worker.js';
55
import { EventBufferArray } from './EventBufferArray';
66
import { EventBufferProxy } from './EventBufferProxy';
77

@@ -16,8 +16,7 @@ export function createEventBuffer({ useCompression }: CreateEventBufferParams):
1616
// eslint-disable-next-line no-restricted-globals
1717
if (useCompression && window.Worker) {
1818
try {
19-
const workerBlob = new Blob([workerString]);
20-
const workerUrl = URL.createObjectURL(workerBlob);
19+
const workerUrl = getWorkerURL();
2120

2221
__DEBUG_BUILD__ && logger.log('[Replay] Using compression worker');
2322
const worker = new Worker(workerUrl);

packages/replay/src/worker/worker.js

Lines changed: 0 additions & 2 deletions
This file was deleted.

packages/replay/tsconfig.worker.json

Lines changed: 0 additions & 19 deletions
This file was deleted.

0 commit comments

Comments
 (0)