Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drop maxAge #37

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 2 additions & 15 deletions index.js
@@ -1,7 +1,6 @@
'use strict';
const mimicFn = require('mimic-fn');
const isPromise = require('p-is-promise');
const mapAgeCleaner = require('map-age-cleaner');

const cacheStore = new WeakMap();

Expand Down Expand Up @@ -31,30 +30,18 @@ const mem = (fn, options) => {
cachePromiseRejection: false
}, options);

if (typeof options.maxAge === 'number') {
mapAgeCleaner(options.cache);
}

const {cache} = options;
options.maxAge = options.maxAge || 0;

const setData = (key, data) => {
cache.set(key, {
data,
maxAge: Date.now() + options.maxAge
});
};

const memoized = function (...arguments_) {
const key = options.cacheKey(...arguments_);

if (cache.has(key)) {
return cache.get(key).data;
return cache.get(key);
}

const cacheItem = fn.call(this, ...arguments_);

setData(key, cacheItem);
cache.set(key, cacheItem);

if (isPromise(cacheItem) && options.cachePromiseRejection === false) {
// Remove rejected promises from cache unless `cachePromiseRejection` is set to `true`
Expand Down
1 change: 0 additions & 1 deletion package.json
Expand Up @@ -39,7 +39,6 @@
},
"devDependencies": {
"ava": "^1.4.1",
"delay": "^4.1.0",
"tsd": "^0.7.1",
"xo": "^0.24.0"
}
Expand Down
35 changes: 5 additions & 30 deletions readme.md
Expand Up @@ -2,8 +2,6 @@

> [Memoize](https://en.wikipedia.org/wiki/Memoization) functions - An optimization used to speed up consecutive function calls by caching the result of calls with identical input

Memory is automatically released when an item expires.


## Install

Expand Down Expand Up @@ -55,26 +53,6 @@ const memoized = mem(counter);
})();
```

```js
const mem = require('mem');
const got = require('got');
const delay = require('delay');

const memGot = mem(got, {maxAge: 1000});
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or I could restore this example with

+  const ExpiryMap = require('expiry-map');

+  const memGot = mem(got, {cache: new ExpiryMap(1000)});
-  const memGot = mem(got, {maxAge: 1000});


(async () => {
await memGot('sindresorhus.com');

// This call is cached
await memGot('sindresorhus.com');

await delay(2000);

// This call is not cached as the cache has expired
await memGot('sindresorhus.com');
})();
```


## API

Expand All @@ -90,13 +68,6 @@ Function to be memoized.

Type: `Object`

##### maxAge

Type: `number`<br>
Default: `Infinity`

Milliseconds until the cache expires.

##### cacheKey

Type: `Function`
Expand All @@ -110,7 +81,11 @@ You could for example change it to only cache on the first argument `x => JSON.s
Type: `Object`<br>
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`](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()`. For example uou could use:

- [`quick-lru`](https://github.com/sindresorhus/quick-lru) for a LRU cache;
- [`expiry-map`](https://github.com/SamVerschueren/expiry-map) to set an expiration date;
- `WeakMap` for automatic garbage collection (you'll also need to set `cacheKey: x => x` for this to work).

##### cachePromiseRejection

Expand Down
59 changes: 0 additions & 59 deletions test.js
@@ -1,5 +1,4 @@
import test from 'ava';
import delay from 'delay';
import mem from '.';

test('memoize', t => {
Expand Down Expand Up @@ -56,64 +55,6 @@ test.failing('memoize with Symbol arguments', t => {
t.is(memoized({foo: argument2}), 4);
});

test('maxAge option', async t => {
let i = 0;
const fixture = () => i++;
const memoized = mem(fixture, {maxAge: 100});
t.is(memoized(1), 0);
t.is(memoized(1), 0);
await delay(50);
t.is(memoized(1), 0);
await delay(200);
t.is(memoized(1), 1);
});

test('maxAge option deletes old items', async t => {
let i = 0;
const fixture = () => i++;
const cache = new Map();
const deleted = [];
const remove = cache.delete.bind(cache);
cache.delete = item => {
deleted.push(item);
return remove(item);
};

const memoized = mem(fixture, {maxAge: 100, cache});
t.is(memoized(1), 0);
t.is(memoized(1), 0);
t.is(cache.has(1), true);
await delay(50);
t.is(memoized(1), 0);
t.is(deleted.length, 0);
await delay(200);
t.is(memoized(1), 1);
t.is(deleted.length, 1);
t.is(deleted[0], 1);
});

test('maxAge items are deleted even if function throws', async t => {
let i = 0;
const fixture = () => {
if (i === 1) {
throw new Error('failure');
}

return i++;
};

const cache = new Map();
const memoized = mem(fixture, {maxAge: 100, cache});
t.is(memoized(1), 0);
t.is(memoized(1), 0);
t.is(cache.size, 1);
await delay(50);
t.is(memoized(1), 0);
await delay(200);
t.throws(() => memoized(1), 'failure');
t.is(cache.size, 0);
});

test('cacheKey option', t => {
let i = 0;
const fixture = () => i++;
Expand Down