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

memoize-cache

Package Overview
Dependencies
Maintainers
1
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

memoize-cache - npm Package Compare versions

Comparing version 5.0.4 to 6.0.0

utils.js

56

base-cache.js

@@ -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

@@ -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'])
})
})
})
})
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