@push.rocks/smartarchive 4.0.39 → 4.2.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 CHANGED
@@ -1,266 +1,333 @@
1
- # @push.rocks/smartarchive
1
+ # @push.rocks/smartarchive 📦
2
2
 
3
- `@push.rocks/smartarchive` is a powerful library designed for managing archive files. It provides utilities for compressing and decompressing data in various formats such as zip, tar, gzip, and bzip2. This library aims to simplify the process of handling archive files, making it an ideal choice for projects that require manipulation of archived data.
3
+ **Powerful archive manipulation for modern Node.js applications**
4
4
 
5
- ## Install
5
+ `@push.rocks/smartarchive` is a versatile library for handling archive files with a focus on developer experience. Work with **zip**, **tar**, **gzip**, and **bzip2** formats through a unified, streaming-optimized API.
6
6
 
7
- To install `@push.rocks/smartarchive`, you can either use npm or yarn. Run one of the following commands in your project directory:
7
+ ## Features 🚀
8
8
 
9
- ```shell
10
- npm install @push.rocks/smartarchive --save
11
- ```
9
+ - 📁 **Multi-format support** - Handle `.zip`, `.tar`, `.tar.gz`, `.tgz`, and `.bz2` archives
10
+ - 🌊 **Streaming-first architecture** - Process large archives without memory constraints
11
+ - 🔄 **Unified API** - Consistent interface across different archive formats
12
+ - 🎯 **Smart detection** - Automatically identifies archive types
13
+ - ⚡ **High performance** - Optimized for speed with parallel processing where possible
14
+ - 🔧 **Flexible I/O** - Work with files, URLs, and streams seamlessly
15
+ - 📊 **Archive analysis** - Inspect contents without extraction
16
+ - 🛠️ **Modern TypeScript** - Full type safety and excellent IDE support
12
17
 
13
- or if you prefer yarn:
18
+ ## Installation 📥
14
19
 
15
- ```shell
16
- yarn add @push.rocks/smartarchive
17
- ```
20
+ ```bash
21
+ # Using npm
22
+ npm install @push.rocks/smartarchive
18
23
 
19
- This will add `@push.rocks/smartarchive` to your project's dependencies.
24
+ # Using pnpm (recommended)
25
+ pnpm add @push.rocks/smartarchive
20
26
 
21
- ## Usage
22
- `@push.rocks/smartarchive` provides an easy-to-use API for extracting, creating, and analyzing archive files. Below, we'll cover how to get started and explore various features of the module.
27
+ # Using yarn
28
+ yarn add @push.rocks/smartarchive
29
+ ```
23
30
 
24
- ### Importing SmartArchive
31
+ ## Quick Start 🎯
25
32
 
26
- First, import `SmartArchive` from `@push.rocks/smartarchive` using ESM syntax:
33
+ ### Extract an archive from URL
27
34
 
28
35
  ```typescript
29
36
  import { SmartArchive } from '@push.rocks/smartarchive';
30
- ```
31
37
 
32
- ### Extracting Archive Files
38
+ // Extract a .tar.gz archive from a URL directly to the filesystem
39
+ const archive = await SmartArchive.fromArchiveUrl(
40
+ 'https://github.com/some/repo/archive/main.tar.gz'
41
+ );
42
+ await archive.exportToFs('./extracted');
43
+ ```
33
44
 
34
- You can extract archive files from different sources using `SmartArchive.fromArchiveUrl`, `SmartArchive.fromArchiveFile`, and `SmartArchive.fromArchiveStream`. Here's an example of extracting an archive from a URL:
45
+ ### Process archive as a stream
35
46
 
36
47
  ```typescript
37
48
  import { SmartArchive } from '@push.rocks/smartarchive';
38
49
 
39
- async function extractArchiveFromURL() {
40
- const url = 'https://example.com/archive.zip';
41
- const targetDir = '/path/to/extract';
42
-
43
- const archive = await SmartArchive.fromArchiveUrl(url);
44
- await archive.exportToFs(targetDir);
50
+ // Stream-based processing for memory efficiency
51
+ const archive = await SmartArchive.fromArchiveFile('./large-archive.zip');
52
+ const streamOfFiles = await archive.exportToStreamOfStreamFiles();
45
53
 
46
- console.log('Archive extracted successfully.');
47
- }
48
-
49
- extractArchiveFromURL();
54
+ // Process each file in the archive
55
+ streamOfFiles.on('data', (fileStream) => {
56
+ console.log(`Processing ${fileStream.path}`);
57
+ // Handle individual file stream
58
+ });
50
59
  ```
51
60
 
52
- ### Extracting an Archive from a File
61
+ ## Core Concepts 💡
53
62
 
54
- Similarly, you can extract an archive from a local file:
63
+ ### Archive Sources
55
64
 
56
- ```typescript
57
- import { SmartArchive } from '@push.rocks/smartarchive';
65
+ `SmartArchive` accepts archives from three sources:
58
66
 
59
- async function extractArchiveFromFile() {
60
- const filePath = '/path/to/archive.zip';
61
- const targetDir = '/path/to/extract';
67
+ 1. **URL** - Download and process archives from the web
68
+ 2. **File** - Load archives from the local filesystem
69
+ 3. **Stream** - Process archives from any Node.js stream
62
70
 
63
- const archive = await SmartArchive.fromArchiveFile(filePath);
64
- await archive.exportToFs(targetDir);
71
+ ### Export Destinations
65
72
 
66
- console.log('Archive extracted successfully.');
67
- }
73
+ Extract archives to multiple destinations:
68
74
 
69
- extractArchiveFromFile();
70
- ```
75
+ 1. **Filesystem** - Extract directly to a directory
76
+ 2. **Stream of files** - Process files individually as streams
77
+ 3. **Archive stream** - Re-stream as different format
71
78
 
72
- ### Stream-Based Extraction
79
+ ## Usage Examples 🔨
73
80
 
74
- For larger files, you might prefer a streaming approach to prevent high memory consumption. Here’s an example:
81
+ ### Working with ZIP files
75
82
 
76
83
  ```typescript
77
84
  import { SmartArchive } from '@push.rocks/smartarchive';
78
- import { createReadStream } from 'fs';
79
-
80
- async function extractArchiveUsingStream() {
81
- const archiveStream = createReadStream('/path/to/archive.zip');
82
- const archive = await SmartArchive.fromArchiveStream(archiveStream);
83
- const extractionStream = await archive.exportToStreamOfStreamFiles();
84
-
85
- extractionStream.pipe(createWriteStream('/path/to/destination'));
86
- }
87
85
 
88
- extractArchiveUsingStream();
86
+ // Extract a ZIP file
87
+ const zipArchive = await SmartArchive.fromArchiveFile('./archive.zip');
88
+ await zipArchive.exportToFs('./output');
89
+
90
+ // Stream ZIP contents for processing
91
+ const fileStream = await zipArchive.exportToStreamOfStreamFiles();
92
+ fileStream.on('data', (file) => {
93
+ if (file.path.endsWith('.json')) {
94
+ // Process JSON files from the archive
95
+ file.pipe(jsonProcessor);
96
+ }
97
+ });
89
98
  ```
90
99
 
91
- ### Analyzing Archive Files
100
+ ### Working with TAR archives
92
101
 
93
- Sometimes, you may need to inspect the contents of an archive before extracting it. The following example shows how to analyze an archive:
102
+ ```typescript
103
+ import { SmartArchive, TarTools } from '@push.rocks/smartarchive';
104
+
105
+ // Extract a .tar.gz file
106
+ const tarGzArchive = await SmartArchive.fromArchiveFile('./archive.tar.gz');
107
+ await tarGzArchive.exportToFs('./extracted');
108
+
109
+ // Create a TAR archive (using TarTools directly)
110
+ const tarTools = new TarTools();
111
+ const packStream = await tarTools.packDirectory('./source-directory');
112
+ packStream.pipe(createWriteStream('./output.tar'));
113
+ ```
114
+
115
+ ### Extracting from URLs
94
116
 
95
117
  ```typescript
96
118
  import { SmartArchive } from '@push.rocks/smartarchive';
97
119
 
98
- async function analyzeArchive() {
99
- const filePath = '/path/to/archive.zip';
100
-
101
- const archive = await SmartArchive.fromArchiveFile(filePath);
102
- const analysisResult = await archive.analyzeContent();
103
-
104
- console.log(analysisResult); // Outputs details about the archive content
105
- }
120
+ // Download and extract in one operation
121
+ const remoteArchive = await SmartArchive.fromArchiveUrl(
122
+ 'https://example.com/data.tar.gz'
123
+ );
106
124
 
107
- analyzeArchive();
108
- ```
125
+ // Extract to filesystem
126
+ await remoteArchive.exportToFs('./local-dir');
109
127
 
110
- ### Creating Archive Files
128
+ // Or process as stream
129
+ const stream = await remoteArchive.exportToStreamOfStreamFiles();
130
+ ```
111
131
 
112
- Creating an archive file is straightforward. Here we demonstrate creating a tar.gz archive:
132
+ ### Analyzing archive contents
113
133
 
114
134
  ```typescript
115
135
  import { SmartArchive } from '@push.rocks/smartarchive';
116
136
 
117
- async function createTarGzArchive() {
118
- const archive = new SmartArchive();
119
-
120
- // Add directories and files
121
- archive.addedDirectories.push('/path/to/directory1');
122
- archive.addedFiles.push('/path/to/file1.txt');
123
-
124
- // Export as tar.gz
125
- const tarGzStream = await archive.exportToTarGzStream();
126
-
127
- // Save to filesystem or handle as needed
128
- tarGzStream.pipe(createWriteStream('/path/to/destination.tar.gz'));
129
- }
137
+ // Analyze without extracting
138
+ const archive = await SmartArchive.fromArchiveFile('./archive.zip');
139
+ const analyzer = archive.archiveAnalyzer;
130
140
 
131
- createTarGzArchive();
141
+ // Use the analyzer to inspect contents
142
+ // (exact implementation depends on analyzer methods)
132
143
  ```
133
144
 
134
- ### Stream Operations
135
-
136
- Here's an example of using `smartarchive`'s streaming capabilities:
145
+ ### Working with GZIP files
137
146
 
138
147
  ```typescript
139
- import { createReadStream, createWriteStream } from 'fs';
140
- import { SmartArchive } from '@push.rocks/smartarchive';
148
+ import { SmartArchive, GzipTools } from '@push.rocks/smartarchive';
141
149
 
142
- async function extractArchiveUsingStreams() {
143
- const archiveStream = createReadStream('/path/to/archive.zip');
144
- const archive = await SmartArchive.fromArchiveStream(archiveStream);
145
- const extractionStream = await archive.exportToStreamOfStreamFiles();
146
-
147
- extractionStream.pipe(createWriteStream('/path/to/extracted'));
148
- }
150
+ // Decompress a .gz file
151
+ const gzipArchive = await SmartArchive.fromArchiveFile('./data.json.gz');
152
+ await gzipArchive.exportToFs('./decompressed', 'data.json');
153
+
154
+ // Use GzipTools directly for streaming
155
+ const gzipTools = new GzipTools();
156
+ const decompressStream = gzipTools.getDecompressionStream();
149
157
 
150
- extractArchiveUsingStreams();
158
+ createReadStream('./compressed.gz')
159
+ .pipe(decompressStream)
160
+ .pipe(createWriteStream('./decompressed'));
151
161
  ```
152
162
 
153
- ### Advanced Decompression Usage
163
+ ### Working with BZIP2 files
154
164
 
155
- `smartarchive` supports multiple compression formats. It also provides detailed control over the decompression processes:
165
+ ```typescript
166
+ import { SmartArchive } from '@push.rocks/smartarchive';
156
167
 
157
- - For ZIP files, `ZipTools` handles decompression using the `fflate` library.
158
- - For TAR files, `TarTools` uses `tar-stream`.
159
- - For GZIP files, `GzipTools` provides a `CompressGunzipTransform` and `DecompressGunzipTransform`.
160
- - For BZIP2 files, `Bzip2Tools` utilizes custom streaming decompression.
168
+ // Handle .bz2 files
169
+ const bzipArchive = await SmartArchive.fromArchiveUrl(
170
+ 'https://example.com/data.bz2'
171
+ );
172
+ await bzipArchive.exportToFs('./extracted', 'data.txt');
173
+ ```
161
174
 
162
- Example: Working with a GZIP-compressed archive:
175
+ ### Advanced streaming operations
163
176
 
164
177
  ```typescript
165
- import { createReadStream, createWriteStream } from 'fs';
166
178
  import { SmartArchive } from '@push.rocks/smartarchive';
179
+ import { pipeline } from 'stream/promises';
180
+
181
+ // Chain operations with streams
182
+ const archive = await SmartArchive.fromArchiveFile('./archive.tar.gz');
183
+ const exportStream = await archive.exportToStreamOfStreamFiles();
184
+
185
+ // Process each file in the archive
186
+ await pipeline(
187
+ exportStream,
188
+ async function* (source) {
189
+ for await (const file of source) {
190
+ if (file.path.endsWith('.log')) {
191
+ // Process log files
192
+ yield processLogFile(file);
193
+ }
194
+ }
195
+ },
196
+ createWriteStream('./processed-logs.txt')
197
+ );
198
+ ```
167
199
 
168
- async function decompressGzipArchive() {
169
- const filePath = '/path/to/archive.gz';
170
- const targetDir = '/path/to/extract';
200
+ ### Creating archives (advanced)
171
201
 
172
- const archive = await SmartArchive.fromArchiveFile(filePath);
173
- await archive.exportToFs(targetDir);
202
+ ```typescript
203
+ import { SmartArchive } from '@push.rocks/smartarchive';
204
+ import { TarTools } from '@push.rocks/smartarchive';
174
205
 
175
- console.log('GZIP archive decompressed successfully.');
176
- }
206
+ // Using SmartArchive to create an archive
207
+ const archive = new SmartArchive();
177
208
 
178
- decompressGzipArchive();
179
- ```
209
+ // Add content to the archive
210
+ archive.addedDirectories.push('./src');
211
+ archive.addedFiles.push('./readme.md');
212
+ archive.addedFiles.push('./package.json');
180
213
 
181
- ### Advancing with Custom Decompression Streams
214
+ // Export as TAR.GZ
215
+ const tarGzStream = await archive.exportToTarGzStream();
216
+ tarGzStream.pipe(createWriteStream('./output.tar.gz'));
217
+ ```
182
218
 
183
- You can inject custom decompression streams where needed:
219
+ ### Extract and transform
184
220
 
185
221
  ```typescript
186
- import { createReadStream, createWriteStream } from 'fs';
187
- import { SmartArchive, GzipTools } from '@push.rocks/smartarchive';
222
+ import { SmartArchive } from '@push.rocks/smartarchive';
223
+ import { Transform } from 'stream';
224
+
225
+ // Extract and transform files in one pipeline
226
+ const archive = await SmartArchive.fromArchiveUrl(
227
+ 'https://example.com/source-code.tar.gz'
228
+ );
229
+
230
+ const extractStream = await archive.exportToStreamOfStreamFiles();
231
+
232
+ // Transform TypeScript to JavaScript during extraction
233
+ extractStream.on('data', (fileStream) => {
234
+ if (fileStream.path.endsWith('.ts')) {
235
+ fileStream
236
+ .pipe(typescriptTranspiler())
237
+ .pipe(createWriteStream(fileStream.path.replace('.ts', '.js')));
238
+ } else {
239
+ fileStream.pipe(createWriteStream(fileStream.path));
240
+ }
241
+ });
242
+ ```
188
243
 
189
- async function customDecompression() {
190
- const filePath = '/path/to/archive.gz';
191
- const targetDir = '/path/to/extract';
244
+ ## API Reference 📚
192
245
 
193
- const archive = await SmartArchive.fromArchiveFile(filePath);
194
- const gzipTools = new GzipTools();
195
- const decompressionStream = gzipTools.getDecompressionStream();
246
+ ### SmartArchive Class
196
247
 
197
- const archiveStream = await archive.getArchiveStream();
198
- archiveStream.pipe(decompressionStream).pipe(createWriteStream(targetDir));
248
+ #### Static Methods
199
249
 
200
- console.log('Custom GZIP decompression successful.');
201
- }
250
+ - `SmartArchive.fromArchiveUrl(url: string)` - Create from URL
251
+ - `SmartArchive.fromArchiveFile(path: string)` - Create from file
252
+ - `SmartArchive.fromArchiveStream(stream: NodeJS.ReadableStream)` - Create from stream
202
253
 
203
- customDecompression();
204
- ```
254
+ #### Instance Methods
205
255
 
206
- ### Custom Pack and Unpack Tar
256
+ - `exportToFs(targetDir: string, fileName?: string)` - Extract to filesystem
257
+ - `exportToStreamOfStreamFiles()` - Get a stream of file streams
258
+ - `exportToTarGzStream()` - Export as TAR.GZ stream
259
+ - `getArchiveStream()` - Get the raw archive stream
207
260
 
208
- When dealing with tar archives, you may need to perform custom packing and unpacking:
261
+ #### Properties
209
262
 
210
- ```typescript
211
- import { SmartArchive, TarTools } from '@push.rocks/smartarchive';
212
- import { createWriteStream } from 'fs';
213
-
214
- async function customTarOperations() {
215
- const tarTools = new TarTools();
216
-
217
- // Packing a directory into a tar stream
218
- const packStream = await tarTools.packDirectory('/path/to/directory');
219
- packStream.pipe(createWriteStream('/path/to/archive.tar'));
220
-
221
- // Extracting files from a tar stream
222
- const extractStream = tarTools.getDecompressionStream();
223
- createReadStream('/path/to/archive.tar').pipe(extractStream).on('entry', (header, stream, next) => {
224
- const writeStream = createWriteStream(`/path/to/extract/${header.name}`);
225
- stream.pipe(writeStream);
226
- stream.on('end', next);
227
- });
228
- }
263
+ - `archiveAnalyzer` - Analyze archive contents
264
+ - `tarTools` - TAR-specific operations
265
+ - `zipTools` - ZIP-specific operations
266
+ - `gzipTools` - GZIP-specific operations
267
+ - `bzip2Tools` - BZIP2-specific operations
229
268
 
230
- customTarOperations();
231
- ```
269
+ ### Specialized Tools
232
270
 
233
- ### Extract and Analyze All-in-One
271
+ Each tool class provides format-specific operations:
234
272
 
235
- To extract and simultaneously analyze archive content:
273
+ - **TarTools** - Pack/unpack TAR archives
274
+ - **ZipTools** - Handle ZIP compression
275
+ - **GzipTools** - GZIP compression/decompression
276
+ - **Bzip2Tools** - BZIP2 operations
236
277
 
237
- ```typescript
238
- import { createReadStream, createWriteStream } from 'fs';
239
- import { SmartArchive } from '@push.rocks/smartarchive';
278
+ ## Performance Tips 🏎️
240
279
 
241
- async function extractAndAnalyze() {
242
- const filePath = '/path/to/archive.zip';
243
- const targetDir = '/path/to/extract';
280
+ 1. **Use streaming for large files** - Avoid loading entire archives into memory
281
+ 2. **Process files in parallel** - Utilize stream operations for concurrent processing
282
+ 3. **Choose the right format** - TAR.GZ for Unix systems, ZIP for cross-platform compatibility
283
+ 4. **Enable compression wisely** - Balance between file size and CPU usage
244
284
 
245
- const archive = await SmartArchive.fromArchiveFile(filePath);
246
- const analyzedStream = archive.archiveAnalyzer.getAnalyzedStream();
247
- const extractionStream = await archive.exportToStreamOfStreamFiles();
285
+ ## Error Handling 🛡️
248
286
 
249
- analyzedStream.pipe(extractionStream).pipe(createWriteStream(targetDir));
287
+ ```typescript
288
+ import { SmartArchive } from '@push.rocks/smartarchive';
250
289
 
251
- analyzedStream.on('data', (chunk) => {
252
- console.log(JSON.stringify(chunk, null, 2));
253
- });
290
+ try {
291
+ const archive = await SmartArchive.fromArchiveUrl('https://example.com/file.zip');
292
+ await archive.exportToFs('./output');
293
+ } catch (error) {
294
+ if (error.code === 'ENOENT') {
295
+ console.error('Archive file not found');
296
+ } else if (error.code === 'EACCES') {
297
+ console.error('Permission denied');
298
+ } else {
299
+ console.error('Archive extraction failed:', error.message);
300
+ }
254
301
  }
255
-
256
- extractAndAnalyze();
257
302
  ```
258
303
 
259
- ### Final Words
304
+ ## Real-World Use Cases 🌍
260
305
 
261
- These examples demonstrate various use cases for `@push.rocks/smartarchive`. Depending on your specific project requirements, you can adapt these examples to suit your needs. Always refer to the latest documentation for the most current information and methods available in `@push.rocks/smartarchive`.
306
+ ### Backup System
307
+ ```typescript
308
+ // Automated backup extraction
309
+ const backup = await SmartArchive.fromArchiveFile('./backup.tar.gz');
310
+ await backup.exportToFs('/restore/location');
311
+ ```
262
312
 
263
- For more information and API references, check the official [`@push.rocks/smartarchive` GitHub repository](https://code.foss.global/push.rocks/smartarchive).
313
+ ### CI/CD Pipeline
314
+ ```typescript
315
+ // Download and extract build artifacts
316
+ const artifacts = await SmartArchive.fromArchiveUrl(
317
+ `${CI_SERVER}/artifacts/build-${BUILD_ID}.zip`
318
+ );
319
+ await artifacts.exportToFs('./dist');
320
+ ```
321
+
322
+ ### Data Processing
323
+ ```typescript
324
+ // Process compressed datasets
325
+ const dataset = await SmartArchive.fromArchiveUrl(
326
+ 'https://data.source/dataset.tar.bz2'
327
+ );
328
+ const files = await dataset.exportToStreamOfStreamFiles();
329
+ // Process each file in the dataset
330
+ ```
264
331
 
265
332
  ## License and Legal Information
266
333
 
@@ -279,4 +346,4 @@ Registered at District court Bremen HRB 35230 HB, Germany
279
346
 
280
347
  For any legal inquiries or if you require further information, please contact us via email at hello@task.vc.
281
348
 
282
- By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
349
+ By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@push.rocks/smartarchive',
6
- version: '4.0.39',
6
+ version: '4.2.0',
7
7
  description: 'A library for working with archive files, providing utilities for compressing and decompressing data.'
8
8
  }
@@ -1,41 +1,44 @@
1
- var BITMASK = [0, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF];
1
+ var BITMASK = [0, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff];
2
2
 
3
3
  // returns a function that reads bits.
4
4
  // takes a buffer iterator as input
5
5
  export function bitIterator(nextBuffer: () => Buffer) {
6
- var bit = 0, byte = 0;
7
- var bytes = nextBuffer();
8
- var f = function(n) {
9
- if (n === null && bit != 0) { // align to byte boundary
10
- bit = 0
11
- byte++;
12
- return;
13
- }
14
- var result = 0;
15
- while(n > 0) {
16
- if (byte >= bytes.length) {
17
- byte = 0;
18
- bytes = nextBuffer();
19
- }
20
- var left = 8 - bit;
21
- if (bit === 0 && n > 0)
22
- // @ts-ignore
23
- f.bytesRead++;
24
- if (n >= left) {
25
- result <<= left;
26
- result |= (BITMASK[left] & bytes[byte++]);
27
- bit = 0;
28
- n -= left;
29
- } else {
30
- result <<= n;
31
- result |= ((bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit));
32
- bit += n;
33
- n = 0;
34
- }
35
- }
36
- return result;
37
- };
38
- // @ts-ignore
39
- f.bytesRead = 0;
40
- return f;
41
- };
6
+ var bit = 0,
7
+ byte = 0;
8
+ var bytes = nextBuffer();
9
+ var f = function (n) {
10
+ if (n === null && bit != 0) {
11
+ // align to byte boundary
12
+ bit = 0;
13
+ byte++;
14
+ return;
15
+ }
16
+ var result = 0;
17
+ while (n > 0) {
18
+ if (byte >= bytes.length) {
19
+ byte = 0;
20
+ bytes = nextBuffer();
21
+ }
22
+ var left = 8 - bit;
23
+ if (bit === 0 && n > 0)
24
+ // @ts-ignore
25
+ f.bytesRead++;
26
+ if (n >= left) {
27
+ result <<= left;
28
+ result |= BITMASK[left] & bytes[byte++];
29
+ bit = 0;
30
+ n -= left;
31
+ } else {
32
+ result <<= n;
33
+ result |=
34
+ (bytes[byte] & (BITMASK[n] << (8 - n - bit))) >> (8 - n - bit);
35
+ bit += n;
36
+ n = 0;
37
+ }
38
+ }
39
+ return result;
40
+ };
41
+ // @ts-ignore
42
+ f.bytesRead = 0;
43
+ return f;
44
+ }