Thursday, July 18, 2013

eddy.js - A Bold Approach

Not the first time some project of mine ends up in JavaScript Weekly, however this time something different happened since eddy.js reached my top 5 projects list in my personal Github repo in about a week since my first tweet and I've never even blogged about that and: This. Is. Awesome!

eddy.js In A Nutshell

JavaScript is the easiest event driven programming language I know and every library out there knows this too!
jQuery, node.js, these are just the most successful JavaScript API out there and mostly based on event driven development, either with asynchronous API and libraries behind or based on DOM behavior as jQuery is for sure.
eddy.js aim is to bring the ease of an event driven application everywhere, hopefully matching everybody taste in both DOM and server side world too!

Fairy Tales ... Less!

Let's face reality: except for switching the light on or off where .switch() is most likely the most semantic and probably a better method name you could think about for such operation, we are used to think that on is a prefix for any sort of event (onload, onresize, onmouseover, onsomethinghappened) and still .on() is the method to define an event handler in most successful libraries since JavaScript time.
Moreover, switching the light on or or off is really a 1% of time edge case action in web/JS programming since the usual habit is disabled or enabled or, electricity speaking, connected.
OK, OK ... if you are programming some developer board based on relays to switch on or off things, these words could have a bigger meaning for you but seriously, in JS, and since about ever, these have been the way to understand events, and event driven behaviors!

eddy.js To The Rescue

In about 1KB minzipped, eddy.js transforms any object and only if needed into an EventTarget or, in a node.js world, EventEmitter, being absolutely as CPU and memory safe as possible, providing though enormous advantages for any kind of object!
var generic = {};
// OK, at this point I'd love to know if
// this object will ever fire a notification
// no matters what it does
// I just would like to register ... but how?
// wait a second, Hell Yeah, eddy.js!!!
generic.on('hell-yeah', notifyMe);
It's really that simple: the moment we need an event drive behavior, we are sure that any object that inherits from Object.prototype will expose those methods we all love and those will work as we expect! Isn't this much simplified than following code?
// the current node.js way
function PretendingThisIsFine() {}
PretendingThisIsFine.prototype = Object.create(
  require('events').EventEmitter.prototype,
  {
    constructor: {
      value: PretendingThisIsFine
    }
  }
);

// later on
var generic = {};
var boring = new PretendingThisIsFine();

// promoting generic now ... but wait ...
// what if it was already defined?
// this will fail like hell since all
// behaviors related to the object are lost!
generic.__proto__ = PretendingThisIsFine.prototype;
// now generic is not the object we know anymore
// this is not a solution!
So here the good news, trusting a simple 1KB library that could be served in any CDN, above scenario could simply be like this:
// the specific EventEmitter class?
// function YAGNI() {}

// later on
var generic = {};

// whenever we need it ...
generic.on(event, behavior);

Slightly Obtrusive But Totally Pragmatic !

Back in those days where libraries defined new needs for JavaScript as Prototype library and its Function#bind did, we are also in a different time where Object.prototype properties can be extended as not enumerable so that every for/in loop will be safe, how great is that?

... And What About IE8 ?

Yes, as much as I am reluctant to this topic, it's supported!
However, right now only for the JScript part, hopefully pretty soon the whole package with DOM too!
Anyway, if you are here worrying about IE8 and Object.prototype pollution and for/in problems, I've got some good news for you:
  • you are still supporting IE8, you are using obj.hasOwnProperty(key) in every loop so you are safe
  • we are in 2013, IE8 survived from 2009 until now but if today some library will start to pollute in a non enumerable way the Object.prototype that's just OK since your IE8 code should be aware of for/in problem, isn't it?
  • if you think it's too late to spend time refactoring for IE8 ... well, you nede to do that pretty soon regardless so this might be your very best occasion to adopt a simplified approach to event driven development: go for it!

Still Some IE8 DOM Gotcha

I am trying to create a way to obtain, and in way less lines of jQuery code, a unified behavior for IE < 9 so that synthetic events can propagate basically same way DOM events would do there but for any other IE8 based library, eddy.js should be just fine!

Already Compatible

If you add eddy.js after libraries that relies in a weak .on() feature detection, eddy.js will be sitting there for all other objects that did not match library criteria so that eddy.js is tested as compatible against jQuery and all other libraries.
Give it a try, please, and let me know what didn't make you happy, if anything except some old school morality about extending the Object.prototype ... I mean, there are no other ways to obtain same usefulness if not enriching the prototype root, isn't it?
Or maybe you want to go down with this chaotic pattern?

No comments: