The JDA Revolution

Synopsis: As the amount of logic implemented in javascript increases in response to demands in accessibility and client-side functionality, the opportunity for foot-shooting has increased exponentially. JDA is a nimble, kevlar-booted javascript message-passing kernel which manages communication between separate javascript modules and enforces that modularization. JDA stands for Javascript Dataflow Architecture. It is an open standard developed by MAYA Design Inc.

Benefits of Modularization

One would think that the Object Oriented revolution would have resulted in a sufficient modularization of software in itself, but recent years has seen the rise of several different types of “external” techniques to further separate parts of code from other parts, mostly for the sake of reuse, but also to release the programmers of the burden of tracking inter-connectivity of different parts of a system.

In the Java world, we have Spring as a very good example. Spring has many features, but one of the most obvious is automated configuration and ‘wiring’ of loosely coupled objects. What does this mean? It means that you can write a java program as a couple of different objects that can use each other, and which can accept initialization data, but nothing explicit about initialization or connections to other objects is ever mentioned in the code itself.

Instead, Spring relies on external configuration files which can initialize and ‘wire’ together java classes which themselves need not be aware of the Spring framework at all. This means that the programmers can focus more on the task at hand and leave interconnectedness and certain state issues to later wiring by Spring (or another container framework).

Why modular Javascript?

And more importantly, don’t we already have modular javascript? Take all those issues with prototype and mochikit way back when. They solved that with name spacing. Dojo had name-spacing since forever, and by having write dojo.byId(‘foo’) you make sure that no parts of your framework will ever barge in on someone elses.

Well, the kind of modularization we’re talking about here is really of another kind, but name-spacing is an important technique which solves the problem of using several frameworks at the same time. Mostly :)

But we already have widgets, you say. Again, taking dojo as an example, the widgets can be created programatically, or marked up as such in the page. They always have a DOM element to hang on, and they are both self-contained and hierarchical.  Well, yes. Sure. But JDA is even more simple than widgets, though it uses similar techniques to mark things up.

The key to understand modular javascript in the JDA way is communication between modules. That’s what it’s all about. Most javascript programs are fairly small. Mostly this is due to a limited problem domain, but also to the expressiveness of modern scripting language. If you could take a JavaScript program and rewrite it in Java (for instance) it would generally be much longer. A good discussion on this can be found in Paul Bucheit’s blog (focusing mainly on APIs) and in CMSWire’s languages overview .

As Javascript programs grow in both size and complexity, spaghetti code tends to be a looming problem. This is of course not unique to javascript, and neither is the JDA pattern, which has been properly implemented in python, for instance (Probably dropping the leading ‘J’).

The basic assumption behind modularization of code in the first place is to protect the programmer from him or herself, by enforcing or encouraging separation of concerns and to create ‘natural’ borders between different parts of a system, the quick-fingered programmer receive cues where to put which new functionality.

In their thorough explanation of JDA, Seung Chan Lim and Peter Lucas defines JDA as “an ecosystem comprised of black box components operating within a JavaScript-based asynchronous message-passing environment”. By allowing for simple definitions of components, and a simple way to create multiple copies of the same, combined with a very simple message-passing abstraction, we get a compelling “workflow” where it costs little complexity to replace on of the components with another, or to make two or more connections from one components to other components, as needs for functionality in the application changes.

 

A Quick example

JDA uses the term ‘Infotron’ for a javascript module. A web page can contain any number of infotrons. Each infotron is an instance of a javascript ‘Blueprint’. That’s not a hand-waving term either, by the way. If you have loaded the JDA runtime in a page, you can define a blueprint like this;


BLUEPRINT(
“~027F54CD51114410dB7A77CB8A523E340″,
{
  “iterms” : [],
  “oterms” : ["click_value_out"],
  “properties” : ["bname", "message"],
  “name” : “Simple Button”
},
function (Class)
{
  Class.prototype._onInit = function(props)
  {
     var self = this;

     function _onClick(e)   
     {
        self.postMessage(“click_value_out”, props["message"]); // postMessage is also provided to ‘this’ by JDA
     }

    this.button = document.createElement(“button”);
    this.button.onclick = _onClick;
    this.button.innerHTML = props["bname"]; // This is a named property which can be passed to us upon initialization
    this.dom_node.appendChild(this.button); // this.dom_node is set by JDA to the element we are attached to
  };
});

The abov
e script defines a blueprint named “Simple Button”. You see that the first argument of the function BLUEPRINT in the JDA runtime is a unique identifier for the blueprint being defined. We could have written “xyzzy” instead and it would have worked, as long as no other blueprint were defined with that same UUID. General good practices, however recommend a proper UUID generated by the method of your choice.

//break//

What is a blueprint?

A blueprint is a template of a component which you might put in your web page. When the BLUEPRINT function is called in JDA, the blueprint is defined, and can then be used multiple times with the page. In the above example, this means you can put ten different buttons on the page, all implementing the same blueprint. It is roughly analogous to the relationship between a class and an instance in true OO languages.

The second argument is a javascript property map with four named values; iterms, oterms, properties and name. The name is pretty obvious. The iterms and oterms stand for input and output terminals.

Input terminals are names which can be accessed externally and which have handler functions. In this first example, we have conveniently dispensed with any input terminals, saving them for later :)

Output terminals are, as you surely have understood by now, the counterparts of the input terminals. Their names are externally visible, and the JDA function postMessage(output_terminal, any_object); can be used to send a javascript object (or literal, whatever) to that specific terminal. An output terminal can then be wired together with an input terminal.

After that comes any number of methods defined inside the blueprint. JDA provides special methods, one being the _onInit, which (if present) is called as soon as any infotron based on the blueprint is instantiated in the page.

The _onInit method first declares a simple event function, and then creates a button element whose onclick event is then tied to that function. What happens in the event function is that the provided property “message” is sent on the output terminal “click_value_out” when the user clicks the button.

Enter the Infotron

Note that this is a blueprint definition and it does not make anything show up in the page at all. For that to happen we must create an Infotron. Confused about Infotrons and Blueprints? Think like this; The blueprint is like prototype, the infotron is like calling element.puff();  You have to load prototype before you can use its goodies. But once you have, you can use them any number of times. Ok?

Let’s see a small example of an infotron using the above blueprint;

    <div id=”buttonexample”
        impl=”~027F54CD51114410dB7A77CB8A523E340
        properties = “bname:’My Button’, message:’Foo!’”
        script=”SimpleButton.js”>
    </div>

Not overly impressive, perhaps, but still a good start. Note that we are defining the infotron by using special tag properties. When JDA ‘boots’, it iterates all elements in the web page and registers all infotrons it finds. Since we might not have defined all blueprints we use prior to that (using the script tag in the head), we can also define the blueprint in the infotron definition. Note the names of the provided properties in the infotron definition, and that they are matched in the blueprint declaration.

We need more than one infotron to pass messages, though, so let’s define a simple blueprint which defines one input terminal and displays any message coming in inside a textarea;

BLUEPRINT(
“~197AA00D51114410d0A078238A52EF5F0″,
{
  “iterms” :
  [
     ["message_in", "onMessage", 10]
  ],
  “oterms” : [],
  “properties” : [],
  “name” : “Simple Show”
},
function (Class)
{
  Class.prototype._onInit = function(props)
  {
   
    this.area = document.createElement(“textarea”);   
    this.dom_node.appendChild(this.area);
  };

  Class.prototype.onMessage = function(msg)
  {
     this.debug(“Simple Show received message ‘”+msg+”‘”);
     this.area.innerHTML = msg; // Ta-daa! :)
  }
});


This blueprint in contrast to the first does not declare any output terminals, but has instead one input terminal. Note that the input terminal declaration contains some more information than the output terminal; The first item ‘message_in’ is the name of the input terminal, the ‘onMessage’ item is the name of the handler function, which is called as soon as a message is sent to the terminal, and the third property is the queue size of the terminal. If several messages are sent while the infotron is disabled for some reason, the are queued up to the number defined.

With some luck you now begin to see how these two blueprints fit together. But first we need to revise out earlier infotron definition snippet. We’ll add an infotron implementing the second blueprint, but also define a connection from the first to the second.

    <div id=”buttonexample”
        impl=”~027F54CD51114410dB7A77CB8A523E340
        properties = “bname:’My Button’, message:’Foo!’”
        connections=”‘startup_message_out’ : [['showexample', 'message_in']]”
        script=”SimpleButton.js”>
    </div>

    <div id=”showexample”
        impl=”~197AA00D51114410d0A078238A52EF5F0“      
        script=”SimpleButton.js”>
    </div>

Before we do anything else, just observe the austere beauty of these two infotrons. The javascript logic is locked up in separate files, which can be combined and pre-loaded by a ser
ver-side script if need be. Also, we are constraining the behavior of our scripts (not really, but we emphasize the encapsulation to the developer) inside the respective div elements. Further we are free to add CSS classes and styles which also separates logic from presentation.

JDA comes with a number of predefined blueprints, like a simple google map, form wrappers, a slideshow viewer, et.c. You also get a couple of convenience functions, like a debug version with copious output, and a debug output wrapper, which you can put in you pages for testing purposes, which redirects all debug output from both JDA itself and any ‘this.debug()’ statements you have in your blueprints to an area of your choice.

//break//

For small demos, it is sometimes convenient to just define the blueprints inside script statements in the page itself, and skimp on the script property in the infotron definitions.

A sample page with the above blueprints, and debugging enable would then look like this;

<!DOCTYPE html PUBLIC
          “-//W3C//DTD XHTML 1.0 Strict//EN”
          “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html>
<head>
<meta name=”uuid” content=”~019FF0001E0DDE94099163F8FEFA8802643″ />

<script language=”javascript” src=”JsStar.debug.js”></script>
<script language=”javascript” src=”init_jsstar.js”></script>

<script>
BLUEPRINT(
“~027F54CD51114410dB7A77CB8A523E340″,
{
  “iterms” : [],
  “oterms” : ["click_value_out"],
  “properties” : ["bname", "message"],
  “name” : “Simple Button”
},
function (Class)
{
  Class.prototype._onInit = function(props)
  {
     var self = this;

     function _onClick(e)  
     {   
        self.postMessage(“click_value_out”, props["message"]); // postMessage is also provided to ‘this’ by JDA
     }

    this.button = document.createElement(“button”);
    this.button.onclick = _onClick;
    this.button.innerHTML = props["bname"]; // This is a named property which can be passed to us upon initialization
    this.dom_node.appendChild(this.button); // this.dom_node is set by JDA to the element we are attached to
  };
});

BLUEPRINT(
“~197AA00D51114410d0A078238A52EF5F0″,
{
  “iterms” :
  [
     ["message_in", "onMessage", 10]
  ],
  “oterms” : [],
  “properties” : [],
  “name” : “Simple Show”
},
function (Class)
{
  Class.prototype._onInit = function(props)
  {
  
    this.area = document.createElement(“textarea”);  
    this.dom_node.appendChild(this.area);
  };

  Class.prototype.onMessage = function(msg)
  {
     this.debug(“Simple Show received message ‘”+msg+”‘”);
     this.area.innerHTML = msg; // Ta-daa! :)
  }
});

window.onload = function(e)
{
     __star.boot(); 
}

</script>
</head>
<body>

    <div id=”buttonexample”
        impl=”~027F54CD51114410dB7A77CB8A523E340″
        properties = “‘bname’:'My Button’,'message’:'Foo!’”
        connections=”‘click_value_out’ : [['showexample', 'message_in']]”>
    </div>

    <div id=”showexample”
        impl=”~197AA00D51114410d0A078238A52EF5F0″>
    </div>

<script language=”javascript” src=”debug.js”></script>
<div id=”debug” style=”position:absolute;bottom:20px;background-color:black;height:120px;width:100%;overflow:auto;”></div>
</body>
</html>

Here we see for the first time how JDA “boots”, by adding the __star.boot() call to window.onload. You framework of choice probably has a more generic onload handler for this event, but for our discussion, we stick to the basics.

If you want to see the demo in action, you can try it out here. If you want to download a zipped file with the demo, do so here.

Links to more information about JDA:

This entry was posted in Articles. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>