Security News
Node.js EOL Versions CVE Dubbed the "Worst CVE of the Year" by Security Experts
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
mojito-pipeline
Advanced tools
mojito-pipeline is a Mojito extension that allows applications to render mojits as soon as their data is available. It manages all the execution stages of a mojit and progressively flushes and displays content to the user agent. This process significantly improves front-end performance by immediately displaying sections of the page while concurrently rendering mojits as data arrives.
Pipeline consists of three components:
Pipeline Frame: The PipelineFrame, or the Shaker equivalent ShakerPipelineFrame, is a frame mojit, similar to Mojito's HTMLFrameMojit. It accepts one root level mojit, which it surrounds with a full html page frame, including html
, head
, and body
tags. It is responsible for embedding the PipelineClient (see below), and periodically flushing content to the client, including css/js assets. It accepts a configuration consisting of a tree of mojits that can appear on the page (see configuration).
Pipeline Addon: The Pipeline addon implements Pipeline's api, which allows users to push mojits, close the pipeline, and subscribe to events. It is responsible for processing mojits throughout their various stages (see mojit lifecycle), while allowing concurrency between data retrieval, mojit execution, and the flushing of content.
Pipeline Client: The Pipeline client handles the displaying of mojits on the client side. It is minified and inline on the first flush to the client. The Pipeline client consist of a global pipeline
object, which is used to deserialize flushed mojits and display them, observing any user defined displaying rules.
mojito-pipeline requires a Mojito application (Take a look at the Mojito Quickstart)
Install mojito-pipeline in the Mojito application:
$ npm install mojito-pipeline
Recommended. Install mojito-shaker (Shaker automatically processes assets):
$ npm install mojito-shaker
Add or modify a route's configuration to use the PipelineFrame
or ShakerPipelineFrame
(see configuration).
Push mojits into the pipeline using ac.pipeline.push.
Close the pipeline using ac.pipeline.close, after all mojits have been pushed.
Take a look at the "Hello World! example" below.
The source code to the Hello World exmple can be found under example/helloworld . Run ynpm install
, start the application using node app
, and access the application at http://localhost:8666/hello.
Create a new "hello-page" route and point that route to application specs that use the PipelineFrame
mojit:
routes.json
[{
"settings": [ "master" ],
"hello-page": {
"verbs": ["get"],
"path": "/hello",
"call": "hello.index"
}
}]
application.json
[{
"settings": ["master"],
"specs": {
"hello": {
"type": "PipelineFrame",
"config": {
"child": {
"type": "Root",
"children": {
"hello": {
"type": "Hello"
}
}
}
}
}
}
}]
The "hello-page" route specifies that the "hello" application specs should be used for the "/hello" path. The specs refer to the PipelineFrame
mojit, which has one child of mojit type Root
, which only specifies hello
as a child under its children
map (see Configuration).
Create two mojits, Root
and Hello
.
The Hello
mojit's controller simply passes the string "Hello world!" to its view:
mojits/Hello/controller.server.js
YUI.add('HelloController', function (Y, NAME) {
Y.namespace('mojito.controllers')[NAME] = {
index: function (ac) {
ac.done({
text: "Hello World!"
});
}
};
});
mojits/Hello/views/index.hb.html
<div>{{text}}</div>
The Root
mojit has a single child hello
, which it pushes to the pipeline:
mojits/Root/controller.server.js
YUI.add('RootController', function (Y, NAME) {
Y.namespace('mojito.controllers')[NAME] = {
index: function (ac) {
ac.pipeline.push('hello');
ac.pipeline.close();
ac.done(ac.params.body().children);
}
};
}, '0.0.1', {
requires: [
'mojito-params-addon',
'mojito-pipeline-addon'
]
});
mojits/Root/views/index.hb.html
<div>
{{{hello}}}
</div>
The Root
controller simply pushes its only child mojit, reference by its hello
id. It then closes the pipeline and passes its children data to its view. As specified in the configuration above, the top level mojit is of type Root
, which automatically gets pushed to the pipeline. Pipeline always refers to the top level mojit as root
. Before root
is dispatched, Pipeline populates its params.body.children
with the rendered data of its children. In this case root
only has one child, hello
, which hasn't been rendered so ac.params.body().children.hello
is equal to <div id="hello-section"></div>
. This is a placeholder for the hello
child, which Pipeline will fill, whenever hello
is fully rendered, either before rendering root
or on the client side.
After being pushed into the pipeline, mojits undergo various stages before finally being displayed on the client. Pipeline is fully responsible for processing mojits along these stages, but also allows users to precisely control and hook into mojit execution through execution rules and event subscription.
Stage Action | Resulting State | Description |
---|---|---|
push | pushed | The mojit has just been pushed using ac.pipeline.push. |
dispatch | dispatched | The mojit's controller has been called. |
render | rendered | The data passed to ac.done has been used to render the mojit's view. |
flush | flushed | The mojit has been added to the flush queue and will be sent to the client. |
display | displayed | The mojit has been displayed on the client side. |
Exception States
Exception | Resulting State | Description |
---|---|---|
timeout | timedout | The mojit timed out after dependencies prevented it from being dispatched. |
error | errored | There was an error while dispatching the mojit or its error rule returned true. |
A Mojito route that is handled by Pipeline requires an application specs entry that makes use of the PipelineFrame
mojit, or its Shaker equivalent, ShakerPipelineFrame
. This entry is a regular mojit spec, requiring type
to be either PipelineFrame
or ShakerPipelineFrame
, and a config
object:
Pipeline Frame Config Object
Property | Requirement | Description |
---|---|---|
child | Required | The top level mojit, which Pipeline should automatically push. |
deploy | Optional, defaults to false | Whether to deploy the mojito client (see Deploying to Client). |
pipelineClient | Optional, defaults to true | Whether to use the pipeline client, if false then the page is flushed all at once. |
Mojit specs are defined either under Pipeline specs in application.json, or using ac.pipeline.push at runtime. These specs are regular Mojito mojit specs and can include the following optional Pipeline specific properties:
Property | Requirement | Description |
---|---|---|
id | Optional | Only used when pushing a mojit to pipeline; refers to a previously defined mojit. |
children | Optional | A recursive mapping of child id's to mojit specs. Note id's must be unique. |
autoPush | Optional, defaults to false | Whether to push this mojit automatically after its parent has been pushed. |
blockParent | Optional, defaults to false | Whether to block the parent's dispatching until this mojit has been rendered. |
It can also include optional properties that allow precise control over the mojit's flow through its execution stages):
Property | Description |
---|---|
dispatch | When to execute the controller. Can ensure certain children mojits have reach certain states. |
render | When to render the view with the given data. Can ensure children mojits are embeded in mojit's view. |
flush | When to add the mojit to the flush queue. Can control when the mojit can be flushed to the page. |
display | When to display the mojit on the client. Can make sure the mojit is only seen after other mojits. |
error | When to error out the mojit. Allows the mojit to reach the error state given a specified condition. |
Stage action rules are boolean expressions that are evaluated during runtime, right before the specified stage action. Each clause is composed of a mojit instance and its state, for example, mojit-id.dispatched
. Clauses can be combined in complex manners using operands such as &&
, ||
, and parentheses.
Example
...
"dispatch": "(myparent.flushed && child1.rendered) || pipeline.closed)"
...
In this example the mojit will only be dispatched after myparent
has been flushed and child1
has been rendered, or the pipeline has been closed. Note that pipeline
refers to the pipeline itself, and only can reach one state, closed
. pipeline
is a reserved id in Pipeline.
{
"settings": ["master"]
"specs": {
"main": {
"type": "PipelineFrame",
"deploy": true,
"pipelineClient": true,
"child": {
"type": "Main",
"children": {
"child1": {
"type": "Child",
"chlildren": {
"grandChild1": {
"type": "Child",
"autoPush": true,
"blockParent": true
}
}
},
"child2": {
"base": "child2",
"display": "child1.displayed"
}
}
}
}
}
}
Before dispatching a mojit, Pipeline passes the mojit's children's data through ac.params.body().children
. The mojit is responsible for passing the children to its own view; this allows the mojit to process the children if necessary. Each child object contains the child's reached states, and a toString
method, which returns the html. Note that individual child objects should not be modified, since they are used internally by Pipeline.
Note: Unless a child's html needs to be modified, it is unnecessary to call a child object's toString
method since the rendering engine automatically calls toString
on objects before rendering a view. Also calling toString
method of an unrendered mojit results in a placeholder div, forcing the mojit to be flushed separetely from its parent and be embedded on the client side.
Example Controller
...
var body = ac.params.body(),
children = body.children;
if (children.child1.errored) {
children.child1 = '<span>Error:</span>' + children.child1.toString();
else {
children.child1 = '<span>Success:</span>' + children.child1.toString();
}
ac.done(Y.mix(viewData, children));
...
ac.pipeline.push (specs) async
Pushes a mojit into the pipeline, allowing pipeline to process the mojit through its execution stages. Note that this method is asynchronous; this allows multiple consecutive calls to ac.pipeline.push, before Pipeline actually starts processing the mojits.
object
| string
- A mojit specs object (see mojit specs); the id
property should be specified when referring to a previously defined mojit specs, in which case the new specs will be mixed with the old specs, with the new specs taking precedence. This method also accepts a string, corresponding to the id of a previously defined mojit specs.string
- The pushed mojit's id. This id may be a generated id, if the mojit specs pushed did not specify one.Example
ac.pipeline.push('mymojit1');
ac.pipeline.push({
id: 'mymojit2',
config: {
runtimeConfig: runtimeConfig
}
});
ac.pipeline.close (specs)
Closes the pipeline, signaling that no more mojits will be pushed. Note that the pipeline onClose
event is fired after Pipeline finishes processing all the mojits that have been pushed (see event actions).
Example
ac.pipeline.close();
ac.pipeline.on (subject, action, callback) Subscribes to a subject-action event, triggering a callback everytime the specified subject receives the specified action.
string
- The subject (either 'pipeline' or a mojit's id) that received the specified action. If '*' is specified then any subject is used.string
- The action applied to the subject (see event actions below).function
- The callback function that is called after the event is triggered. The callback has two arguments: an event object (see event object below), and any data associated with the event (see event actions below). Note this callback is called every time the event is triggered; to limit the triggering to only once use ac.pipeline.once.object
- A subscription to the event, includes the method unsubscribe
to stop listening to the event.Event | Event Type | Data | Description |
---|---|---|---|
before/afterDispatch | Mojit | Mojit Object | Fired before/after dispatching a mojit. |
before/afterRender | Mojit | Mojit Object | Fired before/after rendering a mojit. |
before/afterFlush | Mojit | Mojit Object | Fired before/after placing a mojit in flush queue. |
onError | Mojit | Mojit Object | Fired once a mojit has reached an error. |
onTimeout | Mojit | Mojit Object | Fired once a mojit has timed out. |
on/afterClose | Pipeline | N/A | Fired once Pipeline finishes processing mojits, and after it has checked for any errors. |
beforeFlush | Pipeline | Mojit Object | Fired before Pipeline flushes the flush queue. |
onError | Pipeline | Mojit Object Array | Fired after closing and determining that there were errors, passes errored mojits. |
Property | Description |
---|---|
target | The subject that received the event's corresponding action. |
action | The action that the target received. |
Example
ac.pipeline.on('*', 'afterRender', function (event, mojit) {
console.log(event.target + ' has been rendered: ' + mojit.toString());
});
ac.pipeline.once (subject, action, callback) Same as ac.pipeline.on, except the subscription is unsubscribed after the first call to the callback.
FAQs
A pipelining processor to render asynchronous page models in mojito
The npm package mojito-pipeline receives a total of 47 weekly downloads. As such, mojito-pipeline popularity was classified as not popular.
We found that mojito-pipeline demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 5 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Critics call the Node.js EOL CVE a misuse of the system, sparking debate over CVE standards and the growing noise in vulnerability databases.
Security News
cURL and Go security teams are publicly rejecting CVSS as flawed for assessing vulnerabilities and are calling for more accurate, context-aware approaches.
Security News
Bun 1.2 enhances its JavaScript runtime with 90% Node.js compatibility, built-in S3 and Postgres support, HTML Imports, and faster, cloud-first performance.