1
0
Fork 0
mirror of https://github.com/codedread/bitjs synced 2025-10-03 17:49:16 +02:00

Fix compress after previous refactor and add a unit test.

This commit is contained in:
Jeff Schiller 2023-12-22 13:18:36 -08:00
parent 65db5bdbd2
commit 8e1a7f3d0f
5 changed files with 81 additions and 10 deletions

View file

@ -29,13 +29,12 @@ or
yarn add @codedread/bitjs
```
### Using in Node
### CommonJS/ESM in Node
This module is an ES Module, which should work as expected in other projects using ES Modules.
However, if you are using a project that uses CommonJs modules, it's a little tricker to use. One
example of this is if a TypeScript project compiles to CommonJS, it will try to turn imports into
require() statements, which will break. The fix for this (unfortunately) is to update your
tsconfig.json:
However, if you are using CommonJS modules, it's a little trickier to use. One example of this is
if a TypeScript project compiles to CommonJS, it will try to turn imports into require() statements,
which will break. The fix for this (unfortunately) is to update your tsconfig.json:
```json
"moduleResolution": "Node16",

View file

@ -16,7 +16,7 @@ import { getConnectedPort } from './common.js';
* @typedef FileInfo An object that is sent to the implementation to represent a file to zip.
* @property {string} fileName The name of the file. TODO: Includes the path?
* @property {number} lastModTime The number of ms since the Unix epoch (1970-01-01 at midnight).
* @property {ArrayBuffer} fileData The bytes of the file.
* @property {Uint8Array} fileData The bytes of the file.
*/
/**
@ -75,6 +75,13 @@ export class Zipper {
*/
port_;
/**
* A function to call to disconnect the implementation from the host.
* @type {Function}
* @private
*/
disconnectFn_;
/**
* @param {CompressorOptions} options
*/
@ -124,7 +131,9 @@ export class Zipper {
* of bytes.
*/
async start(files, isLastFile) {
this.port_ = await getConnectedPort('./zip.js');
const impl = await getConnectedPort('./zip.js');
this.port_ = impl.hostPort;
this.disconnectFn_ = impl.disconnectFn;
return new Promise((resolve, reject) => {
this.port_.onerror = (evt) => {
console.log('Impl error: message = ' + evt.message);
@ -142,6 +151,10 @@ export class Zipper {
break;
case 'finish':
this.compressState = CompressStatus.COMPLETE;
this.port_.close();
this.disconnectFn_();
this.port_ = null;
this.disconnectFn_ = null;
resolve(this.byteArray);
break;
case 'compress':

View file

@ -155,7 +155,7 @@ function zipOneFile(file) {
const fileHeaderSize = 30 + file.fileName.length;
/** @type {ByteBuffer} */
const buffer = new ByteBuffer(fileHeaderSize + file.fileData.length);
const buffer = new ByteBuffer(fileHeaderSize + file.fileData.byteLength);
buffer.writeNumber(zLocalFileHeaderSignature, 4); // Magic number.
buffer.writeNumber(0x0A, 2); // Version.
@ -292,8 +292,8 @@ export function disconnect() {
hostPort = null;
filesCompressed = [];
centralDirectoryInfos = [];
numBytesWritten = 0;
state = CompressorState.NOT_STARTED;
lastFileReceived = false;
}

View file

@ -1,6 +1,6 @@
{
"name": "@codedread/bitjs",
"version": "1.1.7",
"version": "1.1.8",
"description": "Binary Tools for JavaScript",
"homepage": "https://github.com/codedread/bitjs",
"author": "Jeff Schiller",

59
tests/compress.spec.js Normal file
View file

@ -0,0 +1,59 @@
import * as fs from 'node:fs';
import 'mocha';
import { expect } from 'chai';
import { Unarchiver, getUnarchiver } from '../archive/decompress.js';
import { CompressStatus, Zipper, ZipCompressionMethod } from '../archive/compress.js';
/**
* @typedef {import('./archive/compress.js').FileInfo} FileInfo
*/
const PATH = `tests/archive-testfiles/`;
const INPUT_FILENAMES = [
'sample-1.txt',
'sample-2.csv',
'sample-3.json',
];
describe('bitjs.archive.compress', () => {
/** @type {Map<string, FileInfo>} */
let inputFileInfos = new Map();
let decompressedFileSize = 0;
before(() => {
for (const fileName of INPUT_FILENAMES) {
const fullFilename = `${PATH}${fileName}`;
const fd = fs.openSync(fullFilename, 'r');
const lastModTime = fs.fstatSync(fd).mtimeMs;
const nodeBuf = fs.readFileSync(fullFilename);
const fileData = new Uint8Array(
nodeBuf.buffer.slice(nodeBuf.byteOffset, nodeBuf.byteOffset + nodeBuf.length));
inputFileInfos.set(fileName, {fileName, lastModTime, fileData});
decompressedFileSize += fileData.byteLength;
fs.closeSync(fd);
}
});
it('zipper works', (done) => {
const files = new Map(inputFileInfos);
const zipper = new Zipper({zipCompressionMethod: ZipCompressionMethod.STORE});
zipper.start(Array.from(files.values()), true).then(byteArray => {
expect(zipper.compressState).equals(CompressStatus.COMPLETE);
expect(byteArray.byteLength > decompressedFileSize).equals(true);
const unarchiver = getUnarchiver(byteArray.buffer);
unarchiver.addEventListener('extract', evt => {
const {filename, fileData} = evt.unarchivedFile;
expect(files.has(filename)).equals(true);
const inputFile = files.get(filename).fileData;
expect(inputFile.byteLength).equals(fileData.byteLength);
for (let b = 0; b < inputFile.byteLength; ++b) {
expect(inputFile[b]).equals(fileData[b]);
}
});
unarchiver.addEventListener('finish', evt => done());
unarchiver.start();
});
});
});