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
Methods available on memoized functions for direct cache access, manipulation, and introspection, enabling fine-grained control over cached data.
Direct access to the current cache state and snapshots.
interface Moized {
/**
* Current cache state containing all cached entries
*/
cache: Cache<MoizeableFn>;
/**
* Snapshot of cache state at the time of memoization creation
*/
cacheSnapshot: Cache<MoizeableFn>;
/**
* Array of active expirations for TTL-based caching
*/
expirations: Expiration[];
/**
* Snapshot of expirations at the time of memoization creation
*/
expirationsSnapshot: Expiration[];
}
type Cache<MoizeableFn extends Moizeable = Moizeable> = BaseCache<MoizeableFn>;
type Expiration = {
expirationMethod: () => void;
key: Key;
timeoutId: ReturnType<typeof setTimeout>;
};Usage Examples:
import moize from "moize";
const fibonacci = (n: number): number => {
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
};
const memoizedFib = moize.maxSize(10)(fibonacci);
// Generate some cached entries
memoizedFib(5);
memoizedFib(8);
memoizedFib(10);
// Inspect cache state
console.log('Cache entries:', memoizedFib.cache.size);
console.log('Cache keys:', memoizedFib.keys());
console.log('Cache values:', memoizedFib.values());
// For TTL-enabled functions
const apiCall = moize.maxAge(30000)(async (endpoint: string) => {
const response = await fetch(endpoint);
return response.json();
});
// Check active expirations
console.log('Active expirations:', apiCall.expirations.length);Get specific cached values using cache keys.
interface Moized {
/**
* Retrieve a cached value for the given key
* @param key The cache key (argument array) to look up
* @returns The cached value, or undefined if not found
*/
get(key: Key): any;
/**
* Check if a cache entry exists for the given key
* @param key The cache key (argument array) to check
* @returns Whether the key exists in cache
*/
has(key: Key): boolean;
}
type Key<Arg extends any = any> = Arg[];Usage Examples:
import moize from "moize";
const add = (a: number, b: number) => a + b;
const memoizedAdd = moize(add);
// Call function to cache result
memoizedAdd(2, 3); // 5
// Retrieve cached value directly
const cachedResult = memoizedAdd.get([2, 3]);
console.log(cachedResult); // 5
// Check if key exists
console.log(memoizedAdd.has([2, 3])); // true
console.log(memoizedAdd.has([1, 1])); // false
// Complex key example
const processUser = (user: { id: string; name: string }) => {
return `User: ${user.name} (${user.id})`;
};
const memoizedProcess = moize.deep(processUser);
const userObj = { id: "123", name: "Alice" };
memoizedProcess(userObj);
// For deep equality, must use equivalent object
console.log(memoizedProcess.has([userObj])); // true
console.log(memoizedProcess.has([{ id: "123", name: "Alice" }])); // true (deep equality)Directly manipulate cache entries by adding, updating, or removing cached values.
interface Moized {
/**
* Manually set a cache entry
* @param key The cache key (argument array)
* @param value The value to cache
*/
set(key: Key, value: any): void;
/**
* Remove a specific cache entry
* @param key The cache key (argument array) to remove
*/
remove(key: Key): void;
/**
* Clear all cached entries
*/
clear(): void;
}Usage Examples:
import moize from "moize";
const expensiveCalculation = (n: number) => {
console.log(`Computing for ${n}`);
return n * n * n;
};
const memoized = moize.maxSize(5)(expensiveCalculation);
// Pre-populate cache with known values
memoized.set([1], 1);
memoized.set([2], 8);
memoized.set([3], 27);
console.log(memoized(1)); // 1 (from cache, no computation)
console.log(memoized(2)); // 8 (from cache, no computation)
console.log(memoized(4)); // 64 (computed, since not pre-cached)
// Remove specific entry
memoized.remove([2]);
console.log(memoized.has([2])); // false
// Clear all cache
memoized.clear();
console.log(memoized.keys().length); // 0
// Update existing cache entry
memoized(5); // 125 (computed)
memoized.set([5], 999); // Override with custom value
console.log(memoized(5)); // 999 (custom value)Inspect all cache keys and values for debugging and analysis.
interface Moized {
/**
* Get all cache keys
* @returns Array-like object containing all cache keys
*/
keys(): Cache<MoizeableFn>['keys'];
/**
* Get all cached values
* @returns Array-like object containing all cached values
*/
values(): Cache<MoizeableFn>['values'];
}Usage Examples:
import moize from "moize";
const processData = (type: string, data: any[]) => {
return { type, count: data.length, processed: true };
};
const memoized = moize.maxSize(10)(processData);
// Generate some cache entries
memoized("users", [1, 2, 3]);
memoized("posts", [{ id: 1 }, { id: 2 }]);
memoized("comments", []);
// Inspect all keys
const keys = Array.from(memoized.keys());
console.log('Cache keys:', keys);
// [["users", [1, 2, 3]], ["posts", [{ id: 1 }, { id: 2 }]], ["comments", []]]
// Inspect all values
const values = Array.from(memoized.values());
console.log('Cache values:', values);
// [
// { type: "users", count: 3, processed: true },
// { type: "posts", count: 2, processed: true },
// { type: "comments", count: 0, processed: true }
// ]
// Debug cache contents
function debugCache(memoizedFn: any, name: string) {
console.log(`\n=== ${name} Cache Debug ===`);
console.log(`Cache size: ${Array.from(memoizedFn.keys()).length}`);
const keys = Array.from(memoizedFn.keys());
const values = Array.from(memoizedFn.values());
keys.forEach((key, index) => {
console.log(`Key ${index}:`, JSON.stringify(key));
console.log(`Value ${index}:`, values[index]);
});
}
debugCache(memoized, 'processData');Get information about the memoized function configuration and original function.
interface Moized {
/**
* The original unmemoized function
*/
originalFunction: MoizeableFn;
/**
* The options used to create this memoized function
*/
options: CombinedOptions;
/**
* Internal micro-memoize options (for advanced introspection)
*/
_microMemoizeOptions: MicroMemoizeOptions<MoizeableFn>;
/**
* Type guard function that always returns true for memoized functions
* @returns Always true (indicates this is a memoized function)
*/
isMoized(): true;
}Usage Examples:
import moize from "moize";
const originalAdd = (a: number, b: number) => a + b;
const memoizedAdd = moize.maxSize(20).maxAge(5000).profile('math')(originalAdd);
// Access original function
console.log(memoizedAdd.originalFunction === originalAdd); // true
console.log(memoizedAdd.originalFunction.name); // "originalAdd"
// Inspect configuration
console.log(memoizedAdd.options);
// {
// maxSize: 20,
// maxAge: 5000,
// profileName: 'math',
// isDeepEqual: false,
// isPromise: false,
// // ... other default options
// }
// Type checking
console.log(memoizedAdd.isMoized()); // true
// Check if a function is memoized
function isMemoizedFunction(fn: any): boolean {
return typeof fn === 'function' && typeof fn.isMoized === 'function' && fn.isMoized();
}
console.log(isMemoizedFunction(memoizedAdd)); // true
console.log(isMemoizedFunction(originalAdd)); // false
// Create cache debugging utility
function createCacheInspector(memoizedFn: any) {
return {
getCacheInfo() {
return {
size: Array.from(memoizedFn.keys()).length,
maxSize: memoizedFn.options.maxSize,
maxAge: memoizedFn.options.maxAge,
profileName: memoizedFn.options.profileName,
hasExpirations: memoizedFn.expirations.length > 0
};
},
dumpCache() {
const keys = Array.from(memoizedFn.keys());
const values = Array.from(memoizedFn.values());
return keys.map((key, index) => ({
key,
value: values[index],
index
}));
},
findByKey(searchKey: any[]) {
const keys = Array.from(memoizedFn.keys());
const values = Array.from(memoizedFn.values());
const index = keys.findIndex(key =>
JSON.stringify(key) === JSON.stringify(searchKey)
);
return index >= 0 ? { key: keys[index], value: values[index] } : null;
}
};
}
const inspector = createCacheInspector(memoizedAdd);
memoizedAdd(1, 2);
memoizedAdd(3, 4);
console.log(inspector.getCacheInfo());
console.log(inspector.dumpCache());
console.log(inspector.findByKey([1, 2]));