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

ansuko

v1.3.7

Published

A modern JavaScript/TypeScript utility library that extends lodash with practical, intuitive behaviors. Fixes lodash quirks, adds Promise support, Japanese text processing, and GeoJSON utilities.

Readme

ansuko

在lodash基础上扩展、提供实用且直观易懂的现代JavaScript/TypeScript工具库。

English | 日本語 | 简体中文

为什么选择 ansuko?

"ansuko"这个名字有多重含义:

  • アンスコ (ansuko) - 日文中"underscore"(下划线)的缩写(アンダースコア)
  • ansuko = underscore → low dash → lodash - 延续这个系列
  • スコ (suko) - 日文俚语,意为"喜欢"或"最爱"

安装

npm install ansuko

或添加到你的 package.json

{
  "dependencies": {
    "ansuko"
  }
}

核心理念

ansuko以直观的语法,解决了JavaScript中常见的痛点。

修正 lodash 的非常规行为

// ❌ lodash(不直观)
_.isEmpty(0)           // true  - 0真的为「空」吗?
_.isEmpty(true)        // true  - true算「空」吗?
_.castArray(null)      // [null] - 为何保留null?

// ✅ ansuko(直观)
_.isEmpty(0)           // false - 数值不为空
_.isEmpty(true)        // false - 布尔值不为空
_.castArray(null)      // []    - 得到空数组

安全的 JSON 处理

// ❌ 标准 JSON(繁琐)
JSON.stringify('hello')  // '"hello"'  - 多余的引号
JSON.parse(badJson)      // throws    - 必须用try-catch

// ✅ ansuko(简洁直观)
_.jsonStringify('hello')     // null     - 非对象不序列化
_.jsonStringify({ a: 1 })    // '{"a":1}' - 结构简洁
_.parseJSON(badJson)         // null     - 不抛异常
_.parseJSON('{ a: 1, }')     // {a:1}    - 支持JSON5!

支持Promise的回滚

// ❌ 冗长写法
const data = await fetchData()
const result = data ? data : await fetchBackup()

// ✅ ansuko(简洁)
const result = await _.valueOr(
  () => fetchData(),
  () => fetchBackup()
)

智能比较

// ❌ 三元运算符地狱
const value = a === b ? a : (a == null && b == null ? a : defaultValue)

// ✅ ansuko(可读)
const value = _.equalsOr(a, b, defaultValue)  // null == undefined

主要特性

增强型lodash函数

  • isEmpty - 检查是否为空(数字和布尔值不视为空)
  • castArray - 转换为数组,若为null/undefined 则返回 []
  • 支持所有lodash函数:sizeisNildebounceisEqualkeysvalueshas

数值处理与流控制

  • valueOr - 支持Promise和函数,获取目标值或默认值
  • emptyOr - 若为空则返回null,否则应用回调或返回值
  • hasOr - 检查路径是否存在,不存在则返回默认值(支持深层路径及 Promise)
  • equalsOr - 支持Promise的比较与回退,具备直观的Nil处理机制
  • changes - 用于数据库更新的对象差分追踪(支持 profile.tags[1]等深层路径及排除模式)`和排除模式)
  • swallow - 执行函数并在报错时返回undefined(支持同步/异步)
  • swallowMap - 将错误处理为undefined的数组map(支持compact模式排除错误项)

类型转换与验证

  • toNumber - 解析包含逗号、全角字符的数字,无效时返回null
  • toBool - 智能布尔值转换(支持 "yes"/"no"/"true"/"false"/数字),可配置未检测到时的行为检测处理
  • boolIf - 带有回退机制的安全布尔值转换
  • isValidStr - 非空字符串验证

JSON 处理

  • parseJSON - 无需try-catch的安全JSON/JSON5解析(支持注释及末尾逗号)
  • jsonStringify - 仅字符串化有效对象,防止字符串被重复包裹

数组工具

  • arrayDepth - 返回数组的嵌套深度(非数组:0,空数组:1)
  • castArray - 转换为数组,nil 变为 [](而非 [null]

日语文本处理(插件:ansuko/plugins/ja

  • kanaToFull - 半角片假名 → 全角(例如 ガギガギ
  • kanaToHalf - 全角 → 半角片假名(浊音拆分:ガギガギ
  • kanaToHira - 片假名 → 平假名(自动先转换半角)
  • hiraToKana - 平假名 → 片假名
  • toHalfWidth - 全角 → 半角,可选连字符标准化
  • toFullWidth - 半角 → 全角,可选连字符标准化
  • haifun - 将各种形式的连字符统一正规化

Geo地理空间工具(插件:ansuko/plugins/geo

  • toGeoJson - 具备自动检测功能的通用GeoJSON转换器(按高维到低维顺序尝试)
  • toPointGeoJson - 将坐标或对象转换为Point GeoJSON
  • toPolygonGeoJson - 将外环转换为Polygon(验证闭合环)
  • toLineStringGeoJson - 将坐标转换为LineString(检查自相交)
  • toMultiPointGeoJson - 将多个点转换为MultiPoint
  • toMultiPolygonGeoJson - 将多个多边形转换为MultiPolygon
  • toMultiLineStringGeoJson - 将多条线转换为MultiLineString
  • unionPolygon - 将多个Polygon/MultiPolygon合并为单一几何体
  • parseToTerraDraw - 将GeoJSON转换为兼容Terra Draw的Feature
  • mZoomInterpolate - 将缩放对象转换为MapBox插值表达式
  • mProps - 将(camelCase)属性转换为MapBox兼容格式(处理minzoom、visibility等特殊情况)

Prototype原型扩展(插件:ansuko/plugins/prototype

  • Array.prototype.notMap - 使用谓词取反进行map,返回布尔数组
  • Array.prototype.notFilter - 使用谓词取反进行filter(筛选不匹配的项)

时间工具

  • waited - 延迟N个动画帧后执行(在 React/DOM 環境下比setTimeout更优)

插件架构

ansuko使用最小核心 + 插件架构来保持你的包大小小:

  • 核心(约 20KB):在 lodash 上增强的必备工具
  • 日文插件(约 5KB):仅在需要日文文本处理时引入
  • Geo 插件(约 100KB,含 @turf/turf):面向 GIS 应用
  • Prototype 插件(约 1KB):仅在需要扩展 Array.prototype 时引入
// 最小打包:仅核心
import _ from 'ansuko'  // ~20KB

// 按需加入日文支持
import jaPlugin from 'ansuko/plugins/ja'
const extended = _.extend(jaPlugin)  // +5KB

// 地图类应用再挂载 GIS
import geoPlugin from 'ansuko/plugins/geo'
const full = extended.extend(geoPlugin)  // +100KB

快速开始

基本用法

import _ from 'ansuko'

// 增强的 lodash 函数
_.isEmpty(0)           // false(不像 lodash 那样是 true!)
_.isEmpty([])          // true
_.castArray(null)      // [](不是 [null]!)
_.toNumber('1,234.5')  // 1234.5

// 支持 Promise 的值处理
const value = await _.valueOr(
  () => cache.get(id),
  () => api.fetch(id)
)

// 安全的 JSON 解析
const data = _.parseJSON('{ "a": 1, /* 注释 */ }')  // 支持 JSON5!

// 跟踪对象更改以进行数据库更新
const diff = _.changes(
  original, 
  updated, 
  ['name', 'email', 'profile.bio']
)

// 无需 try-catch 的错误处理
const result = _.swallow(() => riskyOperation())  // 出错时为 undefined
const items = _.swallowMap([1, 2, 3], item => processItem(item), true)  // 过滤错误

使用插件

日文文本插件

import _ from 'ansuko'
import jaPlugin from 'ansuko/plugins/ja'

_.extend(jaPlugin)

_.kanaToFull('ガギ')              // 'ガギ'
_.kanaToHira('アイウ')             // 'あいう'
_.toHalfWidth('ABCー123', '-') // 'ABC-123'
_.haifun('test‐data', '-')       // 'test-data'

地理插件

import _ from 'ansuko'
import geoPlugin from 'ansuko/plugins/geo'

const extended = _.extend(geoPlugin)

// 将各种格式转换为 GeoJSON
extended.toPointGeoJson([139.7671, 35.6812])
// => { type: 'Point', coordinates: [139.7671, 35.6812] }

extended.toPointGeoJson({ lat: 35.6895, lng: 139.6917 })
// => { type: 'Point', coordinates: [139.6917, 35.6895] }

// 合并多个多边形
const unified = extended.unionPolygon([polygon1, polygon2])

// MapBox 工具
extended.mZoomInterpolate({ 10: 1, 15: 5, 20: 10 })
// => ["interpolate", ["linear"], ["zoom"], 10, 1, 15, 5, 20, 10]

extended.mProps({
  fillColor: "#ff0000",
  sourceLayer: "buildings",
  visibility: true
})
// => { "fill-color": "#ff0000", "source-layer": "buildings", "visibility": "visible" }

原型插件

import _ from 'ansuko'
import prototypePlugin from 'ansuko/plugins/prototype'

_.extend(prototypePlugin)

// 现在 Array.prototype 已扩展
[1, 2, 3].notMap(n => n > 1)      // [true, false, false]
[1, 2, 3].notFilter(n => n % 2)   // [2](偶数)

链式插件

import _ from 'ansuko'
import jaPlugin from 'ansuko/plugins/ja'
import geoPlugin from 'ansuko/plugins/geo'

const extended = _
  .extend(jaPlugin)
  .extend(geoPlugin)

// 现在你同时拥有日文和地理工具!
extended.kanaToHira('アイウ')
extended.toPointGeoJson([139.7, 35.6])

文档

更多详细信息,请参阅:

支持TypeScript

完美支持TypeScript,包含完整的类型定义。所有函数均支持泛型,并经过严格的类型标注。

为什么仅有lodash还不够?

lodash很优秀,但存在一些被社区广为诟病的怪癖:

已修正的部分

  1. _.isEmpty(true) 返回 true - 布尔值真的为"空"吗?
  2. _.isEmpty(1) 返回 true - 数字1怎么能为"空"呢?
  3. _.castArray(null) 返回 [null] - 为什么要把null包含在数组里?

lodash中没有的工具函数

  1. 无安全的 JSON 解析 - 总是需要写重复的try-catch代码块
  2. 无内置的比较与后备 - 代码中到处充斥着冗余的三元运算符
  3. 无 Promise 感知的值解析 - 手动处理Promise逻辑非常繁琐
  4. 无对象差异跟踪 - 进行数据库更新操作时往往需要引入额外库
  5. **JSON.stringify("hello") 会添加多余引号 —— 生成 '"hello"'这种带引号的繁琐字符串

实际使用案例

// lodash的常见写法(冗长且易错)
let data
try {
  const cached = cache.get(id)
  if (cached && !_.isEmpty(cached)) {
    data = cached
  } else {
    const fetched = await api.fetch(id)
    data = fetched || defaultValue
  }
} catch (e) {
  data = defaultValue
}

// ansuko的实现逻辑(简洁且安全)
const data = await _.valueOr(
  () => cache.get(id),
  () => api.fetch(id),
  defaultValue
)

ansuko在修正上述问题的同时,为现代JavaScript开发增添了强大的工具函数,并保持了与Lodash的100%兼容性。

依赖项

  • lodash - 核心工具函数
  • json5 - 支持注释和末尾逗号的扩展JSON解析
  • @turf/turf - 地理空间分析(用于geo插件)

从源代码构建

npm install
npm run build

执行后将在dist目录下生成编译后的JavaScript文件和类型定义。

开发相关

因为不太擅长写测试和文档,我在使用 Claude 构思的同时,也得到了一位好朋友的贴心帮助,共同完成了这份文档。

许可证

MIT

作者

Naoto Sera


技术无国界,开源即和平。无论世界如何变迁,愿代码始终纯粹。