├── .gitignore
├── README.md
├── async-you
├── each.js
├── map.js
├── reduce.js
├── series-object.js
├── times.js
├── waterfall.js
└── whilst.js
├── browserify-adventure
├── .gitignore
├── beep-boop.js
├── build-a-widget.js
├── builtins.js
├── multi-export.js
├── ndjson.js
├── single-export.js
├── uniquely.js
├── using-npm-packages.js
├── using-transforms.js
├── wake.txt
├── writing-transforms-main.js
├── writing-transforms-tr.js
└── writing-transforms-transform.js
├── bytewiser
├── array-buffers.js
├── buffer-concat.js
├── buffer-from-string.js
├── hexadecimal-encoding.js
├── line-splitter.js
├── modifying-buffers.js
└── typed-arrays.js
├── expressworks
├── good-old-form.js
├── hello-world.js
├── jade.js
├── json-me.js
├── static.js
├── stylus-css.js
└── templates
│ └── index.jade
├── functional-javascript
├── async-loop.js
├── call-duck-typing.js
├── curryn.js
├── dependency-tree.js
├── every-some.js
├── filter.js
├── function-call.js
├── hello-world.js
├── higher-order-function.js
├── map-using-reduce.js
├── map.js
├── non-blocking-recursion.js
├── partial-apply-with-bind.js
├── partial-apply-without-bind.js
├── recursive-reduce.js
├── reduce.js
├── spies.js
└── trampoline.js
├── learn-generators
├── 01-run-stop-run.js
├── 02-generator-iterator.js
├── 03-delegating-generators.js
├── 04-catch-error.js
├── 05-look-sync-do-async.js
└── 06-look-sync-make-promise.js
├── learnyounode
├── baby-steps.js
├── filter-dir.js
├── filtered-ls.js
├── hello-world.js
├── http-client.js
├── http-collect.js
├── http-file-server.js
├── http-json-api-server.js
├── http-reverserer.js
├── juggling-async.js
├── make-it-modular.js
├── my-first-async-io.js
├── my-first-io.js
└── time-server.js
├── learnyoureact
└── hello-react
│ ├── app.js
│ ├── program.js
│ └── views
│ └── index.jsx
├── levelmeup
├── .gitignore
├── all-you-base.js
├── basics-batch.js
├── basics-get.js
├── basics-put.js
├── get-your-level-on.js
├── horse_js-count.js
├── horse_js-tweets.js
├── keywise.js
├── multilevel.js
├── short-scrabble-words.js
├── streaming.js
└── sublevel.js
├── makemehapi
├── directories.js
├── handling.js
├── hello-hapi.js
├── helpers
│ └── helper.js
├── helping.js
├── proxies.js
├── public
│ ├── file.html
│ └── index.html
├── routes.js
├── stream-text.txt
├── streams.js
├── templates
│ ├── helper-template.html
│ └── index.html
└── views.js
├── nodebot-workshop
└── 01-blink-blink.js
├── promise-it-wont-hurt
├── always-async.js
├── an-important-rule.js
├── do-some-work.js
├── fetch-json.js
├── fulfill-a-promise.js
├── more-functional.js
├── multiple-promises.js
├── reject-a-promise.js
├── throw-an-error.js
├── to-reject-or-not-to-reject.js
├── using-qfcall.js
└── values-and-promises.js
└── stream-adventure
├── beep-boop.js
├── combiner.js
├── concat.js
├── crypt.js
├── duplexer-redux.js
├── duplexer.js
├── html-stream.js
├── http-client.js
├── http-server.js
├── input-output.js
├── lines.js
├── meet-pipe.js
├── secretz.js
├── transform.js
└── websockets.js
/.gitignore:
--------------------------------------------------------------------------------
1 | git-it/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | #learning node with nodeschool
2 |
3 | My solutions for [Node School][nodeschool] classes.
4 |
5 | Each level has its own folder.
6 |
7 | [nodeschool]: http://nodeschool.io/
8 |
--------------------------------------------------------------------------------
/async-you/each.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | async = require('async');
3 |
4 | async.each([process.argv[2], process.argv[3]], function (item, done) {
5 | http.get(item, function (res) {
6 | res.on('data', function (chunk) {
7 | });
8 |
9 | res.on('end', function () {
10 | return done();
11 | });
12 | }).on('error', function (err) {
13 | return console.log(err);
14 | });
15 | }, function (err) {
16 | if (err) {
17 | console.log(err);
18 | }
19 | });
20 |
21 |
--------------------------------------------------------------------------------
/async-you/map.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | async = require('async');
3 |
4 | async.map(process.argv.slice(2, 4), function (item, done) {
5 | http.get(item, function (res) {
6 | var body = '';
7 | res.on('data', function (chunk) {
8 | body += chunk.toString();
9 | });
10 |
11 | res.on('end', function () {
12 | done(null, body);
13 | });
14 | }).on('error', function (err) {
15 | done(err);
16 | });
17 | }, function (err, results) {
18 | if (err) {
19 | return console.error(err);
20 | }
21 |
22 | console.log(results);
23 | });
24 |
25 |
--------------------------------------------------------------------------------
/async-you/reduce.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | async = require('async');
3 |
4 | var url = process.argv[2];
5 |
6 | async.reduce(['one', 'two', 'three'], 0, function (memo, item, cb) {
7 | http.get(url + '?number=' + item, function (res) {
8 | var body = '';
9 | res.on('data', function (chunk) {
10 | body += chunk.toString();
11 | });
12 |
13 | res.on('end', function () {
14 | cb(null, memo + parseInt(body, 10));
15 | });
16 | }).on('error', function (err) {
17 | return console.error(err);
18 | });
19 | }, function (err, result) {
20 | if (err) {
21 | return console.error(err);
22 | }
23 |
24 | console.log(result);
25 | });
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/async-you/series-object.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | async = require('async');
3 |
4 | async.series({
5 | requestOne: function (cb) {
6 | http.get(process.argv[2], function (res) {
7 | var body = '';
8 | res.on('data', function (chunk) {
9 | body += chunk.toString();
10 | }).on('end', function () {
11 | cb(null, body);
12 | });
13 | }).on('error', function (err) {
14 | return cb(err);
15 | });
16 | },
17 |
18 | requestTwo: function (cb) {
19 | http.get(process.argv[3], function (res) {
20 | var body = '';
21 | res.on('data', function (chunk) {
22 | body += chunk.toString();
23 | }).on('end', function () {
24 | cb(null, body);
25 | });
26 | }).on('error', function (err) {
27 | return cb(err);
28 | });
29 | }
30 | }, function (err, result) {
31 | if (err) {
32 | return console.error(err);
33 | }
34 |
35 | console.log(result);
36 | });
37 |
38 |
39 |
--------------------------------------------------------------------------------
/async-you/times.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | async = require('async');
3 |
4 | var hostname = process.argv[2];
5 | var port = process.argv[3];
6 |
7 | async.series({
8 | post: function (done) {
9 |
10 | var opts = {
11 | hostname: hostname,
12 | port: port,
13 | method: 'POST',
14 | path: '/users/create'
15 | };
16 |
17 | async.times(5, function (i, timesDone) {
18 | var req = http.request(opts, function (res) {
19 |
20 | res.on('data', function (chunk) {
21 | });
22 |
23 | res.on('end', function () {
24 | timesDone(null);
25 | });
26 | }).on('error', function (err) {
27 | return console.error(err);
28 | });
29 |
30 | var data = JSON.stringify({ user_id : i + 1 });
31 | req.write(data);
32 | req.end();
33 | }, function (err) {
34 | if (err) {
35 | return console.error(err);
36 | }
37 |
38 | done(null);
39 | });
40 |
41 | },
42 |
43 | get: function (done) {
44 | http.get('http://' + process.argv.slice(2).join(':') + '/users', function (res) {
45 | var body = '';
46 |
47 | res.on('data', function (chunk) {
48 | body += chunk.toString();
49 | });
50 |
51 | res.on('end', function () {
52 | done(null, body);
53 | });
54 | })
55 | }
56 | }, function (err, results) {
57 | if (err) {
58 | return console.error(err);
59 | }
60 | console.log(results.get);
61 | });
62 |
63 |
--------------------------------------------------------------------------------
/async-you/waterfall.js:
--------------------------------------------------------------------------------
1 | var http = require('http'),
2 | fs = require('fs'),
3 | async = require('async');
4 |
5 | var filename = process.argv[2];
6 |
7 | async.waterfall([
8 | function (cb) {
9 | fs.readFile(filename, 'utf-8', function (err, data) {
10 | if (err) {
11 | return cb(err);
12 | }
13 |
14 | cb(null, data);
15 | });
16 | },
17 |
18 | function (data, cb) {
19 | var body = '';
20 |
21 | http.get(data, function (res) {
22 | res.on('data', function (chunk) {
23 | body += chunk.toString();
24 | })
25 | .on('end', function () {
26 | cb(null, body);
27 | });
28 | })
29 | .on('error', function (err) {
30 | cb(err);
31 | });
32 | }
33 | ], function (err, result) {
34 |
35 | if (err) {
36 | return console.error(err);
37 | }
38 |
39 | console.log(result);
40 | });
41 |
42 |
43 |
--------------------------------------------------------------------------------
/async-you/whilst.js:
--------------------------------------------------------------------------------
1 | var async = require('async'),
2 | http = require('http');
3 |
4 | var lastResponse = '',
5 | totalRequests = 0,
6 | url = process.argv[2];
7 |
8 | async.whilst(function () { return lastResponse !== 'meerkat'; },
9 | function (callback) {
10 | http.get(url, function (res) {
11 | totalRequests++;
12 |
13 | var body = '';
14 | res.on('data', function (chunk) {
15 | body += chunk.toString();
16 | });
17 |
18 | res.on('end', function () {
19 | lastResponse = body.trim();
20 | callback();
21 | });
22 |
23 | }).on('error', function (err) {
24 | return console.error(err);
25 | });
26 | },
27 |
28 | function (err) {
29 | console.log(totalRequests);
30 | }
31 | );
32 |
33 |
--------------------------------------------------------------------------------
/browserify-adventure/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | npm-debug.log
3 |
4 |
--------------------------------------------------------------------------------
/browserify-adventure/beep-boop.js:
--------------------------------------------------------------------------------
1 | console.log('BEEP BOOP');
2 |
--------------------------------------------------------------------------------
/browserify-adventure/build-a-widget.js:
--------------------------------------------------------------------------------
1 | var domify = require('domify');
2 |
3 | module.exports = function () {
4 | var name = '';
5 |
6 | function getHtml() {
7 | return '
Hello ' + name + '!
';
8 | }
9 |
10 | return {
11 | setName: function (newName) {
12 | name = newName;
13 | },
14 |
15 | appendTo: function (el) {
16 | return el.appendChild(domify(getHtml()));
17 | }
18 | };
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/browserify-adventure/builtins.js:
--------------------------------------------------------------------------------
1 | var url = require('url'),
2 | querystring = require('querystring');
3 |
4 | var webaddress = prompt();
5 |
6 | var parsedUrl = url.parse(webaddress),
7 | parsedQuery = querystring.parse(parsedUrl.query);
8 |
9 | console.log(url.resolve(webaddress, parsedQuery.file));
10 |
--------------------------------------------------------------------------------
/browserify-adventure/multi-export.js:
--------------------------------------------------------------------------------
1 | var ndjson = require('./ndjson');
2 |
3 | console.log(ndjson.parse(prompt()));
4 | console.log(ndjson.stringify(prompt()));
5 |
6 |
--------------------------------------------------------------------------------
/browserify-adventure/ndjson.js:
--------------------------------------------------------------------------------
1 | exports.parse = function (str) {
2 | return str.split('\n').map(JSON.parse);
3 | };
4 |
5 | exports.stringify = function (rows) {
6 | return rows.map(JSON.stringify).join('\n');
7 | };
8 |
9 |
--------------------------------------------------------------------------------
/browserify-adventure/single-export.js:
--------------------------------------------------------------------------------
1 | var uniquely = require('./uniquely');
2 |
3 | console.log(uniquely(prompt()));
4 |
5 |
--------------------------------------------------------------------------------
/browserify-adventure/uniquely.js:
--------------------------------------------------------------------------------
1 | var uniq = require('uniq');
2 |
3 | module.exports = function (str) {
4 | return uniq(str.split(','));
5 | };
6 |
7 |
--------------------------------------------------------------------------------
/browserify-adventure/using-npm-packages.js:
--------------------------------------------------------------------------------
1 | var uniq = require('uniq');
2 |
3 | var string = prompt();
4 |
5 | console.log(uniq(string.split(',')));
6 |
7 |
--------------------------------------------------------------------------------
/browserify-adventure/using-transforms.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var sprintf = require('sprintf');
3 |
4 | var src = fs.readFileSync('/usr/local/lib/node_modules/browserify-adventure/problems/using_transforms/wake.txt', 'utf8');
5 |
6 | src.split('\n').forEach(function (line, index) {
7 | if (index % 5 === 0) {
8 | console.log(sprintf("%3d %s", index, line));
9 | }
10 | else {
11 | console.log(sprintf(" %s", line));
12 | }
13 | });
14 |
15 |
--------------------------------------------------------------------------------
/browserify-adventure/wake.txt:
--------------------------------------------------------------------------------
1 | Be that as it may, but for that light phantastic of his gnose's glow as it
2 | slid lucifericiously within an inch of its page (he touch at its from time
3 | to other, the red eye of his fear in saddishness, to ensign the colours by
4 | the beerlitz in his mathness and his educandees to outhue to themselves in
5 | the cries of girl-glee: gember! inkware! chonchambre! cinsero! zinnzabar!
6 | tincture and gin!) Nibs never would have quilled a seriph to sheepskin. By
7 | that rosy lampoon's effluvious burning and with help of the simulchronic
8 | flush in his pann (a ghinee a ghirk he ghets there!) he scrabbled and
9 | scratched and scriobbled and skrevened namelesss shamelessness about
10 | everybody ever he met, even sharing a precipitation under the idlish
11 | tarriers' umbrella of a showerproof wall, while all over up and down the
12 | four margins of this rancid Shem stuff the evilsmeller (who was devoted to
13 | Uldfadar Sardanapalus) used to stipple endlessly inartistic portraits of
14 | himself in the act of reciting old Nichiabilli's monolook interyerear
15 | Hanno, o Nonanno, acce'l brubblemm'as, ser Autore, q.e.d., a
16 | heartbreakingly handsome young paolo with love lyrics for the goyls in his
17 | eyols, a plain-tiff's tanner vuice, a jucal inkome of one hundred and
18 | thirtytwo dranchmas per yard from Broken Hill stranded estate, Camebreech
19 | mannings, cutting a great dash in a brandnew two guinea dress suit and a
20 | burled hogsford hired for a Fursday evenin merry pawty, anna loavely long
21 | pair of inky Italian moostarshes glistering with boric vaseline and
22 | frangipani. Puh! How unwhisperably so!
23 |
--------------------------------------------------------------------------------
/browserify-adventure/writing-transforms-main.js:
--------------------------------------------------------------------------------
1 | var txt = require('./wake.txt');
2 |
3 | console.log(txt);
4 |
--------------------------------------------------------------------------------
/browserify-adventure/writing-transforms-tr.js:
--------------------------------------------------------------------------------
1 | var through = require('through2');
2 | var split = require('split');
3 | var quote = require('quote-stream');
4 | var combiner = require('stream-combiner2');
5 |
6 | var ftr = require('./writing-transforms-transform');
7 |
8 | module.exports = function (file) {
9 | if (!/\.txt$/.test(file)) return through();
10 |
11 | var prefix = through();
12 | prefix.push('module.exports=');
13 |
14 | return combiner([ split(), ftr, quote(), prefix ]);
15 | };
16 |
--------------------------------------------------------------------------------
/browserify-adventure/writing-transforms-transform.js:
--------------------------------------------------------------------------------
1 | var through = require('through2');
2 | var sprintf = require('sprintf');
3 |
4 | var lineNumber = 0;
5 |
6 | module.exports = through(function (buf, enc, next) {
7 | if (lineNumber % 5 === 0) {
8 | this.push(sprintf("%3d %s", lineNumber, buf.toString()));
9 | }
10 | else {
11 | this.push(sprintf(" %s", buf.toString()));
12 | }
13 | this.push('\n');
14 | lineNumber++;
15 |
16 | next();
17 | });
18 |
19 |
--------------------------------------------------------------------------------
/bytewiser/array-buffers.js:
--------------------------------------------------------------------------------
1 | var num = process.argv[2];
2 | var u32 = new Uint32Array(1);
3 |
4 | u32[0] = num;
5 |
6 | var u16 = new Uint16Array(u32.buffer);
7 |
8 | console.log(JSON.stringify(u16));
9 |
10 |
--------------------------------------------------------------------------------
/bytewiser/buffer-concat.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | var buffers = [];
4 |
5 | process.stdin.on('data', function (buf) {
6 | buffers.push(buf);
7 | });
8 |
9 | process.stdin.on('end', function () {
10 | console.log(Buffer.concat(buffers));
11 | });
12 |
--------------------------------------------------------------------------------
/bytewiser/buffer-from-string.js:
--------------------------------------------------------------------------------
1 | console.log(new Buffer("bytewiser"))
2 |
--------------------------------------------------------------------------------
/bytewiser/hexadecimal-encoding.js:
--------------------------------------------------------------------------------
1 | var numbers = process.argv.slice(2).map(parseFloat);
2 |
3 | console.log(new Buffer(numbers).toString('hex'));
4 |
5 |
--------------------------------------------------------------------------------
/bytewiser/line-splitter.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | var filepath = process.argv[2];
4 |
5 | fs.readFile(filepath, function (err, buf) {
6 |
7 | for (var prev = 0, curr = 0; curr < buf.length; ++curr) {
8 | if (buf[curr] === 0x0a) {
9 | console.log(new Buffer(buf.slice(prev, curr)));
10 | prev = curr + 1;
11 | }
12 | }
13 | // last line
14 | console.log(new Buffer(buf.slice(prev, buf.length - 1)));
15 | });
16 |
17 |
--------------------------------------------------------------------------------
/bytewiser/modifying-buffers.js:
--------------------------------------------------------------------------------
1 |
2 | process.stdin.on('data', function (buf) {
3 | for (var i = 0; i < buf.length; ++i) {
4 | if (buf[i] === 46) {
5 | buf.write("!", i);
6 | }
7 | }
8 | console.log(buf);
9 | });
10 |
11 |
--------------------------------------------------------------------------------
/bytewiser/typed-arrays.js:
--------------------------------------------------------------------------------
1 |
2 | process.stdin.on('data', function (buf) {
3 | var arr = new Uint8Array(buf.length);
4 | for (var i = 0; i < buf.length; ++i) {
5 | arr[i] = buf[i];
6 | }
7 |
8 | console.log(JSON.stringify(arr));
9 |
10 | return;
11 | });
12 |
--------------------------------------------------------------------------------
/expressworks/good-old-form.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 |
3 | var app = express();
4 |
5 | app.use(express.urlencoded());
6 | app.post('/form', (req, res) => {
7 | res.end(req.body.str.split('').reverse().join(''));
8 | });
9 | app.listen(process.argv[2] || 3000);
10 |
--------------------------------------------------------------------------------
/expressworks/hello-world.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 |
3 | var app = express();
4 | app.get('/home', (req, res) => {
5 | res.send('Hello World!');
6 | });
7 | app.listen(process.argv[2] || 3000);
8 |
9 |
--------------------------------------------------------------------------------
/expressworks/jade.js:
--------------------------------------------------------------------------------
1 | var express = require('express'),
2 | path = require('path');
3 |
4 | var app = express();
5 |
6 | app.set('view engine', 'jade');
7 | app.set('views', process.argv[3] || path.join(__dirname, 'templates'));
8 |
9 | app.get('/home', (req, res) => {
10 | res.render('index', { date: new Date().toDateString() });
11 | });
12 | app.listen(process.argv[2] || 3000);
13 |
--------------------------------------------------------------------------------
/expressworks/json-me.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var app = express();
3 | var fs = require('fs');
4 |
5 | app.get('/books', (req, res) => {
6 | fs.readFile(process.argv[3], (err, content) => {
7 | if(err) {
8 | res.send(500);
9 | }
10 |
11 | try {
12 | var books = JSON.parse(content.toString());
13 | res.json(books);
14 | } catch(error) {
15 | res.send(500);
16 | }
17 | });
18 | });
19 |
20 | app.listen(process.argv[2]);
--------------------------------------------------------------------------------
/expressworks/static.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var express = require('express');
3 |
4 | var app = express();
5 |
6 | app.use(express.static(process.argv[3] || path.join(__dirname, 'public')));
7 | app.listen(process.argv[2] || 3000);
8 |
--------------------------------------------------------------------------------
/expressworks/stylus-css.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var app = express();
3 |
4 | app.use(express.static(process.argv[3]));
5 | app.use(require('stylus').middleware(process.argv[3]));
6 |
7 | app.listen(process.argv[2]);
--------------------------------------------------------------------------------
/expressworks/templates/index.jade:
--------------------------------------------------------------------------------
1 | h1 Hello World
2 | p Today is #{date}.
3 |
--------------------------------------------------------------------------------
/functional-javascript/async-loop.js:
--------------------------------------------------------------------------------
1 | function loadUsers(userIds, load, done) {
2 | var totalUsers = userIds.length,
3 | usersLoaded = 0,
4 | users = [];
5 |
6 | userIds.map(function(id, index) {
7 | load(id, function(user) {
8 | users[index] = user;
9 | usersLoaded++;
10 |
11 | if (usersLoaded === totalUsers) {
12 | done(users);
13 | }
14 | });
15 | });
16 | }
17 |
18 | module.exports = loadUsers;
19 |
--------------------------------------------------------------------------------
/functional-javascript/call-duck-typing.js:
--------------------------------------------------------------------------------
1 | function duckCount() {
2 | return Array.prototype.slice.call(arguments).reduce(function(prev, curr) {
3 | return prev + (Object.prototype.hasOwnProperty.call(curr, 'quack') ? 1 : 0);
4 | }, 0);
5 | }
6 |
7 | module.exports = duckCount;
8 |
--------------------------------------------------------------------------------
/functional-javascript/curryn.js:
--------------------------------------------------------------------------------
1 | function curryN(fn, n) {
2 | n = typeof n !== 'undefined' ? n : fn.length;
3 |
4 | if (n) {
5 | return function(arg) {
6 | return curryN(fn.bind(null, arg), n - 1);
7 | }
8 | }
9 | else {
10 | return fn();
11 | }
12 | }
13 |
14 | module.exports = curryN;
15 |
--------------------------------------------------------------------------------
/functional-javascript/dependency-tree.js:
--------------------------------------------------------------------------------
1 | function getDependencies(tree, allDeps) {
2 | allDeps = allDeps || {};
3 | var dependencies = tree.dependencies || [];
4 |
5 | Object.keys(dependencies).forEach(function(dep) {
6 | var fullDepName = [dep, dependencies[dep].version].join('@');
7 | allDeps[fullDepName] = fullDepName;
8 | getDependencies(dependencies[dep], allDeps);
9 | });
10 |
11 | return Object.keys(allDeps).sort();
12 | }
13 |
14 | module.exports = getDependencies;
15 |
--------------------------------------------------------------------------------
/functional-javascript/every-some.js:
--------------------------------------------------------------------------------
1 | module.exports = function checkUsersValid(goodUsers) {
2 | return function(testUsers) {
3 | return testUsers.every(function(testUser) {
4 | return goodUsers.some(function(goodUser) {
5 | return testUser.id === goodUser.id;
6 | });
7 | });
8 | }
9 | };
10 |
--------------------------------------------------------------------------------
/functional-javascript/filter.js:
--------------------------------------------------------------------------------
1 | module.exports = function getShortMessages(msgs) {
2 | return msgs.filter(function(msg) {
3 | return msg.message.length < 50;
4 | }).map(function(msg) {
5 | return msg.message;
6 | });
7 | };
8 |
--------------------------------------------------------------------------------
/functional-javascript/function-call.js:
--------------------------------------------------------------------------------
1 | module.exports = Function.prototype.call.bind(Array.prototype.slice);
2 |
--------------------------------------------------------------------------------
/functional-javascript/hello-world.js:
--------------------------------------------------------------------------------
1 | module.exports = function(str) {
2 | return str.toUpperCase();
3 | };
4 |
5 |
--------------------------------------------------------------------------------
/functional-javascript/higher-order-function.js:
--------------------------------------------------------------------------------
1 | function repeat(fn, num) {
2 | if (!num) return;
3 |
4 | fn();
5 | return repeat(fn, num - 1);
6 | }
7 |
8 | module.exports = repeat;
9 |
--------------------------------------------------------------------------------
/functional-javascript/map-using-reduce.js:
--------------------------------------------------------------------------------
1 | module.exports = function arrayMap(arr, fn) {
2 | return arr.reduce(function(prev, curr, index, array) {
3 | return prev.concat(fn.call(null, curr, index, array));
4 | }, []);
5 | }
6 |
--------------------------------------------------------------------------------
/functional-javascript/map.js:
--------------------------------------------------------------------------------
1 | function doubleAll(numbers) {
2 | return numbers.map(function(n) {
3 | return n * 2;
4 | });
5 | }
6 |
7 | module.exports = doubleAll;
8 |
--------------------------------------------------------------------------------
/functional-javascript/non-blocking-recursion.js:
--------------------------------------------------------------------------------
1 | function repeat(fn, num) {
2 | if (!num) return;
3 |
4 | fn();
5 |
6 | if (num % 200 === 0) {
7 | setTimeout(function() {
8 | repeat(fn, --num);
9 | }, 0);
10 | }
11 | else {
12 | repeat(fn, --num);
13 | }
14 | }
15 |
16 | module.exports = repeat;
17 |
--------------------------------------------------------------------------------
/functional-javascript/partial-apply-with-bind.js:
--------------------------------------------------------------------------------
1 | function logger(namespace) {
2 | return console.log.bind(console, namespace);
3 | }
4 |
5 | module.exports = logger;
6 |
--------------------------------------------------------------------------------
/functional-javascript/partial-apply-without-bind.js:
--------------------------------------------------------------------------------
1 | var slice = Array.prototype.slice;
2 |
3 | function logger(namespace) {
4 | return function() {
5 | console.log.apply(console, [namespace].concat(slice.call(arguments)));
6 | }
7 | }
8 |
9 | module.exports = logger;
10 |
--------------------------------------------------------------------------------
/functional-javascript/recursive-reduce.js:
--------------------------------------------------------------------------------
1 | function reduce(array, fn, init) {
2 | var arrayDup = array.slice(), i = 0;
3 |
4 | return (function recursiveReduce(arrayDup, fn, init) {
5 | return arrayDup.length ? recursiveReduce(arrayDup, fn, fn(init, arrayDup.shift()), i++, array) : init;
6 | }(arrayDup, fn, init));
7 | }
8 |
9 | module.exports = reduce;
10 |
--------------------------------------------------------------------------------
/functional-javascript/reduce.js:
--------------------------------------------------------------------------------
1 | module.exports = function countWords(words) {
2 | return words.reduce(function(wordsTotal, word) {
3 | (++wordsTotal[word]) || (wordsTotal[word] = 1);
4 | return wordsTotal;
5 | }, {});
6 | };
7 |
8 |
--------------------------------------------------------------------------------
/functional-javascript/spies.js:
--------------------------------------------------------------------------------
1 | function Spy(target, method) {
2 | var oldMethod = target[method],
3 | spy = { count: 0 };
4 |
5 | target[method] = function() {
6 | spy.count++;
7 | return oldMethod.apply(target, arguments);
8 | }
9 |
10 | return spy;
11 | }
12 |
13 | module.exports = Spy;
14 |
--------------------------------------------------------------------------------
/functional-javascript/trampoline.js:
--------------------------------------------------------------------------------
1 | function repeat(operation, num) {
2 | if (!num) return;
3 | return function() {
4 | operation();
5 | return repeat(operation, --num);
6 | }
7 | }
8 |
9 | function trampoline(fn) {
10 | while (fn());
11 | }
12 |
13 | module.exports = function(operation, num) {
14 | return trampoline(repeat(operation, num));
15 | };
16 |
17 |
--------------------------------------------------------------------------------
/learn-generators/01-run-stop-run.js:
--------------------------------------------------------------------------------
1 |
2 | function *range(from, to) {
3 | while (from <= to) yield from++
4 | }
5 |
6 | for (var a of range(5, 10)) {
7 | console.log(a)
8 | }
9 |
10 |
11 |
--------------------------------------------------------------------------------
/learn-generators/02-generator-iterator.js:
--------------------------------------------------------------------------------
1 |
2 | function *factorial(n) {
3 | let curr = 1
4 | let total = 1
5 | while (n >= curr) yield total = curr++ * total
6 | }
7 |
8 | for (let a of factorial(5)) console.log(a)
9 |
--------------------------------------------------------------------------------
/learn-generators/03-delegating-generators.js:
--------------------------------------------------------------------------------
1 |
2 | function *flat(arr) {
3 | for (let i = 0; i < arr.length; i++) {
4 | if (arr[i].constructor === Array) yield *flat(arr[i])
5 | else yield arr[i]
6 | }
7 | }
8 |
9 | const A = [ 1, [ 2, [ 3, 4 ], 5 ], 6 ]
10 |
11 | for (let a of flat(A)) console.log(a)
12 |
--------------------------------------------------------------------------------
/learn-generators/04-catch-error.js:
--------------------------------------------------------------------------------
1 |
2 | function *upper(list) {
3 | for (let i = 0; i < list.length; ++i) {
4 | try {
5 | yield list[i].toUpperCase()
6 | } catch (e) {
7 | yield null
8 | }
9 | }
10 | }
11 |
12 | let items = [ 'a', 'B', 1, 'c' ]
13 |
14 | for (let a of upper(items)) console.log(a)
15 |
--------------------------------------------------------------------------------
/learn-generators/05-look-sync-do-async.js:
--------------------------------------------------------------------------------
1 |
2 | var fs = require('fs')
3 |
4 | function run(generator) {
5 | const it = generator(go)
6 |
7 | function go(err, result) {
8 | if (err) return it.throw(err)
9 | it.next(result)
10 | }
11 |
12 | go()
13 | }
14 |
15 | run(function* (done) {
16 | let firstFile
17 |
18 | try {
19 | const files = yield fs.readdir('NoNoNo', done)
20 | firstFile = files[0]
21 | } catch (e) {
22 | firstFile = null
23 | }
24 |
25 | console.log(firstFile)
26 | })
27 |
28 |
--------------------------------------------------------------------------------
/learn-generators/06-look-sync-make-promise.js:
--------------------------------------------------------------------------------
1 |
2 | const askFoo = () => new Promise((resolve) => resolve('foo'))
3 |
4 | const run = generator => {
5 | const it = generator()
6 |
7 | it.next().value
8 | .then(result => it.next(result))
9 | .catch(err => it.throw(err))
10 | }
11 |
12 | run(function* () {
13 | try {
14 | const foo = yield askFoo()
15 | console.log(foo)
16 | } catch (e) {
17 | console.log(e)
18 | }
19 | })
20 |
--------------------------------------------------------------------------------
/learnyounode/baby-steps.js:
--------------------------------------------------------------------------------
1 |
2 | var numbers = process.argv.slice(2),
3 | sum = numbers.reduce((curr, prev) => { return +curr + +prev; });
4 |
5 | console.log(sum);
6 |
7 |
--------------------------------------------------------------------------------
/learnyounode/filter-dir.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var path = require('path');
3 |
4 | module.exports = (dirPath, extension, cb) => {
5 | var filteredFiles = [];
6 |
7 | fs.readdir(dirPath, (err, list) => {
8 | if (err) {
9 | return cb(err);
10 | }
11 |
12 | list.forEach((file) => {
13 | if (path.extname(file) === '.' + extension) {
14 | filteredFiles.push(file);
15 | }
16 | });
17 |
18 | cb(null, filteredFiles);
19 | });
20 | };
21 |
22 |
--------------------------------------------------------------------------------
/learnyounode/filtered-ls.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var path = require('path');
3 |
4 | fs.readdir(process.argv[2], (err, list) => {
5 | list.forEach((filename) => {
6 | if (path.extname(filename) === '.' + process.argv[3]) {
7 | console.log(filename);
8 | }
9 | });
10 | });
11 |
12 |
--------------------------------------------------------------------------------
/learnyounode/hello-world.js:
--------------------------------------------------------------------------------
1 | console.log('HELLO WORLD');
2 |
--------------------------------------------------------------------------------
/learnyounode/http-client.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 |
3 | var url = process.argv[2];
4 |
5 | http.get(url, (response) => {
6 | response.setEncoding('utf8');
7 |
8 | response.on('data', (data) => {
9 | console.log(data);
10 | });
11 | });
12 |
13 |
--------------------------------------------------------------------------------
/learnyounode/http-collect.js:
--------------------------------------------------------------------------------
1 | var concatStream = require('concat-stream');
2 | var http = require('http');
3 |
4 | var url = process.argv[2];
5 |
6 | http.get(url, (response) => {
7 | response.setEncoding('utf8');
8 | response.pipe(concatStream((data) => {
9 | console.log(data.length);
10 | console.log(data);
11 | }));
12 | });
13 |
14 |
--------------------------------------------------------------------------------
/learnyounode/http-file-server.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var http = require('http');
3 |
4 | var port = process.argv[2];
5 | var file = process.argv[3];
6 |
7 | http.createServer((req, res) => {
8 | res.writeHead(200, { 'content-type' : 'text/plain' });
9 |
10 | fs.createReadStream(file).pipe(res);
11 | }).listen(port);
12 |
--------------------------------------------------------------------------------
/learnyounode/http-json-api-server.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 | var url = require('url');
3 |
4 | http.createServer((req, res) => {
5 | var urlObj = url.parse(req.url, true),
6 | pathname = urlObj.pathname,
7 | strtime = urlObj.query.iso,
8 | result;
9 |
10 | if (pathname === '/api/unixtime') {
11 | result = getUnixTimestamp(strtime);
12 | }
13 | else if (pathname === '/api/parsetime') {
14 | result = getTimeObj(strtime);
15 | }
16 |
17 | if (result) {
18 | res.writeHead(200, { 'Content-Type': 'application/json' });
19 | res.end(JSON.stringify(result));
20 | }
21 | else {
22 | res.writeHead(404);
23 | res.end();
24 | }
25 |
26 | }).listen(process.argv[2]);
27 |
28 |
29 | var getUnixTimestamp = (strtime) => {
30 | return {
31 | unixtime: getTimestamp(strtime)
32 | };
33 | }
34 |
35 | var getTimestamp = (strtime) => {
36 | return Date.parse(strtime);
37 | }
38 |
39 | var getTimeObj = (strtime) => {
40 | var date = new Date(getTimestamp(strtime));
41 |
42 | return {
43 | hour: date.getHours(),
44 | minute: date.getMinutes(),
45 | second: date.getSeconds()
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/learnyounode/http-reverserer.js:
--------------------------------------------------------------------------------
1 | var map = require('through2-map');
2 | var http = require('http');
3 |
4 | var port = process.argv[2];
5 |
6 | http.createServer((req, res) => {
7 | if (req.method === 'POST') {
8 | req.pipe(map((chunk) => {
9 | return chunk.toString().toUpperCase();
10 | })).pipe(res);
11 | }
12 | }).listen(port);
13 |
--------------------------------------------------------------------------------
/learnyounode/juggling-async.js:
--------------------------------------------------------------------------------
1 | var http = require('http');
2 | var concatStream = require('concat-stream');
3 |
4 | var urls = process.argv.slice(2),
5 | results = [],
6 | resultsCount = 0;
7 |
8 | urls.forEach((url, i) => {
9 | http.get(url, (response) => {
10 | response.setEncoding('utf8');
11 |
12 | response.pipe(concatStream((data) => {
13 | results[i] = data;
14 | resultsCount++;
15 |
16 | if (resultsCount === urls.length) {
17 | results.forEach((result) => {
18 | console.log(result);
19 | });
20 | }
21 | }));
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/learnyounode/make-it-modular.js:
--------------------------------------------------------------------------------
1 | var filterDir = require('./filter-dir');
2 |
3 | var dirPath = process.argv[2];
4 | var extension = process.argv[3];
5 |
6 | filterDir(dirPath, extension, (err, list) => {
7 | if (err) {
8 | console.log('An error happened when reading ' + dirPath);
9 | return err;
10 | }
11 |
12 | list.forEach((filename) => {
13 | console.log(filename);
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/learnyounode/my-first-async-io.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | fs.readFile(process.argv[2], 'utf8', (err, data) => {
4 | if (err) throw err;
5 | console.log(data.split('\n').length - 1);
6 | });
7 |
--------------------------------------------------------------------------------
/learnyounode/my-first-io.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 |
3 | var text = fs.readFileSync(process.argv[2]);
4 |
5 | console.log(text.toString().split('\n').length - 1);
6 |
--------------------------------------------------------------------------------
/learnyounode/time-server.js:
--------------------------------------------------------------------------------
1 | var net = require('net');
2 |
3 | var server = net.createServer((socket) => {
4 |
5 | socket.end(getFormattedCurrentTime() + "\n");
6 |
7 | });
8 |
9 | server.listen(process.argv[2]);
10 |
11 | var getFormattedCurrentTime = () => {
12 | var now = new Date();
13 |
14 | return [now.getFullYear(), formatNumber(now.getMonth() + 1), formatNumber(now.getDate())].join("-")
15 | + " " + [formatNumber(now.getHours()), formatNumber(now.getMinutes())].join(":");
16 | }
17 |
18 | var formatNumber = (number) => {
19 | return number < 10 ? "0" + number : number;
20 | }
21 |
--------------------------------------------------------------------------------
/learnyoureact/hello-react/app.js:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 | var TodoBox = require('./views/index.jsx');
3 |
4 | var data = JSON.parse(document.getElementById('initial-data').getAttribute('data-json'));
5 | React.render(, document.getElementById('app'));
6 |
7 |
--------------------------------------------------------------------------------
/learnyoureact/hello-react/program.js:
--------------------------------------------------------------------------------
1 | var express = require('express');
2 | var app = express();
3 |
4 | var React = require('react');
5 | var DOM = React.DOM;
6 | var body = DOM.body;
7 | var div = DOM.div;
8 | var script = DOM.script;
9 |
10 | var browserify = require('browserify');
11 |
12 | app.set('port', process.argv[2] || 3000);
13 | app.set('view engine', 'jsx');
14 | app.set('views', __dirname + '/views');
15 | app.engine('jsx', require('express-react-views').createEngine());
16 |
17 | require('node-jsx').install();
18 | var TodoBox = require('./views/index.jsx');
19 |
20 | var data = [
21 | {
22 | title: 'Shopping',
23 | detail: process.argv[3]
24 | },
25 | {
26 | title: 'Hair cut',
27 | detail: process.argv[4]
28 | }
29 | ];
30 |
31 | app.use('/bundle.js', function (req, res) {
32 | res.setHeader('Content-Type', 'application/javascript');
33 | browserify('./app.js')
34 | .transform('reactify')
35 | .bundle()
36 | .pipe(res);
37 | });
38 |
39 | app.use('/', function (req, res) {
40 | var initialData = JSON.stringify(data);
41 | var markup = React.renderToString(React.createElement(TodoBox, {data: data}));
42 |
43 | res.setHeader('Content-Type', 'text/html');
44 |
45 | var html = React.renderToStaticMarkup(body(null,
46 | div({ id: 'app', dangerouslySetInnerHTML: { __html: markup }}),
47 | script({ id: 'initial-data',
48 | type: 'text/plain',
49 | 'data-json': initialData
50 | }),
51 | script({ src: '/bundle.js' })
52 | ));
53 |
54 | res.end(html);
55 | });
56 |
57 | app.listen(app.get('port'), function () {
58 | console.log('server listening on port %s', app.get('port'));
59 | });
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/learnyoureact/hello-react/views/index.jsx:
--------------------------------------------------------------------------------
1 | var React = require('react');
2 |
3 | var TodoBox = React.createClass({
4 | render: function () {
5 | return (
6 |
7 |
Todos
8 |
9 |
10 |
11 | );
12 | }
13 | });
14 |
15 | var TodoList = React.createClass({
16 | render: function () {
17 | var todos = this.props.data.map(function (todo) {
18 | return {todo.detail};
19 | });
20 | return (
21 |
22 |
23 |
24 | {todos}
25 |
26 |
27 |
28 | );
29 | }
30 | });
31 |
32 | var Todo = React.createClass({
33 | propTypes: {
34 | title: React.PropTypes.string.isRequired
35 | },
36 |
37 | getInitialState: function () {
38 | return { checked: false };
39 | },
40 |
41 | handleChange: function () {
42 | this.setState({
43 | checked: !this.state.checked
44 | });
45 | },
46 |
47 | render: function () {
48 | var rowStyle = this.state.checked ? style.checkedTodo : style.notCheckedTodo;
49 |
50 | return (
51 |
52 | |
53 | {this.props.title} |
54 | {this.props.children} |
55 |
56 | );
57 | }
58 | });
59 |
60 | var TodoForm = React.createClass({
61 | render: function () {
62 | return (
63 |
64 | I am a TodoForm.
65 |
66 | );
67 | }
68 | });
69 |
70 | var style = {
71 | checkedTodo: {
72 | textDecoration: 'line-through'
73 | },
74 | notCheckedTodo: {
75 | textDecoration: 'none'
76 | },
77 | tableContent: {
78 | border: '1px solid black'
79 | }
80 | };
81 |
82 | module.exports = TodoBox;
83 |
--------------------------------------------------------------------------------
/levelmeup/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/levelmeup/all-you-base.js:
--------------------------------------------------------------------------------
1 | var x = process.argv[2],
2 | y = process.argv[3];
3 |
4 | console.log("ALL YOUR " + x + " ARE BELONG TO " + y);
5 |
6 |
--------------------------------------------------------------------------------
/levelmeup/basics-batch.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs');
2 | var level = require('level');
3 | var db = level(process.argv[2]);
4 |
5 | var operations = [];
6 |
7 | fs.readFile(process.argv[3], function (err, data) {
8 | if (err)
9 | throw err;
10 |
11 | var lines = data.toString().split('\n');
12 |
13 | operations = lines.map(function (line) {
14 | var params = line.split(','),
15 | op = {
16 | type: params[0],
17 | key: params[1]
18 | };
19 |
20 | if (params[2]) {
21 | op.value = params[2];
22 | }
23 |
24 | return op;
25 | });
26 |
27 | db.batch(operations, function (err) {
28 | if (err)
29 | console.error(err);
30 | });
31 | });
32 |
33 |
--------------------------------------------------------------------------------
/levelmeup/basics-get.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var db = level(process.argv[2]);
3 |
4 | for (var i = 0; i <= 100; ++i) {
5 | (function (currKey) {
6 | db.get(currKey, function (err, data) {
7 | if (err) {
8 | return;
9 | }
10 |
11 | console.log("%s=%s", currKey, data);
12 | });
13 | }("key" + i));
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/levelmeup/basics-put.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var db = level(process.argv[2]);
3 |
4 | var data = JSON.parse(process.argv[3]);
5 |
6 | Object.keys(data).forEach(function (key) {
7 | db.put(key, data[key], function (err) {
8 | if (err) {
9 | return console.error('Error in put();');
10 | }
11 |
12 | console.error(key + " = " + data[key]);
13 | });
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/levelmeup/get-your-level-on.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var db = level(process.argv[2]);
3 |
4 | db.get('levelmeup', function (err, data) {
5 | if (err) {
6 | throw err;
7 | }
8 |
9 | console.log(data);
10 | });
11 |
--------------------------------------------------------------------------------
/levelmeup/horse_js-count.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = function (db, date, callback) {
3 | var count = 0,
4 | stream = db.createReadStream({ start: date });
5 |
6 | stream.on('data', function (data) {
7 | count++;
8 | });
9 |
10 | stream.on('error', function (err) {
11 | db.close();
12 | callback(err);
13 | });
14 |
15 | stream.on('end', function () {
16 | callback(null, count);
17 | });
18 | };
19 |
20 |
21 |
--------------------------------------------------------------------------------
/levelmeup/horse_js-tweets.js:
--------------------------------------------------------------------------------
1 | module.exports = function (db, date, cb) {
2 | var tweets = [];
3 |
4 | db.createReadStream({
5 | start: date,
6 |
7 | // append last ASCII character to 'end' date to differentiate from 'start'
8 | end: date + '\xff'
9 | })
10 | .on('data', function (data) {
11 | tweets.push(data.value);
12 | })
13 | .on('error', function (err) {
14 | cb(err);
15 | })
16 | .on('end', function () {
17 | cb(null, tweets);
18 | });
19 | };
20 |
--------------------------------------------------------------------------------
/levelmeup/keywise.js:
--------------------------------------------------------------------------------
1 | var db = require('level')(process.argv[2], { valueEncoding: 'json' });
2 | var data = require(process.argv[3]);
3 |
4 | var operations = [];
5 | data.forEach(function (entry) {
6 | var key;
7 | if (entry.type === 'user') {
8 | key = entry.name;
9 | }
10 | else {
11 | key = entry.user + "!" + entry.name;
12 | }
13 |
14 | operations.push({
15 | type: 'put',
16 | key: key,
17 | value: entry
18 | });
19 | });
20 |
21 | db.batch(operations);
22 |
23 |
--------------------------------------------------------------------------------
/levelmeup/multilevel.js:
--------------------------------------------------------------------------------
1 | var multilevel = require('multilevel');
2 | var net = require('net');
3 |
4 | var db = multilevel.client();
5 | var connection = net.connect(4545);
6 |
7 | connection.pipe(db.createRpcStream()).pipe(connection);
8 |
9 | db.get('multilevelmeup', function (err, data) {
10 | if (err) {
11 | throw err;
12 | }
13 |
14 | console.log(data);
15 | connection.end();
16 | });
17 |
--------------------------------------------------------------------------------
/levelmeup/short-scrabble-words.js:
--------------------------------------------------------------------------------
1 | module.exports.init = function (db, words, cb) {
2 | var ops = [];
3 |
4 | words.forEach(function (word) {
5 | var key = word.length + '!' + word;
6 |
7 | ops.push({ type: 'put', key: key, value: word });
8 | });
9 |
10 | db.batch(ops, cb);
11 | };
12 |
13 | module.exports.query = function (db, word, cb) {
14 | var length = word.length,
15 | word = word.replace(/\*/g, ''),
16 | key = length + '!' + word,
17 | words = [];
18 |
19 | db.createReadStream({ start: key, end: key + '\xff' })
20 | .on('data', function (data) {
21 | words.push(data.value);
22 | })
23 | .on('error', function (err) {
24 | cb(err);
25 | throw err;
26 | })
27 | .on('end', function () {
28 | cb(null, words);
29 | });
30 | };
31 |
32 |
--------------------------------------------------------------------------------
/levelmeup/streaming.js:
--------------------------------------------------------------------------------
1 | var level = require('level');
2 | var db = level(process.argv[2]);
3 |
4 | db.createReadStream().on('data', function (data) {
5 | console.log('%s=%s', data.key, data.value);
6 | });
7 |
8 |
--------------------------------------------------------------------------------
/levelmeup/sublevel.js:
--------------------------------------------------------------------------------
1 | var level = require('level'),
2 | sub = require('level-sublevel');
3 |
4 | var db = sub(level(process.argv[2]));
5 |
6 | db.sublevel('dinosaurs').put('slogan', 'rawr');
7 | db.sublevel('robots').put('slogan', 'beep boop');
8 |
9 |
--------------------------------------------------------------------------------
/makemehapi/directories.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi'),
2 | path = require('path');
3 |
4 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080);
5 |
6 | server.route({
7 | method: 'GET',
8 | path: '/foo/bar/baz/{param}',
9 | handler: {
10 | directory: {
11 | path: path.join(__dirname, '/public')
12 | }
13 | }
14 | });
15 |
16 | server.start();
17 |
18 |
--------------------------------------------------------------------------------
/makemehapi/handling.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi');
2 | var path = require('path');
3 |
4 | var server = Hapi.createServer('localhost', process.argv[2] || 8080);
5 |
6 | server.route({
7 | method: 'GET',
8 | path: '/',
9 | handler: {
10 | file: path.join(__dirname, 'public/index.html')
11 | }
12 | });
13 |
14 | server.start();
15 |
16 |
--------------------------------------------------------------------------------
/makemehapi/hello-hapi.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi');
2 |
3 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080);
4 |
5 | server.route({
6 | method: 'GET',
7 | path: '/',
8 | handler: function (req, reply) {
9 | reply('Hello Hapi');
10 | }
11 | });
12 |
13 | server.start();
14 |
15 |
16 |
--------------------------------------------------------------------------------
/makemehapi/helpers/helper.js:
--------------------------------------------------------------------------------
1 | module.exports = function (context) {
2 | return context.data.root.query.name + context.data.root.query.suffix;
3 | };
4 |
5 |
--------------------------------------------------------------------------------
/makemehapi/helping.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi'),
2 | path = require('path');
3 |
4 | var options = {
5 | views: {
6 | path: path.join(__dirname, '/templates'),
7 | engines: {
8 | html: require('handlebars')
9 | },
10 | helpersPath: 'helpers'
11 | }
12 | };
13 |
14 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080, options);
15 |
16 | server.route({
17 | method: 'GET',
18 | path: '/',
19 | handler: {
20 | view: 'helper-template.html'
21 | }
22 | });
23 |
24 | server.start();
25 |
26 |
--------------------------------------------------------------------------------
/makemehapi/proxies.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi');
2 |
3 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080);
4 |
5 | server.route({
6 | method: 'GET',
7 | path: '/proxy',
8 | handler: {
9 | proxy: {
10 | host: 'localhost',
11 | port: 65535
12 | }
13 | }
14 | });
15 |
16 | server.start();
17 |
18 |
--------------------------------------------------------------------------------
/makemehapi/public/file.html:
--------------------------------------------------------------------------------
1 |
2 | Hello Directories
3 |
4 | Hello Directories
5 |
6 |
7 |
--------------------------------------------------------------------------------
/makemehapi/public/index.html:
--------------------------------------------------------------------------------
1 |
2 | Hello Handling
3 |
4 | Hello Handling
5 |
6 |
7 |
--------------------------------------------------------------------------------
/makemehapi/routes.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi');
2 |
3 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080);
4 |
5 | server.route({
6 | method: 'GET',
7 | path: '/{name}',
8 | handler: function (req, rep) {
9 | rep('Hello ' + req.params.name);
10 | }
11 | });
12 |
13 | server.start();
14 |
15 |
--------------------------------------------------------------------------------
/makemehapi/stream-text.txt:
--------------------------------------------------------------------------------
1 | The Pursuit of Hapi-ness
2 |
--------------------------------------------------------------------------------
/makemehapi/streams.js:
--------------------------------------------------------------------------------
1 | var through = require('through');
2 | var fs = require('fs');
3 | var Hapi = require('hapi');
4 |
5 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080);
6 |
7 | server.route({
8 | method: 'GET',
9 | path: '/',
10 | handler: function (req, rep) {
11 | var data = fs.createReadStream(__dirname + '/stream-text.txt');
12 |
13 | rep(data.pipe(through(function (buf) {
14 | this.queue(rot13(buf.toString()));
15 | }, function () {
16 | this.queue(null);
17 | })));
18 | }
19 | });
20 |
21 | server.start();
22 |
23 | var alphabet = 'abcdefghijklmnopqrstuvwxyz',
24 | rot13Alphabet = rotate(alphabet, 13);
25 |
26 | // Map rot13 letters
27 | var rot13Map = alphabet.split('').reduce(function (prev, curr, idx, arr) {
28 | prev[alphabet[idx]] = rot13Alphabet[idx];
29 | prev[alphabet[idx].toUpperCase()] = rot13Alphabet[idx].toUpperCase();
30 |
31 | return prev;
32 | }, {});
33 |
34 | function rot13(text) {
35 | return text.split('').map(rot13Char).join('');
36 | }
37 |
38 | function rot13Char(c) {
39 | return rot13Map[c] || c;
40 | }
41 |
42 | function rotate(text, size) {
43 | text = text.split('');
44 |
45 | while (size--) {
46 | text.unshift(text.pop());
47 | }
48 |
49 | return text.join('');
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/makemehapi/templates/helper-template.html:
--------------------------------------------------------------------------------
1 |
2 | Hello {{ helper }}
3 |
4 | Hello {{ helper }}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/makemehapi/templates/index.html:
--------------------------------------------------------------------------------
1 |
2 | Hello {{ query.name }}
3 |
4 | Hello {{ query.name }}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/makemehapi/views.js:
--------------------------------------------------------------------------------
1 | var Hapi = require('hapi'),
2 | path = require('path');
3 |
4 | var options = {
5 | views: {
6 | path: path.join(__dirname, '/templates'),
7 | engines: {
8 | html: require('handlebars')
9 | }
10 | }
11 | };
12 |
13 | var server = Hapi.createServer('localhost', Number(process.argv[2]) || 8080, options);
14 |
15 | server.route({
16 | method: 'GET',
17 | path: '/',
18 | handler: {
19 | view: 'index.html'
20 | }
21 | });
22 |
23 |
24 | server.start();
25 |
26 |
--------------------------------------------------------------------------------
/nodebot-workshop/01-blink-blink.js:
--------------------------------------------------------------------------------
1 | var five = require('johnny-five');
2 |
3 | var board = new five.Board();
4 |
5 | board.on('ready', function () {
6 | var led = new five.Led(13);
7 |
8 | led.strobe(1000);
9 | });
10 |
11 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/always-async.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | var defer = q.defer();
4 |
5 | defer.promise.then(console.log);
6 |
7 | defer.resolve('SECOND');
8 | console.log('FIRST');
9 |
10 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/an-important-rule.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | function throwMyGod() {
4 | throw new Error('OH NOES');
5 | }
6 |
7 | function iterate(arg) {
8 | console.log(arg);
9 |
10 | return arg + 1;
11 | }
12 |
13 | q.fcall(iterate, 1)
14 | .then(iterate)
15 | .then(iterate)
16 | .then(iterate)
17 | .then(iterate)
18 | .then(throwMyGod)
19 | .then(iterate)
20 | .then(iterate)
21 | .then(iterate)
22 | .then(iterate)
23 | .then(iterate)
24 | .then(null, console.log);
25 |
26 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/do-some-work.js:
--------------------------------------------------------------------------------
1 | var qioHttp = require('q-io/http');
2 |
3 | qioHttp.read('http://localhost:7000')
4 | .then(function (data) {
5 | return qioHttp.read('http://localhost:7001/' + data);
6 | })
7 | .then(function (user) {
8 | console.log(JSON.parse(user));
9 | })
10 | .then(null, console.error)
11 | .done();
12 |
13 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/fetch-json.js:
--------------------------------------------------------------------------------
1 | var qioHttp = require('q-io/http');
2 |
3 | qioHttp.read('http://localhost:1337')
4 | .then(function (data) {
5 | console.log(JSON.parse(data));
6 | })
7 | .then(null, console.error)
8 | .done();
9 |
10 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/fulfill-a-promise.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | var defer = q.defer();
4 |
5 | defer.promise.then(console.log);
6 |
7 | setTimeout(defer.resolve, 300, 'RESOLVED!');
8 |
9 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/more-functional.js:
--------------------------------------------------------------------------------
1 | var qioHttp = require('q-io/http'),
2 | _ = require('lodash');
3 |
4 |
5 | qioHttp.read('http://localhost:7000')
6 | .then(_.compose(qioHttp.read, function (id) { return 'http://localhost:7001/' + id; }))
7 | .then(_.compose(console.log, JSON.parse))
8 | .then(null, console.error)
9 | .done();
10 |
11 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/multiple-promises.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | var defer1 = q.defer(),
4 | defer2 = q.defer();
5 |
6 | function all(prom1, prom2) {
7 | var defer = q.defer(),
8 | results = [undefined, undefined],
9 | counter = 0;
10 |
11 | prom1
12 | .then(function (data) {
13 | counter += 1;
14 | results[0] = data;
15 |
16 | if (counter === 2) {
17 | defer.resolve(results);
18 | }
19 | })
20 | .then(null, defer.reject);
21 |
22 | prom2
23 | .then(function (data) {
24 | counter += 1;
25 | results[1] = data;
26 |
27 | if (counter === 2) {
28 | defer.resolve(results);
29 | }
30 | })
31 | .then(null, defer.reject);
32 |
33 | return defer.promise;
34 | }
35 |
36 | all(defer1.promise, defer2.promise)
37 | .then(console.log);
38 |
39 | setTimeout(function () {
40 | defer1.resolve('PROMISES');
41 | defer2.resolve('FTW');
42 | }, 200);
43 |
44 |
45 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/reject-a-promise.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | var defer = q.defer();
4 |
5 | defer.promise.then(null, function (err) {
6 | console.log(err.message);
7 | });
8 |
9 | setTimeout(defer.reject, 300, new Error('REJECTED!'));
10 |
11 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/throw-an-error.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | function parsePromised(arg) {
4 | var defer = q.defer();
5 |
6 | try {
7 | defer.resolve(JSON.parse(arg));
8 | } catch (e) {
9 | defer.reject(e);
10 | }
11 |
12 | return defer.promise;
13 | }
14 |
15 |
16 | parsePromised(process.argv[2])
17 | .then(null, console.log);
18 |
19 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/to-reject-or-not-to-reject.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | var defer = q.defer();
4 |
5 | defer.promise.then(console.log, console.log);
6 |
7 | defer.resolve('I FIRED');
8 | defer.reject('I DID NOT FIRE');
9 |
10 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/using-qfcall.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | q.fcall(JSON.parse, process.argv[2])
4 | .then(null, console.log);
5 |
6 |
7 |
--------------------------------------------------------------------------------
/promise-it-wont-hurt/values-and-promises.js:
--------------------------------------------------------------------------------
1 | var q = require('q');
2 |
3 | function attachTitle(arg) {
4 | return 'DR. ' + arg;
5 | }
6 |
7 | var defer = q.defer();
8 |
9 | defer.promise
10 | .then(attachTitle)
11 | .then(console.log);
12 |
13 | defer.resolve('MANHATTAN');
14 |
15 |
--------------------------------------------------------------------------------
/stream-adventure/beep-boop.js:
--------------------------------------------------------------------------------
1 | console.log('beep boop');
2 |
--------------------------------------------------------------------------------
/stream-adventure/combiner.js:
--------------------------------------------------------------------------------
1 | var combine = require('stream-combiner');
2 | var split = require('split');
3 | var through = require('through');
4 | var zlib = require('zlib');
5 |
6 |
7 | module.exports = function () {
8 | var genreInfo;
9 |
10 | function write(buf) {
11 | if (buf.length === 0) {
12 | return;
13 | }
14 |
15 | buf = JSON.parse(buf);
16 | if (buf.type === 'genre') {
17 | if (genreInfo) {
18 | this.queue(JSON.stringify(genreInfo) + '\n');
19 | }
20 |
21 | genreInfo = {
22 | name: buf.name,
23 | books: []
24 | }
25 | }
26 | else {
27 | genreInfo.books.push(buf.name);
28 | }
29 | }
30 |
31 | function end() {
32 | this.queue(JSON.stringify(genreInfo) + '\n');
33 | this.queue(null);
34 | };
35 |
36 | return combine(
37 | split(),
38 | through(write, end),
39 | zlib.createGzip()
40 | );
41 | };
42 |
43 |
--------------------------------------------------------------------------------
/stream-adventure/concat.js:
--------------------------------------------------------------------------------
1 | var concatStream = require('concat-stream');
2 |
3 | process.stdin
4 | .pipe(concatStream(function (body) {
5 | process.stdout.write(body.toString().split('').reverse().join(''));
6 | }));
7 |
8 |
--------------------------------------------------------------------------------
/stream-adventure/crypt.js:
--------------------------------------------------------------------------------
1 | var crypto = require('crypto');
2 |
3 | var stream = crypto.createDecipher('aes256', process.argv[2]);
4 |
5 | process.stdin.pipe(stream).pipe(process.stdout);
6 |
7 |
--------------------------------------------------------------------------------
/stream-adventure/duplexer-redux.js:
--------------------------------------------------------------------------------
1 | var duplexer = require('duplexer');
2 | var through = require('through');
3 |
4 | module.exports = function (counter) {
5 | var count = {};
6 | var tr = through(function (buf) {
7 | count[buf.country] = count[buf.country] ? count[buf.country] + 1 : 1;
8 | }, function () {
9 | counter.setCounts(count);
10 | });
11 |
12 | return duplexer(tr, counter);
13 | };
14 |
15 |
--------------------------------------------------------------------------------
/stream-adventure/duplexer.js:
--------------------------------------------------------------------------------
1 | var spawn = require('child_process').spawn;
2 | var duplexer = require('duplexer');
3 |
4 | module.exports = function (cmd, args) {
5 | var proc = spawn(cmd, args);
6 | return duplexer(proc.stdin, proc.stdout);
7 | }
8 |
--------------------------------------------------------------------------------
/stream-adventure/html-stream.js:
--------------------------------------------------------------------------------
1 | var trumpet = require('trumpet');
2 | var through = require('through');
3 |
4 | var tr = trumpet();
5 | var stream = tr.select('.loud').createStream();
6 |
7 | process.stdin.pipe(tr).pipe(process.stdout);
8 | stream
9 | .pipe(through(function (buf) { this.queue(buf.toString().toUpperCase()); }))
10 | .pipe(stream)
11 |
12 |
13 |
--------------------------------------------------------------------------------
/stream-adventure/http-client.js:
--------------------------------------------------------------------------------
1 | var request = require('request');
2 |
3 | var r = request.post('http://localhost:8000');
4 |
5 | process.stdin.pipe(r).pipe(process.stdout);
6 |
7 |
--------------------------------------------------------------------------------
/stream-adventure/http-server.js:
--------------------------------------------------------------------------------
1 | var through = require('through');
2 | var http = require('http');
3 |
4 | var port = process.argv[2];
5 |
6 | function write(buf) {
7 | this.queue(buf.toString().toUpperCase());
8 | }
9 | function end() {
10 | this.queue(null);
11 | };
12 |
13 | http.createServer(function (req, res) {
14 | if (req.method === 'POST') {
15 | req.pipe(through(write, end)).pipe(res);
16 | }
17 | }).listen(port);
18 |
19 |
--------------------------------------------------------------------------------
/stream-adventure/input-output.js:
--------------------------------------------------------------------------------
1 | process.stdin.pipe(process.stdout);
2 |
--------------------------------------------------------------------------------
/stream-adventure/lines.js:
--------------------------------------------------------------------------------
1 | var through = require('through');
2 | var split = require('split');
3 |
4 | var even = false;
5 |
6 | var tr = through(function (buf) {
7 | buf = buf.toString();
8 | if (even) {
9 | buf = buf.toUpperCase();
10 | }
11 | else {
12 | buf = buf.toLowerCase();
13 | }
14 | even = !even;
15 | this.queue(buf + "\n");
16 | });
17 |
18 | process.stdin
19 | .pipe(split())
20 | .pipe(tr)
21 | .pipe(process.stdout);
22 |
23 |
--------------------------------------------------------------------------------
/stream-adventure/meet-pipe.js:
--------------------------------------------------------------------------------
1 | require('fs').createReadStream(process.argv[2]).pipe(process.stdout);
2 |
--------------------------------------------------------------------------------
/stream-adventure/secretz.js:
--------------------------------------------------------------------------------
1 | var tar = require('tar');
2 | var parser = tar.Parse();
3 | var crypto = require('crypto');
4 | var through = require('through');
5 |
6 | var gunzipStream = require('zlib').createGunzip();
7 | var cypherStream = crypto.createDecipher(process.argv[2], process.argv[3]);
8 |
9 | parser.on('entry', function (e) {
10 | var md5Stream = crypto.createHash('md5', { encoding: 'hex' });
11 |
12 | if (e.type !== 'File') {
13 | return;
14 | }
15 |
16 | e.pipe(md5Stream)
17 | .pipe(through(function (buf) {
18 | this.queue(buf.toString());
19 | }, function () {
20 | this.queue(" " + e.path + "\n");
21 | this.queue(null);
22 | }))
23 | .pipe(process.stdout);
24 | });
25 |
26 | process.stdin.pipe(cypherStream).pipe(gunzipStream).pipe(parser);
27 |
--------------------------------------------------------------------------------
/stream-adventure/transform.js:
--------------------------------------------------------------------------------
1 | var through = require('through');
2 |
3 | process.stdin.pipe(through(function (buf) {
4 | this.queue(buf.toString().toUpperCase());
5 | }, function () {
6 | this.queue(null);
7 | })).pipe(process.stdout);
8 |
9 |
--------------------------------------------------------------------------------
/stream-adventure/websockets.js:
--------------------------------------------------------------------------------
1 | var ws = require('websocket-stream');
2 | var stream = ws('ws://localhost:8000');
3 |
4 | stream.end('hello\n');
5 |
6 |
--------------------------------------------------------------------------------