mirror of
https://github.com/codedread/bitjs
synced 2025-10-03 09:39:16 +02:00
Some minor API updates.
This commit is contained in:
parent
24b1603968
commit
cc59935e72
7 changed files with 139 additions and 10 deletions
|
@ -2,6 +2,7 @@
|
|||
* archive.js
|
||||
*
|
||||
* Provides base functionality for unarchiving.
|
||||
* DEPRECATED: Use decompress.js instead.
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
|
@ -12,7 +13,9 @@ import { UnarchiveAppendEvent, UnarchiveErrorEvent, UnarchiveEvent, UnarchiveEve
|
|||
UnarchiveExtractEvent, UnarchiveFinishEvent, UnarchiveInfoEvent,
|
||||
UnarchiveProgressEvent, UnarchiveStartEvent, Unarchiver,
|
||||
UnrarrerInternal, UntarrerInternal, UnzipperInternal,
|
||||
getUnarchiverInternal } from './archive-internal.js';
|
||||
getUnarchiverInternal } from './decompress-internal.js';
|
||||
|
||||
console.warn(`Stop using archive.js and use decompress.js instead. This module will be removed.`);
|
||||
|
||||
export {
|
||||
UnarchiveAppendEvent,
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
|
||||
import { ByteBuffer } from '../io/bytebuffer.js';
|
||||
|
||||
// NOTE: THIS IS A VERY HACKY WORK-IN-PROGRESS! THE API IS NOT FROZEN! USE AT YOUR OWN RISK!
|
||||
|
||||
/**
|
||||
|
@ -10,9 +8,35 @@ import { ByteBuffer } from '../io/bytebuffer.js';
|
|||
* @property {ArrayBuffer} fileData The bytes of the file.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @readonly
|
||||
* @enum {number}
|
||||
*/
|
||||
export const ZipCompressionMethod = {
|
||||
STORE: 0, // Default.
|
||||
// DEFLATE: 8,
|
||||
};
|
||||
|
||||
// export const DeflateCompressionMethod = {
|
||||
// NO_COMPRESSION: 0,
|
||||
// COMPRESSION_FIXED_HUFFMAN: 1,
|
||||
// COMPRESSION_DYNAMIC_HUFFMAN: 2,
|
||||
// }
|
||||
|
||||
/**
|
||||
* Data elements are packed into bytes in order of increasing bit number within the byte,
|
||||
i.e., starting with the least-significant bit of the byte.
|
||||
* Data elements other than Huffman codes are packed starting with the least-significant bit of the
|
||||
data element.
|
||||
* Huffman codes are packed starting with the most-significant bit of the code.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef CompressorOptions
|
||||
* @property {string} pathToBitJS A string indicating where the BitJS files are located.
|
||||
* @property {ZipCompressionMethod} zipCompressionMethod
|
||||
* @property {DeflateCompressionMethod=} deflateCompressionMethod Only present if
|
||||
* zipCompressionMethod is set to DEFLATE.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -30,6 +54,7 @@ export const CompressStatus = {
|
|||
/**
|
||||
* A thing that zips files.
|
||||
* NOTE: THIS IS A VERY HACKY WORK-IN-PROGRESS! THE API IS NOT FROZEN! USE AT YOUR OWN RISK!
|
||||
* TODO: Make a streaming / event-driven API.
|
||||
*/
|
||||
export class Zipper {
|
||||
/**
|
||||
|
@ -43,6 +68,12 @@ export class Zipper {
|
|||
*/
|
||||
this.pathToBitJS = options.pathToBitJS || '/';
|
||||
|
||||
/**
|
||||
* @type {ZipCompressionMethod}
|
||||
* @private
|
||||
*/
|
||||
this.zipCompressionMethod = options.zipCompressionMethod || ZipCompressionMethod.STORE;
|
||||
|
||||
/**
|
||||
* Private web worker initialized during start().
|
||||
* @type {Worker}
|
||||
|
@ -80,9 +111,13 @@ export class Zipper {
|
|||
}
|
||||
|
||||
/**
|
||||
* Send in a set of files to be compressed. Set isLastFile to true if no more files are to added
|
||||
* at some future state. The Promise will not resolve until isLastFile is set to true either in
|
||||
* this method or in appendFiles().
|
||||
* @param {FileInfo[]} files
|
||||
* @param {boolean} isLastFile
|
||||
* @returns {Promise<Uint8Array>} A Promise that contains the entire zipped archive.
|
||||
* @returns {Promise<Uint8Array>} A Promise that will contain the entire zipped archive as an array
|
||||
* of bytes.
|
||||
*/
|
||||
start(files, isLastFile) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
|
|
@ -207,11 +207,15 @@ export class UnarchiveExtractEvent extends UnarchiveEvent {
|
|||
*/
|
||||
this.pathToBitJS_ = options.pathToBitJS || '/';
|
||||
|
||||
/** @orivate {boolean} */
|
||||
/**
|
||||
* @orivate
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.debugMode_ = !!(options.debug);
|
||||
|
||||
/**
|
||||
* A map from event type to an array of listeners.
|
||||
* @private
|
||||
* @type {Map.<string, Array>}
|
||||
*/
|
||||
this.listeners_ = {};
|
||||
|
@ -221,8 +225,8 @@ export class UnarchiveExtractEvent extends UnarchiveEvent {
|
|||
|
||||
/**
|
||||
* Private web worker initialized during start().
|
||||
* @type {Worker}
|
||||
* @private
|
||||
* @type {Worker}
|
||||
*/
|
||||
this.worker_ = null;
|
||||
}
|
84
archive/decompress.js
Normal file
84
archive/decompress.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
/**
|
||||
* decompress.js
|
||||
*
|
||||
* Provides base functionality for unarchiving/decompression.
|
||||
*
|
||||
* Licensed under the MIT License
|
||||
*
|
||||
* Copyright(c) 2021 Google Inc.
|
||||
*/
|
||||
|
||||
import { UnarchiveAppendEvent, UnarchiveErrorEvent, UnarchiveEvent, UnarchiveEventType,
|
||||
UnarchiveExtractEvent, UnarchiveFinishEvent, UnarchiveInfoEvent,
|
||||
UnarchiveProgressEvent, UnarchiveStartEvent, Unarchiver,
|
||||
UnrarrerInternal, UntarrerInternal, UnzipperInternal,
|
||||
getUnarchiverInternal } from './decompress-internal.js';
|
||||
|
||||
export {
|
||||
UnarchiveAppendEvent,
|
||||
UnarchiveErrorEvent,
|
||||
UnarchiveEvent,
|
||||
UnarchiveEventType,
|
||||
UnarchiveExtractEvent,
|
||||
UnarchiveFinishEvent,
|
||||
UnarchiveInfoEvent,
|
||||
UnarchiveProgressEvent,
|
||||
UnarchiveStartEvent,
|
||||
Unarchiver,
|
||||
}
|
||||
|
||||
/**
|
||||
* All extracted files returned by an Unarchiver will implement
|
||||
* the following interface:
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef UnarchivedFile
|
||||
* @property {string} filename
|
||||
* @property {Uint8Array} fileData
|
||||
*/
|
||||
|
||||
/**
|
||||
* The goal is to make this testable - send getUnarchiver() an array buffer of
|
||||
* an archive, call start on the unarchiver, expect the returned result.
|
||||
*
|
||||
* Problem: It relies on Web Workers, and that won't work in a nodejs context.
|
||||
* Solution: Make archive.js very thin, have it feed web-specific things into
|
||||
* an internal module that is isomorphic JavaScript.
|
||||
*
|
||||
* TODO:
|
||||
* - write unit tests for archive-internal.js that use the nodejs Worker
|
||||
* equivalent.
|
||||
* - maybe use @pgriess/node-webworker or @audreyt/node-webworker-threads or
|
||||
* just node's worker_threads ?
|
||||
*/
|
||||
|
||||
const createWorkerFn = (scriptFilename) => new Worker(scriptFilename);
|
||||
|
||||
// Thin wrappers of compressors for clients who want to construct a specific
|
||||
// unarchiver themselves rather than use getUnarchiver().
|
||||
export class Unzipper extends UnzipperInternal {
|
||||
constructor(ab, options) { super(ab, createWorkerFn, options); }
|
||||
}
|
||||
|
||||
export class Unrarrer extends UnrarrerInternal {
|
||||
constructor(ab, options) { super(ab, createWorkerFn, options); }
|
||||
}
|
||||
|
||||
export class Untarrer extends UntarrerInternal {
|
||||
constructor(ab, options) { super(ab, createWorkerFn, options); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method that creates an unarchiver based on the byte signature found
|
||||
* in the arrayBuffer.
|
||||
* @param {ArrayBuffer} ab The ArrayBuffer to unarchive. Note that this ArrayBuffer
|
||||
* must not be referenced after calling this method, as the ArrayBuffer is marked
|
||||
* as Transferable and sent to a Worker thread once start() is called.
|
||||
* @param {Object|string} options An optional object of options, or a string
|
||||
* representing where the path to the unarchiver script files.
|
||||
* @return {Unarchiver}
|
||||
*/
|
||||
export function getUnarchiver(ab, options = {}) {
|
||||
return getUnarchiverInternal(ab, createWorkerFn, options);
|
||||
}
|
|
@ -493,7 +493,7 @@ function inflate(compressedData, numDecompressedBytes) {
|
|||
// Bit stream representing the compressed data.
|
||||
/** @type {bitjs.io.BitStream} */
|
||||
const bstream = new bitjs.io.BitStream(compressedData.buffer,
|
||||
false /* rtl */,
|
||||
false /* mtl */,
|
||||
compressedData.byteOffset,
|
||||
compressedData.byteLength);
|
||||
/** @type {bitjs.io.ByteBuffer} */
|
||||
|
|
|
@ -2,4 +2,4 @@
|
|||
|
||||
1. Create a zip or rar file with just one file inside it.
|
||||
2. Use test-uploader.html and choose the archived file and the unarchived file.
|
||||
3. Paste that jSON output into a test json file.
|
||||
3. Paste that JSON output into a test json file.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
import { Zipper } from '../archive/compress.js';
|
||||
import { Zipper, ZipCompressionMethod } from '../archive/compress.js';
|
||||
|
||||
const result = document.querySelector('#result');
|
||||
const fileInputEl = document.querySelector('#zip-tester');
|
||||
|
@ -36,7 +36,10 @@ async function getFiles(fileChangeEvt) {
|
|||
|
||||
result.innerHTML = `Loaded files`;
|
||||
|
||||
const zipper = new Zipper({ pathToBitJS: '../' });
|
||||
const zipper = new Zipper({
|
||||
pathToBitJS: '../',
|
||||
zipCompressionMethod: ZipCompressionMethod.DEFLATE,
|
||||
});
|
||||
byteArray = await zipper.start(fileInfos, true);
|
||||
result.innerHTML = `Zipping done`;
|
||||
saveButtonEl.style.display = '';
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue