release: v0.6.0 — 完全移除 IndexedDB,自研 KVStore 事务存储引擎(多key原子写/快照日志恢复/CRC自愈)+ KVStoreEngine + 旧库迁移工具 + 10万级压力验证 + 崩溃注入e2e
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# MetonaSqlark
|
||||
|
||||
<p align="center">
|
||||
<img src="https://img.shields.io/badge/version-0.5.1-blue?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/version-0.6.0-blue?style=flat-square" alt="version">
|
||||
<img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="license">
|
||||
<img src="https://img.shields.io/badge/coverage-87.3%25-brightgreen?style=flat-square" alt="coverage">
|
||||
<img src="https://img.shields.io/badge/tests-1009%20passed-success?style=flat-square" alt="tests">
|
||||
<img src="https://img.shields.io/badge/coverage-89.1%25-brightgreen?style=flat-square" alt="coverage">
|
||||
<img src="https://img.shields.io/badge/tests-1021%20passed-success?style=flat-square" alt="tests">
|
||||
</p>
|
||||
|
||||
> 基于 TypeScript 的**前端关系型数据库**,支持完整 SQL 查询、Query Builder 链式 API、与 **AriaEngine 自研存储引擎**。
|
||||
@@ -19,7 +19,9 @@
|
||||
- 🔐 **多标签页独占锁** — Web Locks API,第二个标签页打开同一库抛 `ARIA_LOCKED`(v0.5.0)
|
||||
- 🛠 **维护语句 SQL 入口** — `EXPLAIN`/`ANALYZE`/`REINDEX`/`VACUUM`/`SAVEPOINT` 原生 SQL 支持(v0.5.1 补齐)
|
||||
- 🛡 **输入校验全覆盖** — `maxLength`/`min`/`max` 约束、类型检查、必填验证
|
||||
- 💾 **多引擎架构** — Memory / IndexedDB / OPFS / Hybrid(write-through) / Aria 五种模式
|
||||
- 💾 **多引擎架构** — Memory / **KVStore**(自研 KV 引擎)/ OPFS / Hybrid(write-through) / Aria 五种模式(v0.6.0: IndexedDB 完全移除)
|
||||
- 💾 **KVStore 自研 KV 引擎** — 日志结构化事务存储:多 key 原子写(putMany/deleteMany 单记录原子追加)、快照 checkpoint、崩溃两阶段恢复、CRC-32 自愈;替代 IndexedDB(v0.6.0)
|
||||
- 🔄 **旧库一键迁移** — `migrateFromIndexedDB()` 把旧 IndexedDB 数据(schema/索引/行)导入新引擎(v0.6.0)
|
||||
- 📝 **完整 SQL 支持** — SELECT/JOIN/子查询/GROUP BY/HAVING/ORDER BY/LIMIT/BETWEEN/IF NOT EXISTS/ALTER TABLE/TRUNCATE TABLE/UNION/INSERT...SELECT/事务语句/CREATE INDEX/EXISTS(v0.3.0)+ CASE WHEN/哈希连接/组提交(v0.3.1)+ 多标签页同步(v0.3.2)
|
||||
- 🚰 **流式查询** — `queryStream`/`stream()` 逐行回调,Aria LSM 惰性扫描不物化结果集(v0.4.0)
|
||||
- 🧩 **派生表** — `FROM (SELECT ...)` 子查询作为行源,多列 ON 哈希连接,COUNT(DISTINCT),NULLS FIRST/LAST(v0.4.0)
|
||||
@@ -32,7 +34,7 @@
|
||||
- 🌲 **RB-Tree 完整实现** — 标准红黑树插入+删除修复,O(log n) 保证
|
||||
- ⚡ **性能优化** — SSTableReader 二分查找统一、IndexedDB 索引利用、crypto 实例化避免全局状态
|
||||
- 🌐 **浏览器兼容** — Chrome 80+ / Firefox 80+ / Safari 14+ / Edge 80+ / Node.js 16+
|
||||
- 🧪 **1009 测试 · 87.3% 覆盖率** — 62 套件 + 7 个 Playwright 真实 Chromium e2e,生产级质量保证
|
||||
- 🧪 **1021 测试 · 89.1% 覆盖率** — 64 套件 + 9 个 Playwright 真实 Chromium e2e(含崩溃注入),生产级质量保证
|
||||
|
||||
---
|
||||
|
||||
@@ -276,6 +278,30 @@ await db2.disconnect(); // 引用计数 -1
|
||||
|
||||
> 不支持的引擎执行维护语句抛 `NOT_SUPPORTED`。
|
||||
|
||||
### 旧库迁移(v0.6.0)
|
||||
|
||||
> IndexedDB 已从引擎中完全移除。使用旧版本(v0.5.x 及更早)的用户,可通过
|
||||
> 一次性迁移工具把磁盘模式(IndexedDBEngine)旧库导入新引擎(KVStore)。
|
||||
|
||||
```typescript
|
||||
import { migrateFromIndexedDB } from '@metona-team/metona-sqlark/migration';
|
||||
|
||||
// 目标库(新引擎,disk 模式)
|
||||
const target = await MetonaSqlark.create({ name: 'my-app-new', mode: 'disk' });
|
||||
|
||||
// 从旧 IndexedDB 库导入(旧库名 'my-app',旧引擎 disk 模式)
|
||||
const result = await migrateFromIndexedDB({
|
||||
dbName: 'my-app',
|
||||
engine: 'disk', // 仅支持 disk 模式(IndexedDBEngine)
|
||||
target,
|
||||
onProgress: (done, total, table) => console.log(`迁移 ${done}/${total}: ${table}`),
|
||||
});
|
||||
// result: { migratedTables, rowCount, skippedTables }
|
||||
```
|
||||
|
||||
> 注:aria 模式旧库(IndexedDBBackend)数据为引擎私有格式(SSTable/WAL),
|
||||
> 无法按行迁移——此类用户请从应用层导出(exportAll)后重新导入。
|
||||
|
||||
### 连接池(v0.1.13)
|
||||
|
||||
| 静态方法 | 说明 |
|
||||
@@ -301,18 +327,19 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
|
||||
|
||||
## 📊 存储模式对比
|
||||
|
||||
| 特性 | Memory | Disk (IndexedDB) | Disk (OPFS) | Hybrid | Aria |
|
||||
|------|--------|------------------|-------------|--------|------|
|
||||
| **持久化** | ❌ 重启丢失 | ✅ IndexedDB | ✅ OPFS(schema 持久化) | ✅ 内存+磁盘 | ✅ 后端决定 |
|
||||
| **事务回滚** | ✅ 快照 | ✅ 原子flush | ✅ 快照 | ✅ 双引擎 | ✅ MVCC |
|
||||
| **二级索引** | ✅ Hash | ✅ Hash | ✅ Hash(重启恢复) | ✅ Hash | ✅ LSM(重启恢复) |
|
||||
| **查询性能** | ⚡ O(1) PK | 🟡 O(1) PK | 🟡 O(1) PK | ⚡ O(1) PK | ⚡ O(log n) |
|
||||
| **数据上限** | 内存限制 | ~2GB(IDB限制) | ~磁盘可用(页面化后大表可行) | ~2GB(IDB) | 内存限制 |
|
||||
| **浏览器** | 全部 | 全部 | Chrome/Edge 102+ / Firefox 111+ / Safari 15.2+ | 全部 | 全部 |
|
||||
| **多标签页** | — | ✅ versionchange | ❌ 无保护 | ❌ 无保护 | ✅ Web Locks 独占锁(v0.5.0) |
|
||||
| 特性 | Memory | Disk (KVStore) | Disk (OPFS) | Hybrid | Aria |
|
||||
|------|--------|----------------|-------------|--------|------|
|
||||
| **持久化** | ❌ 重启丢失 | ✅ KVStore(OPFS) | ✅ OPFS(schema 持久化) | ✅ 内存+磁盘 | ✅ 后端决定 |
|
||||
| **事务回滚** | ✅ 快照 | ✅ 原子日志 flush | ✅ 快照 | ✅ 双引擎 | ✅ MVCC |
|
||||
| **多 key 原子写** | — | ✅ 单日志记录原子(v0.6.0) | — | ✅ 委托磁盘 | ✅ WAL 单文件原子 |
|
||||
| **二级索引** | ✅ Hash | ✅ Hash(重启恢复) | ✅ Hash(重启恢复) | ✅ Hash | ✅ LSM(重启恢复) |
|
||||
| **查询性能** | ⚡ O(1) PK | ⚡ O(1) PK(内存热路径) | 🟡 O(1) PK | ⚡ O(1) PK | ⚡ O(log n) |
|
||||
| **数据上限** | 内存限制 | 磁盘可用(行级存储,大表可行) | ~磁盘可用(整表 JSON,≤1000 行) | 磁盘可用 | 内存限制 |
|
||||
| **浏览器** | 全部 | Chrome/Edge 102+ / Firefox 111+ / Safari 15.2+ | 同上 | 同上 | 同上 |
|
||||
| **多标签页** | — | —(无事务锁,Hybrid 场景) | ❌ 无保护 | ❌ 无保护 | ✅ Web Locks 独占锁(v0.5.0) |
|
||||
| **全库加密** | — | — | — | — | ✅ AES-GCM(v0.5.0) |
|
||||
| **适用场景** | 缓存/测试 | 标准持久化 | Chromium+ 持久化 | 速度+持久化 | 大规模/分析 |
|
||||
| **测试覆盖** | 30+ | 30+ | 15+e2e | 15+ | 400+ |
|
||||
| **适用场景** | 缓存/测试 | 标准持久化(替代 IndexedDB) | 小数据集 | 速度+持久化 | 大规模/分析 |
|
||||
| **测试覆盖** | 30+ | 50+(含 10 万级压力) | 15 | 15+ | 400+ |
|
||||
|
||||
### Memory 模式
|
||||
- **环境**: 所有浏览器、Node.js
|
||||
@@ -320,11 +347,12 @@ const { data, loading, refresh } = useSqlarkQuery(db, 'SELECT * FROM users');
|
||||
- **能力**: 完整 CRUD、事务回滚、外键级联、二级索引、SQL 全支持
|
||||
- **适用**: 临时数据、单元测试、缓存层
|
||||
|
||||
### Disk (IndexedDB) 模式
|
||||
- **环境**: 所有现代浏览器(Chrome/Firefox/Safari/Edge)、Node.js(fake-indexeddb)
|
||||
- **限制**: 受浏览器 IndexedDB 配额限制(通常 ~2GB),多标签页需处理版本冲突
|
||||
- **能力**: 完整 CRUD、事务原子性(单 IDB 事务包裹)、外键级联、onversionchange 感知
|
||||
- **适用**: 标准前端数据库持久化场景
|
||||
### Disk (KVStore) 模式
|
||||
- **环境**: Chrome/Edge 102+ / Firefox 111+ / Safari 15.2+(OPFS)、Node.js(内存介质)
|
||||
- **限制**: 依赖 OPFS;多标签页并发写无锁保护(单标签页内可靠)
|
||||
- **能力**: 完整 CRUD、**多 key 原子事务**(单日志记录原子追加)、外键级联、事务内 DDL、
|
||||
二级索引(重启恢复)、schema/数据/索引完整持久化、10 万级数据量压力验证
|
||||
- **适用**: 标准前端数据库持久化(v0.6.0 替代 IndexedDB)
|
||||
|
||||
### Disk (OPFS) 模式
|
||||
- **环境**: Chrome 102+ / Edge 102+ / Firefox 111+ / Safari 15.2+(Origin Private File System)
|
||||
@@ -418,7 +446,7 @@ npm install # 安装依赖
|
||||
npm run dev # 开发模式(localhost:3001)
|
||||
npm run build # 生产构建(生成 dist/)
|
||||
npm test # 运行测试
|
||||
npm run test:e2e # Playwright e2e(真实 Chromium + OPFS,需先 build)
|
||||
npm run test:e2e # Playwright e2e(真实 Chromium + OPFS + 崩溃注入,需先 build)
|
||||
npm run lint # 代码检查
|
||||
npm run typecheck # 类型检查
|
||||
```
|
||||
@@ -429,21 +457,21 @@ npm run typecheck # 类型检查
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 测试用例 | 1009 |
|
||||
| 测试套件 | 62(+7 Playwright e2e) |
|
||||
| 行覆盖率 | 87.3% |
|
||||
| 测试用例 | 1021 |
|
||||
| 测试套件 | 64(+9 Playwright e2e) |
|
||||
| 行覆盖率 | 89.1% |
|
||||
| SQL 关键字 | 72 |
|
||||
| 存储引擎 | 5(Memory / IndexedDB / OPFS / Hybrid / **Aria**) |
|
||||
| 存储引擎 | 5(Memory / **KVStore** / OPFS / Hybrid / **Aria**) |
|
||||
|
||||
### 🌐 浏览器兼容性
|
||||
|
||||
| 浏览器 | 最低版本 | Memory | IndexedDB | OPFS | Web Locks | Aria |
|
||||
|--------|----------|--------|-----------|------|-----------|------|
|
||||
| Chrome | 80+ | ✅ | ✅ | ✅ (102+) | ✅ (69+) | ✅ |
|
||||
| Firefox | 80+ | ✅ | ✅ | ✅ (111+) | ✅ (96+) | ✅ |
|
||||
| Safari | 14+ | ✅ | ✅ | ✅ (15.2+) | ✅ (15.4+) | ✅ |
|
||||
| Edge | 80+ | ✅ | ✅ | ✅ (102+) | ✅ (79+) | ✅ |
|
||||
| Node.js | 16+ | ✅ | ✅ (fake-idb) | ❌ (测试用 mock) | ❌ | ✅ |
|
||||
| 浏览器 | 最低版本 | Memory | KVStore(OPFS) | OPFS | Web Locks | Aria |
|
||||
|--------|----------|--------|---------------|------|-----------|------|
|
||||
| Chrome | 102+ | ✅ | ✅ | ✅ | ✅ (69+) | ✅ |
|
||||
| Firefox | 111+ | ✅ | ✅ | ✅ | ✅ (96+) | ✅ |
|
||||
| Safari | 15.2+ | ✅ | ✅ | ✅ | ✅ (15.4+) | ✅ |
|
||||
| Edge | 102+ | ✅ | ✅ | ✅ | ✅ (79+) | ✅ |
|
||||
| Node.js | 16+ | ✅ | ✅ (内存介质) | ❌ (测试用 mock) | ❌ | ✅ |
|
||||
|
||||
> **OPFS 支持说明(v0.4.5 更新)**: Chromium(Chrome/Edge 102+)、Firefox 111+、Safari 15.2+
|
||||
> 均已支持基础 OPFS API(`createWritable` 原子写)。OPFS 无跨文件事务,
|
||||
|
||||
Reference in New Issue
Block a user