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

@aurouscia/au-undo-redo

v1.0.1

Published

一个轻量级的撤销/重做(Undo/Redo)状态管理工具,支持两种存储模式:完整状态存储和增量补丁存储。

Readme

au-undo-redo

一个轻量级的撤销/重做(Undo/Redo)状态管理工具,支持两种存储模式:完整状态存储和增量补丁存储。

安装

npm install @aurouscia/au-undo-redo

特性

  • 🔄 两种存储模式:完整状态存储(StateStore)和增量补丁存储(PatchStore)
  • 🧠 智能去重:自动跳过无变化的状态记录
  • 🗂️ 带 ID 数组支持:对带有 id 属性的数组进行智能差异计算
  • 📦 深拷贝保护:使用 rfdc 进行高性能深拷贝,防止外部修改影响历史记录
  • 轻量快速:使用 fast-deep-equal 进行高效的深度比较
  • 🎯 TypeScript 支持:完整的类型定义

快速开始

AurStateStore - 完整状态存储

适用于状态对象较小,或需要简单实现的场景。

import { AurStateStore } from '@aurouscia/au-undo-redo'

interface EditorState {
  title: string
  content: string
  settings: { fontSize: number }
}

// 创建 store,容量为 20(默认),可选回调函数
const store = new AurStateStore<EditorState>(20, (canUndo, canRedo) => {
  console.log('Can undo:', canUndo, 'Can redo:', canRedo)
})

// 写入状态
store.push({ title: 'Hello', content: 'World', settings: { fontSize: 14 } })
store.push({ title: 'Hello', content: 'World!', settings: { fontSize: 14 } })

// 撤销
const prevState = store.undo()

// 重做
const nextState = store.redo()

AurPatchStore - 增量补丁存储

适用于大型状态对象,只存储差异补丁,节省内存。

import { AurPatchStore } from '@aurouscia/au-undo-redo'

interface AppState {
  user: { name: string; email: string }
  items: Array<{ id: number; text: string; done: boolean }>
  settings: { theme: 'light' | 'dark' }
}

const initialState: AppState = {
  user: { name: 'John', email: '[email protected]' },
  items: [
    { id: 1, text: 'Task 1', done: false },
    { id: 2, text: 'Task 2', done: true }
  ],
  settings: { theme: 'light' }
}

const store = new AurPatchStore<AppState>(initialState, 50)

// 修改普通属性
store.push({
  ...store.currentState,
  user: { name: 'Jane', email: '[email protected]' }
})

// 修改带 id 的数组(智能差异计算)
store.push({
  ...store.currentState,
  items: [
    { id: 1, text: 'Task 1 modified', done: true },  // 修改
    { id: 2, text: 'Task 2', done: true },           // 不变
    { id: 3, text: 'Task 3', done: false }           // 新增
  ]
})

// 撤销会恢复到之前的状态
const prevState = store.undo()

API 参考

构造函数

new AurStateStore<T>(historyMaxLength?: number, callBack?: AurAvailabilityCallBack)
new AurPatchStore<T>(initialState: T, historyMaxLength?: number, callBack?: AurAvailabilityCallBack)

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | initialState | T | - | PatchStore 需要初始状态 | | historyMaxLength | number | 20 | 历史记录最大容量,超出后丢弃最老的记录 | | callBack | (canUndo: boolean, canRedo: boolean) => void | - | 状态可用性变化时的回调 |

方法

| 方法 | 返回值 | 说明 | |------|--------|------| | push(state) | void | 写入新状态 | | undo() | T \| undefined | 撤销到上一步,返回状态或 undefined(如果没有可撤销的) | | redo() | T \| undefined | 重做到下一步,返回状态或 undefined(如果没有可重做的) |

属性

| 属性 | 类型 | 说明 | |------|------|------| | currentState | T | PatchStore 特有,获取当前状态 | | history | T[] | 历史记录数组(只读) |

高级特性

带 ID 的数组处理

PatchStore 对带有 id 属性的数组会进行智能差异计算:

  • 根据 id 匹配数组元素
  • 支持新增、删除、修改操作
  • 如果数组中有重复 id 或部分元素没有 id,会自动退化为普通数组处理
interface State {
  items: Array<{ id: number; name: string }>
}

// 这种数组会走智能差异计算
const state1 = { items: [{ id: 1, name: 'A' }, { id: 2, name: 'B' }] }

// 这种数组会退化为普通属性处理(因为有重复 id)
const state2 = { items: [{ id: 1, name: 'A' }, { id: 1, name: 'B' }] }

无变化自动跳过

两个 Store 都会自动检测状态是否真正发生变化:

  • 引用相同(===)的对象不会记录
  • 深度相等(内容相同)的对象不会记录
const store = new AurStateStore<Data>(20)

const data = { x: 1 }
store.push(data)  // 记录
store.push(data)  // 不记录(引用相同)
store.push({ x: 1 })  // 不记录(深度相等)
store.push({ x: 2 })  // 记录(有变化)

选择合适的 Store

| 场景 | 推荐 Store | |------|-----------| | 状态对象较小(< 100KB) | AurStateStore | | 状态对象较大或历史记录多 | AurPatchStore | | 需要频繁保存状态 | AurPatchStore | | 简单的使用场景 | AurStateStore | | 带 ID 的数组需要精确 diff | AurPatchStore |

技术细节

  • 深拷贝:使用 rfdc(Really Fast Deep Clone)进行高性能深拷贝
  • 深度比较:使用 fast-deep-equal 进行高效的深度相等性检查
  • 内存管理:历史记录超出容量后自动丢弃最老的记录