226 lines · 9.3 KB
import { structuredPatch } from "diff";
import { env, waitUntil } from "cloudflare:workers";
import type { GitStore } from "./store";
import type { DiffResult, FileChange } from "~/lib/types";

const MAX_CONTENT_FILES = 300;
const MAX_BLOB_BYTES = 512 * 1024;
const BINARY_SNIFF_BYTES = 8000;
const BLOB_CONCURRENCY = 8;
const CONTEXT_LINES = 3;
const MAX_CACHED_PATCH_BYTES = 4 * 1024 * 1024;
const DIFF_CACHE_TTL_SECONDS = 60 * 60 * 24 * 7;
const DIFF_CACHE_VERSION = "v1";
const decoder = new TextDecoder();

type Entry = { name: string; mode: string; hash: string; type: ArtifactsTreeEntryType };

function joinPath(parent: string, name: string): string {
  return parent ? `${parent}/${name}` : name;
}

async function entriesOf(store: GitStore, sha: string | null): Promise<Map<string, Entry>> {
  if (!sha) return new Map();
  const entries = (await store.tree(sha)) ?? [];
  return new Map(entries.map((entry) => [entry.name, entry]));
}

async function collectAll(store: GitStore, entry: Entry, path: string, side: "old" | "new", out: FileChange[]) {
  if (entry.type !== "tree") {
    out.push({
      path,
      oldPath: null,
      status: side === "old" ? "deleted" : "added",
      oldSha: side === "old" ? entry.hash : null,
      newSha: side === "new" ? entry.hash : null,
      oldMode: side === "old" ? entry.mode : null,
      newMode: side === "new" ? entry.mode : null,
    });
    return;
  }