fix(cli): omit skipped Lottie previews

This commit is contained in:
Miguel Ángel
2026-07-31 20:30:07 +00:00
parent b38e907404
commit ac9458888c
2 changed files with 55 additions and 4 deletions
+50 -1
View File
@@ -1,4 +1,4 @@
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs"; import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import { join } from "node:path"; import { join } from "node:path";
import type { Browser, Page } from "puppeteer-core"; import type { Browser, Page } from "puppeteer-core";
@@ -75,6 +75,55 @@ describe("Lottie capture budget", () => {
expect(previewPage.setViewport).not.toHaveBeenCalled(); expect(previewPage.setViewport).not.toHaveBeenCalled();
expect(previewPage.screenshot).not.toHaveBeenCalled(); expect(previewPage.screenshot).not.toHaveBeenCalled();
}); });
it("omits a preview path when the budget expires after Lottie readiness", async () => {
const dir = tempDir();
const lottieDir = join(dir, "assets", "lottie");
mkdirSync(join(dir, "extracted"), { recursive: true });
mkdirSync(lottieDir, { recursive: true });
writeFileSync(
join(lottieDir, "logo.json"),
JSON.stringify({
nm: "Logo",
w: 100,
h: 100,
fr: 30,
ip: 0,
op: 30,
layers: [],
}),
);
const screenshot = vi.fn(async () => undefined);
const previewPage = {
setViewport: vi.fn(async () => undefined),
setContent: vi.fn(async () => undefined),
evaluate: vi.fn(async () => undefined),
waitForFunction: vi.fn(async () => undefined),
screenshot,
close: vi.fn(async () => undefined),
};
const browser = { newPage: vi.fn(async () => previewPage) } as unknown as Browser;
let budgetChecks = 0;
await renderLottiePreviews(browser, lottieDir, dir, {
remainingMs: () => (++budgetChecks < 4 ? 10_000 : 0),
});
const manifest = JSON.parse(
readFileSync(join(dir, "extracted", "lottie-manifest.json"), "utf-8"),
);
expect(screenshot).not.toHaveBeenCalled();
expect(manifest).toHaveLength(1);
expect(manifest[0]).toMatchObject({
file: "assets/lottie/logo.json",
name: "Logo",
width: 100,
height: 100,
});
expect(manifest[0]).not.toHaveProperty("preview");
expect(existsSync(join(lottieDir, "previews", "logo-preview.png"))).toBe(false);
});
}); });
describe("video capture live budget", () => { describe("video capture live budget", () => {
+5 -3
View File
@@ -122,7 +122,7 @@ export async function saveLottieAnimations(
* *
* Opens each Lottie JSON in a headless Chrome page via lottie-web, * Opens each Lottie JSON in a headless Chrome page via lottie-web,
* seeks to ~30% through the animation, and takes a transparent screenshot. * seeks to ~30% through the animation, and takes a transparent screenshot.
* Writes a lottie-manifest.json with metadata + preview paths. * Writes a lottie-manifest.json with metadata and successfully rendered preview paths.
*/ */
// fallow-ignore-next-line complexity // fallow-ignore-next-line complexity
export async function renderLottiePreviews( export async function renderLottiePreviews(
@@ -133,7 +133,7 @@ export async function renderLottiePreviews(
): Promise<void> { ): Promise<void> {
const manifest: Array<{ const manifest: Array<{
file: string; file: string;
preview: string; preview?: string;
name: string; name: string;
width: number; width: number;
height: number; height: number;
@@ -152,6 +152,7 @@ export async function renderLottiePreviews(
const fr = raw.fr || 30; const fr = raw.fr || 30;
const dur = ((raw.op || 0) - (raw.ip || 0)) / fr; const dur = ((raw.op || 0) - (raw.ip || 0)) / fr;
const previewName = file.replace(".json", "-preview.png"); const previewName = file.replace(".json", "-preview.png");
let preview: string | undefined;
// Render a mid-frame thumbnail using Puppeteer + lottie-web // Render a mid-frame thumbnail using Puppeteer + lottie-web
// Skip huge Lottie files for preview (CDP has a ~256MB message limit) // Skip huge Lottie files for preview (CDP has a ~256MB message limit)
@@ -202,6 +203,7 @@ export async function renderLottiePreviews(
type: "png", type: "png",
omitBackground: true, omitBackground: true,
}); });
preview = `assets/lottie/previews/${previewName}`;
} }
} catch { } catch {
/* preview rendering failed — non-critical */ /* preview rendering failed — non-critical */
@@ -211,7 +213,7 @@ export async function renderLottiePreviews(
manifest.push({ manifest.push({
file: `assets/lottie/${file}`, file: `assets/lottie/${file}`,
preview: `assets/lottie/previews/${previewName}`, ...(preview ? { preview } : {}),
name: raw.nm || file, name: raw.nm || file,
width: raw.w || 0, width: raw.w || 0,
height: raw.h || 0, height: raw.h || 0,