Add jsdoc comments to compression.js (#1062)

* Add jsdoc to compression

* undo formatting
This commit is contained in:
Georges-Antoine Assi 2025-08-17 15:22:23 -05:00 committed by GitHub
parent 5bf17873d1
commit b5a719b846
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 93 additions and 17 deletions

1
.gitignore vendored
View File

@ -13,3 +13,4 @@ data/cores/*
.vscode/*
*.tgz
dist/
jsdoc/

View File

@ -1,18 +1,55 @@
class EJS_COMPRESSION {
/**
* Handles compression and decompression of various archive formats (ZIP, 7Z, RAR)
* for the EmulatorJS system.
*
* This class provides functionality to detect compressed file formats and extract
* their contents using web workers for better performance.
*/
class EJSCompression {
/**
* Creates a new compression handler instance.
*
* @param {Object} EJS - The main EmulatorJS instance
*/
constructor(EJS) {
this.EJS = EJS;
}
isCompressed(data) { //https://www.garykessler.net/library/file_sigs.html
//todo. Use hex instead of numbers
if ((data[0] === 80 && data[1] === 75) && ((data[2] === 3 && data[3] === 4) || (data[2] === 5 && data[3] === 6) || (data[2] === 7 && data[3] === 8))) {
return "zip";
} else if (data[0] === 55 && data[1] === 122 && data[2] === 188 && data[3] === 175 && data[4] === 39 && data[5] === 28) {
return "7z";
} else if ((data[0] === 82 && data[1] === 97 && data[2] === 114 && data[3] === 33 && data[4] === 26 && data[5] === 7) && ((data[6] === 0) || (data[6] === 1 && data[7] == 0))) {
return "rar";
/**
* Detects if the given data represents a compressed archive format.
*
* @param {Uint8Array|ArrayBuffer} data - The binary data to analyze
* @returns {string|null} The detected compression format ('zip', '7z', 'rar') or null if not compressed
*
* @description
* Checks the file signature (magic bytes) at the beginning of the data to identify
* the compression format. Supports ZIP, 7Z, and RAR formats.
*
* @see {@link https://www.garykessler.net/library/file_sigs.html|File Signature Database}
*/
isCompressed(data) {
if ((data[0] === 0x50 && data[1] === 0x4B) && ((data[2] === 0x03 && data[3] === 0x04) || (data[2] === 0x05 && data[3] === 0x06) || (data[2] === 0x07 && data[3] === 0x08))) {
return "zip";
} else if (data[0] === 0x37 && data[1] === 0x7A && data[2] === 0xBC && data[3] === 0xAF && data[4] === 0x27 && data[5] === 0x1C) {
return "7z";
} else if ((data[0] === 0x52 && data[1] === 0x61 && data[2] === 0x72 && data[3] === 0x21 && data[4] === 0x1A && data[5] === 0x07) && ((data[6] === 0x00) || (data[6] === 0x01 && data[7] === 0x00))) {
return "rar";
}
return null;
}
return null;
}
/**
* Decompresses the given data and extracts all files.
*
* @param {Uint8Array|ArrayBuffer} data - The compressed data to extract
* @param {Function} updateMsg - Callback function for progress updates (message, isProgress)
* @param {Function} fileCbFunc - Callback function called for each extracted file (filename, fileData)
* @returns {Promise<Object>} Promise that resolves to an object mapping filenames to file data
*
* @description
* Automatically detects the compression format and delegates to the appropriate
* decompression method. If the data is not compressed, returns it as-is.
*/
decompress(data, updateMsg, fileCbFunc) {
const compressed = this.isCompressed(data.slice(0, 10));
if (compressed === null) {
@ -23,6 +60,20 @@ class EJS_COMPRESSION {
}
return this.decompressFile(compressed, data, updateMsg, fileCbFunc);
}
/**
* Retrieves the appropriate worker script for the specified compression method.
*
* @param {string} method - The compression method ('7z', 'zip', or 'rar')
* @returns {Promise<Blob>} Promise that resolves to a Blob containing the worker script
*
* @description
* Downloads the necessary worker script and WASM files for the specified compression
* method. For RAR files, also downloads the libunrar.wasm file and creates a custom
* worker script with the WASM binary embedded.
*
* @throws {Error} When network errors occur during file downloads
*/
getWorkerFile(method) {
return new Promise(async (resolve, reject) => {
let path, obj;
@ -107,6 +158,26 @@ class EJS_COMPRESSION {
}
})
}
/**
* Decompresses a file using the specified compression method.
*
* @param {string} method - The compression method ('7z', 'zip', or 'rar')
* @param {Uint8Array|ArrayBuffer} data - The compressed data to extract
* @param {Function} updateMsg - Callback function for progress updates (message, isProgress)
* @param {Function} fileCbFunc - Callback function called for each extracted file (filename, fileData)
* @returns {Promise<Object>} Promise that resolves to an object mapping filenames to file data
*
* @description
* Creates a web worker to handle the decompression process asynchronously.
* The worker communicates progress updates and extracted files back to the main thread.
*
* @example
* // Message types from worker:
* // t: 4 - Progress update (current, total, name)
* // t: 2 - File extracted (file, size, data)
* // t: 1 - Extraction complete
*/
decompressFile(method, data, updateMsg, fileCbFunc) {
return new Promise(async callback => {
const file = await this.getWorkerFile(method);
@ -139,4 +210,4 @@ class EJS_COMPRESSION {
}
}
window.EJS_COMPRESSION = EJS_COMPRESSION;
window.EJS_COMPRESSION = EJSCompression;

View File

@ -17,19 +17,23 @@
"start": "http-server",
"minify": "node minify/minify.js",
"build": "node build.js",
"update": "node update.js"
"update": "node update.js",
"docs": "jsdoc data/src/*.js -d jsdoc"
},
"dependencies": {
"@node-minify/clean-css": "^9.0.1",
"@node-minify/core": "^9.0.2",
"@node-minify/terser": "^9.0.1",
"http-server": "^14.1.1",
"node-7z": "^3.0.0",
"node-fetch": "^3.3.2",
"nipplejs": "^0.10.2",
"socket.io": "^4.8.1"
"node-7z": "^3.0.0"
},
"optionalDependencies": {
"@emulatorjs/cores": "latest"
},
"devDependencies": {
"jsdoc": "^4.0.4",
"nipplejs": "^0.10.2",
"node-fetch": "^3.3.2",
"socket.io": "^4.8.1"
}
}