Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
The p-memoize package is a promise-memoization library for JavaScript. It allows you to memoize the results of asynchronous functions, which can help improve performance by caching the results of expensive function calls and returning the cached result when the same inputs occur again.
Basic Memoization
This feature allows you to memoize an asynchronous function. The first call to the function with a specific input will take the usual time, but subsequent calls with the same input will return the cached result immediately.
const pMemoize = require('p-memoize');
const expensiveFunction = async (input) => {
// Simulate an expensive operation
return new Promise(resolve => setTimeout(() => resolve(input * 2), 1000));
};
const memoizedFunction = pMemoize(expensiveFunction);
(async () => {
console.log(await memoizedFunction(2)); // Waits 1 second, logs 4
console.log(await memoizedFunction(2)); // Logs 4 immediately
})();
Custom Cache
This feature allows you to use a custom cache implementation. In this example, QuickLRU is used as the cache, which provides a least-recently-used (LRU) cache mechanism.
const pMemoize = require('p-memoize');
const QuickLRU = require('quick-lru');
const expensiveFunction = async (input) => {
// Simulate an expensive operation
return new Promise(resolve => setTimeout(() => resolve(input * 2), 1000));
};
const cache = new QuickLRU({ maxSize: 1000 });
const memoizedFunction = pMemoize(expensiveFunction, { cache });
(async () => {
console.log(await memoizedFunction(2)); // Waits 1 second, logs 4
console.log(await memoizedFunction(2)); // Logs 4 immediately
})();
Cache Key Customization
This feature allows you to customize the cache key. By default, the cache key is generated based on the function arguments, but you can provide a custom function to generate the cache key.
const pMemoize = require('p-memoize');
const expensiveFunction = async (input) => {
// Simulate an expensive operation
return new Promise(resolve => setTimeout(() => resolve(input * 2), 1000));
};
const memoizedFunction = pMemoize(expensiveFunction, {
cacheKey: ([input]) => `key-${input}`
});
(async () => {
console.log(await memoizedFunction(2)); // Waits 1 second, logs 4
console.log(await memoizedFunction(2)); // Logs 4 immediately
})();
memoizee is a general-purpose memoization library for JavaScript. It supports both synchronous and asynchronous functions, and offers a wide range of configuration options, including custom cache size, expiration, and more. Compared to p-memoize, memoizee is more feature-rich but also more complex to configure.
lru-cache is a simple and efficient LRU (Least Recently Used) cache library for JavaScript. While it does not provide memoization out of the box, it can be used in conjunction with custom memoization logic to achieve similar results. It is more focused on providing a robust caching mechanism rather than memoization specifically.
moize is a high-performance memoization library for JavaScript that supports both synchronous and asynchronous functions. It offers a variety of configuration options, including custom cache keys, expiration, and more. moize is similar to p-memoize in terms of functionality but provides more advanced features and optimizations.
Memoize promise-returning & async functions
Useful for speeding up consecutive function calls by caching the result of calls with identical input.
By default, only the memoized function's first argument is considered via strict equality comparison. If you need to cache multiple arguments or cache object
s by value, have a look at alternative caching strategies below.
This package is similar to mem but with async-specific enhancements; in particular, it allows for asynchronous caches and does not cache rejected promises.
npm install p-memoize
import pMemoize from 'p-memoize';
import got from 'got';
const memoizedGot = pMemoize(got);
await memoizedGot('https://sindresorhus.com');
// This call is cached
await memoizedGot('https://sindresorhus.com');
Similar to the caching strategy for mem
with the following exceptions:
cache
. Special properties assigned to a returned promise will not be kept after resolution and every promise may need to resolve with a serializable object if caching results in a database..get()
, .has()
and .set()
methods on cache
can run asynchronously by returning a promise..set()
being provided an object with the properties value
and maxAge
, it will only be provided value
as the first argument. If you want to implement time-based expiry, consider doing so in cache
.Returns a memoized version of the given function.
Type: Function
Promise-returning or async function to be memoized.
Type: object
Type: Function
Default: arguments_ => arguments_[0]
Example: arguments_ => JSON.stringify(arguments_)
Determines the cache key for storing the result based on the function arguments. By default, only the first argument is considered.
A cacheKey
function can return any type supported by Map
(or whatever structure you use in the cache
option).
See the caching strategy section for more information.
Type: object | false
Default: new Map()
Use a different cache storage. Must implement the following methods: .has(key)
, .get(key)
, .set(key, value)
, .delete(key)
, and optionally .clear()
. You could for example use a WeakMap
instead or quick-lru
for a LRU cache. To disable caching so that only concurrent executions resolve with the same value, pass false
.
See the caching strategy section in the mem
package for more information.
Returns a decorator to memoize class methods or static class methods.
Notes:
--experimentalDecorators
; follow TypeScript’s docs.Type: object
Same as options for pMemoize()
.
import {pMemoizeDecorator} from 'p-memoize';
class Example {
index = 0
@pMemoizeDecorator()
async counter() {
return ++this.index;
}
}
class ExampleWithOptions {
index = 0
@pMemoizeDecorator()
async counter() {
return ++this.index;
}
}
Clear all cached data of a memoized function.
It will throw when given a non-memoized function.
import pMemoize from 'p-memoize';
import ExpiryMap from 'expiry-map';
import got from 'got';
const cache = new ExpiryMap(10000); // Cached values expire after 10 seconds
const memoizedGot = pMemoize(got, {cache});
import pMemoize from 'p-memoize';
import pReflect from 'p-reflect';
const memoizedGot = pMemoize(async (url, options) => pReflect(got(url, options)));
await memoizedGot('https://example.com');
// {isFulfilled: true, isRejected: false, value: '...'}
FAQs
Memoize promise-returning & async functions
The npm package p-memoize receives a total of 839,659 weekly downloads. As such, p-memoize popularity was classified as popular.
We found that p-memoize demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.