@bwt-st/storage
v0.2.1
Published
Framework-agnostic browser storage client for BWT-ST projects.
Downloads
229
Readme
@bwt-st/storage
无框架浏览器存储库,支持 localStorage、sessionStorage、内存存储和自定义适配器,并提供命名空间、版本隔离、JSON 序列化和 TTL 过期控制。
安装
pnpm add @bwt-st/storage快速使用
建议在业务项目的基础设施层只创建一次实例并统一导出,使 namespace、version、驱动和序列化规则保持一致:
// src/services/storage.ts
import { createLocalStorage } from '@bwt-st/storage'
export const storage = createLocalStorage({
namespace: 'bwt-admin',
version: 1,
})业务模块直接复用实例:
import { storage } from '@/services/storage'
storage.set('user', { id: 1, name: 'Ada' })
const user = storage.get<{ id: number; name: string }>('user')创建函数
| 函数 | 说明 |
| -------------------------------- | ------------------------------------------ |
| createLocalStorage(options?) | 创建浏览器 localStorage 客户端。 |
| createSessionStorage(options?) | 创建浏览器 sessionStorage 客户端。 |
| createMemoryStorage(options?) | 创建内存客户端,适合 SSR、测试和临时数据。 |
| createStorage(options) | 使用自定义适配器创建客户端。 |
浏览器驱动会在第一次读写时获取浏览器对象,因此可以在 SSR 模块顶层创建实例;但 SSR 环境实际读写时会抛出 StorageUnavailableError。SSR 和测试环境应使用 createMemoryStorage。
创建配置
interface BrowserStorageOptions {
namespace?: string
version?: string | number
serializer?: StorageSerializer
now?: () => number
}
interface StorageOptions extends BrowserStorageOptions {
adapter: StorageAdapter | (() => StorageAdapter)
}| 配置 | 默认值 | 说明 |
| ------------ | ----------------------- | ---------------------------------------- |
| namespace | bwt-st | 物理键命名空间,不能为空且不能包含 :。 |
| version | 1 | 数据版本,不能为空且不能包含 :。 |
| serializer | jsonSerializer | 自定义序列化器。 |
| now | Date.now | 当前时间函数,主要用于测试。 |
| adapter | 必填(createStorage) | Web Storage 兼容适配器或延迟创建函数。 |
物理键格式为 <namespace>:v<version>:<key>。例如 bwt-admin:v1:user。不同命名空间或版本相互隔离,clear() 只清理当前命名空间和版本,不会自动删除旧版本数据。
客户端 API
interface StorageClient {
get<T>(key: string): T | null
set<T>(key: string, value: T, options?: SetOptions): void
has(key: string): boolean
remove(key: string): void
keys(): string[]
clear(): void
}
interface SetOptions {
ttl?: number
}get<T>(key):读取值。键不存在或已过期时返回null。set<T>(key, value, options?):写入值;ttl单位为毫秒,必须是非负有限数值,0表示立即过期。has(key):判断键是否存在且未过期,可区分“存储的值为null”和“键不存在”。remove(key):删除当前命名空间和版本下的指定键。keys():返回当前命名空间和版本下所有未过期的逻辑键名。clear():清理当前命名空间和版本下的全部数据。
storage.set('preferences', { theme: 'dark' })
storage.set('toast', '保存成功', { ttl: 5_000 })
storage.has('preferences') // true
storage.get<{ theme: string }>('preferences')
storage.keys() // ['preferences', 'toast']
storage.remove('toast')常见场景
登录态
export function saveToken(token: string) {
storage.set('access-token', token)
}
export function getToken() {
return storage.get<string>('access-token')
}
export function clearAuth() {
storage.remove('access-token')
storage.remove('current-user')
}HTTP 客户端可以从同一个实例读取 Token:
import { createHttpClient } from '@bwt-st/http'
const http = createHttpClient({
baseURL: '/api',
hooks: {
getAccessToken: () => storage.get<string>('access-token'),
},
})用户偏好和临时草稿
主题、语言、表格分页大小等低敏感偏好适合持久化;提示、验证码状态和表单草稿可以设置 TTL:
storage.set('preferences', {
theme: 'dark',
locale: 'zh-CN',
pageSize: 20,
})
storage.set('order-draft', draft, {
ttl: 24 * 60 * 60 * 1000,
})应用和版本隔离
不同应用使用不同命名空间;数据结构发生不兼容变化时提升版本:
const adminStorage = createLocalStorage({
namespace: 'bwt-admin',
version: 2,
})
const portalStorage = createLocalStorage({
namespace: 'bwt-portal',
version: 1,
})自定义适配器和序列化器
interface StorageAdapter {
readonly length: number
clear(): void
getItem(key: string): string | null
key(index: number): string | null
removeItem(key: string): void
setItem(key: string, value: string): void
}
interface StorageSerializer {
serialize(value: unknown): string
deserialize<T>(value: string): T
}createStorage 可以接收任意实现了 StorageAdapter 的对象。默认的 jsonSerializer 适合普通 JSON 数据,也可以注入业务自己的稳定编码协议。
错误和边界行为
| 错误 | 触发场景 |
| --------------------------- | ---------------------------------------- |
| StorageError | 存储操作失败的基类。 |
| StorageUnavailableError | 当前环境无法使用指定驱动。 |
| StorageQuotaError | 浏览器存储空间不足。 |
| StorageSerializationError | 数据无法序列化、反序列化或记录格式无效。 |
存储值默认必须能被 JSON 稳定序列化。函数、Symbol、顶层 undefined 和循环引用会失败。不要将密码、私钥等高敏感信息直接存入浏览器存储。Cookie、IndexedDB、跨标签页订阅和数据迁移不属于当前版本范围。
运行环境
- Node.js
>=20.19.0 - 浏览器环境需要可用的 Web Storage API
- SSR、单元测试和临时数据使用
createMemoryStorage - 详细 API 与场景示例可参阅仓库的
docs/storage/index.md
