diff --git a/.changeset/odd-onions-brush.md b/.changeset/odd-onions-brush.md new file mode 100644 index 0000000000..a0996ee8c8 --- /dev/null +++ b/.changeset/odd-onions-brush.md @@ -0,0 +1,5 @@ +--- +"@rrweb/web-extension": patch +--- + +fix: remove the permission not needed and update the player style link diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f870937fd3..5ba49c811b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -33,7 +33,17 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - # - name: Send a Slack notification if a publish happens - # if: steps.changesets.outputs.published == 'true' - # # You can do something when a publish happens. - # run: my-slack-bot send-notification --message "A new version of ${GITHUB_REPOSITORY} was published!" + - name: Build Chrome Extension + if: steps.changesets.outputs.published == 'true' + run: NODE_OPTIONS='--max-old-space-size=4096' DISABLE_WORKER_INLINING=true yarn turbo run prepublish --filter=@rrweb/web-extension + + - name: Publish Chrome Extension + uses: mnao305/chrome-extension-upload@v5.0.0 + if: steps.changesets.outputs.published == 'true' + with: + extension-id: 'pdaldeopoccdhlkabbkcjmecmmoninhe' + file-path: ./packages/web-extension/dist/chrome.zip + client-id: ${{ secrets.CWS_CLIENT_ID }} + client-secret: ${{ secrets.CWS_CLIENT_SECRET }} + refresh-token: ${{ secrets.CWS_REFRESH_TOKEN }} + publish: true diff --git a/packages/rrweb-player/package.json b/packages/rrweb-player/package.json index ae90af35ea..e9e7614bea 100644 --- a/packages/rrweb-player/package.json +++ b/packages/rrweb-player/package.json @@ -14,7 +14,7 @@ "svelte": "^4.2.14", "svelte-check": "^3.4.3", "svelte-preprocess": "^5.0.3", - "svelte2tsx": "^0.7.6", + "svelte2tsx": "^0.7.30", "tslib": "^2.0.0", "vite": "^5.3.1" }, diff --git a/packages/web-extension/package.json b/packages/web-extension/package.json index bb44441072..f9f340a53c 100644 --- a/packages/web-extension/package.json +++ b/packages/web-extension/package.json @@ -19,9 +19,12 @@ }, "devDependencies": { "@rrweb/types": "^2.0.0-alpha.18", + "@types/chrome": "^0.0.287", "@types/react-dom": "^18.0.6", + "@types/semver": "^7.5.8", "@types/webextension-polyfill": "^0.9.1", "@vitejs/plugin-react": "^4.2.1", + "semver": "^7.6.3", "type-fest": "^2.19.0", "vite": "^5.3.1", "vite-plugin-web-extension": "^4.1.3", diff --git a/packages/web-extension/src/content/index.ts b/packages/web-extension/src/content/index.ts index 51899c5dca..0fb866c1e5 100644 --- a/packages/web-extension/src/content/index.ts +++ b/packages/web-extension/src/content/index.ts @@ -1,4 +1,4 @@ -import Browser, { type Storage } from 'webextension-polyfill'; +import Browser from 'webextension-polyfill'; import { nanoid } from 'nanoid'; import type { eventWithTime } from '@rrweb/types'; import { @@ -166,9 +166,7 @@ async function initMainPage() { async function initCrossOriginIframe() { Browser.storage.local.onChanged.addListener((change) => { if (change[LocalDataKey.recorderStatus]) { - const statusChange = change[ - LocalDataKey.recorderStatus - ] as Storage.StorageChange; + const statusChange = change[LocalDataKey.recorderStatus]; const newStatus = statusChange.newValue as LocalData[LocalDataKey.recorderStatus]; if (newStatus.status === RecorderStatus.RECORDING) startRecord(); diff --git a/packages/web-extension/src/manifest.json b/packages/web-extension/src/manifest.json index 482335d4c6..cdf9d3c443 100644 --- a/packages/web-extension/src/manifest.json +++ b/packages/web-extension/src/manifest.json @@ -14,7 +14,7 @@ "48": "icon48.png", "128": "icon128.png" }, - "permissions": ["activeTab", "tabs", "storage", "unlimitedStorage"] + "permissions": ["activeTab", "storage", "unlimitedStorage"] }, "v2": { "common": { diff --git a/packages/web-extension/src/pages/Player.tsx b/packages/web-extension/src/pages/Player.tsx index df0bf0aadf..56f3fa4d00 100644 --- a/packages/web-extension/src/pages/Player.tsx +++ b/packages/web-extension/src/pages/Player.tsx @@ -1,3 +1,4 @@ +/// import { useRef, useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import Replayer from 'rrweb-player'; @@ -29,9 +30,10 @@ export default function Player() { .then((events) => { if (!playerElRef.current) return; + const manifest = chrome.runtime.getManifest(); + const rrwebPlayerVersion = manifest.version_name || manifest.version; const linkEl = document.createElement('link'); - linkEl.href = - 'https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css'; + linkEl.href = `https://cdn.jsdelivr.net/npm/rrweb-player@${rrwebPlayerVersion}/dist/style.min.css`; linkEl.rel = 'stylesheet'; document.head.appendChild(linkEl); playerRef.current = new Replayer({ @@ -46,6 +48,7 @@ export default function Player() { console.error(err); }); return () => { + // eslint-disable-next-line playerRef.current?.pause(); }; }, [sessionId]); diff --git a/packages/web-extension/src/pages/index.html b/packages/web-extension/src/pages/index.html index bac6dabc6f..3450454799 100644 --- a/packages/web-extension/src/pages/index.html +++ b/packages/web-extension/src/pages/index.html @@ -1,9 +1,14 @@ - -rrweb - -
- - - + + + + rrweb + + + +
+ + + + \ No newline at end of file diff --git a/packages/web-extension/vite.config.ts b/packages/web-extension/vite.config.ts index 2ca58feab9..f4fcec49d1 100644 --- a/packages/web-extension/vite.config.ts +++ b/packages/web-extension/vite.config.ts @@ -4,6 +4,7 @@ import zip from 'vite-plugin-zip-pack'; import * as path from 'path'; import type { PackageJson } from 'type-fest'; import react from '@vitejs/plugin-react'; +import semver from 'semver'; const emptyOutDir = !process.argv.includes('--watch'); @@ -39,6 +40,29 @@ function useSpecialFormat( }; } +/** + * Get the extension version based on the rrweb version. + */ +function getExtensionVersion(rrwebVersion: string): string { + const parsedVersion = semver.parse(rrwebVersion.replace('^', '')); + + if (!parsedVersion) { + throw new Error('Invalid version format'); + } + + if (parsedVersion.prerelease.length > 0) { + // If it's a pre-release version like alpha or beta, strip the pre-release identifier + return `${parsedVersion.major}.${parsedVersion.minor}.${ + parsedVersion.patch + }.${parsedVersion.prerelease[1] || 0}`; + } else if (rrwebVersion === '2.0.0') { + // This version has already been released as the first version. We need to add a patch version to it to avoid publishing conflicts. + return '2.0.0.100'; + } else { + return rrwebVersion; + } +} + export default defineConfig({ root: 'src', // Configure our outputs - nothing special, this is normal vite config @@ -73,10 +97,11 @@ export default defineConfig({ const BrowserName = process.env.TARGET_BROWSER === 'chrome' ? 'chrome' : 'firefox'; const commonManifest = originalManifest.common; + const rrwebVersion = packageJson.dependencies!.rrweb!.replace('^', ''); const manifest = { - version: '2.0.0', + version: getExtensionVersion(rrwebVersion), author: packageJson.author, - version_name: packageJson.dependencies?.rrweb?.replace('^', ''), + version_name: rrwebVersion, ...commonManifest, }; Object.assign( @@ -92,7 +117,7 @@ export default defineConfig({ watchIgnored: ['*.md', '*.log'], }, additionalInputs: ['pages/index.html', 'content/inject.ts'], - }), + }) as PluginOption, // https://github.com/aklinker1/vite-plugin-web-extension/issues/50#issuecomment-1317922947 // transfer inject.ts to iife format to avoid error useSpecialFormat( diff --git a/turbo.json b/turbo.json index 54bd1b278f..6dbac94d2e 100644 --- a/turbo.json +++ b/turbo.json @@ -7,7 +7,7 @@ "vite.config.defaults.ts", "tsconfig.json" ], - "globalPassThroughEnv": ["PUPPETEER_HEADLESS"], + "globalPassThroughEnv": ["PUPPETEER_HEADLESS", "DISABLE_WORKER_INLINING"], "tasks": { "prepublish": { "dependsOn": ["^prepublish", "//#references:update"], diff --git a/vite.config.default.ts b/vite.config.default.ts index 0dce01c40a..d29556987e 100644 --- a/vite.config.default.ts +++ b/vite.config.default.ts @@ -2,7 +2,6 @@ import dts from 'vite-plugin-dts'; import { copyFileSync } from 'node:fs'; import { defineConfig, LibraryOptions, LibraryFormats, Plugin } from 'vite'; -import glob from 'fast-glob'; import { build, Format } from 'esbuild'; import path, { resolve } from 'path'; import { umdWrapper } from 'esbuild-plugin-umd-wrapper'; @@ -11,6 +10,11 @@ import { visualizer } from 'rollup-plugin-visualizer'; // don't empty out dir if --watch flag is passed const emptyOutDir = !process.argv.includes('--watch'); +/** + * Chrome web store does not allow base64 inline workers. + * For chrome extension, we need to disable worker inlining to pass the review. + */ +const disableWorkerInlining = process.env.DISABLE_WORKER_INLINING === 'true'; function minifyAndUMDPlugin({ name, @@ -183,6 +187,18 @@ export default function ( filename: path.resolve(__dirname, name + '-bundle-analysis.html'), // Path for the HTML report open: false, // don't Automatically open the report in the browser }), + name: 'remove-worker-inline', + enforce: 'pre', + transform(code, id) { + if (!disableWorkerInlining) return; + if (/\.(js|ts|jsx|tsx)$/.test(id)) { + return { + code: code.replace(/\?worker&inline/g, '?worker'), + map: null, + }; + } + }, + }, ...plugins, ], })); diff --git a/yarn.lock b/yarn.lock index 634432d67c..1ac78ba7bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2585,6 +2585,14 @@ dependencies: "@babel/types" "^7.20.7" +"@types/chrome@^0.0.287": + version "0.0.287" + resolved "https://registry.yarnpkg.com/@types/chrome/-/chrome-0.0.287.tgz#239969b1195b441836d2137125543b5241c41157" + integrity sha512-wWhBNPNXZHwycHKNYnexUcpSbrihVZu++0rdp6GEk5ZgAglenLx+RwdEouh6FrHS0XQiOxSd62yaujM1OoQlZQ== + dependencies: + "@types/filesystem" "*" + "@types/har-format" "*" + "@types/cookie@^0.6.0": version "0.6.0" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" @@ -2622,6 +2630,18 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/filesystem@*": + version "0.0.36" + resolved "https://registry.yarnpkg.com/@types/filesystem/-/filesystem-0.0.36.tgz#7227c2d76bfed1b21819db310816c7821d303857" + integrity sha512-vPDXOZuannb9FZdxgHnqSwAG/jvdGM8Wq+6N4D/d80z+D4HWH+bItqsZaVRQykAn6WEVeEkLm2oQigyHtgb0RA== + dependencies: + "@types/filewriter" "*" + +"@types/filewriter@*": + version "0.0.33" + resolved "https://registry.yarnpkg.com/@types/filewriter/-/filewriter-0.0.33.tgz#d9d611db9d9cd99ae4e458de420eeb64ad604ea8" + integrity sha512-xFU8ZXTw4gd358lb2jw25nxY9QAgqn2+bKKjKOYfNCzN4DKCFetK7sPtrlpg66Ywe3vWY9FNxprZawAh9wfJ3g== + "@types/fs-extra@11.0.1": version "11.0.1" resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-11.0.1.tgz#f542ec47810532a8a252127e6e105f487e0a6ea5" @@ -2637,6 +2657,11 @@ dependencies: "@types/node" "*" +"@types/har-format@*": + version "1.2.16" + resolved "https://registry.yarnpkg.com/@types/har-format/-/har-format-1.2.16.tgz#b71ede8681400cc08b3685f061c31e416cf94944" + integrity sha512-fluxdy7ryD3MV6h8pTfTYpy/xQzCFC7m89nOH9y94cNqJ1mDIDPut7MnRHI3F6qRmh/cT2fUjG1MLdCNb4hE9A== + "@types/http-cache-semantics@^4.0.2": version "4.0.4" resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" @@ -2820,7 +2845,7 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/semver@^7.3.12", "@types/semver@^7.5.0": +"@types/semver@^7.3.12", "@types/semver@^7.5.0", "@types/semver@^7.5.8": version "7.5.8" resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== @@ -9009,6 +9034,11 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.6.3: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + semver@~7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" @@ -9584,7 +9614,15 @@ svelte-preprocess@^5.0.3, svelte-preprocess@^5.1.3: sorcery "^0.11.0" strip-indent "^3.0.0" -svelte2tsx@^0.7.6, svelte2tsx@~0.7.0: +svelte2tsx@^0.7.30: + version "0.7.30" + resolved "https://registry.yarnpkg.com/svelte2tsx/-/svelte2tsx-0.7.30.tgz#5dbd9e38c2fe54170b441409ebb2ee46c807be9e" + integrity sha512-sHXK/vw/sVJmFuPSq6zeKrtuZKvo0jJyEi8ybN0dfrqSYVvHu8zFbO0zQKAL8y/fYackYojH41EJGe6v8rd5fw== + dependencies: + dedent-js "^1.0.1" + pascal-case "^3.1.1" + +svelte2tsx@~0.7.0: version "0.7.9" resolved "https://registry.yarnpkg.com/svelte2tsx/-/svelte2tsx-0.7.9.tgz#a2b42e218e8808b9bd4b292dedba18ae8468abb0" integrity sha512-Rm+0LAwg9wT4H2IsR8EaM9EWErTzi9LmuZKxkH5b1ua94XjQmwHstBP4VabLgA9AE6XmwBg+xK7Cjzwfm6ustQ==