0.7.3 • Published 7 years ago

cudo v0.7.3

Weekly downloads
-
License
BSD-2-Clause
Repository
github
Last release
7 years ago

cudo

Core package for Cudo, a distributed application framework

Build Status Coverage Status

Overview

This package provides the core mechanics of a Cudo app. It enables creating and running of an app, and provides a structure for extending the app's functionality.

Creating and running an app

In the most basic scenario, a new app can be created and run using the following:

const cudo = require("cudo");

// Initialise and run an app.
cudo.init()
    .then((app) => {
        return app.run();
    });

Setting configuration

Configuration properties for the given app object can be set by passing a configuration object as an argument to cudo.init().

Configuration properties must be scoped using a component identifier, like so:

const conf = {
    myComponent: {
        myConfProperty: "myConfPropertyValue"
    }
}

The core component allows specifying the following:

  • core.handlers.autoLoadDisabled - boolean - if true, auto-loading handlers is disabled, regardless of core.handlers.paths
  • core.handlers.paths - array - specifies directories where auto-loader looks for handlers
  • core.handlers.quietMode - boolean - enables/disables printing console log and error messages generated by the core module

A path for auto-loader lookup can be added like so:

// Define configuration.
const conf = {
    core: {
        handlers: {
            paths: [
                fs.realpathSync(__dirname + "/handlers")
            ]
        }
    }
};

// Initialise and run an app.
cudo.init(conf)
    .then((app) => {
        return app.run();
    });

Alternatively, handlers can be grouped into containers by defining the lookup configurations as follows:

// Define configuration.
const conf = {
    core: {
        handlers: {
            paths: [{
                containerName: "myContainer"
                path: fs.realpathSync(__dirname + "/handlers")
            }]
        }
    }
};

Handlers loaded with this configuration will be accessible via context.app.handlers.myContainer.

Working with contexts

Contexts used to pass data and a reference to the app object between the app's functions. When an app is run, a default context, called root context, is created.

Context data is stored within context.data property, while the app object can be accessed via context.app property.

To limit the amount of data passed between functions, and to better control which data is available to which parts of the application, child contexts can be created. A child contexts can be passed to a nested promise chain, making it available only to that chain.

A child context can be created like so:

let childContext = context.app.contextCreateSync(context);

Pre-setting root context data

Root context data can be pre-set by passing an object to the app's run() method like so:

app.run({
    myProperty: "myValue"
});

Working with handlers

Handlers are functions providing app functionality beyond the creation and running of the app.

Handlers must:

  • return a promise
  • take an context argument
  • pass the received context object as an argument to the resolve() function
  • be always scoped using a component identifier, e.g. app.handlers.myComponent.myHandler

Handlers should:

  • reject a promise, passing an error message as an argument to the reject() function

Auto-loading handlers

Upon running cudo.init() an auto-load mechanism will be triggered, which will attempt to load handlers within directories specified in conf.core.handlers.path setting.

Handlers will be placed into nested objects, based on their path, relative to the lookup directory. Thus a handler with a relative path test/auto-load-test.js will be placed in app.handlers.test.autoLoadTest.

For a handler to be properly detected and auto loaded, it must export the following:

module.exports.handler = (context) => {
    return new Promise(resolve) {
        resolve(context);
    };
};

Adding handlers manually

A basic handler can be added manually as follows:

app.handlers.myComponent = {
    myHandler: (context) => {
        return new Promise(resolve) {
            resolve(context);
        }
    };
};

Calling handlers

All handlers for the given app object can be accessed within the handlers property of the context.app object. Thus, a call to myComponent.myHandler can be made as follows:

context.app.handlers.myComponent.myHandler(context);

Modifying handlers

Handlers can be overwritten by assigning a different function in place of the existing handler. To reuse the existing handler within the new function, place the new function in a wrapper like so:

let myHandler = (context) => {
    return new Promise((resolve) => {
        resolve(context);
    });
}

app.handlers.core.run = ((existingHandler) => {
    return (context) => {
        return existingHandler(context)
            .then(myHandler);
    }
})(app.handlers.core.run);

In this example we have extended the functionality of the core.run handler by appending myHandler to the existing promise.

0.7.3

7 years ago

0.7.2

7 years ago

0.7.1

7 years ago

0.7.0

7 years ago

0.6.0

7 years ago

0.5.6

7 years ago

0.5.5

7 years ago

0.5.4

7 years ago

0.5.3

7 years ago

0.5.2

7 years ago

0.5.1

7 years ago

0.5.0

7 years ago

0.4.4

7 years ago

0.4.3

7 years ago

0.4.2

7 years ago

0.4.1

7 years ago

0.4.0

7 years ago

0.3.0

7 years ago

0.2.0

7 years ago

0.1.1

7 years ago

0.1.0

7 years ago