@tni/cache
v2.0.0
Published
localStorage、sessionStorage、Cookies、IndexedDB 统一封装
Readme
@tni/cache
浏览器缓存能力的统一封装,覆盖 localStorage、sessionStorage、Cookie、IndexedDB,并补齐过期时间、加解密和空间估算能力。
适用场景
- 登录态、偏好设置、本地草稿缓存
- 需要统一 TTL 和序列化行为的前端项目
- 需要在不同存储后端之间切换但不想改业务调用方式
安装
vp add @tni/cache快速开始
import { createLocalStorage } from "@tni/cache";
const storage = createLocalStorage({
prefix: "admin:",
defaultTtl: 300,
});
await storage.set("user", { id: 1, name: "duan" });
const user = await storage.get("user");
await storage.remove("user");存储实现
| 实现 | 工厂函数 | 说明 |
| --------------- | -------------------------- | -------------------------- |
| Local Storage | createLocalStorage() | 持久化、同步接口、同源共享 |
| Session Storage | createSessionStorage() | 会话级缓存 |
| Cookie | createCookieStorage() | 适合简单键值和服务端协同 |
| IndexedDB | createIndexedDBStorage() | 大容量、异步场景 |
过期时间
await storage.set("token", "xxx", { ttl: 3600 });
await storage.set("profile", data, {
expires: new Date(Date.now() + 24 * 60 * 60 * 1000),
});加解密
import { createEncryptor } from "@tni/cache";
const cipher = await createEncryptor("my-passphrase");
const secureStorage = createLocalStorage({ prefix: "secure:", cipher });
await secureStorage.set("secret", "sensitive");也可以接入业务自己的加解密实现:
const storage = createLocalStorage({
cipher: {
encrypt: async (raw) => myEncrypt(raw),
decrypt: async (raw) => myDecrypt(raw),
},
});空间与异常处理
import { estimateQuota, formatBytes, StorageQuotaExceededError } from "@tni/cache";
const quota = await estimateQuota();
if (quota) {
console.log(formatBytes(quota.usage), formatBytes(quota.quota));
}
try {
await storage.set("large", hugePayload);
} catch (error) {
if (error instanceof StorageQuotaExceededError) {
console.error("缓存空间不足");
}
}设计约定
- 所有实现都统一走字符串存储
- 复杂值先序列化,再按需加密
- 读取时先判断是否过期,再解密、反序列化
- 调用接口统一为异步,业务侧切换存储后端时无需改调用方式
导出
- 存储工厂:
createLocalStorage、createSessionStorage、createCookieStorage、createIndexedDBStorage - 加解密:
createEncryptor、createBase64Cipher - 配额工具:
estimateQuota、formatBytes、isQuotaExceededError - 错误类型:
StorageQuotaExceededError
API 速查
存储工厂
createLocalStorage(options?)createSessionStorage(options?)createCookieStorage(options?)createIndexedDBStorage(options?)
它们都会返回统一风格的异步存储接口,常用方法包括:
get(key)set(key, value, options?)remove(key)clear()
加解密工具
createEncryptor(passphrase)createBase64Cipher()
适合快速给存储层补一层对称加密或轻量编码。
配额工具
estimateQuota(): 获取浏览器当前源估算配额formatBytes(bytes): 格式化字节数isQuotaExceededError(error): 判断是否为空间不足错误
关键配置项
BaseStorageOptions
prefix: key 前缀defaultTtl: 默认过期秒数serialize/deserialize: 自定义序列化方案cipher/encrypt/decrypt: 自定义加解密isAvailable: 当前存储实现是否可用
SetOptions
ttl: 相对过期秒数expires: 绝对过期时间
边界与限制
- 这是浏览器缓存抽象,不适合作为服务端通用缓存方案
- 不同浏览器的配额和异常细节并不完全一致,空间检测只能做到尽量统一
- 加解密只负责数据保护,不负责密钥管理
- Cookie 后端天然不适合大对象和高频复杂读写
验证建议
- 改动 TTL 逻辑后,重点验证过期读写行为
- 改动加解密后,重点验证序列化和逆向解密链路
- 改动不同存储实现时,至少验证
set/get/remove/clear
