1.1.2 • Published 5 months ago

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

Weekly downloads
-
License
MIT
Repository
github
Last release
5 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