import { env } from "cloudflare:workers";
import { CAPS } from "../limits";
import { forgetReachability } from "./reachable";
import type { RepoRow } from "~/lib/types";
/** Every KV namespace that caches a repository's objects or derived data, keyed by its Artifacts name. */
const PREFIXES = ["commit:", "tree:", "blob:", "diff:v2:", "compare:v1:", "path-log:v1:", "last-commit:v2:"];
/**
* Best-effort purge of a repository's cached objects after deletion or a visibility change (GIT-A13). Every
* read path re-checks permission before touching these keys, so this is hygiene rather than access control;
* the loop is bounded by `CAPS.cachePurgeKeys` and never throws into the caller.
*/
export async function purgeRepoCaches(repo: Pick<RepoRow, "id" | "artifacts_name">): Promise<void> {
await forgetReachability(repo.id);
let budget = CAPS.cachePurgeKeys;
for (const prefix of PREFIXES) {
let cursor: string | undefined;
while (budget > 0) {
const page = await env.KV.list({
prefix: `${prefix}${repo.artifacts_name}:`,
cursor,
limit: Math.min(budget, 1000),
});
for (const key of page.keys) await env.KV.delete(key.name);
budget -= page.keys.length;
if (page.list_complete) break;
cursor = page.cursor;
}
if (budget <= 0) break;
}
}