/** @type {Function} 日志输出 */ var log = console.warn; /** * 判断值是否为 String 类型 * @param {*} str - 待检测值 * @returns {boolean} * @private */ var isString = function (str) { return Object.getTypeString(str) === "String"; }; /** * IndexedDB 存储实现(大容量存储优先选择) * * @class IDBStorage * @example * const storage = new IDBStorage('myDb', 'myStore', 1); * await storage.set('key', { data: 123 }); * await storage.get('key', null); */ class IDBStorage { /** * 创建 IndexedDB 存储实例 * @param {string} [dbName='dbName'] - 数据库名称 * @param {string} [storeName='storeName'] - 对象存储名称 * @param {number} [version=1] - 数据库版本号 */ constructor(dbName, storeName, version) { /** @type {number} 数据库版本号 */ this.version = version || 1; /** @type {string} 数据库名称 */ this.dbName = dbName || "dbName"; /** @type {string} 对象存储名称 */ this.storeName = storeName || "storeName"; var request = indexedDB.open(this.dbName, this.version); /** @type {Promise} 数据库连接 Promise */ this.requestPromise = new Promise( function (resolve, reject) { request.onupgradeneeded = function (e) { if ( e && e.target && !request.result.objectStoreNames.contains(this.storeName) ) { request.result .createObjectStore(this.storeName, { keyPath: "key" }) .createIndex("key", "key", { unique: false }); } log("[Index][open]-upgrade"); resolve(request.result); }.bind(this); request.onsuccess = function () { log("[IndexDB][open]-success"); resolve(request.result); }; request.onerror = function (e) { log("[IndexDB][open]-error", 2); reject(e); }; }.bind(this), ); } /** * 获取存储值 * @template T * @param {string} key - 键名 * @param {T} initValue - 默认值(未找到时返回) * @returns {Promise} 存储的值或默认值 */ get(key, initValue) { var _this = this; return new Promise(async function (resolve) { var db = await _this.requestPromise; var transaction = db.transaction(_this.storeName, "readonly"); var objectStore = transaction.objectStore(_this.storeName); var req = objectStore.get(key); req.onsuccess = function () { resolve(req.result ? req.result.value : initValue || null); }; req.onerror = function (e) { log("[indexDB][get]-error", 2, e); resolve(initValue || null); }; }); } /** * 设置存储值 * @template T * @param {string} key - 键名 * @param {T} value - 要存储的值 * @returns {Promise} 返回写入的值 */ set(key, value) { var _this = this; return new Promise(async function (resolve) { var db = await _this.requestPromise; var transaction = db.transaction(_this.storeName, "readwrite"); var objectStore = transaction.objectStore(_this.storeName); var req = objectStore.put({ key: key, value: value }); req.onsuccess = function () { resolve(value); }; req.onerror = function (e) { log("[indexDB][set]-error", 2, e); resolve(value); }; }); } } /** * localStorage 存储实现(兼容性好,带内存缓存) * * @class ILocalStorage * @example * const storage = new ILocalStorage(); * await storage.set('key', { data: 456 }); * await storage.get('key', null); */ class ILocalStorage { constructor() { /** @type {Map} 内存缓存 */ this.cache = new Map(); this.load(); } /** 从 localStorage 全量加载到缓存 */ load() { var _this = this; Object.entries(localStorage).forEach(function (entry) { var key = entry[0], value = entry[1]; try { _this.cache.set(key, JSON.parse(value)); } catch (error) { log("[localStorage][load]-error", 2, error, key, value); } }); } /** * 从缓存获取值 * @template T * @param {string} key - 键名 * @param {T} initValue - 默认值 * @returns {Promise} 缓存的值或默认值 */ get(key, initValue) { return new Promise( function (resolve) { resolve( this.cache.get(key) !== undefined ? this.cache.get(key) : initValue, ); }.bind(this), ); } /** * 写入 localStorage 并更新缓存 * @template T * @param {string} key - 键名 * @param {T} value - 要存储的值 * @returns {Promise} 返回写入的值 */ set(key, value) { return new Promise( function (resolve) { var _value = isString(value) ? value : ""; try { _value = JSON.stringify(value); } catch (e) { log("[localStorage][set]-error", 2, e); } localStorage.setItem(key, _value); this.cache.set(key, _value); resolve(value); }.bind(this), ); } } /** * 纯内存存储实现(无持久化,适用于所有环境兜底) * * @class MemoryStorage * @example * const storage = new MemoryStorage(); * await storage.set('key', { data: 789 }); * await storage.get('key', null); */ class MemoryStorage { constructor() { /** @type {Map} 内存缓存 */ this.cache = new Map(); } /** * 从内存获取值 * @template T * @param {string} key - 键名 * @param {T} initValue - 默认值 * @returns {Promise} 缓存的值或默认值 */ get(key, initValue) { return Promise.resolve( this.cache.has(key) ? this.cache.get(key) : initValue !== undefined ? initValue : null, ); } /** * 写入内存 * @template T * @param {string} key - 键名 * @param {T} value - 要存储的值 * @returns {Promise} 返回写入的值 */ set(key, value) { this.cache.set(key, value); return Promise.resolve(value); } } /** * Node.js SQLite 持久化存储实现 * 仅在 Node.js 环境下可用,浏览器/webpack 打包中为 null * * @class SqliteStorage * @example * const storage = new SqliteStorage('./data/storage.db'); * await storage.set('key', { data: 123 }); * await storage.get('key', null); * @private */ var _SqliteStorageClass = function () { var Database = require("better-sqlite3"); var pathModule = require("path"); var fs = require("fs"); return class SqliteStorage { /** * 创建 SQLite 存储实例 * @param {string} [dbPath='.windychen-storage/storage.db'] - 数据库文件路径 */ constructor(dbPath) { this.dbPath = dbPath || pathModule.resolve(".windychen-storage", "storage.db"); var dir = pathModule.dirname(this.dbPath); if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } this.db = new Database(this.dbPath); this.db.pragma("journal_mode = WAL"); this.db.exec( "CREATE TABLE IF NOT EXISTS kv_store (key TEXT PRIMARY KEY, value TEXT)", ); } /** * 获取存储值 * @template T * @param {string} key - 键名 * @param {T} initValue - 默认值(未找到时返回) * @returns {Promise} 存储的值或默认值 */ async get(key, initValue) { var row = this.db .prepare("SELECT value FROM kv_store WHERE key = ?") .get(key); if (row) { try { return JSON.parse(row.value); } catch (e) { log("[SqliteStorage][get]-parse-error", 2, e); } } return initValue !== undefined ? initValue : null; } /** * 设置存储值 * @template T * @param {string} key - 键名 * @param {T} value - 要存储的值 * @returns {Promise} 返回写入的值 */ async set(key, value) { var json = JSON.stringify(value); this.db .prepare("INSERT OR REPLACE INTO kv_store (key, value) VALUES (?, ?)") .run(key, json); return value; } }; }; var SqliteStorage = null; try { SqliteStorage = _SqliteStorageClass(); } catch (e) { // better-sqlite3 不可用(浏览器 / webpack 打包环境),SqliteStorage 保持为 null } // ===== 环境检测与自动导出 ===== if (typeof window !== "undefined") { // 浏览器环境:优先 IndexedDB → localStorage → 内存 window.IStorage = window.indexedDB ? IDBStorage : window.localStorage ? ILocalStorage : MemoryStorage; if (typeof module !== "undefined") { module.exports = new window.IStorage(); } } else if (typeof module !== "undefined") { // Node.js 环境:SQLite 存储 → 内存 module.exports = SqliteStorage ? new SqliteStorage() : new MemoryStorage(); }