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

@arms/rum-electron

v0.0.3

Published

ARMS RUM SDK for Electron (monitoring layer; implementation pending)

Downloads

268

Readme

@arms/rum-electron

阿里云 ARMS 用户体验监控 Electron SDK。一次主进程 init() 即覆盖主进程与渲染进程:自动采集异常、原生崩溃、HTTP/tRPC、应用启动指标、页面 PV、性能、Web Vitals 等数据,由主进程统一上报。

核心特性

  • 零配置自动注入:主进程 init() 后,所有 BrowserWindow 自动注入 Browser SDK 与 IPC Bridge,渲染进程零改造
  • 统一上报通道:渲染进程事件经 arms:rum-bridge IPC 通道回流至主进程,由主进程统一组织与上报
  • 主进程监控全覆盖
    • 未捕获异常、未处理 Promise 拒绝、console.error 拦截
    • 原生崩溃(集成 WASM minidump-processor,解析 .dmp 获取完整堆栈与模块)
    • 应用启动指标(app ready 耗时、进程数、主进程 CPU/内存)
    • globalThis.fetch 全局 patch,自动产出 type='api' 资源事件
    • tRPC server 端 procedure 调用(type='rpc'),通过 armsRum.instrumentTRPC() 一行接入
  • 渲染进程自动注入:PV、性能、Web Vitals、白屏、API、长任务等
  • 分布式链路追踪:内置 tracing 配置,支持 W3C tracecontext / B3 / B3 multi / Jaeger / SW8;主进程 fetch 与 tRPC procedure 共享同一份决策
  • 远程配置:支持 ARMS 控制台下发配置,动态调整采样率、采集器开关等

安装

npm install @arms/rum-electron

| 依赖 | 版本要求 | 说明 | |------|----------|------| | electron | >= 28.0.0 | peerDependency(optional),由项目自行安装 | | @trpc/server | * | 仅在使用 instrumentTRPC() 时由业务侧安装(optional peer) |

需要 Electron 28+ 是因为 SDK 使用 session.registerPreloadScript()(v28 新增),低版本会自动回退到 session.setPreloads()

快速接入

1. 主进程顶层 importinit()

SDK 必须在 app.ready 之前被 import——src/index.ts 顶层会调用 protocol.registerSchemesAsPrivileged() 注册 rum-event 协议(占位用,预留给后续降级通道,不影响功能)。

// main/index.ts —— 文件顶部
import armsRum from '@arms/rum-electron';
import { app } from 'electron';

armsRum.init({
  endpoint: '<your-endpoint>',  // 控制台「用户体验监控 > 应用列表」创建应用后获取
  env: 'prod',                  // 'prod' | 'gray' | 'pre' | 'daily' | 'local'
  version: '1.0.0',
});

app.whenReady().then(() => {
  // 创建 BrowserWindow 等
});

2. 渲染进程零改造

默认 autoInject: true:SDK 监听 web-contents-created,在每个 BrowserWindowdom-ready 时机注入 Browser SDK 脚本与 IPC Bridge。渲染进程既不需要 import SDK,也不需要修改 preload。

3.(可选)验证数据

armsRum.init({
  endpoint: '<your-endpoint>',
  beforeReport(bundle) {
    console.log('[RUM]', bundle);
    return bundle;     // 返回 undefined 不会丢弃;若需丢弃请显式处理
  },
});

4.(可选)自定义 partition

BrowserWindow 使用了自定义 partition(如 'persist:main')时,必须显式声明,否则该 partition 下的窗口不会注入 IPC Bridge:

// 方式一:init 时声明(单 partition 推荐)
await armsRum.init({
  endpoint: '<your-endpoint>',
  partition: 'persist:main',
});

// 方式二:init 之后动态注册(多 partition 场景)
await armsRum.init({ endpoint: '<your-endpoint>' });
await armsRum.registerSession('persist:other');

5.(可选)启用 tRPC 监控

主进程使用 tRPC 定义 server router 时(如 electron-trpc),用 armsRum.instrumentTRPC() 包一层 t,所有 procedure 自动带监控 middleware:

import { initTRPC } from '@trpc/server';
import armsRum from '@arms/rum-electron';

const t = armsRum.instrumentTRPC(initTRPC.create());

export const appRouter = t.router({
  greeting: t.procedure.input(...).query(...),
});

详见 docs/接入tRPC监控.md

主进程作为 tRPC client 调用云端 HTTP 服务时无需额外接入:底层 fetch 会被 ApiCollector 自动采集为 type='api' 事件。

配置一览

init(config) 接收 IElectronConfig,继承自 @arms/rum-coreIConfiguration。下表为常用字段,完整版见 docs/Electron SDK配置参考.md

基础

| 字段 | 类型 | 必填 | 默认值 | 说明 | |------|------|------|--------|------| | endpoint | string | 是 | — | ARMS 数据上报地址 | | enable | boolean | 否 | true | 关闭后所有采集器与上报均不工作 | | env | 'prod' \| 'gray' \| 'pre' \| 'daily' \| 'local' \| string | 否 | — | 应用环境标识 | | version | string | 否 | — | 应用版本号 | | app | object | 否 | — | 应用扩展信息(name / channel / framework 等) | | user | object | 否 | — | 用户信息(id / name / tags) |

Electron 专属

| 字段 | 类型 | 默认值 | 说明 | |------|------|--------|------| | autoInject | boolean | true | 是否自动向 BrowserWindow 注入 Browser SDK | | partition | string | — | 自定义 session partition;与 BrowserWindow.webPreferences.partition 对应 | | spaMode | false \| true \| 'auto' \| 'hash' \| 'history' | false | SPA 路由追踪模式 | | tracing | boolean \| ITracingOption | — | 分布式链路追踪(主进程 fetch + tRPC procedure 共用) | | evaluateApi | (request, response, error?) => Promise<IApiBaseAttr> | — | 自定义 API/RPC payload 解析,返回值经 reviseApiAttr 裁剪后合并 | | parseViewName | (url: string) => string | — | 自定义页面 name 解析(兜底用 SpaMode 解析 URL) | | parseResourceName | (url: string) => string | — | 自定义资源 name 解析;默认取 URL pathname | | beforeReport | (bundle) => any | — | 上报前回调,可改写 bundle | | browserCollectors | Record<string, boolean \| ICollectorConfig> | 全部启用 | 渲染进程 Browser SDK 采集器开关(仅 autoInject 模式生效) | | properties | Record<string, number \| string> | — | 全局自定义属性,附加到所有上报事件 |

主进程采集器(collectors)

armsRum.init({
  endpoint: '<your-endpoint>',
  collectors: {
    crash: false,            // 关闭崩溃采集
    consoleError: false,     // 关闭 console.error 拦截
    api: {
      enable: true,
      filters: [/\.internal\.example\.com/],   // 命中即不上报
    },
    rpc: {
      enable: true,
      filters: [/^internal\./],                // 按 procedure path 跳过
    },
  },
});

| 采集器 | 默认 | 说明 | |--------|------|------| | jsError | true | 主进程未捕获异常 + 未处理 Promise 拒绝 | | consoleError | true | console.error 拦截上报 | | crash | true | 原生崩溃采集(依赖 crashReporter) | | application | true | 应用启动指标 | | api | true | 主进程 globalThis.fetch patch(type='api') | | rpc | true | tRPC server middleware(配合 instrumentTRPCtype='rpc') |

渲染进程采集器(browserCollectors)

autoInject: true 时控制注入到渲染进程的 Browser SDK 采集器:

| 采集器 | 说明 | |--------|------| | perf | 页面加载性能 | | webvitals | Web Vitals(LCP / FID / CLS) | | exception | 未捕获异常 + Promise 拒绝 | | whiteScreen | 白屏检测 | | api | XHR / Fetch HTTP 请求 | | staticResource | 静态资源加载 | | click / action | 用户交互 | | longTask | 长任务(>50ms) |

armsRum.init({
  endpoint: '<your-endpoint>',
  browserCollectors: {
    longTask: false,
    whiteScreen: false,
    api: { enable: true },
  },
});

链路追踪(tracing)

armsRum.init({
  endpoint: '<your-endpoint>',
  tracing: {
    enable: true,
    sample: 10,                                    // 10% 采样(取值 0–100)
    propagatorTypes: ['tracecontext', 'b3'],
    allowedUrls: [/^https:\/\/api\.example\.com/], // 仅向白名单注入追踪头
  },
});

| 字段 | 类型 | 说明 | |------|------|------| | enable | boolean | 是否启用链路追踪 | | sample | number | 采样率,取值 0–100(默认 100) | | propagatorTypes | Array<'tracecontext' \| 'b3' \| 'b3multi' \| 'jaeger' \| 'sw8'> | 传播协议 | | allowedUrls | Array<MatchOption \| TraceOption> | 命中规则的 URL/path 才会注入追踪头;未配置时默认全量命中 | | tracestate / baggage | boolean | 是否携带 W3C tracestate / baggage |

主进程 fetch(ApiCollector)与 tRPC procedure(RpcCollector)共用同一份 tracing 决策,自动在 outbound 请求注入 traceparent 等头。

evaluateApi:把 payload 写入 snapshots

evaluateApi 用于把请求/响应内容写入事件。SDK 不会自动采集 payload——业务侧按需提取并经返回值 snapshots 上报,SDK 自动经 reviseApiAttr 裁剪至 5KB:

armsRum.init({
  endpoint: '<your-endpoint>',
  async evaluateApi(request, response, error) {
    const snapshot: Record<string, unknown> = {};
    if (request && typeof request === 'object' && 'input' in request) {
      snapshot.input = (request as { input?: unknown }).input;
    }
    if (response && typeof response === 'object' && 'data' in response) {
      snapshot.output = (response as { data?: unknown }).data;
    }
    return {
      success: error ? 0 : 1,
      snapshots: JSON.stringify(snapshot),
    };
  },
});

字段约定:snapshots 留给 SDK / evaluateApi 写采集元数据,properties 保留给用户业务标签。回调有 50ms 超时硬限,超时后回退到原始事件。

运行时 API

// 修改单个字段
armsRum.setConfig('enable', false);

// 批量修改
armsRum.setConfig({ env: 'staging', version: '1.1.0' });

// 读取当前完整配置
const config = armsRum.getConfig();

// 为额外的 partition 注册 preload(init 之后调用)
await armsRum.registerSession('persist:other');

// 一行接入 tRPC server 监控(需 @trpc/server)
const t = armsRum.instrumentTRPC(initTRPC.create());

注意事项

  1. init() 必须在 app.ready 之前调用,且 SDK 模块本身必须更早被 import——src/index.ts 顶层调用 protocol.registerSchemesAsPrivileged(),错过 ready 之前的窗口会导致协议注册失败并触发 Electron 警告。
  2. Electron 版本 >= 28:SDK 优先使用 session.registerPreloadScript()(v28 新增),低版本自动降级到 session.setPreloads()
  3. 不要覆盖 SDK 注册的 preload:若应用层调用 session.setPreloads() 覆盖全部 preload,渲染进程事件将无法回流。建议使用追加方式。
  4. autoInject: true 模式下禁止在渲染进程手动 import '@arms/rum-electron/browser':会导致重复初始化与事件双采。
  5. 自定义 partition 必须显式声明:未声明的 partition 下的窗口里 window.ArmsEventBridgeundefined,RUM 数据无法上报。
  6. evaluateApi 内禁止同步阻塞:回调有 50ms 超时硬限,超时后回退到原始事件不抛错。
  7. tRPC 监控仅采 server 端:主进程作为 tRPC client 调用云端 HTTP 时由 ApiCollector 在 fetch 层自动采集为 type='api',不需要再包 link。