UNPKG

@ort-fe/storage-cache-kit

Version:

Unified client-side cache and storage manager with expiration control

696 lines (695 loc) 18.7 kB
var g = Object.defineProperty; var y = (a, e, t) => e in a ? g(a, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : a[e] = t; var n = (a, e, t) => y(a, typeof e != "symbol" ? e + "" : e, t); function v(a) { try { return btoa(encodeURIComponent(a)); } catch (e) { return console.error("Encryption failed:", e), a; } } function S(a) { try { return decodeURIComponent(atob(a)); } catch (e) { return console.error("Decryption failed:", e), a; } } function w() { return typeof process < "u" && process.versions != null && process.versions.node != null; } function A() { return typeof window < "u" && typeof document < "u"; } function E() { return ( // Vitest环境检测 typeof process < "u" && process.env && (process.env.NODE_ENV === "test" || process.env.VITEST !== void 0) ); } const d = /* @__PURE__ */ (() => { const a = {}; return function(e) { a[e] || (console.warn(e), a[e] = !0); }; })(); function b(a) { return a.expires ? Date.now() - a.timestamp > a.expires : !1; } function p(a, e = !1) { const t = JSON.stringify(a); return e ? v(t) : t; } function I(a, e = !1) { try { const t = e ? S(a) : a; return JSON.parse(t); } catch (t) { throw console.error("Failed to deserialize item:", t), new Error("Invalid storage item format"); } } function h(a, e = !1) { if (!a) return; try { const r = I(a, e); if (r && typeof r == "object" && "value" in r && "timestamp" in r) return r; } catch (r) { process.env.NODE_ENV === "development" && console.debug("Item not in standard format, trying alternative parsing:", r); } let t; try { t = JSON.parse(a), process.env.NODE_ENV === "development" && console.debug("Successfully parsed as JSON:", t); } catch { t = a, process.env.NODE_ENV === "development" && console.debug("Using raw string as value:", a); } return { value: t, timestamp: Date.now(), expires: void 0 }; } function f(a, e) { return e ? `${e}:${a}` : a; } function k() { try { if (typeof localStorage > "u") return !1; const a = "__test_localStorage__"; return localStorage.setItem(a, "test"), localStorage.removeItem(a), !0; } catch { return !1; } } class O { /** * 创建 localStorage 适配器 * @param encrypt 是否加密数据 */ constructor(e = !1) { n(this, "encrypt"); n(this, "available"); this.encrypt = e, this.available = k(), this.available || d("localStorage is not available in this environment."); } /** * 设置存储项 * @param key 键名 * @param item 存储项 */ async setItem(e, t) { if (!this.available) throw new Error("localStorage is not available in this environment"); try { const r = p(t, this.encrypt); localStorage.setItem(e, r); } catch (r) { throw console.error(`Failed to set item '${e}':`, r), new Error(`Failed to set item '${e}'`); } } /** * 获取存储项 * @param key 键名 * @returns 存储项或undefined(如果不存在) */ async getItem(e) { if (!this.available) throw new Error("localStorage is not available in this environment"); try { const t = localStorage.getItem(e); return t ? h(t, this.encrypt) : void 0; } catch (t) { console.error(`Failed to get item '${e}':`, t); return; } } /** * 移除存储项 * @param key 键名 */ async removeItem(e) { if (!this.available) throw new Error("localStorage is not available in this environment"); localStorage.removeItem(e); } /** * 清空所有存储 */ async clear() { if (!this.available) throw new Error("localStorage is not available in this environment"); localStorage.clear(); } /** * 获取所有键名 * @returns 键名数组 */ async keys() { if (!this.available) throw new Error("localStorage is not available in this environment"); const e = []; for (let t = 0; t < localStorage.length; t++) { const r = localStorage.key(t); r && e.push(r); } return e; } } function C() { try { if (typeof sessionStorage > "u") return !1; const a = "__test_sessionStorage__"; return sessionStorage.setItem(a, "test"), sessionStorage.removeItem(a), !0; } catch { return !1; } } class $ { /** * 创建 sessionStorage 适配器 * @param encrypt 是否加密数据 */ constructor(e = !1) { n(this, "encrypt"); n(this, "available"); this.encrypt = e, this.available = C(), this.available || d("sessionStorage is not available in this environment."); } /** * 设置存储项 * @param key 键名 * @param item 存储项 */ async setItem(e, t) { if (!this.available) throw new Error("sessionStorage is not available in this environment"); try { const r = p(t, this.encrypt); sessionStorage.setItem(e, r); } catch (r) { throw console.error(`Failed to set item '${e}':`, r), new Error(`Failed to set item '${e}'`); } } /** * 获取存储项 * @param key 键名 * @returns 存储项或undefined(如果不存在) */ async getItem(e) { if (!this.available) throw new Error("sessionStorage is not available in this environment"); try { const t = sessionStorage.getItem(e); return t ? h(t, this.encrypt) : void 0; } catch (t) { console.error(`Failed to get item '${e}':`, t); return; } } /** * 移除存储项 * @param key 键名 */ async removeItem(e) { if (!this.available) throw new Error("sessionStorage is not available in this environment"); sessionStorage.removeItem(e); } /** * 清空所有存储 */ async clear() { if (!this.available) throw new Error("sessionStorage is not available in this environment"); sessionStorage.clear(); } /** * 获取所有键名 * @returns 键名数组 */ async keys() { if (!this.available) throw new Error("sessionStorage is not available in this environment"); const e = []; for (let t = 0; t < sessionStorage.length; t++) { const r = sessionStorage.key(t); r && e.push(r); } return e; } } class R { /** * 创建内存存储适配器 * @param encrypt 是否加密数据 */ constructor(e = !1) { n(this, "storage", /* @__PURE__ */ new Map()); n(this, "encrypt"); this.encrypt = e; } /** * 设置存储项 * @param key 键名 * @param item 存储项 */ async setItem(e, t) { try { const r = p(t, this.encrypt); this.storage.set(e, r); } catch (r) { throw console.error(`Failed to set item '${e}':`, r), new Error(`Failed to set item '${e}'`); } } /** * 获取存储项 * @param key 键名 * @returns 存储项或undefined(如果不存在) */ async getItem(e) { try { const t = this.storage.get(e); return t ? h(t, this.encrypt) : void 0; } catch (t) { console.error(`Failed to get item '${e}':`, t); return; } } /** * 移除存储项 * @param key 键名 */ async removeItem(e) { this.storage.delete(e); } /** * 清空所有存储 */ async clear() { this.storage.clear(); } /** * 获取所有键名 * @returns 键名数组 */ async keys() { return Array.from(this.storage.keys()); } } function _() { try { if (typeof document > "u" || typeof document.cookie > "u") return !1; const a = "__test_cookie__", e = "test", t = /* @__PURE__ */ new Date(); t.setTime(t.getTime() + 1e3), document.cookie = `${a}=${e}; expires=${t.toUTCString()}; path=/`; const r = document.cookie.indexOf(a) !== -1; return document.cookie = `${a}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`, r; } catch { return !1; } } class N { /** * 创建Cookie存储适配器 * @param options Cookie配置选项 */ constructor(e = {}) { n(this, "encrypt"); n(this, "defaultDays"); n(this, "path"); n(this, "domain"); n(this, "secure"); n(this, "sameSite"); n(this, "available"); this.encrypt = e.encrypt || !1, this.defaultDays = e.defaultDays || 7, this.path = e.path || "/", this.domain = e.domain, this.secure = e.secure || !1, this.sameSite = e.sameSite || "lax", this.available = _(), this.available || d("Cookie is not available in this environment."); } /** * 设置存储项 * @param key 键名 * @param item 存储项 */ async setItem(e, t) { if (!this.available) throw new Error("Cookie is not available in this environment"); try { const r = p(t, this.encrypt), o = t.expires ? Math.ceil(t.expires / (24 * 60 * 60 * 1e3)) : this.defaultDays, i = /* @__PURE__ */ new Date(); i.setTime(i.getTime() + o * 24 * 60 * 60 * 1e3); let s = `${encodeURIComponent(e)}=${encodeURIComponent(r)}; expires=${i.toUTCString()}; path=${this.path}`; this.domain && (s += `; domain=${this.domain}`), this.secure && (s += "; secure"), s += `; samesite=${this.sameSite}`, document.cookie = s; } catch (r) { throw console.error(`Failed to set cookie '${e}':`, r), new Error(`Failed to set cookie '${e}'`); } } /** * 获取存储项 * @param key 键名 * @returns 存储项或undefined(如果不存在) */ async getItem(e) { if (!this.available) throw new Error("Cookie is not available in this environment"); try { const t = document.cookie.split(";"), r = encodeURIComponent(e); for (const o of t) { const [i, s] = o.trim().split("="); if (i === r && s) { const m = decodeURIComponent(s); return h(m, this.encrypt); } } return; } catch (t) { console.error(`Failed to get cookie '${e}':`, t); return; } } /** * 移除存储项 * @param key 键名 */ async removeItem(e) { if (!this.available) throw new Error("Cookie is not available in this environment"); document.cookie = `${encodeURIComponent(e)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${this.path}`, this.domain && (document.cookie = `${encodeURIComponent(e)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${this.path}; domain=${this.domain}`); } /** * 清空所有存储 * 注意:只能清除当前域下的cookie,且受路径限制 */ async clear() { if (!this.available) throw new Error("Cookie is not available in this environment"); const e = document.cookie.split(";"); for (const t of e) { const r = t.split("=")[0].trim(); await this.removeItem(r); } } /** * 获取所有键名 * @returns 键名数组 */ async keys() { if (!this.available) throw new Error("Cookie is not available in this environment"); const e = document.cookie.split(";"), t = []; for (const r of e) if (r.trim()) { const o = r.split("=")[0].trim(); t.push(decodeURIComponent(o)); } return t; } } const c = { LOCAL_STORAGE: "localStorage", SESSION_STORAGE: "sessionStorage", MEMORY: "memory", COOKIE: "cookie" }; function M() { try { return typeof process < "u" && process.env ? process.env.NODE_ENV === "development" : !1; } catch { return !1; } } function l(...a) { M() && console.debug(...a); } class T { /** * 创建存储管理器 * @param options 配置选项 */ constructor(e = {}) { n(this, "adapters", /* @__PURE__ */ new Map()); n(this, "options"); const t = w(), r = E(), o = A() || r; let i; typeof e.defaultAdapter == "string" ? i = this.mapAdapterString(e.defaultAdapter) : i = !o || t ? c.MEMORY : e.defaultAdapter || c.LOCAL_STORAGE; const s = { ...e }; delete s.defaultAdapter, this.options = { defaultAdapter: i, defaultExpires: 0, // 默认不过期 defaultEncrypt: !1, namespace: "", ...s }, this.registerAdapters(), l("Registered adapters:", Array.from(this.adapters.keys())), this.adapters.has(this.options.defaultAdapter.toLowerCase()) || (d(`Default adapter '${this.options.defaultAdapter}' is not available, falling back to memory adapter.`), this.options.defaultAdapter = c.MEMORY); } /** * 注册所有适配器 * @private */ registerAdapters() { const e = new R(this.options.defaultEncrypt); this.registerAdapterWithAliases(c.MEMORY, e, ["memory", "mem"]); try { const t = new O(this.options.defaultEncrypt); this.registerAdapterWithAliases( c.LOCAL_STORAGE, t, ["localStorage", "local", "localstorage"] ); } catch (t) { l("localStorage adapter registration failed:", t instanceof Error ? t.message : String(t)); } try { const t = new $(this.options.defaultEncrypt); this.registerAdapterWithAliases( c.SESSION_STORAGE, t, ["sessionStorage", "session", "sessionstorage"] ); } catch (t) { l("sessionStorage adapter registration failed:", t instanceof Error ? t.message : String(t)); } try { const t = new N({ encrypt: this.options.defaultEncrypt }); this.registerAdapterWithAliases( c.COOKIE, t, ["cookie", "cookies"] ); } catch (t) { l("cookie adapter registration failed:", t instanceof Error ? t.message : String(t)); } } /** * 注册适配器及其别名 * @private * @param primaryName 主要名称 * @param adapter 适配器实例 * @param aliases 别名数组 */ registerAdapterWithAliases(e, t, r) { const o = e.toLowerCase(); this.adapters.set(o, t); for (const i of r) { const s = i.toLowerCase(); s !== o && this.adapters.set(s, t); } l(`Registered adapter '${e}' with aliases:`, r); } /** * 映射适配器字符串到适配器类型 * @private */ mapAdapterString(e) { if (!e) return c.MEMORY; const t = e.toLowerCase(); return { localstorage: c.LOCAL_STORAGE, local: c.LOCAL_STORAGE, sessionstorage: c.SESSION_STORAGE, session: c.SESSION_STORAGE, cookie: c.COOKIE, cookies: c.COOKIE, memory: c.MEMORY, mem: c.MEMORY }[t] || e; } /** * 注册存储适配器 * @param name 适配器名称 * @param adapter 适配器实例 */ registerAdapter(e, t) { this.adapters.set(e.toLowerCase(), t); } /** * 获取存储适配器 * @param name 适配器名称 * @returns 适配器实例 */ getAdapter(e = this.options.defaultAdapter) { e || (e = this.options.defaultAdapter); const r = this.mapAdapterString(e).toLowerCase(), o = this.adapters.get(r); if (!o) throw l("Available adapters:", Array.from(this.adapters.keys())), l("Requested adapter:", e, "Mapped to:", r), new Error(`Adapter '${e}' not found`); return o; } /** * 设置存储项 * @param key 键名 * @param value 值 * @param options 选项 * @returns Promise */ async set(e, t, r = {}) { const { expires: o = this.options.defaultExpires } = r; let i; r.adapter ? i = this.mapAdapterString(r.adapter) : i = this.options.defaultAdapter; const s = this.getAdapter(i), m = f(e, this.options.namespace), u = { value: t, timestamp: Date.now(), expires: o }; await s.setItem(m, u); } /** * 获取存储项 * @param key 键名 * @param options 选项 * @returns 存储值或undefined(如果不存在或已过期) */ async get(e, t = {}) { let r; t.adapter ? r = this.mapAdapterString(t.adapter) : r = this.options.defaultAdapter; const o = this.getAdapter(r), i = f(e, this.options.namespace), s = await o.getItem(i); if (s) { if (b(s)) { await this.remove(e, { adapter: r }); return; } return s.value; } } /** * 移除存储项 * @param key 键名 * @param options 选项 * @returns Promise */ async remove(e, t = {}) { let r; t.adapter ? r = this.mapAdapterString(t.adapter) : r = this.options.defaultAdapter; const o = this.getAdapter(r), i = f(e, this.options.namespace); await o.removeItem(i); } /** * 清空指定适配器的所有存储 * @param options 选项 * @returns Promise */ async clear(e = {}) { let t; e.adapter ? t = this.mapAdapterString(e.adapter) : t = this.options.defaultAdapter, await this.getAdapter(t).clear(); } /** * 获取指定适配器的所有键名 * @param options 选项 * @returns 键名数组 */ async keys(e = {}) { let t; e.adapter ? t = this.mapAdapterString(e.adapter) : t = this.options.defaultAdapter; const o = await this.getAdapter(t).keys(); if (this.options.namespace) { const i = `${this.options.namespace}:`; return o.filter((s) => s.startsWith(i)).map((s) => s.slice(i.length)); } return o; } /** * 检查键是否存在 * @param key 键名 * @param options 选项 * @returns 是否存在 */ async has(e, t = {}) { return await this.get(e, t) !== void 0; } } class D { /** * 创建简化存储接口 * @param options 配置选项 */ constructor(e) { n(this, "manager"); this.manager = new T(e); } /** * 设置存储项 * @param key 键名 * @param value 值 * @param options 选项 */ async put(e, t, r) { return this.manager.set(e, t, r); } /** * 获取存储项 * @param key 键名 * @param options 选项 */ async get(e, t) { return this.manager.get(e, t); } /** * 删除存储项 * @param key 键名 * @param options 选项 */ async del(e, t) { return this.manager.remove(e, t); } /** * 检查键是否存在 * @param key 键名 * @param options 选项 */ async has(e, t) { return this.manager.has(e, t); } /** * 获取所有键名 * @param options 选项 */ async keys(e) { return this.manager.keys(e); } /** * 清空存储 * @param options 选项 */ async clear(e) { return this.manager.clear(e); } /** * 获取原始存储管理器实例 * 用于访问高级功能 */ getManager() { return this.manager; } /** * 调试方法:获取所有已注册的适配器 * 仅在开发环境中使用 */ getRegisteredAdapters() { return Array.from(this.manager.adapters.keys()); } } const L = new D(); export { c as ADAPTER_TYPES, N as CookieStorageAdapter, O as LocalStorageAdapter, R as MemoryStorageAdapter, $ as SessionStorageAdapter, D as SimpleStore, T as StorageManager, L as store }; //# sourceMappingURL=index.mjs.map