Skip to content

Commit ba9ae06

Browse files
authored
Don't compress formats that are already compressed (#258)
Closes #253
1 parent b8520cc commit ba9ae06

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

src/virtual-machine.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -537,6 +537,22 @@ class VirtualMachine extends EventEmitter {
537537
file.date = date;
538538
}
539539

540+
// Tell JSZip to only compress file formats where there will be a significant gain.
541+
const COMPRESSABLE_FORMATS = [
542+
'.json',
543+
'.svg',
544+
'.wav',
545+
'.ttf',
546+
'.otf'
547+
];
548+
for (const file of Object.values(zip.files)) {
549+
if (COMPRESSABLE_FORMATS.some(ext => file.name.endsWith(ext))) {
550+
file.options.compression = 'DEFLATE';
551+
} else {
552+
file.options.compression = 'STORE';
553+
}
554+
}
555+
540556
return zip;
541557
}
542558

@@ -546,9 +562,9 @@ class VirtualMachine extends EventEmitter {
546562
*/
547563
saveProjectSb3 (type) {
548564
return this._saveProjectZip().generateAsync({
565+
// Don't configure compression here. _saveProjectZip() will set it for each file.
549566
type: type || 'blob',
550-
mimeType: 'application/x.scratch.sb3',
551-
compression: 'DEFLATE'
567+
mimeType: 'application/x.scratch.sb3'
552568
});
553569
}
554570

117 KB
Binary file not shown.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const {test} = require('tap');
2+
const fs = require('fs');
3+
const path = require('path');
4+
const VM = require('../../src/virtual-machine');
5+
const makeTestStorage = require('../fixtures/make-test-storage');
6+
const JSZip = require('@turbowarp/jszip');
7+
8+
test('saveProjectSb3() per-file compression', t => {
9+
const vm = new VM();
10+
vm.attachStorage(makeTestStorage());
11+
const fixture = fs.readFileSync(path.join(__dirname, '../fixtures/tw-mixed-file-formats.sb3'));
12+
vm.loadProject(fixture)
13+
.then(() => vm.saveProjectSb3('arraybuffer'))
14+
.then(buffer => JSZip.loadAsync(buffer))
15+
.then(zip => {
16+
const isCompressed = pathInZip => {
17+
// note: uses JSZip private APIs, not very stable, but it should be okay...
18+
const file = zip.files[pathInZip];
19+
return file._data.compression.magic === '\x08\x00';
20+
};
21+
22+
t.ok(isCompressed('project.json'));
23+
t.ok(isCompressed('5cb46ddd903fc2c9976ff881df9273c9.wav'));
24+
t.ok(isCompressed('cd21514d0531fdffb22204e0ec5ed84a.svg'));
25+
26+
t.notOk(isCompressed('0b2e50ca4107ce57416e2ceb840a6347.jpg'));
27+
t.notOk(isCompressed('5c8826d846c06dddeb77590e8792fb7d.png'));
28+
29+
t.end();
30+
});
31+
});

0 commit comments

Comments
 (0)