Because I've been so busy lately I haven't really had a chance to talk about anything I've built or been using, but i've been publishing so many new modules it's worth going back over.
Real quick, Getable is a mobile/desktop ordering and fullfillment application for commercial construction. Think mobile amazon/ebay for large construction jobsites.
First off, everything is realtime, using
engine.io with everything but long polling turned off. We tried leaving websockets on but there were some nasty bits that made the connection die and not come back on iPhone which we just couldn't debug in time so we turned it off.
Engine.io is a great module as it just provides a simple duplex stream-like (more on this later) interface that upgrades itself when available. This meant that in order to get some use out of it I had to write a few modules.
eiojson sends JSON messages rather than strings bidirectionally.
eioemitter is an event emitter that emits to the other side of the duplex.
eiomethods is a new take on RPC. With
eiomethods only the server exposes methods and it exports them dynamically, which means that it has to be used in conjunction with
eioemitter most of the time. This lets us dynamically expose different methods for different users and to maintain state in closures on the server for each of those connections.
While all of these realtime modules are built for and tested against
engine.io they should work with any duplex stream. None of them actually depend on
engine.io and all add functionality to a socket object by mutating it so they should work just as well with anyone who implements as much of the stream interface as
engine.io (which isn't a complete implementation but is enough for my needs in this case).
For authentication we use
hawk by Eran Hammer (previous author of OAuth and OAuth2) and it is definitely the easiest and most secure authentication I've ever used. Because everything is over a realtime channel we authenticate the channel using
authenticateMessage rather than signing the headers.
All of the frontend is built with
browserify which has been great. A good portion of our client code is also built for and tested in node.js which is made all that much easier by using the same patterns in the frontend as the backend. In a few cases we bundle a frontend resource seperately from its node.js package, which we do use during client testing in node, which was really painful with relative resources and the declarative features in package.json
browserify ships with. Instead, I wrote
broquire to dynamically load resources in node but assume they are already available in the global scope on the frontend.
I don't know much about it because I haven't written any of it but we're also using TJ's
rework for adding features to CSS and concatenting them together in to a single resource. I prefer adding features we need rather than using a full DSL for CSS.
A lot of deployment systems are out there and many of them are quite nice. I'm partial to what substack has been doing but during our beta phase we want continuous deployment for staging and production but without a lot of distribution or parellelism. We want a single process we can keep a good eye on while we work out all the initial bugs and issues. So, I wrote
flipover which has a one-to-one relationship with a child process that is "active" and being proxied to. It uses
hostproxy for the public facing side, finds a port with
getport and lauches a child process on it using
childport. Now the "merge" button in GitHub is a deploy button for the staging and master branches.
Because we're generating all our resources dynamically and won't tolerate a build step pre or post deploy we find it best to test/generate the necessary live resources in a new deploy before sending resources to it.
flipover allows for a test step and we use
webtouch to find and spider all the required resources in html and css for our application before resolving the callback that will flip to the new process.
This week we finally tackled the
appcache monster. A very scary and dangerous feature of the offline web it is also somewhat necessary if you want consistently speedy performance on unreliable mobile networks. The safest and most sustainable way I could think of to generate a cache manifest was similar to how we test a new deploy, by spidering the required resources found in html and css, so I used
webtouch in a new module called
appcached which also includes the combined md5 of every file as a comment which solves a lot of the manifest invalidation problems you get with
None of this would be possible without the immense value available in the node.js ecosytem. In addition to those already mentioned TJ's
css-parse and Matthew Mueller's
cheerio underly webtouch's spidering. Our entire frontend stack is built on substack's
browserify and couldn't exist without it. And
lodash are peppered throughout our code, just to name a few more.