Electron Builder Runtime Utilities

9.5.1 · active · verified Wed Apr 22

builder-util-runtime is an internal utility package within the electron-builder ecosystem, providing core HTTP client functionalities, download progress tracking, and cancellation capabilities. It is primarily used by electron-builder and electron-updater for managing asset downloads, update checks, and publishing operations, rather than being directly consumed by end-user applications. The package ships with TypeScript type declarations, facilitating its use in TypeScript projects. It is part of the larger electron-builder monorepo, which typically follows an 8-week release cadence for major versions, aligning with Chromium's schedule, ensuring frequent updates and maintenance. The current stable version, as a dependency, is 9.6.0. Its main differentiators are its tight integration with the Electron build and update process and its focus on robust HTTP handling for Electron applications.

Common errors

Warnings

Install

Imports

Quickstart

Demonstrates downloading a file with progress tracking and cancellation using builder-util-runtime's HTTP utilities. This showcases basic network operations that the package facilitates internally for Electron-based applications.

import { createWriteStream } from 'fs';
import { createNetClient, ProgressCallbackTransform, HttpError, CancellationToken } from 'builder-util-runtime';

interface RequestOptions {
  url: string;
  headers?: Record<string, string>;
}

// A simplified representation of safeExecute, as the original might be internal or complex.
// This ensures the download operation is wrapped in a way that handles cancellation.
async function safeExecute<T>(task: () => Promise<T>, cancellationToken?: CancellationToken): Promise<T | undefined> {
  if (cancellationToken?.isCancelled) {
    console.log('Operation already cancelled.');
    return undefined;
  }
  try {
    return await task();
  } catch (e) {
    if (cancellationToken?.isCancelled) {
      console.log('Operation cancelled during execution.');
      return undefined;
    }
    throw e;
  }
}

async function downloadFileWithProgress(url: string, outputPath: string) {
  const client = createNetClient();
  const cancellationToken = new CancellationToken();

  const options: RequestOptions = {
    url,
    headers: {
      'User-Agent': 'my-app-downloader/1.0.0',
      'Accept': 'application/octet-stream'
    },
  };

  const fileStream = createWriteStream(outputPath);
  const progressStream = new ProgressCallbackTransform(0, (progress) => {
    console.log(`Downloaded: ${progress.percent.toFixed(2)}% (${(progress.transferred / 1024 / 1024).toFixed(2)}MB / ${(progress.total / 1024 / 1024).toFixed(2)}MB)`);
  });

  try {
    console.log(`Starting download from ${url} to ${outputPath}...`);
    await safeExecute(() => client.download(options, fileStream, progressStream, cancellationToken), cancellationToken);
    console.log(`Download complete: ${outputPath}`);
  } catch (error) {
    if (error instanceof HttpError) {
      console.error(`HTTP Error ${error.statusCode}: ${error.message}`);
    } else if (cancellationToken.isCancelled) {
      console.log('Download operation was cancelled.');
    } else {
      console.error('An unexpected error occurred during download:', error);
    }
  } finally {
    fileStream.close();
  }
}

// Example usage: Download a small public file
// Replace with a valid URL to test, e.g., a small image or text file.
const dummyDownloadUrl = "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png";
const downloadPath = "./downloaded_google_logo.png";

downloadFileWithProgress(dummyDownloadUrl, downloadPath).catch(console.error);

// To demonstrate cancellation (uncomment to test):
// const cancelToken = new CancellationToken();
// downloadFileWithProgress(dummyDownloadUrl, "./cancel_test.png", cancelToken).catch(console.error);
// setTimeout(() => {
//   console.log('Attempting to cancel download...');
//   cancelToken.cancel();
// }, 500);

view raw JSON →