$
This commit is contained in:
14
node_modules/release-zalgo/LICENSE
generated
vendored
Normal file
14
node_modules/release-zalgo/LICENSE
generated
vendored
Normal file
@@ -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.
|
194
node_modules/release-zalgo/README.md
generated
vendored
Normal file
194
node_modules/release-zalgo/README.md
generated
vendored
Normal file
@@ -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
|
9
node_modules/release-zalgo/index.js
generated
vendored
Normal file
9
node_modules/release-zalgo/index.js
generated
vendored
Normal file
@@ -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
|
21
node_modules/release-zalgo/lib/Async.js
generated
vendored
Normal file
21
node_modules/release-zalgo/lib/Async.js
generated
vendored
Normal file
@@ -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
|
24
node_modules/release-zalgo/lib/Sync.js
generated
vendored
Normal file
24
node_modules/release-zalgo/lib/Sync.js
generated
vendored
Normal file
@@ -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
|
39
node_modules/release-zalgo/lib/Thenable.js
generated
vendored
Normal file
39
node_modules/release-zalgo/lib/Thenable.js
generated
vendored
Normal file
@@ -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
|
6
node_modules/release-zalgo/lib/constants.js
generated
vendored
Normal file
6
node_modules/release-zalgo/lib/constants.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
exports.PENDING = Symbol('PENDING')
|
||||
exports.RESOLVED = Symbol('RESOLVED')
|
||||
exports.REJECTED = Symbol('REJECTED')
|
||||
exports.ASYNC = Symbol('ASYNC')
|
54
node_modules/release-zalgo/lib/unwrapSync.js
generated
vendored
Normal file
54
node_modules/release-zalgo/lib/unwrapSync.js
generated
vendored
Normal file
@@ -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
|
49
node_modules/release-zalgo/package.json
generated
vendored
Normal file
49
node_modules/release-zalgo/package.json
generated
vendored
Normal file
@@ -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"
|
||||
}
|
Reference in New Issue
Block a user