Skip to content

Commit ebc0475

Browse files
committed
wip
1 parent 618e992 commit ebc0475

21 files changed

+1046
-0
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"packages/ember",
4949
"packages/eslint-config-sdk",
5050
"packages/eslint-plugin-sdk",
51+
"packages/feedback",
5152
"packages/gatsby",
5253
"packages/hub",
5354
"packages/integrations",

packages/feedback/.eslintignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules/
2+
build/
3+
demo/build/
4+
# TODO: Check if we can re-introduce linting in demo
5+
demo
6+
metrics

packages/feedback/.eslintrc.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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+
'@sentry-internal/sdk/no-unsupported-es6-methods': 'off',
13+
},
14+
},
15+
{
16+
files: ['jest.setup.ts', 'jest.config.ts'],
17+
parserOptions: {
18+
project: ['tsconfig.test.json'],
19+
},
20+
rules: {
21+
'no-console': 'off',
22+
},
23+
},
24+
{
25+
files: ['test/**/*.ts'],
26+
27+
rules: {
28+
// most of these errors come from `new Promise(process.nextTick)`
29+
'@typescript-eslint/unbound-method': 'off',
30+
// TODO: decide if we want to enable this again after the migration
31+
// We can take the freedom to be a bit more lenient with tests
32+
'@typescript-eslint/no-floating-promises': 'off',
33+
},
34+
},
35+
{
36+
files: ['src/types/deprecated.ts'],
37+
rules: {
38+
'@typescript-eslint/naming-convention': 'off',
39+
},
40+
},
41+
],
42+
};

packages/feedback/.gitignore

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

packages/feedback/CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Updating the rrweb dependency
2+
3+
When [updating the `rrweb` dependency](https://github.com/getsentry/sentry-javascript/blob/a493aa6a46555b944c8d896a2164bcd8b11caaf5/packages/replay/package.json?plain=1#LL55),
4+
please be aware that [`@sentry/replay`'s README.md](https://github.com/getsentry/sentry-javascript/blob/a493aa6a46555b944c8d896a2164bcd8b11caaf5/packages/replay/README.md?plain=1#LL204) also needs to be updated.

packages/feedback/LICENSE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Copyright (c) 2022 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/feedback/MIGRATION.md

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
# End of Replay Beta
2+
3+
Sentry Replay is now out of Beta. This means that the usual stability guarantees apply.
4+
5+
Because of experimentation and rapid iteration, during the Beta period some bugs and problems came up which have since been fixed/improved.
6+
We **strongly** recommend anyone using Replay in a version before 7.39.0 to update to 7.39.0 or newer, in order to prevent running Replay with known problems that have since been fixed.
7+
8+
Below you can find a list of relevant replay issues that have been resolved until 7.39.0:
9+
10+
## New features / improvements
11+
12+
- Remove `autoplay` attribute from audio/video tags ([#59](https://github.com/getsentry/rrweb/pull/59))
13+
- Exclude fetching scripts that use `<link rel="modulepreload">` ([#52](https://github.com/getsentry/rrweb/pull/52))
14+
- With maskAllText, mask the attributes: placeholder, title, `aria-label`
15+
- Lower the flush max delay from 15 seconds to 5 seconds (#6761)
16+
- Stop recording when retry fails (#6765)
17+
- Stop without retry when receiving bad API response (#6773)
18+
- Send client_report when replay sending fails (#7093)
19+
- Stop recording when hitting a rate limit (#7018)
20+
- Allow Replay to be used in Electron renderers with nodeIntegration enabled (#6644)
21+
- Do not renew session in error mode (#6948)
22+
- Remove default sample rates for replay (#6878)
23+
- Add `flush` method to integration (#6776)
24+
- Improve compression worker & fallback behavior (#6988, #6936, #6827)
25+
- Improve error handling (#7087, #7094, #7010, getsentry/rrweb#16, #6856)
26+
- Add more default block filters (#7233)
27+
28+
## Fixes
29+
30+
- Fix masking inputs on change when `maskAllInputs:false` ([#61](https://github.com/getsentry/rrweb/pull/61))
31+
- More robust `rootShadowHost` check ([#50](https://github.com/getsentry/rrweb/pull/50))
32+
- Fix duplicated textarea value ([#62](https://github.com/getsentry/rrweb/pull/62))
33+
- Handle removed attributes ([#65](https://github.com/getsentry/rrweb/pull/65))
34+
- Change LCP calculation (#7187, #7225)
35+
- Fix debounced flushes not respecting `maxWait` (#7207, #7208)
36+
- Fix svgs not getting unblocked (#7132)
37+
- Fix missing fetch/xhr requests (#7134)
38+
- Fix feature detection of PerformanceObserver (#7029)
39+
- Fix `checkoutEveryNms` (#6722)
40+
- Fix incorrect uncompressed recording size due to encoding (#6740)
41+
- Ensure dropping replays works (#6522)
42+
- Envelope send should be awaited in try/catch (#6625)
43+
- Improve handling of `maskAllText` selector (#6637)
44+
45+
# Upgrading Replay from 7.34.0 to 7.35.0 - #6645
46+
47+
This release will remove the ability to change the default rrweb recording options (outside of privacy options). The following are the new configuration values all replays will use:
48+
`slimDOMOptions: 'all'` - Removes `script`, comments, `favicon`, whitespace in `head`, and a few `meta` tags in `head`
49+
`recordCanvas: false` - This option did not do anything as playback of recorded canvas means we would have to remove the playback sandbox (which is a security concern).
50+
`inlineStylesheet: true` - Inlines styles into the recording itself instead of attempting to fetch it remotely. This means that styles in the replay will reflect the styles at the time of recording and not the current styles of the remote stylesheet.
51+
`collectFonts: true` - Attempts to load custom fonts.
52+
`inlineImages: false` - Does not inline images to recording and instead loads the asset remotely. During playback, images may not load due to CORS (add sentry.io as an origin).
53+
54+
Additionally, we have streamlined the privacy options. The following table lists the deprecated value, and what it is replaced by:
55+
56+
| deprecated key | replaced by | description |
57+
| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
58+
| maskInputOptions | mask | Use CSS selectors in `mask` in order to mask all inputs of a certain type. For example, `input[type="address"]` |
59+
| blockSelector | block | The selector(s) can be moved directly in the `block` array. |
60+
| blockClass | block | Convert the class name to a CSS selector and add to `block` array. For example, `first-name` becomes `.first-name`. Regexes can be moved as-is. |
61+
| maskClass | mask | Convert the class name to a CSS selector and add to `mask` array. For example, `first-name` becomes `.first-name`. Regexes can be moved as-is. |
62+
| maskSelector | mask | The selector(s) can be moved directly in the `mask` array. |
63+
| ignoreClass | ignore | Convert the class name to a CSS selector and add to `ignore` array. For example, `first-name` becomes `.first-name`. Regexes can be moved as-is. |
64+
65+
# Upgrading Replay from 7.31.0 to 7.32.0
66+
67+
In 7.32.0, we have removed the default values for the replay sample rates.
68+
Previously, they were:
69+
70+
* `replaysSessionSampleRate: 0.1`
71+
* `replaysOnErrorSampleRate: 1.0`
72+
73+
Now, you have to explicitly set the sample rates, otherwise they default to 0.
74+
75+
# Upgrading Replay from 0.6.x to 7.24.0
76+
77+
The Sentry Replay integration was moved to the Sentry JavaScript SDK monorepo. Hence we're jumping from version 0.x to the monorepo's 7.x version which is shared across all JS SDK packages.
78+
79+
## Replay sample rates are defined on top level (https://github.com/getsentry/sentry-javascript/issues/6351)
80+
81+
Instead of defining the sample rates on the integration like this:
82+
83+
```js
84+
Sentry.init({
85+
dsn: '__DSN__',
86+
integrations: [
87+
new Replay({
88+
sessionSampleRate: 0.1,
89+
errorSampleRate: 1.0,
90+
})
91+
],
92+
// ...
93+
});
94+
```
95+
96+
They are now defined on the top level of the SDK:
97+
98+
```js
99+
Sentry.init({
100+
dsn: '__DSN__',
101+
replaysSessionSampleRate: 0.1,
102+
replaysOnErrorSampleRate: 1.0,
103+
integrations: [
104+
new Replay({
105+
// other replay config still goes in here
106+
})
107+
],
108+
});
109+
```
110+
111+
Note that the sample rate options inside of `new Replay({})` have been deprecated and will be removed in a future update.
112+
113+
## Removed deprecated options (https://github.com/getsentry/sentry-javascript/pull/6370)
114+
115+
Two options, which have been deprecated for some time, have been removed:
116+
117+
* `replaysSamplingRate` - instead use `sessionSampleRate`
118+
* `captureOnlyOnError` - instead use `errorSampleRate`
119+
120+
## New NPM package structure (https://github.com/getsentry/sentry-javascript/issues/6280)
121+
122+
The internal structure of the npm package has changed. This is unlikely to affect you, unless you have imported something from e.g.:
123+
124+
```js
125+
import something from '@sentry/replay/submodule';
126+
```
127+
128+
If you only imported from `@sentry/replay`, this will not affect you.
129+
130+
## Changed type name from `IEventBuffer` to `EventBuffer` (https://github.com/getsentry/sentry-javascript/pull/6416)
131+
132+
It is highly unlikely to affect anybody, but the type `IEventBuffer` was renamed to `EventBuffer` for consistency.
133+
Unless you manually imported this and used it somewhere in your codebase, this will not affect you.
134+
135+
## Session object is now a plain object (https://github.com/getsentry/sentry-javascript/pull/6417)
136+
137+
The `Session` object exported from Replay is now a plain object, instead of a class.
138+
This should not affect you unless you specifically accessed this class & did custom things with it.
139+
140+
## Reduce public API of Replay integration (https://github.com/getsentry/sentry-javascript/pull/6407)
141+
142+
The result of `new Replay()` now has a much more limited public API. Only the following methods are exposed:
143+
144+
```js
145+
const replay = new Replay();
146+
147+
replay.start();
148+
replay.stop();
149+
```

packages/feedback/README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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 Feedback
8+
9+
[![npm version](https://img.shields.io/npm/v/@sentry/feedback.svg)](https://www.npmjs.com/package/@sentry/feedback)
10+
[![npm dm](https://img.shields.io/npm/dm/@sentry/feedback.svg)](https://www.npmjs.com/package/@sentry/feedback)
11+
[![npm dt](https://img.shields.io/npm/dt/@sentry/feedback.svg)](https://www.npmjs.com/package/@sentry/feedback)
12+
13+
## Pre-requisites
14+
15+
`@sentry/feedback` requires Node 12+, and browsers newer than IE11.
16+
17+
## Installation
18+
19+
Feedback can be imported from `@sentry/browser`, or a respective SDK package like `@sentry/react` or `@sentry/vue`.
20+
You don't need to install anything in order to use Feedback. The minimum version that includes Feedback is <<CHANGEME>>.
21+
22+
For details on using Feedback when using Sentry via the CDN bundles, see [CDN bundle](#loading-feedback-as-a-cdn-bundle).
23+
24+
## Setup
25+
26+
To set up the integration, add the following to your Sentry initialization. Several options are supported and passable via the integration constructor.
27+
See the [configuration section](#configuration) below for more details.
28+
29+
```javascript
30+
import * as Sentry from '@sentry/browser';
31+
// or e.g. import * as Sentry from '@sentry/react';
32+
33+
Sentry.init({
34+
dsn: '__DSN__',
35+
integrations: [
36+
new Sentry.Feedback({
37+
// Additional SDK configuration goes in here, for example:
38+
// See below for all available options
39+
})
40+
],
41+
// ...
42+
});
43+
```
44+
45+
### Lazy loading Feedback
46+
47+
Feedback will start automatically when you add the integration.
48+
If you do not want to start Feedback immediately (e.g. if you want to lazy-load it),
49+
you can also use `addIntegration` to load it later:
50+
51+
```js
52+
import * as Sentry from "@sentry/react";
53+
import { BrowserClient } from "@sentry/browser";
54+
55+
Sentry.init({
56+
// Do not load it initially
57+
integrations: []
58+
});
59+
60+
// Sometime later
61+
const { Feedback } = await import('@sentry/browser');
62+
const client = Sentry.getCurrentHub().getClient<BrowserClient>();
63+
64+
// Client can be undefined
65+
client?.addIntegration(new Feedback());
66+
```
67+
68+
### Identifying Users
69+
70+
If you have only followed the above instructions to setup session feedbacks, you will only see IP addresses in Sentry's UI. In order to associate a user identity to a session feedback, use [`setUser`](https://docs.sentry.io/platforms/javascript/enriching-events/identify-user/).
71+
72+
```javascript
73+
import * as Sentry from "@sentry/browser";
74+
75+
Sentry.setUser({ email: "[email protected]" });
76+
```
77+
78+
## Loading Feedback as a CDN Bundle
79+
80+
As an alternative to the NPM package, you can use Feedback as a CDN bundle.
81+
Please refer to the [Feedback installation guide](https://docs.sentry.io/platforms/javascript/session-feedback/#install) for CDN bundle instructions.
82+
83+
84+
## Configuration
85+
86+
### General Integration Configuration
87+
88+
The following options can be configured as options to the integration, in `new Feedback({})`:
89+
90+
| key | type | default | description |
91+
| --------- | ------- | ------- | ----------- |
92+
| tbd | boolean | `true` | tbd |
93+
94+
95+
96+
## Manually Sending Feedback Data
97+
98+
Connect your own feedback UI to Sentry's You can use `feedback.flush()` to immediately send all currently captured feedback data.
99+
When Feedback is currently in buffering mode, this will send up to the last 60 seconds of feedback data,
100+
and also continue sending afterwards, similar to when an error happens & is recorded.

packages/feedback/jest.config.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { Config } from '@jest/types';
2+
import { jsWithTs as jsWithTsPreset } from 'ts-jest/presets';
3+
4+
export default async (): Promise<Config.InitialOptions> => {
5+
return {
6+
...jsWithTsPreset,
7+
globals: {
8+
'ts-jest': {
9+
tsconfig: '<rootDir>/tsconfig.test.json',
10+
},
11+
__DEBUG_BUILD__: true,
12+
},
13+
setupFilesAfterEnv: ['./jest.setup.ts'],
14+
testEnvironment: 'jsdom',
15+
testMatch: ['<rootDir>/test/**/*(*.)@(spec|test).ts'],
16+
};
17+
};

0 commit comments

Comments
 (0)