Blazing fast memoization library for JavaScript with comprehensive configuration options and React support
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
The main memoization functionality that wraps functions to cache their results based on arguments, providing significant performance improvements for expensive computations.
The primary memoization function that accepts a function to memoize and optional configuration options.
/**
* Memoize a function based on its arguments, potentially improving runtime performance
* @param fn - The function to memoize, or options when currying
* @param options - The memoization options to apply
* @returns The memoized function with additional methods and properties
*/
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>;Usage Examples:
import moize from "moize";
// Basic memoization
const add = (a: number, b: number) => a + b;
const memoizedAdd = moize(add);
console.log(memoizedAdd(2, 3)); // 5 (computed)
console.log(memoizedAdd(2, 3)); // 5 (cached)
// Memoization with options
const fibonacci = (n: number): number => {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
};
const memoizedFib = moize(fibonacci, {
maxSize: 100,
profileName: 'fibonacci'
});
// Curried usage (options first)
const deepMemoizer = moize({ isDeepEqual: true });
const memoizedDeepFn = deepMemoizer(someFunction);The enhanced function returned by moize with additional methods and properties for cache management.
type Moized<
MoizeableFn extends Moizeable = Moizeable,
CombinedOptions extends Options<MoizeableFn> = Options<MoizeableFn>
> = Memoized<MoizeableFn> & {
// Configuration properties
options: CombinedOptions;
originalFunction: MoizeableFn;
_microMemoizeOptions: Pick<CombinedOptions, 'isPromise' | 'maxSize' | 'onCacheAdd' | 'onCacheChange' | 'onCacheHit'> & {
isEqual: CombinedOptions['matchesArg'];
isMatchingKey: CombinedOptions['matchesKey'];
transformKey: CombinedOptions['transformArgs'];
};
// Cache state
cache: Cache<MoizeableFn>;
cacheSnapshot: Cache<MoizeableFn>;
expirations: Expiration[];
expirationsSnapshot: Expiration[];
// React-specific properties (when isReact: true)
contextTypes?: Record<string, Function>;
defaultProps?: Record<string, unknown>;
displayName?: string;
propTypes: Record<string, Function>;
// Cache management 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;
};
type Key<Arg extends any = any> = Arg[];
type Cache<MoizeableFn extends Moizeable = Moizeable> = BaseCache<MoizeableFn>;
type Expiration = {
expirationMethod: () => void;
key: Key;
timeoutId: ReturnType<typeof setTimeout>;
};The interface for memoization functions that can accept functions or return curried functions.
interface Moizer<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
>;
<MoizedFn extends Moized<Moizeable>>(fn: MoizedFn): Moized<
MoizedFn['fn'],
Options<MoizedFn> & DefaultOptions
>;
<MoizedFn extends Moized<Moizeable>, PassedOptions extends Options<MoizedFn>>(
fn: MoizedFn,
options: PassedOptions
): Moized<
MoizedFn['fn'],
Options<MoizedFn> & DefaultOptions & PassedOptions
>;
<PassedOptions extends Options<Moizeable>>(
options: PassedOptions
): Moizer<PassedOptions>;
}Moize can accept already memoized functions and merge options.
import moize from "moize";
const originalFn = (x: number) => x * 2;
const firstMemoized = moize(originalFn, { maxSize: 5 });
const secondMemoized = moize(firstMemoized, { maxAge: 1000 });
// secondMemoized has both maxSize: 5 and maxAge: 1000
console.log(secondMemoized.options); // Contains merged optionsWhen memoizing an already memoized function, options are merged with later options taking precedence.
const fn = (a: number, b: number) => a + b;
const memoized1 = moize(fn, { maxSize: 10, isDeepEqual: false });
const memoized2 = moize(memoized1, { maxSize: 20, maxAge: 5000 });
// Final options: { maxSize: 20, isDeepEqual: false, maxAge: 5000 }