Skip to content

Commit b39d59b

Browse files
committed
optimise diff zip
1 parent 8c24522 commit b39d59b

6 files changed

Lines changed: 69 additions & 15 deletions

File tree

bun.lock

Lines changed: 5 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"fs-extra": "8",
6464
"global-dirs": "^4.0.0",
6565
"gradle-to-js": "^2.0.1",
66-
"i18next": "^24.2.3",
66+
"i18next": "^26.0.4",
6767
"isomorphic-git": "^1.37.5",
6868
"isomorphic-unzip": "^1.1.5",
6969
"node-fetch": "^2.6.1",
@@ -75,7 +75,7 @@
7575
"registry-auth-token": "^5.1.1",
7676
"semver": "^7.7.4",
7777
"tcp-ping": "^0.1.1",
78-
"tty-table": "4.2",
78+
"tty-table": "5.0",
7979
"yauzl": "^3.3.0",
8080
"yazl": "3.3.1"
8181
},

src/diff.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,11 @@ async function diffFromPPK(
203203
}
204204

205205
//console.log({copies, deletes});
206+
const diffManifest = Buffer.from(JSON.stringify({ copies, deletes }));
206207
zipfile.addBuffer(
207-
Buffer.from(JSON.stringify({ copies, deletes })),
208+
diffManifest,
208209
'__diff.json',
209-
zipOptionsForManifestEntry(),
210+
zipOptionsForManifestEntry(diffManifest.length),
210211
);
211212
zipfile.end();
212213
await writePromise;
@@ -317,10 +318,11 @@ async function diffFromPackage(
317318
}
318319
});
319320

321+
const diffManifest = Buffer.from(JSON.stringify({ copies }));
320322
zipfile.addBuffer(
321-
Buffer.from(JSON.stringify({ copies })),
323+
diffManifest,
322324
'__diff.json',
323-
zipOptionsForManifestEntry(),
325+
zipOptionsForManifestEntry(diffManifest.length),
324326
);
325327
zipfile.end();
326328
await writePromise;

src/utils/zip-options.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export type ZipEntryOptions = {
77
};
88

99
export const ZIP_ENTRY_SNIFF_BYTES = 64;
10+
export const MANIFEST_COMPRESSION_THRESHOLD_BYTES = 256;
1011

1112
const alreadyCompressedExtensions = new Set([
1213
'.7z',
@@ -136,7 +137,10 @@ export function zipOptionsForPatchEntry(): ZipEntryOptions {
136137
return { compress: false };
137138
}
138139

139-
export function zipOptionsForManifestEntry(): ZipEntryOptions {
140+
export function zipOptionsForManifestEntry(byteLength = 0): ZipEntryOptions {
141+
if (byteLength >= MANIFEST_COMPRESSION_THRESHOLD_BYTES) {
142+
return { compressionLevel: 9 };
143+
}
140144
return { compress: false };
141145
}
142146

tests/diff.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,46 @@ describe('diff commands', () => {
184184
expect(diffMeta.deletes['old-only.txt']).toBe(1);
185185
});
186186

187+
test('diff compresses large manifest entries', async () => {
188+
const originPath = path.join(tempRoot, 'origin-large-manifest.ppk');
189+
const nextPath = path.join(tempRoot, 'next-large-manifest.ppk');
190+
const outputPath = path.join(tempRoot, 'out', 'large-manifest-diff.ppk');
191+
const originEntries: Record<string, string | Buffer> = {
192+
'index.bundlejs': 'old-bundle',
193+
};
194+
const nextEntries: Record<string, string | Buffer> = {
195+
'index.bundlejs': 'new-bundle',
196+
};
197+
198+
for (let i = 0; i < 24; i++) {
199+
const content = `same-content-${i}`;
200+
originEntries[`assets/old/path/asset-${i}.txt`] = content;
201+
nextEntries[`assets/new/path/renamed-asset-${i}.txt`] = content;
202+
}
203+
204+
await createZip(originPath, originEntries);
205+
await createZip(nextPath, nextEntries);
206+
207+
await diffCommands.diff(
208+
createContext([originPath, nextPath], {
209+
output: outputPath,
210+
customDiff: () => Buffer.from('patch'),
211+
}),
212+
);
213+
214+
const result = await readZipContent(outputPath);
215+
expect(result.compressionMethods['__diff.json']).toBe(8);
216+
217+
const diffMeta = JSON.parse(
218+
result.files['__diff.json'].toString('utf-8'),
219+
) as {
220+
copies: Record<string, string>;
221+
};
222+
expect(diffMeta.copies['assets/new/path/renamed-asset-0.txt']).toBe(
223+
'assets/old/path/asset-0.txt',
224+
);
225+
});
226+
187227
test('diff throws when origin bundle file is missing', async () => {
188228
const originPath = path.join(tempRoot, 'origin-no-bundle.ppk');
189229
const nextPath = path.join(tempRoot, 'next.ppk');

tests/utils.test.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from 'bun:test';
1010
import { translateOptions } from '../src/utils';
1111
import {
12+
MANIFEST_COMPRESSION_THRESHOLD_BYTES,
1213
zipOptionsForManifestEntry,
1314
zipOptionsForPatchEntry,
1415
zipOptionsForPayloadEntry,
@@ -82,8 +83,17 @@ describe('zipOptionsForPatchEntry', () => {
8283
});
8384

8485
describe('zipOptionsForManifestEntry', () => {
85-
test('returns compress false', () => {
86+
test('stores small manifests', () => {
8687
expect(zipOptionsForManifestEntry()).toEqual({ compress: false });
88+
expect(
89+
zipOptionsForManifestEntry(MANIFEST_COMPRESSION_THRESHOLD_BYTES - 1),
90+
).toEqual({ compress: false });
91+
});
92+
93+
test('compresses manifests at threshold', () => {
94+
expect(
95+
zipOptionsForManifestEntry(MANIFEST_COMPRESSION_THRESHOLD_BYTES),
96+
).toEqual({ compressionLevel: 9 });
8797
});
8898
});
8999

0 commit comments

Comments
 (0)