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

route-cache

Package Overview
Dependencies
Maintainers
1
Versions
30
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

route-cache - npm Package Compare versions

Comparing version 0.4.7 to 0.5.0

ioRedisStore.js

230

index.js
'use strict'
const LRU = require('lru-cache')
const LruStore = require('./lruStore')
const debug = require('debug')('route-cache')

@@ -16,9 +16,17 @@ const queues = Object.create(null)

}
let cacheStore = new LRU(defaults)
let cacheStore = new LruStore(defaults)
module.exports.config = function (opts) {
if (opts && opts.max) {
defaults.max = opts.max
if (opts) {
if (opts.max) {
defaults.max = opts.max
}
if (opts.cacheStore) {
cacheStore = opts.cacheStore
} else {
cacheStore = new LruStore(defaults)
}
module.exports.cacheStore = cacheStore
}
cacheStore = new LRU(defaults)
return this

@@ -49,123 +57,139 @@ }

const redirectKey = cacheStore.get('redirect:' + key)
if (redirectKey) {
return res.redirect(redirectKey.status, redirectKey.url)
}
const value = cacheStore.get(key)
if (value) {
// returns the value immediately
debug('hit!!', key)
if (value.isJson) {
res.json(value.body)
} else {
res.send(value.body)
cacheStore.get('redirect:' + key).then((redirectKey) => {
if (redirectKey) {
res.redirect(redirectKey.status, redirectKey.url)
return true
}
return
}
return false
}).then((handledByRedirect) => {
if (handledByRedirect) return true
return cacheStore.get(key).then((value) => {
if (value) {
// returns the value immediately
debug('hit!!', key)
if (value.isJson) {
res.json(value.body)
} else {
res.send(value.body)
}
return true
}
return false
})
}).then((handledByCache) => {
if (handledByCache) return true
res.original_send = res.send
res.original_end = res.end
res.original_json = res.json
res.original_redirect = res.redirect
res.original_send = res.send
res.original_end = res.end
res.original_json = res.json
res.original_redirect = res.redirect
if (!queues[key]) {
queues[key] = []
}
if (!queues[key]) {
queues[key] = []
}
let didHandle = false
let didHandle = false
function rawSend (data, isJson) {
debug('rawSend', typeof data, data ? data.length : 0)
// pass-through for Buffer - not supported
if (typeof data === 'object') {
if (Buffer.isBuffer(data)) {
queues[key] = [] // clear queue
res.set('Content-Length', data.length)
res.original_send(data)
return
function rawSend (data, isJson) {
debug('rawSend', typeof data, data ? data.length : 0)
// pass-through for Buffer - not supported
if (typeof data === 'object') {
if (Buffer.isBuffer(data)) {
queues[key] = [] // clear queue
res.set('Content-Length', data.length)
res.original_send(data)
return
}
}
}
didHandle = true
const body = data instanceof Buffer ? data.toString() : data
if (res.statusCode < 400) cacheStore.set(key, { body: body, isJson: isJson }, ttl)
didHandle = true
const body = data instanceof Buffer ? data.toString() : data
if (res.statusCode < 400) cacheStore.set(key, { body: body, isJson: isJson }, ttl)
// send this response to everyone in the queue
drainQueue(key)
// send this response to everyone in the queue
drainQueue(key)
if (isJson) {
debug('res.original_json')
res.original_json(body)
} else {
debug('res.original_send')
res.original_send(body)
}
}
// first request will get rendered output
if (queues[key].length === 0) {
debug('miss:', key)
queues[key].push(function noop () {})
didHandle = false
res.send = function (data) {
// debug('res.send() >>', data.length)
if (didHandle) {
res.original_send(data)
if (isJson) {
debug('res.original_json')
res.original_json(body)
} else {
rawSend(data, false)
debug('res.original_send')
res.original_send(body)
}
}
res.end = (data) => {
res.original_end(data)
drainQueue(key)
}
// first request will get rendered output
if (queues[key].length === 0) {
debug('miss:', key)
queues[key].push(function noop () {})
res.json = function (data) {
rawSend(data, true)
}
didHandle = false
// If response happens to be a redirect -- store it to redirect all subsequent requests.
res.redirect = function (url) {
let address = url
let status = 302
// allow statusCode for 301 redirect. See: https://github.com/expressjs/express/blob/master/lib/response.js#L857
if (arguments.length === 2) {
if (typeof arguments[0] === 'number') {
status = arguments[0]
address = arguments[1]
res.send = function (data) {
// debug('res.send() >>', data.length)
if (didHandle) {
res.original_send(data)
} else {
console.log('res.redirect(url, status): Use res.redirect(status, url) instead')
status = arguments[1]
rawSend(data, false)
}
}
cacheStore.set('redirect:' + key, { url: address, status: status }, ttl)
res.original_redirect(status, address)
return drainQueue(key)
}
res.end = (data) => {
res.original_end(data)
drainQueue(key)
}
next()
// subsequent requests will batch while the first computes
} else {
debug(key, '>> has queue.length:', queues[key].length)
queues[key].push(function () {
const redirectKey = cacheStore.get('redirect:' + key)
if (redirectKey) {
return res.redirect(redirectKey.status, redirectKey.url)
res.json = function (data) {
rawSend(data, true)
}
const value = cacheStore.get(key) || {}
debug('>> queued hit:', key, value.length)
if (value.isJson) {
res.json(value.body)
} else {
res.send(value.body)
// If response happens to be a redirect -- store it to redirect all subsequent requests.
res.redirect = function (url) {
let address = url
let status = 302
// allow statusCode for 301 redirect. See: https://github.com/expressjs/express/blob/master/lib/response.js#L857
if (arguments.length === 2) {
if (typeof arguments[0] === 'number') {
status = arguments[0]
address = arguments[1]
} else {
console.log('res.redirect(url, status): Use res.redirect(status, url) instead')
status = arguments[1]
}
}
cacheStore.set('redirect:' + key, { url: address, status: status }, ttl)
res.original_redirect(status, address)
return drainQueue(key)
}
})
}
next()
// subsequent requests will batch while the first computes
} else {
debug(key, '>> has queue.length:', queues[key].length)
queues[key].push(function () {
cacheStore.get('redirect:' + key)
.then((redirectKey) => {
if (redirectKey) {
res.redirect(redirectKey.status, redirectKey.url)
return true
}
return false
})
.then((handledByRedirect) => {
if (handledByRedirect) return
return cacheStore.get(key).then((cachedValue) => {
const value = cachedValue || {}
debug('>> queued hit:', key, value.length)
if (value.isJson) {
res.json(value.body)
} else {
res.send(value.body)
}
})
})
})
}
})
}

@@ -172,0 +196,0 @@ }

{
"name": "route-cache",
"version": "0.4.7",
"version": "0.5.0",
"description": "express middleware for caching your routes",

@@ -30,2 +30,3 @@ "main": "index.js",

"mocha": "^9.1.4",
"sinon": "^14.0.0",
"standard": "^16.0.4",

@@ -32,0 +33,0 @@ "supertest": "^4.0.2"

@@ -73,5 +73,15 @@ # Route-Cache

## Use a distributed cache
```javascript
const Redis = require('ioredis')
const IoRedisStore = require('route-cache/ioRedisStore')
const redisClient = new Redis(6379, '127.0.0.1'))
const cacheStore = new IoRedisStore(redisClient)
routeCache.config({cacheStore})
```
## Future plans / todos
- client-side Cache-Control
- support for distributed caches (redis or memcache)

@@ -78,0 +88,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