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

bx-utils

v1.1.11

Published

常用JavaScript工具函数库,包含防抖节流、剪贴板操作、各种校验工具等

Readme

bx-utils

一个功能丰富的 JavaScript/TypeScript 工具函数库,提供常用的工具方法,帮助开发者提高开发效率。

安装

npm install bx-utils

使用方法

// ES6 模块导入
import { debounce, throttle, deepClone, validateIdCard } from 'bx-utils';

// CommonJS 导入
const { debounce, throttle, deepClone, validateIdCard } = require('bx-utils');

前端监控 SDK

bx-utils 现在同时内置了 BX Monitor 前端采集 SDK,可以直接从同一个包里引入:

import { bxMonitor } from 'bx-utils';

bxMonitor.init({
  endpoint: 'https://collector.example.com',
  appId: 'demo-app',
  appVersion: '1.0.0',
  env: 'production',
  sampleRate: 1,
  enablePerformance: true,
  enableError: true,
  enableRequest: true,
  enablePV: true,
  enableTrace: true,
});

bxMonitor.trackEvent('button_click', { name: 'submit' });

可用导出还包括 BxMonitorBxMonitorConfigReportDataEventType 以及各类 payload 类型。SDK 仅适用于浏览器环境,默认会采集性能、错误、请求、PV、设备信息,并在启用 trace 时自动注入 traceparent

快速接入

  1. 在应用入口尽早调用 bxMonitor.init(...),建议放在首个业务渲染之前。
  2. 填好 endpointappId,其余选项按场景逐步打开。
  3. 如果需要追踪链路,配置 enableTracetracePropagationTargets
  4. 如果需要采集请求体或响应体,再显式开启 captureRequestBody / captureResponseBody

常用配置

  • endpoint:Collector 服务地址,SDK 会自动拼出 /api/v1/report/api/v1/trace
  • appId:应用标识,所有上报数据都会带上它。
  • appVersion:应用版本号,便于区分发布批次。
  • env:环境标识,通常使用 productionstagingdevelopment
  • sampleRate:整体采样率,1 表示全量采集。
  • traceSampleRate:trace 采样率,生产环境默认较低,避免采集过多链路数据。
  • enablePerformance:是否采集性能指标。
  • enableError:是否采集 JS、Promise 和资源错误。
  • enableRequest:是否拦截 XHR / fetch 请求。
  • enablePV:是否采集页面访问和 SPA 路由变化。
  • enableTrace:是否启用分布式追踪。
  • tracePropagationTargets:允许注入 traceparent 的目标地址。
  • requestFilter:过滤不想上报的请求。
  • captureRequestBody / captureResponseBody:是否采集请求体和响应体。
  • maxBodySize:请求体和响应体的最大保留长度。
  • redactKeys:额外脱敏字段名。
  • getUserId:如果你的系统已有用户标识来源,可以直接返回自定义 userId。

场景示例

import { bxMonitor } from 'bx-utils';

// 1. 基础采集:只开默认能力
bxMonitor.init({
  endpoint: 'https://collector.example.com',
  appId: 'web-app',
});

// 2. 生产环境:关闭 body 采集,只保留核心指标
bxMonitor.init({
  endpoint: 'https://collector.example.com',
  appId: 'web-app',
  env: 'production',
  enableTrace: true,
  tracePropagationTargets: ['api.example.com'],
  captureRequestBody: false,
  captureResponseBody: false,
});

// 3. 内部系统:允许采集接口入参,但限制长度并补充脱敏字段
bxMonitor.init({
  endpoint: 'https://collector.example.com',
  appId: 'internal-console',
  captureRequestBody: true,
  captureResponseBody: true,
  maxBodySize: 1024,
  redactKeys: ['phone', 'idCard', 'email'],
});

手动埋点

如果你只想记录一个业务动作,不需要额外封装采集器,可以直接调用:

bxMonitor.trackEvent('order_submit', {
  orderId: 'A20260609',
  amount: 199,
});

建议在页面入口尽早初始化,确保首屏性能、首个 PV 和初始错误都能被采集。对请求体、响应体和 trace 传播的开关,优先按环境分别配置,避免生产环境采集过多敏感信息。

API 文档

性能优化

debounce(func, wait, immediate)

防抖函数,在事件被触发 n 秒后再执行回调,如果在这 n 秒内又被触发,则重新计时。

参数:

  • func (Function): 要执行的函数
  • wait (number): 延迟时间(毫秒),默认 300
  • immediate (boolean): 是否立即执行,默认 false

返回: (Function): 防抖后的函数

示例:

const handleSearch = debounce((value) => {
  console.log('搜索:', value);
}, 500);

// 用户输入时调用
input.addEventListener('input', (e) => handleSearch(e.target.value));

throttle(func, wait, options)

节流函数,规定在一个单位时间内,只能触发一次函数。

参数:

  • func (Function): 要执行的函数
  • wait (number): 间隔时间(毫秒),默认 300
  • options (Object): 配置选项
    • leading (boolean): 是否在开始时执行,默认 true
    • trailing (boolean): 是否在结束时执行,默认 true

返回: (Function): 节流后的函数

示例:

const handleScroll = throttle(() => {
  console.log('滚动位置:', window.scrollY);
}, 200);

window.addEventListener('scroll', handleScroll);

剪贴板操作

copyText(text)

复制文本到剪贴板。

参数:

  • text (string): 要复制的文本

返回: Promise: 是否复制成功

示例:

const success = await copyText('Hello World');
if (success) {
  console.log('复制成功');
}

copyFile(file)

复制文件到剪贴板。

参数:

  • file (File): 要复制的文件对象

返回: Promise: 是否复制成功

示例:

const file = new File(['content'], 'example.txt', { type: 'text/plain' });
const success = await copyFile(file);

readClipboardText()

从剪贴板读取文本。

返回: Promise: 剪贴板中的文本

示例:

const text = await readClipboardText();
console.log('剪贴板内容:', text);

校验工具

validateIdCard(idCard)

校验中国身份证号码(支持15位和18位)。

参数:

  • idCard (string): 身份证号码

返回: (boolean): 是否有效

示例:

const isValid = validateIdCard('110101199001011234');
console.log('身份证是否有效:', isValid);

validatePassport(passport)

校验中国护照号码。

参数:

  • passport (string): 护照号码

返回: (boolean): 是否有效

示例:

const isValid = validatePassport('E12345678');
console.log('护照是否有效:', isValid);

validateCreditCode(creditCode)

校验统一社会信用代码。

参数:

  • creditCode (string): 统一社会信用代码

返回: (boolean): 是否有效

示例:

const isValid = validateCreditCode('91110000600000000D');
console.log('信用代码是否有效:', isValid);

validatePhone(phone)

校验中国大陆手机号码。

参数:

  • phone (string): 手机号码

返回: (boolean): 是否有效

示例:

const isValid = validatePhone('13800138000');
console.log('手机号是否有效:', isValid);

validateEmail(email)

校验邮箱地址。

参数:

  • email (string): 邮箱地址

返回: (boolean): 是否有效

示例:

const isValid = validateEmail('[email protected]');
console.log('邮箱是否有效:', isValid);

validateURL(url)

校验URL地址。

参数:

  • url (string): URL地址

返回: (boolean): 是否有效

示例:

const isValid = validateURL('https://www.example.com');
console.log('URL是否有效:', isValid);

validateIPv4(ip)

校验IPv4地址。

参数:

  • ip (string): IP地址

返回: (boolean): 是否有效

示例:

const isValid = validateIPv4('192.168.1.1');
console.log('IP地址是否有效:', isValid);

validateBankCard(cardNumber)

校验银行卡号(使用Luhn算法)。

参数:

  • cardNumber (string): 银行卡号

返回: (boolean): 是否有效

示例:

const isValid = validateBankCard('6222021234567890123');
console.log('银行卡号是否有效:', isValid);

validateName(val)

验证姓名,支持中文名、英文名以及包含生僻字的姓名。

参数:

  • val (string): 输入姓名

返回: (boolean): 是否有效

示例:

console.log(validateName('张三')); // true
console.log(validateName('Alice')); // true

validateChineseIdName(val)

身份证姓名校验,仅支持中文及生僻字姓名。

参数:

  • val (string): 姓名

返回: (boolean): 是否有效

示例:

console.log(validateChineseIdName('李四')); // true
console.log(validateChineseIdName('John')); // false

validateChinesePassportName(val)

中国护照姓名校验,支持中文(含生僻字)、大写英文及特定的空格组合。

参数:

  • val (string): 姓名

返回: (boolean): 是否有效

示例:

console.log(validateChinesePassportName('张三 ZHANG SAN')); // true

对象操作

deepClone(obj)

深拷贝对象,支持Date、RegExp、Map、Set等复杂类型。

参数:

  • obj (any): 要拷贝的对象

返回: (any): 拷贝后的对象

示例:

const original = { a: 1, b: { c: 2 }, d: [3, 4] };
const cloned = deepClone(original);
cloned.b.c = 999;
console.log(original.b.c); // 2,原对象未被修改

deepMerge(target, ...sources)

深度合并多个对象。

参数:

  • target (Object): 目标对象
  • sources (Object[]): 源对象

返回: (Object): 合并后的对象

示例:

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { b: { d: 3 }, e: 4 };
const merged = deepMerge(obj1, obj2);
console.log(merged); // { a: 1, b: { c: 2, d: 3 }, e: 4 }

日期时间

formatDate(date, format)

格式化日期。

参数:

  • date (Date | number): 日期对象或时间戳,默认为当前时间
  • format (string): 格式字符串,默认 'YYYY-MM-DD HH:mm:ss'
    • YYYY: 年份
    • MM/M: 月份(补零/不补零)
    • DD/D: 日期(补零/不补零)
    • HH/H: 小时(补零/不补零)
    • mm/m: 分钟(补零/不补零)
    • ss/s: 秒(补零/不补零)

返回: (string): 格式化后的日期字符串

示例:

const date = new Date('2024-01-15 08:30:45');
console.log(formatDate(date, 'YYYY-MM-DD')); // '2024-01-15'
console.log(formatDate(date, 'YYYY年MM月DD日 HH:mm')); // '2024年01月15日 08:30'

timeAgo(date)

相对时间显示(如"5分钟前")。

参数:

  • date (Date | number): 日期对象或时间戳

返回: (string): 相对时间字符串

示例:

const date = new Date(Date.now() - 5 * 60 * 1000); // 5分钟前
console.log(timeAgo(date)); // '5分钟前'

daysBetween(date1, date2)

计算两个日期之间的天数。

参数:

  • date1 (Date | number): 日期1
  • date2 (Date | number): 日期2

返回: (number): 天数

示例:

const days = daysBetween(new Date('2024-01-01'), new Date('2024-01-10'));
console.log(days); // 9

随机工具

randomString(length, chars)

生成随机字符串。

参数:

  • length (number): 字符串长度,默认 8
  • chars (string): 字符集,默认为数字和大小写字母

返回: (string): 随机字符串

示例:

const str = randomString(16);
console.log(str); // 如 'aB3dE9fG2hI5jK8l'

uuid()

生成UUID。

返回: (string): UUID字符串

示例:

const id = uuid();
console.log(id); // 如 '550e8400-e29b-41d4-a716-446655440000'

randomInt(min, max)

生成指定范围内的随机整数。

参数:

  • min (number): 最小值(包含)
  • max (number): 最大值(包含)

返回: (number): 随机整数

示例:

const num = randomInt(1, 100);
console.log(num); // 1到100之间的随机数

shuffle(array)

随机打乱数组。

参数:

  • array (Array): 要打乱的数组

返回: (Array): 打乱后的新数组

示例:

const arr = [1, 2, 3, 4, 5];
const shuffled = shuffle(arr);
console.log(shuffled); // 如 [3, 1, 5, 2, 4]

格式化

formatFileSize(bytes, decimals)

格式化文件大小。

参数:

  • bytes (number): 字节数
  • decimals (number): 小数位数,默认 2

返回: (string): 格式化后的字符串

示例:

console.log(formatFileSize(1024)); // '1 KB'
console.log(formatFileSize(1536000)); // '1.46 MB'

formatNumber(num, separator)

格式化数字,添加千分位分隔符。

参数:

  • num (number): 数字
  • separator (string): 分隔符,默认为 ','

返回: (string): 格式化后的字符串

示例:

console.log(formatNumber(1234567)); // '1,234,567'

formatCurrency(amount, decimals, currency)

格式化金额。

参数:

  • amount (number): 金额
  • decimals (number): 小数位数,默认 2
  • currency (string): 货币符号,默认 '¥'

返回: (string): 格式化后的金额字符串

示例:

console.log(formatCurrency(12345.6)); // '¥12,345.60'
console.log(formatCurrency(12345.6, 2, '$')); // '$12,345.60'

numberToChinese(num)

将数字转换为中文大写。

参数:

  • num (number): 数字

返回: (string): 中文大写字符串

示例:

console.log(numberToChinese(12345)); // '壹万贰仟叁佰肆拾伍'

数组操作

unique(array)

数组去重。

参数:

  • array (Array): 要去重的数组

返回: (Array): 去重后的新数组

示例:

const arr = [1, 2, 2, 3, 3, 4];
console.log(unique(arr)); // [1, 2, 3, 4]

chunk(array, size)

数组分组。

参数:

  • array (Array): 要分组的数组
  • size (number): 每组的大小,默认 1

返回: (Array[]): 分组后的二维数组

示例:

const arr = [1, 2, 3, 4, 5];
console.log(chunk(arr, 2)); // [[1, 2], [3, 4], [5]]

flatten(array, depth)

数组扁平化。

参数:

  • array (Array): 要扁平化的数组
  • depth (number): 扁平化深度,默认 Infinity

返回: (Array): 扁平化后的数组

示例:

const arr = [1, [2, [3, [4]]]];
console.log(flatten(arr, 2)); // [1, 2, 3, [4]]

sum(array)

数组求和。

参数:

  • array (number[]): 数字数组

返回: (number): 总和

示例:

console.log(sum([1, 2, 3, 4, 5])); // 15

average(array)

数组平均值。

参数:

  • array (number[]): 数字数组

返回: (number): 平均值

示例:

console.log(average([1, 2, 3, 4, 5])); // 3

max(array) / min(array)

数组最大值 / 最小值。

参数:

  • array (number[]): 数字数组

返回: (number): 最大值 / 最小值

示例:

console.log(max([1, 5, 3, 9, 2])); // 9
console.log(min([1, 5, 3, 9, 2])); // 1

intersection(...arrays)

数组交集。

参数:

  • arrays (Array[]): 多个数组

返回: (Array): 交集数组

示例:

const arr1 = [1, 2, 3];
const arr2 = [2, 3, 4];
console.log(intersection(arr1, arr2)); // [2, 3]

union(...arrays)

数组并集。

参数:

  • arrays (Array[]): 多个数组

返回: (Array): 并集数组

示例:

const arr1 = [1, 2, 3];
const arr2 = [3, 4, 5];
console.log(union(arr1, arr2)); // [1, 2, 3, 4, 5]

difference(array, ...others)

数组差集。

参数:

  • array (Array): 第一个数组
  • others (Array[]): 其他数组

返回: (Array): 差集数组

示例:

const arr1 = [1, 2, 3, 4];
const arr2 = [3, 4, 5];
console.log(difference(arr1, arr2)); // [1, 2]

字符串操作

isEmpty(str)

判断字符串是否为空(包括空白字符)。

参数:

  • str (string | null | undefined): 字符串

返回: (boolean)

示例:

console.log(isEmpty('  ')); // true
console.log(isEmpty('hello')); // false

capitalize(str)

首字母大写。

参数:

  • str (string): 字符串

返回: (string): 首字母大写的字符串

示例:

console.log(capitalize('hello world')); // 'Hello world'

camelToSnake(str)

驼峰转下划线。

参数:

  • str (string): 驼峰字符串

返回: (string): 下划线字符串

示例:

console.log(camelToSnake('helloWorld')); // 'hello_world'

snakeToCamel(str)

下划线转驼峰。

参数:

  • str (string): 下划线字符串

返回: (string): 驼峰字符串

示例:

console.log(snakeToCamel('hello_world')); // 'helloWorld'

truncate(str, length, suffix)

字符串截断。

参数:

  • str (string): 字符串
  • length (number): 截断长度
  • suffix (string): 后缀,默认 '...'

返回: (string): 截断后的字符串

示例:

console.log(truncate('Hello World', 5)); // 'Hello...'

stripHtml(html)

移除HTML标签。

参数:

  • html (string): HTML字符串

返回: (string): 纯文本字符串

示例:

console.log(stripHtml('<p>Hello <b>World</b></p>')); // 'Hello World'

escapeHtml(str)

转义HTML特殊字符。

参数:

  • str (string): 字符串

返回: (string): 转义后的字符串

示例:

console.log(escapeHtml('<div>')); // '&lt;div&gt;'

unescapeHtml(str)

反转义HTML特殊字符。

参数:

  • str (string): 字符串

返回: (string): 反转义后的字符串

示例:

console.log(unescapeHtml('&lt;div&gt;')); // '<div>'

数据掩码

maskChineseName(name)

中文姓名掩码,保留姓,其余打掩码显示。

参数:

  • name (string): 中文姓名

返回: (string): 掩码后的姓名

示例:

console.log(maskChineseName('张三')); // '张*'
console.log(maskChineseName('张小三')); // '张**'

maskEnglishName(name)

英文姓名掩码,保留首字母,其余掩码显示。

参数:

  • name (string): 英文姓名

返回: (string): 掩码后的姓名

示例:

console.log(maskEnglishName('ZHANGSAN')); // 'Z*******'

maskName(name)

智能姓名掩码,根据内容自动判断中英文。

参数:

  • name (string): 姓名

返回: (string): 掩码后的姓名

示例:

console.log(maskName('李四')); // '李*'
console.log(maskName('Alice')); // 'A****'

maskCompanyName(name)

公司名称掩码,保留第一个字,其余掩码显示。

参数:

  • name (string): 公司名称

返回: (string): 掩码后的公司名称

示例:

console.log(maskCompanyName('华为技术有限公司')); // '华*******'

maskIdCard(idCard)

证件号码掩码,保留前3后2,中间掩码。

参数:

  • idCard (string): 证件号码

返回: (string): 掩码后的证件号码

示例:

console.log(maskIdCard('370101199001011234')); // '370*************34'

maskPhone(phone)

电话号码掩码,前3后3明文,中间掩码。

参数:

  • phone (string): 电话号码

返回: (string): 掩码后的电话号码

示例:

console.log(maskPhone('15862518411')); // '158*****411'

maskGeneric(str, frontLen, endLen)

通用掩码方法。

参数:

  • str (string): 需要掩码的字符串
  • frontLen (number): 前面保留的字符数,默认 3
  • endLen (number): 后面保留的字符数,默认 2

返回: (string): 掩码后的字符串

示例:

console.log(maskGeneric('abcdefg')); // 'abc**fg'
console.log(maskGeneric('123456', 2, 0)); // '12****'

URL操作

getUrlParams(url)

获取URL参数。

参数:

  • url (string): URL字符串,默认为当前页面URL

返回: (Object): 参数对象

示例:

const params = getUrlParams('https://example.com?id=1&name=test');
console.log(params); // { id: '1', name: 'test' }

setUrlParams(url, params)

设置URL参数。

参数:

  • url (string): URL字符串
  • params (Object): 参数对象

返回: (string): 新的URL字符串

示例:

const newUrl = setUrlParams('https://example.com', { id: '1', name: 'test' });
console.log(newUrl); // 'https://example.com?id=1&name=test'

removeUrlParams(url, keys)

移除URL参数。

参数:

  • url (string): URL字符串
  • keys (string[]): 要移除的参数键名

返回: (string): 新的URL字符串

示例:

const newUrl = removeUrlParams('https://example.com?id=1&name=test', ['name']);
console.log(newUrl); // 'https://example.com?id=1'

parseUrl(url)

解析URL。

参数:

  • url (string): URL字符串

返回: (Object): URL各部分组成的对象

示例:

const parsed = parseUrl('https://example.com:8080/path?id=1#hash');
console.log(parsed);
// {
//   protocol: 'https:',
//   host: 'example.com:8080',
//   hostname: 'example.com',
//   port: '8080',
//   pathname: '/path',
//   search: '?id=1',
//   hash: '#hash',
//   origin: 'https://example.com:8080',
//   params: { id: '1' }
// }

存储操作

storage.set(key, value, expire)

设置localStorage。

参数:

  • key (string): 键名
  • value (any): 值
  • expire (number): 过期时间(毫秒),可选

示例:

storage.set('user', { name: 'Tom', age: 20 }, 3600000); // 1小时后过期

storage.get(key)

获取localStorage。

参数:

  • key (string): 键名

返回: (any): 值

示例:

const user = storage.get('user');
console.log(user); // { name: 'Tom', age: 20 }

storage.remove(key)

移除localStorage。

参数:

  • key (string): 键名

示例:

storage.remove('user');

storage.clear()

清空localStorage。

示例:

storage.clear();

cookie.set(name, value, days)

设置cookie。

参数:

  • name (string): 名称
  • value (string): 值
  • days (number): 有效天数,可选

示例:

cookie.set('token', 'abc123', 7); // 7天后过期

cookie.get(name)

获取cookie。

参数:

  • name (string): 名称

返回: (string | null): 值

示例:

const token = cookie.get('token');

cookie.remove(name)

删除cookie。

参数:

  • name (string): 名称

示例:

cookie.remove('token');

图片操作

compressImage(file, maxSize)

压缩图片,支持自定义目标文件大小和分辨率限制。

参数:

  • file (File): 图片文件对象
  • maxSize (number): 压缩目标大小(MB),默认 4

返回: Promise: 压缩后的 File 对象

特性:

  • 自动缩小超过 2560x2560 的图片分辨率
  • 通过逐步降低 JPEG 质量递归压缩,直到文件大小满足要求
  • 保留原文件名和修改时间
  • 处理加载失败和 Canvas 异常情况

示例:

// 基础用法,压缩至 4MB
const imageInput = document.querySelector('input[type="file"]') as HTMLInputElement;
imageInput.addEventListener('change', async (e) => {
  const file = (e.target as HTMLInputElement).files?.[0];
  if (file) {
    const compressedFile = await compressImage(file);
    console.log(`原始大小: ${(file.size / 1024 / 1024).toFixed(2)}MB`);
    console.log(`压缩后大小: ${(compressedFile.size / 1024 / 1024).toFixed(2)}MB`);
  }
});

// 自定义压缩大小为 2MB
const compressedFile = await compressImage(file, 2);

// 上传压缩后的图片
const formData = new FormData();
formData.append('image', compressedFile);
await fetch('/api/upload', { method: 'POST', body: formData });

通用工具

getType(value)

获取数据类型。

参数:

  • value (any): 任意值

返回: (string): 类型字符串

示例:

console.log(getType([])); // 'array'
console.log(getType({})); // 'object'
console.log(getType(null)); // 'null'
console.log(getType(new Date())); // 'date'

isPromise(value)

判断是否为Promise。

参数:

  • value (any): 任意值

返回: (boolean)

示例:

console.log(isPromise(Promise.resolve())); // true
console.log(isPromise({})); // false

sleep(ms)

休眠函数。

参数:

  • ms (number): 毫秒数

返回: (Promise)

示例:

await sleep(1000); // 暂停1秒
console.log('1秒后执行');

retry(fn, retries, delay)

重试函数。

参数:

  • fn (Function): 要执行的函数
  • retries (number): 重试次数,默认 3
  • delay (number): 重试延迟(毫秒),默认 1000

返回: (Promise)

示例:

const result = await retry(async () => {
  const response = await fetch('https://api.example.com/data');
  return response.json();
}, 3, 2000);

curry(fn)

函数柯里化。

参数:

  • fn (Function): 要柯里化的函数

返回: (Function): 柯里化后的函数

示例:

function add(a, b, c) {
  return a + b + c;
}
const curriedAdd = curry(add);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6

compose(...fns)

函数组合(从右到左执行)。

参数:

  • fns (Function[]): 函数数组

返回: (Function): 组合后的函数

示例:

const add1 = (x) => x + 1;
const multiply2 = (x) => x * 2;
const composed = compose(multiply2, add1);
console.log(composed(5)); // 12 (先加1再乘2)

pipe(...fns)

函数管道(从左到右执行)。

参数:

  • fns (Function[]): 函数数组

返回: (Function): 管道函数

示例:

const add1 = (x) => x + 1;
const multiply2 = (x) => x * 2;
const piped = pipe(add1, multiply2);
console.log(piped(5)); // 12 (先加1再乘2)

水印工具

提供文本水印、条形码水印注入,以及水印还原能力。

injectWatermark(options)

在网页中注入全屏平铺水印。支持自动响应窗口大小变化及防删除逻辑。

参数 options 对象属性:

通用参数:

  • type ('text' | 'barcode'): 水印类型,默认 'text'
  • text (string): 文本内容或条形码内容
  • opacity (number): 透明度 (0~1)
  • angle (number): 旋转角度(负值向左倾斜)
  • gapX (number): 横向间距
  • gapY (number): 纵向间距
  • antiDelete (boolean): 是否开启防删除/防篡改模式(通过 MutationObserver 监控)

文本水印参数:

  • fontSize (number): 字号大小,默认建议 16-20
  • color (string): 文本颜色,如 '#000000'

条形码水印参数:

  • format (string): 条形码格式,默认 'CODE128'
  • lineColor (string): 条形码线条颜色,默认 '#000'
  • barWidth (number): 条码单条宽度,默认 1
  • barHeight (number): 条形码高度,默认 40
  • displayValue (boolean): 是否显示条码文字,默认 true
  • fontSize (number): 条码文字字号,默认 14
  • color (string): 线条颜色兜底值,仅在未传 lineColor 时使用

文本水印示例:

import { injectWatermark } from 'bx-utils';

injectWatermark({
  text: '内部资料\n仅供参考',
  fontSize: 18,
  color: '#000',
  opacity: 0.1,
  angle: -20,
  gapX: 100,
  gapY: 100,
  antiDelete: false,
});

条形码水印示例:

import { injectWatermark } from 'bx-utils';

injectWatermark({
  type: 'barcode',
  text: 'ORDER-20260428-001',
  format: 'CODE128',
  lineColor: '#1f2937',
  barWidth: 2,
  barHeight: 56,
  displayValue: true,
  fontSize: 14,
  opacity: 0.12,
  angle: -18,
  gapX: 120,
  gapY: 96,
  antiDelete: true,
});

removeWatermark()

清理并移除页面上的全屏水印。同时会停止防删除监控和窗口缩放监听。

示例:

import { removeWatermark } from 'bx-utils';

removeWatermark();

revealWatermark(file, options)

对图片中的暗水印做增强还原,返回 PNG Data URL。

参数:

  • file (File | Blob | string): 原始图片文件或 dataURL
  • options.method ('multiscale' | 'highfreq' | 'amplify' | 'stretch' | 'filter'): 还原方法,默认 'multiscale'
  • options.grayscale (boolean): 是否输出灰度图
  • options.amplify (number): 高频或偏差放大倍数
  • options.blockSize (number): multiscale 的局部块大小
  • options.blurRadius (number): highfreq 的模糊半径
  • options.bgType ('bright' | 'dark'): amplify 的背景类型
  • options.lowP (number): stretch 的低分位点,默认 1
  • options.highP (number): stretch 的高分位点,默认 99
  • options.contrast (number): filter 的对比度系数
  • options.brightness (number): filter 的亮度系数

示例:

import { revealWatermark } from 'bx-utils';

const result = await revealWatermark(file, {
  method: 'stretch',
  lowP: 2,
  highP: 98,
  grayscale: true,
});

console.log(result); // data:image/png;base64,...

许可证

MIT

贡献

欢迎提交 Issue 和 Pull Request!