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

@swiftcrab/tracker

v1.0.5

Published

埋点上报

Readme

使用示例

安装: pnpm add @swiftcrab/tracker @swiftcrab/spm

使用

import { trackerManager, type ITracker } from '@swiftcrab/tracker'

interface ClickTrackerOption {
  allTracker?: boolean
}

interface PageTrackerOptions {
  /** 防重复安装 key */
  installFlagKey?: string
  /**
   * 去重口径:
   * - 'href':path+query+hash(默认)
   * - 'path+query':忽略 hash
   * - 'path':仅 path
   * - 自定义函数:返回用于去重的 key
   */
  dedupeBy?: 'href' | 'path+query' | 'path' | ((loc: Location) => string)
  /**
   * 首次 PV 触发时机:
   * - 'immediate':立刻触发(默认)
   * - 'domcontentloaded':等 DOMContentLoaded
   */
  firstFire?: 'immediate' | 'domcontentloaded'
  /** 是否上报 hashchange(Hash Router 场景建议 true),默认 true */
  trackHashChange?: boolean
  /** 上报前加工/丢弃;返回 null 表示丢弃 */
  beforeSend?: (payload: ITracker) => ITracker | null | undefined | void
}

interface HttpTrackerOptions {
  /** 过滤不需要监控的请求 URL,防止上报心跳、健康检查、静态资源等无意义请求 */
  filterUrls?: UrlFilter[]
  /** 限制错误信息的最大长度 */
  maxErrorLength?: number
  /** 对请求URL进行脱敏或简化,常用于移除敏感参数 */
  sanitizeUrl?: (url: string) => string
  /** 对错误内容进行脱敏或结构化处理 */
  sanitizeError?: (errorText: string, ctx: Omit<ITracker, "httpError">) => string
  /** 防止重复安装(多次调用 httpTracker() 不会重复劫持 fetch/XMLHttpRequest) */
  installFlagKey?: string
  /** 同一错误去重窗口(ms) */
  dedupeWindowMs?: number
  /** 单页最多上报条数,防止风暴 */
  maxReportsPerPage?: number
  /** 采样率 0~1 */
  sampleRate?: number
  /** 是否读取并上报响应体(仅对 !ok / status>=400) */
  captureResponseBody?: boolean
  /** 响应体最大长度(字符) */
  maxResponseBodyLength?: number
  /** 强制忽略 tracker 自己的上报请求(默认 true) */
  ignoreSelfRequests?: boolean
  /** 自定义判断是否为“自家上报请求”,用于 enqueue 内部也是 fetch/xhr 时避免循环 */
  isSelfRequest?: (url: string) => boolean
  /** 上报前加工/丢弃 */
  beforeSend?: (payload: ITracker) => ITracker | null | undefined | void
}

interface JsErrorTrackerOptions {
  /** 过滤不需要上报的错误 */
  filterErrors?: (string | RegExp | ((message: string, stack?: string) => boolean))[]
  /** 最大堆栈长度(默认 2000) */
  maxStackLength?: number
  /** 防重复安装 key */
  installFlagKey?: string
  /** 同一错误去重窗口(ms) */
  dedupeWindowMs?: number
  /** 单页最多上报条数,防止风暴 */
  maxReportsPerPage?: number
  /** 资源加载失败是否按 js_error 事件上报(会映射到 jsMessage/jsSource) */
  reportResourceError?: boolean
  /** unhandledrejection 是否上报 */
  reportUnhandledRejection?: boolean
  /** 采样率 0~1 */
  sampleRate?: number
  /** 上报前可做脱敏/清洗;返回 null 表示丢弃 */
  beforeSend?: (payload: ITracker) => ITracker | null | undefined | void
  /** 对 URL query 做脱敏(默认原样) */
  sanitizeUrl?: (url: string) => string
}

interface TrackerManagerOptions {
  /** localStorage 缓存键名 */
  storageKey?: string
  /** 最大缓存事件数(防内存/存储爆炸) */
  maxCacheSize?: number
  /** 批量上报间隔(毫秒), 默认 3 分钟 */
  batchInterval?: number
  /** 上报失败后的重试延迟(毫秒) */
  retryDelay?: number
  /** 是否启用 localStorage 持久化(默认 true) */
  enableStorage?: boolean
  /** 采样率:0.0 ~ 1.0,1.0 表示 100% 上报 */
  sampleRate?: number
}

interface IOption {
  clickTrackerOption?: ClickTrackerOption
  httpTrackerOptions?: HttpTrackerOptions
  trackerManagerOptions?: TrackerManagerOptions
  jsErrorTrackerOptions?: JsErrorTrackerOptions
  pageTrackerOptions?: PageTrackerOptions
}

interface ITracker {
  /** 事件类型 */
  event: TEvent
  /** 页面URL */
  url: string
  /** 页面路径 */
  path: string
  /** 点击事件文本 */
  text?: string
  /** 点击事件spm */
  spm?: string
  /** 页面浏览量来源 */
  from?: TPageFrom
  /** 页面查询参数 */
  query?: string
  /** 页面hash值 */
  hash?: string
  /** HTTP请求方法 */
  method?: string
  /** HTTP请求URL */
  httpUrl?: string
  /** HTTP请求状态码 */
  httpStatus?: number
  /** HTTP请求错误信息 */
  httpError?: string
  /** HTTP请求耗时 */
  httpDuration?: number
  /** 设备名称 */
  deviceName?: string
  /** 设备版本 */
  deviceVersion?: string
  /** 操作系统 */
  deviceOs?: string
  /** 设备类型 */
  deviceType?: string
  /** 设备是否有网 */
  deviceIsOnline?: boolean
  /** jsError错误的核心描述信息,通常是错误对象的 message 属性 */
  jsMessage?: string
  /** jsError完整的调用栈 */
  jsStack?: string
  /** jsError发生错误的脚本文件 URL */
  jsSource?: string
  /** jsError错误发生的行号 */
  jsLine?: number
  /** jsError错误发生的列号 */
  jsColumn?: number
  /** 用户信息 */
  user?: {
    userId?: string
    userName?: string
    [key: string]: any
  }
}

trackerManager(async (batch: ITracker[]) => {
  /** 上报接口逻辑 */
}, {
  clickTrackerOption: {},
  httpTrackerOptions: {},
  trackerManagerOptions: {},
  jsErrorTrackerOptions: {},
  pageTrackerOptions: {},
})