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_json

v1.0.7

Published

JSON文件数据库操作模块,提供与mm_mysql完全兼容的API接口,以JSON文件存储数据,支持字段索引快速搜索

Readme

mm_json

一个基于 JSON 文件存储的 Node.js 数据库操作库,与 mm_mysql 保持完全一致的 API 接口,无需安装任何数据库服务。

架构设计

db/                          # 数据库根目录
└── game/                    # 数据库名 = 目录名
    ├── characters/          # 表名 = 子目录名
    │   ├── _meta.json       # 表元数据(字段定义、索引配置)
    │   ├── 1.json           # 每行数据 = 一个 JSON 文件
    │   ├── 2.json
    │   └── _index/          # 索引目录
    │       └── class/       # 按字段名分类
    │           └── _E68898E5A3AB.json  # 字段值 → 行ID列表
    ├── items/
    │   ├── _meta.json
    │   ├── 1.json
    │   └── _index/
    └── inventory/

安装

npm install mm_json

基本使用

const { JsonDB } = require('mm_json');

// 创建数据库实例
const db = new JsonDB({
  dir: './data/',           // 数据存储目录
  database: 'game'          // 数据库名
});

// 打开数据库
await db.open();

// 获取表管理器
const userDb = db.table('users', 'id');

// 增删改查
await userDb.add({ name: '张三', level: 10, gold: 5000 });
const list = await userDb.get({ level_min: 5 }, 'level DESC');
await userDb.set({ name: '张三' }, { level: 11 });
await userDb.del({ name: '张三' });

// 关闭
await db.close();

主要特性

  • 🗂️ 零依赖数据库:无需安装 MySQL、SQLite 等服务,纯 JSON 文件存储
  • 🔄 完全兼容 mm_mysql:相同的 API 接口,无缝切换
  • 字段索引:支持按字段建立索引,快速搜索
  • 🔒 事务支持:完整的提交/回滚机制,保证数据一致性
  • 📖 人类可读:JSON 格式存储,调试和手动编辑极其方便
  • 📦 轻量级:适用于小型项目、原型开发、游戏存档

API 文档

JsonDB 类

构造函数

const db = new JsonDB({
  dir: './data/',      // 数据存储目录,默认 './db/'
  database: 'mm',      // 数据库名,对应目录名
  debug: false         // 是否开启调试日志
});

配置参数

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | dir | String | './db/' | 数据存储根目录 | | database | String | 'mm' | 数据库名称 | | debug | Boolean | false | 调试日志开关 |

主要方法

open()

打开数据库(创建存储目录)

  • 返回:Promise<boolean>
close()

关闭数据库

  • 返回:Promise<boolean>
table(name, key)

获取表管理器

  • name {String} 表名
  • key {String} 主键字段名,默认自动推断
  • 返回:DB 表管理器实例
db()

获取数据库管理器

  • 返回:DB 数据库管理器实例
run(descriptor, params)

执行查询操作

  • descriptor {Object} 查询描述符
  • 返回:Promise<Array>
exec(descriptor, params)

执行写入操作

  • descriptor {Object} 操作描述符
  • 返回:Promise<number>
read(table, condition, options)

读取表数据

  • table {String} 表名
  • condition {Object} 查询条件
  • options {Object} 选项(orderBypagesize
  • 返回:Promise<Array>
transaction(callback)

执行事务

  • callback {Function} 事务回调函数
  • 返回:Promise<any>
healthCheck()

健康检查

  • 返回:Promise<Object> 状态信息

DB 类(表管理器)

增删改查

const db = jsonDB.table('users', 'id');

// 添加
await db.add({ name: '张三', level: 10 });
await db.addList([{ name: '李四' }, { name: '王五' }]);

// 查询
await db.get();                              // 查询全部
await db.get({ name: '张三' });               // 精确查询
await db.get({ name_like: '张' });            // 模糊查询
await db.get({ name_like: '张' }, null, null, true);  // 显式模糊
await db.get({ level_min: 10, level_max: 20 });       // 范围查询
await db.get({ name_not: '张三' });                     // 排除查询
await db.get({}, 'level DESC');                         // 排序
await db.getObj({ name: '张三' });                      // 获取单条
await db.count();                             // 统计总数
await db.count({ level_min: 10 });            // 条件统计

// 修改
await db.set({ name: '张三' }, { level: 11 });
await db.set({ name: '张三' }, { gold_add: 500 });  // 数值增加
await db.set({ name: '张三' }, { hp_del: 100 });    // 数值减少

// 删除
await db.del({ name: '张三' });
await db.del({ name_like: '测试' });

操作符说明

| 后缀 | 示例 | 含义 | |------|------|------| | _min | level_min: 10 | >= | | _max | level_max: 20 | <= | | _not | name_not: '张三' | != | | _like | name_like: '张' | 模糊匹配 | | _has | tags_has: 'a,b' | 包含任一值 | | _add | gold_add: 100 | 数值增加 | | _del | hp_del: 50 | 数值减少 |

分页查询

const db = jsonDB.table('users');
db.page = 1;   // 第1页
db.size = 20;  // 每页20条
const list = await db.get();
const total = await db.count();

表管理

const db = jsonDB.db();

// 创建表
await db.addTable('users', 'id', 'int', true, '用户表');

// 添加字段
await db.addField('phone', 'VARCHAR(20)', '', false, false, '电话');

// 修改字段
await db.setField('phone', 'VARCHAR(30)', '', false, false);

// 删除字段
await db.delField('users', 'phone');

// 重命名字段
await db.renameField('users', 'phone', 'mobile', 'VARCHAR(20)');

// 获取所有表
const tables = await db.tables();

// 获取所有字段
const fields = await db.fields('users');

// 检查表/字段是否存在
await db.hasTable('users');
await db.hasField('users', 'phone');

// 清空表
await db.emptyTable('users');

// 删除表
await db.dropTable('users');

// 备份表
await db.backupTable('users', 'users_backup');

// 获取建表语句
const sql = await db.getCreateTable('users');

事务

const db = jsonDB.table('users');

// 事务提交
await jsonDB.transaction(async () => {
  await db.set({ name: '张三' }, { gold_del: 1000 });
  await db.add({ name: '李四', gold: 1000 });
});

// 事务回滚(出错自动回滚)
try {
  await jsonDB.transaction(async () => {
    await db.set({ name: '张三' }, { gold_del: 99999 });
    if (gold < 0) throw new Error('金币不足');
  });
} catch {
  // 数据已自动回滚
}

索引

const store = jsonDB.getStore();
const indexMgr = store.getIndexManager();

// 建立索引
const meta = await store.readMeta('items');
meta.indexes.push('rarity');
await store.writeMeta('items', meta);
await indexMgr.ensureIndex('items', 'rarity');

// 构建索引
const rows = await store.readAllRows('items');
for (const row of rows) {
  await indexMgr.addToIndex('items', row.id, row);
}

// 通过索引快速查询
const ids = await indexMgr.queryByIndex('items', 'rarity', '传说');

游戏开发场景

适用场景

| 场景 | 说明 | |------|------| | 单机 RPG 存档 | 角色数据、背包、任务进度、地图状态 | | 游戏配置管理 | 道具定义、技能树、关卡数据、NPC 对话 | | Electron 桌面游戏 | 本地数据持久化,无需额外安装数据库 | | 网页小游戏 | 不需服务器,纯前端存储 | | 回合制游戏 | 存档/读档,战棋状态保存 | | 成就系统 | 成就进度、解锁记录持久化 | | MOD 工具 | 玩家可手动编辑 JSON 文件修改存档 | | 快速原型 | 开发阶段无需搭建数据库,直接读写文件 |

游戏示例:RPG 角色系统

const { JsonDB } = require('mm_json');

async function initGameDB() {
  const db = new JsonDB({ dir: './save/', database: 'rpg_save' });
  await db.open();

  // 创建表
  const mgr = db.db();
  await mgr.addTable('characters', 'id', 'int', true, '角色表');
  await mgr.addTable('inventory', 'id', 'int', true, '背包表');
  await mgr.addTable('items', 'id', 'int', true, '道具表');
  await mgr.addTable('quests', 'id', 'int', true, '任务表');

  // 添加字段
  const charDb = db.table('characters');
  await charDb.addField('name', 'VARCHAR(50)', '', true);
  await charDb.addField('level', 'INT', '1', true);
  await charDb.addField('gold', 'INT', '0', true);
  await charDb.addField('class', 'VARCHAR(20)', '', true);
  await charDb.addField('hp', 'INT', '100', true);
  await charDb.addField('mp', 'INT', '50', true);

  return db;
}

// 创建角色
async function createCharacter(db, name, className) {
  const charDb = db.table('characters');
  const stats = {
    '战士': { hp: 850, mp: 200 },
    '法师': { hp: 400, mp: 950 },
    '弓箭手': { hp: 550, mp: 350 }
  };
  const s = stats[className] || { hp: 500, mp: 300 };
  return await charDb.add({
    name, level: 1, gold: 100, class: className,
    hp: s.hp, mp: s.mp
  });
}

// 获取背包物品详情(跨表关联)
async function getInventory(db, characterId) {
  const invDb = db.table('inventory');
  const itemDb = db.table('items');
  const slots = await invDb.get({ character_id: characterId });
  const detail = [];
  for (const slot of slots) {
    const item = await itemDb.getObj({ id: slot.item_id });
    detail.push({ ...item, quantity: slot.quantity, equipped: slot.equipped });
  }
  return detail;
}

// 购买道具(事务)
async function buyItem(db, characterId, itemId, quantity) {
  const charDb = db.table('characters');
  const itemDb = db.table('items');
  const invDb = db.table('inventory');

  return await db.transaction(async () => {
    const char = await charDb.getObj({ id: characterId });
    const item = await itemDb.getObj({ id: itemId });
    const totalPrice = item.price * quantity;

    if (char.gold < totalPrice) {
      throw new Error('金币不足!');
    }

    await charDb.set({ id: characterId }, { gold_del: totalPrice });
    await invDb.add({
      character_id: characterId,
      item_id: itemId,
      quantity,
      equipped: 0
    });
    return true;
  });
}

与 mm_mysql 的对比

| 特性 | mm_mysql | mm_json | |------|----------|---------| | 依赖 | MySQL 服务 | 无 | | 存储格式 | 数据库表 | JSON 文件 | | 查询语言 | SQL | 描述符对象 | | 安装部署 | 需安装 MySQL | 零配置 | | 性能 | 高并发优秀 | 小规模优秀 | | 人类可读 | 否 | 是(直接看 JSON) | | 适用场景 | 生产环境 | 原型/小项目/游戏 | | API 兼容 | ✅ | ✅(完全兼容) |

开发

# 安装依赖
npm install

# 运行测试
npm test

# 运行 RPG 游戏示例测试
node rpg_test.js

License

ISC