Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

feat: Add compression in webworker #72

Merged
merged 50 commits into from
Jun 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
4ac249b
feat: intitial compressor web worker
JoshFerge May 12, 2022
feba3b6
split out build steps, combine in build command
JoshFerge May 16, 2022
12d6e2c
Merge branch 'main' into jferg/initial-worker
JoshFerge May 25, 2022
d966a5b
remove export
JoshFerge May 25, 2022
cc0648b
feat: replay compression
JoshFerge May 13, 2022
ec78882
checkpoint
JoshFerge May 13, 2022
edf3b78
trying to get jest working
JoshFerge May 16, 2022
c30075a
get 1 test working
JoshFerge May 16, 2022
bc1e2f3
updates after rebasing
JoshFerge May 26, 2022
1fa6631
Merge branch 'main' into jferg/initial-worker-2
JoshFerge May 26, 2022
d86a5c2
Update worker/src/worker.ts
JoshFerge May 26, 2022
8298fbf
feat: added statusCodes to the xhr and fetch callbacks.
Danondso May 27, 2022
14ad9bf
fix?: handle the webworker not being present.
Danondso May 27, 2022
81f017c
chore: removed TODOs
Danondso May 27, 2022
d5878c1
checkpoint
JoshFerge May 31, 2022
f0408d3
checkpoint2
JoshFerge May 31, 2022
af53cb7
Merge branch 'main' into jferg/initial-worker-2
JoshFerge May 31, 2022
4f6cc09
test failing
JoshFerge May 31, 2022
dedd482
upgrade jest, use single array
JoshFerge Jun 1, 2022
238b059
Merge branch 'main' into jferg/initial-worker-2
JoshFerge Jun 1, 2022
d35d2cf
add todos
JoshFerge Jun 1, 2022
c1d0c7b
update yarn lock
JoshFerge Jun 1, 2022
6fc2d73
fix tests after merge
JoshFerge Jun 1, 2022
2e6df29
Merge branch 'main' into jferg/initial-worker-2
billyvg Jun 3, 2022
82c2183
wip: ensure json when streaming to compression worker
billyvg Jun 3, 2022
23a3ee6
wip fixing tests
billyvg Jun 6, 2022
97e9933
fix timestamp -n
billyvg Jun 6, 2022
8404bf0
fix tests
billyvg Jun 6, 2022
bad899b
fix rest of tests
billyvg Jun 6, 2022
57566f2
fix tests, re-impl retry uploads, re-impl checkout, refactor event bu…
billyvg Jun 7, 2022
6e6b5ea
oops accidentally deleted these
billyvg Jun 7, 2022
743a0f1
fixes
billyvg Jun 7, 2022
3e99763
Merge branch 'main' into jferg/initial-worker-2
billyvg Jun 7, 2022
a004489
upgrade jest + jest types
billyvg Jun 7, 2022
f5c74e9
remove some TODOs
billyvg Jun 7, 2022
40253cd
devdeps
billyvg Jun 7, 2022
656a5ab
noflush
billyvg Jun 13, 2022
7fab70a
do not capture resource events to sentry ingest
billyvg Jun 13, 2022
ebabe5a
cleanup
billyvg Jun 13, 2022
85a7651
do not capture sentry.transaction breadcrumb events
billyvg Jun 13, 2022
d8ea1f8
urg console.log
billyvg Jun 13, 2022
bf003a1
fix hostname
billyvg Jun 13, 2022
9b4fbff
fix ui exit breadcrumb
billyvg Jun 13, 2022
deb6d9d
update worker
billyvg Jun 13, 2022
b14a858
ignore sentry.transaction in handlescope
billyvg Jun 14, 2022
a6c2958
refactor + add tests
billyvg Jun 14, 2022
af314b5
remove use array buffer global
billyvg Jun 14, 2022
1c51dd6
wrong filename
billyvg Jun 14, 2022
ee49bce
bump yarn
billyvg Jun 14, 2022
c0a6d37
fix sticky test
billyvg Jun 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 47 additions & 3 deletions demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1483,8 +1483,12 @@
tslib "^1.9.3"

"@sentry/replay@file:..":
version "0.2.0-9"
version "0.2.0-10"
dependencies:
"@types/pako" "^2.0.0"
pako "^2.0.4"
rollup-plugin-node-resolve "^5.2.0"
rollup-plugin-terser "^7.0.2"
rrweb "^1.1.3"

"@sentry/tracing@^6.18.2":
Expand Down Expand Up @@ -1881,6 +1885,11 @@
version "13.5.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.5.3.tgz#37f1f539b7535b9fb4ef77d59db1847a837b7f17"

"@types/pako@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/pako/-/pako-2.0.0.tgz#12ab4c19107528452e73ac99132c875ccd43bdfb"
integrity sha512-10+iaz93qR5WYxTo+PMifD5TSxiOtdRaxBf7INGGXMQgTCu8Z/7GYWYFUOS3q/G0nE5boj1r4FEB+WSy7s5gbA==

"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
Expand Down Expand Up @@ -1921,6 +1930,13 @@
"@types/prop-types" "*"
csstype "^2.2.0"

"@types/resolve@0.0.8":
version "0.0.8"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
dependencies:
"@types/node" "*"

"@types/resolve@1.17.1":
version "1.17.1"
resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6"
Expand Down Expand Up @@ -3985,6 +4001,11 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==

estree-walker@^0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362"
integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==

estree-walker@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700"
Expand Down Expand Up @@ -6102,6 +6123,11 @@ p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"

pako@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d"
integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==

param-case@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5"
Expand Down Expand Up @@ -7161,7 +7187,7 @@ resolve.exports@^1.1.0:
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9"
integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==

resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0:
resolve@^1.11.1, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0:
version "1.22.0"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==
Expand Down Expand Up @@ -7195,7 +7221,18 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"

rollup-plugin-terser@^7.0.0:
rollup-plugin-node-resolve@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/rollup-plugin-node-resolve/-/rollup-plugin-node-resolve-5.2.0.tgz#730f93d10ed202473b1fb54a5997a7db8c6d8523"
integrity sha512-jUlyaDXts7TW2CqQ4GaO5VJ4PwwaV8VUGA7+km3n6k6xtOEacf61u0VXwN80phY/evMcaS+9eIeJ9MOyDxt5Zw==
dependencies:
"@types/resolve" "0.0.8"
builtin-modules "^3.1.0"
is-module "^1.0.0"
resolve "^1.11.1"
rollup-pluginutils "^2.8.1"

rollup-plugin-terser@^7.0.0, rollup-plugin-terser@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d"
integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==
Expand All @@ -7205,6 +7242,13 @@ rollup-plugin-terser@^7.0.0:
serialize-javascript "^4.0.0"
terser "^5.0.0"

rollup-pluginutils@^2.8.1:
version "2.8.2"
resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e"
integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==
dependencies:
estree-walker "^0.6.1"

rollup@^2.43.1:
version "2.70.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.70.0.tgz#17a92e5938e92a251b962352e904c9f558230ec7"
Expand Down
4 changes: 2 additions & 2 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import { compilerOptions } from './tsconfig.json';
export default async (): Promise<Config.InitialOptions> => {
return {
verbose: true,
preset: 'ts-jest',
preset: 'ts-jest/presets/js-with-ts', // needed when import worker.js
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
prefix: '<rootDir>/',
}),
setupFilesAfterEnv: ['./jest.setup.ts'],
testEnvironment: 'jsdom',
testMatch: ['<rootDir>/src/**/*(*.)@(spec|test).ts'],
testMatch: ['<rootDir>/(src|worker)/**/*(*.)@(spec|test).ts'],
};
};
4 changes: 2 additions & 2 deletions jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ expect.extend({
*/
toHaveSentReplay(
received: jest.Mocked<SentryReplay>,
expected?: RRWebEvent[]
expected?: string | Uint8Array
) {
const { calls } = received.sendReplayRequest.mock;
const lastCall = calls[calls.length - 1];
Expand Down Expand Up @@ -82,7 +82,7 @@ declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest {
interface Matchers<R> {
toHaveSentReplay(expected?: RRWebEvent[]): CustomMatcherResult;
toHaveSentReplay(expected?: string | Uint8Array): CustomMatcherResult;
toHaveSameSession(expected: ReplaySession): CustomMatcherResult;
}
}
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,23 @@
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.1",
"@sentry/types": "7.0.0",
"@types/jest": "^27.4.1",
"@types/jest": "^28.1.1",
"@types/node": "^16.0.0",
"@types/pako": "^1.0.4",
"@types/pako": "^2.0.0",
"@typescript-eslint/eslint-plugin": "^5.14.0",
"@typescript-eslint/parser": "^5.14.0",
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"husky": ">=6",
"jest": "^27.5.1",
"jest": "^28.1.1",
"jest-environment-jsdom": "^28.1.1",
"lint-staged": ">=10",
"prettier": "^2.5.1",
"rimraf": "^3.0.2",
"rollup": "^2.70.0",
"rollup-plugin-terser": "^7.0.2",
"ts-jest": "^27.1.3",
"ts-jest": "^28.0.4",
"ts-node": "^10.7.0",
"tslib": "^2.3.1",
"typescript": "^4.6.2"
Expand All @@ -68,7 +69,7 @@
},
"volta": {
"node": "14.19.0",
"yarn": "1.22.17"
"yarn": "1.22.19"
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": "yarn eslint --cache --fix"
Expand Down
12 changes: 8 additions & 4 deletions src/coreHandlers/handleFetch.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { ReplaySpan } from '@/types';
import { getCurrentHub } from '@sentry/browser';

export function handleFetch(handlerData: any): ReplaySpan {
// TODO: add status code into data, etc.

if (!handlerData.endTimestamp) {
return null;
}

const [op, description] = handlerData.args;

return {
description: handlerData.args[1],
op: handlerData.args[0],
description,
op,
startTimestamp: handlerData.startTimestamp / 1000,
endTimestamp: handlerData.endTimestamp / 1000,
data: {
statusCode: handlerData.response.status,
},
};
}
34 changes: 34 additions & 0 deletions src/coreHandlers/handleScope-unit.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import * as HandleScope from './handleScope';
import { mockSdk } from '@test';
import { getCurrentHub } from '@sentry/browser';

let mockHandleScope: jest.MockedFunction<typeof HandleScope.handleScope>;

jest.useFakeTimers();

beforeAll(function () {
mockSdk();
jest.spyOn(HandleScope, 'handleScope');
mockHandleScope = HandleScope.handleScope as jest.MockedFunction<
typeof HandleScope.handleScope
>;

jest.runAllTimers();
});

it('returns a breadcrumb only if last breadcrumb has changed (integration)', function () {
getCurrentHub().getScope().addBreadcrumb({ message: 'testing' });

expect(mockHandleScope).toHaveBeenCalledTimes(1);
expect(mockHandleScope).toHaveReturnedWith(
expect.objectContaining({ message: 'testing' })
);

mockHandleScope.mockClear();

// This will trigger breadcrumb/scope listener, but handleScope should return
// null because breadcrumbs has not changed
getCurrentHub().getScope().setUser({ email: 'foo@foo.com' });
expect(mockHandleScope).toHaveBeenCalledTimes(1);
expect(mockHandleScope).toHaveReturnedWith(null);
});
52 changes: 52 additions & 0 deletions src/coreHandlers/handleScope.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { Scope } from '@sentry/hub';
import { Breadcrumb } from '@sentry/types';
import * as HandleScope from './handleScope';

jest.spyOn(HandleScope, 'handleScope');
const mockHandleScope = HandleScope.handleScope as jest.MockedFunction<
typeof HandleScope.handleScope
>;

it('returns a breadcrumb only if last breadcrumb has changed (unit)', function () {
const scope = {
_breadcrumbs: [],
} as unknown as Scope;

function addBreadcrumb(breadcrumb: Breadcrumb) {
// @ts-expect-error using private member
scope._breadcrumbs.push(breadcrumb);
}

const testMsg = {
timestamp: new Date().getTime() / 1000,
message: 'testing',
category: 'console',
};

addBreadcrumb(testMsg);
// integration testing here is a bit tricky, because the core SDK can
// interfere with console output from test runner
HandleScope.handleScope(scope);
expect(mockHandleScope).toHaveBeenCalledTimes(1);
expect(mockHandleScope).toHaveReturnedWith(
expect.objectContaining({ message: 'testing', category: 'console' })
);

// This will trigger breadcrumb/scope listener, but handleScope should return
// null because breadcrumbs has not changed
mockHandleScope.mockClear();
HandleScope.handleScope(scope);
expect(mockHandleScope).toHaveBeenCalledTimes(1);
expect(mockHandleScope).toHaveReturnedWith(null);

mockHandleScope.mockClear();
addBreadcrumb({
message: 'f00',
category: 'console',
});
HandleScope.handleScope(scope);
expect(mockHandleScope).toHaveBeenCalledTimes(1);
expect(mockHandleScope).toHaveReturnedWith(
expect.objectContaining({ message: 'f00', category: 'console' })
);
});
17 changes: 15 additions & 2 deletions src/coreHandlers/handleScope.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
import createBreadcrumb from '@/util/createBreadcrumb';
import { Scope } from '@sentry/hub';
import { Breadcrumb } from '@sentry/types';

let _LAST_BREADCRUMB: null | Breadcrumb = null;

export function handleScope(scope: Scope) {
//@ts-expect-error using private val
const newBreadcrumb = scope._breadcrumbs[scope._breadcrumbs.length - 1];

// Listener can be called when breadcrumbs have not changed, so we store the
// reference to the last crumb and only return a crumb if it has changed
if (_LAST_BREADCRUMB === newBreadcrumb) {
return null;
}

_LAST_BREADCRUMB = newBreadcrumb;

if (
['fetch', 'xhr', 'sentry.event'].includes(newBreadcrumb.category) ||
newBreadcrumb.category.startsWith('ui.')
['fetch', 'xhr', 'sentry.event', 'sentry.transaction'].includes(
newBreadcrumb.category
) ||
newBreadcrumb.category?.startsWith('ui.')
) {
return null;
}
Expand Down
5 changes: 3 additions & 2 deletions src/coreHandlers/handleXhr.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { ReplaySpan } from '@/types';

export function handleXhr(handlerData: any): ReplaySpan {
// TODO: add status code into data, etc.

if (handlerData.startTimestamp) {
handlerData.xhr.__sentry_xhr__.startTimestamp = handlerData.startTimestamp;
}
Expand All @@ -18,5 +16,8 @@ export function handleXhr(handlerData: any): ReplaySpan {
handlerData.xhr.__sentry_xhr__.startTimestamp / 1000 ||
handlerData.endTimestamp / 1000.0,
endTimestamp: handlerData.endTimestamp / 1000.0,
data: {
statusCode: handlerData.response.status,
},
};
}
7 changes: 7 additions & 0 deletions src/createPerformanceEntry.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { record } from 'rrweb';
import { getCurrentHub } from '@sentry/browser';

export interface ReplayPerformanceEntry {
/**
Expand Down Expand Up @@ -97,6 +98,12 @@ function createResourceEntry(entry: PerformanceResourceTiming) {
transferSize,
} = entry;

// Do not capture fetches to Sentry ingestion endpoint
const { host, protocol } = getCurrentHub()?.getClient()?.getDsn() || {};
if (name.startsWith(`${protocol}://${host}`)) {
return null;
}

return {
type: `${entryType}.${initiatorType}`,
start: getAbsoluteTime(startTime),
Expand Down
Loading