An open API service indexing awesome lists of open source software.

https://github.com/naugtur/safe-memory-cache

Secure and size-limited in-memory cache for node.js
https://github.com/naugtur/safe-memory-cache

Last synced: 3 months ago
JSON representation

Secure and size-limited in-memory cache for node.js

Awesome Lists containing this project

README

          

# safe-memory-cache
Secure and size-limited in-memory cache for Node.js and browsers.

Updated with defensive coding (for prototype poisoning immunity)

## Why another cache package?

- Is lightweight and has trivial API
- Can't be broken by a malicious key (`__proto__`) or a prototype poisoning of intrinsics
- 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

## Usage

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

cache.set("key1","value1")
cache.get("key1") === "value1"

cache.clear()
cache.get("key1") === undefined

```

### options:

name | type | required | description
--- | --- | --- | ---
limit | number | Y | Maximum number of items to store in cache. When cache length is close to the limit, oldest items are removed to make more room.
maxTTL | number | N | Time in miliseconds within which an element should no longer be in cache if it was not accessed. Actual time is approximate and will be less or equal `maxTTL`
buckets | number | N | Overrides the number of buckets used internally. Default is 2
cleanupListener | function | N | Calls the function with a storage bucket that's been removed
retainUsed | boolean | N | Keep items longer than the maxTTL if they are used

#### What limit should I set ?
If you expect N keys to be used most frequently, (limit/buckets) >= N

## What is it fit for?

Caching in general. When you need to cache results of some long running process or a lot of them and you **don't** have a strong requirement to keep every item until its exact expiry time.

## Technicalities

### How do you know items added to native prototypes won't affect the cache?

Objects used for storing key/value pairs don't inherit from any of the native prototypes, nor `Object`
The implementation uses defensive coding to avoid relying on intrinsics that could be modified later.

### What's with the memory leaks, buckets and delete?

`delete` keyword removes fields from objects, but changes the `hidden class` aka `shape` of the object which takes up some memory. As a result, adding and deleting unique fields to a plain JavaScript object may cause memory consumption to grow. Some JavaScript engines had it leak memory in various ways.

*Then how do you remove old items from cache if you can't use delete?*

Cache consists of a number of buckets and the oldest bucket is removed when new room is needed. Therefore the oldest (1/buckets) of entries gets removed.

There's only one interval created per cache instance.

## TypeScript

This module has TypeScript definitions included. If you're using TypeScript you can optionally
provide a type for the values you're storing in the cache.

```typescript
interface Post {
title: string;
author: string;
text: string;
likes: number;
}

const posts = safeMemoryCache({ limit: 10 });
```

The methods `set()` and `get()` will then expect and return values matching the given type, in this
case: `Post`.