Nunt is a light-weight event eco system for javascript. It allow your app to communicate trough custom events.
It can be used on the browser, with node or to communicate between both.

Nunt exists solely to simplify event driven programming.

You basically use it like this.

// listen
nunt.on("foo", function(event){
     console.log("hello " + event.name);
});

// send
nunt.send("foo", {name: "bar"});

Everything else nunt offers is extra sugar to make your solutions more flexible than ever.

Nunt offerts some helper functions to initialize a full functional event driven eco system. It even has methods for testing and a chrome extension to inspect everything that is sent and received.

just another image to show off nunt

Nunt consists of two base functions and a couple of helper functions. The base functions are the ones that are used most of the time. The helper functions are used in specific cases or when testing your code.

These are two base functions for nunt:

  • nunt.on(event name, callback) To listen for any events (like jQuerys bind)
  • nunt.send(event name, [event data]) To send events with optional data

Example for listening:

// listen
nunt.on("foo", function(event){
     console.log("hello " + event.name);
});

Example for sending:

// send
nunt.send("foo", {message: "bar"});
temp

What is an event?

An event is basically a message with a name. In nunt its usually sent as an object with at least one property called _name which identifies the event.

Event data

Whatever you choose to send as data will be passed forward. However, if you plan to use nunt on both client and server, the data has to be serializable.

Examples

// send an event called "foo.bar" with an object {id: 1}
nunt.send("foo", {id: 1}); 

// will just trigger the event without custom data
nunt.send("foo"); 

// will send an event with a functions as its data
nunt.send("foo", function(){console.log('foo')}); 

Your solution will typically consist of something more than one small function.

As your solution grows, you will end up with many classes and functions that have to be initialized and synchronized.

To make sure everything is up and running, this is a common approach with nunt:

Lets assume you have one class/function in your solution that is called notify, that handles messages shown to the user:

notify.view.js

(function(){
    nunt.on("notification.show", show);
    function show(e){
        alert("Notify: " , e.message);
    }
})();

You might have another function somewhere that checks if the user has a cookie that signlalizes that he/she is logged in:

user.control.js

(function(){
    if (userHasLoggedIn()){
        nunt.send("nofity.show", {message: "Welcome"});
    }

    function userHasLoggedIn()
    {
        // cool user check code here
    }
})();

The problem that arrises here, is that the user function doenst know if notify.view.js has been loaded and run yet. And if it hasnt been loaded, the "notify.show" listener hasnt been registred yet. And if the event hasnt the listener, no message will be shown.

The solution is simple and work pretty much like the ready event in jQuery. When everything is loaded nunt will send a special event called nunt.READY. The event singalizes that all documents have been loaded and them DOM is ready.

With that in place, we can solve the above situation like this instead:

(function(){
    nunt.on(nunt.READY, init);

    function init()
    {
        if (userHasLoggedIn()) {
            nunt.send("nofity.show", {message: "Welcome"});
        }
    }

    function userHasLoggedIn()
    {
        // cool user check code here
    }
})();

Writing testable code

If you want to test your methods, you need to access them ourside their protected scope. Nunt can help you by adding your functions to predefined namespaces and initilizing them for you. So instead of just creating an anonymous function, you can do it like this:

notify.view.js

// register it with nunt
nunt.views.notify = function()
{
    // your code here
};

This will be initilized by nunt exactly in the same way as show before, but with the possibility to access the code later if you want to test it.

Nunt has 4 namespaces that it will iterate trough and look for functions to initilize:

nunt.models, nunt.controls, nunt.views and nunt.objects.

If you want to know more on hwo to use this for testing, read more about it further down.

To help developers write their apps more efficient, nunt has some helper functions.

nunt.addGlobalListeners(callback)

Adds a callback to be called for any event sent to nunt.

This can be used when your application wants to react to all events. Inside the callback you might have condition to react to only one type of events.

Example:

(function(){
    nunt.addGlobalListeners(function(e){
        if (e._name.indexOf("user.") == 0)
        {
            //do something
        }
    }
})();

This example would set a listener for all events and run a callback. The callbacks checks if the event name begins with the string "user." and does something.

nunt.removeListener(event, [callback])

Removes an event listener.

If you create a massive app and you want to make sure unwanted listeners don't take resources, then you might want to unregister them.

This method takes the event name and the callback as parameters. If you omit the callack, it will remove all callbacks connected to the event.

Example:

(function(){
    nunt.removeListener("foo.bar", mySpecialCallback); 
})();

This will remove the listener for the event "foo.bar" connected to the callback "mySpecialCallback".

nunt.getExposedInstance(classRef)

Used for testing

When you call this function with a class reference as the parameter, you get a new class that exposes the private functions.

nunt.getDispatchedEvents()

Used for testing mostly, get a list of all sent events.

nunt.getListeners(event)

Get a list of all callback for one event

When you include nunt in your application by loading it, nunt will prepare itself by doing adding a callback to check when them DOM is ready. It will then go trough a couple of steps to make sure you can develop as easy as possible.

In other words, it you put this into your html document

<script type="text/javascript" src="/js/lib/nunt.js" charset="utf-8"><script>

Then the start process of nunt follows this pattern:

  1. Load nunt script
  2. Nunt adds callback for DOM ready
  3. Everything is loaded (DOM ready)
  4. Nunt loops through everything in nunt.models and makes an instance (singleton) of all classes it finds.
  5. Nunt loops through everything in nunt.controls and makes an instance (singleton) of all classes it finds.
  6. Nunt loops through everything in nunt.views and makes an instance (singleton) of all classes it finds.
  7. Nunt loops through everything in nunt.objects and makes an instance (singleton) of all classes it finds.
  8. Nunt sends the nunt.READY event

By following this process, all our functions are initiated and ready when we get the nunt.READY event. This works in a similar way as jQuerys $(document).ready method.

temp

Nunt in nodejs will work exaclty as on the browser. But it's when you use it on both on the browser and on the server that you really are creating magic.

It lets you send an event from the server and listen to it on the client and vice versa.

The benefits are many...

  • No need to build a bridge between frontend and backend
  • Same kind of events on both sides
  • Same events and same language gives you one mindset when developing

Nunt uses socket.io to build transparent bridge between node and your client. The result is simple, your app communicates with the server without need to develop an extra layer. Just send events.

temp

Lets describe it with an example. Assume you have an app that has a save button:

$(".saveButton").click(function(){
     nunt.send("save", {myData: "lorem"}
});

The server will listen to the event "save" in the same way your client could listen to it. So on you node server you might have something like this:

nunt.on("save", function(event){
     // save your data in some way
     console.log(event.myData);
     nunt.send("save.done", {ok: true});
});

It's almost magic because you are using one kind of event system, one way of communicating, one language and one mindset for your whole app. It makes the two worlds grow a little closer together and makes developing easier.

Note

In the example above, when the "save" events is sent, the server will send the "save.done" event so that the client could show some kind of notification.

If you have events that aren't supposed to be sent from the client to the server (or vice versa), you can just add a property called "local" to your event data, and it will not be send to the other side (like this: nunt.send("myLocalEvent", {local: true})).

Socket.io and sessions

When your app is running nunt on both server and client trough socket.io and events are sent back and forward, you have to manually make sure an event is either sent to all connected clients or just to the one that sent an initial event.

In the case demonstrated above, you might don't want to send the "save.done" event to all clients, but just to the one that clicked the save button.

In that case, you have to add a property to the data called sessionId. Just do it like this:

nunt.on("save", function(event){
     // save your data in some way
     console.log(event.myData);
     nunt.send("save.done", {ok: true, sessionId: event.sessionId});
});

As you can see, we grab the event.sessionId from the incoming event, and set it to the outgoing event. Simple. If we where to omit the sessionId property, the event will be sent to all connected clients.

nunt has some testing helper methods built in. You can set nunt to test mode by setting a property called nunt.unitTestMode = true;

Just put this code before loading nunt:

<script type="text/javascript" charset="utf-8">var nunt = window.nunt || {}; nunt.unitTestMode = true;</script>

This will start nunt in test mode, meaning that it won't initialize all methods registered with the helper methods. It will then allow you to get instances of your classes and test them separately.

So you could test a class called cart by getting an instance of it like this:

var instance = nunt.views.cart.getInstance();

When you are in test mode and you get an instance like this, you are automatically able to access all private methods defined in the class as well.

So a class that is defined the following way:

nunt.views.cart = function()
{
     function hello()
     {
          …
     }
}

And you get the instances as above:

var instance = nunt.views.cart.getInstance();

Will expose its private methods like this:

instance._privates.hello()

...making it even easier to test.

You can also access all triggered events with the methods:

// which gets the last event
nunt.getLatestDispatchedEvents() 

// which gives you a list of all sent events
nunt.getDispatchedEvents(); 
And you can test if an event has a specific listener
nunt.hasListenerWithCallback("shop.cart.updated", foo);

One of the biggest disadvantanges of developing event driven is following the execution of the code. Since no methods are directly called, and you don't have one place to look for listeners (since they might be registered all over your project), people tend to find it difficult to follow. Luckely there are ways to make this easier.

nunt chrome inspector lets you see all listeners, check all callbacks and see what events are triggered. You can even see if an events is sent from node or just in the client. Here is a quick video on how it works:

Lorem