@myrialabs/zipkit 0.0.6

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.
Files changed (185) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +329 -0
  3. package/dist/bench/corpus.d.ts +21 -0
  4. package/dist/bench/corpus.d.ts.map +1 -0
  5. package/dist/bench/corpus.js +92 -0
  6. package/dist/bench/corpus.js.map +1 -0
  7. package/dist/checksum.d.ts +29 -0
  8. package/dist/checksum.d.ts.map +1 -0
  9. package/dist/checksum.js +35 -0
  10. package/dist/checksum.js.map +1 -0
  11. package/dist/cli.d.ts +17 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +427 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/codecs/brotli.d.ts +6 -0
  16. package/dist/codecs/brotli.d.ts.map +1 -0
  17. package/dist/codecs/brotli.js +15 -0
  18. package/dist/codecs/brotli.js.map +1 -0
  19. package/dist/codecs/bzip2.d.ts +6 -0
  20. package/dist/codecs/bzip2.d.ts.map +1 -0
  21. package/dist/codecs/bzip2.js +15 -0
  22. package/dist/codecs/bzip2.js.map +1 -0
  23. package/dist/codecs/deflate.d.ts +6 -0
  24. package/dist/codecs/deflate.d.ts.map +1 -0
  25. package/dist/codecs/deflate.js +25 -0
  26. package/dist/codecs/deflate.js.map +1 -0
  27. package/dist/codecs/gzip.d.ts +6 -0
  28. package/dist/codecs/gzip.d.ts.map +1 -0
  29. package/dist/codecs/gzip.js +25 -0
  30. package/dist/codecs/gzip.js.map +1 -0
  31. package/dist/codecs/image.d.ts +5 -0
  32. package/dist/codecs/image.d.ts.map +1 -0
  33. package/dist/codecs/image.js +16 -0
  34. package/dist/codecs/image.js.map +1 -0
  35. package/dist/codecs/index.d.ts +18 -0
  36. package/dist/codecs/index.d.ts.map +1 -0
  37. package/dist/codecs/index.js +18 -0
  38. package/dist/codecs/index.js.map +1 -0
  39. package/dist/codecs/lz4.d.ts +6 -0
  40. package/dist/codecs/lz4.d.ts.map +1 -0
  41. package/dist/codecs/lz4.js +17 -0
  42. package/dist/codecs/lz4.js.map +1 -0
  43. package/dist/codecs/lzma.d.ts +6 -0
  44. package/dist/codecs/lzma.d.ts.map +1 -0
  45. package/dist/codecs/lzma.js +15 -0
  46. package/dist/codecs/lzma.js.map +1 -0
  47. package/dist/codecs/snappy.d.ts +6 -0
  48. package/dist/codecs/snappy.d.ts.map +1 -0
  49. package/dist/codecs/snappy.js +14 -0
  50. package/dist/codecs/snappy.js.map +1 -0
  51. package/dist/codecs/video.d.ts +13 -0
  52. package/dist/codecs/video.d.ts.map +1 -0
  53. package/dist/codecs/video.js +26 -0
  54. package/dist/codecs/video.js.map +1 -0
  55. package/dist/codecs/xz.d.ts +6 -0
  56. package/dist/codecs/xz.d.ts.map +1 -0
  57. package/dist/codecs/xz.js +30 -0
  58. package/dist/codecs/xz.js.map +1 -0
  59. package/dist/codecs/zlib.d.ts +6 -0
  60. package/dist/codecs/zlib.d.ts.map +1 -0
  61. package/dist/codecs/zlib.js +15 -0
  62. package/dist/codecs/zlib.js.map +1 -0
  63. package/dist/codecs/zstd.d.ts +6 -0
  64. package/dist/codecs/zstd.d.ts.map +1 -0
  65. package/dist/codecs/zstd.js +24 -0
  66. package/dist/codecs/zstd.js.map +1 -0
  67. package/dist/compress.d.ts +20 -0
  68. package/dist/compress.d.ts.map +1 -0
  69. package/dist/compress.js +83 -0
  70. package/dist/compress.js.map +1 -0
  71. package/dist/delta.d.ts +30 -0
  72. package/dist/delta.d.ts.map +1 -0
  73. package/dist/delta.js +44 -0
  74. package/dist/delta.js.map +1 -0
  75. package/dist/detect.d.ts +46 -0
  76. package/dist/detect.d.ts.map +1 -0
  77. package/dist/detect.js +86 -0
  78. package/dist/detect.js.map +1 -0
  79. package/dist/dictionary.d.ts +37 -0
  80. package/dist/dictionary.d.ts.map +1 -0
  81. package/dist/dictionary.js +71 -0
  82. package/dist/dictionary.js.map +1 -0
  83. package/dist/engine.d.ts +102 -0
  84. package/dist/engine.d.ts.map +1 -0
  85. package/dist/engine.js +204 -0
  86. package/dist/engine.js.map +1 -0
  87. package/dist/fsa.d.ts +54 -0
  88. package/dist/fsa.d.ts.map +1 -0
  89. package/dist/fsa.js +45 -0
  90. package/dist/fsa.js.map +1 -0
  91. package/dist/index.d.ts +35 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +47 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/internal.d.ts +21 -0
  96. package/dist/internal.d.ts.map +1 -0
  97. package/dist/internal.js +42 -0
  98. package/dist/internal.js.map +1 -0
  99. package/dist/middleware/elysia.d.ts +15 -0
  100. package/dist/middleware/elysia.d.ts.map +1 -0
  101. package/dist/middleware/elysia.js +43 -0
  102. package/dist/middleware/elysia.js.map +1 -0
  103. package/dist/middleware/express.d.ts +17 -0
  104. package/dist/middleware/express.d.ts.map +1 -0
  105. package/dist/middleware/express.js +62 -0
  106. package/dist/middleware/express.js.map +1 -0
  107. package/dist/middleware/hono.d.ts +17 -0
  108. package/dist/middleware/hono.d.ts.map +1 -0
  109. package/dist/middleware/hono.js +41 -0
  110. package/dist/middleware/hono.js.map +1 -0
  111. package/dist/middleware/index.d.ts +14 -0
  112. package/dist/middleware/index.d.ts.map +1 -0
  113. package/dist/middleware/index.js +14 -0
  114. package/dist/middleware/index.js.map +1 -0
  115. package/dist/middleware/shared.d.ts +29 -0
  116. package/dist/middleware/shared.d.ts.map +1 -0
  117. package/dist/middleware/shared.js +47 -0
  118. package/dist/middleware/shared.js.map +1 -0
  119. package/dist/pack.d.ts +36 -0
  120. package/dist/pack.d.ts.map +1 -0
  121. package/dist/pack.js +75 -0
  122. package/dist/pack.js.map +1 -0
  123. package/dist/parallel/index.d.ts +56 -0
  124. package/dist/parallel/index.d.ts.map +1 -0
  125. package/dist/parallel/index.js +158 -0
  126. package/dist/parallel/index.js.map +1 -0
  127. package/dist/sevenzip/index.d.ts +45 -0
  128. package/dist/sevenzip/index.d.ts.map +1 -0
  129. package/dist/sevenzip/index.js +646 -0
  130. package/dist/sevenzip/index.js.map +1 -0
  131. package/dist/streams/index.d.ts +32 -0
  132. package/dist/streams/index.d.ts.map +1 -0
  133. package/dist/streams/index.js +74 -0
  134. package/dist/streams/index.js.map +1 -0
  135. package/dist/string.d.ts +38 -0
  136. package/dist/string.d.ts.map +1 -0
  137. package/dist/string.js +64 -0
  138. package/dist/string.js.map +1 -0
  139. package/dist/tar/index.d.ts +99 -0
  140. package/dist/tar/index.d.ts.map +1 -0
  141. package/dist/tar/index.js +380 -0
  142. package/dist/tar/index.js.map +1 -0
  143. package/dist/types.d.ts +59 -0
  144. package/dist/types.d.ts.map +1 -0
  145. package/dist/types.js +22 -0
  146. package/dist/types.js.map +1 -0
  147. package/dist/workers/index.d.ts +58 -0
  148. package/dist/workers/index.d.ts.map +1 -0
  149. package/dist/workers/index.js +158 -0
  150. package/dist/workers/index.js.map +1 -0
  151. package/dist/workers/worker.d.ts +18 -0
  152. package/dist/workers/worker.d.ts.map +1 -0
  153. package/dist/workers/worker.js +45 -0
  154. package/dist/workers/worker.js.map +1 -0
  155. package/dist/zip/crypto/aes.d.ts +25 -0
  156. package/dist/zip/crypto/aes.d.ts.map +1 -0
  157. package/dist/zip/crypto/aes.js +156 -0
  158. package/dist/zip/crypto/aes.js.map +1 -0
  159. package/dist/zip/crypto/winzip.d.ts +28 -0
  160. package/dist/zip/crypto/winzip.d.ts.map +1 -0
  161. package/dist/zip/crypto/winzip.js +87 -0
  162. package/dist/zip/crypto/winzip.js.map +1 -0
  163. package/dist/zip/crypto/zipcrypto.d.ts +14 -0
  164. package/dist/zip/crypto/zipcrypto.d.ts.map +1 -0
  165. package/dist/zip/crypto/zipcrypto.js +65 -0
  166. package/dist/zip/crypto/zipcrypto.js.map +1 -0
  167. package/dist/zip/datetime.d.ts +9 -0
  168. package/dist/zip/datetime.d.ts.map +1 -0
  169. package/dist/zip/datetime.js +13 -0
  170. package/dist/zip/datetime.js.map +1 -0
  171. package/dist/zip/index.d.ts +134 -0
  172. package/dist/zip/index.d.ts.map +1 -0
  173. package/dist/zip/index.js +473 -0
  174. package/dist/zip/index.js.map +1 -0
  175. package/dist/zip/stream.d.ts +38 -0
  176. package/dist/zip/stream.d.ts.map +1 -0
  177. package/dist/zip/stream.js +240 -0
  178. package/dist/zip/stream.js.map +1 -0
  179. package/dist/zipkit.d.ts +74 -0
  180. package/dist/zipkit.d.ts.map +1 -0
  181. package/dist/zipkit.js +168 -0
  182. package/dist/zipkit.js.map +1 -0
  183. package/engine/dist/zipkit-engine.mjs +2 -0
  184. package/engine/dist/zipkit-engine.wasm +0 -0
  185. package/package.json +137 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Myria Labs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,329 @@
1
+ <p align="center">
2
+ <img src="https://zipkit.myrialabs.dev/favicon.svg" alt="ZipKit" width="72" height="72" />
3
+ </p>
4
+
5
+ <h1 align="center">ZipKit</h1>
6
+
7
+ <p align="center">
8
+ <strong>Overkill compression for Node, Bun &amp; the browser.</strong><br />
9
+ gzip · deflate · zlib · zstd · lz4 · snappy · brotli · lzma · bzip2 · ZIP —
10
+ one tiny, typed API over a single Wasm engine.
11
+ </p>
12
+
13
+ <p align="center">
14
+ <a href="https://demo.zipkit.myrialabs.dev/">Demo</a> ·
15
+ <a href="https://zipkit.myrialabs.dev/">Website</a> ·
16
+ <a href="https://www.npmjs.com/package/@myrialabs/zipkit">npm</a> ·
17
+ <a href="./docs/api.md">API reference</a> ·
18
+ <a href="./docs/cli.md">CLI reference</a> ·
19
+ <a href="./examples/README.md">Examples</a> ·
20
+ <a href="https://github.com/myrialabs/zipkit/issues">Issues</a>
21
+ </p>
22
+
23
+ <p align="center">
24
+ <a href="https://www.npmjs.com/package/@myrialabs/zipkit"><img src="https://img.shields.io/npm/v/@myrialabs%2Fzipkit" alt="npm version" /></a>
25
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg" alt="License: MIT" /></a>
26
+ <img src="https://img.shields.io/badge/runtime-Node%2018%2B%20%7C%20Bun%20%7C%20Browser-black" alt="Node 18+, Bun and Browser" />
27
+ </p>
28
+
29
+ ---
30
+
31
+ ZipKit compiles best-in-class C compression libraries (libdeflate, zstd, lz4,
32
+ brotli, snappy, LZMA, bzip2) into one WebAssembly engine, then wraps them in a
33
+ small TypeScript API. The default path is adaptive: native speed where the runtime
34
+ wins, the portable engine where it wins, and libdeflate density when ratio matters.
35
+
36
+ ```ts
37
+ import { gzip, gunzip, zstd, unzstd, zip, unzip, compress, decompress } from '@myrialabs/zipkit';
38
+
39
+ const gz = await gzip(bytes); // balanced default
40
+ const back = await gunzip(gz);
41
+
42
+ const fast = await zstd(bytes, { mode: 'speed' });
43
+ const exact = await unzstd(fast);
44
+
45
+ const archive = await zip([{ name: 'data.bin', data: bytes }]);
46
+ const files = await unzip(archive);
47
+
48
+ const small = await compress(bytes, 'zstd', { mode: 'ratio' });
49
+ const orig = await decompress(small); // auto-detects the format
50
+ ```
51
+
52
+ ```sh
53
+ zipkit compress data.json --codec zstd # CLI
54
+ zipkit zip site.zip index.html app.js --method zstd
55
+ ```
56
+
57
+ ## Why ZipKit
58
+
59
+ - **One simple API, every codec** — named imports (`gzip`, `zstd`, `zip`) when you
60
+ know what you want, or `compress()` / `decompress()` for generic dispatch.
61
+ - **One clear option** — `mode: 'speed' | 'balanced' | 'ratio'`. No tuning maze;
62
+ `level` is still available when you need exact control.
63
+ - **Adaptive performance** — ZipKit chooses native Bun zlib/zstd where it wins,
64
+ the Wasm engine where it wins, and libdeflate for density.
65
+ - **Denser gzip when you ask for ratio** — `mode: 'ratio'` uses libdeflate for
66
+ gzip/deflate/zlib and beats runtime zlib output size on every benchmark dataset.
67
+ - **Runs everywhere** — Node 18+, Bun, and the browser, from the same import. No
68
+ Bun required; native APIs are accelerators only when present.
69
+ - **More than fflate** — feature parity with fflate plus zstd/brotli/lzma/bzip2/xz,
70
+ ZIP-with-zstd, **streaming & AES-encrypted ZIP**, **tar** and **7z** containers,
71
+ **zstd dictionaries** and **delta** compression, native `TransformStream`s, and
72
+ lossless image (QOI) and video (frame-delta) codecs.
73
+ - **Typed & documented** — TypeScript-first, JSDoc on every export, tree-shakeable
74
+ named imports, `sideEffects: false`.
75
+
76
+ ## Install
77
+
78
+ ```sh
79
+ bun add @myrialabs/zipkit # or: npm i @myrialabs/zipkit / pnpm add @myrialabs/zipkit
80
+ bun add -g @myrialabs/zipkit # CLI
81
+ ```
82
+
83
+ ## Quick start
84
+
85
+ | Task | API |
86
+ | --- | --- |
87
+ | Compress | `await zstd(bytes)` |
88
+ | Decompress | `await unzstd(bytes)` |
89
+ | Generic + auto-detect | `await compress(bytes, 'gzip')` · `await decompress(bytes)` |
90
+ | Just the smallest | `await pack(bytes)` · `await unpack(packed)` |
91
+ | Prefer speed | `await gzip(bytes, { mode: 'speed' })` |
92
+ | Prefer ratio | `await zstd(bytes, { mode: 'ratio' })` |
93
+ | ZIP archive | `await zip([{ name, data }])` · `await unzip(archive)` |
94
+ | Encrypted ZIP | `await zip(entries, { password })` · `await unzip(a, { password })` |
95
+ | Streaming ZIP | `zipStream(entries).pipeTo(dest)` |
96
+ | tar / tarball | `tar(entries)` · `await tarGz(entries)` (`@myrialabs/zipkit/tar`) |
97
+ | 7z | `await sevenZip(entries)` · `await unSevenZip(a)` (`@myrialabs/zipkit/sevenzip`) |
98
+ | xz | `await xz(bytes)` · `await unxz(bytes)` |
99
+ | Dictionary / delta | `compressWithDictionary` · `compressDelta` |
100
+ | Stream codec | `readable.pipeThrough(compressionStream('gzip'))` |
101
+
102
+ > **Auto-detect scope.** `decompress()` decodes the self-describing codecs —
103
+ > **gzip, zlib, zstd, xz** — and recognizes container formats (ZIP, tar, 7z,
104
+ > bzip2, lz4-frame), pointing you to the right reader. For headerless or
105
+ > ZipKit-framed codecs (brotli, snappy, lz4, lzma, bzip2) name the codec:
106
+ > `decompressWith(bytes, 'brotli')`.
107
+
108
+ ### The two API styles
109
+
110
+ **Named functions** (async, tree-shakeable) — the default. Each lazily loads the
111
+ shared engine the first time it's called.
112
+
113
+ ```ts
114
+ import { brotli, unbrotli } from '@myrialabs/zipkit';
115
+ const c = await brotli(bytes, { mode: 'ratio' });
116
+ ```
117
+
118
+ **The `ZipKit` class** (synchronous) — load the engine once, then call
119
+ synchronously. It accepts the same `mode` option as the async helpers while still
120
+ supporting the old numeric level argument (`zk.gzip(bytes, 6)`).
121
+
122
+ ```ts
123
+ import { ZipKit } from '@myrialabs/zipkit';
124
+ const zk = await ZipKit.load();
125
+ const gz = zk.gzip(bytes, { mode: 'speed' }); // sync
126
+ const smallest = zk.pack(bytes); // tries brotli/lzma/bzip2/zstd-max, keeps the smallest
127
+ ```
128
+
129
+ ## Performance
130
+
131
+ Bun 1.3.14, every codec against its best competitor. Reproduce with
132
+ `bun run bench.ts`; the full tables (three datasets + parallel + ZIP archive vs
133
+ JSZip/fflate) live in [bench-results.md](./bench-results.md). All roundtrips are
134
+ byte-identical.
135
+
136
+ Representative — **E-commerce API**, ~97 KB JSON (throughput, higher is faster):
137
+
138
+ | Codec | Implementation | Ratio | Compress | Decompress |
139
+ |-------|----------------|------:|---------:|-----------:|
140
+ | **gzip** | | | | |
141
+ | | ZipKit | 5.1% | 396 MB/s | 2.7 GB/s |
142
+ | | ZipKit (ratio) | 4.9% | 51 MB/s | 2.6 GB/s |
143
+ | | fflate | 5.9% | 55 MB/s | 122 MB/s |
144
+ | | Bun.gzipSync | 5.1% | 380 MB/s | 2.5 GB/s |
145
+ | **deflate** | | | | |
146
+ | | ZipKit | 5.1% | 400 MB/s | 2.7 GB/s |
147
+ | | ZipKit (ratio) | 4.9% | 50 MB/s | 2.5 GB/s |
148
+ | | fflate | 5.9% | 68 MB/s | 119 MB/s |
149
+ | | Bun.deflateSync | 5.1% | 399 MB/s | 2.7 GB/s |
150
+ | **zlib** | | | | |
151
+ | | ZipKit | 6.0% | 273 MB/s | 1.2 GB/s |
152
+ | | ZipKit (ratio) | 4.9% | 53 MB/s | 2.0 GB/s |
153
+ | | fflate | 5.9% | 63 MB/s | 112 MB/s |
154
+ | **zstd** | | | | |
155
+ | | ZipKit | 5.6% | 1.5 GB/s | 3.4 GB/s |
156
+ | | ZipKit (ratio) | 3.9% | 2 MB/s | 5.3 GB/s |
157
+ | | zstd-wasm | 5.6% | 354 MB/s | 978 MB/s |
158
+ | | Bun.zstdCompressSync | 5.6% | 1.9 GB/s | 3.5 GB/s |
159
+ | **lz4** | | | | |
160
+ | | ZipKit | 12.9% | 1018 MB/s | 2.1 GB/s |
161
+ | | lz4js | 12.5% | 399 MB/s | 515 MB/s |
162
+ | **snappy** | | | | |
163
+ | | ZipKit | 13.5% | 599 MB/s | 1.5 GB/s |
164
+ | | snappyjs | 13.5% | 358 MB/s | 437 MB/s |
165
+ | **brotli** | | | | |
166
+ | | ZipKit | 4.1% | 107 MB/s | 844 MB/s |
167
+ | | ZipKit (ratio) | 3.4% | 611.5 KB/s | 1.8 GB/s |
168
+ | | brotli-wasm | 4.1% | 42 MB/s | 560 MB/s |
169
+ | **lzma** | | | | |
170
+ | | ZipKit | 3.8% | 18 MB/s | 423 MB/s |
171
+ | **bzip2** | | | | |
172
+ | | ZipKit | 3.4% | 17 MB/s | 83 MB/s |
173
+
174
+ What the full run adds beyond this table:
175
+
176
+ - **Against portable JS** (fflate, pako, zstd-wasm, brotli-wasm), ZipKit
177
+ compresses several× faster at an equal-or-better ratio across all datasets.
178
+ - **`mode: 'ratio'`** trades speed for size: libdeflate gzip/deflate is denser
179
+ than native zlib, and brotli/lzma/bzip2 reach the smallest output (~3.3–3.8% on JSON).
180
+ - **Parallel** (8 cores, 34 MB logs) is the multi-core path native libs lack:
181
+ `compressParallel` gzip runs **5.4× faster** than `Bun.gzipSync`, same output size.
182
+ - **ZIP archives** fan entry compression across the pool: a 20-file, 8 MB archive
183
+ packs **8.9× faster** than `fflate` and **7.8× faster** than JSZip, 10% smaller.
184
+ - **Dictionary & delta** target what generic codecs handle poorly: a zstd
185
+ dictionary makes 500 small JSON records **~66% smaller** than per-record zstd,
186
+ and `compressDelta` encodes a one-line edit to a 64 KB doc **>250× smaller**
187
+ than recompressing it. `xz` is included in every codec table too.
188
+
189
+ ## Streaming
190
+
191
+ Web-standard `TransformStream`s for every codec. gzip / zlib / deflate are backed by
192
+ the platform's native `CompressionStream` (true incremental streaming); the rest
193
+ buffer and compress on flush.
194
+
195
+ ```ts
196
+ import { compressionStream } from '@myrialabs/zipkit/streams';
197
+
198
+ await fetch(url)
199
+ .then((r) => r.body!)
200
+ .then((body) => body.pipeThrough(compressionStream('gzip')).pipeTo(dest));
201
+ ```
202
+
203
+ ## ZIP archives
204
+
205
+ ```ts
206
+ import { zip, unzip } from '@myrialabs/zipkit';
207
+
208
+ const archive = await zip([
209
+ { name: 'index.html', data: html },
210
+ { name: 'app.js', data: js, method: 'zstd' }, // denser, ZipKit-aware peers
211
+ { name: 'logo.png', data: png, method: 'store', unixPermissions: 0o644 }
212
+ ]);
213
+
214
+ const files = await unzip(archive, { filter: (e) => e.name.endsWith('.js') });
215
+ ```
216
+
217
+ `store` and `deflate` entries interoperate with every standard ZIP tool; `zstd`
218
+ entries (method 93) are much denser between ZipKit-aware peers. ZIP64 kicks in
219
+ automatically beyond 4 GB / 65 535 entries.
220
+
221
+ **Encrypted** (WinZip AES-256, reads back in 7-Zip/WinZip), **streaming** (never
222
+ buffers the whole archive), and **integrity-checked**:
223
+
224
+ ```ts
225
+ const enc = await zip(entries, { password: 'secret' }); // AES-256 (AE-2)
226
+ const out = await unzip(enc, { password: 'secret', verify: true });
227
+
228
+ import { zipStream } from '@myrialabs/zipkit/zip';
229
+ await zipStream(entries).pipeTo(destination); // memory-bounded
230
+ ```
231
+
232
+ ## tar, 7z & xz
233
+
234
+ ```ts
235
+ import { tar, tarGz, untarGz } from '@myrialabs/zipkit/tar';
236
+ import { sevenZip, unSevenZip } from '@myrialabs/zipkit/sevenzip';
237
+ import { xz, unxz } from '@myrialabs/zipkit/xz';
238
+
239
+ const tgz = await tarGz([{ name: 'a.txt', data }]); // .tar.gz (also tarZstd)
240
+ const archive = await sevenZip([{ name: 'a.txt', data }]); // 7-Zip-compatible
241
+ const x = await xz(data, { level: 9 }); // standard .xz
242
+ ```
243
+
244
+ tar is POSIX `ustar`+PAX (Unix-`tar`/Docker compatible); 7z reads/writes
245
+ copy/LZMA(2) and interoperates with 7-Zip both directions; xz is the full
246
+ streaming `.xz` container.
247
+
248
+ ## Dictionary & delta
249
+
250
+ ```ts
251
+ import { trainDictionary, compressWithDictionary } from '@myrialabs/zipkit/dictionary';
252
+ import { compressDelta, applyDelta } from '@myrialabs/zipkit/delta';
253
+
254
+ const dict = await trainDictionary(samples); // many small similar payloads
255
+ const small = await compressWithDictionary(record, dict);
256
+
257
+ const patch = await compressDelta(prevRevision, newRevision); // logs/chat/state
258
+ const restored = await applyDelta(prevRevision, patch);
259
+ ```
260
+
261
+ ## HTTP middleware
262
+
263
+ `Accept-Encoding`-negotiating compression for Elysia, Express, and Hono
264
+ (brotli → zstd → gzip → deflate).
265
+
266
+ ```ts
267
+ import { Elysia } from 'elysia';
268
+ import { elysia as compression } from '@myrialabs/zipkit/middleware';
269
+
270
+ new Elysia()
271
+ .onAfterHandle(compression())
272
+ .get('/', () => ({ rows: Array.from({ length: 200 }, (_, i) => ({ i })) }))
273
+ .listen(3000);
274
+ ```
275
+
276
+ ```ts
277
+ import express from 'express';
278
+ import { express as compression } from '@myrialabs/zipkit/middleware';
279
+
280
+ const app = express();
281
+ app.use(compression());
282
+ app.get('/', (_req, res) => res.json({ rows: Array.from({ length: 200 }, (_, i) => ({ i })) }));
283
+ app.listen(3000);
284
+ ```
285
+
286
+ ```ts
287
+ import { Hono } from 'hono';
288
+ import { hono as compression } from '@myrialabs/zipkit/middleware';
289
+
290
+ const app = new Hono();
291
+ app.use('*', compression());
292
+ ```
293
+
294
+ ## Browser
295
+
296
+ The engine loads its `.wasm` via `import.meta.url`, which Vite, webpack 5, esbuild,
297
+ and Rollup resolve as an asset out of the box. See [docs/browser.md](./docs/browser.md).
298
+
299
+ The combined engine is ~1.4 MB of `.wasm` (every codec in one module), loaded
300
+ once and cached. Keep it off your initial bundle with a dynamic import
301
+ (`const { gzip } = await import('@myrialabs/zipkit')`), or skip the engine entirely for
302
+ gzip/zlib/deflate by using [`@myrialabs/zipkit/streams`](./docs/streaming.md), which run on
303
+ the browser's native `CompressionStream`. Per-codec Wasm splitting is on the
304
+ roadmap.
305
+
306
+ ## Documentation
307
+
308
+ - [API reference](./docs/api.md) — every export, option, and method.
309
+ - [CLI reference](./docs/cli.md) — every command and flag.
310
+ - [Algorithms](./docs/algorithms.md) — which codec to use, with benchmark tables.
311
+ - [Streaming](./docs/streaming.md) · [ZIP](./docs/zip.md) · [Browser](./docs/browser.md)
312
+ - [Examples](./examples/README.md) — runnable scenarios.
313
+
314
+ ## Support
315
+
316
+ If ZipKit is useful to you, consider supporting its development:
317
+
318
+ | Method | Address / Link |
319
+ |--------|----------------|
320
+ | Bitcoin (BTC) | `bc1qd9fyx4r84cce2a9hkjksetah802knadw5msls3` |
321
+ | Solana (SOL) | `Ev3P4KLF1PNC5C9rZYP8M3DdssyBQAQAiNJkvNmPQPVs` |
322
+ | Ethereum (ERC-20) | `0x61D826e5b666AA5345302EEEd485Acca39b1AFCF` |
323
+ | USDT (TRC-20) | `TLH49i3EoVKhFyLb6u2JUXZWScK7uzksdC` |
324
+ | Saweria | [saweria.co/myrialabs](https://saweria.co/myrialabs) |
325
+
326
+ ## License
327
+
328
+ MIT — see [LICENSE](LICENSE). Bundles several open-source C libraries; see
329
+ [their licenses](./docs/algorithms.md#third-party-licenses).
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Deterministic benchmark corpora.
3
+ *
4
+ * `zipkit bench` with no file compares codecs on these built-in datasets, so
5
+ * ratio/timing comparisons across versions or PRs are apple-to-apple instead of
6
+ * depending on whatever file a user happened to pass. Everything is generated
7
+ * from a fixed seed (no `Math.random`, no bundled fixtures bloating the
8
+ * package), so the same input bytes are reproduced on every machine and run.
9
+ */
10
+ /** A named benchmark dataset. */
11
+ export interface CorpusEntry {
12
+ /** Short identifier, e.g. `'text'`. */
13
+ name: string;
14
+ /** One-line description of what the dataset models. */
15
+ description: string;
16
+ /** The dataset bytes. */
17
+ data: Uint8Array;
18
+ }
19
+ /** Build the standard corpus at roughly `bytesPerSet` bytes per dataset (default 256 KB). */
20
+ export declare function presetCorpus(bytesPerSet?: number): CorpusEntry[];
21
+ //# sourceMappingURL=corpus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../../src/bench/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,iCAAiC;AACjC,MAAM,WAAW,WAAW;IAC3B,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,IAAI,EAAE,UAAU,CAAC;CACjB;AAkFD,6FAA6F;AAC7F,wBAAgB,YAAY,CAAC,WAAW,SAAa,GAAG,WAAW,EAAE,CAOpE"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Deterministic benchmark corpora.
3
+ *
4
+ * `zipkit bench` with no file compares codecs on these built-in datasets, so
5
+ * ratio/timing comparisons across versions or PRs are apple-to-apple instead of
6
+ * depending on whatever file a user happened to pass. Everything is generated
7
+ * from a fixed seed (no `Math.random`, no bundled fixtures bloating the
8
+ * package), so the same input bytes are reproduced on every machine and run.
9
+ */
10
+ /** A tiny deterministic PRNG (mulberry32) — reproducible, no global state. */
11
+ function rng(seed) {
12
+ let a = seed >>> 0;
13
+ return () => {
14
+ a |= 0;
15
+ a = (a + 0x6d2b79f5) | 0;
16
+ let t = Math.imul(a ^ (a >>> 15), 1 | a);
17
+ t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
18
+ return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
19
+ };
20
+ }
21
+ const WORDS = ('the quick brown fox jumps over a lazy dog while data flows through pipes and ' +
22
+ 'buffers compress into smaller frames across every runtime node bun browser ' +
23
+ 'engine codec stream archive entry header footer index block size ratio').split(' ');
24
+ /** Natural-language-like English text — exercises entropy coding and matching. */
25
+ function textCorpus(targetBytes) {
26
+ const next = rng(0x1234abcd);
27
+ let s = '';
28
+ while (s.length < targetBytes) {
29
+ const len = 6 + Math.floor(next() * 14);
30
+ const line = [];
31
+ for (let i = 0; i < len; i++)
32
+ line.push(WORDS[Math.floor(next() * WORDS.length)]);
33
+ s += line.join(' ') + '.\n';
34
+ }
35
+ return new TextEncoder().encode(s.slice(0, targetBytes));
36
+ }
37
+ /** Repetitive structured JSON records — the everyday API/log-payload shape. */
38
+ function jsonCorpus(targetBytes) {
39
+ const next = rng(0x55aa00ff);
40
+ const levels = ['debug', 'info', 'warn', 'error'];
41
+ const svcs = ['api', 'auth', 'cache', 'db', 'queue'];
42
+ const records = [];
43
+ let size = 0;
44
+ let i = 0;
45
+ while (size < targetBytes) {
46
+ const rec = JSON.stringify({
47
+ ts: 1_700_000_000 + i,
48
+ level: levels[Math.floor(next() * levels.length)],
49
+ svc: svcs[Math.floor(next() * svcs.length)],
50
+ id: Math.floor(next() * 1_000_000),
51
+ ok: next() > 0.1,
52
+ msg: `request ${i} processed in ${Math.floor(next() * 500)}ms`
53
+ });
54
+ records.push(rec);
55
+ size += rec.length + 1;
56
+ i++;
57
+ }
58
+ return new TextEncoder().encode('[' + records.join(',\n') + ']');
59
+ }
60
+ /** Semi-structured log lines with timestamps and repeated tokens. */
61
+ function logCorpus(targetBytes) {
62
+ const next = rng(0x0f0f0f0f);
63
+ const paths = ['/api/users', '/api/orders', '/health', '/assets/app.js', '/login'];
64
+ let s = '';
65
+ let i = 0;
66
+ while (s.length < targetBytes) {
67
+ const ms = 1_700_000_000_000 + i * 137;
68
+ s += `${ms} GET ${paths[Math.floor(next() * paths.length)]} ${200 + Math.floor(next() * 5) * 100} ${Math.floor(next() * 9999)}b\n`;
69
+ i++;
70
+ }
71
+ return new TextEncoder().encode(s.slice(0, targetBytes));
72
+ }
73
+ /** High-entropy bytes with light structure — a near-incompressible baseline. */
74
+ function binaryCorpus(targetBytes) {
75
+ const next = rng(0xdeadbeef);
76
+ const out = new Uint8Array(targetBytes);
77
+ for (let i = 0; i < targetBytes; i++) {
78
+ // Mostly random, but with occasional runs so it isn't pure noise.
79
+ out[i] = next() < 0.15 ? 0 : Math.floor(next() * 256);
80
+ }
81
+ return out;
82
+ }
83
+ /** Build the standard corpus at roughly `bytesPerSet` bytes per dataset (default 256 KB). */
84
+ export function presetCorpus(bytesPerSet = 256 * 1024) {
85
+ return [
86
+ { name: 'text', description: 'English-like natural-language text', data: textCorpus(bytesPerSet) },
87
+ { name: 'json', description: 'repetitive structured JSON records', data: jsonCorpus(bytesPerSet) },
88
+ { name: 'log', description: 'semi-structured server log lines', data: logCorpus(bytesPerSet) },
89
+ { name: 'binary', description: 'high-entropy bytes (near-incompressible)', data: binaryCorpus(bytesPerSet) }
90
+ ];
91
+ }
92
+ //# sourceMappingURL=corpus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.js","sourceRoot":"","sources":["../../src/bench/corpus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Explicit integrity helpers.
3
+ *
4
+ * The codecs already validate their own framed checksums on decode (gzip's
5
+ * CRC-32, zstd's optional content checksum), and {@link import('./zip/index.js').unzip}
6
+ * takes a `verify` option to re-check every entry. This module exposes the raw
7
+ * CRC-32 so callers can verify or fingerprint arbitrary bytes themselves — the
8
+ * same libdeflate SIMD routine the ZIP container uses, not a byte-at-a-time
9
+ * table.
10
+ */
11
+ /**
12
+ * CRC-32 (IEEE 802.3) of `data`. Pass a prior result as `seed` to continue a
13
+ * running checksum across chunks. Returned as an unsigned 32-bit integer.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { crc32 } from '@myrialabs/zipkit';
18
+ * const sum = await crc32(bytes);
19
+ * const running = await crc32(part2, await crc32(part1));
20
+ * ```
21
+ */
22
+ export declare function crc32(data: Uint8Array, seed?: number): Promise<number>;
23
+ /**
24
+ * Verify `data` against an expected CRC-32, returning `true` on a match. A thin
25
+ * convenience over {@link crc32} for the common "does this match what I stored"
26
+ * check.
27
+ */
28
+ export declare function verifyChecksum(data: Uint8Array, expected: number): Promise<boolean>;
29
+ //# sourceMappingURL=checksum.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checksum.d.ts","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH;;;;;;;;;;GAUG;AACH,wBAAsB,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,SAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzF"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Explicit integrity helpers.
3
+ *
4
+ * The codecs already validate their own framed checksums on decode (gzip's
5
+ * CRC-32, zstd's optional content checksum), and {@link import('./zip/index.js').unzip}
6
+ * takes a `verify` option to re-check every entry. This module exposes the raw
7
+ * CRC-32 so callers can verify or fingerprint arbitrary bytes themselves — the
8
+ * same libdeflate SIMD routine the ZIP container uses, not a byte-at-a-time
9
+ * table.
10
+ */
11
+ import { getEngine } from './engine.js';
12
+ /**
13
+ * CRC-32 (IEEE 802.3) of `data`. Pass a prior result as `seed` to continue a
14
+ * running checksum across chunks. Returned as an unsigned 32-bit integer.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { crc32 } from '@myrialabs/zipkit';
19
+ * const sum = await crc32(bytes);
20
+ * const running = await crc32(part2, await crc32(part1));
21
+ * ```
22
+ */
23
+ export async function crc32(data, seed = 0) {
24
+ const e = await getEngine();
25
+ return e.crc32(data, seed) >>> 0;
26
+ }
27
+ /**
28
+ * Verify `data` against an expected CRC-32, returning `true` on a match. A thin
29
+ * convenience over {@link crc32} for the common "does this match what I stored"
30
+ * check.
31
+ */
32
+ export async function verifyChecksum(data, expected) {
33
+ return (await crc32(data)) === (expected >>> 0);
34
+ }
35
+ //# sourceMappingURL=checksum.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checksum.js","sourceRoot":"","sources":["../src/checksum.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAExC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAgB,EAAE,IAAI,GAAG,CAAC;IACrD,MAAM,CAAC,GAAG,MAAM,SAAS,EAAE,CAAC;IAC5B,OAAO,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAgB,EAAE,QAAgB;IACtE,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC;AACjD,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * zipkit CLI
4
+ *
5
+ * A thin command line over the library, so ZipKit can be used straight from a
6
+ * terminal (`npm i -g @myrialabs/zipkit` / `bun add -g @myrialabs/zipkit`).
7
+ *
8
+ * zipkit compress <file> [--codec zstd] [--mode ratio] [--level N] [-o out]
9
+ * zipkit decompress <file> [--codec gzip] [-o out] (auto-detects by default)
10
+ * zipkit zip <archive.zip> <files...> [--method deflate|zstd|store]
11
+ * zipkit unzip <archive.zip> [-d <dir>]
12
+ * zipkit info <file> Inspect a file (format, or ZIP listing)
13
+ * zipkit bench <file> Compare every codec on a file
14
+ * zipkit version | help
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;GAaG"}