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

cashe

v0.3.1

Published

Simple cache utility

Downloads

45

Readme

Build Status Coverage Status Dependency Status devDependency Status Gittip

NPM

cashe

cashe is a simple "get from cache or create if not in yet" little utility for NodeJS.

It seems I always need something like this in my projects as of late so I figured others probably do too and I decided to extract it into its own tiny module.

Install

npm install cashe --save

Usage

The most basic use of cashe is by giving it a function that will create something given a key.

var cache = cashe( function( key ) {
	return key + "value";
} );

You'd use it as follows:

cache( "firstKey" ); // calls function, returns firstKeyValue
cache( "secondKey" ); // calls function, returns secondKeyValue
cache( "firstKey" ); // does NOT call function, returns firstKeyValue

You can go the verbose way and use an options object.

var cache = cashe( {
	create: function( key ) {
		return key + "value";
	}
} );

Custom store

By default, cashe will store values in a plain object. You may wanna use your own store for this as follows:

var cache = cashe( {
	create: createFunction,
	store: myStore
} );

A store must implement the following interface:

  • has( <key> ): returns true if a value is associated to the key, false otherwise
  • get( <key> ): returns the value associated to the key. What happens if no value is associated to the key is unspecified: cashe will never call get if has returned false
  • set( <key>, <value> ): associates the value to the key and returns the value. What happens if a value is already associated to the key is unspecified: cashe will never call set if has returned true

It is recommended that a store also implements the following optional method:

  • del( <key> ): removes value associated with key. What happens if no value is associated to the key is unspecified: del should only be called if has returned true. If the store doesn't support deleting entries yet implements del then del must throw an exception

cashe does not use del internally but it can prove useful in order to implement advanced logic on your end.

As an example, here is the code of the default store:

function ObjectStore() {
	this.object = {};
}

ObjectStore.prototype = {
	has: function( key ) {
		return this.object.hasOwnProperty( key );
	},
	get: function( key ) {
		return this.object[ key ];
	},
	set: function( key, data ) {
		return ( this.object[ key ] =  data );
	},
	del: function( key ) {
		delete this.object[ key ];
	}
};

You can access the default ObjectStore through cashe.ObjectStore and use it as a base for your own stores if you so desire.

The store of a cache is exposed as its storefield:

var cache = cashe( {
	create: createFunction,
	store: myStore
} );

cache.store === myStore; // true

Complex input data for creation

Sometimes, a simple string is not enough as an input to create. Let's take some stupid greeting messages as an example:

function createGreeting( person ) {
	return "Hello, " + person.firstName + " " + person.lastName;
}

var cache = cashe( createGreeting );

cache( JulianData ); // returns "Hello, Julian Aubourg"
cache( CoreyData ); // returns "Hello, Julian Aubourg" !!!!

What happens here is that, cache uses the default ObjectStore which considers whatever is given to it as key to be a string... which means both JulianData and CoreyData will have the same underlying key: [object Object].

To avoid this, you could provide a custom store but that seems like a lot of work for nothing.

That's why there is a key option that you can provide to get a key out of whatever data the cache function will be given:

var cache = cashe( {
	create: createGreeting,
	key: function( personData ) {
		return personData.id;
	}
} );

cache( JulianData ); // returns "Hello, Julian Aubourg"
cache( CoreyData ); // returns "Hello, Corey Frang"

In fact, the function can return any type of data as long as it is compatible with what the associated store expects as keys.

As a convenience, the create function is given whatever the key function returned as a second argument:

function createGreeting( person, key ) {
	person.id === key; // true
}

OMG! THIS IS NOT ASYNCHRONOUS-AWARE! WHAT THE WHAT?!?

Everything in cashe is synchronous: the create function must return synchronously and so do all the methods of a custom store.

If you wanna handle asynchronous stuff behind cashe then (hint hint) use promises (I use JQDeferred extensively myself with great success).

License

Copyright (c) 2012 - 2014 Julian Aubourg Licensed under the MIT license.