{"_id":"fibrous","_rev":"35-a5cf8dbd95e32abdfaeac57137345967","name":"fibrous","description":"Easily mix asynchronous and synchronous programming styles in node.js","dist-tags":{"latest":"0.4.0"},"versions":{"0.2.4":{"name":"fibrous","version":"0.2.4","description":"A library to help with fibers","homepage":"http://github.com/goodeggs/fibrous","repository":{"type":"git","url":"git://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine"],"author":{"name":"Randy Puro","email":"randy@goodeggsinc.com"},"contributors":[{"name":"Bob Zoller","email":"bob@goodeggsinc.com"},{"name":"Alon Salant","email":"alon@goodeggsinc.com"}],"maintainers":[{"name":"asalant","email":"alon@salant.org"}],"licenses":["MIT"],"dependencies":{"fibers":"0.6.x"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"1.2.x"},"main":"lib/fibrous","engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_npmUser":{"name":"asalant","email":"alon@salant.org"},"_id":"fibrous@0.2.4","optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.4","_nodeVersion":"v0.6.12","_defaultsLoaded":true,"dist":{"shasum":"c895632c2c6444f8034260be7a4ba0806c1a5f76","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.2.4.tgz","integrity":"sha512-g/zr222NFHnd/0xc/J4PXJqqBtNhFly5fshgCKUv5tNmxqS7ih6GGSyNBRVmvEMdGtmKECq6yQGJu6HYptjfGQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFJs5rbZHKOY13MB7xfgzrSHzUXusGdruiErd6lmDFS9AiAvvOIpklnchBhTIglDPzWf1f8dK3P19te15gAHaBrXfQ=="}]},"directories":{}},"0.2.5":{"name":"fibrous","version":"0.2.5","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://github.com/goodeggs/fibrous","repository":{"type":"git","url":"git://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":"0.6.x"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"1.2.x"},"main":"lib/fibrous","engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_npmUser":{"name":"asalant","email":"alon@salant.org"},"_id":"fibrous@0.2.5","optionalDependencies":{},"engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.1.4","_nodeVersion":"v0.6.12","_defaultsLoaded":true,"dist":{"shasum":"47be34694c5f289abe2340903a6ac52288d390df","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.2.5.tgz","integrity":"sha512-+dQ3eChOUgXiSh7x2ioJAY3DA9cmHv5/yUue9mqpfaCMMxpMvL7b7P+ugxf7dzBUnrKJ0RVr5HcxX32v14OJEQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBQl+R1TmdZBs7rlElZT7qfplbldmbO0IQGDyoztK/X+AiAomkBAVpRsTTIcMRH4hhpgc1aFfj+iJcWd6u1+CFTWXg=="}]},"maintainers":[{"name":"asalant","email":"alon@salant.org"}],"directories":{}},"0.2.7":{"name":"fibrous","version":"0.2.7","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://github.com/goodeggs/fibrous","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"1.3.x"},"main":"lib/fibrous","engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.2.7","dist":{"shasum":"ef31d8129358161b76454e6ac77aa4eec08eddaf","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.2.7.tgz","integrity":"sha512-h+aDe8B0fRUD99lGxhZtc3XKWpvEBPEXmrbnZsKbqvGzjT3MI9MpmVMeylIkFOm/JK+aa36l8sKEdprXbVMMHQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAEDkrTuhW44Ve7hNAR58aoN5l5bZ6W8d6Ny/hM5+dWRAiEAiaW3ahbLenpelMiUN8UoLz3V5liBXW16ezKwSx8CahM="}]},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"}],"directories":{}},"0.2.8":{"name":"fibrous","version":"0.2.8","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://github.com/goodeggs/fibrous","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.2.8","dist":{"shasum":"eb507ed7240d0f5463dd566ef329d3d09f593afb","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.2.8.tgz","integrity":"sha512-DX61LFWld/6ctQA3ChnbcDIzBG6t0KEKrl33vIvXd41q3Rz4vXdEaDcZ+c9oLyU0lKdea9z3pmgftCzzUviEyA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGIN8xC6JrAM+LKK6B02Pzto7IN9ok59mlgfaC5L9S/gAiAgYHLcl48ZYGisCaQ9+yV5hs2LjtBWtz6LIfCxtj3WSA=="}]},"_npmVersion":"1.1.65","_npmUser":{"name":"asalant","email":"alon@salant.org"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"}],"directories":{}},"0.2.9":{"name":"fibrous","version":"0.2.9","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.2.9","dist":{"shasum":"d8c51f35ce152b97e36f99be7f5c440fa4b50a01","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.2.9.tgz","integrity":"sha512-dHJTCpcustc7BZ4UAYFr4JscpISVGFbgoNoBGpM2p0tafxpUBrFDkmHeLsKyNDlJ0wU48tCudRj4l4hcz67BUQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjl8xdoDk0kfbwj2DgsPGh2g8iGaq5WJXv5hTh5/0iLQIgX4UXx6VF/scurxfUUDuctUaWUnOoJXViYVoVdySUeng="}]},"_npmVersion":"1.1.65","_npmUser":{"name":"randypuro","email":"randypuro@gmail.com"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"}],"directories":{}},"0.3.0":{"name":"fibrous","version":"0.3.0","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.0.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -cl -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.3.0","dist":{"shasum":"cbc5c04d4f13559f036fd774330247ba548086b0","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.3.0.tgz","integrity":"sha512-Rqp4haf5CgGp170kG/2aFhThxH+lPd6GB2VHUZN/8++SReoSBzsPdxRjkMLzPMU+i2UthQy3+U32toDO7+Oyyw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEOOwAcGmbGka4ZgAUNo8es06OAuj/MN1N9eZdbvJ50VAiEAr34vJmc9Y0oJjK6fbvLCxfoHB6TGCiaM/S5NIOvtnLQ="}]},"_npmVersion":"1.1.65","_npmUser":{"name":"asalant","email":"alon@salant.org"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"}],"directories":{}},"0.3.1":{"name":"fibrous","version":"0.3.1","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.8.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -c -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.3.1","dist":{"shasum":"1f43a3c98647eaacc2b79541fb51e4a4e508a5a7","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.3.1.tgz","integrity":"sha512-1sZOp8b2FFXiJF9rwFFBa/Y5a3JauJ7AfqfyolpquOb7Mi6deEnbvtGlMKd45K6TbAqV/Fwj4t3O4i69pJp5+Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCjBtoekHiV5YITH798IDm3LImZJKJvn9kvWiTYqV1lfQIgZ4JXDYKnua0UgS2cVF++9KWHkNEhSsZlodADloOGo9E="}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"hurrymaplelad","email":"adam@hmlad.com"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"},{"name":"hurrymaplelad","email":"adam@hmlad.com"}],"directories":{}},"0.3.2":{"name":"fibrous","version":"0.3.2","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.8.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -c -o lib src","test":"jasmine-node --coffee --junitreport spec"},"_id":"fibrous@0.3.2","dist":{"shasum":"ea578f254cc3a9fa079096526aa725e7493a7943","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.3.2.tgz","integrity":"sha512-qnC5PbrkrrTC92GRTCCHVdurReB/0uuZSkdqbqw8b77iMDSHRbLfQ7iI4bSl9zbckOSwDWIy/nynhPcKA4Y+ig==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHTBJBZ0q0C8N3RsLk3S8opSxIrMkvrcH9TYcQXc0ggQAiBIxm6KEScDk8WOr0VLS1Wb2KqjFEDsdyJf4yCUUQrERw=="}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"asalant","email":"alon@salant.org"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"},{"name":"hurrymaplelad","email":"adam@hmlad.com"}],"directories":{}},"0.3.3":{"name":"fibrous","version":"0.3.3","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.8.x","coffee-script":"*"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.6"},"scripts":{"pretest":"coffee -c -o lib src","test":"jasmine-node --coffee --junitreport spec"},"bugs":{"url":"https://github.com/goodeggs/fibrous/issues"},"_id":"fibrous@0.3.3","dist":{"shasum":"8abbf6c8047969b3422e42f2a511a8ed8ebe79f2","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.3.3.tgz","integrity":"sha512-57vfnS74Wf+eSxHD88izv7L31q4LELNShBHGN2NJm4L2HgSZrNhiHw0L6HXv8XuRvNXiNgiDqPH45L/XK2uPgA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDCFCcUTS3tl75824Olu/gKsQovSrhxw8LDQSYiRMMpBAIgDYJTkem4B+t+L56K3QNvgjgS/6RRzOcSXsKG/GA7EMk="}]},"_from":".","_npmVersion":"1.3.11","_npmUser":{"name":"demands","email":"me@maxedmands.com"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"},{"name":"hurrymaplelad","email":"adam@hmlad.com"},{"name":"demands","email":"me@maxedmands.com"}],"directories":{}},"0.4.0":{"name":"fibrous","version":"0.4.0","description":"Easily mix asynchronous and synchronous programming styles in node.js","homepage":"http://goodeggs.github.com/fibrous/","repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"licenses":["MIT"],"dependencies":{"fibers":">=0.6.7"},"devDependencies":{"jasmine-node":"1.8.x","coffee-script":"1.6.x"},"main":"lib/fibrous","bin":{"fibrous":"./bin/fibrous"},"engine":{"node":">=0.8"},"scripts":{"pretest":"coffee -c -o lib src; for i in `ls lib/*.js`; do cat $i | sed \"1s/Generated by/CodeClimate: don't ignore/\" > $i.tmp; mv $i.tmp $i; done","test":"jasmine-node --coffee spec"},"gitHead":"22869b39bec3134302daa67ca13f1bc16f7fabc2","bugs":{"url":"https://github.com/goodeggs/fibrous/issues"},"_id":"fibrous@0.4.0","_shasum":"09e1d8239beacaa6ec41991e752bf610fe7a1bb6","_from":".","_npmVersion":"1.4.28","_npmUser":{"name":"hurrymaplelad","email":"adam@hmlad.com"},"maintainers":[{"name":"asalant","email":"alon@salant.org"},{"name":"randypuro","email":"randypuro@gmail.com"},{"name":"hurrymaplelad","email":"adam@hmlad.com"},{"name":"demands","email":"me@maxedmands.com"}],"dist":{"shasum":"09e1d8239beacaa6ec41991e752bf610fe7a1bb6","tarball":"https://registry.npmjs.org/fibrous/-/fibrous-0.4.0.tgz","integrity":"sha512-/72yLU9Vtw+N/ftZ2u9OezvAeCYSp609a925HejjCghNMBgrvoBxSLFmYe/ogdNUUn4xXMlEl3kHwXx3GbeMJg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC7DxJOOpzqBno+8RN2A8CEnPhnfEf6rO/kv06uFoH5ewIhAIGTiRXvYMqjDi5GVpa7bmYzyRMvJj4acLeLX5oRJ0+B"}]},"directories":{}}},"readme":"Fibrous\n=======\n\nEasily mix asynchronous and synchronous programming styles in node.js.\n\n[![build status][travis-badge]][travis-link]\n[![npm version][npm-badge]][npm-link]\n[![mit license][license-badge]][license-link]\n[![we're hiring][hiring-badge]][hiring-link]\n\nBenefits\n--------\n\n* Easy-to-follow flow control for both serial and parallel execution\n* Complete stack traces, even for exceptions thrown within callbacks\n* No boilerplate code for error and exception handling\n* Conforms to standard node async API\n\nInstall\n-------\n\nFibrous requires node version 0.6.x or greater.\n\n```\nnpm install fibrous\n```\n\n\nExamples\n-----\n\nWould you rather write this:\n\n```javascript\nvar updateUser = function(id, attributes, callback) {\n  User.findOne(id, function (err, user) {\n    if (err) return callback(err);\n    \n    user.set(attributes);\n    user.save(function(err, updated) {\n      if (err) return callback(err);\n\n      console.log(\"Updated\", updated);\n      callback(null, updated);\n    });\n  });\n});\n```\n\nOr this, which behaves identically to calling code:\n\n```javascript\nvar updateUser = fibrous(function(id, attributes) {\n  user = User.sync.findOne(id);\n  user.set(attributes);\n  updated = user.sync.save();\n  console.log(\"Updated\", updated);\n  return updated;\n});\n```\n\nOr even better, with [CoffeeScript](http://coffeescript.org):\n\n```coffeescript\nupdateUser = fibrous (id, attributes) ->\n  user = User.sync.findOne(id)\n  user.set(attributes)\n  updated = user.sync.save()\n  console.log(\"Updated\", updated)\n  updated\n```\n\n### Without Fibrous\n\nUsing standard node callback-style APIs without fibrous, we write \n(from [the fs docs](http://nodejs.org/docs/v0.6.14/api/fs.html#fs_fs_readfile_filename_encoding_callback)):\n\n```javascript\nfs.readFile('/etc/passwd', function (err, data) {\n  if (err) throw err;\n  console.log(data);\n});\n```\n\n### Using sync\n\nUsing fibrous, we write:\n\n```javascript\ndata = fs.sync.readFile('/etc/passwd');\nconsole.log(data);\n```\n\n### Using future\n\nThis is the same as writing:\n\n```javascript\nfuture = fs.future.readFile('/etc/passwd');\ndata = future.wait();\nconsole.log(data);\n```\n\n### Waiting for Multiple Futures\n\nOr for multiple files read asynchronously:\n\n```javascript\nfutures = [\n  fs.future.readFile('/etc/passwd'),\n  fs.future.readFile('/etc/hosts')\n];\ndata = fibrous.wait(futures);\nconsole.log(data[0], data[1]);\n```\n\nNote that `fs.sync.readFile` is **not** the same as `fs.readFileSync`. The\nlatter blocks while the former allows the process to continue while\nwaiting for the file read to complete.\n\nMake It Fibrous\n---------------\n\nFibrous uses [node-fibers](https://github.com/laverdet/node-fibers)\nbehind the scenes.\n\n`wait` and `sync` (which uses `wait`\ninternally) require that they are called within a fiber. Fibrous\nprovides two easy ways to do this.\n\n### 1. fibrous Function Wrapper\n\nPass any function to `fibrous` and it returns a function that\nconforms to standard node async APIs with a callback as the last\nargument. The callback expects `err` as the first argument and the function\nresult as the second. Any exception thrown will be passed to the\ncallback as an error.\n\n```javascript\nvar asynFunc = fibrous(function() {\n  return fs.sync.readFile('/etc/passwd');\n});\n```\n\nis functionally equivalent to:\n\n```javascript\nvar asyncFunc = function(callback) {\n  fs.readFile('/etc/passwd', function(err, data) {\n    if (err) return callback(err);\n\n    callback(null, data);\n  });\n}\n```\n\nWith coffeescript, the fibrous version is even cleaner:\n\n```coffeescript\nasyncFunc = fibrous ->\n  fs.sync.readFile('/etc/passwd')\n```\n\n`fibrous` ensures that the passed function is\nrunning in an existing fiber (from higher up the call stack) or will\ncreate a new fiber if one does not already exist.\n\n### 2. Express/Connect Middleware\n\nFibrous provides [connect](http://www.senchalabs.org/connect/)\nmiddleware that ensures that every request runs in a fiber.\nIf you are using [express](http://expressjs.com/), you'll\nwant to use this middleware.\n\n```javascript\nvar express = require('express');\nvar fibrous = require('fibrous');\n\nvar app = express();\n\napp.use(fibrous.middleware);\n\napp.get('/', function(req, res){\n  data = fs.sync.readFile('./index.html', 'utf8');\n  res.send(data);\n});\n```\n\n### 3. Wrap-and-run with fibrous.run\n\n`fibrous.run` is a utility function that creates a fibrous function then executes it.\n\nProvide a callback to handle any errors and the return value of the passed function (if you need it).\nIf you don't provide a callback and there is an error, run will throw the error which will produce an uncaught exception.\nThat may be okay for quick and dirty work but is probably a bad idea in production code.\n\n```javascript\nfibrous.run(function() {\n  var data = fs.sync.readFile('/etc/passwd');\n  console.log(data.toString());\n  return data;\n}, function(err, returnValue) {\n  console.log(\"Handle both async and sync errors here\", err);\n});\n```\n\n### 4. Waiting on a callback\n\nSometimes you need to wait for a callback to happen that does not conform to `err, result` format (for example streams). In this case the following pattern works well:\n\n```javascript\nvar stream = <your stream>\n\nfunction wait(callback) {\n  stream.on('close', function(code) {\n    callback(null, code);\n  });\n}\n\nvar code = wait.sync();\n```\n\nDetails\n-------\n\n### Error Handling / Exceptions\n\nIn the above examples, if `readFile` produces an error, the fibrous versions\n(both `sync` and `wait`) will throw an exception. Additionally, the stack\ntrace will include the stack of the calling code unlike exceptions\ntypically thrown from within callback.\n\n\n### Testing\n\nFibrous provides a test helper for [jasmine-node](https://github.com/mhevery/jasmine-node) \nthat ensures that `beforeEach`, `it`, and `afterEach` run in a fiber.\nRequire it in your shared `spec_helper` file or in the spec files where\nyou want to use fibrous.\n\n```javascript\nrequire('fibrous/lib/jasmine_spec_helper');\n\ndescribe('My Spec', function() {\n  \n  it('tests something asynchronous', function() {\n    data = fs.sync.readFile('/etc/password');\n    expect(data.length).toBeGreaterThan(0);\n  });\n});\n```\n\nIf an asynchronous method called through fibrous produces an error, the\nspec helper will fail the spec.\n\n[mocha-fibers](https://github.com/tzeskimo/mocha-fibers) provides a fiber wrapper for [mocha](http://mochajs.org/).\n\nIf you write a helper for other testing frameworks, we'd love to include it in the project.\n\n### Console\n\nFibrous makes it much easier to work with asynchronous methods in an\ninteractive console, or REPL.\n\nIf you find yourself in an interactive session, you can require fibrous so that\nyou can use `future`.\n\n```\n> fs = require('fs');\n> require('fibrous');\n> data = fs.future.readFile('/etc/passwd', 'utf8');\n> data.get()\n```\n\nIn this example, `data.get()` will return the result of the future,\nprovided you have waited long enough for the future to complete.\n(The time it takes to type the next line is almost always long enough.)\n\nYou can't use `sync` in the above scenario because a fiber has not been created\nso you can't call `wait` on a future.\n\nFibrous does provide a bin script that creates a new interactive console where each command\nis run in a fiber so you can use sync. If you install fibrous with `npm install -g fibrous`\nor have `./node_modules/.bin` on your path, you can just run:\n\n```\n$ fibrous\nStarting fibrous node REPL...\n> fs = require('fs');\n> data = fs.sync.readFile('/etc/passwd', 'utf8');\n> console.log(data);\n##\n# User Database\n#\n...\n```\n\nOr for a CoffeeScript REPL:\n\n```\n$ fibrous -c [or --coffee]\nStarting fibrous coffee REPL...\ncoffee> fs = require 'fs'\ncoffee> data = fs.sync.readFile '/etc/passwd', 'utf8'\ncoffee> console.log data\n##\n# User Database\n#\n...\n```\n\n### Gotchas\n\n\nThe first time you call `sync` or `future` on an object, it builds the sync\nand future proxies so if you add a method to the object later, it will\nnot be proxied.\n\n#### With Express and `bodyParser` or `json`\n\nYou might be getting an error in Express that you are not in context of a fiber even after adding `fibrous.middleware` to your stack. This can happen if you added it before `express.json()` or `express.bodyParser()`. Here's an example:\n\n```javascript\n// might not work\napp.use(fibrous.middleware);\napp.use(express.bodyParser());\n\n// or\napp.use(fibrous.middleware);\napp.use(express.json());\n\n// should work\napp.use(express.bodyParser());\napp.use(fibrous.middleware);\n\n// or\napp.use(express.json());\napp.use(fibrous.middleware);\n```\n\nBehind The Scenes\n-----------------\n\n\n### Futures\n\nFibrous uses the `Future` implementation from [node-fibers](https://github.com/laverdet/node-fibers).\n\n`future.wait` waits for the future to resolve then returns the result while allowing the process\nto continue. `fibrous.wait` accepts a single future, multiple future arguments or an array of futures.\nIt returns the result of the future if passed just one, or an array of\nresults if passed multiple.\n\n`future.get` returns the result of the resolved future or throws an\nexception if not yet resolved.\n\n### Object & Function mixins\n\nFibrous mixes `future` and `sync` into `Function.prototype` so you can\nuse them directly as in:\n\n```javascript\nreadFile = require('fs').readFile;\ndata = readFile.sync('/etc/passwd');\n```\n\nFibrous adds `future` and `sync` to `Object.prototype` correctly so they\nare not enumerable.\n\nThese proxy methods also ignore all getters, even those that may\nreturn functions. If you need to call a getter with fibrous that returns an\nasynchronous function, you can do:\n\n```javascript\nfunc = obj.getter\nfunc.future.call(obj, args)\n```\n\n### Disclaimer\n\nSome people don't like libraries that mix in to Object.prototype\nand Function.prototype. If that's how you feel, then fibrous is probably\nnot for you. We've been careful to mix in 'right' so that we don't\nchange property enumeration and find that the benefits of having sync\nand future available without explicitly wrapping objects or functions\nare worth the philosophical tradeoffs.\n\n\nContributing\n------------\n\n```\ngit clone git://github.com/goodeggs/fibrous.git\nnpm install\nnpm test\n```\n\nFibrous is written in [coffeescript](http://coffeescript.org) with\nsource in `src/` compiled to `lib/`.\n\nTests are written with [jasmine-node](https://github.com/mhevery/jasmine-node) in `spec/`.\n\nRun tests with `npm test` which will also compile the coffeescript to\n`lib/`.\n\nPull requests are welcome. Please provide tests for your changes and\nfeatures. Thanks!\n\nContributors\n------------\n\n* Randy Puro ([randypuro](https://github.com/randypuro))\n* Alon Salant ([asalant](https://github.com/asalant))\n* Bob Zoller ([bobzoller](https://github.com/bobzoller))\n\n[travis-badge]: http://img.shields.io/travis/goodeggs/fibrous/master.svg?style=flat-square\n[travis-link]: https://travis-ci.org/goodeggs/fibrous\n[npm-badge]: http://img.shields.io/npm/v/fibrous.svg?style=flat-square\n[npm-link]: https://www.npmjs.org/package/fibrous\n[license-badge]: http://img.shields.io/badge/license-mit-blue.svg?style=flat-square\n[license-link]: LICENSE.md\n[hiring-badge]: https://img.shields.io/badge/we're_hiring-yes-brightgreen.svg?style=flat-square\n[hiring-link]: http://goodeggs.jobscore.com/?detail=Open+Source&sid=161\n","maintainers":[{"email":"open-source@goodeggs.com","name":"goodeggs-admin"},{"email":"randypuro@gmail.com","name":"randypuro"},{"email":"adam@hmlad.com","name":"hurrymaplelad"},{"email":"npm@maxedmands.com","name":"demands"},{"email":"alon@salant.org","name":"asalant"}],"time":{"modified":"2022-06-18T00:28:54.891Z","created":"2012-04-04T20:09:21.196Z","0.2.4":"2012-04-04T20:09:22.488Z","0.2.5":"2012-04-04T20:24:45.931Z","0.2.7":"2012-08-20T22:45:53.042Z","0.2.8":"2012-11-27T06:43:27.253Z","0.2.9":"2012-12-09T03:01:21.433Z","0.3.0":"2013-01-23T01:35:07.369Z","0.3.1":"2013-06-05T00:28:30.532Z","0.3.2":"2013-07-08T16:55:17.884Z","0.3.3":"2013-11-27T22:47:25.722Z","0.4.0":"2015-06-10T02:14:38.483Z"},"repository":{"type":"git","url":"https://github.com/goodeggs/fibrous.git"},"users":{"akanieski":true},"homepage":"http://goodeggs.github.com/fibrous/","keywords":["fiber","fibers","coroutine","future","async","sync","wait"],"contributors":[{"name":"Randy Puro","email":"randypuro@gmail.com","url":"https://github.com/randypuro"},{"name":"Alon Salant","email":"alon@salant.org","url":"https://github.com/asalant"},{"name":"Bob Zoller","email":"bob@zoller.us","url":"https://github.com/bobzoller"}],"bugs":{"url":"https://github.com/goodeggs/fibrous/issues"},"readmeFilename":"README.md"}