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

memojs

v0.0.8

Published

A simple elegant memoizer for node-js that supports pluggable caches

Downloads

4

Readme

memojs

Memoization framework for NodeJS. There are several memoization modules already for Node.JS that are very good. The difference is that this module is built with plugins for cache and ease of use in mind.

This is not a complex ES6-compliant memoization library but it will work for simple caches. In particular, this comes with a very basic memory cache but REDIS, MongoDB and S3 plugins are in the works. In addition, it is possible to do multi-layered caching this way.

NPM info

Travis build status

This module is experimental and the kinks have yet to be worked out.

Install

npm install memojs

Plugins

  • A Redis plugin is available -- memojs-redis
  • A MongoDB plugin is available -- memojs-mongodb
  • A simple in memory plugin is included by default
  • A per-domain cache is also available but not included by default

API

There are two seperate ways to invoke this library. The simpler approach is by Function prototype and the other approach is explicit initialization.

More explicit documentation will be added soon.

Function prototype

   var memojs = require('memojs');

   function someSyncFunction(arg1, arg2) {
     return arg1 + arg2;
   }

   function someFunction(arg1, arg2, done) {
     return done(null, arg1 + arg2);
   }
   
   // note that someFunction.memoized is declared via prototype automatically.
   someFunction.memoized(5, 3, function (err, val) {
     // now if you call someFunction.memoized(5, 3, cb) it will use the cache.
   });

   // you can configure the cache and other details as follows
   someFunction.memoized.configure({store: yourStoreImplementation()});

   // you can also get a one-off implementation that uses a different store as follows
   var someFunctionButDifferentCache = someFunction.memoize({store: anotherStore()});

   // you can get contents from the cache directly via the cached property.
   // the following call will not actually ever call someFunction
   someFunction.memoized.cached(5, 3, callback);

   // you can readThrough values via readThrough.  This does not read from the cache 
   // but will end up saving to the cache though.
   someFunction.memoized.readThrough(5, 3, callback);

   // you can also write through to the cache.  This does not call someFunction but allows updating
   // the caches directly.
   someFunction.memoized.writeThrough(42)(5, 3, callback);

   // if you want to delete an item from the cache, writeThrough 'undefined'
   someFunction.memoized.writeThrough(undefined)(5, 3, callback);

   // if you api was sync instead of callback, you can use the .sync variants but note that 
   // all the responses are still async as the cache underneath is expected to be async.
   someSyncFunction.memoized.sync(5, 3, callback);

   // By default memoized uses the name of the function and JSON.stringify of the arguments to determine
   // the cache key.  If you have two functions with the same name but destined for different caches, you 
   // can configure different names like so:
   someSyncFunction.memoized.configure({name: 'someSyncFunction-alternate'});
   
   // if you want to normalize the arguments for the cache, you can provide your own method that does that.
   someSyncFunction.memoized.configure({getCacheProperties: function (info) { info.key = some_func_of(info.args); }});
}

Explicit usage

   var memojs = require('memojs');

   function someSyncFunction(arg1, arg2) {
     return arg1 + arg2;
   }

   function someFunction(arg1, arg2, done) {
     return done(null, arg1 + arg2);
   }
   
   var memoized;

   // note that someFunction.memoized is declared via prototype automatically.
   memoized = memojs(someFunction);
   memoized(5, 3, function (err, val) {
     // now if you call someFunction.memoized(5, 3, cb) it will use the cache.
   });

   // you can configure the cache and other details as follows
   memoized.configure({store: yourStoreImplementation()});

   // you can also get a one-off implementation that uses a different store as follows
   var someFunctionButDifferentCache = memojs(someFunction, {store: anotherStore()});

   // you can get contents from the cache directly via the cached property.
   // the following call will not actually ever call someFunction
   memoized.cached(5, 3, callback);

   // you can readThrough values via readThrough.  This does not read from the cache 
   // but will end up saving to the cache though.
   memoized.readThrough(5, 3, callback);

   // you can also write through to the cache.  This does not call someFunction but allows updating
   // the caches directly.
   memoized.writeThrough(42)(5, 3, callback);

   // if you want to delete an item from the cache, writeThrough 'undefined'
   memoized.writeThrough(undefined)(5, 3, callback);

   // if you api was sync instead of callback, you can use the .sync variants but note that 
   // all the responses are still async as the cache underneath is expected to be async.
   var memoizedSync = memojs(memoizedSync);
   memoizedSync(5, 3, callback);

   // By default memoized uses the name of the function and JSON.stringify of the arguments to determine
   // the cache key.  If you have two functions with the same name but destined for different caches, you 
   // can configure different names like so:
   memoized.configure({name: 'someSyncFunction-alternate'});
   
   // if you want to normalize the arguments for the cache, you can provide your own method that does that.
   memoized.configure({getCacheProperties: function (info) { info.key = some_func_of(info.args); }});
}

Using the built-in memory cache

The module comes with a built in in-memory cache. While this is interesting for short-lived applications, the memory cache needs to be pruned for long lived applications. To do that, you need to explicitly set the store as follows:


  var memojs = require('memojs');
  var store = require('memojs/memory.js').create();
  
  // configure memojs to use this store.
  memojs.configure({store: store});

  // whenever you want to prune the keys, do:
  // be warned that this could take a while.
  store.prune();

Using the built-in per-domain cache.

Sometimes, the cache is only needed on a per-domain basis. For example, if you are using a new node domain per HTTP request, or you are using one of the excellent expressjs domain middlewares (connect-domain or express-domain-middleware), you may want to provide a cache that is only used on a request and thrown away. For example, you read the user object and any database calls to read it again need to hit the cache.

In that case, you can use the memoryDomain store which stores the cache only on the current active domain.


  var memojs = require('memojs');
  var store = require('memojs/memoryDomain').create();

  // configure memojs to use this store
  memojs.configure({store: store});

  // any future calls to memojs will use the local store as needed.

Chaining stores.

Sometimes you want to chain stores in a write-through fashion. For example, use a per-domain store backed by a REDIS store.

All the stores accept a previous store to pass the request through in case of a cache miss.

   var redisStore = require('memojs-redis').create(null, {redisArgs: [port, host, {auth_pass: pwd}]});
   var memoryStore = require('memojs/memory').create(redisStore);

   // now use this
   memojs.configure({store: memoryStore});