UNPKG

@dtinsight/dt-utils

Version:

袋鼠云前端常用工具库

311 lines (310 loc) 13.4 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; /** * IndexedDB * * @deprecated * @category Storage * @description * 这个类为 IndexedDB 提供了一个包装器,IndexedDB 是一个用于客户端存储大量结构化数据(包括文件/二进制对象)的 API。 * 它允许你以结构化格式存储和检索数据,并使用各种方法查询和操作这些数据。 * * @Methods * | 方法名 | 描述 | 参数 | 返回值 | * |------|------|------|--------| * | `open` | 打开数据库连接 | — | `Promise<IDBDatabase>` | * | `add` | 添加一个新的键值对到对象存储中 | `key: IDBValidKey` <br> `value: any` | `Promise<void>` | * | `set` | 更新对象存储中已存在的键值对 | `key: IDBValidKey` <br> `value: any` | `Promise<void>` | * | `get` | 从对象存储中检索指定键的值 | `key: IDBValidKey` | `Promise<any>` | * | `delete` | 从对象存储中删除指定键对应的数据 | `key: IDBValidKey` | `Promise<void>` | * | `clear` | 清空对象存储中的所有数据 | — | `Promise<void>` | * * @example * ```typescript * import { IndexedDB } from 'dt-utils'; * * // 初始化数据库 * const db = new IndexedDB('userDB', 1, 'users'); * await db.open(); * * // 添加数据 * await db.add('user1', { name: 'John', age: 30 }); * * // 获取数据 * const user = await db.get('user1'); * * // 更新数据 * await db.set('user1', { name: 'John', age: 31 }); * * // 删除数据 * await db.delete('user1'); * * // 清空所有数据 * await db.clear(); * ``` * * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB | MDN IndexedDB 使用指南} * @see {@link https://caniuse.com/#feat=indexeddb | 浏览器兼容性} */ var IndexedDB = /** @class */ (function () { /** * 创建一个新的 IndexedDB 对象 * @param database 数据库名称 * @param version 数据库版本 * @param storeName 对象存储名称 * @param openLog 是否记录 IndexedDB 的变更日志 */ function IndexedDB(database, version, storeName, openLog) { if (openLog === void 0) { openLog = false; } if (!this.checkBrowserSupport()) { console.error("This browser doesn't support IndexedDB"); return; } this._storeName = storeName; this._version = version; this._database = database; this._openLog = openLog; } IndexedDB.prototype.checkBrowserSupport = function () { return 'indexedDB' in window; }; /** * @hidden * 打开在构造函数中指定的数据库。 * 此方法返回一个 Promise,解析为数据库实例。 */ IndexedDB.prototype.open = function () { return __awaiter(this, void 0, void 0, function () { var _a, error_1; return __generator(this, function (_b) { switch (_b.label) { case 0: if (this._db) { return [2 /*return*/, this._db]; } _b.label = 1; case 1: _b.trys.push([1, 3, , 4]); _a = this; return [4 /*yield*/, this.createConnection()]; case 2: _a._db = _b.sent(); return [2 /*return*/, this._db]; case 3: error_1 = _b.sent(); this.log('Failed to open database:', error_1); throw error_1; case 4: return [2 /*return*/]; } }); }); }; IndexedDB.prototype.createConnection = function () { var _this = this; return new Promise(function (resolve, reject) { /** * If exist the same version database, there need upgrade an new version database, * because of the same version can't trigger onupgradeneeded event which will occur * object stores was not found exception. */ var request = window.indexedDB.open(_this._database, _this._version); request.onsuccess = function () { _this._db = request.result; _this.setupVersionChangeHandler(); _this.log('Open indexedDB success!'); resolve(_this._db); }; request.onupgradeneeded = function (event) { _this._db = request.result; _this.handleUpgrade(event, request, resolve); }; request.onblocked = function (event) { _this.log('Database open blocked', event); reject(new Error('Database open blocked')); }; request.onerror = function (event) { _this.log('Maybe you not allow my web app to use IndexedDB!', event); reject(event); }; }); }; IndexedDB.prototype.handleUpgrade = function (event, request, resolve) { if (!this._db.objectStoreNames.contains(this._storeName)) { var objectStore = this._db.createObjectStore(this._storeName); objectStore.transaction.oncomplete = function () { resolve(request.result); }; } this.log('Database Upgraded', event); }; IndexedDB.prototype.setupVersionChangeHandler = function () { var _this = this; this._db.onversionchange = function (event) { _this.log('Database version changed', event); // Close database connection to avoid blocking upgrade operations in other tabs _this._db.close(); _this._db = null; }; }; IndexedDB.prototype.createTransactionStore = function (storeName, mode) { if (!this._db) { throw new Error('Database not connected, please call open() method first'); } var transaction = this._db.transaction([storeName], mode); return transaction.objectStore(storeName); }; /** @hidden */ IndexedDB.prototype.add = function (key, value) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.ensureConnection()]; case 1: _a.sent(); return [2 /*return*/, this.executeStoreOperation(function (store) { return store.add(value, key); })]; } }); }); }; /** @hidden */ IndexedDB.prototype.set = function (key, value) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.ensureConnection()]; case 1: _a.sent(); this.log('IndexedDB set', key, value); return [2 /*return*/, this.executeStoreOperation(function (store) { return store.put(value, key); })]; } }); }); }; /** @hidden */ IndexedDB.prototype.get = function (key) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.ensureConnection()]; case 1: _a.sent(); this.log('IndexedDB get', key); return [2 /*return*/, this.executeStoreOperation(function (store) { return store.get(key); })]; } }); }); }; /** @hidden */ IndexedDB.prototype.delete = function (key) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.ensureConnection()]; case 1: _a.sent(); return [2 /*return*/, this.executeStoreOperation(function (store) { return store.delete(key); })]; } }); }); }; /** @hidden */ IndexedDB.prototype.clear = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.ensureConnection()]; case 1: _a.sent(); return [2 /*return*/, this.executeStoreOperation(function (store) { return store.clear(); })]; } }); }); }; IndexedDB.prototype.ensureConnection = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: if (!!this._db) return [3 /*break*/, 2]; return [4 /*yield*/, this.open()]; case 1: _a.sent(); _a.label = 2; case 2: return [2 /*return*/]; } }); }); }; IndexedDB.prototype.executeStoreOperation = function (operate) { var _this = this; return new Promise(function (resolve, reject) { try { var store = _this.createTransactionStore(_this._storeName, 'readwrite'); var request_1 = operate(store); request_1.onsuccess = function () { return resolve(request_1.result); }; request_1.onerror = function (event) { _this.log('Store operation error:', event); reject(event); }; } catch (error) { _this.log('Error during store operation:', error); reject(error); } }); }; IndexedDB.prototype.log = function () { var args = []; for (var _i = 0; _i < arguments.length; _i++) { args[_i] = arguments[_i]; } if (this._openLog) { console.log.apply(console, __spreadArray(["[IndexedDB ".concat(this._database, "]")], args, false)); } }; return IndexedDB; }()); export default IndexedDB;