Skip to content

Serialization and runtime storage

Use a string serializer with KeyStorage; use a native Storage backend or the exported in-memory implementation. Runtime detection selects a backend, not a durability or availability guarantee.

Backend selection

isBrowser(): boolean only checks typeof window !== 'undefined'. getStorage(): Storage returns window.localStorage in that case, otherwise a new InMemoryStorage on each call. It does not catch security/access errors or fall back when localStorage is blocked. For SSR request isolation or deliberate sharing, construct and inject the storage explicitly. Browser session storage is selected by passing storage: window.sessionStorage; there is no separate automatic session selector.

InMemoryStorage implements Storage using Map<string, string>:

MemberContract
lengthNumber of stored keys.
setItem(key, value): voidStore/replace string value.
getItem(key): string | nullMissing key returns null.
removeItem(key): voidRemove if present.
key(index): string | nullInsertion-order key; outside range returns null.
clear(): voidRemove every entry.

Memory storage does not dispatch native storage events or persist across process/page lifetimes. Its TypeScript API expects strings; do not rely on the runtime string coercion of browser Storage for non-string inputs.

Serializers

Serializer<Serialized, Deserialized> requires serialize(value: any): Serialized and deserialize(value: Serialized): Deserialized. Optional deserializeLegacy(value: unknown) supports old broadcast payloads, not ordinary get() reads.

APIContract
JsonSerializer, jsonSerializerClass and singleton wrapping JSON.stringify / JSON.parse. No schema validation or special handling of Date/BigInt/cycles.
IdentitySerializer<T>Both methods return their input unchanged.
identitySerializerShared IdentitySerializer<any>.
typedIdentitySerializer<T>()Same singleton cast to IdentitySerializer<T>, not a new object.

JSON stringify can throw for cycles/BigInt, and its runtime output for unsupported top-level values can be undefined despite the string return declaration. Do not persist such values. For a raw string use typedIdentitySerializer<string>(); an object identity serializer is not a valid Serializer<string, T> for KeyStorage. Custom codecs must agree across readers/writers and throw for malformed input rather than fabricate a valid value.

See KeyStorage for caching, synchronous failures, broadcast snapshots, and listener cleanup.

Complete example

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

Public symbols and source

SymbolImplementation
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

Package index

Released under the Apache License 2.0.