fix(poster): isolate automatic thumbnail generation in Node
This commit is contained in:
1 parent
1069edb8f4
commit
9234bac79e
7 files changed
+29
-22
No files matched your search
+1
-1
@@ -25,7 +25,7 @@ RUN bun install --frozen-lockfile \
|
||||
|
||||
FROM dependencies AS build
|
||||
# Only stale template previews need the build browser; it stays out of runtime.
|
||||
RUN apk add --no-cache chromium
|
||||
RUN apk add --no-cache chromium nodejs
|
||||
ENV EDGE_EVER_POSTER_CHROME_EXECUTABLE=/usr/bin/chromium
|
||||
COPY apps/api apps/api
|
||||
COPY apps/web apps/web
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import path from "node:path";
|
||||
import type { Plugin, ViteDevServer } from "vite";
|
||||
import { ensurePosterThumbnails, projectRoot, sources } from "../../scripts/prepare-poster-thumbnails.mjs";
|
||||
import { runPosterThumbnailGeneration, projectRoot, sources } from "../../scripts/prepare-poster-thumbnails.mjs";
|
||||
|
||||
/** Generate on build/startup and coalesce template saves while rendering. */
|
||||
export function automaticPosterThumbnails({ root = projectRoot, generate = ensurePosterThumbnails } = {}): Plugin {
|
||||
export function automaticPosterThumbnails({ root = projectRoot, generate = runPosterThumbnailGeneration } = {}): Plugin {
|
||||
let command: "build" | "serve";
|
||||
let server: ViteDevServer | undefined;
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"version": 2,
|
||||
"sourceHash": "9cd2f217b58072425f856730ab245e9723160c7fb387b02300824887e91a955e",
|
||||
"sourceHash": "014dc1441fe7b47b32069e372c8820d70a8b58aa353f6232efaf7f4e1330f508",
|
||||
"painterHash": "21dcb74339638258001efc7f15a679376cf51ff95ccbcf2cc31026d4f2a94a96",
|
||||
"width": 480,
|
||||
"height": 640,
|
||||
|
||||
@@ -80,7 +80,7 @@ describe("Docker release contract", () => {
|
||||
);
|
||||
expect(dockerfile).toContain("RUN bun run build:web && bun run build:self-hosted");
|
||||
expect(dockerfile).toContain("scripts/prepare-poster-thumbnails.mjs scripts/prepare-poster-thumbnails.d.mts scripts/");
|
||||
expect(dockerfile).toContain("RUN apk add --no-cache chromium");
|
||||
expect(dockerfile).toContain("RUN apk add --no-cache chromium nodejs");
|
||||
expect(dockerfile).toContain("EDGE_EVER_POSTER_CHROME_EXECUTABLE=/usr/bin/chromium");
|
||||
expect(dockerfile).toContain("COPY tests/browser/poster-thumbnail-generator.html tests/browser/poster-thumbnail-generator.ts tests/browser/");
|
||||
expect(runtimeStage).toContain(
|
||||
|
||||
@@ -5,3 +5,4 @@ export function ensurePosterThumbnails(options?: {
|
||||
output?: string;
|
||||
log?: (message: string) => void;
|
||||
}): Promise<{ generated: number; skipped: boolean }>;
|
||||
export function runPosterThumbnailGeneration(options?: { root?: string }): Promise<{ generated: number; skipped: boolean }>;
|
||||
@@ -243,12 +243,29 @@ export async function ensurePosterThumbnails({ root = projectRoot, output = path
|
||||
}
|
||||
}
|
||||
|
||||
// Playwright's process/transport lifecycle is supported by Node. Keep browser
|
||||
// generation out of the application's Vite/Bun process, including Docker builds.
|
||||
export async function runPosterThumbnailGeneration({ root = projectRoot } = {}) {
|
||||
if (await thumbnailsCurrent(path.join(root, "apps/web/src/assets/poster-template-previews"), await sourceState(root))) return { generated: 0, skipped: true };
|
||||
const { stdout, stderr } = await promisify(execFile)("node", [fileURLToPath(import.meta.url), "--json", "--root", root], {
|
||||
cwd: root, maxBuffer: 8 * 1024 * 1024,
|
||||
});
|
||||
if (stderr) process.stderr.write(stderr);
|
||||
return JSON.parse(stdout);
|
||||
}
|
||||
|
||||
if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
|
||||
const rootIndex = process.argv.indexOf("--root");
|
||||
const root = rootIndex < 0 ? projectRoot : path.resolve(process.argv[rootIndex + 1]);
|
||||
if (process.argv.includes("--check")) {
|
||||
if (!await thumbnailsCurrent(path.join(projectRoot, "apps/web/src/assets/poster-template-previews"), await sourceState())) throw new Error("Poster thumbnails are stale; normal dev/build will regenerate them automatically.");
|
||||
if (!await thumbnailsCurrent(path.join(root, "apps/web/src/assets/poster-template-previews"), await sourceState(root))) throw new Error("Poster thumbnails are stale; normal dev/build will regenerate them automatically.");
|
||||
console.log("Poster thumbnails are current");
|
||||
} else {
|
||||
const result = await ensurePosterThumbnails();
|
||||
if (result.skipped) console.log("[poster thumbnails] Already current; no renderer needed");
|
||||
const json = process.argv.includes("--json");
|
||||
const result = process.versions.bun
|
||||
? await runPosterThumbnailGeneration({ root })
|
||||
: await ensurePosterThumbnails({ root, log: json ? message => console.error(message) : console.log });
|
||||
if (json) console.log(JSON.stringify(result));
|
||||
else if (result.skipped) console.log("[poster thumbnails] Already current; no renderer needed");
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Run with Bun. A temporary source fixture and Chrome exercise the real Vite
|
||||
// Run with Node (native TypeScript support). A temporary source fixture and Chrome exercise the real Vite
|
||||
// watcher and renderer; no working-tree templates or user notes are changed.
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtemp, mkdir, cp, readFile, writeFile, symlink, rm, stat } from "node:fs/promises";
|
||||
@@ -6,7 +6,7 @@ import path from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { createServer } from "vite";
|
||||
import { automaticPosterThumbnails } from "../apps/web/poster-thumbnails.ts";
|
||||
import { sources, projectRoot, ensurePosterThumbnails, openRenderer, sourceState, thumbnailsCurrent } from "./prepare-poster-thumbnails.mjs";
|
||||
import { sources, projectRoot, ensurePosterThumbnails, sourceState, thumbnailsCurrent } from "./prepare-poster-thumbnails.mjs";
|
||||
|
||||
await ensurePosterThumbnails();
|
||||
const root = await mkdtemp(path.join(tmpdir(), "edgeever-poster-watch-"));
|
||||
@@ -34,18 +34,7 @@ try {
|
||||
await symlink(path.join(projectRoot, "apps/web/node_modules"), path.join(root, "apps/web/node_modules"), process.platform === "win32" ? "junction" : "dir");
|
||||
server = await createServer({
|
||||
configFile: false, root, logLevel: "error", appType: "mpa",
|
||||
plugins: [automaticPosterThumbnails({ root, generate: options => ensurePosterThumbnails({
|
||||
...options,
|
||||
renderer: async root => {
|
||||
const runtime = await openRenderer(root);
|
||||
const prepare = runtime.prepare;
|
||||
runtime.prepare = async (id, language) => {
|
||||
if (language === "zh") console.log(`[watch test] Inspecting ${id}`);
|
||||
return prepare(id, language);
|
||||
};
|
||||
return runtime;
|
||||
},
|
||||
}) })],
|
||||
plugins: [automaticPosterThumbnails({ root })],
|
||||
server: { host: "127.0.0.1", port: 0, fs: { allow: [root, projectRoot] } },
|
||||
optimizeDeps: { noDiscovery: true },
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user