clone

a self-hosted sync node for lofi apps: jazz sync over iroh, ticket-gated, with no static ip or cloud needed

feat/connection-observability
lofi-node / src / native / loader.ts
loader.ts 2.1K
1// Resolve the vendored iroh-js napi addon for this platform. Resolution2// order: explicit option → LOFI_NODE_IROH env → in-repo cargo build output →3// prebuilt/<triple>. Embedding artifacts into a compiled binary comes with4// packaging, later.56interface Triple {7 dir: string;8 cargoFile: string;9}1011const TRIPLES: Record<string, Triple> = {12 "darwin-aarch64": { dir: "aarch64-apple-darwin", cargoFile: "libnumber0_iroh.dylib" },13 "darwin-x86_64": { dir: "x86_64-apple-darwin", cargoFile: "libnumber0_iroh.dylib" },14 "linux-x86_64": { dir: "x86_64-unknown-linux-gnu", cargoFile: "libnumber0_iroh.so" },15 "linux-aarch64": { dir: "aarch64-unknown-linux-gnu", cargoFile: "libnumber0_iroh.so" },16 "windows-x86_64": { dir: "x86_64-pc-windows-gnu", cargoFile: "number0_iroh.dll" },17};1819export type IrohLibResolution =20 | { status: "ok"; path: string }21 | { status: "unsupported-platform"; platform: string }22 | { status: "not-found"; tried: string[] };2324function exists(path: string): boolean {25 try {26 return Deno.statSync(path).isFile;27 } catch {28 return false;29 }30}3132/** Repo-relative candidate, resolved through URL so `..` segments normalize —33 * the embedded vfs of a `deno compile` binary does not resolve them itself. */34function repoPath(rel: string): string {35 return new URL(`../../${rel}`, import.meta.url).pathname;36}3738export function resolveIrohLib(explicitPath?: string): IrohLibResolution {39 const platform = `${Deno.build.os}-${Deno.build.arch}`;40 const triple = TRIPLES[platform];41 if (!triple) return { status: "unsupported-platform", platform };4243 const tried: string[] = [];44 const candidates = [45 explicitPath,46 Deno.env.get("LOFI_NODE_IROH"),47 repoPath(`native/iroh-js/target/release/${triple.cargoFile}`),48 `./native/iroh-js/target/release/${triple.cargoFile}`,49 repoPath(`native/iroh-js/prebuilt/${triple.dir}/${triple.cargoFile}`),50 ];51 for (const candidate of candidates) {52 if (!candidate) continue;53 tried.push(candidate);54 if (exists(candidate)) return { status: "ok", path: candidate };55 }56 return { status: "not-found", tried };57}