memoize-cache
Advanced tools
Comparing version 5.0.4 to 6.0.0
@@ -1,18 +0,1 @@ | ||
var keyGetter = require('memoize-cache-utils/key-getter') | ||
var keysGetter = require('memoize-cache-utils/keys-getter') | ||
function callbackify (func) { | ||
return function _callbackify () { | ||
// get arguments | ||
var context = this | ||
var args = Array.prototype.slice.call(arguments, 0, -1) | ||
var cb = arguments[arguments.length - 1] | ||
try { | ||
var output = func.apply(context, args) | ||
} catch (e) { | ||
return cb(e) | ||
} | ||
cb(null, output) | ||
} | ||
} | ||
/* | ||
@@ -26,8 +9,8 @@ | ||
this.opts = opts = opts || {} | ||
this.getCacheKey = keyGetter(opts.key) | ||
this.getTags = keysGetter(opts.tags) | ||
this.getCacheKey = opts.getKey || function () { return '_default' } | ||
this.getTags = opts.getTags || function () { return [] } | ||
this.getMaxAge = typeof opts.maxAge !== 'function' ? function () { return opts.maxAge } : opts.maxAge | ||
this.serialize = opts.serializeAsync || (opts.serialize && callbackify(opts.serialize)) || function (v, cb) { cb(null, v) } | ||
this.deserialize = opts.deserializeAsync || (opts.deserialize && callbackify(opts.deserialize)) || function (v, cb) { cb(null, v) } | ||
this.serialize = opts.serialize || function (v) { return v } | ||
this.deserialize = opts.deserialize || function (v) { return v } | ||
@@ -53,2 +36,3 @@ this.maxValidity = typeof opts.maxValidity === 'undefined' | ||
var keys = { key: k, tags: tags } | ||
this.set(keys, maxValidity, maxAge, output, next) | ||
@@ -60,14 +44,7 @@ return keys | ||
next = next || function () {} // next is optional | ||
var payload | ||
var set = this._set.bind(this) | ||
var serialize = this.serialize | ||
serialize(output, function (err, data) { | ||
var payload | ||
if (err) { | ||
return next(err) | ||
} | ||
payload = { data: data, maxValidity: maxValidity } | ||
set(keys, payload, maxAge, next) | ||
}) | ||
payload = { data: this.serialize(output), maxValidity: maxValidity } | ||
set(keys, payload, maxAge, next) | ||
} | ||
@@ -104,13 +81,8 @@ | ||
data = payload.data | ||
deserialize(data, function (err, output) { | ||
if (err) { | ||
return next(err) | ||
} | ||
next(null, { | ||
timing: Date.now() - t0, | ||
cached: true, | ||
key: key, | ||
hit: output, | ||
stale: Boolean(maxValidity && maxValidity < Date.now()) | ||
}) | ||
next(null, { | ||
timing: Date.now() - t0, | ||
cached: true, | ||
key: key, | ||
hit: deserialize(data), | ||
stale: Boolean(maxValidity && maxValidity < Date.now()) | ||
}) | ||
@@ -117,0 +89,0 @@ }) |
{ | ||
"name": "memoize-cache", | ||
"version": "5.0.4", | ||
"version": "6.0.0", | ||
"description": "A cache support for memoized functions", | ||
@@ -33,5 +33,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"little-ds-toolkit": "0.4.0", | ||
"memoize-cache-utils": "^0.1.1" | ||
"little-ds-toolkit": "^1.1.0" | ||
} | ||
} |
@@ -23,4 +23,4 @@ memoize-cache | ||
The constructor takes an option object with 3 optional attributes: | ||
* key: a function used to extract the cache key (used in the push and query method for storing, retrieving the cached value). The key returned should be a string or it will be converted to JSON and then md5. Default: a function returning a fixed key. The value won't be cached if the function returns null | ||
* tags: a function that returns an array of tags (strings). You can use that for purging a set of items from the cache. | ||
* getKey: a function used to extract the cache key (used in the push and query method for storing, retrieving the cached value). The key returned can be any value (when using cache-ram and ES2015 maps and sets are supported). Default: a function returning a fixed key. The value won't be cached if the function returns null. | ||
* getTags: a function that returns an array of tags (strings). You can use that for purging a set of items from the cache. | ||
* maxLen: the maximum number of items stored in the cache. Default: Infinity. Cache items will be purged using an LRU algorithm | ||
@@ -31,4 +31,2 @@ * maxAge: the maximum age of the item stored in the cache (in seconds). Default: Infinity. You can also pass a function that will calculate the ttl of a specific item (0 will mean no cache). The function will take the same arguments as the "push" method (an array of inputs and the output). | ||
* deserialize: it is an optional function that deserialize the value stored (takes a value, returns a value). | ||
* serializeAsync: it is an optional function that serialize the value stored, it returns using a callback. It can be used for pruning part of the object we don't want to save or even using a custom compression algorithm | ||
* deserializeAsync: it is an optional function that deserialize the value stored, it returns using a callback. | ||
@@ -45,3 +43,3 @@ Example: | ||
// every item will be considered stale and purged after 20 seconds. | ||
var cache = new Cache({ key: function (config){ | ||
var cache = new Cache({ getKey: function (config){ | ||
return config.id; | ||
@@ -99,3 +97,3 @@ } }, maxLen: 100, maxAge: 20000); | ||
It takes as arguments the same arguments of the function. It returns the cache key. | ||
It uses the function passed in the factory function. If it returns a string it uses it as key. In case it is not a string it tries to serialize it to JSON and then to an hash (using md5). | ||
It uses the function passed in the factory function. | ||
@@ -102,0 +100,0 @@ The cache object |
66
tags.js
@@ -1,45 +0,23 @@ | ||
function Bucket (arr) { | ||
arr = arr || [] | ||
this.data = {} | ||
this.len = 0 | ||
for (var i = 0, len = arr.length; i < len; i++) { | ||
this.add(arr[i]) | ||
} | ||
}; | ||
var utils = require('./utils') | ||
Bucket.prototype.has = function (key) { | ||
return key in this.data | ||
} | ||
var getSet = utils.getSet | ||
var getMap = utils.getMap | ||
var setToArray = utils.setToArray | ||
Bucket.prototype.add = function (key) { | ||
this.len++ | ||
this.data[key] = true | ||
function Tags (forceLegacy) { | ||
this.forceLegacy = forceLegacy | ||
this.keysToTags = getMap(forceLegacy) | ||
this.tagsToKeys = getMap(forceLegacy) | ||
} | ||
Bucket.prototype.del = function (key) { | ||
if (this.has(key)) { | ||
delete this.data[key] | ||
this.len-- | ||
} | ||
} | ||
Bucket.prototype.toArray = function () { | ||
return Object.keys(this.data) | ||
} | ||
function Tags () { | ||
this.keysToTags = {} | ||
this.tagsToKeys = {} | ||
} | ||
Tags.prototype.add = function (key, tags) { | ||
tags = tags || [] | ||
var tag | ||
this.keysToTags[key] = new Bucket(tags) | ||
this.keysToTags.set(key, getSet(tags, this.forceLegacy)) | ||
for (var i = 0; i < tags.length; i++) { | ||
tag = tags[i] | ||
if (!(tag in this.tagsToKeys)) { | ||
this.tagsToKeys[tag] = new Bucket() | ||
if (!this.tagsToKeys.has(tag)) { | ||
this.tagsToKeys.set(tag, getSet(undefined, this.forceLegacy)) | ||
} | ||
this.tagsToKeys[tag].add(key) | ||
this.tagsToKeys.get(tag).add(key) | ||
} | ||
@@ -49,7 +27,7 @@ } | ||
Tags.prototype.getTags = function (key) { | ||
return key in this.keysToTags ? this.keysToTags[key].toArray() : [] | ||
return this.keysToTags.has(key) ? setToArray(this.keysToTags.get(key)) : [] | ||
} | ||
Tags.prototype.getKeys = function (tag) { | ||
return tag in this.tagsToKeys ? this.tagsToKeys[tag].toArray() : [] | ||
return this.tagsToKeys.has(tag) ? setToArray(this.tagsToKeys.get(tag)) : [] | ||
} | ||
@@ -60,8 +38,8 @@ | ||
for (var i = 0; i < tags.length; i++) { | ||
this.tagsToKeys[tags[i]].del(key) | ||
if (this.tagsToKeys[tags[i]].len === 0) { | ||
delete this.tagsToKeys[tags[i]] | ||
this.tagsToKeys.get(tags[i]).delete(key) | ||
if (this.tagsToKeys.get(tags[i]).size === 0) { | ||
this.tagsToKeys.delete(tags[i]) | ||
} | ||
} | ||
delete this.keysToTags[key] | ||
this.keysToTags.delete(key) | ||
} | ||
@@ -72,10 +50,10 @@ | ||
for (var i = 0; i < keys.length; i++) { | ||
this.keysToTags[keys[i]].del(tag) | ||
if (this.keysToTags[keys[i]].len === 0) { | ||
delete this.keysToTags[keys[i]] | ||
this.keysToTags.get(keys[i]).delete(tag) | ||
if (this.keysToTags.get(keys[i]).size === 0) { | ||
this.keysToTags.delete(keys[i]) | ||
} | ||
} | ||
delete this.tagsToKeys[tag] | ||
this.tagsToKeys.delete(tag) | ||
} | ||
module.exports = Tags |
@@ -7,11 +7,4 @@ /* eslint-env node, mocha */ | ||
describe('cache-ram', function () { | ||
it('must translate args to key', function () { | ||
var cache = new Cache({ key: function (n) { return n } }) | ||
assert.equal(cache.getCacheKey('1'), '1') | ||
assert.equal(cache.getCacheKey(1), 'c4ca4238a0b923820dcc509a6f75849b') | ||
assert.equal(cache.getCacheKey({ d: 1 }), 'dc6f789c90af7a7f8156af120f33e3be') | ||
}) | ||
it('must return null key', function () { | ||
var cache = new Cache({ key: function (n) { return null } }) | ||
var cache = new Cache({ getKey: function (n) { return null } }) | ||
assert.equal(cache.getCacheKey('1'), null) | ||
@@ -101,3 +94,3 @@ }) | ||
it('must not cache if key is null', function (done) { | ||
var cache = new Cache({ key: function (n) { return null } }) | ||
var cache = new Cache({ getKey: function (n) { return null } }) | ||
cache.push([], 'result') | ||
@@ -115,3 +108,3 @@ cache.query({}, function (err, res) { | ||
var cache = new Cache({ | ||
key: function (n) { | ||
getKey: function (n) { | ||
return n | ||
@@ -141,3 +134,3 @@ }, | ||
beforeEach(function () { | ||
cache = new Cache({ key: function (data) { | ||
cache = new Cache({ getKey: function (data) { | ||
return data.test | ||
@@ -183,13 +176,15 @@ } }) | ||
it('must configure cache: string key/object', function (done) { | ||
var cache = new Cache({ key: function (data) { | ||
var cache = new Cache({ getKey: function (data) { | ||
return data.test | ||
} }) | ||
cache.push([{ test: [1, 2] }], 'result1') | ||
cache.push([{ test: [3, 4] }], 'result2') | ||
var array1 = [1, 2] | ||
var array2 = [3, 4] | ||
cache.push([{ test: array1 }], 'result1') | ||
cache.push([{ test: array2 }], 'result2') | ||
cache.query([{ test: [1, 2] }], function (err, res1) { | ||
cache.query([{ test: array1 }], function (err, res1) { | ||
if (err) return done(err) | ||
assert.equal(res1.cached, true) | ||
assert.equal(res1.stale, false) | ||
assert.equal(res1.key, 'f79408e5ca998cd53faf44af31e6eb45') | ||
assert.equal(res1.key, array1) | ||
assert.equal(res1.hit, 'result1') | ||
@@ -201,3 +196,3 @@ done() | ||
it('must configure cache: array key', function (done) { | ||
var cache = new Cache({ key: function (data) { | ||
var cache = new Cache({ getKey: function (data) { | ||
return data.test[0] | ||
@@ -211,3 +206,3 @@ } }) | ||
assert.equal(res1.stale, false) | ||
assert.equal(res1.key, 'c4ca4238a0b923820dcc509a6f75849b') | ||
assert.equal(res1.key, 1) | ||
assert.equal(res1.hit, 'result1') | ||
@@ -219,11 +214,12 @@ done() | ||
it('must configure cache: array key/object', function (done) { | ||
var cache = new Cache({ key: function (data) { | ||
var cache = new Cache({ getKey: function (data) { | ||
return data.test | ||
} }) | ||
cache.push([{ test: [1, 2] }], 'result1') | ||
var array1 = [1, 2] | ||
cache.push([{ test: array1 }], 'result1') | ||
cache.query([{ test: [1, 2] }], function (err, res1) { | ||
cache.query([{ test: array1 }], function (err, res1) { | ||
if (err) return done(err) | ||
assert.equal(res1.cached, true) | ||
assert.equal(res1.key, 'f79408e5ca998cd53faf44af31e6eb45') | ||
assert.equal(res1.key, array1) | ||
assert.equal(res1.hit, 'result1') | ||
@@ -235,3 +231,3 @@ done() | ||
it('must configure cache: func', function (done) { | ||
var cache = new Cache({ key: function (config) { | ||
var cache = new Cache({ getKey: function (config) { | ||
return config.test * 2 | ||
@@ -244,3 +240,3 @@ } }) | ||
assert.equal(res1.cached, true) | ||
assert.equal(res1.key, 'c9f0f895fb98ab9159f51fd0297e236d') | ||
assert.equal(res1.key, 8) | ||
assert.equal(res1.hit, 'result1') | ||
@@ -255,3 +251,3 @@ done() | ||
beforeEach(function () { | ||
cache = new Cache({ key: function (data) { | ||
cache = new Cache({ getKey: function (data) { | ||
return data.test | ||
@@ -306,3 +302,3 @@ }, | ||
beforeEach(function () { | ||
cache = new Cache({ key: function (data) { | ||
cache = new Cache({ getKey: function (data) { | ||
return data.test | ||
@@ -361,3 +357,3 @@ }, | ||
cache = new Cache({ | ||
key: function (data) { | ||
getKey: function (data) { | ||
return data.test | ||
@@ -442,3 +438,3 @@ }, | ||
} | ||
cache = new Cache({ key: getKey, tags: getTags, maxLen: 1 }) | ||
cache = new Cache({ getKey: getKey, getTags: getTags, maxLen: 1 }) | ||
}) | ||
@@ -445,0 +441,0 @@ |
@@ -6,70 +6,73 @@ /* eslint-env node, mocha */ | ||
describe('tags', function () { | ||
it('must add a key', function () { | ||
var tags = new Tags() | ||
tags.add('key') | ||
assert.ok(tags.keysToTags['key']) | ||
assert.deepEqual(tags.getTags('key'), []) | ||
assert.equal(Object.keys(tags.tagsToKeys).length, 0) | ||
}) | ||
[false, true].forEach(function (forceLegacy) { | ||
describe(forceLegacy ? 'es5' : 'es6', function () { | ||
var tags | ||
beforeEach(function () { | ||
tags = new Tags(forceLegacy) | ||
}) | ||
it('must add a key', function () { | ||
tags.add('key') | ||
assert.ok(tags.keysToTags.get('key')) | ||
assert.deepEqual(tags.getTags('key'), []) | ||
assert.equal(tags.tagsToKeys.size, 0) | ||
}) | ||
it('must add a key with tags', function () { | ||
var tags = new Tags() | ||
tags.add('key', ['1', '2']) | ||
assert.ok(tags.keysToTags['key']) | ||
assert.deepEqual(tags.getTags('key'), ['1', '2']) | ||
assert.ok(tags.tagsToKeys['1']) | ||
assert.ok(tags.tagsToKeys['2']) | ||
assert.deepEqual(tags.getKeys('1'), ['key']) | ||
assert.deepEqual(tags.getKeys('2'), ['key']) | ||
}) | ||
it('must add a key with tags', function () { | ||
tags.add('key', ['1', '2']) | ||
assert.ok(tags.keysToTags.get('key')) | ||
assert.deepEqual(tags.getTags('key'), ['1', '2']) | ||
assert.ok(tags.tagsToKeys.get('1')) | ||
assert.ok(tags.tagsToKeys.get('2')) | ||
assert.deepEqual(tags.getKeys('1'), ['key']) | ||
assert.deepEqual(tags.getKeys('2'), ['key']) | ||
}) | ||
it('must add a 2 keys with tags', function () { | ||
var tags = new Tags() | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
assert.ok(tags.keysToTags['key1']) | ||
assert.ok(tags.keysToTags['key2']) | ||
assert.deepEqual(tags.getTags('key1'), ['1', '2']) | ||
assert.deepEqual(tags.getTags('key2'), ['1', '3']) | ||
assert.ok(tags.tagsToKeys['1']) | ||
assert.ok(tags.tagsToKeys['2']) | ||
assert.ok(tags.tagsToKeys['3']) | ||
assert.deepEqual(tags.getKeys('1'), ['key1', 'key2']) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), ['key2']) | ||
}) | ||
it('must add a 2 keys with tags', function () { | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
assert.ok(tags.keysToTags.get('key1')) | ||
assert.ok(tags.keysToTags.get('key2')) | ||
assert.deepEqual(tags.getTags('key1'), ['1', '2']) | ||
assert.deepEqual(tags.getTags('key2'), ['1', '3']) | ||
assert.ok(tags.tagsToKeys.get('1')) | ||
assert.ok(tags.tagsToKeys.get('2')) | ||
assert.ok(tags.tagsToKeys.get('3')) | ||
assert.deepEqual(tags.getKeys('1'), ['key1', 'key2']) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), ['key2']) | ||
}) | ||
it('must remove a key', function () { | ||
var tags = new Tags() | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
tags.removeKey('key2') | ||
assert.ok(tags.keysToTags['key1']) | ||
assert.isUndefined(tags.keysToTags['key2']) | ||
assert.deepEqual(tags.getTags('key1'), ['1', '2']) | ||
assert.deepEqual(tags.getTags('key2'), []) | ||
assert.ok(tags.tagsToKeys['1']) | ||
assert.ok(tags.tagsToKeys['2']) | ||
assert.isUndefined(tags.tagsToKeys['3']) | ||
assert.deepEqual(tags.getKeys('1'), ['key1']) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), []) | ||
}) | ||
it('must remove a key', function () { | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
tags.removeKey('key2') | ||
assert.ok(tags.keysToTags.get('key1')) | ||
assert.isUndefined(tags.keysToTags.get('key2')) | ||
assert.deepEqual(tags.getTags('key1'), ['1', '2']) | ||
assert.deepEqual(tags.getTags('key2'), []) | ||
assert.ok(tags.tagsToKeys.get('1')) | ||
assert.ok(tags.tagsToKeys.get('2')) | ||
assert.isUndefined(tags.tagsToKeys.get('3')) | ||
assert.deepEqual(tags.getKeys('1'), ['key1']) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), []) | ||
}) | ||
it('must remove a tag', function () { | ||
var tags = new Tags() | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
tags.removeTag('1') | ||
assert.ok(tags.keysToTags['key1']) | ||
assert.ok(tags.keysToTags['key2']) | ||
assert.deepEqual(tags.getTags('key1'), ['2']) | ||
assert.deepEqual(tags.getTags('key2'), ['3']) | ||
assert.isUndefined(tags.tagsToKeys['1']) | ||
assert.ok(tags.tagsToKeys['2']) | ||
assert.ok(tags.tagsToKeys['3']) | ||
assert.deepEqual(tags.getKeys('1'), []) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), ['key2']) | ||
it('must remove a tag', function () { | ||
tags.add('key1', ['1', '2']) | ||
tags.add('key2', ['1', '3']) | ||
tags.removeTag('1') | ||
assert.ok(tags.keysToTags.get('key1')) | ||
assert.ok(tags.keysToTags.get('key2')) | ||
assert.deepEqual(tags.getTags('key1'), ['2']) | ||
assert.deepEqual(tags.getTags('key2'), ['3']) | ||
assert.isUndefined(tags.tagsToKeys.get('1')) | ||
assert.ok(tags.tagsToKeys.get('2')) | ||
assert.ok(tags.tagsToKeys.get('3')) | ||
assert.deepEqual(tags.getKeys('1'), []) | ||
assert.deepEqual(tags.getKeys('2'), ['key1']) | ||
assert.deepEqual(tags.getKeys('3'), ['key2']) | ||
}) | ||
}) | ||
}) | ||
}) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
32513
1
13
799
116
+ Addedlittle-ds-toolkit@1.1.1(transitive)
- Removedmemoize-cache-utils@^0.1.1
- Removedlittle-ds-toolkit@0.4.0(transitive)
- Removedmd5-o-matic@0.1.1(transitive)
- Removedmemoize-cache-utils@0.1.1(transitive)
- Removedsizeof@1.0.0(transitive)
Updatedlittle-ds-toolkit@^1.1.0