26. October 2015

React DOM Stream

React DOM Stream (GitHub: aickin/react-dom-stream, License: MIT, npm: react-dom-stream)

react-dom-stream is a React renderer for generating markup on a NodeJS server. Unlike the built-in ReactDOM.renderToString, this module renders to a stream. Streams make this library as much as 47% faster in sending down a full page than ReactDOM.renderToString.

One difficulty with ReactDOM.renderToString is that it is synchronous, which could cost you performance with server-side rendering of React sites. Especially true with large HTML payloads. Which could lead to the following problems as the developer saids:

  1. The server cannot send out any part of the response until all the HTML is created, which means that browsers can’t start working on painting the page until the renderToString call is done. With larger pages, this can introduce a latency of hundreds of milliseconds.
  2. The server has to allocate memory for the entire HTML string.
  3. One call to ReactDOM.renderToString can dominate the CPU and starve out other requests. This is particularly troublesome on servers that serve a mix of small and large pages.

react-dom-stream tries to fix those problems for us.

Let’s take a look, To use the server-side methods, we’ll need to require react-dom-stream/server. To render an element as a stream using express we would use the renderToString method. This would look something like this:

var ReactDOMStream = require("react-dom-stream/server");

app.get('/', function (req, res) {
    ReactDOMStream.renderToString(<Foo prop={value}/>, res)
        .then(function(hash) {
            // TODO: write the hash out to the page in a script tag
            res.end();
        });
});

When you are working with static pages where you don’t intend to use React to render on the client side you could use the renderToStaticMarkup method to generates smaller sized markup than renderToString.

Again with an express example:

var ReactDOMStream = require("react-dom-stream/server");

app.get('/', function (req, res) {
    ReactDOMStream.renderToStaticMarkup(<Foo prop={value}/>, res)
        .then(function() {
            res.end();
        });
});

When you are generating server markup using react-dom-stream, you cannot use the standard ReactDOM.render; you must use the render method in react-dom-stream. The difference between react-dom’s version and this one is that this render also takes in the hash returned from renderToString.

var ReactDOMStream = require("react-dom-stream");

var hash = 1234567890; // returned from renderToString's promise and read out into the page
ReactDOMStream.render(<Foo prop={value}/>, document.getElementById("bar"), hash);

22. October 2015

Observatory

Observatory (GitHub: mikesizz/observatory, License: MIT, npm: observatoryjs)

When you are following the spec proposals or read any other blog you have probably heard about Object.observe, which is used for asynchronously observing the changes to an object.

Observatory is an attempt to provide javascript developers an interface for Object.observe with mongodb style querying for specificity.

In order to use it we need to create a new instance of Observatory.

import Observatory from 'Observatory';
const observer = new Observatory();

Now we can observe an object by binding an event to it like so:

observer.on( object , query , callback );

Currently it supports the following events:

  • $update which observes events that include an update to a queried property
  • $add which observes events that include an addition to a queried property
  • $delete which observes events that include an deletion from a queried property

The real power is within the query expressions, by using different selectors you can create an expression for more specific event handling.

let cat = {
    age: 3
};

observer.on( cat , { $update: { "age": { $gt: 10 } } } , () => {
    console.log("Your cat is older than 10");
});

It provides the following value selectors:

  • $lt - check if the property is less than the query value
  • $gte - check if the property is greater than or equal to the query value
  • $lte - check if the property is less than or equal to the query value
  • $eq - check if the property is equal to the query value

For arrays it has a couple extra:

  • $in - check if the target array contains any of the query values after the event fires
  • $all - check if the target array contains all of the query values after the event fires

21. October 2015

Rollup.js

Rollup.js (GitHub: rollup/rollup, License: MIT, npm: rollup)

Rollup is a next-generation Javascript module bundler. Build your app or library using ES2015 modules, then efficiently bundle them up into a single file for use in browsers and Node.js. This is not an unfamiliar concept to the most of us. What makes Rollup stand out is that fact that it’s using only the functionality that you import.

Normally you would do something like this:

var util = require('util');
util.ajax('http://some-api.com/?q=DailyJavascript').then( handleData );

What this does is include the entire module util but we only use the ajax method. This will increase the total size of our app. Now there is ES2015 module loading which allows us to include only the functions we need like this:

import { ajax } from 'util';
ajax('http://some-api.com/?q=DailyJavascript').then( handleData );

When we build the second example, with for instance Browserify, what would happen is that the entire module would still get loaded. Kinda beats the point of using import right? Luckily there is Rollup to the rescue which will only build that what you need.

For the moment it only provides a command line interface which you can acquire via:

npm i rollup -g

The usage is pretty straight forward.

# create a self-executing bundle...
rollup --format iife -- src/app.js > build/app.js

# ...with inline sourcemaps:
rollup -f iife --sourcemap inline -- src/app.js > build/app.js

# create a bundle with dependencies on jQuery and Angular,
# with a sourcemap in a separate file
rollup -f iife --globals jquery:jQuery,angular:ng \
  -i src/app.js -o build/app.js -m build/app.js.map

For more commands check out the --help.

Alternatively, you could use rollup command from an npm run script cntext, you can install it as a devDependency using:

npm i rollup -D

20. October 2015

λJSON

λJSON (GitHub: MaiaVictor/LJSON, License: MIT, npm: ljson)

λJSON is a drop-in replacement for JSON which also allows you to parse and stringify pure functions and their contents. There are good security reasons for functions to be out of the JSON specs, but most of those are only significant when you allow arbitrary, side-effective programs. With pure functions, one is able to interchange code while still being as safe as with regular JSON.

var LJSON = require("LJSON");

// `newPlayer` is a function and couldn't be serialized with JSON.
function newPlayer(name){
    return {
        name      : name,
        hp        : 12,
        atk       : 5,
        def       : 5,
        inventory : []}
};

// LJSON has no trouble doing it because `newPlayer` is pure.
var newPlayerSource = LJSON.stringify(newPlayer);
var John            = LJSON.parse(newPlayerSource)("John");

console.log("Serialized λJSON: " + newPlayerSource);
console.log("Parsed and applied: " + John);

Outputs:


//Serialized λJSON: (function(v0){return {name:v0,hp:12,atk:5,def:5,inventory:[]}})
//Parsed and applied: { name: 'John', hp: 12, atk: 5, def: 5, inventory: [] }

The fact you have to explicitly provide primitives to LJSON functions is what gives you confidence they won’t do any nasty thing such as stealing your password, mining bitcoins or launching missiles. LJSON functions can only do what you give them power to. You are still able to serialize side-effective functions, but the side effects will happen on the act of the serialization and get stripped from the serialized output.

function nastyPair(a,b){
    console.log("booom");
    return {
        fst : a,
        snd : (function nastyId(x){
            for (var i=0; i<3; ++i)
                console.log("mwahahhahha");
            return x;
        })(b)};
};

// output:
// booom
// mwahahhahha
// mwahahhahha
// mwahahhahha
// (function(v0,v1){return {fst:v0,snd:v1})

19. October 2015

Vorpal.js

Vorpal (GitHub: dthree/vorpal, License: MIT, npm: vorpal)

Vorpal is a framework for building interactive CLI applications. Inspired and based on commander.js which is a port from the wonderful work done on this Ruby Gem. It provides you with an interactive prompt provided by inquirer and also provides a very extensive API with features such as: piped commands, command history, built-in help menu, tab autocompletion and the list goes on.

For full documentation of the API you should take a look at the Wiki.

Getting started with Vorpal.

import vorpal from 'vorpal'

const program = vorpal();

program
  .command('foo', 'Outputs "bar"')
  .action((args, callback) => {
    this.log('bar');
    callback();
  });

program
  .delimiter('app $')
  .show();

This creates an instance of Vorpal, adds a command which logs “bar”, sets the prompt delimiter to say “app $”, and shows the prompt.