xz-compat 1.0.0 → 1.1.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.
@@ -8,8 +8,8 @@
8
8
  * when native bindings are available.
9
9
  */
10
10
  export { decode7zLzma, decode7zLzma2, type SevenZDecodeCallback } from './sevenz.js';
11
- export { createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.js';
11
+ export { type BufferLike, createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.js';
12
12
  export { createLzma2Decoder, createLzmaDecoder, decodeLzma, decodeLzma2 } from './lzma/index.js';
13
13
  export * from './filters/index.js';
14
14
  export { isNativeAvailable } from './native.js';
15
- export type { DecodeCallback } from './utils/runDecode.js';
15
+ export type { DecodeCallback } from './sevenz.js';
@@ -8,8 +8,8 @@
8
8
  * when native bindings are available.
9
9
  */
10
10
  export { decode7zLzma, decode7zLzma2, type SevenZDecodeCallback } from './sevenz.js';
11
- export { createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.js';
11
+ export { type BufferLike, createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.js';
12
12
  export { createLzma2Decoder, createLzmaDecoder, decodeLzma, decodeLzma2 } from './lzma/index.js';
13
13
  export * from './filters/index.js';
14
14
  export { isNativeAvailable } from './native.js';
15
- export type { DecodeCallback } from './utils/runDecode.js';
15
+ export type { DecodeCallback } from './sevenz.js';
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/index.ts"],"sourcesContent":["/**\n * XZ-Compat: XZ/LZMA Decompression Library\n *\n * Pure JavaScript implementation with optional native acceleration\n * via lzma-native on Node.js 10+.\n *\n * Works on Node.js 0.8+ with automatic performance optimization\n * when native bindings are available.\n */\n\n// ============================================================================\n// High-Level APIs (Recommended)\n// ============================================================================\n\n// 7z-specific decoders - accept properties separately, try native automatically\nexport { decode7zLzma, decode7zLzma2, type SevenZDecodeCallback } from './sevenz.ts';\n// XZ container format - self-describing, works great with native acceleration\nexport { createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.ts';\n\n// ============================================================================\n// Low-Level APIs (Backward Compatibility)\n// ============================================================================\n\n// Raw LZMA decoders (for specialized use cases)\nexport { createLzma2Decoder, createLzmaDecoder, decodeLzma, decodeLzma2 } from './lzma/index.ts';\n\n// ============================================================================\n// Supporting APIs\n// ============================================================================\n\n// Preprocessing filters (BCJ/Delta - used by 7z-iterator)\nexport * from './filters/index.ts';\n\n// Native acceleration utilities\nexport { isNativeAvailable } from './native.ts';\n\n// Callback type used by async decoders\nexport type { DecodeCallback } from './utils/runDecode.ts';\n"],"names":["createLzma2Decoder","createLzmaDecoder","createXZDecoder","decode7zLzma","decode7zLzma2","decodeLzma","decodeLzma2","decodeXZ","isNativeAvailable"],"mappings":"AAAA;;;;;;;;CAQC,GAED,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E,gFAAgF;;;;;;;;;;;;QAUvEA;eAAAA,2BAAkB;;QAAEC;eAAAA,0BAAiB;;QAPrCC;eAAAA,0BAAe;;QAFfC;eAAAA,sBAAY;;QAAEC;eAAAA,uBAAa;;QASYC;eAAAA,mBAAU;;QAAEC;eAAAA,oBAAW;;QAP7CC;eAAAA,mBAAQ;;QAiBzBC;eAAAA,2BAAiB;;;wBAnB6C;yBAEN;uBAOc;qBAOjE;wBAGoB"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/index.ts"],"sourcesContent":["/**\n * XZ-Compat: XZ/LZMA Decompression Library\n *\n * Pure JavaScript implementation with optional native acceleration\n * via lzma-native on Node.js 10+.\n *\n * Works on Node.js 0.8+ with automatic performance optimization\n * when native bindings are available.\n */\n\n// ============================================================================\n// High-Level APIs (Recommended)\n// ============================================================================\n\n// 7z-specific decoders - accept properties separately, try native automatically\nexport { decode7zLzma, decode7zLzma2, type SevenZDecodeCallback } from './sevenz.ts';\n// XZ container format - self-describing, works great with native acceleration\nexport { type BufferLike, createXZDecoder, decodeXZ, type XzDecodeCallback } from './xz/Decoder.ts';\n\n// ============================================================================\n// Low-Level APIs (Backward Compatibility)\n// ============================================================================\n\n// Raw LZMA decoders (for specialized use cases)\nexport { createLzma2Decoder, createLzmaDecoder, decodeLzma, decodeLzma2 } from './lzma/index.ts';\n\n// ============================================================================\n// Supporting APIs\n// ============================================================================\n\n// Preprocessing filters (BCJ/Delta - used by 7z-iterator)\nexport * from './filters/index.ts';\n\n// Native acceleration utilities\nexport { isNativeAvailable } from './native.ts';\n\n// Callback type used by async decoders\nexport type { DecodeCallback } from './sevenz.ts';\n"],"names":["createLzma2Decoder","createLzmaDecoder","createXZDecoder","decode7zLzma","decode7zLzma2","decodeLzma","decodeLzma2","decodeXZ","isNativeAvailable"],"mappings":"AAAA;;;;;;;;CAQC,GAED,+EAA+E;AAC/E,gCAAgC;AAChC,+EAA+E;AAE/E,gFAAgF;;;;;;;;;;;;QAUvEA;eAAAA,2BAAkB;;QAAEC;eAAAA,0BAAiB;;QAPpBC;eAAAA,0BAAe;;QAFhCC;eAAAA,sBAAY;;QAAEC;eAAAA,uBAAa;;QASYC;eAAAA,mBAAU;;QAAEC;eAAAA,oBAAW;;QAP5BC;eAAAA,mBAAQ;;QAiB1CC;eAAAA,2BAAiB;;;wBAnB6C;yBAEW;uBAOH;qBAOjE;wBAGoB"}
@@ -4,6 +4,7 @@
4
4
  * LZMA2 is a container format that wraps LZMA chunks with framing.
5
5
  * Decodes LZMA2 data from a buffer.
6
6
  */
7
+ import { type BufferLike } from 'extract-base-iterator';
7
8
  import { type OutputSink } from '../types.js';
8
9
  /**
9
10
  * Synchronous LZMA2 decoder
@@ -40,26 +41,26 @@ export declare class Lzma2Decoder {
40
41
  decodeLzmaData(input: Buffer, offset: number, outSize: number, solid?: boolean): Buffer;
41
42
  /**
42
43
  * Decode LZMA2 data with streaming output
43
- * @param input - LZMA2 compressed data
44
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
44
45
  * @returns Total number of bytes written to sink
45
46
  */
46
- decodeWithSink(input: Buffer): number;
47
+ decodeWithSink(input: BufferLike): number;
47
48
  /**
48
49
  * Decode LZMA2 data
49
- * @param input - LZMA2 compressed data
50
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
50
51
  * @param unpackSize - Expected output size (optional, for pre-allocation)
51
52
  * @returns Decompressed data
52
53
  */
53
- decode(input: Buffer, unpackSize?: number): Buffer;
54
+ decode(input: BufferLike, unpackSize?: number): Buffer;
54
55
  }
55
56
  /**
56
57
  * Decode LZMA2 data synchronously
57
- * @param input - LZMA2 compressed data
58
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
58
59
  * @param properties - 1-byte properties (dictionary size)
59
60
  * @param unpackSize - Expected output size (optional, autodetects if not provided)
60
61
  * @param outputSink - Optional output sink with write callback for streaming (returns bytes written)
61
62
  * @returns Decompressed data (or bytes written if outputSink provided)
62
63
  */
63
- export declare function decodeLzma2(input: Buffer, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: {
64
+ export declare function decodeLzma2(input: BufferLike, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: {
64
65
  write(buffer: Buffer): void;
65
66
  }): Buffer | number;
@@ -4,6 +4,7 @@
4
4
  * LZMA2 is a container format that wraps LZMA chunks with framing.
5
5
  * Decodes LZMA2 data from a buffer.
6
6
  */
7
+ import { type BufferLike } from 'extract-base-iterator';
7
8
  import { type OutputSink } from '../types.js';
8
9
  /**
9
10
  * Synchronous LZMA2 decoder
@@ -40,26 +41,26 @@ export declare class Lzma2Decoder {
40
41
  decodeLzmaData(input: Buffer, offset: number, outSize: number, solid?: boolean): Buffer;
41
42
  /**
42
43
  * Decode LZMA2 data with streaming output
43
- * @param input - LZMA2 compressed data
44
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
44
45
  * @returns Total number of bytes written to sink
45
46
  */
46
- decodeWithSink(input: Buffer): number;
47
+ decodeWithSink(input: BufferLike): number;
47
48
  /**
48
49
  * Decode LZMA2 data
49
- * @param input - LZMA2 compressed data
50
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
50
51
  * @param unpackSize - Expected output size (optional, for pre-allocation)
51
52
  * @returns Decompressed data
52
53
  */
53
- decode(input: Buffer, unpackSize?: number): Buffer;
54
+ decode(input: BufferLike, unpackSize?: number): Buffer;
54
55
  }
55
56
  /**
56
57
  * Decode LZMA2 data synchronously
57
- * @param input - LZMA2 compressed data
58
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
58
59
  * @param properties - 1-byte properties (dictionary size)
59
60
  * @param unpackSize - Expected output size (optional, autodetects if not provided)
60
61
  * @param outputSink - Optional output sink with write callback for streaming (returns bytes written)
61
62
  * @returns Decompressed data (or bytes written if outputSink provided)
62
63
  */
63
- export declare function decodeLzma2(input: Buffer, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: {
64
+ export declare function decodeLzma2(input: BufferLike, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: {
64
65
  write(buffer: Buffer): void;
65
66
  }): Buffer | number;
@@ -76,13 +76,15 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
76
76
  };
77
77
  /**
78
78
  * Decode LZMA2 data with streaming output
79
- * @param input - LZMA2 compressed data
79
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
80
80
  * @returns Total number of bytes written to sink
81
81
  */ _proto.decodeWithSink = function decodeWithSink(input) {
82
+ // Convert BufferList to Buffer for low-level parsing
83
+ var buf = Buffer.isBuffer(input) ? input : input.toBuffer();
82
84
  var totalBytes = 0;
83
85
  var offset = 0;
84
- while(offset < input.length){
85
- var result = (0, _Lzma2ChunkParserts.parseLzma2ChunkHeader)(input, offset);
86
+ while(offset < buf.length){
87
+ var result = (0, _Lzma2ChunkParserts.parseLzma2ChunkHeader)(buf, offset);
86
88
  if (!result.success) {
87
89
  throw new Error('Truncated LZMA2 chunk header');
88
90
  }
@@ -92,7 +94,7 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
92
94
  }
93
95
  // Validate we have enough data for the chunk
94
96
  var dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;
95
- if (offset + chunk.headerSize + dataSize > input.length) {
97
+ if (offset + chunk.headerSize + dataSize > buf.length) {
96
98
  throw new Error("Truncated LZMA2 ".concat(chunk.type, " data"));
97
99
  }
98
100
  // Handle dictionary reset
@@ -101,7 +103,7 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
101
103
  }
102
104
  var dataOffset = offset + chunk.headerSize;
103
105
  if (chunk.type === 'uncompressed') {
104
- var uncompData = input.slice(dataOffset, dataOffset + chunk.uncompSize);
106
+ var uncompData = buf.slice(dataOffset, dataOffset + chunk.uncompSize);
105
107
  // Feed uncompressed data to dictionary so subsequent LZMA chunks can reference it
106
108
  this.lzmaDecoder.feedUncompressed(uncompData);
107
109
  totalBytes += uncompData.length;
@@ -128,7 +130,7 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
128
130
  // Determine solid mode
129
131
  var useSolid = !chunk.stateReset || chunk.stateReset && !chunk.dictReset;
130
132
  // Decode LZMA chunk directly to sink
131
- totalBytes += this.lzmaDecoder.decodeWithSink(input, dataOffset, chunk.uncompSize, useSolid);
133
+ totalBytes += this.lzmaDecoder.decodeWithSink(buf, dataOffset, chunk.uncompSize, useSolid);
132
134
  offset = dataOffset + chunk.compSize;
133
135
  }
134
136
  }
@@ -138,10 +140,12 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
138
140
  };
139
141
  /**
140
142
  * Decode LZMA2 data
141
- * @param input - LZMA2 compressed data
143
+ * @param input - LZMA2 compressed data (Buffer or BufferList)
142
144
  * @param unpackSize - Expected output size (optional, for pre-allocation)
143
145
  * @returns Decompressed data
144
146
  */ _proto.decode = function decode(input, unpackSize) {
147
+ // Convert BufferList to Buffer for low-level parsing
148
+ var buf = Buffer.isBuffer(input) ? input : input.toBuffer();
145
149
  // Pre-allocate output buffer if size is known
146
150
  var outputBuffer = null;
147
151
  var outputPos = 0;
@@ -150,8 +154,8 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
150
154
  outputBuffer = (0, _extractbaseiterator.allocBufferUnsafe)(unpackSize);
151
155
  }
152
156
  var offset = 0;
153
- while(offset < input.length){
154
- var result = (0, _Lzma2ChunkParserts.parseLzma2ChunkHeader)(input, offset);
157
+ while(offset < buf.length){
158
+ var result = (0, _Lzma2ChunkParserts.parseLzma2ChunkHeader)(buf, offset);
155
159
  if (!result.success) {
156
160
  throw new Error('Truncated LZMA2 chunk header');
157
161
  }
@@ -161,7 +165,7 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
161
165
  }
162
166
  // Validate we have enough data for the chunk
163
167
  var dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;
164
- if (offset + chunk.headerSize + dataSize > input.length) {
168
+ if (offset + chunk.headerSize + dataSize > buf.length) {
165
169
  throw new Error("Truncated LZMA2 ".concat(chunk.type, " data"));
166
170
  }
167
171
  // Handle dictionary reset
@@ -170,7 +174,7 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
170
174
  }
171
175
  var dataOffset = offset + chunk.headerSize;
172
176
  if (chunk.type === 'uncompressed') {
173
- var uncompData = input.slice(dataOffset, dataOffset + chunk.uncompSize);
177
+ var uncompData = buf.slice(dataOffset, dataOffset + chunk.uncompSize);
174
178
  // Copy to output
175
179
  if (outputBuffer) {
176
180
  uncompData.copy(outputBuffer, outputPos);
@@ -205,11 +209,11 @@ var Lzma2Decoder = /*#__PURE__*/ function() {
205
209
  // Decode LZMA chunk - use zero-copy when we have pre-allocated buffer
206
210
  if (outputBuffer) {
207
211
  // Zero-copy: decode directly into caller's buffer
208
- var bytesWritten = this.lzmaDecoder.decodeToBuffer(input, dataOffset, chunk.uncompSize, outputBuffer, outputPos, useSolid);
212
+ var bytesWritten = this.lzmaDecoder.decodeToBuffer(buf, dataOffset, chunk.uncompSize, outputBuffer, outputPos, useSolid);
209
213
  outputPos += bytesWritten;
210
214
  } else {
211
215
  // No pre-allocation: decode to new buffer and collect chunks
212
- var chunkData = input.slice(dataOffset, dataOffset + chunk.compSize);
216
+ var chunkData = buf.slice(dataOffset, dataOffset + chunk.compSize);
213
217
  var decoded = this.lzmaDecoder.decode(chunkData, 0, chunk.uncompSize, useSolid);
214
218
  outputChunks.push(decoded);
215
219
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/lzma/sync/Lzma2Decoder.ts"],"sourcesContent":["/**\n * Synchronous LZMA2 Decoder\n *\n * LZMA2 is a container format that wraps LZMA chunks with framing.\n * Decodes LZMA2 data from a buffer.\n */\n\nimport { allocBufferUnsafe } from 'extract-base-iterator';\nimport { parseLzma2ChunkHeader } from '../lib/Lzma2ChunkParser.ts';\nimport { type OutputSink, parseLzma2DictionarySize } from '../types.ts';\nimport { LzmaDecoder } from './LzmaDecoder.ts';\n\n/**\n * Synchronous LZMA2 decoder\n */\nexport class Lzma2Decoder {\n private lzmaDecoder: LzmaDecoder;\n private dictionarySize: number;\n private propsSet: boolean;\n\n constructor(properties: Buffer | Uint8Array, outputSink?: OutputSink) {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n this.dictionarySize = parseLzma2DictionarySize(properties[0]);\n this.lzmaDecoder = new LzmaDecoder(outputSink);\n this.lzmaDecoder.setDictionarySize(this.dictionarySize);\n this.propsSet = false;\n }\n\n /**\n * Reset the dictionary (for stream boundaries)\n */\n resetDictionary(): void {\n this.lzmaDecoder.resetDictionary();\n }\n\n /**\n * Reset all probability models (for stream boundaries)\n */\n resetProbabilities(): void {\n this.lzmaDecoder.resetProbabilities();\n }\n\n /**\n * Set LZMA properties\n */\n setLcLpPb(lc: number, lp: number, pb: number): boolean {\n return this.lzmaDecoder.setLcLpPb(lc, lp, pb);\n }\n\n /**\n * Feed uncompressed data to the dictionary (for subsequent LZMA chunks)\n */\n feedUncompressed(data: Buffer): void {\n this.lzmaDecoder.feedUncompressed(data);\n }\n\n /**\n * Decode raw LZMA data (used internally for LZMA2 chunks)\n * @param input - LZMA compressed data\n * @param offset - Input offset\n * @param outSize - Expected output size\n * @param solid - Use solid mode\n * @returns Decompressed data\n */\n decodeLzmaData(input: Buffer, offset: number, outSize: number, solid = false): Buffer {\n return this.lzmaDecoder.decode(input, offset, outSize, solid);\n }\n\n /**\n * Decode LZMA2 data with streaming output\n * @param input - LZMA2 compressed data\n * @returns Total number of bytes written to sink\n */\n decodeWithSink(input: Buffer): number {\n let totalBytes = 0;\n let offset = 0;\n\n while (offset < input.length) {\n const result = parseLzma2ChunkHeader(input, offset);\n\n if (!result.success) {\n throw new Error('Truncated LZMA2 chunk header');\n }\n\n const chunk = result.chunk;\n\n if (chunk.type === 'end') {\n break;\n }\n\n // Validate we have enough data for the chunk\n const dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;\n if (offset + chunk.headerSize + dataSize > input.length) {\n throw new Error(`Truncated LZMA2 ${chunk.type} data`);\n }\n\n // Handle dictionary reset\n if (chunk.dictReset) {\n this.lzmaDecoder.resetDictionary();\n }\n\n const dataOffset = offset + chunk.headerSize;\n\n if (chunk.type === 'uncompressed') {\n const uncompData = input.slice(dataOffset, dataOffset + chunk.uncompSize);\n\n // Feed uncompressed data to dictionary so subsequent LZMA chunks can reference it\n this.lzmaDecoder.feedUncompressed(uncompData);\n\n totalBytes += uncompData.length;\n offset = dataOffset + chunk.uncompSize;\n } else {\n // LZMA compressed chunk\n\n // Apply new properties if present\n if (chunk.newProps) {\n const { lc, lp, pb } = chunk.newProps;\n if (!this.lzmaDecoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n this.propsSet = true;\n } else {\n // No new properties, check if we already have them\n if (!this.propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunk.stateReset) {\n this.lzmaDecoder.resetProbabilities();\n }\n\n // Determine solid mode\n const useSolid = !chunk.stateReset || (chunk.stateReset && !chunk.dictReset);\n\n // Decode LZMA chunk directly to sink\n totalBytes += this.lzmaDecoder.decodeWithSink(input, dataOffset, chunk.uncompSize, useSolid);\n\n offset = dataOffset + chunk.compSize;\n }\n }\n\n // Flush any remaining data in the OutWindow\n this.lzmaDecoder.flushOutWindow();\n\n return totalBytes;\n }\n\n /**\n * Decode LZMA2 data\n * @param input - LZMA2 compressed data\n * @param unpackSize - Expected output size (optional, for pre-allocation)\n * @returns Decompressed data\n */\n decode(input: Buffer, unpackSize?: number): Buffer {\n // Pre-allocate output buffer if size is known\n let outputBuffer: Buffer | null = null;\n let outputPos = 0;\n const outputChunks: Buffer[] = [];\n\n if (unpackSize && unpackSize > 0) {\n outputBuffer = allocBufferUnsafe(unpackSize);\n }\n\n let offset = 0;\n\n while (offset < input.length) {\n const result = parseLzma2ChunkHeader(input, offset);\n\n if (!result.success) {\n throw new Error('Truncated LZMA2 chunk header');\n }\n\n const chunk = result.chunk;\n\n if (chunk.type === 'end') {\n break;\n }\n\n // Validate we have enough data for the chunk\n const dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;\n if (offset + chunk.headerSize + dataSize > input.length) {\n throw new Error(`Truncated LZMA2 ${chunk.type} data`);\n }\n\n // Handle dictionary reset\n if (chunk.dictReset) {\n this.lzmaDecoder.resetDictionary();\n }\n\n const dataOffset = offset + chunk.headerSize;\n\n if (chunk.type === 'uncompressed') {\n const uncompData = input.slice(dataOffset, dataOffset + chunk.uncompSize);\n\n // Copy to output\n if (outputBuffer) {\n uncompData.copy(outputBuffer, outputPos);\n outputPos += uncompData.length;\n } else {\n outputChunks.push(uncompData);\n }\n\n // Feed uncompressed data to dictionary so subsequent LZMA chunks can reference it\n this.lzmaDecoder.feedUncompressed(uncompData);\n\n offset = dataOffset + chunk.uncompSize;\n } else {\n // LZMA compressed chunk\n\n // Apply new properties if present\n if (chunk.newProps) {\n const { lc, lp, pb } = chunk.newProps;\n if (!this.lzmaDecoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n this.propsSet = true;\n } else {\n // No new properties, check if we already have them\n if (!this.propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunk.stateReset) {\n this.lzmaDecoder.resetProbabilities();\n }\n\n // Determine solid mode - preserve dictionary if not resetting state or if only resetting state (not dict)\n const useSolid = !chunk.stateReset || (chunk.stateReset && !chunk.dictReset);\n\n // Decode LZMA chunk - use zero-copy when we have pre-allocated buffer\n if (outputBuffer) {\n // Zero-copy: decode directly into caller's buffer\n const bytesWritten = this.lzmaDecoder.decodeToBuffer(input, dataOffset, chunk.uncompSize, outputBuffer, outputPos, useSolid);\n outputPos += bytesWritten;\n } else {\n // No pre-allocation: decode to new buffer and collect chunks\n const chunkData = input.slice(dataOffset, dataOffset + chunk.compSize);\n const decoded = this.lzmaDecoder.decode(chunkData, 0, chunk.uncompSize, useSolid);\n outputChunks.push(decoded);\n }\n\n offset = dataOffset + chunk.compSize;\n }\n }\n\n // Return pre-allocated buffer or concatenated chunks\n if (outputBuffer) {\n return outputPos < outputBuffer.length ? outputBuffer.slice(0, outputPos) : outputBuffer;\n }\n return Buffer.concat(outputChunks);\n }\n}\n\n/**\n * Decode LZMA2 data synchronously\n * @param input - LZMA2 compressed data\n * @param properties - 1-byte properties (dictionary size)\n * @param unpackSize - Expected output size (optional, autodetects if not provided)\n * @param outputSink - Optional output sink with write callback for streaming (returns bytes written)\n * @returns Decompressed data (or bytes written if outputSink provided)\n */\nexport function decodeLzma2(input: Buffer, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: { write(buffer: Buffer): void }): Buffer | number {\n const decoder = new Lzma2Decoder(properties, outputSink as OutputSink);\n if (outputSink) {\n // Zero-copy mode: write to sink during decode\n return decoder.decodeWithSink(input);\n }\n // Buffering mode: returns Buffer (zero-copy)\n return decoder.decode(input, unpackSize);\n}\n"],"names":["Lzma2Decoder","decodeLzma2","properties","outputSink","length","Error","dictionarySize","parseLzma2DictionarySize","lzmaDecoder","LzmaDecoder","setDictionarySize","propsSet","resetDictionary","resetProbabilities","setLcLpPb","lc","lp","pb","feedUncompressed","data","decodeLzmaData","input","offset","outSize","solid","decode","decodeWithSink","totalBytes","result","parseLzma2ChunkHeader","success","chunk","type","dataSize","uncompSize","compSize","headerSize","dictReset","dataOffset","uncompData","slice","newProps","stateReset","useSolid","flushOutWindow","unpackSize","outputBuffer","outputPos","outputChunks","allocBufferUnsafe","copy","push","bytesWritten","decodeToBuffer","chunkData","decoded","Buffer","concat","decoder"],"mappings":"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"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/lzma/sync/Lzma2Decoder.ts"],"sourcesContent":["/**\n * Synchronous LZMA2 Decoder\n *\n * LZMA2 is a container format that wraps LZMA chunks with framing.\n * Decodes LZMA2 data from a buffer.\n */\n\nimport { allocBufferUnsafe, type BufferLike } from 'extract-base-iterator';\nimport { parseLzma2ChunkHeader } from '../lib/Lzma2ChunkParser.ts';\nimport { type OutputSink, parseLzma2DictionarySize } from '../types.ts';\nimport { LzmaDecoder } from './LzmaDecoder.ts';\n\n/**\n * Synchronous LZMA2 decoder\n */\nexport class Lzma2Decoder {\n private lzmaDecoder: LzmaDecoder;\n private dictionarySize: number;\n private propsSet: boolean;\n\n constructor(properties: Buffer | Uint8Array, outputSink?: OutputSink) {\n if (!properties || properties.length < 1) {\n throw new Error('LZMA2 requires properties byte');\n }\n\n this.dictionarySize = parseLzma2DictionarySize(properties[0]);\n this.lzmaDecoder = new LzmaDecoder(outputSink);\n this.lzmaDecoder.setDictionarySize(this.dictionarySize);\n this.propsSet = false;\n }\n\n /**\n * Reset the dictionary (for stream boundaries)\n */\n resetDictionary(): void {\n this.lzmaDecoder.resetDictionary();\n }\n\n /**\n * Reset all probability models (for stream boundaries)\n */\n resetProbabilities(): void {\n this.lzmaDecoder.resetProbabilities();\n }\n\n /**\n * Set LZMA properties\n */\n setLcLpPb(lc: number, lp: number, pb: number): boolean {\n return this.lzmaDecoder.setLcLpPb(lc, lp, pb);\n }\n\n /**\n * Feed uncompressed data to the dictionary (for subsequent LZMA chunks)\n */\n feedUncompressed(data: Buffer): void {\n this.lzmaDecoder.feedUncompressed(data);\n }\n\n /**\n * Decode raw LZMA data (used internally for LZMA2 chunks)\n * @param input - LZMA compressed data\n * @param offset - Input offset\n * @param outSize - Expected output size\n * @param solid - Use solid mode\n * @returns Decompressed data\n */\n decodeLzmaData(input: Buffer, offset: number, outSize: number, solid = false): Buffer {\n return this.lzmaDecoder.decode(input, offset, outSize, solid);\n }\n\n /**\n * Decode LZMA2 data with streaming output\n * @param input - LZMA2 compressed data (Buffer or BufferList)\n * @returns Total number of bytes written to sink\n */\n decodeWithSink(input: BufferLike): number {\n // Convert BufferList to Buffer for low-level parsing\n const buf = Buffer.isBuffer(input) ? input : input.toBuffer();\n let totalBytes = 0;\n let offset = 0;\n\n while (offset < buf.length) {\n const result = parseLzma2ChunkHeader(buf, offset);\n\n if (!result.success) {\n throw new Error('Truncated LZMA2 chunk header');\n }\n\n const chunk = result.chunk;\n\n if (chunk.type === 'end') {\n break;\n }\n\n // Validate we have enough data for the chunk\n const dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;\n if (offset + chunk.headerSize + dataSize > buf.length) {\n throw new Error(`Truncated LZMA2 ${chunk.type} data`);\n }\n\n // Handle dictionary reset\n if (chunk.dictReset) {\n this.lzmaDecoder.resetDictionary();\n }\n\n const dataOffset = offset + chunk.headerSize;\n\n if (chunk.type === 'uncompressed') {\n const uncompData = buf.slice(dataOffset, dataOffset + chunk.uncompSize);\n\n // Feed uncompressed data to dictionary so subsequent LZMA chunks can reference it\n this.lzmaDecoder.feedUncompressed(uncompData);\n\n totalBytes += uncompData.length;\n offset = dataOffset + chunk.uncompSize;\n } else {\n // LZMA compressed chunk\n\n // Apply new properties if present\n if (chunk.newProps) {\n const { lc, lp, pb } = chunk.newProps;\n if (!this.lzmaDecoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n this.propsSet = true;\n } else {\n // No new properties, check if we already have them\n if (!this.propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunk.stateReset) {\n this.lzmaDecoder.resetProbabilities();\n }\n\n // Determine solid mode\n const useSolid = !chunk.stateReset || (chunk.stateReset && !chunk.dictReset);\n\n // Decode LZMA chunk directly to sink\n totalBytes += this.lzmaDecoder.decodeWithSink(buf, dataOffset, chunk.uncompSize, useSolid);\n\n offset = dataOffset + chunk.compSize;\n }\n }\n\n // Flush any remaining data in the OutWindow\n this.lzmaDecoder.flushOutWindow();\n\n return totalBytes;\n }\n\n /**\n * Decode LZMA2 data\n * @param input - LZMA2 compressed data (Buffer or BufferList)\n * @param unpackSize - Expected output size (optional, for pre-allocation)\n * @returns Decompressed data\n */\n decode(input: BufferLike, unpackSize?: number): Buffer {\n // Convert BufferList to Buffer for low-level parsing\n const buf = Buffer.isBuffer(input) ? input : input.toBuffer();\n\n // Pre-allocate output buffer if size is known\n let outputBuffer: Buffer | null = null;\n let outputPos = 0;\n const outputChunks: Buffer[] = [];\n\n if (unpackSize && unpackSize > 0) {\n outputBuffer = allocBufferUnsafe(unpackSize);\n }\n\n let offset = 0;\n\n while (offset < buf.length) {\n const result = parseLzma2ChunkHeader(buf, offset);\n\n if (!result.success) {\n throw new Error('Truncated LZMA2 chunk header');\n }\n\n const chunk = result.chunk;\n\n if (chunk.type === 'end') {\n break;\n }\n\n // Validate we have enough data for the chunk\n const dataSize = chunk.type === 'uncompressed' ? chunk.uncompSize : chunk.compSize;\n if (offset + chunk.headerSize + dataSize > buf.length) {\n throw new Error(`Truncated LZMA2 ${chunk.type} data`);\n }\n\n // Handle dictionary reset\n if (chunk.dictReset) {\n this.lzmaDecoder.resetDictionary();\n }\n\n const dataOffset = offset + chunk.headerSize;\n\n if (chunk.type === 'uncompressed') {\n const uncompData = buf.slice(dataOffset, dataOffset + chunk.uncompSize);\n\n // Copy to output\n if (outputBuffer) {\n uncompData.copy(outputBuffer, outputPos);\n outputPos += uncompData.length;\n } else {\n outputChunks.push(uncompData);\n }\n\n // Feed uncompressed data to dictionary so subsequent LZMA chunks can reference it\n this.lzmaDecoder.feedUncompressed(uncompData);\n\n offset = dataOffset + chunk.uncompSize;\n } else {\n // LZMA compressed chunk\n\n // Apply new properties if present\n if (chunk.newProps) {\n const { lc, lp, pb } = chunk.newProps;\n if (!this.lzmaDecoder.setLcLpPb(lc, lp, pb)) {\n throw new Error(`Invalid LZMA properties: lc=${lc} lp=${lp} pb=${pb}`);\n }\n this.propsSet = true;\n } else {\n // No new properties, check if we already have them\n if (!this.propsSet) {\n throw new Error('LZMA chunk without properties');\n }\n }\n\n // Reset probabilities if state reset\n if (chunk.stateReset) {\n this.lzmaDecoder.resetProbabilities();\n }\n\n // Determine solid mode - preserve dictionary if not resetting state or if only resetting state (not dict)\n const useSolid = !chunk.stateReset || (chunk.stateReset && !chunk.dictReset);\n\n // Decode LZMA chunk - use zero-copy when we have pre-allocated buffer\n if (outputBuffer) {\n // Zero-copy: decode directly into caller's buffer\n const bytesWritten = this.lzmaDecoder.decodeToBuffer(buf, dataOffset, chunk.uncompSize, outputBuffer, outputPos, useSolid);\n outputPos += bytesWritten;\n } else {\n // No pre-allocation: decode to new buffer and collect chunks\n const chunkData = buf.slice(dataOffset, dataOffset + chunk.compSize);\n const decoded = this.lzmaDecoder.decode(chunkData, 0, chunk.uncompSize, useSolid);\n outputChunks.push(decoded);\n }\n\n offset = dataOffset + chunk.compSize;\n }\n }\n\n // Return pre-allocated buffer or concatenated chunks\n if (outputBuffer) {\n return outputPos < outputBuffer.length ? outputBuffer.slice(0, outputPos) : outputBuffer;\n }\n return Buffer.concat(outputChunks);\n }\n}\n\n/**\n * Decode LZMA2 data synchronously\n * @param input - LZMA2 compressed data (Buffer or BufferList)\n * @param properties - 1-byte properties (dictionary size)\n * @param unpackSize - Expected output size (optional, autodetects if not provided)\n * @param outputSink - Optional output sink with write callback for streaming (returns bytes written)\n * @returns Decompressed data (or bytes written if outputSink provided)\n */\nexport function decodeLzma2(input: BufferLike, properties: Buffer | Uint8Array, unpackSize?: number, outputSink?: { write(buffer: Buffer): void }): Buffer | number {\n const decoder = new Lzma2Decoder(properties, outputSink as OutputSink);\n if (outputSink) {\n // Zero-copy mode: write to sink during decode\n return decoder.decodeWithSink(input);\n }\n // Buffering mode: returns Buffer (zero-copy)\n return decoder.decode(input, unpackSize);\n}\n"],"names":["Lzma2Decoder","decodeLzma2","properties","outputSink","length","Error","dictionarySize","parseLzma2DictionarySize","lzmaDecoder","LzmaDecoder","setDictionarySize","propsSet","resetDictionary","resetProbabilities","setLcLpPb","lc","lp","pb","feedUncompressed","data","decodeLzmaData","input","offset","outSize","solid","decode","decodeWithSink","buf","Buffer","isBuffer","toBuffer","totalBytes","result","parseLzma2ChunkHeader","success","chunk","type","dataSize","uncompSize","compSize","headerSize","dictReset","dataOffset","uncompData","slice","newProps","stateReset","useSolid","flushOutWindow","unpackSize","outputBuffer","outputPos","outputChunks","allocBufferUnsafe","copy","push","bytesWritten","decodeToBuffer","chunkData","decoded","concat","decoder"],"mappings":"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"}
@@ -27,7 +27,8 @@
27
27
  * and writes directly to it. Wrapping with an OutputSink that buffers to an
28
28
  * array defeats this optimization by creating unnecessary intermediate copies.
29
29
  */
30
- import { type DecodeCallback } from './utils/runDecode.js';
30
+ /** Callback for async decode operations: (error, result) => void */
31
+ export type DecodeCallback<T = Buffer> = (error: Error | null, result?: T) => void;
31
32
  /** Callback invoked when an async 7z decode completes */
32
33
  export type SevenZDecodeCallback = DecodeCallback<Buffer>;
33
34
  export declare function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;
@@ -27,7 +27,8 @@
27
27
  * and writes directly to it. Wrapping with an OutputSink that buffers to an
28
28
  * array defeats this optimization by creating unnecessary intermediate copies.
29
29
  */
30
- import { type DecodeCallback } from './utils/runDecode.js';
30
+ /** Callback for async decode operations: (error, result) => void */
31
+ export type DecodeCallback<T = Buffer> = (error: Error | null, result?: T) => void;
31
32
  /** Callback invoked when an async 7z decode completes */
32
33
  export type SevenZDecodeCallback = DecodeCallback<Buffer>;
33
34
  export declare function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;
@@ -47,24 +47,28 @@ _export(exports, {
47
47
  var _Lzma2Decoderts = require("./lzma/sync/Lzma2Decoder.js");
48
48
  var _LzmaDecoderts = require("./lzma/sync/LzmaDecoder.js");
49
49
  var _nativets = require("./native.js");
50
- var _runDecodets = require("./utils/runDecode.js");
50
+ var schedule = typeof setImmediate === 'function' ? setImmediate : function(fn) {
51
+ return process.nextTick(fn);
52
+ };
51
53
  function decode7zLzma(data, properties, unpackSize, callback) {
52
- return (0, _runDecodets.runDecode)(function(done) {
54
+ var worker = function(cb) {
53
55
  var fallback = function() {
54
- return (0, _runDecodets.runSync)(function() {
55
- return (0, _LzmaDecoderts.decodeLzma)(data, properties, unpackSize);
56
- }, done);
56
+ schedule(function() {
57
+ try {
58
+ cb(null, (0, _LzmaDecoderts.decodeLzma)(data, properties, unpackSize));
59
+ } catch (err) {
60
+ cb(err);
61
+ }
62
+ });
57
63
  };
58
64
  var native = (0, _nativets.tryLoadNative)();
59
- if (native && native.lzma) {
65
+ if (native === null || native === void 0 ? void 0 : native.lzma) {
60
66
  try {
61
67
  var promise = native.lzma(data, properties, unpackSize);
62
68
  if (promise && typeof promise.then === 'function') {
63
69
  promise.then(function(value) {
64
- return done(null, value);
65
- }, function() {
66
- return fallback();
67
- });
70
+ return cb(null, value);
71
+ }, fallback);
68
72
  return;
69
73
  }
70
74
  } catch (unused) {
@@ -72,25 +76,33 @@ function decode7zLzma(data, properties, unpackSize, callback) {
72
76
  }
73
77
  }
74
78
  fallback();
75
- }, callback);
79
+ };
80
+ if (typeof callback === 'function') return worker(callback);
81
+ return new Promise(function(resolve, reject) {
82
+ return worker(function(err, value) {
83
+ return err ? reject(err) : resolve(value);
84
+ });
85
+ });
76
86
  }
77
87
  function decode7zLzma2(data, properties, unpackSize, callback) {
78
- return (0, _runDecodets.runDecode)(function(done) {
88
+ var worker = function(cb) {
79
89
  var fallback = function() {
80
- return (0, _runDecodets.runSync)(function() {
81
- return (0, _Lzma2Decoderts.decodeLzma2)(data, properties, unpackSize);
82
- }, done);
90
+ schedule(function() {
91
+ try {
92
+ cb(null, (0, _Lzma2Decoderts.decodeLzma2)(data, properties, unpackSize));
93
+ } catch (err) {
94
+ cb(err);
95
+ }
96
+ });
83
97
  };
84
98
  var native = (0, _nativets.tryLoadNative)();
85
- if (native && native.lzma2) {
99
+ if (native === null || native === void 0 ? void 0 : native.lzma2) {
86
100
  try {
87
101
  var promise = native.lzma2(data, properties, unpackSize);
88
102
  if (promise && typeof promise.then === 'function') {
89
103
  promise.then(function(value) {
90
- return done(null, value);
91
- }, function() {
92
- return fallback();
93
- });
104
+ return cb(null, value);
105
+ }, fallback);
94
106
  return;
95
107
  }
96
108
  } catch (unused) {
@@ -98,6 +110,12 @@ function decode7zLzma2(data, properties, unpackSize, callback) {
98
110
  }
99
111
  }
100
112
  fallback();
101
- }, callback);
113
+ };
114
+ if (typeof callback === 'function') return worker(callback);
115
+ return new Promise(function(resolve, reject) {
116
+ return worker(function(err, value) {
117
+ return err ? reject(err) : resolve(value);
118
+ });
119
+ });
102
120
  }
103
121
  /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/sevenz.ts"],"sourcesContent":["/**\n * High-Level 7z-Specific Decoders\n *\n * These functions accept properties separately (matching 7z format structure)\n * and execute either the native lzma-native path or the pure JS fallback.\n *\n * This provides automatic native acceleration for 7z files while maintaining\n * the API that 7z-iterator expects.\n *\n * IMPORTANT: Buffer Management Pattern\n *\n * ❌ SLOW - DO NOT use OutputSink with buffering:\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← 3 copies: push + concat + return\n *\n * OutWindow → chunks.push(chunk) → Buffer.concat(chunks) → result\n * COPY TO ARRAY COPY ALL FINAL BUFFER\n *\n * ✅ FAST - Direct return (let decoder manage buffer):\n * return decodeLzma2(data, props, size) as Buffer; // ← 1 copy\n *\n * OutWindow → pre-allocated buffer → result\n * DIRECT WRITE\n *\n * The decodeLzma2() function internally pre-allocates the exact output size\n * and writes directly to it. Wrapping with an OutputSink that buffers to an\n * array defeats this optimization by creating unnecessary intermediate copies.\n */\n\nimport { decodeLzma2 } from './lzma/sync/Lzma2Decoder.ts';\nimport { decodeLzma } from './lzma/sync/LzmaDecoder.ts';\nimport { tryLoadNative } from './native.ts';\nimport { type DecodeCallback, runDecode, runSync } from './utils/runDecode.ts';\n\n/** Callback invoked when an async 7z decode completes */\nexport type SevenZDecodeCallback = DecodeCallback<Buffer>;\n\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number): Promise<Buffer>;\n/**\n * Decode LZMA-compressed data from a 7z file\n */\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n return runDecode((done) => {\n const fallback = () => runSync(() => decodeLzma(data, properties, unpackSize) as Buffer, done);\n const native = tryLoadNative();\n\n if (native && native.lzma) {\n try {\n const promise = native.lzma(data, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then(\n (value) => done(null, value),\n () => fallback()\n );\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n\n fallback();\n }, callback);\n}\n\n/**\n * Decode LZMA2-compressed data from a 7z file\n */\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize: number | undefined, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize?: number): Promise<Buffer>;\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize?: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n return runDecode((done) => {\n const fallback = () => runSync(() => decodeLzma2(data, properties, unpackSize) as Buffer, done);\n const native = tryLoadNative();\n\n if (native && native.lzma2) {\n try {\n const promise = native.lzma2(data, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then(\n (value) => done(null, value),\n () => fallback()\n );\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n\n fallback();\n }, callback);\n}\n"],"names":["decode7zLzma","decode7zLzma2","data","properties","unpackSize","callback","runDecode","done","fallback","runSync","decodeLzma","native","tryLoadNative","lzma","promise","then","value","decodeLzma2","lzma2"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC;;;;;;;;;;;QAeeA;eAAAA;;QA6BAC;eAAAA;;;8BA1CY;6BACD;wBACG;2BAC0B;AAUjD,SAASD,aAAaE,IAAY,EAAEC,UAAkB,EAAEC,UAAkB,EAAEC,QAA+B;IAChH,OAAOC,IAAAA,sBAAS,EAAC,SAACC;QAChB,IAAMC,WAAW;mBAAMC,IAAAA,oBAAO,EAAC;uBAAMC,IAAAA,yBAAU,EAACR,MAAMC,YAAYC;eAAuBG;;QACzF,IAAMI,SAASC,IAAAA,uBAAa;QAE5B,IAAID,UAAUA,OAAOE,IAAI,EAAE;YACzB,IAAI;gBACF,IAAMC,UAAUH,OAAOE,IAAI,CAACX,MAAMC,YAAYC;gBAC9C,IAAIU,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CACV,SAACC;+BAAUT,KAAK,MAAMS;uBACtB;+BAAMR;;oBAER;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QAEAA;IACF,GAAGH;AACL;AAOO,SAASJ,cAAcC,IAAY,EAAEC,UAAkB,EAAEC,UAAmB,EAAEC,QAA+B;IAClH,OAAOC,IAAAA,sBAAS,EAAC,SAACC;QAChB,IAAMC,WAAW;mBAAMC,IAAAA,oBAAO,EAAC;uBAAMQ,IAAAA,2BAAW,EAACf,MAAMC,YAAYC;eAAuBG;;QAC1F,IAAMI,SAASC,IAAAA,uBAAa;QAE5B,IAAID,UAAUA,OAAOO,KAAK,EAAE;YAC1B,IAAI;gBACF,IAAMJ,UAAUH,OAAOO,KAAK,CAAChB,MAAMC,YAAYC;gBAC/C,IAAIU,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CACV,SAACC;+BAAUT,KAAK,MAAMS;uBACtB;+BAAMR;;oBAER;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QAEAA;IACF,GAAGH;AACL"}
1
+ {"version":3,"sources":["/Users/kevin/Dev/iterators/xz-compat/src/sevenz.ts"],"sourcesContent":["/**\n * High-Level 7z-Specific Decoders\n *\n * These functions accept properties separately (matching 7z format structure)\n * and execute either the native lzma-native path or the pure JS fallback.\n *\n * This provides automatic native acceleration for 7z files while maintaining\n * the API that 7z-iterator expects.\n *\n * IMPORTANT: Buffer Management Pattern\n *\n * ❌ SLOW - DO NOT use OutputSink with buffering:\n * const chunks: Buffer[] = [];\n * decodeLzma2(data, props, size, { write: c => chunks.push(c) });\n * return Buffer.concat(chunks); // ← 3 copies: push + concat + return\n *\n * OutWindow → chunks.push(chunk) → Buffer.concat(chunks) → result\n * COPY TO ARRAY COPY ALL FINAL BUFFER\n *\n * ✅ FAST - Direct return (let decoder manage buffer):\n * return decodeLzma2(data, props, size) as Buffer; // ← 1 copy\n *\n * OutWindow → pre-allocated buffer → result\n * DIRECT WRITE\n *\n * The decodeLzma2() function internally pre-allocates the exact output size\n * and writes directly to it. Wrapping with an OutputSink that buffers to an\n * array defeats this optimization by creating unnecessary intermediate copies.\n */\n\nimport { decodeLzma2 } from './lzma/sync/Lzma2Decoder.ts';\nimport { decodeLzma } from './lzma/sync/LzmaDecoder.ts';\nimport { tryLoadNative } from './native.ts';\n\n/** Callback for async decode operations: (error, result) => void */\nexport type DecodeCallback<T = Buffer> = (error: Error | null, result?: T) => void;\n\n/** Callback invoked when an async 7z decode completes */\nexport type SevenZDecodeCallback = DecodeCallback<Buffer>;\n\nconst schedule = typeof setImmediate === 'function' ? setImmediate : (fn: () => void) => process.nextTick(fn);\n\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number): Promise<Buffer>;\n/**\n * Decode LZMA-compressed data from a 7z file\n */\nexport function decode7zLzma(data: Buffer, properties: Buffer, unpackSize: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma) {\n try {\n const promise = native.lzma(data, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n\n/**\n * Decode LZMA2-compressed data from a 7z file\n */\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize: number | undefined, callback: SevenZDecodeCallback): void;\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize?: number): Promise<Buffer>;\nexport function decode7zLzma2(data: Buffer, properties: Buffer, unpackSize?: number, callback?: SevenZDecodeCallback): Promise<Buffer> | void {\n const worker = (cb: SevenZDecodeCallback) => {\n const fallback = () => {\n schedule(() => {\n try {\n cb(null, decodeLzma2(data, properties, unpackSize) as Buffer);\n } catch (err) {\n cb(err as Error);\n }\n });\n };\n\n const native = tryLoadNative();\n if (native?.lzma2) {\n try {\n const promise = native.lzma2(data, properties, unpackSize);\n if (promise && typeof promise.then === 'function') {\n promise.then((value) => cb(null, value), fallback);\n return;\n }\n } catch {\n // fall through to fallback\n }\n }\n fallback();\n };\n\n if (typeof callback === 'function') return worker(callback);\n return new Promise((resolve, reject) => worker((err, value) => (err ? reject(err) : resolve(value as Buffer))));\n}\n"],"names":["decode7zLzma","decode7zLzma2","schedule","setImmediate","fn","process","nextTick","data","properties","unpackSize","callback","worker","cb","fallback","decodeLzma","err","native","tryLoadNative","lzma","promise","then","value","Promise","resolve","reject","decodeLzma2","lzma2"],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BC;;;;;;;;;;;QAmBeA;eAAAA;;QAoCAC;eAAAA;;;8BArDY;6BACD;wBACG;AAQ9B,IAAMC,WAAW,OAAOC,iBAAiB,aAAaA,eAAe,SAACC;WAAmBC,QAAQC,QAAQ,CAACF;;AAOnG,SAASJ,aAAaO,IAAY,EAAEC,UAAkB,EAAEC,UAAkB,EAAEC,QAA+B;IAChH,IAAMC,SAAS,SAACC;QACd,IAAMC,WAAW;YACfX,SAAS;gBACP,IAAI;oBACFU,GAAG,MAAME,IAAAA,yBAAU,EAACP,MAAMC,YAAYC;gBACxC,EAAE,OAAOM,KAAK;oBACZH,GAAGG;gBACL;YACF;QACF;QAEA,IAAMC,SAASC,IAAAA,uBAAa;QAC5B,IAAID,mBAAAA,6BAAAA,OAAQE,IAAI,EAAE;YAChB,IAAI;gBACF,IAAMC,UAAUH,OAAOE,IAAI,CAACX,MAAMC,YAAYC;gBAC9C,IAAIU,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CAAC,SAACC;+BAAUT,GAAG,MAAMS;uBAAQR;oBACzC;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QACAA;IACF;IAEA,IAAI,OAAOH,aAAa,YAAY,OAAOC,OAAOD;IAClD,OAAO,IAAIY,QAAQ,SAACC,SAASC;eAAWb,OAAO,SAACI,KAAKM;mBAAWN,MAAMS,OAAOT,OAAOQ,QAAQF;;;AAC9F;AAOO,SAASpB,cAAcM,IAAY,EAAEC,UAAkB,EAAEC,UAAmB,EAAEC,QAA+B;IAClH,IAAMC,SAAS,SAACC;QACd,IAAMC,WAAW;YACfX,SAAS;gBACP,IAAI;oBACFU,GAAG,MAAMa,IAAAA,2BAAW,EAAClB,MAAMC,YAAYC;gBACzC,EAAE,OAAOM,KAAK;oBACZH,GAAGG;gBACL;YACF;QACF;QAEA,IAAMC,SAASC,IAAAA,uBAAa;QAC5B,IAAID,mBAAAA,6BAAAA,OAAQU,KAAK,EAAE;YACjB,IAAI;gBACF,IAAMP,UAAUH,OAAOU,KAAK,CAACnB,MAAMC,YAAYC;gBAC/C,IAAIU,WAAW,OAAOA,QAAQC,IAAI,KAAK,YAAY;oBACjDD,QAAQC,IAAI,CAAC,SAACC;+BAAUT,GAAG,MAAMS;uBAAQR;oBACzC;gBACF;YACF,EAAE,eAAM;YACN,2BAA2B;YAC7B;QACF;QACAA;IACF;IAEA,IAAI,OAAOH,aAAa,YAAY,OAAOC,OAAOD;IAClD,OAAO,IAAIY,QAAQ,SAACC,SAASC;eAAWb,OAAO,SAACI,KAAKM;mBAAWN,MAAMS,OAAOT,OAAOQ,QAAQF;;;AAC9F"}
@@ -18,14 +18,26 @@
18
18
  * decodeLzma2(data, props, size, { write: c => chunks.push(c) });
19
19
  * return Buffer.concat(chunks); // ← Unnecessary copies!
20
20
  */
21
+ import { type BufferLike } from 'extract-base-iterator';
21
22
  import type { Transform as TransformType } from 'stream';
22
- import { type DecodeCallback } from '../utils/runDecode.js';
23
+ import type { DecodeCallback } from '../sevenz.js';
24
+ export type { BufferLike } from 'extract-base-iterator';
23
25
  /** Callback invoked when an async decode completes */
24
- export type XzDecodeCallback = DecodeCallback<Buffer>;
26
+ export type XzDecodeCallback = DecodeCallback<BufferLike>;
27
+ /**
28
+ * Decompress XZ data. With a callback the result is provided asynchronously;
29
+ * otherwise a Promise resolves with the decoded data.
30
+ *
31
+ * Returns Buffer for single-block files (most small files).
32
+ * Returns BufferList for multi-block files (avoids large contiguous allocation).
33
+ */
25
34
  export declare function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;
26
- export declare function decodeXZ(input: Buffer): Promise<Buffer>;
35
+ export declare function decodeXZ(input: Buffer): Promise<BufferLike>;
27
36
  /**
28
37
  * Create an XZ decompression Transform stream
29
38
  * @returns Transform stream that decompresses XZ data
39
+ *
40
+ * Uses BufferList to avoid large contiguous buffer allocations.
41
+ * Decompresses and pushes blocks one at a time for streaming output.
30
42
  */
31
43
  export declare function createXZDecoder(): TransformType;
@@ -18,14 +18,26 @@
18
18
  * decodeLzma2(data, props, size, { write: c => chunks.push(c) });
19
19
  * return Buffer.concat(chunks); // ← Unnecessary copies!
20
20
  */
21
+ import { type BufferLike } from 'extract-base-iterator';
21
22
  import type { Transform as TransformType } from 'stream';
22
- import { type DecodeCallback } from '../utils/runDecode.js';
23
+ import type { DecodeCallback } from '../sevenz.js';
24
+ export type { BufferLike } from 'extract-base-iterator';
23
25
  /** Callback invoked when an async decode completes */
24
- export type XzDecodeCallback = DecodeCallback<Buffer>;
26
+ export type XzDecodeCallback = DecodeCallback<BufferLike>;
27
+ /**
28
+ * Decompress XZ data. With a callback the result is provided asynchronously;
29
+ * otherwise a Promise resolves with the decoded data.
30
+ *
31
+ * Returns Buffer for single-block files (most small files).
32
+ * Returns BufferList for multi-block files (avoids large contiguous allocation).
33
+ */
25
34
  export declare function decodeXZ(input: Buffer, callback: XzDecodeCallback): void;
26
- export declare function decodeXZ(input: Buffer): Promise<Buffer>;
35
+ export declare function decodeXZ(input: Buffer): Promise<BufferLike>;
27
36
  /**
28
37
  * Create an XZ decompression Transform stream
29
38
  * @returns Transform stream that decompresses XZ data
39
+ *
40
+ * Uses BufferList to avoid large contiguous buffer allocations.
41
+ * Decompresses and pushes blocks one at a time for streaming output.
30
42
  */
31
43
  export declare function createXZDecoder(): TransformType;