Upgrade to Pro — share decks privately, control downloads, hide ads and more …

streamer VS spaghetti ninjas

gozala
October 02, 2011

streamer VS spaghetti ninjas

Streamer library, which suggests opinionated stream definition / pattern and utilizes core library, that makes asynchronously recursive, pure function <3 possible without spaghetti code ninjas!

gozala

October 02, 2011
Tweet

More Decks by gozala

Other Decks in Programming

Transcript

  1. function spaghetti(a, b, callback) { assemble(a, function(error, c) { if

    (error) callback(error) else combine(b, c, callback) }) }
  2. function listTree(path, callback) { fs.readdir(path, function(error, entries) { if (error)

    return callback(error) function onStateChange(e, paths) { if (e) return callback(error = e) result = result.concat(paths) if (--waiting === 0) callback(null, result) } function onStat(path, e, stat) { if (error) return null // error already reported if (e) return callback(error = e) if (!stat.isDirectory()) onStateChange(null, [ path ]) else listTree(path, onStateChange) } var waiting = entries.length, result = [ path ] if (!waiting) return callback(null, result) entries.forEach(function(entry) { entry = join(path, entry) fs.stat(entry, onStat.bind(null, entry)) }) })
  3. function numbers(min, max) { var d = max - min

    return function stream(next) { setInterval(function generate() { next(min + Math.round(Math.random() * d)) }, 20) } } print(numbers(0, 100))
  4. function print(stream) { console.log('>>>') // start stream(function onElement(element) { console.log(element)

    // yeild }, function onStop(error) { if (!error) return console.log('<<<') console.log('!!!') console.error(error) }) }
  5. function list() { // Capture arguments as an array. var

    array array = Array.prototype.slice.call(arguments) return function stream(next, stop) { array.forEach(function(element) { next(element) }) stop() } }
  6. function listTree(path, callback) { fs.readdir(path, function(error, entries) { if (error)

    return callback(error) function onStateChange(e, paths) { if (e) return callback(error = e) result = result.concat(paths) if (--waiting === 0) callback(null, result) } function onStat(path, e, stat) { if (error) return null // error already reported if (e) return callback(error = e) if (!stat.isDirectory()) onStateChange(null, [ path ]) else listTree(path, onStateChange) } var waiting = entries.length, result = [ path ] if (!waiting) return callback(null, result) entries.forEach(function(entry) { entry = join(path, entry) fs.stat(entry, onStat.bind(null, entry)) }) })
  7. var fs = require("fs") var path = require("path") function ls(base)

    { return function stream(next, stop) { fs.readdir(base, function(error, entries) { var entry // stop on error with error if (error) return stop(error) // Otherwise we yield each entry. while ((entry = entries.shift())) next(path.join(base, entry)) stop() }) } }
  8. print(ls('./')) // >>> // ./.gitignore // ./History.md // ./package.json //

    ./readme.js // ./Readme.md // ./streamer.js // ./tests // <<<
  9. function stat(path) { return function stream(next, stop) { fs.stat(path, function(error,

    stats) { // if error, stop stream with error. if (error) return stop(error) // save path to find stat’s owner stats.path = path // We yield `stats` and stop the stream. next(stats) stop() }) } }
  10. print(stat('./')) // >>> // { dev: 234881026, // ino: 19933437,

    // mode: 16877, // nlink: 17, // uid: 502, // gid: 20, // rdev: 0, // size: 578, // blksize: 4096, // blocks: 0, // atime: Thu, 09 Jun 2011 10:51:25 GMT, // mtime: Thu, 09 Jun 2011 12:48:32 GMT, // ctime: Thu, 09 Jun 2011 12:48:32 GMT, // path: './' }
  11. function map(lambda, source) { return function stream(next, stop) { source(function

    onElement(element) { next(lambda(element)) }, stop) } }
  12. function filter(lambda, source) { return function stream(next, stop) { source(function

    onElement(element) { if (lambda(element)) next(element) }, stop) } }
  13. function dirs(paths) { var stats = map(stat, paths) var dirStats

    = filter(function(stat) { return stat.isDirectory() }, stats) return map(function(stat) { return stat.path }, dirStats) }
  14. function merge(source) { return function stream(next, stop) { var open

    = 1 function onStop(error) { if (!open) return false if (error) open = 0 else open -- if (!open) stop(error) } source(function onStream(stream) { open ++ stream(function(value) { if (open) next(value) }, onStop) }, onStop) }
  15. function dirs(paths) { var stats = merge(map(paths, stat)) var dirStats

    = filter(function(stat) { return stat.isDirectory() }, stats) return map(function(stat) { return stat.path }, dirStats) }
  16. function lstree(path) { var paths = ls(path) var nested =

    merge(map(lstree, dirs(paths))) return merge(list(paths, nested)) }
  17. function listTree(path, callback) { fs.readdir(path, function(error, entries) { if (error)

    return callback(error) function onStateChange(e, paths) { if (e) return callback(error = e) result = result.concat(paths) if (--waiting === 0) callback(null, result) } function onStat(path, e, stat) { if (error) return null // error already reported if (e) return callback(error = e) if (!stat.isDirectory()) onStateChange(null, [ path ]) else listTree(path, onStateChange) } var waiting = entries.length, result = [ path ] if (!waiting) return callback(null, result) entries.forEach(function(entry) { entry = join(path, entry) fs.stat(entry, onStat.bind(null, entry)) }) })
  18. function dirs(paths) { var stats = merge(map(paths, stat)) var dirStats

    = filter(function($) { return $.isDirectory() }, stats) return map(function(stat) { return stat.path }, dirStats) } function lstree(path) { var paths = ls(path) var nested = merge(map(lstree, dirs(paths))) return merge(list(paths, nested)) }
  19. function blackbox(a, b) { var c = assemble(a) return combine(b,

    c) } function assemble(a) { return function stream(next, stop) { fs.readFile(a, function(e, content) { e ? stop(e) : next(context) }) } } function combine(b, c) { return map(function($) { return $ + b }, c) }
  20. var http = require('http-streamer/server') var fs = require('fs-streamer') var streamer

    = require('streamer') var server = http.server(function(request) { return { status: 200, head: { 'ContentType': 'text/plain' }, body: streamer.append(fs.read(header), request.body, fs.read(footer)) } }, 8080)
  21. var http = require('http-streamer/server') var streamer = require('streamer') function domEvents(target,

    type, capture) { return function stream(next, stop) { target.addEventListener(type, function onEvent(event) { if (false === next(event)) target.removeEventListener(type, onEvent, !!capture) }, !!capture) } } var keys = domEvents(document, 'keypress') var codes = streamer.map(function($) { return url + '?q=' + $.keyCode }, keys) var data = streamer.merge(streamer.map(http.get, codes)) print(data)