npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

smiling-source-down

v2.0.5

Published

A powerful source download library with resume capability and batch processing

Readme

Smiling Source Down

一个强大的源代码下载库,支持断点续传、批量下载和并发控制。

特性

  • 🚀 断点续传: 支持下载中断后继续下载
  • 📦 批量下载: 支持批量文件下载
  • 并发控制: 可配置并发下载数量
  • 🔄 自动重试: 下载失败时自动重试
  • ⏱️ 超时控制: 支持连接超时和请求超时配置,防止请求无限期挂起
  • 📊 进度监控: 实时监控下载进度(支持批量进度和单文件字节级进度)
  • 🎯 灵活配置: 支持多种配置选项
  • 🌐 内置网络: 使用 Node.js 内置模块,无需额外依赖

安装

npm install smiling-source-down

使用方法

基本用法

const { download } = require("smiling-source-down");

// 配置下载任务
const config = [
  {
    type: "file",
    name: "example.txt",
    path: "https://example.com/file.txt",
  },
  {
    type: "directory",
    name: "docs",
    children: [
      {
        type: "file",
        name: "readme.md",
        path: "https://example.com/docs/readme.md",
      },
    ],
  },
];

// 开始下载
download(config, {
  baseDir: "./downloads",
  concurrency: 5,
  retries: 3,
  timeout: 30000, // 总体超时 30秒(包括连接、响应和数据传输)
  onStart: (info) => {
    console.log(info.msg);
  },
  onProgress: (progress) => {
    console.log(`下载进度: ${progress.percent}% (${progress.count})`);
  },
  onSuccess: (filePath) => {
    console.log(`下载成功: ${filePath}`);
  },
  onError: (error) => {
    console.error(`下载失败: ${error.message}`);
  },
  onEnd: (result) => {
    console.log(`下载完成! 耗时: ${result.time}秒`);
  },
});

从 URL 加载配置

const { download } = require("smiling-source-down");

// 从远程URL加载配置
download("https://example.com/download-config.json", {
  baseDir: "./downloads",
  concurrency: 10,
});

检查是否需要下载

const { isNeedDownload } = require("smiling-source-down");

// 检查目录是否存在
if (isNeedDownload("./downloads")) {
  console.log("开始下载...");
  // 执行下载逻辑
} else {
  console.log("文件已存在,跳过下载");
}

API 文档

download(config, options)

参数

  • config (Array|string): 下载配置数组或配置文件的 URL
  • options (Object): 下载选项

配置格式

[
  {
    type: 'file',           // 文件类型
    name: 'filename.txt',   // 文件名
    path: 'https://...'     // 文件URL
  },
  {
    type: 'directory',      // 目录类型
    name: 'dirname',        // 目录名
    children: [...]         // 子文件/目录
  }
]

选项

| 参数 | 类型 | 默认值 | 描述 | | ---------------- | ------------------------------------------------------ | -------------- | ------------------------------------------------- | | baseDir | string | "./download" | 文件保存的基础目录 | | concurrency | number | 10 | 并发下载数量 | | retries | number | 3 | 下载失败重试次数 | | delayMs | number | 1000 | 重试间隔时间(毫秒) | | timeout | number | 30000 | 请求超时时间(毫秒),包括连接、响应和数据传输 | | onStart | (info: StartInfo) => void | () => {} | 批量下载开始时的回调 | | onProgress | (progress: ProgressInfo) => void | () => {} | 批量下载进度回调(按文件数计算) | | onFileProgress | ((progressInfo: FileProgressInfo) => void)null | () => {} | 单文件下载进度回调(按字节计算),可设置为 null | | onSuccess | (filePath: string) => void | () => {} | 单个文件下载成功时的回调 | | onError | (error: Error) => void | () => {} | 单个文件下载失败时的回调 | | onEnd | (result: EndResult) => void | () => {} | 批量下载结束时的回调 |

回调函数详细说明

onStart(info: StartInfo) - 批量下载开始回调

批量下载开始时的回调函数,在整个下载任务启动时调用一次。

  • info.msg (string): 开始信息消息,例如 "配置文件加载完成,共提取到 X 个文件任务"

onProgress(progress: ProgressInfo) - 批量下载进度回调(按文件数)

每完成一个文件下载时触发,用于监控整体下载进度。

  • progress.url (string): 当前刚完成的文件 URL
  • progress.progress (number): 下载进度 (0-1),例如 0.5 表示 50%
  • progress.percent (number): 下载进度百分比 (0-100),例如 50.00
  • progress.completed (number): 已完成的下载数量
  • progress.total (number): 总下载数量
  • progress.count (string): 下载计数字符串,例如 "5/10"

onFileProgress(progressInfo: FileProgressInfo) - 单文件下载进度回调(按字节)⭐

单个文件下载过程中实时触发,用于监控每个文件的字节级下载进度。可设置为 null 禁用。

  • progressInfo.url (string): 当前文件的下载 URL
  • progressInfo.dest (string): 文件保存路径
  • progressInfo.loaded (number): 已下载的字节数
  • progressInfo.total (number): 文件总字节数(从 Content-Length 响应头获取)
  • progressInfo.progress (number): 下载进度 (0-1),例如 0.75 表示 75%
  • progressInfo.percent (number): 下载进度百分比 (0-100),例如 75.00
  • progressInfo.startByte (number): 断点续传的起始位置(如果文件已部分下载,此值大于 0)

注意:

  • onFileProgress 只在服务器返回 Content-Length 响应头时才会触发
  • 可以设置为 null 来禁用单文件进度监控,以减少性能开销
  • 在断点续传场景下,loadedprogress 会从 startByte 位置开始计算

onSuccess(filePath: string) - 单个文件下载成功回调

单个文件下载成功时触发。

  • filePath (string): 下载成功的文件完整路径

onError(error: Error) - 单个文件下载失败回调

单个文件下载失败时触发(包括超时、网络错误等)。即使下载失败,也不会中断其他文件的下载。

  • error (Error): 错误对象,包含错误信息
    • 超时错误:error.message 包含 "timeout" 关键字
    • 网络错误:error.message 包含网络相关错误信息
    • HTTP 错误:error.message 包含状态码信息

onEnd(result: EndResult) - 批量下载结束回调

所有文件下载完成(成功或失败)时触发一次。

  • result.progress (number): 最终进度 (0-1),例如 1.0 表示 100%
  • result.percent (number): 最终进度百分比 (0-100),例如 100.00
  • result.completed (number): 成功完成的下载数量
  • result.total (number): 总下载数量
  • result.count (string): 下载计数字符串,例如 "10/10"
  • result.time (number): 总耗时(秒),例如 45.5 表示 45.5 秒
  • result.isAllSuccess (boolean): 是否全部下载成功,true 表示所有文件都成功下载

isNeedDownload(baseDir)

参数

  • baseDir (string): 要检查的目录路径

返回值

  • boolean: 如果目录不存在返回 true,存在返回 false

示例

监控单个文件下载进度

const { download } = require("smiling-source-down");

download(config, {
  baseDir: "./downloads",

  // 批量进度:监控完成了几个文件
  onProgress: ({ completed, total, percent }) => {
    console.log(`总进度: ${completed}/${total} (${percent}%)`);
  },

  // 单文件进度:实时监控每个文件的下载字节 ⭐
  onFileProgress: ({ url, loaded, total, percent }) => {
    const loadedMB = (loaded / 1024 / 1024).toFixed(2);
    const totalMB = (total / 1024 / 1024).toFixed(2);
    console.log(`${url}: ${loadedMB}MB / ${totalMB}MB (${percent}%)`);
  },
});

配置超时时间

const { download } = require("smiling-source-down");

download(config, {
  baseDir: "./downloads",
  concurrency: 10,
  retries: 3,

  // 超时配置:适用于慢速网络或大文件下载
  timeout: 60000, // 总体超时 60秒(包括连接、响应和数据传输)

  onError: (error) => {
    if (error.message.includes("timeout")) {
      console.error("下载超时:", error.message);
    } else {
      console.error("下载失败:", error.message);
    }
  },
});

超时说明

  • timeout: 总体超时时间,包括连接建立、等待响应头和数据传输三个阶段。如果超过这个时间,请求会被取消。
  • 如果不设置,将使用默认值(timeout: 30000ms
  • 超时后会抛出错误,可以在 onError 回调中处理

更多示例

  • 基本用法:查看 example/index.js
  • 单文件进度监控:查看 example/file-progress.js
  • 详细指南:查看 docs/file-progress-guide.md

依赖

注意: 本库使用 Node.js 内置模块处理网络请求和文件操作,无需安装额外的网络库。

系统要求

  • Node.js >= 14.0.0

许可证

ISC

贡献

欢迎提交 Issue 和 Pull Request!

Issue 地址 https://github.com/smilingovo/smiling-source-down/issues