diff --git a/.craft.yml b/.craft.yml
new file mode 100644
index 0000000000..6032f44ad7
--- /dev/null
+++ b/.craft.yml
@@ -0,0 +1,15 @@
+github:
+ owner: getsentry
+ repo: rrweb
+changelogPolicy: simple
+preReleaseCommand: bash scripts/craft-pre-release.sh
+requireNames:
+ - /^sentry-internal-rrweb-snapshot-.*\.tgz$/
+ - /^sentry-internal-rrweb-player-.*\.tgz$/
+ - /^sentry-internal-rrweb-.*\.tgz$/
+ - /^sentry-internal-rrdom-.*\.tgz$/
+targets:
+ - name: github
+ includeNames: /^sentry-.*.tgz$/
+ - name: npm
+ includeNames: /^sentry-.*.tgz$/
diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml
index 128b0da4eb..081895b70e 100644
--- a/.github/workflows/ci-cd.yml
+++ b/.github/workflows/ci-cd.yml
@@ -1,11 +1,16 @@
-name: Tests
+name: Build & Tests
-on: [pull_request]
+on:
+ push:
+ branches:
+ - master
+ - release/**
+ pull_request:
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
- release:
+ job_test:
name: Tests
runs-on: ubuntu-latest
steps:
@@ -26,5 +31,31 @@ jobs:
- name: Run tests
# Skip this for now, as it somehow always fails
- if: 1 == 2
- run: xvfb-run --server-args="-screen 0 1920x1080x24" yarn test
\ No newline at end of file
+ if: 1 == 2
+ run: xvfb-run --server-args="-screen 0 1920x1080x24" yarn test
+
+ job_artifacts:
+ needs: job_test
+ name: Upload Artifacts
+ runs-on: ubuntu-latest
+ # Build artifacts are only needed for releasing workflow.
+ if: startsWith(github.ref, 'refs/heads/release/')
+ steps:
+ - name: Checkout Repo
+ uses: actions/checkout@v3
+
+ - name: Set up Node
+ uses: volta-cli/action@v3
+
+ - name: Install Dependencies
+ run: yarn --frozen-lockfile
+
+ - name: Build Tarballs
+ run: yarn build:tarball
+
+ - name: Upload Artifacts
+ uses: actions/upload-artifact@v3
+ with:
+ name: ${{ github.sha }}
+ path: |
+ ${{ github.workspace }}/packages/**/*.tgz
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000000..e6335c507e
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,30 @@
+name: Prepare Release
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: Version to release
+ required: true
+ force:
+ description: Force a release even when there are release-blockers (optional)
+ required: false
+ merge_target:
+ description: Target branch to merge into. Uses the default branch, sentry-v1, as a fallback (optional)
+ required: false
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ name: 'Release a new version'
+ steps:
+ - uses: actions/checkout@v3
+ with:
+ token: ${{ secrets.GH_RELEASE_PAT }}
+ fetch-depth: 0
+ - name: Prepare release
+ uses: getsentry/action-prepare-release@v1
+ env:
+ GITHUB_TOKEN: ${{ secrets.GH_RELEASE_PAT }}
+ with:
+ version: ${{ github.event.inputs.version }}
+ force: ${{ github.event.inputs.force }}
+ merge_target: ${{ github.event.inputs.merge_target }}
diff --git a/LICENSE b/LICENSE
index fce28eb837..d11896ba11 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,21 +1,14 @@
-MIT License
+Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved.
-Copyright (c) 2018 Contributors (https://github.com/rrweb-io/rrweb/graphs/contributors) and SmartX Inc.
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
index 3e6490f17b..fefcc0e451 100644
--- a/README.md
+++ b/README.md
@@ -1,160 +1,28 @@
-# rrweb
-
-**[The rrweb documentary (in Chinese, with English subtitles)](https://www.bilibili.com/video/BV1wL4y1B7wN?share_source=copy_web)**
-
-[](https://join.slack.com/t/rrweb/shared_invite/zt-siwoc6hx-uWay3s2wyG8t5GpZVb8rWg)
-[](https://twitter.com/rrweb_io)
-
-
-[](https://www.jsdelivr.com/package/npm/rrweb)
-
-[δΈζζζ‘£](./README.zh_CN.md)
-
-> I have joined Github Sponsors and highly appreciate your sponsorship.
-
-rrweb refers to 'record and replay the web', which is a tool for recording and replaying users' interactions on the web.
-
-## Guide
-
-[**π Read the rrweb guide here. π**](./guide.md)
-
-[**π³ Recipes π³**](./docs/recipes/index.md)
-
-## Project Structure
-
-rrweb is mainly composed of 3 parts:
-
-- **[rrweb-snapshot](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-snapshot/)**, including both snapshot and rebuilding features. The snapshot is used to convert the DOM and its state into a serializable data structure with a unique identifier; the rebuilding feature is to rebuild the snapshot into corresponding DOM.
-- **[rrweb](https://github.com/rrweb-io/rrweb)**, including two functions, record and replay. The record function is used to record all the mutations in the DOM; the replay is to replay the recorded mutations one by one according to the corresponding timestamp.
-- **[rrweb-player](https://github.com/rrweb-io/rrweb/tree/master/packages/rrweb-player/)**, is a player UI for rrweb, providing GUI-based functions like pause, fast-forward, drag and drop to play at any time.
-
-## Roadmap
-
-- rrdom: an ad-hoc DOM for rrweb session data [#419](https://github.com/rrweb-io/rrweb/issues/419)
-- storage engine: do deduplication on a large number of rrweb sessions
-- more end-to-end tests
-- compact mutation data in common patterns
-- provide plugins via the new plugin API, including:
- - XHR plugin
- - fetch plugin
- - GraphQL plugin
- - ...
+# Sentry rrweb Fork
-## Internal Design
+This repo is a fork of [rrweb](https://github.com/rrweb-io/rrweb). The purpose is to apply patches and bugfixes to rrweb and release Sentry-internal packages with our patches included. All credits and attribution for rrweb go to the original creators of the library and all its contributors.
-- [serialization](./docs/serialization.md)
-- [incremental snapshot](./docs/observer.md)
-- [replay](./docs/replay.md)
-- [sandbox](./docs/sandbox.md)
+From this monorepo, Sentry maintains and publishes the following NPM packages:
-## Contribute Guide
+- `@sentry-internal/rrweb` (corresponds to the [original `rrweb` package](https://www.npmjs.com/package/rrweb))
+- `@sentry-internal/rrdom` (corresponds to the [original `rrdom` package](https://www.npmjs.com/package/rrdom))
+- `@sentry-internal/rrweb-player` (corresponds to the [original `rrweb-player` package](https://www.npmjs.com/package/rrweb-player))
+- `@sentry-internal/rrweb-snapshot` (corresponds to the [original `rrweb-snapshot` package](https://www.npmjs.com/package/rrweb-snapshot))
-Since we want the record and replay sides to share a strongly typed data structure, rrweb is developed with typescript which provides stronger type support.
-
-[Typescript handbook](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html)
-
-1. Fork this repository.
-2. Run `yarn install` in the root to install required dependencies for all sub-packages (note: `npm install` is _not_ recommended).
-3. Run `yarn dev` in the root to get auto-building for all the sub-packages whenever you modify anything.
-4. Navigate to one of the sub-packages (in the `packages` folder) where you'd like to make a change.
-5. Patch the code and run `yarn test` to run the tests, make sure they pass before you commit anything.
-6. Push the code and create a pull request.
-
-Protip: You can run `yarn test` in the root folder to run all the tests.
-
-In addition to adding integration tests and unit tests, rrweb also provides a REPL testing tool.
-
-[Using the REPL tool](./guide.md#REPL-tool)
-
-## Core Team Members
-
-
diff --git a/package.json b/package.json
index 42e45ff27c..dffd879233 100644
--- a/package.json
+++ b/package.json
@@ -30,7 +30,8 @@
"test:watch": "yarn lerna run test:watch --parallel",
"dev": "yarn lerna run dev --parallel",
"repl": "cd packages/rrweb && npm run repl",
- "postinstall": "node node_modules/puppeteer/install.js"
+ "postinstall": "node node_modules/puppeteer/install.js",
+ "build:tarball": "yarn lerna run build:tarball"
},
"volta": {
"node": "12.22.12",
diff --git a/packages/rrdom/LICENSE b/packages/rrdom/LICENSE
new file mode 100644
index 0000000000..d11896ba11
--- /dev/null
+++ b/packages/rrdom/LICENSE
@@ -0,0 +1,14 @@
+Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/rrdom/package.json b/packages/rrdom/package.json
index a1ed991ca5..9df6631c12 100644
--- a/packages/rrdom/package.json
+++ b/packages/rrdom/package.json
@@ -1,12 +1,13 @@
{
- "name": "rrdom",
+ "name": "@sentry-internal/rrdom",
"version": "0.1.2",
"scripts": {
"dev": "rollup -c -w",
"bundle": "rollup --config",
"bundle:es-only": "cross-env ES_ONLY=true rollup --config",
"test": "jest",
- "prepublish": "npm run bundle"
+ "prepublish": "npm run bundle",
+ "build:tarball": "npm pack"
},
"keywords": [
"rrweb",
@@ -33,7 +34,7 @@
"rollup": "^2.56.3",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.30.0",
- "rrweb-snapshot": "^1.1.14",
+ "@sentry-internal/rrweb-snapshot": "^1.1.14",
"ts-jest": "^27.0.5",
"tslib": "^2.3.1",
"typescript": "^3.9.5"
diff --git a/packages/rrdom/rollup.config.js b/packages/rrdom/rollup.config.js
index 80baed3473..d0117e98e9 100644
--- a/packages/rrdom/rollup.config.js
+++ b/packages/rrdom/rollup.config.js
@@ -55,6 +55,7 @@ for (let config of baseConfigs) {
name: config.name,
format: 'iife',
file: pkg.unpkg.replace(pkg.name, config.path),
+ extend: true,
},
],
},
@@ -67,6 +68,7 @@ for (let config of baseConfigs) {
format: 'iife',
file: toMinPath(pkg.unpkg).replace(pkg.name, config.path),
sourcemap: true,
+ extend: true,
},
],
},
diff --git a/packages/rrdom/src/document-nodejs.ts b/packages/rrdom/src/document-nodejs.ts
index aff8d90512..2125b44bdc 100644
--- a/packages/rrdom/src/document-nodejs.ts
+++ b/packages/rrdom/src/document-nodejs.ts
@@ -1,4 +1,8 @@
-import { INode, NodeType, serializedNodeWithId } from 'rrweb-snapshot';
+import {
+ INode,
+ NodeType,
+ serializedNodeWithId,
+} from '@sentry-internal/rrweb-snapshot';
import { NWSAPI } from 'nwsapi';
import { parseCSSText, camelize, toCSSText } from './style';
const nwsapi = require('nwsapi');
diff --git a/packages/rrdom/src/style.ts b/packages/rrdom/src/style.ts
index 1e49b83619..fd57dee1a1 100644
--- a/packages/rrdom/src/style.ts
+++ b/packages/rrdom/src/style.ts
@@ -1,40 +1,39 @@
export function parseCSSText(cssText: string): Record {
- const res: Record = {};
- const listDelimiter = /;(?![^(]*\))/g;
- const propertyDelimiter = /:(.+)/;
- cssText.split(listDelimiter).forEach(function (item) {
- if (item) {
- const tmp = item.split(propertyDelimiter);
- tmp.length > 1 && (res[camelize(tmp[0].trim())] = tmp[1].trim());
- }
- });
- return res;
+ const res: Record = {};
+ const listDelimiter = /;(?![^(]*\))/g;
+ const propertyDelimiter = /:(.+)/;
+ cssText.split(listDelimiter).forEach(function (item) {
+ if (item) {
+ const tmp = item.split(propertyDelimiter);
+ tmp.length > 1 && (res[camelize(tmp[0].trim())] = tmp[1].trim());
+ }
+ });
+ return res;
+}
+
+export function toCSSText(style: Record): string {
+ const properties = [];
+ for (let name in style) {
+ const value = style[name];
+ if (typeof value !== 'string') continue;
+ const normalizedName = hyphenate(name);
+ properties.push(`${normalizedName}:${value};`);
}
-
- export function toCSSText(style: Record): string {
- const properties = [];
- for (let name in style) {
- const value = style[name];
- if (typeof value !== 'string') continue;
- const normalizedName = hyphenate(name);
- properties.push(`${normalizedName}:${value};`);
- }
- return properties.join(' ');
- }
-
- /**
- * Camelize a hyphen-delimited string.
- */
- const camelizeRE = /-(\w)/g;
- export const camelize = (str: string): string => {
- return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
- };
-
- /**
- * Hyphenate a camelCase string.
- */
- const hyphenateRE = /\B([A-Z])/g;
- export const hyphenate = (str: string): string => {
- return str.replace(hyphenateRE, '-$1').toLowerCase();
- };
-
\ No newline at end of file
+ return properties.join(' ');
+}
+
+/**
+ * Camelize a hyphen-delimited string.
+ */
+const camelizeRE = /-(\w)/g;
+export const camelize = (str: string): string => {
+ return str.replace(camelizeRE, (_, c) => (c ? c.toUpperCase() : ''));
+};
+
+/**
+ * Hyphenate a camelCase string.
+ */
+const hyphenateRE = /\B([A-Z])/g;
+export const hyphenate = (str: string): string => {
+ return str.replace(hyphenateRE, '-$1').toLowerCase();
+};
diff --git a/packages/rrweb-player/LICENSE b/packages/rrweb-player/LICENSE
new file mode 100644
index 0000000000..d11896ba11
--- /dev/null
+++ b/packages/rrweb-player/LICENSE
@@ -0,0 +1,14 @@
+Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
+rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
+persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
+Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/rrweb-player/package.json b/packages/rrweb-player/package.json
index ec09c21361..1db1cf2223 100644
--- a/packages/rrweb-player/package.json
+++ b/packages/rrweb-player/package.json
@@ -1,5 +1,5 @@
{
- "name": "rrweb-player",
+ "name": "@sentry-internal/rrweb-player",
"version": "0.7.14",
"devDependencies": {
"@rollup/plugin-commonjs": "^11.0.0",
@@ -25,7 +25,7 @@
},
"dependencies": {
"@tsconfig/svelte": "^1.0.0",
- "rrweb": "^1.1.3"
+ "@sentry-internal/rrweb": "^1.1.3"
},
"scripts": {
"build": "rollup -c",
@@ -33,7 +33,8 @@
"prepublishOnly": "yarn build",
"start": "sirv public",
"validate": "svelte-check",
- "prepublish": "yarn build"
+ "prepublish": "yarn build",
+ "build:tarball": "npm pack"
},
"description": "rrweb's replayer UI",
"main": "lib/index.js",
diff --git a/packages/rrweb-player/src/Controller.svelte b/packages/rrweb-player/src/Controller.svelte
index 33cfac775a..d3303ac688 100644
--- a/packages/rrweb-player/src/Controller.svelte
+++ b/packages/rrweb-player/src/Controller.svelte
@@ -1,11 +1,11 @@
-
-
{#if showController}