1import type { Database } from "bun:sqlite";2import { mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";3import { join } from "node:path";4import { filesAt, objectBytes } from "../mirror/queries.ts";5import { buildTarball } from "./tar.ts";67891011export function cachedTarball(12 tarballDir: string,13 db: Database,14 repo: string,15 saveId: string,16): Uint8Array<ArrayBuffer> {17 const path = join(tarballDir, repo, `${saveId}.tar.gz`);18 try {19 return readFileSync(path);20 } catch (error) {21 if ((error as NodeJS.ErrnoException).code !== "ENOENT") throw error;22 }23 const files = filesAt(db, saveId).map((file) => {24 const bytes = objectBytes(db, file.hash);25 if (!bytes) throw new Error(`${repo}: object ${file.hash} is missing from the mirror`);26 return { path: file.path, executable: file.executable, bytes };27 });28 const tarball = buildTarball(`${repo}-${saveId.slice(0, 8)}`, files);29 mkdirSync(join(tarballDir, repo), { recursive: true });30 writeFileSync(`${path}.tmp`, tarball);31 renameSync(`${path}.tmp`, path);32 return tarball;33}343536export function dropTarballs(tarballDir: string, repo: string, saveId: string): void {37 const target =38 saveId === "" ? join(tarballDir, repo) : join(tarballDir, repo, `${saveId}.tar.gz`);39 rmSync(target, { recursive: true, force: true });40}