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

@ostore/db

v2.0.0

Published

基于文件系统的轻量级 NoSQL 数据库【Lightweight file-based NoSQL database】

Downloads

31

Readme

@ostore/db

基于文件系统的轻量级 NoSQL 数据库【Lightweight file-based NoSQL database】

特性【Features】

  • 🚀 零配置,开箱即用【Zero configuration】
  • 💾 JSON 文件存储【JSON file storage】
  • 🔍 支持函数查询【Function-based queries】
  • 📝 软删除机制【Soft delete】
  • 🔒 自动备份恢复【Auto backup】
  • ⚡️ 批量操作并发优化【Concurrent batch operations】
  • 📦 完整 TypeScript 支持【Full TypeScript support】

安装【Installation】

npm install @ostore/db

快速开始【Quick Start】

import DB from '@ostore/db';

const db = new DB({ model: 'users' });

// 创建【Create】
await db.create({ name: 'Alice', age: 25 });

// 查询【Query】
const result = await db.findMany({ age: (v) => v >= 18 });
console.log(result.data); // [{ name: 'Alice', age: 25, _$id: ... }]

API 文档【API Documentation】

初始化【Constructor】

new DB(config: IDBConfig)

| 参数【Parameter】 | 类型【Type】 | 必填【Required】 | 说明【Description】 | |---------|------|------|------| | model | string | ✅ | 模型名称【Model name】 | | base | string | - | 数据根目录(默认:process.cwd())【Root directory】 |

const db = new DB({ 
  model: 'users',
  base: '/path/to/data'
});

create()

创建文档【Create document】

create(data: object): Promise<IWriteDatabaseResult>
const result = await db.create({ 
  name: 'Bob', 
  age: 30 
});
// { code: 200, doc: { _$id, _$status, content } }

findOne()

查询单个文档【Find one document】

findOne(query: object, options?: IFindOptions): Promise<IFindResult>

参数【Parameters】:

  • query - 查询条件【Query conditions】
  • options.skip - 跳过数量【Skip count】(默认:0)
  • options.limit - 限制数量【Limit】(默认:10000)
  • options.sort - 排序【Sort】(1: 升序【asc】, -1: 降序【desc】)
// 精确查询【Exact match】
await db.findOne({ name: 'Alice' });

// 按 _$id 查询【Query by _$id】
await db.findOne({ _$id: 123 });

// 函数查询【Function query】
await db.findOne({ age: (v) => v >= 18 });

findMany()

查询所有匹配文档【Find all documents】

findMany(query: object, options?: IFindOptions): Promise<IFindResult>
// 查询所有【Find all】
await db.findMany({});

// 条件查询【Conditional query】
await db.findMany({ age: (v) => v > 20 });

// 分页查询【Pagination】
await db.findMany(
  { status: 'active' },
  { skip: 10, limit: 10, sort: -1 }
);

updateOne()

更新单个文档【Update one document】

updateOne(target: object, source?: object): Promise<IUpdateResult>

参数【Parameters】:

  • target - 更新的数据【Update data】
  • source - 查询条件(可选)【Query condition (optional)】

⚠️ 重要【Important】:source 为空时,target 必须包含 _$id【When source is empty, target must include _$id】

// 用法 1:使用 _$id【Usage 1: With _$id】
await db.updateOne({ 
  _$id: 123, 
  age: 26 
});

// 用法 2:明确 source【Usage 2: Explicit source】
await db.updateOne(
  { age: 26, email: '[email protected]' },  // 更新数据【Update data】
  { name: 'Alice' }                     // 查询条件【Query condition】
);

// 用法 3:按 _$id 查询【Usage 3: Query by _$id】
await db.updateOne(
  { name: 'NewName' },
  { _$id: 123 }
);

❌ 错误用法【Invalid usage】:

// 缺少 _$id 会报错【Missing _$id will cause error】
await db.updateOne({ name: 'Alice', age: 99 });
// Error: updateOne requires _$id in target when source is not provided

updateMany()

批量更新文档【Update multiple documents】

updateMany(target: object, source?: object): Promise<IUpdateResult>

✨ 智能过滤【Smart filtering】: 只移除值相同的查询字段【Only removes query fields with same value】

// 批量更新【Batch update】
await db.updateMany(
  { status: 'active' },
  { age: (v) => v >= 18 }
);

// ✅ 支持更新查询字段本身【Support updating query field itself】
await db.updateMany(
  { name: 'NewName', age: 30 },
  { name: 'OldName' }
);
// name 会被更新为 'NewName'【name will be updated to 'NewName'】

removeOne()

删除单个文档(软删除)【Remove one document (soft delete)】

removeOne(query: object, options?: IFindOptions): Promise<IUpdateResult>
await db.removeOne({ _$id: 123 });
await db.removeOne({ name: 'Alice' });

removeMany()

批量删除文档(软删除)【Remove multiple documents (soft delete)】

removeMany(query: object): Promise<IUpdateResult>
await db.removeMany({ status: 'inactive' });
await db.removeMany({ age: (v) => v < 18 });

高级用法【Advanced Usage】

函数查询【Function Queries】

// 范围查询【Range query】
await db.findMany({ 
  age: (val) => val >= 18 && val <= 65 
});

// 模糊匹配【Fuzzy match】
await db.findMany({ 
  name: (val) => val.includes('Alice') 
});

// 多条件【Multiple conditions】
await db.findMany({
  age: (val) => val > 20,
  status: 'active',
  email: (val) => val.endsWith('@example.com')
});

分页和排序【Pagination & Sorting】

// 获取第 2 页,每页 10 条【Get page 2, 10 per page】
const page2 = await db.findMany(
  {},
  { skip: 10, limit: 10, sort: -1 }
);

// 按 _$id 升序【Sort by _$id ascending】
const sorted = await db.findMany({}, { sort: 1 });

批量操作【Batch Operations】

// ⚡️ 并发执行,性能优化【Concurrent execution, optimized】
await db.updateMany(
  { verified: true },
  { status: 'active' }
);

await db.removeMany({ 
  createdAt: (val) => val < Date.now() - 30 * 86400000 
});

Koa 集成示例【Koa Integration】

import Koa from 'koa';
import Router from '@koa/router';
import DB from '@ostore/db';

const app = new Koa();
const router = new Router();
const db = new DB({ model: 'users' });

// 错误处理【Error handling】
app.use(async (ctx, next) => {
  try {
    await next();
  } catch (err) {
    ctx.status = 500;
    ctx.body = { error: err.message };
  }
});

// 创建【Create】
router.post('/users', async (ctx) => {
  const result = await db.create(ctx.request.body);
  ctx.body = result;
});

// 查询【Query】
router.get('/users', async (ctx) => {
  const { name } = ctx.query;
  const result = await db.findMany({ name });
  ctx.body = result;
});

// 更新【Update】
router.put('/users/:id', async (ctx) => {
  const result = await db.updateOne(
    ctx.request.body,
    { _$id: +ctx.params.id }
  );
  ctx.body = result;
});

// 删除【Delete】
router.delete('/users/:id', async (ctx) => {
  const result = await db.removeOne({ _$id: +ctx.params.id });
  ctx.body = result;
});

app.use(router.routes());
app.listen(3000);

数据结构【Data Structure】

存储格式【Storage Format】

{
  "_$id": 1766848000000000,
  "_$status": 1,
  "content": {
    "name": "Alice",
    "age": 25,
    "email": "[email protected]"
  }
}

| 字段【Field】 | 说明【Description】 | |-------|------| | _$id | 唯一标识(微秒级时间戳)【Unique ID (microsecond timestamp)】 | | _$status | 状态(1=正常,0=已删除)【Status (1=active, 0=deleted)】 | | content | 实际数据【Actual data】 |

文件存储【File Storage】

project/
└── data/
    └── users/
        ├── 1766848000000000.json
        └── 1766848000000001.json

性能特性【Performance】

| 特性【Feature】 | 说明【Description】 | |---------|------| | 批量操作并发 | 使用 Promise.allSettled 并发执行【Concurrent with Promise.allSettled】 | | 单次排序 | 避免重复排序,性能提升 50%【Avoid duplicate sorting, 50% faster】 | | 自动备份 | 更新时自动创建备份,失败时恢复【Auto backup on update, restore on failure】 | | 软删除 | 标记删除,不删除文件【Mark as deleted, keep files】 |

性能数据【Performance Metrics】

  • 批量更新 100 个文档:~300ms(优化前 ~3s)【Batch update 100 docs: ~300ms (was ~3s)】
  • 单个文档查询:< 10ms【Single doc query: < 10ms】
  • 分页查询 1000 条:~50ms【Paginated query 1000 docs: ~50ms】

类型定义【Type Definitions】

interface IDBConfig {
  base?: string;
  model: string;
}

interface IFindOptions {
  skip?: number;
  limit?: number;
  sort?: number;  // 1: 升序【asc】, -1: 降序【desc】
}

interface IFindResult {
  code: 200 | 500;
  data?: any[];
  count: number;
  error?: any;
}

interface IUpdateResult {
  code: 200 | 500;
  status?: boolean;
  errlist?: any[];
  doc?: any;
  error?: any;
}

注意事项【Important Notes】

1. 线程安全【Thread Safety】

不支持多进程并发写入【Not thread-safe, single process recommended】

2. 数据规模【Data Scale】

适用于中小型数据集(< 10000 条)【Suitable for small to medium datasets (< 10k docs)】

3. 软删除【Soft Delete】

删除操作仅标记 _$status=0,文件仍保留【Delete only marks _$status=0, files remain】

4. updateOne 限制【updateOne Restriction】

source 为空时,target 必须包含 _$id【When source is empty, target must include _$id】

5. 查询性能【Query Performance】

函数查询需遍历所有文档,大数据集时性能较低【Function queries iterate all docs, slow for large datasets】


最佳实践【Best Practices】

✅ 推荐【Recommended】

// 使用 _$id 更新【Update with _$id】
await db.updateOne({ _$id: 123, age: 26 });

// 明确查询条件【Explicit query condition】
await db.updateOne({ age: 26 }, { name: 'Alice' });

// 批量操作用函数查询【Function query for batch ops】
await db.updateMany({ status: 'active' }, { 
  age: (v) => v >= 18 
});

❌ 避免【Avoid】

// 不要:source 为空且无 _$id【Don't: empty source without _$id】
await db.updateOne({ name: 'Alice', age: 26 });

// 不要:在大数据集上使用复杂函数查询【Don't: complex function queries on large datasets】
await db.findMany({ 
  field: (v) => someExpensiveOperation(v) 
});

错误处理【Error Handling】

const result = await db.updateOne({ _$id: 123, age: 26 });

if (result.code === 200) {
  console.log('✅ 更新成功【Update success】');
} else {
  console.error('❌ 更新失败【Update failed】:', result.error);
}

示例项目【Example Project】

project/
├── src/
│   └── index.ts
├── data/              # 自动创建【Auto created】
│   └── users/
│       └── *.json
├── package.json
└── tsconfig.json
// package.json
{
  "dependencies": {
    "@ostore/db": "^1.0.0"
  },
  "scripts": {
    "start": "ts-node src/index.ts"
  }
}

License

MIT