Periscope UP

So, I'm a great fan of codepen.io, but its hard to argue that recently it's become so painfully slow that it's actually difficult to use at all.

I'm sure there are lots of technical reasons for this, but it's just annoying.

So, in my on-going efforts to learn ES6, I've started down the slope of writing a simple replacement for Codepen that you can run locally.

The work in progress code is here on github and honestly, there's not a lot of see right now. All it does is some simple pug/sass/es6 compliation and then streams the result back to the browser using a websocket.

However, the interesting thing here is that it uses gulp to do this. Since gulp plugins are basically 'just modules', you can invoke a single (or chain) of operations as simply as:

var babel = require('gulp-babel');
var File = require('vinyl');
var StringDecoder = require('string_decoder').StringDecoder;

// Create a new 'fake' file using vinyl
var file = new File({
  path: 'source.scss',
  cwd: 'fake/',
  base: 'fake/',
  contents: new Buffer(data.raw)
});

// Create a 'babel' ES6 compile stream processor
var stream = babel();

// Handle stream output chunks
var bufs = [];
stream.on('readable', function() {
  var read = stream.read();
  if (read) {
    bufs.push(read.contents);
  }
});

// And when the stream is done, do something with the result.
stream.on('end', function() {
  var all = Buffer.concat(bufs);
  var decoder = new StringDecoder('utf8');
  var content = decoder.write(all).trim();
  console.log(content);
});

// Push the fake file into the stream for processing
stream.write(file);

// ...and finally make sure to close the stream to trigger end.
stream.end();

Pretty cute trick. I'm definitely going to be using gulp more in the future; the compositablity of streaming input and output like this is just so much more powerful than grunt.

However, a word to the wary. There are plenty of really terrible gulp plugins out there.

You'll see this error over and over again:

Stream content is not supported

Oh my! coughfarkyoucough. Turns out that working with node streams is too hard for many plugin developers, who choose to just ignore streams entirely. I can't even begin to describe how annoying it is to find a plugin and then discover the author actually only did a half-assed job.

It's really very simple to handle streamed content in a trivial manner. Just read the entire stream, and convert it into a 'File' object for the next item in the chain; you don't have to try to do a chunk-by-chunk streaming operation on the data.

Gulp. It's a mixed bag. :P

Still, onwards and upwards. Next up for periscope is a text-editor component; that'll be fun~