Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

pipep

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pipep - npm Package Compare versions

Comparing version 0.0.2 to 0.1.0

10

package.json
{
"name": "pipep",
"description": "Functional, composable, immutable and curried promise sequences that automatically handle Promise resolution.",
"version": "0.0.2",
"version": "0.1.0",
"author": "Declan de Wet <declandewet@me.com>",

@@ -14,2 +14,3 @@ "ava": {

"ava": "^0.15.2",
"babel-eslint": "^6.1.0",
"codecov": "^1.0.1",

@@ -19,2 +20,3 @@ "cross-env": "^1.0.8",

"nyc": "^6.6.1",
"standard": "^7.1.2",
"uglify-js": "^2.6.4",

@@ -47,3 +49,3 @@ "umd": "^3.0.1"

"include": [
"src/*.js"
"index.js"
],

@@ -61,4 +63,4 @@ "reporter": [

"build": "concurrently \"npm run build-umd\" \"npm run build-umd-min\"",
"build-umd": "cat src/index.js | umd pipe-p -c > pipep.js",
"build-umd-min": "cat src/index.js | umd pipe-p -c | uglifyjs -c -m > pipep.min.js",
"build-umd": "cat index.js | umd pipe-p -c > pipep.js",
"build-umd-min": "cat index.js | umd pipe-p -c | uglifyjs -c -m > pipep.min.js",
"codecov": "npm run coverage && codecov",

@@ -65,0 +67,0 @@ "coverage": "cross-env NODE_ENV=test nyc report",

206

pipep.js
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.pipeP = f()}})(function(){var define,module,exports;module={exports:(exports={})};
'use strict'
module.exports = pipeP
// enable point-free capabilities
var call = curry(_call)
var replace = curry(_replace)
var resolvePromises = curry(_resolvePromises)
var _slice = [].slice
/**

@@ -22,74 +23,64 @@ * returns a variadic function that pipes its arguments through a promise chain

*/
function pipeP () {
module.exports = function pipeP () {
// throw error if environment has no Promise support
if (Promise == null) {
throw new Error('[pipeP] Use a `Promise` polyfill for environments that do not support native ES2015 Promises.')
if (!exists(Promise)) {
throw new Error(s('Use a `Promise` polyfill for environments that do not support native ES2015 Promises.'))
}
// throw error if environment has no Object.assign support
if (!_is(Function, Object.assign)) {
throw new Error('[pipeP] Use an `Object.assign` polyfill for environments that do not support native ES2015 Object properties.')
if (!is(Function, Object.assign)) {
throw new Error(s('Use an `Object.assign` polyfill for environments that do not support native ES2015 Object properties.'))
}
// flatten arguments in case they contain arrays
var rest = _slice.apply(arguments).reduce(function concat (prev, next) {
return prev.concat(next)
}, [])
var remainingHandlers = flatten(arrayFrom(arguments))
// grab the initial handler from args
var initial = rest.shift()
var initialHandler = remainingHandlers.shift()
// throw if first handler is missing
if (!initial) {
throw new SyntaxError('[pipeP] expects at least one argument')
if (!exists(initialHandler)) {
throw new SyntaxError(s('expects at least one argument'))
}
// throw if first handler has incorrect type
if (!_is(Function, initial)) {
throw new SyntaxError('[pipeP] first handler must be a variadic function that returns a promise or value')
if (!is(Function, initialHandler)) {
throw new SyntaxError(s('first handler must be a variadic function that returns a promise or value'))
}
// create curried executor function that accepts n paramaters and evaluates all functions as a dynamic promise chain
var _executor = _curryN(initial.length, function _executor () {
var values = _slice.apply(arguments)
// store arity of initial handler for future reference
var initialArity = length(initialHandler)
// prevent mutations
var clonedValues = values.map(function clone (val) {
if (_is(Function, val.then)) { // if val is a promise, just return it
return val
} else if (_is(Array, val)) {
return Promise.all([].concat(val)) // wait for resolution of arrays containing promises
} else if (_is(Object, val)) {
return Object.assign({}, val)
}
return val
})
// create curried sequencer function that accepts n paramaters and evaluates all functions as a dynamic promise chain
var callSequence = curryN(initialArity, function executor () {
// duplicate values & resolve all individual promises
var resolvedValues = arrayFrom(arguments).map(resolvePromises({ duplicate: true }))
// compute initial values
var computedValues = Promise.all(clonedValues).then(function initialize (args) {
return initial.apply(null, args)
})
var initialComputation = Promise.all(resolvedValues).then(call(initialHandler))
// pipe all handlers through promise chain
var promise = rest.reduce(function sequence (prev, next, i) {
if (_is(Function, next)) {
return prev.then(resolveArrayValue).then(next)
}
var promiseForFinalComputation = remainingHandlers.reduce(function sequence (prev, next, i) {
return is(Function, next)
// resolve individual promises before calling next handler
? prev.then(resolvePromises(null)).then(next)
// if next handler is not a function, reject the promise
: Promise.reject(new SyntaxError(s("expected handler '%d' to have type 'function', got '%s': '%s'", i + 2, typeof next, next)))
}, initialComputation)
// if next handler is not a function, reject the promise
return Promise.reject(new SyntaxError("[pipeP] expected handler '" + (i + 2) + "' to have type 'function', got '" + typeof next + "': '" + next + "'"))
}, computedValues)
// return resolved promise in case of arrays
return promise.then(resolveArrayValue)
// resolve individual promises in final computation
return promiseForFinalComputation.then(resolvePromises(null))
})
// ensure returned executor reports correct arity
Object.defineProperty(_executor, 'length', {
get: function get () {
return initial.length
}
})
try {
// ensure sequencer reports correct arity so currying works when callSequence is the first handler in a sequence
Object.defineProperty(callSequence, 'length', {
get: function get () {
return initialArity
}
})
} catch (error) {} // supress errors on Object.defineProperty in case of IE8
return _executor
// return the promise-sequence-calling curried function
return callSequence
}

@@ -99,10 +90,66 @@

* Calls Promise.all on passed value if it is an array
* Duplicates value if required.
* @param {Object} opts - options
* @param {*} val - value to resolve
* @return {*} - if val is an array, a promise for all resolved elements, else the original value
*/
function resolveArrayValue (val) {
return _is(Array, val) ? Promise.all(val) : val
function _resolvePromises (opts, val) {
opts = opts || {}
var duplicate = opts.duplicate
if (is(Array, val)) {
return Promise.all(duplicate ? concat([], val) : val)
} else if (duplicate && is(Object, val) && !is(Function, val.then)) {
return Object.assign({}, val)
}
return val
}
/**
* Flattens an array of arrays and values into an array of values
* @param {Array} list - the array to flatten
* @return {Array} - flattened result
*/
function flatten (list) {
return list.reduce(concat, [])
}
/**
* Converts an array-like object into an array
* @param {Object} args - an array-like object
* @return {Array} - array representation
*/
function arrayFrom (args) {
return [].slice.apply(args)
}
/**
* Returns the length property of passed value
* @param {*} val - Object to access length on
* @return {Number} - Object's length value
*/
function length (val) {
return val.length
}
/**
* Calls a function with supplied arguments
* @param {Function} fn - function to call
* @param {Array} args - array of arguments to supply
* @return {*} - return value of function `fn` called with `args`
*/
function _call (fn, args) {
return fn.apply(null, args)
}
/**
* Concatenates "b" onto "a"
* @param {String|Array} a - the value in which to concat
* @param {*} b - value to concat onto "a"
* @return {String|Array} - the new value containing "a" & "b" merged
*/
function concat (a, b) {
return a.concat(b)
}
/**
* Checks that the type of value provided as second argument is the same as the constructor provided as first argument

@@ -113,7 +160,25 @@ * @param {Function} Ctor - Constructor function / class of the type to check on `val`

*/
function _is (Ctor, val) {
return val != null && val.constructor === Ctor || val instanceof Ctor
function is (Ctor, val) {
return exists(val) && val.constructor === Ctor || val instanceof Ctor
}
/**
* Checks if val is not null or undefined.
* @param {*} val - value to check
* @return {Boolean} - true if val exists
*/
function exists (val) {
return val != null
}
/**
* Takes a function and curries it to it's own arity
* @param {Function} fn - function to curry
* @return {Function} - curried function
*/
function curry (fn) {
return _curry(length(fn), fn)
}
/**
* Takes an arity and a function and returns a new function curried to arity

@@ -124,3 +189,3 @@ * @param {Number} n - arity

*/
function _curryN (n, fn) {
function curryN (n, fn) {
return _curry(n, fn)

@@ -139,10 +204,33 @@ }

return function partial () {
var rest = _slice.apply(arguments)
var allArgs = args.concat(rest)
return n > allArgs.length
var rest = arrayFrom(arguments)
var allArgs = concat(args, rest)
return n > length(allArgs)
? _curry(n, fn, allArgs)
: fn.apply(null, allArgs.slice(0, n))
: _call(fn, allArgs.slice(0, n))
}
}
/**
* Replaces `pattern` found in `str` with `val`
* @param {Regex|String} pattern - the pattern to replace
* @param {*} val - the value that will replace pattern
* @param {String} str - the string which is being manipulated
* @return {String} - the new string
*/
function _replace (pattern, str, val) {
return str.replace(pattern, val)
}
/**
* Generic error message utility. Takes a formatted string
* and returns that string with a `[pipep]` label.
* Behaves in similar fashion to `sprintf`
* @return {String} - the new message
*/
function s () {
var args = arrayFrom(arguments)
var msg = args.shift()
return args.reduce(replace(/(?:%s|%d)/), '[pipeP] ' + msg)
}
return module.exports;});

@@ -1,1 +0,1 @@

!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var n;n="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,n.pipeP=e()}}(function(){function e(){if(null==Promise)throw new Error("[pipeP] Use a `Promise` polyfill for environments that do not support native ES2015 Promises.");if(!t(Function,Object.assign))throw new Error("[pipeP] Use an `Object.assign` polyfill for environments that do not support native ES2015 Object properties.");var e=a.apply(arguments).reduce(function(e,n){return e.concat(n)},[]),o=e.shift();if(!o)throw new SyntaxError("[pipeP] expects at least one argument");if(!t(Function,o))throw new SyntaxError("[pipeP] first handler must be a variadic function that returns a promise or value");var i=r(o.length,function(){var r=a.apply(arguments),i=r.map(function(e){return t(Function,e.then)?e:t(Array,e)?Promise.all([].concat(e)):t(Object,e)?Object.assign({},e):e}),u=Promise.all(i).then(function(e){return o.apply(null,e)}),p=e.reduce(function(e,r,o){return t(Function,r)?e.then(n).then(r):Promise.reject(new SyntaxError("[pipeP] expected handler '"+(o+2)+"' to have type 'function', got '"+typeof r+"': '"+r+"'"))},u);return p.then(n)});return Object.defineProperty(i,"length",{get:function(){return o.length}}),i}function n(e){return t(Array,e)?Promise.all(e):e}function t(e,n){return null!=n&&n.constructor===e||n instanceof e}function r(e,n){return o(e,n)}function o(e,n,t){return t=t||[],function(){var r=a.apply(arguments),i=t.concat(r);return e>i.length?o(e,n,i):n.apply(null,i.slice(0,e))}}var i,u;i={exports:u={}},i.exports=e;var a=[].slice;return i.exports});
!function(n){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define([],n);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.pipeP=n()}}(function(){function n(n,e){n=n||{};var t=n.duplicate;return u(Array,e)?Promise.all(t?i([],e):e):t&&u(Object,e)&&!u(Function,e.then)?Object.assign({},e):e}function e(n){return n.reduce(i,[])}function t(n){return[].slice.apply(n)}function r(n){return n.length}function o(n,e){return n.apply(null,e)}function i(n,e){return n.concat(e)}function u(n,e){return f(e)&&e.constructor===n||e instanceof n}function f(n){return null!=n}function c(n){return s(r(n),n)}function a(n,e){return s(n,e)}function s(n,e,u){return u=u||[],function(){var f=t(arguments),c=i(u,f);return n>r(c)?s(n,e,c):o(e,c.slice(0,n))}}function l(n,e,t){return e.replace(n,t)}function p(){var n=t(arguments),e=n.shift();return n.reduce(v(/(?:%s|%d)/),"[pipeP] "+e)}var d,h;d={exports:h={}};var y=c(o),v=c(l),m=c(n);return d.exports=function(){if(!f(Promise))throw new Error(p("Use a `Promise` polyfill for environments that do not support native ES2015 Promises."));if(!u(Function,Object.assign))throw new Error(p("Use an `Object.assign` polyfill for environments that do not support native ES2015 Object properties."));var n=e(t(arguments)),o=n.shift();if(!f(o))throw new SyntaxError(p("expects at least one argument"));if(!u(Function,o))throw new SyntaxError(p("first handler must be a variadic function that returns a promise or value"));var i=r(o),c=a(i,function(){var e=t(arguments).map(m({duplicate:!0})),r=Promise.all(e).then(y(o)),i=n.reduce(function(n,e,t){return u(Function,e)?n.then(m(null)).then(e):Promise.reject(new SyntaxError(p("expected handler '%d' to have type 'function', got '%s': '%s'",t+2,typeof e,e)))},r);return i.then(m(null))});try{Object.defineProperty(c,"length",{get:function(){return i}})}catch(s){}return c},d.exports});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc