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

public-client-sdk

v1.2.0

Published

跨端前端通用微内核 SDK - 提供 DEDS 多维动态安全签名、网络拦截器、跨端排他路由锁、跨端持久化缓存、高可用 WebSocket、常用业务格式化工具等 (零 Node 依赖,极小包体,兼容 Uni-app、微信/抖音小程序、Web 与移动端 App)

Readme

public-client-sdk

npm version license

面向 Uni-app(Web / App / 小程序)、微信小程序、抖音小程序、Web SPA 等前端环境的通用客户端 SDK。 无 Node.js 内置模块依赖,全量打包体积小于 3KB,配合后端 public-sdk 提供接口签名校验、路由并发拦截、多端缓存与长连接封装能力。


前后端协同架构

public-client-sdk 与后端 public-sdk 协同工作,提供端到端的基础通信与安全能力支持:

  ┌─────────────────────────────────────────────────────────────┐
  │                 前端应用集群 (Frontends)                     │
  │   - B端工厂小程序 (factory-mp)   - C端商城小程序 (market-mp)    │
  │   - 平台管理后台 (pc-admin)       - 移动端混合 App (App-Plus)    │
  └──────────────────────────────┬──────────────────────────────┘
                                 │
                    驱动层: public-client-sdk
      (DEDSSigner / UniRequest / UniversalRouter / Storage / Socket)
                                 │
                                 ▼ [DEDS 动态加签 / Send 数据规范]
                                 │
                    后端服务: public-sdk
      (SignatureGuard / Http / Send / TokenService / WX)
                                 │
  ┌──────────────────────────────┴──────────────────────────────┐
  │                 后端微服务集群 (ts-server)                  │
  │   - factory-service  - market-service  - admin-service      │
  │   - pay-service      - ws-service      - cron-service       │
  └─────────────────────────────────────────────────────────────┘

| 功能模块 | 前端 SDK (public-client-sdk) | 后端 SDK (public-sdk) | 说明 | | :--- | :--- | :--- | :--- | | 接口防篡改与防重放 | DEDSSigner (动态签名发生器) | SignatureGuard (Express 守卫中间件) | 客户端计算动态时间戳与摘要签名,服务端基于时间片窗口及防重放机制完成校验 | | 统一数据响应与解包 | UniRequestClient / Fetch / Axios | Send.success / Send.fail | 前端自动解包 body.data,统一错误状态码与 401 登录态防抖拦截 | | 跨端路由并发锁 | UniversalRouter (多端通用 Router) | - | 跳转未完成前拦截后续并发跳转,防止快速连点造成重复打开或页面栈溢出 | | 多端持久化缓存 | UniversalStorage (多端统一 Storage) | - | 统一多端本地存储接口,支持指定秒级/毫秒级过期时间(TTL) | | 长连接消息推送 | SocketClient (WebSocket 客户端) | ws-service / Redis PubSub | 内置心跳检测、指数退避重连、页面生命周期事件解绑与离线消息缓冲 | | 时间漂移校准 | setServerTimeOffset | /common/timestamp | 校准客户端与服务端时间差,保证签名校验时间片对齐与业务倒计时准确 |


安装

npm install public-client-sdk --save

核心功能

1. 路由并发拦截 (Router / UniversalRouter)

针对小程序与单页应用在快速连点时可能出现的页面重复打开、页面栈溢出或跳转动画异常问题,Router 在单次跳转完成或报错前,自动拦截并发发起的后续跳转请求。

全局拦截(推荐)

import { Router } from 'public-client-sdk'

// 应用初始化入口 (如 main.js / init.js) 中执行一次
Router.install()

// 拦截全局 uni.navigateTo、uni.redirectTo、uni.switchTab 等路由跳转并发

API 显式调用

import { Router } from 'public-client-sdk'

// 1. 保留当前页面跳转 (支持自动格式化 query 对象参数)
await Router.navigateTo('/pages/order/detail', { id: 10086, role: 'cutter' })

// 2. 重定向关闭当前页
await Router.redirectTo('/pages/login/index')

// 3. TabBar 切换
await Router.switchTab('/pages/index/index')

// 4. 关闭所有页面并打开
await Router.reLaunch('/pages/index/index')

// 5. 页面返回
await Router.navigateBack(1)

Vue Router 适配

import { Router } from 'public-client-sdk'
import router from './router'

// 绑定 Vue Router 实例
Router.setWebRouter(router)

// 页面内调用同样支持并发拦截与参数序列化
await Router.navigateTo('/user/list', { page: 1, pageSize: 10 })

2. 网络请求客户端 (UniRequestClient)

适配 Uni-app、微信小程序 (wx)、抖音小程序 (tt) 与原生 App 环境。 自动注入 DEDS 动态签名与 Token,内置 401 防抖拦截、自动解包与统一错误处理。

import { UniRequestClient } from 'public-client-sdk'

export const request = new UniRequestClient({
  baseUrl: 'https://api.yourdomain.com/api',
  kernelSeed: 0x5f3759df,
  clientFp: 'factory_mp',
  unwrapData: true, // 默认 true: 自动解包返回 body.data
  getToken: () => uni.getStorageSync('token'),
  getFactoryId: () => uni.getStorageSync('activeFactoryId'),
  onUnauthorized: (err) => {
    uni.removeStorageSync('token')
    Router.navigateTo('/pages/login/index')
  }
})

// 1. 发起 GET 请求 (自动拼接并清理 undefined 参数)
const list = await request.get('/recruitment/list', { jobType: '车位工' })

// 2. 发起 POST 请求
const res = await request.post('/factory/ticket/accept', { ticketId: 10086 })

// 3. 原样获取完整结构(包含 code, message, timestamp)
const rawRes = await request.raw('/factory/ticket/accept', 'POST', { ticketId: 10086 })
console.log(rawRes.code, rawRes.message, rawRes.data)

// 4. 统一文件上传 (多端兼容)
const uploadRes = await request.upload('/tmp/image.png', '/common/upload')

3. Axios 拦截器 (setupPublicSdkAxios)

适用于基于 Axios 的 Web 管理端项目:

import axios from 'axios'
import { setupPublicSdkAxios } from 'public-client-sdk'

const request = axios.create({ baseURL: '/api', timeout: 10000 })

// 挂载 DEDS 签名请求拦截器及响应统一处理
setupPublicSdkAxios(request, {
  kernelSeed: 0x5f3759df,
  clientFp: 'pc_admin',
  getToken: () => localStorage.getItem('admin_token') || '',
  onUnauthorized: () => {
    localStorage.removeItem('admin_token')
    window.location.href = '/login'
  }
})

export default request

4. 本地缓存 (Storage / UniversalStorage)

统一 Uni-app、微信小程序、抖音小程序与 Web 的本地存储接口,支持指定过期时间(TTL):

import { Storage } from 'public-client-sdk'

// 1. 写入缓存(支持过期时间,单位:秒)
Storage.set('user_profile', { id: 1001, name: '张三' }, { expireSeconds: 3600 })

// 2. 读取缓存(自动反序列化,若已过期则自动清除并返回 null)
const profile = Storage.get('user_profile')

// 3. 删除与清空
Storage.remove('user_profile')
Storage.clear()

5. 动态签名 (DEDSSigner)

与后端 public-sdk 的 SignatureGuard 签名算法一致。纯 TypeScript/JavaScript 实现,无 Node.js 内置依赖,支持在小程序与浏览器环境中生成请求头签名:

import { DEDSSigner, setServerTimeOffset } from 'public-client-sdk'

// 1. 校准服务端时间差
setServerTimeOffset(1787279799862)

// 2. 初始化签名器
const signer = new DEDSSigner({
  kernelSeed: 0x5f3759df,
  clientFp: 'factory_mp'
})

// 3. 计算签名 Headers
const signHeaders = signer.sign({
  method: 'GET',
  url: '/recruitment/list?jobType=全部',
  data: { jobType: '全部' },
  token: 'JWT_TOKEN_STRING'
})

console.log(signHeaders)
// {
//   'X-Timestamp': '1787279799862',
//   'X-Nonce': 'assl9x4456asmta6',
//   'X-Client-Fp': 'factory_mp',
//   'X-Signature': '90ca106aee1600af075570c0bd8bfa673e5666e407f66be2e6b6a5812f991cf8bc5a'
// }

6. WebSocket 客户端 (SocketClient)

提供支持断线重连与页面生命周期绑定的 WebSocket 封装:

import { SocketClient } from 'public-client-sdk'

export const socket = new SocketClient({
  url: 'wss://api.yourdomain.com/ws',
  getToken: () => uni.getStorageSync('token')
})

socket.connect()

// 页面生命周期绑定(页面卸载时自动注销监听,防止内存泄漏)
export default {
  onLoad() {
    socket.bindPage('ticketPage', 'TICKET_UPDATED', (data) => {
      console.log('收到工单状态实时推送:', data)
    })
  },
  onUnload() {
    socket.unbindPage('ticketPage')
  }
}

7. 数据格式化与脱敏工具 (format)

import {
  fenToYuan,
  yuanToFen,
  formatDate,
  timeAgo,
  maskPhone,
  maskName
} from 'public-client-sdk'

fenToYuan(1250)              // '12.50' (货币分转元)
yuanToFen(12.5)              // 1250    (货币元转分)
maskPhone('13812345678')       // '138****5678' (手机号脱敏)
maskName('诸葛孔明')          // '诸**明'     (姓名脱敏)
timeAgo(Date.now() - 60000)  // '1分钟前'

许可证

ISC License © 2026 yajun.xu