diff --git a/eleventy.config.js b/eleventy.config.js index 36bb6af..55335a9 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -10,7 +10,6 @@ import { minify } from "html-minifier-terser"; import { createHash } from "crypto"; import { execFileSync } from "child_process"; import { readFileSync, existsSync } from "fs"; -import { generateOgImages } from "./lib/og.js"; import { resolve, dirname } from "path"; import { fileURLToPath } from "url"; @@ -526,12 +525,20 @@ export default function (eleventyConfig) { }); // Generate OpenGraph images for posts without photos - eleventyConfig.on("eleventy.before", async () => { + eleventyConfig.on("eleventy.before", () => { const contentDir = resolve(__dirname, "content"); const cacheDir = resolve(__dirname, ".cache"); const siteName = process.env.SITE_NAME || "My IndieWeb Blog"; try { - await generateOgImages(contentDir, cacheDir, siteName); + execFileSync(process.execPath, [ + resolve(__dirname, "lib", "og-cli.js"), + contentDir, + cacheDir, + siteName, + ], { + stdio: "inherit", + env: { ...process.env, NODE_OPTIONS: "--max-old-space-size=768" }, + }); } catch (err) { console.error("[og] Image generation failed:", err.message); } diff --git a/lib/og-cli.js b/lib/og-cli.js new file mode 100644 index 0000000..421b5b0 --- /dev/null +++ b/lib/og-cli.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node + +/** + * CLI entry point for OG image generation. + * Runs as a separate process to isolate memory from Eleventy. + * + * Usage: node lib/og-cli.js + */ + +import { generateOgImages } from "./og.js"; + +const [contentDir, cacheDir, siteName] = process.argv.slice(2); + +if (!contentDir || !cacheDir || !siteName) { + console.error("[og] Usage: node og-cli.js "); + process.exit(1); +} + +await generateOgImages(contentDir, cacheDir, siteName); diff --git a/lib/og.js b/lib/og.js index fdffe94..59fefc1 100644 --- a/lib/og.js +++ b/lib/og.js @@ -288,6 +288,7 @@ export async function generateOgImages(contentDir, cacheDir, siteName) { let generated = 0; let skipped = 0; const newManifest = {}; + const SAVE_INTERVAL = 10; for (const filePath of mdFiles) { const raw = readFileSync(filePath, "utf8"); @@ -320,6 +321,11 @@ export async function generateOgImages(contentDir, cacheDir, siteName) { writeFileSync(join(ogDir, `${slug}.png`), pngBuffer); newManifest[slug] = { title: slug, hash }; generated++; + + // Save manifest periodically to preserve progress + if (generated % SAVE_INTERVAL === 0) { + writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2)); + } } writeFileSync(manifestPath, JSON.stringify(newManifest, null, 2));