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

Rework decompression implementations to not be Workers, but instead communicate to the host via a MessagePort. This doesn't address issue #44 directly yet (still need a way to swap out port connection with a non-Web Worker).

This commit is contained in:
Jeff Schiller 2023-12-11 00:12:42 -08:00
parent 1ab380c7c4
commit df5c5cfa0f
6 changed files with 185 additions and 107 deletions

View file

@ -10,9 +10,6 @@
* TAR format: http://www.gnu.org/software/automake/manual/tar/Standard.html
*/
// This file expects to be invoked as a Worker (see onmessage below).
// TODO: Make this a plain ES Module and then write a thin wrapper around it for Worker-ization.
// This will allow us to write proper unit tests for it.
import { ByteStream } from '../io/bytestream.js';
const UnarchiveState = {
@ -22,6 +19,9 @@ const UnarchiveState = {
FINISHED: 3,
};
/** @type {MessagePort} */
let hostPort;
// State - consider putting these into a class.
let unarchiveState = UnarchiveState.NOT_STARTED;
let bytestream = null;
@ -38,13 +38,13 @@ let totalFilesInArchive = 0;
// Helper functions.
const info = function (str) {
postMessage({ type: 'info', msg: str });
hostPort.postMessage({ type: 'info', msg: str });
};
const err = function (str) {
postMessage({ type: 'error', msg: str });
hostPort.postMessage({ type: 'error', msg: str });
};
const postProgress = function () {
postMessage({
hostPort.postMessage({
type: 'progress',
currentFilename,
currentFileNumber,
@ -156,7 +156,7 @@ const untar = function () {
currentFileNumber = totalFilesInArchive++;
currentBytesUnarchivedInFile = oneLocalFile.size;
currentBytesUnarchived += oneLocalFile.size;
postMessage({ type: 'extract', unarchivedFile: oneLocalFile }, [oneLocalFile.fileData.buffer]);
hostPort.postMessage({ type: 'extract', unarchivedFile: oneLocalFile }, [oneLocalFile.fileData.buffer]);
postProgress();
}
}
@ -169,7 +169,7 @@ const untar = function () {
// event.data.file has the first ArrayBuffer.
// event.data.bytes has all subsequent ArrayBuffers.
onmessage = function (event) {
const onmessage = function (event) {
const bytes = event.data.file || event.data.bytes;
logToConsole = !!event.data.logToConsole;
@ -189,7 +189,7 @@ onmessage = function (event) {
totalFilesInArchive = 0;
allLocalFiles = [];
postMessage({ type: 'start' });
hostPort.postMessage({ type: 'start' });
unarchiveState = UnarchiveState.UNARCHIVING;
@ -201,7 +201,7 @@ onmessage = function (event) {
try {
untar();
unarchiveState = UnarchiveState.FINISHED;
postMessage({ type: 'finish', metadata: {} });
hostPort.postMessage({ type: 'finish', metadata: {} });
} catch (e) {
if (typeof e === 'string' && e.startsWith('Error! Overflowed')) {
// Overrun the buffer.
@ -214,3 +214,15 @@ onmessage = function (event) {
}
}
};
/**
* Connect the host to the untar implementation with the given MessagePort.
* @param {MessagePort} port
*/
export function connect(port) {
if (hostPort) {
throw `hostPort already connected`;
}
hostPort = port;
port.onmessage = onmessage;
}