@zip.js/zip.js 2.11.0 → 2.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BENCHMARKS.md +127 -60
- package/deno.json +1 -1
- package/dist/zip-core-external.js +22 -19
- package/dist/zip-core-external.min.js +1 -1
- package/dist/zip-core.js +12 -6
- package/dist/zip-core.min.js +1 -1
- package/dist/zip-fs-core-external.js +22 -19
- package/dist/zip-fs-core-external.min.js +1 -1
- package/dist/zip-fs-core.js +12 -6
- package/dist/zip-fs-core.min.js +1 -1
- package/dist/zip-fs-external.js +22 -19
- package/dist/zip-fs-external.min.js +1 -1
- package/dist/zip-fs-native.js +12 -6
- package/dist/zip-fs-native.min.js +1 -1
- package/dist/zip-fs.js +25 -22
- package/dist/zip-fs.min.js +1 -1
- package/dist/zip-legacy.js +12 -6
- package/dist/zip-legacy.min.js +1 -1
- package/dist/zip-module.wasm +0 -0
- package/dist/zip-native.js +12 -6
- package/dist/zip-native.min.js +1 -1
- package/dist/zip-web-worker.js +1 -1
- package/dist/zip.js +25 -22
- package/dist/zip.min.js +1 -1
- package/eslint.config.mjs +1 -1
- package/index-native.cjs +12 -6
- package/index-native.min.js +1 -1
- package/index.cjs +25 -22
- package/index.d.cts +3 -4
- package/index.d.ts +3 -4
- package/index.min.js +1 -1
- package/lib/core/io.js +2 -3
- package/lib/core/streams/zlib-wasm/zlib-streams.js +10 -13
- package/lib/core/streams/zlib-wasm/zlib-streams.wasm +0 -0
- package/lib/core/version.js +1 -1
- package/lib/core/web-worker-inline-wasm.js +1 -1
- package/lib/core/zip-writer.js +13 -2
- package/lib/core/zlib-streams-inline.js +1 -1
- package/package.json +4 -2
package/BENCHMARKS.md
CHANGED
|
@@ -15,8 +15,10 @@ should not trust anyone's benchmark (including this one) without reproducing it.
|
|
|
15
15
|
> **without spawning a single Web Worker** — it lets the platform's native
|
|
16
16
|
> `CompressionStream` run on the threadpool while you simply issue concurrent `add()`
|
|
17
17
|
> calls. It also streams arbitrarily large files at a flat, low memory ceiling. For
|
|
18
|
-
>
|
|
19
|
-
>
|
|
18
|
+
> archives made of thousands of tiny entries, **fflate** is several times faster and much
|
|
19
|
+
> lighter — but that gap is zip.js's per-entry orchestration, not its codec: measured on
|
|
20
|
+
> their own, the codecs are the other way round (see [Codecs](#codecs-compared-at-equal-output-size)).
|
|
21
|
+
> Against native tooling, zip.js on a modern runtime is a bit
|
|
20
22
|
> faster *and* tighter than 7-Zip's fast mode on single-file streaming; 7-Zip keeps a
|
|
21
23
|
> real edge only on thousands of tiny files.
|
|
22
24
|
|
|
@@ -25,12 +27,13 @@ should not trust anyone's benchmark (including this one) without reproducing it.
|
|
|
25
27
|
| | |
|
|
26
28
|
|---|---|
|
|
27
29
|
| Machine | Apple M2, 8 cores (4 performance + 4 efficiency), 16 GB RAM |
|
|
28
|
-
| OS | macOS 26.
|
|
29
|
-
| Runtime | Node.js
|
|
30
|
-
| zip.js | 2.
|
|
30
|
+
| OS | macOS 26.6.2 (arm64) |
|
|
31
|
+
| Runtime | Node.js v26.7.0 |
|
|
32
|
+
| zip.js | 2.11.2 |
|
|
31
33
|
| jszip | 3.10.1 |
|
|
32
34
|
| fflate | 0.8.3 |
|
|
33
35
|
| archiver | 8.0.0 |
|
|
36
|
+
| Measured | 2026-09-06, except the 7-Zip section (see its own note) |
|
|
34
37
|
|
|
35
38
|
## Method
|
|
36
39
|
|
|
@@ -40,11 +43,15 @@ should not trust anyone's benchmark (including this one) without reproducing it.
|
|
|
40
43
|
- **Timing.** `performance.now()` around the measured operation only. Every combination
|
|
41
44
|
runs **3 times**; the table reports the **median**.
|
|
42
45
|
- **Memory.** Peak resident set size (RSS) reported by `/usr/bin/time -l`. The "peak"
|
|
43
|
-
column is the delta over an empty-process baseline (~
|
|
44
|
-
attributable to the work.
|
|
45
|
-
- **Fair work.** All libraries compress at **DEFLATE level 6
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
column is the delta over an empty-process baseline (~50 MB on this runtime), i.e. the
|
|
47
|
+
memory attributable to the work.
|
|
48
|
+
- **Fair work.** All libraries compress at **DEFLATE level 6**, and output sizes are shown
|
|
49
|
+
next to the times. Read them: a "level" is not a unit shared between libraries. zlib's
|
|
50
|
+
level 6 and fflate's level 6 are different parameter sets, so the two do not produce the
|
|
51
|
+
same amount of compression and a time is only comparable next to the size it achieved.
|
|
52
|
+
The [Codecs](#codecs-compared-at-equal-output-size) section compares them by output size
|
|
53
|
+
instead, which is the only axis on which "faster" means anything. The corpus is generated
|
|
54
|
+
from a seeded PRNG, so every library sees byte-for-byte identical input.
|
|
48
55
|
- **zip.js modes.** zip.js is measured both **single-threaded** (apples-to-apples with
|
|
49
56
|
the single-threaded libraries) and with its **Web Worker** pool, so the worker
|
|
50
57
|
overhead is never hidden.
|
|
@@ -54,26 +61,31 @@ should not trust anyone's benchmark (including this one) without reproducing it.
|
|
|
54
61
|
Level-6 DEFLATE, one entry (or one batch) compressed in the main thread. This is the
|
|
55
62
|
apples-to-apples comparison against the single-threaded libraries.
|
|
56
63
|
|
|
64
|
+
Time, with the size each library produced — the two are only meaningful together.
|
|
65
|
+
|
|
57
66
|
| Workload | @zip.js/zip.js | jszip | fflate | archiver |
|
|
58
67
|
|---|--:|--:|--:|--:|
|
|
59
|
-
| Compressible text (20 MB) |
|
|
60
|
-
| Incompressible data (20 MB) |
|
|
61
|
-
| Already-compressed media (20 MB) |
|
|
62
|
-
| 5,000 files × ~2 KB |
|
|
68
|
+
| Compressible text (20 MB) | 703 ms / 6.1 MB | 1714 ms / 6.2 MB | 908 ms / 6.3 MB | **702 ms** / 6.1 MB |
|
|
69
|
+
| Incompressible data (20 MB) | 364 ms / 21.0 MB | 858 ms / 21.0 MB | **298 ms** / 21.0 MB | 357 ms / 21.0 MB |
|
|
70
|
+
| Already-compressed media (20 MB) | 362 ms / 21.0 MB | 860 ms / 21.0 MB | **297 ms** / 21.0 MB | 356 ms / 21.0 MB |
|
|
71
|
+
| 5,000 files × ~2 KB | 834 ms / 4.9 MB | 826 ms / 4.7 MB | **305 ms** / 4.8 MB | 431 ms / 4.8 MB |
|
|
63
72
|
|
|
64
73
|
Peak memory for the same runs (Δ over baseline):
|
|
65
74
|
|
|
66
75
|
| Workload | @zip.js/zip.js | jszip | fflate | archiver |
|
|
67
76
|
|---|--:|--:|--:|--:|
|
|
68
|
-
| Compressible text (20 MB) |
|
|
69
|
-
| Incompressible data (20 MB) |
|
|
70
|
-
| Already-compressed media (20 MB) |
|
|
71
|
-
| 5,000 files × ~2 KB |
|
|
72
|
-
|
|
73
|
-
zip.js
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
| Compressible text (20 MB) | 90 MB | 69 MB | **62 MB** | 72 MB |
|
|
78
|
+
| Incompressible data (20 MB) | 153 MB | 92 MB | 108 MB | **81 MB** |
|
|
79
|
+
| Already-compressed media (20 MB) | 154 MB | 93 MB | 108 MB | **74 MB** |
|
|
80
|
+
| 5,000 files × ~2 KB | 252 MB | 267 MB | **102 MB** | 137 MB |
|
|
81
|
+
|
|
82
|
+
On compressible text zip.js and archiver are tied (703 ms against 702 ms, inside the
|
|
83
|
+
noise) and both produce the smallest archive; fflate is 29 % slower here *and* 3 % larger,
|
|
84
|
+
which is the level-6-is-not-a-unit effect described above. On incompressible data — where
|
|
85
|
+
no codec has anything to do — fflate wins on both axes. On 5,000 tiny files fflate is 2.7×
|
|
86
|
+
faster than zip.js and uses a third of the memory; that gap is per-entry orchestration
|
|
87
|
+
(worker round trips, header writes, one stream per entry), not codec speed, as the
|
|
88
|
+
[Codecs](#codecs-compared-at-equal-output-size) section shows.
|
|
77
89
|
|
|
78
90
|
## Parallelism & codec backends — 8 files × 8 MB, single process
|
|
79
91
|
|
|
@@ -82,26 +94,29 @@ in a **plain Node process** (no worker threads unless noted). zip.js can select
|
|
|
82
94
|
codec backend at runtime — native `CompressionStream`, the bundled WebAssembly zlib, or
|
|
83
95
|
a pure-JavaScript zlib port — and it can issue `add()` calls concurrently.
|
|
84
96
|
|
|
85
|
-
| Configuration | Median time | vs jszip |
|
|
86
|
-
|
|
87
|
-
| **zip.js — `CompressionStream`, concurrent `add()`** | **
|
|
88
|
-
| fflate — async (its own worker pool) |
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
| fflate — `zipSync` (single thread) |
|
|
92
|
-
| zip.js — WASM zlib |
|
|
93
|
-
| zip.js — pure-JS zlib |
|
|
94
|
-
| jszip (pako, single thread) |
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
| Configuration | Median time | Output | vs jszip |
|
|
98
|
+
|---|--:|--:|--:|
|
|
99
|
+
| **zip.js — `CompressionStream`, concurrent `add()`** | **607 ms** | 19.6 MB | **9.3×** |
|
|
100
|
+
| fflate — async (its own worker pool) | 733 ms | 20.0 MB | 7.7× |
|
|
101
|
+
| zip.js — `CompressionStream`, sequential | 2214 ms | 19.6 MB | 2.6× |
|
|
102
|
+
| archiver — Node zlib (libuv threadpool) | 2278 ms | 19.6 MB | 2.5× |
|
|
103
|
+
| fflate — `zipSync` (single thread) | 3118 ms | 20.0 MB | 1.8× |
|
|
104
|
+
| zip.js — WASM zlib | 3358 ms | 19.7 MB | 1.7× |
|
|
105
|
+
| zip.js — pure-JS zlib | 3840 ms | 19.7 MB | 1.5× |
|
|
106
|
+
| jszip (pako, single thread) | 5671 ms | 19.7 MB | 1.0× |
|
|
107
|
+
|
|
108
|
+
The two fflate rows produce 20.0 MB where every other row produces 19.6–19.7 MB, i.e. ~2 %
|
|
109
|
+
more, so they are not doing quite the same work as the rows above and below them.
|
|
110
|
+
|
|
111
|
+
**The point:** zip.js with the native `CompressionStream` goes from **2214 ms
|
|
112
|
+
sequential to 607 ms with concurrent `add()` — a 3.6× speedup — using no Web Workers at
|
|
98
113
|
all.** The native codec runs on the platform's threadpool, so independent entries
|
|
99
114
|
compress on multiple cores while your code stays on the main thread. That makes it the
|
|
100
|
-
fastest configuration measured,
|
|
115
|
+
fastest configuration measured, ahead of fflate's dedicated worker pool.
|
|
101
116
|
|
|
102
117
|
One honest caveat, visible in the table: **only the native `CompressionStream` backend
|
|
103
118
|
parallelizes this way.** The WASM and pure-JS backends run synchronously on the main
|
|
104
|
-
thread, so concurrent `add()` does not speed them up (
|
|
119
|
+
thread, so concurrent `add()` does not speed them up (3358 ms and 3840 ms whether
|
|
105
120
|
sequential or "parallel"). Use those backends when a native `CompressionStream` is
|
|
106
121
|
unavailable or when you need byte-identical zlib output; use the native backend when you
|
|
107
122
|
want this parallelism.
|
|
@@ -141,6 +156,50 @@ Safari/WebKit, also set `useWebWorkers: true`. Web Workers are the portable way
|
|
|
141
156
|
this parallelism on any runtime — and the only way once you use a non-default level
|
|
142
157
|
(which switches to the WASM codec).
|
|
143
158
|
|
|
159
|
+
## Codecs, compared at equal output size
|
|
160
|
+
|
|
161
|
+
The tables above compare *libraries* — a whole zip pipeline, at each library's default
|
|
162
|
+
"level 6". This one compares only the **codecs**, on the same 20 MB buffer with no zip
|
|
163
|
+
container around them, and sorts by output size rather than by level. That matters because
|
|
164
|
+
zlib's level 6 and fflate's level 6 are different parameter sets: matched by level, the
|
|
165
|
+
comparison silently reads a ratio difference as a speed difference.
|
|
166
|
+
|
|
167
|
+
`frontier` marks a row that nothing smaller beats on time.
|
|
168
|
+
|
|
169
|
+
| Codec | Setting | Output | Ratio | Time | Throughput | |
|
|
170
|
+
|---|---|--:|--:|--:|--:|---|
|
|
171
|
+
| WASM zlib | level 8 | 6,115,980 | 3.429 | 1466 ms | 13.6 MB/s | frontier |
|
|
172
|
+
| `CompressionStream` | no level control | 6,120,503 | 3.426 | 692 ms | 28.9 MB/s | frontier |
|
|
173
|
+
| WASM zlib | level 6 | 6,165,103 | 3.402 | 1023 ms | 19.5 MB/s | |
|
|
174
|
+
| fflate | level 8 — its best | 6,239,025 | 3.361 | 750 ms | 26.7 MB/s | |
|
|
175
|
+
| fflate | level 6 | 6,257,881 | 3.351 | 738 ms | 27.1 MB/s | |
|
|
176
|
+
| WASM zlib | level 5 | 6,562,182 | 3.196 | 494 ms | 40.5 MB/s | frontier |
|
|
177
|
+
| fflate | level 5 | 6,648,574 | 3.154 | 534 ms | 37.4 MB/s | |
|
|
178
|
+
| WASM zlib | level 4 | 6,907,987 | 3.036 | 276 ms | 72.4 MB/s | frontier |
|
|
179
|
+
| fflate | level 1 | 7,261,700 | 2.888 | 316 ms | 63.3 MB/s | |
|
|
180
|
+
| WASM zlib | level 1 | 7,531,042 | 2.785 | 177 ms | 113.1 MB/s | frontier |
|
|
181
|
+
|
|
182
|
+
The pure-JS port produces byte-identical output to the WASM codec at every level and is
|
|
183
|
+
1.2–2× slower; the full 28-row table is in `benchmarks/results/codecs-results.json`.
|
|
184
|
+
|
|
185
|
+
Two things to take from it. **fflate never lands on the frontier here** — at every size it
|
|
186
|
+
reaches, one of zip.js's codecs gets there sooner — and above ratio 3.361 it has no setting
|
|
187
|
+
at all, while the WASM codec keeps going to 3.429. Second, the level numbers really are
|
|
188
|
+
incomparable: fflate's level 6 falls between zlib's levels 5 and 6 on ratio, which is
|
|
189
|
+
exactly why the library tables above show it as both faster *and* larger.
|
|
190
|
+
|
|
191
|
+
Decompression of the same stream:
|
|
192
|
+
|
|
193
|
+
| Codec | Time | Throughput |
|
|
194
|
+
|---|--:|--:|
|
|
195
|
+
| WASM zlib | **46 ms** | 434.7 MB/s |
|
|
196
|
+
| `DecompressionStream` | 56 ms | 354.6 MB/s |
|
|
197
|
+
| pure-JS zlib | 110 ms | 181.5 MB/s |
|
|
198
|
+
| fflate | 123 ms | 162.7 MB/s |
|
|
199
|
+
|
|
200
|
+
The WASM inflate is 2.7× faster than fflate's, and faster than Node's own
|
|
201
|
+
`DecompressionStream`, since the Chromium `inffast_chunk` port landed in 2.11.0.
|
|
202
|
+
|
|
144
203
|
## Decompression
|
|
145
204
|
|
|
146
205
|
Level-6 archives, read back and fully materialized. archiver has no unzip API, so it is
|
|
@@ -148,8 +207,8 @@ excluded.
|
|
|
148
207
|
|
|
149
208
|
| Workload | @zip.js/zip.js | jszip | fflate |
|
|
150
209
|
|---|--:|--:|--:|
|
|
151
|
-
| Compressible text (20 MB) | **
|
|
152
|
-
| 5,000 files × ~2 KB |
|
|
210
|
+
| Compressible text (20 MB) | **66 ms** | 133 ms | 117 ms |
|
|
211
|
+
| 5,000 files × ~2 KB | 603 ms | 445 ms | **104 ms** |
|
|
153
212
|
|
|
154
213
|
zip.js has the fastest large-stream decompression. On thousands of tiny entries the
|
|
155
214
|
per-entry setup cost dominates and **fflate is dramatically faster and lighter** — again
|
|
@@ -160,17 +219,17 @@ the right tool when you are unpacking many small files.
|
|
|
160
219
|
The input is streamed from disk and the archive is streamed back to disk; neither is
|
|
161
220
|
ever fully held in memory (for the libraries that support it).
|
|
162
221
|
|
|
163
|
-
| Library | Median time | Peak memory |
|
|
164
|
-
|
|
165
|
-
|
|
|
166
|
-
|
|
|
167
|
-
| zip.js (1 thread) |
|
|
168
|
-
| fflate |
|
|
169
|
-
| jszip |
|
|
170
|
-
|
|
171
|
-
zip.js, fflate and archiver all hold memory **flat** while streaming — zip.js peaks
|
|
172
|
-
|
|
173
|
-
compression pipeline. **jszip buffers the entire file** and needs ~
|
|
222
|
+
| Library | Median time | Peak memory (Δ) | Output |
|
|
223
|
+
|---|--:|--:|--:|
|
|
224
|
+
| zip.js (workers) | **8888 ms** | 60 MB | 78.3 MB |
|
|
225
|
+
| archiver | 9150 ms | 71 MB | 78.3 MB |
|
|
226
|
+
| zip.js (1 thread) | 9296 ms | 62 MB | 78.3 MB |
|
|
227
|
+
| fflate | 12549 ms | **43 MB** | 80.2 MB |
|
|
228
|
+
| jszip | 22014 ms | 484 MB | 78.9 MB |
|
|
229
|
+
|
|
230
|
+
zip.js, fflate and archiver all hold memory **flat** while streaming — zip.js peaks ~60 MB
|
|
231
|
+
over baseline regardless of the 256 MB input, thanks to real backpressure through the
|
|
232
|
+
compression pipeline. **jszip buffers the entire file** and needs ~484 MB, at more than
|
|
174
233
|
twice the wall-clock time. If you process files that do not fit comfortably in memory,
|
|
175
234
|
avoid jszip.
|
|
176
235
|
|
|
@@ -179,7 +238,10 @@ avoid jszip.
|
|
|
179
238
|
How far is zip.js from a native archiver? [`benchmarks/bench-7z.js`](benchmarks/bench-7z.js)
|
|
180
239
|
compares it against the `7zz` CLI (7-Zip 25.01), disk-to-disk on both sides, under Deno
|
|
181
240
|
2.9.3 and Bun 1.3.14 (both runtimes agree within noise; Deno numbers shown). 7-Zip
|
|
182
|
-
timings include process spawn (~ms).
|
|
241
|
+
timings include process spawn (~ms). Unlike the tables above, this section and the next
|
|
242
|
+
were measured in July 2026 with zip.js 2.8.29 and have not been re-run; they compare
|
|
243
|
+
zip.js against tools that have not changed, so they age slowly, but treat the zip.js
|
|
244
|
+
columns as a floor rather than as current.
|
|
183
245
|
|
|
184
246
|
One comparison is impossible to make perfectly fair: **no 7-Zip preset runs zlib's
|
|
185
247
|
algorithm.** `-mx=5+` is a near-optimal parser (much slower, smaller output) and
|
|
@@ -225,7 +287,6 @@ file, one thread, level-6-class output everywhere:
|
|
|
225
287
|
| zlib-ng — Deno & Bun `CompressionStream` | **4.8–5.1 s** | 79.4 MB |
|
|
226
288
|
| Chromium zlib — Node `CompressionStream` / `node:zlib` | 8.9 s | 78.3 MB |
|
|
227
289
|
| classic zlib — Apple `gzip -6` | 12.5 s | 78.9 MB |
|
|
228
|
-
| classic zlib compiled to WASM — zip.js `useCompressionStream: false` | ~16 s | 78.9 MB |
|
|
229
290
|
| (reference) 7-Zip `-mx=6` | 33.5 s | 73.6 MB |
|
|
230
291
|
|
|
231
292
|
Verified in the runtimes' sources: Deno builds `flate2` with vendored
|
|
@@ -239,11 +300,13 @@ Consequences worth knowing:
|
|
|
239
300
|
- **The same zip.js code runs ~1.75× faster on Deno/Bun than on Node** for bulk
|
|
240
301
|
compression. A "zip.js is fast/slow" measurement is often really a statement about
|
|
241
302
|
the host's zlib — and the Node tables above are the *pessimistic* end.
|
|
242
|
-
- **The WASM backend is
|
|
243
|
-
WebAssembly overhead
|
|
244
|
-
|
|
245
|
-
against
|
|
246
|
-
(
|
|
303
|
+
- **The WASM backend is a fallback, but a much closer one since 2.11.0.** It used to be
|
|
304
|
+
classic zlib plus WebAssembly overhead, ~3× slower than native on compress. It now
|
|
305
|
+
carries Chromium's zlib: on the codec table above it deflates at level 6 in 1023 ms
|
|
306
|
+
against the native `CompressionStream`'s 692 ms — 1.5× slower for 0.7 % more bytes — and
|
|
307
|
+
it *inflates faster* than the native `DecompressionStream` (46 ms against 56 ms). Reach
|
|
308
|
+
for it when no native `CompressionStream` exists, when you need a specific level, or
|
|
309
|
+
when you need output that does not vary with the host's zlib.
|
|
247
310
|
- Output sizes across the zlib family are interchangeable (78–79 MB): it is one
|
|
248
311
|
algorithm at four levels of implementation tuning. zip.js inherits whichever the
|
|
249
312
|
host provides — including future upgrades, for free.
|
|
@@ -255,8 +318,11 @@ Consequences worth knowing:
|
|
|
255
318
|
low-memory streaming of huge files, and the broadest ZIP feature set in one library —
|
|
256
319
|
AES & ZipCrypto encryption, Zip64, split/multi-volume archives, and an optional Web
|
|
257
320
|
Worker pool.
|
|
258
|
-
- **Choose fflate**
|
|
259
|
-
|
|
321
|
+
- **Choose fflate** for archives of thousands of tiny entries, and when you want the
|
|
322
|
+
smallest memory footprint and the smallest bundle. Note what it does *not* buy you: at
|
|
323
|
+
equal output size its codec is not the fastest one here (see
|
|
324
|
+
[Codecs](#codecs-compared-at-equal-output-size)), so the win is fflate's very low
|
|
325
|
+
per-entry cost, not its deflate.
|
|
260
326
|
- **archiver** is a solid streaming compressor on Node but cannot read archives.
|
|
261
327
|
- **jszip** is convenient but the slowest here and buffers whole files in memory.
|
|
262
328
|
|
|
@@ -271,6 +337,7 @@ npm install # jszip, fflate, archiver (zip.js is used from the repo)
|
|
|
271
337
|
npm run corpus # generate the deterministic datasets under .corpus/
|
|
272
338
|
node bench.js # the head-to-head tables (compress / decompress / disk streaming)
|
|
273
339
|
node bench-backends.js # the parallelism & codec-backend matrix
|
|
340
|
+
node bench-codecs.js # the codecs alone, sorted by output size
|
|
274
341
|
deno run -A bench-7z.js # zip.js vs the 7zz CLI (also: bun bench-7z.js)
|
|
275
342
|
```
|
|
276
343
|
|
package/deno.json
CHANGED
|
@@ -3639,11 +3639,10 @@ class Reader extends Stream {
|
|
|
3639
3639
|
const data = await readUint8Array(reader, offset + chunkOffset, dataSize);
|
|
3640
3640
|
if (data.length) {
|
|
3641
3641
|
controller.enqueue(data);
|
|
3642
|
+
chunkOffset += data.length;
|
|
3642
3643
|
}
|
|
3643
|
-
if ((
|
|
3644
|
+
if ((size !== UNDEFINED_VALUE && chunkOffset >= size) || (!data.length && dataSize)) {
|
|
3644
3645
|
controller.close();
|
|
3645
|
-
} else {
|
|
3646
|
-
chunkOffset += chunkSize;
|
|
3647
3646
|
}
|
|
3648
3647
|
}
|
|
3649
3648
|
});
|
|
@@ -6334,6 +6333,7 @@ class ZipWriter {
|
|
|
6334
6333
|
pendingAddFileCalls: new Set(),
|
|
6335
6334
|
pendingErrors: [],
|
|
6336
6335
|
bufferedWrites: 0,
|
|
6336
|
+
directWrites: 0,
|
|
6337
6337
|
lastFileEntry: UNDEFINED_VALUE
|
|
6338
6338
|
});
|
|
6339
6339
|
}
|
|
@@ -7109,6 +7109,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
7109
7109
|
const usdz = zipWriter.options[OPTION_USDZ];
|
|
7110
7110
|
let fileEntry = pendingFileEntry;
|
|
7111
7111
|
let bufferedWrite;
|
|
7112
|
+
let directWrite;
|
|
7112
7113
|
let releaseLockWriter;
|
|
7113
7114
|
let writingBufferedEntryData;
|
|
7114
7115
|
let writingEntryData;
|
|
@@ -7118,7 +7119,7 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
7118
7119
|
const lockPreviousFileEntry = keepOrder && previousFileEntry ? previousFileEntry.lockFileEntry : UNDEFINED_VALUE;
|
|
7119
7120
|
fileEntries.set(name, fileEntry);
|
|
7120
7121
|
try {
|
|
7121
|
-
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || (!dataDescriptor && !emptyEntry)) {
|
|
7122
|
+
if (options.bufferedWrite || !keepOrder || zipWriter.writerLocked || zipWriter.bufferedWrites || zipWriter.directWrites || (!dataDescriptor && !emptyEntry)) {
|
|
7122
7123
|
bufferedWrite = true;
|
|
7123
7124
|
zipWriter.bufferedWrites++;
|
|
7124
7125
|
if (options.createTempStream) {
|
|
@@ -7129,6 +7130,8 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
7129
7130
|
fileWriter.size = 0;
|
|
7130
7131
|
await initStream(writer);
|
|
7131
7132
|
} else {
|
|
7133
|
+
directWrite = true;
|
|
7134
|
+
zipWriter.directWrites++;
|
|
7132
7135
|
fileWriter = writer;
|
|
7133
7136
|
await lockPreviousFileEntry;
|
|
7134
7137
|
await requestLockWriter();
|
|
@@ -7207,6 +7210,9 @@ async function getFileEntry(zipWriter, name, reader, entryInfo, options) {
|
|
|
7207
7210
|
if (bufferedWrite) {
|
|
7208
7211
|
zipWriter.bufferedWrites--;
|
|
7209
7212
|
}
|
|
7213
|
+
if (directWrite) {
|
|
7214
|
+
zipWriter.directWrites--;
|
|
7215
|
+
}
|
|
7210
7216
|
if (releaseLockFileEntry) {
|
|
7211
7217
|
releaseLockFileEntry(lockPreviousFileEntry);
|
|
7212
7218
|
}
|
|
@@ -7351,8 +7357,8 @@ async function createFileEntry(reader, writer, { diskNumberStart, lockFileEntry
|
|
|
7351
7357
|
}
|
|
7352
7358
|
const { writable } = writer;
|
|
7353
7359
|
if (reader) {
|
|
7354
|
-
const readable = toCompatibleReadable(createReadable(reader));
|
|
7355
7360
|
const size = reader.size;
|
|
7361
|
+
const readable = toCompatibleReadable(createReadable(reader, { size }));
|
|
7356
7362
|
const workerOptions = {
|
|
7357
7363
|
options: {
|
|
7358
7364
|
codecType: CODEC_DEFLATE,
|
|
@@ -8531,7 +8537,7 @@ function formatSupported(StreamClass, format) {
|
|
|
8531
8537
|
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
8532
8538
|
*/
|
|
8533
8539
|
|
|
8534
|
-
const VERSION = "2.11.
|
|
8540
|
+
const VERSION = "2.11.2";
|
|
8535
8541
|
|
|
8536
8542
|
/*
|
|
8537
8543
|
Copyright (c) 2025 Gildas Lormeau. All rights reserved.
|
|
@@ -9120,18 +9126,17 @@ function _make(isCompress, type, options = {}) {
|
|
|
9120
9126
|
}
|
|
9121
9127
|
heap.set(buffer.subarray(offset, offset + toRead), this.in);
|
|
9122
9128
|
const result = process(this.streamHandle, this.in, toRead, out, outBufferSize, 0);
|
|
9129
|
+
// checked before the byte count is used, so a status code can never be read as one
|
|
9130
|
+
const code = (result >> 24) & 0xff;
|
|
9131
|
+
const signedCode = (code & 0x80) ? code - 256 : code;
|
|
9132
|
+
if (signedCode < 0) {
|
|
9133
|
+
throw new Error("process error:" + signedCode);
|
|
9134
|
+
}
|
|
9123
9135
|
const prod = result & 0x00ffffff;
|
|
9124
9136
|
if (prod) {
|
|
9125
9137
|
scratch.set(heap.subarray(out, out + prod), 0);
|
|
9126
9138
|
controller.enqueue(scratch.slice(0, prod));
|
|
9127
9139
|
}
|
|
9128
|
-
if (!isCompress) {
|
|
9129
|
-
const code = (result >> 24) & 0xff;
|
|
9130
|
-
const signedCode = (code & 0x80) ? code - 256 : code;
|
|
9131
|
-
if (signedCode < 0) {
|
|
9132
|
-
throw new Error("process error:" + signedCode);
|
|
9133
|
-
}
|
|
9134
|
-
}
|
|
9135
9140
|
const consumed = last_consumed(this.streamHandle);
|
|
9136
9141
|
if (consumed === 0 && prod === 0) {
|
|
9137
9142
|
break;
|
|
@@ -9151,14 +9156,12 @@ function _make(isCompress, type, options = {}) {
|
|
|
9151
9156
|
const scratch = this._scratch;
|
|
9152
9157
|
while (true) {
|
|
9153
9158
|
const result = process(this.streamHandle, 0, 0, out, outBufferSize, 4);
|
|
9154
|
-
const produced = result & 0x00ffffff;
|
|
9155
9159
|
const code = (result >> 24) & 0xff;
|
|
9156
|
-
|
|
9157
|
-
|
|
9158
|
-
|
|
9159
|
-
throw new Error("process error:" + signedCode);
|
|
9160
|
-
}
|
|
9160
|
+
const signedCode = (code & 0x80) ? code - 256 : code;
|
|
9161
|
+
if (signedCode < 0) {
|
|
9162
|
+
throw new Error("process error:" + signedCode);
|
|
9161
9163
|
}
|
|
9164
|
+
const produced = result & 0x00ffffff;
|
|
9162
9165
|
if (produced) {
|
|
9163
9166
|
scratch.set(heap.subarray(out, out + produced), 0);
|
|
9164
9167
|
controller.enqueue(scratch.slice(0, produced));
|