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

dobi-cache-2

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

dobi-cache-2 - npm Package Compare versions

Comparing version 3.0.6 to 3.0.7

82

lib/cacheHelper.js

@@ -7,9 +7,23 @@ /* eslint-disable no-process-env */

const isNil = require('lodash/isNil');
const LRU = require('lru-cache');
module.exports = class CacheHelper {
constructor({ disabled = false, keyPrefix = 'dobiCache', redisUri }) {
this.disabled = !(!disabled && redisUri);
/**
* @param {Object} config
* @param {boolean} config.enabled=true
* @param {string} config.keyPrefix=dobiCache prefix for redis keys
* @param {number} config.lruMaxItems max number of lru items
* @param {string} config.redisUri uri for redis server
*/
constructor({
enabled,
keyPrefix = 'dobiCache',
lruMaxItems: max = 100,
redisUri,
}) {
this.enabled = enabled;
this.redisUri = redisUri;
this.keyPrefix = keyPrefix;
this.state = 'initializing';
this.redisState = 'initializing';
this.lru = LRU({ max });
this.redis = new Redis(this.redisUri, {

@@ -22,20 +36,38 @@ lazyConnect: true,

isDisabled() {
return this.disabled || this.state !== 'connected';
return !(this.enabled && this.method);
}
async connect() {
if (this.disabled || this.state !== 'initializing') {
if (!this.enabled || this.redisState !== 'initializing') {
return;
}
try {
this.state = 'pending';
this.redisState = 'pending';
await this.redis.connect();
this.state = 'connected';
this.redisState = 'connected';
this.method = 'redis';
} catch (err) {
this.state = 'disconnected';
this.redisState = 'disconnected';
this.method = 'lru';
// eslint-disable-next-line no-console
console.warn(`redis server not found, cache disabled: ${this.redisUri}`);
console.warn(`redis server not found: ${this.redisUri}. using LRU cache`);
}
}
async getKeys() {
if (this.isDisabled()) {
return [];
}
let keys = [];
if (this.method === 'redis') {
keys = await this.redis.keys(`${this.keyPrefix}:*`);
} else {
keys = this.lru.keys();
}
return keys.map(key => (
key.replace(new RegExp(`^${this.keyPrefix}:`), '')
));
}
async flushCache() {

@@ -45,6 +77,6 @@ if (this.isDisabled()) {

}
const keys = await this.redis.keys(`${this.keyPrefix}:*`);
const keys = await this.getKeys();
const flushed = [];
const promises = keys.map(async (key) => {
flushed.push(await this.redis.del(key));
flushed.push(await this.delete(key));
});

@@ -56,3 +88,3 @@

getKey(key) {
buildKey(key) {
return `${this.keyPrefix}:${key}`;

@@ -65,3 +97,9 @@ }

}
return this.redis.del(this.getKey(key));
const itemKey = this.buildKey(key);
if (this.method === 'redis') {
return this.redis.del(itemKey);
}
const result = this.lru.peek(itemKey) ? 1 : 0;
this.lru.del(itemKey);
return result;
}

@@ -74,3 +112,8 @@

try {
const document = await this.redis.get(this.getKey(key));
let document;
if (this.method === 'redis') {
document = await this.redis.get(this.buildKey(key));
} else {
document = this.lru.get(this.buildKey(key));
}
if (!document) {

@@ -104,5 +147,12 @@ return null;

}
await this.redis.set(this.getKey(key), JSON.stringify({ type, value }));
await this.redis.expire(this.getKey(key), ttl);
const itemKey = this.buildKey(key);
const itemValue = JSON.stringify({ type, value });
if (this.method === 'redis') {
await this.redis.set(itemKey, itemValue);
await this.redis.expire(itemKey, ttl);
} else {
this.lru.set(itemKey, itemValue, ttl * 1000);
}
}
};

26

lib/index.js

@@ -9,8 +9,20 @@ 'use strict';

module.exports = class Cache {
constructor(config) {
this.config = config;
/**
* @param {Object} config
* @param {boolean} config.enabled=true
* @param {string} config.keyPrefix=dobiCache prefix for redis keys
* @param {number} config.lruMaxItems max number of lru items
* @param {string} config.redisUri uri for redis server
*/
constructor({
enabled = true,
keyPrefix = 'dobiCache',
lruMaxItems = 100,
redisUri,
}) {
// connect to redis
const { disabled, keyPrefix, redisUri } = config;
this.cacheHelper = new CacheHelper({ disabled, keyPrefix, redisUri });
this.enabled = enabled;
this.cacheHelper = new CacheHelper({
enabled, keyPrefix, lruMaxItems, redisUri,
});
this.flushCache = this.cacheHelper.flushCache.bind(this.cacheHelper);

@@ -91,4 +103,2 @@ this.cache = this.cache.bind(this);

const { disabled = false } = this.config;
const {

@@ -103,3 +113,3 @@ headers = {},

if (disabled || method === 'POST' || skipCache) {
if (!this.enabled || method === 'POST' || skipCache) {
const data = await asyncFetch();

@@ -106,0 +116,0 @@ return res.send(data);

@@ -9,2 +9,3 @@ {

"lodash": "^4.17.11",
"lru-cache": "^4.1.3",
"parseurl": "^1.3.2"

@@ -28,3 +29,3 @@ },

},
"version": "3.0.6",
"version": "3.0.7",
"devDependencies": {

@@ -31,0 +32,0 @@ "eslint": "^5.5.0",

@@ -10,3 +10,3 @@ 'use strict';

const cacheFlushTester = new Cache({
disabled: false,
enabled: true,
keyPrefix: 'flushTest',

@@ -16,4 +16,10 @@ redisUri: 'localhost',

const cacheDisabled = new Cache({
enabled: false,
keyPrefix: 'flushTest',
redisUri: 'localhost',
});
const cacheServer = new Cache({
disabled: false,
enabled: true,
redisUri: 'localhost',

@@ -23,3 +29,3 @@ });

const cacheDisconnected = new Cache({
disabled: false,
enabled: true,
redisUri: 'failfailfail',

@@ -30,2 +36,3 @@ });

let disconnectedApp;
let disabledApp;
beforeAll(async () => {

@@ -43,2 +50,3 @@ await cacheFlushTester.cacheHelper.connect();

disconnectedApp = appGenerator(cacheDisconnected.cache);
disabledApp = appGenerator(cacheDisabled.cache);
});

@@ -50,11 +58,13 @@

expect(resp.headers['dobi-cache']).toBe('MISS');
const resp2 = await request(connectedApp).get('/');
if (resp2.headers['dobi-cache'] === 'MISS') {
// eslint-disable-next-line no-console
console.error('run redis locally to test');
}
expect(resp2.headers['dobi-cache']).toBe('HIT');
});
it('works if disabled', async () => {
const resp = await request(disabledApp).get('/');
expect(resp.headers['dobi-cache']).toBe(undefined);
const resp2 = await request(disabledApp).get('/');
expect(resp2.headers['dobi-cache']).toBe(undefined);
});
it('allows bypass', async () => {

@@ -61,0 +71,0 @@ const resp = await request(connectedApp).get('/?_=234234234');

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