Skip to content

Commit

Permalink
Fix issue #44, make decompress work in NodeJS (use Worker only where …
Browse files Browse the repository at this point in the history
…possible).
  • Loading branch information
codedread committed Dec 12, 2023
1 parent 5ad8989 commit f71c893
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 34 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## [1.1.7] - 2023-12-11

### Changed

- decompress: Allow unarchiving in Node.

## [1.1.6] - 2023-10-25

### Changed
Expand Down
34 changes: 28 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,25 @@

A set of dependency-free JavaScript modules to handle binary data in JS (using Typed Arrays). Includes:

* bitjs/archive: Unarchiving files (unzip, unrar, untar) in the browser, implemented as Web Workers and allowing progressively unarchiving while streaming.
* bitjs/codecs: Get the codec info of media containers in a ISO RFC6381 MIME type string
* bitjs/archive: Unarchiving files (unzip, unrar, untar) in JavaScript,
implemented as Web Workers where supported, and allowing progressive
unarchiving while streaming.
* bitjs/codecs: Get the codec info of media containers in a ISO RFC6381
MIME type string
* bitjs/file: Detect the type of file from its binary signature.
* bitjs/image: Conversion of WebP images to PNG or JPEG.
* bitjs/io: Low-level classes for interpreting binary data (BitStream, ByteStream). For example, reading or peeking at N bits at a time.
* bitjs/io: Low-level classes for interpreting binary data (BitStream
ByteStream). For example, reading or peeking at N bits at a time.

## Installation

Install it using your favourite package manager, the package is registered under `@codedread/bitjs`.
```bash
$ npm install @codedread/bitjs
npm install @codedread/bitjs
```
or
```bash
$ yarn add @codedread/bitjs
yarn add @codedread/bitjs
```

### Using in Node
Expand All @@ -44,7 +48,7 @@ const { getFullMIMEString } = await import('@codedread/bitjs');

### bitjs.archive

This package includes objects for unarchiving binary data in popular archive formats (zip, rar, tar) providing unzip, unrar and untar capabilities via JavaScript in the browser. A prototype version of a compressor that creates Zip files is also present. The decompression/compression actually happens inside a Web Worker.
This package includes objects for unarchiving binary data in popular archive formats (zip, rar, tar) providing unzip, unrar and untar capabilities via JavaScript in the browser. A prototype version of a compressor that creates Zip files is also present. The decompression/compression actually happens inside a Web Worker, when the runtime supports it (browsers, deno).

#### Decompressing

Expand Down Expand Up @@ -88,6 +92,24 @@ unzipper.update(anArrayBufferWithMoreBytes);
unzipper.update(anArrayBufferWithYetMoreBytes);
```

##### A NodeJS Example

```javascript
import * as fs from 'fs';
import { getUnarchiver } from './archive/decompress.js';

const nodeBuffer = fs.readFileSync('comic.cbz');
const ab = nodeBuffer.buffer.slice(nodeBuffer.byteOffset, nodeBuffer.byteOffset + nodeBuffer.length);
const unarchiver = getUnarchiver(ab, { pathToBitJS: './' });
unarchiver.addEventListener('progress', () => process.stdout.write('.'));
unarchiver.addEventListener('extract', (evt) => {
const extractedFile = evt.unarchivedFile;
console.log(`${extractedFile.filename} (${extractedFile.fileData.byteLength} bytes)`);
});
unarchiver.addEventListener('finish', () => console.log(`Done!`));
unarchiver.start();
```

#### Compressing

The Zipper only supports creating zip files without compression (store only) for now. The interface
Expand Down
13 changes: 3 additions & 10 deletions archive/decompress-internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,6 @@ import { findMimeType } from '../file/sniffer.js';
* @property {Uint8Array} fileData
*/

/**
* An enum for threading mode. Currently supporting only WebWorkers.
*/
export const ThreadingMode = {
WEB_WORKER: 'WEB_WORKER',
}

/**
* @typedef UnarchiverOptions
* @property {string} pathToBitJS The path to the bitjs folder.
Expand Down Expand Up @@ -232,7 +225,7 @@ export class UnzipperInternal extends Unarchiver {
}

getMIMEType() { return 'application/zip'; }
getScriptFileName() { return 'archive/unzip.js'; }
getScriptFileName() { return './unzip.js'; }
}

export class UnrarrerInternal extends Unarchiver {
Expand All @@ -241,7 +234,7 @@ export class UnrarrerInternal extends Unarchiver {
}

getMIMEType() { return 'application/x-rar-compressed'; }
getScriptFileName() { return 'archive/unrar.js'; }
getScriptFileName() { return './unrar.js'; }
}

export class UntarrerInternal extends Unarchiver {
Expand All @@ -250,7 +243,7 @@ export class UntarrerInternal extends Unarchiver {
}

getMIMEType() { return 'application/x-tar'; }
getScriptFileName() { return 'archive/untar.js'; };
getScriptFileName() { return './untar.js'; };
}

/**
Expand Down
36 changes: 20 additions & 16 deletions archive/decompress.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export {
}

/**
* All extracted files returned by an Unarchiver will implement
* the following interface:
*/
* All extracted files returned by an Unarchiver will implement
* the following interface:
*/

/**
* @typedef UnarchivedFile
Expand All @@ -43,23 +43,27 @@ export {
*/

/**
* Creates a WebWorker with the given decompressor implementation (e.g. unzip.js)
* and transfers a MessagePort for communication. Returns a Promise to the Worker.
* Connects the MessagePort to the unarchiver implementation (e.g. unzip.js). If Workers exist
* (e.g. web browsers or deno), imports the implementation inside a Web Worker. Otherwise, it
* dynamically imports the implementation inside the current JS context.
* The MessagePort is used for communication between host and implementation.
* @param {string} pathToBitJS The path to the bitjs folder.
* @param {string} implFilename The decompressor implementation filename
* relative to this path (e.g. './unzip.js').
* @param {MessagePort} implPort The MessagePort to connect to the decompressor
* implementation.
* @returns {Promise<*>} Returns a Promise that resolves to the Worker object.
* @param {string} implFilename The decompressor implementation filename relative to this path
* (e.g. './unzip.js').
* @param {MessagePort} implPort The MessagePort to connect to the decompressor implementation.
* @returns {Promise<void>} The Promise resolves once the ports are connected.
*/
const connectPortFn = (pathToBitJS, implFilename, implPort) => {
return new Promise((resolve, reject) => {
const worker = new Worker(pathToBitJS + 'archive/unarchiver-webworker.js', {
type: 'module'
const connectPortFn = async (pathToBitJS, implFilename, implPort) => {
if (typeof Worker === 'undefined') {
return import(`${implFilename}`).then(implModule => {
implModule.connect(implPort)
});
}

worker.postMessage({ implSrc: (pathToBitJS + implFilename), }, [implPort]);
resolve(worker);
return new Promise((resolve, reject) => {
const worker = new Worker(pathToBitJS + 'archive/unarchiver-webworker.js', { type: 'module' });
worker.postMessage({ implSrc: implFilename }, [implPort]);
resolve();
});
};

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@codedread/bitjs",
"version": "1.1.6",
"version": "1.1.7",
"description": "Binary Tools for JavaScript",
"homepage": "https://github.com/codedread/bitjs",
"author": "Jeff Schiller",
Expand Down
2 changes: 1 addition & 1 deletion types/archive/decompress.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit f71c893

Please sign in to comment.