Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

mem

Package Overview
Dependencies
Maintainers
3
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mem - npm Package Compare versions

Comparing version 6.0.1 to 6.1.0

25

index.js

@@ -7,7 +7,11 @@ 'use strict';

const mem = (fn, {
cacheKey = ([firstArgument]) => firstArgument,
cache = new Map(),
maxAge
} = {}) => {
const mem = (fn, options = {}) => {
// Automatically use WeakMap unless the user provided their own cache
const weakCache = options.cache || new WeakMap();
const {
cacheKey = ([firstArgument]) => firstArgument,
cache = new Map(),
maxAge
} = options;
if (typeof maxAge === 'number') {

@@ -20,4 +24,9 @@ mapAgeCleaner(cache);

if (cache.has(key)) {
return cache.get(key).data;
// Prefer WeakMap if the key allows it
const bestCache = key && (typeof key === 'object' || typeof key === 'function') ?
weakCache :
cache;
if (bestCache.has(key)) {
return bestCache.get(key).data;
}

@@ -27,3 +36,3 @@

cache.set(key, {
bestCache.set(key, {
data: cacheItem,

@@ -30,0 +39,0 @@ maxAge: maxAge ? Date.now() + maxAge : Infinity

{
"name": "mem",
"version": "6.0.1",
"version": "6.1.0",
"description": "Memoize functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input",

@@ -5,0 +5,0 @@ "license": "MIT",

@@ -7,3 +7,3 @@ # mem [![Build Status](https://travis-ci.org/sindresorhus/mem.svg?branch=master)](https://travis-ci.org/sindresorhus/mem)

By default, **only the first argument is considered** and it only works with [primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). If you need to cache multiple arguments or cache `object`s *by value*, use the `cacheKey` option.
By default, **only the first argument is considered** and it only works with [primitives](https://developer.mozilla.org/en-US/docs/Glossary/Primitive). If you need to cache multiple arguments or cache `object`s *by value*, have a look at alternative [caching strategies](#caching-strategy) below.

@@ -85,3 +85,78 @@

### Caching strategy
By default, only the first argument is compared via exact equality (`===`) to determine whether a call is identical.
```js
const power = mem((a, b) => Math.power(a, b));
power(2, 2); // => 4, stored in cache with the key 2 (number)
power(2, 3); // => 4, retrieved from cache at key 2 (number), it's wrong
```
You will have to use the `cache` and `cacheKey` options appropriate to your function. In this specific case, the following could work:
```js
const power = mem((a, b) => Math.power(a, b), {
cacheKey: arguments_ => arguments_.join(',')
});
power(2, 2); // => 4, stored in cache with the key '2,2' (both arguments as one string)
power(2, 3); // => 8, stored in cache with the key '2,3'
```
More advanced examples follow.
#### Example: Options-like argument
If your function accepts an object, it won't be memoized out of the box:
```js
const heavyMemoizedOperation = mem(heavyOperation);
heavyMemoizedOperation({full: true}); // Stored in cache with the object as key
heavyMemoizedOperation({full: true}); // Stored in cache with the object as key, again
// The objects look the same but for JS they're two different objects
```
You might want to serialize or hash them, for example using `JSON.stringify` or something like [serialize-javascript](https://github.com/yahoo/serialize-javascript), which can also serialize `RegExp`, `Date` and so on.
```js
const heavyMemoizedOperation = mem(heavyOperation, {cacheKey: JSON.stringify});
heavyMemoizedOperation({full: true}); // Stored in cache with the key '[{"full":true}]' (string)
heavyMemoizedOperation({full: true}); // Retrieved from cache
```
The same solution also works if it accepts multiple serializable objects:
```js
const heavyMemoizedOperation = mem(heavyOperation, {cacheKey: JSON.stringify});
heavyMemoizedOperation('hello', {full: true}); // Stored in cache with the key '["hello",{"full":true}]' (string)
heavyMemoizedOperation('hello', {full: true}); // Retrieved from cache
```
#### Example: Multiple non-serializable arguments
If your function accepts multiple arguments that aren't supported by `JSON.stringify` (e.g. DOM elements and functions), you can instead extend the initial exact equality (`===`) to work on multiple arguments using [`many-keys-map`](https://github.com/fregante/many-keys-map):
```js
const ManyKeysMap = require('many-keys-map');
const addListener = (emitter, eventName, listener) => emitter.on(eventName, listener);
const addOneListener = mem(addListener, {
cacheKey: arguments_ => arguments_, // Use *all* the arguments as key
cache: new ManyKeysMap() // Correctly handles all the arguments for exact equality
});
addOneListener(header, 'click', console.log); // `addListener` is run, and it's cached with the `arguments` array as key
addOneListener(header, 'click', console.log); // `addListener` is not run again
addOneListener(mainContent, 'load', console.log); // `addListener` is run, and it's cached with the `arguments` array as key
```
Better yet, if your function’s arguments are compatible with `WeakMap`, you should use [`deep-weak-map`](https://github.com/futpib/deep-weak-map) instead of `many-keys-map`. This will help avoid memory leaks.
## API

@@ -118,26 +193,13 @@

You can have it cache **all** the arguments by value with `JSON.stringify`, if they are compatible:
Refer to the [caching strategies](#caching-strategy) section for more information.
```js
const mem = require('mem');
mem(function_, {cacheKey: JSON.stringify});
```
Or you can use a more full-featured serializer like [serialize-javascript](https://github.com/yahoo/serialize-javascript) to add support for `RegExp`, `Date` and so on.
```js
const mem = require('mem');
const serializeJavascript = require('serialize-javascript');
mem(function_, {cacheKey: serializeJavascript});
```
##### cache
Type: `object`\
Default: `new Map()`
Default: `new Map()`, but it also intelligently uses `new WeakMap()` whenevever possible
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`](https://github.com/sindresorhus/quick-lru) for a LRU cache.
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 [`quick-lru`](https://github.com/sindresorhus/quick-lru) for a LRU cache.
Refer to the [caching strategies](#caching-strategy) section for more information.
### mem.clear(fn)

@@ -144,0 +206,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc