@seepine/cache
v0.1.3
Published
cache
Readme
@seepine/cache
轻量缓存工具,支持:
- 纯内存缓存(基于 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')