import { readFileSync } from "node:fs"; import { join } from "node:path"; import type { OgRuntime } from "./render"; /** Bun counterpart of runtime.ts for tests and scripts/og-samples.tsx: the same precompiled modules, read from disk. */ export function loadRuntimeFromDisk(): OgRuntime { const root = join(import.meta.dir, "../../.."); const bytes = (path: string) => { const buffer = readFileSync(join(root, path)); return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer; }; return { yoga: new WebAssembly.Module(bytes("node_modules/satori/yoga.wasm")), resvg: new WebAssembly.Module(bytes("node_modules/@resvg/resvg-wasm/index_bg.wasm")), fonts: { regular: bytes("src/server/og/fonts/plex-sans-400.bin"), semibold: bytes("src/server/og/fonts/plex-sans-600.bin"), }, }; } const IHDR_END = 24; /** Width and height from a PNG's IHDR chunk, or null when the bytes are not a PNG. */ export function pngSize(png: Uint8Array): { width: number; height: number } | null { const signature = [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]; if (png.length < IHDR_END || signature.some((byte, index) => png[index] !== byte)) return null; const view = new DataView(png.buffer, png.byteOffset, png.byteLength); return { width: view.getUint32(16), height: view.getUint32(20) }; }