Blazing fast memoization library for JavaScript with comprehensive configuration options and React support
npx @tessl/cli install tessl/npm-moize@6.1.0Moize is a consistently blazing fast memoization library for JavaScript and TypeScript. It handles multiple parameters without additional configuration and offers comprehensive options for cache management, performance optimization, and specialized use cases including React component memoization and promise caching.
npm install moizeimport moize from "moize";For CommonJS:
const moize = require("moize");For Node.js ESM:
import moize from "moize/mjs/index.mjs";import moize from "moize";
// Basic function memoization
const add = (a: number, b: number) => a + b;
const memoizedAdd = moize(add);
// Memoization with options
const fetchUser = async (id: string) => {
const response = await fetch(`/api/users/${id}`);
return response.json();
};
const memoizedFetchUser = moize(fetchUser, {
isPromise: true,
maxSize: 10,
maxAge: 30000, // 30 seconds
});
// Using chainable shortcut methods
const expensiveCalculation = (data: any[]) => data.reduce((a, b) => a + b.value, 0);
const memoizedCalculation = moize.deep.maxSize(5)(expensiveCalculation);
// React hook pattern (custom implementation)
import { useMoize } from './moize-hooks';
function MyComponent({ first, second }) {
const sum = useMoize((a: number, b: number) => a + b, [first, second]);
return <div>Sum: {sum}</div>;
}Moize is built around several key components:
Main memoization function with extensive configuration options for performance optimization and cache control.
interface Moize<DefaultOptions extends Options<Moizeable> = Options<Moizeable>> {
<MoizeableFn extends Moizeable>(fn: MoizeableFn): Moized<MoizeableFn, Options<MoizeableFn> & DefaultOptions>;
<MoizeableFn extends Moizeable, PassedOptions extends Options<MoizeableFn>>(
fn: MoizeableFn,
options: PassedOptions
): Moized<MoizeableFn, Options<MoizeableFn> & DefaultOptions & PassedOptions>;
<PassedOptions extends Options<Moizeable>>(
options: PassedOptions
): Moizer<PassedOptions>;
}
type AnyFn = (...args: any[]) => any;
type Moizeable = AnyFn & Record<string, any>;Methods for customizing how arguments and cache keys are compared for equality.
interface Moize {
deep: Moizer<{ isDeepEqual: true }>;
shallow: Moizer<{ isShallowEqual: true }>;
matchesArg<Matcher extends IsEqual>(argMatcher: Matcher): Moizer<{ matchesArg: Matcher }>;
matchesKey<Matcher extends IsMatchingKey>(keyMatcher: Matcher): Moizer<{ matchesKey: Matcher }>;
}
type IsEqual = (cacheKeyArg: any, keyArg: any) => boolean;
type IsMatchingKey = (cacheKey: Key, key: Key) => boolean;
type Key<Arg extends any = any> = Arg[];Methods for controlling cache size limits and time-to-live expiration.
interface Moize {
infinite: Moizer;
maxAge: MaxAge;
maxArgs<MaxArgs extends number>(args: MaxArgs): Moizer<{ maxArgs: MaxArgs }>;
maxSize<MaxSize extends number>(size: MaxSize): Moizer<{ maxSize: MaxSize }>;
}
interface MaxAge {
<MaxAge extends number>(maxAge: MaxAge): Moizer<{ maxAge: MaxAge }>;
<MaxAge extends number, UpdateExpire extends boolean>(
maxAge: MaxAge,
expireOptions: UpdateExpire
): Moizer<{ maxAge: MaxAge; updateExpire: UpdateExpire }>;
<MaxAge extends number, ExpireHandler extends OnExpire>(
maxAge: MaxAge,
expireOptions: ExpireHandler
): Moizer<{ maxAge: MaxAge; onExpire: ExpireHandler }>;
}
type OnExpire = (key: Key) => any;Specialized memoization methods for specific use cases like promises, React components, and serialization.
interface Moize {
promise: Moizer<{ isPromise: true }>;
react: Moizer<{ isReact: true }>;
serialize: Moizer<{ isSerialized: true }>;
serializeWith<Serializer extends Serialize>(serializer: Serializer): Moizer<{ isSerialized: true; serializer: Serializer }>;
}
type Serialize = (key: Key) => string[];Methods for transforming and manipulating arguments before caching.
interface Moize {
transformArgs<Transformer extends TransformKey>(transformer: Transformer): Moizer<{ transformArgs: Transformer }>;
updateCacheForKey<UpdateWhen extends UpdateCacheForKey>(updateCacheForKey: UpdateWhen): Moizer<{ updateCacheForKey: UpdateWhen }>;
}
type TransformKey = (key: Key) => Key;
type UpdateCacheForKey = (key: Key) => boolean;Methods for collecting and analyzing memoization performance statistics.
interface Moize {
clearStats(profileName?: string): void;
collectStats(isCollectingStats?: boolean): void;
getStats(profileName?: string): StatsObject;
isCollectingStats(): boolean;
profile<ProfileName extends string>(profileName: ProfileName): Moizer<{ profileName: ProfileName }>;
}
type StatsObject = {
calls: number;
hits: number;
usage: string;
};
type GlobalStatsObject = StatsObject & {
profiles?: Record<string, StatsProfile>;
};
type StatsProfile = {
calls: number;
hits: number;
};Methods available on memoized functions for direct cache access and manipulation.
type Moized<MoizeableFn extends Moizeable = Moizeable, CombinedOptions extends Options<MoizeableFn> = Options<MoizeableFn>> =
Memoized<MoizeableFn> & {
// Properties
cache: Cache<MoizeableFn>;
cacheSnapshot: Cache<MoizeableFn>;
expirations: Expiration[];
options: CombinedOptions;
originalFunction: MoizeableFn;
// Cache methods
clear(): void;
get(key: Key): any;
has(key: Key): boolean;
remove(key: Key): void;
set(key: Key, value: any): void;
keys(): Cache<MoizeableFn>['keys'];
values(): Cache<MoizeableFn>['values'];
// Statistics methods
clearStats(): void;
getStats(): StatsProfile;
isCollectingStats(): boolean;
// Introspection
isMoized(): true;
};Utility functions for working with memoized functions and composition.
interface Moize {
isMoized(value: any): value is Moized;
compose(...moizers: Array<Moize | Moizer>): Moizer;
}type Options<MoizeableFn extends Moizeable = Moizeable> = Partial<{
isDeepEqual: boolean;
isPromise: boolean;
isReact: boolean;
isSerialized: boolean;
isShallowEqual: boolean;
matchesArg: IsEqual;
matchesKey: IsMatchingKey;
maxAge: number;
maxArgs: number;
maxSize: number;
onCacheAdd: OnCacheOperation<MoizeableFn>;
onCacheChange: OnCacheOperation<MoizeableFn>;
onCacheHit: OnCacheOperation<MoizeableFn>;
onExpire: OnExpire;
profileName: string;
serializer: Serialize;
transformArgs: TransformKey;
updateCacheForKey: UpdateCacheForKey;
updateExpire: boolean;
}>;
type OnCacheOperation<MoizeableFn extends Moizeable = Moizeable> = (
cache: Cache<MoizeableFn>,
options: Options<MoizeableFn>,
moized: (...args: any[]) => any
) => void;