Friday, May 24, 2013

LocalJS & Grimwire: A program architecture for Web Workers

Recently, I tagged 0.1.0 of Grimwire, and 0.3.0 of LocalJS. After 14+ months of development, the software is stable enough - still experimental, but stable enough - to use.


TL;DR


Grimwire is a frontend Javascript environment that gives user control over loaded scripts using a program architecture built on Web Workers and RESTful messaging. It's multi-threaded and provides tools for composing user interfaces.


A User-Extensible GUI Environment


This project was started to improve the flexibility of Web software and make it convenient for users to inject their own programs into the page. It's meant to do this while maintaining the convenience of on-demand software (that is, loaded in-browser). The end goal is to create a GUI environment that's easy and safe to extend with applications, thereby decoupling frontend software from backend services.

It attacks this goal in two ways: first, by creating a client-side toolset which gives Web services control of the document without delivering custom client-side code; second, by applying a RESTful messaging protocol over the Web Workers postMessage() API, enabling Javascript servers to be downloaded and executed in isolated threads. The net effect is a program architecture which the document software manages.

Restricting client-side code from the servers is an atypical constraint. Doing so, however, enables finer-grained security and composition:

  • Security. The client-side namespace only loads trusted software from the host. Web Workers, then, contain userland applications which must pass their messages through the document for auditing and delivery. This, combined with Content Security Policies, should make fine-grained security & permissions policies possible. (Iframes may also play a role, but their lack of thread isolation makes them bad candidates for user software.)
  • Composition. With Web Workers receiving Ajax calls under the "httpl://" interface (LocalJS), a general-purpose client can intercept request-forming events (link clicks and form submits) and route them to the Workers. That client program (Grimwire) then manages the document's resources (sessionStorage, security credentials, the DOM) under the user's direction. Using Hypermedia tools, software can discover resources in the environment, providing auto-configuration and composition between unfamiliar programs.

LocalJS - the core framework


LocalJS is a program architecture for frontend software. It can be used in any web app (games, applications, web desktops) to host third-party software. Because the programs are hosted in Web Workers, all user code is isolated in separate threads, and all interactions occur through messaging. Local applies REST over the Workers' messaging to allow them to behave as Web servers.

// load a local web server into a worker
local.env.addServer('helloworld.usr', new local.env.WorkerServer({
  src: 'data:application/javascript,'+
  'function main(request, response) {'+
    'response.writeHead(200, "ok", {"content-type":"text/html"});'+
    'response.end("<h1>Hello, World!</h1>");'+
  '}'
}));

// load the HTML from the worker server into #content
var region = local.env.addClientRegion('content');
region.dispatchRequest('httpl://helloworld.usr');

Some APIs in the Worker (such as XMLHttpRequest) are nullified so that all traffic must be routed through the document to be examined. For applications using HTML, Local isolates browsing regions on divs - iframes without the sandboxing. To keep the document trusted, services can use Content Security Policies to restrict client-side code and styles.

Note: Though LocalJS is being built for secure computing, the security features aren't complete yet, and many browsers have half-baked CSP support. Don't run untrusted code yet!

The libraries use promises for all async and take some cues from NodeJS, including require() & module.exports (for the Workers). You can find more information at http://grimwire.com/local/index.html.


Grimwire - a Web OS built for composable social computing


Grimwire is a deployment of LocalJS which behaves as a generic program execution environment. It defines applications using JSON configurations and includes tools to modify the software within the browser session. Future releases will include permissioning (so that users can share programs) and WebRTC as an Ajax transport (so users can serve applications directly to peers).

Since applications can't touch the document directly, they rely on HTML directives, response status codes, and special content-types to create rich & realtime UIs. There's a pretty wide set of use-cases already covered, but some needs are not yet covered. Getting this toolset right is the main objective of the 0.1.x release schedule. Afterwards, 0.2.x will focus on the security and multi-user features.

REST Architecture


Grimwire/LocalJS first started as an attempt to implement Plan9's universal files interface in the Web. It eventually dropped files in favor of REST, and now focuses heavily on Hypermedia discovery. In Grimwire, a link or form can refer to either: a chunk of data (data-uris), a local script, or a remote service. This initial abstraction simplifies the task of injecting new code into the environment - rather than event-binding, programs describe interactions in HTML and HRefs. The Link header, combined with URI templates, enables programmatic discovery of services and resources. Additionally, Server-Sent Events allow programs to sycronise by subscribing to event-streams (local or remote). These tools make it relatively painless to get unfamiliar programs talking to each other.

// programmatic hypermedia discovery with the navigator
local.http.navigator('http://myhost.com')
  .collection('users')
  .item('pfraze')
  .getJson();

// event subscription
var stream = local.http.subscribe('httpl://myhost.com/news');
stream.on('update', function(e) { console.log(e); });

There's more to find in the documentation, as well as some new tools at work in the dev branch.

How to Get Involved


Grimwire is meant to be used as a frontend framework for services. The host can add CSS to skin the environment, and also add client-side code if needed. There are no backend dependencies, so you can deploy statically or from a custom server.

Eventually, Grim should be an easy-to-use platform with a strong selection of apps, reducing the time to develop and deploy Web software. Right now, it's just a decent set of tools with a few holes to fill. If you want to get involved, there's a lot of opportunity to help make core decisions and core apps. Get in touch at pfrazee@gmail.com, @pfrazee, or any of the project's boards.

You can find the documentation in the nightly build. Questions and comments should be posted to the Grimwire Google Group. The repository can be found at github.com/grimwire/grimwire, MIT license.




Very special thanks to Goodybag for supporting Grimwire's development and actively investing in FOSS. It's because of progressive businesses like them that the Web can change for the better. If you're in Austin, keep an eye out for their tablets at restaurants, and bug the shops that don't have one yet!




No comments:

Post a Comment