Web2OS
A framework for rich internet applications

An example Web2OS application

The Web2OS javascript web framework is based on SQLite with Trimpath Junction and Template markup, which gives a Model-View-Controller setup in javascript.

The controller is extended to incorporate the concept of passing through requests, which is the normal action for a web proxy. The controller makes a call for each URL upon outgoing request, incoming response header, and for the response data itself. You can therefore plug in applications into the Web2OS proxy that can monitor web calls, store them locally, add your own data into responses, or respond directly to the browser rather than forwarding to the server (when offline, for example).

Suppose you would like to extend Google's search to store a history of each query you make, and keep a local copy of each search result. A special search cache, if you like, allowing you to bring up all your past searches and their results. This is just a toy example, but allows us to show the elements of a typical Web2OS application.

Create the Model

First of all, we create our Model. This will be a single History structure with two attributes - the query and the result.

History = function(){
}
with(modelFor('History')){
  hasColumn('query');
  hasColumn('result');
}
This will need to match the SQL database that gives us our local storage, so we define it in the same way as part of our setup:

function setup() {
  try {Web2os.execSQL("drop table History");} catch(e){};
  Web2os.execSQL("create table History (query varchar(200), result text)");
}

Create the Controller

Google searches use the URL www.google.com/search, so we will therefore need to create our controller to proxy each search query:

HistoryController = function(){
  this.search = function(action, req, res){
    if (action.browserRequest) {
      currentQuery=req.query.q;
    }
    if (action.serverHeader) {
      res.streamData='0';
    }
    if (action.serverData) {
      currentHistory=History.newInstance({'query':currentQuery, 'result':req.web2osData.data})
      currentHistory.save();
    }
    return res;
  }
}
The controller is called on three actions:

For each three actions, we return the "res" structure unchanged, allowing the proxy to pass through the request and response unchaneed from browser to server.

Create the Views

Our Web2os application will now store each search query and result for us, but how do we view them from our browser? To do so, we will need to create two more views - an index, and a query view.
this.index = function(action, req, res) {
    if (action.browserRequest) {
      res.histories = History.findAll();
      res.renderAction('index');
    }
    return res;
  }

The index view returns all the stored search Histories, and returns the local index template which will render the html back to the browser. The renderAction() call will return the template file called model_view.jst , which is history_index.jst in this example:

<html>
<head><title>Google Search History</title></head>
<body>
<h2>Google Search History</h2>
<ul>
{for h in histories}
  <li> <a href="/history/${h.id}">${h.query}</a>
{/for}
</ul>
</body>
</html>

This will list all past query Histories in a single page, and link to each one by its unique id.

The view controller is along the same lines, taking the id of a search history and displaying its result:

this.view = function(action, req, res) {
    if (action.browserRequest) {
      res.history = History.find(req['objId']);
      res.renderAction('view');
    }
    return res;
  }

The page template history_view.jst displays the query result:

<html>
<head><title>Google Search History</title></head>
<body>
<h2><a href="/history">Google Search History</a> : ${history.query}</h2>
${history.result}
</body>
</html>

Bringing it together

All that remains is to set up the URLs that the controller will act upon. This is defined in a list of regular expressions that should match the URLS seen by the proxy as the browser makes its requests to different web servers. The regluar expressions match to a given Controller (history in our example), and a given method, with the option of passing through any matching parameters:

requestURLs=[
  ['^/setup$', 'history', 'setup'],
  ['^/search.*$', 'history', 'search'],
  ['^/history$', 'history', 'index'],
  ['^/history/(\\d+)$', 'history', 'view', 1],
];

Now when searching on Google, your search requests and response pages are stored locally, and you can view past queries and your search result history through the url http://www.google.com/history

The entire javascript source of this simple Web2OS application can be found here

Further example code can be seen for the applications shown in the screenshots

Feedback
We'd welcome your feedback on Web2OS!