@ort-fe/storage-cache-kit
Version:
Unified client-side cache and storage manager with expiration control
696 lines (695 loc) • 18.7 kB
JavaScript
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