<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Guillermo Rauch&#039;s Devthought</title>
	<atom:link href="http://www.devthought.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devthought.com</link>
	<description></description>
	<lastBuildDate>Mon, 30 Jan 2012 16:38:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Staying up with Node.JS</title>
		<link>http://www.devthought.com/2012/01/29/staying-up-with-node-js/</link>
		<comments>http://www.devthought.com/2012/01/29/staying-up-with-node-js/#comments</comments>
		<pubDate>Sun, 29 Jan 2012 15:38:41 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Server side]]></category>

		<guid isPermaLink="false">http://www.devthought.com/?p=1360</guid>
		<description><![CDATA[To many beginner Node.JS users, a fundamental and immediate apparent disadvantage of writing their web applications with Node.JS lies in the inability to save a file, refresh the browser and see their changes live. This &#8220;problem&#8221; is rooted of course &#8230; <a href="http://www.devthought.com/2012/01/29/staying-up-with-node-js/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>To many beginner Node.JS users, a fundamental and immediate apparent disadvantage of writing their web applications with Node.JS lies in the inability to save a file, refresh the browser and see their changes live.</p>
<p>This &#8220;problem&#8221; is rooted of course in significantly different architectures. In the case of, for example, PHP applications we traditionally separate the role of the <strong>web server</strong> and <strong>request handler</strong>. The monolithic web server maps incoming requests to the execution of particular files in the file system, which become our handlers.</p>
<p>In most setups, the web server is mostly limited to inspecting two pieces of a HTTP request: the <strong>resource</strong> (like <code>/test.php</code>) and the <strong>Host</strong> header (like <code>www.mydomain.com</code>) for <em>virtual hosts (vhosts)</em> support.</p>
<p><span id="more-1360"></span></p>
<pre class="highlight" lang="bash">
GET /test.php HTTP/1.1
Host: www.mydomain.com
</pre>
<p>With this in place, it&#8217;s up to the execution of the &#8220;test.php&#8221; file to handle the work and produce the response. If we change this file, even while other requests are ongoing, subsequent requests will be handled by our new code.</p>
<p>In Node.JS, this separation is not part of the core design. You write your web server and requests handlers as part of the same unit. This of course is the result of a tradeoff: Node.JS offers <em>complete control</em> over how the entire system operates, allowing programmability of aspects beyond the execution of a request. This includes for example, control over the <em>connections</em> that trigger the requests, easy awareness of other connections/requests, and other details that made the development of software like <a href="http://socket.io">Socket.IO</a> possible.</p>
<div class="annotations">
<div class="annotation" style="top: 40px; left: 300px;">^ The web server</div>
<div class="annotation" style="top: 140px; left: 200px;">^ The request handler</div>
<pre class="highlight" lang="javascript">
var server = require('http').createServer(onRequest);
server.listen(80);

function onRequest (req, res) {
  res.writeHead(200);
  res.end('Hello world');
});
</pre>
</div>
<p>The need for seamless code reloads extends into the realm of production deployment as well: one needs to be able to serve new requests with fresh code immediately, without breaking existing ones (such as file uploads or content transfer).</p>
<h2>The up solution</h2>
<p>Over at <a href="https://www.learnboost.com">LearnBoost</a>, we&#8217;ve solved these problems with two small projects: <a href="http://github.com/learnboost/distribute">distribute</a> and <a href="http://github.com/learnboost/up">up</a>.</p>
<p>In order to reload code without dropping requests, no changes to a codebase are needed other than ensuring that there&#8217;s a file that exports a <code>http.Server</code> as a module (let&#8217;s call it <code>server.js</code>).</p>
<pre class="highlight" lang="javascript">
  var server = require('express').createServer();
  // … code
  module.exports = server;
</pre>
<p>Then, during development you can leverage <a href="http://github.com/learnboost/up">up</a> from the CLI:</p>
<pre class="highlight" lang="bash">
$ up --watch --port 8080 server.js
</pre>
<p>The <code>--watch</code> flag will watch the working directory for changes. <code>up</code> will start workers to handle the requests, and reload them seamlessly. Alternatively, one can also do this programmatically. In the following example I listen on the <code>SIGUSR2</code> signal to trigger a reload, which allows for easy interoperability between components.</p>
<pre class="highlight" lang="javascript">
var up = require('up')
  , master = http.createServer().listen(8080)

var srv = up(master, __dirname + '/server');

process.on('SIGUSR2', function () {
  srv.reload();
});
</pre>
<h2>The power to distribute</h2>
<p>The server returned by <code>up</code> builds on top of another LearnBoost project called <a href="http://github.com/learnboost/distribute">distribute</a>, which leverages <a href="http://github.com/nodejitsu/node-http-proxy">node-http-proxy</a> by <a href="http://nodejitsu.com">NodeJitsu</a></p>
<p>The idea is simple: we can handle requests to be proxied in a middleware-style API. This allows us to solve, for example, the lack of multiple VHosts:</p>
<pre class="highlight" lang="javascript">
var httpServer = require('http').createServer()
  , srv = require('distribute')(httpServer);

httpServer.listen(80);

srv.use(function (req, res, next) {
  if ('blog.learnboost.com' == req.headers.host) {
    next(3500); // port 3500
  } else {
    next(3000); // otherwise port 3000
  }
});
</pre>
<p>And since it&#8217;s possible to re-use and chain multiple middleware functions together, it provides a proven foundation for code re-usability. In fact, it&#8217;s possible to leverage existing Express/Connect middleware like query string or cookie parsing, should a certain proxying function need it.</p>
<p>Head to <a href="http://github.com/learnboost">GitHub</a> for the projects, or find them on NPM as <code>distribute</code> and <code>up</code>. And stay tuned for an upcoming distribute middleware component release.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2012/01/29/staying-up-with-node-js/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>A tweet filtering proxy with Node.JS: Part 1</title>
		<link>http://www.devthought.com/2012/01/24/filtering-tweets-for-your-favorite-client-with-node-js/</link>
		<comments>http://www.devthought.com/2012/01/24/filtering-tweets-for-your-favorite-client-with-node-js/#comments</comments>
		<pubDate>Tue, 24 Jan 2012 20:16:57 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Server side]]></category>

		<guid isPermaLink="false">http://www.devthought.com/?p=1304</guid>
		<description><![CDATA[We all have that guy who tweets too much about a certain topic we dislike. Or all those hardcore seasonal fans of the current NFL sensation. Or those annoying spotify/rdio links you&#8217;re never going to click! I&#8217;ve been waiting for &#8230; <a href="http://www.devthought.com/2012/01/24/filtering-tweets-for-your-favorite-client-with-node-js/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>We all have that guy who tweets too much about a certain topic we dislike. Or all those hardcore seasonal fans of the current NFL sensation. Or those annoying spotify/rdio links you&#8217;re never going to click!</p>
<p>I&#8217;ve been waiting for a while for mainstream Twitter clients to allow keyword or pattern based filtering, and when I realized people were starting to tweet about the 49ers the night before the game, I decided to finally address it myself.</p>
<p>The technique I&#8217;m going to describe consists in setting up a proxy to the Twitter API that lives in our computer, powered by Node.JS, that filters back responses based on arbitrary rules we setup. Not only does this give us the flexibility of using JavaScript, but it also means it will work with <em>any</em> Twitter client that leverages the API transparently. Yes, this includes the Twitter website!</p>
<p><span id="more-1304"></span></p>
<h2>The premises</h2>
<p>Before we begin, we must fully understand how the majority of Twitter desktop (and mobile) clients work. </p>
<ol>
<li>
<p>The app first needs to authenticate the user. Two methods can be used:</p>
<p><strong>OAuth</strong>: relies on the user going to a web page that <em>grants</em> access.<br />
  <br /><strong>XAuth</strong>: asks for user and password. This is the most practical method of authentication for a custom client, and this is the technique that <em>Twitter for Mac</em> uses.</p>
</li>
<li>Once this authorization is successful, the Twitter client will make HTTP requests to the Twitter API (located at <code>api.twitter.com</code>). In order to make these requests on <em>behalf of the user</em>, it must first sign them. To sign a request means to add an <code>Authorization</code> header that&#8217;s created with a token obtained on step 1.</li>
<li>Just like any other application that leverages the API, the Twitter client will then exchange content in some format (XML or JSON).</li>
</ol>
<h2>Our plan of action</h2>
<ol>
<li>We&#8217;ll leverage the internal DNS lookup system (<code>/etc/hosts</code>) to override <code>api.twitter.com</code> and make it point to a Node.JS server hosted locally.</li>
<li>Since the Twitter client will attempt to connect to our overridden IP over port <code>443</code>, we&#8217;ll set up a <em>&#8220;second&#8221;</em> loopback interface <code>127.0.0.2</code>. This will prevent our Twitter hack from getting in the way of your projects and apps that try to serve traffic on port <code>443</code>.</li>
<li>To bypass SSL security checks in the client, we&#8217;ll set up a new root certificate for our computer that validates <code>127.0.0.2</code> claims that it is <code>api.twitter.com</code>.</li>
<li>We&#8217;ll forward all requests to Twitter, but we&#8217;ll capture the response of the timeline one to execute our filters.</li>
<li>We&#8217;ll expose a middleware API for filters to be setup.</li>
</ol>
<h2>Forwarding api.twitter.com</h2>
<p>Redirecting <code>api.twitter.com</code> to <code>127.0.0.2</code> is as straightforward as editing <code>/etc/hosts</code>:</p>
<pre class="highlight" lang="bash">
∞ ~ sudo sh -c "echo '127.0.0.2 api.twitter.com' >> /etc/hosts"
∞ ~ tail -n 1 /etc/hosts
127.0.0.2 api.twitter.com
</pre>
<h2>There&#8217;s no place like 127.0.0.2</h2>
<p>Our plan is to capture all the HTTPS traffic going to api.twitter.com over port <code>443</code>, by forwarding it to <code>127.0.0.2</code>. To accomplish this, we must first make that IP resolve to our loopback interface.</p>
<p>On OS X, we can accomplish this by aliasing it to <code>lo0</code>:</p>
<pre class="highlight" lang="bash">
∞ ~ sudo ifconfig lo0 alias 127.0.0.2
</pre>
<p>As a result, we can now bind to port <code>443</code> over distinct IP addresses. As a test, you can run the following Node programs (with <code>sudo</code>):</p>
<pre class="highlight" lang="javascript">
require('http').createServer(function (req, res) {
  res.writeHead(200);
  res.end('welcome to 127.0.0.1:80');
}).listen(80, '127.0.0.1');
</pre>
<pre class="highlight" lang="javascript">
require('http').createServer(function (req, res) {
  res.writeHead(200);
  res.end('welcome to 127.0.0.2:80');
}).listen(80, '127.0.0.2');
</pre>
<p>Pointing your browser to <code>http://127.0.0.1</code> and <code>http://127.0.0.2</code> will yield different responses.</p>
<h2>Port 443 or port 3000?</h2>
<p>In our previous Node servers examples, binding to port <code>80</code> forced us to use <code>sudo</code>, since it&#8217;s considered a <em>privileged port</em>. We can skip this every time we need to run our server by forwarding the traffic destined to port <code>443</code> over <code>127.0.0.2</code> to the unprivileged port <code>3000</code>:</p>
<pre class="highlight" lang="javascript">
∞ ~ sudo ipfw add fwd 127.0.0.2,3000 tcp from any to 127.0.0.2 443 in
</pre>
<p>As a result, we can now run code like this (notice I run <code>listen()</code> with <code>3000</code>)</p>
<pre class="highlight" lang="javascript">
function read (file) { return require('fs').readFileSync(__dirname + '/' + file, 'utf8'); };
require('https').createServer({
    key: read('key.key')
  , cert: read('cert.crt')
}, function (req, res) {
  res.writeHead(200);
  res.end('welcome to ' + req.headers.host + ' bound to 127.0.0.2:3000');
}).listen(3000, '127.0.0.2');
</pre>
<p>But still point our browser to <code>https://api.twitter.com</code>, just like the Twitter client will do:</p>
<p><img src="http://f.cl.ly/items/460U2u0Y0f1y3J3C3Q13/Image%202012.01.22%2010:31:03%20AM.png"></p>
<p>For this example, I used self signed certificates that will trigger a security warning. You can download this example from <a href="http://cl.ly/3X3Q3D1e2I0P0v321U1n">here</a>.</p>
<h2>Hacking SSL</h2>
<p>At this point, not only will our Twitter client be unable to make any requests (since we&#8217;re not proxying them yet), but it will be refuse to establish any connection at all, due to the SSL checks:</p>
<p><img src="http://f.cl.ly/items/0j0b1T2D2E2138413e1A/Image%202012.01.22%2010:39:05%20AM.png"></p>
<p>The client is onto us! Stop SOPA!</p>
<p>Thankfully, it&#8217;s fairly for us to create a new certificate Root (like <em>VeriSign</em>), then generate a certificate request that we sign our own Twitter certificate with. If we then install the root certificate at the system level, the Twitter client and browsers will recognize it as legitimate.</p>
<p>We start by creating our root. For this, we can leverage a perl script that ships with OpenSSL. We also first create a <code>~/root</code> directory where all the generated files will be kept:</p>
<pre class="highlight" lang="bash">
 ∞ ~ mkdir ~/root
 ∞ ~ cd ~/root/
 ∞ root perl /System/Library/OpenSSL/misc/CA.pl -newca
</pre>
<p>This will ask a series of questions, most of which you can respond with the default value. Set the passphrase when asked. When it asks for a <code>Common Name</code>, set it to something easily identifiable like &#8220;Guillermo&#8221;, in case you want to remove the root certificate in the future from your system.</p>
<p>The result will be the creation of a directory called <code>demoCA</code>, which contains the root certificate database.</p>
<p>Now that we rolled our own VeriSign, we want to do what we normally do when we get real certificates for our websites. Generate a key, generate a signing request and sign it ourselves:</p>
<pre class="highlight" lang="bash">
 ∞ root openssl genrsa 1024 > api.twitter.com.key
Generating RSA private key, 1024 bit long modulus
....++++++
.......++++++
e is 65537 (0x10001)
 ∞ root openssl req -new -key api.twitter.com.key -out newreq.pem
</pre>
<p>The second command will again ask a series of questions. The only one that matters is the <code>Common Name</code>. Set it to <code>api.twitter.com</code></p>
<p>Our friend the perl script can also aid in the process of signing a request file (in this case <code>newreq.pem</code>).</p>
<pre class="highlight" lang="bash">
 ∞ root perl /System/Library/OpenSSL/misc/CA.pl -sign
</pre>
<p>The signature process is very difficult and gruesome and that&#8217;s why certificates are very expensive: type in your passcode, write <code>y</code> and press enter.</p>
<p>The signature process will yield a file <code>newcert.pem</code>, which we want to rename to <code>api.twitter.com.crt</code> to easily identify it.</p>
<p>We now have the <code>.key</code> and <code>.crt</code> files that we&#8217;ll give to our Node web server. But before we let the Twitter client attempt a connection, we install the root certificate located at <code>~/root/demoCA</code> by double-clicking it:</p>
<p><img src="http://f.cl.ly/items/3i2l17320g3p0f3Y0z1R/Image%202012.01.22%2011:31:29%20AM.png"></p>
<h2>Proxying</h2>
<p>Let&#8217;s try setting up our newly signed certificate and outputting our incoming requests.</p>
<pre class="highlight" lang="javascript">
require('https').createServer({
    key: read('api.twitter.com.key')
  , cert: read('api.twitter.com.crt')
}, function (req, res) {
  console.error(' - \033[96m%s\033[90m %s\033[39m'
    , req.method, req.url);
  res.writeHead(500);
  res.end();
}).listen(3000, '127.0.0.2');
</pre>
<p>If we run our server and relaunch Twitter for mac, we should see the requests flowing in:</p>
<p><img src="http://f.cl.ly/items/1n313Y0g1a1p0V0e0Y0h/Image%202012.01.22%2011:38:58%20AM.png"></p>
<p>Our own Twitter client now trusts us! And since we're replying with status code <code>500</code>, it reflects it:</p>
<p><img src="http://f.cl.ly/items/2c2W2h0B0f2H1Q2z3R3P/Image%202012.01.22%2011:40:00%20AM.png"></p>
<p>Our proxying strategy is as follows:</p>
<ol>
<li>We capture all requests.</li>
<li>We create new requests (using <a href="http://github.com/visionmedia/superagent">superagent</a>) that we send to twitter over their IP (since <code>api.twitter.com</code> resolves to our own computer).</li>
<li>To avoid dealing with gzip, we want to re-write the responses to not include <code>Content-Encoding</code>. Ideally we'd also re-write the request to exclude <code>Accept-Encoding</code>, but this would invalidate the OAuth signature.</li>
<li>When the response comes back, we send it back unless it targets the <code>home_timeline</code> API endpoint.</li>
<li>For timeline requests, we parse the XML, we filter or change what we want, we re-encode it and send it back. Since we're changing the response body, some headers will need to be altered, like <code>Content-Length</code>.</li>
</ol>
<h2>Re-writing</h2>
<p>To illustrate the rewriting process, consider this example in which we replace all our tweets with the text "haha":</p>
<p><img src="http://f.cl.ly/items/322j3c1q462V3z3R2K33/Image%202012.01.24%208:52:53%20PM.png"></p>
<p>The first thing we want to do is detect the requests for the <code>home_timeline.xml</code> endpoint:</p>
<pre class="highlight" lang="javascript">
// detect timeline xml request
var filter = /home_timeline\.xml/.test(req.url);
</pre>
<p>Then, we want to buffer all the request data for the incoming request:</p>
<pre class="highlight" lang="javascript">
var data = '';
req.on('data', function (chunk) { data += chunk; });
req.on('end', function () {
  // …
});
</pre>
<p>We finally create our new request, and parse the XML with the excellent <a href="http://github.com/polotek/libxmljs">libxmljs</a> by Marco Rogers.</p>
<pre class="highlight" lang="javascript">
var proxy = request[req.method.toLowerCase()]
  ('https://199.59.149.232' + req.url)

if (data) proxy.send(data);

proxy.end(function (apiRes) {
  // delete content-encoding
  delete apiRes.headers['content-encoding'];

  // parse xml
  if (200 == apiRes.status &#038;&#038; filter) {
    var doc = libxml.parseXmlString(apiRes.text);
    doc.find('//text').forEach(function (node, i) {
      node.text('haha');
    });
    proxy(doc.toString());
  } else {
    proxy(apiRes.text);
  }

  function proxy(text) {
    // rewrite content-length
    apiRes.headers['content-length'] = text.length;
    res.writeHead(apiRes.status, apiRes.headers);
    res.end(text);
  }
});
</pre>
<p>This is a slightly over-simplified example. In reality, in order for the OAuth signature to stay valid we need to proxy the headers exactly as we receive them. Node.JS unfortunately lowercases all headers, and drops the original strings. I performed the following replacement to try to restore them to their originals based on convention:</p>
<pre class="highlight" lang="javascript">
for (var i in req.headers) {
  var h = i.replace(/^[a-z]|-[a-z]/g, function (a) {
    return a.toUpperCase();
  });
  proxy.set(h, req.headers[i]);
}
</pre>
<p>In part II I&#8217;ll describe the creation of the API that lives on top of the proxy to ease on the tweet re-writing and filtering process exposed to the end user through a NPM module.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2012/01/24/filtering-tweets-for-your-favorite-client-with-node-js/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>An Object is not a Hash</title>
		<link>http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/</link>
		<comments>http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 19:45:50 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Server side]]></category>

		<guid isPermaLink="false">http://www.devthought.com/?p=1279</guid>
		<description><![CDATA[Following my article A String is not an Error, I want to bring attention to an issue that similarly applies to JavaScript in general, but has special relevance in the Node.JS environment. The problem boils down to the usage of &#8230; <a href="http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Following my article <a href="http://www.devthought.com/2011/12/22/a-string-is-not-an-error/">A String is not an Error</a>, I want to bring attention to an issue that similarly applies to JavaScript in general, but has special relevance in the Node.JS environment.</p>
<p>The problem boils down to the usage of <code class="inline">{}</code> as a data-structure where the keys are supplied by untrusted user input, and the mechanisms that are normally used to assert whether a key exists.</p>
<p>Consider the example of a simple blog created with <a href="http://expressjs.com/">Express</a>. We decide to store blog posts in memory in a <code class="inline">{}</code>, indexed by the blog post slug. For example, this blog post would be <code class="inline">posts['an-object-is-not-a-hash']</code>.</p>
<p><span id="more-1279"></span></p>
<p>We start writing the route <code class="inline">/create</code>, which takes a few POST fields like &#8220;title&#8221; and &#8220;slug&#8221; and passes it to a <code class="inline">Post</code> constructor.</p>
<pre class="highlight" lang="javascript">
var posts = {};

app.post('/create', function (req, res) {
  if (req.body.title &#038;&#038; req.body.slug) {
    // avoid duplicates
    if (!posts[req.body.slug]) {
      posts[req.body.slug] = new Post(req.body);
      res.send(200);
    } else {
      res.send(500);
    }
  }
});
</pre>
<p>Our first stab for trying to avoid duplicates is checking whether the key exists in our object.</p>
<pre class="highlight" lang="javascript">
    if (!posts[req.body.slug]) {
</pre>
<p>Normally this would work fine, but let&#8217;s consider that the user could pick any of the keys that are present in <em>any JavaScript object</em> as a name:</p>
<pre class="highlight" lang="javascript">
 __defineGetter__       __defineSetter__          valueOf
 __lookupGetter__       __lookupSetter__
constructor             hasOwnProperty
isPrototypeOf           propertyIsEnumerable
toLocaleString          toString
</pre>
<p>If the user wanted to, for example, name his blog post <code>"constructor"</code> our program would behave incorrectly. We therefore change our code to leverage <code class="inline">hasOwnProperty</code>, which will allows to check whether the property has been set by us:</p>
<pre class="highlight" lang="javascript">
  if (!posts.hasOwnProperty(req.body.slug)) {
    posts[req.body.slug] = new Post(req.body);
    res.send(200);
  }
</pre>
<p>Most JavaScript programmers are already familiar with <code class="inline">hasOwnProperty</code>, since in the browser world it&#8217;s the standard way of writing libraries that work well in environments where <code class="inline">Object.prototype</code> is modified, so this addition should come to most as no surprise.</p>
<h2>The hasOwnProperty trap</h2>
<p>Our program, however, is still susceptible to potential misbehaving. Let&#8217;s say our user decides to call his blog post <code class="inline">"hasOwnProperty"</code>. The first time our check executes, everything will behave correctly, since the check will return false:</p>
<pre class="highlight" lang="javascript">
 ∞ ~ node
> var a = {};
> a.hasOwnProperty('hasOwnProperty')
false
</pre>
<p>Our code would therefore set the <code class="inline">hasOwnProperty</code> value in our object to the <code class="inline">Post</code> instance, which is an object. We can now simulate what would happen if the user tries that again:</p>
<pre class="highlight" lang="javascript">
&gt; a.hasOwnProperty = {}
{}
&gt; a.hasOwnProperty('hasOwnProperty')
TypeError: Property 'hasOwnProperty' of object #&lt;Object&gt; is not a function
    at [object Context]:1:3
</pre>
<p>As a result:</p>
<ul>
<li>Our code would throw a (potentially) uncaught exception.</li>
<li>Execution of our <code class="inline">/create</code> route would be aborted and response would not be sent to the user.</li>
<li>The request would be left hanging until it times out on both ends.</li>
</ul>
<p>The solution to this problem is to avoid relying on the &#8220;hasOwnProperty&#8221; provided by the object we&#8217;re dealing with, and use the generic one from the <code class="inline">Object.prototype</code>. If we execute it on our test subject, <code class="inline">true</code> will be returned after we set it as expected:</p>
<pre class="highlight" lang="javascript">
> Object.prototype.hasOwnProperty.call(a, 'hasOwnProperty')
true
</pre>
<h2>Conclusions</h2>
<p>The first conclusion from this experiment is that from the moment we decide to use a JavaScript object as a general-purpose hash table <strong>we can no longer rely on any of its inherited properties</strong>, specially <code class="inline">hasOwnProperty</code> (which we&#8217;re normally bound to use). This oversight, as a matter of fact, afflicted the Node.JS core <a href="https://github.com/joyent/node/issues/1707">querystring library</a> in the past.</p>
<p>If your code relies heavily on data structures where the possibility for collisions like this exist, you might want to consider having a <code class="inline">has</code> utility around:</p>
<pre class="highlight" lang="javascript">
function has (obj, key) {
  return Object.prototype.hasOwnProperty.call(obj, key);
}
</pre>
<p>And use it as follows:</p>
<pre class="highlight" lang="javascript">
  if (has(posts, req.body.slug)) { }
</pre>
<p>As a side note, you should generally stick to this method in the browser environment as well. Host objects such as <code class="inline">window</code> in older Internet Explorer versions <em>do not have</em> <code class="inline">hasOwnProperty</code>, leading to potentially inconsistent behavior in your code.</p>
<p>As correctly pointed out by different comments and tweets, another possibility surfaces in Node.JS:</p>
<pre class="highlight" lang="javascript">
  var posts = Object.create(null);
</pre>
<p>This will yield an object with a null prototype, which therefore <em>does not inherit</em> any methods, and would simplify our code to look like the original example:</p>
<pre class="highlight" lang="javascript">
    if (!posts[req.body.slug]) {}
</pre>
<p>Finally, a hashing scheme such as a prefix could do the job as well:</p>
<pre class="highlight" lang="javascript">
    if (!posts['posts-' + req.body.slug]) {
      posts['posts-' + req.body.slug] = new Post(req.body);
    }
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>A String is not an Error</title>
		<link>http://www.devthought.com/2011/12/22/a-string-is-not-an-error/</link>
		<comments>http://www.devthought.com/2011/12/22/a-string-is-not-an-error/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 19:11:59 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Client side]]></category>
		<category><![CDATA[Server side]]></category>

		<guid isPermaLink="false">http://next.devthought.com/?p=1241</guid>
		<description><![CDATA[I decided to write a little article to discourage an unfortunately common pattern in Node.JS modules (and browser JavaScript, to a lesser extent) that can boil down to these two examples: // A: function myFunction () { if (somethingWrong) { &#8230; <a href="http://www.devthought.com/2011/12/22/a-string-is-not-an-error/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I decided to write a little article to discourage an unfortunately common pattern in Node.JS modules (and browser JavaScript, to a lesser extent) that can boil down to these two examples:</p>
<pre class='highlight ' lang="javascript">// A:
function myFunction () {
  if (somethingWrong) {
    throw 'This is my error'
  }
  return allGood;
}
</pre>
<p>and</p>
<pre class='highlight ' lang="javascript">// B: async Node.JS-style callback with signature `fn(err, …)`
function myFunction (callback) {
  doSomethingAsync(function () {
    // …
    if (somethingWrong) {
      callback('This is my error')
    } else {
      callback(null, …);
    }
  });
}
</pre>
<p>In both cases, passing a string instead of an error results in reduced interoperability between modules. It breaks contracts with APIs that might be performing <code>instanceof Error</code> checks, or that want to know <em>more</em> about the error.</p>
<p><span id="more-1241"></span></p>
<p><code>Error</code> objects, as we&#8217;ll see, have very interesting properties in modern JavaScript engines besides holding the message passed to the constructor.</p>
<h2>The stack property</h2>
<p>The fundamental benefit of Error objects is that they automatically keep track of where they were built and originated.</p>
<p>The mechanism of how this happens is specific to each JavaScript engine and/or browser that implements it.</p>
<h2>V8 (Node.JS)</h2>
<p>The way that V8 handles this, which directly affects us who develop in Node.JS is described by the <a href="http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi">StackTraceApi</a> document.</p>
<p>We can test its behavior by simply initializing a <code>Error</code> object and inspecting its <code>stack</code> property:</p>
<pre class='highlight ' lang="javascript">// error.js
var err = new Error();
console.log(typeof err.stack);
console.log(err.stack);</pre>
<pre class="highlight" lang="text">∞ node error.js
string
Error
    at Object.&lt;anonymous&gt; (/private/tmp/error.js:2:11)
    at Module._compile (module.js:411:26)
    at Object..js (module.js:417:10)
    at Module.load (module.js:343:31)
    at Function._load (module.js:302:12)
    at Array.0 (module.js:430:10)
    at EventEmitter._tickCallback (node.js:126:26)
</pre>
<p>As you can see, even without <code>throw</code>ing or passing it around, V8 is able to tell us exactly where that object was created, and how it got there.</p>
<p>By default, V8 limits the stack trace size to 10 frames. You can alter this by changing the <code>Error.stackTraceLimit</code> during runtime.</p>
<pre class='highlight ' lang="javascript">Error.stackTraceLimit = 0; // disables it
Error.stackTraceLimit = Infinity; // disables any limit
</pre>
<h4>Custom Errors</h4>
<p>If you wanted to extend the native <code>Error</code> object so that stack collection is preserved, you can do so by calling the <code>captureStackTrace</code> function. This is an example extracted from the <a href="http://github.com/learnboost/mongoose">Mongoose ODM</a></p>
<pre class='highlight ' lang="javascript">function MongooseError (msg) {
  Error.call(this);
  Error.captureStackTrace(this, arguments.callee);
  this.message = msg;
  this.name = 'MongooseError';
};

MongooseError.prototype.__proto__ = Error.prototype;
</pre>
<p>The second argument passed to the <code>captureStackTrace</code> prevents unnecessary noise  in the <code>stack</code> generation by hiding the <code>MongooseError</code> constructor calls from the stack.</p>
<h4>Beyond stack strings</h4>
<p>As you might have noticed in my previous code example, I purposedly printed the <code>typeof</code> of the <code>stack</code> property. As it turns out, it&#8217;s a regular String with a format optimized for readability.</p>
<p>V8, much like Java, allows complete runtime introspection of the stack. Instead of a string, we can access an array of <code>CallSite</code>s that retain as much information as possible about the function call in the stack, including the object scope (<code>this</code>).</p>
<p>In this example, we override the <code>prepareStackTrace</code> function to access this raw array and examine it. We call `getFileName` and other methods on each <code>CallSite</code> (all the available methods are described <a href="http://code.google.com/p/v8/wiki/JavaScriptStackTraceApi#Customizing_stack_traces">here</a>)</p>
<pre class='highlight ' lang="javascript">function a () {
  b();
}

function b () {
  var err = new Error;

  Error.prepareStackTrace = function (err, stack) {
    return stack;
  };

  Error.captureStackTrace(err, b);

  err.stack.forEach(function (frame) {
    console.error(' call: %s:%d - %s'
      , frame.getFileName()
      , frame.getLineNumber()
      , frame.getFunctionName());
  });
}

a();
</pre>
<p>This is an example of the output this script produces:</p>
<pre class='highlight ' lang="javascript">∞ node error-2.js
call: /private/tmp/error-2.js:3 - a
call: /private/tmp/error-2.js:23 -
call: module.js:432 - Module._compile
call: module.js:450 - Module._extensions..js
call: module.js:351 - Module.load
call: module.js:310 - Module._load
call: module.js:470 - Module.runMain
call: node.js:192 - startup.processNextTick.process._tickCallback
</pre>
<p>All this functionality would of course be non-existent if we were to pass around strings, therefore drastically shrinking our debugging panorama.</p>
<p>For real-world usage, restoring the original <code>prepareStackTrace</code> after overriding it is probably a good idea. Thankfully, TJ Holowaychuck has released a tiny <a href="http://github.com/visionmedia/callsite">callsite</a> module to make this painless.</p>
<h2>Browsers</h2>
<p>Like the V8 document states:</p>
<blockquote>
<p><em>The API described here is specific to V8 and is not supported by any other JavaScript implementations. Most implementations do provide an error.stack property but the format of the stack trace is likely to be different from the format described here</em></p>
</blockquote>
<ul>
<li>Firefox exposes <code>error.stack</code>. It has its own format.</li>
<li>Opera exposes <code>error.stacktrace</code>. It has its own format.</li>
<li>IE has no stack.</li>
</ul>
<p>A very interesting solution to this is provided by <a href="https://github.com/eriwen/javascript-stacktrace">javascript-stacktrace</a>, which attempts to normalize a printed stack trace across all browsers.</p>
<p>On IE (and older versions of Safari), for example, it uses a clever method: it recursively looks for the <code>caller</code> property of a function, calls <code>toString</code> on it and parses out the function name.</p>
<pre class='highlight ' lang="javascript">var currentFunction = arguments.callee.caller;
while (currentFunction) {
  var fn = currentFunction.toString();
  var fname = fn.substring(fn.indexOf(&amp;amp;quot;function&amp;amp;quot;) + 8, fn.indexOf('')) || 'anonymous';
  callstack.push(fname);
  currentFunction = currentFunction.caller;
}
</pre>
<h2>Conclusions</h2>
<ul>
<li>When doing async I/O (in Node.JS or otherwise), since <code>throw</code>ing is not a<br />
possibility (as it results in uncaught exceptions), <code>Error</code>s are the only way to<br />
allow proper stack trace collection.</li>
<li>Even in non-V8 browser environments, it&#8217;s probably a good idea to still initialize<br />
<code>Error</code>s. The API exists in all browsers, and the extended API facilities that V8<br />
provides are bound to be available to most engines in the future.</li>
<li>If you&#8217;re throwing or passing around strings for errors, consider switching today!</li>
</ul>
<p>The examples in the beginning of the post can thus be rewritten this way:</p>
<pre class='highlight ' lang="javascript">// A:
function myFunction () {
  if (somethingWrong) {
    throw new Error('This is my error')
  }
  return allGood;
}
</pre>
<p>and</p>
<pre class='highlight ' lang="javascript">// B: async Node.JS-style callback with signature `fn(err, …)`
function myFunction (callback) {
  doSomethingAsync(function () {
    // …
    if (somethingWrong) {
      callback(new Error('This is my error'))
    } else {
      callback(null, …);
    }
  });
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2011/12/22/a-string-is-not-an-error/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Devthought v3</title>
		<link>http://www.devthought.com/2011/01/05/devthought-v3/</link>
		<comments>http://www.devthought.com/2011/01/05/devthought-v3/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 10:55:19 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1191</guid>
		<description><![CDATA[So here it is, the long awaited redesign! A few months ago I decided I wanted to re-focus my website on my writing and projects, so I reached out to my friend, the genius Rogie King, with some ideas. Some &#8230; <a href="http://www.devthought.com/2011/01/05/devthought-v3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So here it is, the long awaited redesign! A few months ago I decided I wanted to re-focus my website on my writing and projects, so I reached out to my friend, the genius <a href="http://www.komodomedia.com/">Rogie King</a>, with some ideas.</p>
<p>Some of the new features that I&#8217;m excited about:</p>
<ul>
<li>Clearly defined post types: article, code snippet, video, photo and quote.</li>
<li>Cool dynamic filtering and Twitter-like pagination. (#hash and pushState to come soon)</li>
<li>Projects page that highlights my past and present work</li>
<li>CSS3 animated sidebar with links to social networks &amp; bio</li>
<li>Commenting through DisqUS customized to my needs</li>
</ul>
<p><span id="more-1191"></span></p>
<p>As far as my old posts, they&#8217;re hidden from the main view so that I can focus on my current topics of interest:</p>
<ul>
<li>Open Source development</li>
<li>Node.JS and JavaScript as the ubiquitous dynamic language</li>
<li>&#8220;NOSQL&#8221; Databases and scalability</li>
<li>Server administration</li>
<li>User experience &amp; design</li>
<li>Startups</li>
</ul>
<p>I have many articles lined up for you guys, so please look forward to my updates. Also, keep in mind certain things still need tweaking and are likely to change or improve over the next few days.</p>
<p>Remember to stay in touch through <a href="http://twitter.com/rauchg">Twitter</a> or <a href="http://feeds.feedburner.com/devthought">RSS</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2011/01/05/devthought-v3/feed/</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>LearnBoost</title>
		<link>http://www.devthought.com/2010/07/26/learnboost/</link>
		<comments>http://www.devthought.com/2010/07/26/learnboost/#comments</comments>
		<pubDate>Mon, 26 Jul 2010 17:36:34 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1175</guid>
		<description><![CDATA[If you&#8217;ve been wondering what I&#8217;ve been up to these days, I have some compelling news to share about my company, LearnBoost I&#8217;m excited to announce that my company has raised a seed round of $975K from several leading angels &#8230; <a href="http://www.devthought.com/2010/07/26/learnboost/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been wondering what I&#8217;ve been up to these days, I have some compelling news to share about my company, <a href="http://learnboost.com">LearnBoost</a></p>
<p>I&#8217;m excited to announce that my company has raised a seed round of $975K from several leading angels and venture capital firms. Our VC&#8217;s are Bessemer Venture Partners, Charles River Ventures, RRE Ventures, and Atlas Ventures. Our angels include Naval Ravikant, Bill Lee, James Hong, Othman Laraki, Karl Jacob, and several other fantastic angels. We’re thrilled this entire group of investors share LearnBoost&#8217;s vision for developing free and amazing software for schools.</p>
<p><span id="more-1175"></span></p>
<p>In early August, LearnBoost will release our free, easy-to-use, and beautiful application built on the powerful technology we&#8217;ve developed. <!--more-->LearnBoost completely replaces other gradebook providers, both free and paid. Our accounts give teachers a <a href="http://learnboost.com">free gradebook</a> to manage their classroom, as well as integrated software to create and manage lesson plans, track attendance in a list or innovative visual format, maintain schedules, import and integrate Google calendars, &#8220;tag&#8221; standards to assignments and lesson plans, and much more. If you are a teacher, or know a teacher, they can use our software for free &#8212; please tell them to <a href="http://app.learnboost.com"><strong>get on our free account list</strong></a>.</p>
<p>We’ll be using this funding to move towards developing the best student information system on the market, in addition to the free teacher software we&#8217;ll be releasing in August. We&#8217;re aiming right at Blackboard, Pearson, and other slow legacy software providers with our free, wonderful offerings. We closed our financing a few months ago, so we already have a team in place to reach our goals. That said, we&#8217;re always looking for more talent; if you are a developer or designer and want to be part of a fast-growing team dedicated to education and open source software, please <a href="http://www.learnboost.com/jobs">check out our jobs page</a>.</p>
<p>So what&#8217;s next? If you&#8217;re a teacher or know a teacher, tell them about LearnBoost and make sure they <a href="http://app.learnboost.com">get on the free account list</a>. Our free and amazing software can be used by any teacher and in our test phase we&#8217;ve gotten lots of praise already. I&#8217;m excited for our release in early August and to continue to share our <a href="http://github.com/learnboost/">open source releases</a> and developments.</p>
<p>Guillermo Rauch<br />
<a href="http://learnboost.com">LearnBoost</a> CTO</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2010/07/26/learnboost/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Attribution</title>
		<link>http://www.devthought.com/2010/07/20/attribution/</link>
		<comments>http://www.devthought.com/2010/07/20/attribution/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 17:15:26 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[attribution]]></category>
		<category><![CDATA[open source]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1155</guid>
		<description><![CDATA[Like most nights, tonight I was reading the public GitHub News Feed to keep up with interesting projects that people I follow might create, follow or contribute to. One that caught my eye immediately is a project called FCBKcomplete, currently &#8230; <a href="http://www.devthought.com/2010/07/20/attribution/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Like most nights, tonight I was reading the public GitHub News Feed to keep up with interesting projects that people I follow might create, follow or contribute to. One that caught my eye immediately is a project called <a href="http://github.com/emposha/FCBKcomplete">FCBKcomplete</a>, currently with over a 100 followers and <a href="http://github.com/emposha/FCBKcomplete/network">22 very active forks</a>.</p>
<p>As I was glancing the list of files, I notice one called <code class="inline">close.gif</code>, which specially intrigued me: when I released the initial version of my project TextboxList (<a href="http://devthought.com/projects/mootools/textboxlist/">MooTools</a>, <a href="http://devthought.com/projects/jquery/textboxlist/">jQuery</a>), that&#8217;s exactly what I had called the sprite image which contained the normal, hover and active states of the boxes close buttons.</p>
<p>But there was a small problem: in the entire GitHub repository, I couldn&#8217;t find a single mention of <a href="http://www.google.com/search?hl=en&#038;client=safari&#038;rls=en&#038;q=site%3Ahttp%3A%2F%2Fgithub.com%2Femposha%2FFCBKcomplete+guillermo&#038;aq=f&#038;aqi=&#038;aql=&#038;oq=&#038;gs_rfai=">my name</a> or <a href="http://www.google.com/search?hl=en&#038;client=safari&#038;rls=en&#038;q=site%3Ahttp%3A%2F%2Fgithub.com%2Femposha%2FFCBKcomplete+devthought&#038;aq=f&#038;aqi=&#038;aql=&#038;oq=&#038;gs_rfai=">my website</a>.</p>
<h3>The early days of TextboxList</h3>
<p>Around <a href="http://devthought.com/blog/projects-news/2008/01/textboxlist-meets-autocompletion/">January</a> <a href="http://ajaxian.com/archives/facebook-style-input-box">2008</a>, I announced the first open source widget released under the MIT license intended to mimic the behavior of the Facebook tokenizer.</p>
<p>The header of the <a href="http://devthought.com/wp-content/articles/autocompletelist/textboxlist.js">source file</a>, still up today, contains two interesting bits:</p>
<pre class='highlight ' lang="text">Credits:
  - Idea: Facebook + Apple Mail
  - Caret position method: Diego Perini <http://javascript.nwbox.com/cursor_position/cursor.js></pre>
<p>I included credit for the ideas and sources of inspiration, and for a relevant key piece of source code which had been written by another developer.</p>
<p>The second interesting bit is my copyright message:</p>
<pre class='highlight ' lang="text">/* Copyright: Guillermo Rauch <http://devthought.com/> - Distributed under MIT - Keep this message! */</pre>
<p>When I started writing this project, I was a 16-year-old high school student trying to seek some recognition for a piece of work given away for free. Today, with the message formatting unchanged we can find:</p>
<pre class='highlight ' lang="text">/* Copyright: Emposha.com <http://www.emposha.com/> - Distributed under MIT - Keep this message! */</pre>
<h3>The problems</h3>
<ol>
<li>The file close.gif was copy-pasted</li>
<li>
<p>The stylesheet was entirely copy-pasted.</p>
<p>For the <a href="http://devthought.com/blog/projects-news/2008/01/textboxlist-fancy-facebook-like-dynamic-inputs/">first release</a> of the project, I wrote an article about the thought process behind the creation of the widget.</p>
<p>One of the core ideas emphasized in it is that you should start by having the markup and CSS be as bullet proof as possible, as you don&#8217;t want to hinder the JavaScript development with debugging related to style, positions, floats, and you don&#8217;t want to solve problems within JavaScript that CSS alone can solve. Years later, this is still a design principle I live by for the creation of web applications</p>
</li>
<li>
<p>At <a href="http://github.com/emposha/FCBKcomplete/blob/master/jquery.fcbkcomplete.js">550 lines of code</a>, it has considerably less features than my very old version at <a href="http://pastie.org/1051729">350 lines of code</a>. Namely, no keyboard navigation of the boxes, one of the premises of the original Facebook tokenizer.</p>
<p>Since my first release, the entire codebase was <a href="http://devthought.com/projects/jquery/textboxlist/">re-written</a>, with full documentation and many more characteristics. This version wasn&#8217;t released under MIT. However, hundreds of people are using it for free, others have chosen to willingly contribute (as I have no mechanisms to prevent unfair use), and special licenses were given to open source projects, companies with dozens of subdomains and very well known web application makers.</p>
</li>
<li>Many parts of the code show a striking resemblance, which of course is not coincidental.</li>
<li>Even the <a href="http://github.com/emposha/FCBKcomplete/blob/master/fetched.php">JSON data</a> used to feed autocompletion values, which is a collection of my favorite argentinean writers, has been blatantly reproduced. Quite interesting considering the author seems to be from Israel, and I&#8217;m sure he wasn&#8217;t just including it out of passion for good foreign literature.</li>
<li>Under these conditions, it managed to sneak dozens of commits from people in the community, including <a href="http://github.com/voodootikigod/FCBKcomplete/">Chris Williams</a>. It&#8217;s left for me to wonder if they ever learned of all the effort that took me to research this particular problem and execute its solution, now shown to <a href="http://github.com/emposha/FCBKcomplete/watchers">the world</a> under <a href="http://emposha.com">a very intriguing brand</a>.</li>
</ol>
<p>Update: special thanks to Chris Williams who updated his fork to reflect proper copyright</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2010/07/20/attribution/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>JSConf 2010 Slides</title>
		<link>http://www.devthought.com/2010/05/03/jsconf-2010-slides/</link>
		<comments>http://www.devthought.com/2010/05/03/jsconf-2010-slides/#comments</comments>
		<pubDate>Mon, 03 May 2010 13:07:08 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Client side]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jsconf]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1144</guid>
		<description><![CDATA[For those of us who didn&#8217;t make it, I&#8217;ve compiled a list of slides + blog posts from the JSConf 2010 Track A speakers Alex Russell &#8211; &#8220;Google Chrome Frame&#8221; Post: http://alex.dojotoolkit.org/ Slides: http://alex.dojotoolkit.org/10/jsconf/gcf.html Francisco Tolmasky &#8211; &#8220;Socratic: Documentation Done &#8230; <a href="http://www.devthought.com/2010/05/03/jsconf-2010-slides/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>For those of us who didn&#8217;t make it, I&#8217;ve compiled a list of slides + blog posts from the JSConf 2010 Track A speakers</p>
<p><strong>Alex Russell &#8211; &#8220;Google Chrome Frame&#8221;</strong><br />
Post: <a href="http://alex.dojotoolkit.org/">http://alex.dojotoolkit.org/</a><br />
Slides: <a href="http://alex.dojotoolkit.org/10/jsconf/gcf.html">http://alex.dojotoolkit.org/10/jsconf/gcf.html</a></p>
<p><strong>Francisco Tolmasky &#8211; &#8220;Socratic: Documentation Done Right&#8221;</strong><br />
GitHub: <a href="http://github.com/tolmasky/socratic">http://github.com/tolmasky/socratic</a><br />
Slides: ?</p>
<p><strong>Aaron Newton &#8211; &#8220;Programming To Patterns&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/guest2ee5e2c/programming-to-patterns-presentation">http://www.slideshare.net/guest2ee5e2c/programming-to-patterns-presentation</a> (not up-to-date)</p>
<p><strong>Jed Schmidt &#8211; &#8220;A (fab) approach to web apps&#8221;</strong><br />
GitHub: <a href="http://github.com/jed/fab">http://github.com/jed/fab</a><br />
Slides: <a href="http://www.flickr.com/photos/tr4nslator/sets/72157623883700702/show/">http://www.flickr.com/photos/tr4nslator/sets/72157623883700702/show/</a></p>
<p><strong>Dmitry Baranovskiy &#8211; &#8220;Raphaël the Great&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/Dmitry.Baranovskiy/raphal-js-conf">http://www.slideshare.net/Dmitry.Baranovskiy/raphal-js-conf</a></p>
<p><strong>Douglas Crockford &#8211; &#8220;Really, JavaScript?&#8221;</strong><br />
?</p>
<p><strong>Tobias Schneider &#8211; &#8220;Flash is dead, long live Flash!&#8221;</strong><br />
GitHub: <a href="http://github.com/tobeytailor/gordon">http://github.com/tobeytailor/gordon</a><br />
Slides: <a href="http://www.slideshare.net/ConfEcho/flash-is-dead-long-live-flash">http://www.slideshare.net/ConfEcho/flash-is-dead-long-live-flash</a></p>
<p><strong>Makinde Adeagbo &#8211; &#8220;Primer: Facebook&#8217;s 2k of JavaScript to power (almost) all interactions&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/makinde/javascript-primer">http://www.slideshare.net/makinde/javascript-primer</a></p>
<p><strong>Steve Souders &#8211; &#8220;The Best of Steve&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/souders/jsconf-us-2010">http://www.slideshare.net/souders/jsconf-us-2010</a></p>
<p><strong>Jenn Lukas &#8211; &#8220;JavaScript and Web Standards Sitting in a Tree&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/JennLukas/javascript-and-web-standards-sitting-in-a-tree">http://www.slideshare.net/JennLukas/javascript-and-web-standards-sitting-in-a-tree</a></p>
<p><strong>Ryan Dahl &#8211; &#8220;Less is More in Node.js&#8221;</strong><br />
Slides: <a href="http://nodejs.org/jsconf2010.pdf">http://nodejs.org/jsconf2010.pdf</a></p>
<p><strong>Billy Hoffman &#8211; &#8220;JavaScript&#8217;s Evil Side&#8221;</strong><br />
Slides: ?</p>
<p><strong>John David Dalton &#8211; &#8220;All you can leet&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/johndaviddalton/jsconf-all-you-can-leet">http://www.slideshare.net/johndaviddalton/jsconf-all-you-can-leet</a></p>
<p><strong>Aaron Quint &#8211; &#8220;Making Bacon / Making Code&#8221;</strong><br />
GitHub: <a href="http://github.com/quirkey/sammy">http://github.com/quirkey/sammy</a><br />
Post: <a href="http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/">http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/</a><br />
Slides: <a href="http://swinger.quirkey.com/#/preso/aq-jsconf/display/1">http://swinger.quirkey.com/#/preso/aq-jsconf/display/1</a><br />
Video: <a href="http://bit.ly/9j7u3L">http://bit.ly/9j7u3L</a></p>
<p><strong>Dion Almaer, Ben Galbraith, and Matt McNulty &#8211; &#8220;The mobile web&#8221;</strong><br />
Slides: <a href="http://www.slideshare.net/dion/the-mobile-web-2010-jsconf">http://www.slideshare.net/dion/the-mobile-web-2010-jsconf</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2010/05/03/jsconf-2010-slides/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Socket.IO: sockets for the rest of us</title>
		<link>http://www.devthought.com/2010/03/17/socketio-sockets-for-the-rest-of-us/</link>
		<comments>http://www.devthought.com/2010/03/17/socketio-sockets-for-the-rest-of-us/#comments</comments>
		<pubDate>Wed, 17 Mar 2010 20:57:38 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Client side]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1137</guid>
		<description><![CDATA[Over at LearnBoost, I just released Socket.IO, a normalized Socket API that hides the complexity of the realtime transports. With code as simple as this: socket = new io.Socket('localhost'); socket.connect(); socket.send('some data'); socket.addEvent('message', function(data){ alert('got some data' + data); }); &#8230; <a href="http://www.devthought.com/2010/03/17/socketio-sockets-for-the-rest-of-us/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Over at LearnBoost, I just <a href="http://www.learnboost.com/socket-io-sockets-for-the-rest-of-us/">released</a> <code class="inline">Socket.IO</code>,  a normalized Socket API that hides the complexity of the realtime transports.</p>
<p>With code as simple as this:</p>
<pre class='highlight ' lang="JavaScript">
socket = new io.Socket('localhost');
socket.connect();
socket.send('some data');
socket.addEvent('message', function(data){
    alert('got some data' + data);
});
</pre>
<p>you&#8217;ll be leveraging:</p>
<p><span id="more-1137"></span></p>
<ul>
<li>WebSocket</li>
<li>Adobe Flash Socket</li>
<li>ActiveX HTMLFile (IE)</li>
<li>Server-Sent Events (Opera)</li>
<li>XHR with multipart encoding</li>
<li>XHR with long-polling</li>
</ul>
<p>And on the server side, things are equally simple. This is a chat application written in Socket.IO-node, the Node.JS backend implementation:</p>
<pre class='highlight ' lang="JavaScript">
var buffer = [], json = JSON.stringify;

io.listen(server, {

	onClientConnect: function(client){
		client.send(json({ buffer: buffer }));
		client.broadcast(json({ announcement: client.sessionId + ' connected' }));
	},

	onClientDisconnect: function(client){
		client.broadcast(json({ announcement: client.sessionId + ' disconnected' }));
	},

	onClientMessage: function(message, client){
		var msg = { message: [client.sessionId, message] };
		buffer.push(msg);
		if (buffer.length > 15) buffer.shift();
		client.broadcast(json(msg));
	}

});
</pre>
<p>As usual, head to <a href="http://github.com/LearnBoost">GitHub</a> to experiment with the code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2010/03/17/socketio-sockets-for-the-rest-of-us/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Google Chrome and 1Password</title>
		<link>http://www.devthought.com/2010/02/11/google-chrome-and-1password/</link>
		<comments>http://www.devthought.com/2010/02/11/google-chrome-and-1password/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 18:48:01 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Tumble]]></category>
		<category><![CDATA[chrome]]></category>
		<category><![CDATA[mac]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=1119</guid>
		<description><![CDATA[The new Google Chrome Beta for mac and the alpha 1Password extension work perfectly together!]]></description>
			<content:encoded><![CDATA[<p><img src="http://cld.ly/571csx" /></p>
<p>The new <a href="http://chrome.blogspot.com/2010/02/new-beta-of-google-chrome-for-mac-with.html">Google Chrome Beta</a> for mac and the <a href="http://www.switchersblog.com/2010/01/a-1password-alpha-for-chromium-is-here.html">alpha 1Password extension</a> work perfectly together!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2010/02/11/google-chrome-and-1password/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

