BronsonJS

Module application and pub/sub framework for RequireJS

View project on GitHub Download Bronson Download Minified Bronson

What is Bronson?

Bronson is an opinionated module application framework for the building of large scale javascript applications. It sits on top of RequireJS and makes the loading, unloading, management and communication of your modular web components easier and more importantly loosely coupled. Bronson was born from the need to do modular application development in the real world not just on single page applications.

Features

Getting Started

Installation

Download the scripts manually from the links above or optionally install with bower bower install bronsonjs

Module Loading & Management

Let's start by creating a basic Bronson module by extending Bronson's base object.

define(['bronson'], function(Bronson) {
  var Foo = Bronson.Module.extend({
    onLoad: function(data) {
      console.log('loaded with:', data);
    },
    onStart: function() {
      console.log('started');
    },
    onStop: function() {
      console.log('stopped');
    },
    onUnload: function() {
      console.log('unloaded');
    }
  });
  return Foo;
});

Next lets load the module through Bronson somewhere else in the application.

require(['bronson'], function(Bronson) {
  // load up the module asynchronously through RequireJS and registers with Bronson
  Bronson.load({
    id: 'foo',                // unique id used for API methods
    path: 'path/to/foo',      // path for RequireJS to load
    data: {                   // optional data object to pass to onLoad
      message: 'hi from foo'
    }
  }); 

  // start the module by id
  Bronson.start('foo'); // log: 'started'

  // stop the module by id
  Bronson.stop('foo'); // log: 'stopped'

  // unload the module by id
  Bronson.unload('foo'); // log: 'unloaded'
});

Event Aggregation (Pub/Sub)

To encourage strong decoupling of your modules Bronson comes with a build in publish/subscribe system complete with a permissions gateway and consistent enforced naming convention in the form of subscriber:channel:topic

Let's take a look at a simple example

// first set up your subscription scoping it to a channel and topic
Bronson.subscribe('foo:app:helloworld', function(data) {
  console.log(data.message);
});

// next publish a method to the channel topic (leaving off subscriber)
Bronson.publish('app:helloworld', { message: 'hey!' }); // hey!

// finally we'll use unsubscribe to remove the subscription. 
Bronson.unsubscribe('foo:app:helloworld');

// unsubscribe can be scoped to subscriber only (removing all subscriptions for that subscriber)
Bronson.unsubscribe('foo');

Putting it all together

Now we know the very basics of loading and controlling modules with Bronson. Next lets add some basic pub/sub communication to communicate with the module. Bronson modules themselves act as mediators interfacing with Bronson's built in event aggregation system. This gives structure to your event based communication with modules acting as the controllers of all inbound and outbound communication.

Bronson modules have an events hash mapping Bronson's event aggregation to modules onLoad

require(['bronson'], function(Bronson) {
  var Foo = Bronson.Module.extend({
    // Event hash mapping callbacks to Bronson events 
    // (notice we leave the subscriber ID off as it's inferred)
    events: {
      'app:notification': 'notification'
    },
    onLoad: function(data) {
      // good for ajax request, creating Backbone views or similar
    },
    onStart: function() {
      // good for rendering of Backbone views or similar
    },
    onStop: function() {
      // stop animations pause components
    },
    onUnload: function() {
      // remove elements from DOM && clean up memory
    },
    notification: function(data) {
      // started is automatically kept track of via start() & stop() methods
      if(this.started) {
        alert(data.message);
      }
    }
  });
  return Foo;
}); 

require(['bronson'], function(Bronson) {
  // verbose options for load() including defaults
  Bronson.load({
    id: 'foo',                // unique id used for API methods
    path: 'path/to/foo',      // path for RequireJS to load
    options: {
      autoload: true,
      autostart: false
    },
    success: function(module) {},
    error: function(error) {},
    data: {                   // optional data object to pass to onLoad
      message: 'hi from foo'
    }
  }); 

  Bronson.publish('app:notification', { message: 'hey!'}); // nothing

  Bronson.start('foo');

  Bronson.publish('app:notification', { message: 'hey!'}); // alert('hey!')

});

Module Permissions

Bronson comes with a Permissions manager for managing which modules can communicate with other modules. The first thing we must do is enable it.

Bronson.options.permissions = true;

Next create a hash of module to module relationships.

Bronson.Permissions.set({
  'foo': {
    'baz': true,
    'bar': false
  }
});

Advanced Usage

Please review the documentation or the working demo's source code for more advanced usage.

Dependencies

Acknowledgments