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

@aieasyto/history

v1.2.2

Published

```typescript export abstract class Action< AUTO_MERGE = boolean | undefined, NAME = AUTO_MERGE extends true ? string : boolean | undefined, > { name?: NAME autoMerge?: AUTO_MERGE

Readme

Action

abstract Action

export abstract class Action<
  AUTO_MERGE = boolean | undefined,
  NAME = AUTO_MERGE extends true ? string : boolean | undefined,
> {
  name?: NAME
  autoMerge?: AUTO_MERGE

  constructor(config?: { name?: NAME; autoMerge?: AUTO_MERGE }) {
    config && (this.name = config.name)
    config && (this.autoMerge = config.autoMerge)
  }
  do(): Promise<any> {
    return Promise.resolve()
  }
  undo(): Promise<any> {
    return Promise.resolve()
  }
}

根据抽象类Action派生需要复用的Action,比如 BatchAction

BatchAction

批量执行的行为,想要某些操作一同执行,撤销的时候也一同撤销

/**
 * 批量执行多个action,会按照顺序执行,并且会等待上一个action执行完成再执行下一个action
 */
export class BatchAction extends Action {
  constructor(protected actions: Action[]) {
    super()
  }

  async do() {
    return Promise.all(this.actions.map(a => a.do()))
  }

  async undo() {
    const actionList = this.actions.slice().reverse()
    return Promise.all(actionList.map(a => a.undo()))
  }
}

createAction & 自动合并Action

type CreateActionFunction = <Data>(config: ActionConfig<Data>) => MyAction<Data>
export const createAction: CreateActionFunction = config => {
  return new MyAction(config)
}

config 中如果设置了 autoMerge 为true,则一定需要传递name字段。

config: {
  autoMerge?: undefined
  name?: string
  data?: DATA
  do: Function
  undo: Function
}

do 以及 undo 中可以通过this访问到配置中的data属性



const action = createAction({
  autoMerge: true,
  name: 'changeColor',
  data: { color: '#ff0000' },
  do: () => {
    console.log('do', this.data!.color)
  },
  undo: () => {
    console.log('undo', this.data!.color)
  },
})

history 会自动将相同name的action合并成一个BatchAction,用于ColorPicker这类改变值非常频繁的情况。ColorPicker 一次可能创建上百个Action,可能会超出limit限制

export class CommonAction<Data> extends Action {
  private doFn: Function
  private undoFn: Function

  // @ts-expect-error
  private data?: Data

  constructor(config: ActionConfig<Data>) {
    super()
    this.doFn = config.do
    this.undoFn = config.undo
    this.data = config.data
    this.name = config.name
    this.autoMerge = config.autoMerge
  }

  do() {
    return wrapPromise(() => this.doFn())
  }

  undo() {
    return wrapPromise(() => this.undoFn())
  }
}

CommonAction 是从 abstract Action 派生的类,也是createAction会创建并加入到history中的类

useAction


const { createHelloAction } = useAction('hello')

config action createHelloAction({
  ...config
})

useAction 参数是一个name,会根据这个name返回一个action creator,并且动态生成函数命名

History

import ActionHistory from 'src/lib/history'

const history = new ActionHistory({ limit: 100, logger: __DEV__, mergeTime: 500 })
  • logger: __DEV__ 在研发模式下开启logger
  • limit: 限制history最大容量
  • mergeTime: 自动合并同类Action的时间间隔,默认2_000

history.do

import ActionHistory from 'src/lib/history'

const history = new ActionHistory({ limit: 100, logger: __DEV__, mergeTime: 500 })

const action = createAction({...config})

history.do(action)

history.do(action) 会执行actiondo方法,并将此action加入到historyundoStack