aboutsummaryrefslogtreecommitdiff
path: root/node_modules/slide
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2017-05-28 00:38:50 +0200
committerFlorian Dold <florian.dold@gmail.com>2017-05-28 00:40:43 +0200
commit7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027 (patch)
tree6de9a1aebd150a23b7f8c273ec657a5d0a18fe3e /node_modules/slide
parent963b7a41feb29cc4be090a2446bdfe0c1f1bcd81 (diff)
downloadwallet-core-7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027.tar.xz
add linting (and some initial fixes)
Diffstat (limited to 'node_modules/slide')
-rw-r--r--node_modules/slide/LICENSE15
-rw-r--r--node_modules/slide/README.md143
-rw-r--r--node_modules/slide/index.js1
-rw-r--r--node_modules/slide/lib/async-map-ordered.js65
-rw-r--r--node_modules/slide/lib/async-map.js54
-rw-r--r--node_modules/slide/lib/bind-actor.js16
-rw-r--r--node_modules/slide/lib/chain.js20
-rw-r--r--node_modules/slide/lib/slide.js3
-rw-r--r--node_modules/slide/package.json20
9 files changed, 337 insertions, 0 deletions
diff --git a/node_modules/slide/LICENSE b/node_modules/slide/LICENSE
new file mode 100644
index 000000000..05eeeb88c
--- /dev/null
+++ b/node_modules/slide/LICENSE
@@ -0,0 +1,15 @@
+The ISC License
+
+Copyright (c) Isaac Z. Schlueter
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/node_modules/slide/README.md b/node_modules/slide/README.md
new file mode 100644
index 000000000..59ad738bc
--- /dev/null
+++ b/node_modules/slide/README.md
@@ -0,0 +1,143 @@
+# Controlling Flow: callbacks are easy
+
+## What's actually hard?
+
+- Doing a bunch of things in a specific order.
+- Knowing when stuff is done.
+- Handling failures.
+- Breaking up functionality into parts (avoid nested inline callbacks)
+
+
+## Common Mistakes
+
+- Abandoning convention and consistency.
+- Putting all callbacks inline.
+- Using libraries without grokking them.
+- Trying to make async code look sync.
+
+## Define Conventions
+
+- Two kinds of functions: *actors* take action, *callbacks* get results.
+- Essentially the continuation pattern. Resulting code *looks* similar
+ to fibers, but is *much* simpler to implement.
+- Node works this way in the lowlevel APIs already, and it's very flexible.
+
+## Callbacks
+
+- Simple responders
+- Must always be prepared to handle errors, that's why it's the first argument.
+- Often inline anonymous, but not always.
+- Can trap and call other callbacks with modified data, or pass errors upwards.
+
+## Actors
+
+- Last argument is a callback.
+- If any error occurs, and can't be handled, pass it to the callback and return.
+- Must not throw. Return value ignored.
+- return x ==> return cb(null, x)
+- throw er ==> return cb(er)
+
+```javascript
+// return true if a path is either
+// a symlink or a directory.
+function isLinkOrDir (path, cb) {
+ fs.lstat(path, function (er, s) {
+ if (er) return cb(er)
+ return cb(null, s.isDirectory() || s.isSymbolicLink())
+ })
+}
+```
+
+# asyncMap
+
+## Usecases
+
+- I have a list of 10 files, and need to read all of them, and then continue when they're all done.
+- I have a dozen URLs, and need to fetch them all, and then continue when they're all done.
+- I have 4 connected users, and need to send a message to all of them, and then continue when that's done.
+- I have a list of n things, and I need to dosomething with all of them, in parallel, and get the results once they're all complete.
+
+
+## Solution
+
+```javascript
+var asyncMap = require("slide").asyncMap
+function writeFiles (files, what, cb) {
+ asyncMap(files, function (f, cb) {
+ fs.writeFile(f, what, cb)
+ }, cb)
+}
+writeFiles([my, file, list], "foo", cb)
+```
+
+# chain
+
+## Usecases
+
+- I have to do a bunch of things, in order. Get db credentials out of a file,
+ read the data from the db, write that data to another file.
+- If anything fails, do not continue.
+- I still have to provide an array of functions, which is a lot of boilerplate,
+ and a pita if your functions take args like
+
+```javascript
+function (cb) {
+ blah(a, b, c, cb)
+}
+```
+
+- Results are discarded, which is a bit lame.
+- No way to branch.
+
+## Solution
+
+- reduces boilerplate by converting an array of [fn, args] to an actor
+ that takes no arguments (except cb)
+- A bit like Function#bind, but tailored for our use-case.
+- bindActor(obj, "method", a, b, c)
+- bindActor(fn, a, b, c)
+- bindActor(obj, fn, a, b, c)
+- branching, skipping over falsey arguments
+
+```javascript
+chain([
+ doThing && [thing, a, b, c]
+, isFoo && [doFoo, "foo"]
+, subChain && [chain, [one, two]]
+], cb)
+```
+
+- tracking results: results are stored in an optional array passed as argument,
+ last result is always in results[results.length - 1].
+- treat chain.first and chain.last as placeholders for the first/last
+ result up until that point.
+
+
+## Non-trivial example
+
+- Read number files in a directory
+- Add the results together
+- Ping a web service with the result
+- Write the response to a file
+- Delete the number files
+
+```javascript
+var chain = require("slide").chain
+function myProgram (cb) {
+ var res = [], last = chain.last, first = chain.first
+ chain([
+ [fs, "readdir", "the-directory"]
+ , [readFiles, "the-directory", last]
+ , [sum, last]
+ , [ping, "POST", "example.com", 80, "/foo", last]
+ , [fs, "writeFile", "result.txt", last]
+ , [rmFiles, "./the-directory", first]
+ ], res, cb)
+}
+```
+
+# Conclusion: Convention Profits
+
+- Consistent API from top to bottom.
+- Sneak in at any point to inject functionality. Testable, reusable, ...
+- When ruby and python users whine, you can smile condescendingly.
diff --git a/node_modules/slide/index.js b/node_modules/slide/index.js
new file mode 100644
index 000000000..0a9277f6e
--- /dev/null
+++ b/node_modules/slide/index.js
@@ -0,0 +1 @@
+module.exports=require("./lib/slide")
diff --git a/node_modules/slide/lib/async-map-ordered.js b/node_modules/slide/lib/async-map-ordered.js
new file mode 100644
index 000000000..5cca79a82
--- /dev/null
+++ b/node_modules/slide/lib/async-map-ordered.js
@@ -0,0 +1,65 @@
+
+throw new Error("TODO: Not yet implemented.")
+
+/*
+usage:
+
+Like asyncMap, but only can take a single cb, and guarantees
+the order of the results.
+*/
+
+module.exports = asyncMapOrdered
+
+function asyncMapOrdered (list, fn, cb_) {
+ if (typeof cb_ !== "function") throw new Error(
+ "No callback provided to asyncMapOrdered")
+
+ if (typeof fn !== "function") throw new Error(
+ "No map function provided to asyncMapOrdered")
+
+ if (list === undefined || list === null) return cb_(null, [])
+ if (!Array.isArray(list)) list = [list]
+ if (!list.length) return cb_(null, [])
+
+ var errState = null
+ , l = list.length
+ , a = l
+ , res = []
+ , resCount = 0
+ , maxArgLen = 0
+
+ function cb (index) { return function () {
+ if (errState) return
+ var er = arguments[0]
+ var argLen = arguments.length
+ maxArgLen = Math.max(maxArgLen, argLen)
+ res[index] = argLen === 1 ? [er] : Array.apply(null, arguments)
+
+ // see if any new things have been added.
+ if (list.length > l) {
+ var newList = list.slice(l)
+ a += (list.length - l)
+ var oldLen = l
+ l = list.length
+ process.nextTick(function () {
+ newList.forEach(function (ar, i) { fn(ar, cb(i + oldLen)) })
+ })
+ }
+
+ if (er || --a === 0) {
+ errState = er
+ cb_.apply(null, [errState].concat(flip(res, resCount, maxArgLen)))
+ }
+ }}
+ // expect the supplied cb function to be called
+ // "n" times for each thing in the array.
+ list.forEach(function (ar) {
+ steps.forEach(function (fn, i) { fn(ar, cb(i)) })
+ })
+}
+
+function flip (res, resCount, argLen) {
+ var flat = []
+ // res = [[er, x, y], [er, x1, y1], [er, x2, y2, z2]]
+ // return [[x, x1, x2], [y, y1, y2], [undefined, undefined, z2]]
+
diff --git a/node_modules/slide/lib/async-map.js b/node_modules/slide/lib/async-map.js
new file mode 100644
index 000000000..ccf345f3c
--- /dev/null
+++ b/node_modules/slide/lib/async-map.js
@@ -0,0 +1,54 @@
+
+/*
+usage:
+
+// do something to a list of things
+asyncMap(myListOfStuff, function (thing, cb) { doSomething(thing.foo, cb) }, cb)
+// do more than one thing to each item
+asyncMap(list, fooFn, barFn, cb)
+
+*/
+
+module.exports = asyncMap
+
+function asyncMap () {
+ var steps = Array.prototype.slice.call(arguments)
+ , list = steps.shift() || []
+ , cb_ = steps.pop()
+ if (typeof cb_ !== "function") throw new Error(
+ "No callback provided to asyncMap")
+ if (!list) return cb_(null, [])
+ if (!Array.isArray(list)) list = [list]
+ var n = steps.length
+ , data = [] // 2d array
+ , errState = null
+ , l = list.length
+ , a = l * n
+ if (!a) return cb_(null, [])
+ function cb (er) {
+ if (er && !errState) errState = er
+
+ var argLen = arguments.length
+ for (var i = 1; i < argLen; i ++) if (arguments[i] !== undefined) {
+ data[i - 1] = (data[i - 1] || []).concat(arguments[i])
+ }
+ // see if any new things have been added.
+ if (list.length > l) {
+ var newList = list.slice(l)
+ a += (list.length - l) * n
+ l = list.length
+ process.nextTick(function () {
+ newList.forEach(function (ar) {
+ steps.forEach(function (fn) { fn(ar, cb) })
+ })
+ })
+ }
+
+ if (--a === 0) cb_.apply(null, [errState].concat(data))
+ }
+ // expect the supplied cb function to be called
+ // "n" times for each thing in the array.
+ list.forEach(function (ar) {
+ steps.forEach(function (fn) { fn(ar, cb) })
+ })
+}
diff --git a/node_modules/slide/lib/bind-actor.js b/node_modules/slide/lib/bind-actor.js
new file mode 100644
index 000000000..6a3707274
--- /dev/null
+++ b/node_modules/slide/lib/bind-actor.js
@@ -0,0 +1,16 @@
+module.exports = bindActor
+function bindActor () {
+ var args =
+ Array.prototype.slice.call
+ (arguments) // jswtf.
+ , obj = null
+ , fn
+ if (typeof args[0] === "object") {
+ obj = args.shift()
+ fn = args.shift()
+ if (typeof fn === "string")
+ fn = obj[ fn ]
+ } else fn = args.shift()
+ return function (cb) {
+ fn.apply(obj, args.concat(cb)) }
+}
diff --git a/node_modules/slide/lib/chain.js b/node_modules/slide/lib/chain.js
new file mode 100644
index 000000000..17b371149
--- /dev/null
+++ b/node_modules/slide/lib/chain.js
@@ -0,0 +1,20 @@
+module.exports = chain
+var bindActor = require("./bind-actor.js")
+chain.first = {} ; chain.last = {}
+function chain (things, cb) {
+ var res = []
+ ;(function LOOP (i, len) {
+ if (i >= len) return cb(null,res)
+ if (Array.isArray(things[i]))
+ things[i] = bindActor.apply(null,
+ things[i].map(function(i){
+ return (i===chain.first) ? res[0]
+ : (i===chain.last)
+ ? res[res.length - 1] : i }))
+ if (!things[i]) return LOOP(i + 1, len)
+ things[i](function (er, data) {
+ if (er) return cb(er, res)
+ if (data !== undefined) res = res.concat(data)
+ LOOP(i + 1, len)
+ })
+ })(0, things.length) }
diff --git a/node_modules/slide/lib/slide.js b/node_modules/slide/lib/slide.js
new file mode 100644
index 000000000..6e9ec2327
--- /dev/null
+++ b/node_modules/slide/lib/slide.js
@@ -0,0 +1,3 @@
+exports.asyncMap = require("./async-map")
+exports.bindActor = require("./bind-actor")
+exports.chain = require("./chain")
diff --git a/node_modules/slide/package.json b/node_modules/slide/package.json
new file mode 100644
index 000000000..779918479
--- /dev/null
+++ b/node_modules/slide/package.json
@@ -0,0 +1,20 @@
+{
+ "name": "slide",
+ "version": "1.1.6",
+ "author": "Isaac Z. Schlueter <i@izs.me> (http://blog.izs.me/)",
+ "contributors": [
+ "S. Sriram <ssriram@gmail.com> (http://www.565labs.com)"
+ ],
+ "description": "A flow control lib small enough to fit on in a slide presentation. Derived live at Oak.JS",
+ "main": "./lib/slide.js",
+ "dependencies": {},
+ "devDependencies": {},
+ "engines": {
+ "node": "*"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/isaacs/slide-flow-control.git"
+ },
+ "license": "ISC"
+}