The trend in frameworks for Single Page Web Applications has been to make one page be “an application” with a single domain and typically a global state object. This has been the approach taken in React/Redux, Angular and others. This seems to be a philosophical trend from the “Windows Way” of building large monolithic everything-including-the-kitchen-sink school of systems design.

As a natural contrarian with a preference for the elegance of combining single purpose tools, the UNIX way, or The One True Way, I find the current trends in JavaScript browser based application development distasteful. So was born the Web Bus project, an implementation of a “micro kernel” like component architecture to compose Single Page Applications out of smaller self contained components. And building highly modular systems in JavaScript is not a foreign a concept as one might guess for a humble scripting language. The goal is create a system where complex applications can be constructed out of simple components that can snap together via small additions to the markup.

Web Bus provides three pieces of functionality. Nothing more.

  1. Create instances of Components and link them to specific elements in the DOM tree.
  2. Pass initialization state when instantiating components.
  3. Send messages to public functions on the instances, messages are DOM aware.

DOM awareness is one area where Web Bus differs from other frameworks that try to minimize the importance of the DOM Tree as the foundational data structure when working in a browser. The path of DOM IDs to each instance of a component is tracked so that sending a message can be targeted to instances within only part of the page. All well behaved components respect that the DOM pointer passed is its only responsibility to manipulate. Web Bus imposes no restrictions on what additional libraries or frameworks might be used inside a component.

Web Bus component instances are defined in the HTML mark-up using custom attributes on DIV tags. For example:

<div id="instance_name" class="webbus_container" data-logic="hello_world" data-params='{"parameter":"value"}'></div>

The ID will become the internal name of the instance, the class “webbus_container” marks the div as a container for Web Bus managed logic, “data-logic” is the name of the factory function used to create the instance and “data-params” is an optional in-line JSON data object to be passed to the new instance.

Ether after the main mark-up or on the page load the Web Bus system needs to be started as in the following code:

<script>
var wb = new _webbus_factory({});
wb.register(“hello_world”,
    function(web_bus, name, dom_element, params) {
        this._setup = function() {};
        this._start = function() {
            dom_element.innerHTML = “Hello World!”;
        };
    }
);
wb.autostart();
</script>

The factory function registered is passed the Web Bus object library, its own name, the DOM element it is in and any parameter object passed. The required public handler setup is called on all components followed by a call to all start functions.

The passed Web Bus object provides six public functions:

fire_event(‘event_name’, data) On any instance with a public function named event_name call the function passing the data provided. The function returns an object with properties named the name of each component instance called containing anything the event handler returned. The name of the event can contain a path to specify where the event should be called, ‘container_name/event_name’ will only call instances that are attached to decedents of a DOM element with the ID of “container_name”

page_config(“prop_name”) If an object passed to _webbus_factory() with page scoped data retrieve a property on that global data.

register(“factory_name”, function) Register a function as a component factory. Function must accept the standard parameters and implement _setup() and _start().

autostart() Scan the DOM for component instance definitions and set them up.

construct(“instance_name”, “factory_name”, dom_element, parameters) Create an instance of a registered component factory. Only creates the instance, usually only called by autostart() and boot_component().

boot_component(“instance_name”, “factory_name”, dom_element, parameters) Sets up a new instance and calls the _setup() and _start(). This is intended as a way to create instances after the initial autostart() in the case of a component spawning another component instance at run time.

Full examples of the Web Bus system are hosted at: http://arcdigitalservices.com/sandbox/webbus2/

And available from https://bitbucket.org/jhickmanarc/webbus2/

Next Post Previous Post