node-liblzma 2.1.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 +431 -727
- package/index.d.ts +34 -0
- package/lib/cli/nxz.d.ts +7 -0
- package/lib/cli/nxz.d.ts.map +1 -0
- package/lib/cli/nxz.js +578 -0
- package/lib/cli/nxz.js.map +1 -0
- 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.d.ts +83 -0
- package/lib/lzma.d.ts.map +1 -1
- 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/lzma.js +78 -0
- package/lib/lzma.js.map +1 -1
- 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 +27 -3
- package/src/bindings/module.cpp +196 -0
package/index.d.ts
CHANGED
|
@@ -116,6 +116,40 @@ export declare class Unxz extends XzStream {
|
|
|
116
116
|
/** Check if threading support is available */
|
|
117
117
|
export declare function hasThreads(): boolean;
|
|
118
118
|
|
|
119
|
+
/** Check if a buffer starts with XZ magic bytes */
|
|
120
|
+
export declare function isXZ(buffer: Buffer): boolean;
|
|
121
|
+
|
|
122
|
+
/** Get the runtime liblzma version string (e.g., "5.4.1") */
|
|
123
|
+
export declare function versionString(): string;
|
|
124
|
+
|
|
125
|
+
/** Get the runtime liblzma version number (e.g., 50040010 for 5.4.1) */
|
|
126
|
+
export declare function versionNumber(): number;
|
|
127
|
+
|
|
128
|
+
/** Get memory usage estimate for encoding with given preset */
|
|
129
|
+
export declare function easyEncoderMemusage(presetLevel: number): number;
|
|
130
|
+
|
|
131
|
+
/** Get memory usage estimate for decoding */
|
|
132
|
+
export declare function easyDecoderMemusage(): number;
|
|
133
|
+
|
|
134
|
+
/** Metadata extracted from an XZ file index */
|
|
135
|
+
export interface XZFileIndex {
|
|
136
|
+
/** Uncompressed size in bytes */
|
|
137
|
+
uncompressedSize: number;
|
|
138
|
+
/** Compressed size in bytes (excluding headers) */
|
|
139
|
+
compressedSize: number;
|
|
140
|
+
/** Number of streams in the file */
|
|
141
|
+
streamCount: number;
|
|
142
|
+
/** Number of blocks in the file */
|
|
143
|
+
blockCount: number;
|
|
144
|
+
/** Integrity check type */
|
|
145
|
+
check: number;
|
|
146
|
+
/** Memory usage of the index structure */
|
|
147
|
+
memoryUsage: number;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Parse the index from a complete XZ file to get metadata */
|
|
151
|
+
export declare function parseFileIndex(buffer: Buffer): XZFileIndex;
|
|
152
|
+
|
|
119
153
|
/** Create a compression stream */
|
|
120
154
|
export declare function createXz(lzmaOptions?: LZMAOptions, options?: TransformOptions): Xz;
|
|
121
155
|
|
package/lib/cli/nxz.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nxz.d.ts","sourceRoot":"","sources":["../../src/cli/nxz.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/lib/cli/nxz.js
ADDED
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* nxz - Node.js XZ compression CLI
|
|
4
|
+
* A portable xz-like command line tool using node-liblzma
|
|
5
|
+
*/
|
|
6
|
+
import { closeSync, createReadStream, createWriteStream, existsSync, fstatSync, openSync, readFileSync, statSync, unlinkSync, writeFileSync, } from 'node:fs';
|
|
7
|
+
import { performance } from 'node:perf_hooks';
|
|
8
|
+
import { pipeline } from 'node:stream/promises';
|
|
9
|
+
import { parseArgs } from 'node:util';
|
|
10
|
+
import { check, createUnxz, createXz, hasThreads, isXZ, parseFileIndex, preset, unxzSync, versionString, xzSync, } from '../lzma.js';
|
|
11
|
+
/** Size threshold for using streams vs sync (1 MB) */
|
|
12
|
+
const STREAM_THRESHOLD_BYTES = 1024 * 1024;
|
|
13
|
+
/** Exit codes matching xz conventions */
|
|
14
|
+
const EXIT_SUCCESS = 0;
|
|
15
|
+
const EXIT_ERROR = 1;
|
|
16
|
+
const EXIT_SIGNAL = 128;
|
|
17
|
+
/** Track current output file for SIGINT cleanup */
|
|
18
|
+
let currentOutputFile = null;
|
|
19
|
+
/** Global quiet flag for warn() function */
|
|
20
|
+
let quietMode = false;
|
|
21
|
+
/**
|
|
22
|
+
* Print warning message (respects -q flag)
|
|
23
|
+
*/
|
|
24
|
+
function warn(message) {
|
|
25
|
+
if (!quietMode) {
|
|
26
|
+
console.error(message);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Setup SIGINT handler for graceful cleanup
|
|
31
|
+
*/
|
|
32
|
+
function setupSignalHandlers() {
|
|
33
|
+
process.on('SIGINT', () => {
|
|
34
|
+
// Cleanup partial output file if exists
|
|
35
|
+
if (currentOutputFile && existsSync(currentOutputFile)) {
|
|
36
|
+
try {
|
|
37
|
+
unlinkSync(currentOutputFile);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Ignore cleanup errors
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Exit with 128 + signal number (SIGINT = 2)
|
|
44
|
+
process.exit(EXIT_SIGNAL + 2);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parse command line arguments
|
|
49
|
+
*/
|
|
50
|
+
function parseCliArgs(args) {
|
|
51
|
+
// Extract preset from args (e.g., -0 through -9)
|
|
52
|
+
let presetLevel = 6; // default
|
|
53
|
+
const filteredArgs = [];
|
|
54
|
+
for (const arg of args) {
|
|
55
|
+
const presetMatch = arg.match(/^-(\d)$/);
|
|
56
|
+
if (presetMatch) {
|
|
57
|
+
presetLevel = Number.parseInt(presetMatch[1], 10);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
filteredArgs.push(arg);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const { values, positionals } = parseArgs({
|
|
64
|
+
args: filteredArgs,
|
|
65
|
+
options: {
|
|
66
|
+
compress: { type: 'boolean', short: 'z', default: false },
|
|
67
|
+
decompress: { type: 'boolean', short: 'd', default: false },
|
|
68
|
+
list: { type: 'boolean', short: 'l', default: false },
|
|
69
|
+
benchmark: { type: 'boolean', short: 'B', default: false },
|
|
70
|
+
keep: { type: 'boolean', short: 'k', default: false },
|
|
71
|
+
force: { type: 'boolean', short: 'f', default: false },
|
|
72
|
+
stdout: { type: 'boolean', short: 'c', default: false },
|
|
73
|
+
output: { type: 'string', short: 'o' },
|
|
74
|
+
verbose: { type: 'boolean', short: 'v', default: false },
|
|
75
|
+
quiet: { type: 'boolean', short: 'q', default: false },
|
|
76
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
77
|
+
version: { type: 'boolean', short: 'V', default: false },
|
|
78
|
+
extreme: { type: 'boolean', short: 'e', default: false },
|
|
79
|
+
},
|
|
80
|
+
allowPositionals: true,
|
|
81
|
+
strict: false,
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
compress: values.compress === true,
|
|
85
|
+
decompress: values.decompress === true,
|
|
86
|
+
list: values.list === true,
|
|
87
|
+
benchmark: values.benchmark === true,
|
|
88
|
+
keep: values.keep === true,
|
|
89
|
+
force: values.force === true,
|
|
90
|
+
stdout: values.stdout === true,
|
|
91
|
+
output: typeof values.output === 'string' ? values.output : null,
|
|
92
|
+
verbose: values.verbose === true,
|
|
93
|
+
quiet: values.quiet === true,
|
|
94
|
+
help: values.help === true,
|
|
95
|
+
version: values.version === true,
|
|
96
|
+
preset: presetLevel,
|
|
97
|
+
extreme: values.extreme === true,
|
|
98
|
+
files: positionals,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Print help message
|
|
103
|
+
*/
|
|
104
|
+
function printHelp() {
|
|
105
|
+
console.log(`nxz - Node.js XZ compression CLI (using node-liblzma)
|
|
106
|
+
|
|
107
|
+
Usage: nxz [OPTION]... [FILE]...
|
|
108
|
+
|
|
109
|
+
Compress or decompress FILEs in the .xz format.
|
|
110
|
+
|
|
111
|
+
Operation mode:
|
|
112
|
+
-z, --compress force compression
|
|
113
|
+
-d, --decompress force decompression
|
|
114
|
+
-l, --list list information about .xz files
|
|
115
|
+
-B, --benchmark benchmark native vs WASM compression
|
|
116
|
+
|
|
117
|
+
Operation modifiers:
|
|
118
|
+
-k, --keep keep (don't delete) input files
|
|
119
|
+
-f, --force force overwrite of output file
|
|
120
|
+
-c, --stdout write to standard output and don't delete input files
|
|
121
|
+
-o, --output=FILE write output to FILE
|
|
122
|
+
|
|
123
|
+
Compression presets:
|
|
124
|
+
-0 ... -9 compression preset level (default: 6)
|
|
125
|
+
-e, --extreme use extreme compression (slower)
|
|
126
|
+
|
|
127
|
+
Other options:
|
|
128
|
+
-v, --verbose be verbose (show progress)
|
|
129
|
+
-q, --quiet suppress warnings
|
|
130
|
+
-h, --help display this help and exit
|
|
131
|
+
-V, --version display version information and exit
|
|
132
|
+
|
|
133
|
+
With no FILE, or when FILE is -, read standard input.
|
|
134
|
+
|
|
135
|
+
Report bugs at: https://github.com/oorabona/node-liblzma/issues`);
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Print version information
|
|
139
|
+
*/
|
|
140
|
+
function printVersion() {
|
|
141
|
+
// Read package.json for nxz version
|
|
142
|
+
const packageJsonPath = new URL('../../package.json', import.meta.url);
|
|
143
|
+
let nxzVersion = 'unknown';
|
|
144
|
+
try {
|
|
145
|
+
const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
146
|
+
nxzVersion = pkg.version;
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
// Ignore error, use 'unknown'
|
|
150
|
+
}
|
|
151
|
+
const threadSupport = hasThreads() ? 'yes' : 'no';
|
|
152
|
+
const year = new Date().getFullYear();
|
|
153
|
+
console.log(`nxz ${nxzVersion}
|
|
154
|
+
node-liblzma using liblzma ${versionString()}
|
|
155
|
+
Thread support: ${threadSupport}
|
|
156
|
+
|
|
157
|
+
Copyright (C) ${year} Olivier ORABONA
|
|
158
|
+
License: LGPL-3.0`);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Determine operation mode based on options and file extension
|
|
162
|
+
*/
|
|
163
|
+
function determineMode(options, filename) {
|
|
164
|
+
if (options.benchmark)
|
|
165
|
+
return 'benchmark';
|
|
166
|
+
if (options.list)
|
|
167
|
+
return 'list';
|
|
168
|
+
if (options.decompress)
|
|
169
|
+
return 'decompress';
|
|
170
|
+
if (options.compress)
|
|
171
|
+
return 'compress';
|
|
172
|
+
// Auto-detect from extension
|
|
173
|
+
if (filename.endsWith('.xz') || filename.endsWith('.lzma')) {
|
|
174
|
+
return 'decompress';
|
|
175
|
+
}
|
|
176
|
+
return 'compress';
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get output filename based on operation mode
|
|
180
|
+
*/
|
|
181
|
+
function getOutputFilename(inputFile, mode) {
|
|
182
|
+
if (mode === 'compress') {
|
|
183
|
+
return `${inputFile}.xz`;
|
|
184
|
+
}
|
|
185
|
+
// Decompress: remove .xz or .lzma extension
|
|
186
|
+
if (inputFile.endsWith('.xz')) {
|
|
187
|
+
return inputFile.slice(0, -3);
|
|
188
|
+
}
|
|
189
|
+
if (inputFile.endsWith('.lzma')) {
|
|
190
|
+
return inputFile.slice(0, -5);
|
|
191
|
+
}
|
|
192
|
+
return `${inputFile}.out`;
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Format bytes to human-readable string
|
|
196
|
+
*/
|
|
197
|
+
function formatBytes(bytes) {
|
|
198
|
+
if (bytes < 1024)
|
|
199
|
+
return `${bytes} B`;
|
|
200
|
+
if (bytes < 1024 * 1024)
|
|
201
|
+
return `${(bytes / 1024).toFixed(1)} KiB`;
|
|
202
|
+
if (bytes < 1024 * 1024 * 1024)
|
|
203
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
204
|
+
return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GiB`;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* List information about an XZ file
|
|
208
|
+
*/
|
|
209
|
+
function listFile(filename, options) {
|
|
210
|
+
try {
|
|
211
|
+
const data = readFileSync(filename);
|
|
212
|
+
const info = parseFileIndex(data);
|
|
213
|
+
const ratio = info.compressedSize > 0
|
|
214
|
+
? ((1 - info.uncompressedSize / info.compressedSize) * -100).toFixed(1)
|
|
215
|
+
: '0.0';
|
|
216
|
+
const checkNames = {
|
|
217
|
+
[check.NONE]: 'None',
|
|
218
|
+
[check.CRC32]: 'CRC32',
|
|
219
|
+
[check.CRC64]: 'CRC64',
|
|
220
|
+
[check.SHA256]: 'SHA-256',
|
|
221
|
+
};
|
|
222
|
+
const checkName = checkNames[info.check] ?? `Unknown(${info.check})`;
|
|
223
|
+
if (options.verbose) {
|
|
224
|
+
console.log(`File: ${filename}`);
|
|
225
|
+
console.log(` Streams: ${info.streamCount}`);
|
|
226
|
+
console.log(` Blocks: ${info.blockCount}`);
|
|
227
|
+
console.log(` Compressed: ${formatBytes(info.compressedSize)}`);
|
|
228
|
+
console.log(` Uncompressed: ${formatBytes(info.uncompressedSize)}`);
|
|
229
|
+
console.log(` Ratio: ${ratio}%`);
|
|
230
|
+
console.log(` Check: ${checkName}`);
|
|
231
|
+
console.log(` Memory needed: ${formatBytes(info.memoryUsage)}`);
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Compact format similar to xz -l
|
|
235
|
+
console.log('Strms Blocks Compressed Uncompressed Ratio Check Filename');
|
|
236
|
+
console.log(` ${info.streamCount} ${info.blockCount} ${formatBytes(info.compressedSize).padStart(12)} ${formatBytes(info.uncompressedSize).padStart(12)} ${ratio.padStart(5)}% ${checkName.padEnd(6)} ${filename}`);
|
|
237
|
+
}
|
|
238
|
+
return EXIT_SUCCESS;
|
|
239
|
+
}
|
|
240
|
+
catch (err) {
|
|
241
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
242
|
+
warn(`nxz: ${filename}: ${message}`);
|
|
243
|
+
return EXIT_ERROR;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Compress a file
|
|
248
|
+
*/
|
|
249
|
+
/** Resolve output file and check for overwrites. Returns null for stdout mode. */
|
|
250
|
+
function resolveOutputFile(inputFile, mode, options) {
|
|
251
|
+
if (options.stdout)
|
|
252
|
+
return null;
|
|
253
|
+
return options.output ?? getOutputFilename(inputFile, mode);
|
|
254
|
+
}
|
|
255
|
+
/** Attach verbose progress tracking to a stream. */
|
|
256
|
+
function attachProgress(stream, inputFile, totalSize) {
|
|
257
|
+
let lastPercent = -1;
|
|
258
|
+
stream.on('progress', ({ bytesRead, bytesWritten }) => {
|
|
259
|
+
const percent = Math.floor((bytesRead / totalSize) * 100);
|
|
260
|
+
if (percent !== lastPercent) {
|
|
261
|
+
lastPercent = percent;
|
|
262
|
+
process.stderr.write(`\r${inputFile}: ${percent}% (${formatBytes(bytesRead)} -> ${formatBytes(bytesWritten)})`);
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
/** Clean up a partial output file and reset tracking state. */
|
|
267
|
+
function cleanupPartialOutput(outputFile) {
|
|
268
|
+
if (outputFile && existsSync(outputFile)) {
|
|
269
|
+
try {
|
|
270
|
+
unlinkSync(outputFile);
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
// Ignore cleanup errors
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
currentOutputFile = null;
|
|
277
|
+
}
|
|
278
|
+
/** Read file content using fd-based operations (avoids TOCTOU race). Returns [data, fileSize]. */
|
|
279
|
+
function readFileSafe(inputFile) {
|
|
280
|
+
const fd = openSync(inputFile, 'r');
|
|
281
|
+
try {
|
|
282
|
+
const size = fstatSync(fd).size;
|
|
283
|
+
const data = readFileSync(fd);
|
|
284
|
+
return { data, size };
|
|
285
|
+
}
|
|
286
|
+
finally {
|
|
287
|
+
closeSync(fd);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/** Write compressed/decompressed output to stdout or file. */
|
|
291
|
+
function writeOutput(output, outputFile) {
|
|
292
|
+
if (outputFile) {
|
|
293
|
+
writeFileSync(outputFile, output);
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
process.stdout.write(output);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
/** Delete the original file after successful compression/decompression. */
|
|
300
|
+
function removeOriginalIfNeeded(inputFile, options) {
|
|
301
|
+
if (!options.keep && !options.stdout) {
|
|
302
|
+
unlinkSync(inputFile);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
async function compressFile(inputFile, options) {
|
|
306
|
+
const outputFile = resolveOutputFile(inputFile, 'compress', options);
|
|
307
|
+
if (outputFile && existsSync(outputFile) && !options.force) {
|
|
308
|
+
warn(`nxz: ${outputFile}: File already exists; use -f to overwrite`);
|
|
309
|
+
return EXIT_ERROR;
|
|
310
|
+
}
|
|
311
|
+
currentOutputFile = outputFile;
|
|
312
|
+
try {
|
|
313
|
+
const { data, size } = readFileSafe(inputFile);
|
|
314
|
+
const presetValue = options.extreme ? options.preset | preset.EXTREME : options.preset;
|
|
315
|
+
if (!outputFile || size <= STREAM_THRESHOLD_BYTES) {
|
|
316
|
+
// Stdout or small file: sync compression
|
|
317
|
+
const compressed = xzSync(data, { preset: presetValue });
|
|
318
|
+
writeOutput(compressed, outputFile);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
// Large file: stream compression with optional progress
|
|
322
|
+
const compressor = createXz({ preset: presetValue });
|
|
323
|
+
if (options.verbose) {
|
|
324
|
+
attachProgress(compressor, inputFile, size);
|
|
325
|
+
}
|
|
326
|
+
await pipeline(createReadStream(inputFile), compressor, createWriteStream(outputFile));
|
|
327
|
+
if (options.verbose) {
|
|
328
|
+
process.stderr.write('\n');
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
removeOriginalIfNeeded(inputFile, options);
|
|
332
|
+
currentOutputFile = null;
|
|
333
|
+
return EXIT_SUCCESS;
|
|
334
|
+
}
|
|
335
|
+
catch (err) {
|
|
336
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
337
|
+
warn(`nxz: ${inputFile}: ${message}`);
|
|
338
|
+
cleanupPartialOutput(outputFile);
|
|
339
|
+
return EXIT_ERROR;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Decompress a file
|
|
344
|
+
*/
|
|
345
|
+
async function decompressFile(inputFile, options) {
|
|
346
|
+
const outputFile = resolveOutputFile(inputFile, 'decompress', options);
|
|
347
|
+
if (outputFile && existsSync(outputFile) && !options.force) {
|
|
348
|
+
warn(`nxz: ${outputFile}: File already exists; use -f to overwrite`);
|
|
349
|
+
return EXIT_ERROR;
|
|
350
|
+
}
|
|
351
|
+
currentOutputFile = outputFile;
|
|
352
|
+
try {
|
|
353
|
+
const { data, size } = readFileSafe(inputFile);
|
|
354
|
+
if (!isXZ(data)) {
|
|
355
|
+
warn(`nxz: ${inputFile}: File format not recognized`);
|
|
356
|
+
currentOutputFile = null;
|
|
357
|
+
return EXIT_ERROR;
|
|
358
|
+
}
|
|
359
|
+
if (!outputFile || size <= STREAM_THRESHOLD_BYTES) {
|
|
360
|
+
// Stdout or small file: sync decompression
|
|
361
|
+
const decompressed = unxzSync(data);
|
|
362
|
+
writeOutput(decompressed, outputFile);
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
// Large file: stream decompression with optional progress
|
|
366
|
+
const decompressor = createUnxz();
|
|
367
|
+
if (options.verbose) {
|
|
368
|
+
attachProgress(decompressor, inputFile, size);
|
|
369
|
+
}
|
|
370
|
+
await pipeline(createReadStream(inputFile), decompressor, createWriteStream(outputFile));
|
|
371
|
+
if (options.verbose) {
|
|
372
|
+
process.stderr.write('\n');
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
removeOriginalIfNeeded(inputFile, options);
|
|
376
|
+
currentOutputFile = null;
|
|
377
|
+
return EXIT_SUCCESS;
|
|
378
|
+
}
|
|
379
|
+
catch (err) {
|
|
380
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
381
|
+
warn(`nxz: ${inputFile}: ${message}`);
|
|
382
|
+
cleanupPartialOutput(outputFile);
|
|
383
|
+
return EXIT_ERROR;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Process a single file
|
|
388
|
+
*/
|
|
389
|
+
/** Measure execution time of an async function in milliseconds. */
|
|
390
|
+
async function measureAsync(fn) {
|
|
391
|
+
const start = performance.now();
|
|
392
|
+
const result = await fn();
|
|
393
|
+
return { result, ms: performance.now() - start };
|
|
394
|
+
}
|
|
395
|
+
/** Measure execution time of a sync function in milliseconds. */
|
|
396
|
+
function measureSync(fn) {
|
|
397
|
+
const start = performance.now();
|
|
398
|
+
const result = fn();
|
|
399
|
+
return { result, ms: performance.now() - start };
|
|
400
|
+
}
|
|
401
|
+
/** Format milliseconds for display. */
|
|
402
|
+
function formatMs(ms) {
|
|
403
|
+
if (ms < 1)
|
|
404
|
+
return `${(ms * 1000).toFixed(0)} µs`;
|
|
405
|
+
if (ms < 1000)
|
|
406
|
+
return `${ms.toFixed(1)} ms`;
|
|
407
|
+
return `${(ms / 1000).toFixed(2)} s`;
|
|
408
|
+
}
|
|
409
|
+
/** Format a ratio as "Nx faster" or "Nx slower". */
|
|
410
|
+
function formatSpeedup(baseline, candidate) {
|
|
411
|
+
if (candidate === 0 || baseline === 0)
|
|
412
|
+
return 'N/A';
|
|
413
|
+
const ratio = baseline / candidate;
|
|
414
|
+
if (ratio >= 1)
|
|
415
|
+
return `${ratio.toFixed(1)}x faster`;
|
|
416
|
+
return `${(1 / ratio).toFixed(1)}x slower`;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Benchmark native vs WASM compression/decompression on a file.
|
|
420
|
+
*/
|
|
421
|
+
async function benchmarkFile(inputFile, options) {
|
|
422
|
+
// Initialize WASM module with Node.js file-based loader
|
|
423
|
+
const { initModule, resetModule } = await import('../wasm/bindings.js');
|
|
424
|
+
const { xzAsync: wasmXzAsync, unxzAsync: wasmUnxzAsync } = await import('../wasm/index.js');
|
|
425
|
+
const { readFileSync: fsReadFileSync } = await import('node:fs');
|
|
426
|
+
const { fileURLToPath } = await import('node:url');
|
|
427
|
+
const { dirname, join } = await import('node:path');
|
|
428
|
+
const wasmDir = dirname(fileURLToPath(import.meta.url));
|
|
429
|
+
const wasmPath = join(wasmDir, '..', 'wasm', 'liblzma.wasm');
|
|
430
|
+
resetModule();
|
|
431
|
+
await initModule(async () => {
|
|
432
|
+
const { default: createLZMA } = await import('../wasm/liblzma.js');
|
|
433
|
+
const wasmBinary = fsReadFileSync(wasmPath);
|
|
434
|
+
return (await createLZMA({ wasmBinary }));
|
|
435
|
+
});
|
|
436
|
+
const { data, size } = readFileSafe(inputFile);
|
|
437
|
+
const presetValue = options.extreme ? options.preset | preset.EXTREME : options.preset;
|
|
438
|
+
console.error(`\nBenchmark: ${inputFile} (${formatBytes(size)}, preset ${options.preset}${options.extreme ? 'e' : ''})\n`);
|
|
439
|
+
// --- Compression ---
|
|
440
|
+
const nativeCompress = measureSync(() => xzSync(data, { preset: presetValue }));
|
|
441
|
+
const wasmCompress = await measureAsync(() => wasmXzAsync(data, { preset: presetValue }));
|
|
442
|
+
// --- Decompression ---
|
|
443
|
+
const nativeDecompress = measureSync(() => unxzSync(nativeCompress.result));
|
|
444
|
+
const wasmDecompress = await measureAsync(() => wasmUnxzAsync(wasmCompress.result));
|
|
445
|
+
// --- Verify correctness ---
|
|
446
|
+
const nativeOk = Buffer.compare(nativeDecompress.result, data) === 0;
|
|
447
|
+
const wasmOk = Buffer.compare(Buffer.from(wasmDecompress.result), data) === 0;
|
|
448
|
+
// --- Cross-decompression ---
|
|
449
|
+
const crossNativeToWasm = await measureAsync(() => wasmUnxzAsync(nativeCompress.result));
|
|
450
|
+
const crossWasmToNative = measureSync(() => unxzSync(Buffer.from(wasmCompress.result)));
|
|
451
|
+
const crossOk1 = Buffer.compare(Buffer.from(crossNativeToWasm.result), data) === 0;
|
|
452
|
+
const crossOk2 = Buffer.compare(crossWasmToNative.result, data) === 0;
|
|
453
|
+
// --- Output table ---
|
|
454
|
+
const col1 = 22;
|
|
455
|
+
const col2 = 16;
|
|
456
|
+
const col3 = 16;
|
|
457
|
+
const col4 = 18;
|
|
458
|
+
const sep = '-'.repeat(col1 + col2 + col3 + col4 + 7);
|
|
459
|
+
const row = (label, native, wasm, diff) => ` ${label.padEnd(col1)} ${native.padStart(col2)} ${wasm.padStart(col3)} ${diff.padStart(col4)}`;
|
|
460
|
+
console.error(sep);
|
|
461
|
+
console.error(row('', 'Native', 'WASM', 'Comparison'));
|
|
462
|
+
console.error(sep);
|
|
463
|
+
console.error(row('Compress time', formatMs(nativeCompress.ms), formatMs(wasmCompress.ms), formatSpeedup(wasmCompress.ms, nativeCompress.ms)));
|
|
464
|
+
console.error(row('Compressed size', formatBytes(nativeCompress.result.length), formatBytes(wasmCompress.result.length), nativeCompress.result.length === wasmCompress.result.length
|
|
465
|
+
? 'identical'
|
|
466
|
+
: `${((wasmCompress.result.length / nativeCompress.result.length - 1) * 100).toFixed(1)}%`));
|
|
467
|
+
console.error(row('Decompress time', formatMs(nativeDecompress.ms), formatMs(wasmDecompress.ms), formatSpeedup(wasmDecompress.ms, nativeDecompress.ms)));
|
|
468
|
+
console.error(row('Roundtrip OK', nativeOk ? 'YES' : 'FAIL', wasmOk ? 'YES' : 'FAIL', ''));
|
|
469
|
+
console.error(sep);
|
|
470
|
+
console.error(row('Cross: Native→WASM', '', formatMs(crossNativeToWasm.ms), crossOk1 ? 'OK' : 'FAIL'));
|
|
471
|
+
console.error(row('Cross: WASM→Native', formatMs(crossWasmToNative.ms), '', crossOk2 ? 'OK' : 'FAIL'));
|
|
472
|
+
console.error(sep);
|
|
473
|
+
const allOk = nativeOk && wasmOk && crossOk1 && crossOk2;
|
|
474
|
+
console.error(`\n Verdict: ${allOk ? 'ALL PASS — Both backends produce valid output' : 'FAIL — Data mismatch detected'}\n`);
|
|
475
|
+
// Reset WASM module to not interfere with other operations
|
|
476
|
+
resetModule();
|
|
477
|
+
return allOk ? EXIT_SUCCESS : EXIT_ERROR;
|
|
478
|
+
}
|
|
479
|
+
async function processFile(filename, options) {
|
|
480
|
+
// Check file exists
|
|
481
|
+
if (!existsSync(filename)) {
|
|
482
|
+
warn(`nxz: ${filename}: No such file or directory`);
|
|
483
|
+
return EXIT_ERROR;
|
|
484
|
+
}
|
|
485
|
+
// Check if it's a directory
|
|
486
|
+
if (statSync(filename).isDirectory()) {
|
|
487
|
+
warn(`nxz: ${filename}: Is a directory, skipping`);
|
|
488
|
+
return EXIT_ERROR;
|
|
489
|
+
}
|
|
490
|
+
const mode = determineMode(options, filename);
|
|
491
|
+
switch (mode) {
|
|
492
|
+
case 'list':
|
|
493
|
+
return listFile(filename, options);
|
|
494
|
+
case 'benchmark':
|
|
495
|
+
return benchmarkFile(filename, options);
|
|
496
|
+
case 'compress':
|
|
497
|
+
return compressFile(filename, options);
|
|
498
|
+
case 'decompress':
|
|
499
|
+
return decompressFile(filename, options);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Read from stdin and process
|
|
504
|
+
*/
|
|
505
|
+
async function processStdin(options) {
|
|
506
|
+
const chunks = [];
|
|
507
|
+
for await (const chunk of process.stdin) {
|
|
508
|
+
chunks.push(chunk);
|
|
509
|
+
}
|
|
510
|
+
const input = Buffer.concat(chunks);
|
|
511
|
+
const mode = options.decompress ? 'decompress' : 'compress';
|
|
512
|
+
try {
|
|
513
|
+
if (mode === 'compress') {
|
|
514
|
+
const presetValue = options.extreme ? options.preset | preset.EXTREME : options.preset;
|
|
515
|
+
const compressed = xzSync(input, { preset: presetValue });
|
|
516
|
+
process.stdout.write(compressed);
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
if (!isXZ(input)) {
|
|
520
|
+
warn('nxz: (stdin): File format not recognized');
|
|
521
|
+
return EXIT_ERROR;
|
|
522
|
+
}
|
|
523
|
+
const decompressed = unxzSync(input);
|
|
524
|
+
process.stdout.write(decompressed);
|
|
525
|
+
}
|
|
526
|
+
return EXIT_SUCCESS;
|
|
527
|
+
}
|
|
528
|
+
catch (err) {
|
|
529
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
530
|
+
warn(`nxz: (stdin): ${message}`);
|
|
531
|
+
return EXIT_ERROR;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Main entry point
|
|
536
|
+
*/
|
|
537
|
+
async function main() {
|
|
538
|
+
// Setup signal handlers for graceful cleanup
|
|
539
|
+
setupSignalHandlers();
|
|
540
|
+
const options = parseCliArgs(process.argv.slice(2));
|
|
541
|
+
// Set global quiet mode
|
|
542
|
+
quietMode = options.quiet;
|
|
543
|
+
// Handle help and version first
|
|
544
|
+
if (options.help) {
|
|
545
|
+
printHelp();
|
|
546
|
+
process.exit(EXIT_SUCCESS);
|
|
547
|
+
}
|
|
548
|
+
if (options.version) {
|
|
549
|
+
printVersion();
|
|
550
|
+
process.exit(EXIT_SUCCESS);
|
|
551
|
+
}
|
|
552
|
+
// No files: read from stdin
|
|
553
|
+
if (options.files.length === 0 || (options.files.length === 1 && options.files[0] === '-')) {
|
|
554
|
+
const exitCode = await processStdin(options);
|
|
555
|
+
process.exit(exitCode);
|
|
556
|
+
}
|
|
557
|
+
// Process each file
|
|
558
|
+
let exitCode = EXIT_SUCCESS;
|
|
559
|
+
for (const file of options.files) {
|
|
560
|
+
if (file === '-') {
|
|
561
|
+
const code = await processStdin(options);
|
|
562
|
+
if (code !== EXIT_SUCCESS)
|
|
563
|
+
exitCode = code;
|
|
564
|
+
}
|
|
565
|
+
else {
|
|
566
|
+
const code = await processFile(file, options);
|
|
567
|
+
if (code !== EXIT_SUCCESS)
|
|
568
|
+
exitCode = code;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
process.exit(exitCode);
|
|
572
|
+
}
|
|
573
|
+
// Run main
|
|
574
|
+
main().catch((err) => {
|
|
575
|
+
console.error(`nxz: ${err.message}`);
|
|
576
|
+
process.exit(EXIT_ERROR);
|
|
577
|
+
});
|
|
578
|
+
//# sourceMappingURL=nxz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nxz.js","sourceRoot":"","sources":["../../src/cli/nxz.ts"],"names":[],"mappings":"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"}
|