/ concept-collection / fastandaccurate
Sign in
concept-collection / fastandaccurate
fastandaccurate / src / cli / nodeFileIO.ts
41 lines · 1.4 KBBlameHistoryRaw
1// The node substitute for numbl's synchronous-XHR file I/O: websave and
2// webread shell out to curl (node has no synchronous fetch), with
3// responses cached under ~/.cache/fastandaccurate keyed by URL, so
4// repeated runs are offline. Used by the CLI and the node tests for
5// solvers that mip-install packages.
7import { execFileSync } from "node:child_process";
8import { createHash } from "node:crypto";
9import { existsSync, mkdirSync, readFileSync } from "node:fs";
10import { homedir } from "node:os";
11import { join } from "node:path";
12import { BrowserFileIOAdapter, type VirtualFileSystem } from "numbl";
14const cacheDir = join(homedir(), ".cache", "fastandaccurate");
16function curlCached(url: string): Buffer {
17 mkdirSync(cacheDir, { recursive: true });
18 const key = createHash("sha1").update(url).digest("hex").slice(0, 16);
19 const cached = join(cacheDir, key);
20 if (!existsSync(cached)) {
21 execFileSync("curl", ["-sfL", "-o", cached, url], { stdio: "inherit" });
22 }
23 return readFileSync(cached);
26export class NodeFileIOAdapter extends BrowserFileIOAdapter {
27 private nodeVfs: VirtualFileSystem;
28 constructor(vfs: VirtualFileSystem) {
29 super(vfs);
30 this.nodeVfs = vfs;
31 }
32 override websave(url: string, filename: string): void {
33 this.nodeVfs.writeFile(
34 this.nodeVfs.normalizePath(filename),
35 new Uint8Array(curlCached(url))
36 );
37 }
38 override webread(url: string): string {
39 return curlCached(url).toString("utf8");
40 }
moveopenescclose