New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cashbox

Package Overview
Dependencies
Maintainers
1
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cashbox - npm Package Compare versions

Comparing version 0.1.1 to 0.2.0

112

lib/cashbox.js
var extend = require('deap/shallow'),
slice = Array.prototype.slice;
timestr = require('timestr'),
slice = Array.prototype.slice,
noop = function() {};

@@ -10,2 +12,7 @@ module.exports = function(stores) {

function parseTTL(value) {
if(typeof value != 'string') return value;
return timestr(value).toSeconds();
}
function Cache(config) {

@@ -52,7 +59,7 @@ config = extend({}, DEFAULTS, config||{});

load(key, function(err, loadedValue) {
load(key, function(err, loadedValue, tags) {
if(err) return done(err);
done(null, loadedValue);
self.set(key, loadedValue, ttl);
self.set(key, loadedValue, tags, ttl, noop);
});

@@ -64,10 +71,24 @@ });

set: function(key, value, ttl, done) {
if(typeof ttl == 'function') {
done = ttl;
ttl = undefined;
set: function(/* key, value, tags, ttl, done */) {
var args = slice.call(arguments),
done = args.pop(),
key = args.shift(),
value = args.shift(),
tags, ttl;
if(args.length == 2) {
tags = args.shift();
ttl = args.shift();
} else if(args.length == 1) {
tags = args.shift();
if(typeof tags != 'object') {
ttl = tags;
tags = undefined;
}
}
this.store.set(key, value, ttl, done);
this.store.set(key, value, convertTags(tags), parseTTL(ttl), done);
return this;

@@ -98,8 +119,7 @@ },

loadMissingKeys(keys, values, load, function(err, allthethings, loaded) {
loadMissingKeys(keys, values, load, function(err, allthethings, loaded, tagMap) {
if(err) return done(err);
done(null, allthethings);
self.mset(loaded, ttl);
self.mset(loaded, tagMap, ttl, noop);
});

@@ -111,9 +131,28 @@ });

mset: function(keysValues, ttl, done) {
if(typeof ttl == 'function') {
done = ttl;
ttl = undefined;
mset: function(/* keysValues, tags, ttl, done */) {
var args = slice.call(arguments),
done = args.pop(),
keysValues = args.shift(),
tags, ttl;
if(args.length == 2) {
tags = args.shift();
ttl = args.shift();
} else if(args.length == 1) {
tags = args.shift();
if(typeof tags != 'object') {
ttl = tags;
tags = undefined;
}
}
this.store.mset(keysValues, ttl, done);
this.store.mset(
keysValues,
tags && Object.keys(tags).reduce(function(map, key) {
map[key] = convertTags(tags[key]);
return map;
}, {}),
parseTTL(ttl),
done
);

@@ -129,5 +168,12 @@ return this;

this.store.expire(key, ttl, done);
this.store.expire(key, parseTTL(ttl), done);
return this;
},
getKeys: function(tags, done) {
if(!this.store.getKeys) throw new Error('Cache store does not support tagging');
this.store.getKeys(convertTags(tags), done);
return this;
}

@@ -137,2 +183,24 @@

function convertTags(tags) {
if(!tags) return undefined;
if(tags instanceof Array) return tags;
if(typeof tags == 'string') return [tags];
var rTags = [];
for(var key in tags) {
rTags.push([key, tags[key]].join(':'));
}
return Array.prototype.concat.apply(
[],
Object.keys(tags).map(function(name) {
var values = (tags[name] instanceof Array) ? tags[name] : [tags[name]];
return values.map(function(value) {
return [name, value].join(':');
});
})
);
}
function loadMissingKeys(keys, values, load, done) {

@@ -153,10 +221,13 @@ var results = {},

// call the load() callback provided to load missing keys
load(missingKeys, function(err, values) {
load(missingKeys, function(err, values, tags) {
if(!err && !(values instanceof Array)) err = new Error('Invalid values passed into load function: "values" must be an array');
if(err) return done(err);
var loaded = {};
var loaded = {},
tagMap = {};
(values||[]).forEach(function(value, idx) {
loaded[missingKeys[idx]] = value;
if(tags) tagMap[missingKeys[idx]] = tags[idx];
});

@@ -170,3 +241,4 @@ extend(results, loaded);

}),
loaded
loaded,
tagMap
);

@@ -173,0 +245,0 @@ });

@@ -5,2 +5,3 @@

this.data = {};
this.tags = {};
};

@@ -15,4 +16,6 @@ Memory.prototype = {

set: function(key, value, ttl, done) {
set: function(key, value, tags, ttl, done) {
this.data[key] = packageData(value, ttl);
if(tags) setTags.call(this, key, tags);
if(done) done(null, true);

@@ -34,10 +37,16 @@

mset: function(hash, ttl, done) {
mset: function(hash, tagMap, ttl, done) {
var self = this;
var self = this,
keys = Object.keys(hash||{});
Object.keys(hash||{}).forEach(function(key) {
keys.forEach(function(key) {
self.data[key] = packageData(hash[key], ttl);
});
if(tagMap) {
Object.keys(tagMap).forEach(function(key) {
setTags.call(self, key, tagMap[key]);
});
}
if(done) done(null, true);

@@ -62,2 +71,16 @@

return this;
},
getKeys: function(tags, done) {
var self = this;
done(null, Object.keys(
Array.prototype.concat.apply(
[],
tags.map(function(tag) { return self.tags[tag] || []; })
).reduce(function(map, key) { //to make it unique
map[key] = true;
return map;
}, {})
));
return this;
}

@@ -67,2 +90,12 @@

function setTags(key, tags, done) {
var self = this;
tags.forEach(function(tag) {
if(!self.tags[tag]) self.tags[tag] = [];
self.tags[tag].push(key);
});
}
function getValue(cache, key) {

@@ -69,0 +102,0 @@ var value = cache.data[key];

{
"name": "cashbox",
"version": "0.1.1",
"version": "0.2.0",
"description": "javascript cache library with configurable storage",

@@ -20,6 +20,18 @@ "main": "index.js",

"author": "Brad Harris <bmharris@gmail.com> (http://selfcontained.us)",
"contributors": [
{
"name": "Brad Harris",
"email": "bmharris@gmail.com",
"url": "http://selfcontained.us"
},
{
"name": "Nathan Broslawsky",
"url": "http://github.com/nbroslawsky"
}
],
"license": "BSD",
"readmeFilename": "README.md",
"dependencies": {
"deap": "~0.1.2"
"deap": "~0.1.2",
"timestr": "~0.1.0"
},

@@ -26,0 +38,0 @@ "devDependencies": {

@@ -116,2 +116,25 @@ var assert = require('chai').assert,

it('should have tagging capabilities on the load object for get()', function(done) {
var cache = new Cache();
cache.get({
key: key,
ttl: 1,
load: function(key, cb) {
cb(null, value, { test : 1 });
},
done: function(err, v) {
assert.isNull(err);
assert.equal(v, value);
setTimeout(function() {
cache.getKeys({ test : 1 }, function(err, keys) {
assert.equal(keys[0], key);
done();
});
}, 0);
}
});
});
describe('without a ttl', function() {

@@ -284,2 +307,80 @@

it('should accept an object with tagging capabilities (as an object)', function(done) {
var cache = new Cache();
cache.mget({
keys: [key1, key2],
ttl: 1,
load: function(keys, cb) {
cb(
null,
[value1, value2],
[{ test : 1 }, { test : 2 }]
);
},
done: function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.equal(results[0], value1);
assert.equal(results[1], value2);
setTimeout(function() {
cache.getKeys({ test : 2 }, function(err, keys) {
assert.equal(keys[0], key2);
done();
});
}, 0);
}
});
});
it('should accept an object with tagging capabilities (as an array)', function(done) {
var cache = new Cache();
cache.mget({
keys: [key1, key2],
ttl: 1,
load: function(keys, cb) {
cb(
null,
[value1, value2],
['test_1', 'test_2']
);
},
done: function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.equal(results[0], value1);
assert.equal(results[1], value2);
setTimeout(function() {
cache.getKeys('test_2', function(err, keys) {
assert.equal(keys[0], key2);
done();
});
}, 0);
}
});
});
it('should accept an object with a string ttl', function(done) {
var cache = new Cache();
cache.mget({
keys: [key1, key2],
ttl: '1 second',
load: function(keys, cb) {
cb(null, [value1, value2]);
},
done: function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.equal(results[0], value1);
assert.equal(results[1], value2);
done();
}
});
});
it('should handle a load function for missing values', function(done) {

@@ -327,2 +428,23 @@ var called = false,

it('should handle a load function and a string ttl for missing values', function(done) {
var called = false,
cache = new Cache();
function loadIt(keys, cb) {
called = true;
cb(null, [value2, value1]);
}
cache.mget([key2, key1], loadIt, '1s', function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.equal(results[0], value2);
assert.equal(results[1], value1);
assert.isTrue(called);
done();
});
});
it('should handle a load function and a ttl for missing values and not return them after expiration', function(done) {

@@ -359,2 +481,33 @@ var called = false,

it('should handle a load function and a string ttl for missing values and not return them after expiration', function(done) {
var called = false,
cache = new Cache();
function loadIt(keys, cb) {
called = true;
cb(null, [value2, value1]);
}
cache.mget([key2, key1], loadIt, '1 sec', function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.equal(results[0], value2);
assert.equal(results[1], value1);
assert.isTrue(called);
setTimeout(function() {
cache.mget([key1, key2], function(err, results) {
assert.isNull(err);
assert.lengthOf(results, 2);
assert.isUndefined(results[0]);
assert.isUndefined(results[1]);
done();
});
}, 1025);
});
});
});

@@ -361,0 +514,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