feat-ai(storage.js): 添加nodejs环境下的sqlite存储支持,调用方法与浏览器环境下保存一致

This commit is contained in:
windychen0
2026-06-06 19:51:30 +08:00
parent 4f8be6293d
commit 3994bca0ab
7 changed files with 418 additions and 90 deletions
+123
View File
@@ -0,0 +1,123 @@
# Windychen Utils 项目开发记录
**日期**: 2026-06-06
**项目**: windychen-untils (v1.0.1)
**类型**: Storage 模块跨环境兼容改造
---
## 一、本次需求
`storage.js` 从**仅浏览器环境**扩展为**浏览器 + Node.js 双环境**可用,并在 Node.js 端使用 SQLite 持久化。
---
## 二、新增存储类
### 1. MemoryStorage(通用兜底)
| 方法 | 功能 | 后端 |
| ---------------------- | ------------ | ----- |
| `get(key, initValue?)` | 从内存获取值 | `Map` |
| `set(key, value)` | 写入内存 | `Map` |
- 纯内存,进程退出即丢失
- 所有环境通用,作为最低优先级兜底
### 2. SqliteStorageNode.js 专用)
| 方法 | 功能 | 后端 |
| ---------------------- | -------------- | ---------------- |
| `get(key, initValue?)` | 从 SQLite 查询 | `better-sqlite3` |
| `set(key, value)` | 写入 SQLite | `better-sqlite3` |
**实现细节:**
```javascript
// 表结构
CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT)
// set: INSERT OR REPLACEvalue 经 JSON.stringify
// get: SELECT value WHERE key = ?,结果经 JSON.parse
```
**优化点:**
- WAL 模式(`PRAGMA journal_mode = WAL`)提升并发读写性能
- 预编译语句(`db.prepare().get/run`)避免重复解析 SQL
- 延迟 require`_SqliteStorageClass` 工厂函数 + try-catch 包装,使 better-sqlite3 在浏览器/webpack 环境中静默降级为 null
---
## 三、环境自动选择策略(更新后)
```
浏览器:IndexedDB → localStorage → MemoryStorage
Node.jsSqliteStorage → MemoryStorage
```
**改动文件:**
| 文件 | 变更 |
| -------------- | ------------------------------------------------------------------ |
| `storage.js` | +MemoryStorage 类,+SqliteStorage 类,更新导出逻辑 |
| `index.js` | 移除 `try { require('./storage') } catch (e) {}`,改为直接 require |
| `test.js` | 新增 5 条 Storage 异步测试(对象/字符串/数字/数组/默认值) |
| `.gitignore` | 新增 `*.db` `*.db-wal` `*.db-shm` |
| `package.json` | 新增 `better-sqlite3` 依赖 |
---
## 四、演进过程
1. **第一版**`FileStorage`(每 key 一个 JSON 文件,`fs.promises` 读写)
2. **TS 报错**async 方法在 try-catch 块内部定义类导致解析异常 → 提取为 `_FileStorageClass` 工厂函数
3. **用户反馈**:改用 SQLite 而非 JSON 文件存储
4. **最终方案**`SqliteStorage`better-sqlite3 同步 API + WAL 模式
---
## 五、数据文件
```
.windychen-storage/
├── storage.db # 主数据库
├── storage.db-shm # WAL 共享内存
└── storage.db-wal # WAL 日志
```
---
## 六、测试结果
```
共 21 项,21 通过,0 失败
─── Object.getPro ─── (4 项)
─── Object.setPro ─── (2 项)
─── Array.findPro ─── (3 项)
─── Array.filterPro ─── (2 项)
─── Array.findIndexPro ─── (1 项)
─── Array.findLastPro ─── (1 项)
─── Array.somePro / everyPro ─── (3 项)
─── Storage ─── (5 项)
```
---
## 七、关键决策记录
1. **SQLite 选型**: 选择 better-sqlite3(原生编译、同步 API)而非 sql.js(纯 JS),优先性能
2. **降级策略**: Node.js → SqliteStorage → MemoryStorage,与浏览器端 IndexedDB → localStorage → MemoryStorage 保持一致的链式降级模式
3. **JSON 序列化**: 所有值通过 `JSON.stringify/parse` 统一存取,保证类型可靠性
4. **WAL 模式**: 启用 Write-Ahead Logging,避免写阻塞读
---
## 八、待改进方向
- [ ] Storage 模块添加 delete/clear 方法
- [ ] 添加单元测试框架(如 Jest/Vitest
- [ ] 支持 TypeScript 类型声明 (.d.ts)
- [ ] 考虑添加更多工具方法(日期、字符串、数字等)
- [ ] CI/CD 自动化构建与发布