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 🙏

© 2026 – Pkg Stats / Ryan Hefner

electron-auto-updater-enhanced

v1.3.1

Published

Enhanced auto-updater for Electron applications

Downloads

9

Readme

electron-auto-updater-enhanced

支持 1,增量更新(无需安装,请确保文件夹有读写权限) 2,强制更新 3,静默更新 4,版本回退(增量更新后可以回退) 5,日志输出 6,自定义灰度 目前仅支持 windows

安装

npm install electron-auto-updater-enhanced
yarn add electron-auto-updater-enhanced

演示地址

https://github.com/huhulanglang/electron-update-add.git

初始化

const ElectronAutoUpdater = require("electron-auto-updater-enhanced");

updateManager = new ElectronAutoUpdater({
    mainWindow: mainWindow, // 传递主窗口对象给更新管理器
    logPath: logPath  // 日志路径
  });

监听日志

updateManager.emitter.on('auto-update-log', (data) => {
    console.log(data);
  });

检查更新

updateManager.checkForUpdateVersion(url);   // url 为更新地址

强制更新

updateManager.checkForUpdates();

静默更新

  updateManager.updateInProgress = true;
      updateManager
        .updateDownloadFile(updateManager.silentZipPath)
        .then(() => {
        })
        .catch((err) => {
        });

版本回退

updateManager.reduction(
    path.join(process.resourcesPath, "./app.asar.unpacked")
);

afterPack.js 示例 (afterPack.js 为 electron-builder 的钩子函数 afterPack)

const path = require('path');
const fs = require('fs');
const crypto = require('crypto');
const package = require('./package.json');
const AdmZip = require('adm-zip');
function calculateMD5(filePath) {
  return new Promise((resolve, reject) => {
    const md5 = crypto.createHash('md5');
    const stream = fs.createReadStream(filePath);
    stream.on('data', chunk => md5.update(chunk));
    stream.on('end', () => {
      const hex = md5.digest('hex');
      resolve(hex);
    });
    stream.on('error', (err) => {
      reject(err);
    });
  })
}
exports.default = async function(context) {
  let targetPath
  if(context.packager.platform.nodeName === 'darwin') {
    targetPath = path.join(context.appOutDir, `${context.packager.appInfo.productName}.app/Contents/Resources`);
  } else {
    targetPath = path.join(context.appOutDir, './resources');
  }
  const appPath = path.join(targetPath, './app.asar.unpacked');//打包文件路径
  var zip = new AdmZip();
  zip.addLocalFolder(appPath);
  const unpacked = path.join(context.outDir, 'unpacked.zip');
  zip.writeZip(unpacked);
  const md5Value = await calculateMD5(unpacked);
  const jsonData = {
    version:package.version,
    percentage:1,   //灰度
    updatePath:"",   //自定义更新地址,不填默认资源下载地址
    md5:md5Value,
    isSilent:false   //静默更新
  };
  var jsonContent = JSON.stringify(jsonData);
  fs.writeFile(path.join(context.outDir, "pcVersion.json"), jsonContent, 'utf8', function (err) {
    if (err) {
      console.log(err);
    }
 });
}

logger.js 示例

const {
    app,
    dialog
} = require("electron");
const log = require("electron-log");
const fs = require("fs");
const path = require("path");
const dataCu = new Date();
const year = dataCu.getFullYear();
const month = (dataCu.getMonth() + 1).toString().padStart(2, '0'); // 确保月份为两位数
const day = dataCu.getDate().toString().padStart(2, '0'); // 确保日期为两位数
const fullDateName = year + "-" + month + "-" + day + ".log";
const logDir = path.join(path.dirname(app.getPath('exe')), 'logs');
try {
    if (!fs.existsSync(logDir)) {
        fs.mkdirSync(logDir); // 如果目录不存在,则创建
    }
} catch (error) {
    const response = dialog.showMessageBoxSync({
        type: 'error',
        title: '日志目录创建失败',
        message: `无法创建日志目录: ${logDir}`,
        detail: `错误信息: ${error.message}\n请以管理员账号运行程序,选择仅为自己安装,否则可能会导致程序无法正常运行或更新。`,
        buttons: ['退出', '继续运行'],
        defaultId: 0,
        cancelId: 1
    });
    if (response === 0) {
        app.quit();
    }
    log.error("Error occurred while creating log directory:", error);
}

log.transports.console.format = "{h}:{i}:{s} {text}";
log.transports.file.maxSize = 50 * 1024 * 1024;
const logPath = path.join(logDir, fullDateName);
log.transports.file.resolvePath = () => {
    return logPath;
};
const MAX_LOG_AGE_DAYS = 30;
function cleanUpLogs() {
    try {
        const files = fs.readdirSync(logDir);

        files.forEach(file => {
            if (file.endsWith('.log')) { // 只处理.log结尾的文件
                const filePath = path.join(logDir, file);
                const stats = fs.statSync(filePath);
                const now = new Date();
                const fileAgeDays = (now - stats.mtime) / (24 * 60 * 60 * 1000);

                if (fileAgeDays > MAX_LOG_AGE_DAYS) {
                    fs.unlinkSync(filePath);
                    log.info(`Deleted expired log file: ${filePath}`);
                }
            }
        });
    } catch (err) {
        log.error("Error occurred while cleaning up logs:", err);
    }
}
module.exports = {
    log,
    logPath,
    cleanUpLogs
}