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

treasury

v2.2.1

Published

Check your caching layer before running your promises

Downloads

67

Readme

Node Treasury: A promise to check for data in your cache layer first

Check your caching layer before running your promises.

master: master develop: develop

Version 2.0.0+

  • Removes Promise factory overrides
  • Provides TypeScript definitions
  • Performance Optimized
  • Upgraded dependencies

Platforms / Technologies

Currently supported cache adapters

Install

  $ npm install treasury --save

Usage

Constructor Options

var Treasury = require('treasury');

// default options for main class wrapper
var treasury = new Treasury({
    client: null,
    namespace: 'Treasury',
    ttl: tauist.s.fiveMinutes
});

option: client

If null, Treasury will default to in-memory cache with managed expiration.

You can also pass a redis or memcached client in:

var Memcached = require('memcached');
var client = new Memcached();
// please see adapters section for all currently supported adapters
var redis = require('redis');
var client = redis.createClient();

var treasury = new Treasury({client: client});

option: namespace

This is used to set a default namespace in the event that the invest function is invoked without a namespace option.

option: ttl

The default time-to-live for any cached objects, which will be used in the event that the invest function is invoked without a ttl option. It is recommended to utilize the Tauist package to ease your reuse of expiration amounts.

Treasury.invest(thePromise, options)

The invest function is used to wrap cache logic around a Promise, where the cache provider is checked for the data first before running the code for the promised value. If the cache cannot retrieve the data, the Promise is invoked and then the successfully promised value is stored in cache for later use.

The first parameter is the promise that you wish to wrap with this logic.

treasury.invest(doTheThingToReallyGetData);

Additionally, you may utilize the options parameter to customize the cache usage for this invest call.

treasury.invest(doTheThingToReallyGetData, {
    namespace: 'aCustomCachePrefix',
    ttl: 'in minutes'
});

option: namespace

This is used to set the namespace for this wrapped Promise. It will fall back to the default Treasury namespace option if not set.

option: ttl

This is used to set the time-to-live for this wrapped Promise. It will fall back to the default Treasury default ttl option if not set.

using invest() with bind

When using the Function.prototype.bind() method to curry a new function with some arguments, please advise that you need to pass these into the options parameter in order for Treasury to properly differentiate that invocation compared to others.

In this example, id is the main parameter to doTheThingToReallyGetData, so it is bound for the Promise to be called. Additionally it is passed as a property to the options object to identify it for a unique cache later on.

treasury.invest(doTheThingToReallyGetData.bind(null, id), {id: id});

Treasury.divest(options)

The divest function is used to manually delete or invalidate a cached item. It expects the same options object used by the invest function in order to find the proper row of data to remove.

treasury.divest({
    namespace: 'aCustomCachePrefix',
    ttl: 'in minutes'
});

option: namespace

This is used to find the namespace for this wrapped Promise. It will fall back to the default Treasury namespace option if not set.

Basic usage - see full code in the examples

Here is a basic sample of "before" code using a redis cache layer.

var key = 'MyModel:' + id;  // you have to manage the keys!
var cacheClient = redis.createClient();

cacheClient.getAsync(key) // you have to promisify the cache client!
      .then(function(data) {
          if (data) {
              // you have to manage the object --> JSON string!
              return Promise.resolve(JSON.parse(data));
          } else {
              return Promise.reject('NO_CACHE');
          }
      })
      .catch(function(err) {
          if (err !== 'NO_CACHE') {
              // you have to manage error filtering!
              return Promise.reject(err);
          } else {
              return doTheThingToReallyGetData({id: id})
                  .then(function(modelData) {
                      // return data
                      // also cache
                      // you have to manage the JSON string --> object!
                      return cacheClient.setexAsync(key, 10, JSON.stringify(modelData))
                          .then(function() {
                              return modelData;
                          });
                  });
          }
      })
      .then(function(data) {
          console.log('found data:', data);
      })
      .catch(function(err) {
          console.log('could not find data, err:', err);
      });

Wouldn't it be great to just do this?

treasury.invest(doTheThingToReallyGetData({id: id}))
    .then(function(data) {
        console.log('found data:', data);
    })
    .catch(function(err) {
        console.log('could not find data, err:', err);
    });

Pull Requests

In order to properly run the tests for this repo, on top of the npm install, you will need the dependencies in Circle CI config. All PRs require passing eslint and code coverage and updated/added/passing unit and integration tests.

Notes

I tried really hard not to use a cache/cash pun when writing node-treasury.

This project was inspired by the excellent Node.js callback wrapper souvenir.