A vibe coded tangled fork which supports pijul.
1/**
2 * Bun/Node.js runtime implementation
3 * Uses filesystem APIs to load WASM and fonts
4 */
5import { readFile } from "node:fs/promises";
6import { createRequire } from "node:module";
7import type { FontData, SatoriFn, ResvgClass } from "./types";
8
9const require = createRequire(import.meta.url);
10
11let satoriFn: SatoriFn | null = null;
12let resvgInitialized = false;
13let Resvg: ResvgClass | null = null;
14
15export async function initSatori(): Promise<SatoriFn> {
16 if (satoriFn) return satoriFn;
17
18 const { default: satori } = await import("satori");
19 satoriFn = satori;
20
21 return satoriFn;
22}
23
24export async function initResvg(): Promise<ResvgClass> {
25 if (resvgInitialized) return Resvg!;
26
27 const { Resvg: ResvgClass, initWasm } = await import("@resvg/resvg-wasm");
28 const wasmPath = require.resolve("@resvg/resvg-wasm/index_bg.wasm");
29 const wasmBuffer = await readFile(wasmPath);
30 await initWasm(wasmBuffer);
31
32 Resvg = ResvgClass;
33 resvgInitialized = true;
34 return Resvg;
35}
36
37export async function loadFonts(): Promise<FontData[]> {
38 // In Bun, .woff imports return a Module object with `default` being the file path
39 const inter400Module = await import(
40 "@fontsource/inter/files/inter-latin-400-normal.woff"
41 );
42 const inter500Module = await import(
43 "@fontsource/inter/files/inter-latin-500-normal.woff"
44 );
45 const inter600Module = await import(
46 "@fontsource/inter/files/inter-latin-600-normal.woff"
47 );
48
49 const inter400Path = (inter400Module as { default: string }).default;
50 const inter500Path = (inter500Module as { default: string }).default;
51 const inter600Path = (inter600Module as { default: string }).default;
52
53 const [buf400, buf500, buf600] = await Promise.all([
54 readFile(inter400Path),
55 readFile(inter500Path),
56 readFile(inter600Path),
57 ]);
58
59 return [
60 {
61 name: "Inter",
62 data: buf400.buffer.slice(
63 buf400.byteOffset,
64 buf400.byteOffset + buf400.byteLength,
65 ),
66 weight: 400,
67 style: "normal",
68 },
69 {
70 name: "Inter",
71 data: buf500.buffer.slice(
72 buf500.byteOffset,
73 buf500.byteOffset + buf500.byteLength,
74 ),
75 weight: 500,
76 style: "normal",
77 },
78 {
79 name: "Inter",
80 data: buf600.buffer.slice(
81 buf600.byteOffset,
82 buf600.byteOffset + buf600.byteLength,
83 ),
84 weight: 600,
85 style: "normal",
86 },
87 ];
88}