soon-storage
v3.0.0
Published
A type-safe storage solution for localStorage and sessionStorage with built-in TypeScript support, ensuring robust and scalable browser data persistence.
Maintainers
Readme
soon-storage 🚀
Language / 语言
English
A type-safe storage solution for localStorage, sessionStorage, and IndexedDB with built-in TypeScript support, ensuring robust and scalable browser data persistence.
Features ✨
- 🔐 Type-Safe: Built with TypeScript for strong typing and better developer experience.
- 📦 Flexible Storage: Supports
localStorage,sessionStorage, andIndexedDB. - ⚙️ Customizable: Easily define custom data transformations.
- ⏰ Expiration Support: Set expiration times for stored items.
- 🔒 Encryption/Decryption: Built-in support for data encryption and decryption.
- 🚀 Batch Operations: Support for batch get, set, and remove operations for improved performance.

Installation
npm install soon-storageUsage
1. Synchronous Storage (localStorage/sessionStorage)
import { createStorage, parsers as p } from "soon-storage";
const storage = createStorage({
// stored key prefix
prefix: "soon-",
// choose localStorage or SessionStorage
provider: () => localStorage,
// string,number,boolean,json are built-in transform method
// you can define your own transform like below for a Date type
transforms: {
name: p.string("Guest"), // field with default value
age: p.number(() => Math.random() * 100), // field with default value function
birth: p.any({
getter: (val) => (val === null ? null : new Date(val)),
setter: (val) => val.toISOString(),
}),
graduated: p.boolean(false), // field with default value
school: p.json<{
name: string;
address: string;
}>(), // field without default value
},
});
// set a key-value
storage.birth.set(new Date("2008-08-08"));
// get a key-value
storage.birth.get();
// remove a key-value
storage.birth.remove();
// Get values with and without defaults
console.log(storage.name.get()); // Returns "Guest" if not set
console.log(storage.age.get()); // Returns random number if not set
console.log(storage.graduated.get()); // Returns false if not set
console.log(storage.school.get()); // Returns null if not set
// Using expires parser for explicit expiration support
const storageWithExpires = createStorage({
prefix: "expires-",
provider: () => localStorage,
define: {
// Using expires parser
userSession: p.expires<{ userId: string; token: string }>(),
tempData: p.expires<string>("default"),
},
});
// Set with expiration
storageWithExpires.userSession.set({ userId: "123", token: "abc123" }, expirationTime);
// Set without expiration
storageWithExpires.tempData.set("temporary value");
// Get values
const userSession = storageWithExpires.userSession.get();
const tempData = storageWithExpires.tempData.get();
//set all key-values
storage.$.setAll({
name: "Lucy",
age: 100,
birth: new Date(),
graduated: false,
school: {
name: "Green Land",
address: "Qingdao",
},
});
// get all key-values
const allData = storage.$.getAll();
console.log(allData);
// remove all key-values
// only this instance keys would be removed
storage.$.removeAll();
2. Asynchronous Storage (IndexedDB)
import { createStorageAsync, parsers as p, indexedDBProvider } from "soon-storage";
// Create IndexedDB storage instance
const indexedDbStorage = indexedDBProvider('my-db', 'my-store');
const asyncStorage = createStorageAsync({
prefix: "async-",
provider: () => indexedDbStorage,
transforms: {
name: p.string("Guest"),
age: p.number(18),
isAdmin: p.boolean(false),
},
});
// Async operations
await asyncStorage.name.set("John");
const name = await asyncStorage.name.get();
await asyncStorage.name.remove();
// Batch operations
await asyncStorage.$.setAll({ name: "Alice", age: 25, isAdmin: true });
const allData = await asyncStorage.$.getAll();
await asyncStorage.$.removeAll();
3. Encryption/Decryption
import { createStorage, parsers as p } from "soon-storage";
// Simple encryption/decryption functions
const encrypt = (data: string) => btoa(data);
const decrypt = (data: string) => atob(data);
const secureStorage = createStorage({
prefix: "secure-",
provider: () => localStorage,
define: {
// Add encryption/decryption to parsers
token: p.string(null, [encrypt, decrypt]),
userData: p.json<{ id: number; name: string }>(null, [encrypt, decrypt]),
},
});
// Data will be encrypted when stored and decrypted when retrieved
secureStorage.token.set("secret-token-123");
const token = secureStorage.token.get(); // Returns "secret-token-123"
4. Key Encryption
Per-key Key Encryption
You can now specify different key encryption processors for each key:
import { createStorage, parsers as p } from "soon-storage";
// Different key encryption functions for different keys
const encryptUserKey = (key: string) => btoa(key);
const encryptTokenKey = (key: string) => btoa(btoa(key)); // Double encryption for token
const storageWithPerKeyEncryption = createStorage({
prefix: "app-",
provider: () => localStorage,
define: {
// Username with its own key encryption
username: p.string(null, undefined, encryptUserKey),
// Token with double encryption
token: p.string(null, undefined, encryptTokenKey),
// Age with no key encryption
age: p.number(),
},
});
// Keys will be encrypted with their respective encryption methods
storageWithPerKeyEncryption.username.set("john");
storageWithPerKeyEncryption.token.set("secret-token");
storageWithPerKeyEncryption.age.set(30);
// Keys will be automatically decrypted when retrieved
const username = storageWithPerKeyEncryption.username.get();
const token = storageWithPerKeyEncryption.token.get();
const age = storageWithPerKeyEncryption.age.get();
API Reference
createStorage(config)
Creates a synchronous storage instance.
Parameters
config: Configuration objectprefix: Optional key prefix for stored itemsprovider: Function that returns a storage provider (localStorage or sessionStorage)define: Object defining data transformations for each field
Returns
- A storage object with methods for each defined field and batch operations.
createStorageAsync(config)
Creates an asynchronous storage instance.
Parameters
config: Configuration object (same as createStorage)
Returns
- A storage object with async methods for each defined field and batch operations.
indexedDBProvider(dbName, storeName)
Creates an IndexedDB storage provider.
Parameters
dbName: Optional database name (default: 'soon-storage')storeName: Optional object store name (default: 'storage')
Returns
- An IndexedDB storage provider with batch support.
Parsers
p.string(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): String parserp.number(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): Number parserp.boolean(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): Boolean parserp.json<T>(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): JSON parserp.expires<T>(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): Expiring value parserp.any<T>({ getter, setter }, [beforeSet, afterGet]?, keyProcessor?): Custom parser
Processor Functions
beforeSet(value): Process value before storageafterGet(value): Process value after retrievalkeyProcessor(key): Process key before storage (optional, used for key encryption)
License
MIT License
中文
一个类型安全的存储解决方案,支持 localStorage、sessionStorage 和 IndexedDB,内置 TypeScript 支持,确保健壮且可扩展的浏览器数据持久化。
特性 ✨
- 🔐 类型安全:使用 TypeScript 构建,提供强大的类型检查和更好的开发体验。
- 📦 灵活存储:支持
localStorage、sessionStorage和IndexedDB。 - ⚙️ 可定制:轻松定义自定义数据转换。
- ⏰ 过期支持:为存储项设置过期时间。
- 🔒 加密/解密:内置数据加密和解密支持。
- 🚀 批量操作:支持批量获取、设置和删除操作,提高性能。

安装
npm install soon-storage使用
1. 同步存储 (localStorage/sessionStorage)
import { createStorage, parsers as p } from "soon-storage";
const storage = createStorage({
// 存储键前缀
prefix: "soon-",
// 选择 localStorage 或 SessionStorage
provider: () => localStorage,
// string,number,boolean,json 是内置的转换方法
// 你可以像下面这样为 Date 类型定义自己的转换
define: {
name: p.string("Guest"), // 带默认值的字段
age: p.number(() => Math.random() * 100), // 带默认值函数的字段
birth: p.any({
getter: (val) => (val === null ? null : new Date(val)),
setter: (val) => val.toISOString(),
}),
graduated: p.boolean(false), // 带默认值的字段
school: p.json<{
name: string;
address: string;
}>(), // 不带默认值的字段
},
});
// 设置键值对
storage.birth.set(new Date("2008-08-08"));
// 获取键值对
storage.birth.get();
// 删除键值对
storage.birth.remove();
// 获取带默认值和不带默认值的值
console.log(storage.name.get()); // 如果未设置,返回 "Guest"
console.log(storage.age.get()); // 如果未设置,返回随机数
console.log(storage.graduated.get()); // 如果未设置,返回 false
console.log(storage.school.get()); // 如果未设置,返回 null
// 使用 expires 解析器获得显式过期支持
const storageWithExpires = createStorage({
prefix: "expires-",
provider: () => localStorage,
define: {
// 使用 expires 解析器
userSession: p.expires<{ userId: string; token: string }>(),
tempData: p.expires<string>("default"),
},
});
// 设置带过期时间的值
storageWithExpires.userSession.set({ userId: "123", token: "abc123" }, expirationTime);
// 设置不带过期时间的值
storageWithExpires.tempData.set("temporary value");
// 获取值
const userSession = storageWithExpires.userSession.get();
const tempData = storageWithExpires.tempData.get();
// 设置所有键值对
storage.$.setAll({
name: "Lucy",
age: 100,
birth: new Date(),
graduated: false,
school: {
name: "Green Land",
address: "Qingdao",
},
});
// 获取所有键值对
const allData = storage.$.getAll();
console.log(allData);
// 删除所有键值对
// 只会删除此实例的键
storage.$.removeAll();
2. 异步存储 (IndexedDB)
import { createStorageAsync, parsers as p, indexedDBProvider } from "soon-storage";
// 创建 IndexedDB 存储实例
const indexedDbStorage = indexedDBProvider('my-db', 'my-store');
const asyncStorage = createStorageAsync({
prefix: "async-",
provider: () => indexedDbStorage,
define: {
name: p.string("Guest"),
age: p.number(18),
isAdmin: p.boolean(false),
},
});
// 异步操作
await asyncStorage.name.set("John");
const name = await asyncStorage.name.get();
await asyncStorage.name.remove();
// 批量操作
await asyncStorage.$.setAll({ name: "Alice", age: 25, isAdmin: true });
const allData = await asyncStorage.$.getAll();
await asyncStorage.$.removeAll();
3. 加密/解密
import { createStorage, parsers as p } from "soon-storage";
// 简单的加密/解密函数
const encrypt = (data: string) => btoa(data);
const decrypt = (data: string) => atob(data);
const secureStorage = createStorage({
prefix: "secure-",
provider: () => localStorage,
define: {
// 为解析器添加加密/解密
token: p.string(null, [encrypt, decrypt]),
userData: p.json<{ id: number; name: string }>(null, [encrypt, decrypt]),
},
});
// 数据存储时会被加密,检索时会被解密
secureStorage.token.set("secret-token-123");
const token = secureStorage.token.get(); // 返回 "secret-token-123"
4. 键加密
每个键的独立键加密
现在你可以为每个键指定不同的键加密处理器:
import { createStorage, parsers as p } from "soon-storage";
// 不同键的不同加密函数
const encryptUserKey = (key: string) => btoa(key);
const encryptTokenKey = (key: string) => btoa(btoa(key)); // Token 使用双重加密
const storageWithPerKeyEncryption = createStorage({
prefix: "app-",
provider: () => localStorage,
define: {
// 用户名使用自己的键加密
username: p.string(null, undefined, encryptUserKey),
// Token 使用双重加密
token: p.string(null, undefined, encryptTokenKey),
// 年龄不使用键加密
age: p.number(),
},
});
// 键会使用各自的加密方法加密
storageWithPerKeyEncryption.username.set("john");
storageWithPerKeyEncryption.token.set("secret-token");
storageWithPerKeyEncryption.age.set(30);
// 键会自动解密
const username = storageWithPerKeyEncryption.username.get();
const token = storageWithPerKeyEncryption.token.get();
const age = storageWithPerKeyEncryption.age.get();
API 参考
createStorage(config)
创建一个同步存储实例。
参数
config: 配置对象prefix: 存储项的可选键前缀provider: 返回存储提供者的函数(localStorage 或 sessionStorage)define: 定义每个字段的数据转换的对象
返回值
- 一个存储对象,具有每个定义字段的方法和批量操作。
createStorageAsync(config)
创建一个异步存储实例。
参数
config: 配置对象(与 createStorage 相同)
返回值
- 一个存储对象,具有每个定义字段的异步方法和批量操作。
indexedDBProvider(dbName, storeName)
创建一个 IndexedDB 存储提供者。
参数
dbName: 可选的数据库名称(默认: 'soon-storage')storeName: 可选的对象存储名称(默认: 'storage')
返回值
- 一个带有批量支持的 IndexedDB 存储提供者。
解析器
p.string(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): 字符串解析器p.number(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): 数字解析器p.boolean(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): 布尔值解析器p.json<T>(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): JSON 解析器p.expires<T>(defaultValue?, [beforeSet, afterGet]?, keyProcessor?): 带过期时间的解析器p.any<T>({ getter, setter }, [beforeSet, afterGet]?, keyProcessor?): 自定义解析器
处理器函数
beforeSet(value): 存储前处理值afterGet(value): 检索后处理值keyProcessor(key): 存储前处理键(可选,用于键加密)
许可证
MIT 许可证
