or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

artifact-download.mdbasic-download.mdconfiguration.mddownloaders.mdindex.mdutilities.md
tile.json

downloaders.mddocs/

Custom Downloaders

Extensible downloader system allowing custom download implementations for specialized requirements. The library provides a default got-based downloader but supports any custom implementation.

Capabilities

Downloader Interface

Generic interface that all downloader implementations must follow.

/**
 * Generic interface for the artifact downloader library.
 * The default implementation is GotDownloader,
 * but any custom downloader can be passed to @electron/get via
 * the ElectronDownloadRequestOptions.downloader option.
 */
interface Downloader<T> {
  /**
   * Download an artifact from an arbitrary URL to a file path on system
   * @param url URL of the file to download
   * @param targetFilePath Filesystem path to download the artifact to (including the file name)
   * @param options Options to pass to the downloader
   */
  download(url: string, targetFilePath: string, options: T): Promise<void>;
}

Default Got Downloader

Built-in downloader implementation using the got HTTP library.

/**
 * Default Downloader implemented with got.
 */
class GotDownloader implements Downloader<GotDownloaderOptions> {
  async download(
    url: string,
    targetFilePath: string,
    options?: Partial<GotDownloaderOptions>
  ): Promise<void>;
}

/**
 * Options for the default got Downloader implementation.
 */
type GotDownloaderOptions = GotOptions & { isStream?: true } & {
  /** if defined, triggers every time got's downloadProgress event callback is triggered. */
  getProgressCallback?: (progress: GotProgress) => Promise<void>;
  /** if true, disables the console progress bar */
  quiet?: boolean;
};

Usage Examples:

import { download, GotDownloader } from "@electron/get";

// Use default downloader with custom options
await download('31.0.0', {
  downloadOptions: {
    timeout: { response: 60000 },
    retry: { limit: 5 },
    getProgressCallback: async (progress) => {
      console.log(`Progress: ${Math.round(progress.percent * 100)}%`);
    }
  }
});

// Create custom GotDownloader instance
const customDownloader = new GotDownloader();
await download('31.0.0', {
  downloader: customDownloader,
  downloadOptions: {
    headers: { 'Authorization': 'Bearer token123' }
  }
});

Custom Downloader Implementation

Create custom downloaders for specialized requirements.

type DownloadOptions = any; // Custom downloaders can implement any set of options

Custom Downloader Example:

import { Downloader } from "@electron/get";
import fs from 'fs';
import https from 'https';

interface CustomDownloaderOptions {
  timeout?: number;
  retries?: number;
  userAgent?: string;
}

class CustomDownloader implements Downloader<CustomDownloaderOptions> {
  async download(
    url: string,
    targetFilePath: string,
    options: CustomDownloaderOptions = {}
  ): Promise<void> {
    const { timeout = 30000, retries = 3, userAgent = 'CustomDownloader/1.0' } = options;
    
    for (let attempt = 0; attempt <= retries; attempt++) {
      try {
        await this.downloadWithTimeout(url, targetFilePath, timeout, userAgent);
        return; // Success
      } catch (error) {
        if (attempt === retries) throw error;
        await this.delay(1000 * Math.pow(2, attempt)); // Exponential backoff
      }
    }
  }

  private downloadWithTimeout(
    url: string,
    targetFilePath: string,
    timeout: number,
    userAgent: string
  ): Promise<void> {
    return new Promise((resolve, reject) => {
      const file = fs.createWriteStream(targetFilePath);
      const request = https.get(url, {
        headers: { 'User-Agent': userAgent },
        timeout
      }, response => {
        if (response.statusCode !== 200) {
          reject(new Error(`HTTP ${response.statusCode}`));
          return;
        }
        response.pipe(file);
        file.on('finish', () => {
          file.close();
          resolve();
        });
      });
      
      request.on('error', reject);
      request.on('timeout', () => {
        request.destroy();
        reject(new Error('Download timeout'));
      });
    });
  }

  private delay(ms: number): Promise<void> {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// Use custom downloader
const customDownloader = new CustomDownloader();
await download('31.0.0', {
  downloader: customDownloader,
  downloadOptions: {
    timeout: 60000,
    retries: 5,
    userAgent: 'MyApp/2.0'
  }
});

Got Progress Interface

Progress information provided by the default downloader.

interface GotProgress {
  /** Percentage of download completed (0-1) */
  percent: number;
  /** Bytes transferred so far */
  transferred: number;
  /** Total bytes to transfer */
  total?: number;
}

Progress Tracking Example:

import { download } from "@electron/get";

await download('31.0.0', {
  downloadOptions: {
    getProgressCallback: async (progress) => {
      const percent = Math.round(progress.percent * 100);
      const transferred = Math.round(progress.transferred / 1024 / 1024);
      const total = progress.total ? Math.round(progress.total / 1024 / 1024) : '?';
      
      console.log(`Download: ${percent}% (${transferred}MB / ${total}MB)`);
    },
    quiet: true // Disable built-in progress bar
  }
});

Default Downloader Features

The built-in GotDownloader provides:

  • Progress Tracking: Automatic progress bar after 30 seconds
  • Error Handling: Enhanced 404 error messages with URLs
  • Stream Processing: Efficient streaming downloads
  • Got Integration: Full access to got library options
  • Timeout Support: Configurable request and response timeouts
  • Retry Logic: Built-in retry mechanisms with exponential backoff
  • Proxy Support: Automatic proxy detection when initializeProxy() is called