Node.js adapter
This adapter is used to make applications run on servers or embedded devices.
The following are only two examples of use cases. Expect more to come from Joshfire or from the community.
Building server-side websites
Usage of JavaScript on the server side with Node.js is currently exploding. One of its most powerful prospects is to share code between client and server. This feature has been planned since the early stages of the framework and is completely integrated in its design thanks to the Node.js adapter.
Request lifecycle
An incoming request from the client goes through a few components in this order:
- Webserver: The code actually listening on the port. Joshfire has a sample Express.js middleware
so that you can integrate it in your existing server code and benefit from all the features of Express. It is also the
recommended way to bootstrap a new project. But you could also use Node.js'
http.createServer()method or any other webserver code. - App Factory: Instanciates the App class and does a
app.setState()call to set the current environment (request URI, headers, ...)
Once the client has received the page from the server, you can also run the application client-side, depending
on the capabilities of the browser. The Navigation Util from the Browser adapter
will then intercept clicks on links and perform the same app.setState() that the App Factory does.
This design allows the Browser connector to change pages just by manipulating the DOM, like "single-page" apps do. This will bring all the benefits of such apps like responsiveness and improved user experience, while the Node.js connector solves all their usual issues by still being able to generate individual pages server-side (SEO, Old/specific browsers without JavaScript support, accessibility, ...). See Sylvain Zimmer's slides on this topic.
Rendering
Let's zoom on what is happening inside the App itself when processing the request.
- The Router util listens to
the
state.locationevents on the app. - It is often bound to a Panel Manager containing the part of
the layout that changes depending on the page. Usually this excludes headers and footers.
When a route matches, the Router issues a
manager.setState(route)call. - The Panel Manager selects only one of its children to be rendered depending on the route.
- The App issues a render() call to the root element of the UI Tree, which will trigger a cascade of render() calls down the tree to build the actual page.
Freshness
In the Browser adapter, the actual rendering of all the UI Elements of the UI Tree is done with simple
progressive DOM manipulation.
However it is a bit more complex with the Node.js adapter because the adapter needs to know
when all the components are fully rendered and not in a "loading" state anymore.
All the UI Elements can signal their "freshness" with a uielement.setState('fresh',true); call,
meaning that they are in a state that can be immediately serialized with uielement.getHtml() and sent
to the client.
The page will be serialized and sent to the client when all the displayable elements of the UI Tree are marked as "fresh".
Examples
The first public example is this website, which can be generated both from the server and the client sides.
It is open source on GitHub so that you can learn from it.
Expect many more to come in the next few weeks.
Receiving events via HTTP
Thanks to its HTTP Input, the Node.js adapter can receive requests and convert them to internal events.
These events can then be either processed locally by the application or sent again over the network, for instance to another application running in a browser via websockets (supporter in the Browser adapter's own HTTP Input).
Examples
The videolist example has an Arduino controller that works as described above.