{"_id":"tamejs","_rev":"71-e1aa261ab08bcb07f1c6efbec71e2b56","name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","dist-tags":{"latest":"0.4.14"},"versions":{"0.0.1":{"author":{"name":"Max Krohn","email":"max@okcupid.com","url":"http://maxk.org"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.0.1","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/compiler.js"},"engines":{"node":"0.4 || 0.5"},"devDependencies":{"jison":"*"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.0.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.0.1","dependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"a22482d3bbca97d89f15fbc303304c81f5149276","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.0.1.tgz","integrity":"sha512-prpBVj3na4SKLJgK/t7R5D050Xr+90ilxQuA39xvnKyGF46S1vECkmCkmLHBsVxFiweMdqlN7IMJgc+wZdr5xg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8bppie3WPYuk6vI84Nbj2dOHs/bZn4YbJpmB4hys84AIgFhdsJ+qNiXeelCcTIZ+LCx00H79OWLzeXLrNmEqIiIw="}]},"scripts":{}},"0.1.0":{"author":{"name":"Max Krohn","email":"max@okcupid.com","url":"http://maxk.org"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.0","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/compiler.js"},"engines":{"node":"0.4 || 0.5"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.0","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"ec4bbdcd4ae23c1964e6537aab91c6996835e79d","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.0.tgz","integrity":"sha512-T2lecIxp6vHWrpCoKrti5JhFi5PDBtNMvHdDr/H6fYRlb6kQX3xRCZZbQFdsyAaxigrBad0M2eio/7EaX1p6Bw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDeHp5QZHbC0MokNl6E+y70S8wW7fXPoEYaqIAN5Fo2bgIhAIL/39DKsYF6laJOvh5t1nTwkTEuq4gy2JVr4EJOGaCZ"}]},"scripts":{}},"0.1.1":{"author":{"name":"Max Krohn","email":"max@okcupid.com","url":"http://maxk.org"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.1","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.1","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"50f93cf52ca3fbf665cf351c5f9c52727418034f","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.1.tgz","integrity":"sha512-+a9qZR9y64nUWV+VU3qj/BMzVxKUJ7bX/d21gDhzlzLZQ4r772NO0yJRGnNqJqCrqrV+/dbCN1VK1rF3wzNDZg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD2zv/GtL0pRxbh88UWFjGPXqCqy2g7JxSdzc/eW2BSuAIhAKAh+8Plz4T+p6WjpGRIxyAChcqpBWYgI3nfhh3YF/jI"}]},"scripts":{}},"0.1.2":{"author":{"name":"Max Krohn","email":"max@okcupid.com","url":"http://maxk.org"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.2","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.2/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.2","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"d6731ea6eedb5877666685477509c0405e3a4b90","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.2.tgz","integrity":"sha512-6wfFcVgJ6NfTQJ4LPZ/iR2H86DeYQ7JeORZ0qX/n1GKwzejC9jDZCD2WDP/KIUo5VyiHbMUJ3eYNb62b5IJ1uw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDqev9G5wtYSOY27VtOLsngQ97Pe+wU0QXwW93M6dPkggIgNz8R2MycHCT30/lrl6KuwQSC6izi8hfeJGbpV5BUmGk="}]}},"0.1.3":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.3","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.3/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.3","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"1b0f20b9746c0408e3a92f490992cd6233e7eccf","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.3.tgz","integrity":"sha512-j7sFJge2OAma10bkntTuNOZQDgxKgd+R6l+xgpphcgoTySBpWUK14xoY/7i77Nz4He3cn9j8x5XqfaT0Arcnqw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCJ2DLN0rapZUltaCdbNRW7tC0ryMwFMtl4duFjzN1qqAIgUXL78WfLmSUs6W1bJQH92EJTTQBWaNqP0wjLQMfRUpE="}]}},"0.1.4":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.4","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.4/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.4","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"3fef9fe572a66aa13cdb7330eaedd6303f5e797b","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.4.tgz","integrity":"sha512-QLXU122ZrlpYcFFm1o2cEA6ZW1vumuAqHvjNLl8kjBaKEC8eycQLbcp2IRJ3xFEPkH2q2bkl/zkbKjY8y2XDlg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDcVdefv1VkwbDs094sZU93hD6Sww0myYj2nQAYnkKpCAIgYNHDwCoXyJt+H/j6XQrKo28JZyFIxljgREs1iU6v8Cs="}]}},"0.1.5":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.1.5","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.1.5/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.1.5","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"62ff24b445afd52c75cc27dfb02143d01e5907a0","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.1.5.tgz","integrity":"sha512-AnVTPbUF0vTz8v6hTDm3TjkrRoaLVgJpnDtR1v6391t6cCiys3lcpCYyNxweitydoQxQ2pMDnrPwLgEpPhG9LA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCd9ZZcjg5UfEhSiVQyqHzXZ5s+rkxPmJDxs1UZuEeLIAIhAJoonOJhfX0iolgSCf55mdUZ9cStV2yKAu/tUfaqM62y"}]}},"0.2.0":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.2.0","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.2.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.2.0","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"6151544e6d3779b65e503062c05b55029a156bdc","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.2.0.tgz","integrity":"sha512-f+VULHHCoPwILTU641LNfrWZm1UtEC0i8vwKmCD+blpUC7OrG8CbQTfk03hrU0oZqhM7uWVX/5PLlPFONEn53Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDVCWFI4n8D480rcfRjYR/fO82vXw9nNXW5XvPi1wdeRwIhAMvGMeU9hh/o1pTb9RmDgANko47rHUryZJvu6TLPmK5W"}]}},"0.2.1":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.2.1","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.2.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.2.1","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"7c90843941d8d1158dfccf2d836d147f373dd4c7","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.2.1.tgz","integrity":"sha512-aLgL7gXaSLZoa89Wymqu1ArWhRYsmwqhGykm3kliX3Fk0EY/NWiw9m1PR2QD06STJdR54Q3T6hWEd0MB9S5jEQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCyeuGw8GkwTdMEaq22fqgfh1Tn6pIMbW5dPIcvOdHqcQIgdVROXQcXwfKNzcI9yjqv/24qo2y45RLPJGfBKMP2hTc="}]}},"0.2.2":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.2.2","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.2.2/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.2.2","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"58df2c578b9339521f19d8f49d145e1a6f85f374","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.2.2.tgz","integrity":"sha512-V9pwinBmF+tusV2MLGdBCv02UaPryi61jYraXFysrpMBraAIzeO8yy7GNBXbmQ0T7LgHjdNLFAFLWf4naV4yQQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC5rIuTYM7FuFQXw3mijLl7HY0dfxp/f47tVso4Wv3YogIhAJ7PANp8JgePU8oBpCjJBCcAaQsF8e6UeMSYhpSH29l+"}]}},"0.2.3":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.2.3","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.2.3/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.2.3","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"68bc8381cddf3b3b785b84ad0f3190c11cda0abb","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.2.3.tgz","integrity":"sha512-+8+llPY0c4TwLkA2B3Sh6s5kTtiQi1bbPPB37hy6lL35BkwV6Z9GLQszuPH5UKZ28FgDbyjHF8VFC9lCHfhrSw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHsMphq1B3kwApCl8AY6p65J004r40XLcByrZtGpFM/4AiEAtVxXntzEWxoPcjaPR1TWzUFMNyAwcrvkAEqmnkMvoIc="}]}},"0.3.0":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.0","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.0/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.0","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"8d110cfa2dfbadc124a6a65e880afb79e26cb1ae","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.0.tgz","integrity":"sha512-57FBX3w/WJsRfrGjmKw6SvOFR7a+3hj2v2aHPka3ldxs1Fxb3RY66bJ9pTR+O5emzQyThIyylMTwoeqTWGJgyQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDjkCg4Iv6cx2GsA3iG/g/0WQF09uHxLNkZCm4o/fdV+wIhAOxfzRTSo30xHne1AVGjuNS3S5UhY6K6Zvcpn0C1EuiB"}]}},"0.3.1":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.1","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.1","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"0f3ea66792c85e61a90dc59e82f98e7ad36c6667","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.1.tgz","integrity":"sha512-yP0WfGtl5TOAZLzjWTBFlOf2TFjCsOJlG1zpUytPwaFCZrv6u0ueQq/w97d59Y1Gis9TQ9RcGXbnsFduHKTA0Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA1ss1vzjebf6DpVfgJ7CoOs2mty/2L3AChDZFubt30RAiAhDKUtaOxLXMH7QSEMxLRvkHH0scdaf/SXSJcnnSeykg=="}]}},"0.3.3":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.3","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.3/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.3","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"0183ece899ff47fe00b42b5f81689f00d27c1b23","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.3.tgz","integrity":"sha512-OR29aoVrrazTokC5EEvGwxGppV+l66o85ZfTV19Bq5XRS5m6P4h4qaXHUiJLSEwHz2XOzmNmVgC6sEiWEz86Kw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICM6nBxp6LLT2jHD+Gyc1mJSqqOpNqneAoef4AbX3VC9AiBdct/2y7RIeG3PgXjFP7GvsoQP8yqTnDH1SFhP80Ugmw=="}]}},"0.3.4":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.4","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.4/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.4","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"1dee53337bcb0e4283b5b419d419c2f043fd7a97","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.4.tgz","integrity":"sha512-th9dKgjL6K7JJmu+JKPS2/4uWlN4xzRR2pG6Khtms/W0HaBZngJaSKJ6/WJ/IFsmafycxd6lMBw69GNg9DxNxQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFDGHrxAF6Pzw4Qsbs8EgdTGXtGB6JUSXphYKlYBvftdAiEAoMQ7YZ2ZipwKBRFaM1+w0s7HfTfGBk0Z5jS747A06u4="}]}},"0.3.5":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.5","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.5/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.5","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"bf520fa4255e0a85aded4fa76a4a7a1061dd1331","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.5.tgz","integrity":"sha512-/FZwESNcYQN0GheFUVlIrx5y7N+kQVaXIUu1TCcNHlfj+Nqt+cjMkne3Klgxoax8vWcgeFcPKIEkLWA0CWgFhA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHw0JK74034wU10ZWwEfxNqAk4HaL/fH5OYTmJB4CjD2AiBKB5dKy/rM5pecyoNSFI5POICQ1mPrP13asSnpxmH0mw=="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.3.6":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.6","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.6/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.6","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"08c2ff7ce9f8170913fdc130cdb16bb2afcdae1d","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.6.tgz","integrity":"sha512-K8tZnUZ8lqW96PJ656jGVNHvWQH4HRCfof6io88MYF5B2jjHSe01JnQ1jjx46AyDgv9mqn0pIn4G6pPanQbpNw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHu0ZaY7Y3kR+mIq//OqZUTZO9Z3xwSlZldmT2QFQ15zAiEArF4y4MigrjwdmZNzucE0BIeqBsaMMNp0eVQ+R5M9KSg="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.3.7":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.3.7","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.3.7/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.3.7","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"16ed30b6e81a74cb9afa7e55624840c3c7fece30","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.3.7.tgz","integrity":"sha512-4PjjSvBDTLJTdyUh5D4E36BSWmiYZ4d1M8sVhZroCYyHncZ5AoXpGz1qvj5Cony/UA2R5UbWUruRiV7oy7Z7UQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC1kQo9Ad8vyZpwatsqQo1zzG6ZdyOkkAUFQKVsIpUE6AIgI0ROQ3LJCMpOu0reB1z5nkLyCoC/aphMXGNeVr4QdwA="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.1":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.1","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.4.1/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.4.1","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"7b67b8e3e369efac9a6022eefba9536d56b9e76d","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.1.tgz","integrity":"sha512-4h0QR/oUebWTHvxvBsxCL2lnrTqfi5GnCQKrrVSoUmQ4WJJ1zOmb3gXEgoVWnf0nBnz1nmdVRO1/4/CV7zaMWA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGOEgpM/qhszZxxmPvXS30GZdwM/ojIi9bTco8SeHv53AiByWZ6aT0yx37Cp+iu/oDSRMFfd/RKP75zWlS1clNywiQ=="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.2":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.2","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.4.2/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.4.2","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"93a63e30551e5277884a67b924a3f4639a996d5e","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.2.tgz","integrity":"sha512-H7bR3l9GgNeOwWaoudfyvtLojc+4TwppUtsfOpGJUgVK321gyB0YonQiof/O1BmZvZZ3S4bRPT/0hMFwvu5XOA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCxSRSB0J0bqPHf9DNdHCvQjXRtikDsYVTf23xCvHPdgQIhAPldEW8x0o1VY/du8CWyXX+bfFENLM48It1PSJSFjCxO"}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.3":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.3","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmJsonOpts":{"file":"/home/max/.npm/tamejs/0.4.3/package/package.json","wscript":false,"contributors":false,"serverjs":false},"_id":"tamejs@0.4.3","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.13","_nodeVersion":"v0.4.9-pre","_defaultsLoaded":true,"dist":{"shasum":"715c57c27021f0b7ab6af52fa0b1d8261ddb3928","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.3.tgz","integrity":"sha512-/pD6Xeu9MKYa57H9zOB9IqUTg0KEnCgTJX8I/ZDEA16C7qAuV1drqJtEVm7HkVz6LCsoQuj0fjj9khJ+ezPh6Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEUmOOzDPV/JOND9nDmIpCxeqLwhCa6KWSsWtJHrJwEyAiEA5V2zwG/YfjOQ9iULqZ+oErmK3F+y0trEyUONYkGw9Q0="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.4":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.4","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"0.4 || 0.5"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmUser":{"name":"maxtaco","email":"max@okcupid.com"},"_id":"tamejs@0.4.4","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.103","_nodeVersion":"v0.5.11-pre","_defaultsLoaded":true,"dist":{"shasum":"12d37a0d769f6311935f5803684f0a5474b8d8d9","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.4.tgz","integrity":"sha512-K6z0Wa6oMRhcJTyvgWrJSr/kZE5Tjgz2vnfns+3nmuCtzsNipRu7B6a5zWLpKZQP7owYD/gv8lTWjjPH/7zsMQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGHTksQ/S1SVPK2C5+cVEpwKGJSpyLXBD8ZiBv2HUryBAiEA6JBvA+agg7fcCgYOe9pB0yFbbL1WqRBtAnz7f7pQA60="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.5":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.5","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"node >= 0.4"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmUser":{"name":"maxtaco","email":"max@okcupid.com"},"_id":"tamejs@0.4.5","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.103","_nodeVersion":"v0.5.11-pre","_defaultsLoaded":true,"dist":{"shasum":"7e22d2c5da885c54ad483ed546b74bfa2e635611","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.5.tgz","integrity":"sha512-tM3A6cS4YWBnwNs+TKJlwCajBhF4//IhuWSfe2g6LrmaFmXWw7OpFwc5PW6/pjs1/nu4QV7ThxNLuo6BCanQuw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCMMkUqmyfKh7KgDYz94dUXQBQQtc7EzMVesKgzUfyogQIgPrPvPRREnyYb2nntOm4WUfeicTdNyO5S+8Yd6jVWBoM="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.7":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.7","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"node >= 0.4"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmUser":{"name":"maxtaco","email":"max@okcupid.com"},"_id":"tamejs@0.4.7","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.106","_nodeVersion":"v0.6.3","_defaultsLoaded":true,"dist":{"shasum":"675cd2e9f8d5489536182af8b301873650aae900","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.7.tgz","integrity":"sha512-CmGdbH4IocAHiEv5MVLjVe4YnQJ2iM+0/5hmi9Xw5cuD/fUBGVllZZcLDdFZsBpkofY8Gke2CcdaSZaHmC3Brg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG463yvWuwKdv4hz2EewVYZMiUYhAgu1OYtZBuEcElkYAiEA1QunOAbZolyhNSmt5PZj7RFdVVZeFjO242fZ1i4ViGU="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.8":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.8","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"node >= 0.4"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmUser":{"name":"maxtaco","email":"max@okcupid.com"},"_id":"tamejs@0.4.8","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.1.0-alpha-2","_nodeVersion":"v0.6.3","_defaultsLoaded":true,"dist":{"shasum":"5154a4b1489857887e9216cbbe6d9d7304796d52","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.8.tgz","integrity":"sha512-AEoCn5epElmqwxxAdYDrXGxu97NfBw1itnSruzqHyOrKp/4jz/XIeGzXymJ0kJvMmo1KAxQ/fUxaLdq6xZ6QqA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFoiH2AxovaigELtFJ+NdcR3SK01JO+LmCUxfpVqyc4vAiEA4pamAEfFXNhBxPt7DXEpa95t1FIDRwPWkj5KB2P95ws="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.9":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.9","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":{"node":"node >= 0.4"},"scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_npmUser":{"name":"maxtaco","email":"max@okcupid.com"},"_id":"tamejs@0.4.9","dependencies":{},"devDependencies":{},"_engineSupported":true,"_npmVersion":"1.0.106","_nodeVersion":"v0.5.0-pre","_defaultsLoaded":true,"dist":{"shasum":"905d6e7975a52704c900302633aadc118e9240d8","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.9.tgz","integrity":"sha512-ONu0atimqW4rJiajrtnyDphBEZ61sAmbejcV6ybHquXAEKNwOIlddKUtCQ8TJsh2TdwYtbR63Aw9DGb/lKEszw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC8IkB9Ecq7qLhCriizfbPGlbpnDJo2Lw4nVEauWaLvBAiEAvTsdDuCuLxiDfw4JOyxOtr5x6KGsGMS7u8ySv/VBaYI="}]},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.10":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.10","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":"node >= 0.4","scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_id":"tamejs@0.4.10","dist":{"shasum":"d01251f5c0625cb29ac2fcd7b84d1087b09ecefd","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.10.tgz","integrity":"sha512-/Y2d7n4qyS7HNNWtW6lKS8wQgnEsSh/0FbPwu/pevn3FNpRFPjj1k53CeREoGmnUJG6vY9jB3EkWcWstN5xfVQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBsYFA1KoNXq9/Lu6GxgDVVd7jLk2mrLpWI4X2Tmi4LNAiEAhjhw7LE8qDJ3YRpycHgntkJQTiAEIgI+ZxisonfaAMg="}]},"_from":".","_npmVersion":"1.2.11","_npmUser":{"name":"maxtaco","email":"themax@gmail.com"},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.11":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.11","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"email":"max@okcupid.com","url":"http://github.com/maxtaco/tamejs/issues"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":"node >= 0.4","scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_id":"tamejs@0.4.11","dist":{"shasum":"c7ec8f4286c625112d05abc25616a55888685d63","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.11.tgz","integrity":"sha512-34gv4gDmA5tVFBB9FjpI3+GfTDUp9xsHHdmbZJ5AijZ/F0/4buJlSWnNn1fEbJ8nVYNyVFvxNHXU/XcSYfldEw==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCmm5EQiN6P8kP44K4QxJ/2kkECsawcrfay7rr1JO9lqgIgdcvG0C6ro4UlzonWyRa7j7y8fE4uXEQY3hIr/ncz9J0="}]},"_from":".","_npmVersion":"1.2.18","_npmUser":{"name":"maxtaco","email":"themax@gmail.com"},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"}]},"0.4.12":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.12","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"url":"http://github.com/maxtaco/tamejs/issues","email":"max@okcupid.com"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":"node >= 0.4","scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","_id":"tamejs@0.4.12","dist":{"shasum":"c619da4e4169489b16feb1965ad69bc2a99f8978","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.12.tgz","integrity":"sha512-07fp+SpGulRnPbZTj0i4dfUq28nuaRFptcCvWjl7Ipigni24AqV/gbDHlobpcSmBqss/LQFyqdEUZaCHkQnCwg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDSN8F/rX0eoSA5V2ZxwtWcwo0VYWDMZttcL5ZXkxp11AIhAOD4vrYkjaFW0oYLdnNPHMDylvv9jObMGbJR1HSRlRre"}]},"_from":".","_npmVersion":"1.2.32","_npmUser":{"name":"kendrick","email":"sktayloriii@gmail.com"},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"},{"name":"kendrick","email":"sktayloriii@gmail.com"}]},"0.4.14":{"author":{"name":"Max Krohn","email":"max@okcupid.com"},"name":"tamejs","description":"JavaScript-to-JavaScript code rewriter for taming async-callback-style code","version":"0.4.14","keywords":["tame","libasync","okws","sfslite"],"preferGlobal":true,"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"bugs":{"url":"http://github.com/maxtaco/tamejs/issues","email":"max@okcupid.com"},"main":"lib/tamejs.js","bin":{"tamejs":"lib/main.js"},"engines":"node >= 0.4","scripts":{"test":"node test/harness.js"},"directories":{"lib":"lib","bin":"./bin"},"homepage":"http://github.com/maxtaco/tamejs","gitHead":"703525b1f1c8425dc42bc6e3ade99d81d2adbdf4","_id":"tamejs@0.4.14","_shasum":"611482bcec57023b3c08c00f657f66d59a8c25a8","_from":".","_npmVersion":"1.4.14","_npmUser":{"name":"kendrick","email":"kendrick@circuitsix.com"},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"},{"name":"kendrick","email":"sktayloriii@gmail.com"}],"dist":{"shasum":"611482bcec57023b3c08c00f657f66d59a8c25a8","tarball":"https://registry.npmjs.org/tamejs/-/tamejs-0.4.14.tgz","integrity":"sha512-n1NZ2xDj6i+21AJBZ0zRQOfjTq6NVj9IEddILo16OtnHtZHXIEAyxTI/rKOz1k3o6+oMEWs+CNz+LQMINX32Ug==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCrbKDALEKPzKp+UXWb1WlNWc4dE//rRRX10eduiEkfDAIhAPPVlSGXJz0W6byDUSTx2alHkMF2rAI2OfgbVDlwO6YD"}]}}},"maintainers":[{"name":"maxtaco","email":"max@okcupid.com"},{"name":"kendrick","email":"sktayloriii@gmail.com"}],"time":{"modified":"2022-06-27T03:45:16.744Z","created":"2011-06-30T16:06:59.604Z","0.0.1":"2011-06-30T16:06:59.743Z","0.1.0":"2011-06-30T23:42:42.212Z","0.1.1":"2011-07-01T14:34:03.724Z","0.1.2":"2011-07-05T13:23:21.226Z","0.1.3":"2011-07-06T14:20:49.737Z","0.1.4":"2011-07-12T16:37:24.995Z","0.1.5":"2011-07-14T15:21:08.511Z","0.2.0":"2011-07-14T21:18:26.327Z","0.2.1":"2011-07-14T21:52:09.836Z","0.2.2":"2011-07-14T22:51:00.745Z","0.2.3":"2011-07-15T20:03:31.908Z","0.3.0":"2011-07-22T15:05:54.577Z","0.3.1":"2011-07-22T21:44:37.943Z","0.3.3":"2011-07-27T11:59:03.959Z","0.3.4":"2011-07-28T11:52:55.357Z","0.3.5":"2011-08-30T14:08:02.753Z","0.3.6":"2011-08-30T21:50:37.085Z","0.3.7":"2011-09-01T16:16:30.362Z","0.4.1":"2011-09-21T16:29:17.083Z","0.4.2":"2011-10-05T18:26:37.448Z","0.4.3":"2011-10-06T13:22:31.509Z","0.4.4":"2011-10-27T19:16:51.384Z","0.4.5":"2011-11-10T21:02:13.988Z","0.4.7":"2011-11-29T16:30:55.846Z","0.4.8":"2011-12-01T17:39:08.466Z","0.4.9":"2011-12-03T15:17:37.120Z","0.4.10":"2013-03-19T12:30:36.484Z","0.4.11":"2013-05-22T02:11:40.098Z","0.4.12":"2014-05-09T18:39:18.483Z","0.4.13":"2014-07-03T20:16:25.113Z","0.4.14":"2014-07-03T23:09:32.805Z"},"author":{"name":"Max Krohn","email":"max@okcupid.com"},"repository":{"type":"git","url":"git://github.com/maxtaco/tamejs.git"},"homepage":"http://github.com/maxtaco/tamejs","keywords":["tame","libasync","okws","sfslite"],"bugs":{"url":"http://github.com/maxtaco/tamejs/issues","email":"max@okcupid.com"},"readme":"tamejs\n======\nThis package is a source-to-source translator that outputs JavaScript. The\ninput dialect looks a lot like JavaScript, but introduces the `await` \nprimitive, which allows asynchronous callback style code to work more\nlike straight-line threaded code.  *tamejs* is written in JavaScript.\n\nOne of the core powers of the *tamejs* rewriting idea is that it's\nfully compatible with existing vanilla-JS code (like `node.js`'s\nlibraries).  That is, existing `node.js` can call code that's been\noutput by the *tamejs* rewriter, and conversely, code output by the\n*tamejs* rewriter can call existing `node.js` code.  Thus, *tamejs* is\nincrementally deployable --- you can keep all of your old code and\njust write the new bits in *tamejs*!  So try it out and let us\nknow what you think.\n\nNEWS\n--------\n\nNow available in\n[NEWS.md](https://github.com/maxtaco/tamejs/blob/master/NEWS.md).\nVersion v0.4 just released, with initial support for what everyone has\nbeen asking for --- Tame-aware stack traces! See the section\n\"Debugging and Stack Traces...\" below for more details.   Also,\nwe've added `autocb`s, that fire whenever your tamed function returns.\n\n\nCode Examples\n--------\nHere is a simple example that prints \"hello\" 10 times, with 100ms delay\nslots in between:\n\n```javascript  \nfor (var i = 0; i < 10; i++) {\n    await { setTimeout (defer (), 100); }\n    console.log (\"hello\");\n}\n```\n\nThere is one new language addition here, the `await { ... }` block,\nand also one new primitive function, `defer`.  The two of them work\nin concert.  A function must \"wait\" at the close of a `await` block\nuntil all `defer`rals made in that `await` block are fulfilled.  The\nfunction `defer` returns a callback, and a callee in an `await`\nblock can fulfill a deferral by simply calling the callback it was\ngiven.  In the code above, there is only one deferral produced in each\niteration of the loop, so after it's fulfilled by `setTimer` in 100ms,\ncontrol continues past the `await` block, onto the log line, and back\nto the next iteration of the loop.  The code looks and feels like\nthreaded code, but is still in the asynchronous idiom (if you look at\nthe rewritten code output by the *tamejs* compiler).\n\nThis next example does the same, while showcasing power of the\n`await{..}` language addition.  In the example below, the two timers\nare fired in parallel, and only when both have fulfilled their deferrals\n(after 100ms), does progress continue...\n\n```javascript\nfor (var i = 0; i < 10; i++) {\n    await { \n        setTimeout (defer (), 100); \n        setTimeout (defer (), 10); \n    }\n    console.log (\"hello\");\n}\n```\n\nNow for something more useful. Here is a parallel DNS resolver that\nwill exit as soon as the last of your resolutions completes:\n\n```javascript\nvar dns = require(\"dns\");\n\nfunction do_one (cb, host) {\n    var err, ip;\n    await { dns.resolve (host, \"A\", defer (err, ip));}\n    if (err) { console.log (\"ERROR! \" + err); } \n    else { console.log (host + \" -> \" + ip); }\n    cb();\n}\n\nfunction do_all (lst) {\n    await {\n        for (var i = 0; i < lst.length; i++) {\n            do_one (defer (), lst[i]);\n        }\n    }\n}\n\ndo_all (process.argv.slice (2));\n```\n\nYou can run this on the command line like so:\n\n    node src/13out.js yahoo.com google.com nytimes.com okcupid.com tinyurl.com\n\nAnd you will get a response:\n\n    yahoo.com -> 72.30.2.43,98.137.149.56,209.191.122.70,67.195.160.76,69.147.125.65\n    google.com -> 74.125.93.105,74.125.93.99,74.125.93.104,74.125.93.147,74.125.93.106,74.125.93.103\n    nytimes.com -> 199.239.136.200\n    okcupid.com -> 66.59.66.6\n    tinyurl.com -> 195.66.135.140,195.66.135.139\n\nIf you want to run these DNS resolutions in serial (rather than\nparallel), then the change from above is trivial: just switch the\norder of the `await` and `for` statements above:\n\n```javascript  \nfunction do_all (lst) {\n    for (var i = 0; i < lst.length; i++) {\n        await {\n            do_one (defer (), lst[i]);\n        }\n    }\n}\n```\n\nSlightly More Advanced Example\n-----------------------------\n\nWe've shown parallel and serial work flows, what about something in\nbetween?  For instance, we might want to make progress in parallel on\nour DNS lookups, but not smash the server all at once. A compromise is\nwindowing, which can be achieved in *tamejs* conveniently in a number\nof different ways.  The [2007 academic paper on\ntame](http://pdos.csail.mit.edu/~max/docs/tame.pdf) suggests a\ntechnique called a *rendezvous*.  A rendezvous is implemented in\n*tamejs* as a pure JS construct (no rewriting involved), which allows\na program to continue as soon as the first deferral is fulfilled (rather than\nthe last):\n\n```javascript  \nfunction do_all (lst, windowsz) {\n    var rv = new tame.Rendezvous ();\n    var nsent = 0;\n    var nrecv = 0;\n\n    while (nrecv < lst.length) {\n        if (nsent - nrecv < windowsz && nsent < n) {\n            do_one (rv.id (nsent).defer (), lst[nsent]);\n            nsent++;\n        } else {\n            var evid;\n            await { rv.wait (defer (evid)); }\n            console.log (\"got back lookup nsent=\" + evid);\n            nrecv++;\n        }\n    }\n}\n```\n\nThis code maintains two counters: the number of requests sent, and the\nnumber received.  It keeps looping until the last lookup is received.\nInside the loop, if there is room in the window and there are more to\nsend, then send; otherwise, wait and harvest.  `Rendezvous.defer`\nmakes a deferral much like the `defer` primitive, but it can be\nlabeled with an idenfitier.  This way, the waiter can know which\ndeferral has fulfileld.  In this case we use the variable `nsent` as the\ndefer ID --- it's the ID of this deferral in launch order.  When we\nharvest the deferral, `rv.wait` fires its callback with the ID of the\ndeferral that's harvested.  \n\nNote that with windowing, the arrival order might not be the same as\nthe issue order. In this example, a slower DNS lookup might arrive\nafter faster ones, even if issued before them.\n\nComposing Serial And Parallel Patterns\n--------------------------------------\n\nIn Tame, arbitrary composition of serial and parallel control flows is\npossible with just normal functional decomposition.  Therefore, we\ndon't allow direct `await` nesting.  With inline anonymous JavaScript\nfunctions, you can consicely achieve interesting patterns.  The code\nbelow launches 10 parallel computations, each of which must complete\ntwo serial actions before finishing:\n\n```javascript\nfunction f(cb) {\n    await {\n        for (var i = 0; i < n; i++) {\n            (function (cb) {\n                await { setTimeout (defer (), 5*Math.random ()); }\n                await { setTimeout (defer (), 4*Math.random ()); }\n                cb();\n             })(defer ());\n        }\n    }\n    cb();\n}\n```\n\n\nautocb\n-------------------\n\nMost of the times, a tamed function will call its callback and return\nat the same time.  To get this behavior \"for free\", you can simply\nname this callback `autocb` and it will fire whenver your tamed function\nreturns.  For instance, the above example could be equivalently written as:\n\n```javascript\nfunction f(autocb) {\n    await {\n        for (var i = 0; i < n; i++) {\n            (function (autocb) {\n                await { setTimeout (defer (), 5*Math.random ()); }\n                await { setTimeout (defer (), 4*Math.random ()); }\n             })(defer ());\n        }\n    }\n}\n```\nIn the first example, recall, you call `cb()` explicitly.  In this\nexample, because the callback is named `autocb`, it's fired\nautomatically when the tamed function returns.\n\nIf your callback needs to fulfill with a value, then you can pass\nthat value via `return`.  Consider the following function, that waits\nfor a random number of seconds between 0 and 4. After waiting, it\nthen fulfills its callback `cb` with the amount of time it waited:\n\n```javascript\nfunction rand_wait(cb) {\n    var time = Math.floor (Math.random()*5);\n    if (time == 0) {\n         cb(0); return;\n    }\n    await setTimeout (defer (), time);\n    cb(time); // return here, implicitly.....\n}\n```\n\nThis function can written equivalently with `autocb` as:\n\n```javascript\nfunction rand_wait(autocb) {\n    var time = Math.floor (Math.random()*5);\n    if (time == 0) {\n        return 0;\n    }\n    await setTimeout (defer (), time);\n    return time;\n}\n```\nImplicitly, `return 0;` is mapped by the tamejs compiler to `autocb(0); return`.\n \n\nInstalling and Using\n--------------------\n\nInstall via npm:\n\n    npm install -g tamejs\n\nYou can their either use the *tamejs* compiler on the command line:\n\n    tamejs -o <outfile> <infile>\n    node <outfile> # or whatever you want\n\nOr as an extension to node's module import system:\n\n```javascript\nrequire ('tamejs').register (); // register the *.tjs suffix\nrequire (\"mylib.tjs\");          // then use node.js's import as normal\n```\n\nIf you want a different extension, this will work:\n\n```javascript\nrequire ('tamejs').register ('tamejs'); // register the *.tamejs suffix\nrequire (\"mylib.tamejs\");               // then use node.js's import as normal\n```\n\nOr, finally, you can call `register` to do a few things at once,\nincluding multiple suffix registrations:\n\n```javascript\n// Will register suffixes 'tamejs' and 'yojs'; will\n// also enable tame stack tracing, and disable caching of\n// .tjs files included at runtime\nrequire ('tamejs').register ({ extension       : [ 'tamejs', 'yojs'], \n                               catchExceptions : true,\n\t\t\t       disableCache    : true })\nrequire (\"mylib.tamejs\");\nrequire (\"yourlib.yojs\");\n```\n\n\nAPI and Documentation\n---------------------\n\n### defer\n\n`defer` can be called in one of two ways.\n\n\n#### Inline Variable Declaration\n\nThe first allows for inline declaration of the callback slot\nvariables:\n\n```javascript\n\nawait { dns.resolve (\"okcupid.com\", defer (var err, ip)); }\n\n```\n\nIn the tamed output code, the variables `err` and `ip` will be\ndeclared right before the start of the `await` block that contains them.\n\n\n#### Generic LHS Assignment w/ \"Rest\" Parameters\n\nThe second approach does not auto-declare the callback slot variables, but\nallows more flexibility:\n\n```javascript\nvar d = {};\nvar err = [];\nawait { dns.resolve (\"okcupid.com\", defer (err[0], d.ip)); }\n```\nThis second version allows anything you'd normally put on the\nleft-hand side of an assignment.\n\nFor callbcacks with variadic return, `tamejs` also supports the [rest\nparameter](http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters)\nproposal. The above code could have been written as:\n\n```javascript\nvar d = {};\nvar err = [];\nvar rest;\nawait { dns.resolve (\"okcupid.com\", defer (...rest)); }\nerr[0] = rest[0];\nd.ip = rest[1];\n```\n\nAnd of course, it's allowable to mix and match:\n\n```javascript\nvar d = {};\nvar err = [];\nvar rest;\nawait { dns.resolve (\"okcupid.com\", defer (err[0], ...rest)); }\nd.ip = rest[0];\n```\n\n### tame.Rendezvous\n\nThe `Rendezvous` is a not a core *tamejs* feature, meaning it's written as a \nstraight-ahead JavaScript library.  It's quite useful for more advanced\ncontrol flows, so we've included it in the main runtime library.\n\nThe `Rendezvous` is similar to a blocking condition variable (or a\n\"Hoare sytle monitor\") in threaded programming.\n\n#### tame.Rendezvous.id (i).defer (slots,...)\n\nAssociate a new deferral with the given Rendezvous, whose deferral ID is\n`i`, and whose callbacks slots are supplied as `slots`.  Those slots\ncan take the two forms of `defer` return as above (i.e.,\ndeclarative, or generic).  As with standard `defer`, the\nreturn value of the `Rendezvous`'s `defer` is fed to a function\nexpecting a callback.  As soon as that callback fires (and the deferral\nis fulfilled), the provided slots will be filled with the arguments to\nthat callback.\n\n#### tame.Rendezvous.defer (slots,...)\n\nYou don't need to explicitly assign an ID to a deferral generated from a\nRendezvous.  If you don't, one will automatically be assigned, in\nascending order starting from `0`.\n\n#### tame.Rendezvous.wait (cb)\n\nWait until the next deferral on this rendezvous is fulfilled.  When it\nis, callback `cb` with the ID of the fulfilled deferral.  If an\nunclaimed deferral fulfilled before `wait` was called, then `cb` is fired\nimmediately.\n\nThough `wait` would work with any hand-rolled JS function expecting\na callback, it's meant to work particularly well with *tamejs*'s\n`await` function.\n\n#### Example\n\nHere is an example that shows off the different inputs and \noutputs of a `Rendezvous`.  It does two parallel DNS lookups,\nand reports only when the first returns:\n\n```javascript\nvar hosts = [ \"okcupid.com\", \"google.com\" ];\nvar ips = [ ], errs = [];\nvar rv = new tame.Rendezvous ();\nfor (var i in hosts) {\n    dns.resolve (hosts[i], rv.id (i).defer (errs[i], ips[i]));\n}\nawait rv.wait (defer (var which));\nconsole.log (hosts[which] + \" -> \" + ips[which]);\n```\n\n### connectors\n\nA *connector* is a *tamejs* function that takes as input\na callback, and outputs another callback.   The best example \nis a `timeout`, given here:\n\n#### connectors.timeout(cb, time, res = [])\n\nTimeout an arbitrary async operation.\n\nGiven a callback `cb`, a time to wait `time`, and an array to output a\nresult `res`, return another callback.  This connector will set up a\nrace between the callback returned to the caller, and the timer that\nfires after `time` milliseconds.  If the callback returned to the\ncaller fires first, then fill `res[0] = true;`.  If the timer won\n(i.e., if there was a timeout), then fill `res[0] = false;`.\n\nIn the following example, we timeout a DNS lookup after 100ms:\n\n```javascript\nrequire ('tamejs').register (); // since connectors is a tamed library...\nvar timeout = require ('tamejs/lib/connectors').timeout;\nvar info = [];\nvar host = \"pirateWarezSite.ru\";\nawait dns.lookup (host, timeout (defer (var err, ip), 100, info));\nif (!info[0]) {\n    console.log (host + \": timed out!\");\n} else if (err) {\n    console.log (host + \": error: \" + err);\n} else {\n    console.log (host + \" -> \" + ip);\n}\n```\n\n### The Pipeliner library\n\nThere's another way to do the windowed DNS lookups we saw earlier ---\nyou can use the control flow library called `Pipeliner`, which \nmanages the common pattern of having \"m calls total, with only\nn of them in flight at once, where m > n.\"\n\nThe Pipeliner class is available in the connectors library:\n\n```javascript\nrequire ('tamejs').register (); // since connectors is a tamed library...\nvar Pipeliner = require ('tamejs/lib/connectors').Pipeliner;\nvar pipeliner = new Pipeliner (w,s);\n```\n\nUsing the pipeliner, we can rewrite our earlier windowed DNS lookups\nas follows:\n\n```javascript  \nfunction do_all (lst, windowsz) {\n    var pipeliner = new Pipeliner (windowsz);\n\n    for (var i in lst) {\n        await pipeliner.waitInQueue (defer ());\n        do_one (pipeliner.defer (), lst[i]);\n    }\n    await pipeliner.flush (defer ());\n}\n```\n\nThe API is as follows:\n\n### new Pipeliner (w, s)\n\nCreate a new Pipeliner controller, with a window of at most `w` calls\nout at once, and waiting `s` seconds before launching each call.  The\ndefault values are `w = 10` and `s = 0`.\n\n### Pipeliner.waitInQueue (c)\n\nWait in a queue until there's room in the window to launch a new call.\nThe callback `c` will be fulfilled when there is room.\n\n### Pipeliner.defer (...args)\n\nCreate a new `defer`al for this pipeline, and pass it to whatever\nfunction is doing the actual work.  When the work completes, fulfill\nthis `defer`al --- that will update the accounting in the pipeliner\nclass, allowing queued actions to proceed.\n\n### Pipeliner.flush (c)\n\nWait for the pipeline to clear out.  Fulfills the callback `c`\nwhen the last action in the pipeline is done.\n\n\nDebugging and Stack Traces -- Now Greatly Improved!\n---------------------------------------------------\n\nAn oft-cited problem with async-style programming, with Tame or\nhand-rolled, is that stack traces are often incomplete or\nincomprehensible.  If an exception is caught in a tamed function, the\nstack trace will only show the \"bottom half\" of the call stack, or all\nof those functions that are descendents of the main event loop.  The\n\"top half\" of the call stack, telling you \"who _really_ called this\nfunction,\" is probably long gone.\n\nTame has a workaround to this problem.  When a tamed function is\nentered, the runtime will find the first argument to the function that\nwas output by `defer()`.  Such callbacks are annotated to contain the\nfile, line and function where they were created.  They also are\nannotated to hold a refernce to `defer()`-generated callback passed to\nthe function in which they were created.  This chaining creates an\nimplicit stack that can be walked when an exception is thrown.\n\nConsider this example:\n\n```javascript\ntame.catchExceptions ();\n\nfunction foo (y) {\n    await setTimeout (defer (), 10);\n    throw new Error (\"oh no!\")\n    y(10);\n}\n\nfunction bar (x) {\n    await foo (defer ());\n    x();\n}\n\nfunction baz () {\n   await bar (defer ());\n};\n\nbaz ();\n```\n\nThe function `tame.catchExceptions` sets the `uncaughtException`\nhandler in Node to print out the standard callstack, and also the Tame\n\"callstack\", and then to exit.  The callback generated by `defer()`\nin the function `bar` holds a reference to `x`.  Similarly, \nthe callback generated in `foo` holds a reference to `y`.\nHere's what happens when this program is run:\n\n```\nError: oh no!\n    at /home/max/node/tamejs/8.js:31:23\n    at callChain (/home/max/node/tamejs/lib/runtime.js:38:2)\n    at Deferrals._continuation (/home/max/node/tamejs/lib/runtime.js:38:23)\n    at Deferrals._fulfill (/home/max/node/tamejs/lib/runtime.js:149:11)\n    at Object._onTimeout (/home/max/node/tamejs/lib/runtime.js:64:4)\n    at Timer.callback (timers.js:83:39)\nTame 'stack' trace:\n    at bar (8.tjs:10)\n    at baz (8.tjs:15)\n```\n\nThe first stack trace is the standard Node stacktrace.  It is\ninscrutable, since it mainly covers Tame internals, and has line\nnumbering relative to the translated file (I still haven't fixed this\nbug, sorry). The second stack trace is much better.  It tells the\nsequence of tamed calls the lead to this exception.  Line numbers are\nrelative to the original input file.\n\nIn future releases, we'll be cleaning this feature up, but for now, it's a\nmarked improvement over previous versions of tamejs.\n\nThe relavant API is as follows:\n\n#### tame.stackWalk (cb)\n\nStart from the given `cb`, or use the currently active callback\nif none was given, and walk up the Tame-generated stack. Return\na list of call site descriptions.  You can call this from your\nown exception-handling code.\n\n#### tame.catchExceptions()\n\nTell the Tame runtime to catch uncaught exceptions, and to print\na Tame-aware stack dump as above.\n\n\nHow It's Implemented In JavaScript\n----------------------------------\n\nThe key idea behind the *tamejs* implementation is\n[Continuation-Passing Style\n(CPS)](http://en.wikipedia.org/wiki/Continuation-passing_style)\ncompilation.  That is, elements of code like `for`, `while` and `if`\nstatements are converted to anonymous JavaScript functions written\nin continuation-passing style.  Then, `await` blocks just grab\nthose continuations, store them away, and call them when the\ntime is right (i.e., when all relevant deferrals have been fulfilled).\n\nFor example, the simple program:\n\n```javascript\nif (true) { await { setTimeout (defer (), 100); } }\n```\n\nIs rewritten to something like the following (which has been hand-simplified\nfor demonstration purposes):\n\n```javscript\nvar tame = require('tamejs').runtime;\nvar f0 = function (k) {\n    var f1 = function (k) {\n        var __cb = new tame.Deferrals (k);\n        setTimeout ( __cb.defer(), 100 ) ;\n    };\n    if (true) {\n        f1 (k);\n    } else {\n        k();\n    }\n};\nf0 (tame.end);\n\n```\n\nThat is, the function `f0` is the rewrite of the `if` statement.\nFunction `f0` takes as a parameter the continuation `k`, which\nsignifies \"the rest of the program\".  In the case of this trivial\nprogram, the rest of the program is just a call to the exit function\n`tame.end`.  Inside the `if` statement, there are two branches.  In\nthe `true` branch, we call into `f1`, the rewrite of the `await`\nblock, and in the `false` branch, it's just go on with the rest of the\nprogram by calling the continuation `k`.  Function `f1` is doing\nsomething a little bit different --- it's passing its continuation\ninto the pure JavaScript class `tame.Deferrals`, which will hold onto it\nuntil all associated deferrals (like the one passed to `setTimeout`) have\nbeen fulfilled.  When the last deferral is fulfileld (here after 100ms), then\nthe `tame.Deferrals` class calls the continuation `k`, which here refers\nto `tame.end`.\n\nThe *tamejs* implementation uses other CPS-conversions for `while` and\n`for` loops, turning standard iteration into tail-recursion.  If you\nare curious to learn more, examine the output of the *tamejs* compiler\nto see what your favorite JavaScript control flow is translated to.\nThe translation of `switch` is probably the trickiest.\n\nAs you might guess, the output code is less efficient than the input\ncode.  All of the anonymous functions add bloat.  This unfortunate\nside-effect of our approach is mitigated by skipping CPS compilation\nwhen possible.  Functions with no `await` blocks are passed through\nunmolested.  Similarly, blocks within tamed functions that don't call\n`await` can also pass through.\n\nAnother concern is that the use of tail recursion in translated loops\nmight overflow the runtime callstack.  That is certainly true for\nprograms like the following:\n\n```javascript\nwhile (true) { await { i++; } }\n```\n\n...but you should never write programs like these!  That is, there's no\nreason to have a `await` block unless your program needs to wait for\nsome asynchronous event, like a timer fired, a packet arrival, or a \nuser action.  Programs like these:\n\n```javascript\nwhile (true) { await { setTimeout (defer (), 1); i++; } }\n```\n\nwill **not** overflow the runtime stack, since the stack is unwound every\niteration through the loop (via `setTimeout`). And these are the types\nof programs that you should be using `await` for.\n\nToDos\n------\nSee the github issue tracker for the more immediate issues.\n\n* Optimizations\n     * Can passThrough blocks in a tamed function that don't have awaits,\nso can get more aggressive here --- in progress, but can still\nseek out some more optimizations....\n* Parsing\n     * Switch to uglify's parser?  Would have to slightly modify it.\n\nHistory\n-------\n\nThe Tame rewriting idea come about at\n[OkCupid](http://www.okcupid.com) in 2006. Until that time, the\nwebsite was written in an entirely asynchronous-callback-based style\nwith [OKWS](http://www.okws.org) in C++.  This serving technology was\nextremely fast, and led to huge cost savings in hardware and hosting,\nbut as the site's code grew, it became increasingly\nunmanageable. Simple serial loops with network access, like the\nsequential DNS example above, required \"stack-ripping\" into multiple\nmutually recursive calls.  As more employees began to work the code,\nand editted code that they didn't write, development slowed to a\ncrawl.\n\nChris Coyne, OkCupid's director of product, demanded that something be\ndone.  The requirements were manifold.  The new solution had to be\ncompatible with existing code; it had to be incrementally deployable,\nso that the whole codebase wouldn't need to be rewritten at once; it\nhad to be nearly as fast as the status quo; it had to clean the code\nup, so that it was readable; it had to speed up and simplify\ndevelopment.\n\nThe answer that emerged was Tame for C++.  It's a source-to-source\ntranslator that mapped C++ with a few language additions into regular\nC++, which is then compiled with a standard compiler (like `gcc`). The\nkey implementation ideas behind Tame C++ are: (1) generate a heap-allocated\n\"closure\" for each tamed function; (2) use labels and `goto` to jump\nback into tamed function as asynchronous events fired.  Once Tame was\nbrought to bear on OkCupid's code, it offered almost all of the\nflexibilty and performance of hand-crafted\nasynchronous-callback-passing code without any of the stack-ripping\nheadaches.  New employees picked it right up, and contributed to\nthe incremental effort to modernize OkCupid's code to the Tame\ndialect.\n\nOkCupid to this day runs Tame and OKWS in C++ to churn out\nhigh-performance, parallel applications, without worrying about\ntraditional thread-based headaches, like deadlock and race-conditions.\nOur goal with *tamejs* is to bring these benefits to JavaScript and\nthe `node.js` platform.\n\nSee our \"Glossy Page\"\n---------------------\n\nSee [tamejs.org](http://tamejs.org) for documentation and information on \n*tamejs*.\n\nRelated Projects & Plugs\n------------------------\n\n[pubjs](https://github.com/maxtaco/pubjs) is yet another a node.js\ntemplating engine.  But it allows arbtirarily nested code and output\nsections.  Check it out, if you like this sample code:\n\n```html\n<table>\n{% \n  foreach (match in matches) {\n    if (match.score > 60) {{<div>Excellent Match (%{match.score})</div>}}\n    else                  {{<div>Crap Match  (%{match.score})</div>}}\n    foreach (friend in match.friends) {{\n      <p>\n        Has a friend named %{friend.name}\n        {%\n          if (friend.gender == \"f\") {{ and she's a girl }}\n        %}\n      </p>\n    }}\n  }\n%}\n</table>\n```\n\n\nAlso Available In C++!\n----------------------\n\nAs described above, the Tame source-to-source translator was\noriginally written for asynchronous C++ code.  It's an actively\nmaintained project, and it is in widespread use at\n[OkCupid.com](http://www.okcupid.com).  See the [sfslite/tame\nWiki](https://github.com/okws/sfslite/wiki/tame) for more information,\nor read the [2007 Usenix ATC\npaper](http://pdos.csail.mit.edu/~max/docs/tame.pdf).\n\nAuthors\n-------\n* Max Krohn (first name AT okcupid DOT com)\n* Chris Coyne (first name AT okcupid DOT com)\n* Eddie Kohler (original Tame coauthor, and advisor)\n* Martin Schürrer (vim mode; see `extras/vim`, see https://github.com/MSch/vim-tamejs)\n\nLicense\n-------\nCopyright (c) 2011 Max Krohn for HumorRainbow, Inc., under the MIT license\n","readmeFilename":"README.md"}