Skip to content
File

Blob: src/worker/git/pack/build.ts

typescript34 lines
1import type { GitObjectType } from "@/worker/git/core";
2import { objTypeCode, encodeObjHeader, concatChunks } from "@/worker/git/core";
3import { asBufferSource, deflate } from "@/worker/common";
4 
5/**
6 * Builds a PACKv2 file from a list of thick objects (no deltas expected here).
7 * Shared between upload-pack assembly and DO hydration segment builder.
8 */
9export async function buildPackV2(
10 objs: { type: GitObjectType; payload: Uint8Array }[]
11): Promise<Uint8Array> {
12 // Header: 'PACK' + version (2) + number of objects (big-endian)
13 const hdr = new Uint8Array(12);
14 hdr.set(new TextEncoder().encode("PACK"), 0);
15 const dv = new DataView(hdr.buffer);
16 dv.setUint32(4, 2); // version 2
17 dv.setUint32(8, objs.length);
18 
19 const parts: Uint8Array[] = [hdr];
20 for (const o of objs) {
21 const typeCode = objTypeCode(o.type);
22 const head = encodeObjHeader(typeCode, o.payload.byteLength);
23 parts.push(head);
24 const comp = await deflate(o.payload);
25 parts.push(comp);
26 }
27 const body = concatChunks(parts);
28 const sha = new Uint8Array(await crypto.subtle.digest("SHA-1", asBufferSource(body)));
29 const out = new Uint8Array(body.length + 20);
30 out.set(body, 0);
31 out.set(sha, body.length);
32 return out;
33}