Configuration

You should require only one script tag on your html since Arenite can take care of loading your javascript. This is advisable as there is a mechanism within Arenite to run in different flavors with different files

(ex: dev with all source files and prod with minified versions)

There are three ways to configure your instances to be registered with Arenite. You can use object configuration, annotation-based configuration or an AMD-style call to define. You can use all at the same time if such is desired.

A base object is always required for at the very least declaring the dependencies.

For the dev API documentation please go here.

Object Configuration

The object configuration relies on a simple object to define the desired properties for arenite to act upon.

Expose

The property expose is name of the variable to be used for exposing the arenite instance in the window object. This property can also be a function to determine if the variable should be exposed.

Expose Arenite as a window variable arenite:

  Arenite({
    expose: 'arenite',
    ...
  });

Expose Arenite as a window variable arenite only if a mode has been specified:

Arenite({
  expose: function(arenite){
    if (arenite.url.getUrl().mode){
      return 'arenite'
    }
  },
  ...
});

Imports

For any non-trivial web-application you can (and should) separate your configuration into several different components/files, known to arenite as modules. These can then be specified in your main configuration (usually in index.html).

Arenite({
  imports: {
    "templates": {    
      "module": "doT",
      "vendor": "arenite/template-extension",
      "version": "1.0.2"
    ...
  }
});

The key used in imports is used to uniquely identify each imported modules.

module is the name/path of the module. If no vendor is defined, it will use the name as a relative path. If the vendor is defined it will import the module from the repository (defaults to //cdn.rawgit.com/{vendor}/{version}/{module}/ and can be overriden by defining the config property repo) This name must correspond to the relative path of the configuration for the module.

vendor optional specifies the vendor of the module you are about to import.

version optional Defines which version of the module to fetch.

Note 1: Any arenite and non-arenite properties defined are merged and exposed in the property config of arenite.

Note 2: Local modules are packaged into the minified files by the gulp plugin while non-local are not.

Note 3 Any module must have a module.json file with the configuration for that module.

Context

The context is composed of four sections, all of them optional.

Dependencies

A minimal initial object based configuration is required to at the very least specify the resources. The dependencies section of the context is the configuration part where you define the script to load. Note there is a default entry in this element and that will be the files loaded by default. You can add any other sections you’d like and trigger those alternatives by appending the query param mode to the url.

Arenite({
  context: {
    dependencies: {
      default: {
        sync: [
            ...
        ],
        async: [
          ...
        ]
      }
    }
  }
});

Example: ...index.html?mode=debug will attempt to load scripts defined in a debug section.

Each dependency configuration contains two lists,sync and async which are used to list your scripts that need to be loaded synchronously or can be loaded asynchronously respectively.

Note that all sync scripts are loaded one after the other and only then the async scripst are loaded in parallel.

The entries can be simple strings with the location of the script:

Arenite({
  context: {
    dependencies: {
      ...
      dev: {
        sync: [
            '//code.jquery.com/jquery-2.1.3.min.js'
        ]
      ...
      }
    }
  }
});

Or you can, besides specifying the script, define the dependency extracts a variables from the window and registers them in arenite as an instances:

Arenite({
  context: {
    dependencies: {
      ...
      dev: {
        sync: [
            {
              url:'//code.jquery.com/jquery-2.1.3.min.js'
              instances:{
                'jquery':'$'
                ...
              },
              init:function(arenite){...}
            }
            ...
        ]
      }
    }
  }
});

url URL from which to retrieve the script. instances Object with the list of variables to extract from window and register in arenite’s context (the key is the instance name and the value is the variable name in the window object) init is an optional function that is executed after the script is imported and before the instance is extracted from the window object.

Instances

This section declares the instances that are to be wired and registered in the arenite context.

Any instance declared in this section can be accessed using arenite.context.get('model') where ‘model’ is the name of the instance to retrieve.

An instance is composed of four elements: namespace, args, init and the optional factory flag.

The namespace is a string declaring the function to execute to create the instance. args is the list of arguments to be passed when executing the namespace function and init is the function to initialize the instance (). The flag factory, which is false by default, defines if a new instance should be returned everytime the dependency is requested.

instances: {
...
 todo: {
    factory: true,
    namespace: 'App.Todo',
    args: [
      {ref: 'arenite'},
      {ref: 'model'},
      {
        instance: {
          namespace: 'App.TodoView',
          args: [
            {ref: 'arenite'},
            {ref: 'jquery'}
          ]
        }
      }
    ]
  }
...
}

There are four types of args: ref which declares the dependency is a arenite registered instance with the specified name, value which is a raw value (string, number, array, object, etc…), instance which is a declaration of an anonymous instance and exec which is the declaration of an execution (see the Start section of this document for more details).

Anonoymous instances are used in the wiring and inherit the factory flag from its parent but are not registered in the context. The anonymous instances are particularly useful if you use MVC or MVP design patterns where only the controller/presenter are registered in the context and the view can be declared (instantiated) for it but are not accessible from other controllers/presenters since they don’t exist in the context.

Extensions

You register your extensions in this section. There are a few extensions defined in the arenite project itself like the event bus, a simple router, a local storage extension (using StorageJS), a templating extension (using doT) and a test runner for jasmine with blanket code coverage.

An extension is pretty much a regular instance that instead of being added to the context registry is used to extend the arenite object itself.

...
 extensions: {
   templates: {
    namespace: 'Arenite.Templates',
    args: [
      {ref: 'arenite'},
      {ref: 'doT'}
    ],
    init: {
      wait: true,
      func: 'add',
      args: [
        {value: ['build/templates.html']}
      ]
    }
  }
   bus: {
      namespace: 'Arenite.Bus'
    }
 }
 ...

The name of the instance is used as the collection of utility functions. The sample snippet will add the return structure from Arenite.Bus into arenite.bus and Arenite.Templates into arentite.templates.

Having wait: true in an extension declaration will cause arenite to hold off the processing of the instances section until the extension has been completely instantiated and resolved. The callback to mark the instance as ready is passed as the last argument of the init function of the instance.

Start

The start section as the name implies is used to start the application after everything has been wired and initialized. It is a collection of function executions that is ran sequencially.

...
start: [
  {
    instance: 'model',
    func: 'load'
  }
],
...

The structure of the function executions is instance declaring the instance to use (the name), func the name of the function to be used and args the list of arguments. Starts can also be declared by using func as an actual Function that receives the arguments declared in the args.

...
start: [
  {
    func: function (model) {
      model.load();
    },
    args:[
      {ref:'model'}
    ]
  }
]
...

Full example

Here’s a full configuration as used in Arenite’s TodoMVC demo app. For the complete source go here

{
  "imports": {
    "templates": {
      "vendor": "arenite/template-extension",
      "module": "doT",
      "version": "1.0.2"
    },
    "storage": {
      "vendor": "arenite/storage-module",
      "module": "storagejs",
      "version": "1.0.2"
    },
    "router": {
      "vendor": "arenite/router-extension",
      "module": "",
      "version": "1.0.5"
    }
  },
  "context": {
    "dependencies": {
      "default": {
        "async": [
          {
            "url": "build/todo.min.js",
            "instances": {
              "jquery": "$"
            }
          }
        ]
      },
      "dev": {
        "async": [
          "//code.jquery.com/jquery-2.1.3.min.js",
          "js/model.js",
          "js/list/list.js",
          "js/list/listView.js",
          "js/list/toolbarView.js",
          "js/todo/todo.js",
          "js/todo/todoView.js"
        ]
      }
    },
    "start": [
      {
        "instance": "model",
        "func": "load"
      }
    ],
    "extensions": {
      "templates": {
        "init": {
          "wait": true,
          "func": "add",
          "args": [
            {
              "value": [
                "build/template.html"
              ]
            }
          ]
        }
      }
    },
    "instances": {
      "model": {
        "namespace": "App.Model",
        "args": [
          {
            "ref": "arenite"
          },
          {
            "ref": "storage"
          }
        ]
      },
      "list": {
        "namespace": "App.List",
        "init": "init",
        "args": [
          {
            "ref": "arenite"
          },
          {
            "ref": "model"
          },
          {
            "instance": {
              "namespace": "App.ListView",
              "args": [
                {
                  "ref": "arenite"
                },
                {
                  "ref": "jquery"
                }
              ],
              "init": "init"
            }
          },
          {
            "instance": {
              "namespace": "App.ToolbarView",
              "args": [
                {
                  "ref": "arenite"
                },
                {
                  "ref": "jquery"
                }
              ],
              "init": "init"
            }
          }
        ]
      },
      "todo": {
        "factory": true,
        "namespace": "App.Todo",
        "args": [
          {
            "ref": "arenite"
          },
          {
            "ref": "model"
          },
          {
            "instance": {
              "namespace": "App.TodoView",
              "args": [
                {
                  "ref": "arenite"
                },
                {
                  "ref": "jquery"
                }
              ]
            }
          }
        ]
      }
    }
  }
}