@ort-fe/storage-cache-kit
Version:
Unified client-side cache and storage manager with expiration control
501 lines (364 loc) • 14.2 kB
Markdown
# Storage Cache Kit
一个用于统一管理各种类型客户端存储和缓存的轻量级库。支持浏览器和Node.js环境。
## 目录
1. [特性](#特性)
2. [安装](#安装)
3. [快速开始](#快速开始)
4. [浏览器环境使用指南](#浏览器环境使用指南)
5. [Node.js环境使用指南](#nodejs环境使用指南)
6. [高级用法](#高级用法)
7. [API参考](#api参考)
8. [最佳实践](#最佳实践)
9. [许可证](#许可证)
## 特性
- 统一的API接口管理不同存储类型(localStorage, sessionStorage, cookie, 内存存储)
- 支持数据过期时间控制
- 支持简单的数据加密
- 支持命名空间隔离
- 完全类型化的API(TypeScript)
- 异步API设计,支持未来扩展
- 跨平台支持(浏览器和Node.js)
- 简化API,更易于使用
## 安装
```bash
# 使用npm
npm install -fe/storage-cache-kit
# 使用yarn
yarn add -fe/storage-cache-kit
# 使用pnpm
pnpm add -fe/storage-cache-kit
```
## 快速开始
### 浏览器环境
浏览器环境默认情况下使用localStorage进行存储。如果需要使用sessionStorage,cookie, memoey请往下看。
```typescript
// 导入store对象 (推荐)
import { store } from '@ort-fe/storage-cache-kit';
// 存储数据
await store.put('user', { id: 1, name: 'John' });
// 获取数据
const user = await store.get('user');
console.log(user); // { id: 1, name: 'John' }
// 删除数据
await store.del('user');
```
### Node.js环境
Node.js环境支持两种模块导入方式:CommonJS (require) 和 ES Modules (import)。
#### CommonJS 方式 (require)
```javascript
// 使用 CommonJS 导入方式
const { store } = require('@ort-fe/storage-cache-kit');
// 在Node.js中,自动使用内存存储
store.put('config', { port: 3000, debug: true })
.then(() => store.get('config'))
.then(config => {
console.log(config); // { port: 3000, debug: true }
});
// 使用 async/await (在异步函数内)
async function example() {
await store.put('config', { port: 3000, debug: true });
const config = await store.get('config');
console.log(config); // { port: 3000, debug: true }
}
example();
```
#### ES Modules 方式 (import)
```javascript
// 使用 ES Modules 导入方式
// 在 package.json 中设置 "type": "module" 或使用 .mjs 扩展名
import { store } from '@ort-fe/storage-cache-kit';
// 使用 async/await
async function example() {
await store.put('config', { port: 3000, debug: true });
const config = await store.get('config');
console.log(config); // { port: 3000, debug: true }
}
example();
```
### 完整API (适用于两种环境)
```typescript
// 导入StorageManager实例
import storageManager from '@ort-fe/storage-cache-kit';
// 存储数据
await storageManager.set('user', { id: 1, name: 'John' });
// 获取数据
const user = await storageManager.get('user');
// 删除数据
await storageManager.remove('user');
```
## 浏览器环境使用指南
在浏览器环境中,Storage Cache Kit支持多种存储方式,包括localStorage、sessionStorage、cookie和内存存储。
### 默认存储(localStorage)
默认情况下,Storage Cache Kit使用localStorage作为存储方式:
```typescript
import { store } from '@ort-fe/storage-cache-kit';
// 使用localStorage存储
await store.put('preferences', { theme: 'dark', fontSize: 16 });
const preferences = await store.get('preferences');
```
### 使用不同存储适配器
```typescript
import { store, ADAPTER_TYPES } from '@ort-fe/storage-cache-kit';
// 使用sessionStorage(会话存储,浏览器关闭后数据消失)
await store.put('temporaryData', { id: 123 }, {
adapter: ADAPTER_TYPES.SESSION_STORAGE
});
// 使用cookie存储(可跨页面请求传递)
await store.put('authToken', 'xyz123', {
adapter: ADAPTER_TYPES.COOKIE,
expires: 7 * 24 * 60 * 60 * 1000 // 7天过期
});
// 使用内存存储(页面刷新后数据消失)
await store.put('pageState', { scrollPosition: 350 }, {
adapter: ADAPTER_TYPES.MEMORY
});
```
### 使用字符串映射适配器
从 v1.1.0 版本开始,你可以直接使用字符串来指定适配器类型,而不必导入 `ADAPTER_TYPES` 常量:
```typescript
import { store } from '@ort-fe/storage-cache-kit';
// 使用字符串指定适配器类型
await store.put('sessionData', { user: 'John' }, { adapter: 'sessionStorage' });
await store.put('cookieData', { token: 'xyz' }, { adapter: 'cookie' });
await store.put('memoryData', { temp: true }, { adapter: 'memory' });
// 大小写不敏感
await store.put('data', { value: 123 }, { adapter: 'LOCAL' }); // 使用localStorage
```
支持的字符串映射包括:
| 字符串名称 | 对应适配器 |
| ------------------ | ------------------------------- |
| `'localStorage'` | `ADAPTER_TYPES.LOCAL_STORAGE` |
| `'sessionStorage'` | `ADAPTER_TYPES.SESSION_STORAGE` |
| `'cookie'` | `ADAPTER_TYPES.COOKIE` |
| `'memory'` | `ADAPTER_TYPES.MEMORY` |
### 设置数据过期时间
```typescript
import { store } from '@ort-fe/storage-cache-kit';
// 设置1小时后过期
await store.put('sessionToken', 'abc123', {
expires: 60 * 60 * 1000 // 毫秒
});
// 设置10分钟后过期
await store.put('verificationCode', '123456', {
expires: 10 * 60 * 1000
});
```
### Cookie存储高级配置
当使用Cookie存储时,可以通过创建自定义实例来设置更多Cookie相关选项:
```typescript
import { SimpleStore, ADAPTER_TYPES } from '@ort-fe/storage-cache-kit';
const cookieStore = new SimpleStore({
defaultAdapter: ADAPTER_TYPES.COOKIE,
defaultExpires: 30 * 24 * 60 * 60 * 1000, // 30天默认过期时间
});
// 使用自定义Cookie存储适配器
import { CookieStorageAdapter, StorageManager } from '@ort-fe/storage-cache-kit';
const cookieAdapter = new CookieStorageAdapter({
path: '/app',
domain: 'example.com',
secure: true,
sameSite: 'strict',
defaultDays: 14 // 14天默认过期
});
const manager = new StorageManager();
manager.registerAdapter('secureCookie', cookieAdapter);
await manager.set('sensitiveData', { userId: 12345 }, { adapter: 'secureCookie' });
```
## Node.js环境使用指南
在Node.js环境中,Storage Cache Kit会自动检测环境并默认使用内存存储适配器。
### 基本用法
#### CommonJS 方式
```javascript
// 使用 CommonJS 导入
const { store } = require('@ort-fe/storage-cache-kit');
// 在Node.js中,自动使用内存存储
store.put('serverConfig', { port: 3000, debug: true })
.then(() => {
return store.get('serverConfig');
})
.then(config => {
console.log(config); // { port: 3000, debug: true }
});
// 或者在异步函数中使用
async function example() {
await store.put('serverConfig', { port: 3000, debug: true });
const config = await store.get('serverConfig');
console.log(config); // { port: 3000, debug: true }
}
```
#### ES Modules 方式
```javascript
// 使用 ES Modules 导入 (需要在 package.json 中设置 "type": "module")
import { store } from '@ort-fe/storage-cache-kit';
// 在Node.js中,自动使用内存存储
await store.put('serverConfig', { port: 3000, debug: true });
const config = await store.get('serverConfig');
console.log(config); // { port: 3000, debug: true }
```
### 内存存储的局限性
需要注意,在Node.js环境中使用内存存储有以下局限性:
1. **非持久化**:服务器重启后,所有数据都会丢失
2. **进程隔离**:不同的Node.js进程无法共享存储数据
3. **内存占用**:大量数据可能导致内存占用过高
### 适用场景
Node.js环境中的内存存储适合以下场景:
1. **请求级缓存**:在单个请求处理过程中缓存数据
2. **短期会话数据**:存储短期有效的会话信息
3. **开发和测试**:在开发和测试环境中模拟存储行为
### 持久化存储建议
如果需要在Node.js环境中进行持久化存储,建议:
1. 使用数据库(MongoDB、Redis、MySQL等)
2. 使用文件系统存储
3. 使用专门的缓存服务
## 高级用法
### 命名空间
使用命名空间可以隔离不同模块或功能的存储数据:
```typescript
import { SimpleStore } from '@ort-fe/storage-cache-kit';
const userStore = new SimpleStore({ namespace: 'user' });
const settingsStore = new SimpleStore({ namespace: 'settings' });
// 这两个操作使用相同的键,但存储在不同的命名空间
await userStore.put('profile', { name: 'John' });
await settingsStore.put('profile', { darkMode: true });
// 获取各自命名空间的数据
const userProfile = await userStore.get('profile'); // { name: 'John' }
const settingsProfile = await settingsStore.get('profile'); // { darkMode: true }
```
### 数据加密
启用加密功能可以保护敏感数据:
```typescript
import { SimpleStore } from '@ort-fe/storage-cache-kit';
const secureStore = new SimpleStore({
defaultEncrypt: true // 启用加密
});
await secureStore.put('creditCard', { number: '1234-5678-9012-3456', cvv: '123' });
// 数据将以加密形式存储
```
### 批量操作
```typescript
import { store } from '@ort-fe/storage-cache-kit';
// 批量存储
const data = {
user: { id: 1, name: 'John' },
settings: { theme: 'dark' },
token: 'abc123'
};
// 使用Promise.all进行批量操作
await Promise.all(
Object.entries(data).map(([key, value]) => store.put(key, value))
);
// 批量获取
const keys = ['user', 'settings', 'token'];
const values = await Promise.all(keys.map(key => store.get(key)));
// 批量删除
await Promise.all(keys.map(key => store.del(key)));
```
### 自定义适配器
你可以创建并注册自己的存储适配器:
```typescript
import { StorageAdapter, StorageItem, StorageManager } from '@ort-fe/storage-cache-kit';
// 创建自定义适配器
class MyCustomAdapter implements StorageAdapter {
private storage = new Map<string, string>();
async setItem<T>(key: string, item: StorageItem<T>): Promise<void> {
this.storage.set(key, JSON.stringify(item));
}
async getItem<T>(key: string): Promise<StorageItem<T> | undefined> {
const data = this.storage.get(key);
return data ? JSON.parse(data) as StorageItem<T> : undefined;
}
async removeItem(key: string): Promise<void> {
this.storage.delete(key);
}
async clear(): Promise<void> {
this.storage.clear();
}
async keys(): Promise<string[]> {
return Array.from(this.storage.keys());
}
}
// 注册自定义适配器
const manager = new StorageManager();
manager.registerAdapter('custom', new MyCustomAdapter());
// 使用自定义适配器
await manager.set('key', 'value', { adapter: 'custom' });
```
## API参考
### 简化API (SimpleStore)
- `put<T>(key: string, value: T, options?): Promise<void>` - 设置存储项
- `get<T>(key: string, options?): Promise<T | undefined>` - 获取存储项
- `del(key: string, options?): Promise<void>` - 删除存储项
- `has(key: string, options?): Promise<boolean>` - 检查键是否存在
- `keys(options?): Promise<string[]>` - 获取所有键名
- `clear(options?): Promise<void>` - 清空存储
### 完整API (StorageManager)
- `set<T>(key: string, value: T, options?): Promise<void>` - 设置存储项
- `get<T>(key: string, options?): Promise<T | undefined>` - 获取存储项
- `remove(key: string, options?): Promise<void>` - 移除存储项
- `clear(options?): Promise<void>` - 清空存储
- `keys(options?): Promise<string[]>` - 获取所有键名
- `has(key: string, options?): Promise<boolean>` - 检查键是否存在
- `registerAdapter(name: string, adapter: StorageAdapter): void` - 注册自定义适配器
### 存储适配器类型
- `ADAPTER_TYPES.LOCAL_STORAGE` - localStorage适配器
- `ADAPTER_TYPES.SESSION_STORAGE` - sessionStorage适配器
- `ADAPTER_TYPES.COOKIE` - Cookie适配器
- `ADAPTER_TYPES.MEMORY` - 内存存储适配器
### 配置选项
```typescript
interface StorageManagerOptions {
// 默认存储适配器类型
defaultAdapter?: AdapterType;
// 默认过期时间(毫秒)
defaultExpires?: number;
// 是否默认加密数据
defaultEncrypt?: boolean;
// 命名空间前缀
namespace?: string;
}
```
## 最佳实践
### 1. 使用await处理异步操作
虽然所有操作都返回Promise,但强烈建议使用await等待操作完成:
```typescript
// 推荐
async function saveUserData() {
await store.put('user', userData);
console.log('用户数据已保存');
}
// 不推荐
function saveUserData() {
store.put('user', userData);
console.log('这条消息可能在数据实际保存前就显示了');
}
```
### 2. 适当设置过期时间
为敏感数据或临时数据设置合理的过期时间:
```typescript
// 身份验证令牌 - 1小时过期
await store.put('authToken', token, { expires: 60 * 60 * 1000 });
// 用户偏好设置 - 长期存储(不设置过期时间)
await store.put('userPreferences', preferences);
```
### 3. 选择合适的存储类型
- **localStorage**: 持久性数据,如用户偏好
- **sessionStorage**: 会话级数据,如表单状态
- **cookie**: 需要随HTTP请求发送的数据,如认证令牌
- **memory**: 临时数据,如页面状态
### 4. 使用命名空间隔离数据
```typescript
const authStore = new SimpleStore({ namespace: 'auth' });
const uiStore = new SimpleStore({ namespace: 'ui' });
```
### 5. 错误处理
```typescript
try {
await store.put('complexData', largeObject);
await store.put('sensitiveData', sensitiveInfo, { encrypt: true });
} catch (error) {
console.error('存储操作失败:', error);
// 实现备用存储策略或通知用户
}
```
## 许可证
MIT