feat-ai(storage.js): 添加nodejs环境下的sqlite存储支持,调用方法与浏览器环境下保存一致
This commit is contained in:
@@ -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. SqliteStorage(Node.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 REPLACE,value 经 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.js:SqliteStorage → 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 自动化构建与发布
|
||||
Reference in New Issue
Block a user