ipull
Version:
The only file downloader you'll ever need. For node.js and the browser, CLI and library for fast and reliable file downloads.
137 lines • 5.96 kB
JavaScript
import DownloadEngineMultiDownload from "../../download-engine/engine/download-engine-multi-download.js";
import TransferCli from "./transfer-cli.js";
import { BaseMultiProgressBar } from "./multiProgressBars/BaseMultiProgressBar.js";
import switchCliProgressStyle from "./progress-bars/switch-cli-progress-style.js";
import { DownloadStatus } from "../../download-engine/download-file/progress-status-file.js";
const DEFAULT_CLI_STYLE = "auto";
class GlobalCLI {
_multiDownloadEngine = this._createMultiDownloadEngine();
_eventsRegistered = new Set();
_transferCLI = GlobalCLI._createOptions({});
_cliActive = false;
_downloadOptions = new WeakMap();
constructor() {
this._registerCLIEvents();
}
async addDownload(engine, cliOptions = {}) {
if (!this._cliActive && cliOptions.cliProgress) {
this._transferCLI = GlobalCLI._createOptions(cliOptions);
}
if (engine instanceof Promise) {
engine.then((engine) => this._downloadOptions.set(engine, cliOptions));
}
else {
this._downloadOptions.set(engine, cliOptions);
}
await this._multiDownloadEngine.addDownload(engine);
this._multiDownloadEngine.download();
}
_createMultiDownloadEngine() {
return new DownloadEngineMultiDownload({
unpackInnerMultiDownloadsStatues: true,
finalizeDownloadAfterAllSettled: false,
naturalDownloadStart: true,
parallelDownloads: Number.MAX_VALUE,
downloadName: "Global CLI"
});
}
_registerCLIEvents() {
const isDownloadActive = (parentEngine = this._multiDownloadEngine) => {
if (parentEngine.loadingDownloads > 0) {
return true;
}
for (const engine of parentEngine.activeDownloads) {
if (engine instanceof DownloadEngineMultiDownload) {
if (isDownloadActive(engine)) {
return true;
}
}
if (engine.status.downloadStatus === DownloadStatus.Active || parentEngine.status.downloadStatus === DownloadStatus.Active && [DownloadStatus.Loading, DownloadStatus.NotStarted].includes(engine.status.downloadStatus)) {
return true;
}
}
return false;
};
const checkPauseCLI = () => {
if (this._cliActive && !isDownloadActive()) {
this._transferCLI.stop();
this._cliActive = false;
}
};
const checkCloseCLI = (engine) => {
this._eventsRegistered.delete(engine);
checkPauseCLI();
};
const checkResumeCLI = (engine) => {
if (engine.status.downloadStatus === DownloadStatus.Active) {
this._transferCLI.start();
this._cliActive = true;
}
};
const eventsRegistered = this._eventsRegistered;
this._multiDownloadEngine.on("childDownloadStarted", function registerEngineStatus(engine) {
if (eventsRegistered.has(engine))
return;
eventsRegistered.add(engine);
checkResumeCLI(engine);
engine.on("paused", checkPauseCLI);
engine.on("closed", () => checkCloseCLI(engine));
engine.on("resumed", () => checkResumeCLI(engine));
engine.on("start", () => checkResumeCLI(engine));
if (engine instanceof DownloadEngineMultiDownload) {
engine.on("childDownloadStarted", registerEngineStatus);
}
});
const getCLIEngines = (multiEngine) => {
const enginesToShow = [];
for (const engine of multiEngine.downloads) {
const isShowEngine = this._downloadOptions.get(engine)?.cliProgress;
if (engine instanceof DownloadEngineMultiDownload) {
if (isShowEngine) {
enginesToShow.push(...engine._flatEngines);
continue;
}
enginesToShow.push(...getCLIEngines(engine));
}
else if (isShowEngine) {
enginesToShow.push(engine);
}
}
return enginesToShow.filter((engine, index, self) => self.indexOf(engine) === index);
};
const printProgress = (progress) => {
const statues = getCLIEngines(this._multiDownloadEngine)
.map(x => x.status);
this._transferCLI.updateStatues(statues, progress, this._multiDownloadEngine.loadingDownloads);
};
this._multiDownloadEngine.on("progress", (progress) => {
if (!this._cliActive)
return;
printProgress(progress);
});
this._multiDownloadEngine.on("finished", () => {
if (this._transferCLI.isFirstPrint) {
printProgress(this._multiDownloadEngine.status);
}
this._transferCLI.isFirstPrint = true;
this._multiDownloadEngine = this._createMultiDownloadEngine();
this._eventsRegistered = new Set();
this._registerCLIEvents();
});
}
static _createOptions(options) {
const cliOptions = { ...options };
cliOptions.createProgressBar ??= typeof options.cliStyle === "function" ?
{
createStatusLine: options.cliStyle,
multiProgressBar: options.createMultiProgressBar ?? BaseMultiProgressBar
} :
switchCliProgressStyle(options.cliStyle ?? DEFAULT_CLI_STYLE, {
truncateName: options.truncateName,
loadingSpinner: options.loadingAnimation
});
return new TransferCli(cliOptions);
}
}
export const globalCLI = new GlobalCLI();
//# sourceMappingURL=GlobalCLI.js.map