Node Roundup: Command-Option-Argument, Nodemailer, Node.js-Ultra-REPL

14 Mar 2012 | By Alex Young | Comments | Tags node modules inspectors repl email
You can send in your Node projects for review through our contact form or @dailyjs.

Command-Option-Argument

Command-Option-Argument (npm: coa) by Sergey Berezhnoy is a command-line option parser that uses a chainable API:

require('coa').Cmd() // main (top level) command declaration
  .name(process.argv[1]) // set top level command name from program name
  .title('My awesome command line util') // title for use in text messages
  .helpful() // make command "helpful", i.e. options -h --help with usage message
  .opt() // add an option
    .name('version') // name for use in API
    .title('Version') // title for use in text messages
    .short('v') // short key: -v
    .long('version') // long key: --version
    .flag() // for options without value
    .act(function(opts) { // add action for option
      // return message as result of action
      return JSON.parse(require('fs').readFileSync(__dirname + '/package.json'))
          .version;
    })
    .end() // end option chain and return to main command

The API’s chainable design uses stack-like hierarchies, so when an option is declared with opt() subsequent method calls will apply to that option. The author has included a makefile which runs tests with Vows.

Nodemailer

Nodemailer (License: MIT, npm: nodemailer) by Andris Reinman is a module for sending emails that supports Unicode, attachments, connection pools, and SSL/STARTTLS. It’s even designed to work with popular mail services like Gmail and Hotmail.

The API centres around SMTP transports:

var nodemailer = require('nodemailer')
  , smtpTransport = nodemailer.createTransport('SMTP', {})
  , options = { from: 'alex@example.com', subject: 'Subject', text: 'Hello' };

smtpTransport.sendMail(options, function(err, response) {
});

Notice the use of the standard leading error argument in the callback. This project includes a test suite written with Nodeunit.

Node.js-Ultra-REPL

ultra-repl

Node.js-Ultra-REPL (License: MIT, npm: ultra-repl) by Brandon Benvie is a REPL for Node that’s intended to be used as a development environment. It provides a command-line UI where JavaScript can be executed and explored. Before using it, I strongly recommend pressing F1 to learn the basic commands. The command prompt stays at the bottom of the screen, while the result of any code is displayed above. Results can be read through by using page up and down. New V8 contexts can be created using control shift up, then switched between using control up and control down.

jQuery Roundup: 1.7.2 RC1, OEmbed All, Ignition, nextVal, jquery-ui-rails

13 Mar 2012 | By Alex Young | Comments | Tags jquery plugins frameworks embedding validation
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery 1.7.2 RC1

jQuery 1.7.2 RC1 has been released. Several bugs have been fixed since the last beta release, which are fully documented in the announcement blog post. The announcement also contains an interesting call for IE6 help:

If you are particularly interested in IE6 support, please help us out. We are having sporadic trouble running the unit tests in IE6. It hasn’t been possible for us to determine the cause of these problems, but the problem doesn’t happen consistently and the sheer size of our test suite may just be overwhelming a browser that is more than a decade old.

jQuery OEmbed

jQuery OEmbed All (GitHub: starfishmod / jquery-oembed-all, License: MIT) can embed content like YouTube videos simply by providing a URL to the item’s page. It was originally created by Richard Chamorro, but this version has been forked by Andrew Mee to rely less on the OEmbed API.

The plugin will attempt to use various third party services to embed the content, including JSONP oEmbed and YQL. Services that require an API key are also supported:

$('.oembed').oembed(null,{
  embedMethod: 'auto',
  apikeys: {
    etsy: '<your etsy key>'
  }
});

Ignition

Ignition logo

Ignition (GitHub: daytona / ignition, License: MIT/GPL) by Johan Sahlén of Daytona Communication AB is a jQuery MVC framework. It was sent in by Wade Stebbings who said he’d struggled to find information on it after it was recommended by a friend. It’s definitely an interesting framework, even though it seems to have stalled development in 2009.

It supports URL routing:

var $i = new Ignition({ modules: ['UrlManager', 'HistoryDispatcher'] });

$i.addRoute('articles/(\d+)', function(article_id) {
  $i.c.Articles.show(article_id);
});

And models:

$i.m('Article', {
  find_by_id: function(id, callback) {
    this.json($i.getUrl('article', { id: id }), { success: callback });
  }
});

Controllers and programmatic views are also included:

$i.c('Articles', {
  show: function(id) {
    $i.m.Article.find_by_id(id, $i.v.Articles.show);
  }
});

$i.v('Articles', {
  show: function(data) {
    var list = $('<ul id="articles"></ul>');
    for (var i = 0; i < data.articles.length; i++) {
      var article = data.articles[i];
      var listItem = $('<li><a href="'+article.url+'">'+article.title+'</a></li>');
      list.append(listItem);
    }

    $('body').append(list);
  }
});

API documentation is available if you want to dig a little deeper into the framework: Ignition API documentation.

nextVal

nextVal (GitHub: jukebox42 / nextVal, License: MIT) by John Norton is a form validation plugin. It uses a validate attribute with options that work a little bit like a mini validation DSL:

<input type="text" validate="email" placeholder="Please enter a proper email address" />

Then $(selector).nextVal() can be called on the form. Custom validation rules can also be added:

$(function() {
   $('form[name=FORMNAME]').nextVal({
      customRules:[
         ['matchpassword',function($o){return !($o.val() == $('#password').val());},''],
         ['xheader',function($o){return !$o.val().match(/^X-[a-zA-Z0-9_\-]+$/);},'Please enter a valid xheader. For example X-UserData1'],
      ]
   });
});

The only problem I have with this approach is the use of the validate attribute. To my knowledge, there is no validate attribute, so this should probably use a data attribute instead. Also, HTML5 already provides some validation attributes (required, pattern, min and max, step, and maxlength).

jquery-ui-rails

jquery-ui-rails makes adding jQuery UI 1.8.18 and its associated assets easy to install in Rails projects. It’s configured to work with the Rails asset pipeline, so it’s easy to require specific modules and get jQuery UI projects off the ground quickly.

Nools, Procstreams, Kalendae

12 Mar 2012 | By Alex Young | Comments | Tags node modules calendars unix

Nools

Nools (License: MIT, npm: nools) by Doug Martin is a rules engine. Rules are contained in “flows”, and instances of flows are known as “sessions” – these are used to add or retract facts from the engine:

var nools = require('nools')
  , session
  , message;

function Message(message) {
  this.message = message;
}

session = flow.getSession();
message = new Message('hello');

// Add the fact to the engine
session.assert(message);

// Change it
message.message = 'Bye';
session.modify(message);

// Remove it
session.retract(message);

For examples of how to define flows, have a look at the Nools readme.

Procstreams

Procstreams (License: MIT, npm: procstreams) by Marco Rogers is an attempt to create a more idiomatic JavaScript shell scripting API:

var $p = require('procstreams');
$p('cat lines.txt').pipe('wc -l')
  .data(function(stdout, stderr) {
      console.log(stdout); // prints number of lines in the file lines.txt
  });

$p('mkdir foo')
  .and('cp file.txt foo/')
  .and('rm file.txt')
    .on('exit', function() {
      console.log('done');
    });

As we’ve seen many times on DailyJS, chainable APIs offer an elegant solution to reducing unnecessary callbacks in asynchronous APIs, so this module is definitely appealing on that level.

Kalendae

Kalendae example screenshot

Kalendae (License: MIT) by Jarvis Badgley provides a date picker without any dependencies. There’s a demo of Kalendae showing calendars instantiated with various options.

If jQuery is available, then a plugin will also be available through $(selector).kalendae(options).

The author has also provided a makefile that can build the project, minimise it, and run it through Google Closure.

RPG, Luca, KSS

09 Mar 2012 | By Alex Young | Comments | Tags node modules games backbone.js

JavaScript Tile-Based RPG

RPG screenshot

Probed / RPG is a tile-based RPG written with server-side JavaScript. It’s built with Node, but the author has only deployed it to Windows so far. There’s a video of the game here:

The goal of the project is to create a random game world with quests, a battle system, loot, equipment, and levelling.

 Luca

Luca.JS (GitHub: http://datapimp.github.com/luca/) by Jonathan Soeder is a library for Backbone.js that provides augmented View and Collection classes:

Luca [includes] best practices and optimizations that I have personally come up with developing some rather large Backbone.js apps. It assumes a style of progamming very similar to ExtJS where you define almost all of your views and components as large nested JSON structures.

Luca is built on Twitter’s Bootstrap CSS, and includes CoffeeScript examples. It’s initially distributed as a Ruby library for Rails projects. The author is planning to add JavaScript examples and distribute an alternate version through npm in the future.

Regardless, it may provide some inspiration for those who want to further their Backbone.js knowledge.

KSS

KSS (GitHub: hughsk / kss-node, npm: kss) by Hugh Kennedy is a Node implementation of Knyle Style Sheets which is a methodology for writing maintainable CSS.

Specifically, KSS is a documentation specification and styleguide format. It is not a preprocessor, CSS framework, naming convention, or specificity guideline.

Installing the KSS module provides a kss-node command-line tool that will generate styleguide documentation based on your LESS or CSS stylesheets.

The project’s site includes a demo – take a look at the KSS Modules documentation for an example.

The module also includes an API, and it includes tests written with Mocha.

Unix and Node: Pipes and Streams

08 Mar 2012 | By Alex Young | Comments | Tags node tutorials unix

An anonymous pipe can be used to connect the standard streams of multiple processes.

tput setaf 48 ; whoami | figlet | tr _ … | tr \\ \` | tr \| ¡ | tr / √

This example prints out the result of whoami using FIGlet, and also uses tput to colourise the output.

Unix pipe example

Pipes are typically denoted with the vertical bar character. Both the | notation and concept of pipes were created by Doug McIlroy, who was quoted in part one of this series for his “Write programs that do one thing and do it well” quote.

Streams

Node provides an abstract representation of a stream through the Stream class. It’s actually widely used within Node, and represents the Unix text streams we’ve been discussing very neatly. In fact, it even includes a pipe method:

stream.pipe(destination, [options])

That means we can actually connect the standard input and output like this:

#!/usr/bin/env node

process.stdin.resume();
process.stdin.pipe(process.stdout);

The resume method is called here because standard input is paused by default.

➜ chmod 700 cat.js 
➜ echo 'Unix has a funny idea about what a cat is' | ./cat.js
Unix has a funny idea about what a cat is

The nice thing about streams in Node is they work like everything else: they’re asynchronous and event-based:

stream.on('data', function(data) {
  console.log('Received data:', data);
});

Whenever a stream is passed to a readable stream’s pipe method, the pipe event will be emitted.

Example

By combining what we’ve learned in the last few Unix and Node articles, we can start to build command-line tools that resemble real Unix tools. The following example uses Commander.js, which can be installed with npm install commander.

#!/usr/bin/env node

var program = require('commander')
  , c = 90;

program
  .version('1.0.0')
  .option('-r, --red', 'Red text')
  .option('-g, --green', 'Green text')
  .option('-b, --blue', 'Blue text')
  .parse(process.argv);

function colour(c, str) {
  return '\033[' + c + 'm' + str + '\033[0m';
}

if (program.red) {
  c = 91;
} else if (program.green) {
  c = 92;
} else if (program.blue) {
  c = 94;
}

process.stdin.resume();
process.stdin.setEncoding('utf8');
process.stdin.on('data', function(data) {
  process.stdout.write(colour(c, data));
});

Running echo "Some text" | ./colour.js --red will display red text. The expected encoding is set with process.stdin.setEncoding('utf8'), else the data argument passed to the data event on the stdin stream would be a plain buffer. The output is written to stdout using stream.write(string, [encoding], [fd]).

Conclusion

By having such a simple asynchronous API for streams, building Node programs that can work well with pipelines in shell scripts is straightforward. Other methods like stream.pipe are also useful. Read Node’s Stream documentation for more details and examples.

Node Roundup: Plunker, Mixr, FnQueue, timekeeper

07 Mar 2012 | By Alex Young | Comments | Tags node modules testing mocking assets apps async
You can send in your Node projects for review through our contact form or @dailyjs.

Plunker

Plunker

Plunker (GitHub: ggoodman / stsh, License: MIT) by Geoff Goodman is a web application for editing web snippets. It’s inspired by other popular services like jsFiddle, but has Node source that you can fork, and has an interface more suited to editing multiple files. It has all the obvious features like syntax highlighting, using the venerable Ace editor. The interface has been built with Twitter’s Bootstrap, so it also serves as an example of a Bootstrap web application.

There’s a public API for Plunker which allows “plunks” to be created, updated, retrieved, and deleted.

Mixr

Mixr (npm: mixr) by Alex Barlow is an Express compiler and pre-processor for client-side JavaScript and CSS. It can also handle other formats like LESS and CoffeeScript. To use Mixr, write client-side code in separate files, then include other files using comments:

//= require lib/jquery.min.js
//= require main.js
//= require something.js.coffee

In this example, Mixr would automatically process the CoffeeScript file.

During development, it’s possible to compile assets on each request:

app.configure(function(){
  Mixr.addHelpers(app);
});

app.configure('development', function(){
  // Add Mixr routes for development mode only
  Mixr.addExpressRoutes(app);
});

Then during deployment, a compiled file can be generated with ./node_modules/mixr/bin/mixr compile.

FnQueue

FnQueue (License: MIT, npm: fnqueue) by Kilian Ciuffolo is a utility for chaining functions:

new FnQueue({
  // This will wait for 'searchSomething'
  funnyStuff: function(processSomething, callback) {
    callback(null, 'ciao!');
  },
  searchSomething: function(callback) {
    callback(err, results);
  },
}, function(err, data) {
    if (err) {
      throw(err);
    }

    console.log(data.searchSomething);
  }
});

If you want to read more about Node’s wealth of control flow libraries, check out New Control Flow Libraries.

timekeeper

I often find myself needing to travel time, so rather than hacking Date I’d prefer to use mocks through Veselin Todorov’s timekeeper (License: MIT, npm: timekeeper) library. Time can be frozen by using timekeeper.freeze(date). Once the normal passage of time is required, the fourth dimension can be corrected simply by calling timekeeper.reset().

The only caveat is setTimeout and setInteval won’t work as expected until timekeeper.reset() is called.

jQuery Roundup: StyleDocco, noUiSlider, jecookie

06 Mar 2012 | By Alex Young | Comments | Tags jquery plugins css cookies
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

StyleDocco

_______ __         __        _____
|     __|  |_.--.--|  |-----.|     \-----.----.----.-----.
|__     |   _|  |  |  |  -__||  --  | _  |  __|  __|  _  |
|_______|____|___  |__|_____||_____/_____|____|____|_____|
             |_____|

StyleDocco (GitHub: jacobrask / styledocco, License: MIT, npm: styledocco) by Jacob Rask generates documentation and style guides from stylesheets.

It’s distributed as a command-line tool, and can be installed using npm:

npm install -g styledocco

Adding descriptive comments is enough for StyleDocco to generate its results. For an example, see StyleDocco 0.3.0 default styles.

noUiSlider

noUiSlider (GitHub: leongersen / noUiSlider, License: MPL 1.1/2.0) by Leon Gersen generates sliders. The basic usage is $('.sliderbar').noUiSlider(), but it also supports a wide range of options and events.

The sliders can be conventional value sliders, or represent a range with two draggable controls. The author has supplied CSS as well, so it can be used quite quickly out of the box.

jecookie

jecookie (License: MIT) by Alejandro El Informático is a friendly cookie library. JSON is supported, and cookies can be marked as secure.

var cookie = new jecookie('cookie_name', { secure: true, domain: '.example.org' });
cookie.data = { name : value, content : value };

It’s been tested in IE 6+, Firefox 3+, Chrome 10+, and Opera 10+.

Jed, messageformat.js, Blossom

05 Mar 2012 | By Alex Young | Comments | Tags node modules translation sproutcore

Jed

Jed (GitHub: SlexAxton / Jed, License: WTFPL/Dojo CLA, npm: jed) by Alex Sexton is a JavaScript implementation of gettext. Plural forms are parsed using a Jison grammar (in plurals.jison)), and it has a chainable API:

var n = 5;

i18n
  .translate("%d key doesn't exist")
  .ifPlural(n, "%d keys don't exist")
  .fetch();

This can be used in both browsers and Node, and the author also demonstrates using it in the AMD style. As a bonus, Jed includes a useful sprintf implementation.

messageformat.js

messageformat.js (License: WTFPL/Dojo CLA, npm: messageformat) also by Alex Sexton handles both pluralization and gender in translations. Despite sounding similar to Jed, this is a different approach to gettext:

Gettext can generally go only one level deep without hitting some serious roadblocks. For example, two plural elements in a sentence, or the combination of gender and plurals.

Basic interpolation looks like this:

var mf = new MessageFormat('en')
  , message = mf.compile('His name is {NAME}.');

message({ 'NAME' : 'Jed' });
// "His name is Jed."

More complex replacements can use SelectFormat and PluralFormat:

var message = mf.compile('{GENDER, select, male{He} female{She} other{They}} liked this.');
message({ 'GENDER' : 'male' });
// "He liked this."

message({ 'GENDER' : 'female' });
// "She liked this."

Blossom

Blossom (GitHub: fohr / blossom, License: GPLv3 for non-commercial projects, npm: blossom) is an early beta of what Erich Ocean hopes represents the future of SproutCore:

Blossom is a serious attempt to advance SproutCore 1.x forward after the failure of SproutCore 2. I put forward the rational behind Blossom in early December, 2011 and also demo’d early work I had done on Blossom at the SproutCore User Group in Washington D.C. late January, 2012. […] Blossom is designed to become the future of SproutCore, but it also stands on its own.

Blossom has a Node-based build system, and it can be installed with npm install blossom. It includes the latest datastore and statechart code from SproutCore 1.8, and Node-based unit tests for foundation and datastore.

Currently, the SproutCore documentation should suffice for working with parts of Blossom. The Blossom developers are currently working towards their first release candidate on April 1st. The current code on GitHub is 1.0.0-beta.1.

Despite its SproutCore heritage, it’s important to understand where Blossom is different:

instead of simulating a web browser, Blossom’s native runtime has high-performance, platform-native implementations of the various Blossom and SproutCore classes, such as SC.Request (for networking), SC.Layer (for animation), as well as the various JavaScript runtime objects such as CanvasRenderingContext2D, Float32Array and ArrayBuffer that are exposed to Blossom developers.

reMarked.js, Scroll.js, Andro.js, IndexedDB Examples

02 Mar 2012 | By Alex Young | Comments | Tags libraries browser indexeddb ui databases

reMarked.js

reMarked.js (GitHub: leeoniya / reMarked.js, License: MIT) by Leon Sorokin converts a client-side DOM fragment into Markdown. The reMarked.js homepage has several links to GitHub READMEs on the left-hand side, and pressing the ‘reMark it!’ button will convert their HTML into Markdown.

The author’s ultimate goal is to use this in a WYSIWYG editor. It seems like a difficult project, so it features tests as well.

Scroll.js

Scroll.js (License: MIT) by David Babaioff is a cross-browser library for managing the scroll event:

Scroll.bind('scroll_1', function() {
    // Your event handler code goes here.
}).bind({
    'scroll_2': function() {
        // Your event handler code goes here.
    },
    'scroll_3': function() {
        // Your event handler code goes here.
    }
});

It doesn’t have any dependencies, so it may be useful in cases where you don’t want to use a larger library like jQuery.

Andro.js

Andro.js (GitHub: maryrosecook / androjs, License: MIT) by Mary Rose Cook combines the idea of reusable behaviour with events:

Behaviour mixins are good for writing video games. They help with the concoction of game object logic: no more nightmarish inheritance hierarchies or weird bundles of functions that invent cryptic interfaces for the objects upon which they operate.

The author’s example is a cube that gets augmented with behaviours to provide logic based around events:

var Andro = require('andro').Andro
  , andro = new Andro()
  , soundBehaviour
  , cube;

function Cube() {
  this.touch = function(contact) {
    andro.eventer(this).emit('touch', contact);
  };
}

soundBehaviour = {
  setup: function(owner, eventer) {
    eventer.bind(this, 'touch', function() {
      console.log('SFX: Leo_the_Lion.wav');
    });
  }
};

cube = new Cube();
andro.setup(cube);
andro.augment(cube, firstTouchBehaviour);
cube.touch('added');

Here I’ve paraphrased the original example at androjs.maryrosecook.com/ just to give an idea of the syntax. I agree with the author that this library provides some useful tools for representing game logic, and the documentation also provides examples of situations where this might not work so well.

IndexedDB Examples

These IndexedDB examples by Parashuram Narasimhan show what works in Chrome, Firefox, and Internet Explorer 8+. The standards are still changing, but Parashuram has been working hard to track the current state of API changes in both his blog and the jquery-indexeddb plugin.

For more on IndexedDB, see the usual suspects: W3C: Indexed Database API, MDN: IndexedDB.

Unix and Node: Command-line Arguments

01 Mar 2012 | By Alex Young | Comments | Tags node tutorials essay unix documentation

Shebang Bootcamp

Writing an executable script with Node begins with the shebang: #!, followed by the path to a Node executable. Not all Unix systems use the same file system layout, and not all users want to install Node in the same place. Since the shebang must specify an absolute path, a common way around this is to introduce a level of indirection through env:

#!/usr/bin/env node

This can be seen in many popular Node modules, and in other scripting languages too. If I try and run a script like this in my shell, I’ll get an error:

➜ ./echo.js
zsh: permission denied: ./echo.js

I have read permission on the file, but it isn’t executable:

➜ ls -l
-rw-r--r--  1 alex  wheel  21  1 Mar 17:24 echo.js
➜ chmod u+x ./echo.js 
➜ ls -l
total 8
-rwxr--r--  1 alex  wheel  21  1 Mar 17:24 echo.js

Here I’ve used chmod to set the executable flag for the user that owns the file. Most people use the octal notation for setting permissions, which looks complicated but isn’t as hard as it seems.

Argument Vector

Command-line arguments are available through the process global in an array called argv. This term comes from “argument vector”, influenced by C where it’s conventional to name the argument count and argument vector this way:

int main(int argc, char *argv[])

Technically these parameters could be named anything, but this is a strongly followed convention.

Compared to C, JavaScript’s array is a handy type for representing arguments:

#!/usr/bin/env node

console.log('Arguments:', process.argv.length);
console.log(process.argv);

Running this script with no arguments shows what the script was run with:

Arguments: 2
[ 'node', '/private/tmp/unix-node/echo.js' ]

Conversely, passing in arguments looks like this:

➜ ./echo.js --text JavaScript in the shell
Arguments: 7
[ 'node',
  '/private/tmp/unix-node/echo.js',
  '--text',
  'JavaScript',
  'in',
  'the',
  'shell' ]

Handling more complex arguments takes a little bit of work, so it’s often preferable to offload the effort to a suitable module. However, some scripts have simple requirements, so array manipulation of process.argv may suffice. This example is from Node’s cluster.js file:

exports.start = function() {
  amMaster = true;

  if (process.argv.length < 1) {
    console.error('Usage: node cluster script.js');
    process.exit(1);
  }

  var args = process.argv.slice(2);
  var scriptFilename = args.shift();

The length of process.argv is validated to ensure the expected option has been supplied, and process.exit(1) is called if validation fails. This is interesting because an argument has been supplied to process.exit. Why 1?

Exit Status

Unix and Unix-like systems use a convention that a non-zero exit status from a program is an error. In C, EXIT_FAILURE is a macro that can be used to denote this, and on POSIX systems this value is 1. Changing the previous example to return a non-zero exit code looks like this:

#!/usr/bin/env node

console.log('Arguments:', process.argv.length);
console.log(process.argv);

if (process.argv.length < 3) {
  process.exit(1);
}

Running this script with no arguments should return 1. However, look what happens:

➜ ./echo.js 
Arguments: 2
[ 'node', '/private/tmp/unix-node/echo.js' ]

… nothing? There’s no error message or anything! This is actually a good thing – think back to the philosophies behind Unix, in particular Doug McIlroy’s quote:

Write programs to handle text streams, because that is a universal interface.

In a world based around text streams, we don’t want default behaviour that’s too noisy. If someone built upon this script, they’d rather deal with a concrete error status. This value can be obtained in most shells by reading $?:

➜ echo $?
1

Option Parsing Libraries

The two most popular option parsing libraries for Node are Optimist (License: MIT/X11, npm: optimist) and Commander.js (GitHub: visionmedia / commander.js, License: MIT, npm: commander) by TJ Holowaychuk. These are both well-maintained libraries by active members of the Node community.

Optimist has its own argv object that can deal with grouped, long, and short options, and can even display usage:

#!/usr/bin/env node
var argv = require('optimist')
    .usage('Usage: $0 -x [num] -y [num]')
    .demand(['x','y'])
    .argv;

console.log(argv.x / argv.y);

Commander.js has a chainable API that’s like a DSL for option processing:

#!/usr/bin/env node

var program = require('commander');

program
  .version('0.0.1')
  .option('-p, --peppers', 'Add peppers')
  .option('-P, --pineapple', 'Add pineapple')
  .option('-b, --bbq', 'Add bbq sauce')
  .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
  .parse(process.argv);

console.log('you ordered a pizza with:');
if (program.peppers) console.log('  - peppers');
if (program.pineapple) console.log('  - pineappe');
if (program.bbq) console.log('  - bbq');
console.log('  - %s cheese', program.cheese);

The program’s usage is automatically generated.

Conclusion

In Node, powerful option parsing is only an npm install away. The built-in process.argv array is also convenient and easy to manage for simple situations. Just remember to exit programs with conventional status codes, or angry shell scripters may fill up your GitHub issues before you know it!

Node Roundup: Shrinkwrap, Connect 2.0, ClientSide, Pretty-Data, Clusterhub, Introspect

29 Feb 2012 | By Alex Young | Comments | Tags node modules connect npm scaling
You can send in your Node projects for review through our contact form or @dailyjs.

Shrinkwrap

As of version 1.1.2, npm has a new feature called shrinkwrap. This allows dependencies to be locked down across the full module hierarchy. Running npm shrinkwrap will generate a npm-shrinkwrap.json file that contains the exact version of everything installed in node_modules/.

This makes deploying Node apps easier to manage, because new releases of installed modules can (and probably will) be released during development.

Dave Pacheco had some interesting things to say about how Joyent use Node as part of this feature’s announcement:

It’s not exactly news that Joyent is heavy on Node. Node is the heart of our SmartDataCenter (SDC) product, whose public-facing web portal, public API, Cloud Analytics, provisioning, billing, heartbeating, and other services are all implemented in Node. That’s why it’s so important to us to have robust components (like logging and REST) and tools for understanding production failures post mortem, profile Node apps in production, and now managing Node dependencies.

Connect 2.0

TJ Holowaychuk has announced the release of Connect 2.0 (GitHub: senchalabs / connect, License: MIT, npm: connect). The Connect documentation is now much improved, and tests have been rewritten to use Mocha.

New features include:

  • cookieSession() middleware for cookie-only sessions
  • compress() middleware for gzip / deflate support
  • json() middleware for parsing application/json

One major change is connect(), which replaces connect.createServer():

var connect = require('connect')
  , http = require('http')
  , https = require('https');

var app = connect()
  .use(connect.logger('dev'))
  .use(connect.static('public'))
  .use(function(req, res){
    res.end('hello world\n');
  })

http.createServer(app).listen(80);
https.createServer(tlsOptions, app).listen(443);

TJ notes that previous versions of Connect used a connect.Server object that inherited from net.Server. The newer connect() method simply returns a Function, which can be used with http.createServer() or https.createServer(), thereby simplifying supporting both HTTP and HTTPS.

ClientSide

ClientSide (GitHub: jgallen23 / clientside, npm: clientside) by Greg Allen is a command-line tool for packaging client-side code from scripts that use CommonJS modules. It can read a package.json to determine how your library is structured.

The author is planning to write Connect middleware, and has shipped the project with thorough Mocha/Chai tests.

Pretty-Data

Pretty-Data (GitHub: vkiryukhin / pretty-data, License: MIT/GPL, npm: pretty-data) by Vadim Kiryukhin can beautify or minify JSON, CSS, and XML. Rather than using existing libraries, the author has opted to use his own regular expression-based parsing. This reduces the module’s dependencies, so if you’re looking for something lightweight, it might fit the bill.

The project’s site also has live demos that show off the library’s main features with data from sources like Yahoo! Weather and Google’s minified CSS.

Clusterhub

Clusterhub (License: MIT, npm: clusterhub) by Roly Fentanes is a bit like interprocess communication for Node:

var cluster = require('cluster')
  , numCPUs = require('os').cpus().length
  , hub = require('clusterhub');

if (cluster.isMaster) {
  // Fork workers
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }

} else {
  hub.on('event', function(data) {
    // Do something with `data`
  });

  // Emit event to all workers
  hub.emit('event', { foo: 'bar' });
}

Each hub has an in-memory EventVat key/value store. Roly has written some example apps, including clusterchat.

If you’re looking to get more out of a CPU by running several Node processes, then this looks like a simple but potentially fast option. The author notes that the project is still experimental, but given that he’s written some Mocha tests it should be relatively hackable.

Introspect

Introspect (License: MIT, npm: introspect) by Kilian Ciuffolo provides Function introspection:

var introspect = require('introspect');

function fn(foo, bar, callback) {
  // function body
}

var arguments = introspect(fn);
console.log(arguments);
// [ 'foo', 'bar', 'callback' ]

Kilian has included benchmarks, tests written with Vows, and provided instructions on how to run them.

jQuery Roundup: TOC, Curtain.js, Griffin.editor, imgg

28 Feb 2012 | By Alex Young | Comments | Tags jquery plugins ui effects editors
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

TOC

TOC (GitHub: jgallen23 / toc, License: MIT) by Greg Allen will generate a table of contents for a page, and automatically highlight the current section. Basic usage is simply $('#toc').toc();, but it supports some configuration options as well:

$('#toc').toc({
  'selectors': 'h1,h2,h3',   // elements to use as headings
  'container': 'body',       // element to find all selectors in
  'smoothScrolling': true,   // enable or disable smooth scrolling on click
  'prefix': 'toc',           // prefix for anchor tags and class names
  'highlightOnScroll': true, // add class to heading that is currently in focus
  'highlightOffset': 100     //offset to trigger the next headline
});

The design of the plugin allows multiple tables of contents to be used on a page, and the author is planning to add support for Zepto and Ender.

Curtain.js

Curtain.js (GitHub: Victa / curtain.js, License: MIT) by Victor Coulon and submitted by Hirvesh displays pages using an effect similar to a slide show. It supports keyboard shortcuts and conventional scrolling. The panels that make up the page will automatically resize to fill the window.

The plugin is invoked by $('.curtains').curtain() and expects an ordered list:

<ol class="curtains">
  <li class="cover">your content</li>
  <li>
    <div class="fixed"> <!-- if you need a "fixed" content -->
      Fixed content
    </div>
  </li>
</ol>

Panels can also be added dynamically using $('.curtains').data('plugin_curtain').insert().

Griffin.editor

Griffin.editor (GitHub: jgauffin / griffin.editor, License: MPL) by Jonas Gauffin is a jQuery-enhanced, zero configuration, textarea. It supports markdown, but the author notes other formats are easily supported, access keys, and syntax highlighting. It uses jQuery UI, and is easily set up with a call to $('.editor').griffinEditor() and suitable HTML.

The griffin.editor / Demos folder contains examples of how to use the plugin.

imgg

imgg (GitHub: bugzu / imgg, License: MIT) by Gaurav Sharma displays images using an animated mosaic effect. It’s used by passing an array of image locations to $().imgg:

$('#gallery').imgg({
  images: ['images/img11.png', 'images/img22.jpg', 'images/img33.jpg']
});

The author has provided sample images and CSS.

Chaplin, KinectJS, Inject, Minion

27 Feb 2012 | By Alex Young | Comments | Tags kinect backbone.js oo modules commonjs

Chaplin

Chaplin (License: MIT) from Moviepilot and 9elements is an example architecture using Backbone.js. It features lazy loading through RequireJS, module inter-communication using the mediator and publish/subscribe patterns, controllers for managing UI views, Rails-style routes, and strict memory management and object disposal.

While developing web applications like moviepilot.com and salon.io, we felt the need for conventions on how to structure Backbone applications. While Backbone is fine […], it’s not a framework for single-page applications.

All Chaplin needs is a web server to serve the client-side code. The example app, “Facebook Likes Browser”, even includes client-side OAuth 2.0, thereby demonstrating client-side authentication.

KinectJS

KinectJS (License: MIT) aims to bring Kinect controls to HTML5. The author has created some KinectJS demos and KinectJS YouTube videos, so with the required hardware it should be possible to try it out.

The client-side JavaScript is only one part of the implementation – the other is an Adobe AIR application that provides the bridge to the Kinect drivers. The AIR application isn’t currently open source, but the JavaScript code is MIT licensed.

Inject

Inject (License: Apache 2.0, GitHub: linkedin / inject) from LinkedIn is a library agnostic dependency manager. It adds CommonJS support to the browser, and the authors have created a Inject/CommonJS compatibility document to show what exactly is supported. Resources can be loaded cross-domain, and the AMD API is also supported. Inject also has a lot of unit tests, written with QUnit.

Once Inject is loaded, it’ll find and load dependencies automatically:

<script type="text/javascript" src="/js/inject.js"></script>
<script type="text/javascript">
  require.setModuleRoot('http://example.com/js/modules');
  require.run('program');
</script>

Now if program.js looked liked this:

var hello = require('hello').hello;
alert(hello());

Then Inject will load the hello module.

Inject finds the dependencies automatically and loads them asynchronously. If a developer changes some downstream dependency - for example, changes hello.js to depend on new-name-module.js instead of name.js - your code will keep working because Inject will automatically find and download the new dependencies on the next page load.

MinionJS

MinionJS (License: MIT/X11, npm: minion) by Taka Kojima is a small library that provides classical inheritance for Node and browsers:

minion.require('example.Example', function(Example) {
  var instance = new Example();
      instance.doSomething();
});

Minion also includes a publish/subscribe implementation. All classes have subscribe and publish methods which can be used to bind callbacks to notifications.

Finally, Minion has a build script that can be used to package classes for client-side deployment.

Ender Roundup: Radio.js, one.color, Hypher

You can send in your Ender-related projects for review through our contact form or @dailyjs. Be sure to also update the Ender package list page on the Ender wiki.

Radio.js

Radio.js (GitHub: uxder/Radio, Licence: MIT, npm / Ender: radio) by Scott Murphy is a simple publish / subscribe library with a well-designed chainable API. Radio.js operates through the $.radio() method from within Ender.

//create topic called changeTabEvent and subscribe myFunction
$.radio('changeTabEvent').subscribe(myfunction);
//publish to the topic changeTabEvent
$.radio('changeTabEvent').broadcast(data);
//unsubscribe myFunction from the topic changeTabEvent
$.radio('changeTabEvent').unsubscribe(myFunction);
//do all of the above in one line via chaining
$.radio('changeTabEvent').subscribe(myFunction).broadcast(data).unsubscribe(myFunction);

Event “channels” are created by the main radio() method. You can then use the three main API calls to interact with the channels: subscribe(), broadcast() and unsubscribe(), each able to take different types and numbers of arguments.

Radio.js will also work as a stand-alone browser library and in node.js.

one.color

one.color (GitHub: One-com/one-color, Licence: BSD, npm / Ender: onecolor) by Peter Müller and One.com is an amazingly comprehensive color toolkit. It implicitly converts between RGB, HSV, HSL and CMYK color spaces with or without alpha transparency. Its API is chainable for composing, adjusting, and serializing color values. A demo page gives you some idea of the potential of one.color.

one.color

$.color('rgb(102, 76, 230)'). // Can parse CSS color strings
    lightness(+.2, true).     // Implicit conversion to HSL
    red(-.1).                 // Implicit conversion back to RGB
    hex();                    // "#00a6f2"

one.color will also work as a stand-alone browser library and in node.js.

Hypher

Hypher (GitHub: bramstein/hypher, Licence: BSD, npm / Ender: hypher) by Bram Stein is a small hyphenation engine compatible with Hyphenation.js language objects.

Hypher adds soft hyphens to text strings (Unicode: U+00AD, HTML: &#173; or &shy;) according to language rules as defined in the patterns objects. Modern browsers then use these soft hyphens to break words where wrapping is required, otherwise they are invisible.

Hypher comes with a large number of language patterns which are also available in the npm repository as hyphenation.lang (e.g. hyphenation.en-us or hyphenation.fr). Simply include hypher and at least one language pattern in your Ender build.

// generates 'Hy|phen|ation is use|ful when cen|ter jus|ti|fy|ing a text.'
// where `|` is a soft hyphen
$('<p>Hyphenation is useful when center justifying a text.</p>')
  .appendTo('body')
  .hyphenate('en-us');

Hypher is also available as a jQuery plugin and will work as a stand-alone browser library and in node.js.

Tidbits and updates

Some minor notable items since the last Roundup:

Bonzo goes 1.0.0

Bonzo, the DOM manipulation library included in The Jeesh, has received a lot of minor fixes this week and its test suite has been significantly expanded, so much that a bump to 1.0.0 seemed appropriate.

Minor Qwery update

Qwery, the selector engine included in The Jeesh had some minor performance improvements, particularly for IE8, and can now be configured to turn off use of native querySelectorAll if required: $.configure({ useNativeQSA: false }).

Bean does better delegation

Bean, the event manager included in The Jeesh, has received some delegation-love, fixing bugs related to clone() and erroneous event.currentTarget values.

Bean is also likely to see a change in the implementation of on() that will make it (mostly) compatible with the implementations in Prototype, jQuery and Zepto. Further details are available on GitHub.

Ender via CDN

After the flurry of recent activity on core Ender modules, Dustin Diaz has updated the The Jeesh and a more bulky Ender build on S3 this week, so is these builds suit your needs then point your script tag to one of these CloudFront URLs:

The Jeesh (Qwery, Bonzo, Bean, domReady)

http://cdn.enderjs.com/jeesh.js
http://cdn.enderjs.com/jeesh.min.js

Jeesh++ (Qwery, Bonzo, Bean, domReady, Reqwest, Morpheus, Valentine, Bowser, $script.js)

http://cdn.enderjs.com/ender.js
http://cdn.enderjs.com/ender.min.js

Twitter’s Bootstrap for Ender

Along with the release of Bootstrap v2, an Ender compatible version is now available on npm. Unlike the v1.x port, this new version makes each plugin available separately so you only need to include the ones you intend to use in your Ender build.

With all plugins installed, a minimal Ender build for full Bootstrap functionality comes in at a little under half the size of the equivalent jQuery Bootstrap.

Further details available on the new ender-bootstrap repository.

Getting Started with the Chai Assertion Library

23 Feb 2012 | By Jake Luer | Comments | Tags testing node tutorials

Jake Luer is a Node developer and consultant focused on helping to shape the next-generation of mobile and web applications. He is logicalparadox on GitHub and @jakeluer on Twitter.

Chai (GitHub: logicalparadox / chai, npm: chai, License: MIT) is a BDD / TDD assertion library for Node and the browser that can be delightfully paired with any JavaScript testing framework.

Chai aims to be an expressive and easily approachable way to write assertions for JavaScript project testing. Developers have already started expanding on Chai’s available language through plugins such as spies, mocks/stubs, and jQuery support. Starting out, however, I think you will find Chai’s language easy to pick up and powerful enough for even the most unruly of testing scenarios.

The motivation for Chai came about with the release of Mocha, TJ Holowaychuk’s incredible testing framework that can also be used with both Node and browsers. At the time, there was no apparent assertion library to pair with it that would allow for the same assertions to be used on both server and client with the inherent simplicity that Mocha provides.

The Basics

To get started in Node, add chai to your package.json under devDependacies. Or, if using in the browser, include the script in your page:

<script src="http://chaijs.com/chai.js" type="text/javascript"></script>

Chai currently supports all modern browsers: IE 9+, Chrome 7+, FireFox 4+, Safari 5+.

Assertion Styles

Chai comes packaged with three different assertion styles: expect, should, and assert. The expect and should interfaces are similar in that they are based on self descriptive language chains. The assert interface is similar to Node’s assert module but includes many more assertions.

For our examples we will assume the following:

var chai = require('chai')
  , foo = 'bar'
  , beverages = { tea: [ 'rooibos', 'matcha', 'oolong' ] };

First up is the BDD styles: expect and should:

var expect = chai.expect;
expect(foo).to.be.a('string').and.equal('bar');
expect(beverages).to.have.property('tea').with.length(3);

As you can see, the expect interface provides a function as a starting point for chaining your language assertions. Alternatively, the should interface extends Object.prototype with the single getter should as the starting point:

var should = chai.should();
foo.should.be.a('string').and.equal('bar');
beverages.should.have.property('tea').with.length(3);

Finally, the TDD style is exposed through the assert interface. This features the classic assert.test notation.

var assert = chai.assert;
assert.equal(foo, 'bar', 'Foo equal bar');
assert.length(beverages.tea, 3, 'We have three types of tea');

A few assertions that are also available are deep equality, exception testing, and instanceof. The full API documentation is available for all styles on Chaijs.com.

Extending Chai with Plugins

Though Chai provides all the basics of testing, we all know there can be much more to it. Chai can easily be extended through plugins that can add-on or modify Chai’s Assertion prototype. One example of this is logicalparadox/chai-spies, a basic function spying implementation.

Here is a simple example to assert that events have been emitted using chai-spies:

var chai = require('chai')
  , spies = require('chai-spies');

chai.use(spies);

var should = chai.should()
  , myspy = chai.spy(originalFn); // originalFn not required

eventemitter.on('some event', myspy);
// ... testing
myspy.should.have.been.called.twice;

The plugin approach makes it easy to use Chai for complex testing scenarios. Chai-spies is also a good resource for developers looking to build plugins that work for both Node and the browser.

These awesome developers have already started to build on Chai:

chai-jquery (License: MIT) by John Firebaugh provides deep jQuery integration with Chai’s `should` and `expect` styles.
$('#header').should.have.class('foo');
expect($('#title')).to.have.html('Chai Tea');
sinon-chai (License: WTFPL) by Domenic Denicola extends Chai with assertions for use with the Sinon.js mocking framework.
mySpy.should.have.been.calledWith('foo');
expect(mySpy).to.have.been.calledWith('foo');
jack (License: MIT) by Veselin Todorov is a mock/stub library that can be used as a stand-alone utility or with Chai.
mockedMethod.should.have.been.called.twice;
expect(mockedMethod).to.have.been.called.twice;

Node Roundup: Mongorito, Memcacher, Restify, Versionator, FeedSub

22 Feb 2012 | By Alex Young | Comments | Tags node modules mongo rss feeds express

Mongorito

Mongorito (License: MIT, npm: mongorito) by Vadim Demedes is a new MongoDB ODM with some interesting features: it has built-in caching using Memcacher (another module by the same author), and a small codebase by building on Mongolian. Automatic caching can even be set up, simply by setting a Memcached host using Mongorito.cache.

Mongorito has a model class, and the author gives examples in both JavaScript and CoffeeScript:

var Post = (function(){
  function Post() {
    Post.__super__.constructor.call(this, 'posts');
  }

  Post.prototype.validateTitle = function(callback) {
    if (!this.title) {
      callback(false);
    } else {
      callback(true);
    }
  }
})();

Post = Mongorito.bake(Post);

Post.find(function(err, posts){
  var length = posts.length;
  for (var i = 0; i < length; i++) {
    // posts[i] is an instance of the Post class
    posts[i].remove(function() {
    });
  }
});

The model definitions offer an alternative to Mongoose, and may appeal to those working on CoffeeScript-based projects:

class Post
  constructor: ->
    super 'posts'

Post = Mongorito.bake Post

post = new Post
post.title = 'About Mongorito'

post.save (err) ->
  # saved!

Despite being a new library, the author says the code is being used in production software, and he’s written some Mocha unit tests.

Memcacher

Memcacher (License: MIT, npm: memcacher) also by Vadim Demedes adds additional functionality to the Memcached module by Arnout Kazemier, in the form of tags and chainable methods:

Client
  .set('test-key', 'value', 2592000, ['some-tag'])
  .get('test-key', function(err, value) {
    // This callback intentionally left blank
  });

It’s a small but significant addition that should help those working with Memcached.

Restify

Restify (GitHub: mcavage / node-restify, License: MIT, npm: restify) by Mark Cavage is a new Express-inspired framework for building REST APIs. It includes both client and server support, so it’ll consume REST services as well as serve them.

Creating a basic server and setting up middleware looks just like Express:

var server = restify.createServer({
  name: 'myapp',
  version: '1.0.0'
});

server.listen(8080, function() {
  console.log('%s listening at %s', server.name, server.url);
});

It made me wonder if it’s Connect middleware compatible, because setting up routes looks the same as Express as well:

server.get('/echo/:name', function(req, res, next) {
  res.send(req.params);
  return next();
});

There are a healthy amount of unit tests (built with the tap module), detailed documentation, and a demo app.

Versionator

Versionator (GitHub: serby / versionator, License: New BSD, npm: versionator) by Paul Serby is Connect middleware for managing static asset caching. The basic middleware allows a global application version to be set, and adds an extra path to asset URLs so they’ll effectively be expired when the app version changes:

app.version = '0.1.0';
var basic = require('versionator').createBasic(app.version);

app.configure(function() {
  app.use(basic.middleware('v' + app.version))
    .use(express.static(__dirname + '/public', { maxAge: 2592000000 }));
});

Assuming a client-side script is at /js/app.js, it’ll now be available from /js/v0.1.0/app.js. There’s a Jade helper so the original URL can be referenced in templates.

There’s also ‘mapped’ middleware, which will only change resource locations when the files have changed.

FeedSub

FeedSub (License: MIT, npm: feedsub) by Roly Fentanes is an event-based feed downloader, that works the way a Node developer would expect:

var FeedSub = require('feedsub');

reader = new FeedSub('http://feeds.feedburner.com/dailyjs', {
  interval: 10 // check feed every 10 minutes
});

reader.on('item', function(item) {
  console.log('Got item!');
  console.dir(item);
});

reader.start();

It’ll also do a conditional GET based on the last modified headers:

// check headers for conditional get
if (res.headers['last-modified']) {
  self.getOpts['If-Modified-Since'] = res.headers['last-modified'];
}
if (res.headers.etag) {
  self.getOpts['If-None-Match'] = res.headers.etag;
}

jQuery Roundup: Auto-geocoder, Jade for jQuery, Swipe

21 Feb 2012 | By Alex Young | Comments | Tags jquery plugins ui mobile geo
Note: You can send your plugins and articles in for review through our contact form or @dailyjs.

jQuery Auto-geocoder

jQuery Auto-geocoder

jQuery Auto-geocoder (GitHub: tristandunn / jquery-auto-geocoder, License: MIT) by Tristan Dunn enables incremental search for Google Maps. A text input is displayed, and the results of a location search on Google’s geocoding API are displayed in the map view.

$(function() {
  $('#location').autoGeocoder();
});

The autoGeocoder method also accepts options – for example, delay can be used to control how often locations will be geocoded, and initial contains the options used to create the map.

One thing I wanted to do when testing this plugin was allowing the marker to be dragged. As far as I can tell, there’s no direct support for manipulating the resulting marker position. However, it’s possible to bind to the events used by the plugin, then the listener will be in the right context to access the marker:

$('#location').autoGeocoder({
  initial: {
    zoom: 1
  , center: [34, 0]
  , draggable: true
  , mapTypeId: google.maps.MapTypeId.ROADMAP
  , mapTypeControl: false
  }
}).bind('auto-geocoder.onGeocodeResult', function() {
  this.marker.draggable = true;
});

I had to write a similar interface widget once that allowed people to search for a location, then fine-tune the position.

Jade for jQuery

Jade for jQuery (License: MIT/GPL v2) by Jeremy Martin is a lightweight jQuery wrapper for Jade. Seeing as both of these technologies are all about CSS selectors, I’ve always felt like it makes sense to use them together. In my own work, Jade has formed the server-side templates. How does this look for a client-side template solution?

<script id='my-template' type='text/x-jade'>
h1 Hello #{name}!
</script>

<script type="text/javascript">
$('#my-template').jade({ name: 'World' }).appendTo('body');
</script>

It’s also possible to render string templates with $.jade(template, data).

Swipe

Swipe screenshot

Hirvesh sent in Swipe (GitHub: bradbirdsall / Swipe, License: MIT/GPL) by Brad Birdsall:

Swipe is a lightweight mobile slider with 1:1 touch movement, resistant bounds, scroll prevention, and completely library agnostic.

It works with a series of elements inside a container, and the author recommends using it with a feature detection library like Modernizr:

if (Modernizr.csstransforms) {
  window.mySwipe = new Swipe(
    document.getElementById('slider')
  );
}

One of the nice features in Swipe is scroll prevention – it’ll detect if a swipe was intended to scroll the screen down, or slide content horizontally.

New Control Flow Libraries

20 Feb 2012 | By Alex Young | Comments | Tags node libraries async

There are a lot of control flow libraries for Node. Most libraries seek to wrap more complex patterns like promises with a simpler API, and others place a unique emphasis on a particular aspect of control flow. Some are the result of extracting generic functionality from another project, and others purport to be the next great ‘async micro-framework’.

Here are some interesting new control flow libraries that I’ve been looking at recently.

Nue

Nue (License: MIT, npm: nue) by Toshihiro Nakamura supports serial execution, nesting, error handling, and sharing data between functions through this.data:

var flow = require('nue').flow
  , fs = require('fs')
  , myFlow;

myFlow = flow(
  function(file1, file2) {
    this.data.file1 = file1;
    this.data.file2 = file2;
    fs.readFile(file1, 'utf8', this.async());
    fs.readFile(file2, 'utf8', this.async());
  },
  function(data1, data2) {
    this.next(data1 + data2);
  },
  function(data) {
    if (this.err) throw this.err;
    console.log(data);
    console.log(this.data.file1 ' and ' + this.data.file2 ' are concatenated.');
    this.next();
  }
);

myFlow('file1', 'file2');

I liked the way the author’s examples made each ‘flow’ a reusable function, rather than simply demonstrating that arbitrary asynchronous functions can be executed in series. The API for Nue uses this quite a lot – for example, this.async is used to accept the parameters for the next function and return a suitable callback.

The author has also written Mocha tests.

 Batch

Batch (License: MIT, npm: batch) by TJ Holowaychuk makes it easier to collect groups of results from asynchronous operations:

var Batch = require('batch')
  , batch = new Batch;

ids.forEach(function(id) {
  batch.push(function(done) {
    User.get(id, done);
  });
});

batch.end(function(err, users) {
  // `users` now has all of the users that were loaded
});

Rather than using a promise, or enhancing forEach, TJ has opted to use an event-based API that should be familiar to Node developers.

Cascade

Cascade (License: MIT, npm: cascade) by Scott Rabin allows nested callbacks to be flattened by passing an array of functions and their arguments to the cascade function:

// Standard code
fs.rename('/tmp/hello', '/tmp/world', function(err) {
  if (err) throw err;
  fs.stat('/tmp/world', function(err, stats) {
    if (err) throw err;
    console.log('stats: ' + JSON.stringify(stats));
  });
});

// Cascade
cascade('/tmp/hello', '/tmp/world',
  cascade.chain(fs.rename),
  cascade.raise(null, 2),
  fs.stat,
  cascade.raise,
  function(stats) {
     console.log('stats: ' + JSON.stringify(stats));
  }
);

The API has lots of helpers for working with arguments, like filter, join, and map:

cascade(1, 2, 3, 4, 5, 6,
  cascade.map(function(i) {
     return (i % 2 === 0 ? 'even' : 'odd');
  }),
  callout
);

// "callout" receives these arguments:
// 'odd', 'even', 'odd', 'even', 'odd', 'even'

The author has written detailed tests using Vows.

 Pattern

Pattern (License: Apache v2.0, npm: p) by Nuno Job uses patterns to manage asynchronous iteration:

var insert_all = require('p')(), _;

// Simulate an asynchronous operation
function insert_element(data, callback) {
  setTimeout(function() { callback(data); },
    Math.ceil(Math.random() * 100));
}

insert_all([], _, function stop(l,cb) { cb(); });
insert_all(_, _, function catchall(l, cb) {
  insert_element(l.shift(), function elem_cb(elem) {
    console.log(elem + ' inserted');
    insert_all(l, cb);
  });
});

insert_all([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 
  function done() { console.error('done'); });

This is by the same developer who made Clarinet, an evented SAX parser. There’s a blog post about the library here: Pattern Matching in JavaScript for Asynchronous Iteration.

Invoke

Invoke (License: MIT, npm: invoke) by Steve Lloyd combines chainable methods with an API that looks inspired by promises:

invoke(function(data, callback) {
  // Async operation
}).and(function(data, callback) {
  // Parallel operation
}).then(function(data, callback) {
  // Runs after the first two
}).rescue(function(err) {
  // Error handler
}).end(initialData, function(data) {
  // Done
});

Notice how .then implies serial execution, while .and is used for parallel invocations.

This library has some nodeunit tests, and a full example (in examples / simple.js).

More

As I was researching this post I built up metadata from GitHub and npm to figure out what the newest modules were. For modules that I didn’t cover, have a look at New Control Flow Libraries.

tQuery, Catchall, Geometry.js

17 Feb 2012 | By Alex Young | Comments | Tags webgl errors games mathematics

tQuery Valentine’s Day Card

Jerome Etienne, WebGL experimenter and author of the Learning Three.js blog, recently published a WebGL Valentine’s Day card tutorial which demonstrates his new library, tQuery (License: MIT). While development on tQuery is still ongoing, it provides a friendly alternative API for WebGL based around chainable calls:

tQuery.createText('tQuery is fun!').addTo(world);

tQuery.createShape()
  .moveTo(0, 0)
  .lineTo(1, 1)
  .lineTo(-1, 1)
  .lineTo(0, 0);

As a JavaScript developer, this API appeals to me and results in some surprisingly concise code. The tutorial also includes a screencast which covers the methods used by the Valentine’s Day card example in detail.

Catchall

Catchall (License: MIT) by Craig Condon is an alternative to window.onerror created to aid development by catching all exceptions. To do this, all functions are wrapped, which is why the author recommends using it during development and testing only.

Connect middleware is also included, which allows arbitrary scripts to be wrapped by the catchall module. The project’s API allows strings of code to be wrapped by using catchall.wrap, and catchall.load can be called on a source file URL or file system path:

catchall.load('http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js', function(err, result) {
    //do something
});

catchall.load('/from/fs', function(err, result) {
    //do something
});

Geometry.js

Geometry.js (License: AOL) by Nijiko Yonskai is a collection of geometry classes used by the author for game development. The following classes are included: Circle, Direction, Rectangle, Vec2d. The vector class in particular seems like something I’ve found myself writing and rewriting for various WebGL and game-related experiments.

The library includes a rich set of methods, and even aliases mathematical operators:

var v1 = new Vec2d(10, 20)
  , v2 = new Vec2d(33, 10);

v1['+'](v2).x;
// 43
v1.add(v2).x;
// 43
v2.toArray();
// [33, 10]
Vec2d.Zero().toArray();
// [0, 0]

Unix and Node: Manual Pages

16 Feb 2012 | By Alex Young | Comments | Tags node tutorials essay unix documentation

If you’re familiar with npm’s documentation you’ll have noticed that it comes with a lot of manual pages. I don’t think I could have published an npm module without reading man npm-json several times first. To this day I still bring it up to search for the correct properties for the more obscure features.

Let’s look at npm to see how Isaac did this, then generalise it a little bit so you can publish your own manual pages.

Background

npm man page

The now ubiquitous npm makes use of man pages for its documentation. This isn’t the only way to view these files, but it’s my preferred way to read them. The way npm generates documentation is clever – Isaac has chosen to write files in Markdown, which has a positive side-effect of allowing GitHub to render them. These files are then converted to a markup language that man will understand.

This markup language is derived from early typesetting tools, known as the roff system. If you’re interested in writing manual pages by hand, take a look at man groff. To learn about the history of these tools, man roff is an interesting read.

Converting a Markdown document to something roff-like was solved rather well by ronn by Ryan Tomayko. Ronn is a Ruby program, so Isaac has used his own fork of ronnjs to generate his manual pages for npm.

To make this work, npm’s makefile will run scripts/doc-build.sh:

man/man1/%.1: doc/cli/%.md scripts/doc-build.sh package.json
  @[ -d man/man1 ] || mkdir -p man/man1
  scripts/doc-build.sh $< $@

The doc-build.sh script uses bash, sed, and perl to replace values in the Markdown files:

./node_modules/.bin/ronn --roff $src \
| sed "s|@VERSION@|$version|g" \
| perl -pi -e 's/npm\\-([^\(]*)\(1\)/npm help \1/g' \
| perl -pi -e 's/npm\\-([^\(]*)\(3\)/npm apihelp \1/g' \
| perl -pi -e 's/npm\(1\)/npm help npm/g' \
| perl -pi -e 's/npm\(3\)/npm apihelp npm/g' \
> $dest

Another option for manual page generation is the mantastic web service, mentioned by TJ Holowaychuk in the comments on HelsinkiJS February, Todo, Testing Backbone.js.

Therefore, a general pattern for generating manual pages in Node apps is as follows:

  • Create files for documentation using your preferred markup language
  • Use a suitable tool to generate something similar to the groff language
  • The resulting manual pages can be distributed when publishing to npm, (Node includes node.1 in its source)

An alternative would just be to write the manual pages using the groff language to begin with. It’s surprisingly easy to pick up, although it’s not as friendly as Markdown and doesn’t have the advantage of being easily read without formatting.

Installing Manual Pages

When a module is installed with npm, it’ll actually copy man pages to {prefix}/share/man if they’re available. To do this, tell npm where the man pages are in the directories property:

"directories": {
  "man": "./doc/man"
}

If this module is installed as a global module, then npm will copy the manual pages from ./doc/man to {prefix}/share/man.

Conclusion

When writing a general purpose tool with Node, consider writing a manual page using groff, or converting your Markdown documentation. The command-line jockeys amongst us will appreciate it, and it’ll bring your application a little bit closer to feeling like a true part of a Unix system.