mojito-pipeline

A pipelining processor to render asynchronous page models in mojito

npm install mojito-pipeline
49 downloads in the last week
66 downloads in the last month

mojito-pipeline

Mojito-pipeline allows a mojito app to selectively schedule the rendering, the streaming, and the displaying of mojits (sections) of the page from the server to, and on, the client (browser). It leverages Node's event-oriented architecture to let you push those sections as their data comes from the backend; it handles structural dependencies, custom programmatic dependencies, errors and timeouts; and it gives you a lot of power to manage the lifecycle of your sections.

Build Status

Build Status

Table of contents

Terminology

task

a pipeline internal object that represents the scheduled runtime of a mojit instance and is created with a mojit configuration pushed in the pipeline by the user

section

a child task that can be replaced by a stub and asynchronously streamed to the browser when it's available (in the example below, the ads are sections)

dependency

a child task which needs to be blocking the parent task (often in order to be process by it, for example bolding or counting search results)

default section

a child section that the parent should push automatically

'rendered', 'flushed', 'displayed', 'errored', 'timedOut'

members of a task object that describe a task state and are modified throughout its lifecycle

'render', 'flush', 'display', 'error', 'timeout'

task actions which can be triggered under certain conditions defined by a boolean expression of other task states

Example

# application.yaml
[
    {
        "settings": [ "master" ],
        # ...
        "specs": {
            "rootframe": {
                "type": "SearchHTMLFrame",
                "config": {
                    "deploy": true,
                    "pipeline": true,
                    "child": {
                        "type": "Master",
                        "sections": {
                            "search-box": {
                                "type": "Box",
                                "default": true,
                                "config": {
                                    "title": "Search Box"
                                }
                            },
                            "search-results": {
                                "type": "SearchResults"
                            },
                            "ads": {
                                "type": "Ads",
                                "render": "search-results.rendered",
                                "sections": {
                                    "north-ad": {
                                        "type": "Box"
                                    },
                                    "south-ad": {
                                        "type": "Box"
                                    }
                                }
                            },
                            "footer": {
                                "type": "Box",
                                "flush": "pipeline.closed",
                                "default": true,
                                "config": {
                                    "title": "footer"
                                }
                            }
                        }
                    }
                }
            }
        },
        # ...
    }
]
// Master/Parent Controller
Y.namespace('mojito.controllers')[NAME] = {

    index: function (ac) {

        backend.getData(function (dataBit) {
            // this function is invoked for each data bit received
            var runtimeTaskConfig;

            if (!dataBit) {
                return ac.pipeline.close();
            }

            runtimeTaskConfig = makeTaskConfig(dataBit);
            ac.pipeline.push(runtimeTaskConfig);
        });

        ac.done(ac.params.body('children'));
    }
};

In the code above, you can see an number of arbitrary variables that are hopefully self-explanatory. One of them, makeTaskConfig represents a function that generates a task configuration with the data returned by the backend. This configuration and the one you can find in application.yaml are documented in the API Doc section below.

API Doc.

Static and runtime task configuration

what is runtimeTaskConfig in ac.pipeline.push(runtimeTaskConfig);?

the object passed to the ac.pipeline.push method will be merged with the static mojit configuration listed in application.yaml under the corresponding id. It is expected that static configurations will be located in the application.yaml, whereas the configurations that require runtime, will be the members of runtimeTaskConfig. If listed in both application.yaml and in the runtimeTaskConfig, properties will be overridden by the latter. Here is the list of the members that a task can receive that are meaningful to pipeline:

id

the id that this task can be referenced with (in business rules or when setting dependencies)

type

the mojit type that the task should instantiate. This is a normal mojito parameter.

sections

an Object defining this task's children sections (see terminology above) indexed by the task ids of those sections.

dependencies

an Array containing the ids of this task's dependencies (see terminology above).

default

a Boolean indicating whether this task should be automatically pushed by it's parent with the static config (see terminology above).

group

a String of a name for an Array allocated in the ac.params.body('children') of the parent of this task where all the rendered tasks having the same group name will be listed when they are rendered. Grouped tasks will usually be defined at runtime and be dependencies/blocking of their parent.

timeout

a Number representing the time in milliseconds that this task should stay blocked on its dependencies before it should be forced to unblock itself.

action rules

there is 4 possible action rules that can be defined by the user. their names are render, flush, display, and error. Each rule defines the condition that should trigger a new stage in the lifecycle of the task (see the lifecycle of a task above). Each rule is a String that symbolizes boolean expressions based on javascript's syntax. Each term of the expression can be a boolean true or false, or another expression based on a task attributes/states. To refer to a task in a rule, you can use the dot-notation on the task id just as if it was a javascript object. example (taken from the example above):

                            "ads": {
                                "type": "Ads",
                                "render": "search-results.rendered",
                                "sections": {
                    # ...
                                }
                            }

In this example, the 'render' rule means "render 'ads' whenever 'search-results' is rendered". The states of a task that you can use are: 'pushed', 'dispatched', 'rendered', 'flushed', 'displayed', 'errored' and 'timedOut'. In addition you can use the 'closed' state on the id 'pipeline' (just try to not call any of you tasks 'pipeline'...).

ac.pipeline.push(Object taskConfig)

Pushes a given task into the pippeline. This task will be processed according to the configuration given to the pipeline and the taskConfig object. This call is non-blocking: upon return, the task will exist in the pipeline but will not have started its lifecyle.

taskConfig

Some additional task configuration that will be merged with the configuration given to the pipeline in application.yaml. See the API above for more details about this object.

ac.pipeline.close()

Indicates to Pipeline that no more tasks will be pushed. The pipeline will trigger its 'onClose' event, flush the remaining tasks and send the closing markup.

Code Structure

addons

ac/pipeline.server.js

Exposes the main access points into the pipeline. Implements the public ac.pipeline addon and private Task class.

rs/pipeline.server.js

Handles pipeline's client-side minification

assets/void/pipeline-client.js

The client-side piece of the pipeline that handles the end of the processing of the tasks that are shipped to the client.

mojits

PipelineHTMLFrameMojit

A replacement for mojito's HTMLFrameMojit that handles pipelining of the frame.

ShakerPipelineHTMLFrameMojit

A replacement for mojito's HTMLFrameMojit that handles both pipelining and mojito-shaker

yui_modules/target-action-events.common.js

An implementation of a publish-subscribe model that lets the subscriber choose multiple publishers and multiple events at a time.

npm loves you