local-fake-api
Version:
A simple async local mock API without backend.
63 lines (62 loc) • 2.08 kB
JavaScript
import Dexie from "dexie";
/**
* IndexedDB 封装,支持动态创建表
* 支持任意主键,不仅限于 "id"
*/
export class IndexedDbWrapper extends Dexie {
constructor() {
super("localFakeApiDB");
// 缓存已创建的 Table 实例
this._dynamicTables = {};
// 已存在的表名集合
this._tableNames = new Set();
// 记录每个表的主键字段
this._primaryKeys = {};
this.version(1).stores({}); // 初始空 schema
}
/** 确保数据库已打开 */
async ensureOpen() {
if (!this.isOpen()) {
await this.open();
}
}
/**
* 获取表实例,如果表不存在则动态创建
* @param tableName 表名
* @param primaryKey 主键字段(仅第一次创建表时使用)
*/
async getTable(tableName, primaryKey) {
// 表已存在,直接返回缓存实例
if (this._dynamicTables[tableName]) {
await this.ensureOpen();
return this._dynamicTables[tableName];
}
// 表第一次创建
const pk = primaryKey ? String(primaryKey) : "id"; // 默认主键 "id"
this._tableNames.add(tableName);
this._primaryKeys[tableName] = pk;
// 更新 Dexie schema,需要关闭已打开的数据库
if (this.isOpen())
await this.close();
const newVersion = this.verno + 1;
const schema = {};
this._tableNames.forEach((name) => (schema[name] = this._primaryKeys[name]));
this.version(newVersion).stores(schema);
await this.open();
const tableInstance = this.table(tableName);
this._dynamicTables[tableName] = tableInstance;
return tableInstance;
}
/**
* 获取表的主键字段
* @param tableName 表名
*/
getPrimaryKey(tableName) {
const pk = this._primaryKeys[tableName];
if (!pk)
throw new Error(`表 "${tableName}" 不存在`);
return pk;
}
}
// 单例导出
export const db = new IndexedDbWrapper();