import { toHex } from "../crypto";
import { inflateZlib } from "./inflate";
import type { GitObjectType } from "./objects";
const PACK_HEADER_BYTES = 12;
const OFS_DELTA = 6;
const REF_DELTA = 7;
const SHA_BYTES = 20;
const OFFSET_BYTES = 4;
const SIZE_BYTES = 3;
const TYPE_NAMES: Record<number, GitObjectType> = { 1: "commit", 2: "tree", 3: "blob", 4: "tag" };
const encoder = new TextEncoder();
export type PackObject = { type: GitObjectType; sha: string; content: Uint8Array };
/** A delta whose base lives outside the pack (thin pack); only its inserted literals are known. */
export type UnresolvedDelta = { baseSha: string; inserted: Uint8Array[]; delta: Uint8Array };
export type PackLimits = { maxObjects: number; maxObjectBytes: number; maxTotalBytes: number };
export type ParsedPack = { objects: PackObject[]; unresolved: UnresolvedDelta[]; truncated: boolean };
type Raw = { offset: number; type: number; data: Uint8Array; baseOffset?: number; baseSha?: string };
async function objectSha(type: GitObjectType, content: Uint8Array): Promise<string> {
const header = encoder.encode(`${type} ${content.byteLength}\0`);
const bytes = new Uint8Array(header.byteLength + content.byteLength);
bytes.set(header);
bytes.set(content, header.byteLength);
return toHex(await crypto.subtle.digest("SHA-1", bytes));
}
function readVarint(data: Uint8Array, start: number): { value: number; next: number } {
let value = 0;
let shift = 0;
let position = start;
let byte: number;
do {
byte = data[position++];
value += (byte & 0x7f) * 2 ** shift;