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

@seepine/cache

v0.1.3

Published

cache

Readme

@seepine/cache

npm version npm downloads bundle License

轻量缓存工具,支持:

  • 纯内存缓存(基于 LRU Cache)
  • 通过 Adapter 接入外部缓存(如 Redis)
  • 内存 + 外部多级缓存
  • 分布式锁(无 Adapter 时自动退化为进程内锁)

一、安装

npm install @seepine/cache

二、快速开始

2.1 内存缓存

无需任何配置,开箱即用:

import { Cache } from '@seepine/cache'

const cache = new Cache()

await cache.set('k1', 'v1', '30s')
const value = await cache.get('k1') // 'v1'

2.2 使用 Adapter(以 Bun Redis 为例)

通过 adapter 参数传入实现了 CacheAdapter 的实例:

import { Cache } from '@seepine/cache'
import { BunRedisAdapter } from '@seepine/cache/adapt/bun'

const cache = new Cache({
  adapter: new BunRedisAdapter('redis://localhost:6379'),
  namespace: 'my-app',
})

2.3 自定义 Adapter

实现 CacheAdapter 抽象类即可接入任意缓存后端:

import { Cache, CacheAdapter } from '@seepine/cache'

class MyRedisClient extends CacheAdapter {
  async set<T>(key: string, value: T, expireSeconds?: number) {
    /* ... */
  }
  async setnx<T>(key: string, value: T, expireSeconds?: number) {
    /* ... */
  }
  async get<T>(key: string): Promise<T | undefined> {
    /* ... */
  }
  async del(key: string) {
    /* ... */
  }
  async expire(key: string, expireSeconds: number) {
    /* ... */
  }
  async clear(namespace: string) {
    /* ... */
  }
  async close() {
    /* ... */
  }
}

const cache = new Cache({
  adapter: new MyRedisClient(),
})

2.4 开启多级缓存(内存 + Adapter)

需要传入 adapter 才可启用多级缓存:

import { Cache } from '@seepine/cache'
import { BunRedisAdapter } from '@seepine/cache/adapt/bun'

const cache = new Cache({
  adapter: new BunRedisAdapter(),
  multiLevelEnabled: true,
  multiLevelTtl: 1000, // 内存层 TTL,单位毫秒
})

三、API

3.1 Constructor Options

| 参数 | 类型 | 默认值 | 说明 | | ----------------------- | -------------- | --------- | --------------------------------------------------- | | adapter | CacheAdapter | — | 外部缓存客户端,不传则使用纯内存模式 | | namespace | string | 'cache' | 命名空间,键前缀,避免不同应用键冲突 | | multiLevelEnabled | boolean | false | 是否启用多级缓存(需要传入 adapter) | | multiLevelTtl | number | 1000 | 多级缓存中内存层 TTL(毫秒) | | lockTimeoutSeconds | number | 0 | 锁等待超时(秒),0 为无限等待 | | lockAcquireIntervalMs | number | 100 | 尝试获取锁的时间间隔(毫秒) | | lockWatchDogSeconds | number | 20 | 看门狗续期间隔(秒),实际锁过期时间为此值 × 2 + 5s |

3.2 方法

| 方法 | 说明 | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | | set<T>(key, value, ttl?) | 写入缓存。ttl 支持秒数(如 60)或字符串("10s" / "5m" / "2h" / "3d" / "1y") | | get<T>(key) | 读取缓存,不存在返回 undefined | | getOrSet<T>(key, getFn, ttl?) | 若 key 有值直接返回;否则加锁后执行 getFn 获取并写入缓存后返回 | | del(key) | 删除缓存 | | clear() | 清空当前命名空间缓存 | | lock<T>(key, fn, timeoutSeconds?) | 获取锁后执行 fn,结束后自动释放。有 Adapter 时使用分布式锁(含自动续约 watchdog),无 Adapter 时使用进程内锁。timeoutSeconds < 0 会抛错 | | close() | 关闭连接,建议在应用退出前调用 |

3.3 TTL 格式

| 格式 | 含义 | 示例 | | ---- | ---- | ------------ | | 数字 | 秒 | 60 → 60 秒 | | Ns | 秒 | "30s" | | Nm | 分钟 | "5m" | | Nh | 小时 | "2h" | | Nd | 天 | "7d" | | Ny | 年 | "1y" |

四、示例:防止缓存击穿

import { Cache } from '@seepine/cache'
import { BunRedisAdapter } from '@seepine/cache/adapt/bun'

const cache = new Cache({
  adapter: new BunRedisAdapter(),
  multiLevelEnabled: true,
  multiLevelTtl: 1000,
})

async function getUser(userId: string) {
  // 首次走 DB,之后命中内存缓存,内存过期后走 Adapter 缓存
  return cache.getOrSet(
    `user:${userId}`,
    async () => {
      return await db.user.findById(userId)
    },
    '30s',
  )
}

五、内置 Adapter

Bun Redis

基于 Bun 内置的 Bun.RedisClient,无需额外依赖:

import { BunRedisAdapter } from '@seepine/cache/adapt/bun'

// 默认连接 localhost:6379,也支持 REDIS_URL / VALKEY_URL 环境变量
const client = new BunRedisAdapter()

// 或指定地址
const client = new BunRedisAdapter('redis://localhost:6379')