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

usey

v1.9.5

Published

Generic middleware/plugin framework inspired by express.js's .use()

Downloads

39

Readme

usey

Generic middleware/plugin framework inspired by express.js's .use()

about

build status

This module generates a single function which when called will pass the values passed to it to each of the functions specified with the .use() method. If one of the functions passes an error to the next() function the main callback will be immediately called (if specified) and no functions further in the chain will be processed.

This is inspired by the express.js .use() method and is a generic implementation of it.

install

npm install usey

basic example

var Usey = require('usey');

var app = Usey();

app.use(function (obj1, obj2, next) {
   obj1.x += 1;
   obj2.y += 1;

   return next();
});

app.use(function (obj1, obj2, next) {
   obj1.x += 2;
   obj2.y += 2;

   return next();
});

app({ x : 0 }, { y : 0 }, function (err, obj1, obj2) {
   console.log(arguments);
});

named chains example

var Usey = require('usey');

var app = Usey();

//do a thing, and then goto cleanup
//going to cleanup because of this is not going to happen
//because doThing is going to throw an error
app.use(doThing, Usey.goto('cleanup'));

//use the goto helper to jump to the cleanup chain when
//and if the error chain gets hit
app.use('error', Usey.goto('cleanup'))
app.use('cleanup', doCleanup)

app({ x : 0 }, function (err, obj) {

});

function doThing (obj, next) {
	//throwing an error will cause the 'error' chain
	//to be called
	return next(new Error("this thing failed"));
}

function doCleanup (obj, next) {
	return next();
}

usage

Create an instance

When you create an instance by calling Usey(), it returns a function. That function has one method: .use().

var Usey = require('usey');
var u = Usey(); //this creates the instance function

The Usey constructor takes an options object with the following options:

  • context : [object] this is the context (the this value) for each of the functions passed to the use() function and for the main callback.
    • By default a new empty object created when calling the usey instance function and that is used as the context for each function passed to use()
  • timeout : [number] a numeric value that specifies the maximum number of milliseconds to wait for any of the .use() specified functions to callback
  • stackNames : [boolean] if true, when .use() is called, we will use stack traces to determine where the function was defined. This information is used when debugging
  • debug : [function] an optional function that will be called with debug information. If not defined, it defaults to using the debug module.

Add middleware/plugins/functions

When you call the .use() method, you may pass it a single function, an array of functions or many functions as arguments.

u.use(fn1);
u.use([fn2, fn3, fn4]);
u.use(fn5, fn6, fn7, fn8);
u.use(fn9);

Remove middleware/plugins/functions

When you call the .unuse() method passing it a function reference, you can remove that function from the processing chain.

u.unuse(fn9);

Inserting / unshifting middleware/plugins/functions

You can insert a function to specific position using .insert() or .unshift()

//put the function f10 at the beginning of a chain
u.unshift(f10);

//put the function f11 at some specific position
u.insert(5, f11);

//you can also to it to named chains
u.unshift('error', logErrorMessage);

u.insert('cleanup', 4, closeDatabase);

Call the main function

Now when you call u(arg1, arg2, arg3, ..., function (err, arg1, arg2, arg3, ...){}), it will in turn call, in order:

fn1(arg1, arg2, arg3, ..., next);
fn2(arg1, arg2, arg3, ..., next);
fn3(arg1, arg2, arg3, ..., next);
fn4(arg1, arg2, arg3, ..., next);
fn5(arg1, arg2, arg3, ..., next);
fn6(arg1, arg2, arg3, ..., next);
fn7(arg1, arg2, arg3, ..., next);
fn8(arg1, arg2, arg3, ..., next);
fn9(arg1, arg2, arg3, ..., next);

However, it will only call each function after the currently executing function calls the next() method.

var obj = {};
u(obj, function (err, obj) {
	console.log(obj);
});

Named Function Chains

You may call the .use() method passing it a string as the first argument. That string should be the name of a chain. You can then call that chain from another.

The named chain error is a special named chain that will be called if an error is passed to the next() callback at any time. The error named chain will be processed before the main callback will be called. This is helpful for cleaning up after errors have occurred.

var u = Usey();

u.use(openDatabase('mydatabase'));
u.use(beginTransaction);
u.use(insertOrderHeader);
u.use(insertOrderItems);
u.use(commitTransaction);
u.use(goto('finally'));
u.use('finally', closeDatabase);
u.use('finally', closeRedis);
u.use('error', rollbackTransaction);
u.use('error', goto('finally'));

u(order, function (err) {
	//done
});

function openDatabase(db) {
	return function () {
		var self = this
			, next = getNext(arguments);

		//this is hypothetical
		mysql.open(db, function (err, client) {
			if (err) {
				return next(err);
			}

			self.db = client;

			return next();
		});
	}
}

function beginTransaction() {
	var next = getNext(arguments);

	this.db.beginTransaction(next);
}

function goto(name) {
	return function () {
		var next = getNext(arguments);

		next(name);
	}
};

function getNext(a) {
	return a[a.length -1];
}

http server example

var Usey = require('usey')
   , responseTime = require('response-time')
   ;

var app = Usey();

app.use(responseTime()) //this middleware adds a X-Response-Time http header
   .use(Redirect) //this middleware attaches .redirect() to the response object
   .use(Router(app)) //this middleware attaches .get() and .post() methods to app
   .use(_404) //this middleware is called last

app.get('/test', function (req, res, next) {
   return res.end('hello');
});

app.get('/redirect-me', function (req, res, next) {
   return res.redirect('https://www.npmjs.org');
});

var server = http.createServer(app)

server.listen(1337);

function Redirect(req, res, next) {
   //append redirect method to response object
   res.redirect = function (url) {
      res.writeHead(302, {
         Location : url
      });
   };

   return next();
}

function Router(app) {
   var routes = [];

   ['get', 'post'].forEach(function (method) {
      app[method] = addRoute.bind(app, method)
   });

   app.add = addRoute;

   function addRoute (method, path, handler) {
      routes.push({
         method : method.toUpperCase()
         , path : path
         , handler : handler
      });

      return app;
   }

   return function (req, res, next) {
      var route;
      for (var x = 0; x < routes.length; x ++ ){
         route = routes[x];

         if (route.method == req.method && route.path == req.url) {
            return route.handler(req, res, next);
         }
      };

      return next();
   }
}

function _404 (req, res, next) {
   res.writeHead(404);
   res.end('File not found');
}

license

MIT