UNPKG

bun-downloader-manager

Version:

bun-download-manager is a simple yet powerful package manager-like download manager built with Bun.js. It allows you to download files sequentially or with a queue-based approach, handling retries and concurrency limits efficiently.

111 lines (110 loc) 4.54 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Queue_1 = __importDefault(require("./Queue")); class DownloadManager { downloadQueue; // Queue to handle multiple downloads concurrencyLimit; // Maximum number of concurrent downloads retries; // Max retries for failed downloads method; // Download method downloadFolder; getFileName; otherTaskFunction; log; overWriteFile; constructor(options = {}) { const { method = "queue", concurrencyLimit = 5, retries = 3, consoleLog = false, downloadFolder = "./downloads", overWriteFile = false, getFileName, otherTaskFunction, } = options; this.method = method; this.concurrencyLimit = concurrencyLimit; this.retries = retries; this.log = consoleLog; this.downloadFolder = downloadFolder; this.getFileName = getFileName; this.otherTaskFunction = otherTaskFunction; this.overWriteFile = overWriteFile; // Initialize queue if the method is "queue" if (this.method === "queue") { this.downloadQueue = new Queue_1.default(this.concurrencyLimit, retries, this.log); } } logger(message, type = "info") { if (this.log || type === "error") { console[type](`[${process.pid}] : [${new Date().toLocaleString()}] : `, message); } } // Method to handle single URL download async downloadFile(url, fileName) { try { const file = Bun.file(`${this.downloadFolder}/${fileName}`); const isFileExists = await file.exists(); if (!isFileExists || this.overWriteFile) { this.logger(`Download started from ${url}`); const res = await fetch(url); if (res.status !== 200) { this.logger(`Could not download the file from ${url}, status ${res.status}`, "error"); throw new Error(`Download failed from ${url} with status ${res.status}`); } await file.write(res); this.logger(`File ${fileName} downloaded successfully. Downloaded from ${url}`); } if (this.otherTaskFunction) { this.logger("Running other task function"); await this.otherTaskFunction(url, fileName); } return true; } catch (error) { this.logger(`Error downloading ${fileName} from ${url}. Error:- ${error}`, "error"); throw error; } } // Method to add single download task to the queue enqueueDownloadTask(url, fileName, priority = 1) { this.logger(`${fileName} file downloading task added to Queue`); const downloadableFile = { id: `${Date.now()}-${fileName}`, // Unique task ID priority, // Default priority is 1 retries: this.retries, action: () => this.downloadFile(url, fileName), }; this.downloadQueue.enqueue(downloadableFile); } createFileName(url) { const fileName = this.getFileName ? this.getFileName(url) : url.split("/").pop() ?? "file"; return fileName; } // Main method to handle multiple URL downloads async download(urls) { // If the method is "simple", download the files sequentially if (this.method === "simple") { if (typeof urls === "string") { const fileName = this.createFileName(urls); await this.downloadFile(urls, fileName); } else { await Promise.all(urls.map((url) => { const fileName = this.createFileName(url); return this.downloadFile(url, fileName); })); } } // If the method is "queue", enqueue the download tasks else if (this.method === "queue") { if (typeof urls === "string") { const fileName = this.createFileName(urls); this.enqueueDownloadTask(urls, fileName); } else { for await (const url of urls) { const fileName = this.createFileName(url); this.enqueueDownloadTask(url, fileName); } } } } } exports.default = DownloadManager;