From dca14900c4746153555d4c1b805324b1397a452a Mon Sep 17 00:00:00 2001 From: Honey Tyagi <78690656+HoneyTyagii@users.noreply.github.com> Date: Wed, 7 Oct 2026 21:16:44 +0530 Subject: [PATCH] perf(domain): batch canonical digest writes with bounded buffer --- src/domain/canonicalDigest.test.ts | 7 +++++++ src/domain/canonicalDigest.ts | 13 ++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/domain/canonicalDigest.test.ts b/src/domain/canonicalDigest.test.ts index 02a641905..51df94619 100644 --- a/src/domain/canonicalDigest.test.ts +++ b/src/domain/canonicalDigest.test.ts @@ -62,6 +62,13 @@ describe("incremental canonical digest", () => { expect(digestCanonicalValue(value)).toBe(legacyDigest(value)); }); + it("keeps digests identical when buffered parts cross flush boundaries", () => { + const manyKeys: Record = {}; + for (let i = 0; i < 2000; i += 1) manyKeys[`k${i}`] = i; + const value = { keys: manyKeys, tail: ["€", "😀", "x".repeat(9000)] }; + expect(digestCanonicalValue(value)).toBe(legacyDigest(value)); + }); + it("preserves canonicalize property access and toJSON cycle behavior", () => { const createAccessor = () => { let reads = 0; diff --git a/src/domain/canonicalDigest.ts b/src/domain/canonicalDigest.ts index c9f1c6260..3c4f9e3c6 100644 --- a/src/domain/canonicalDigest.ts +++ b/src/domain/canonicalDigest.ts @@ -6,8 +6,19 @@ export const digestCanonicalValue = ( context = "Comparison", ): string => { const hash = createHash("sha256"); - const encoded = emitCanonical(value, (part) => hash.update(part), new Set()); + // Batch small emitted parts to cut hash.update crossings. + // Flush cuts only at part boundaries, so the hashed byte stream is unchanged. + let buffered = ""; + const emit = (part: string): void => { + buffered += part; + if (buffered.length >= 8192) { + hash.update(buffered); + buffered = ""; + } + }; + const encoded = emitCanonical(value, emit, new Set()); if (!encoded) throw new TypeError(`${context} could not canonicalize data`); + if (buffered) hash.update(buffered); return hash.digest("hex"); };