alinea
Version:
Headless git-based CMS
48 lines (46 loc) • 1.77 kB
JavaScript
import "../../chunks/chunk-NZLE2WMY.js";
// src/core/source/FilePatch.ts
import { assert } from "../util/Assert.js";
import { applyGitDelta, createGitDelta } from "./GitDelta.js";
import { sha1Bytes as computeSha1Bytes } from "./Utils.js";
var encoder = new TextEncoder();
var decoder = new TextDecoder();
var HASH_BYTES = 20;
async function createFilePatch(base, updated) {
const baseBytes = encoder.encode(base);
const updatedBytes = encoder.encode(updated);
const delta = createGitDelta(baseBytes, updatedBytes);
const [baseHash, updatedHash] = await Promise.all([
computeSha1Bytes(baseBytes),
computeSha1Bytes(updatedBytes)
]);
const out = new Uint8Array(HASH_BYTES + delta.length + HASH_BYTES);
out.set(baseHash, 0);
out.set(delta, HASH_BYTES);
out.set(updatedHash, HASH_BYTES + delta.length);
return out;
}
async function applyFilePatch(base, patch) {
assert(patch.length >= HASH_BYTES * 2, "Invalid patch: too small");
const baseBytes = encoder.encode(base);
const expectedBaseHash = patch.subarray(0, HASH_BYTES);
const actualBaseHash = await computeSha1Bytes(baseBytes);
assert(bytesEqual(expectedBaseHash, actualBaseHash), "Patch does not match base");
const delta = patch.subarray(HASH_BYTES, patch.length - HASH_BYTES);
const result = applyGitDelta(baseBytes, delta);
const expectedHash = patch.subarray(patch.length - HASH_BYTES);
const actualHash = await computeSha1Bytes(result);
assert(bytesEqual(actualHash, expectedHash), "Patched content hash mismatch");
return decoder.decode(result);
}
function bytesEqual(a, b) {
if (a.length !== b.length) return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i]) return false;
}
return true;
}
export {
applyFilePatch,
createFilePatch
};