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

@saco/monitor

v1.0.0

Published

Frontend monitor: JS error, resource, unhandledrejection, XHR / fetch

Readme

@saco/monitor

前端监控运行时:采集 JS 错误、资源加载失败、未处理 Promise,以及 XHR / fetch 请求。核心无框架。

内置两种插件,也可按同样格式自写:

| 插件 | 采集内容 | | --- | --- | | errorPlugin | window.error(含资源失败)、unhandledrejection | | httpPlugin | 全局 XMLHttpRequestfetch |

安装

pnpm add @saco/monitor

快速开始

import { createMonitor, errorPlugin, httpPlugin } from '@saco/monitor'

const monitor = createMonitor({
  dsn: '/api/monitor',
  method: 'post',
  app: 'pc',
  env: import.meta.env.MODE,
  reportType: 'count',
  count: 10,
})

monitor.use(errorPlugin)
monitor.use(httpPlugin)
monitor.start()

// 只停错误采集,HTTP 继续
monitor.pause('error')

// 手动上报当前队列
monitor.report()

// 卸监听、还原 XHR / fetch
monitor.destroy()

use 之后才会挂对应监听;start 之后才会入队。发往 dsn 的请求不会被 http 插件采集,避免上报自己打自己。

配置项

传入 createMonitor(options)reportType 决定何时把队列发出去:

| 字段 | 类型 | 说明 | | --- | --- | --- | | dsn | string | 上报地址 | | method | 'get' \| 'post' | 上报请求方法 | | app | 'pc' \| 'mobile' \| 'app' \| 'mini' 或自定义字符串 | 应用标识 | | env | 'development' \| 'production' \| 'test' 或自定义字符串 | 环境 | | reportType | 'manual' \| 'timer' \| 'count' | 上报策略 |

reportType 追加字段:

| reportType | 额外字段 | 行为 | | --- | --- | --- | | manual | — | 只在调用 report() / 句柄 report() 时上报 | | timer | interval: number | 用 rAF 按间隔上报已启动的插件 | | count | count: number | 某插件队列达到条数后自动上报该插件 |

实例方法

| 方法 | 说明 | | --- | --- | | use(plugin) | 安装封装插件(type + install)。同 type 只能装一次 | | start(types?) | 开始入队。不传则启动全部已安装插件 | | pause(types?) | 暂停入队。全部暂停时才会停掉 timer | | report(types?) | 立刻上报并清空对应队列 | | destroy() | 暂停全部、卸页面监听、还原 XHR / fetch |

types 可以是 'error''http' 或数组。

采集数据结构

transform 入参(不写 transform 时队列里就是这些字段):

error

| 字段 | 说明 | | --- | --- | | name | 错误名;资源失败为 ResourceError,Promise 为 UnhandledRejection | | message | 错误信息 | | stack? | 堆栈 | | href? | 当前页面 | | timestamp | 采集时间 |

http

| 字段 | 说明 | | --- | --- | | url | 请求地址 | | method | 请求方法 | | requestTime | 发出时间 | | responseTime | 结束时间 | | duration | 耗时(ms) | | status | HTTP 状态;网络失败为 0 |

自定义插件

业务方可直接 use(errorPlugin) / use(httpPlugin),也可照此格式自写。install 里必须再 use({ transform, watch }) 一次,用来改结构和观察队列:

const myErrorPlugin = {
  type: 'error' as const,
  install(ctx) {
    ctx.use({
      transform: (data) => ({ ...data, userId: '1' }),
      watch: (list, instance) => {
        if (list.length > 5) instance.report()
      },
    })
  },
}

monitor.use(myErrorPlugin)
monitor.start('error')
  • transform:把原始采集数据转成你要入队的结构
  • watch:入队后回调,第二个参数是该插件句柄(data / pause / report

License

MIT