@juangadm/pre-post 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/video.js ADDED
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Animated GIF capture via sequential Playwright screenshots + gifenc encoding.
3
+ *
4
+ * Pipeline: PNG screenshots → canvas decode → gifenc quantize → animated GIF.
5
+ * Single codepath. No FFmpeg. No external dependencies beyond Playwright + gifenc.
6
+ */
7
+ import { getBrowser } from './browser.js';
8
+ import { createRequire } from 'module';
9
+ // gifenc ships as CJS — use createRequire for ESM compat
10
+ const require = createRequire(import.meta.url);
11
+ let gifencModule = null;
12
+ function getGifenc() {
13
+ if (gifencModule)
14
+ return gifencModule;
15
+ try {
16
+ gifencModule = require('gifenc');
17
+ return gifencModule;
18
+ }
19
+ catch {
20
+ throw new Error('GIF capture requires the "gifenc" dependency for --video captures. Install dependencies with `npx pnpm install`.');
21
+ }
22
+ }
23
+ // Mobile viewport height cap for GIF mode (above-the-fold, not comically tall)
24
+ const MOBILE_GIF_HEIGHT = 667;
25
+ const DEFAULT_DURATION_SECONDS = 3;
26
+ const DEFAULT_FPS = 5;
27
+ const MAX_DURATION_SECONDS = 10;
28
+ const MAX_FPS = 10;
29
+ const MIN_FPS = 1;
30
+ // ============================================================
31
+ // Canvas decoder page (reused across frames)
32
+ // ============================================================
33
+ /**
34
+ * Decode an image buffer to raw RGBA pixels at target dimensions.
35
+ * Uses a hidden Playwright page with canvas for decoding.
36
+ */
37
+ async function decodeImageToRgba(decoderPage, imageBuffer, width, height) {
38
+ const pg = decoderPage;
39
+ const base64 = imageBuffer.toString('base64');
40
+ const base64Rgba = await pg.evaluate(async ({ b64, w, h }) => {
41
+ const img = new Image();
42
+ await new Promise((resolve, reject) => {
43
+ img.onload = () => resolve();
44
+ img.onerror = reject;
45
+ img.src = `data:image/png;base64,${b64}`;
46
+ });
47
+ const canvas = document.getElementById('c');
48
+ canvas.width = w;
49
+ canvas.height = h;
50
+ const ctx = canvas.getContext('2d');
51
+ ctx.drawImage(img, 0, 0, w, h);
52
+ const bytes = ctx.getImageData(0, 0, w, h).data;
53
+ // Transfer as base64 instead of JSON array (~5MB vs ~12MB per frame)
54
+ const parts = [];
55
+ for (let i = 0; i < bytes.length; i += 8192) {
56
+ parts.push(String.fromCharCode(...bytes.subarray(i, Math.min(i + 8192, bytes.length))));
57
+ }
58
+ return btoa(parts.join(''));
59
+ }, { b64: base64, w: width, h: height });
60
+ return new Uint8Array(Buffer.from(base64Rgba, 'base64'));
61
+ }
62
+ // ============================================================
63
+ // Core capture function
64
+ // ============================================================
65
+ /**
66
+ * Capture animated GIF frames from an existing Playwright Page.
67
+ * Caller manages page lifecycle.
68
+ */
69
+ export async function captureGif(page, url, options) {
70
+ const duration = normalizeDuration(options.duration);
71
+ const fps = normalizeFps(options.fps);
72
+ const delay = options.delay ?? 0;
73
+ const totalFrames = Math.ceil(duration * fps);
74
+ const frameInterval = Math.round(1000 / fps);
75
+ // Navigate — do NOT kill animations
76
+ const response = await page.goto(url, { waitUntil: 'domcontentloaded' });
77
+ await Promise.race([
78
+ page.waitForLoadState('networkidle'),
79
+ page.waitForTimeout(3000),
80
+ ]);
81
+ // Warn on HTTP errors (but continue — page may still have content)
82
+ if (response && response.status() >= 400) {
83
+ console.warn(`Warning: ${url} returned HTTP ${response.status()}`);
84
+ }
85
+ // Wait for fonts (capped at 2s)
86
+ await Promise.race([
87
+ page.evaluate(() => document.fonts.ready),
88
+ page.waitForTimeout(2000),
89
+ ]);
90
+ // Optional delay before recording
91
+ if (delay > 0) {
92
+ await page.waitForTimeout(delay);
93
+ }
94
+ // Scroll selector into view if specified
95
+ if (options.selector) {
96
+ const locator = page.locator(options.selector);
97
+ const count = await locator.count();
98
+ if (count === 0) {
99
+ throw new Error(`Element not found: ${options.selector}`);
100
+ }
101
+ await locator.first().scrollIntoViewIfNeeded();
102
+ }
103
+ // Capture PNG frames
104
+ const frames = [];
105
+ let identicalCount = 0;
106
+ for (let i = 0; i < totalFrames; i++) {
107
+ const screenshot = await page.screenshot({ type: 'png' });
108
+ const frame = Buffer.from(screenshot);
109
+ // Early-stop: 3 consecutive identical frames means animation has settled
110
+ if (frames.length > 0 && frame.equals(frames[frames.length - 1])) {
111
+ identicalCount++;
112
+ if (identicalCount >= 3) {
113
+ console.log(`Animation settled after ${i} frames`);
114
+ break;
115
+ }
116
+ }
117
+ else {
118
+ identicalCount = 0;
119
+ }
120
+ frames.push(frame);
121
+ if (i < totalFrames - 1) {
122
+ await page.waitForTimeout(frameInterval);
123
+ }
124
+ }
125
+ // Encode GIF
126
+ const browser = page.context().browser();
127
+ if (!browser) {
128
+ throw new Error('Cannot encode GIF: browser instance is not available on this page context.');
129
+ }
130
+ const gifBuffer = await encodeGif(browser, frames, options.viewport, fps);
131
+ return {
132
+ gif: gifBuffer,
133
+ format: 'gif',
134
+ viewport: options.viewport,
135
+ url,
136
+ duration,
137
+ frameCount: frames.length,
138
+ selector: options.selector,
139
+ };
140
+ }
141
+ function normalizeDuration(duration) {
142
+ if (duration === undefined)
143
+ return DEFAULT_DURATION_SECONDS;
144
+ if (!Number.isFinite(duration)) {
145
+ throw new Error('Duration must be a finite number.');
146
+ }
147
+ return Math.min(MAX_DURATION_SECONDS, Math.max(0.1, duration));
148
+ }
149
+ function normalizeFps(fps) {
150
+ if (fps === undefined)
151
+ return DEFAULT_FPS;
152
+ if (!Number.isFinite(fps)) {
153
+ throw new Error('FPS must be a finite number.');
154
+ }
155
+ return Math.min(MAX_FPS, Math.max(MIN_FPS, Math.round(fps)));
156
+ }
157
+ // ============================================================
158
+ // High-level entry point
159
+ // ============================================================
160
+ /**
161
+ * Capture an animated GIF of a URL.
162
+ * Creates its own page at DPR 1 (no retina), captures, cleans up.
163
+ */
164
+ export async function captureVideo(url, options) {
165
+ const browser = await getBrowser();
166
+ // For mobile, cap height at 667px for GIF mode
167
+ const viewport = { ...options.viewport };
168
+ if (viewport.width <= 430 && viewport.height > MOBILE_GIF_HEIGHT) {
169
+ viewport.height = MOBILE_GIF_HEIGHT;
170
+ }
171
+ const page = await browser.newPage({
172
+ viewport,
173
+ deviceScaleFactor: 1, // DPR 1 — retina wastes pixels in 256-color GIF
174
+ });
175
+ try {
176
+ return await captureGif(page, url, { ...options, viewport });
177
+ }
178
+ finally {
179
+ await page.close();
180
+ }
181
+ }
182
+ // ============================================================
183
+ // GIF encoding
184
+ // ============================================================
185
+ /**
186
+ * Encode an array of screenshot Buffers into an animated GIF.
187
+ */
188
+ async function encodeGif(browser, frames, viewport, fps) {
189
+ const { GIFEncoder, quantize, applyPalette } = getGifenc();
190
+ const width = viewport.width;
191
+ const height = viewport.height;
192
+ const delayCs = Math.round(1000 / fps / 10); // GIF delay is in centiseconds
193
+ const encoder = GIFEncoder();
194
+ const rgbaFrames = [];
195
+ const decoderPage = await browser.newPage();
196
+ await decoderPage.setContent('<canvas id="c"></canvas>');
197
+ try {
198
+ for (let i = 0; i < frames.length; i++) {
199
+ console.log(`Decoding frame ${i + 1}/${frames.length}...`);
200
+ rgbaFrames.push(await decodeImageToRgba(decoderPage, frames[i], width, height));
201
+ }
202
+ const palette = quantize(buildPaletteSample(rgbaFrames), 256, { format: 'rgba4444' });
203
+ let previousIndexed = null;
204
+ let duplicateRunLength = 0;
205
+ for (let i = 0; i < rgbaFrames.length; i++) {
206
+ const indexed = applyPalette(rgbaFrames[i], palette, 'rgba4444');
207
+ if (!previousIndexed) {
208
+ previousIndexed = indexed;
209
+ duplicateRunLength = 1;
210
+ continue;
211
+ }
212
+ if (indexedEquals(previousIndexed, indexed)) {
213
+ duplicateRunLength++;
214
+ continue;
215
+ }
216
+ encoder.writeFrame(previousIndexed, width, height, {
217
+ palette,
218
+ delay: delayCs * duplicateRunLength,
219
+ repeat: 0,
220
+ });
221
+ previousIndexed = indexed;
222
+ duplicateRunLength = 1;
223
+ }
224
+ if (previousIndexed) {
225
+ encoder.writeFrame(previousIndexed, width, height, {
226
+ palette,
227
+ delay: delayCs * duplicateRunLength,
228
+ repeat: 0,
229
+ });
230
+ }
231
+ encoder.finish();
232
+ return Buffer.from(encoder.bytes());
233
+ }
234
+ finally {
235
+ if (!decoderPage.isClosed()) {
236
+ await decoderPage.close();
237
+ }
238
+ }
239
+ }
240
+ function buildPaletteSample(frames) {
241
+ if (frames.length === 0)
242
+ return new Uint8Array(0);
243
+ const stride = 4 * 4;
244
+ const samplesPerFrame = Math.ceil(frames[0].length / stride);
245
+ const sample = new Uint8Array(samplesPerFrame * frames.length * 4);
246
+ let offset = 0;
247
+ for (const frame of frames) {
248
+ for (let i = 0; i < frame.length; i += stride) {
249
+ sample[offset++] = frame[i];
250
+ sample[offset++] = frame[i + 1];
251
+ sample[offset++] = frame[i + 2];
252
+ sample[offset++] = frame[i + 3];
253
+ }
254
+ }
255
+ return sample;
256
+ }
257
+ function indexedEquals(a, b) {
258
+ if (a.length !== b.length)
259
+ return false;
260
+ return Buffer.from(a.buffer, a.byteOffset, a.byteLength)
261
+ .equals(Buffer.from(b.buffer, b.byteOffset, b.byteLength));
262
+ }
263
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../src/video.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juangadm/pre-post",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Visual diff tool for PRs — captures before/after screenshots of web pages",
5
5
  "author": "Juan Gabriel Delgado (forked from James Clements)",
6
6
  "license": "MIT",
@@ -50,6 +50,7 @@
50
50
  "test:integration": "vitest run tests/integration"
51
51
  },
52
52
  "dependencies": {
53
+ "gifenc": "^1.0.3",
53
54
  "playwright": "^1.50.0"
54
55
  },
55
56
  "devDependencies": {