Skip to content

Collection of common utils. Tree-shakable ESM. Typesafe.

License

Notifications You must be signed in to change notification settings

GreatAuk/utopia-utils

Repository files navigation

Utopia-Utils

NPM Version License

目录

Install

# 包含所有的 utils
pnpm add @utopia-utils/core

树结构工具

# 如果只需要使用树结构 utils
pnpm add @utopia-utils/tree

字符串

  • randomString: 随机生成指定长度、指定字符集的字符串。source
  • capitalize: 首字母大写。source

Dom

# 如果只需要使用 Dom utils
pnpm add @utopia-utils/dom
  • waitForSelector: 等待指定的选择器匹配的元素出现在页面中,如果调用此方法时已经有匹配的元素,那么此方法立即返回。 如果指定的选择器在超时时间后扔不出现,返回 nullsource
  • panzoom: 为指定的元素添加拖拽缩放功能。source
  • canUseDom: 判断是否可以使用 documentwindow 对象,判断是否是 ssr 场景。source
  • domContains: 原生 Node.contains() 的兼容写法 。source
  • updateCSS: 注入 css 样式(通过动态插入 style 标签)。source
  • isAlipay: 判断是否是支付宝浏览器。source
  • isAndroid: 判断是否是 Android 系统。source
  • isIOS: 判断是否是 IOS 系统。source
  • isWeixin: 判断是否是微信浏览器。source
  • isMobile: 判断是否是移动端浏览器。source
  • loadCSS: 动态加载 CSS。source
  • loadScript: 动态加载脚本。source
  • setCssVar: 设置 css 变量。 source
  • checkWebpFeature: 检测浏览器是否支持 webp 的一些特性('lossy' | 'lossless' | 'alpha' | 'animation')。source
  • checkWebpSupport: 检测浏览器是否支持 webp。source

杂项

  • defineDictionary: 定义业务字典。 typesafe source
  • createEnumFromOptions: 通过 options 自动生成对应的 enum, 后期只需要维护 optionstypesafesource
  • sleep: 等待指定的时间。source
  • retry: 重试函数(如果函数抛出错误)直到成功或者达到最大重试次数。source
  • objectKeys: 带类型的 Object.keys()source
  • omit: 删除 object 对象的指定属性。source
  • pick: 从 object 对象中获取指定属性。source
  • randomInt: 生成指定范围内[min, max]的整数。source
  • awaitTo: Async await wrapper for easy error handling without try-catch。source
  • escapeStringRegexp: 把字符串中的特殊字符转义为它可以在正则表达式中使用的形式。source
  • toFixedWithoutZeros: Number.toFixed 并移除末尾的零。source
  • average: 计算数组的平均值,支持 objectsource
  • sum: 计算数组的和,支持 objectsource
  • sort: 数组排序,支持 objectsource
  • alphabetical: 数组按字母顺序排序,支持 objectsource
  • debounce: 防抖。(export from throttle-debounce
  • throttle: 节流。(export from throttle-debounce
  • callLimit: 限制函数调用次数。source
  • once: 限制函数只能调用一次。source
  • encryptPhone: 加密手机号, 中间 4 位显示成 *。source
  • getByPath: 通过路径获取对象的值。typesafe source
  • setByPath: 通过路径设置对象的值。typesafe source
  • arrayToCSV: 数组转换为 CSV 字符串。source
  • memoize: 创建一个会缓存返回结果的函数。source
  • getFileName: 获取文件名。source
  • Cookies: cookie utils.(export from js-cookie
  • NP: 🚀1K tiny & 解决浮点数计算错误.(export from number-precision
  • mitt: event emitter / pubsub, typesafe.(export from mitt
  • merge: Merge two objects x and y deeply, returning a new merged object with the elements from both x and y.(export from deepmerge
  • merge.all: Merges any number of objects into a single result object.(export from deepmerge
  • unique: 数组去重。source
  • union: 数组并集。source
  • uniqueWith: 数组去重,使用自定义的比较函数。source
  • intersection: 两个数组交集。source
  • deepClone: 深拷贝。source
  • deepEqual: 深比较。source
  • compose: 函数组合, 从右到左执行。source
  • pipe: 函数组合, 从左到右执行。source
  • onlyResolvesLast: 解决竞态问题,只保留最后一次调用的结果。source
  • parseQuery: 解析 url query。source
  • groupBy: 数组根据指定的 key 分组。source
  • arrLast: 获取数组最后一个元素。source
  • onTimeout: wrap for setTimeout, return a function to remove the timeout。source
  • onWindowFocus: 监听 window focus 和 visibilitychange 事件,当窗口可见时,触发回调。source
  • formatNumberThousand: 数字千分位格式化。source
  • base64ToFile: base64 转 File, 如图片裁剪时,我们获取到的是 base64,但上传接口一般需要 formData 上传。source
  • toBase64: 将 File | Blob | imgUrl 转 base64。source
  • yuanToFen: 人民币:元转分。source
  • fenToYuan: 人民币:分转元。source
  • yuanFormat: 人民币格式化(单位默认是分,会进行分转元再格式化)。source
  • formatterBankCard: 银行卡号格式化。source
  • formatterPhoneNumber: 手机号格式化。source
  • formatterIdCard: 身份证呈格式化。source
  • desensitizeName: 姓名脱敏。source
  • desensitizePhone: 手机号脱敏。source
  • desensitizeIdCard: 身份证脱敏。source
  • desensitizeEmail: 邮箱脱敏。source
  • createPoll: 创建一个轮询器。source
  • createControledPromise: 创建一个可控的 Promise。source

类型判断

# 如果只需要使用类型判断 utils
pnpm add @utopia-utils/share
  • isBoolean
  • isString
  • isNumber
  • isFunction
  • isSymbol
  • isArray
  • isRegExp
  • isMap
  • isPromise
  • isSet
  • isDate
  • isPlainObject
  • isObject
  • isIntegerKey
  • isUndef
  • isDef
  • isEmpty source
  • isNumberLike source
  • isValidUrl source

vendor

@utopia-utils/core 导出了下面这些 package

  • debounce: 防抖。
  • throttle: 节流。
  • js-cookie: A simple, lightweight JavaScript API for handling browser cookies.
  • mitt: 🥊 Tiny 200 byte functional event emitter / pubsub. typesafe.

推荐的工具库

  • file-saver: An HTML5 saveAs() FileSaver implementation.
  • zod: TypeScript-first schema validation with static type inference.
  • dayjs: ⏰ Day.js 2kB immutable date-time library alternative to Moment.js with the same modern API.
  • any-rule: 常用正则大全。
  • fast-deep-equal: The fastest deep equality check with Date, RegExp and ES6 Map, Set and typed arrays support.
  • big.js: 一个小型,快速的 JavaScript 库,用于任意精度的十进制算术运算。
  • browser-image-compression: Javascript module to be run in the web browser for image compression.
  • hashids: generate YouTube-like ids from numbers.
defineDictionary

定义业务字典, typesafe

// at src/constant.ts
const { get_MUSIC_TYPE_KEYS, get_MUSIC_TYPE_KV, get_MUSIC_TYPE_MAP, get_MUSIC_TYPE_MAP_BY_KEY, get_MUSIC_TYPE_MAP_BY_VALUE, get_MUSIC_TYPE_OPTIONS, get_MUSIC_TYPE_VALUES, get_MUSIC_TYPE_VK } = defineDictionary([
  {
    key: 'POP',
    value: 1,
    label: '流行音乐',
    color: 'red',
  },
  {
    key: 'ROCK',
    value: 2,
    label: '摇滚音乐',
    color: 'blue',
  },
] as const, 'MUSIC_TYPE') // !!! as const is required for type safe

export const MUSIC_TYPE_KEYS = get_MUSIC_TYPE_KEYS()
// ['POP', 'ROCK']
export const MUSIC_TYPE_VALUES = get_MUSIC_TYPE_VALUES()
// [1, 2]
export const MUSIC_TYPE_KV = get_MUSIC_TYPE_KV()
// { POP: 1, ROCK: 2 }
export const MUSIC_TYPE_VK = get_MUSIC_TYPE_VK()
// { 1: 'POP', 2: 'ROCK' }
export const MUSIC_TYPE_MAP_BY_KEY = get_MUSIC_TYPE_MAP_BY_KEY()
// POP: {
//   key: 'POP',
//   value: 1,
//   label: '流行音乐',
//   color: 'red',
// },
// ROCK: {
//   key: 'ROCK',
//   value: 2,
//   label: '摇滚音乐',
//   color: 'blue',
// },
export const MUSIC_TYPE_MAP_BY_VALUE = get_MUSIC_TYPE_MAP_BY_VALUE()
// 1: {
//   key: 'POP',
//   value: 1,
//   label: '流行音乐',
//   color: 'red',
// },
// 2: {
//   key: 'ROCK',
//   value: 2,
//   label: '摇滚音乐',
//   color: 'blue',
// },
export const MUSIC_TYPE_MAP = get_MUSIC_TYPE_MAP()
// { POP: 1, ROCK: 2 }
export const MUSIC_TYPE_OPTIONS = get_MUSIC_TYPE_OPTIONS()
// [
//   {
//     key: 'POP',
//     value: 1,
//     label: '流行音乐',
//     color: 'red',
//   },
//   {
//     key: 'ROCK',
//     value: 2,
//     label: '摇滚音乐',
//     color: 'blue',
//   }
// ]
createEnumFromOptions

通过 options 自动生成对应的 enum, 后期只需要维护 optionstypesafe

废弃, 使用 defineDictionary 代替。

// example
const optionsLevel = [
  {
    value: 0,
    label: 'level1',
  },
  {
    value: 1,
    label: 'level2',
  },
] as const // as const is required to make the typesafe

const enumLevel = createEnumFromOptions(optionsLevel)
console.log(enumLevel.level1) // 0
console.log(enumLevel['0']) // 'level1'
console.log(enumLevel)
// {
//   "0": "level1",
//   "1": "level2",
//   "level1": 0,
//   "level2": 1
// }
retry

重试函数(如果函数抛出错误)直到成功或者达到最大重试次数。

let callNum = 0
function fn() {
  callNum++
  return Promise.reject(new Error('foo'))
}
const [err, res] = await retry(fn, 2, (attemptTime) => {
  return attemptTime * 5
})
// output
// err is Error, res is null, callNum is 3
// execute time is greater than or equal to 15

Tree Utils

所有的 Tree utils 支持定义 fieldName

export interface FieldNames {
  id?: string
  children?: string
  parentId?: string
}
breadthFirstTraverse

广度优先遍历。

img

// example
const tree = [
  {
    name: 'a',
    Children_: [
      { name: 'b' },
    ],
  },
  {
    name: 'c',
  },
]

breadthFirstTraverse(tree, node => console.log(node.name), {
  fieldNames: {
    children: 'Children_', // default is children
  },
})
// output 'a', 'c', 'b'
treeFindNode

查找符合条件的单个节点或多个节点,通过广度优先遍历查找。

// example
const tree = [
  {
    name: 'a',
    children: [
      { name: 'b' },
    ],
  }
]

const res = treeFindNode(tree, node => node.name === 'b') // res is [{ name: 'b' }]
buildTreeFromList

列表结构转树结构。

// example
const list = [
  { uid: '1', title: 'node 1', pid: '' },
  { uid: '1-1', title: 'node 1-1', pid: '1' },
  { uid: '1-2', title: 'node 1-2', pid: '1' },
  { uid: '1-1-1', title: 'node 1-1-1', pid: '1-1' },
]

interface TreeNode {
  key: string
  title: string
  children: TreeNode[]
  pid: string
}

const tree = buildTreeFromList<TreeNode>(list, {
  listFieldNames: { id: 'uid', parentId: 'pid', children: '_Children' },
  treeFieldNames: { id: 'key', parentId: 'pid', children: 'children' },
})
flattenTree

打平,树结构转列表结构。

// example
const tree = {
  id: 1,
  children: [
    {
      id: 2,
    },
  ],
}
const list = flattenTree(tree)
console.log(list)
// output
// [
//   {
//     "ID": 1,
//     "children": [
//       {
//         "ID": 2,
//       },
//     ],
//   },
//   {
//     "ID": 2,
//   },
// ]
treeFindPath

查打符合条件节点的路径。

// example
const tree = [
  {
    name: 'a',
    children: [
      { name: 'b' },
    ],
  },
  {
    name: 'c',
  },
]

const path = treeFindPath(tree, node => node.name === 'b')
console.log(path?.map(v => v.name)) // ['a', 'b']
treeFilterNode

过滤不符合条件的树节点。

const tree = [
  {
    id: 'root',
    children: [
      {
        id: 'child1',
      },
      {
        id: 'child2',
      },
    ],
  },
]
treeFilterNode(tree, node => node.id.includes('1'))
// output
// [
//   {
//     children: [
//       {
//         id: 'child1',
//       },
//     ],
//     id: 'root',
//   },
// ]

License

MIT

About

Collection of common utils. Tree-shakable ESM. Typesafe.

Resources

License

Stars

Watchers

Forks

Packages

No packages published