Migrates to vite@6 to drop base64 inlined worker source from all bundles (#1762)
* chore: maintain CSS output file name in vite@6.0.1 Without this change, build would fail because the produced stylesheet assumes the `package.json['name']` i.e., `styles/rrweb.css`. To maintain the existing behavior, these changes are required. See https://vite.dev/guide/migration.html#customize-css-output-file-name-in-library-mode * build(rrvideo): upgrade playwright from 1.32.1 to 1.56.1 Update playwright dependency to latest version and refactor test execution options to use a shared configuration with increased timeout for stability. * debug(rrvideo): add comprehensive logging to video transformation process Add detailed console.log statements throughout the transformToVideo function to track execution flow and debug potential issues. Logging covers browser launch, context creation, page navigation, replay progress, and video file operations. * ci(rrvideo): install playwright browsers and improve test output visibility - Add Playwright Chromium installation step to CI workflow - Change test execution stdio from 'pipe' to 'inherit' for better debugging * fix(rrvideo): prevent autoplay and manually start playback after event listeners Set autoPlay to false in replayer configuration and manually call play() after all event listeners are attached. This ensures event handlers are properly registered before playback begins, preventing potential race conditions. Also refactor test execution options to separate stdio configuration from timeout settings for better control over test output visibility. * fix(rrvideo): add timeout and error handling to replay process Add comprehensive error handling to prevent hanging during video transformation: - Add 2-minute timeout for replay finish event - Add console and error listeners for better debugging - Improve promise chain with proper error catching - Clear timeout on successful completion or error This prevents the process from hanging indefinitely when the replay finish event never fires. * fix(rrvideo): add error handling and restructure replayer initialization Wrap replayer initialization in try-catch block to handle potential errors gracefully. Restructure Player instantiation to use rrwebPlayer directly instead of rrwebPlayer.Player, and move width/height into props object for correct API usage. On error, log to console and trigger onReplayFinish callback to prevent hanging state. * build(umd): rename record and replay globals Update UMD build globals for recorder and replayer and refresh documentation accordingly. BREAKING CHANGE: UMD global names changed to rrwebRecord and rrwebReplay. * fix(rrvideo): adjust replay timeout to duration * docs: update rrweb-player CDN script path * Update vite.config.default.ts Co-authored-by: Eoghan Murray <eoghan@getthere.ie> --------- Co-authored-by: Rui <rui@conti.sh> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Eoghan Murray <eoghan@getthere.ie>
This commit is contained in:
@@ -50,7 +50,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"puppeteer": "^20.9.0",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
"package.json"
|
||||
],
|
||||
"devDependencies": {
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"devDependencies": {
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"devDependencies": {
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
"devDependencies": {
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"puppeteer": "^20.9.0"
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"@rrweb/rrweb-plugin-console-record": "^2.0.0-alpha.20",
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
"devDependencies": {
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"@rrweb/rrweb-plugin-sequential-id-record": "^2.0.0-alpha.20",
|
||||
"rrweb": "^2.0.0-alpha.20",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"puppeteer": "^20.9.0",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import config from '../../vite.config.default';
|
||||
|
||||
export default config(path.resolve(__dirname, 'src/index.ts'), 'rrweb');
|
||||
export default config(path.resolve(__dirname, 'src/index.ts'), 'rrwebRecord');
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"puppeteer": "^20.9.0",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import path from 'path';
|
||||
import config from '../../vite.config.default';
|
||||
|
||||
export default config(path.resolve(__dirname, 'src/index.ts'), 'rrweb');
|
||||
export default config(path.resolve(__dirname, 'src/index.ts'), 'rrwebReplay');
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"compare-versions": "^4.1.3",
|
||||
"eslint": "^8.15.0",
|
||||
"puppeteer": "^9.1.1",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0",
|
||||
"typescript": "^5.4.5"
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
"eslint": "^8.15.0",
|
||||
"puppeteer": "^17.1.3",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -57,22 +57,27 @@ function getHtml(events: Array<eventWithTime>, config?: RRvideoConfig): string {
|
||||
)};
|
||||
/*-->*/
|
||||
const userConfig = ${JSON.stringify(config?.rrwebPlayer || {})};
|
||||
window.replayer = new rrwebPlayer.Player({
|
||||
target: document.body,
|
||||
width: userConfig.width,
|
||||
height: userConfig.height,
|
||||
props: {
|
||||
...userConfig,
|
||||
events,
|
||||
showController: false,
|
||||
},
|
||||
});
|
||||
window.replayer.addEventListener('finish', () => window.onReplayFinish());
|
||||
window.replayer.addEventListener('ui-update-progress', (payload)=> window.onReplayProgressUpdate
|
||||
(payload));
|
||||
window.replayer.addEventListener('resize',()=>document.querySelector('.replayer-wrapper').style.transform = 'scale(${
|
||||
(config?.resolutionRatio ?? 1) * MaxScaleValue
|
||||
}) translate(-50%, -50%)');
|
||||
try {
|
||||
window.replayer = new rrwebPlayer({
|
||||
target: document.body,
|
||||
props: {
|
||||
...userConfig,
|
||||
events,
|
||||
showController: false,
|
||||
autoPlay: false,
|
||||
},
|
||||
});
|
||||
window.replayer.addEventListener('finish', () => window.onReplayFinish());
|
||||
window.replayer.addEventListener('ui-update-progress', (payload)=> window.onReplayProgressUpdate(payload));
|
||||
window.replayer.addEventListener('resize', () => document.querySelector('.replayer-wrapper').style.transform = 'scale(${
|
||||
(config?.resolutionRatio ?? 1) * MaxScaleValue
|
||||
}) translate(-50%, -50%)');
|
||||
// Start playback after event listeners are attached
|
||||
window.replayer.play();
|
||||
} catch (error) {
|
||||
console.error('Error initializing replayer:', error);
|
||||
window.onReplayFinish();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -139,6 +144,16 @@ export async function transformToVideo(options: RRvideoConfig) {
|
||||
});
|
||||
const page = await context.newPage();
|
||||
await page.goto('about:blank');
|
||||
// Listen to console messages from the page
|
||||
page.on('console', (msg) => {
|
||||
console.log('[PAGE CONSOLE]', msg.type(), msg.text());
|
||||
});
|
||||
|
||||
// Listen to page errors
|
||||
page.on('pageerror', (error) => {
|
||||
console.error('[PAGE ERROR]', error.message);
|
||||
});
|
||||
|
||||
await page.exposeFunction(
|
||||
'onReplayProgressUpdate',
|
||||
(data: { payload: number }) => {
|
||||
@@ -147,12 +162,41 @@ export async function transformToVideo(options: RRvideoConfig) {
|
||||
);
|
||||
|
||||
// Wait for the replay to finish
|
||||
await new Promise<void>(
|
||||
(resolve) =>
|
||||
void page
|
||||
.exposeFunction('onReplayFinish', () => resolve())
|
||||
.then(() => page.setContent(getHtml(events, config))),
|
||||
);
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const timeoutBuffer = 120000; // 2 minute timeout buffer
|
||||
const videoStartTime = events[0]?.timestamp;
|
||||
const videoEndTime = events[events.length - 1]?.timestamp;
|
||||
const videoDuration = videoEndTime - videoStartTime;
|
||||
const videoPlaybackSpeed = options.rrwebPlayer?.speed || 1;
|
||||
const expectedPlaybackTime = videoDuration / videoPlaybackSpeed;
|
||||
console.log(
|
||||
`[DEBUG] Expected playback time: ${expectedPlaybackTime}ms (video duration: ${videoDuration}ms, playback speed: ${videoPlaybackSpeed}x)`,
|
||||
);
|
||||
const totalTimeout = expectedPlaybackTime + timeoutBuffer;
|
||||
const timeout = setTimeout(() => {
|
||||
console.error('[DEBUG] Replay timeout - finish event never fired');
|
||||
reject(new Error('Replay timeout'));
|
||||
}, totalTimeout); // playback + 2 minute timeout
|
||||
|
||||
void page
|
||||
.exposeFunction('onReplayFinish', () => {
|
||||
console.log('[DEBUG] Replay finished');
|
||||
clearTimeout(timeout);
|
||||
resolve();
|
||||
})
|
||||
.then(() => {
|
||||
console.log('[DEBUG] Setting page content');
|
||||
return page.setContent(getHtml(events, config));
|
||||
})
|
||||
.then(() => {
|
||||
console.log('[DEBUG] Page content set successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('[DEBUG] Error setting page content:', err);
|
||||
clearTimeout(timeout);
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
const videoPath = (await page.video()?.path()) || '';
|
||||
const cleanFiles = async (videoPath: string) => {
|
||||
await fs.remove(videoPath);
|
||||
|
||||
@@ -18,18 +18,19 @@ describe('should be able to run cli', () => {
|
||||
await fs.remove(path.resolve(__dirname, './generated'));
|
||||
});
|
||||
|
||||
const execOptions = { stdio: 'pipe', timeout: 60_000 } as const;
|
||||
const execOptions = { timeout: 60_000 } as const;
|
||||
const execOptionsWithOutput = { ...execOptions, stdio: 'inherit' } as const;
|
||||
|
||||
it('should throw error without input path', () => {
|
||||
expect(() => {
|
||||
execSync('node ./build/cli.js', execOptions);
|
||||
execSync('node ./build/cli.js', { ...execOptions, stdio: 'pipe' });
|
||||
}).toThrowError(/.*please pass --input to your rrweb events file.*/);
|
||||
});
|
||||
|
||||
it('should generate a video without output path', () => {
|
||||
execSync(
|
||||
'node ./build/cli.js --input ./test/generated/example.json',
|
||||
execOptions,
|
||||
execOptionsWithOutput,
|
||||
);
|
||||
const outputFile = path.resolve(__dirname, '../rrvideo-output.webm');
|
||||
expect(fs.existsSync(outputFile)).toBe(true);
|
||||
@@ -40,7 +41,7 @@ describe('should be able to run cli', () => {
|
||||
const outputFile = path.resolve(__dirname, './generated/output.webm');
|
||||
execSync(
|
||||
`node ./build/cli.js --input ./test/generated/example.json --output ${outputFile}`,
|
||||
execOptions,
|
||||
execOptionsWithOutput,
|
||||
);
|
||||
expect(fs.existsSync(outputFile)).toBe(true);
|
||||
fs.removeSync(outputFile);
|
||||
|
||||
@@ -19,7 +19,7 @@ rrweb-player can also be included with `<script>`:
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/style.css"
|
||||
/>
|
||||
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/index.umd.cjs"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/rrweb-player@latest/dist/rrweb-player.umd.cjs"></script>
|
||||
```
|
||||
|
||||
Or installed by using NPM:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"svelte-preprocess": "^5.0.3",
|
||||
"svelte2tsx": "^0.7.30",
|
||||
"tslib": "^2.0.0",
|
||||
"vite": "^5.3.1"
|
||||
"vite": "^6.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tsconfig/svelte": "^1.0.0",
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
"ts-node": "^7.0.1",
|
||||
"tslib": "^1.9.3",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1",
|
||||
"vitest": "^1.4.0"
|
||||
},
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
"ts-node": "^10.9.1",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^5.4.5",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"package.json"
|
||||
],
|
||||
"devDependencies": {
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.9.1"
|
||||
},
|
||||
"browserslist": [
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"package.json"
|
||||
],
|
||||
"devDependencies": {
|
||||
"vite": "^5.2.8",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-dts": "^3.8.1"
|
||||
},
|
||||
"dependencies": {}
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"@vitejs/plugin-react": "^4.2.1",
|
||||
"semver": "^7.6.3",
|
||||
"type-fest": "^2.19.0",
|
||||
"vite": "^5.3.1",
|
||||
"vite": "^6.0.1",
|
||||
"vite-plugin-web-extension": "^4.1.3",
|
||||
"vite-plugin-zip-pack": "^1.2.2",
|
||||
"webextension-polyfill": "^0.10.0"
|
||||
|
||||
Reference in New Issue
Block a user