The Future of Mobile Sync

03 Sep 2010 | By Alex Kessinger | Comments | Tags mobile data storage

This article is by Alex Kessinger. He works for Yahoo! as an FE, and is currently working on a book about HTML5 Apps for Packt. You can also follow him on Twitter: @voidfiles.

The mobile web apps community has been systematically knocking down the barriers to building apps on web technologies. We have offline data storage, offline application cache, coming soon we will have access to devices, and files, but there is something missing: data sync.

As a web developer, I have always felt that mobile web apps are just like small web pages. If you think about web apps like that, you can see how many of our traditional FE methods can be used to build mobile apps. Data sync is a relatively new requirement for web developers. Yes, we have had server communication for a long time, in which we could transfer data, but web pages going offline for long periods of time is new.

It also doesn’t seem like we are going to get any guidance from the standards bodies. In the Dive Into HTML5, Mark Pilgrim states:

“If your application creates data or saves state, it’s up to you to store that data locally while you’re offline and synchronize it with the remote server once you’re back online. In other words, HTML5 can take your web application offline. What you do once you’re there is up to you.” (source)

While Pilgrim is not the W3C, he does have input, and was apart of the process. What it means is that it’s up to us the community to figure this out. I am writing this for a couple of reasons. First, let’s get all the prior work into the open. It’s possible somebody somewhere has figured this out, or there might be a solution that has been overlooked. Two, there are existing standards that might be used, we should take a look. Finally, there are a couple of different sync scenarios, and they might have different solutions we should take a look at a couple.

Libraries, and the greater Internet, might have the information we need, but I figured that if I couldn’t even find anything on the surface that looked close to a solution then I should ask the community first, it might save time. I was able to find a couple possible starting points. These are specific to sync.

These seem to have a largish amount of people behind each project. SyncML seems to be the most open, which I know is hard word to define, but they are all lacking something. I know it’s an incredibly un-technical way of assessing an idea, but I don’t see hackers using any of the above I am open to be proven wrong though. I also found a 2 year old link to a thing called AtomDB, which was going to be based on the AtomPub spec, but it’s 2 years old.

Are any of the above possible players in mobile web apps? I don’t know, I am partial to saying I don’t think so. If there isn’t anything out there we should probably try and define some of the problems that will need to be solved. I have two scenarios in mind.

The first scenario is like a text based sync. In this scenario the user has lots of textual data, like a bunch of notes, something similar to Simplenote. The user goes offline for a while. While offline they make changes to a note, and let’s say they have a shared note with a friend. This friend modifies the same note while the user is offline. Now, we have two notes with changes that aren’t in sync. The user comes back online, and then what happens? That is scenario one. I think this one could be handled by some kind of versioning scheme like git, and svn merge code.

The second one is a buisnessy one. Let’s say a traveling sales man is out selling some widgets. He has a mobile order entry device. He has an internal copy of the inventory data that stays closely in sync with the central copy until he goes offline. When he enters his order he is offline. While he is offline a co-worker in the central office takes a phone order. They both need to see the rest of the inventory. When the traveling salesmen comes back online there is now a conflict, but it can’t easily be merged — there has to be a resolution of some kind.

Mayby both of these problems are incredibly unique to their respective circumstances. Even if they are unique, there has to be repeatable patterns that can be used. There must be a way to provide a framework to handle sync, and either it exists out there, or someone needs to build it.

I would like to note that Couchio seems to be trying to fix this problem with CouchDB. They might have more to say, but they have an interesting model for how web apps could use CouchDB. For example, on the Android platform CouchDB can run as a service in the background. Your web app would be able to talk to the local CouchDB server all the time. When you device is online CouchDB will handle the data sync to an upstream database.

That would be awesome, but it’s not a standard, and it’s not everywhere. Even if they figure out how to get it on to many different devices in the future it still might take awhile, and I think we need something sooner then that.

This is a call to action, do we have a problem, is their a solution already, do we need to build something?

Let's Make a Framework: Chaining

02 Sep 2010 | By Alex Young | Comments | Tags frameworks tutorials lmaf

Welcome to part 28 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.

If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing.

Last week I was talking about chaining DOM finders, jQuery style. I demonstrated a little script that duplicated a fake version of this functionality. This week I’ll start building it for real.

Please read last week’s tutorial if any of this sounds confusing, everything here draws on that.

Recap

What we want to be able to do is chain finder methods:

turing('.example').find('p')

This would find things with the class example, then the associated paragraphs. We can use turing.dom.get to implement the core functionality, but get() does not accept a “root” element, so we’ll need to add that.

Another thing is, calling turing() makes no sense, because it isn’t a function. Let’s address that while we’re at it.

The alias module will also have to be changed, because it currently wraps turing.dom.get anyway.

Tests

The implementation should satisfy the following test in test/dom_test.js:

given('chained DOM calls', function() {
  should('find a nested tag', turing('.example3').find('p').length).equals(1);
});

I should cover more methods and cases, but I’m on a tight schedule here!

Updating Core

This is simpler that you might expect. The core module currently exposes turing as an object with a bunch of metadata properties. This can be changed to a function to get the jQuery-style API. The only issue is I don’t want to make turing.dom a core requirement.

To get around that I’m going to allow an init method to be overridden from outside core. This could be handled in a better way to allow other libraries to extend the core functionality, but let’s do it like this for now:

function turing() {
  return turing.init.apply(turing, arguments);
}

turing.VERSION = '0.0.28';
turing.lesson = 'Part 28: Chaining';
turing.alias = '$t';

// This can be overriden by libraries that extend turing(...)
turing.init = function() { };

Then in the DOM library:

turing.init = function(selector) {
  return new turing.domChain.init(selector);    
};

This last snippet is based on the fakeQuery example from last week.

Updating turing.dom

This is all completely taken from the fakeQuery example. The real find method in turing.domChain (which came from fakeQuery.fn) looks like this:

find: function(selector) {
  var elements = [],
      ret = turing(),
      root = document;

  if (this.prevObject) {
    if (this.prevObject.elements.length > 0) {
      root = this.prevObject.elements[0];
    } else {
      root = null;
    }
  }

  elements = dom.get(selector, root);
  this.elements = elements;
  ret.elements = elements;
  ret.selector = selector;
  ret.length = elements.length;
  ret.prevObject = this;
  ret.writeElements();
  return ret;
}

It depends on dom.get for the real work, which I covered way back in part 6 (and onwards).

The writeElements method sets each element to a numerical property, so the Array-like API is available:

$t('.example3').find('p')[0]

I also added a shorthand first() method to the same class while I was at it.

DOM Root

Setting a “root” element for dom.get looks like this:

dom.get = function(selector) {
  var tokens = dom.tokenize(selector).tokens,
      root = typeof arguments[1] === 'undefined' ? document : arguments[1],
      searcher = new Searcher(root, tokens);
  return searcher.parse();
};

An undefined property will become document, which means it can accept null. I had to make the existing find methods check for null as a special case.

Conclusion

These two chainer tutorials illustrate:

  • How to create an API for jQuery-like DOM traversal
  • How to create a prototype of a feature using abstracted data
  • How to write a test then satisfy it with code

Adapting the fakeQuery prototype was actually surprisingly easy. And now the chainer returns domChain, we can decorate it with lots of helper methods like first() to make DOM traversal very easy.

This is far from a complete solution, but the foundations are now there.

Node Roundup 4

01 Sep 2010 | By Alex Young | Comments | Tags node server programming

Welcome to the Node Roundup. Send your apps in for review through our contact form or @dailyjs.

Bounce

Bounce by Jonah Fox is a wrapper around a Node process that will watch for JavaScript file changes and restart the Node process. You can run it like this:

bounce lib/server.js

The author has also included tests (!). At the moment it recursively watches the file system, rather than using kernel-based notifications, but it’s still great for those of us that are used to automatic reloading on other development platforms/frameworks.

node-supervisor

node-supervisor is a similar project by Isaac Z. Schlueter; it can also relaunch programs when they crash. Supervisor also uses a recursive file system approach to watch for file changes.

Nodules

On a related topic… Nodules is a URL-based CommonJS module loader for Node. That means it has automatic dependency resolution, so modules will be downloaded as required. It’s part of Persevere, which is a Dojo Foundation project.

Node Knockout

Node Knockout voting is still open:

All voting will take place at the same time: between 03:00 GMT on Monday, August 30 and 0:00 GMT on Friday, September 3.

I’ve had a lot of fun playing with the entries, check them out if you haven’t already!

jQuery Roundup

31 Aug 2010 | By Alex Young | Comments | Tags jquery plugins

Welcome to the jQuery Plugin Roundup 21. You can send your plugins in for review through our contact form or @dailyjs.

jquery-flickr-plugin

I go through phases when I have a lot of fun with photography and get really creative, so I was looking for a way to package up photo sets and display them on my own site. jquery-flickr-plugin by Mickael Blatiere (MIT License) is a great way to display Flickr photos — check out the third demo.

Setting it up is pretty easy:

$(function() {
  $('#my_gallery').flickr({
    user_id: '##USER_ID##',
    api_key: '##API_KEY##',
  });
});

Another popular related plugin is Galleria (the fullscreen demos are interesting).

jquery-bitly-plugin

jquery-bitly-plugin by Victor Gumayunov lets you access Bitly through jQuery. This looks similar to the bitly JavaScript client but has a more jQuery-style API:

var b = new jQuery.Bitly({ login: 'LOGIN', key: 'KEY' });
b.shorten('http://google.com', function(short_url) { console.debug(short_url)});

JOSHUA

JOSHUA (or jQuery Operating System, HUA!) is an amusing artefact I found while searching GitHub. It’s a web-based command line interface by Alexander Støver. It’s not a jQuery plugin, and it’s not fundamentally useful, but it’s fun to play with!

Making Joshua has been (and still is) a fun challenge for me. Although in all honesty it’s pretty much the most awkward way to navigate a website ever perceived. But then again; Mouseclicking is so 90’s.

Try it out here: JOSHUA

Traits

30 Aug 2010 | By Alex Young | Comments | Tags libraries organisation

Traits.js (Apache License 2.0) is a library for creating modular components using traits. Traits can be used to recombine reusable code in a similar way to mixins without introducing traditional classes. Within the library, traits are like JavaScript functions, in that they’re first-class and anonymous.

Trait.compose can be used to combine a set of traits, which can then be instantiated with Trait.create. From the documentation:

Create is similar to the Ecmascript 5 built-in Object.create except that it generates high-integrity, “final” objects.

It also ensures the resulting object is frozen, and this is bound to the instantiated object in all accessors and methods.

As you can see by what create does, this process generates objects that are more strictly controlled than mixin or multiple inheritance-based code.

The tutorial has a good example called An Enumerable Trait which helped me get the hang of the basic usage of the library.

PaintbrushJS, Canvas Wrapper, Rangy

27 Aug 2010 | By Alex Young | Comments | Tags graphics canvas

PaintbrushJS

PaintbrushJS by Dave Shea, released under the MIT License, is a browser-based image processing library. It creates a canvas that contains the image and applies various image filtering algorithms. There’s a page of demos that illustrate the effects.

The effects work by getting pixels with getImageData then looping through them and applying the selected filter.

CanvasContext2DWrapper

CanvasContext2DWrapper by Miller Medeiros, released under the prestigious WTFPL license, wraps canvas context 2D properties to allow method chaining:

contextWrapper.fillStyle('#F00').fillRect(25,25,100,100).fillStyle('#0F0').fillRect(50,50,100,100);

Rangy

I hate dealing with range selection. I can’t remember if it’s due to IE, or if every browser does it differently, but I have a piece of JavaScript I’ve been using to do this for years and I barely remember how it works. Rangy by Tim Down (MIT License) is a library that addresses this lapse in my pragmatism. It’s currently pre-alpha, but already has some useful functionality:

var range = rangy.createRange();

// All DOM Range methods and properties supported
range.selectNodeContents(document.body);

// All HTML5 Selection methods and properties supported
var sel = rangy.getSelection();
sel.removeAllRanges();
sel.addRange(range);

Let's Make a Framework: Chaining

26 Aug 2010 | By Alex Young | Comments | Tags frameworks tutorials lmaf

Welcome to part 27 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.

If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing.

Namespaces and Chaining

Throughout this series I’ve referenced techniques used by widely-used frameworks like jQuery and Prototype. Prototype packs a lot of functionality and extends global JavaScript objects to do this.

jQuery takes a different approach. It uses large module-like chunks of functionality wrapped in closures, then specific parts are exposed through the jQuery object (we usually write $() instead).

Turing has been designed in a similar way to jQuery — to carefully keep implementation details private and make functionality available without polluting global objects.

One drawback of our current implementation is everything takes a lot of typing. Disregarding the alias we created, code looks like this:

var element = turing.dom.get('#events-test a')[0];
turing.events.add(element, 'click', callback);

// Or...
turing.events.add(turing.dom.get('#events-test a')[0], 'click', callback);

We’d do this in jQuery:

$('#events-test').click(function() {
  // Handler
});

In this case, click is a shortcut, so the following is equivalent:

$('#events-test').bind('click', (function() {
  // Handler
});

This chaining can go on as long as you want. jQuery even provides tools for popping up to different points in a chained result stack, like end():

$('ul.first').find('.selected')
  .css('background-color', 'red')
.end().find('.hover')
  .css('background-color', 'green')
.end();

This works particularly well when working with DOM traversal.

What this style of API gives us is the safety of namespaced code with the power and succinctness of prototype hacking, without actually modifying objects that don’t belong to us.

API

The way this works in jQuery is jQuery() accepts a selector and returns an array-like jQuery object. The returned object has a length property, and each element can be accessed with square brackets. It’s not a true JavaScript Array, just something similar enough.

Each call in the chain is operating on a jQuery object, which means all of the appropriate methods are available.

Previously…

We’ve already seen a combination of aliasing and currying to create a chainable API in Turing — check out turing.enumerable.js and turing.anim.js. In these cases, API calls were chained based on the first parameter — the first parameter for functions in these classes was always a certain type, so we could shortcut this and create a chain.

This is really a case of currying, and is one of those fine examples of a nice bit of functional programming in JavaScript.

fakeQuery

jQuery’s chaining is based around the DOM, so the previous examples don’t really help. Rather than jumping straight into Turing code, I’ve created a little class you can play with called fakeQuery. This will illustrate what underpins jQuery.

It uses a mock up of the DOM so it has something to query:

var dom = [
  { tag: 'p', innerHTML: 'Test 1', color: 'green' },
  { tag: 'p', innerHTML: 'Test 2', color: 'black' },
  { tag: 'p', innerHTML: 'Test 3', color: 'red' },
  { tag: 'div', innerHTML: 'Name: Bob' }
];

It’s not a particularly accurate representation of the DOM, but it’s readable.

This is the core function:

function fakeQuery(selector) {
  return new fakeQuery.fn.init(selector);
}

It returns a new object based on an init method. The init method builds an object which can carry around the current selector and related elements:

fakeQuery.fn = fakeQuery.prototype = {
  init: function(selector) {
    this.selector = selector;
    this.length = 0;
    this.prevObject = null;

    if (!selector) {
      return this;
    } else {
      return this.find(selector);
    }
  },

  find: function(selector) {
    // Finds elements
    // Returns a new fakeQuery
  },

  color: function(value) {
    // Creates a copy of the current elements
    // Changes them
    // Returns a fakeQuery object with these elements
  }
};

fakeQuery.fn.init.prototype = fakeQuery.fn;

The prevObject property could be used to implement end() (mentioned above). The full code is in a gist: fakeQuery. This code uses Node, but you could delete the Node-related parts if you want to run it with Rhino.

Running this code with something like fakeQuery('p').color('red').elements will produce:

[ { tag: 'p', innerHTML: 'Test 1', color: 'red' }
, { tag: 'p', innerHTML: 'Test 2', color: 'red' }
, { tag: 'p', innerHTML: 'Test 3', color: 'red' }
]

Overall Pattern

The overall architecture of jQuery is deceptively simple:

  • A “container function” is used to create new objects without having to type new
  • It returns objects based on a CSS selector
  • A class is created and copied so usage of methods like find can be called in a chain

The key to the last part is fakeQuery.fn.init.prototype = fakeQuery.fn;. This line is what allows the init method reference fakeQuery.prototype. You can try running the code without this if you want to see what happens.

Conclusion

jQuery’s design offers an efficient way of traversing and modifying the DOM. This is attractive to us because we’re building a framework without modifying global objects in the way Prototype does.

Next week I’ll look at building this into Turing. The interesting challenge here is that as it stands there are no dependencies between Turing’s components.

Node Roundup 4

25 Aug 2010 | By Alex Young | Comments | Tags node server

Welcome to the Node Roundup. Send your apps and libraries in for review through our contact form or @dailyjs.

Webshell

Webshell from Fictive Kin (by Evan Haas and Sean Coates) is a JavaScript HTTP client, released under Apache License 2.0 that uses Node.

You can issue commands like this:

It supports HTTP auth, cookies, and JSON. There’s lots of examples of usage in the README. It seems like something I might end up using when I’m debugging JSON-heavy Node projects. And by “debugging” I mean “should be writing tests but would prefer to do things the hackish way.”

nDistro

nDistro by TJ Holowaychuk is a way of quickly installing Node with a bunch of dependencies, based on simple configuration files. Configuration looks like this:

node 0.1.102
module senchalabs connect
module visionmedia express 1.0.0beta2
module visionmedia connect-form
module visionmedia connect-redis
module visionmedia jade
module visionmedia ejs

This is useful for a few things: testing your libraries against different versions of Node, or recreating a particular environment for a production server. It’s a shell script that downloads binary distributions of Node, which means you should technically only need a shell to get Node up and running.

Full installation and usage instructions are available in the README.

The author also posted a screencast of nDistro in use.

Node on Windows

If you usually work on a Windows desktop machine, you might have found building Node a bit of a chore. Try following Step by step instructions to install NodeJS on Windows — it relies on Cygwin but at least you can get Node running without dual-booting or starting a VM.

Japanese Node Group

I noticed there’s a Japanese Node Google Group started by Toshihiro Shimizu. He’s also been translating the Node site into Japanese at nodejs.jp.

Group Discussions

V8 Object Limits, started by Timothy Caswell, is an interesting discussion on the nodejs Google Group about performance and plain JavaScript objects. He was looking into the speed at which V8 can insert properties, then analysing the performance characteristics as the object grows.

You’ll notice that it starts out nice and fast at 2,673,179 inserts per second, but by the time it reaches about 13,273,357 properties, it’s down to taking almost 2 seconds to insert a single property. Also I’m seeing some blips in my graph that I assume are the stop-the-world garbage collector.

A related discussion is Node / v8 1gb memory limit?

TJ Holowaychuk mentioned that perhaps frameworks should adopt NODE_ENV as a convention for determining the application’s environment (production, development, testing, etc.) I think this would be useful, especially now that everyone on GitHub has started their own Node web framework.

jQuery Roundup

24 Aug 2010 | By Alex Young | Comments | Tags jquery plugins

Welcome to the jQuery Plugin Roundup, episode 20. You can send your plugins in for review through our contact form or @dailyjs.

Touch Gallery

Touch Gallery’s site says this is not another lightbox. Hooray! Touch Gallery is a fullscreen photo gallery aimed at touchscreen devices. It works best in Safari, but will also work in other browsers.

To use it, create a container that contains a bunch of links and call:

  $('#container a').touchGallery();

It’s released under the MIT license.

Felix Gnass sent me this plugin, and there are more by the same people at neteye.github.com

jQuery Globalization Plugin

I missed this plugin when it was announced, but I’ve been doing localisation work lately so I discovered it. jquery-glob features complex number and date parsing for many “cultures”:

Each language, and the countries that speak that language, have different expectations when it comes to how numbers (including currency and percentages) and dates should appear.

This plugin allows people to write data in their native format and it’ll get converted into data-types JavaScript likes.

Interestingly, this is a plugin from Microsoft: jQuery Globalization Plugin from Microsoft. That meant the first thing I thought was, “So what’s the license? Something crazy I’d need a law degree to understand?” It turns out there is no license. Or tests. Like most jQuery plugins!

Simulating JavaScript Events

In Programatically simulating JavaScript events in your test environment, Jamie Dyer discusses using Jasmine and jsMocha for testing with a jQuery project. Technically this isn’t a plugin, but when I review plugins for this site I often find problems with them, look for the tests, discover there aren’t any, get angry, then wish people would write tests for their plugins.

To that end, add this article to your “to read list” if you’re a plugin author who doesn’t write tests.

Polymaps

23 Aug 2010 | By Alex Young | Comments | Tags maps geojson svg

I noticed Polymaps has been updated recently, which is one of the graphics-related libraries I usually keep tabs on for my Friday graphics and gaming-themed posts. Polymaps by SimpleGeo Inc. and Stamen is an open source (License) library for dealing with scalable SVG maps. It only works with SVG, but is fast and can deal with some cool technology like GeoJSON.

The project is professionally presented, with clear documentation and excellent examples. There’s a cool Mandelbrot zoomer example — it even puts the Mandelbrot co-ordinates in the URL!

In the “Why SVG?” part of the documentation, the authors state:

Existing libraries are hamstrung by the need to support antiquated browsers, in particular IE6.

They actually answer why they’re not using a Canvas and VML approach like other projects:

SVG allows styling to be applied via CSS, which simplifies development and allows the use of CSS3 transitions and animation. In contrast to HTML5 Canvas, SVG facilitates interaction through event handlers, :hover psuedo-classes, and tooltips.

I know you’re probably thinking “but I’d just use Google Maps!” There are many instances where you can’t rely on Google Maps, like legal issues with Google’s terms, or specific design requirements that it can’t support.

Brequire, Node Pipe, Enable JavaScript

20 Aug 2010 | By Alex Young | Comments | Tags node commonjs browser

Brequire

Brequire makes CommonJS features available to browsers. It uses a compiler to inject the functionality into your scripts. It’s actually a script that you run before loading your code in a browser:

bin/brequire test/src test/lib

Node Yahoo! Pipe

Alex Kessinger sent me a blog post about a Yahoo! Pipe that gets the latest updated packages from the npm registry.

At the moment npm traffic isn’t too insane, so you could follow this to keep abreast of what’s being released. Of course, not everything is released through npm, but it’s getting very popular.

Enable JavaScript

This is a simple idea, but genuinely useful. Enable JavaScript by Toni Podmanick explains how to enable JavaScript in each major browser. It’s the kind of thing that will come in handy when trying to explain such a thing to an awkward client.

Write for Us

Despite popular opinion I don’t spend all day tinkering with JavaScript and writing for DailyJS; I have a day job! I’m looking for writers to help with the site. I’d like people who can write short news posts like this one, and also people who can write awesome tutorials. You’ll get full credits and mad links to your sites and projects.

I haven’t got a formal advertising system for DailyJS yet so the site doesn’t make much revenue, which means I won’t be able to pay you some kind of salary. I could pay you in beer if you live within a train trip of London. Get in touch through the site’s contact form, or join JsChat #dailyjs room.

Let's Make a Framework: Feedback

19 Aug 2010 | By Alex Young | Comments | Tags frameworks tutorials lmaf

Welcome to part 26 of Let’s Make a Framework, the ongoing series about building a JavaScript framework.

If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing.

I received some feedback last week about Turing — very useful and interesting points that I thought followers of the series would enjoy.

Alias Library Eval Usage

Øyvind Sean Kinsey commented on one of my commits to say that he thought the way Turing creates a global alias was unnecessary. My code looked like this:

eval(turing.alias + ' = turing.aliasFramework()');

The reason I did this was so turing.alias would expand to the variable name. This was so people using Turing could alias it to a short name, like jQuery’s $.

turing.core stores a reference to the global context, which is generally window. As I like to write unit tests outside a browser I pass in an object rather than relying on window. Because the old version of turing.core didn’t expose this global, I used eval to create a similar effect.

Taking on board Øyvind’s feedback, I’ve added a method called exportAlias to the core library, and changed eval to:

turing.exportAlias(turing.alias, turing.aliasFramework);

A lot of libraries and frameworks set properties on window in a similar way.

DOM Ready Not Required

After all the work I put into creating a DOM ready implementation, it wasn’t really required! It’s possible to insert <script> tags at the end of a document to get a similar effect — this is actually recommended for performance reasons by people like Yahoo! and Google.

Arnout Kazemier let me know that all my hard work and the source of my steadily worsening RSI was worthless, so thanks Arnout!

In all seriousness, it’s useful to be aware of this alternative. Arnout even provided an example that clearly backs up the performance claims:

Here’s a good example of blocking rendering with a script. The script in the head takes 3 seconds to load and 1 second to execute. You will see a white page for 4 seconds because it blocks the rendering of the page because it’s loaded in the head. And the browser can’t continue because the contents might affect how the rest of page needs to be rendered.

I enjoyed the simplicity of this approach versus dozens of lines of JavaScript. And as far as this tutorial series is concerned, it’s good to know when frameworks are doing a lot of heavy lifting for features that aren’t always required.

Node Roundup 3

18 Aug 2010 | By Alex Young | Comments | Tags node server

Welcome to the Node Roundup. Send your apps in for review through our contact form or @dailyjs.

Nitrode

Nitrode is a new HTTP server. It’s a young project but it already has some interesting features:

  • Basic auth
  • Redirects
  • ETag and If-Modified-Since support
  • Static files
  • SSL
  • Virtual hosts

The thread on the nodejs list has more details, with a good discussion from list regulars.

Node Boilerplate

Node Boilerplate bundles lots of commonly used libraries together to make starting a new Node/Express project very easy. If you use Node a lot you probably have your own way of doing this, or perhaps you use npm, but it seems like it might be a good starting point for new users or tutorial writers.

If you want to experiment with Node, try it out. The author, Rob Righter, is also on twitter: @robrighter.

Twitter Node.js WebSocket Example

This has been kicking around for a while, but I noticed Twitter Node.js WebSocket Example has been updated. I was looking for examples of Node and WebSockets yesterday when I wrote that jQuery polling post, and I dug it up on GitHub.

It’s by Andre Goncalves (@andregoncalves on Twitter), and it’s pretty simple — the server-side part is only 50 lines.

jQuery Rolling and Polling

17 Aug 2010 | By Alex Young | Comments | Tags jquery plugins

Welcome to the jQuery Plugin Roundup, episode 19. Remember you can send your plugins in for review through our contact form or @dailyjs.

The Evolution of a Polling Plugin

Everybody hates polling. If you use polling Internet goblins will attack you for not using WebSockets. There are times when polling makes sense, but the main thing you need is a good library. Ajax.PeriodicalUpdater served me well for many years, and I could technically use it alongside jQuery, but a jQuery plugin would be better.

360innovate

360innovate (GPL and MIT) rewrote PeriodicalUpdater for jQuery.

It has a jQuery-style API:

$(document).ready(function(){
  $.PeriodicalUpdater({
    url : 'random.php'
  },
  function(data){
    var myHtml = 'The data returned from the server was: ' + data + '';
    $('#results').append(myHtml);
  });
});

It can do useful things like decay the time between requests when the response doesn’t change. This not only limits the traffic but also limits the amount of work your browser’s doing.

Robert Fischer

Robert Fischer updated 360innovate’s plugin in JQuery-PeriodicalUpdater. The usage changes a little bit, and it plays better with jQuery’s $.ajax:

$.PeriodicalUpdater('/path/to/service', {
    method: 'get',          // method; get or post
      data: '',                   // array of values to be passed to the page - e.g. {name: "John", greeting: "hello"}
      minTimeout: 1000,       // starting value for the timeout in milliseconds
      maxTimeout: 8000,       // maximum length of time between requests
      multiplier: 2,          // if set to 2, timerInterval will double each time the response hasn't changed (up to maxTimeout)
      type: 'text',           // response type - text, xml, json, etc.  See $.ajax config options
    maxCalls: 0,            // maximum number of calls. 0 = no limit.
    autoStop: 0             // automatically stop requests after this many returns of the same data. 0 = disabled.
}, function(data) {
      // Handle the new data (only called when there was a change)
});

Here’s a comment I liked from Robert’s post:

One stunt which people should definitely pay attention to is using executable code blocks for factoring out loop-invariant checks. In this case, it’s demonstrated in the logic to boost the decay:

var boostPeriod = function() { return; };
if (settings.multiplier > 1) {
  boostPeriod = function() {
    timerInterval = timerInterval * settings.multiplier;

    if (timerInterval > settings.maxTimeout) {
        timerInterval = settings.maxTimeout;
    }
  };
}

jquery.poll

Ethan Fremen modified Robert’s plugin to produce jquery.poll (simplified BSD license). This version can handle multiple active pollers and allows changes to the polling interval. His blog post, jquery.poll – a periodic polling plugin for jquery, has more details.

Robert and Ethan briefly discuss some of the changes in the comments.

smartupdater

Meanwhile, smartupdater (GPL and MIT) by Vadim Kiryukhin has been released. This one has a demo site with a lot of examples.

Smartupdater has some interesting features, like dynamic timeouts, decay (he calls it multiplier), and it even supports remote control from the server to reduce load.

So What?

As you can see from the evolution of Prototype’s PeriodicalUpdater, polling is not a simple problem to solve. The original Prototype code made it look easy, but it hid a lot of complexity. And there are some really bad jQuery polling plugins out there. If you’ve got a good one, please tell me about it!

jQuery Mobile, Hummingbird, Mongoose

16 Aug 2010 | By Alex Young | Comments | Tags jquery node server apps

jQuery Mobile

You’ve probably already heard about jQuery Mobile, but as I like jQuery and mobile JavaScript, I thought I should link it up. jQuery Mobile is aimed at touch-based phones and tablets. There’s a great graded browser support checklist — they’re working hard to support a wide range of devices.

The framework includes layouts and widgets, and ThemeRoller support.

jQuery’s Mobile Strategy is a detailed overview of the project. It covers progress so far and future plans.

We’ve been fixing bugs as we go and will continue to do so throughout the rest of the summer of 2010. We’re hoping to have a fully A and B grade-compatible release of jQuery and Sizzle ready by October of 2010.

Hummingbird

Hummingbird is a Node app for web analytics. It uses MongoDB and as such is a good example of a site built with Mongo and Node.

It uses git submodules for dependency management, which makes it easy to deploy to services like Heroku. If you’re addicted to npm but not comfortable with git submodules, you could reference how Hummingbird does it.

I’ve been looking through the source and it seems like a solid app. Even if you’re not interested in using the app, it’s a good example of a Node app that uses Express and Mongo.

Mongoose

I’ve been using MongoDB for a project with Node, and I felt a bit disappointed with node-mongodb-native. It’s a good library, but it does suffer from the old JavaScript nested callback problem.

The Mongo site links to Mongoose which attempts to address this problem. Mongoose uses models which are wrappers around collections. Promises are used to help create a slightly “flatter” syntax.

Mongoose uses __defineGetter__ to define getters and setters, so your collection fields can be accessed with succinct syntax.

It looks like a good library to me but I haven’t used it in anger yet.

jsvi

I love vi, so here’s jsvi. I was pleasantly surprised with the bits of vi that it supports. If I can find a way of jamming it into gmail I’ll be happy. I’ve spent a few weeks using Vimperator once and I was actually fairly happy with it.

nTPL

13 Aug 2010 | By Alex Young | Comments | Tags node templating server

nTPL

nTPL by Fedor Indutny is a simple templating system for Node. The author has concentrated on making it fast, and it can be installed with npm.

Part of this library is written with C++, and it can reload templates when the file is saved. It’s not a template language like haml, so if you’re looking for a Node-friendly alternative to haml you could try Jade.

Tab Completion in Node

I checked out the latest version of Node yesterday, and I noticed tab completion was mentioned. It looks like the readline support has been improved by Trent Mick, and this was posted to the group: Node v0.1.104.

I actually alias rlwrap js for various JavaScript REPLs because I’m used to history and completion. If you’ve never tried it before it’s worth knowing about. I installed it with either dpkg, port, or Homebrew, but you can get the source here: rlwrap.

Let's Make a Framework: Return of the DOM

12 Aug 2010 | By Alex Young | Comments | Tags frameworks tutorials lmaf events dom

Welcome to part 25 of Let’s Make a Framework, the ongoing series about building a JavaScript framework. This part is about handling when the DOM had loaded.

If you haven’t been following along, these articles are tagged with lmaf. The project we’re creating is called Turing and is available on GitHub: turing.js.

The Point

I’m taking us on a diversion this week because I’m tired of creating Turing examples without a DOM ready handler. This is a core feature of browser-based frameworks, and it’s the key to unobtrusive JavaScript.

The point is to watch for the DOM to finish loading, rather than the entire document (with all of the related images and other assets). This is useful because it gives the illusion of JavaScript-related code being instantly available. If this wasn’t done, JavaScript code could be evaluated after the user has started interacting with the document.

Most jQuery users use this feature without realising it’s there:

$(document).ready(function() {
  // Let the fun begin
});

Here’s the core of what makes this happen:

bindReady: function() {
  if ( readyBound ) {
    return;
  }

  readyBound = true;

  // Catch cases where $(document).ready() is called after the
  // browser event has already occurred.
  if ( document.readyState === "complete" ) {
    return jQuery.ready();
  }

  // Mozilla, Opera and webkit nightlies currently support this event
  if ( document.addEventListener ) {
    // Use the handy event callback
    document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );

    // A fallback to window.onload, that will always work
    window.addEventListener( "load", jQuery.ready, false );

  // If IE event model is used
  } else if ( document.attachEvent ) {
    // ensure firing before onload,
    // maybe late but safe also for iframes
    document.attachEvent("onreadystatechange", DOMContentLoaded);

    // A fallback to window.onload, that will always work
    window.attachEvent( "onload", jQuery.ready );

    // If IE and not a frame
    // continually check to see if the document is ready
    var toplevel = false;

    try {
      toplevel = window.frameElement == null;
    } catch(e) {}

    if ( document.documentElement.doScroll && toplevel ) {
      doScrollCheck();
    }
  }
}

Prototype and other frameworks have similar code. It’s not surprising that Prototype’s DOM loaded handling references Resig and other prominent developers (Dan Webb, Matthias Miller, Dean Edwards, John Resig, and Diego Perini). jQuery.ready gets called through either a modern DOMContentLoaded event, or onload events.

I like the way Prototype fires a custom event when the document is ready. Prototype uses a colon to denote a custom event, because these have to be handled differently by IE — element.fireEvent('something else', event) causes an argument error. I tried to duplicate that in Turing, but it’d take a fair amount of work to adapt Turing’s current event handling so I left it out for now and used an array of callbacks instead.

Setting up multiple observer callbacks will work:

<!DOCTYPE html>
<html>
<head>
  <style>p { color:red; }</style>
  <script src="http://code.jquery.com/jquery-latest.min.js"></script>
  <script>
  $(document).ready(function() {
    $("#a").text("A.");
  });
  
  $(document).ready(function() {
    $("#b").text("B.");
  });
  
  $(document).ready(function() {
    $("#c").text("C.");
  });
  </script>

</head>
<body>
  <p id="a"></p>
  <p id="b"></p>
  <p id="c"></p>
</body>
</html>

Our API

I’m shooting for this:

turing.events.ready(function() {
  // The DOM is ready, but some other stuff might be
});

Implementing “onready”

I’ve based the current code on jQuery. It’s just enough to work cross-browser and do what I need it to do. It’s all handled by private methods and variables. The last thing to get called is ready():

function ready() {
  if (!isReady) {
    // Make sure body exists
    if (!document.body) {
      return setTimeout(ready, 13);
    }

    isReady = true;

    for (var i in readyCallbacks) {
      readyCallbacks[i]();
    }

    readyCallbacks = null;
  }
}

This is just a tiny snippet, but to summarise the rest of the code:

  1. The public method, turing.events.ready calls bindOnReady
  2. If bindOnReady has already been called once, it will return
  3. This method sets up DOMContentLoaded as an event, and will fall over to simply call ready()
  4. The “doScroll check” is used for IE through DOMReadyScrollCheck, which also calls ready() when it’s done
  5. setTimeout and recursive calls to DOMReadyScrollCheck make this happen

The isReady variable is bound to the closure for turing.events, so it’s safely tucked away where we need it. The rest of the code is similar to jQuery’s — after going through the tickets referenced in the code comments relating to IE problems, I didn’t have enough time to create my own truly original version.

Something from the Archives

If you’re interested, I previously used the following code which I created (based on various blog posts and other bits of research) about 4 years ago:

function init(run) {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // kill the timer
  if (_timer) clearInterval(_timer);

  // do stuff
  run();
}

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>")
  var script = document.getElementById("__ie_onload")
  
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init() // call the onload handler
    }
  }
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) {
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
window.onload = init;

As you can see, the concept of a loaded DOM is a messy thing to deal with. It’s not really the fault of any one browser manufacturer, it’s just growing pains as a consequence of JavaScript evolving through the DOM levels.

I had this old code kicking around for years, and I was convinced the whole DOM loaded thing was over. But last year Dean Edwards wrote Callbacks vs Events on the topic. In particular he deals with handling DOMContentLoaded through custom events, and the article has some interesting comments.

Conclusion

The current version of turing.dom.ready isn’t exactly what I wanted, and I had to cut short some features due to time constraints (I spent about 4 hours on this article and had to call it a day). The code is here: turing.dom.js — if you can help simplify or improve it, I’d appreciate it! Maybe it could be a guest post?

Ryan Dahl Interview: Part 2

11 Aug 2010 | By Oleg Podsechin | Comments | Tags interviews nodejs
This interview was conducted by Oleg Podsechin with Ryan Dahl on the 8th of July, shortly after Ryan’s talk in Cologne. Oleg is a JavaScript enthusiast who runs Ionsquare Ltd, an IT consultancy.

OP: So on the topic of CommonJS, are you following any of the APIs or any of the discussions on the list?

RD: Yeah, sure

OP: And which ones are you most interested in?

RD: CommonJS has some good specs and some less good specs. Some specs are rather prescriptive without any implementation – which I find wrong. I do like the idea of having a common server-side javascript interface – I just think it’s going to take some time to experiment with different APIs. A binary spec is quite important because JavaScript currently lacks a way of dealing with raw binary in any reasonable way. The module spec is good, the assert spec is good, the others are questionable.

OP: What about the package spec?

RD: Oh yeah, it also looks good. I don’t want to work on a package system, so I’m not following it super closely, but I think that there’s a lot of good ideas there.

OP: As a user you must use a package management system. Which ones do you use?

RD: I’m playing around with NPM. It’s OK, kind of buggy, but you can use it.

OP: So with regards to packages, obviously there’s some stuff that’s going into the core of Node, but external packages, like XML parsing, are there any packages that you think are important that aren’t there already?

RD: There needs to be a better MySQL solution, libmysql_client, the library that comes with MySQL is blocking so that is not a solution. There are other solutions, but they seem kind of buggy. A lot of people use MySQL and it would be a hindrance for them if they couldn’t access that easily. That’s one.
For a long time I was lusting after a good JavaScript HTML parser, but it seems that has solved. I also wanted a DOM implementation and it seems like that’s been solved too. I would really like a way to access Cassandra, which uses Thrift – that’s not been done yet.

OP: There aren’t really any decent JavaScript Thrift libraries

RD: Thrift is a piece of crap but unfortunately some projects are using it so we’ve got to interface with it. Some sort of Thrift binding would be good.

OP: I think in the next release they’re looking to have a RESTful interface.

RD: I’ve heard they’re introducing an interface based on Avro, a new message serialization RPC thing, but I’m not sure how good the Avro support is. Avro seems a lot better than Thrift so just binding to Avro would be the best way go for talking to Casandra – I don’t know.

Being able to connect to databases is important for users. If it’s not there, then it’s a total roadblock for a lot of people. So, MySQL is a major one.

OP: A slight aside, but a big trend, aside from server side JavaScript is non relational databases and Node seems like the perfect glue, if you will, to connect these different data stores together. CouchDB guys are using it for that purpose. What are your thoughts, can you see an opportunity there?

RD: Exactly, Node perfectly fills the proxy and authentication layer, between the storage backend and client. So yeah, I think it’s a good sort of glue and I agree with the CouchDB philosophy that the bulk of the application can kind of sit in the database. All the hard stuff can be back in Couch and Node can just proxy data back and forth.

OP: So talking about the packages you’d like in Node, moving into the core and looking at the way the project is being built, what are your thoughts on project leadership in open source projects? What do you think is the right way to do it, which things shouldn’t you do? What’s your personal approach? Because you used to post little challenges for people to get them excited and get them contributing a little bit. Can you talk more about that?

RD: I have a strong arm in the project. I’m the only committer and I dictate how things go and I think that’s a good approach for Node at this stage. At some point, hopefully, Node will grow up and we’ll a committee that decides on things. But at the moment having somebody that’s dedicated to the project and who will make sure that any changes that go in will be maintained is important. Part of that roll is not accepting changes that I can’t maintain myself, and so it means rejecting a lot of good code – just because it doesn’t fit into my contrained idea of what “Node core” is. There are users who would have contributed, for example, package manager code, but it’s not something I have time to maintain.

Another part of leading this project is getting people involved by very explicitly suggesting to people what needs to be done. I’m sending a lot of I emails to people saying “hey, you should give me a patch on this thing, that would be very helpful”.

OP: Nudging them a little bit in the right direction …

RD: Yeah.

OP: So how big of a role has GitHub played in this? And git and the social coding element of it?

RD: GitHub is great – it’s best feature is the ability to have web links source code – at a particular commit, with a specific section highlighted. Linking to source code like that really improves communication in email and on IRC. That’s probably the best feature of GitHub.

OP: Issue tracker?

RD: The issue tracker I use, which is OK, but it could be better. Generally, GitHub could be doing more by hosting a mailing lists. Google Groups sucks.

OP: Moving on, with regards to commitment to the project, you’re saying that you’re fully behind (it and so on and so forth,) so you’re currently employed by Joyent? and working 100% on Node?

RD: Yeah – Node and projects based on Node. It’s great.

OP: I guess the question is more about the commercial nature of Node and commercialization of Node. Clearly Joyent have an interest in it, being a hosting company, but do you see an ecosystem of businesses emerging around Node at some point and if so what types of businesses are these likely to be?

RD: One obvious thing is hosting of applications in an simple way like Heroku is doing. Node opens the door to independent contractors making little real-time websites for people — so there’s that ecosystem.

OP: You don’t have an interest in building a service on top of Node? Rather you wish to maintain the core project?

RD: I work for Joyent, so I work on products for them, but my main interest is making Node perform well and make users happy.

OP: So the last couple of questions are a bit more abstract. The first one is about the asynchronous nature of Node. Do you see event driven webapps becoming more prevalent in the future? Not only Node, but asynchronous webapps in general.

RD: Yeah, definitely. Not waiting for a database is a big win in terms of performance – the amount of bagage associated with each TCP stream is just much smaller. We need that for real-time applications where many mostly-idle connections are being held. But even for normal request response websites I think we’ll see more asynchronous setups just because of the performance wins – even if it’s necessary. It’s clear that asynchronous servers perform better in almost every way, it’s difficult to ignore that.

OP: I guess writing callbacks and indentation in JavaScript is one hurdle towards asynchronous programming, but JavaScript is much easier for doing such stuff than other languages.

RD: There are of course efficient green thread and coroutine implementations which allow you to write asynchronous code in a synchronous looking way – Eventlet for example. I’m not convinced that’s the right approach, I think it’s a leaky abstraction. There’s no abstraction with callbacks – it’s a rather direct translation from the interface the operating system gives.

OP: Have you tried other languages that compile to JavaScript, like CoffeeScript, they do callbacks and deferred and stuff like that.

RD: CoffeeScript is cute. I’m not convinced by CoffeeScript’s deferred thing. I haven’t used it but it seems maybe that it will confuse the users.

OP: Do you not like the idea of using JavaScript as an intermediary language? If you’re going to be writing stuff for JavaScript, you should write it in JavaScript?

RD: I mean nobody would choose JavaScript if they had a choose, there are a lot of things wrong with it, but it’s an important language and it’s set in stone by its ties to the browser.

OP: So all these tools, like debugging …

RD: CoffeeScript is beautiful but it makes programming more difficult. If there was more toolage around CoffeeScript, like a debugger which translated line numbers from compiled code to CoffeScript lines, it will be interesting. For myself, Node is already buggy enough, another layer hurts rather than helps. The deferred concept is interesting, basically when you put in a deferred keyword before a function call, the rest of the current callback is put into a callback as the last parameter to the deferred call. Wonder how that’s going to work out – it seems too simplisitic. It’s kind of cute that you still have the same programming model. I mean, it’s not the same as what’s happening for coroutines or green threads, there’s still only one execution stack. Who knows, maybe CoffeeScript’s deferred keyword will end up working out well, I’m skeptical though.

OP: So, last question. Which is sort of two questions rolled into one really. At the last talk you gave the other day you mention that your view of a program is that it’s a set of inputs of data from various sources, somehow transforms that data and forwards it on. Can you elaborate on that a bit?

RD: Yeah, I think most of the programs, or a large part of the programs that we write, are just proxies of some form or another. We proxy data from a database to a web browser, but maybe run it through a template first and put some HTML around or do some sort of logic with it. But largely, we’re just passing data from one place to the other. It’s important that Node is setup to pass data from one place to the other efficiently and with proper data throttling. So that when data is coming in too quickly from the database, that you can stop that incoming flow. Suppose it’s over a TCP connection, you can just stop reading from that data source and not fill up your memory with the whole response. Start sending out the first part of the template that you’re sending to the web browser and then pull in more data from the DB. You know, it must properly shuffle the data through the process without blowing up the memory if one side is slower than the other. You shouldn’t have to pull down the entire table, put into a template and then send it out. It should just be able to flow through your system, so creating an environment where it’s easy to setup these flows in the proper way is important. We’re not there yet, but that’s kind of my vision of what Node will be. Lots of shuffling of data from one file descriptor to the next, without having to buffer a ton of data.

OP: So in a way you can look at different Node instances talking to each other, forming a graph with directed edges between the different nodes? Is that where the name Node comes from? How did you come up with the name?

RD: I used the name “Node” because I envision it as one part of a larger program. A program is not a process, a program is a database plus an application plus a load balancer and Node is one node of that. It’s not necessarily a bunch of NodeJS instances but a couple Node.js instances plus some other things.

OP: Sounds good! Thank you for taking the time to chat.

Ryan Dahl Interview: Part 1

10 Aug 2010 | By Oleg Podsechin | Comments | Tags interviews nodejs
This interview was conducted by Oleg Podsechin with Ryan Dahl on the 8th of July, shortly after Ryan’s talk in Cologne. Oleg is a JavaScript enthusiast who runs Ionsquare Ltd, an IT consultancy.

OP: The first question is an introduction really. How did you arrive at Node? Did you have experience with JavaScript before? When did you get started with JavaScript? And also event driven software?

RD: I was a contractor and I was doing various little C projects usually involving server and event driven software and I realized that I was doing this same code over and over. C is a nice language to work in, but I wanted something I could script in the same way that I was programming these servers.

OP: Had you done any front end stuff in JavaScript?

RD: A little. I used to work a lot with Ruby on Rails – so I’d often be dealing with front-end code. Back then I wrote a little Ruby web server called Ebb that was meant to be a faster Mongrel. That code was the starting point for Node.

OP: Ebb was mostly in C right? So you went from writing it in Ruby, then writing it in C and now you’re sort of ending up writing it in JavaScript?

RD: Right. So what originally was Ruby turned into C. For a while I toyed with the idea of having a small web server C library – but it’s hard to get anything done in C. One day I had this epiphany: “JavaScript is exactly the language that I’m looking for here.” That happened shortly after V8 being released.

OP: You’ve said that there are two languages that will always be around: C and JavaScript. So, what are your thoughts on JavaScript as a general purposed programming language?

RD: JavaScript has certain characteristics that make it very different than other dynamic languages, namely that it has no concept of threads. Its model of concurrency is completely based around events. This makes it rather different than other general purpose dynamic programming languages like Ruby and Python. At least for certain classes of problems, I’ve found JavaScript to be much easier to program in—for example when writing an IRC server.

OP: How do you see the future of JavaScript? Do you see JavaScript becoming increasingly more prevalent, not only on servers but also on desktops?

RD: JavaScript is already doing a great job describing GUIs. I think with a familiar browser-like API JavaScript could also make a good desktop application language.

OP: JavaScript is quite unstructured, so people just copy paste JavaScript code …

RD: Yeah, not having a module system doesn’t help. JavaScript really encourages people to dump everything into global variables. That’s a real detractor for JavaScript but in the end better practices can overcome that sort of thing.

OP: So, did you follow the whole discussion around EcmaScript 4 and EcmaScript 5?

RD: I like Crockford’s opinion that the language should be kept simple. One of the best things about JavaScript was its simplicity. It didn’t have many predefined ideas about how to do stuff – particularly for I/O. Although EcmaScript 4 didn’t define any I/O, it did define a lot. It did make a lot of breaking changes. That said, I wish EcmaScript 5 did have a few more features.

OP: Any particular ones in mind?

RD: What’s this called? Destructive assignment? If you have an array on the right and a list of variables on the left, and they can be define that way. That would be nice to have.

OP: That’s included in Rhino, but not in V8

OP: So let’s move on to Node itself. what is the most difficult design decision you made with regards to the project?

RD: Something that was very hard for me was … my original idea was that it was going to be purely non-blocking system and I’ve backed out of that a big in the module system and a few other areas. In the browser load JavaScript from a script tag is non-blocking. You don’t really know when the scripts are completely evaluated until an onLoad callback is made. Originally Node was similar. You would load a bunch of module files and you wouldn’t know that they were fully interpreted, fully evaluated, until a “loaded” event was . This made things a bit complicated. You couldn’t just do “require” and start using that stuff right below it, you had to wait for the callback to do that.

OP: The hello world app would have one more indentation.

RD: Right.

OP: But it’s funny because people say that one of the benefits JavaScript offers is that you can use it in the browser as well. You can run the same validation logic on the server and browser, but the CommonJS module spec doesn’t work within the browser, so there are these efforts to try and make frameworks with asynchronous module loading.

RD: Right, so in terms of difficult design decisions, I wanted Node to be browser-like. Maybe it didn’t use the same methods but the same structures could be ported easily, aliasing methods to the browser ones. Originally Node achieved that—it was totally browser-like. Originally, it even had a ‘window’ object. I slowly backed off that API as it became clear it wasn’t necessary to have the server-side environment be exactly the same. So I went with the CommonJS module system which was rather reasonable; the CommonJS people had put a lot of thought into it and I didn’t really want to worry about modules so much. So yeah, require is blocking and there are some other minor things that are blocking in Node. Generally this pragmatic approach of being non-blocking 99% of the time, but allowing a few synchronous operations here and there has worked out well. It probably doesn’t matter for a server-side program if you load modules synchronously.

Part 2 of this interview will be posted tomorrow (Wednesday 11th August).

CgnJS Meetings in Cologne

09 Aug 2010 | By Alex Young | Comments | Tags events

CgnJS is a open meet-up that takes place once a month in Cologne, Germany. Matthias Lübken is one of the founders, and the rest are on this Twitter list: @cgnjs/founders

Matthias got in touch with us recently about the group:

Back in June a couple of JavaScript enthusiasts met and founded the Cologne JavasScript Meetup aka CgnJS. Although we have very different backgrounds (Web, jQuery, Dojo, Server, Node, Mobile …) we share the enthusiasm about Javascript and hope that we can share this with other developers.

CgnJS meets once a month on the second tuesday. There are two short talks with discussions. The focus of the meetup is to meet other JavaScript developers so there is plenty of room to talk and discuss.

The next meeting will be tomorrow (August 10th) with talks on Test-driven Widget Development, and Getting started with the Dojo Toolkit. Doors open at 7pm, and the talks start at 7:30pm. They’re meeting at Cowoco, Deutz-Mülheimer Straße 129, 51063 Köln.

If you want to read more, try The Google group or @cgnjs. There’s also colognejs.

Fellow JavaScript enthusiast Oleg Podsech (who also has an awesome DailyJS Node-related article coming soon) has been to CgnJS and he enjoys it, so it’s worth checking out if you can make it.

1 2 3 4 5 6 7 8 9 10 11