Something went wrong. Try again.
fork of prime agent with changes i want but are not upstreamable probqbly (and some fixes)
Something went wrong. Try again.
3.7 kB · 139 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140/** * Photon image processing wrapper. * * This module provides a unified interface to @silvia-odwyer/photon-node that works in: * 1. Node.js (development, npm run build) * 2. Bun compiled binaries (standalone distribution) * * The challenge: photon-node's CJS entry uses fs.readFileSync(__dirname + '/photon_rs_bg.wasm') * which bakes the build machine's absolute path into Bun compiled binaries. * * Solution: * 1. Patch fs.readFileSync to redirect missing photon_rs_bg.wasm reads * 2. Copy photon_rs_bg.wasm next to the executable in build:binary */
import type { PathOrFileDescriptor } from "fs";import { createRequire } from "module";import * as path from "path";import { fileURLToPath } from "url";
const require = createRequire(import.meta.url);const fs = require("fs") as typeof import("fs");
// Re-export types from the main packageexport type { PhotonImage as PhotonImageType } from "@silvia-odwyer/photon-node";
type ReadFileSync = typeof fs.readFileSync;
const WASM_FILENAME = "photon_rs_bg.wasm";
// Lazy-loaded photon modulelet photonModule: typeof import("@silvia-odwyer/photon-node") | null = null;let loadPromise: Promise<typeof import("@silvia-odwyer/photon-node") | null> | null = null;
function pathOrNull(file: PathOrFileDescriptor): string | null { if (typeof file === "string") { return file; } if (file instanceof URL) { return fileURLToPath(file); } return null;}
function getFallbackWasmPaths(): string[] { const execDir = path.dirname(process.execPath); return [ path.join(execDir, WASM_FILENAME), path.join(execDir, "photon", WASM_FILENAME), path.join(process.cwd(), WASM_FILENAME), ];}
function patchPhotonWasmRead(): () => void { const originalReadFileSync: ReadFileSync = fs.readFileSync.bind(fs); const fallbackPaths = getFallbackWasmPaths(); const mutableFs = fs as { readFileSync: ReadFileSync };
const patchedReadFileSync: ReadFileSync = ((...args: Parameters<ReadFileSync>) => { const [file, options] = args; const resolvedPath = pathOrNull(file);
if (resolvedPath?.endsWith(WASM_FILENAME)) { try { return originalReadFileSync(...args); } catch (error) { const err = error as NodeJS.ErrnoException; if (err?.code && err.code !== "ENOENT") { throw error; }
for (const fallbackPath of fallbackPaths) { if (!fs.existsSync(fallbackPath)) { continue; } if (options === undefined) { return originalReadFileSync(fallbackPath); } return originalReadFileSync(fallbackPath, options); }
throw error; } }
return originalReadFileSync(...args); }) as ReadFileSync;
try { mutableFs.readFileSync = patchedReadFileSync; } catch { Object.defineProperty(fs, "readFileSync", { value: patchedReadFileSync, writable: true, configurable: true, }); }
return () => { try { mutableFs.readFileSync = originalReadFileSync; } catch { Object.defineProperty(fs, "readFileSync", { value: originalReadFileSync, writable: true, configurable: true, }); } };}
/** * Load the photon module asynchronously. * Returns cached module on subsequent calls. */export async function loadPhoton(): Promise<typeof import("@silvia-odwyer/photon-node") | null> { if (photonModule) { return photonModule; }
if (loadPromise) { return loadPromise; }
loadPromise = (async () => { const restoreReadFileSync = patchPhotonWasmRead(); try { photonModule = await import("@silvia-odwyer/photon-node"); return photonModule; } catch { photonModule = null; return photonModule; } finally { restoreReadFileSync(); } })();
return loadPromise;}