import satori, { init as initSatori } from "satori/standalone"; import { initWasm, Resvg } from "@resvg/resvg-wasm"; import type { ReactNode } from "react"; import { OG_HEIGHT, OG_WIDTH } from "~/lib/og"; /** Wasm modules and font bytes; the Worker passes bundled modules, tests and scripts read the same files from disk. */ export type OgRuntime = { yoga: WebAssembly.Module; resvg: WebAssembly.Module; fonts: { regular: ArrayBuffer; semibold: ArrayBuffer }; }; let satoriReady: Promise | null = null; let resvgReady: Promise | null = null; function alreadyInitialized(error: unknown): boolean { return error instanceof Error && error.message.startsWith("Already initialized"); } /** Each wasm instance lives for the isolate and is initialized once; a failed init is retried on the next render. */ function ensureReady(runtime: OgRuntime): Promise<[void, void]> { satoriReady ??= initSatori(runtime.yoga).catch((error: unknown) => { satoriReady = null; throw error; }); resvgReady ??= initWasm(runtime.resvg).catch((error: unknown) => { // A reloaded module (dev HMR) loses this flag while resvg keeps its instance. if (alreadyInitialized(error)) return; resvgReady = null; throw error; }); return Promise.all([satoriReady, resvgReady]); } export async function renderPng(element: ReactNode, runtime: OgRuntime): Promise { await ensureReady(runtime); const svg = await satori(element, { width: OG_WIDTH, height: OG_HEIGHT, fonts: [ { name: "IBM Plex Sans", data: runtime.fonts.regular, weight: 400, style: "normal" }, { name: "IBM Plex Sans", data: runtime.fonts.semibold, weight: 600, style: "normal" }, ], }); const resvg = new Resvg(svg, { fitTo: { mode: "original" }, font: { loadSystemFonts: false } }); const image = resvg.render(); try { return image.asPng(); } finally { image.free(); resvg.free(); } }