Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Functional, composable, immutable and curried promise sequences that automatically handle Promise resolution.
Functional, composable, immutable and curried promise sequences that automatically handle Promise resolution. Inspired by the function of the same name in Ramda.
pipeP has no dependencies and is exported as a UMD module, so it should be consumable anywhere. However, it does rely on access to ES2015 native Promise
and Object.assign
. Since these are standard, your environment needs to support them. By default, pipeP does not ship with any fallbacks in order to keep the code size manageable. If you're already using an ES2015 environment, you have nothing to worry about. Otherwise, see CoreJS.
$ npm i pipep -S
Then your code:
var pipeP = require('pipep')
// if using ES2015: `import pipeP from 'pipep'`
You can grab the latest release from npm CDN (See this for instructions on how to specify a specific version):
<script src="//npmcdn.com/pipep"></script>
<script src="//npmcdn.com/pipep/pipep.min.js"></script>
pipeP can do some pretty cool things:
.then()
in a promise pipelineThis abstraction gives you the ability to process variable-length promise chains and also enables chains to be point-free:
// pipeline - use of composed "fetch" is point-free
const getJSON = pipeP(fetch, handleError, grabJSON)
getJSON('http://randomuser.me/api')
.then(console.log.bind(console))
.catch((err) => console.error(err))
function handleError (response) {
if (!response.ok) {
throw new Error(response.status + ' ' + response.statusText)
}
return response
}
function grabJSON (response) {
return response.json()
}
pipeP abstracts all type resolution for you:
const process = pipeP((x) => [x, 5], ([x, y]) => [x, y, Promise.resolve(15)])
process(Promise.resolve(10)).then(console.log.bind(console)) // logs '[10, 5, 15]'
All handlers passed to pipeP operate on and receive a single value (this is how promises work), but you can reduce a single value from many arguments in the first handler:
const addAndSquare = pipeP(
(a, b) => a + b,
(n) => n * n
)
addAndSquare(2, 3).then(console.log.bind(console)) // logs '25'
pipeP makes a best effort to not mutate your data:
const obj = { foo: 'bar' }
const process = pipeP(
(x) => {
x.foo = x.foo.toUpperCase()
x.bar = 'baz'
}
)
process(obj).then((x) => {
console.log(x) // logs '{ foo: 'BAR', bar: 'baz' }'
console.log(obj) // logs '{ foo: 'bar' }'
})
pipeP automatically curries the returned function to the arity of the first handler:
const add = pipeP((a, b) => a + b)
const increment = add(1)
increment(5).then(console.log.bind(console)) // logs '6'
Functions returned from pipeP are just functions, so they can also be used as handlers in a pipeP sequence. They also support currying:
const add = pipeP((a, b) => a + b)
const square = pipeP((n) => n * n)
const addAndSquare = pipeP(add, square)
addAndSquare(5, 2).then(console.log.bind(console)) // logs '25'
addAndSquare(1)(3).then(console.log.bind(console)) // logs '9'
If you already have an array of functions, pipeP will accept it as input anywhere in the argument list, and will still support currying:
const mathbomb = pipeP(
[(a, b) => a + b, (n) => n * n],
(n) => n / 2,
[(n) => n - 1, (n) => n + 5]
)
mathbomb(1, 2).then(console.log.bind(console)) // logs '8.5'
mathbomb(2)(3).then(console.log.bind(console)) // logs '16.5
You can share context between pipeP handlers by passing an array of arguments to the next handler. Behind the scenes, pipeP will use Promise.all
to resolve the arguments. Here is a recursive call to the Github API that serves as a good example:
const GET = pipeP(fetch, (res) => {
if (!res.ok) {
throw new Error(`${response.status} ${response.statusText}`)
}
return res
})
const constructCommitAPICall = (repo, page) => {
return `https://api.github.com/repos/${repo}/commits?page=${page}&per_page=100`
}
const getCommits = pipeP(
// if only received 1 arg, set some defaults
(...args) => args.length > 1 ? args : [...args, [], 1],
// get page `page` of the commits for the passed `repo` & martial down arguments
([repo, _, page]) => [...arguments, GET(constructCommitAPICall(repo, page))],
// martial down the commits
([repo, pages, page, commits]) => {
// append the commits for page `page` in the `pages` array
pages.push(commits.json())
// inspect response headers for current page
for (const curr of Array.values(commits.headers.get('Link').split(', '))) {
// if there is a link for the next page, grab the commits from it
if (/rel="next"/.test(curr)) {
return getCommits(repo, pages, page + 1)
}
}
return pages
},
// flatten the pages into a single list of commits
(pages) => pages.reduce((a, b) => a.concat(b), [])
)
Accepts any number of arguments. Each argument can either be a unary function or an array containing unary functions.
"Unary" means that they can only accept one argument and return one argument.
The first function passed to pipeP (whether in an array or not) can accept as many arguments as you want it to, as long as it returns a single value.
These functions may accept and/or return values or promises for values. Conversion between arrays, promises and values is abstracted for you.
Returns a function that is curried to the same number of arguments as the first function passed to pipeP. When this function receives all expected arguments, it will return a promise for the single computed value of its input after being piped through each function passed to pipeP.
Please read the Contribution Guidelines.
MIT. See LICENSE.
FAQs
Functional, composable, immutable and curried promise sequences that automatically handle Promise resolution.
The npm package pipep receives a total of 1 weekly downloads. As such, pipep popularity was classified as not popular.
We found that pipep demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.