cod-retrieve
Version:
A repo to retrieve/ download study dicom files in the specified local folder.
103 lines • 3.53 kB
JavaScript
class Job {
filesToFetch;
headers;
handleSaving = () => Promise.resolve();
handleZipping;
progressCallbacks = [];
downloadedCallbacks = [];
extractedCallbacks = [];
savedCallbacks = [];
completedCallbacks = [];
errorCallbacks = [];
constructor(filesToFetch, headers, handleSaving, handleZipping) {
this.filesToFetch = filesToFetch;
this.headers = headers;
this.handleSaving = handleSaving;
this.handleZipping = handleZipping;
}
async start() {
await Promise.all(this.filesToFetch.map(async ({ url, size }) => {
let fetchedFile = new ArrayBuffer();
try {
fetchedFile = await this.streamFetchToBuffer(url, this.headers);
this.downloadedCallbacks.forEach((callback) => {
callback({ url, size, file: fetchedFile });
});
}
catch (error) {
this.errorCallbacks.forEach((callback) => callback({ url, size, error: error }));
}
if (fetchedFile.byteLength) {
try {
await this.handleSaving(url, fetchedFile, this.extractedCallbacks, this.savedCallbacks);
}
catch (error) {
this.errorCallbacks.forEach((callback) => callback({ url, size, error: error }));
}
}
}));
try {
if (this.handleZipping) {
await this.handleZipping();
}
this.completedCallbacks.forEach((callback) => {
callback({ files: this.filesToFetch });
});
}
catch (error) {
this.errorCallbacks.forEach((callback) => callback({ error: error }));
}
}
onProgress(callback) {
this.progressCallbacks.push(callback);
}
onDownload(callback) {
this.downloadedCallbacks.push(callback);
}
onExtract(callback) {
this.extractedCallbacks.push(callback);
}
onSave(callback) {
this.savedCallbacks.push(callback);
}
onComplete(callback) {
this.completedCallbacks.push(callback);
}
onError(callback) {
this.errorCallbacks.push(callback);
}
async streamFetchToBuffer(url, headers) {
const response = await fetch(url, { headers });
const totalLength = +(response.headers.get("Content-Length") || "");
if (!totalLength) {
throw new Error("Content-Length header is missing or invalid.");
}
const fullBuffer = new Uint8Array(totalLength);
const reader = response.body?.getReader();
if (!reader) {
throw new Error("Failed to get response body reader.");
}
let received = 0;
while (true) {
const { done, value } = await reader.read();
if (done) {
break;
}
fullBuffer.set(value, received);
received += value.length;
this.progressCallbacks.forEach((callback) => {
callback({
url,
bytesDownloaded: value.length,
bytesTotal: totalLength,
});
});
}
if (received !== totalLength) {
throw new Error(`Downloaded size (${received}) does not match Content-Length (${totalLength})`);
}
return fullBuffer.buffer;
}
}
export default Job;
//# sourceMappingURL=Job.js.map