node-liblzma 2.2.0 → 3.0.0
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/README.md +379 -778
- package/lib/cli/nxz.js +176 -84
- package/lib/cli/nxz.js.map +1 -1
- package/lib/lzma.browser.d.ts +24 -0
- package/lib/lzma.browser.d.ts.map +1 -0
- package/lib/lzma.browser.js +30 -0
- package/lib/lzma.browser.js.map +1 -0
- package/lib/lzma.inline.d.ts +30 -0
- package/lib/lzma.inline.d.ts.map +1 -0
- package/lib/lzma.inline.js +68 -0
- package/lib/lzma.inline.js.map +1 -0
- package/lib/wasm/bindings.d.ts +109 -0
- package/lib/wasm/bindings.d.ts.map +1 -0
- package/lib/wasm/bindings.js +307 -0
- package/lib/wasm/bindings.js.map +1 -0
- package/lib/wasm/compress.d.ts +32 -0
- package/lib/wasm/compress.d.ts.map +1 -0
- package/lib/wasm/compress.js +47 -0
- package/lib/wasm/compress.js.map +1 -0
- package/lib/wasm/decompress.d.ts +32 -0
- package/lib/wasm/decompress.d.ts.map +1 -0
- package/lib/wasm/decompress.js +45 -0
- package/lib/wasm/decompress.js.map +1 -0
- package/lib/wasm/index.d.ts +14 -0
- package/lib/wasm/index.d.ts.map +1 -0
- package/lib/wasm/index.js +18 -0
- package/lib/wasm/index.js.map +1 -0
- package/lib/wasm/liblzma.inline.d.ts +10 -0
- package/lib/wasm/liblzma.inline.d.ts.map +1 -0
- package/lib/wasm/liblzma.inline.js +10 -0
- package/lib/wasm/liblzma.inline.js.map +1 -0
- package/lib/wasm/memory.d.ts +57 -0
- package/lib/wasm/memory.d.ts.map +1 -0
- package/lib/wasm/memory.js +108 -0
- package/lib/wasm/memory.js.map +1 -0
- package/lib/wasm/stream.d.ts +35 -0
- package/lib/wasm/stream.d.ts.map +1 -0
- package/lib/wasm/stream.js +164 -0
- package/lib/wasm/stream.js.map +1 -0
- package/lib/wasm/types.d.ts +77 -0
- package/lib/wasm/types.d.ts.map +1 -0
- package/lib/wasm/types.js +55 -0
- package/lib/wasm/types.js.map +1 -0
- package/lib/wasm/utils.d.ts +62 -0
- package/lib/wasm/utils.d.ts.map +1 -0
- package/lib/wasm/utils.js +162 -0
- package/lib/wasm/utils.js.map +1 -0
- package/package.json +24 -3
package/README.md
CHANGED
|
@@ -10,31 +10,43 @@ Node-liblzma
|
|
|
10
10
|
[](https://www.typescriptlang.org/)
|
|
11
11
|
[](https://docs.npmjs.com/generating-provenance-statements)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
13
|
+
Native Node.js bindings for liblzma — XZ/LZMA2 compression with **browser support via WebAssembly**.
|
|
14
|
+
|
|
15
|
+
## Table of Contents
|
|
16
|
+
|
|
17
|
+
- [Quick Start](#quick-start)
|
|
18
|
+
- [What's New](#whats-new)
|
|
19
|
+
- [v3.0.0 — Browser & WASM Support](#v300--browser--wasm-support)
|
|
20
|
+
- [v2.0.0 — TypeScript Modernization](#v200--typescript-modernization)
|
|
21
|
+
- [Browser Usage](#browser-usage)
|
|
22
|
+
- [CLI Tool (nxz)](#cli-tool-nxz)
|
|
23
|
+
- [API Reference](#api-reference)
|
|
24
|
+
- [API Comparison with Zlib](#api-comparison-with-zlib)
|
|
25
|
+
- [Options](#options)
|
|
26
|
+
- [Advanced Configuration](#advanced-configuration)
|
|
27
|
+
- [Thread Support](#thread-support)
|
|
28
|
+
- [Progress Monitoring](#progress-monitoring)
|
|
29
|
+
- [Concurrency Control (LZMAPool)](#concurrency-control-with-lzmapool)
|
|
30
|
+
- [File Compression Helpers](#file-compression-helpers)
|
|
31
|
+
- [Error Handling](#error-handling)
|
|
32
|
+
- [Benchmark](#benchmark)
|
|
33
|
+
- [Installation](#installation)
|
|
34
|
+
- [Testing](#testing)
|
|
35
|
+
- [Migration Guide (v1 → v2)](#migration-guide)
|
|
36
|
+
- [Contributing](#contributing)
|
|
37
|
+
- [Troubleshooting](#troubleshooting)
|
|
38
|
+
- [Bugs](#bugs)
|
|
39
|
+
- [Acknowledgements](#acknowledgements)
|
|
40
|
+
- [License](#license)
|
|
41
|
+
|
|
42
|
+
## What is liblzma/XZ?
|
|
43
|
+
|
|
44
|
+
[XZ](https://tukaani.org/xz/xz-file-format.txt) is a container for compressed archives. It offers one of the best compression ratios available, with a good balance between compression time and decompression speed/memory.
|
|
33
45
|
|
|
34
46
|
> Only LZMA2 is supported for compression output.
|
|
35
|
-
But the library can open and read any LZMA1 or LZMA2 compressed file.
|
|
47
|
+
> But the library can open and read any LZMA1 or LZMA2 compressed file.
|
|
36
48
|
|
|
37
|
-
|
|
49
|
+
## Quick Start
|
|
38
50
|
|
|
39
51
|
```bash
|
|
40
52
|
npm install node-liblzma
|
|
@@ -61,7 +73,8 @@ compressor.on('progress', ({ bytesRead, bytesWritten }) => {
|
|
|
61
73
|
});
|
|
62
74
|
```
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
<details>
|
|
77
|
+
<summary><strong>Promise style (with .then())</strong></summary>
|
|
65
78
|
|
|
66
79
|
```typescript
|
|
67
80
|
import { xzAsync, unxzAsync } from 'node-liblzma';
|
|
@@ -79,7 +92,10 @@ xzAsync(Buffer.from('Hello, World!'))
|
|
|
79
92
|
});
|
|
80
93
|
```
|
|
81
94
|
|
|
82
|
-
|
|
95
|
+
</details>
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary><strong>Callback style (Node.js traditional)</strong></summary>
|
|
83
99
|
|
|
84
100
|
```typescript
|
|
85
101
|
import { xz, unxz } from 'node-liblzma';
|
|
@@ -93,25 +109,142 @@ xz(Buffer.from('Hello, World!'), (err, compressed) => {
|
|
|
93
109
|
});
|
|
94
110
|
```
|
|
95
111
|
|
|
112
|
+
</details>
|
|
113
|
+
|
|
96
114
|
📖 **Full API documentation**: [oorabona.github.io/node-liblzma](https://oorabona.github.io/node-liblzma/)
|
|
97
115
|
|
|
98
|
-
|
|
116
|
+
## What's New
|
|
117
|
+
|
|
118
|
+
### v3.0.0 — Browser & WASM Support
|
|
119
|
+
|
|
120
|
+
> **[Live Demo](https://oorabona.github.io/node-liblzma/demo/)** — Try XZ compression in your browser.
|
|
121
|
+
|
|
122
|
+
- **Browser/WASM support**: Full XZ compression and decompression via WebAssembly
|
|
123
|
+
- Same API as Node.js (`xzAsync`, `unxzAsync`, `createXz`, `createUnxz`)
|
|
124
|
+
- WASM binary: ~52KB gzipped (under 100KB budget)
|
|
125
|
+
- Web Streams API for streaming compression/decompression
|
|
126
|
+
- Zero-config inline mode: `import from 'node-liblzma/inline'`
|
|
127
|
+
- **CLI tool (nxz)**: Portable xz-like command line tool
|
|
128
|
+
- Full xz compatibility: `-z`, `-d`, `-l`, `-k`, `-f`, `-c`, `-o`, `-v`, `-q`
|
|
129
|
+
- Compression presets 0-9 with extreme mode (`-e`)
|
|
130
|
+
- Progress display, stdin/stdout piping, benchmarking (`-B`)
|
|
131
|
+
- **Progress events**: Monitor compression/decompression in real-time
|
|
132
|
+
- **XZ Utils 5.8.x**: Updated to latest stable version
|
|
133
|
+
- **458+ tests**: Comprehensive test suite with 100% code coverage
|
|
134
|
+
|
|
135
|
+
### v2.0.0 — TypeScript Modernization
|
|
136
|
+
|
|
137
|
+
- **Full TypeScript migration**: Complete rewrite from CoffeeScript
|
|
138
|
+
- **Promise-based APIs**: `xzAsync()` and `unxzAsync()`
|
|
139
|
+
- **Modern tooling**: Vitest, Biome, pnpm, pre-commit hooks
|
|
140
|
+
- **Node.js >= 16** required (updated from >= 12)
|
|
141
|
+
|
|
142
|
+
<details>
|
|
143
|
+
<summary><strong>Legacy (N-API migration)</strong></summary>
|
|
144
|
+
|
|
145
|
+
In previous versions, [N-API](https://nodejs.org/api/n-api.html) replaced [nan](https://github.com/nodejs/nan) as the stable ABI for native modules.
|
|
146
|
+
|
|
147
|
+
Tested on: Linux x64, macOS (x64/arm64), Raspberry Pi 2/3/4, Windows.
|
|
148
|
+
|
|
149
|
+
**Prebuilt binaries** are bundled for: Windows x64, Linux x64, macOS x64/arm64.
|
|
150
|
+
|
|
151
|
+
| Flag | Description | Default | Values |
|
|
152
|
+
|------|-------------|---------|--------|
|
|
153
|
+
| `USE_GLOBAL` | Use system liblzma library | `yes` (`no` on Windows) | `yes`, `no` |
|
|
154
|
+
| `RUNTIME_LINK` | Static or shared linking | `shared` | `static`, `shared` |
|
|
155
|
+
| `ENABLE_THREAD_SUPPORT` | Enable thread support | `yes` | `yes`, `no` |
|
|
156
|
+
|
|
157
|
+
If no prebuilt binary matches your platform, `node-gyp` will compile from source automatically.
|
|
158
|
+
|
|
159
|
+
</details>
|
|
160
|
+
|
|
161
|
+
## Browser Usage
|
|
162
|
+
|
|
163
|
+
> **[Live Demo](https://oorabona.github.io/node-liblzma/demo/)** — Try XZ compression in your browser right now.
|
|
164
|
+
|
|
165
|
+
node-liblzma v3.0.0+ supports XZ compression in the browser via WebAssembly. The same API works in both Node.js and browsers — bundlers (Vite, Webpack, esbuild) automatically resolve the WASM-backed implementation.
|
|
166
|
+
|
|
167
|
+
### Basic Usage
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// Bundlers auto-resolve to WASM in browser, native in Node.js
|
|
171
|
+
import { xzAsync, unxzAsync, isXZ } from 'node-liblzma';
|
|
172
|
+
|
|
173
|
+
// Compress
|
|
174
|
+
const compressed = await xzAsync('Hello, browser!');
|
|
175
|
+
|
|
176
|
+
// Decompress
|
|
177
|
+
const original = await unxzAsync(compressed);
|
|
178
|
+
|
|
179
|
+
// Check if data is XZ-compressed
|
|
180
|
+
if (isXZ(someBuffer)) {
|
|
181
|
+
const data = await unxzAsync(someBuffer);
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Streaming with Web Streams API
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { createXz, createUnxz } from 'node-liblzma';
|
|
189
|
+
|
|
190
|
+
// Compress a fetch response
|
|
191
|
+
const response = await fetch('/large-file.bin');
|
|
192
|
+
const compressed = response.body.pipeThrough(createXz({ preset: 6 }));
|
|
193
|
+
|
|
194
|
+
// Decompress
|
|
195
|
+
const decompressed = compressedStream.pipeThrough(createUnxz());
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Import Modes
|
|
199
|
+
|
|
200
|
+
| Import | When to use |
|
|
201
|
+
|--------|-------------|
|
|
202
|
+
| `node-liblzma` | Standard — bundler resolves to WASM (browser) or native (Node.js) |
|
|
203
|
+
| `node-liblzma/wasm` | Explicit WASM usage in Node.js (no native addon needed) |
|
|
204
|
+
| `node-liblzma/inline` | Zero-config — WASM embedded as base64 (no external file to serve) |
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
// Explicit WASM (works in Node.js too, no native build required)
|
|
208
|
+
import { xzAsync } from 'node-liblzma/wasm';
|
|
209
|
+
|
|
210
|
+
// Inline mode (larger bundle, but no WASM file to configure)
|
|
211
|
+
import { ensureInlineInit, xzAsync } from 'node-liblzma/inline';
|
|
212
|
+
await ensureInlineInit(); // Decodes embedded base64 WASM
|
|
213
|
+
const compressed = await xzAsync(data);
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Browser Limitations
|
|
217
|
+
|
|
218
|
+
- **No sync APIs**: `xzSync()` / `unxzSync()` throw `LZMAError` in browsers
|
|
219
|
+
- **Presets 0-6 only**: Presets 7-9 require more memory than WASM's 256MB limit
|
|
220
|
+
- **No filesystem**: `xzFile()` / `unxzFile()` are not available
|
|
221
|
+
- **No Node Streams**: Use `createXz()` / `createUnxz()` (Web TransformStream) instead of `Xz` / `Unxz` classes
|
|
222
|
+
|
|
223
|
+
### Bundle Size
|
|
224
|
+
|
|
225
|
+
| Component | Raw | Gzipped |
|
|
226
|
+
|-----------|-----|---------|
|
|
227
|
+
| liblzma.wasm | ~107KB | ~52KB |
|
|
228
|
+
| Glue code (liblzma.js) | ~6KB | ~2KB |
|
|
229
|
+
| **Total** | **~113KB** | **~54KB** |
|
|
230
|
+
|
|
231
|
+
For detailed browser setup instructions, see [docs/BROWSER.md](docs/BROWSER.md).
|
|
232
|
+
|
|
233
|
+
## CLI Tool (nxz)
|
|
99
234
|
|
|
100
235
|
This package includes `nxz`, a portable xz-like CLI tool that works on any platform with Node.js.
|
|
101
236
|
|
|
102
|
-
|
|
237
|
+
### Installation
|
|
103
238
|
|
|
104
239
|
```bash
|
|
105
240
|
# Global installation (recommended for CLI usage)
|
|
106
241
|
npm install -g node-liblzma
|
|
107
|
-
# or
|
|
108
|
-
pnpm add -g node-liblzma
|
|
109
242
|
|
|
110
243
|
# Then use directly
|
|
111
244
|
nxz --help
|
|
112
245
|
```
|
|
113
246
|
|
|
114
|
-
|
|
247
|
+
### Quick Examples
|
|
115
248
|
|
|
116
249
|
```bash
|
|
117
250
|
# Compress a file (creates file.txt.xz, deletes original)
|
|
@@ -123,41 +256,27 @@ nxz file.txt.xz
|
|
|
123
256
|
# Keep original file (-k)
|
|
124
257
|
nxz -k file.txt
|
|
125
258
|
|
|
126
|
-
# Decompress explicitly (-d)
|
|
127
|
-
nxz -d archive.xz
|
|
128
|
-
|
|
129
259
|
# Maximum compression (-9) with extreme mode (-e)
|
|
130
260
|
nxz -9e large-file.bin
|
|
131
261
|
|
|
132
262
|
# Compress to stdout (-c) for piping
|
|
133
263
|
nxz -c file.txt > file.txt.xz
|
|
134
264
|
|
|
135
|
-
#
|
|
136
|
-
nxz -dc file.txt.xz | grep "pattern"
|
|
137
|
-
|
|
138
|
-
# Custom output file (-o)
|
|
139
|
-
nxz -d archive.xz -o /tmp/output.bin
|
|
140
|
-
|
|
141
|
-
# List archive info (-l)
|
|
265
|
+
# List archive info (-l / -lv for verbose)
|
|
142
266
|
nxz -l file.txt.xz
|
|
143
267
|
|
|
144
|
-
#
|
|
145
|
-
nxz -
|
|
146
|
-
|
|
147
|
-
# Compress from stdin
|
|
148
|
-
cat file.txt | nxz -c > file.txt.xz
|
|
149
|
-
|
|
150
|
-
# Quiet mode - suppress warnings (-q)
|
|
151
|
-
nxz -q file.txt
|
|
268
|
+
# Benchmark native vs WASM performance (-B)
|
|
269
|
+
nxz -B file.txt
|
|
152
270
|
```
|
|
153
271
|
|
|
154
|
-
|
|
272
|
+
### All Options
|
|
155
273
|
|
|
156
274
|
| Option | Long | Description |
|
|
157
275
|
|--------|------|-------------|
|
|
158
276
|
| `-z` | `--compress` | Force compression mode |
|
|
159
277
|
| `-d` | `--decompress` | Force decompression mode |
|
|
160
278
|
| `-l` | `--list` | List archive information |
|
|
279
|
+
| `-B` | `--benchmark` | Benchmark native vs WASM performance |
|
|
161
280
|
| `-k` | `--keep` | Keep original file (don't delete) |
|
|
162
281
|
| `-f` | `--force` | Overwrite existing output file |
|
|
163
282
|
| `-c` | `--stdout` | Write to stdout, keep original file |
|
|
@@ -169,18 +288,20 @@ nxz -q file.txt
|
|
|
169
288
|
| `-h` | `--help` | Show help |
|
|
170
289
|
| `-V` | `--version` | Show version |
|
|
171
290
|
|
|
172
|
-
|
|
291
|
+
<details>
|
|
292
|
+
<summary><strong>One-shot usage (without global install)</strong></summary>
|
|
173
293
|
|
|
174
294
|
```bash
|
|
175
295
|
# npm/npx
|
|
176
296
|
npx --package node-liblzma nxz --help
|
|
177
|
-
npx -p node-liblzma nxz file.txt
|
|
178
297
|
|
|
179
298
|
# pnpm
|
|
180
299
|
pnpm dlx --package node-liblzma nxz --help
|
|
181
300
|
```
|
|
182
301
|
|
|
183
|
-
|
|
302
|
+
</details>
|
|
303
|
+
|
|
304
|
+
### Exit Codes
|
|
184
305
|
|
|
185
306
|
| Code | Meaning |
|
|
186
307
|
|------|---------|
|
|
@@ -188,92 +309,11 @@ pnpm dlx --package node-liblzma nxz --help
|
|
|
188
309
|
| 1 | Error (file not found, format error, etc.) |
|
|
189
310
|
| 130 | Interrupted (SIGINT/Ctrl+C) |
|
|
190
311
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
## Latest Updates (2026)
|
|
194
|
-
|
|
195
|
-
* **CLI Tool (nxz)**: Portable xz-like command line tool included in the package
|
|
196
|
-
- Full xz compatibility: `-z`, `-d`, `-l`, `-k`, `-f`, `-c`, `-o`, `-v`, `-q`
|
|
197
|
-
- Compression presets 0-9 with extreme mode (`-e`)
|
|
198
|
-
- Progress display for large files, stdin/stdout piping
|
|
199
|
-
- Works on any platform with Node.js
|
|
200
|
-
- See [Command Line Interface](#command-line-interface-nxz) section
|
|
201
|
-
* **Progress Events**: Monitor compression/decompression progress with real-time events
|
|
202
|
-
```typescript
|
|
203
|
-
const compressor = createXz();
|
|
204
|
-
compressor.on('progress', ({ bytesRead, bytesWritten }) => {
|
|
205
|
-
console.log(`Read: ${bytesRead}, Written: ${bytesWritten}`);
|
|
206
|
-
});
|
|
207
|
-
```
|
|
208
|
-
* **API Documentation**: Full TypeDoc documentation with Material theme at [oorabona.github.io/node-liblzma](https://oorabona.github.io/node-liblzma/)
|
|
209
|
-
* **XZ Utils 5.8.2**: Updated to latest stable version
|
|
210
|
-
|
|
211
|
-
## Version 2.0 (2025) - Complete Modernization
|
|
212
|
-
|
|
213
|
-
This major release brings the library into 2025 with modern tooling and TypeScript support:
|
|
214
|
-
|
|
215
|
-
* **Full TypeScript migration**: Complete rewrite from CoffeeScript to TypeScript for better type safety and developer experience
|
|
216
|
-
* **Promise-based APIs**: New async functions `xzAsync()` and `unxzAsync()` with Promise support
|
|
217
|
-
* **Modern testing**: Migrated from Mocha to Vitest with improved performance and better TypeScript integration
|
|
218
|
-
* **Enhanced tooling**:
|
|
219
|
-
- [Biome](https://biomejs.dev/) for fast linting and formatting
|
|
220
|
-
- Pre-commit hooks with nano-staged and simple-git-hooks
|
|
221
|
-
- pnpm as package manager for better dependency management
|
|
222
|
-
* **Updated Node.js support**: Requires Node.js >= 16 (updated from >= 12)
|
|
223
|
-
|
|
224
|
-
## Legacy (N-API migration)
|
|
225
|
-
|
|
226
|
-
In previous versions, [N-API](https://nodejs.org/api/n-api.html) became the _de facto_ standard to provide stable ABI API for NodeJS Native Modules, replacing [nan](https://github.com/nodejs/nan).
|
|
227
|
-
|
|
228
|
-
It has been tested and works on:
|
|
229
|
-
|
|
230
|
-
* Linux x64 (Ubuntu)
|
|
231
|
-
* OSX (`macos-11`)
|
|
232
|
-
* Raspberry Pi 2/3/4 (both on 32-bit and 64-bit architectures)
|
|
233
|
-
* Windows (`windows-2019` and `windows-2022` are part of GitHub CI)
|
|
234
|
-
|
|
235
|
-
> Notes:
|
|
236
|
-
>
|
|
237
|
-
> * For [Windows](https://github.com/oorabona/node-liblzma/actions/workflows/ci-windows.yml)
|
|
238
|
-
> There is no "global" installation of the LZMA library on the Windows machine provisionned by GitHub, so it is pointless to build with this config
|
|
239
|
-
>
|
|
240
|
-
* For [Linux](https://github.com/oorabona/node-liblzma/actions/workflows/ci-linux.yml)
|
|
312
|
+
## API Reference
|
|
241
313
|
|
|
242
|
-
|
|
314
|
+
### API Comparison with Zlib
|
|
243
315
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
Several prebuilt versions are bundled within the package.
|
|
247
|
-
|
|
248
|
-
* Windows x86_64
|
|
249
|
-
* Linux x86_64
|
|
250
|
-
* MacOS x86_64 / Arm64
|
|
251
|
-
|
|
252
|
-
If your OS/architecture matches, you will use this version which has been compiled using the following default flags:
|
|
253
|
-
|
|
254
|
-
| Flag | Description | Default | Values |
|
|
255
|
-
|------|-------------|---------|--------|
|
|
256
|
-
| `USE_GLOBAL` | Use system liblzma library | `yes` (`no` on Windows) | `yes`, `no` |
|
|
257
|
-
| `RUNTIME_LINK` | Static or shared linking | `shared` | `static`, `shared` |
|
|
258
|
-
| `ENABLE_THREAD_SUPPORT` | Enable thread support | `yes` | `yes`, `no` |
|
|
259
|
-
|
|
260
|
-
If not `node-gyp` will automagically start compiling stuff according to the environment variables set, or the default values above.
|
|
261
|
-
|
|
262
|
-
If you want to change compilation flags, please read on [here](#installation).
|
|
263
|
-
|
|
264
|
-
# Related projects
|
|
265
|
-
|
|
266
|
-
Thanks to the community, there are several choices out there:
|
|
267
|
-
|
|
268
|
-
* [lzma-purejs](https://github.com/cscott/lzma-purejs)
|
|
269
|
-
A pure JavaScript implementation of the algorithm
|
|
270
|
-
* [node-xz](https://github.com/robey/node-xz)
|
|
271
|
-
Node binding of XZ library
|
|
272
|
-
* [lzma-native](https://github.com/addaleax/lzma-native)
|
|
273
|
-
A very complete implementation of XZ library bindings
|
|
274
|
-
* Others are also available but they fork "xz" process in the background.
|
|
275
|
-
|
|
276
|
-
# API comparison
|
|
316
|
+
The API mirrors Node.js Zlib for easy adoption:
|
|
277
317
|
|
|
278
318
|
```js
|
|
279
319
|
// CommonJS
|
|
@@ -296,9 +336,7 @@ import * as lzma from 'node-liblzma';
|
|
|
296
336
|
| - | `xzFile` | `(input, output, [options])` → `Promise<void>` |
|
|
297
337
|
| - | `unxzFile` | `(input, output, [options])` → `Promise<void>` |
|
|
298
338
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
The `options` object accepts the following attributes:
|
|
339
|
+
### Options
|
|
302
340
|
|
|
303
341
|
| Attribute | Type | Description | Values |
|
|
304
342
|
|-----------|------|-------------|--------|
|
|
@@ -309,15 +347,13 @@ The `options` object accepts the following attributes:
|
|
|
309
347
|
| `filters` | array | Filter chain | `filter.LZMA2`, `filter.X86`, `filter.ARM`, etc. |
|
|
310
348
|
| `chunkSize` | number | Processing chunk size | Default: 64KB |
|
|
311
349
|
|
|
312
|
-
For further information
|
|
350
|
+
For further information, see the [XZ SDK documentation](http://7-zip.org/sdk.html).
|
|
313
351
|
|
|
314
352
|
## Advanced Configuration
|
|
315
353
|
|
|
316
354
|
### Thread Support
|
|
317
355
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
**Thread values:**
|
|
356
|
+
Multi-threaded compression is available when built with `ENABLE_THREAD_SUPPORT=yes` (default).
|
|
321
357
|
|
|
322
358
|
| Value | Behavior |
|
|
323
359
|
|-------|----------|
|
|
@@ -325,26 +361,15 @@ The library supports multi-threaded compression when built with `ENABLE_THREAD_S
|
|
|
325
361
|
| `1` | Single-threaded (default) |
|
|
326
362
|
| `N` | Use exactly N threads |
|
|
327
363
|
|
|
328
|
-
**Example:**
|
|
329
|
-
|
|
330
364
|
```typescript
|
|
331
365
|
import { createXz, hasThreads } from 'node-liblzma';
|
|
332
366
|
|
|
333
|
-
// Check if threading is available
|
|
334
367
|
if (hasThreads()) {
|
|
335
|
-
|
|
336
|
-
const compressor = createXz({ threads: 0 });
|
|
337
|
-
|
|
338
|
-
// Or specify exact thread count
|
|
339
|
-
const compressor4 = createXz({ threads: 4 });
|
|
368
|
+
const compressor = createXz({ threads: 0 }); // auto-detect
|
|
340
369
|
}
|
|
341
370
|
```
|
|
342
371
|
|
|
343
|
-
**
|
|
344
|
-
- Thread support only applies to **compression**, not decompression
|
|
345
|
-
- Requires LZMA library built with pthread support (`ENABLE_THREAD_SUPPORT=yes`)
|
|
346
|
-
- Default is `threads: 1` (single-threaded) for predictable behavior
|
|
347
|
-
- Check availability: `hasThreads()` returns `true` if multi-threading is supported
|
|
372
|
+
> **Note**: Threads only apply to compression, not decompression.
|
|
348
373
|
|
|
349
374
|
### Progress Monitoring
|
|
350
375
|
|
|
@@ -357,65 +382,52 @@ const compressor = createXz({ preset: 6 });
|
|
|
357
382
|
|
|
358
383
|
compressor.on('progress', ({ bytesRead, bytesWritten }) => {
|
|
359
384
|
const ratio = bytesWritten / bytesRead;
|
|
360
|
-
console.log(`Progress: ${bytesRead}
|
|
361
|
-
});
|
|
362
|
-
|
|
363
|
-
// Works with both compression and decompression
|
|
364
|
-
const decompressor = createUnxz();
|
|
365
|
-
decompressor.on('progress', ({ bytesRead, bytesWritten }) => {
|
|
366
|
-
console.log(`Decompressing: ${bytesRead} → ${bytesWritten} bytes`);
|
|
385
|
+
console.log(`Progress: ${bytesRead} in, ${bytesWritten} out (ratio: ${ratio.toFixed(2)})`);
|
|
367
386
|
});
|
|
368
387
|
|
|
369
388
|
inputStream.pipe(compressor).pipe(outputStream);
|
|
370
389
|
```
|
|
371
390
|
|
|
372
|
-
|
|
373
|
-
- Progress events fire after each chunk is processed
|
|
374
|
-
- `bytesRead`: Total input bytes processed so far
|
|
375
|
-
- `bytesWritten`: Total output bytes produced so far
|
|
376
|
-
- Works with streams, not buffer APIs (`xz`/`unxz`)
|
|
391
|
+
Progress events fire after each chunk is processed. Works with streams, not buffer APIs.
|
|
377
392
|
|
|
378
|
-
###
|
|
393
|
+
### Concurrency Control with LZMAPool
|
|
379
394
|
|
|
380
|
-
For
|
|
395
|
+
For production environments with high concurrency needs:
|
|
381
396
|
|
|
382
397
|
```typescript
|
|
383
|
-
|
|
384
|
-
preset: lzma.preset.DEFAULT,
|
|
385
|
-
chunkSize: 256 * 1024 // 256KB chunks (default: 64KB)
|
|
386
|
-
});
|
|
387
|
-
```
|
|
398
|
+
import { LZMAPool } from 'node-liblzma';
|
|
388
399
|
|
|
389
|
-
|
|
390
|
-
- **Small files (< 1MB)**: Use default 64KB chunks
|
|
391
|
-
- **Medium files (1-10MB)**: Use 128-256KB chunks
|
|
392
|
-
- **Large files (> 10MB)**: Use 512KB-1MB chunks
|
|
393
|
-
- **Maximum buffer size**: 512MB per operation (security limit)
|
|
400
|
+
const pool = new LZMAPool(10); // Max 10 concurrent operations
|
|
394
401
|
|
|
395
|
-
|
|
402
|
+
pool.on('metrics', (metrics) => {
|
|
403
|
+
console.log(`Active: ${metrics.active}, Queued: ${metrics.queued}`);
|
|
404
|
+
});
|
|
396
405
|
|
|
397
|
-
|
|
406
|
+
const compressed = await pool.compress(buffer);
|
|
407
|
+
const decompressed = await pool.decompress(compressed);
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
### File Compression Helpers
|
|
398
411
|
|
|
399
412
|
```typescript
|
|
400
|
-
import {
|
|
401
|
-
import { createXz } from 'node-liblzma';
|
|
413
|
+
import { xzFile, unxzFile } from 'node-liblzma';
|
|
402
414
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
415
|
+
await xzFile('input.txt', 'output.txt.xz');
|
|
416
|
+
await unxzFile('output.txt.xz', 'restored.txt');
|
|
417
|
+
|
|
418
|
+
// With options
|
|
419
|
+
await xzFile('large-file.bin', 'compressed.xz', { preset: 9, threads: 4 });
|
|
406
420
|
```
|
|
407
421
|
|
|
422
|
+
Handles files > 512MB automatically via streams with lower memory footprint.
|
|
423
|
+
|
|
408
424
|
### Error Handling
|
|
409
425
|
|
|
410
|
-
|
|
426
|
+
Typed error classes for precise error handling:
|
|
411
427
|
|
|
412
428
|
```typescript
|
|
413
429
|
import {
|
|
414
|
-
xzAsync,
|
|
415
|
-
LZMAError,
|
|
416
|
-
LZMAMemoryError,
|
|
417
|
-
LZMADataError,
|
|
418
|
-
LZMAFormatError
|
|
430
|
+
xzAsync, LZMAError, LZMAMemoryError, LZMADataError, LZMAFormatError
|
|
419
431
|
} from 'node-liblzma';
|
|
420
432
|
|
|
421
433
|
try {
|
|
@@ -427,339 +439,106 @@ try {
|
|
|
427
439
|
console.error('Corrupt data:', error.message);
|
|
428
440
|
} else if (error instanceof LZMAFormatError) {
|
|
429
441
|
console.error('Invalid format:', error.message);
|
|
430
|
-
} else {
|
|
431
|
-
console.error('Unknown error:', error);
|
|
432
442
|
}
|
|
433
443
|
}
|
|
434
444
|
```
|
|
435
445
|
|
|
436
|
-
**Available error classes
|
|
437
|
-
- `LZMAError` - Base error class
|
|
438
|
-
- `LZMAMemoryError` - Memory allocation failed
|
|
439
|
-
- `LZMAMemoryLimitError` - Memory limit exceeded
|
|
440
|
-
- `LZMAFormatError` - Unrecognized file format
|
|
441
|
-
- `LZMAOptionsError` - Invalid compression options
|
|
442
|
-
- `LZMADataError` - Corrupt compressed data
|
|
443
|
-
- `LZMABufferError` - Buffer size issues
|
|
444
|
-
- `LZMAProgrammingError` - Internal errors
|
|
445
|
-
|
|
446
|
-
### Error Recovery
|
|
447
|
-
|
|
448
|
-
Streams automatically handle recoverable errors and provide state transition hooks:
|
|
449
|
-
|
|
450
|
-
```typescript
|
|
451
|
-
const decompressor = createUnxz();
|
|
452
|
-
|
|
453
|
-
decompressor.on('error', (error) => {
|
|
454
|
-
console.error('Decompression error:', error.errno, error.message);
|
|
455
|
-
// Stream will emit 'close' event after error
|
|
456
|
-
});
|
|
457
|
-
|
|
458
|
-
decompressor.on('close', () => {
|
|
459
|
-
console.log('Stream closed, safe to cleanup');
|
|
460
|
-
});
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Concurrency Control with LZMAPool
|
|
446
|
+
**Available error classes**: `LZMAError` (base), `LZMAMemoryError`, `LZMAMemoryLimitError`, `LZMAFormatError`, `LZMAOptionsError`, `LZMADataError`, `LZMABufferError`, `LZMAProgrammingError`.
|
|
464
447
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
```typescript
|
|
468
|
-
import { LZMAPool } from 'node-liblzma';
|
|
469
|
-
|
|
470
|
-
const pool = new LZMAPool(10); // Max 10 concurrent operations
|
|
471
|
-
|
|
472
|
-
// Monitor pool metrics
|
|
473
|
-
pool.on('metrics', (metrics) => {
|
|
474
|
-
console.log(`Active: ${metrics.active}, Queued: ${metrics.queued}`);
|
|
475
|
-
console.log(`Completed: ${metrics.completed}, Failed: ${metrics.failed}`);
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
// Compress with automatic queuing
|
|
479
|
-
const compressed = await pool.compress(buffer);
|
|
480
|
-
const decompressed = await pool.decompress(compressed);
|
|
481
|
-
|
|
482
|
-
// Get current metrics
|
|
483
|
-
const status = pool.getMetrics();
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
**Pool Events:**
|
|
487
|
-
- `queue` - Task added to queue
|
|
488
|
-
- `start` - Task started processing
|
|
489
|
-
- `complete` - Task completed successfully
|
|
490
|
-
- `error-task` - Task failed
|
|
491
|
-
- `metrics` - Metrics updated (after each state change)
|
|
492
|
-
|
|
493
|
-
**Benefits:**
|
|
494
|
-
- ✅ Automatic backpressure
|
|
495
|
-
- ✅ Prevents resource exhaustion
|
|
496
|
-
- ✅ Production-ready monitoring
|
|
497
|
-
- ✅ Zero breaking changes (opt-in)
|
|
498
|
-
|
|
499
|
-
### File Compression Helpers
|
|
500
|
-
|
|
501
|
-
Simplified API for file-based compression:
|
|
448
|
+
### Buffer Size Optimization
|
|
502
449
|
|
|
503
450
|
```typescript
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
//
|
|
507
|
-
await xzFile('input.txt', 'output.txt.xz');
|
|
508
|
-
|
|
509
|
-
// Decompress a file
|
|
510
|
-
await unxzFile('output.txt.xz', 'restored.txt');
|
|
511
|
-
|
|
512
|
-
// With options
|
|
513
|
-
await xzFile('large-file.bin', 'compressed.xz', {
|
|
514
|
-
preset: 9,
|
|
515
|
-
threads: 4
|
|
451
|
+
const stream = createXz({
|
|
452
|
+
preset: lzma.preset.DEFAULT,
|
|
453
|
+
chunkSize: 256 * 1024 // 256KB chunks (default: 64KB)
|
|
516
454
|
});
|
|
517
455
|
```
|
|
518
456
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
## Async callback contract (errno-based)
|
|
526
|
-
|
|
527
|
-
The low-level native callback used internally by streams follows an errno-style contract to match liblzma behavior and to avoid mixing exception channels:
|
|
528
|
-
|
|
529
|
-
- Signature: `(errno: number, availInAfter: number, availOutAfter: number)`
|
|
530
|
-
- Success: `errno` is either `LZMA_OK` or `LZMA_STREAM_END`.
|
|
531
|
-
- Recoverable/other conditions: any other `errno` value (for example, `LZMA_BUF_ERROR`, `LZMA_DATA_ERROR`, `LZMA_PROG_ERROR`) indicates an error state.
|
|
532
|
-
- Streams emit `onerror` with the numeric `errno` when `errno !== LZMA_OK && errno !== LZMA_STREAM_END`.
|
|
533
|
-
|
|
534
|
-
Why errno instead of JS exceptions?
|
|
535
|
-
|
|
536
|
-
- The binding mirrors liblzma’s status codes and keeps a single error channel that’s easy to reason about in tight processing loops.
|
|
537
|
-
- This avoids throwing across async worker boundaries and keeps cleanup deterministic.
|
|
538
|
-
|
|
539
|
-
High-level APIs remain ergonomic:
|
|
540
|
-
|
|
541
|
-
- Promise-based functions `xzAsync()`/`unxzAsync()` still resolve to `Buffer` or reject with `Error` as expected.
|
|
542
|
-
- Stream users can listen to `error` events, where we map `errno` to a human-friendly message (`messages[errno]`).
|
|
543
|
-
|
|
544
|
-
If you prefer Node’s error-first callbacks, you can wrap the APIs and translate `errno` to `Error` objects at your boundaries without changing the native layer.
|
|
545
|
-
|
|
546
|
-
# Installation
|
|
547
|
-
|
|
548
|
-
Well, as simple as this one-liner:
|
|
549
|
-
|
|
550
|
-
```sh
|
|
551
|
-
npm i node-liblzma --save
|
|
552
|
-
```
|
|
553
|
-
|
|
554
|
-
--OR--
|
|
555
|
-
|
|
556
|
-
```sh
|
|
557
|
-
yarn add node-liblzma
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
--OR-- (recommended for development)
|
|
457
|
+
| File Size | Recommended chunkSize |
|
|
458
|
+
|-----------|-----------------------|
|
|
459
|
+
| < 1MB | 64KB (default) |
|
|
460
|
+
| 1-10MB | 128-256KB |
|
|
461
|
+
| > 10MB | 512KB-1MB |
|
|
561
462
|
|
|
562
|
-
|
|
563
|
-
pnpm add node-liblzma
|
|
564
|
-
```
|
|
463
|
+
Maximum buffer size: 512MB per operation (security limit). For larger files, use streaming APIs.
|
|
565
464
|
|
|
566
|
-
|
|
465
|
+
### Async Callback Contract (errno-based)
|
|
567
466
|
|
|
568
|
-
|
|
569
|
-
ENABLE_THREAD_SUPPORT=no npm install node-liblzma --build-from-source
|
|
570
|
-
```
|
|
467
|
+
The low-level native callback follows an errno-style contract matching liblzma behavior:
|
|
571
468
|
|
|
572
|
-
|
|
573
|
-
|
|
469
|
+
- **Signature**: `(errno: number, availInAfter: number, availOutAfter: number)`
|
|
470
|
+
- **Success**: `errno` is `LZMA_OK` or `LZMA_STREAM_END`
|
|
471
|
+
- **Error**: any other `errno` value
|
|
574
472
|
|
|
575
|
-
|
|
473
|
+
High-level APIs remain ergonomic — Promise functions resolve to `Buffer` or reject with `Error`, stream users listen to `error` events.
|
|
576
474
|
|
|
577
|
-
|
|
578
|
-
2. Ask the build system to download `xz` and build it
|
|
579
|
-
3. Compile `xz` yourself, outside `node-liblzma`, and have it use it after
|
|
475
|
+
## Benchmark
|
|
580
476
|
|
|
581
|
-
|
|
477
|
+
### Performance Hierarchy
|
|
582
478
|
|
|
583
|
-
|
|
479
|
+
All three backends use the same liblzma library and produce **identical compression ratios**:
|
|
584
480
|
|
|
585
481
|
```
|
|
586
|
-
|
|
482
|
+
System xz > nxz native (C++ addon) > nxz WASM (Emscripten)
|
|
483
|
+
fastest ~1-2x slower ~2-5x slower (decompress)
|
|
484
|
+
~1x (compress, large files)
|
|
587
485
|
```
|
|
588
486
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
If you do not plan on having a local install, you can ask for automatic download and build of whatever version of `xz` you want.
|
|
487
|
+
### Full Comparison (246 KB source code, preset 6)
|
|
592
488
|
|
|
593
|
-
|
|
489
|
+
| Backend | Compress | Decompress | Size | Environment |
|
|
490
|
+
|---------|----------|------------|------|-------------|
|
|
491
|
+
| **System `xz` 5.8** | 81 ms | 4 ms | 76.7 KB | C binary |
|
|
492
|
+
| **nxz native** | 90 ms | 3.4 ms | 76.7 KB | Node.js + C++ addon |
|
|
493
|
+
| **nxz WASM** | 86 ms | 7.9 ms | 76.7 KB | Node.js + Emscripten |
|
|
594
494
|
|
|
595
|
-
|
|
596
|
-
npm install node-liblzma --build-from-source
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
When no option is given in the commandline arguments, it will build with default values.
|
|
495
|
+
### Native vs WASM (nxz -B, preset 6)
|
|
600
496
|
|
|
601
|
-
|
|
497
|
+
| Data | Compress | Decompress | Notes |
|
|
498
|
+
|------|----------|------------|-------|
|
|
499
|
+
| 1 KB text | WASM 2.8x slower | WASM 4.9x slower | Startup overhead dominates |
|
|
500
|
+
| 135 KB binary | ~1:1 | WASM 2x slower | Compression near-parity |
|
|
501
|
+
| 246 KB source | ~1:1 | WASM 2.3x slower | Realistic workload |
|
|
502
|
+
| 1 MB random | ~1:1 | WASM 1.6x slower | Gap narrows with size |
|
|
602
503
|
|
|
603
|
-
|
|
504
|
+
<details>
|
|
505
|
+
<summary><strong>Running benchmarks</strong></summary>
|
|
604
506
|
|
|
605
|
-
|
|
507
|
+
```bash
|
|
508
|
+
# Compare nxz (native) vs system xz across file sizes
|
|
509
|
+
./scripts/benchmark.sh
|
|
510
|
+
./scripts/benchmark.sh -s 1,50,200 -p 6,9 # custom sizes/presets
|
|
511
|
+
./scripts/benchmark.sh -o csv > results.csv # export as CSV/JSON
|
|
606
512
|
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
export LD_LIBRARY_PATH=$HOME/path/to/lib:$LD_LIBRARY_PATH
|
|
513
|
+
# Compare native addon vs WASM backend
|
|
514
|
+
nxz --benchmark file.txt
|
|
515
|
+
nxz -B -3 large-file.bin # with preset 3
|
|
611
516
|
```
|
|
612
517
|
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
Once done, this should suffice:
|
|
518
|
+
</details>
|
|
616
519
|
|
|
617
|
-
|
|
618
|
-
npm install
|
|
619
|
-
```
|
|
520
|
+
### When to Use What
|
|
620
521
|
|
|
621
|
-
|
|
522
|
+
| Scenario | Recommended |
|
|
523
|
+
|----------|-------------|
|
|
524
|
+
| Browser | WASM (only option) |
|
|
525
|
+
| Node.js, performance-critical | Native addon |
|
|
526
|
+
| Node.js, no C++ toolchain available | WASM (`node-liblzma/wasm`) |
|
|
527
|
+
| Cross-platform scripts | nxz CLI |
|
|
528
|
+
| Batch processing many files | System xz |
|
|
529
|
+
| CI/CD with Node.js already installed | nxz CLI |
|
|
622
530
|
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
You can run tests with:
|
|
531
|
+
## Installation
|
|
626
532
|
|
|
627
|
-
```
|
|
628
|
-
npm
|
|
533
|
+
```bash
|
|
534
|
+
npm install node-liblzma
|
|
629
535
|
# or
|
|
630
|
-
pnpm
|
|
631
|
-
```
|
|
632
|
-
|
|
633
|
-
It will build and launch the test suite (325+ tests) with [Vitest](https://vitest.dev/) with TypeScript support and coverage reporting.
|
|
634
|
-
|
|
635
|
-
Additional testing commands:
|
|
636
|
-
|
|
637
|
-
```sh
|
|
638
|
-
# Watch mode for development
|
|
639
|
-
pnpm test:watch
|
|
640
|
-
|
|
641
|
-
# Coverage report
|
|
642
|
-
pnpm test:coverage
|
|
643
|
-
|
|
644
|
-
# Type checking
|
|
645
|
-
pnpm type-check
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
# Usage
|
|
649
|
-
|
|
650
|
-
As the API is very close to NodeJS Zlib, you will probably find a good reference
|
|
651
|
-
[there](http://www.nodejs.org/api/zlib.html).
|
|
652
|
-
|
|
653
|
-
Otherwise examples can be found as part of the test suite, so feel free to use them!
|
|
654
|
-
They are written in TypeScript with full type definitions.
|
|
655
|
-
|
|
656
|
-
# Migration Guide
|
|
657
|
-
|
|
658
|
-
## Migrating from v1.x to v2.0
|
|
659
|
-
|
|
660
|
-
Version 2.0 introduces several breaking changes along with powerful new features.
|
|
661
|
-
|
|
662
|
-
### Breaking Changes
|
|
663
|
-
|
|
664
|
-
1. **Node.js Version Requirement**
|
|
665
|
-
```diff
|
|
666
|
-
- Requires Node.js >= 12
|
|
667
|
-
+ Requires Node.js >= 16
|
|
668
|
-
```
|
|
669
|
-
|
|
670
|
-
2. **ESM Module Format**
|
|
671
|
-
```diff
|
|
672
|
-
- CommonJS: var lzma = require('node-liblzma');
|
|
673
|
-
+ ESM: import * as lzma from 'node-liblzma';
|
|
674
|
-
+ CommonJS still works via dynamic import
|
|
675
|
-
```
|
|
676
|
-
|
|
677
|
-
3. **TypeScript Migration**
|
|
678
|
-
- Source code migrated from CoffeeScript to TypeScript
|
|
679
|
-
- Full type definitions included
|
|
680
|
-
- Better IDE autocomplete and type safety
|
|
681
|
-
|
|
682
|
-
### New Features You Should Adopt
|
|
683
|
-
|
|
684
|
-
1. **Promise-based APIs** (Recommended for new code)
|
|
685
|
-
```typescript
|
|
686
|
-
// Old callback style (still works)
|
|
687
|
-
xz(buffer, (err, compressed) => {
|
|
688
|
-
if (err) throw err;
|
|
689
|
-
// use compressed
|
|
690
|
-
});
|
|
691
|
-
|
|
692
|
-
// New Promise style
|
|
693
|
-
try {
|
|
694
|
-
const compressed = await xzAsync(buffer);
|
|
695
|
-
// use compressed
|
|
696
|
-
} catch (err) {
|
|
697
|
-
// handle error
|
|
698
|
-
}
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
2. **Typed Error Classes** (Better error handling)
|
|
702
|
-
```typescript
|
|
703
|
-
import { LZMAMemoryError, LZMADataError } from 'node-liblzma';
|
|
704
|
-
|
|
705
|
-
try {
|
|
706
|
-
await unxzAsync(corruptData);
|
|
707
|
-
} catch (error) {
|
|
708
|
-
if (error instanceof LZMADataError) {
|
|
709
|
-
console.error('Corrupt compressed data');
|
|
710
|
-
} else if (error instanceof LZMAMemoryError) {
|
|
711
|
-
console.error('Out of memory');
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
3. **Concurrency Control** (For high-throughput applications)
|
|
717
|
-
```typescript
|
|
718
|
-
import { LZMAPool } from 'node-liblzma';
|
|
719
|
-
|
|
720
|
-
const pool = new LZMAPool(10); // Max 10 concurrent operations
|
|
721
|
-
|
|
722
|
-
// Automatic queuing and backpressure
|
|
723
|
-
const results = await Promise.all(
|
|
724
|
-
files.map(file => pool.compress(file))
|
|
725
|
-
);
|
|
726
|
-
```
|
|
727
|
-
|
|
728
|
-
4. **File Helpers** (Simpler file compression)
|
|
729
|
-
```typescript
|
|
730
|
-
import { xzFile, unxzFile } from 'node-liblzma';
|
|
731
|
-
|
|
732
|
-
// Compress a file (handles streaming automatically)
|
|
733
|
-
await xzFile('input.txt', 'output.txt.xz');
|
|
734
|
-
|
|
735
|
-
// Decompress a file
|
|
736
|
-
await unxzFile('output.txt.xz', 'restored.txt');
|
|
737
|
-
```
|
|
738
|
-
|
|
739
|
-
### Testing Framework Change
|
|
740
|
-
|
|
741
|
-
If you maintain tests for code using node-liblzma:
|
|
742
|
-
|
|
743
|
-
```diff
|
|
744
|
-
- Mocha test framework
|
|
745
|
-
+ Vitest test framework (faster, better TypeScript support)
|
|
536
|
+
pnpm add node-liblzma
|
|
746
537
|
```
|
|
747
538
|
|
|
748
|
-
###
|
|
539
|
+
### System Libraries
|
|
749
540
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
- **Linter**: Biome (replaces ESLint + Prettier)
|
|
753
|
-
- **Package Manager**: pnpm recommended (npm/yarn still work)
|
|
754
|
-
- **Pre-commit Hooks**: nano-staged + simple-git-hooks
|
|
755
|
-
|
|
756
|
-
# Troubleshooting
|
|
757
|
-
|
|
758
|
-
## Common Build Issues
|
|
759
|
-
|
|
760
|
-
### Issue: "Cannot find liblzma library"
|
|
761
|
-
|
|
762
|
-
**Solution**: Install system development package or let node-gyp download it:
|
|
541
|
+
If prebuilt binaries don't match your platform, install system development libraries:
|
|
763
542
|
|
|
764
543
|
```bash
|
|
765
544
|
# Debian/Ubuntu
|
|
@@ -768,374 +547,196 @@ sudo apt-get install liblzma-dev
|
|
|
768
547
|
# macOS
|
|
769
548
|
brew install xz
|
|
770
549
|
|
|
771
|
-
# Windows (
|
|
550
|
+
# Windows (automatic download and build)
|
|
772
551
|
npm install node-liblzma --build-from-source
|
|
773
552
|
```
|
|
774
553
|
|
|
775
|
-
###
|
|
776
|
-
|
|
777
|
-
**Symptoms**: Build fails with C++ compilation errors
|
|
778
|
-
|
|
779
|
-
**Solutions**:
|
|
780
|
-
1. Install build tools:
|
|
781
|
-
```bash
|
|
782
|
-
# Ubuntu/Debian
|
|
783
|
-
sudo apt-get install build-essential python3
|
|
784
|
-
|
|
785
|
-
# macOS (install Xcode Command Line Tools)
|
|
786
|
-
xcode-select --install
|
|
787
|
-
|
|
788
|
-
# Windows
|
|
789
|
-
npm install --global windows-build-tools
|
|
790
|
-
```
|
|
791
|
-
|
|
792
|
-
2. Clear build cache and retry:
|
|
793
|
-
```bash
|
|
794
|
-
rm -rf build node_modules
|
|
795
|
-
npm install
|
|
796
|
-
```
|
|
797
|
-
|
|
798
|
-
### Issue: "Prebuilt binary not found"
|
|
799
|
-
|
|
800
|
-
**Solution**: Your platform might not have prebuilt binaries. Build from source:
|
|
554
|
+
### Build from Source
|
|
801
555
|
|
|
802
556
|
```bash
|
|
557
|
+
# Force rebuild with default options
|
|
803
558
|
npm install node-liblzma --build-from-source
|
|
804
|
-
```
|
|
805
|
-
|
|
806
|
-
## Runtime Issues
|
|
807
|
-
|
|
808
|
-
### Issue: "Memory allocation failed" (LZMAMemoryError)
|
|
809
|
-
|
|
810
|
-
**Causes**:
|
|
811
|
-
- Input buffer exceeds 512MB limit (security protection)
|
|
812
|
-
- System out of memory
|
|
813
|
-
- Trying to decompress extremely large archive
|
|
814
|
-
|
|
815
|
-
**Solutions**:
|
|
816
|
-
1. For files > 512MB, use streaming APIs:
|
|
817
|
-
```typescript
|
|
818
|
-
import { createReadStream, createWriteStream } from 'fs';
|
|
819
|
-
import { createXz } from 'node-liblzma';
|
|
820
|
-
|
|
821
|
-
createReadStream('large-file.bin')
|
|
822
|
-
.pipe(createXz())
|
|
823
|
-
.pipe(createWriteStream('large-file.xz'));
|
|
824
|
-
```
|
|
825
|
-
|
|
826
|
-
2. Or use file helpers (automatically handle large files):
|
|
827
|
-
```typescript
|
|
828
|
-
await xzFile('large-file.bin', 'large-file.xz');
|
|
829
|
-
```
|
|
830
|
-
|
|
831
|
-
### Issue: "Corrupt compressed data" (LZMADataError)
|
|
832
|
-
|
|
833
|
-
**Symptoms**: Decompression fails with `LZMADataError`
|
|
834
559
|
|
|
835
|
-
|
|
836
|
-
- File is not actually XZ/LZMA compressed
|
|
837
|
-
- File is corrupted or incomplete
|
|
838
|
-
- Wrong file format (LZMA1 vs LZMA2)
|
|
839
|
-
|
|
840
|
-
**Solutions**:
|
|
841
|
-
1. Verify file format:
|
|
842
|
-
```bash
|
|
843
|
-
file compressed.xz
|
|
844
|
-
# Should show: "XZ compressed data"
|
|
845
|
-
```
|
|
846
|
-
|
|
847
|
-
2. Check file integrity:
|
|
848
|
-
```bash
|
|
849
|
-
xz -t compressed.xz
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
3. Handle errors gracefully:
|
|
853
|
-
```typescript
|
|
854
|
-
try {
|
|
855
|
-
const data = await unxzAsync(buffer);
|
|
856
|
-
} catch (error) {
|
|
857
|
-
if (error instanceof LZMADataError) {
|
|
858
|
-
console.error('Invalid or corrupt XZ file');
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
```
|
|
862
|
-
|
|
863
|
-
### Issue: Thread support warnings during compilation
|
|
864
|
-
|
|
865
|
-
**Symptoms**: Compiler warnings about `-Wmissing-field-initializers`
|
|
866
|
-
|
|
867
|
-
**Status**: This is normal and does not affect functionality. Thread support still works correctly.
|
|
868
|
-
|
|
869
|
-
**Disable thread support** (if warnings are problematic):
|
|
870
|
-
```bash
|
|
560
|
+
# Disable thread support
|
|
871
561
|
ENABLE_THREAD_SUPPORT=no npm install node-liblzma --build-from-source
|
|
872
562
|
```
|
|
873
563
|
|
|
874
|
-
|
|
564
|
+
<details>
|
|
565
|
+
<summary><strong>Custom XZ installation</strong></summary>
|
|
875
566
|
|
|
876
|
-
|
|
567
|
+
If you compiled XZ outside of node-liblzma:
|
|
877
568
|
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
xz(buffer, { threads: 4 }, (err, compressed) => {
|
|
884
|
-
// 4 threads used for compression
|
|
885
|
-
});
|
|
569
|
+
```bash
|
|
570
|
+
export CPATH=$HOME/path/to/headers
|
|
571
|
+
export LIBRARY_PATH=$HOME/path/to/lib
|
|
572
|
+
export LD_LIBRARY_PATH=$HOME/path/to/lib:$LD_LIBRARY_PATH
|
|
573
|
+
npm install
|
|
886
574
|
```
|
|
887
575
|
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
### Issue: High memory usage with concurrent operations
|
|
891
|
-
|
|
892
|
-
**Solution**: Use `LZMAPool` to limit concurrency:
|
|
576
|
+
</details>
|
|
893
577
|
|
|
894
|
-
|
|
895
|
-
import { LZMAPool } from 'node-liblzma';
|
|
896
|
-
|
|
897
|
-
const pool = new LZMAPool(5); // Limit to 5 concurrent operations
|
|
578
|
+
## Testing
|
|
898
579
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
580
|
+
```bash
|
|
581
|
+
pnpm test # Run all 458+ tests
|
|
582
|
+
pnpm test:watch # Watch mode
|
|
583
|
+
pnpm test:coverage # Coverage report
|
|
584
|
+
pnpm type-check # TypeScript type checking
|
|
903
585
|
```
|
|
904
586
|
|
|
905
|
-
|
|
587
|
+
Tests use [Vitest](https://vitest.dev/) with 100% code coverage across statements, branches, functions, and lines.
|
|
906
588
|
|
|
907
|
-
|
|
589
|
+
## Migration Guide
|
|
908
590
|
|
|
909
|
-
|
|
910
|
-
1. Install Visual Studio Build Tools:
|
|
911
|
-
```powershell
|
|
912
|
-
npm install --global windows-build-tools
|
|
913
|
-
```
|
|
591
|
+
### v1.x → v2.0
|
|
914
592
|
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
npm config set python python3
|
|
918
|
-
```
|
|
593
|
+
<details>
|
|
594
|
+
<summary><strong>Breaking changes and new features</strong></summary>
|
|
919
595
|
|
|
920
|
-
|
|
921
|
-
```powershell
|
|
922
|
-
npm install node-liblzma --build-from-source
|
|
923
|
-
```
|
|
596
|
+
#### Breaking Changes
|
|
924
597
|
|
|
925
|
-
|
|
598
|
+
1. **Node.js >= 16** required (was >= 12)
|
|
599
|
+
2. **ESM module format** (`import` instead of `require`)
|
|
600
|
+
3. **TypeScript source** (CoffeeScript removed)
|
|
926
601
|
|
|
927
|
-
|
|
602
|
+
#### New Features
|
|
928
603
|
|
|
929
|
-
**Solution**: Use forward slashes or `path.join()`:
|
|
930
604
|
```typescript
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
```
|
|
605
|
+
// Promise-based APIs (recommended)
|
|
606
|
+
const compressed = await xzAsync(buffer);
|
|
934
607
|
|
|
935
|
-
|
|
608
|
+
// Typed error classes
|
|
609
|
+
import { LZMAMemoryError, LZMADataError } from 'node-liblzma';
|
|
936
610
|
|
|
937
|
-
|
|
611
|
+
// Concurrency control
|
|
612
|
+
const pool = new LZMAPool(10);
|
|
613
|
+
const results = await Promise.all(files.map(f => pool.compress(f)));
|
|
938
614
|
|
|
939
|
-
|
|
615
|
+
// File helpers
|
|
616
|
+
await xzFile('input.txt', 'output.txt.xz');
|
|
617
|
+
```
|
|
940
618
|
|
|
941
|
-
|
|
942
|
-
```bash
|
|
943
|
-
git clone https://github.com/oorabona/node-liblzma.git
|
|
944
|
-
cd node-liblzma
|
|
945
|
-
```
|
|
619
|
+
#### Tooling Changes
|
|
946
620
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
# or
|
|
951
|
-
npm install
|
|
952
|
-
```
|
|
621
|
+
- **Linter**: Biome (replaces ESLint + Prettier)
|
|
622
|
+
- **Tests**: Vitest (replaces Mocha)
|
|
623
|
+
- **Package Manager**: pnpm recommended
|
|
953
624
|
|
|
954
|
-
|
|
955
|
-
```bash
|
|
956
|
-
pnpm build
|
|
957
|
-
```
|
|
625
|
+
</details>
|
|
958
626
|
|
|
959
|
-
|
|
960
|
-
```bash
|
|
961
|
-
pnpm test
|
|
962
|
-
```
|
|
627
|
+
## Contributing
|
|
963
628
|
|
|
964
|
-
|
|
629
|
+
We welcome contributions! See the full [contributing guidelines](#development-workflow) below.
|
|
965
630
|
|
|
966
|
-
###
|
|
631
|
+
### Development Setup
|
|
967
632
|
|
|
968
633
|
```bash
|
|
969
|
-
|
|
634
|
+
git clone https://github.com/oorabona/node-liblzma.git
|
|
635
|
+
cd node-liblzma
|
|
636
|
+
pnpm install
|
|
637
|
+
pnpm build
|
|
970
638
|
pnpm test
|
|
971
|
-
|
|
972
|
-
# Watch mode (re-run on changes)
|
|
973
|
-
pnpm test:watch
|
|
974
|
-
|
|
975
|
-
# Coverage report
|
|
976
|
-
pnpm test:coverage
|
|
977
|
-
|
|
978
|
-
# Interactive UI
|
|
979
|
-
pnpm test:ui
|
|
980
639
|
```
|
|
981
640
|
|
|
982
|
-
###
|
|
983
|
-
|
|
984
|
-
We use [Biome](https://biomejs.dev/) for linting and formatting:
|
|
641
|
+
### Development Workflow
|
|
985
642
|
|
|
986
643
|
```bash
|
|
987
|
-
#
|
|
988
|
-
pnpm
|
|
989
|
-
|
|
990
|
-
#
|
|
991
|
-
pnpm check:write
|
|
992
|
-
|
|
993
|
-
# Lint only
|
|
994
|
-
pnpm lint
|
|
995
|
-
|
|
996
|
-
# Format only
|
|
997
|
-
pnpm format:write
|
|
644
|
+
pnpm test # Run tests
|
|
645
|
+
pnpm test:watch # Watch mode
|
|
646
|
+
pnpm test:coverage # Coverage report
|
|
647
|
+
pnpm check # Lint + format check (Biome)
|
|
648
|
+
pnpm check:write # Auto-fix lint/format
|
|
649
|
+
pnpm type-check # TypeScript types
|
|
998
650
|
```
|
|
999
651
|
|
|
1000
|
-
|
|
652
|
+
We follow [Conventional Commits](https://www.conventionalcommits.org/):
|
|
1001
653
|
|
|
1002
|
-
```
|
|
1003
|
-
|
|
654
|
+
```
|
|
655
|
+
feat: add LZMAPool for concurrency control
|
|
656
|
+
fix: resolve memory leak in FunctionReference
|
|
657
|
+
docs: add migration guide for v2.0
|
|
1004
658
|
```
|
|
1005
659
|
|
|
1006
|
-
|
|
660
|
+
### Pull Request Process
|
|
1007
661
|
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
662
|
+
1. Fork and create a feature branch (`feat/`, `fix/`, `refactor/`, `docs/`)
|
|
663
|
+
2. Add tests for new functionality (100% coverage required)
|
|
664
|
+
3. Run `pnpm check:write && pnpm type-check && pnpm test`
|
|
665
|
+
4. Commit with conventional commits and push
|
|
666
|
+
5. CI checks run automatically on PR
|
|
1012
667
|
|
|
1013
|
-
##
|
|
668
|
+
## Troubleshooting
|
|
1014
669
|
|
|
1015
|
-
|
|
670
|
+
<details>
|
|
671
|
+
<summary><strong>Build issues</strong></summary>
|
|
1016
672
|
|
|
673
|
+
**"Cannot find liblzma library"** — Install system dev package:
|
|
674
|
+
```bash
|
|
675
|
+
sudo apt-get install liblzma-dev # Debian/Ubuntu
|
|
676
|
+
brew install xz # macOS
|
|
1017
677
|
```
|
|
1018
|
-
<type>(<scope>): <description>
|
|
1019
678
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
679
|
+
**"node-gyp rebuild failed"** — Install build tools:
|
|
680
|
+
```bash
|
|
681
|
+
sudo apt-get install build-essential python3 # Linux
|
|
682
|
+
xcode-select --install # macOS
|
|
683
|
+
npm install --global windows-build-tools # Windows
|
|
1023
684
|
```
|
|
1024
685
|
|
|
1025
|
-
**
|
|
1026
|
-
- `feat`: New feature
|
|
1027
|
-
- `fix`: Bug fix
|
|
1028
|
-
- `docs`: Documentation changes
|
|
1029
|
-
- `refactor`: Code refactoring
|
|
1030
|
-
- `test`: Test changes
|
|
1031
|
-
- `chore`: Build/tooling changes
|
|
1032
|
-
- `perf`: Performance improvements
|
|
1033
|
-
|
|
1034
|
-
**Examples**:
|
|
686
|
+
**"Prebuilt binary not found"** — Build from source:
|
|
1035
687
|
```bash
|
|
1036
|
-
|
|
1037
|
-
git commit -m "fix: resolve memory leak in FunctionReference"
|
|
1038
|
-
git commit -m "docs: add migration guide for v2.0"
|
|
688
|
+
npm install node-liblzma --build-from-source
|
|
1039
689
|
```
|
|
1040
690
|
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
1. **Fork the repository** and create a feature branch:
|
|
1044
|
-
```bash
|
|
1045
|
-
git checkout -b feat/my-new-feature
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
2. **Make your changes** following code style guidelines
|
|
1049
|
-
|
|
1050
|
-
3. **Add tests** for new functionality:
|
|
1051
|
-
- All new code must have 100% test coverage
|
|
1052
|
-
- Tests go in `test/` directory
|
|
1053
|
-
- Use Vitest testing framework
|
|
1054
|
-
|
|
1055
|
-
4. **Ensure all checks pass**:
|
|
1056
|
-
```bash
|
|
1057
|
-
pnpm check:write # Fix code style
|
|
1058
|
-
pnpm type-check # Verify TypeScript types
|
|
1059
|
-
pnpm test # Run test suite
|
|
1060
|
-
```
|
|
1061
|
-
|
|
1062
|
-
5. **Commit with conventional commits**:
|
|
1063
|
-
```bash
|
|
1064
|
-
git add .
|
|
1065
|
-
git commit -m "feat: add new feature"
|
|
1066
|
-
```
|
|
1067
|
-
|
|
1068
|
-
6. **Push and create Pull Request**:
|
|
1069
|
-
```bash
|
|
1070
|
-
git push origin feat/my-new-feature
|
|
1071
|
-
```
|
|
691
|
+
</details>
|
|
1072
692
|
|
|
1073
|
-
|
|
693
|
+
<details>
|
|
694
|
+
<summary><strong>Runtime issues</strong></summary>
|
|
1074
695
|
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
- **Coverage**: Maintain 100% code coverage (statements, branches, functions, lines)
|
|
1078
|
-
- **Test files**: Name tests `*.test.ts` in `test/` directory
|
|
1079
|
-
- **Structure**: Use `describe` and `it` blocks with clear descriptions
|
|
1080
|
-
- **Assertions**: Use Vitest's `expect()` API
|
|
1081
|
-
|
|
1082
|
-
**Example test**:
|
|
696
|
+
**LZMAMemoryError** — Input too large for buffer API. Use streaming:
|
|
1083
697
|
```typescript
|
|
1084
|
-
|
|
1085
|
-
import { xzAsync, unxzAsync } from '../src/lzma.js';
|
|
1086
|
-
|
|
1087
|
-
describe('Compression', () => {
|
|
1088
|
-
it('should compress and decompress data', async () => {
|
|
1089
|
-
const original = Buffer.from('test data');
|
|
1090
|
-
const compressed = await xzAsync(original);
|
|
1091
|
-
const decompressed = await unxzAsync(compressed);
|
|
1092
|
-
|
|
1093
|
-
expect(decompressed.equals(original)).toBe(true);
|
|
1094
|
-
});
|
|
1095
|
-
});
|
|
698
|
+
createReadStream('large.bin').pipe(createXz()).pipe(createWriteStream('large.xz'));
|
|
1096
699
|
```
|
|
1097
700
|
|
|
1098
|
-
|
|
701
|
+
**LZMADataError** — File is not XZ-compressed or is corrupted. Verify with `file compressed.xz` or `xz -t compressed.xz`.
|
|
1099
702
|
|
|
1100
|
-
|
|
703
|
+
**Slow on multi-core** — Enable threads: `createXz({ threads: 0 })` (auto-detect cores).
|
|
1101
704
|
|
|
1102
|
-
|
|
1103
|
-
# Standard release (patch/minor/major based on commits)
|
|
1104
|
-
pnpm release
|
|
705
|
+
**High memory with concurrency** — Use `LZMAPool` to limit simultaneous operations.
|
|
1105
706
|
|
|
1106
|
-
|
|
1107
|
-
pnpm release:manual
|
|
707
|
+
</details>
|
|
1108
708
|
|
|
1109
|
-
|
|
1110
|
-
|
|
709
|
+
<details>
|
|
710
|
+
<summary><strong>Windows-specific</strong></summary>
|
|
1111
711
|
|
|
1112
|
-
|
|
1113
|
-
|
|
712
|
+
**Build fails** — Install Visual Studio Build Tools and set Python:
|
|
713
|
+
```powershell
|
|
714
|
+
npm install --global windows-build-tools
|
|
715
|
+
npm config set python python3
|
|
1114
716
|
```
|
|
1115
717
|
|
|
1116
|
-
**
|
|
718
|
+
**Path issues** — Use `path.join()` instead of hardcoded separators.
|
|
1117
719
|
|
|
1118
|
-
|
|
720
|
+
</details>
|
|
1119
721
|
|
|
1120
|
-
|
|
1121
|
-
- **Bugs**: Open an [Issue](https://github.com/oorabona/node-liblzma/issues)
|
|
1122
|
-
- **Security**: Email security@example.com (do not open public issues)
|
|
722
|
+
## Related Projects
|
|
1123
723
|
|
|
1124
|
-
|
|
724
|
+
- [lzma-purejs](https://github.com/cscott/lzma-purejs) — Pure JavaScript LZMA implementation
|
|
725
|
+
- [node-xz](https://github.com/robey/node-xz) — Node binding of XZ library
|
|
726
|
+
- [lzma-native](https://github.com/addaleax/lzma-native) — Complete XZ library bindings
|
|
1125
727
|
|
|
1126
|
-
|
|
728
|
+
## Bugs
|
|
1127
729
|
|
|
1128
|
-
|
|
730
|
+
If you find one, feel free to contribute and post a new [issue](https://github.com/oorabona/node-liblzma/issues)!
|
|
731
|
+
PRs are accepted as well :)
|
|
1129
732
|
|
|
1130
|
-
If you
|
|
1131
|
-
|
|
733
|
+
If you compile with threads, you may see warnings about `-Wmissing-field-initializers`.
|
|
734
|
+
This is normal and does not prevent threading from being active and working.
|
|
1132
735
|
|
|
1133
|
-
|
|
736
|
+
## Acknowledgements
|
|
1134
737
|
|
|
1135
|
-
|
|
1136
|
-
This is _normal_ and does not prevent threading from being active and working.
|
|
1137
|
-
I did not yet figure how to fix this except by masking the warning..
|
|
738
|
+
Kudos to [addaleax](https://github.com/addaleax) for helping out with C++ stuff!
|
|
1138
739
|
|
|
1139
|
-
|
|
740
|
+
## License
|
|
1140
741
|
|
|
1141
|
-
This software is released under [
|
|
742
|
+
This software is released under [LGPL-3.0+](LICENSE).
|