donejs / donejs/vdom-streaming-serializer
Introduction
- Dominant language
- JavaScript
- Stars
- 1
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
The **vdom-streaming-serializer** is a library for serializing virtual DOM objects into chunks of strings that can be written into an HTTP response.
# Serializers
A **serializer** takes a data structure and turns it into a format that can be transferred betweens processes and then reconstructed later (called **deserialization**) back into the data structure from which it originated. See [the Wikipedia](https://en.wikipedia.org/wiki/Serialization) article for more information.
A **DOM serializer** is a serializer that takes DOM objects (such as Elements) and turns them into HTML strings.
A basic DOM serializer looks like this:
```js
function serialize(element) {
if(element.nodeType === Node.TEXT_NODE) {
return element.nodeValue;
}
var out = '<' + element.localName;
var attr;
for(var i = 0, len = element.attributes.length; i < len; i++) {
attr = element.attributes[i];
out += attr.name + '=' + attr.value;
}
out += '>';
for(var i = 0, len = element.childNodes.length; i < len; i++) {
out += serialize(element.childNodes[i]);
}
out += element.localName + '/>';
return out;
}
serialize(document.documentElement);
```
To server-render applications DoneJS uses the [can-simple-dom](https://github.com/canjs/can-simple-dom) library which provides DOM-like objects and includes it's own serializer which can be [viewed here](https://github.com/canjs/can-simple-dom/blob/master/lib/simple-dom/html-serializer.js) for reference.
# Streaming
Streaming is a way to deliver data incrementally. If you've ever used Netflix you've used streaming.
Similar to how Netflix can stream video over the internet, the a web server can stream HTML to the browser over HTTP. In Node.js you can write to an HTTP request's **response** stream like so:
```js
var http = require('http');
var hostname = '127.0.0.1';
var port = 3000;
var server = http.createServer(function(request, response){
response.statusCode = 200;
response.setHeader('Content-Type', 'text/html');
response.write("
My homepage
"); setTimeout(function(){
response.write("
Hello world!
");response.end();
}, 50);
});
server.listen(port, hostname);
```
In the above example we write some HTML into the response, wait `50` milliseconds, write some more HTML, and then end the response. You can imagine how this technique might be useful:
* If you need to make a request to a database to retrieve data before rendering some HTML.
* If you need to make a request to an external API.
* If you have an incoming stream containing a list of items to render.
* A slower database query that is not needed until the user has scrolled down the page.
If you are familiar with MVC, Model-View-Controller, much of the **controller**'s job is to get the **model**s ready to hand over to the **view**. Streaming is a method that allows you to do this work incrementally, showing your users *something* while you wait for all of the db requests to complete.
# This project
This project combines the two above ideas, taking a DOM serializer and making it so that it can stream chunks of HTML into an HTTP response.
A *streaming serializer* works similar to the above example DOM serializer, except that when it encounters a [Node](https://developer.mozilla.org/en-US/docs/Web/API/Node) that is marked as being asynchronous, it will **flush** any HTML it has already generated and wait for that Node to be complete.
Nodes will be marked as being async using a [Symbol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol) like so:
```js
var ASYNC = Symbol.for('async-node');
element[ASYNC] = new Promise( ... )
```
The streaming serializer will do something like this:
```js
if(element[ASYNC]) {
// Call the `flush` method to write any existing HTML
// that has been accumulated.
this.flush();
element[ASYNC].then(function(){
// Now we can continue serializing from where we left off
});
}
```
This will allow HTML to be delivered as incremental chunks:
**chunk 1**
```
Todos page
- Go to the grocery
- Walk the dog
```
**chunk 2**
```
```
**chunk 3**
```
```
**chunk 4**
```
Thanks for visiting my page!
```
# What's Next
Hopefully this introduction provides an idea of what this project hopes to achieve. Next check out these issues to learn more.
* [API](https://github.com/donejs/vdom-streaming-serializer/issues/3)
* [Tasks](https://github.com/donejs/vdom-streaming-serializer/issues/2)
Contributor guide
No contributing guide indexed for this repository
Research direction
The issue body is the only named starting point; read its serializer, streaming, and “What’s Next” sections first. No file, test, or concrete documentation change is specified, so completion cannot be verified until the requested scope and target documentation location are clarified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- documentation
- Issue type
- Documentation
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100