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

mm_cachebase

v2.0.2

Published

一个轻量级的本地缓存类库,接口与 mm_redis 完全对齐:全异步API、冒号风格事件、统一签名与返回值,支持字符串、哈希、列表、集合、有序集合、发布订阅。

Downloads

1,223

Readme

mm_cachebase

一个轻量级的本地缓存类库,提供与 mm_redis 完全对齐 的异步缓存操作接口,支持过期时间、哈希表、列表、集合、有序集合、发布订阅等功能,以及冒号风格的事件通知系统。

项目信息

特点

  • 接口与 mm_redis 完全对齐:全异步 API、冒号风格事件、统一方法签名与返回值,可与 mm_redis 无缝切换
  • 全异步设计:所有公共方法均为 async,返回 Promise
  • 冒号风格事件set:before / set:after / set:error,与 mm_redis 一致
  • 完整的数据类型支持:字符串、哈希表、列表、集合、有序集合、发布订阅
  • 过期时间管理:支持秒级 expire 与毫秒级 pexpire
  • 多文件持久化:通过 scope 参数实现多实例数据隔离

安装

npm install mm_cachebase

基本使用

const { CacheBase } = require('mm_cachebase');

// 创建缓存实例(构造时自动初始化)
const cache = new CacheBase({ scope: 'myapp' });

async function example() {
    // 设置缓存,10 秒过期
    await cache.set("name", "张三", 10);
    
    // 获取缓存
    const value = await cache.get("name");
    $.log.debug(value); // 输出: 张三
    
    // 删除缓存(返回删除数量)
    const deleted = await cache.del("name");
    $.log.debug(deleted); // 输出: 1
}

连接管理

与 mm_redis 一致的连接管理接口:

const cache = new CacheBase({ scope: 'myapp' });
await cache.init();           // 初始化(构造时已自动调用)
await cache.open();           // 打开连接(等同于 init)
const connected = cache.isConnected(); // 检查连接状态,返回 Boolean
await cache.close();          // 关闭连接(等同于 destroy)
cache.dispose();              // 同步销毁(清理定时器与数据)

API 说明

所有方法均为 async,返回 Promise。事件名采用冒号风格(xxx:before / xxx:after / xxx:error)。

键值操作

| 方法 | 签名 | 返回值 | |------|------|--------| | set | set(key, value, seconds=0) | Promise<Boolean> | | get | get(key) | Promise<Object\|null> | | del | del(key) | Promise<Number> 删除数量 | | exists | exists(key) | Promise<Number> 0/1 | | has | has(key) | Promise<Boolean> | | getset | getset(key, value, seconds=0) | Promise<Object\|null> 旧值 | | add | add(key, value, seconds=0) | Promise<Boolean> SETNX 语义 |

批量操作

| 方法 | 签名 | 返回值 | |------|------|--------| | mset | mset(obj, seconds=0) | Promise<Boolean> | | mget | mget(keys) | Promise<Array> |

过期时间管理

| 方法 | 签名 | 返回值 | |------|------|--------| | expire | expire(key, seconds) | Promise<Boolean> | | pexpire | pexpire(key, milliseconds) | Promise<Boolean> | | persist | persist(key) | Promise<Boolean> | | ttl | ttl(key, [seconds]) | Promise<Number\|Boolean> |

哈希表操作

| 方法 | 签名 | 返回值 | |------|------|--------| | hset | hset(key, field, value) | Promise<Boolean> | | hget | hget(key, field) | Promise<Object\|null> | | hgetall | hgetall(key) | Promise<Object> | | hdel | hdel(key, field) | Promise<Number> 删除字段数 | | hmset | hmset(key, obj) | Promise<Boolean> | | hmget | hmget(key, fields) | Promise<Array> | | hlen | hlen(key) | Promise<Number> |

数值操作

| 方法 | 签名 | 返回值 | |------|------|--------| | incr | incr(key, seconds=0) | Promise<Number> 错误返回 null | | decr | decr(key, seconds=0) | Promise<Number> 错误返回 null | | incrby | incrby(key, increment, seconds=0) | Promise<Number> 错误返回 null | | decrby | decrby(key, decrement, seconds=0) | Promise<Number> 错误返回 null | | incrbyfloat | incrbyfloat(key, increment, seconds=0) | Promise<Number> 错误返回 null | | addInt | addInt(key, value, seconds=0) | Promise<Number> 兼容方法 | | addFloat | addFloat(key, num, seconds=0) | Promise<Number> 兼容方法 |

字符串操作

| 方法 | 签名 | 返回值 | |------|------|--------| | setrange | setrange(key, value, seconds=0) | Promise<Number> 追加后长度 | | append | append(key, value) | Promise<Number> 长度 | | strlen | strlen(key) | Promise<Number> |

列表操作

| 方法 | 签名 | 返回值 | |------|------|--------| | setForList | setForList(key, value, seconds=0) | Promise<Number> 列表长度 | | addForList | addForList(key, value, seconds=0) | Promise<Number> 列表长度 | | getForList | getForList(key, start=0, end=-1) | Promise<Array> | | hasForList | hasForList(key, value) | Promise<Boolean> | | clearForList | clearForList(key) | Promise<Boolean> |

集合操作

| 方法 | 签名 | 返回值 | |------|------|--------| | sadd | sadd(key, members) | Promise<Number> 添加数量 | | srem | srem(key, members) | Promise<Number> 移除数量 | | sismember | sismember(key, member) | Promise<Boolean> | | smembers | smembers(key) | Promise<Array> | | scard | scard(key) | Promise<Number> | | sinter | sinter(...keys) | Promise<Array> 交集 | | sunion | sunion(...keys) | Promise<Array> 并集 | | sdiff | sdiff(...keys) | Promise<Array> 差集 |

有序集合操作

| 方法 | 签名 | 返回值 | |------|------|--------| | zadd | zadd(key, score, member) | Promise<Boolean> 新成员返回 true | | zrem | zrem(key, members) | Promise<Number> 移除数量 | | zscore | zscore(key, member) | Promise<Number\|null> | | zrank | zrank(key, member) | Promise<Number\|null> | | zrange | zrange(key, start, stop, withScores=false) | Promise<Array> | | zcard | zcard(key) | Promise<Number> | | zincrby | zincrby(key, increment, member) | Promise<Number> |

发布订阅

注意:发布订阅为进程内实现,无跨进程能力,与 mm_redis 的跨进程语义不同。

| 方法 | 签名 | 返回值 | |------|------|--------| | subscribe | subscribe(channel, func) | Promise<Boolean> | | unsubscribe | unsubscribe(channel) | Promise<Boolean> | | publish | publish(channel, message) | Promise<Number> 接收者数量 |

键管理

| 方法 | 签名 | 返回值 | |------|------|--------| | keys | keys(pattern) | Promise<Array> 支持 * 通配符 | | dbsize | dbsize() | Promise<Number> | | flushdb | flushdb() | Promise<Boolean> | | clear | clear() | Promise<Boolean> flushdb 别名 |

事件系统

事件名采用冒号风格,与 mm_redis 完全一致。每个操作有 :before:after:error 三种事件。

const cache = new CacheBase({ scope: 'myapp' });

// 监听 set 前置事件,可修改参数或取消操作
cache.on('set:before', (ctx) => {
    $.log.debug('即将设置键:', ctx.key, '值:', ctx.value);
    // 可修改 ctx.key / ctx.value / ctx.seconds
    // 设置 ctx.cancel = true 可取消操作
});

// 监听 set 后置事件
cache.on('set:after', (data) => {
    $.log.debug('设置完成:', data.key, '成功:', data.success);
});

// 监听错误事件
cache.on('set:error', (data) => {
    $.log.error('设置出错:', data.key, data.error);
});

支持的事件

所有公共方法均有对应事件,命名规则为 方法名:before / 方法名:after / 方法名:error

  • 键值:setgetdelexistsadd
  • 批量:msetmget
  • 过期:expirepexpirepersistttl
  • 哈希:hsethgethgetallhdelhmsethmgethlen
  • 数值:incrdecrincrbydecrbyincrbyfloataddIntaddFloat
  • 字符串:setrangeappend
  • 列表:setForListaddForListgetForListhasForListclearForList
  • 集合:saddsremsismembersmembers
  • 有序集合:zaddzrem
  • 键管理:keysclear

使用示例

集合操作

async function setExample() {
    await cache.sadd('tags', ['node', 'js', 'cache']);
    const isMember = await cache.sismember('tags', 'node'); // true
    const members = await cache.smembers('tags'); // ['node', 'js', 'cache']
    const count = await cache.scard('tags'); // 3
    await cache.srem('tags', ['js']);
}

有序集合操作

async function zsetExample() {
    await cache.zadd('ranking', 100, 'user1');
    await cache.zadd('ranking', 200, 'user2');
    const rank = await cache.zrank('ranking', 'user1'); // 0
    const top = await cache.zrange('ranking', 0, -1, true); // [{member:'user1', score:100}, ...]
    await cache.zincrby('ranking', 50, 'user1'); // 新分数 150
}

发布订阅

async function pubsubExample() {
    await cache.subscribe('news', (message) => {
        $.log.debug('收到消息:', message);
    });
    await cache.publish('news', 'hello world'); // 接收者数量: 1
}

与 mm_redis 的接口一致性

本模块与 mm_redis 提供完全对齐的接口,调用方可通过统一的方式使用内存缓存或 Redis 缓存:

  • 全异步:所有方法返回 Promise
  • 事件命名:冒号风格 xxx:before / xxx:after / xxx:error
  • 方法签名set(key, value, seconds=0)mset(obj, seconds=0)incrby(key, increment, seconds=0)
  • 返回值hset 返回 Booleandel/exists/hdel 返回 Numberhget 不存在返回 null

差异点

  • 发布订阅为进程内实现(mm_redis 支持跨进程)
  • 集合/有序集合用 JS 原生 Set/Map 实现,无 Redis 的 O(log N) 复杂度保证
  • 构造函数自动初始化(内存缓存特性),mm_redis 需显式 open()