Skip to content

Commit

Permalink
feat(browser): Export Replay integration from Browser SDK
Browse files Browse the repository at this point in the history
wip
  • Loading branch information
Lms24 committed Dec 13, 2022
1 parent 60b5a7b commit 41f9db7
Show file tree
Hide file tree
Showing 12 changed files with 84 additions and 25 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
"karma-firefox-launcher": "^1.1.0",
"lerna": "3.13.4",
"madge": "4.0.2",
"magic-string": "^0.27.0",
"mocha": "^6.1.4",
"nodemon": "^2.0.16",
"npm-run-all": "^4.1.5",
Expand Down
1 change: 1 addition & 0 deletions packages/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
},
"dependencies": {
"@sentry/core": "7.25.0",
"@sentry/replay": "7.25.0",
"@sentry/types": "7.25.0",
"@sentry/utils": "7.25.0",
"tslib": "^1.9.3"
Expand Down
26 changes: 9 additions & 17 deletions packages/browser/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,20 @@
import { BaseClient, getEnvelopeEndpointWithUrlEncodedAuth, Scope, SDK_VERSION } from '@sentry/core';
import { ClientOptions, Event, EventHint, Options, Severity, SeverityLevel } from '@sentry/types';
import {
BrowserClientReplayOptions,
ClientOptions,
Event,
EventHint,
Options,
Severity,
SeverityLevel,
} from '@sentry/types';
import { createClientReportEnvelope, dsnToString, logger, serializeEnvelope } from '@sentry/utils';

import { eventFromException, eventFromMessage } from './eventbuilder';
import { WINDOW } from './helpers';
import { Breadcrumbs } from './integrations';
import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs';
import { BrowserTransportOptions } from './transports/types';

type BrowserClientReplayOptions = {
/**
* The sample rate for session-long replays.
* 1.0 will record all sessions and 0 will record none.
*/
replaysSessionSampleRate?: number;

/**
* The sample rate for sessions that has had an error occur.
* This is independent of `sessionSampleRate`.
* 1.0 will record all sessions and 0 will record none.
*/
replaysOnErrorSampleRate?: number;
};

/**
* Configuration options for the Sentry Browser SDK.
* @see @sentry/types Options for more information.
Expand Down
9 changes: 9 additions & 0 deletions packages/browser/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,12 @@ const INTEGRATIONS = {
};

export { INTEGRATIONS as Integrations };

// DO NOT DELETE THESE COMMENTS!
// We want to exclude Replay from CDN bundles, so we remove the block below with our
// excludeReplay Rollup plugin when generating bundles. Everything between
// ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN and _END__ is removed for bundles.

// __ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__
export { Replay } from '@sentry/replay';
// __ROLLUP_EXCLUDE_FROM_BUNDLES_END__
1 change: 0 additions & 1 deletion packages/replay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@
"homepage": "https://github.com/getsentry/sentry-replay#readme",
"devDependencies": {
"@babel/core": "^7.17.5",
"@sentry/browser": "7.25.0",
"@types/lodash.debounce": "4.0.7",
"@types/pako": "^2.0.0",
"jsdom-worker": "^0.2.1",
Expand Down
7 changes: 3 additions & 4 deletions packages/replay/src/integration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { BrowserClient, BrowserOptions } from '@sentry/browser';
import { getCurrentHub } from '@sentry/core';
import { Integration } from '@sentry/types';
import { BrowserClientReplayOptions, Integration } from '@sentry/types';

import { DEFAULT_ERROR_SAMPLE_RATE, DEFAULT_SESSION_SAMPLE_RATE } from './constants';
import { ReplayContainer } from './replay';
Expand Down Expand Up @@ -184,8 +183,8 @@ Sentry.init({ replaysOnErrorSampleRate: ${errorSampleRate} })`,

/** Parse Replay-related options from SDK options */
private _loadReplayOptionsFromClient(): void {
const client = getCurrentHub().getClient() as BrowserClient | undefined;
const opt = client && (client.getOptions() as BrowserOptions | undefined);
const client = getCurrentHub().getClient();
const opt = client && (client.getOptions() as BrowserClientReplayOptions | undefined);

if (opt && typeof opt.replaysSessionSampleRate === 'number') {
this.options.sessionSampleRate = opt.replaysSessionSampleRate;
Expand Down
18 changes: 18 additions & 0 deletions packages/types/src/browseroptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Options added to the Browser SDK's init options that are specific for Replay.
* Note: This type was moved to @sentry/types to avoid a circular dependency between Browser and Replay.
*/
export type BrowserClientReplayOptions = {
/**
* The sample rate for session-long replays.
* 1.0 will record all sessions and 0 will record none.
*/
replaysSessionSampleRate?: number;

/**
* The sample rate for sessions that has had an error occur.
* This is independent of `sessionSampleRate`.
* 1.0 will record all sessions and 0 will record none.
*/
replaysOnErrorSampleRate?: number;
};
2 changes: 2 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,5 @@ export type {
export type { User, UserFeedback } from './user';
export type { WrappedFunction } from './wrappedfunction';
export type { Instrumenter } from './instrumenter';

export type { BrowserClientReplayOptions } from './browseroptions';
4 changes: 3 additions & 1 deletion rollup/bundleHelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
makeSucrasePlugin,
makeTerserPlugin,
makeTSPlugin,
makeExcludeReplayPlugin,
} from './plugins/index.js';
import { mergePlugins } from './utils';

Expand All @@ -30,6 +31,7 @@ export function makeBaseBundleConfig(options) {
const markAsBrowserBuildPlugin = makeBrowserBuildPlugin(true);
const licensePlugin = makeLicensePlugin(licenseTitle);
const tsPlugin = makeTSPlugin(jsVersion.toLowerCase());
const excludeReplayPlugin = makeExcludeReplayPlugin();

// The `commonjs` plugin is the `esModuleInterop` of the bundling world. When used with `transformMixedEsModules`, it
// will include all dependencies, imported or required, in the final bundle. (Without it, CJS modules aren't included
Expand All @@ -43,7 +45,7 @@ export function makeBaseBundleConfig(options) {
name: 'Sentry',
},
context: 'window',
plugins: [markAsBrowserBuildPlugin],
plugins: [markAsBrowserBuildPlugin, excludeReplayPlugin],
};

// used by `@sentry/integrations` and `@sentry/wasm` (bundles which need to be combined with a stand-alone SDK bundle)
Expand Down
29 changes: 29 additions & 0 deletions rollup/plugins/bundlePlugins.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import resolve from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';
import { terser } from 'rollup-plugin-terser';
import typescript from 'rollup-plugin-typescript2';
import MagicString from 'magic-string';

/**
* Create a plugin to add an identification banner to the top of stand-alone bundles.
Expand Down Expand Up @@ -165,6 +166,34 @@ export function makeTSPlugin(jsVersion) {
return plugin;
}

/**
* Creates a Rollup plugin that removes all code between the `__ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__`
* and `__ROLLUP_EXCLUDE_FROM_BUNDLES_END__` comment guards. This is used to exclude the Replay integration
* from the browser and browser+tracing bundles.
*/
export function makeExcludeReplayPlugin() {
const replacementRegex = /\/\/ __ROLLUP_EXCLUDE_FROM_BUNDLES_BEGIN__(.|\n)*__ROLLUP_EXCLUDE_FROM_BUNDLES_END__/gm;

const plugin = {
transform(code) {
if (!replacementRegex.test(code)) {
return null;
}

const ms = new MagicString(code);
const transformedCode = ms.replace(new RegExp(replacementRegex), '');
return {
code: transformedCode.toString(),
map: transformedCode.generateMap({ hires: true }),
};
},
};

plugin.name = 'excludeReplay';

return plugin;
}

// We don't pass these plugins any options which need to be calculated or changed by us, so no need to wrap them in
// another factory function, as they are themselves already factory functions.
export { resolve as makeNodeResolvePlugin };
Expand Down
2 changes: 1 addition & 1 deletion rollup/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function mergePlugins(pluginsA, pluginsB) {
// Hacky way to make sure the ones we care about end up where they belong in the order. (Really the TS and sucrase
// plugins are tied - both should come first - but they're mutually exclusive, so they can come in arbitrary order
// here.)
const order = ['typescript', 'sucrase', '...', 'terser', 'license'];
const order = ['excludeReplay', 'typescript', 'sucrase', '...', 'terser', 'license'];
const sortKeyA = order.includes(a.name) ? a.name : '...';
const sortKeyB = order.includes(b.name) ? b.name : '...';

Expand Down
9 changes: 8 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2232,7 +2232,7 @@
resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==

"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10":
"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13":
version "1.4.14"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
Expand Down Expand Up @@ -16567,6 +16567,13 @@ magic-string@^0.26.2:
dependencies:
sourcemap-codec "^1.4.8"

magic-string@^0.27.0:
version "0.27.0"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"

make-dir@^1.0.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c"
Expand Down

0 comments on commit 41f9db7

Please sign in to comment.