First upload version 0.0.1
This commit is contained in:
140
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js
generated
vendored
Normal file
140
node_modules/ipull/dist/download/download-engine/engine/base-download-engine.js
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
import UrlInputError from "./error/url-input-error.js";
|
||||
import { EventEmitter } from "eventemitter3";
|
||||
import ProgressStatisticsBuilder from "../../transfer-visualize/progress-statistics-builder.js";
|
||||
import DownloadAlreadyStartedError from "./error/download-already-started-error.js";
|
||||
import StatusCodeError from "../streams/download-engine-fetch-stream/errors/status-code-error.js";
|
||||
import { InvalidOptionError } from "./error/InvalidOptionError.js";
|
||||
const IGNORE_HEAD_STATUS_CODES = [405, 501, 404];
|
||||
export default class BaseDownloadEngine extends EventEmitter {
|
||||
options;
|
||||
_engine;
|
||||
_progressStatisticsBuilder = new ProgressStatisticsBuilder();
|
||||
_downloadStarted = false;
|
||||
_latestStatus;
|
||||
constructor(engine, options) {
|
||||
super();
|
||||
this.options = options;
|
||||
this._engine = engine;
|
||||
this._progressStatisticsBuilder.add(engine);
|
||||
this._initEvents();
|
||||
}
|
||||
get file() {
|
||||
return this._engine.file;
|
||||
}
|
||||
get downloadSize() {
|
||||
return this._engine.downloadSize;
|
||||
}
|
||||
get fileName() {
|
||||
return this.file.localFileName;
|
||||
}
|
||||
get status() {
|
||||
return this._latestStatus ?? ProgressStatisticsBuilder.oneStatistics(this._engine);
|
||||
}
|
||||
get downloadStatues() {
|
||||
return [this.status];
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
get _fileEngineOptions() {
|
||||
return this._engine.options;
|
||||
}
|
||||
_initEvents() {
|
||||
this._engine.on("start", () => {
|
||||
return this.emit("start");
|
||||
});
|
||||
this._engine.on("save", (info) => {
|
||||
return this.emit("save", info);
|
||||
});
|
||||
this._engine.on("finished", () => {
|
||||
return this.emit("finished");
|
||||
});
|
||||
this._engine.on("closed", () => {
|
||||
return this.emit("closed");
|
||||
});
|
||||
this._engine.on("paused", () => {
|
||||
return this.emit("paused");
|
||||
});
|
||||
this._engine.on("resumed", () => {
|
||||
return this.emit("resumed");
|
||||
});
|
||||
this._progressStatisticsBuilder.on("progress", (status) => {
|
||||
this._latestStatus = status;
|
||||
return this.emit("progress", status);
|
||||
});
|
||||
}
|
||||
async download() {
|
||||
if (this._downloadStarted) {
|
||||
throw new DownloadAlreadyStartedError();
|
||||
}
|
||||
try {
|
||||
this._downloadStarted = true;
|
||||
await this._engine.download();
|
||||
}
|
||||
finally {
|
||||
await this.close();
|
||||
}
|
||||
}
|
||||
pause() {
|
||||
return this._engine.pause();
|
||||
}
|
||||
resume() {
|
||||
return this._engine.resume();
|
||||
}
|
||||
close() {
|
||||
return this._engine.close();
|
||||
}
|
||||
static async _createDownloadFile(parts, fetchStream) {
|
||||
const localFileName = decodeURIComponent(new URL(parts[0], "https://example").pathname.split("/")
|
||||
.pop() || "");
|
||||
const downloadFile = {
|
||||
totalSize: 0,
|
||||
parts: [],
|
||||
localFileName
|
||||
};
|
||||
let counter = 0;
|
||||
for (const part of parts) {
|
||||
try {
|
||||
const { length, acceptRange, newURL, fileName } = await fetchStream.fetchDownloadInfo(part);
|
||||
const downloadURL = newURL ?? part;
|
||||
const size = length || 0;
|
||||
downloadFile.totalSize += size;
|
||||
downloadFile.parts.push({
|
||||
downloadURL,
|
||||
size,
|
||||
acceptRange: size > 0 && acceptRange
|
||||
});
|
||||
if (counter++ === 0 && fileName) {
|
||||
downloadFile.localFileName = fileName;
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
if (error instanceof StatusCodeError && IGNORE_HEAD_STATUS_CODES.includes(error.statusCode)) {
|
||||
// if the server does not support HEAD request, we will skip that step
|
||||
downloadFile.parts.push({
|
||||
downloadURL: part,
|
||||
size: 0,
|
||||
acceptRange: false
|
||||
});
|
||||
continue;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
return downloadFile;
|
||||
}
|
||||
static _validateURL(options) {
|
||||
if ("partURLs" in options && "url" in options) {
|
||||
throw new UrlInputError("Either `partURLs` or `url` should be provided, not both");
|
||||
}
|
||||
if (!("partURLs" in options) && !("url" in options)) {
|
||||
throw new UrlInputError("Either `partURLs` or `url` should be provided");
|
||||
}
|
||||
}
|
||||
static _validateOptions(options) {
|
||||
if ("tryHeaders" in options && options.tryHeaders?.length && "defaultFetchDownloadInfo" in options) {
|
||||
throw new InvalidOptionError("Cannot use `tryHeaders` with `defaultFetchDownloadInfo`");
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=base-download-engine.js.map
|
||||
Reference in New Issue
Block a user