<br />
<b>Deprecated</b>:  The each() function is deprecated. This message will be suppressed on further calls in <b>/home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php</b> on line <b>456</b><br />
<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Max Ogden Blog]]></title><description><![CDATA[Open Web Developer]]></description><link>http://maxogden.com/</link><image><url>http://maxogden.com/icon.png</url><title>Max Ogden Blog</title><link>http://maxogden.com/</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 08 Apr 2019 21:33:54 GMT</lastBuildDate><atom:link href="http://maxogden.com/rss.xml" rel="self" type="application/rss+xml"/><author><![CDATA[Max Ogden]]></author><item><title><![CDATA[Voxel.js Next]]></title><description><![CDATA[<div id="header"><h1 class="title">Voxel.js Next</h1></div>

<p>Check out the voxel.js reboot, April 2019</p>
<p>Just wanted to leave a quick note on my inactive blog for any Voxel.js fans out there: Mozillian and Fellow Oregonian <a href="https://github.com/joshmarinacci">Josh Marinacci</a> has been working on porting the now 5 year old Voxel.js codebase to work in modern browsers. </p>
<p>He&#39;s calling his reboot Voxel.js Next, and is working on the project because his nine year old son is a huge Minecraft fan and keeps bugging him to make a web based version. </p>
<p>You can check out Voxel.js Next on the <a href="https://blog.mozvr.com/voxeljs-next/">Mozilla Mixed Reality Blog here</a>.</p>
]]></description><link>http://maxogden.com/voxeljs-next.html</link><guid isPermaLink="true">http://maxogden.com/voxeljs-next.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sat, 06 Apr 2019 06:32:56 GMT</pubDate></item><item><title><![CDATA[Getting Started With Node For Distributed Systems]]></title><description><![CDATA[<div id="header"><h1 class="title">Getting Started With Node For Distributed Systems</h1></div>

<p>Where to get started with streams and peer to peer, May 2016</p>
<p>The great thing about node (and it&#39;s streams) is that its easy to plug different modules together into powerful pipelines.</p>
<p>For example in <a href="http://dat-data.com">Dat</a> we use <a href="https://github.com/maxogden/rabin">rabin</a> to chunk a file stream and then pipe into a merkle tree generator (<a href="https://www.npmjs.com/package/merkle-tree-stream">merkle-tree-stream</a>):</p>
<pre><code class="lang-js">var merkle = require(&#39;merkle-tree-stream&#39;)
var rabin = require(&#39;rabin&#39;)
var fs = require(&#39;fs&#39;)

fs.createReadStream(&#39;big.file&#39;)
  .pipe(rabin())
  .pipe(merkle())
  .on(&#39;data&#39;, function (data) {
    console.log(&#39;tree node&#39;, data)
  })
</code></pre>
<p>It&#39;s basically unix pipes all over again. To work with streams in various ways, try out the <a href="http://github.com/maxogden/mississippi">mississippi</a> module. For node and streams skill building, <a href="http://nodeschool.io">NodeSchool</a> is great for an intro to most of the skills you will need.</p>
<p>After getting through NodeSchool, <a href="https://p2p-workshop.mafintosh.com">this P2P workshop</a> by <a href="https://github.com/mafintosh">mafintosh</a> is a good challenge. It&#39;s doable once you have a basic knowledge of Node.</p>
<p>In the workshop you build a peer to peer chat system piece by piece using network streams, DNS, LevelDB and append-only log based message replication. It&#39;s best to try with friends, so you can chat with each other as you go through the lessons.</p>
<p>For some authors who write distributed systems modules, start with these (not an exhaustive list by any means):</p>
<ul>
<li><a href="https://github.com/substack?tab=repositories">https://github.com/substack?tab=repositories</a></li>
<li><a href="https://github.com/mafintosh?tab=repositories">https://github.com/mafintosh?tab=repositories</a></li>
<li><a href="https://github.com/maxogden?tab=repositories">https://github.com/maxogden?tab=repositories</a></li>
<li><a href="https://github.com/feross?tab=repositories">https://github.com/feross?tab=repositories</a></li>
<li><a href="https://github.com/dominictarr?tab=repositories">https://github.com/dominictarr?tab=repositories</a></li>
</ul>
]]></description><link>http://maxogden.com/node-distributed-systems.html</link><guid isPermaLink="true">http://maxogden.com/node-distributed-systems.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Fri, 06 May 2016 06:32:56 GMT</pubDate></item><item><title><![CDATA[What's the deal with iot.js and JerryScript]]></title><description><![CDATA[<div id="header"><h1 class="title">What&#39;s the deal with iot.js and JerryScript</h1></div>

<p>Node.js will soon be running on tiny low power chips.</p>
<p><a href="http://samsung.github.io/iotjs/">iot.js</a> is a Node.js compatible runtime being written by Samsung. The project is still in active development, is open source and Apache Licensed. It hasn&#39;t yet had a stable release but has been in development for over a year. It is built on a new JavaScript VM called <a href="http://samsung.github.io/jerryscript/">JerryScript</a> (named after <a href="https://en.wikipedia.org/wiki/Jerry_Mouse">Jerry Mouse</a>) that they are also working on. Node.js is built on V8, and iot.js is built on JerryScript. The major goal of iot.js is to run Node code on low power devices.</p>
<p>JerryScript doesn&#39;t have a logo yet, so I made one:</p>
<p><a href="media/jerryscript-large.png"><img src="http://maxogden.com/media/jerryscript.png" alt="jerryscript"></a></p>
<p>The current hardware requirements for iot.js are around 350KB ROM and 100KB RAM. This is a huge difference compared with V8, the VM that Node.js is built on, which is notoriously memory hungry and doesn&#39;t run on devices with less than 64MB of RAM (the lowest power device I&#39;ve seen running it is the <a href="https://www.arduino.cc/en/Main/ArduinoBoardYun?from=Products.ArduinoYUN">Arduino Yun</a>).</p>
<p>As you can <a href="https://github.com/Samsung/iotjs/wiki/IoT.js%20API%20Reference">see on their wiki</a> and the <a href="https://github.com/Samsung/iotjs/tree/master/src">current implementation</a>, iot.js is a Node.js compatible JS + C runtime that binds to JerryScript. </p>
<p>The first two officially supported devices are the STM32F4-Discovery and the Raspberry Pi 2:</p>
<p><a href="https://www.youtube.com/watch?v=hZXPa6szk3Q"><img src="http://maxogden.com/media/STM32F4.png" alt="STM32F4"></a></p>
<p><a href="https://www.flickr.com/photos/travelinlibrarian/16012874634/in/photolist-qp1aKq-cDBDks-gVeh8G-cteaUY-r4La4W-rp7cPE-g2nwfp-q3AdFU-rfmy16-uB73KM-c5JmRd-caokMG-dcFPis-eseAkY-rBAA2v-rinQFa-rkfjxi-dorXrE-c7JHuo-diztsQ-qeGZid-pZzc1H-pk154Y-pk14Ry-pZzbHP-pZrjR1-cDBYvJ-qDvwFe-daTWwG-omP1sP-rrJCaF-h4gEiw-qXTK4K-qKX8dV-qKVmAH-qKPr6N-r3nYtT-r3nYpV-r3dWga-q6zWGv-r3dVU8-q6nmh3-qKPrY9-qKPpoE-r15RSU-r3iasd-q6zXiF-q6zZmP-qKVjAF-r3dV1e"><img src="http://maxogden.com/media/raspberry-pi-2.png" alt="raspi2"></a></p>
<p>The exciting thing about this stuff is that it makes low power hardware more accessible to coders like me who know JS and can install modules from NPM but don&#39;t want to deal with C and compiled language tooling and debugging headaches.</p>
<p>I&#39;ve done a number of projects with the Arduino which can&#39;t run Node but has great battery life, and the Raspberry Pi which can run Node but has poor battery life and requires Linux sysadmin skills to operate effectively. The Raspberry Pi (or any Linux machine) is totally overkill for a lot of the projects I&#39;m interested in doing (e.g. a computer that lives on my bicycle, or on that sits in my garden measuring soil moisture levels). Low power node.js seems like the sweet spot for me - I can leverage the Node + NPM ecosystem to deploy stuff to hardware that can potentially run for weeks on a single charge.</p>
<p>In the future they will work on support for other devices (according to <a href="https://github.com/Samsung/iotjs/wiki/Getting-Started">their wiki</a>), including the Intel Edison and Samsungs recently announced Artik 1.</p>
<p><a href="https://www.youtube.com/watch?v=CPXQ65QRV3k"><img src="http://maxogden.com/media/intel-edison-size.png" alt="edison"></a></p>
<p><a href="https://www.artik.io/"><img src="http://maxogden.com/media/artik-1.png" alt="artik-1"></a></p>
<p>Perhaps the closest thing to iot.js is Espruino, who both develop a custom JavaScript runtime as well as manufacture development boards like the <a href="http://www.espruino.com/Pico">Espruino Pico</a>. The major difference between iot.js and Espruino is that Espruino is not Node.js compatible. The Espruino boards use a family of chips (STM32F4) that iot.js supports, so it should be possible to run iot.js on Espruino hardware in the future.</p>
<p>In addition to JerryScript and Espruino there is also <a href="http://duktape.org">Duktape</a> which is &quot;an embeddable Javascript engine, with a focus on portability and compact footprint&quot;. There is a project called <a href="https://github.com/creationix/dukluv">Duklove</a> that combines Duktape and LibUV, which in the future could form the basis of a Node.js compatible runtime build on top of Duktape.</p>
<p>It would be interesting to get the authors of JerryScript, Espruino and Duklove to sit down and talk to each other.</p>
<p>Another similar device is the <a href="http://www.esp8266.com/wiki/doku.php">ESP8266</a>, which is a low power microcontroller with an integrated WiFi networking stack. They are really cheap - you can get ESP8266 development boards for around $8 from Amazon or the raw chips in bulk for around $2 a piece. However, with only 64KB of RAM and ROM it is not quite beefy enough to run iot.js. The closest thing you can get is Lua through a project called <a href="https://github.com/nodemcu/nodemcu-firmware">NodeMCU</a> or the <a href="https://github.com/creationix/uscript/">μScript</a> project.</p>
<p>I think a low power Node.js runtime is long overdue and am looking forward to the first stable iot.js release.</p>
]]></description><link>http://maxogden.com/iotjs-and-jerryscript.html</link><guid isPermaLink="true">http://maxogden.com/iotjs-and-jerryscript.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Fri, 24 Jul 2015 06:32:56 GMT</pubDate></item><item><title><![CDATA[Electron Fundamentals]]></title><description><![CDATA[<div id="header"><h1 class="title">Electron Fundamentals</h1></div>

<p>A quick intro to Electron, a desktop application runtime.</p>
<p><a href="http://electron.atom.io/">Electron</a> is an open source project written by <a href="https://github.com/zcbenz">Cheng Zhao AKA zcbenz</a>, an engineer who works for GitHub in Beijing on the <a href="http://atom.io/">Atom text editor</a> team. It combines Chromium and Node into a single runtime suitable for building custom desktop web applications that also have access to Node for things that web browsers normally can&#39;t do.</p>
<p>Before starting Electron zcbenz <a href="https://github.com/nwjs/nw.js/graphs/contributors">contributed heavily</a> to the node-webkit (now called nw.js) project. Electron is conceptually similar to nw.js but has some important technical differences which are <a href="https://github.com/atom/electron/blob/master/docs/development/atom-shell-vs-node-webkit.md">explained here</a>. A key difference is that Electron uses Googles <a href="http://www.chromium.org/developers/content-module">Chromium Content Module</a> to bring in Chromium functionality vs nw.js which uses a <a href="https://github.com/nwjs/chromium.src/commits">forked version of Chromium itself</a>.</p>
<h2 id="it-s-a-runtime">It&#39;s a runtime</h2>
<p>Electron is a runtime, just like <code>node</code>. This means instead of running <code>node app.js</code> you run <code>electron app.js</code>. To make installing the Electron runtime easier I created a module called <a href="https://www.npmjs.com/package/electron-prebuilt"><code>electron-prebuilt</code></a> that downloads the latest release of Electron and installs it in your CLI path as <code>electron</code>.</p>
<pre><code>$ npm install electron-prebuilt -g
Downloading electron-v0.30.0-darwin-x64.zip
[=================================================&gt;] 100.0% of 37.07 MB (3.53 MB/s)

$ electron -v
v0.30.0
</code></pre><p>I&#39;d also like to give a shoutout to John Muhl who wrote <a href="https://github.com/johnmuhl/electron-prebuilt-updater">electron-prebuilt-updater</a>, which runs on a free Heroku server, listens for GitHub Releases on Electron with a WebHook and automatically does an NPM publish to <code>electron-prebuilt</code> with the new release. It&#39;s an awesome bit of automation that has saved me a lot of maintenance time!</p>
<p>My favorite part of Electron is that it combines Node and Chromium into a single context. This means you can write code like this:</p>
<pre><code class="lang-js">// require a C++ module in a browser!
var leveldb = require(&#39;level&#39;)

// open the database on the real HD
var db = leveldb(&#39;./data&#39;)

db.get(&#39;maxogden-profile&#39;, function (err, profile) {
  if (err) throw err

  // render data to the DOM
  document.body.appendChild(JSON.stringify(profile))
})
</code></pre>
<p>Normally to get <code>require</code> in the browser you have to use <a href="http://browserify.org/">browserify</a> to transform your code. In Electron apps <code>require</code> is already defined along with <code>process</code> and all of the other Node globals as well as <code>window</code>, <code>document</code> and all of the browser globals. Again, this is because Electron combines a Node JS context with a Chromium JS context. Anything you can do in Node and/or Chromium you can do in Electron.</p>
<h2 id="electron-is-low-level">Electron is low level</h2>
<p>The Electron API, similar to Node, is designed to support a rich userland of modules and applications. I was able to write a module called <a href="https://github.com/maxogden/menubar">menubar</a> that hides much of the complexity of the Electron API from you and lets you make a &#39;menubar&#39; style app (e.g. Dropbox) in just a few lines of code. Check out <a href="https://github.com/maxogden/menubar/blob/143f12309a5b617a586584a40fb5c52325f769d4/index.js">the source code</a> for menubar itself to get an idea of how you might wrap the Electron API in a higher level module (just like you would do with Node).</p>
<h2 id="apps-work-cross-platform">Apps work cross-platform</h2>
<p>Node itself has supported Mac, Windows and Linux equally since version 0.6, and Chromium is also cross platform. The Electron API philosophy is that it only adds support for features that can work on all platforms. For example, Windows has a &#39;system tray&#39; but Mac OS has a &#39;menubar&#39;. Electron implements an abstraction over these called the &#39;Tray&#39; API that is generic enough to function on whatever platform it is running on. Here&#39;s the same app running on Mac and Windows (using a Cat icon):</p>
<p><img src="http://maxogden.com/media/electron-tray.png" alt="electron tray"></p>
<p>Electron itself doesn&#39;t include a way to package your code into a executable (e.g. a <code>.app</code> for Mac or a <code>.exe</code> for Windows), so I wrote a module called <a href="https://github.com/maxogden/electron-packager"><code>electron-packager</code></a> that lets you build Mac, Windows or Linux apps from your source code.</p>
<pre><code>$ electron-packager /src/my-electron-foobar-app FooBar --platform=darwin --arch=x64 --version=0.25.1
</code></pre><h2 id="app-examples">App examples</h2>
<p>There are some big companies using Electron (in additon to GitHub). Notably Microsoft with their <a href="https://code.visualstudio.com/">VisualStudio Code editor</a> and Faceboook with their <a href="http://nuclide.io/">Nuclide editor</a>. However, Electron can be used for lots of things besides Code editors.</p>
<p>Myself and some friends have worked on a few apps in our spare time, just to get acquainted with Electron. Along the way I&#39;ve <a href="https://github.com/atom/electron/issues?utf8=%E2%9C%93&amp;q=is%3Aissue+author%3Amaxogden">opened ~20 issues</a> on the Electron repo when I got stuck and have got a response from zcbenz on each one. Some turned out to be bugs, some were feature requests that got implemented, and others turned into discussions that helped me find workaround.</p>
<h3 id="playback">Playback</h3>
<p><img src="http://maxogden.com/media/playback-app.png" alt="Playback"></p>
<p><a href="https://mafintosh.github.io/playback/">Playback</a> is an experiment in trying to write an app like VLC but based on web technologies. Some notable features include the ability to stream movies directly from Torrent files and Chromecast integration, all done with Node modules!</p>
<h3 id="monu">Monu</h3>
<p><img src="http://maxogden.com/media/monu.png" alt="monu"></p>
<p><a href="https://github.com/maxogden/monu">Monu</a> is a menubar app that wraps a process monitor in a little UI. It lets me run persistent command-line processes on my machine, much like I would do with <code>upstart</code> or even <code>cron</code> on a Linux server. It was something I&#39;ve wanted to make for a while and was a good way to get to know Electron. I use it to run <a href="https://www.npmjs.com/package/ssid-checkin">ssid-checkin</a> which logs me into Foursquare when I join known WiFi hotspots.</p>
<h3 id="screencat">ScreenCat</h3>
<p><img src="http://maxogden.com/media/screencat.gif" alt="screencat"></p>
<p><a href="https://github.com/maxogden/screencat">ScreenCat</a> is a screen/keyboard/mouse sharing + voice chat app that uses WebRTC. If you have ScreenCat running you can share your screen with someone else who has ScreenCat, or you can share your screen with someone in a WebRTC enabled web browser. It&#39;s a little rough around the edges, but I use it to do remote pair programming with coworkers from time to time.</p>
<h3 id="friends">Friends</h3>
<p><img src="http://maxogden.com/media/friends-app.png" alt="friends"></p>
<p><a href="https://github.com/moose-team/friends">Friends</a> is a <strong>highly experimental</strong> decentralized public chat app, similar to Slack or IRC but built entirely on WebRTC Peer-to-Peer systems so it doesn&#39;t depend on a central server -- all messages are exchanged directly between users. It&#39;s totally pre-alpha quality, so don&#39;t expect it to be easy to run just yet, but it has been a fun way to play with WebRTC and Node together.</p>
<h3 id="electron-microscope">Electron Microscope</h3>
<p>This one isn&#39;t an app per-se, but I&#39;m working on a web scraping/spidering tool based on Electron called <a href="https://github.com/maxogden/electron-microscope">Electron Microscope</a>. It adds an automation + data streaming API to Electron browser windows to visit, interact with, and stream data out of websites. If you&#39;re interested in giving it a spin I&#39;d appreciate <a href="https://github.com/maxogden/electron-microscope/issues/1">API feedback</a>.</p>
<h2 id="summary">Summary</h2>
<p>Given that Electron is a young open source project largely maintained by a single individual I think it&#39;s off to a great start. Browsers are complex beasts and I believe, given the interest it has had so far, that Electron will grow into a healthy open source source project with many core contributors and even better cross platform support.</p>
<p>I should note that I don&#39;t work at GitHub, I just like Node and Chromium and hence got excited about Electron and have written a few &#39;missing utilities&#39; to automate Electron workflows. I encourage you to do the same if you get the chance, or to get involved with any of my utilities as they are all open source projects.</p>
<p>For more Electron resources you should check out the <a href="https://github.com/sindresorhus/awesome-electron">awesome-electron</a> list by Sindre Sorhus.</p>
]]></description><link>http://maxogden.com/electron-fundamentals.html</link><guid isPermaLink="true">http://maxogden.com/electron-fundamentals.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Thu, 23 Jul 2015 06:32:56 GMT</pubDate></item><item><title><![CDATA[HD Live Streaming Cats to YouTube with the Raspberry Pi Camera]]></title><description><![CDATA[<div id="header"><h1 class="title">HD Live Streaming Cats to YouTube with the Raspberry Pi Camera</h1></div>

<p>How to stream in 1080p to YouTube Live Events, May 2015</p>
<p>Over the past few months I&#39;ve built three versions of a camera to detect cats in my backyard, where I have placed a potted catnip plant. I don&#39;t have my own cat (allergies/landlord) so this is how I get my fix. Plus I recently got gigabit fiber at home and have this burning desire to use the bandwidth. The final version supports full HD live streaming (skip to bottom for that), but it took a few iterations to get there.</p>
<h2 id="version-one">Version one</h2>
<p>The first version was using some motion detection software called <code>motion-mmal</code>. It worked but the framerate was less than 1FPS, which isn&#39;t very good at all compared to the camera modules max resolution of 1920x1080 at 30FPS. I captured 3 cats helping themselves to my catnip, but the quality left me wanting more. I also found out there is a family of 3 opossum living in the large bush in my yard, and that there is a very, very <a href="media/fat-raccoon.png">fat raccoon</a> that frequently visits.</p>
<p><img src="http://maxogden.com/media/fatcat.png" alt="fat cat"></p>
<p>Here&#39;s an example of the framerate it captured (in lower resolution gif form). In this gif the offending cat (which I have never seen other than in this video) reaches such an emotional peak during its time with my catnip that it throws the nip off the first step, breaking the pot. If this act was intentional or not we will never know for sure. The catnip survived.</p>
<p><img src="http://maxogden.com/media/fatcat.gif" alt="fat cat gif"></p>
<p>I believe the reason for the slowness of <code>motion-mmal</code> is that it isn&#39;t designed to run on such a low CPU power device as the Raspberry Pi. Maybe this issue will be fixed in the future, but as you can see from the framerate of the above gif, it has a long way to go.</p>
<h2 id="version-two">Version two</h2>
<p>The next version happened thanks to a donation from my friend <a href="https://github.com/beaugunderson/">@beaugunderson</a>, who donated a IP Network Cam to me for the cat surveillance cause. The camera, made by Axis Network, has an ethernet port and a web interface that had a video feed. I set up a wireless -&gt; ethernet bridge using a <a href="http://www.tp-link.com/en/products/details/cat-9_TL-WR702N.html">WR702N</a> and hooked the camera up in my back yard pointing down at my catnip plant.</p>
<p><img src="http://maxogden.com/media/axis-cam.png" alt="axis cam"></p>
<p>It also boasted motion detection built in to the camera. Upon setting it up I found that it required Internet Explorer to configure the motion detection (thanks to an ActiveX-only UI), so I installed VirtualBox and configured it. It wasn&#39;t as easy to calibrate as <code>motion-mmal</code>, and I ended up getting a lot of shots of shadows on my porch.</p>
<p>Then came the problem of capturing video from it. It had a <code>.mjpeg</code> (Motion JPEG) live stream endpoint, but no storage and no way to record. I did discover a setting in the ActiveX UI that let me give it a HTTP endpoint to POST to when the motion detection was triggered. So I rigged it up to tell the server in my living room via HTTP POST when the motion detection triggered, and then that server would kick off a <code>ffmpeg</code> job that would archive the <code>.mjpeg</code> stream for 30 seconds.</p>
<p>This approach worked, but the quality wasn&#39;t acceptable:</p>
<p><img src="http://maxogden.com/media/backporch-cat.png" alt="backporch cat"></p>
<p>Worse yet, the framerate was under 10FPS. Not gonna cut it in the age of HD! Another downside of the Axis Cam is that it required an AC outlet, whereas the Raspberry Pi has the nice quality of only needing USB power.</p>
<h2 id="version-three-current-version-">Version three (current version)</h2>
<p>The main thing I learned in the first two versions is that I wanna try and avoid re-encoding video. It&#39;s slow (and especially too slow for CPU weak Raspi) and degrades quality.</p>
<p>For the latest iteration I went back to using the <a href="https://www.raspberrypi.org/products/camera-module/">Raspberry Pi Camera Module</a>. It&#39;s $25 bucks, so along with the $25 Raspberry Pi that brings the project cost to a nice even $50.</p>
<p><img src="http://maxogden.com/media/raspi-cam.png" alt="raspi cam"></p>
<p><em>Raspberry Pi + Camera in 3D printed cases and a highly engineered stabilization mechanism</em></p>
<p>The raw data that comes from <code>raspivid</code>, a CLI tool that is part of the Raspberry Pi <a href="https://github.com/raspberrypi/userland">userland</a> repository, is straight H264 encoded video data that comes from the on-board H264 encoder hardware chip built into the Raspi. This means it&#39;s fast and high quality. Re-encoding it in software is slow and crappy looking. Side note: it makes me deeply, deeply sad that our devices now come with chips that encode video data into a patented, closed video format.</p>
<p>I spent some time learning about the differences between encoding/decoding and muxing/demuxing. Muxing/demuxing is cheap (it just means wrapping the encoded video in a container format, e.g. <code>.mp4</code> or <code>.avi</code>), but encoding/decoding is difficult and slow and involves lots of math and patents.</p>
<p>Then recently I agreed to take care of some kittens for a week. And since part my job was to find them adoptive parents (can&#39;t keep cats permanently), I figured a HD live stream would help find them a home. I looked the options, and the best one was YouTube &quot;Live Events&quot;. UStream charges $99 bucks a month for HD streaming (seriously) and YouTube &quot;Live Events&quot;, a feature <a href="https://www.youtube.com/my_live_events">baked into YouTube.com</a>, offers 24 hour HD live streaming for free, with the last 4 hours of each stream available as a regular YouTube video afterwards.</p>
<p>Basically you create a new &#39;Live Event&#39; on YouTube and it gives you a <code>rtsp://</code> url you can stream audio/video to, and a public YouTube URL that anyone with a browser or YouTube app can watch live. And it&#39;s free, and supports HD. Pretty sweet!</p>
<p>Here&#39;s an <a href="https://www.youtube.com/watch?v=Xn4yNavjdR4&amp;t=4m50s">example YouTube video of some kittens</a> made using this method.</p>
<p><a href="https://www.youtube.com/watch?v=Xn4yNavjdR4&amp;t=4m50s"><img src="http://maxogden.com/media/youtube-cats.png" alt="youtube cats"></a></p>
<h2 id="how-to-set-up-the-raspberry-pi">How to set up the Raspberry Pi</h2>
<p>For this I used the Raspberry Pi B+. I don&#39;t have a Raspberry Pi 2 yet. I&#39;m using the Raspbian OS. The trickiest part is getting <code>ffmpeg</code>. You can <code>apt-get install libav-tools</code> to get libav, the ffmpeg fork, but it didn&#39;t work for me and ffmpeg did. <em>shrug</em>. To get ffmpeg compiled for the correct ARM architecture that the Raspi B+ needs the easiest way I&#39;ve found is to get it from <a href="https://github.com/fiorix/ffmpeg-arm">this docker container</a>:</p>
<pre><code>docker run -t fiorix/ffmpeg-arm cat /opt/ffmpeg/bin/ffmpeg &gt; ffmpeg
</code></pre><p>This will download the container if you don&#39;t have it already and save the <code>ffmpeg</code> binary as <code>./ffmpeg</code> in whatever folder you run this as.</p>
<p>I have also forked the repo just to add the <code>ffmpeg</code> binary to GitHub so <a href="https://github.com/maxogden/ffmpeg-arm/releases/tag/1.0.0">you can download it from here</a> if you don&#39;t want to compile it (assuming you trust I didn&#39;t actually upload a virus).</p>
<p>You will also need the <code>raspivid</code> command. If you don&#39;t have it, try using a newer Raspbian, where it is included. Make sure you follow some Raspi camera tutorials to make sure the camera works.</p>
<p>To start the stream, run this command:</p>
<pre><code>raspivid -o - -t 0 -vf -hf -fps 30 -b 6000000 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 50 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/your-custom-session-here
</code></pre><p>Let&#39;s break it down:</p>
<ul>
<li><code>-o -</code> makes it write the video data to STDOUT so it gets piped into <code>ffmpeg</code>. </li>
<li><code>-t 0</code> is how you make it record forever</li>
<li><code>-vf -hf</code> flips it horizontal and vertical so it looks correct</li>
<li><code>-fps 30</code> sets frames per second to 30</li>
<li><code>-b 6000000</code> - output bitrate limit. YouTube recommends 400-600kbps, this is 600kbps. Change this to save upload bandwidth at the expense of a lower quality video</li>
<li><code>-re</code> - tells ffmpeg to slow down the reading of the input to the native frame rate of the input (useful when live streaming)</li>
<li><code>-ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero</code> and <code>-acodec aac -ab 128k</code> and <code>-strict experimental</code> - adds a fake audio channel filled with zeroes (silence). YouTube rejects streams without an audio channel. You can also change the input device to a microphone if you want (I haven&#39;t done this yet)</li>
<li><code>-g 50</code> adds a keyframe every 50 frames. Feel free to tweak, its one of those tradeoff variables.</li>
<li><code>-f h264</code> and <code>-f flv</code> tells ffmpeg it&#39;s receiving h264 input and that you should mux it into <code>flv</code> output (<code>flv</code> is the container format that works with YouTube. Others might work but I haven&#39;t tried them)</li>
<li>by <em>not</em> specifying <code>-w</code> and <code>-h</code> to raspivid we get the full 1920x1080 resolution (aka 1080p). You can specify these if you want a lower resolution</li>
</ul>
<p>If your stream is working you should see something like this:</p>
<p><img src="http://maxogden.com/media/ffmpeg-output.png" alt="ffmpeg-output"></p>
<p>The bitrate in the bottom rate should match what you set on YouTube. Also important is the <code>Stream 1 (copy)</code>. The <code>copy</code> means it isn&#39;t re-encoding the input video into the output -- it is copying it. This is what makes it fast and high quality.</p>
<h2 id="future-plans">Future plans</h2>
<p>I&#39;m gonna try these things out:</p>
<ul>
<li>Set up a 24 hour live YouTube channel of my catnip</li>
<li>Run the motion detection out-of-band to try and capture specific events separately out of the live stream</li>
<li>Try and get my friends who are smarter at video stuff than I am to write better cat detection algorithms</li>
<li>Get other cat weirdos on the internet to set up their own catnip cams (looking at you, person who read the whole blog post)</li>
<li>Try out a device using an Ambarella video capture chip. The Raspberry Pi Camera uses a OV5647 video capture chip and supports HD live streaming over the network thx to the Pi, but maybe the e.g. GoPro/Xiaomi Yi/SJCam (which are tiny ARM linux boxes too) can be hacked to do this with less overhead</li>
</ul>
<p>If you found this post useful, or made something cool with the tips here, send me a tweet at <a href="https://twitter.com/maxogden">@maxogden</a> on twitter.</p>
<p>Happy streaming!</p>
]]></description><link>http://maxogden.com/hd-live-streaming-cats.html</link><guid isPermaLink="true">http://maxogden.com/hd-live-streaming-cats.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Tue, 26 May 2015 06:32:56 GMT</pubDate></item><item><title><![CDATA[Interdisciplinary Open Source Community Conferences]]></title><description><![CDATA[<div id="header"><h1 class="title">Interdisciplinary Open Source Community Conferences</h1></div>

<p>A bunch of events that are community organized and not specific to one language/framework silo.</p>
<p>I&#39;m a huge fan of interdisciplinary learning. As someone who attends a lot of conferences related to open source or more general knowledge sharing, I have found that I enjoy events more if they span multiple topic areas. I&#39;ve spent some time curating this list and can wholeheartedly recommend spending your dollars to attend these events.</p>
<p>If you have a suggestion for an event that should be on this list, leave a comment on <a href="https://gist.github.com/maxogden/322a649ff84fe1c2a680">this gist</a>.</p>
<h3 id="criteria">Criteria</h3>
<ul>
<li>Must be an event that someone involved in open source would be interested in attending</li>
<li>Must be a community oriented event (no corporate owned for-profit events are listed here)</li>
<li>Can&#39;t be about a specific language/framework.</li>
</ul>
<h4 id="codeneuro">CodeNeuro</h4>
<ul>
<li>SF, NYC</li>
<li><a href="http://codeneuro.org/">http://codeneuro.org/</a></li>
<li>&quot;Bringing neuroscience and data science together&quot;</li>
</ul>
<h4 id="open-source-bridge">Open Source Bridge</h4>
<ul>
<li>Portland, OR</li>
<li><a href="http://opensourcebridge.org/">http://opensourcebridge.org/</a></li>
<li>&quot;The Conference For Open Source Citizens&quot;</li>
</ul>
<h4 id="open-source-open-society">Open Source Open Society</h4>
<ul>
<li>Wellington, NZ</li>
<li><a href="http://www.opensourceopensociety.com/">http://www.opensourceopensociety.com/</a></li>
<li>&quot;OS//OS is a two-day gathering of bright minds and communities from open technology, open government, open business and open education&quot;</li>
</ul>
<h4 id="chaos-communication-congress">Chaos Communication Congress</h4>
<ul>
<li>Hamburg, Germany</li>
<li><a href="http://www.ccc.de/en/">http://www.ccc.de/en/</a></li>
<li>&quot;The Chaos Computer Club e. V. (CCC) is Europe&#39;s Largest association of hackers.&quot;</li>
</ul>
<h4 id="csv-conf">CSV Conf</h4>
<ul>
<li>Berlin, Germany (next one not scheduled yet)</li>
<li><a href="http://maxogden.github.io/csvconf.com/">http://maxogden.github.io/csvconf.com/</a></li>
<li>&quot;A conference for data makers&quot;</li>
</ul>
<h4 id="data-terra-nemo">Data Terra Nemo</h4>
<ul>
<li>Berlin, Germany</li>
<li><a href="http://dtn.is">http://dtn.is</a></li>
<li>&quot;Terra nemo is a Latin expression meaning &quot;No man&#39;s land&quot;. In this context we describe systems and protocols without centralized ownership and how they impact the landscape of the internet.&quot;</li>
</ul>
<h4 id="src-con">SRC Con</h4>
<ul>
<li>Minneapolis, MN</li>
<li><a href="http://srccon.org/">http://srccon.org/</a></li>
<li>&quot;Two days of building better newsroom code, culture, and processâ€”together.&quot;</li>
</ul>
<h4 id="openvisconf">OpenVisConf</h4>
<ul>
<li>Boston, MA</li>
<li><a href="http://openvisconf.com">http://openvisconf.com</a></li>
<li>&quot;OpenVis Conf is a two-day, single track conference about the practice of visualizing data on the web. &quot;</li>
</ul>
<h4 id="polyglot-unconference">Polyglot Unconference</h4>
<ul>
<li>Vancouver, CA</li>
<li><a href="http://www.polyglotconf.com/">http://www.polyglotconf.com/</a></li>
<li>&quot;Polyglot is a &quot;non-denominational&quot; software development un-conference event that encourages software developers and operators from different stacks, backgrounds and with different opinions to come together for one day of spontaneous sharing, teaching and learning.&quot;</li>
</ul>
<h4 id="nonprofit-software-development-summit">Nonprofit Software Development Summit</h4>
<ul>
<li>Oakland, CA</li>
<li><a href="https://aspirationtech.org/events/devsummit15">https://aspirationtech.org/events/devsummit15</a></li>
<li>&quot;interactive festival of people who are passionate about co-developing technology to support the work of nonprofit and community organizations.&quot;</li>
</ul>
<h4 id="mozilla-festival">Mozilla Festival</h4>
<ul>
<li>London, UK</li>
<li><a href="http://mozillafestival.org">http://mozillafestival.org</a></li>
<li>&quot;MozFest is a yearly festival with hundreds of passionate people exploring the Web, learning together, and making things that can change the world. It&#39;s very hands-on and immersive. Sometimes it will feel chaotic, but everyone is open-minded and eager to help you make and learn with them.&quot;</li>
</ul>
<h4 id="foss4g">foss4g</h4>
<ul>
<li>All Over! Next is Seoul, Korea</li>
<li><a href="http://foss4g.org">http://foss4g.org</a></li>
<li>&quot;FOSS4G is the acronym for Free and Open Source Software for Geospatial. It is the annual recurring global event hosted by OSGeo since itâ€™s inception in 2006.&quot;</li>
</ul>
<h4 id="open-knowledge-festival">Open Knowledge Festival</h4>
<ul>
<li>Berlin, Germany (next one TBA)</li>
<li><a href="http://okfestival.org">http://okfestival.org</a></li>
<li>&quot;Organised by Open Knowledge and owned, in the broadest sense, by the open community, the Festival will bring together over 1,000 people from more than 60 countries to share their skills and experiences; encouraging them to work together to build the very tools and partnerships that will further the power of openness as a positive force for change.&quot;</li>
</ul>
<h4 id="hope-hackers-on-planet-earth">HOPE - Hackers on Planet Earth</h4>
<ul>
<li>New York City</li>
<li><a href="http://www.hope.net/">http://www.hope.net/</a></li>
<li>&quot;the most European of the American hacker conferences. defcon for cipher hippies. put on by 2600 magazine&quot;</li>
</ul>
<h4 id="fosdem">FOSDEM</h4>
<ul>
<li>Brussels, Belgium</li>
<li><a href="https://fosdem.org">https://fosdem.org</a></li>
<li>&quot;FOSDEM is a free event for software developers to meet, share ideas and collaborate.&quot;</li>
</ul>
<h4 id="fscons">FSCONS</h4>
<ul>
<li>Gothenburg, Sweden</li>
<li><a href="https://fscons.org">https://fscons.org</a></li>
<li>&quot;FSCONS exists to provide a meeting place where subjects covering society, culture and technology can be discussed and brought to life in peer discussions, without being confined to each particular subject area. It should provide both the physical and virtual space where people, organisations and governments, with interest in the three subject areas can meet in a participatory and constructive dialogue. The unique combination of topics creates a platform where cross-pollination between the areas can occur, and where new co-operations and thoughts can emerge which allows the participants to find new inspiration even from areas outside of their own.&quot;</li>
</ul>
<h4 id="libre-graphics-meeting">Libre Graphics Meeting</h4>
<ul>
<li>location alternates between Europe and Northern America (next one Toronto, Canada)</li>
<li><a href="http://libregraphicsmeeting.org">http://libregraphicsmeeting.org</a></li>
<li>&quot;The Libre Graphics Meeting (LGM) is an annual meeting on free and open source software for graphics. Held yearly since 2006 the Libre Graphics Meeting aims to attract developers, artists and professionals who use and improve free and open source software graphics applications. The LGM aims to bring these people together in the cause of creating high quality free graphics applications.&quot;</li>
</ul>
<h4 id="border-none">border:none</h4>
<ul>
<li>Nuremberg, Germany (next one TBA)</li>
<li><a href="https://border-none.net">https://border-none.net</a></li>
<li>&quot;A novel 2-day concept conference about the decentralization of the web, featuring inspiring talks and creative sessions, spreading over several outstanding venues in medieval Nuremberg.&quot;</li>
</ul>
<h4 id="decentralize-camp">Decentralize Camp</h4>
<ul>
<li>Dusseldorf, Germany (next one TBA)</li>
<li><a href="http://decentralizecamp.com">http://decentralizecamp.com</a></li>
<li>&quot;The web is more and more converting to a monoculture. Big global players like Google, Facebook and Co. control every part of our digital life and build an alternative web of walled gardens. It&#39;s in our hands to move the web in a new direction and keep it open and decentralized and it&#39;s our responsibility to get started now. This camp is about defining the status quo, about exchanging ideas, making plans and moving forward.&quot;</li>
</ul>
<h4 id="wutheringbytes">WutheringBytes</h4>
<ul>
<li>Hebden Bridge, UK</li>
<li><a href="http://wutheringbytes.com/">http://wutheringbytes.com/</a></li>
<li>&quot;A weekend festival of technology&quot;. &quot;Was an amazing conference last year with talks from Sophie Wilson co-designed the ARM processor , Live rocket launching and a profound talk from Sarah Angliss on the origins of techno&quot;</li>
</ul>
<h4 id="squatconf">Squatconf</h4>
<ul>
<li>In squats. Last one was in Paris.</li>
<li><a href="http://squatconf.eu/">http://squatconf.eu/</a></li>
<li>&quot;Squatconfs are tech conference that happen... in squats, hence the name. It started because some of us are lucky enough to attend marvelous conventions, made with love by amazing people. Great events with top-notch speakers, incredible venues, and amazing parties. These conferences are run with huge contributions from volunteers, and financial support from sponsors, providing top-notch events at affordable prices. But even then, they&#39;re not affordable for everyone.&quot;</li>
</ul>
<h4 id="notacon">Notacon</h4>
<ul>
<li>Cleveland, Ohio</li>
<li><a href="http://notacon.org">http://notacon.org</a></li>
<li>&quot;security, arts, culture. killer demoparty&quot;</li>
</ul>
<h4 id="theorizing-the-web">Theorizing The Web</h4>
<ul>
<li>New York City</li>
<li><a href="http://theorizingtheweb.tumblr.com/">http://theorizingtheweb.tumblr.com/</a></li>
<li>&quot;Theorizing the Web is an inter- and non-disciplinary annual conference that brings together scholars, journalists, artists, activists, and commentators to ask conceptual questions about the interrelationships between the web and society. We deeply value public engagement, and consider insights from academics, non-academics, and non-â€œtech theoristsâ€ alike to be equally valuable.&quot;</li>
</ul>
<h4 id="polyconf">PolyConf</h4>
<ul>
<li><a href="http://polyconf.com/">http://polyconf.com/</a></li>
<li>PoznaÅ„, Poland</li>
<li>&quot;a three-day, single track, multi-disciplinary conference on advanced technologies
for programmers interested in polyglot approach to software development.&quot;</li>
</ul>
<h4 id="indie-web-camp">Indie Web Camp</h4>
<ul>
<li>USA: Portland, SF, NYC, Cambridge</li>
<li>Europe: Brighton UK, Berlin &amp; Dusseldorf DE</li>
<li><a href="http://indiewebcamp.com">http://indiewebcamp.com</a></li>
<li>The IndieWeb is a people-focused alternative to the &quot;corporate web&quot;</li>
</ul>
<h4 id="open-help">Open Help</h4>
<ul>
<li>Cincinnati, OH, USA</li>
<li><a href="http://conf.openhelp.cc/">http://conf.openhelp.cc/</a></li>
<li>Documentation and support in open source and open communities</li>
</ul>
<h4 id="write-the-docs">Write The Docs</h4>
<ul>
<li>North America, Europe</li>
<li><a href="http://conf.writethedocs.org">http://conf.writethedocs.org</a></li>
<li>&quot;a series of conferences and local meetups focused on documentation systems, tech writing theory, and information delivery.&quot;</li>
</ul>
]]></description><link>http://maxogden.com/interdisciplinary-open-source-events.html</link><guid isPermaLink="true">http://maxogden.com/interdisciplinary-open-source-events.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sun, 10 May 2015 06:32:56 GMT</pubDate></item><item><title><![CDATA[Setting up HTTPS with a wildcard certificate and Nginx]]></title><description><![CDATA[<div id="header"><h1 class="title">Setting up HTTPS with a wildcard certificate and Nginx</h1></div>

<p>How I set up HTTPS with Nginx, April 2015</p>
<p>I finally got a wildcard certificate for my new domain <code>publicbits.org</code>. This means I can use one cert for e.g. <code>https://foo.publicbits.org</code> or <code>https://bar.publicbits.org</code> but also <code>https://publicbits.org</code> or <code>https://www.publicbits.org</code>.</p>
<p>At the recommendation of my friend <a href="https://konklone.com/">Eric Mill</a> I decided to try out <a href="https://sslmate.com/">SSLMate</a>. Wildcard certs aren&#39;t cheap. From SSLMate it costs $149 USD. However, it was super easy compared to every other SSL purchasing experience I&#39;ve ever dealt with.</p>
<p>It should take about 20 minutes to do all the things in this blog post.</p>
<p>I have high hopes for <a href="https://letsencrypt.org">Let&#39;s Encrypt</a>, which will essentially make this process cost $0 instead of $149, but until then this is the easiest way to do it that I&#39;ve seen.</p>
<p>Note: my domain <code>maxogden.com</code> is hosted on GitHub Pages and they don&#39;t yet support HTTPS with custom domains. Email GitHub support and request this feature if it is important to you!</p>
<h2 id="installing-sslmate-and-buying-the-cert">Installing SSLMate and buying the cert</h2>
<p>First I <a href="https://sslmate.com/signup">signed up at SSLMate</a>. I picked a username and password and entered my payment info.</p>
<p>Then they have you install their <code>sslmate</code> CLI utility.</p>
<pre><code class="lang-sh">sudo wget -P /etc/apt/sources.list.d https://sslmate.com/apt/ubuntu1404/sslmate.list
sudo wget -P /etc/apt/trusted.gpg.d https://sslmate.com/apt/ubuntu1404/sslmate.gpg
sudo apt-get update
sudo apt-get install sslmate
</code></pre>
<p>Then you can buy a wildcard cert from the CLI:</p>
<pre><code class="lang-sh">sslmate buy *.publicbits.org
</code></pre>
<p>Then they ask you some questions, verify the order, purchase the cert and then send you an email. The email has instructions for verifying your ownership of the domain on a Comodo site. Turns out SSLMate is basically a user friendly front end to Comodo&#39;s positiveSSL service. I really appreciate how easy they make the process, and hope more SSL providers will follow suit!</p>
<p>Then I did <code>mkdir keys</code> and <code>cd keys</code>. I was now in <code>/home/max/keys</code>.</p>
<p>Next was <code>sslmate download --all</code>. Now a bunch of files appeared in my <code>keys</code> folder.</p>
<p>The ones I&#39;m using are <code>*.publicbits.org.key</code> and <code>*.publicbits.org.chained.crt</code>.</p>
<h2 id="installing-and-configuring-nginx">Installing and configuring Nginx</h2>
<p>Then I installed the latest Nginx. I have a utility I wrote last year called <a href="https://github.com/maxogden/install-nginx-on-ubuntu">install-nginx-on-ubuntu</a> that I used. It basically does this:</p>
<pre><code class="lang-sh">sudo apt-get install -y software-properties-common
sudo add-apt-repository -y ppa:nginx/stable
sudo apt-get update
sudo apt-get install -y nginx
sudo initctl start nginx
</code></pre>
<p>Then after lots of twiddling around with configs I ended up creating this &#39;default&#39; config and wrote it to <code>/etc/nginx/conf.d/ssl.conf</code>. It redirects all <code>http://</code> traffic to <code>https://</code>.</p>
<pre><code># redirect http -&gt; https
server {
  listen 80;
  server_name *.publicbits.org;
  return 301 https://$host$request_uri;
}  

# default config (server_name _; makes this &#39;base&#39; config)
server {
  listen 443 default ssl;
  server_name _;

  ssl_certificate_key /home/max/keys/*.publicbits.org.key;
  ssl_certificate /home/max/keys/*.publicbits.org.chained.crt;

  # These this next block of settings came directly from the SSLMate recommend nginx configuration
  # Recommended security settings from https://wiki.mozilla.org/Security/Server_Side_TLS
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_ciphers &#39;ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA&#39;;
  ssl_prefer_server_ciphers on;
  ssl_session_timeout 5m;
  ssl_session_cache shared:SSL:5m;
  # Enable this if you want HSTS (recommended)
  add_header Strict-Transport-Security max-age=15768000;

  # from https://gist.github.com/konklone/6532544
  # Generated by OpenSSL with the following command:
  #   openssl dhparam -outform pem -out dhparam2048.pem 2048
  ssl_dhparam /home/max/keys/dhparam2048.pem;
}
</code></pre><p>Make sure you run <code>openssl dhparam -outform pem -out dhparam2048.pem 2048</code> inside your <code>keys</code> folder (it will take a while).</p>
<h2 id="deploying-processes">Deploying processes</h2>
<p>Then I use <a href="https://www.npmjs.com/package/taco-nginx">taco-nginx</a> to deploy individual processes:</p>
<pre><code>taco-nginx --name signalhub signalhub listen -m 10
</code></pre><p><code>taco-nginx</code> takes care of generating a configuration for my app and then reloading nginx. For the above command the configuration file it generated is <code>/etc/nginx/conf.d/signalhub.conf</code> with the contents:</p>
<pre><code># generated by taco-nginx
upstream signalhub {
  server 127.0.0.1:54082;
}

server {
  listen 443;
  server_name signalhub.*;
  location / {
    proxy_pass http://signalhub;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_buffering off;
    proxy_request_buffering off;
    proxy_http_version 1.1;
  }
}
</code></pre><p>With this configuration I can deploy new apps with <code>taco-nginx</code> quickly without having to configure them for HTTPS, since Nginx can reverse proxy HTTPS -&gt; HTTP. </p>
<p>My <a href="https://www.ssllabs.com/ssltest/analyze.html?d=signalhub.publicbits.org">score on SSLLabs</a> is an A:</p>
<p><img src="http://maxogden.com/media/ssllabs.png" alt="ssl labs"></p>
<p>Thanks a ton to <a href="https://konklone.com">Eric Mill</a> for helping tweak my HTTPS settings and <a href="https://github.com/mafintosh">Mathias Buus</a> for helping with Nginx.</p>
]]></description><link>http://maxogden.com/https-wildcard-nginx-setup.html</link><guid isPermaLink="true">http://maxogden.com/https-wildcard-nginx-setup.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Thu, 30 Apr 2015 06:32:56 GMT</pubDate></item><item><title><![CDATA[A Month of Modules]]></title><description><![CDATA[<div id="header"><h1 class="title">A Month of Modules</h1></div>

<p>Modules mafintosh and I wrote this month</p>
<p>I work on a distributed team with two other developers. The three of us are in three different cities. This month <a href="http://github.com/mafintosh/">mafintosh</a> came out and stayed in my guest room for the month. I wanted to take the time to document what we wrote during his trip to give a little insight into what is it like to work in an &quot;open source first&quot; way.</p>
<p>Most of these were written for use cases involving our day job, <a href="http://dat-data.com/">dat</a>. Some, such as the Playback video player, were written for fun.</p>
<h3 id="airpaste"><a href="https://npmjs.org/airpaste">airpaste</a></h3>
<p>Run <code>airpaste</code> on two computers that are on the same network and airpaste opens a two way binary pipe. Uses mdns (aka Bonjour) to connect peers.</p>
<h3 id="axis-camera"><a href="https://npmjs.org/axis-camera">axis-camera</a></h3>
<p>A module to control a webcam in my backyard from node. The webcam points at <a href="https://twitter.com/maxogden/status/587743809947086849">some catnip in my yard</a> and motion detects cats.</p>
<h3 id="ble-stream"><a href="https://npmjs.org/ble-stream">ble-stream</a></h3>
<p>Implements a duplex stream interface on top of Bluetooth Low Energy</p>
<h3 id="ble-swarm"><a href="https://npmjs.org/ble-swarm">ble-swarm</a></h3>
<p>Implements a swarm API (mesh networking) using ble-stream</p>
<h3 id="blecat"><a href="https://npmjs.org/blecat">blecat</a></h3>
<p>Works like <code>airpaste</code> except uses bluetooth</p>
<h3 id="electron-packager"><a href="https://npmjs.org/electron-packager">electron-packager</a></h3>
<p>Creates a mac <code>.app</code> from your Electron source code</p>
<h3 id="electron-prebuilt"><a href="https://npmjs.org/electron-prebuilt">electron-prebuilt</a></h3>
<p>Lets you do <code>npm install electron-prebuilt -g</code> to get <code>electron</code> in your PATH.</p>
<h3 id="electron-spawn"><a href="https://npmjs.org/electron-spawn">electron-spawn</a></h3>
<p>Run <code>electron-spawn foo.js</code> to run <code>foo.js</code> inside a headless Electron window</p>
<h3 id="idlecast"><a href="https://npmjs.org/idlecast">idlecast</a></h3>
<p>Play videos on your chromecast when nothing else is playing. I use it to play the captured cat videos from the catnip cam.</p>
<h3 id="mon-prebuilt"><a href="https://npmjs.org/mon-prebuilt">mon-prebuilt</a></h3>
<p>Lets you <code>npm install mon-prebuilt -g</code> to get the <code>mon</code> C process monitor in your PATH</p>
<h3 id="multicast-dns-service-types"><a href="https://npmjs.org/multicast-dns-service-types">multicast-dns-service-types</a></h3>
<p>A low level module for parsing MDNS data. Factored out, like many of these, because Unix philosophy!</p>
<h3 id="multileveldown"><a href="https://npmjs.org/multileveldown">multileveldown</a></h3>
<p>Lets us access a single LevelDB from multiple processes in a failsafe way</p>
<h3 id="pbs"><a href="https://npmjs.org/pbs">pbs</a></h3>
<p>Protocol Buffer Streaming. A standard way to serialize protobuf data. We use protobufs for almost all data interchange now. We are getting friends to implement pbs in Golang and C++.</p>
<h3 id="pick-random-stream"><a href="https://npmjs.org/pick-random-stream">pick-random-stream</a></h3>
<p>Tiny utility stream that lets you pick a random item from a stream.</p>
<h3 id="playback"><a href="https://github.com/mafintosh/playback">playback</a></h3>
<p>Desktop video player written in JS that supports torrent streaming, chromecast and youtube.</p>
<h3 id="playback-chrome"><a href="https://github.com/maxogden/playback-chrome">playback-chrome</a></h3>
<p>Chrome extension to that adds a &#39;open in Playback&#39; button to YouTube videos.</p>
<h3 id="random-iterate"><a href="https://npmjs.org/random-iterate">random-iterate</a></h3>
<p>Tiny array module that can iterate an array in random order</p>
<h3 id="require-times"><a href="https://npmjs.org/require-times">require-times</a></h3>
<p>Tells you how long <code>require()</code> calls take in your program</p>
<h3 id="signalhub"><a href="https://npmjs.org/signalhub">signalhub</a></h3>
<p>A stateless pub/sub server with &#39;channels&#39; that we use to introduce peers in p2p apps like <a href="https://moose-team.github.io/friends">Friends</a>.</p>
<h3 id="sorted-diff-stream"><a href="https://npmjs.org/sorted-diff-stream">sorted-diff-stream</a></h3>
<p>Used by dat to compute diffs between two branches, used when merging forked data</p>
<h3 id="sorted-union-stream"><a href="https://npmjs.org/sorted-union-stream">sorted-union-stream</a></h3>
<p>Join two sorted streams based on a key</p>
<h3 id="stream-iterate"><a href="https://npmjs.org/stream-iterate">stream-iterate</a></h3>
<p>A simple stream module to go through items in stream one at a time. We factored this out of our <code>sorted-*-stream</code> modules above.</p>
<h3 id="subcommand"><a href="https://npmjs.org/subcommand">subcommand</a></h3>
<p>CLI routing tool that we use in dat to route subcommands like <code>dat cat</code> or <code>dat add</code>.</p>
<h3 id="taco"><a href="https://npmjs.org/taco">taco</a></h3>
<p>We rewrote our deploy tools, and produced a series of small modules that can compose together into deploy pipelines. We&#39;re calling the system <code>taco</code></p>
<h3 id="taco-build"><a href="https://npmjs.org/taco-build">taco-build</a></h3>
<p>Runs a command inside a taco tarball (e.g. <code>npm install --production</code>)</p>
<h3 id="taco-git-push-deploy"><a href="https://npmjs.org/taco-git-push-deploy">taco-git-push-deploy</a></h3>
<p>Lets you <code>git push</code> deploy with taco</p>
<h3 id="taco-mon"><a href="https://npmjs.org/taco-mon">taco-mon</a></h3>
<p>Deploys apps using the <code>mon</code> C process monitor</p>
<h3 id="taco-nginx"><a href="https://npmjs.org/taco-nginx">taco-nginx</a></h3>
<p>Auto configures Nginx to route traffic to your process</p>
<h3 id="taco-pack"><a href="https://npmjs.org/taco-pack">taco-pack</a></h3>
<p>Creates a tarball from your app source code</p>
<h3 id="tape-spawn"><a href="https://npmjs.org/tape-spawn">tape-spawn</a></h3>
<p>Testing module to make testing spawned processes easier</p>
<h3 id="transport-stream"><a href="https://npmjs.org/transport-stream">transport-stream</a></h3>
<p>Abstract module to support different transports (used in dat), e.g. <code>tcp://</code>, <code>ssh://</code>, <code>https://</code></p>
<h3 id="utp-native"><a href="https://npmjs.org/utp-native">utp-native</a></h3>
<p>An experimental C implementation of the utp (micro-tp) protocol from Bittorrent.</p>
<h3 id="webcat"><a href="https://npmjs.org/webcat">webcat</a></h3>
<p>Like airpaste or blecat but over webrtc. Uses github usernames for auth/discovery. Opens a duplex stream to someone over webrtc.</p>
<h3 id="webrtc-swarm"><a href="https://npmjs.org/webrtc-swarm">webrtc-swarm</a></h3>
<p>A connection swarm API for webrtc. Manages a pool of webrtc connections. Used in Friends.</p>
]]></description><link>http://maxogden.com/a-month-of-modules.html</link><guid isPermaLink="true">http://maxogden.com/a-month-of-modules.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Thu, 30 Apr 2015 03:32:56 GMT</pubDate></item><item><title><![CDATA[Tessel Powered Plant Watering System]]></title><description><![CDATA[<div id="header"><h1 class="title">Tessel Powered Plant Watering System</h1></div>

<p>Make a water pump that can be turned on and off over HTTP using only JavaScript.</p>
<p><strong>Warning</strong> Do not try this at home without the help of an electronics expert. Solid state relays switch high voltage and can cause bodily harm if used improperly.</p>
<p>I have been looking for a way to do hobby electronics projects using JavaScript running on microcontrollers. You can control an Arduino remotely from a laptop over USB with libraries like <a href="https://www.npmjs.com/package/johnny-five">johnny-five</a>, but you can&#39;t keep your code running after you close your laptop since the Arduino can&#39;t run JavaScript.</p>
<p>The <a href="https://tessel.io/">Tessel</a> is a microcontroller that runs Node code <strong>on the board</strong>. The team at Tessel wrote a <a href="https://github.com/tessel/colony-compiler">JS to Lua compiler</a> and then they run Lua directly on the Tessel hardware. It&#39;s not the fastest thing in the world, but it opens up most of npm to run on a wi-fi enabled, USB powered microcontroller the size of an Arduino.</p>
<p>For this project I used four components. It takes about an hour to put together:</p>
<ul>
<li><a href="https://shop.tessel.io/">Tessel Microcontroller</a></li>
<li><a href="http://www.amazon.com/DC-AC-Solid-State-Relay-Heatsink/dp/B005K2IXHU/ref=sr_1_4?ie=UTF8&qid=1424888528&sr=8-4&keywords=Lightobject">Fotek SSR-25DA Solid State Relay</a></li>
<li><a href="http://www.amazon.com/AquaTop-NP-80-Aquatop-Aquarium-Submersible/dp/B00798FYR0">AquaTop NP-80 Submersible Pump</a></li>
<li><a href="http://www.amazon.com/Lutron-TT-300NLH-WH-Credenza-Dimmer-White/dp/B0000DI241/ref=sr_1_1?ie=UTF8&qid=1424888624&sr=8-1&keywords=dimmer+light">Lutron TT-300NLH-WH Lamp Dimmer</a></li>
</ul>
<p>I would also recommend using a junction box/electronics enclosure for housing the SSR along the lines of <a href="http://www.amazon.com/Estone%C2%AE-85x58x33mm-Waterproof-Electronic-Enclosure/dp/B00M1HL2UM/ref=sr_1_2?s=hi&amp;ie=UTF8&amp;qid=1424891818&amp;sr=1-2&amp;keywords=estone+box#productDetails">this one</a>.</p>
<p>The key is the solid state relay. For background on how these works check out <a href="http://www.scienceprog.com/considering-solid-state-relays-ssr-for-your-projects/">this excellent article</a>, but the short version is that they let you use a small voltage (3.3V or 5V such as those available in &quot;digital out&quot; pins in microcontrollers) to turn on and off high voltage circuits such as 110V or 220V (wall outlets).</p>
<p>Instead of using an SSR directly as I did you could also purchase a <a href="http://www.powerswitchtail.com/Pages/default.aspx">PowerSwitch Tail</a>, which is a pre-made, safely housed relay enclosure that comes to you already built.</p>
<p><a href="media/tessel-components-large.png"><img src="http://maxogden.com/media/tessel-components.png" alt="components"></a></p>
<p>To build the &#39;circuit&#39;, I simply cut the dimmer slider portion off of the Lamp Dimmer, stripped the ends off of the wires, and connected them to the SSR instead. Where there used to be a dimmer slider the circuit there is now the SSR.</p>
<p>The flow of electricity is roughly: Wall -&gt; Dimmer -&gt; SSR -&gt; Pump. The tessel is connected to the SSR and can turn it on and off at will.</p>
<p><strong>Again, I can&#39;t stress enough that you should really not try this on your own unless you have someone who is experienced with Solid State Relays and 110V/220V electricity.</strong></p>
<p>Here&#39;s a <a href="http://youtu.be/sgU3McOF-l8">video of the system in action</a>:</p>
<iframe width="640" height="360" src="https://www.youtube.com/embed/sgU3McOF-l8?rel=0" frameborder="0" allowfullscreen=""></iframe>

<p>The tessel is running a small HTTP server written in Node that turns the G3 GPIO pin on or off. When it is on it outputs 3.3V to the SSR, which tells the SSR to turn on voltage, which turns on the pump.</p>
<pre><code class="lang-js">var tessel = require(&#39;tessel&#39;)
var http = require(&#39;http&#39;)

var pin = tessel.port[&#39;GPIO&#39;].pin[&#39;G3&#39;]

var server = http.createServer(function (req, res) {
  console.log(req.url)
  if (req.url === &#39;/on&#39;) return on(req, res)
  if (req.url === &#39;/off&#39;) return off(req, res)
  return res.end(&#39;&lt;a href=&quot;/on&quot;&gt;/on&lt;/a&gt; or &lt;a href=&quot;/off&quot;&gt;/off&lt;/a&gt;\n&#39;)
})

server.listen(80, function(err) {
  if (err) console.log(&#39;error!&#39; + err)
  console.log(&#39;http listening&#39;)
})

function on (req, res) {
  console.log(&#39;turning on&#39;)
  pin.write(1)
  res.end(&#39;turned on\n&#39;)
}

function off (req, res) {
  console.log(&#39;turning off&#39;)
  pin.write(0)
  res.end(&#39;turned off\n&#39;)
}
</code></pre>
<p>Save the above code as a file called <code>server.js</code>, plug your Tessel over USB, and run <code>tessel push server.js</code> to upload the server onto your Tessel. You can run <code>tessel logs</code> to view the HTTP server logs while your tessel is connected over USB.</p>
<p>Once you have the Tessel configured to join your home Wi-Fi (using the <code>tessel wifi</code> CLI command) it will then always automatically connect a few seconds after powering up, every time. You can put it anywhere in your house, power it over USB, and it will start up it&#39;s HTTP server and be accessible over your local network.</p>
<p>You could definitely use other microcontrollers instead of the Tessel for this. I like the Tessel, however, because it is the simplest way to run Node code on hardware, and they also make add-on hardware modules that are easy to use. For example, you could use the Raspberry Pi for this project, but it would be more complicated as you would have to configure Linux. I just prefer to keep things easy!</p>
<p>Happy hacking! Questions? Open an issue <a href="https://github.com/maxogden/blog/issues">in this repository</a></p>
]]></description><link>http://maxogden.com/tessel-powered-plant-watering-system.html</link><guid isPermaLink="true">http://maxogden.com/tessel-powered-plant-watering-system.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Wed, 25 Feb 2015 03:32:56 GMT</pubDate></item><item><title><![CDATA[Portland Fiber Internet]]></title><description><![CDATA[<div id="header"><h1 class="title">Gigabit Fiber in Portland</h1></div>

<p>Review of 1Gb fiber from CenturyLink</p>
<p>Yesterday I got Gigabit fiber Internet installed at home in Portland, OR from <a href="https://www.centurylink.com/fiber/">CenturyLink</a>. If you haven&#39;t checked out how fiber works here&#39;s a good <a href="https://www.youtube.com/watch?v=Rz1gv2JkmXQ">intro video</a>. The variety that CenturyLink offers is a <a href="http://en.wikipedia.org/wiki/Passive_optical_network">passive optical network</a> consisting of fiber optic cables strung up on telephone poles around town.</p>
<p><img src="http://maxogden.com/media/centurylink-technicians.png" alt="fiber techs"></p>
<p>Here&#39;s the result of a speedtest I did today:</p>
<p><img src="http://maxogden.com/media/speedtest.png" alt="speedtest"></p>
<p>Gigabit fiber probably isn&#39;t practical for most Internet users today because it&#39;s more bandwidth than most Internet applications know what to do with. However, in a few years time, as more people get retina screens, 4K TVs, 8TB hard drives and neighbors with fiber Internet who stream super-HD video then there will hopefully be a tipping point. And the fiber infrastructure is relatively future-proof.</p>
<p>My day job is to work on data replication tools for really large scientific datasets so I jumped at the opportunity to get it at home.</p>
<h2 id="centurylink-vs-google-fiber">CenturyLink vs Google Fiber</h2>
<p>CenturyLink costs $109 a month (for the first year) and Google Fiber is $70 a month. Both offer 1000mbps up/1000mpbs down (133MB/s) with no download/upload limits or caps. CenturyLink&#39;s <a href="http://www.centurylink.com/Pages/AboutUs/Legal/InternetServiceManagement/">ToS states</a> &quot;Residential 1 Gbps plans are not subject to download limits&quot; and this has been <a href="http://www.reddit.com/r/Seattle/comments/2cooqy/centurylink_plans_to_bring_gigabit_internet_to/cji4gul">verified by the Seattle Mayor&#39;s office</a>. <a href="https://fiber.google.com/legal/network.html">Google Fiber&#39;s ToS</a> also states they do &quot;not employ volume-based data caps&quot;.</p>
<p>CenturyLink seems to be quite secretive when it comes to disclosing the price after the first 12 months. From looking at my first bill it seems their &#39;standard rate&#39; for gigabit appears to be $153.95, and they give a $44.00 per month discount for the first 12 months of service. This information isn&#39;t advertised publicly on their website (from what I can tell).</p>
<p>The only major difference (beyond price) that I can find is that Google Fiber specifically prohibits commercial servers, but CenturyLink does not seem to.</p>
<p>CenturyLink&#39;s FTTH (Fiber To The Home) service seems to currently be in most of inner SE Portland (where I live).</p>
<p>Google Fiber isn&#39;t in Portland yet, and might never be. If I had the choice between Google Fiber and CenturyLink on my block, I would pick Google because of the price. That being said I am still incredibly excited to get gigabit internet direct to my home for less than some of my friends pay for their cell phone.</p>
<p>There&#39;s another local ISP doing Gigabit fiber in Portland called <a href="http://www.fibersphere.com/">Fibersphere</a> but they only offer it in selected apartment buildings and are still working on their broader rollout strategy.</p>
<h2 id="installation">Installation</h2>
<p>You pay a (roughly) $100 setup fee and then another $100 for an <a href="http://www.actiontec.com/301.html">Actiontec C2000A modem/router</a>. They send a technician (or in my case two) out to your house for the 3-5 hour installation process.</p>
<p>First they allocate you a fiber optic cable up to 500ft in length. In my case it was 450. Here it is on the sidewalk outside:</p>
<p><img src="http://maxogden.com/media/fiber-spool.png" alt="fiber spool"></p>
<p>They have to run it along the aerial wiring along your street and connect it to the nearest fiber splitter, which are little black boxes attached to aerial wires. </p>
<p><img src="http://maxogden.com/media/fiber-splitter.png" alt="fiber splitter"></p>
<p>In my case the nearest one was at the end of my block. They actually said that starting from two more houses down the block from me they wouldn&#39;t be able to offer fiber service because it would exceed the 500ft limit.</p>
<p><img src="http://maxogden.com/media/fiber-install.png" alt="fiber install"></p>
<p>Then they put a optical terminator on the outside of your house. This thing converts data from the fiber optic cable into ethernet, which then enters your home and goes into the modem/router. Behind the terminator is the &#39;slack box&#39; which holds the extra spooled fiber extension cable.</p>
<p><img src="http://maxogden.com/media/fiber-box.png" alt="fiber box"></p>
<p>They also throw a power unit for the terminator in your basement.</p>
<p><img src="http://maxogden.com/media/fiber-power.png" alt="fiber power"></p>
<p>Finally here is the modem/router combo unit they provided. It supports Gigabit Ethernet but only 802.11N wireless, meaning wireless bandwidth is limited to around 100Mbps.</p>
<p><img src="http://maxogden.com/media/fiber-router.png" alt="fiber router"></p>
<p>Attached to the yellow cat6 ethernet cable is an <a href="http://store.apple.com/us/product/MD463ZM/A/thunderbolt-to-gigabit-ethernet-adapter">Apple Thunderbolt to Gigabit Ethernet</a> adapter. The speed test from the top of this article was made while plugged in using this on a mid-2013 MacBook Air.</p>
<p>I also have a Raspberry Pi running a <a href="https://www.eff.org/torchallenge/what-is-tor.html">Tor Relay Node</a>.</p>
<p>All in all it must cost CenturyLink quite a bit of money to upgrade a house to fiber, much more than the $100 in setup fees. Hopefully Google Fiber (and others!) enter the market to keep the competition going.</p>
<p>See you in the future!</p>
]]></description><link>http://maxogden.com/portland-fiber.html</link><guid isPermaLink="true">http://maxogden.com/portland-fiber.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sun, 01 Feb 2015 03:32:56 GMT</pubDate></item><item><title><![CDATA[node-repl]]></title><description><![CDATA[<div id="header"><h1 class="title">node-repl</h1></div>

<p>An interactive console for node</p>
<p>You can <a href="https://www.npmjs.com/package/node-repl#installation">install node-repl with npm</a>.</p>
<p>Recently I was asked if there was an equivalent of the <a href="http://en.wikipedia.org/wiki/Interactive_Ruby_Shell">Interactive Ruby Shell (IRB)</a> for node. IRB is great because it lets you quickly poke around in your program while it is running without having to set up breakpoints or print messages out to the console.</p>
<p>Node ships with a <a href="http://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop">repl</a> that you can run by simply typing <code>node</code>, and you can run a program by running <code>node program.js</code>, but you cannot both run a program <em>and</em> open a repl at the same time.</p>
<p>To solve this, with the help of my friends <a href="http://github.com/mafintosh">Mathias</a> and <a href="https://github.com/chrisdickinson">Chris</a> I whipped up a command-line module called <a href="http://npmjs.org/node-repl"><code>node-repl</code></a>.</p>
<p>Here&#39;s how to use it:</p>
<p><img src="http://maxogden.com/media/node-repl.png" alt="node-repl"></p>
<p>When you run a program with <code>node-repl program.js</code>, it both spawns your program but also opens a repl. The useful part is that the repl is executing code in the same JavaScript scope that your program is running in.</p>
<h2 id="how-it-works">How it works</h2>
<p>The functionality offered by <code>node-repl</code> seems simple at first, but underneath the hood it is doing a few tricky things: injecting the repl code, intercepting node&#39;s <code>require</code> and patching in <code>eval</code> from your program&#39;s scope into the repl.</p>
<h3 id="injecting-the-repl-code">Injecting the repl code</h3>
<p>Node has a <code>repl</code> module <a href="https://iojs.org/api/repl.html">in the core library</a> that makes it easy to implement a fully featured repl. By default the repl executes code in it&#39;s own scope, but in order to get the desired IRB-style functionality (e.g. where <code>pizza</code> is available to the repl as in the above example) we want the repl to execute in the same scope as the program.</p>
<p>The <a href="https://github.com/maxogden/node-repl/blob/master/repl.js">repl code itself</a> that <code>node-repl</code> injects is relatively simple:</p>
<pre><code class="lang-js">;(function() {
  var repl = require(&#39;repl&#39;)
  var os = require(&#39;os&#39;)
  var empty = &#39;(&#39; + os.EOL + &#39;)&#39;
  repl.start({
    input: process.stdin,
    output: process.stdout,
    eval: function(cmd, context, filename, callback) {
      if (cmd === empty) return callback()
      var result = eval(cmd)
      callback(null, result)
    }
  })
})();
</code></pre>
<p>The whole thing is wrapped in an <a href="http://en.wikipedia.org/wiki/Immediately-invoked_function_expression">IIFE</a> to avoid altering any external state in the users program, since <a href="https://github.com/maxogden/node-repl/blob/master/bin.js#L19">this code is concatenated</a> onto the end of the program. I very rarely use IIFEs any more because node&#39;s module system handles isolating files for you automatically (and if you use browserify you can use node&#39;s module system for client side code), but this case is an exception.</p>
<p>The code <code>var empty = &#39;(&#39; + os.EOL + &#39;)&#39;</code> is specific to how node&#39;s repl works. When you hit <code>&lt;return&gt;</code> in node&#39;s it takes whatever you typed and wrapps it in parentheses. For example, if you enter <code>var x = 1</code> and hit return you will end up with <code>(var x = 1\n)</code> on OSX/Linux or <code>(var x = 1\r\n)</code> on Windows. The code <code>require(&#39;os&#39;).EOL</code> gets the correct line ending for the users current OS. Also (warning: this is just a parlour trick) try going into the default node repl and typing <code>console.log)(42</code>. Even though you didn&#39;t type valid JS code, it ends up working because it gets turned into <code>(console.log)(42)\n</code> by the repl.</p>
<h3 id="a-quick-primer-on-scopes-in-node-modules">A quick primer on scopes in node modules</h3>
<p>When you run a program with node, e.g. <code>node hello.js</code> or <code>require(&#39;hello.js&#39;)</code>, node takes the contents of <code>hello.js</code> and wraps them in a function like this:</p>
<pre><code class="lang-js">(function (exports, require, module, __filename, __dirname) {
  var pizza = 1
});
</code></pre>
<p>Wrapping your code in a a function like this causes a new scope to be created for your code to run in. You could have two different modules that both set <code>var pizza</code> to different values, and because of the way that JavaScript&#39;s function scope works they can both exist in their own scopes without conflicting. This property of JavaScript is what allows node&#39;s <a href="http://maxogden.com/nested-dependencies.html">nested dependency</a> system to work and is extremely simple and powerful.</p>
<p>The problem with this for us is that your code is running in it&#39;s own scope, and <code>node-repl</code> needs access to it! This is why we &quot;inject&quot; (in this case by concatenating) our repl code into your code before it gets required.</p>
<h3 id="intercepting-node-s-require-call">Intercepting node&#39;s require call</h3>
<p>Node has a somewhat obscure API called <code>require.extensions</code> that lets you change what happens when files of a certain file extension are required. For <code>node-repl</code> we use this to rewrite the users program before it gets executed.</p>
<p>The following code is from <a href="https://github.com/maxogden/node-repl/blob/master/bin.js">https://github.com/maxogden/node-repl/blob/master/bin.js</a></p>
<pre><code class="lang-js">var original = require.extensions[&#39;.js&#39;]
require.extensions[&#39;.js&#39;] = function(module, filename) {
  if (filename !== file) return original(module, filename)
  var content = fs.readFileSync(filename).toString()
  module._compile(stripBOM(content + replCode), filename)
}

require(file)
</code></pre>
<p>First we store the original <code>.js</code> require function, so that we can call it for files other than our program. Then we define our own custom <code>require.extension</code> that emulates what the default <code>.js</code> require code does, but does <code>content + replCode</code> first, which &#39;injects&#39; our repl into the users program code. We reverse engineered the default <code>.js</code> functionality by looking at the output of <code>console.log(require.extensions[&#39;.js&#39;])</code>.</p>
<p>Finally, we <code>require(file)</code> which triggers the extension we just defined with the users program. This was confusing to me at first because the users program may not have <code>module.exports</code> in it, and it seemed unintuitive to me to <code>require</code> something when I really just wanted to execute it, but this is in fact a valid way to simply run code. <code>module.exports</code> defaults to an empty object (<code>{}</code>), meaning you can simply use <code>require</code> to run a JS program in it&#39;s own scope.</p>
<h3 id="patching-in-eval">Patching in <code>eval</code></h3>
<p>The node repl <a href="https://iojs.org/api/repl.html#repl_repl_start_options">supports passing in a custom <code>eval</code> function</a>, which is how we are able to swap out it&#39;s default eval with the eval from the program scope.</p>
<p>After being wrapped by <code>require</code> and having our repl injected the code looks like this:</p>
<pre><code class="lang-js">(function (exports, require, module, __filename, __dirname) {
  var pizza = 1
  ;(function() {
    var repl = require(&#39;repl&#39;)
    var os = require(&#39;os&#39;)
    var empty = &#39;(&#39; + os.EOL + &#39;)&#39;
    repl.start({
      input: process.stdin,
      output: process.stdout,
      eval: function(cmd, context, filename, callback) {
        if (cmd === empty) return callback()
        var result = eval(cmd)
        callback(null, result)
      }
    })
  })();
});
</code></pre>
<p>The trick here is that <code>eval</code> above is the eval from the same scope as what the program is running in, which gives it access to local variables like <code>pizza</code>.</p>
<p>Happy hacking!</p>
]]></description><link>http://maxogden.com/node-repl.html</link><guid isPermaLink="true">http://maxogden.com/node-repl.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sat, 24 Jan 2015 23:04:02 GMT</pubDate></item><item><title><![CDATA[Nested Dependencies]]></title><description><![CDATA[<div id="header"><h1 class="title">Nested Dependencies</h1></div>

<p>Insight into why node_modules works the way it does</p>
<p>There are a lot of package managers in use today, but the only popular one (to my knowledge) that is designed to support + works by default with nested dependencies is <a href="http://npmjs.org/">npm</a>.</p>
<p><img src="http://maxogden.com/media/nested-vs-flat-deps.png" alt="nested-vs-flat"></p>
<p>In the above diagram the <code>deps</code> containers represent <em>isolated</em> sets of dependencies. In most package managers there is only a single &#39;namespace&#39; for all dependencies. I refer to this behavior as &#39;flat&#39; because it means you only have one level of discoverability when resolving a dependency, which means you can only have one dependency called &#39;foo&#39; in your entire app.</p>
<p>Let&#39;s look at a close-up example of how dependency resolution works in a flat dependency system.</p>
<p><img src="http://maxogden.com/media/flat-deps.png" alt="flat"></p>
<p>In this example we have three dependencies. The black lines represent &#39;depends-on&#39; relationships, so our app depends on <code>a</code>, <code>b</code> and <code>c</code>, and <code>c</code> depends on <code>a</code>. So both our app <em>and</em> <code>c</code> depend on <code>a</code>.</p>
<p>Because the dependencies are flat, meaning we can only have one copy of <code>a</code> in our entire app, it means we have to make sure that both our app and <code>c</code> both depend on <em>compatible versions</em> of <code>a</code>. If we want to upgrade <code>c</code> to a newer version, but that new version also upgrades <code>a</code> to a version that in incompatible with the <code>a</code> that our app depends on, we have a dependency conflict. This phenomenon is referred to as &quot;DLL Hell&quot; (from Windows) or more generally &quot;Dependency Hell&quot;.</p>
<p>Let&#39;s look at the same example but in a nested system.</p>
<p><img src="http://maxogden.com/media/nested-deps.png" alt="nested"></p>
<p>Here we don&#39;t just have one level of dependencies, we have multiple. Assume <code>a</code> and <code>b</code> have no dependencies. Our app and <code>c</code> both still depend on <code>a</code>. </p>
<p>With nested dependencies we now have two copies of <code>a</code>. If our app needs <code>a</code> at version 1 and <code>c</code> needs <code>a</code> at version 2 then there is we just install both versions of <code>a</code>. The dependencies of <code>c</code> are only available to <code>c</code>, nothing else can access them. Additionally, if it turns out that our app and <code>c</code> both depend on a compatible version of <code>a</code>, we never need to create the <code>c&#39;s deps</code> folder -- so the behavior in that case would mimic flat deps (this is how <a href="https://docs.npmjs.com/cli/dedupe"><code>npm dedupe</code></a> works).</p>
<h3 id="pros-and-cons">Pros and Cons</h3>
<h4 id="flat">Flat</h4>
<ul>
<li>The simpler of the two designs. It&#39;s up to you to decide how much complexity you want to deal with.</li>
<li>Dependency conflicts (AKA dependency hell)</li>
<li>Sometimes the only option for languages where you cannot load dependencies in isolation</li>
</ul>
<h4 id="nested">Nested</h4>
<ul>
<li>No dependency conflicts</li>
<li>Encourages use of small, isolated modules</li>
<li>More complicated</li>
<li>Good for languages like JavaScript with first class scoping support for isolating dependencies from each other</li>
<li>Installs multiple copies of dependencies (when necessary), so takes up more disk space (though in practice this is rarely an issue because code is small).</li>
<li>Confuses users who use dependencies that aren&#39;t designed to be modular (e.g. &#39;Why do I have five versions of jQuery in my browserify app?&#39;)</li>
</ul>
]]></description><link>http://maxogden.com/nested-dependencies.html</link><guid isPermaLink="true">http://maxogden.com/nested-dependencies.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Tue, 13 Jan 2015 22:24:35 GMT</pubDate></item><item><title><![CDATA[Node Packaged Modules]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Node Packaged Modules</title>
  </head>
  
  <body>
    <div id="header">
      
<h1 class="title" style="font-size: 56px;">Introducing RequireBin, Browserify-CDN and npmsearch</h1>

      
<h2 class="author">Max Ogden</h2>

    </div>
    <p>Three new projects that bring npm modules to the web</p>
    
<h1 id="npm">npm: Node Packaged Modules</h1>

    <p>A common misconception about <a href="http://npmjs.org/" target="_blank">npm</a> is that since it has 'Node' in the name that it must only be used for server side JS modules. This is completely untrue! npm actually stands for Node <i>Packaged</i> Modules, e.g. modules that Node packages together for you. The modules themselves can be whatever you want -- they are just a folder of files wrapped up in a <code>.tar.gz</code>, and a file called <code>package.json</code> that declares the module version and a list of all modules that are dependencies of the module (as well as their version numbers so the working versions get installed automatically). It's turtles all the way down - module dependencies are just modules, and those modules can have dependencies etc. etc. etc.</p>
    <p><a href="http://npmjs.org" target="_blank"><img src="http://maxogden.com/media/npm.png"></a></p>
    <p>The main features that npm brings to the table (in my opinion) are:</p>
    <ul>
      <li>Automatic installation + upgrading (e.g. no more downloading individual .js files and moving them manually into your js/ folder)</li>
      <li>Modules specify a list of other modules that are dependencies</li>
      <li>Dependencies get installed at known working versions</li>
      <li>Each module gets it's own local set of working dependencies (different versions of the same module can be depended on by different modules in the same project)</li>
      <li>Dependencies can have dependencies</li>
      <li>The availability of solutions on npm makes you feel like a <a href="https://twitter.com/ceejbot/status/354406370289782785" target="_blank">kid in a candy store</a></li>
    </ul>
    <p>I've written more about the specifics of writing programs with npm in my <a href="https://github.com/maxogden/art-of-node#modules" target="_blank">Art of Node</a> article. If you haven't grokked how npm works yet I highly encourage you to give it a spin. Some other great reads on the subject: <a href="http://dontkry.com/posts/code/using-npm-on-the-client-side.html" target="_blank">Using npm on the client side</a> and <a href="http://dontkry.com/posts/code/browserify-and-the-universal-module-definition.html" target="_blank">Browserify and the Universal Module Definition</a> by <a href="https://twitter.com/shamakry" target="_blank">@shamakry</a> and <a href="http://superbigtree.tumblr.com/post/54873453939/introduction-to-browserify" target="_blank">Introduction to Browserify</a> by Seth Vincent.</p>
    <h1 id="browserify">Browserify: Using npm for client-side programs</h1>
    <p>A traditional JS app that might have a few libraries like jquery.js, bootstrap.js, angular.js, underscore.js and a few additional plugins. Since there are only a handful of js files it's not a big deal to manually download, move and add a script tag for each one.</p>
    <p>Node programs, on the other hand, don't have the same limitations as browsers. Any program can require() another program and start using it. Programs can be published as tiny components that do one thing well, a la Unix. There isn't a strict definition but generally speaking code is modular if it exposes a generically useful API that be used by multiple dependent modules.</p>
    <p>There is only one problem: browsers don't have a good way to load modules. The state of the art is to have a ton of script tags that either leak globals e.g. how jQuery plugins all use $ or use RequireJS to manage loading code into the correct scopes.</p>
    <p>Both of these approaches make tons of HTTP requests which means when your app gets bigger than a dozen or so dependencies then you'll want to start thinking about a build step to reduce page load time.</p>
    <p>A good module system enables better code to be written. When you have to worry about limiting the number of script tags you will tend to use large kitchen sink style projects like jQuery. A build step is just some process that combines multiple JS programs into one larger JS program so that you can reduce the number of script tags on your page (and sometimes also other things like minifying code).</p>
    <p><a href="http://browserify.org" target="_blank">Browserify</a> is a build tool that builds bundles of modules from npm. Here is a visualization (using the <a href="https://twitter.com/maxogden/status/348185617907200000" target="_blank">colony</a> node module) of what the bundle looks like when browserify packages up the <a href="http://voxeljs.com" target="_blank"><code>voxel-engine</code></a> module:</p>
    <p><img src="http://maxogden.com/media/voxel-hello-world.png"></p>
    <p>Each dot is a fully fledged node module, complete with its own version number, github repo, author/maintainer and optional list of dependent modules. Each author gets their own color and the circle sizes are based on how large the modules are.</p>
    <p>Thanks to npm and browserify the <a href="http://voxeljs.com" target="_blank">Voxel.js project</a> has seen a couple dozen unique contributors create around 100 modules over the last six months. The conventions are pretty simple: Use npm and name your module voxel-"something" so that it's easy to find. Most of them don't even run in node itself as they require WebGL to function, but that's okay because node is simply packaging them up for browsers.
    </p>
    <p>When browserify bundles up the <code>voxel-engine</code> module it gathers up all of the dependencies in the graph and combines them into a single JS program that you can load into a web browser and run.</p>
    <h1 id="browserify-cdn">Browserify CDN</h1>
    <p>Browserify is written with Node and is usually executed on the command line on the same computer that a program is being developed on. To make browserify more accessible to JavaScripters that aren't as comfortable with the command line or Node <a href="https://github.com/jesusabdullah/browserify-cdn">browserify-cdn</a> was developed by <a href="https://github.com/jesusabdullah/" target="_blank">Joshua Holbrook</a>, a Node hacker who has formerly worked on the Node hosting platform Nodejitsu. It's a really well designed caching + API layer built on top of browserify that automatically installs and packages up any module available on npm.</p>
    <p>This week I set up a production ready instance of browserify-cdn over at <a href="http://wzrd.in" target="_blank">http://wzrd.in</a> (wizardin', like the browserify logo). It's also pretty easy to host an instance yourself. The browserify-cdn API is CORS enabled which means you can load bundles from anywhere on the internet (and do things like <a href="https://github.com/shama/browser-module-cache" target="_blank">cache them in IndexedDB</a>).
    </p><p><a href="http://wzrd.in" target="_blank"><img src="http://maxogden.com/media/browserify-cdn.png"></a></p>
    <h1 id="requirebin">RequireBin</h1>
    <p>In the spirit of <a href="http://jsfiddle.net/" target="_blank">JSFiddle</a> and <a href="http://jsbin.com/" target="_blank">JSBin</a>, <a href="http://requirebin.com/" target="_blank">RequireBin</a> is a web application that I wrote over this last weekend for making short + sweet shareable JS applications that run in the browser. The major difference from similar works being that RequireBin is built on top of browserify-cdn and therefore provides access to the wealth of modules on npm. RequireBins are <a href="https://gist.github.com/maxogden/5953535" target="_blank">saved as github gists</a> so that each one is clone-able and fork-able and the RequireBin website itself is just a static site that is hosted on Github Pages.</p>
    <p><a href="http://requirebin.com" target="_blank"><img src="http://maxogden.com/media/requirebin.png"></a></p>
    <h1 id="npmsearch">npmsearch</h1>
    <p>The npm command line tool has a built in search feature but it is quite barebones and doesn't have a dedicated full text index. To provide a better search experience to npm users <a href="http://github.com/tmpvar" target="_blank">Elijah Insua (tmpvar)</a> has created <a href="http://npmsearch.com" target="_blank">npmsearch.com</a> which offers lightning fast search (Solr + SSDs) and a CORS enabled JSON API for adding npm search to any app.</p>
    <p><a href="http://npmsearch.com" target="_blank"><img src="http://maxogden.com/media/npmsearch.png"></a></p>
    <p>Here's a live embedded iframe of <a href="http://requirebin.com/?gist=5953535&q=voxel" target="_blank">this RequireBin</a> integrating with the npmsearch API and rendering output to a fake ANSI terminal via <a href="https://npmjs.org/package/hypernal" target="_blank">hypernal</a> and <a href="https://npmjs.org/package/tablify" target="_blank">tablify</a>, two modules I recently found on npm.</p>
    <p>
    <iframe width="750" height="315" src="http://requirebin.com/embed?gist=5953535&q=voxel" frameborder="0" allowfullscreen=""></iframe>
    </p>
    <p>For a more complex RequireBin example check out this WebGL Ambient Occlusion Voxel rendering demo by computational geometry PHD student <a href="http://twitter.com/mikolalysenko">Mikola Lysenko</a>:</p>
    <p><a href="http://requirebin.com/?gist=5941747" target="_blank"><img src="http://maxogden.com/media/voxel-ao-requirebin.png"></a></p>
    <p>Mikola also happens to be the most prolific author of node modules lately (according to npmjs.org), you should definitely <a href="https://npmjs.org/~mikolalysenko" target="_blank">look at his modules</a> and <a href="http://0fps.wordpress.com" target="_blank">read his blog</a>.
    </p>
    <p>I'll end this post with this, the first and arguably most important rule from <a href="https://en.wikipedia.org/wiki/Unix_philosophy" target="_blank">The Art of Unix Programming</a>, a text close to the hearts of <a href="http://blog.izs.me/post/48281998870/unix-philosophy-and-node-js" target="_blank">many of the Node community members</a>.</p>
    <p><img src="http://maxogden.com/media/rule-of-modularity.png"></p>
  </body>

</html>]]></description><link>http://maxogden.com/node-packaged-modules.html</link><guid isPermaLink="true">http://maxogden.com/node-packaged-modules.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Mon, 08 Jul 2013 20:48:11 GMT</pubDate></item><item><title><![CDATA[Kindleberry Wireless]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="author" content="Max Ogden">
    <title>Kindleberry Wireless</title>
  </head>
  
  <body>
    <div id="header">
      
      <h1 class="title">Kindleberry Wireless: A Portable Outdoor Hackstation</h1>
      
      <h2 class="author">Max Ogden</h2>

    </div>
      <p>An updated, wireless version of the <a href="http://www.ponnuki.net/2012/09/kindleberry-pi/">kindleberry</a> using the kindle paperwhite</p>
      <p>
        <img src="http://maxogden.com/media/kindleberry-sun.png">
      </p>
      <p>Recently I got to go down to Australia to attend an awesome conference called <a href="http://campjs.com">CampJS</a>. It isn't really a conference, actually, but instead a bunch of programmers in the woods for a few days hacking on side projects and learning new things. Getting out of the big city was really refreshing and at the same time made me realize how badly my glossy screened laptop works in the great outdoors.
      </p>
      <p>
        It got me wondering if there existed a laptop that was designed for hacking in direct sunlight... something that had a ridiculously long battery life and was still readable in high brightness situations. Instead I stumbled upon a more awesome solution: the <a href="http://www.ponnuki.net/2012/09/kindleberry-pi/">kindleberry</a>, a combination of the <a href="http://www.raspberrypi.org/">Raspberry Pi</a> and the Amazon Kindle.
      </p>
      <p>The advantages of the kindleberry are pretty desirable for me:</p>
      <ul>
        <li>Week-long battery life: the pi and the kindle both have low power ARM processors so you can use any USB charger to power them</li>
        <li>The kindle screen is designed for use in direct sunlight</li>
        <li>The whole setup is small enough to carry around in a pouch inside my normal backpack along with my normal laptop. I work from coffee shops in Oakland and often move around by bicycle during the day -- now I can work from almost anywhere and still be at least a little productive.</li>
      </ul>
      <p><img src="http://maxogden.com/media/kindle-table.png"></p>
      <p>The idea of the kindleberry is to have the kindle just act as screen and have it log into an ssh session on the pi. Then you can plug a keyboard into the pi and it when you type it will show up on the kindle screen. This approach pretty much only works for terminals so you can't do anything except edit code in vim. I like this limitation as it gives me an option that is free from distraction for writing long pieces of code or text.
      </p><p>Since the screen on the kindle is e-ink it has a slower-than-normal refresh rate. If you are a touch typist this shouldn't be an issue, I would recon that between the wifi latency and the screen latency there is a ~200ms screen delay, but it doesn't bother me at all when typing.</p>
      <p>
        The first problem I ran into was that the kindleberry instructions only worked on Kindle 3 devices, and the newest generation of Kindles (e.g. the paperwhite) are Kindle 5's. While the end result is similar this just means that essentially all of the steps to set up and install the peripherals correctly were different, including the terminal software that runs on the kindle. The other issue was that I wanted a totally wireless version: no cords between the keyboard, kindle or pi.
      </p>
      <p>Here is a list of physical parts that I am using in my setup:</p>
      <ul>
        <li>Raspberry Pi Model B with a 3D printed fork of <a href="http://www.thingiverse.com/thing:24945">this case</a></li>
        <li><a href="http://www.amazon.com/gp/product/B003VNKNEG/ref=oh_details_o03_s00_i01?ie=UTF8&psc=1">8gb SD card</a> to put the raspbian OS onto</li>
        <li><a href="http://www.amazon.com/gp/product/B007OZNUCE/ref=oh_details_o05_s00_i00?ie=UTF8&psc=1">Kindle Paperwhite</a> cause it has the fastest e-ink refresh rate of all the kindles + a nice backlight</li>
        <li><a href="http://www.amazon.com/gp/product/B005DLDO4U/ref=oh_details_o03_s00_i03?ie=UTF8&psc=1">Apple Wireless Keyboard</a> because I use a mac laptop and the layout is the same</li>
        <li><a href="http://www.amazon.com/gp/product/B0018O9JIG/ref=oh_details_o04_s00_i00?ie=UTF8&psc=1">IOGEAR GBU421 bluetooth USB</a> because it is small and works on raspbian</li>
        <li><a href="http://www.amazon.com/gp/product/B003MTTJOY/ref=oh_details_o06_s00_i00?ie=UTF8&psc=1&redirect=true">Edimax EW-7811Un wifi USB</a> because it is small and works on raspbian</li>
        <li><a href="http://www.amazon.com/gp/product/B008YRG5JQ/ref=oh_details_o06_s00_i02?ie=UTF8&psc=1"></a></li>
        <li><a href="http://www.amazon.com/gp/product/B008YRG5JQ/ref=oh_details_o06_s00_i02?ie=UTF8&psc=1">EasyAcc USB LiPo battery pack</a> a friend recommended this and said he ran a raspi off of it for a week</li>
        <li><a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16833704134">TP-LINK TL-WR702N Travel Router</a> for establishing wireless connectivity between the kindle and the pi</li>
        <li><a href="http://www.amazon.com/gp/product/B003M0NURK/ref=oh_details_o03_s00_i00?ie=UTF8&psc=1">4 port USB hub</a> just because it is useful to have around for cable management</li>
      </ul>
      <p><img src="http://maxogden.com/media/kindleberry-detail.png"></p>
      <p>
        For the software side of things, the best resource is <a href="https://gist.github.com/rvagg/5095506">this nice tutorial</a> that Rod Vagg has put together for getting the paperwhite set up with a terminal emulator. He even compiled node.js 0.10.0 for the kindle as well!
      </p>
      <p>My pi is configured to boot up and join the wifi hotspot that the TP-LINK router creates, then I can have the kindle communicate to the pi over wifi. There is probably a way to ad-hoc them together automatically but having a little hotspot is handy for other things like too like mobile web app development.
  </p></body>

</html>]]></description><link>http://maxogden.com/kindleberry-wireless.html</link><guid isPermaLink="true">http://maxogden.com/kindleberry-wireless.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sun, 24 Mar 2013 20:48:11 GMT</pubDate></item><item><title><![CDATA[Bringing Minecraft-style games to the Open Web]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="author" content="Max Ogden">
    <title>Bringing Minecraft-style games to the Open Web</title>
  </head>
  
  <body>
    <div id="header">
      
      <h1 class="title">Bringing Minecraft-style games to the Open Web</h1>
      
      <h2 class="author">Max Ogden</h2>

    </div>
      <p>A status report from the one month old <a href="http://voxeljs.com">voxel.js project</a></p>
      <p>
        <img src="http://maxogden.com/media/voxeljs.png">
      </p>
      <p>Shortly after Christmas 2012 (about 3 and a half weeks ago) the <a href="http://www.2playerproductions.com/projects/minecraft">Story of Mojang</a> was <a href="http://www.gameinformer.com/b/news/archive/2012/12/22/minecraft-the-story-of-mojang-documentary-creators-torrent-their-own-film.aspx">intentionally released</a> as a torrent. I watched it and was inspired. A year earlier I had purchased 2 copies of Minecraft for my nephews to play (and they haven't done much else since) but as gaming hasn't been a big part of my life for the last few years (because I've been too busy programming) I never had much time to play the game. Seeing how engaging Minecraft could be for my nephews was fascinating so I started looking into the modding community to see how feasible it would be to do things like hook Minecraft up to <a href="http://en.wikipedia.org/wiki/OpenStreetMap">OpenStreetMap</a>. My first foray into programming logic was <a href="http://maxogden.com/little-coders.html">in Starcraft</a> over a decade ago so I figured that a game that is so addicting and yet so simple could be a really powerful platform for education.
      </p>
      <p>
        I was disappointed to find out that not only is Minecraft closed-source but it also hasn't shipped an official API (these are used to extend a programs functionality). Instead, if you want to change the way Minecraft works, you have to decompile the Java program that Mojang distributes and then reverse engineer it to make it do what you want. Despite these technical hurdles, due to the success of Minecraft there is still a huge modding community. One of my favorites is <a href="http://wiki.sk89q.com/wiki/WorldEdit">World Edit</a>, which lets you bulk edit the Minecraft world by doing things like making giant pyramids, spheres, rectangles or even <a href="http://www.youtube.com/watch?v=PmyBs4IXFdM">frosted donuts</a>. 
      </p>
      <p>
        The first thing I tried to do was install a plugin. I immediately found myself on old forum posts that I found on google while looking for answers to obscure questions like what the OS X path is for the plugin folder, how to downgrade my Minecraft version because I had upgraded to the newest version which broke the plugin I was trying to use and how to edit a Minecraft world file that I had downloaded from someone else to change the game mode from Survival to Creative (turns out you have to use a hex editor).
      </p>
      <p>For the last couple years I have grown accustomed to the automated installation of modules that <a href="http://npmjs.org">NPM</a> provides and wondered if anyone had tried to make a package manager for Minecraft plugins. There are a few out there, but quite frankly they all reeked of Java (too many abstract interfaces, lots of boilerplate and hard to use build tools. Java was the first language I learned so I may very well be scarred from the experience) and were limited by the nature of decompiling as a workaround to Minecrafts lack of an API. 
      </p>
      <h2>Had anyone written a voxel engine in JS?</h2>
      <p>At this point I had decided that decompiling Java wasn't in my future, so as any JavaScript programmer would do I decided to rewrite the entire thing in JavaScript. The fun part is that at the time (3.5 weeks ago) I had zero experience programming games. But I had google search and free time. 
      </p>
      <p>On Github I <a href="https://gist.github.com/4637750">found 26 repositories</a> that contained some approach to rendering voxels in a browser. I spent a few days getting them to run on my computer and reading the source code of every single one. The projects that stood out were <a href="https://github.com/mitsuhiko/webgl-meincraft">webgl-meincraft</a>, <a href="https://github.com/jwagner/voxelworlds">voxelworlds</a> and <a href="https://github.com/danielribeiro/WebGLCraft">WebGLCraft</a>. Daniel Ribeiro wrote a post one year ago called <a href="http://metaphysicaldeveloper.wordpress.com/2011/12/20/implementing-minecraft-in-webgl/">Implementing Minecraft in WebGL</a> and Jonas Wagner did a talk at <a href="http://ongamestart.com/">OnGameStart</a> a few months ago called <a href="http://29a.ch/2012/12/9/webgl-voxel-worlds">Rendering Voxel Worlds using WebGL</a> and produced <a href="http://29a.ch/sandbox/2012/voxelworld/">this impressive demo</a>. I later found <a href="https://github.com/benvanik/blk-game">BLK Game</a> by Ben Vanik from Google which also has an <a href="http://benvanik.github.com/blk-game/">impressive demo</a>. My problem with every single one of the 26 projects that I found is that they were all huge projects that were hard to wrap your head around and hack on. I was trying to escape the Java mentality and make game development small and modular (like NPM) but didn't find a single project that had well documented, modular components. Some were written in coffeescript, hadn't been updated in over a year, had giant lib/ folders filled with custom written modules or only produced a single tech demo and then were never used again. To summarize: it was possible but still not very accessible.
      </p>
      <p>
        I also discovered an obscure subreddit called <a href="http://www.reddit.com/r/voxelgamedev">voxelgamedev</a> that had produced a wiki page called <a href="http://www.reddit.com/r/gamedev/wiki/block_engines">The BIG list of block engines and resources!</a>. Through this I found out about Mikola Lysenko's blog <a href="http://0fps.wordpress.com">0fps.wordpress.com</a> and his articles <a href="http://0fps.wordpress.com/2012/06/30/meshing-in-a-minecraft-game/">Meshing in a Minecraft Game</a>, <a href="http://0fps.wordpress.com/2012/07/07/meshing-minecraft-part-2/">Meshing in a Minecraft Game (Part 2)</a> and <a href="http://0fps.wordpress.com/2012/01/14/an-analysis-of-minecraft-like-engines/">An Analysis of Minecraft-like Engines</a>. Not only were these written in an amazingly accessible way but they also had a <a href="http://mikolalysenko.github.com/MinecraftMeshes2/">voxel meshing sandbox</a> implemented in WebGL and <a href="http://mrdoob.github.com/three.js/">three.js</a>.
      </p>
      <h2>Start with a few small modules</h2>
      <p>Mikola had some code <a href="https://github.com/mikolalysenko/mikolalysenko.github.com/tree/master/MinecraftMeshes2/js">hidden away</a> in his blog that I used a the basis for two modules: <a href="https://npmjs.org/package/voxel">voxel</a> and <a href="https://npmjs.org/package/voxel-mesh">voxel-mesh</a>. With these two modules I could create a little wireframe world.
      </p>
      <p>
        <img src="http://maxogden.com/media/wireframe-hill.png">
      </p>
      <p>You should read Mikola's posts but the main idea with a voxel rendering engine is to create chunks of voxels. If you try to treat each individual voxel as an individual cube then you will have to send too much state back and forth to the GPU and your game will be slow. If you use one giant mesh for all the voxels in your world then it will take to long when a player digs a hole in the ground because you will have to recalculate the entire world. Chunks should be sized "just-right" in the middle of these two extremes so that you aren't making thousands of draw calls per frame but also can make voxel editing imperceptibly fast.</p>
      <p>
        <img src="http://maxogden.com/media/wireframe-edit.gif">
      </p>
      <p>
        When you edit a voxel (to make a cave or build a tower) you are actually telling the engine to recalculate an entire chunk with or without a voxel present. To reduce the number of vertices these get culled/decimated (jargon for simplified) so that you aren't drawing voxel edges that the player can't see. To implement voxel editing I shoot an invisible ray (using the Raycaster in three.js), see where it intersected with the world, look up if the voxel there is air, dirt, brick or some other material, toggle it, and then tell the parent chunk to re-render (which includes the simplification). All of this happens quickly enough that the editing feels fast while you are playing the game.
      </p>
      <p>The next thing to tackle was to get first person shooter style controls and physics hooked up. Luckily Chrome 23 was recently released and included support for the <a href="https://developer.mozilla.org/en-US/docs/API/Pointer_Lock_API">HTML5 Pointer Lock API</a>. I based my physics on the code behind <a href="http://mrdoob.github.com/three.js/examples/misc_controls_pointerlock.html">this demo</a> by mrdoob but heavily modified it (made it more modular) and turned into the <a href="https://npmjs.org/package/player-physics">player-physics</a> module. It still isn't perfect and I would love to see other approaches to FPS controls in JS now that Pointer Lock is here.</p>
      <p>
        The project was a week old when I got stuck on collision detection and voxel texturing. I called for reinforcements and fellow Oakland JS hacker <a href="http://twitter.com/substack">Substack</a> answered the call. We stayed up until 2AM a couple of nights in a row and had a thing that kind of looked like Minecraft. Substack had some experience doing 3D programming and figured out how to calculate UV mappings and normals to texture our meshes. He also wrote some basic collision code so that the player could jump on top of and run into voxels. If you got stuck inside a voxel (which happened a lot) you would slowly float up to the top and pop out on the surface again. Good enough for a first version! One thing we couldn't figure out is how to have separate bottom, top and side textures for voxels so our world looked a little bland (but not too bad).
      </p>
      <p>
        <img src="http://maxogden.com/media/bland-voxels.png">
      </p>
      <p>
        During all of this early-on hacking Substack said something along the lines of "I can't wait until all of this 3D rendering stuff is done so we can never think about it again". What he meant was doing things like UV mapping, player physics and occlusion culling are things that some game developer should write once in a generic way and then be used by other higher level developers to hack together awesome experimental voxel games. I personally appreciate 3D programming and think game developers are super smart, but JavaScripts place in the world is <a href="http://www.futurealoof.com/posts/generation-gap.html">to amateurize</a>. This stuff should be easy and approachable for new programmers. Once we establish a nice platform of abstraction then we can enable any JS programmer to make their own Minecraft clone from scratch in just a few lines of JS.
      </p>
      <h2>Voxel.js</h2>
      <p>
        I decided to name the project voxel.js and figured that we should have a website. My wonderful girlfriend <a href="http://jlord.us/">Jessica Lord</a> offered to help design a basic website because she also wanted in on the exciting voxel action. We threw together <a href="http://voxeljs.com">voxeljs.com</a> over the course of a couple days and substack and I made a bunch of inaugural modules to get the point across.
      </p>
      <p>
        The core module is called <a href="http://npmjs.org/voxel-engine">voxel-engine</a>. This module is used to create a game instance which can be given to other modules so that they can augment the game. The engine is responsible for doing things like rendering the world using a game loop. The goal of the engine is to be simple with sensible defaults that are easy to override. 
      </p>
      <p>To use Pointer Lock we got some help from <a href="https://twitter.com/isntitvacant">Chris Dickinson</a> who ended up writing the <a href="https://npmjs.org/interact">interact</a> module for us (though it would be useful in many programs). I made a module for HTML selectable toolbars (used for selecting block types) called <a href="https://npmjs.org/package/toolbar">toolbar</a> and another for generating terrain called <a href="https://github.com/maxogden/voxel-perlin-terrain">perlin-terrain</a>. Substack then wrote <a href="https://github.com/substack/voxel-creature">creature</a>, <a href="https://github.com/substack/voxel-debris">debris</a> and <a href="https://github.com/substack/voxel-forest">forest</a> which really proved to me that we were on to something. 
      </p>
      <p>Before we "announced" the project publicly (I use quotes because all the code had been in public Github repos the whole time) I thought I should try to make a multiplayer server and a couple hundred lines of JS later had a basic implementation where every player was an animated 3D horse :D.
      </p>
      <p>
        <img src="http://maxogden.com/media/isaachorse.png">
      </p>
      <p>
        Pictured here is <a href="http://twitter.com/izs">@izs</a> (Node.js maintainer) running across a bridge he made in an early multiplayer test.
      </p>
      <p>I later learned about techniques to make real time multiplayer games fast like the <a href="https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking">Source Multiplayer Networking</a> article and the <a href="http://buildnewgames.com/real-time-multiplayer/">Build New Games HTML5 Networking</a> article. The server is still a work in progress but has server-side physics and (somewhat currently broken) client-side prediction. If this project interests you then get in touch and I can help you start hacking on it!</p>
      <p>
        <iframe width="560" height="315" src="http://www.youtube.com/embed/Y0JiIDhdeuw" frameborder="0" allowfullscreen=""></iframe>
      </p>
      <h2>Contributions!</h2>
      <p>The goal in most of my open source projects is to solve stupid problems so other people don't have to. Then people will use your solution to build other new things. It is a great feeling to see someone make something because of work that you did to make that thing easy.</p>
      <p>In this way voxel.js has totally exceeded all of my expectations, even though I am writing this only a week and a half after the initial public release. Since the project started we have generated about 25 modules, half of which are from me and substack but half of which have come from outside contributors.</p>
      <p>
        <img src="http://maxogden.com/media/voxelmodules.png">
      </p>
      <p>The first mind blowing module that I saw was made by <a href="https://github.com/shama">Kyle Robinson Young (@shama)</a>. It is called <a href="http://npmjs.org/voxel-drone">voxel-drone</a> and is a full emulator for the <a href="http://nodecopter.com/">nodecopter</a>. At Node.js + JavaScript conferences around the world over the last few months (largely in part to some awesome work by <a href="http://twitter.com/felixe">@felixge</a>) there have been offshoot events called NodeCopter in which participants with (usually) zero hardware experience spend a day writing JS to control quadcopter robots. Kyle had been to a nodecopter event in San Francisco and also other node events around the bay like <a href="http://www.tacoconf.com/">TacoConf</a>. What he did with voxel-drone is allow you to use the exact same JS library that you would use to control an actual drone but all in your browser on top of a voxel landscape. On top of that he implemented a virtual iPad of sorts in the game so that you can see what the drone sees. Go and <a href="http://shama.github.com/voxel-drone">play with the demo</a> now, seriously. There is a list of commands in the readme for the <a href="https://github.com/felixge/node-ar-drone#client">node-ar-drone</a> project.</p>
      <p>Many members of the Node.js community also are disciplined in writing small, Unixy pieces of software that do one thing and do them well. This is where the modular design of voxel.js comes from but also where our contributors come from. Since we used the package manager from node, put all of our code on Github, made some exciting demos and encouraged others to build new modules we were able to tap into the creativity of other members in our community like Kyle.</p>
      <p>While I was writing this article Kyle actually released a new module called <a href="http://npmjs.org/voxel-sky">voxel-sky</a> which lets you add sun and moon cycles to your voxel world.</p>
      <p>
        <iframe width="560" height="315" src="http://www.youtube.com/embed/iES7EKhTJXU" frameborder="0" allowfullscreen=""></iframe>
      </p>
      <p>
        At a <a href="http://musichackday.org/">Music Hack Day</a> hackathon somewhere in northern Europe last weekend a developer named <a href="http://github.com/andreypopp">Andrey Popp</a> made a project called MusVox that adds Soundcloud powered voxels. It even won a prize!
      </p>
      <p>
        <iframe width="420" height="315" src="http://www.youtube.com/embed/k54Zq421PiI" frameborder="0" allowfullscreen=""></iframe>
      </p>
      <p>Also in the realm of audio <a href="https://twitter.com/eckoit">Ryan Ramage</a> from the CouchDB community wrote the very impressively executed <a href="http://ryanramage.github.com/voxel-audio/">voxel-audio</a> which adds 3D positional audio to voxel games using the new HTML5 Web Audio API.</p>
      <p>Our old collision code needed some major love and luckily Chris Dickinson was knowledgable in the realm of collisions and physics and whipped up a ton of super useful (for any game) modules: <a href="https://github.com/chrisdickinson/aabb-3d">aabb-3d</a>, <a href="https://github.com/chrisdickinson/collide-3d-tilemap">collide-3d-tilemap</a>, <a href="https://github.com/chrisdickinson/spatial-events">spatial-events</a> and <a href="https://github.com/chrisdickinson/spatial-trigger">spatial-trigger</a>. Chris also sent a bunch of pull requests to the various voxel core modules to integrate in his modules and make our collisions super awesome. 
      </p>
      <p>We event had <a href="http://twitter.com/dariusk">Darius</a> and <a href="twitter.com/_gsmith">Greg</a> from <a href="http://bocoup.com">Bocoup</a> volunteer two entire work days to hack on voxel.js. Darius edits the site <a href="http://buildnewgames.com/">Build New Games</a> and made some great contributions to the player physics code and Greg made an awesome <a href="https://github.com/incompl/voxel-heightmap-terrain#voxel-heightmap-terrain">heightmap module</a>.
      </p><p>
        This week I have written a handful of new modules: <a href="http://maxogden.github.com/voxel-city/?lat=37.7750&lon=-122.4183&zoom=16">city</a>, which dynamically renders any area of San Francisco into a crude voxel world, <a href="http://github.com/maxogden/voxel-highlight">highlight</a> and <a href="http://maxogden.github.com/voxel-script-gun">script-gun</a>. Here is a video of highlight in action:
      </p>
      <p>
        <iframe width="560" height="315" src="http://www.youtube.com/embed/R3P0LN82QFY" frameborder="0" allowfullscreen=""></iframe>
      </p>
      <p>I am most excited about script-gun though. From here on out I'm going to focus on making voxel.js an environment in which you can learn to program. Script-gun is my first attempt (the module itself is only about 50 lines of JS) at a WorldEdit style module in the browser. You can try <a href="http://maxogden.github.com/voxel-script-gun/">the demo here</a> and use some example scripts that I prepared <a href="http://maxogden.github.com/voxel-script-gun/">here</a> to get an idea of the possibilities. It will get more intuitive as time goes on, this is just the very first version.</p>
      <h2>What is next</h2>
      <p>
        Substack is currently implementing detached chunks so that you can build voxel space ships and robots that walk around but are still editable. He also has mentioned that he wants to make a space vacuum with cellular automata logic for hull breaches to enable space battles where you would have to patch your hull to contain air leaks. An early example of these detached chunks is in <a href="http://substack.net/projects/voxel-servo/">voxel-servo</a>.
      </p>
      <p>
        We both see so many awesome things that can be done with voxel games that Minecraft isn't doing at all and don't intend on porting Minecraft in any way to JS. We instead just want to make it easier to make your own game in the same style. To me Minecraft should be a category and not an instance. (note: Minecraft is a trademark of <a href="http://mojang.com/">Mojang</a>.)
      </p>
      <p>
        The next thing I am going to build is an in-browser game editor so that you don't need to know how to use the command line in order to start making games with voxel.js. JSFiddle is a great example of a web based editor like this. I'm going to implement it in such a way that you can create a game and then get a URL to share with your friends so that they can play your game, fork it, and remix your game.
      </p>
      <p>
        The newest version of Chrome Beta for Android lets you enable WebGL through about:flags and I have a demo called <a href="http://maxogden.github.com/fps-touch-controls/">fps-touch-controls</a> that adds touch screen controls to voxel.js. The controls are still wonky but it is definitely possible to play on a phone.
      </p>
      <p>
        Raspberry Pi is also capable of running it... in theory. Back in August someone got Firefox OS to run with WebGL enabled on the Pi but I haven't been able to get the newer versions of Firefox OS to work. FFOS is nearing a 1.0 release so hopefully someone makes it easy to install FFOS on a Pi soon! Once that is well supported I have plans to buy 10 Pis and start doing pop up computer labs for kids to teach them programming through hacking on voxel.js. The Raspberry Pi Foundation and Mojang have actually been working on a <a href="http://www.raspberrypi.org/archives/2872">Minecraft Pi Edition</a> that is intended for education but it isn't out yet, will be very stripped down and won't be open source!
      </p>
      <p>
        To stay up to date with the project you can follow <a href="http://twitter.com/voxeljs">@voxeljs</a> on twitter or hang out in #voxel.js on freenode IRC. But more importantly you should go forth and create modules and games!
      </p>
  </body>

</html>]]></description><link>http://maxogden.com/bringing-minecraft-style-games-to-the-open-web.html</link><guid isPermaLink="true">http://maxogden.com/bringing-minecraft-style-games-to-the-open-web.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Fri, 25 Jan 2013 20:48:11 GMT</pubDate></item><item><title><![CDATA[A Proposal For Streaming XHR]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>A Proposal For Streaming XHR</title>
  </head>
  
  <body>
    <div id="header">
      <h1 class="title">A Proposal For Streaming XHR</h1>
      <h2 class="author">Max Ogden</h2>
    </div>
    <p>XHR2 isn't stream friendly. Lets explore why and propose a solution!</p>
    <p>Note: This article predates the <a href="https://streams.spec.whatwg.org/">HTML5 Streams work</a></p>
    <p><a href="http://www.html5rocks.com/en/tutorials/file/xhr2/">XHR2</a> (XHR is short for XMLHTTPRequest and is the HTTP client in AJAX) does some cool stuff. You can get binary response data, either read-only in a <a href="https://developer.mozilla.org/en-US/docs/DOM/Blob">Blob</a> or mutable in an <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays/ArrayBuffer#ArrayBuffer()">Array Buffer</a> (which you can turn into one of the many flavors of <a href="https://developer.mozilla.org/en-US/docs/JavaScript_typed_arrays">Typed Arrays</a>). Binary data in JavaScript pushes the boundaries of the web by enabling rich multimedia experiences (like those demonstrated in <a href="http://www.youtube.com/watch?v=PN8Eg1K9xjE">this mind-blowing talk</a> on the Web Audio API by <a href="twitter.com/stuartmemo">@stuartmemo</a>).</p>
    <p>There is one fundamental problem with the current XHR specification (and implementations) which is that they aren't designed for real-time streaming, but with a few tweaks I believe they can enable a much better web experience.
      
    </p><p>Here is an example of trying to wrap XHR in the <a href="https://github.com/substack/stream-handbook">node.js Stream API</a>. The important part of the following code is the <code>write</code> function which takes the Array Buffer that XHR returns, turns it into a Typed Array and then emits each new chunk of binary data each time that xhr.readyState 3 is fired.</p>
<pre><code data-language="javascript">var stream = require('stream')
var util = require('util')

function XHRStream(xhr) {
  stream.Stream.call(this)
  this.xhr = xhr
  this.offset = 0
  xhr.onreadystatechange = this.handle.bind(this)
  xhr.send(null)
}

// copy the Stream methods to this prototype
util.inherits(XHRStream, stream.Stream)

XHRStream.prototype.handle = function () {
  // readyState 3 will be fired many times during a large download
  if (this.xhr.readyState === 3) this.write()
  if (this.xhr.readyState === 4) this.emit('end')
}

XHRStream.prototype.write = function () {
  if (!this.responseArray) this.responseArray = new Int8Array(this.xhr.response)
  if (this.responseArray.byteLength > this.offset) {
    this.emit('data', this.responseArray.slice(this.offset))
    this.offset = this.responseArray.byteLength
  }
}

module.exports = XHRStream
</code></pre>
    <p>Fundamentally what node Streams (and the above code) do is take a huge response that may take a loooooong time to complete (like downloading a Blu-ray DVD) and splits the response up into chunks. This is a beautiful pattern due to its simplicity. The programmer can decide if they want to combine the chunks and store them in a file or database OR if they want to process the chunks one at a time immediately and then throw the chunks away so that the JavaScript VM can clean the chunks up and free up the memory they were using. The <code>xhr.response</code> (<code>xhr.responseText</code> when getting non-binary responseTypes) in an XHR request is a single JavaScript object that just grows and grows and grows so if you are downloading a 5GB file you will have a 5GB JavaScript object in memory at the end of the request. The "node way" would be to have hundreds of small objects that each contain a contiguous chunk of the file that get emitted as soon as the client receives the data from the network.</p>
    <p>The XHRStream prototype lets you write code that looks like this:</p>
<pre><code data-language="javascript">var xhr = new XMLHttpRequest()
xhr.responseType = 'arraybuffer'
xhr.open("GET", "http://bigdata.com/hugefile.zip", true)
var response = new XHRStream(xhr)

// 'data' events will happen each time a new chunk gets to the browser
response.on('data', function(chunk) {
  // chunk size in this case is determined by TCP and will
  // probably be in the range of 10s or 100s of kilobytes
})
</code></pre>
    <p>Unfortunately this isn't possible with the current XHR implementation for two reasons. The first is that <code>xhr.response</code> is essentially one big buffer that keeps growing linearly as the response data comes in which means it can't get garbage collected. This just means you can't download files with XHR that are larger than the amount of RAM in your machine which isn't a total deal breaker for streaming data. The other reason is that currently the XHR spec prevents access to binary response data before the request has completed. Here is a simplified excerpt from the <a href="http://www.w3.org/TR/XMLHttpRequest/#the-response-attribute">XMLHTTPRequest specification on w3.org</a> (thanks to <a href="http://twitter.com/tobie">@tobie</a> for assisting me in navigating the web standards world here):</p>
    <pre><code>If responseType is "text"
  If the state is not LOADING or DONE, return empty string and terminate these steps
  Otherwise return the text response entity body.
Otherwise (for all other types of responseTypes such as 'arraybuffer' or 'blob')
  If the state is not DONE, return null and terminate these steps.
    </code></pre>
    <p>Here is <a href="http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2011-January/029992.html">a discussion from the whatwg mailing list</a> on this topic that contains this particularly insightful comment:</p>
    <pre><code>Hmm! And I guess it's very difficult to create a abstract in/out 
interface that can handle any protocol/stream.
Although an abstract in/out would be ideal as that would let new 
protocols to be supported without needing to rewrite anything at the 
higher level.

-- 
Roger "Rescator" Hågensen.
    </code></pre>
    <p>I totally agree! It turns out that the node Stream API, which is the core I/O abstraction in Node.js (which is a tool for I/O) is essentially an abstract in/out interface that can handle any protocol/stream that also happens to be written in JavaScript.</p>
    <p>It should be noted that websockets now support transporting binary data but the websocket spec still <a href="https://github.com/maxogden/websocket-stream/issues/1">isn't perfect</a> for streaming and the overwhelming majority of APIs are HTTP.</p>
    <p>So, to any standards people or browser implementers reading this: please please please take some notes from Node.js and change the spec to allow for truly streaming data over XMLHTTPRequest.</p>
</body>

</html>]]></description><link>http://maxogden.com/a-proposal-for-streaming-xhr.html</link><guid isPermaLink="true">http://maxogden.com/a-proposal-for-streaming-xhr.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Tue, 20 Nov 2012 20:48:11 GMT</pubDate></item><item><title><![CDATA[Scraping With Node]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Scraping with Node</title>
  </head>
  
  <body>
    <div id="header">
      <h1 class="title">Scraping with Node</h1>
      <h2 class="author">Max Ogden</h2>
    </div>
    <p>Modules and tutorial demonstrating HTML parsing with node.js</p>
    <p>One of the the best parts about server side JavaScript is the lack of the DOM, but sometimes you need to parse HTML in your node programs. For a while JSDOM has been the most well known module for accomplishing this task, but it has a number of issues. The author, <a href="http://twitter.com/tmpvar">@tmpvar</a>, has been developing <a href="http://www.flickr.com/photos/gasi/7534134630/in/photostream/">super awesome node powered robots</a> instead of maintaining it. It also turns out that a full DOM level 3 implementation is super complex and crazy which means JSDOM suffers from some pretty bad memory leaks that leaves it unusable for a lot of complex use cases.</p>
    <p>Instead of rewriting the DOM in pure JS, a more realistic approach is a nice and simple HTML parser that implements a CSS selector API. Enter <a href="http://npmjs.org/cheerio"><code>cheerio</code></a>, a module that can teach your server HTML.</p>
    <p>Cheerio is built on top of the <a href="http://npmjs.org/htmlparser2"><code>htmlparser2</code></a> module, a sax-like parser for HTML/XML. The goal of Cheerio is to implement most of the jQuery API in pure JS, without the need for a DOM. There is a separate dependency called <a href="https://npmjs.org/package/cheerio-select"><code>cheerio-select</code></a> that implements the sizzle API. The <code>cheerio</code> module itself more or less implements the jQuery API.</p>
    <h2>Using Cheerio</h2>
    <p>Since there is no DOM in node you have to initialize a <code>cheerio</code> instance from an HTML string. (this example comes from the <a href="http://npmjs.org/cheerio#readme">cheerio readme</a>)</p>
    
<pre><code data-language="javascript">var cheerio = require(&#39;cheerio&#39;),
    $ = cheerio.load(&#39;&lt;h2 class = &quot;title&quot;&gt;Hello world&lt;/h2&gt;&#39;);

$(&#39;h2.title&#39;).text(&#39;Hello there!&#39;);
$(&#39;h2&#39;).addClass(&#39;welcome&#39;);

$.html();
//=&gt; &lt;h2 class = &quot;title welcome&quot;&gt;Hello there!&lt;/h2&gt;
</code></pre>
<p>If you have an HTML file on disk that you want to load, you can use nodes <code>fs</code> module (warning: don't use sync calls inside an event loop, only use them when you don't care about performance):</p>

<pre><code data-language="javascript">var $ = require('cheerio')
var fs = require('fs')

var htmlString = fs.readFileSync('index.html').toString()
var parsedHTML = $.load(htmlString)

// query for all elements with class 'foo' and loop over them
parsedHTML('.foo').map(function(i, foo) {
  // the foo html element into a cheerio object (same pattern as jQuery)
  foo = $(foo)
  console.log(foo.text())
})
</code></pre>

<p>Similarly, you can use the popular <a href="http://npmjs.org/request">request</a> module to grab HTML from a remote server using HTTP and then pass it to <code>cheerio</code>:</p>

<pre><code data-language="javascript">var $ = require('cheerio')
var request = require('request')

function gotHTML(err, resp, html) {
  if (err) return console.error(err)
  var parsedHTML = $.load(html)
  // get all img tags and loop over them
  var imageURLs = []
  parsedHTML('a').map(function(i, link) {
    var href = $(link).attr('href')
    if (!href.match('.png')) return
    imageURLs.push(domain + href)
  })
}

var domain = 'http://substack.net/images/'
request(domain, gotHTML)
</code></pre>

<p>Building on the last example, here is how to fetch the raw binary data of each <code>img</code> on the page and render the images in your terminal using <a href="http://npmjs.org/picture-tube">picture-tube</a> and the node <a href="https://github.com/substack/stream-handbook">Stream API</a>:</p>

<pre><code data-language="javascript">var pictureTube = require('picture-tube')

var randomIndex = Math.floor(Math.random() * imageURLs.length)
var randomImage = imageURLs[randomIndex]
request(randomImage).pipe(pictureTube()).pipe(process.stdout)
</code></pre>

<p><img src="http://maxogden.com/media/picture-tube.png"></p>

<p>Now, go forth and scrape!</p>
</body>

</html>]]></description><link>http://maxogden.com/scraping-with-node.html</link><guid isPermaLink="true">http://maxogden.com/scraping-with-node.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Wed, 24 Oct 2012 20:48:11 GMT</pubDate></item><item><title><![CDATA[Building WebView Applications]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="author" content="Max Ogden">
    <title>Building WebView Applications</title>
  </head>
  
  <body>
    <div id="header">
      
      <h1 class="title">Building WebView Applications</h1>
      
      <h2 class="author">Max Ogden</h2>

    </div>
    <p>Article version of <a href="http://www.youtube.com/watch?v=rn597gDdlng">this PhoneGap Day EU presentation</a> given in September 2012</p>
      <p>Summary: WebKit browsers are capable of a lot, but writing native code is still necessary for certain things. Hence: "hybrid apps". The web is a double edged sword. Openness on one side and splintered bugginess on the other. Most of the bugs I've encountered have been squashed in <a href="https://github.com/maxogden/ViewKit">ViewKit</a>, a jQuery mobile-esque UI library designed for mobile WebKits.
      </p>
      
      <p><i>This is part two of a series, the first part is called <a href="http://maxogden.com/fast-webview-applications.html">Fast WebView Applications</a>.</i></p>
      
<h1 id="javascript-everywhere">JS all the things!</h1>

      <p>My company (<a href="http://twitter.com/gather">@gather</a>) is a little under a year old and consists of 2.5 (two full time, me and <a href="http://twitter.com/mikeal">@mikeal</a>, and one design contractor, <a href="http://twitter.com/objcts">@objcts</a>). Mikeal does all the backend... node, redis, couch, apple + google push notifications, load balancing, deployment, etc and I work on our mobile app. As covered in part one, we rolled with PhoneGap due to a) front end team size of 1 (with little to no iOS or Android experience) and b) a somewhat dogmatic belief in the open web and c) cross-platform.
      </p>

      <p>So far mobile development has been an uphill battle. Not as bad as IE6 but it approaches the same level of facepalm. Here are some example commit messages to give you a sense of the day-to-day reality of cross platform development:</p>
      <p><img src="http://maxogden.com/media/commit-messages.png"></p>
      <p>If you aren't already a super capable client side developer I would definitely not recommend attempting to make a high quality hybrid native app today. The community just isn't there yet. If you buy an iOS book you learn about the built in UI libraries and Interface Builder, have world class documentation, tons of google-able error messages and stack overflow posts, and generally lots of great example products in the App Store to draw inspiration from. PhoneGap gives you a blank white browser window and you take it from there. Fixing cross browser bugs, the entire UI for your app and custom native plugin functionality are all left as exercises for the reader.</p>
      
      <p>It isn't that these things aren't possible. As HTML5 gets better and better these problems will disappear. But the state of mobile app development today is that the current JS UI framework offerings just don't compete with the UX of the native smartphone SDKs.
      </p>
      <p>So if it is a pain, why are we doing it this way? The redeeming quality of the web is that the more work you pour into it, the more value you create in the ecosystem. Things like Firefox OS, which will allow mobile app developers to fork the operating system, are going to be huge wins. We just happen to be among the first on the bandwagon :)</p>

<h1 id="architecture">Architecture</h1>
      <p>At the moment, our app has one set of front-end assets that run on most iOS (5.1+) and Android (2.3+) devices. We use native plugins to do only a few things: popup browsers for the OAuth login dance, date + time pickers for forms and push notifications. Our entire UI is just one big web view.</p>
      <p>A few months into development I realized that I needed to abstract out a few of the UI components into a library so that I could make sure everything worked in all of the browsers that we aim to support. This library is called <a href="https://github.com/maxogden/ViewKit">ViewKit</a> and can be thought of as a WebKit specific jQuery mobile with way less features.
      </p>
      <p><img src="http://maxogden.com/media/architecture-diagram.png"></p>
      <p>All in all we have five repos: ViewKit, our app specific front-end code that uses ViewKit, Android and iOS projects (that both symlink to the same front-end code), and our backend.
      </p>
      <p>At the moment the only way to use Gather is to install the native app. We want to release a web-app version but haven't had enough time to do enough testing to feel good about a more wide release like that. The cool part is that when we are ready we would just serve the same application code in the above diagram directly from a static file server.
      </p>

      <h1 id="development-workflow">Development workflow</h1>
      <p>The majority of the app was written on my laptop in Chrome + its dev tools, the same workflow I've been using for years. Our designer, Michael Felix (<a href="http://twitter.com/objcts">@objcts</a>) worked with us during the initial conceptual phase and then starting whipping up some pixel perfect PSDs.</p>
      <p><img src="http://maxogden.com/media/gather-psd.png"></p>
      <p>On device testing is a must. Get a new Android + iPhone and an old Android and iPhone. We went with the Galaxy Nexus, iPhone 4S, some random LG android phone that runs 2.3 and an iPhone 3GS. Turns out nobody has really complained to us about iPhone 4.x compatibility so we are currently iOS5+6 only. Android emulators are a waste of time, just plug your device in. iPhone Simulator is nice though. With PhoneGap nowadays you can do pretty much everything from the command line:</p>
      
      <pre><code data-language="bash">      
      // get phonegap
      git clone https://github.com/apache/incubator-cordova-ios.git
      cd incubator-cordova-ios

      // create a new XCode project
      ./bin/create ~/src/gather-ios com.gather.gather Gather
      cd ~/src/gather-ios
      
      // compile app
      ./cordova/build
      
      // run in simulator
      ./cordova/emulate
      
      // get an .ipa for ad-hoc (testflight) or app store distribution
      gem install shenzhen && ipa build
      </code></pre>
      
      <p>or for Android:</p>
      
      <pre><code data-language="bash">      
      // get phonegap
      git clone https://github.com/apache/incubator-cordova-android.git
      cd incubator-cordova-android

      // create a new Eclipse project
      ./bin/create ~/src/gather-android com.gather.gather Gather
      cd ~/src/gather-android
      
      // generate an .apk and run it on a plugged in phone
      ./cordova/BOOM
      </code></pre>
      
      <p><img src="http://maxogden.com/media/native-app-folders.png"></p>
      
      <h1 id="cross-platform">Cross-platform code</h1>
      <p>
        On app load we first execute all of the common, platform independent JS and then do a bit of UA sniffing (using zeptos <code>$.os</code> plugin) to load browser + platform specific scripts. These scripts include things like the required <code>cordova.js</code> library (which at the time of this writing has specific builds for specific platforms), our phonegap plugin JS files, and any browser specific polyfills. We also have a iOS specific stylesheet that currently has a single line to enable <code>-webkit-transform</code> animations (they are disabled by default because Android animation performance is abysmal).
      </p>
      <p>
        There are a few other places in the app where we have platform specific code. Here is a snippet from our date picker code that executes after you choose a date or time (or both) in the native date picker UI popup dialog:
      </p>
      <pre><code data-language="javascript">
      if ($.os.ios) {
        $('.datepicker').text(moment(start).format("MMM Do h:mma"))          
      } else {
        $('.datepicker').text(moment(start).format("MMM Do"))
        $('.timepicker').text(moment(start).format("h:mma"))
      }
      </code></pre>
      <p>
        iOS has a combination date + time picker in a single dialog but Android offers only date or time but not both, so we have to add a new input field for Android users and branch a few times in the code to handle both platforms correctly.
      </p>
      <p><img src="http://maxogden.com/media/datepickers.png"></p>
      <h1 id="real-time">Networking and real-time</h1>
      <p>Since the app is just a WebView I just use XHR for most things. We wrote a RESTy JSON API in node for doing things like authentication, retrieving user data and posting new data, etc. Since our API has CORS turned on I can use Chrome on my laptop to develop directly against our production servers over SSL to make sure everything works. This speeds up development workflow dramatically because mobile debugging is a pain.
      </p>
      <p>
        The latest (and unfinished) thing we've been working on is a real time chat in the app built with <a href="http://socket.io/">socket.io</a>, a popular cross-browser node powered real time abstraction. In my experience so far socket.io is a bit too monolithic and ends up being a pain to debug and configure. It doesn't implement things like the node Stream API but instead has it's own connection state API and automagic reconnect logic. When it works it works great but when it doesn't you have to ask the socket.io team for assistance. The next version of socket.io (currently in development) is supposed to fix lots of these issues but it isn't done yet :(.
      </p>
      <p>In order to actually transmit data over websockets on mobile there are a couple of requirements: a) <code>wss://</code> is a must because normal <code>ws://</code> messages sometimes randomly get lost by poorly implemented mobile carrier proxies, b) you have to be able to handle the <code>wss://</code> encryption overhead on your server (equivalent to <code>https://</code>). In node right now SSL is 10X slower than non-SSL so this can be a deal breaker (SSL speed is a priority for the node team but OpenSSL is hard).
      </p>
      <p>Due to the limited <code>wss://</code> support in mobile browsers (pretty much only iOS) we have just been forcing socket.io to use its XHR polling transport because XHR works everywhere. If I had to re-write the whole chat feature again from scratch I would probably just use a custom XHR polling transport or shop around for something way more focused and simple. However, socket.io will be awesome when we release a webapp version of Gather because ideally we wouldn't have to worry about as many cross browser + desktop issues. Both solutions have tradeoffs. I'd love to hear others experience with the open source real-time web on mobile!
      </p>
      <h1 id="responsive-design">Fluid + responsive design</h1>
      <p>This might sound fancy but it just means that you should make your web app look good on different screen sizes. I employ three techniques with Gather to make sure the app works on all the random Android phones it gets installed on: fluid css (for slightly different screen widths and heights), sprites (for different pixel densities) and responsive design/media queries (for drastically different screen widths and heights). I'm not gonna go into detail here (since there are tons of <a href="http://girliemac.github.com/presentation-slides/SFHTML5DevConf/#1">better sources for info</a> on these techniques) other than on two points: css <code>flexbox</code> is awesome (even though the spec is in flux) and <a href="http://github.com/jorgebastida/glue">glue</a> is super great for creating sprites.
      </p>
      <p>
        We don't officially tablets yet but the app is at least somewhat usable on them without any modifications -- the buttons are just kind of small. It wouldn't be that much work to put in a media query and tweak the css, I just haven't gotten around to it.
      </p>
      <h1 id="native-plugins">Native plugins</h1>
      <p>
        As I mentioned earlier, there are a few places where we use PhoneGap plugins. Plugins are designed so that they expose a single JS API and then offer a number of platform specific native code implementations. That way you can write your JS once and then use the <code>.java</code> plugin for Android or <code>.h</code> and .m files for iOS. Another awesome thing about PhoneGap plugins is that it is a way to prototype experimental W3C APIs via native polyfills. The date picker shown above is a native plugin.
      </p>
      <p>
        For bringing up pop-up browser windows we use a popular 3rd party PhoneGap plugin called "child browser". This plugin is soon changing its name and moving into PhoneGap core. On iOS I wasn't happy with the default child browser UX so I wrote a API compatible alternative that is based on the UX of the iOS Facebook SDK (pictured below on the right). It's <a href="https://github.com/maxogden/cordova-modalwebview">available here</a>. The picture on the left is the same JS API running on Android to generate a web browser overlay written in Java using the Android SDK.
      </p>
      <p><img src="http://maxogden.com/media/childbrowser.png"></p>
      <p>
        Push notifications are one of the biggest reasons we aren't a web app. There are some nice plugins for both <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">iOS</a> and <a href="https://github.com/marknutter/GCM-Cordova">Android</a> to handle registering devices for push notifications and getting device tokens than you can send to your server and use to send push notifications later. At the moment the APIs are different between the two platforms but there is some work happening now to standardize the JS API for registering a device and receiving a push notification across all platforms that offer push notification functionality. There is a plugin for Android called StatusBarNotification that lets you send messages to display in the Android status bar (as pictured below on the left). The JS API <a href="https://github.com/phonegap/phonegap-plugins/blob/master/Android/StatusBarNotification/statusbarnotification.js#L61-133">actually polyfills</a> the <a href="http://www.w3.org/TR/notifications/">Web Notification API</a> from the W3C, which is a big win for future proofing our app.
      </p>
      <p><img src="http://maxogden.com/media/pushnotifications.png"></p>
      <h1 id="app-stores">App Stores</h1>
      <p>Submitting to the Android Play marketplace is pretty straightforward and once you upload your app it only takes between 30 minutes and 6 hours for it to become available for download. iOS, on the other hand, usually takes 1-2 weeks for app review and involves an insanely complicated certificate signing and device provisioning process. Be prepared to search stack overflow for obscure XCode generated errors and find answers that tell you to delete your entire XCode project and start over from scratch.</p>
      <p>We've been using Testflight for beta testing. It is worth checking out and simplifies the process of distributing beta builds to authorized beta testing devices (that you have to manually add to the Apple developer portal). Unfortunately there is no API for a lot of the Apple developer portal so there are a lot of manual processes involved in distributing iOS apps.</p>
      <h1 id="future-pans">Future plans</h1>
      <p>There are two things that aren't here yet but are super exciting. One is the ability to programmatically install native plugins in the same way that you can type `npm install foobar` to get modules in node. The PhoneGap team is working on this and it will make development way easier, as well as enable the PhoneGap user ecosystem to really blossom (just look at what NPM did for node).</p>
      <p>The other thing is doing remote updates. Since PhoneGap apps are just a bunch of dynamic code you can easily write a Google Chrome style autoupdating capability into the apps as a way of circumventing Apples crazy long review process. There are definitely guidelines from Apple that you can't break (bait and switch -- changing your apps UI so that it suddenly shows naked people), but for things like fixing JS bugs and making minor updates to libraries, templates and stylesheets this kind of remote update functionality is going to be super awesome.</p>
      <h1 id="conclusion">In Conclusion</h1>
      <p>Don't use PhoneGap if you aren't willing to get down and dirty and help establish some good patterns for hybrid mobile app development. It is still the early days. But the idea that you can use the open web stack to write nice mobile phone apps isn't crazy. After going through the process I would say I did about 80% web, 10% iOS and 10% Android. Would I have been able to achieve the same goals with me doing 50% iOS and 50% Android? I couldn't tell ya! I'm just happy that I got to keep writing JS without sacrificing too much in terms of quality.
      </p>
  </body>

</html>]]></description><link>http://maxogden.com/building-webview-applications.html</link><guid isPermaLink="true">http://maxogden.com/building-webview-applications.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Mon, 15 Oct 2012 20:48:11 GMT</pubDate></item><item><title><![CDATA[Fast WebView Applications]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Fast WebView Applications</title>
  </head>
  
  <body>
    <div id="header">
      
<h1 class="title">Fast WebView Applications</h1>

      
<h2 class="author">Max Ogden</h2>

    </div>
    <p>Article version of a JSConf Argentina presentation given in May 2012</p>
    <h1 id="tldr">tl;dr</h1>
      <p>Embedded mobile <a href="http://developer.apple.com/library/ios/#documentation/uikit/reference/UIWebView_Class/Reference/Reference.html">WebViews</a> have
        bad default behaviors that result in slow applications. To help fix the
        bad defaults I started some new libraries, <a href="https://github.com/maxogden/ViewKit">ViewKit</a> and
        <a href="https://github.com/maxogden/masseuse.js">masseuse.js</a>, and found some helpful libraries written by others. Additionally,
          all of the specific things covered in this article have associated code
          examples available in <a href="https://github.com/maxogden/fast-webview-applications-presentation">https://github.com/maxogden/fast-webview-applications-presentation</a>
      </p>
      
<h1 id="why-not-go-full-native">Why not go &quot;full native&quot;?</h1>

      <p>Having been recently tasked with writing <a href="https://gather.at/">an iPhone application</a> I
        found myself at a fork in the road. Going down the path of Objective-C
        meant diving head first into a painful world of static typing, subclassing,
        IDEs, closed source frameworks and cultish fanaticism. The other path,
        JavaScript and HTML5, is one I have been working with every day for years.
        For me the natural choice would be to work with the tools I knew best,
        but I also recognized that most developers who write iPhone applications
        choose Objective-C so there would be a lot (see: tons) of rough edges along
        the road less traveled.</p>
      
<h1 id="cordova">Cordova</h1>

      <p>I ended up using <a href="http://incubator.apache.org/cordova/">Cordova</a> (formerly
        PhoneGap). The name Cordova comes from <a href="http://goo.gl/maps/HLRM">the street</a> in
        Vancouver, Canada that was home to the software developers who built the
        framework, but the project's goals actually remind me a lot of the Spanish
        city of <a href="http://en.wikipedia.org/wiki/C%C3%B3rdoba,_Andalusia">Cordoba</a> (Cordova
        is actually the English form of Cordoba according to Encyclopedia Britannica).
        Around 1000 years ago Spain was filled, like much of pre-enlightenment
        western Europe, with people who got all of their information from the church.
        Then Muslims from northern Africa started moving into southern Spain and
        spread their ideology: to seek knowledge through science. Cordoba quickly
        became the most incredible city in the world with paved streets, street
        lights (gas powered), public hospitals, universities, medical schools,
        restaurants and the world’s largest library.</p>
      <p>The whole Objective-C vs JavaScript debate is a modern version of what
        happened in Spain back in the day. Then: The church delivered the facts
        and you weren't encouraged to modify them. Now: Apple delivers SDKs and
        developers aren't allowed to modify them. Then: Cordoba made giant leaps
        and bounds due to a culture of open science. Now: JavaScript has created
        of the <a href="https://github.com/popular/watched">largest</a> open source
        projects and <a href="http://www.modulecounts.com/">fastest growing</a> package
        repositories.</p>
      <blockquote>
        <p>Contemporary Muslims who bring up the memory of Cordoba typically do so
          either to emphasize the need for a new Islamic scientific and industrial
          renaissance, or to emphasize the need for a multi-cultural and tolerant
          society.</p>
      </blockquote>
      <p>— <a href="http://www.el-baghdadi.com/projects/the-islamic-paradigm/56-cordoba-victory-over-christianity.html">via</a>
      </p>
      <p>Cordova gives you a nice platform to build HTML5 iOS apps on top of. Essentially
        Cordova wraps a full screen WebView in a native app 'container' so you
        get nice things like the ability to call from JavaScript into Objective-C
        to do things like send and receive <a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/PushNotification">push notifications</a>,
        <a href="http://docs.phonegap.com/en/1.7.0/cordova_media_capture_capture.md.html#Capture">take photos</a>, integrate with SDKs (<a href="https://github.com/phonegap/phonegap-plugins/tree/master/iOS/Twitter">Twitter</a> and
          <a href="https://github.com/davejohnson/phonegap-plugin-facebook-connect">Facebook</a>for example), etc. At the end of the day, though, most of
            your time will be spent working on the HTML, CSS and JS that runs in that
            WebView. The harsh reality is that where Apple ships both the platform
            and the UI framework together, Cordova is just the platform. You are expected
            to BYOUI.</p>
      <p>Even though Cordova implements the same <a href="http://docs.phonegap.com/en/1.7.0/index.html">core JS API</a> across
        many platforms many mobile developers will tell you a bigger issue is that
        WebKit is turning into the new Internet Explorer: huge <a href="http://www.bgr.com/2012/05/16/android-fragmentation-visualized-opensignalmaps/">fragmentation in the Android market</a> and
        a we-do-whatever-we-want attitude at Apple means it's not realistic to
        expect the code that runs in a WebView on iOS5 to run on iOS4 or an Android
        browser. Because of these issues I decided to first target iOS5 and then
        port to other platforms later.</p>
      <p>There are a few big frameworks for iOS like <a href="http://jquerymobile.com/">jQuery Mobile</a> and
        <a href="http://www.sencha.com/products/touch">Sencha Touch</a>but having built web apps with them in the past I always
          felt too constricted by their monolithic approach. Instead, I prefer a
          small modules loosely joined approach.</p>
      
<h1 id="touch-events">Touch Events</h1>

      <p>The first thing you'll want to do is speed up your clicks. By default
        in WebViews there is a ~300ms delay if you are responding to <code>click</code> events.
        This is for capturing certain gestures like double tap to zoom in. Since
        we are in a viewport controlled unzoomable application container we don't
        actually want this behavior but sadly there is no easy way to disable this
        and make clicks fast again. <code>touch</code> events, on the other hand,
        have no artificial delay. Google has offered up <a href="https://developers.google.com/mobile/articles/fast_buttons">one solution to this problem</a> but
        I find their approach requires tight coupling between events and DOM elements.
        Rather than having a 1:1 ratio between DOM elements and their associated
        event listeners I instead use a few global listeners that aren't tightly
        coupled to any specific DOM elements.</p>
      <p><a href="https://github.com/maxogden/masseuse.js">masseuse.js</a> is a
        library I wrote that includes all of the touch related helpers (in a less
        contrived form than this post) that I developed while working on my application.</p>
      <p>
        <video preload="none" poster="media/doinitwrong.jpg" controls>
          <source src="media/doinitwrong.m4v">
            <source src="media/doinitwrong.ogv">
        </source></source></video>
      </p>
      <p><i>Strange default behavior.</i>
      </p>
      <p>The numbers shown are a rough calculation of the time between when the
        user's finger touches the screen to when the associated <code>click</code> event
        finishes firing.</p>
      <p>Beyond the click delay there are also certain CSS properties enabled in
        WebViews that can create a confusing UX (as you can see in the above video).
        Here's a rundown (via the <a href="http://wiki.phonegap.com/w/page/16494795/iPhone%3A%20Prevent%20callout,%20link%20selection,%20text%20auto-resize">PhoneGap wiki</a>):</p>
<pre><code data-language="css">* {
  /* prevent callout when holding tap on links (the native dialog that comes up) */
  -webkit-touch-callout: none; 

  /* prevent webkit from resizing text to fit */
  -webkit-text-size-adjust: none; 

  /* make transparent link selection, adjust last value opacity 0 to 1.0 */
  -webkit-tap-highlight-color: rgba(0,0,0,0);

  /* prevent copy paste, to allow, change &#39;none&#39; to &#39;text&#39; */
  -webkit-user-select: none; 
}

// turn off webkit checkbox style, works for other inputs too
input[type=&quot;checkbox&quot;] { -webkit-appearance: none; }

// placeholder text opacity
input::-webkit-input-placeholder { opacity: .8; }</code></pre>

      <p>To fix slow touches you must turn off <code>click</code> events for each
        kind of element that needs to be fast:</p>
<pre><code data-language="javascript">$(&#39;a&#39;).live(&#39;click&#39;, function(e) {
  e.preventDefault()
  return false
})</code></pre>

      <p>To replace clicks you can use the <code>tap</code> abstraction from zepto.js
        to handle touch events:</p>
<pre><code data-language="javascript">$(&#39;a&#39;).live(&#39;tap&#39;, handleTaps)</code></pre>

      <p>Since we are disabling <code>click</code> we are also throwing away the
        native behavior that we get from <code>click</code> events (focus for inputs,
        href changes for anchor tags, checkbox checking, etc) so we will have to
        re-implement that behavior in javascript. To implement this for anchor
        tags in a very rudimentary way:</p>
<pre><code data-language="javascript">function handleTaps( event ) {
  window.location.href = $(event.currentTarget).attr(&#39;href&#39;)
}</code></pre>

      <p>
        <video preload="none" poster="media/touchevents.jpg" controls>
          <source src="media/touchevents.m4v">
            <source src="media/touchevents.ogv">
        </source></source></video>
      </p>
      <p><i>Fast clicks and CSS disabling in action</i>
      </p>
      
<h1 id="zepto">Zepto</h1>

      <p><a href="http://zeptojs.com/">Zepto</a> is a jQuery API compatible library
        designed specifically for WebKit so it is smaller and much more easy to
        read because it doesn't aim to support every weird browser under the sun.
        It also has some nice mobile specific modules like <a href="https://github.com/madrobby/zepto/blob/master/src/gesture.js">gesture</a> and
        <a href="https://github.com/madrobby/zepto/blob/master/src/touch.js">touch</a>.</p>
      
<h1 id="templating-and-routing">Templating and Routing</h1>

      <p>Client side templating is good for mobile apps, as you wouldn't want to
        fetch remote templates over a wireless connection.</p>
      <p>There are a ton of templating and routing engines out there, so you can
        pick whichever one you like! I happen to use mustache.js and director.js
        because they are nice and simple. Here's a simple example:</p>
<pre><code data-language="javascript">// render a template and insert it into the dom
function render( template, target, data ) {
  target = $( target ).first()
  target.html( buildTemplate(template, data) )
}

// gets templates out of hidden &lt;script&gt; tags in the DOM:
function buildTemplate(template, data) {
  return $.mustache( $( &quot;.&quot; + template + &quot;Template&quot; ).first().html(), data || {} )
}

var routes = {
  cats: function() {
    var cats = [&#39;aristotle.png&#39;, &#39;bikecat.png&#39;, &#39;awesomecat.gif&#39;, &#39;walkingcat.png&#39;, &#39;seriouscat.png&#39;]
    render(&#39;gallery&#39;, &#39;.content&#39;, {pictures: cats})
  },
  dogs: function() {
    var dogs = [&#39;hellodog.png&#39;, &#39;shopdog.png&#39;, &#39;bearddog.png&#39;, &#39;coco.png&#39;]
    render(&#39;gallery&#39;, &#39;.content&#39;, {pictures: dogs})
  }
}

// Router is provided by Director
Router({
  &#39;/&#39;: {
    on: function() { window.location.href = &quot;#/cats&quot; }
  },
  &#39;/:page&#39;: { 
    on: function(page) {
      routes[page]()
    }
  }
}).init(&#39;/&#39;)</code></pre>

      <p>
        <video preload="none" poster="media/templating.jpg" controls>
          <source src="media/templating.m4v">
            <source src="media/templating.ogv">
        </source></source></video>
      </p>
      <p><i>The above code in action.</i>
      </p>
      <p>To get the fixed header and nice scroll behavior of the content div in
        the above: as of iOS5 you can use CSS to assign native scroll behavior
        to a DOM element:</p>
<pre><code data-language="css">.content { -webkit-overflow-scrolling: touch; }</code></pre>

      <p>To get this behavior on pre-iOS5 WebViews you have to use JS libraries
        like <a href="http://cubiq.org/iscroll">iScroll</a>. I personally have found
        most of these libraries to be very clunky to work with.</p>
      
<h1 id="sprites-and-retina-images">Sprites and Retina Images</h1>

      <p>When testing on device I noticed significant latency when loading images
        from the filesystem. Given the following CSS, when you tap on an input
        it will focus before the image loads and appears, which makes the app feel
        slow.</p>
<pre><code data-language="css">input { background-image: url(&#39;images/text.png&#39;) }
input:focus { background-image: url(&#39;images/text-focus.png&#39;) }</code></pre>

      <p>
        <video preload="none" poster="media/nosprite.jpg" controls>
          <source src="media/nosprite.m4v">
            <source src="media/nosprite.ogv">
        </source></source></video>
      </p>
      <p><i>Image load time in the simulator. On actual devices it is even more noticeable.</i>
      </p>
      <p>If you look closely at the icons in the input fields you'll see that they
        are grainy, as the simulator in that video is simulating a retina display.
        To support retina devices I would have to have a copy of each CSS rule
        inside of a media query:</p>
<pre><code data-language="css">@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  input { background-image: url(&#39;images/text@2x.png&#39;) }
  input:focus { background-image: url(&#39;images/text-focus@2x.png&#39;) }
}</code></pre>

      <p>This isn't very maintainable as it would double the amount of CSS required
        to show images. Instead, I create sprites using the glue utility:</p>
<pre><code>glue images/ . --simple --algorithm=vertical</code></pre>

      <p>This will give me a single sprite png as well as CSS rules based on the
        filenames of the original images from within the sprite, so now my CSS
        looks like this:</p>
<pre><code data-language="css">.sprite { 
  background-image: url(sprite.png);
  background-repeat:no-repeat;
}
.sprite.text { background-position:0px 0px; }
.sprite.text:focus { background-position:0px -40px; }

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  .sprite {
    background-image: url(&#39;sprite@2x.png&#39;);
    background-repeat:no-repeat;
    background-size: 40px 160px;
  }
}</code></pre>

      <p>Now I don't have to re-define each element with a sprite inside of the
        media query -- I only need to swap out all elements with a <code>sprite</code> class
        on them with the retina sprite. The small caveat here is that I have to
        add the <code>sprite</code> class to each element in the markup that uses
        a sprite for it's background image:</p>
<pre><code>&lt;input type=&quot;text&quot; name=&quot;name&quot; class=&quot;text sprite&quot; value=&quot;&quot; placeholder=&quot;Name&quot;&gt;</code></pre>

      <p>
        <video preload="none" poster="media/sprite.jpg" controls>
          <source src="media/sprite.m4v">
            <source src="media/sprite.ogv">
        </source></source></video>
      </p>
      <p><i>With the retina sprite enabled. Again, on an actual device the improvement is much more noticeable.</i>
      </p>
      <p>There are lots of WebView quirks not related to performance that I will
        save for another blog post.</p>
  </body>

</html>]]></description><link>http://maxogden.com/fast-webview-applications.html</link><guid isPermaLink="true">http://maxogden.com/fast-webview-applications.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Thu, 31 May 2012 20:48:11 GMT</pubDate></item><item><title><![CDATA[Node Streams: How do they work?]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Node Streams: How do they work?</title>
  </head>
  
  <body>
    <div id="header">
      
<h1 class="title">Node Streams: How do they work?</h1>

      
<h2 class="author">Max Ogden</h2>

    </div>
    <p>Description of and notes on the node.js Stream API</p>
    <center>
      <p>There is also <a href="http://www.youtube.com/watch?feature=player_embedded&v=tnXz4HigcoI#!">a screencast</a> version
        of this article.</p>
    </center>
    
    <h1 id="what-are-streams"><bold>UPDATE:</bold> new information about Node >= 0.10</h1>
        <p>
          Since writing this blog post (back in the Node 0.6 days) there have been major changes made to the Node Stream API. In Node 0.10 a new version of Streams called Streams2 were released. Here is a summary of using Streams2.
        </p>
        <p>
         <h2>
          <a name="user-content-how-to-destroyend-streams-in-node--010" class="anchor" href="#how-to-destroyend-streams-in-node--010" rel="noreferrer"><span class="octicon octicon-link"></span></a>how to destroy/end streams in node &gt;= 0.10</h2>

            <ul class="task-list">
              <li>usually you call <code>.destroy()</code> if it has <code>.destroy</code>

              </li>
              <li>if it doesnt have <code>.destroy</code> you are out of luck and the stream
                should upgrade to use e.g. newer <code>through2</code>

              </li>
              <li>in request you call <code>.abort()</code> (this should get fixed to use <code>.destroy()</code>)</li>
            </ul>
  
          <h3>
          <a name="user-content-what-about-close-end" class="anchor" href="#what-about-close-end" rel="noreferrer"><span class="octicon octicon-link"></span></a>what about close, end</h3>

            <ul class="task-list">
              <li>usually no <code>.close</code> method exists except in FD backed streams
                (usually only <code>fs</code>). usually you would never call <code>.close()</code>

              </li>
              <li>
          <code>.end()</code> tries to end the stream gracefully</li>
            </ul>
  
          <h3>
          <a name="user-content-what-about-events" class="anchor" href="#what-about-events" rel="noreferrer"><span class="octicon octicon-link"></span></a>what about events</h3>

          <ul class="task-list">
              <li>
          <code>finish</code> event is emitted when a stream ends nicely (e.g. <code>stream.end()</code>)</li>
              <li>
          <code>close</code> and <code>error</code> events are emitted when a stream
                ends due to failure (e.g. <code>stream.destroy()</code>)</li>
              <li>
          <code>end</code> is emitted when a readable stream has no more data</li>
              <li>
          <code>end</code> in streams2 behaves more like a flush event, it only gets
                emitted when the data has been read from the readable</li>
            </ul>
        </p>
    
<h1 id="why-streams">Why Streams?</h1>

    <p>node bills itself as <em>JavaScript evented I/O</em>. In a nutshell that
      means if you are trying to solve a problem that is <em>I/O bound</em> (the
      limiting factor is reading/writing to relatively slow interfaces) then
      node can provide some useful abstractions to you. An example is if you
      are writing an application that has to talk to multiple databases, a caching
      layer, a load balancer, external web services, mobile clients, third party
      auth providers and serve web applications then node acts as a nice glue
      between all of the things.</p>
    <p><em>&quot;Streams in node are one of the rare occasions when doing something the fast way is actually easier. SO USE THEM. not since bash has streaming been introduced into a high level language as nicely as it is in node.&quot;</em>
    </p>
    <p><em>-</em><a href="http://twitter.com/dominictarr">@dominictarr</a> in
      his <a href="https://gist.github.com/2401787">high level node style guide</a>
    </p>
    
<h1 id="what-are-streams">What are Streams?</h1>

    <p>The main tool in node's evented toolbox is the <a href="http://nodejs.org/api/stream.html">Stream</a>.
      Stream instances are basically Unix pipes. They can be readable, writable
      or both and are easy to reason about -- you can pipe a readable stream
      to a writable stream by doing <code data-language="javascript">readableStream.pipe(writableStream)</code>.</p>
    <h2 id="readable">Readable</h2>
      <p>Readable streams will emit <code>data</code> events each time they get a
        &quot;chunk&quot; of data and then they will emit <code>end</code> when they
        are all finished. emit (from <a href="http://nodejs.org/api/events.html">EventEmitter</a>)
        is the observer pattern - a publish/subscribe pattern which allows a number
        of observer objects to see an event. Different types of streams will have
        different ways of chunking up their data. For example, a library that reads
        CSVs might emit <code>data</code> every time it reads a new line whereas
        an HTTP request might emit <code>data</code> every few kilobytes during the
        download.</p>
      <p>Readable streams can also be paused and resumed, and it's up to the Stream
        implementer to write the <code>pause()</code> and <code>resume()</code> methods.
        Pause is intended to be an advisory API meaning when you call it you are
        telling the stream to stop emitting <code>data</code> events but you may
        still receive some <code>data</code> events after you call pause because
        certain things may already <em>in-flight</em>, or between states at the
        moment you called pause.</p>
      
<h2 id="writable">Writable</h2>

      <p>Writable streams must implement two functions: <code>write</code> and <code>end</code>.
        When you write data to a writable stream it will return either <code>true</code> or <code>false</code>. <code>true</code> means <em>cool, keep sending more data with write</em> and <code>false</code> means <em>Uh-oh I am backed up -- don't write any more data until I emit drain</em>.</p>
      <p>This is a form of <em>back pressure</em> which is a very powerful feature
        as it lets stream communicate &quot;upstream&quot; to their writers. Most
        of the back pressure related APIs are advisory so there is sort of a gentlemens
        agreement to honor requests to start or stop writing as timely as possible.
        However, since they are advisory it means a writable stream may still receive <code>write</code> calls
        after it returns <code>false</code>.</p>
      
<h1 id="streams-on-the-client">Streams on the client</h1>

      <p>After working with node for a while I came to love the Stream API (
        <a href="https://gist.github.com/2401787">and I'm not the only one</a>) but sorely missed it when I had to deal
          with the variety of I/O bound APIs in the client side realm. Some examples
          of these are XHR, WebSockets, IndexedDB, WebWorkers, WebRTC, and DOM Events
          (mouse, touch, etc). Wouldn't it be great if you could use the same node
          style Stream semantics to interface with all of these things? Unfortunately
          it seems that standards bodies have instead implemented their own (usually
          inconsistent or poorly done) streaming semantics for the client.</p>
      <p>I thought it would be useful to write something like <code data-language="javascript">fingerSwipe.pipe(webSocket)</code> (pseudo-code
        for detecting swipe <code>touch</code> events and streaming them to the server
        as they happen over a WebSocket connection) so I started a project called
        <a href="https://github.com/maxogden/domnode/">domnode</a>which intends to wrap common I/O bound APIs in node style streams
          so that you can render them into the DOM easily.</p>
      <p>There is a magical project by <a href="http://twitter.com/substack">@substack</a> called
        <a href="http://github.com/substack/node-browserify">browserify</a>that makes domnode possible. It lets you write code in client
          side JS that looks like node code:</p>
<pre><code data-language="javascript">var stream = require(&#39;stream&#39;)
var util = require(&#39;util&#39;)
   
function XHRStream(xhr) {
  stream.Stream.call(this)
  xhr.onreadystatechange = function () { me.handle() }
  xhr.send(null)
}

util.inherits(XHRStream, stream.Stream)</code></pre>

      <p>The best part about browserify is that it avoids reinventing the wheel/not
        invented here by letting you use the pure JavaScript parts of node or thousands
        of third party modules while maintaining node's simplified require API.
        Since browserify uses node's source code verbatim you get to use the
        <a href="http://nodejs.org/api/">node documentation</a>as well as the multitude of related information
          floating around on the internets to look up how these things work.</p>
      <p><a href="http://twitter.com/dominictarr">@dominictarr</a> contributed a
        Stream wrapper for Socket.io called <a href="https://github.com/dominictarr/browser-stream">browser-stream</a> that
        nicely integrates with domnode so you can emit things from node and rest
        assured that they will make their way into your web app.</p>
      
<h1 id="streams.next">Streams.next</h1>

      <p>As wonderful as streams are today, they can definitely use some improvements.
        <a href="http://twitter.com/izs">@izs</a>tells me node v0.9 is going to feature a major Stream overhaul
          to make the API even more unified. When node started it created a few domain
          specific evented I/O abstractions for things like the filesystem or TCP
          and then later, around 0.4, it consolidated them into the Stream API we
          have today, but there are still some vestigial phantoms lurking around.</p>
      <p>One of the major blemishes is the collection of methods used end a stream. <code>destroy()</code> initiates
        a forceful end to a stream, whereas <code>destroySoon()</code> and <code>end()</code> both
        wait for the current data to finish buffering. <code>end()</code> and <code>destroySoon()</code> came
        from different parts of node originally but after being consolidated into
        Streams they have some overlap and can probably be redesigned.</p>
      <p>There is also some confusion between the <code>close</code> and <code>end</code> events. <code>end</code> means <em>no more data will be emitted but if this stream is also writable it should stay open for more writes if they need to happen</em> and <code>close</code> means <em>whatever this thing was tied to, it's done now. you may dispose of it, it's gone</em>.
        Close comes from the <code>fs.close()</code> method and end is tied to the <code>end()</code> function
        on Streams and as you can see these can probably be refactored.</p>
      <p>Another possibility is that streams will get automagic buffering. This
        means that if you create a writable stream but haven't yet piped it anywhere
        then it will buffer any data you write to it and then emit that data when
        someone asks for it later. This same behavior will be available if you
        pause a stream and then resume later. Currently you have to roll your own
        buffered stream implementation or use a generic third party module like
        <a href="https://github.com/mikeal/morestreams/blob/master/main.js">BufferedStream</a>by <a href="http://twitter.com/mikeal">@mikeal</a>.</p>
      <h1 id="code-examples">Code examples</h1>
        
<h2 id="simplified-writable-stream">Simplified writable stream</h2>

<pre><code data-language="javascript">var writestream = new stream.Stream()
writestream.writable = true
writestream.write = function (data) {
  return true // true means &#39;yes i am ready for more data now&#39;
  // OR return false and emit(&#39;drain&#39;) when ready later
}
writestream.end = function (data) {
  // no more writes after end
  // emit &quot;close&quot; (optional)
}

writestream.write({number: 1})
// note: in node core data is always a buffer or string</code></pre>

        <h2 id="simplified-stream.pipe-implementation">Simplified Stream.pipe() implementation</h2>
<pre><code data-language="javascript">var readstream = new stream.Stream()
readstream.readable = true

readstream.on(&#39;data&#39;, function(data) {
  var ready = writestream.write(data)
  if (ready === false) {
    this.pause()
    writestream.once(&#39;drain&#39;, this.resume.bind(this))
  }
})

readstream.on(&#39;end&#39;, function() {
  writestream.end()
})</code></pre>

  </body>

</html>]]></description><link>http://maxogden.com/node-streams.html</link><guid isPermaLink="true">http://maxogden.com/node-streams.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Tue, 17 Apr 2012 23:52:20 GMT</pubDate></item><item><title><![CDATA[Gut: Hosted Open Data Filet Knives]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Gut: Hosted Open Data Filet Knives</title>
  </head>
  
  <body>
    <div id="header">
      
<h1 class="title">Gut: Hosted Open Data Filet Knives</h1>

      
<h2 class="author">Max Ogden</h2>

    </div>
    <p>HTTP Unix pipes for Open Data</p>
    
<h1 id="not-invented-here">Not Invented Here</h1>

    <p>A topic that has fascinated me for years now is (broadly speaking) <a href="http://en.wikipedia.org/wiki/Nationalism">nationalism</a>.
      In the world of the internet that essentially boils down to something like
      &quot;<em>I am a Python programmer and this project is written in Java! Ignored!&quot;</em>.
      It is this behavior (which I see a lot in programming, mostly manifested
      as &quot;<a href="http://en.wikipedia.org/wiki/Not_invented_here">Not invented here</a>&quot;)
      that leads to a bunch of solutions to the same problem written in a bunch
      of different languages where many of the solutions are half-baked.</p>
    <p>For a concrete example consider open data catalogues. As evidenced by
      <a href="http://datacatalogs.org">datacatalogs.org</a>there are a ton of different solutions to the same
        set of problems, namely hosting open data. Having a rich ecosystem is a
        good thing, but I believe that there is a common open data infrastructure
        layer that we aren't maximizing our collaborating on: the conversion of
        data between different formats.</p>
    <p>Wouldn't it be great if I, as a Javascript developer, could use the awesome
      data conversion libraries available in Java like <a href="http://poi.apache.org">Apache POI</a>?
      Or if Ruby developers could use Python packages like <a href="https://github.com/onyxfish/csvkit">csvkit</a> (which
      contains the super useful csvclean utility). The good news is that the
      internet has settled on a common language for crossing these language barriers:
      HTTP and JSON. Additionally, nowadays the web is filled with hosted services
      (see SaaS, PaaS). There are numerous platforms where hosted services can
      be deployed for free (Google App Engine, Heroku, Dotcloud, Nodejitsu, etc).</p>
    <h1 id="unix-pipes">Unix pipes</h1>
      <p>On the Unix command line there are a bunch of useful single purpose utilities.
        The <a href="http://en.wikipedia.org/wiki/Unix_philosophy">Unix philosophy</a> is <em>&quot;write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface&quot;</em>.
        The Unix command <code>wc</code> is a great example. You give it a bunch
        of text and it will count the number of words, lines and characters. Combined
        with the <code>cat</code> command, which reads and file and dumps out all
        the text, you can use a Unix pipe (the | character) to 'pipe' the data
        that <code>cat</code> dumps out into <code>wc</code>:</p>
<pre><code>cat awesomeText.txt | wc
21      55     507</code></pre>

      
<h1 id="what-is-gut">What is gut</h1>

      <p>Taking heavy inspiration from unix pipes, HTTP and JSON I have come up
        with a modest proposal for how we might share our best tools for various
        data conversion jobs as hosted web services. I'm calling it gut, as in
        gutting a fish and getting the yummy filet out while leaving behind all
        of the junk.</p>
      <p>Here's a simple example of how a gut server would work that takes in a
        CSV file and returns JSON data. As a developer using the gut server to
        process my CSV file I would send the following HTTP request containing
        my CSV data:</p>
<pre><code>POST / HTTP/1.1
User-Agent: curl
Host: gutcsv.nodejitsu.com
Accept: */*
Content-Length: 64
Content-Type: application/x-www-form-urlencoded

name,appearance
chewbacca,hairy
bill,nonplussed
bubbles,relaxed</code></pre>

      <p>This is what the gut server would give me back:</p>
<pre><code>POST / HTTP/1.1
host: gutcsv.nodejitsu.com
content-type: application/json
content-length: 186
Connection: close
  
{
  &quot;headers&quot;: [
    {
      &quot;name&quot;: &quot;name&quot;
    },
    {
      &quot;name&quot;: &quot;appearance&quot;
    }
  ],
  &quot;rows&quot;: [
    {
      &quot;name&quot;: &quot;chewbacca&quot;,
      &quot;appearance&quot;: &quot;hairy&quot;
    },
    {
      &quot;name&quot;: &quot;bill&quot;,
      &quot;appearance&quot;: &quot;nonplussed&quot;
    },
    {
      &quot;name&quot;: &quot;bubbles&quot;,
      &quot;appearance&quot;: &quot;relaxed&quot;
    }
  ]
}</code></pre>

      <p>Essentially I am piping data from my computer through a gut server and
        when it comes back it is in the new format. In this example I used the
        node.js hosting platform Nodejitsu to deploy my CSV-to-JSON code so that
        it is available to anyone in the world who can make an HTTP request.</p>
      <h1 id="voltron-assemble">Voltron, assemble!</h1>
        <p>If you are writing code that converts data from one format to another,
          consider also exposing your solution in the form of a gut server! Last
          year I had great success at <a href="http://opendataday.org">International Open Data Day</a> teachin
          ScraperWiki because it scaled out well to a room full of people with different
          programming backgrounds. I think that writing these lightweight data converters/massagers/transformer
          servers is also a task that anyone can tackle in a short amount of time.</p>
        <p>There is a <a href="https://github.com/maxogden/gut">Github project</a> that
          contains the current gut servers that I have been working on and also a
          <a href="https://github.com/maxogden/gut/wiki/List-of-gut-servers">wiki page</a>where you can add your gut server to the list. Once there
            are a handful of gut servers we can start working on more extensive discovery
            and testing tools (ensuring gut server availability, better documentation,
            web based gut server API playground, etc).</p>
  </body>

</html>]]></description><link>http://maxogden.com/gut-hosted-open-data-filets.html</link><guid isPermaLink="true">http://maxogden.com/gut-hosted-open-data-filets.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Fri, 02 Dec 2011 20:36:31 GMT</pubDate></item><item><title><![CDATA[Little Coders]]></title><description><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta name="generator" content="pandoc">
    <meta name="author" content="Max Ogden">
    <title>Little Coders</title>
  </head>
  
  <body>
    <div id="header">
      
<h1 class="title">Little Coders</h1>

      
<h2 class="author">Max Ogden</h2>

    </div>
    <p>Elementary school programming</p>
    <p>My first foray into programming was in 1999 and happened accidentally
      inside the Starcraft custom level editor. I would sit, fully <a href="http://cyborganthropology.com/Paracosmic_Immersion">immersed in a paracosm</a>,
      and create complex storylines that the player could play through, one small
      objective at a time. You could specify, for instance, that if a Zergling
      walks onto a particular platform then an event should trigger. You could
      subscribe other elements of the game to listen for events on that platform
      and perform other callbacks. I was getting exposed to event based publish/subscribe
      asynchronous programming without realizing it.</p>
    <div class="figure">
      <img src="http://maxogden.com/media/sc_triggers.png" alt="triggers inside a Starcraft scenario">
      <p class="caption">triggers inside a Starcraft scenario</p>
    </div>
    <p>When my older brother asked me how to get his nine year old interested
      in programming, I told him to look for a programming environment that sacrifices
      practicality for imagination. Nine year olds aren't worried about vendor
      lock in or job security, they are only going to get hooked if the feel
      like they are playing a video game (in my case with Starcraft I was literally
      playing a video game). A good example of this mentality is <a href="http://hacketyhack.heroku.com/">Hackety Hack</a> by
      _why the lucky stiff. Hackety Hack aims to &quot;offer a place for plainspeople
      to tinker with code&quot;. Here is a wonderful video from the <a href="http://www.flong.com/projects/artandcode/">Art &amp;&amp; Code Symposium</a> where
      _why talks about his thoughts on programming education for youngsters and
      shows off Hackety Hack. <a href="http://vimeo.com/5047563">Highly recommended viewing.</a>
    </p>
    <p>Near the end of the above video, _why describes a card game called Kaxxt
      that is designed to get little coders introduced to fundamental programming
      concepts. At it's core Kaxxt is about robots, lazers and pyramids. What
      nine year old wouldn't want to play that? When kids play this game they
      get exposed to ideas such as enumerability or thinking recursively, much
      in the same fashion that <a href="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;tid=4825">The Little Schemer</a> tries
      to &quot;present abstract concepts in a humorous and easy-to-grasp fashion&quot;.
      The Flash game <a href="http://armorgames.com/play/2205/light-bot">Lightbot</a> also
      comes to mind. In Lightbot, you visually program an animated robot through
      a series of puzzles. It seems that robots and lazers may be the key to
      connecting with today's youth.</p>
    <p>Sadly, _why mysteriously stopped contributing to his projects at some
      point in 2009, leaving many orphaned works behind. His projects have been
      adopted by various open source community members. <a href="http://blog.steveklabnik.com/2010/11/17/the-hardest-decision-i-ve-ever-made.html">Steve Klabnik</a> recently
      quit his job to courageously follow his heart and work on Hackety Hack
      full time. Similarly, <a href="http://kitenet.net/~joey/">Joey Hess</a> then
      took the liberty of creating an alpha, playtestable version of Kaxxt that
      uses the pieces from the board game <a href="http://boardgamegeek.com/boardgame/225/icehouse">Icehouse</a>.
      His port is called '<a href="http://kitenet.net/~joey/code/kaxxt/">Kaxxt on Ice</a>'</p>
    <p>There are also a few notable academic programming education efforts.
      <a href="http://www.greenfoot.org/">Greenfoot</a>is designed to teach kids Java. There is an entertaining
        <a href="http://blogs.kent.ac.uk/mik/2008/01/20/teaching-my-daughter-to-code/">series of posts</a>from a programmer who tried teaching his nine year
          old daughter how to program using Greenfoot. Google has been lightly researching
          alternative curriculum designs through their <a href="http://www.google.com/educators/index.html">Google for Educators</a> program.
          As described by Google's director of education relations in the tech talk
          &quot;<a href="http://www.youtube.com/watch?v=Hz4ZgC_A77g">Initiatives in Education</a>&quot;,
          Google has been working on &quot;integrating computing curriculum across
          K-12 core subjects&quot;. They also recently donated 2 million USD to Sal
          Khan's <a href="http://www.khanacademy.org/">Khan Academy</a>, which offers
          a staggering amount of free, digestible education lectures.</p>
    <p>MIT's <a href="http://scratch.mit.edu/">Scratch</a> and Carnegie Mellon's
      Alice seem to each have years of development poured into them, as well
      as some friendly competitionand actual in-classroom testing. At first glance,
      both Scratch and Alice appear deep and involved, much like a complicated
      programming IDE. I would personally like to see more lightweight artistic
      interpretations, mockups and spikes of the PhD level programming educational
      research that is happening between Google, MIT, Carnegie Mellon and elsewhere.
      In the Hackety Hack Manifesto it is explictly stated that&quot;IDEs are
      a disaster. Newbs should see only one non-scary window free of tree controls
      and pinned windows and toolbars. As such, we want to stay away from project
      files and makefiles, the trappings of an IDE.&quot;</p>
    <p>As part of my fellowship with <a href="http://codeforamerica.org/">Code for America</a> in
      2011 I will be working with the city of Boston on software to improve public
      school education (more details <a href="http://codeforamerica.org/2010/11/19/2011-projects-overview-video-and-deck/">here</a>).
      I am excited at the prospect of getting to meet those working on Scratch
      at MIT or researchers from the <a href="http://www.concord.org/">Concord Consortium</a>.</p>
  </body>

</html>]]></description><link>http://maxogden.com/little-coders.html</link><guid isPermaLink="true">http://maxogden.com/little-coders.html</guid><dc:creator><![CDATA[Max Ogden]]></dc:creator><pubDate>Sun, 17 Jul 2011 02:56:48 GMT</pubDate></item></channel></rss>