tar-xz 5.0.0 → 6.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 +323 -115
- package/lib/browser/create.d.ts +10 -17
- package/lib/browser/create.d.ts.map +1 -1
- package/lib/browser/create.js +76 -84
- package/lib/browser/create.js.map +1 -1
- package/lib/browser/extract.d.ts +12 -13
- package/lib/browser/extract.d.ts.map +1 -1
- package/lib/browser/extract.js +50 -25
- package/lib/browser/extract.js.map +1 -1
- package/lib/browser/index.d.ts +4 -4
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +4 -4
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/list.d.ts +7 -11
- package/lib/browser/list.d.ts.map +1 -1
- package/lib/browser/list.js +23 -15
- package/lib/browser/list.js.map +1 -1
- package/lib/index.browser.d.ts +5 -4
- package/lib/index.browser.d.ts.map +1 -1
- package/lib/index.browser.js +4 -3
- package/lib/index.browser.js.map +1 -1
- package/lib/index.d.ts +6 -4
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -3
- package/lib/index.js.map +1 -1
- package/lib/internal/to-async-iterable.browser.d.ts +18 -0
- package/lib/internal/to-async-iterable.browser.d.ts.map +1 -0
- package/lib/internal/to-async-iterable.browser.js +66 -0
- package/lib/internal/to-async-iterable.browser.js.map +1 -0
- package/lib/internal/to-async-iterable.d.ts +19 -0
- package/lib/internal/to-async-iterable.d.ts.map +1 -0
- package/lib/internal/to-async-iterable.js +73 -0
- package/lib/internal/to-async-iterable.js.map +1 -0
- package/lib/node/create.d.ts +10 -12
- package/lib/node/create.d.ts.map +1 -1
- package/lib/node/create.js +109 -124
- package/lib/node/create.js.map +1 -1
- package/lib/node/extract.d.ts +14 -17
- package/lib/node/extract.d.ts.map +1 -1
- package/lib/node/extract.js +44 -111
- package/lib/node/extract.js.map +1 -1
- package/lib/node/file.d.ts +61 -0
- package/lib/node/file.d.ts.map +1 -0
- package/lib/node/file.js +337 -0
- package/lib/node/file.js.map +1 -0
- package/lib/node/index.d.ts +3 -2
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +2 -2
- package/lib/node/index.js.map +1 -1
- package/lib/node/list.d.ts +8 -8
- package/lib/node/list.d.ts.map +1 -1
- package/lib/node/list.js +13 -15
- package/lib/node/list.js.map +1 -1
- package/lib/node/xz-helpers.d.ts +15 -0
- package/lib/node/xz-helpers.d.ts.map +1 -0
- package/lib/node/xz-helpers.js +65 -0
- package/lib/node/xz-helpers.js.map +1 -0
- package/lib/types.d.ts +55 -66
- package/lib/types.d.ts.map +1 -1
- package/lib/types.js +7 -0
- package/lib/types.js.map +1 -1
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -1,180 +1,332 @@
|
|
|
1
1
|
# tar-xz
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Universal tar.xz library — stream-first, Node and Browser, same API.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/tar-xz)
|
|
6
|
+
[](https://www.gnu.org/licenses/lgpl-3.0)
|
|
7
|
+
|
|
8
|
+
Create and extract `.tar.xz` archives with streaming support for Node.js and
|
|
9
|
+
WebAssembly-powered support for browsers — using the same `create`/`extract`/`list`
|
|
10
|
+
function names in both environments.
|
|
4
11
|
|
|
5
12
|
## Features
|
|
6
13
|
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
|
|
11
|
-
- **
|
|
14
|
+
- **Unified API** — `create`, `extract`, `list` work identically in Node.js and browsers
|
|
15
|
+
- **Stream-shaped API** — all functions return `AsyncIterable<…>`; stream-shaped inputs accepted. Note: current Node `extract()`/`list()` implementations buffer internally — true streaming is a planned optimization
|
|
16
|
+
- **Flexible input** — `extract()` and `list()` accept `AsyncIterable`, `Uint8Array`,
|
|
17
|
+
`ArrayBuffer`, Web `ReadableStream`, or Node `ReadableStream`
|
|
18
|
+
- **Flexible source** — `create()` accepts fs paths (Node), `Buffer`/`Uint8Array`, or
|
|
19
|
+
`AsyncIterable<Uint8Array>` per file
|
|
20
|
+
- **File helpers** — `tar-xz/file` subpath for disk I/O (Node only)
|
|
21
|
+
- **Full TAR support** — POSIX ustar with PAX extensions for long filenames and metadata
|
|
22
|
+
- **TypeScript** — full type definitions included
|
|
23
|
+
- **Zero runtime deps** — only requires `node-liblzma` (native in Node, WASM in browser)
|
|
12
24
|
|
|
13
25
|
## Installation
|
|
14
26
|
|
|
15
27
|
```bash
|
|
16
28
|
npm install tar-xz
|
|
17
|
-
# or
|
|
18
29
|
pnpm add tar-xz
|
|
19
|
-
# or
|
|
20
30
|
yarn add tar-xz
|
|
21
31
|
```
|
|
22
32
|
|
|
23
|
-
##
|
|
33
|
+
## Quick Start
|
|
24
34
|
|
|
25
|
-
|
|
35
|
+
Node.js and browser use the **same import**:
|
|
26
36
|
|
|
27
37
|
```typescript
|
|
28
38
|
import { create, extract, list } from 'tar-xz';
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Bundlers (Vite, Webpack, esbuild) resolve to the WASM implementation in browser
|
|
42
|
+
builds automatically via the `browser` condition in `package.json`.
|
|
43
|
+
|
|
44
|
+
## API Usage
|
|
45
|
+
|
|
46
|
+
### Creating an archive
|
|
29
47
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
`create()` returns an `AsyncIterable<Uint8Array>`. Pipe it wherever you need:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { create } from 'tar-xz';
|
|
52
|
+
|
|
53
|
+
const enc = new TextEncoder();
|
|
54
|
+
const archiveStream = create({
|
|
55
|
+
files: [
|
|
56
|
+
{ name: 'hello.txt', source: enc.encode('Hello, world!') },
|
|
57
|
+
{ name: 'data.json', source: enc.encode(JSON.stringify({ ok: true })) },
|
|
58
|
+
],
|
|
59
|
+
preset: 6, // XZ compression level 0–9 (default: 6)
|
|
60
|
+
filter: (file) => !file.name.endsWith('.tmp'), // optional
|
|
36
61
|
});
|
|
37
62
|
|
|
38
|
-
//
|
|
39
|
-
const
|
|
40
|
-
for (const
|
|
41
|
-
|
|
63
|
+
// Collect to a Uint8Array (browser / in-memory use)
|
|
64
|
+
const chunks: Uint8Array[] = [];
|
|
65
|
+
for await (const chunk of archiveStream) {
|
|
66
|
+
chunks.push(chunk);
|
|
67
|
+
}
|
|
68
|
+
const archive = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));
|
|
69
|
+
let offset = 0;
|
|
70
|
+
for (const chunk of chunks) { archive.set(chunk, offset); offset += chunk.length; }
|
|
71
|
+
|
|
72
|
+
// Or pipe to a WritableStream (browser)
|
|
73
|
+
const writer = writable.getWriter();
|
|
74
|
+
for await (const chunk of create({ files: [...] })) {
|
|
75
|
+
await writer.write(chunk);
|
|
42
76
|
}
|
|
77
|
+
await writer.close();
|
|
78
|
+
```
|
|
43
79
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
strip: 1, // remove leading path component
|
|
49
|
-
filter: (entry) => !entry.name.startsWith('.') // skip hidden files
|
|
50
|
-
});
|
|
80
|
+
### Extracting an archive
|
|
81
|
+
|
|
82
|
+
`extract()` yields `TarEntryWithData` objects. Consume `entry.data` or use the
|
|
83
|
+
convenience helpers `entry.text()` and `entry.bytes()`:
|
|
51
84
|
|
|
52
|
-
|
|
53
|
-
import {
|
|
54
|
-
|
|
55
|
-
for (const
|
|
56
|
-
|
|
85
|
+
```typescript
|
|
86
|
+
import { extract } from 'tar-xz';
|
|
87
|
+
|
|
88
|
+
for await (const entry of extract(archiveStream)) {
|
|
89
|
+
if (entry.type === '0') { // regular file — TarEntryType.FILE
|
|
90
|
+
const content = await entry.text();
|
|
91
|
+
console.log(entry.name, content);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Or collect raw bytes
|
|
96
|
+
for await (const entry of extract(archive)) {
|
|
97
|
+
if (entry.type === '0') {
|
|
98
|
+
const bytes = await entry.bytes();
|
|
99
|
+
console.log(entry.name, bytes.byteLength, 'bytes');
|
|
100
|
+
}
|
|
57
101
|
}
|
|
58
102
|
```
|
|
59
103
|
|
|
60
|
-
|
|
104
|
+
> **Important:** `entry.data` is a lazy `AsyncIterable` — consume or skip each entry
|
|
105
|
+
> before the `for await` loop advances to the next one. Calling `entry.bytes()` or
|
|
106
|
+
> iterating `entry.data` fully satisfies this requirement.
|
|
107
|
+
|
|
108
|
+
### Listing an archive
|
|
109
|
+
|
|
110
|
+
`list()` yields `TarEntry` metadata without reading file content:
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { list } from 'tar-xz';
|
|
114
|
+
|
|
115
|
+
for await (const entry of list(archiveStream)) {
|
|
116
|
+
console.log(entry.name, entry.size, entry.mtime);
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Inputs accepted by `extract()` and `list()`
|
|
121
|
+
|
|
122
|
+
All of the following are valid as the first argument:
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
extract(asyncIterable) // AsyncIterable<Uint8Array>
|
|
126
|
+
extract(syncIterable) // Iterable<Uint8Array> (e.g. [chunk1, chunk2])
|
|
127
|
+
extract(uint8array) // Uint8Array (in-memory archive)
|
|
128
|
+
extract(arrayBuffer) // ArrayBuffer
|
|
129
|
+
extract(webReadableStream) // ReadableStream<Uint8Array> (Web Streams)
|
|
130
|
+
extract(nodeReadableStream) // NodeJS.ReadableStream (Node only)
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Source types per file in `create()`
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
create({
|
|
137
|
+
files: [
|
|
138
|
+
{ name: 'from-disk.txt', source: '/absolute/or/relative/path' }, // Node only
|
|
139
|
+
{ name: 'from-buffer.bin', source: Buffer.from([0x01, 0x02]) },
|
|
140
|
+
{ name: 'from-uint8.bin', source: new Uint8Array([0x03, 0x04]) },
|
|
141
|
+
{ name: 'from-stream.bin', source: asyncIterableOfChunks },
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
`string` sources (fs paths) throw a helpful error in browser environments — there
|
|
147
|
+
is no filesystem access in browsers.
|
|
148
|
+
|
|
149
|
+
## File Helpers (Node only)
|
|
150
|
+
|
|
151
|
+
`tar-xz/file` wraps the stream API with disk I/O convenience functions:
|
|
61
152
|
|
|
62
153
|
```typescript
|
|
63
|
-
import {
|
|
154
|
+
import { createFile, extractFile, listFile } from 'tar-xz/file';
|
|
64
155
|
|
|
65
|
-
//
|
|
66
|
-
|
|
156
|
+
// Write archive to disk
|
|
157
|
+
await createFile('archive.tar.xz', {
|
|
67
158
|
files: [
|
|
68
|
-
{ name: '
|
|
69
|
-
{ name: '
|
|
159
|
+
{ name: 'a.txt', source: '/path/to/a.txt' },
|
|
160
|
+
{ name: 'b.txt', source: Buffer.from('hello') },
|
|
70
161
|
],
|
|
71
|
-
preset: 3 // lower preset for browser performance
|
|
72
162
|
});
|
|
73
163
|
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
//
|
|
164
|
+
// Extract archive from disk to a directory
|
|
165
|
+
await extractFile('archive.tar.xz', {
|
|
166
|
+
cwd: './output', // target directory (default: process.cwd())
|
|
167
|
+
strip: 1, // strip N leading path components (default: 0)
|
|
168
|
+
filter: (entry) => entry.name.endsWith('.ts'), // optional
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// List archive on disk (returns TarEntry[])
|
|
172
|
+
const entries = await listFile('archive.tar.xz');
|
|
173
|
+
for (const entry of entries) {
|
|
174
|
+
console.log(entry.name, entry.size);
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Do not import `tar-xz/file` in browser bundles — it imports `node:fs` and will
|
|
179
|
+
fail at runtime. Use `create`/`extract`/`list` directly in browser code.
|
|
180
|
+
|
|
181
|
+
## Streaming Patterns
|
|
182
|
+
|
|
183
|
+
### Hash while creating
|
|
184
|
+
|
|
185
|
+
Compute a checksum over the compressed bytes as they are produced:
|
|
186
|
+
|
|
187
|
+
```typescript
|
|
188
|
+
import { create } from 'tar-xz';
|
|
189
|
+
import { createHash } from 'node:crypto';
|
|
78
190
|
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
const data = await response.arrayBuffer();
|
|
82
|
-
const files = await extractTarXz(data);
|
|
191
|
+
const hasher = createHash('sha256');
|
|
192
|
+
const chunks: Uint8Array[] = [];
|
|
83
193
|
|
|
84
|
-
for (const
|
|
85
|
-
|
|
194
|
+
for await (const chunk of create({ files: [...] })) {
|
|
195
|
+
hasher.update(chunk);
|
|
196
|
+
chunks.push(chunk);
|
|
86
197
|
}
|
|
87
198
|
|
|
88
|
-
|
|
89
|
-
|
|
199
|
+
const digest = hasher.digest('hex');
|
|
200
|
+
console.log('SHA-256:', digest);
|
|
90
201
|
```
|
|
91
202
|
|
|
92
|
-
|
|
203
|
+
### HTTP upload
|
|
93
204
|
|
|
94
|
-
|
|
205
|
+
Stream the archive directly to an HTTP endpoint without buffering:
|
|
95
206
|
|
|
96
|
-
|
|
207
|
+
```typescript
|
|
208
|
+
import { create } from 'tar-xz';
|
|
209
|
+
import { Readable } from 'node:stream';
|
|
210
|
+
import { pipeline } from 'node:stream/promises';
|
|
97
211
|
|
|
98
|
-
|
|
212
|
+
const archiveStream = Readable.from(create({ files: [...] }));
|
|
213
|
+
// Use with node:http or any streaming HTTP client
|
|
214
|
+
```
|
|
99
215
|
|
|
100
|
-
|
|
101
|
-
- `file` - Output archive path
|
|
102
|
-
- `cwd` - Base directory for file paths (default: `process.cwd()`)
|
|
103
|
-
- `files` - Array of file/directory paths to include
|
|
104
|
-
- `preset` - XZ compression preset 0-9 (default: 6)
|
|
105
|
-
- `follow` - Follow symbolic links (default: false)
|
|
216
|
+
### Extract from HTTP response (browser)
|
|
106
217
|
|
|
107
|
-
|
|
218
|
+
```typescript
|
|
219
|
+
import { extract } from 'tar-xz';
|
|
220
|
+
|
|
221
|
+
const response = await fetch('https://example.com/archive.tar.xz');
|
|
222
|
+
// ReadableStream<Uint8Array> is accepted directly
|
|
223
|
+
for await (const entry of extract(response.body!)) {
|
|
224
|
+
if (entry.type === '0') {
|
|
225
|
+
const text = await entry.text();
|
|
226
|
+
console.log(entry.name, text);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
```
|
|
108
230
|
|
|
109
|
-
|
|
231
|
+
### Large file extraction to IndexedDB (browser)
|
|
110
232
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
233
|
+
```typescript
|
|
234
|
+
import { extract } from 'tar-xz';
|
|
235
|
+
|
|
236
|
+
const response = await fetch('large.tar.xz');
|
|
237
|
+
for await (const entry of extract(response.body!)) {
|
|
238
|
+
if (entry.type === '0') {
|
|
239
|
+
const bytes = await entry.bytes();
|
|
240
|
+
// write to IndexedDB, OPFS, etc.
|
|
241
|
+
await saveToStorage(entry.name, bytes);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
```
|
|
117
245
|
|
|
118
|
-
|
|
246
|
+
## API Reference
|
|
119
247
|
|
|
120
|
-
|
|
248
|
+
### Core API (`tar-xz`)
|
|
121
249
|
|
|
122
|
-
|
|
250
|
+
| Function | Signature | Returns |
|
|
251
|
+
|----------|-----------|---------|
|
|
252
|
+
| `create` | `(options: CreateOptions) => AsyncIterable<Uint8Array>` | Compressed archive chunks |
|
|
253
|
+
| `extract` | `(input: TarInput, options?: ExtractOptions) => AsyncIterable<TarEntryWithData>` | Entries with data |
|
|
254
|
+
| `list` | `(input: TarInput) => AsyncIterable<TarEntry>` | Metadata only |
|
|
123
255
|
|
|
124
|
-
|
|
256
|
+
### File Helpers API (`tar-xz/file`, Node only)
|
|
125
257
|
|
|
126
|
-
|
|
258
|
+
| Function | Signature | Returns |
|
|
259
|
+
|----------|-----------|---------|
|
|
260
|
+
| `createFile` | `(path: string, options: CreateOptions) => Promise<void>` | Writes archive to `path` |
|
|
261
|
+
| `extractFile` | `(archivePath: string, options?: ExtractOptions & { cwd?: string }) => Promise<void>` | Extracts to `cwd` |
|
|
262
|
+
| `listFile` | `(archivePath: string) => Promise<TarEntry[]>` | Collected entry array |
|
|
127
263
|
|
|
128
|
-
|
|
264
|
+
### `CreateOptions`
|
|
129
265
|
|
|
130
|
-
|
|
266
|
+
| Field | Type | Default | Description |
|
|
267
|
+
|-------|------|---------|-------------|
|
|
268
|
+
| `files` | `TarSourceFile[]` | required | Files to include |
|
|
269
|
+
| `preset` | `number` | `6` | XZ compression level 0–9 |
|
|
270
|
+
| `filter` | `(file: TarSourceFile) => boolean` | — | Return `false` to exclude |
|
|
131
271
|
|
|
132
|
-
|
|
133
|
-
- `files` - Array of `{ name, content, mode?, mtime? }`
|
|
134
|
-
- `preset` - XZ compression preset 0-9 (default: 3)
|
|
272
|
+
### `TarSourceFile`
|
|
135
273
|
|
|
136
|
-
|
|
274
|
+
| Field | Type | Description |
|
|
275
|
+
|-------|------|-------------|
|
|
276
|
+
| `name` | `string` | Path inside the archive |
|
|
277
|
+
| `source` | `string \| Uint8Array \| ArrayBuffer \| AsyncIterable<Uint8Array>` | File content or fs path (Node only) |
|
|
278
|
+
| `mode` | `number?` | File permissions (default: `0o644`) |
|
|
279
|
+
| `mtime` | `Date?` | Modification time (default: now) |
|
|
137
280
|
|
|
138
|
-
|
|
281
|
+
### `ExtractOptions`
|
|
139
282
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
283
|
+
| Field | Type | Default | Description |
|
|
284
|
+
|-------|------|---------|-------------|
|
|
285
|
+
| `strip` | `number` | `0` | Strip N leading path components |
|
|
286
|
+
| `filter` | `(entry: TarEntry) => boolean` | — | Return `false` to skip entry |
|
|
143
287
|
|
|
144
|
-
|
|
288
|
+
### `TarEntry`
|
|
145
289
|
|
|
146
|
-
|
|
290
|
+
Metadata yielded by `list()` and attached to each `TarEntryWithData`:
|
|
147
291
|
|
|
148
|
-
|
|
292
|
+
| Field | Type | Description |
|
|
293
|
+
|-------|------|-------------|
|
|
294
|
+
| `name` | `string` | Relative file path |
|
|
295
|
+
| `type` | `TarEntryTypeValue` | Entry type (`'0'`=file, `'5'`=dir, `'2'`=symlink, …) |
|
|
296
|
+
| `size` | `number` | File size in bytes |
|
|
297
|
+
| `mode` | `number` | File permissions |
|
|
298
|
+
| `uid` / `gid` | `number` | Owner user/group IDs |
|
|
299
|
+
| `uname` / `gname` | `string` | Owner user/group names |
|
|
300
|
+
| `mtime` | `number` | Modification time (seconds since epoch) |
|
|
301
|
+
| `linkname` | `string` | Symlink / hardlink target |
|
|
149
302
|
|
|
150
|
-
|
|
303
|
+
### `TarEntryWithData` (extends `TarEntry`)
|
|
151
304
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
calculatePadding,
|
|
158
|
-
createEndOfArchive,
|
|
159
|
-
needsPaxHeaders,
|
|
160
|
-
createPaxHeaderBlocks,
|
|
161
|
-
} from 'tar-xz';
|
|
162
|
-
```
|
|
305
|
+
| Member | Description |
|
|
306
|
+
|--------|-------------|
|
|
307
|
+
| `data` | `AsyncIterable<Uint8Array>` — lazy content stream (consume once, in order) |
|
|
308
|
+
| `text(encoding?)` | Collect all chunks and decode to string (default UTF-8) |
|
|
309
|
+
| `bytes()` | Collect all chunks into a single `Uint8Array` |
|
|
163
310
|
|
|
164
311
|
## Compression Presets
|
|
165
312
|
|
|
166
|
-
| Preset | Memory
|
|
167
|
-
|
|
168
|
-
| 1 | ~10 MB | Fastest | Lowest |
|
|
169
|
-
| 3 | ~20 MB | Fast | Good
|
|
170
|
-
| 6 | ~100 MB | Medium | Very
|
|
171
|
-
| 9 | ~700 MB | Slowest | Best |
|
|
313
|
+
| Preset | WASM Memory | Speed | Ratio | Recommendation |
|
|
314
|
+
|--------|------------|-------|-------|----------------|
|
|
315
|
+
| 1 | ~10 MB | Fastest | Lowest | Batch of many small files |
|
|
316
|
+
| 3 | ~20 MB | Fast | Good | Memory-constrained environments |
|
|
317
|
+
| 6 | ~100 MB | Medium | Very good | Default (Node + Browser) |
|
|
318
|
+
| 9 | ~700 MB | Slowest | Best | Archive longevity |
|
|
319
|
+
|
|
320
|
+
## Browser Limitations
|
|
172
321
|
|
|
173
|
-
|
|
322
|
+
- **No fs path source** — `source: '/path/to/file'` throws; use `Uint8Array` or `AsyncIterable` instead
|
|
323
|
+
- **256 MB WASM memory cap** — single-file content exceeding this limit will fail; batch large files carefully
|
|
324
|
+
- **No synchronous APIs** — all browser operations are async
|
|
325
|
+
- **Preset 1–6 recommended** — presets 7–9 approach or exceed the memory cap
|
|
174
326
|
|
|
175
327
|
## Compatibility
|
|
176
328
|
|
|
177
|
-
Archives
|
|
329
|
+
Archives produced by `tar-xz` are fully compatible with standard tooling:
|
|
178
330
|
|
|
179
331
|
```bash
|
|
180
332
|
# Extract with system tar
|
|
@@ -182,20 +334,76 @@ tar -xJf archive.tar.xz
|
|
|
182
334
|
|
|
183
335
|
# List contents
|
|
184
336
|
tar -tJf archive.tar.xz
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
## Migration: v5 → v6
|
|
340
|
+
|
|
341
|
+
v6 unifies the Node and browser APIs under a single set of function names.
|
|
342
|
+
|
|
343
|
+
### Renamed / removed exports
|
|
344
|
+
|
|
345
|
+
| v5 | v6 |
|
|
346
|
+
|----|----|
|
|
347
|
+
| `createTarXz(options)` | `create(options)` (browser entry point) |
|
|
348
|
+
| `extractTarXz(archive)` | `extract(archive)` (browser entry point) |
|
|
349
|
+
| `listTarXz(archive)` | `list(archive)` (browser entry point) |
|
|
350
|
+
| `extractToMemory(path)` | `extract(createReadStream(path))` + `entry.bytes()` |
|
|
351
|
+
| `BrowserCreateOptions` | `CreateOptions` |
|
|
352
|
+
| `BrowserExtractOptions` | `ExtractOptions` |
|
|
353
|
+
| `ExtractedFile` | `TarEntryWithData` |
|
|
354
|
+
|
|
355
|
+
### Return type changes
|
|
356
|
+
|
|
357
|
+
`create()` now returns `AsyncIterable<Uint8Array>` instead of `Promise<Uint8Array>`.
|
|
358
|
+
Collect all chunks if you need the full buffer:
|
|
359
|
+
|
|
360
|
+
```typescript
|
|
361
|
+
// v5
|
|
362
|
+
const archive = await createTarXz({ files: [...] });
|
|
363
|
+
|
|
364
|
+
// v6
|
|
365
|
+
const chunks: Uint8Array[] = [];
|
|
366
|
+
for await (const chunk of create({ files: [...] })) chunks.push(chunk);
|
|
367
|
+
const archive = Buffer.concat(chunks); // Node
|
|
368
|
+
// or new Blob(chunks) for a Blob in browser
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
`extract()` now returns `AsyncIterable<TarEntryWithData>` instead of `Promise<Array<...>>`.
|
|
372
|
+
Iterate with `for await`:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
// v5
|
|
376
|
+
const files = await extractTarXz(archive);
|
|
377
|
+
for (const f of files) { /* f.name, f.data */ }
|
|
378
|
+
|
|
379
|
+
// v6
|
|
380
|
+
for await (const entry of extract(archive)) {
|
|
381
|
+
if (entry.type === '0') {
|
|
382
|
+
const data = await entry.bytes(); // f.data equivalent
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Node-only file helpers moved to subpath
|
|
388
|
+
|
|
389
|
+
```typescript
|
|
390
|
+
// v5 (mixed in main export)
|
|
391
|
+
import { create, extract } from 'tar-xz';
|
|
392
|
+
await create({ file: 'archive.tar.xz', cwd: '.', files: ['a.txt'] });
|
|
185
393
|
|
|
186
|
-
|
|
187
|
-
|
|
394
|
+
// v6 (dedicated subpath)
|
|
395
|
+
import { createFile, extractFile } from 'tar-xz/file';
|
|
396
|
+
await createFile('archive.tar.xz', { files: [{ name: 'a.txt', source: 'a.txt' }] });
|
|
188
397
|
```
|
|
189
398
|
|
|
190
399
|
## Why tar-xz?
|
|
191
400
|
|
|
192
|
-
|
|
193
|
-
|
|
401
|
+
[node-tar](https://github.com/isaacs/node-tar) (230M+ downloads/month) does not
|
|
402
|
+
support `.tar.xz`. `tar-xz` fills that gap by combining:
|
|
194
403
|
|
|
195
|
-
|
|
196
|
-
-
|
|
197
|
-
- A minimal TAR implementation (no external dependencies)
|
|
404
|
+
- **node-liblzma** for XZ compression (native addon in Node, WASM in browser)
|
|
405
|
+
- A minimal POSIX ustar TAR implementation (no external dependencies)
|
|
198
406
|
|
|
199
407
|
## License
|
|
200
408
|
|
|
201
|
-
LGPL-3.0
|
|
409
|
+
[LGPL-3.0](https://www.gnu.org/licenses/lgpl-3.0) — same as node-liblzma.
|
package/lib/browser/create.d.ts
CHANGED
|
@@ -1,27 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Browser-based TAR creation with XZ compression
|
|
2
|
+
* Browser-based TAR creation with XZ compression — v6 AsyncIterable API
|
|
3
3
|
*/
|
|
4
|
-
import { type
|
|
4
|
+
import { type CreateOptions } from '../types.js';
|
|
5
5
|
/**
|
|
6
|
-
* Create a tar.xz archive
|
|
6
|
+
* Create a tar.xz archive (browser).
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* @returns Compressed archive as Uint8Array
|
|
8
|
+
* Returns an `AsyncIterable<Uint8Array>` of compressed chunks.
|
|
10
9
|
*
|
|
11
10
|
* @example
|
|
12
11
|
* ```ts
|
|
13
|
-
* const
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* preset: 3
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* // Download the archive
|
|
22
|
-
* const blob = new Blob([archive], { type: 'application/x-xz' });
|
|
23
|
-
* const url = URL.createObjectURL(blob);
|
|
12
|
+
* const chunks: Uint8Array[] = [];
|
|
13
|
+
* for await (const chunk of create({ files })) {
|
|
14
|
+
* chunks.push(chunk);
|
|
15
|
+
* }
|
|
16
|
+
* const blob = new Blob(chunks, { type: 'application/x-xz' });
|
|
24
17
|
* ```
|
|
25
18
|
*/
|
|
26
|
-
export declare function
|
|
19
|
+
export declare function create(options: CreateOptions): AsyncIterable<Uint8Array>;
|
|
27
20
|
//# sourceMappingURL=create.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/browser/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,
|
|
1
|
+
{"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../../src/browser/create.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,OAAO,EACL,KAAK,aAAa,EAInB,MAAM,aAAa,CAAC;AAqFrB;;;;;;;;;;;;;GAaG;AACH,wBAAuB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,aAAa,CAAC,UAAU,CAAC,CAY/E"}
|