diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-05-28 00:38:50 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-05-28 00:40:43 +0200 |
commit | 7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027 (patch) | |
tree | 6de9a1aebd150a23b7f8c273ec657a5d0a18fe3e /node_modules/release-zalgo | |
parent | 963b7a41feb29cc4be090a2446bdfe0c1f1bcd81 (diff) | |
download | wallet-core-7fff4499fd915bcea3fa93b1aa8b35f4fe7a6027.tar.xz |
add linting (and some initial fixes)
Diffstat (limited to 'node_modules/release-zalgo')
-rw-r--r-- | node_modules/release-zalgo/LICENSE | 14 | ||||
-rw-r--r-- | node_modules/release-zalgo/README.md | 194 | ||||
-rw-r--r-- | node_modules/release-zalgo/index.js | 9 | ||||
-rw-r--r-- | node_modules/release-zalgo/lib/Async.js | 21 | ||||
-rw-r--r-- | node_modules/release-zalgo/lib/Sync.js | 24 | ||||
-rw-r--r-- | node_modules/release-zalgo/lib/Thenable.js | 39 | ||||
-rw-r--r-- | node_modules/release-zalgo/lib/constants.js | 6 | ||||
-rw-r--r-- | node_modules/release-zalgo/lib/unwrapSync.js | 54 | ||||
-rw-r--r-- | node_modules/release-zalgo/package.json | 49 |
9 files changed, 410 insertions, 0 deletions
diff --git a/node_modules/release-zalgo/LICENSE b/node_modules/release-zalgo/LICENSE new file mode 100644 index 000000000..a192d7dbf --- /dev/null +++ b/node_modules/release-zalgo/LICENSE @@ -0,0 +1,14 @@ +ISC License (ISC) +Copyright (c) 2017, Mark Wubben <mark@novemberborn.net> (novemberborn.net) + +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/release-zalgo/README.md b/node_modules/release-zalgo/README.md new file mode 100644 index 000000000..9f84fe3ab --- /dev/null +++ b/node_modules/release-zalgo/README.md @@ -0,0 +1,194 @@ +# release-zalgo + +Helps you write code with promise-like chains that can run both synchronously +and asynchronously. + +## Installation + +```console +$ npm install --save release-zalgo +``` + +## Usage + +If you use this module, you'll release **Ẕ̶̨̫̹̌͊͌͑͊̕͢͟a̡̜̦̝͓͇͗̉̆̂͋̏͗̍ͅl̡̛̝͍̅͆̎̊̇̕͜͢ģ̧̧͍͓̜̲͖̹̂͋̆̃̑͗̋͌̊̏ͅǫ̷̧͓̣͚̞̣̋̂̑̊̂̀̿̀̚͟͠ͅ**. You mustn't do that. + +Before you proceed, please read this great post by [Isaac +Schlueter](http://izs.me/) on [Designing APIs for +Asynchrony](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony). + +The first rule of using this package is to keep your external API consistent. + +The second rule is to accept the burden of controlling Ẕ̶̨̫̹̌͊͌͑͊̕͢͟a̡̜̦̝͓͇͗̉̆̂͋̏͗̍ͅl̡̛̝͍̅͆̎̊̇̕͜͢ģ̧̧͍͓̜̲͖̹̂͋̆̃̑͗̋͌̊̏ͅǫ̷̧͓̣͚̞̣̋̂̑̊̂̀̿̀̚͟͠ͅ by ensuring he does not escape your API boundary. + +With that out of the way… this package lets you write code that can run both +synchronously and asynchronously. This is useful if you have fairly complex +logic for which you don't want to write multiple implementations. See +[`package-hash`](https://github.com/novemberborn/package-hash) for instance. + +This is best shown by example. Let's say you have a `hashFile()` function: + +```js +const crypto = require('crypto') +const fs = require('fs') + +function hashFile (file) { + return new Promise((resolve, reject) => { + fs.readFile(file, (err, buffer) => err ? reject(err) : resolve(buffer)) + }) + .then(buffer => { + const hash = crypto.createHash('sha1') + hash.update(buffer) + return hash.digest('hex') + }) +} +``` + +A synchronous version could be implemented like this: + +```js +function hashFileSync (file) { + const buffer = fs.readFileSync(file) + const hash = crypto.createHash('sha1') + hash.update(buffer) + return hash.digest('hex') +} +``` + +Here's the version that uses `release-zalgo`: + +```js +const crypto = require('crypto') +const fs = require('fs') + +const releaseZalgo = require('release-zalgo') + +const readFile = { + async (file) { + return new Promise((resolve, reject) => { + fs.readFile(file, (err, buffer) => err ? reject(err) : resolve(buffer)) + }) + }, + + sync (file) { + return fs.readFileSync(file) + } +} + +function run (zalgo, file) { + return zalgo.run(readFile, file) + .then(buffer => { + const hash = crypto.createHash('sha1') + hash.update(buffer) + return hash.digest('hex') + }) +} + +function hashFile (file) { + return run(releaseZalgo.async(), file) +} + +function hashFileSync (file) { + const result = run(releaseZalgo.sync(), file) + return releaseZalgo.unwrapSync(result) +} +``` + +Note how close the `run()` implementation is to the original `hashFile()`. + +Just don't do this: + +```js +function badExample (zalgo, file) { + let buffer + zalgo.run(readFile, file) + .then(result => { buffer = result }) + + const hash = crypto.createHash('sha1') + hash.update(buffer) + return hash.digest('hex') +} +``` + +This won't work asynchronously. Just pretend you're working with promises and +you'll be OK. + +## API + +First require the package: + +```js +const releaseZalgo = require('release-zalgo') +``` + +### `releaseZalgo.sync()` + +Returns a `zalgo` object that runs code synchronously: + +```js +const zalgo = releaseZalgo.sync() +``` + +### `releaseZalgo.async()` + +Returns a `zalgo` object that runs code asynchronously: + +```js +const zalgo = releaseZalgo.async() +``` + +### `releaseZalgo.unwrapSync(thenable)` + +Synchronously unwraps a [thenable], which is returned when running +synchronously. Returns the [thenable]s fulfilment value, or throws its +rejection reason. Throws if the [thenable] is asynchronous. + +### `zalgo.run(executors, ...args)` + +When running synchronously, `executors.sync()` is called. When running +asynchronously `executors.async()` is used. The executer is invoked immediately +and passed the remaining arguments. + +For asynchronous execution a `Promise` is returned. It is fulfilled with +`executors.async()`'s return value, or rejected if `executors.async()` throws. + +For synchronous execution a *[thenable]* is returned. It has the same methods as +`Promise` except that callbacks are invoked immediately. The [thenable] is +fulfilled with `executors.sync()`'s return value, or rejected if +`executors.sync()` throws. + +### `zalgo.all(arr)` + +When running synchronously, returns a new [thenable] which is fulfilled with +an array, after unwrapping all items in `arr`. + +When running asynchronously, delegates to `Promise.all(arr)`. + +### `zalgo.returns(value)` + +When running synchronously, returns a new [thenable] which is fulfilled with +`value`. + +When running asynchronously, delegates to `Promise.resolve(value)`. + +### `zalgo.throws(reason)` + +When running synchronously, returns a new [thenable] which is rejected with +`reason`. + +When running asynchronously, delegates to `Promise.reject(reason)`. + +### Thenables + +Thenables are returned when running sychronously. They're much like `Promise`s, +in that they have `then()` and `catch()` methods. You can pass callbacks and +they'll be invoked with the fulfilment value or rejection reason. Callbacks +can return other thenables or throw exceptions. + +Note that `then()` and `catch()` must be called on the thenable, e.g. +`thenable.then()`, not `(thenable.then)()`. + +Thenables should not be exposed outside of your API. Use +`releaseZalgo.unwrapSync()` to unwrap them. + +[thenable]: #thenables diff --git a/node_modules/release-zalgo/index.js b/node_modules/release-zalgo/index.js new file mode 100644 index 000000000..151cb0d96 --- /dev/null +++ b/node_modules/release-zalgo/index.js @@ -0,0 +1,9 @@ +'use strict' + +const Async = require('./lib/Async') +const Sync = require('./lib/Sync') +const unwrapSync = require('./lib/unwrapSync') + +exports.sync = () => new Sync() +exports.async = () => new Async() +exports.unwrapSync = unwrapSync diff --git a/node_modules/release-zalgo/lib/Async.js b/node_modules/release-zalgo/lib/Async.js new file mode 100644 index 000000000..846f7add0 --- /dev/null +++ b/node_modules/release-zalgo/lib/Async.js @@ -0,0 +1,21 @@ +'use strict' + +class Async { + run (executors) { + const args = Array.from(arguments).slice(1) + return new Promise(resolve => resolve(executors.async.apply(null, args))) + } + + all (arr) { + return Promise.all(arr) + } + + returns (value) { + return Promise.resolve(value) + } + + throws (reason) { + return Promise.reject(reason) + } +} +module.exports = Async diff --git a/node_modules/release-zalgo/lib/Sync.js b/node_modules/release-zalgo/lib/Sync.js new file mode 100644 index 000000000..d081d5f59 --- /dev/null +++ b/node_modules/release-zalgo/lib/Sync.js @@ -0,0 +1,24 @@ +'use strict' + +const Thenable = require('./Thenable') +const unwrapSync = require('./unwrapSync') + +class Sync { + run (executors) { + const args = Array.from(arguments).slice(1) + return new Thenable(() => executors.sync.apply(null, args)) + } + + all (arr) { + return new Thenable(() => arr.map(value => unwrapSync(value))) + } + + returns (value) { + return new Thenable(() => value) + } + + throws (reason) { + return new Thenable(() => { throw reason }) + } +} +module.exports = Sync diff --git a/node_modules/release-zalgo/lib/Thenable.js b/node_modules/release-zalgo/lib/Thenable.js new file mode 100644 index 000000000..7a809b266 --- /dev/null +++ b/node_modules/release-zalgo/lib/Thenable.js @@ -0,0 +1,39 @@ +'use strict' + +const constants = require('./constants') +const unwrapSync = require('./unwrapSync') + +// Behaves like a Promise, though the then() and catch() methods are unbound and +// must be called with the instance as their thisArg. +// +// The executor must either return a value or throw a rejection reason. It is +// not provided resolver or rejecter methods. The executor may return another +// thenable. +class Thenable { + constructor (executor) { + try { + this.result = unwrapSync(executor()) + this.state = constants.RESOLVED + } catch (err) { + this.result = err + this.state = constants.REJECTED + } + } + + then (onFulfilled, onRejected) { + if (this.state === constants.RESOLVED && typeof onFulfilled === 'function') { + return new Thenable(() => onFulfilled(this.result)) + } + + if (this.state === constants.REJECTED && typeof onRejected === 'function') { + return new Thenable(() => onRejected(this.result)) + } + + return this + } + + catch (onRejected) { + return this.then(null, onRejected) + } +} +module.exports = Thenable diff --git a/node_modules/release-zalgo/lib/constants.js b/node_modules/release-zalgo/lib/constants.js new file mode 100644 index 000000000..8c417b5fa --- /dev/null +++ b/node_modules/release-zalgo/lib/constants.js @@ -0,0 +1,6 @@ +'use strict' + +exports.PENDING = Symbol('PENDING') +exports.RESOLVED = Symbol('RESOLVED') +exports.REJECTED = Symbol('REJECTED') +exports.ASYNC = Symbol('ASYNC') diff --git a/node_modules/release-zalgo/lib/unwrapSync.js b/node_modules/release-zalgo/lib/unwrapSync.js new file mode 100644 index 000000000..baa130b18 --- /dev/null +++ b/node_modules/release-zalgo/lib/unwrapSync.js @@ -0,0 +1,54 @@ +'use strict' + +const ExtendableError = require('es6-error') + +const constants = require('./constants') + +class UnwrapError extends ExtendableError { + constructor (thenable) { + super('Could not unwrap asynchronous thenable') + this.thenable = thenable + } +} + +// Logic is derived from the Promise Resolution Procedure, as described in the +// Promises/A+ specification: https://promisesaplus.com/#point-45 +// +// Note that there is no cycle detection. +function unwrapSync (x) { + if (!x || typeof x !== 'object' && typeof x !== 'function') { + return x + } + + const then = x.then + if (typeof then !== 'function') return x + + let state = constants.PENDING + let value + const unwrapValue = y => { + if (state === constants.PENDING) { + state = constants.RESOLVED + value = y + } + } + const unwrapReason = r => { + if (state === constants.PENDING) { + state = constants.REJECTED + value = r + } + } + then.call(x, unwrapValue, unwrapReason) + + if (state === constants.PENDING) { + state = constants.ASYNC + throw new UnwrapError(x) + } + + if (state === constants.RESOLVED) { + return unwrapSync(value) + } + + // state === REJECTED + throw value +} +module.exports = unwrapSync diff --git a/node_modules/release-zalgo/package.json b/node_modules/release-zalgo/package.json new file mode 100644 index 000000000..bb651a4a0 --- /dev/null +++ b/node_modules/release-zalgo/package.json @@ -0,0 +1,49 @@ +{ + "name": "release-zalgo", + "version": "1.0.0", + "description": "Helps you write code with promise-like chains that can run both synchronously and asynchronously", + "main": "index.js", + "files": [ + "index.js", + "lib" + ], + "engines": { + "node": ">=4" + }, + "scripts": { + "lint": "as-i-preach", + "test": "ava", + "posttest": "as-i-preach", + "coverage": "nyc npm test" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/novemberborn/release-zalgo.git" + }, + "keywords": [ + "babel" + ], + "author": "Mark Wubben (https://novemberborn.net/)", + "license": "ISC", + "bugs": { + "url": "https://github.com/novemberborn/release-zalgo/issues" + }, + "homepage": "https://github.com/novemberborn/release-zalgo#readme", + "dependencies": { + "es6-error": "^4.0.1" + }, + "devDependencies": { + "@novemberborn/as-i-preach": "^7.0.0", + "ava": "^0.18.0", + "coveralls": "^2.11.15", + "nyc": "^10.1.2" + }, + "nyc": { + "reporter": [ + "html", + "lcov", + "text" + ] + }, + "standard-engine": "@novemberborn/as-i-preach" +} |