@wyfe/h5-idb-sdk
v1.0.4
Published
IndexedDB 通用数据管理 SDK — 基于 Dexie 的两层架构(IndexedDBManager / StoreManager)
Readme
WyFE H5 IDB SDK
IndexedDB 通用数据管理 SDK — 基于 Dexie 的两层架构(IndexedDBManager / StoreManager)
简介
面向 IndexedDB 的通用数据管理框架,不涉及任何业务逻辑,提供开箱即用的多表管理、读写兜底与回滚机制。
特性一览
| 特性 | 说明 | |------|------| | 多表管理 | 延迟创建 StoreManager | | 读写兜底 | 内存缓存 + cache-only 降级模式 | | 写回滚 | 事务级(Dexie 事务)+ 数据级备份恢复(enableBackup) | | 跨标签页缓存同步 | BroadcastChannel 降级 storage 事件 | | 可用性降级 | 隐私模式 / 旧浏览器自动降级为内存模式 | | 自动重试 | 指数退避,瞬态错误重试 / 非瞬态错误直抛 | | 数据校验钩子 | put / bulkPut / upsert 前校验 | | 大表游标遍历 | each / eachBy,不全量加载到内存 | | 类型安全事件系统 | EventEmitter,解耦 window.dispatchEvent | | 结构化错误 | IndexedDBError + ErrorCode 枚举 | | Per-store 配置覆盖 | 不同表可独立配置 | | 数据导出 / 导入 | JSON 格式备份与恢复 | | 存储配额检测 | navigator.storage.estimate 封装 |
安装
pnpm add @wyfe/h5-idb-sdk前置依赖:需安装
dexie@^4.0.0作为 peer dependency。
快速开始
import { IndexedDBManager, ErrorCode } from '@wyfe/h5-idb-sdk'
const db = new IndexedDBManager({
name: 'app-db',
stores: { cities: '++id, &code, name' },
globalStoreOptions: { enableCache: true, enableBackup: true },
storeOptions: {
cities: { validator: (r) => r.code && r.name ? true : 'code 和 name 必填' }
},
logLevel: 'warn'
})
await db.open()
const cities = db.getStore<CityRecord>('cities')
await cities.put({ code: '001', name: '北京' })
// 批量写入
await cities.bulkPut(fetchedData)
// 事件监听
db.on('error', ({ error }) => {
if (error.code === ErrorCode.QUOTA_EXCEEDED) console.warn('存储空间不足')
})商业场景
| 场景 | 核心 API | 说明 |
|------|----------|------|
| 大表游标遍历 | each / eachBy | 逐条回调处理,不全量加载到内存 |
| 数据校验保护 | storeOptions.validator | Per-store 校验钩子,校验失败抛 VALIDATION_FAILED |
| 隐私模式降级 | 自动检测 | IndexedDB 不可用时进入 cache-only 模式,不抛异常 |
| 跨标签页缓存同步 | BroadcastChannel | 写入后自动通知其他标签页缓存失效 |
| 数据备份迁移 | exportData / importData | JSON 格式导出导入,支持 clearBefore |
| 存储配额监控 | getStorageEstimate | 返回 { usage, quota } 或 null |
| 事件驱动监控 | on('error' \| 'data:written' \| ...) | 5 种事件类型,统一错误处理与状态追踪 |
| Upsert | upsert / bulkUpsert | 按字段判断存在性,存在则更新、不存在则插入 |
API 参考
IndexedDBManager
数据库管理器,继承自 EventEmitter<DBEventMap>。
构造参数(DatabaseConfig):
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| name | string | — | 数据库名称 |
| stores | Record<string, string> | — | 表定义,如 { cities: '++id, &code, name' } |
| globalStoreOptions | StoreOptions | — | 全局 Store 默认配置 |
| storeOptions | Record<string, StoreOptions> | — | Per-store 配置覆盖 |
| logLevel | LogLevel | 'warn' | 日志级别 |
方法:
| 方法 | 说明 |
|------|------|
| open() / close() / destroy() | 生命周期管理 |
| getStore<T>(name) | 获取 StoreManager(延迟创建) |
| hasStore(name) / getStoreNames() | Store 查询 |
| transaction(mode, storeNames, fn) | 跨表事务 |
| exportData(storeNames?) / importData(data, options?) | 数据导出导入 |
| clearStores(storeNames?) | 清空表 |
| getStorageEstimate() | 存储配额估算 |
| on(event, handler) | 订阅事件,返回取消订阅函数 () => void |
| off(event, handler) | 取消事件订阅 |
事件:
| 事件 | 载荷 |
|------|------|
| store:registered | { storeName } |
| data:written | { storeName, action, count } |
| error | { error: IndexedDBError, context } |
| connection | { state: 'open' \| 'closed' \| 'unavailable' } |
StoreManager<T>
单表管理器,由 getStore() 创建。
| 分类 | 方法 |
|------|------|
| 查询 | get(id) / getAll(options?) / getWhere(field, value) / getOne(field, value) / count() / filter(predicate, options?) / find(predicate) |
| 游标 | each(callback, options?) / eachBy(field, callback, options?) |
| 写入 | put(record) / bulkPut(records) / update(id, changes) / delete(id) / bulkDelete(ids) / clear() / replaceAll(records) / upsert(record, keyField) / bulkUpsert(records, keyField) |
| 事务 | transaction(mode, fn) |
写操作自动检测并复用当前事务,不产生嵌套事务。
StoreOptions
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| autoRetry | boolean | true | 写失败自动重试 |
| maxRetries | number | 3 | 最大重试次数 |
| retryDelay | number | 100 | 重试初始延迟(ms),指数退避 |
| enableCache | boolean | false | 启用内存读缓存 |
| enableBackup | boolean | false | 破坏性操作前自动备份 |
| backupThreshold | number | 10000 | 备份阈值,超过则跳过 |
| validator | (record) => boolean \| string | — | 数据校验钩子 |
ErrorCode
DB_NOT_OPEN / DB_ALREADY_OPEN / STORE_NOT_FOUND / STORE_ALREADY_EXISTS / TRANSACTION_FAILED / TRANSACTION_ABORTED / VALIDATION_FAILED / QUOTA_EXCEEDED / INDEXEDDB_UNAVAILABLE / INTERNAL_ERROR
EventEmitter
泛型事件发射器,IndexedDBManager 的基础类,也可独立使用。
| 方法 | 说明 |
|------|------|
| on(event, handler) | 订阅事件,返回取消订阅函数 |
| off(event, handler) | 取消订阅 |
| emit(event, payload) | 触发事件 |
| removeAllListeners(event?) | 移除监听器(不传则全部移除) |
工具函数
可直接从 @wyfe/h5-idb-sdk 导入使用:
| 函数 | 说明 |
|------|------|
| withRetry(fn, options) | 指数退避重试执行器 |
| sleep(ms) | Promise 延迟 |
| deepClone(obj) | 深拷贝(优先 structuredClone) |
| isRetryableError(error) | 判断错误是否可重试 |
| isIndexedDBAvailable() | 检测 IndexedDB 可用性 |
| createCrossTabChannel(name) | 跨标签页通信通道 |
| createLogger(level?) | 创建 [IDB] 前缀日志工具 |
导出类型
BaseRecord / StoreOptions / DatabaseConfig / TransactionMode / QueryOptions / DBConnectionState / DBEventMap / ExportData / LogLevel / Logger / CrossTabChannel
核心机制
读写兜底与回滚
- 读兜底:
enableCache内存缓存 + cache-only 降级 + 跨标签页同步 - 写回滚:事务级(Dexie 事务)+ 数据级(enableBackup 备份恢复)
自动重试
autoRetry: true 时对瞬态错误(AbortError、TransactionInactiveError)指数退避重试;非瞬态错误(QuotaExceeded、Validation、ConstraintError)不重试。
源码结构
src/
├── core/ # 核心管理器
│ ├── database.ts # IndexedDBManager — 数据库生命周期、多表、跨表事务
│ └── storeManager.ts # StoreManager<T> — 单表 CRUD、备份恢复、缓存同步
├── types/
│ └── index.ts # 所有类型定义
├── errors/
│ └── index.ts # ErrorCode 枚举 + IndexedDBError 类
├── utils/ # 工具与基础设施
│ ├── constants.ts # 常量(默认配置)
│ ├── logger.ts # createLogger 工厂函数
│ ├── eventEmitter.ts # 泛型 EventEmitter
│ └── helpers.ts # withRetry / sleep / 跨标签页通道
└── index.ts # 公共 API 导出构建
pnpm run build # ESM + CJS + DTS
pnpm run dev # 监听模式
pnpm run typecheck # 类型检查浏览器兼容性
Chrome 51+ / Firefox 55+ / Safari 10.1+ / Edge 79+
许可证
MIT
