Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

safe-memory-cache

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

safe-memory-cache - npm Package Compare versions

Comparing version
1.5.1
to
2.0.0
+96
legacy.js
function createMem(number, limit) {
var mem = Object.create(bucketsProto)
mem.N = number
mem.max = limit
mem.clear()
return mem
}
var bucketsProto = {
clear: function clear() {
this.size = 0
this.buckets=[];
for (var i = 0; i < this.N; i++) {
this.spawnBucket()
}
},
spawnBucket: function spawnBucket() {
this.buckets.unshift(Object.create(null))
},
rotateBuckets: function rotateBuckets() {
var dropped = this.buckets.pop()
this.spawnBucket()
this.size = 0
if(this.rotationHook){
this.rotationHook(dropped)
}
},
set: function set(key, value) {
if (!(key in this.buckets[0])) {
this.size++;
if (this.max && this.size >= Math.ceil(this.max / this.buckets.length)) {
this.rotateBuckets()
}
}
this.buckets[0][key] = value
return value
},
get: function get(key) {
for (var i = 0; i < this.buckets.length; i++) {
if (key in this.buckets[i]) {
//todo: this should be configurable
if (i) {
//put a reference in the newest bucket
return this.set(key,this.buckets[i][key])
}
return this.buckets[i][key]
}
}
}
}
var protoRegex = /__proto__/g;
function sanitizeSimple(key) {
return '' + key.replace(protoRegex, 'z__proto__')
}
function sanitizeHeavy(key) {
return ('' + key).split('').map(function(char) {
return char.charCodeAt(0).toString(32)
}).join('z')
}
module.exports = function(opts) {
var buckets = ~~(opts.buckets) || 2;
var mem = createMem(buckets, opts.limit)
mem.rotationHook = opts.cleanupListener || null
var sanitize = (opts.strongSanitizer ? sanitizeHeavy : sanitizeSimple)
if (opts.maxTTL) {
var intervalHandle = setInterval(mem.rotateBuckets.bind(mem), ~~(opts.maxTTL / buckets))
}
return {
set: function(key, value) {
return mem.set(sanitize(key), value)
},
get: function(key) {
return mem.get(sanitize(key))
},
clear: mem.clear.bind(mem),
destroy: function() {
mem.rotationHook = null
clearInterval(intervalHandle)
},
_get_buckets: function(){
return mem.buckets
},
_rotate_buckets: function() {
return mem.rotateBuckets()
}
}
}
+30
-46

@@ -12,3 +12,3 @@ function createMem(number, limit) {

this.size = 0
this.buckets=[];
this.buckets = [];
for (var i = 0; i < this.N; i++) {

@@ -19,3 +19,3 @@ this.spawnBucket()

spawnBucket: function spawnBucket() {
this.buckets.unshift(Object.create(null))
this.buckets.unshift(new Map())
},

@@ -26,3 +26,3 @@ rotateBuckets: function rotateBuckets() {

this.size = 0
if(this.rotationHook){
if (this.rotationHook) {
this.rotationHook(dropped)

@@ -32,3 +32,3 @@ }

set: function set(key, value) {
if (!(key in this.buckets[0])) {
if (!(this.buckets[0].has(key))) {
this.size++;

@@ -39,3 +39,3 @@ if (this.max && this.size >= Math.ceil(this.max / this.buckets.length)) {

}
this.buckets[0][key] = value
this.buckets[0].set(key, value)
return value

@@ -45,9 +45,9 @@ },

for (var i = 0; i < this.buckets.length; i++) {
if (key in this.buckets[i]) {
if (this.buckets[i].has(key)) {
//todo: this should be configurable
if (i) {
//put a reference in the newest bucket
return this.set(key,this.buckets[i][key])
return this.set(key, this.buckets[i].get(key))
}
return this.buckets[i][key]
return this.buckets[i].get(key)
}

@@ -58,46 +58,30 @@ }

var protoRegex = /__proto__/g;
function sanitizeSimple(key) {
return '' + key.replace(protoRegex, 'z__proto__')
}
function sanitizeHeavy(key) {
return ('' + key).split('').map(function(char) {
return char.charCodeAt(0).toString(32)
}).join('z')
}
module.exports = {
safeMemoryCache(opts) {
var buckets = ~~(opts.buckets) || 2;
var mem = createMem(buckets, opts.limit)
mem.rotationHook = opts.cleanupListener || null
if (opts.maxTTL) {
var intervalHandle = setInterval(mem.rotateBuckets.bind(mem), ~~(opts.maxTTL / buckets))
}
module.exports = function(opts) {
var buckets = ~~(opts.buckets) || 2;
var mem = createMem(buckets, opts.limit)
mem.rotationHook = opts.cleanupListener || null
var sanitize = (opts.strongSanitizer ? sanitizeHeavy : sanitizeSimple)
return {
set: mem.set.bind(mem),
get: mem.get.bind(mem),
clear: mem.clear.bind(mem),
destroy: function () {
clearInterval(intervalHandle)
},
_get_buckets: function () {
return mem.buckets
},
_rotate_buckets: function () {
return mem.rotateBuckets()
}
}
if (opts.maxTTL) {
var intervalHandle = setInterval(mem.rotateBuckets.bind(mem), ~~(opts.maxTTL / buckets))
}
return {
set: function(key, value) {
return mem.set(sanitize(key), value)
},
get: function(key) {
return mem.get(sanitize(key))
},
clear: mem.clear.bind(mem),
destroy: function() {
mem.rotationHook = null
clearInterval(intervalHandle)
},
_get_buckets: function(){
return mem.buckets
},
_rotate_buckets: function() {
return mem.rotateBuckets()
}
}
}
{
"name": "safe-memory-cache",
"version": "1.5.1",
"version": "2.0.0",
"description": "Secure and size-limited in-memory cache for Node.js and browsers",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -8,4 +8,3 @@ # safe-memory-cache

- Can't be broken by a malicious key (`__proto__`)
- Can't be affected by modifications to native prototypes
- Limits the number of items without the use of `delete` (and no memory leaks caused by `delete`), plays well with garbage collector. But also doesn't drop the whole cache when full, frees up gradually
- Limits the number of items without the use of `delete` (and no memory leaks caused by `delete`), plays well with garbage collector. But also **doesn't drop the whole cache when full, frees up gradually**
- Doesn't waste your eventloop ticks with timeouts set to remove single items from cache, but still deletes oldest items first

@@ -16,3 +15,3 @@

```
var safeMemoryCache = require('safe-memory-cache')
var {safeMemoryCache} = require('safe-memory-cache')
var cache = safeMemoryCache(options)

@@ -29,6 +28,6 @@

If your engine supports `Map`, you can use the map based version. It doesn't need (nor have) sanitization on keys and it uses Maps as buckets for storage.
If your engine doesn't support `Map`, you can use the legacy version. It does manual sanitization on keys and it uses plain objects as buckets for storage.
```
const safeMemoryCache = require('safe-memory-cache/map')
const safeMemoryCache = require('safe-memory-cache/legacy')
```

@@ -35,0 +34,0 @@

@@ -5,4 +5,4 @@ var assert = require('assert')

console.log('# Main implementation')
var safeMemoryCache = require('./index')
console.log('# Legacy implementation')
var safeMemoryCache = require('./legacy')

@@ -53,3 +53,3 @@ var c = safeMemoryCache({

var safeMemoryCache = require('./map')
var {safeMemoryCache} = require('./index')

@@ -56,0 +56,0 @@

function createMem(number, limit) {
var mem = Object.create(bucketsProto)
mem.N = number
mem.max = limit
mem.clear()
return mem
}
var bucketsProto = {
clear: function clear() {
this.size = 0
this.buckets=[];
for (var i = 0; i < this.N; i++) {
this.spawnBucket()
}
},
spawnBucket: function spawnBucket() {
this.buckets.unshift(new Map())
},
rotateBuckets: function rotateBuckets() {
var dropped = this.buckets.pop()
this.spawnBucket()
this.size = 0
if(this.rotationHook){
this.rotationHook(dropped)
}
},
set: function set(key, value) {
if (!(this.buckets[0].has(key))) {
this.size++;
if (this.max && this.size >= Math.ceil(this.max / this.buckets.length)) {
this.rotateBuckets()
}
}
this.buckets[0].set(key, value)
return value
},
get: function get(key) {
for (var i = 0; i < this.buckets.length; i++) {
if (this.buckets[i].has(key)) {
//todo: this should be configurable
if (i) {
//put a reference in the newest bucket
return this.set(key,this.buckets[i].get(key))
}
return this.buckets[i].get(key)
}
}
}
}
module.exports = function(opts) {
var buckets = ~~(opts.buckets) || 2;
var mem = createMem(buckets, opts.limit)
mem.rotationHook = opts.cleanupListener || null
if (opts.maxTTL) {
var intervalHandle = setInterval(mem.rotateBuckets.bind(mem), ~~(opts.maxTTL / buckets))
}
return {
set: mem.set.bind(mem),
get: mem.get.bind(mem),
clear: mem.clear.bind(mem),
destroy: function() {
clearInterval(intervalHandle)
},
_get_buckets: function() {
return mem.buckets
},
_rotate_buckets: function() {
return mem.rotateBuckets()
}
}
}