npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

eu

v1.3.2

Published

Caching HTTP client

Downloads

31

Readme

Eu is a wrapper around request which can cache HTTP GET requests based on response headers - just like a browser does.

It is used to lower latency when consuming data from HTTP/REST APIs that have proper caching headers.

"Eu" means "gotten" in French.

This library is heavily inspired from Kevin Swiber's request-caching.

Features

  • Multiple cache stores:
    • Redis (built-in)
    • In-memory based on LRU (built-in)
    • Medea (3rd party eu-medea-store plugin by Kevin Swiber)
  • Supports both public and private caching.
  • Takes advantage of the ETag response header by using the If-None-Match request header.
  • Takes advantage of the Last-Modified response header by using the If-Modified-Since request header.
  • Cache TTL is based on the Expires response header or max-age value in Cache-Control, but can be overridden.
  • Highly customisable with sensible defaults.

Usage

Usage is similar to request.get. The main difference is that you have to create an Eu instance:

var Eu = require('eu');
var eu = new Eu(cache); // See below for details about how to create a cache

eu.get('http://some.url', function(err, res, body) {
});

// Or pass in request options:
eu.get('http://some.url', {json: true}, function(err, res, body) {
});

A cache uses a store to store cached responses:

In-memory store

var LRU = require('lru-cache');
var store = new Eu.MemoryStore(new LRU());
var cache = new Eu.Cache(store);

Redis store

var redis = require('redis').createClient();
var store = new Eu.RedisStore(redis);
var cache = new Eu.Cache(store);

You can also create a NullCache, which does nothing and doesn't require a store:

Null cache

var cache = new Eu.NullCache();

Cache key name spacing

You should always provide a prefix which prefixes the key with the name of your app (or API). When you invoke Cache.flush, it will only flush the keys starting with that prefix. If you don't specify a prefix, you'll flush the entire cache.

var prefix = 'yourapp:';
var cache = new Eu.Cache(store, prefix);

cache.flush(cb); // only the 'yourapp:*' keys get flushed

Private caching

Some HTTP responses should be cached privately - i.e. they shouldn't be available for other users. This is the case when the server responds with Cache-Control: private.

To handle this you should construct the Cache with a privateSuffix String argument. This suffix will be appended to the key when caching a private response.

var prefix = 'yourapp:';
var unique = req.user.id; // or req.cookies['connect.sid']
var privateSuffix = ':private:' + unique;
var cache = new Eu.Cache(store, prefix, privateSuffix);

You will get an error if no privateSuffix was provided when caching a private response.

For servers that don't reply with a Cache-Control: private header, you can force the request to be cached privately:

cache.get(url, { private: true }, function (err, val) {
  ...
});

Eu will always look in the public cache first, and then in the private cache if there was no hit in the public cache.

Cache entry expiry time

Every time a response is cached, it is cached with an expiry time. This is a timestamp indicating how long the cache entry is valid for. (This is not the same as TTL - Time to Live. See next section).

When Eu finds an entry in the cache it will consult this timestamp to decide whether the entry is still valid - i.e. is the expiry time in the future.

If it's valid, the response is returned immediately. If not, a HTTP request will be issued, setting the If-None-Match request header to the value of the cached ETag value, and the If-Modified-Since request header to the value of the cached Last-Modified value.

If the server responds with 304 Not Modified the cached response will be returned even though it is expired (the server has confirmed that even though it is expired, it hasn't changed).

By default the expiry time is determined by either the Cache-Control max-age or Expires response header. If neither of these headers are set, or if you want to cache more aggressively than what they indicate, you can override this in the options passed to eu.get:

function expiryTimeMillis() {
  return 8640000000000000; // cache forever
}
cache.get(url, { expiryTimeMillis: expiryTimeMillis }, function (err, val) {
  ...
});

TTL

By default, Eu will store entries in the cache with the TTL (Time to Live) equal to the cache expiry time (see above).

If the expiry time is undefined, the response will be cached forever, or until the cache discards it, using whatever expiry algorithm it uses, such as LIFO or FIFO.

You can override the default TTL by supplying your own ttl function:

function myTtl(ttl) {
  return ttl * 1000; // cache it longer than the server told us to.
}

var cache = new Eu.Cache(store, null, null, myTtl);

Debugging

Just set DEBUG=eu in your shell to see debug info.

For extra verbose output (print request and response headers) set DEBUG=eu,eu:*