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