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

pattern-emitter2

v0.1.0

Published

Node.js Event emiiter that allows for complex event name pattern matching and event validation rules

Downloads

2

Readme

node-pattern-emitter

Node Pattern-Emitter is a full implementation of the event emitter API from Node.js built ontop of the crossroads.js parser which allows you to attach event handlers to complex patterns where the pattern matches are passed as arguments to the handlers. This, over the simple string matching with the default EventEmitter, can open the doors for highly generic and flexible code.

Installation

npm install node-pattern-emitter --save

Standard Strings

PatternEmitter is a full implementation of Node.js EventEmitter and functions as you would expect.

var PatternEmitter = require('pattern-emitter');
var emitter = new PatternEmitter();

emitter.on('foobar', function( a, b, c ){
	console.log( a, b, c)
});

emitter.emit('foobar', 1, 2, 3) // -> 1, 2 ,3

Simple variables

In the most simple case, you can include a pattern group in the name of your event with the {} syntax. Whatever value is matched for the group will be passed as a positional argument to the event handler.

var PatternEmitter = require('pattern-emitter');
var emitter = new PatternEmitter();

emitter.on('object/{type}', function( type ){
	console.log( type )
})

emitter.emit('object/create') // -> create
emitter.emit('object/update') // -> update
emitter.emit('object/delete') // -> delete
emitter.emit('foobar')        // No Match

Wildcard Matching

Because of the nature of the crossroads parser, slashes in event names are treated as rough patern delimiters. Pattern Emitter allows you to match against wild cards to work around this edge case, in addition to mitigate the need to account for every named event within your application with {*} notation. For Example, in complex CRUD applications, listening to create, update or delete event pipelines can get messy. It could also be used to re-disaptch / transform events.

var PatternEmitter = require('pattern-emitter');
var emitter = new PatternEmitter();

emitter.on("before/{action*}", function( action ){
    // do some crud magic
    emitter.emit( action )
    emitter.emit("after/" + action)
});

emitter.on('manage/{datatype}', function(datatype){
     // trip off some background tasks...
     console.log('managing %s ! ', datatype )
});

emitter.on('add/{amount}/{type}', function(amount, type){
	console.log("I should add %s more %s", amount, type )
})

emitter.emit("before/update"); // -> dispatches aftrer/update
emitter.emit("before/delete"); // -> dispatches after delete
emitter.emit("before/add/1/post"); // -> dispatches after/add/1/post -> logs "I should add 1 more post"
emitter.emit("before/manage/blogpost"); // -> logs manage/blogpost

Optional Patterns

Rather than having to attatch to event handlers that do essentially the same thing around expected inputs, you can attach a single handler to an event with optional pattern groups with the : : syntax. NOTE - This also means your event names can not contain colons, they are treaded differently.


var PatternEmitter = require("pattern-emitter");
var emitter = new PatternEmitter();

emitter.on('foo:bar:', function( bar ){
	console.log( bar );
});

emitter.emit('foo') // undefined
emitter.emit('foo/bar') // bar
emitter.emit('foo/bar/baz') // No Match!

Optional parameters can also be combined with wild cards


var PatternEmitter = require("pattern-emitter");
var emitter = new PatternEmitter();

emitter.on('foo:bar*:', function( bar ){
	console.log( bar );
});

emitter.emit('foo') // undefined
emitter.emit('foo/bar') // bar
emitter.emit('foo/bar/baz') // bar/baz

Event Validation

You can hook into, and validate the named groups of your event and determine if / when an event should or should not be dispatched. This is achieved by passing an object as the third parameter to addListener or on, where the key is the name of the group to validate.

Literal Values

The simplest validation type is an array of literal values to accept as valid;

var PatternEmitter = require('pattern-emitter');
var emitter = new PatternEmitter();
// only allow object-foo and object-bar events
var rules = {
	type:["foo", "bar"]
};

emitter.on('object-{type}', function( type ){
	console.log( type )
}, rules);

emitter.emit('object-foo') // -> foo
emitter.emit('object-bar') // -> bar
emitter.emit('object-test') // nothing happens

Regular Expression

In situations when simple string matching isn't enough, Regular expressions can be used for complex pattern matching. The same rules object syntax is used to achieve this

var PatternEmitter = require('pattern-emitter');
var emitter        = new PatternEmitter();

// only allow events that are numbers
var rules = {
	amount:/(\d+)/
};

emitter.on('pattern-{amount}', function( type ){
	console.log( type )
}, rules);

emitter.emit('pattern-1234') // -> 1234
emitter.emit('pattern-4321') // -> 4321
emitter.emit('pattern-test') // nothing happens

Functions

For extreme situations where Regular Expressions can't do it, you can use a function to validate pattern groups. You function should return either true or false to indicate if the value has passed your validation rules

var PatternEmitter = require('pattern-emitter');
var emitter        = new PatternEmitter();

// Event is dispatched if
// 1) bar is either baz or far
// 2) AND foo is a number greater than 10
// 3) AND the current user has previously been authenticated.
var rules = {
	foo:/(\d+)/
	,bar: function( value, request, valuesobj ){
		if( value in ['baz', 'far'] ){
			// foo has already been validated to be a number
			if( valuesobj.foo > 10 ){
				// this is not a real thing, just an example
			        if( request.user.is_authenticated ){
			        	return true;
			        }
			}
		}
		return false;
	};
};

emitter.on('pattern/{foo}/{bar}', function( type ){
	console.log( foo, bar );
}, rules);

emitter.emit('pattern/1234/baz') // -> 1234, baz
emitter.emit('pattern/2/far') // -> 2, far
emitter.emit('pattern/one/baz') // nothing happens
emitter.emit('pattern/1') // no match