Skip to content

序列化与运行时存储

KeyStorage 使用字符串序列化器;后端可选择原生 Storage 或导出的内存实现。运行时检测只负责选后端,不保证持久性或可用性。

后端选择

isBrowser(): boolean 只检查 typeof window !== 'undefined'getStorage(): Storage 在浏览器返回 window.localStorage,否则每次返回新的 InMemoryStorage。它不捕获安全/访问错误,也不会在 localStorage 被阻止时回退。SSR 请求隔离或需要共享时,应显式构造并注入存储。浏览器会话存储通过 storage: window.sessionStorage 选择,没有独立的自动会话选择器。

InMemoryStorage 使用 Map<string, string> 实现 Storage

成员契约
length已保存的键数。
setItem(key, value): void保存或替换字符串。
getItem(key): string | null缺失返回 null。
removeItem(key): void存在则移除。
key(index): string | null返回插入顺序对应的键,越界返回 null。
clear(): void删除全部条目。

内存存储不触发原生 storage 事件,也不会跨进程/页面生命周期持久化。TypeScript API 要求字符串,不能依赖浏览器 Storage 对非字符串参数的运行时强制转换。

序列化器

Serializer<Serialized, Deserialized> 要求 serialize(value: any): Serializeddeserialize(value: Serialized): Deserialized。可选 deserializeLegacy(value: unknown) 用于旧广播负载,不用于普通 get() 读取。

API契约
JsonSerializerjsonSerializer类与单例,包装 JSON.stringify / JSON.parse,不做 Schema 校验,也不特殊处理 Date、BigInt、循环引用。
IdentitySerializer<T>两个方法都原样返回输入。
identitySerializer共享 IdentitySerializer<any>
typedIdentitySerializer<T>()将同一单例转换为 IdentitySerializer<T>,不新建对象。

JSON stringify 对循环引用/BigInt 可能抛错;对于不支持的顶层值,即便返回声明是 string,运行时仍可能返回 undefined,不要持久化这些值。原始字符串使用 typedIdentitySerializer<string>();对象 identity 序列化器不能作为 KeyStorage 的 Serializer<string, T>。自定义编解码器必须在读写方一致,并应拒绝无效输入,不应伪造有效值。

缓存、同步失败、广播快照及解绑见 KeyStorage

完整示例

ts
import {
  KeyStorage,
  InMemoryStorage,
  typedIdentitySerializer,
  type Serializer,
} from '@ahoo-wang/fetcher-storage';

const storage = new InMemoryStorage();
const dateCodec: Serializer<string, Date> = {
  serialize: (value: Date) => value.toISOString(),
  deserialize: value => {
    const date = new Date(value);
    if (Number.isNaN(date.getTime())) throw new Error('Invalid date');
    return date;
  },
};
const updatedAt = new KeyStorage({
  key: 'updatedAt',
  storage,
  serializer: dateCodec,
});
updatedAt.set(new Date('2026-01-01T00:00:00Z'));
const token = new KeyStorage({
  key: 'token',
  storage,
  serializer: typedIdentitySerializer<string>(),
});
token.set('demo-token');
console.assert(storage.getItem('token') === 'demo-token');
updatedAt.destroy();
token.destroy();
updatedAt.eventBus.destroy();
token.eventBus.destroy();

公开符号与源码

符号实现
isBrowserenv.ts:20
getStorageenv.ts:29
InMemoryStorageinMemoryStorage.ts:14
Serializerserializer.ts:19
JsonSerializerserializer.ts:41
IdentitySerializerserializer.ts:65
jsonSerializerserializer.ts:88
identitySerializerserializer.ts:92
typedIdentitySerializerserializer.ts:94

包索引

基于 Apache License 2.0 发布。