1.1.2 • Published 10 months ago

@ort-fe/storage-cache-kit v1.1.2

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

Storage Cache Kit

一个用于统一管理各种类型客户端存储和缓存的轻量级库。支持浏览器和Node.js环境。

目录

  1. 特性
  2. 安装
  3. 快速开始
  4. 浏览器环境使用指南
  5. Node.js环境使用指南
  6. 高级用法
  7. API参考
  8. 最佳实践
  9. 常见问题
  10. 版本兼容性与功能支持

特性

  • 统一的API接口管理不同存储类型(localStorage, sessionStorage, cookie, 内存存储)
  • 支持数据过期时间控制
  • 支持简单的数据加密
  • 支持命名空间隔离
  • 完全类型化的API(TypeScript)
  • 异步API设计,支持未来扩展
  • 跨平台支持(浏览器和Node.js)
  • 简化API,更易于使用

安装

# 使用npm
npm install @ort-fe/storage-cache-kit

# 使用yarn
yarn add @ort-fe/storage-cache-kit

# 使用pnpm
pnpm add @ort-fe/storage-cache-kit

快速开始

浏览器环境

浏览器环境默认情况下使用localStorage进行存储。如果需要使用sessionStorage,cookie, memoey请往下看。

// 导入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)

// 使用 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)

// 使用 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 (适用于两种环境)

// 导入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作为存储方式:

import { store } from '@ort-fe/storage-cache-kit';

// 使用localStorage存储
await store.put('preferences', { theme: 'dark', fontSize: 16 });
const preferences = await store.get('preferences');

使用不同存储适配器

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 常量:

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

设置数据过期时间

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相关选项:

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 方式

// 使用 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 方式

// 使用 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. 使用专门的缓存服务

高级用法

命名空间

使用命名空间可以隔离不同模块或功能的存储数据:

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 }

数据加密

启用加密功能可以保护敏感数据:

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' });
// 数据将以加密形式存储

批量操作

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)));

自定义适配器

你可以创建并注册自己的存储适配器:

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 - 内存存储适配器

配置选项

interface StorageManagerOptions {
  // 默认存储适配器类型
  defaultAdapter?: AdapterType;
  
  // 默认过期时间(毫秒)
  defaultExpires?: number;
  
  // 是否默认加密数据
  defaultEncrypt?: boolean;
  
  // 命名空间前缀
  namespace?: string;
}

最佳实践

1. 使用await处理异步操作

虽然所有操作都返回Promise,但强烈建议使用await等待操作完成:

// 推荐
async function saveUserData() {
  await store.put('user', userData);
  console.log('用户数据已保存');
}

// 不推荐
function saveUserData() {
  store.put('user', userData);
  console.log('这条消息可能在数据实际保存前就显示了');
}

2. 适当设置过期时间

为敏感数据或临时数据设置合理的过期时间:

// 身份验证令牌 - 1小时过期
await store.put('authToken', token, { expires: 60 * 60 * 1000 });

// 用户偏好设置 - 长期存储(不设置过期时间)
await store.put('userPreferences', preferences);

3. 选择合适的存储类型

  • localStorage: 持久性数据,如用户偏好
  • sessionStorage: 会话级数据,如表单状态
  • cookie: 需要随HTTP请求发送的数据,如认证令牌
  • memory: 临时数据,如页面状态

4. 使用命名空间隔离数据

const authStore = new SimpleStore({ namespace: 'auth' });
const uiStore = new SimpleStore({ namespace: 'ui' });

5. 错误处理

try {
  await store.put('complexData', largeObject);
  await store.put('sensitiveData', sensitiveInfo, { encrypt: true });
} catch (error) {
  console.error('存储操作失败:', error);
  // 实现备用存储策略或通知用户
}

常见问题

1. 存储限制是多少?

  • localStorage/sessionStorage: 通常为5MB左右(因浏览器而异)
  • cookie: 通常每个域名限制为4KB
  • memory: 受可用内存限制

2. 数据是如何加密的?

默认使用Base64编码进行简单加密,主要用于防止偶然查看,不适用于高安全性需求。如需更强的加密,建议实现自定义加密适配器。

3. 如何在Node.js中实现持久化存储?

可以实现自定义适配器,例如基于文件系统或数据库的适配器:

// 文件系统适配器示例概念
import fs from 'fs';
import path from 'path';
import { StorageAdapter, StorageItem } from '@ort-fe/storage-cache-kit';

class FileSystemAdapter implements StorageAdapter {
  private basePath: string;
  
  constructor(basePath: string = './storage') {
    this.basePath = basePath;
    if (!fs.existsSync(basePath)) {
      fs.mkdirSync(basePath, { recursive: true });
    }
  }
  
  async setItem<T>(key: string, item: StorageItem<T>): Promise<void> {
    const filePath = path.join(this.basePath, `${key}.json`);
    await fs.promises.writeFile(filePath, JSON.stringify(item), 'utf8');
  }
  
  // 实现其他必要方法...
}

// 使用
const manager = new StorageManager();
manager.registerAdapter('file', new FileSystemAdapter('./data'));
await manager.set('config', { port: 3000 }, { adapter: 'file' });

4. 如何处理大型数据?

对于大型数据,建议:

  • 分割成更小的数据块存储
  • 考虑使用IndexedDB(需实现自定义适配器)
  • 对于Node.js,使用文件系统或数据库存储

5. 数据在不同浏览器标签页之间如何共享?

  • localStorage/cookie: 在同一域名下的所有标签页之间共享
  • sessionStorage: 仅在创建它的标签页中可用
  • memory: 仅在当前JavaScript上下文中可用

版本兼容性与功能支持

版本兼容性

浏览器兼容性

Storage Cache Kit库支持以下现代浏览器:

浏览器最低支持版本
Chrome61+
Firefox60+
Safari10.1+
Edge16+
Opera48+
iOS Safari10.3+
Android Browser76+

注意事项:

  • IE11不受支持,因为库使用了现代JavaScript特性
  • 较旧的浏览器可能需要使用Babel和相关polyfill进行转译

Node.js兼容性

Node.js版本兼容性
Node.js 18.x+完全支持
Node.js 16.x支持
Node.js 14.x部分支持(需要使用--harmony标志)
Node.js 12.x及以下不支持

性能考量

存储大小限制

存储类型典型限制备注
localStorage5-10MB每个域名
sessionStorage5-10MB每个域名,每个标签页
Cookie4KB每个Cookie
内存存储无硬性限制受可用内存限制

性能优化建议

  1. 数据分片

    • 将大型数据集分割成更小的块存储
    • 实现懒加载机制,按需获取数据
  2. 缓存策略

    • 为频繁访问的数据实现内存缓存层
    • 为不常变化的数据设置更长的过期时间
  3. 批量操作

    • 使用Promise.all进行批量读写操作
    • 实现事务性操作,确保数据一致性
  4. 压缩数据

    • 考虑在存储前压缩大型数据
    • 移除不必要的数据字段

安全性考量

  1. 敏感数据处理

    • 永远不要在客户端存储未加密的敏感信息
    • 使用强加密算法替代默认的简单加密
  2. 跨站脚本(XSS)防护

    • 存储前验证和清理所有用户输入数据
    • 使用内容安全策略(CSP)限制脚本访问
  3. Cookie安全

    • 使用securehttpOnly标志
    • 实施合适的SameSite策略
  4. 数据隔离

    • 使用命名空间隔离不同功能模块的数据
    • 实现最小权限原则,限制数据访问范围

本库支持功能

功能支持状态说明
存储类型
localStorage✅ 支持持久化存储,适合长期数据
sessionStorage✅ 支持会话级存储,浏览器关闭后清除
Cookie✅ 支持支持设置过期时间、路径、域等选项
内存存储✅ 支持临时存储,页面刷新后清除
功能特性
过期时间控制✅ 支持可为任何存储项设置毫秒级过期时间
命名空间✅ 支持隔离不同模块的存储数据
数据加密✅ 支持基本的数据加密功能
异步API✅ 支持所有操作都返回Promise
类型安全✅ 支持完整的TypeScript类型定义
自定义适配器✅ 支持可扩展自定义存储方式
环境支持
浏览器环境✅ 支持支持所有现代浏览器
Node.js环境✅ 支持自动适配为内存存储
跨标签页共享✅ 部分支持localStorage和Cookie支持
服务端渲染(SSR)✅ 支持自动检测环境
开发体验
简化API✅ 支持提供简洁易用的方法名
链式调用❌ 不支持使用Promise异步模式
批量操作✅ 支持通过Promise.all实现
事件监听❌ 不支持计划在未来版本添加
存储容量检测❌ 不支持计划在未来版本添加

许可证

MIT