docs: document OG batch spawning architecture in CLAUDE.md

Confab-Link: http://localhost:8080/sessions/edb1b7b0-da66-4486-bd9c-d1cfa7553b88
This commit is contained in:
Ricardo
2026-03-09 18:35:09 +01:00
parent db10d9cfbf
commit 508ddf03ca
+15
View File
@@ -286,6 +286,21 @@ Page templates in the root directory:
| `htmlmin` | Minifies HTML (build mode only, not watch mode) | | `htmlmin` | Minifies HTML (build mode only, not watch mode) |
| `eleventyImageTransformPlugin` | Optimizes `<img>` tags | | `eleventyImageTransformPlugin` | Optimizes `<img>` tags |
#### Pre-Build Hook: OG Image Generation (`eleventy.before`)
Generates OpenGraph images for posts without photos using Satori (Yoga WASM → SVG) + Resvg (Rust WASM → PNG).
**Key files:**
- `lib/og.js` — generation logic, card layout, manifest-based caching
- `lib/og-cli.js` — CLI wrapper, accepts `batchSize` argument
- `eleventy.config.js` — spawns og-cli with batch loop
**Architecture:** Runs as a separate process (`execFileSync`) to isolate WASM native memory from Eleventy. Uses **batch spawning** — each invocation generates up to 100 images, then exits with code 2 ("more remain"). The spawner re-loops until exit code 0. This keeps peak RSS at ~460 MB per batch regardless of total image count.
**Why batch spawning:** Satori and Resvg allocate native memory outside V8's heap. `--max-old-space-size` only limits V8 — WASM native allocations are invisible to it. Without batching, 2,350+ images grow native memory to ~3 GB, OOM-killing the process in the 3 GB container. Batching fully releases native memory between invocations.
**Caching:** Manifest at `.cache/og/manifest.json` maps slug → content hash. Only changed/new posts generate images. Manifest saved every 10 images for crash resilience.
#### Post-Build Hooks (`eleventy.after`) #### Post-Build Hooks (`eleventy.after`)
1. **Pagefind indexing** — indexes all HTML files for search 1. **Pagefind indexing** — indexes all HTML files for search