{"_id":"slide","_rev":"68-ee60df029b419fab68685ef11f44c1b8","name":"slide","description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","dist-tags":{"latest":"1.1.6"},"versions":{"1.0.0":{"name":"slide","version":"1.0.0","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","directories":{"lib":"lib"},"_id":"slide@1.0.0","engines":{"node":"*"},"_nodeSupported":true,"_npmVersion":"0.2.7-2","_nodeVersion":"v0.3.1-pre","dist":{"tarball":"https://registry.npmjs.org/slide/-/slide-1.0.0.tgz","shasum":"c3842da5e075b83eb68864c3fa64d752121b17f1","integrity":"sha512-Gp1SBy5DLAInINWyztSAoUn1+X1aasuHN1HcnmRDwoKrxpO3hEgqcfeKcYs4zEbrTVK0cuMGH4vsiSWYBKrpWQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA60XouqJf5H5/AgUCzg1gEk1Z6tTxwQzWGqntTujamwAiBa5kp6ByuSLow0tGq+Iy13c1L4RwWNUSTefWfffaw4DA=="}]}},"1.0.1":{"name":"slide","version":"1.0.1","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","directories":{"lib":"lib"},"_id":"slide@1.0.1","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.2.14-6","_nodeVersion":"v0.3.5-pre","modules":{"b/async-map.js":"lib/async-map.js","b/bind-actor.js":"lib/bind-actor.js","b/chain.js":"lib/chain.js"},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"b7d9076eee798237666e66e3f18157532b297f32","tarball":"https://registry.npmjs.org/slide/-/slide-1.0.1.tgz","integrity":"sha512-jpSKbn4XTyhY0XEAOTpw7NBYkIhDIxWjLUpnhM5FEKRJMO1ctlHHL90d1ATNeBMy1PnxCKv1x4L0kVWVxWyhCA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE0B5MpwvWLI4ZuxsFdyF6+a7TRLf9IBwfz+KXUIVgsSAiEAvw02IJvNIzejXPAfD+7jbGtbu7Ivt/30CHsYjNCG9lc="}]}},"1.1.0":{"name":"slide","version":"1.1.0","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide","_id":"slide@1.1.0","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"0.2.17","_nodeVersion":"v0.3.8-pre","directories":{"lib":"./lib"},"files":[""],"_defaultsLoaded":true,"dist":{"shasum":"a9e135aa14bf5bb8b8c9e16c723c7223ac30f717","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.0.tgz","integrity":"sha512-rY9toXYBX2ni1gl2V1Ibxo/FyZ+XUfMvFmpK65qwgL2TFHjRbFRrtq12th6oWkwZBWlJqgTOyF3b5KY+JEicXA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDle+fE8xU4SH434DEPGAMVMcfHPRqgvCqOdSXRKGUHZAiB9ST2QkK1B72fRbdesL2slMBc0YH6a0jh1Z+OkL0rs8Q=="}]}},"1.1.1":{"name":"slide","version":"1.1.1","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","_id":"slide@1.1.1","engines":{"node":"*"},"_engineSupported":true,"_npmVersion":"1.0.0","_nodeVersion":"v0.5.0-pre","directories":{"lib":"./lib"},"_defaultsLoaded":true,"dist":{"shasum":"198afd3d6aab806681924a08e49b5758fb1c49b6","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.1.tgz","integrity":"sha512-iB9yoC7YN064tesmEcOJuWhicxMyLqHb+8t/InH+hBFJ9zg87g+gpIksSR7XlLva6EsIhfhlq99fbgYgGNurzw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGqdcD2LxQztI0u99PTG1mUiDZC3LgErWfT0wgCvEo7VAiBV71JahfFiY+v2ZnCvS2NoEMwCSQVnSS/kwEDm6YpGlw=="}]}},"1.1.2":{"name":"slide","version":"1.1.2","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"_npmJsonOpts":{"file":"/Users/isaacs/.npm/slide/1.1.2/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"slide@1.1.2","_engineSupported":true,"_npmVersion":"1.0.18","_nodeVersion":"v0.4.10-pre","_defaultsLoaded":true,"dist":{"shasum":"6339e63a65f1d5f6b0ab9a573a6ca276993aad7d","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.2.tgz","integrity":"sha512-DSTx0YisT2rkfU2pyqB/A580poJ0E4nHNErbTnr8ybaN1t+Goqvqtv2vmOA1yWAPDeXt9sPTxeQdMaqIIYZ1HA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIADuw1ll2zJSge+0eMO7hEsrFdVyZhNQwX/EaMd5s2FkAiAclIUKM5Hiy0j29WrDlvifh5JoWNGwx+ruCZgE4hIgxA=="}]},"scripts":{},"directories":{}},"1.1.3":{"name":"slide","version":"1.1.3","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"_npmJsonOpts":{"file":"/Users/isaacs/.npm/slide/1.1.3/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"slide@1.1.3","_engineSupported":true,"_npmVersion":"1.0.22","_nodeVersion":"v0.4.10-pre","_defaultsLoaded":true,"dist":{"shasum":"a16975ba76b766b92f98ef337243336c1fa3238f","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.3.tgz","integrity":"sha512-GGhL1N9nLmdyP92imLjO3BZnHfs3S/M+E3Wp5oZmjbfcEHKpj8kqnADU/Nliw2hAvGASiSLo+fATppkXhVA0wg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGHJpE7iaGedAlQtEvZc4qUKYzF5A2/DAPzY9vPXAOc+AiEAqFnY4HVFxFBybAfHRnddKSInTy59s5qj+4Czfokkwmg="}]},"scripts":{},"directories":{}},"1.1.4":{"name":"slide","version":"1.1.4","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"bugs":{"url":"https://github.com/isaacs/slide-flow-control/issues"},"_id":"slide@1.1.4","dist":{"shasum":"2b23f1949b369ed61d22bd6570ff0320302fc8df","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.4.tgz","integrity":"sha512-X8CjfBmpV6oxslbeMYCLoAIKAPQcZN7bDF+19+3OeB/JwRFy9Ahu+HmwJCq3f7HutSy7r7e4ngK3yd0+bAGMnQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFMwingcvVeizua6W3YYlPCFMLRmvRr5Tf/2F+jsUNDVAiBQn0PeDbUqlZROsd/FL4gIv1ilOb2eqJ93ZRWBpje6Rw=="}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"isaacs","email":"i@izs.me"},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"directories":{}},"1.1.5":{"name":"slide","version":"1.1.5","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"license":"ISC","bugs":{"url":"https://github.com/isaacs/slide-flow-control/issues"},"_id":"slide@1.1.5","dist":{"shasum":"31732adeae78f1d2d60a29b63baf6a032df7c25d","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.5.tgz","integrity":"sha512-8oLEiBSBB5bcp/HjrygKMr0qEkWcjeQVjPWYRij7M8Edj05cvdlc70UnfiVXubOKjeFGKYoZSn5k8jKKxn4cgw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIB9RdH6yEZQcs2+SBWAm2xqOxwxGzqD8WfrI/0jzW1aJAiAxJ2Iw+XFVKpoGTqn2BPSynN1aeRv0hu12ZZP0UIBfUA=="}]},"_from":".","_npmVersion":"1.3.8","_npmUser":{"name":"isaacs","email":"i@izs.me"},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"directories":{}},"1.1.6":{"name":"slide","version":"1.1.6","author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"description":"A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS","main":"./lib/slide.js","dependencies":{},"devDependencies":{},"engines":{"node":"*"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"license":"ISC","gitHead":"8345e51ee41e35825abc1a40750ea11462f57028","bugs":{"url":"https://github.com/isaacs/slide-flow-control/issues"},"homepage":"https://github.com/isaacs/slide-flow-control","_id":"slide@1.1.6","scripts":{},"_shasum":"56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707","_from":".","_npmVersion":"2.0.0-beta.3","_npmUser":{"name":"isaacs","email":"i@izs.me"},"maintainers":[{"name":"isaacs","email":"i@izs.me"}],"dist":{"shasum":"56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707","tarball":"https://registry.npmjs.org/slide/-/slide-1.1.6.tgz","integrity":"sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID0Mj2bpJQiHRE8tRK8UwUVA63fJ/qljzJ9yfnT+1z0XAiEAm05PT7YJbb/vJHW+6DONSbtGTNmOdNRr7FZEuqNNzO0="}]},"directories":{}}},"maintainers":[{"email":"i@izs.me","name":"isaacs"}],"author":{"name":"Isaac Z. Schlueter","email":"i@izs.me","url":"http://blog.izs.me/"},"time":{"modified":"2024-04-20T07:05:49.178Z","created":"2011-01-13T21:21:32.280Z","1.0.0":"2011-01-13T21:21:32.280Z","1.0.1":"2011-01-13T21:21:32.280Z","1.1.0":"2011-02-03T19:17:03.150Z","1.1.1":"2011-03-17T04:10:26.257Z","1.1.2":"2011-07-20T09:29:21.068Z","1.1.3":"2011-07-27T20:22:03.040Z","1.1.4":"2013-04-29T15:33:13.142Z","1.1.5":"2013-08-19T22:27:46.044Z","1.1.6":"2014-09-12T23:34:41.727Z"},"repository":{"type":"git","url":"git://github.com/isaacs/slide-flow-control.git"},"users":{"agnat":true,"stdarg":true,"matteo.collina":true,"jian263994241":true,"hal9zillion":true,"mattmcfarland":true,"lgomez":true,"gekowa":true,"wangnan0610":true},"readme":"# Controlling Flow: callbacks are easy\n\n## What's actually hard?\n\n- Doing a bunch of things in a specific order.\n- Knowing when stuff is done.\n- Handling failures.\n- Breaking up functionality into parts (avoid nested inline callbacks)\n\n\n## Common Mistakes\n\n- Abandoning convention and consistency.\n- Putting all callbacks inline.\n- Using libraries without grokking them.\n- Trying to make async code look sync.\n\n## Define Conventions\n\n- Two kinds of functions: *actors* take action, *callbacks* get results.\n- Essentially the continuation pattern. Resulting code *looks* similar\n  to fibers, but is *much* simpler to implement.\n- Node works this way in the lowlevel APIs already, and it's very ﬂexible.\n\n## Callbacks\n\n- Simple responders\n- Must always be prepared to handle errors, that's why it's the first argument.\n- Often inline anonymous, but not always.\n- Can trap and call other callbacks with modified data, or pass errors upwards.\n\n## Actors\n\n- Last argument is a callback.\n- If any error occurs, and can't be handled, pass it to the callback and return.\n- Must not throw. Return value ignored.\n- return x ==> return cb(null, x)\n- throw er ==> return cb(er)\n\n```javascript\n// return true if a path is either\n// a symlink or a directory.\nfunction isLinkOrDir (path, cb) {\n  fs.lstat(path, function (er, s) {\n    if (er) return cb(er)\n    return cb(null, s.isDirectory() || s.isSymbolicLink())\n  })\n}\n```\n\n# asyncMap\n\n## Usecases\n\n- I have a list of 10 files, and need to read all of them, and then continue when they're all done.\n- I have a dozen URLs, and need to fetch them all, and then continue when they're all done.\n- I have 4 connected users, and need to send a message to all of them, and then continue when that's done.\n- I have a list of n things, and I need to dosomething with all of them, in parallel, and get the results once they're all complete.\n\n\n## Solution\n\n```javascript\nvar asyncMap = require(\"slide\").asyncMap\nfunction writeFiles (files, what, cb) {\n  asyncMap(files, function (f, cb) {\n    fs.writeFile(f, what, cb)\n  }, cb)\n}\nwriteFiles([my, file, list], \"foo\", cb)\n```\n\n# chain\n\n## Usecases\n\n- I have to do a bunch of things, in order. Get db credentials out of a file,\n  read the data from the db, write that data to another file.\n- If anything fails, do not continue.\n- I still have to provide an array of functions, which is a lot of boilerplate,\n  and a pita if your functions take args like\n\n```javascript\nfunction (cb) {\n  blah(a, b, c, cb)\n}\n```\n\n- Results are discarded, which is a bit lame.\n- No way to branch.\n\n## Solution\n\n- reduces boilerplate by converting an array of [fn, args] to an actor\n  that takes no arguments (except cb)\n- A bit like Function#bind, but tailored for our use-case.\n- bindActor(obj, \"method\", a, b, c)\n- bindActor(fn, a, b, c)\n- bindActor(obj, fn, a, b, c)\n- branching, skipping over falsey arguments\n\n```javascript\nchain([\n  doThing && [thing, a, b, c]\n, isFoo && [doFoo, \"foo\"]\n, subChain && [chain, [one, two]]\n], cb)\n```\n\n- tracking results: results are stored in an optional array passed as argument,\n  last result is always in results[results.length - 1].\n- treat chain.first and chain.last as placeholders for the first/last\n  result up until that point.\n\n\n## Non-trivial example\n\n- Read number files in a directory\n- Add the results together\n- Ping a web service with the result\n- Write the response to a file\n- Delete the number files\n\n```javascript\nvar chain = require(\"slide\").chain\nfunction myProgram (cb) {\n  var res = [], last = chain.last, first = chain.first\n  chain([\n    [fs, \"readdir\", \"the-directory\"]\n  , [readFiles, \"the-directory\", last]\n  , [sum, last]\n  , [ping, \"POST\", \"example.com\", 80, \"/foo\", last]\n  , [fs, \"writeFile\", \"result.txt\", last]\n  , [rmFiles, \"./the-directory\", first]\n  ], res, cb)\n}\n```\n\n# Conclusion: Convention Profits\n\n- Consistent API from top to bottom.\n- Sneak in at any point to inject functionality. Testable, reusable, ...\n- When ruby and python users whine, you can smile condescendingly.\n","readmeFilename":"README.md","homepage":"https://github.com/isaacs/slide-flow-control","contributors":[{"name":"S. Sriram","email":"ssriram@gmail.com","url":"http://www.565labs.com"}],"bugs":{"url":"https://github.com/isaacs/slide-flow-control/issues"},"license":"ISC"}