Inspired by a brilliant talk by David Heinemeier Hansson (creator of Ruby on Rails), I started thinking about code clarity in Javascript, in what can be done to make the language more expressive and powerful, but also more concise. Blueprint is an attempt to focus on one aspect of code clarity: minimalistic single-purpose functions. This is achieved by borrowing Python's function decorators in order to separate side-effects and setup logic from the core intention of the function itself.

Simply put, Blueprint is an API for constructing classes. Once the class is fully defined, call .create() to receive it's final constructor. You can also use it to extend external classes, like Backbone Models:

var User = blueprint( Backbone.Model )

.define("defaults",{ name:"", age:null})

.thenable()// makes save return a new Promise

.define("save",function(attrs, options, fulfill, reject){

options ||( options ={});

options.success=function(model){

fulfill( model );

};

options.error=function(model, err){

reject( err );

}

Backbone.Model.prototype.save.call(this, attrs, options )

})

.create();

Blueprint encourages the use of Promises, instead of the traditional nesting callbacks. In the example above, we converted the save method to return a thenable object which can be accessed like this:

newUser({ name:"John", age:29})

.save()

.then(function(model){

// user is saved successfully

})

.catch(function(err){

// something went wrong

});

Of course we can chain several thenable methods one after the other, using the then() directive, in order to flatten complex functions:

Decorates the next method to return a Promise (the real return value is ignored) and also automatically appends callbacks for fulfilling and rejecting the promise. This is the Blueprint approach to building async code.

You can easily define your own custom decorators, using the .decorate() directive. Decorators, are simply functions that receive some previous defition of a property or method, and returns a new one:

varlog_decorator=function(name, fn){

returnfunction(){

console.log( name, arguments );

return fn.apply(this, arguments );

}

};

var Class = blueprint()

.decorate( log_decorator )

.define("hello",function(){})

.create();

newClass().hello(1,2);// will log: "hello", [ 1, 2 ]

That's it. You can use decorators to augument the class in any possible way, especially for separating side-effects and different aspects of the code out of the core function/property. You can also define a named decorator for easy re-usability (beware of conflicts):