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

@kengic/client-telemetry

v2026.4.13

Published

Platform-neutral, offline-first client log telemetry SDK for Kengic applications

Readme

@kengic/client-telemetry

面向 PDA、Web 和后续客户端的轻量远程日志 SDK。包本身不依赖浏览器、uni-app 或 plus 全局;宿主应用只需配置存储、身份、上下文和传输适配器。

第一版只解决最核心的问题:脱敏日志、离线队列、用户/API 分桶、认证事务隔离、逐事件 ACK、失败重试、坏事件隔离、发送超时和协议/SDK版本标识。它不包含 Metrics、Session Replay、可视化控制台或插件体系。

安装

npm install @kengic/[email protected]

包按现有发布配置发布到 npmjs.org(public),业务仓库只依赖版本号,不依赖本机目录。

最小接入

import { createClientTelemetry } from '@kengic/client-telemetry';

export const telemetry = createClientTelemetry({
  namespace: 'WMS.PDA.Telemetry',
  authStorageKey: 'WMS.PDA.Telemetry.Auth.v1',
  context: () => ({
    clientType: 'PDA',
    appName: 'WMS-PDA',
    appVersion: '1.0.0',
    environment: 'production',
    installationId: 'installation-id',
    sessionId: 'session-id',
    deviceBrand: 'Kengic',
    deviceModel: 'PDA',
    osName: 'Android',
    osVersion: '13',
  }),
  storage: {
    get: (key) => platformStorage.get(key),
    set: (key, value) => platformStorage.set(key, value),
    remove: (key) => platformStorage.remove(key),
    keys: (prefix) => platformStorage.keys().filter((key) => key.indexOf(prefix) === 0),
  },
  identity: () => ({
    apiOrigin: auth.apiOrigin,
    userId: auth.userId,
    token: auth.token,
    uploadUrl: `${auth.apiOrigin}/clientTelemetry/logs`,
  }),
  route: () => router.currentRoute,
  transport: {
    send: (payload, identity, { keepalive, signal }) =>
      sendToServer(payload, identity.token, { keepalive, signal }),
  },
});

telemetry.initialize();
telemetry.info('APP', 'READY', 'application ready');

业务代码只调用 trace/debug/info/warn/error/breadcrumb。SDK 不拦截业务 HTTP,也不会把 Token 写入日志队列。

多命名空间共享预算

Web 多标签页等宿主会创建多个 namespace。SDK 配置中的 maxGlobalBytes 只限制当前 namespace;若它们共用 localStorage 一类有总配额的存储,应在适配器外再配置同源遥测总预算:

import {
  createBoundedClientTelemetryStorage,
  createClientTelemetry,
} from '@kengic/client-telemetry';

const telemetryStorage = createBoundedClientTelemetryStorage({
  storage: rawLocalStorageAdapter,
  scopePrefix: 'ClientTelemetry.WEB.',
  maxBytes: 2 * 1024 * 1024,
});

const telemetry = createClientTelemetry({
  // 其余宿主配置省略
  namespace: `ClientTelemetry.WEB.${tabId}`,
  storage: telemetryStorage,
  options: {
    maxBucketBytes: 128 * 1024,
    maxGlobalBytes: 128 * 1024,
  },
});

共享预算只统计并拒绝 scopePrefix 下的遥测写入,不扫描、覆盖或删除业务键。对不具备事务能力的 localStorage,该预算是跨标签页并发下的保护上限而非严格原子配额;宿主仍应在跨上下文互斥下回收已稳定迁移的退役 namespace。更强的一致性可由 IndexedDB readwrite 事务适配器提供。

认证生命周期

Token 与用户缓存通常不是一次写入,必须把登录更新包在同一认证事务中:

const result = await telemetry.auth.run(newToken, async () => {
  saveToken(newToken);
  const user = await loadCurrentUser();
  saveUser(user);
  return user;
});

遥测存储或提交失败不会改变回调的业务结果,只会冻结遥测上传。并发登录使用事务 epoch 和 Token/API 指纹做 CAS,旧响应不能提交新身份。退出登录在业务缓存清理后调用:

telemetry.auth.clear();

clear() 写入持久墓碑,防止旧标签页用残留缓存复活已退出身份;它返回 Promise,退出流程可选择 await 或显式 void。

Web 多标签页接入还应在配置中提供 authCoordinator,使用 Web Locks 或 IndexedDB readwrite 事务等真正跨上下文的互斥能力;不能静默退化为标签页内 Promise 队列。SDK 默认协调器只保证当前实例内串行,PDA 这类单 WebView 场景可直接使用默认值。协调器不可用时应让遥测认证安全失败并冻结上传,不能反向改变业务登录结果。

传输结果

适配器需将响应归类为:

  • SUCCESS:必须返回明确的 acceptedEventIds、duplicateEventIds 或 rejectedEventIds。
  • AUTH、RATE_LIMITED、TRANSIENT:保留队列并退避。
  • PERMANENT_EVENT:二分定位并隔离单个坏事件。
  • PAYLOAD_TOO_LARGE:缩小批次,最终只隔离无法单独发送的事件。
  • PERMANENT_BATCH:整批配置错误,保留全部事件,不能逐条误删。

核心层有独立发送截止时间,即使平台传输 Promise 永不结束也不会永久锁死队列。适配器必须监听 SDK 提供的 signal 并尽量中止底层 fetch/XHR/原生请求,减少悬挂资源。

隐私与数据归属

  • 只对认证凭据脱敏:Authorization(含 Basic/Digest/Bearer)、独立 Bearer、API/Secret Key、Token、密码、完整 Cookie Header、Credential 和 JWT 在入队前替换。
  • 邮箱、手机号、长数字业务编号、蓝牙地址、仓储业务编号和路由路径中的业务 ID 原样保留;路由查询参数整体丢弃。
  • 每个批次和事件都携带 schemaVersion 与 sdkVersion,服务端可以兼容识别离线积压的旧协议事件。
  • jobId、diagnosticId、correlationId、lookupKey 原值保留,同时为 1–256 位严格 ASCII 关联号生成 128 位 v2- 指纹,兼容按完整诊断号查询。
  • v2- 指纹只用于跨语言协议关联,不能作为授权。服务端落盘前仍使用仅服务端持有的高熵密钥计算版本化 HMAC 索引;原值和索引都只允许通过受限遥测查询接口访问。
  • 结构化详情字段不做固定数量裁剪,每个 key/value 仍受长度和事件总字节数限制。
  • 对象只记录结构摘要,不递归展开。
  • 队列按规范化 API 地址和大小写敏感用户 ID 分桶,只上传当前已确认身份的桶。
  • 认证切换期间的匿名事件,只有同一 epoch、installation 和事务开始时 session 的事件会在成功提交后归入新用户;恢复意图持久化,因此应用重启产生新 session 后仍可补偿。
  • 运行中 namespace 接管必须调用 SDK 实例的 adoptNamespace():它会先持久化目标内存缓存、拒绝与上传并发、按全局容量校验合并,再刷新目标缓存;不能只在宿主外部改存储。inspectNamespace() 可只读比较 generation,避免重复接管未变化的归档队列。
  • removeTelemetryNamespace() 只适用于源 writer 已被持久围栏阻止写入,并且恢复与回收共用跨上下文互斥,或底层存储能原子覆盖“generation 检查到整段删除”的场景。建议在接管完成后保留稳定宽限期,删除前再次校验 generation、围栏和存活租约;存在非空死信或无法确认完整迁移时继续保留。浏览器 localStorage 不具备多键事务,因此共享预算仍是必要的最后一道容量保护。

验证

npm run verify

该命令依次运行行为测试、严格类型检查和构建,再生成唯一 tarball、复核 SHA-512,并在无本地链接或源码依赖的临时目录完成安装与导入冒烟。

发布

版本一经发布不得覆盖。发布账号或 CI 需要公司私有 registry 的 @kengic scope 写权限:

cd frontend/vue3
pnpm run verify
pnpm run version:bump -- --dry-run
pnpm run version:bump

仓库内置的 GitLab CI 不绑定固定域名或项目 ID:普通流水线运行 npm run verify,只有受保护的 纯版本标签(例如 2026.3.0)且标签版本与 Maven、package.json、pack metadata 完全一致时,才使用当前项目的 CI_JOB_TOKEN 同时发布后端和前端包到 当前项目 npm registry。首次接入时需要:

  1. 为本仓库创建 GitLab project 并配置 origin;
  2. 在项目设置中把版本标签规则配置成 Protected tags,只允许发布负责人创建;
  3. 运行 pnpm run version:bump -- --dry-run 预览按年、季度、修订号计算的新版本;
  4. 运行 pnpm run version:bump,由命令更新 Maven 和前端版本、提交、创建同名标签并原子推送;
  5. 发布成功后从消费项目需要使用的 project/group/instance endpoint 做一次无缓存安装冒烟。

流水线通过 CI_API_V4_URL 兼容 GitLab 自定义端口和子路径,只把认证写入 mktemp 创建的临时 npmrc,并在 job 结束时删除;仓库同时忽略 .npmrc 和 npm 缓存目录。verify 阶段把 dist、tarball 与 pack metadata 作为 artifact 交给 publish,发布的是已经验证和洁净安装过的同一 tarball,不会二次打包。 不要将 CI_JOB_TOKEN、个人 Token 或生成后的 npmrc 作为 artifact。

默认流水线使用公司阿里云镜像 registry.cn-shanghai.aliyuncs.com/kengic_k8s/node:24.14.1-slim,不依赖 Docker Hub,并在安装前校验 Node 24.14.1 和 npm 11.11.0。如需覆盖项目变量 CLIENT_TELEMETRY_NODE_IMAGE,也必须指向公司网络可访问的同版本镜像;版本校验会阻止镜像标签被错误复用或静默降级。

年.季度.修订号 是稳定 SemVer,发布到 npm latest。低层工具仍兼容的 alpha.N、beta.N、rc.N 分别发布到 alpha、beta、rc dist-tag,但不作为统一发布命令的正常版本格式。

消费端和 Docker 构建也必须把 @kengic:registry 指向同一私服,并通过 CI secret 注入只读 Token;不要把 Token 写入仓库或镜像层。消费仓库使用 BuildKit 时,将完整的只读配置作为临时文件挂载:

docker build --secret id=npmrc,src=/run/secrets/kengic-npmrc ...

Dockerfile 的安装步骤使用 --mount=type=secret,id=npmrc,target=/root/.npmrc,required=true,不能改用包含 Token 的 ARG 或 ENV。发布后应在一个没有本地链接和 pnpm store 缓存的临时目录安装精确版本,再运行 import/build 冒烟验证。

发布物是供 Vite/Webpack 等构建器消费的 ES Module,编译目标为 ES2015;宿主需提供 Promise、Map、Set,或在自己的兼容构建中加入相应 polyfill。第一版不作为可直接插入旧浏览器的独立 <script> 分发。

组件知识库

核验基线:dbade1cf603e4b392044141b770ffeffd31fcce4;日期:2026-10-12。无平台全局依赖的客户端日志 SDK,宿主提供存储、身份、上下文和传输。

修改前按本目录 AGENTS.md 读取相关主题。历史只覆盖记录的 Git 基线;正文依据当前工作区,未提交代码/测试不能当成已发布行为。