effepi
Fun functional programming with pipelinable functions.
What is effepi?
Effepi is a functional way to enqueue and use different functions. You can put your functions in a pipeline and resolve them both asynchronously or synchronously, creating new async functions or sync functions.
Install
Npm
npm i effepi
Yarn
yarn add effepi
Index
- effepi
- What is effepi?
- Install
- Install
- How to use it
- Functions
Install
npm i pipe # or yarn add pipe
How to use it
; .pipemath.divideBy100 .pipemath.multiplyByvatPercentage .toSyncFunction; vatCalculator22100; // 22vatCalculator221285; // 282.7
To create a pipeline, use the pipe
function. This function can be used with any function, althought is recommended if you are building a function from a pipeline to use the useCallValue
function.
; p10 // returns 10p'hello world' // returns 'hello world'
A pipeline can be memoized, it is useful when you have to call a pipeline a lot of times.
.pipeadd10 .pipemultiplyBy2 .toSyncFunction; test1 // returns 22test1 // returns the cached previous resulttest2 // returns 24test2 // returns the cached previous resulttest2 // returns the cached previous result
iterating a pipeline
You can iterate a pipeline.
Each iteration returns an immutable pipeline result.
.pipepow2 .pipeadd10 .pipemultiplyBy4; ;;;; first.value // 10second.value // 100third.value // 110last.value // 440
pipeline context
Each function passed in a pipeline can use the previous value and can access to the current pipeline context. A passed context can be enriched with a mutation
function, which is the only way to mutate the pipeline from the inside of a function.
; .pipeaFunctionUsingContext // uses console.log for context callValue .toSyncFunction; // returns true if the number is even isEven10 // logs 10, logs true, returns true
A context has also the call
method, which can be used to invoke a function with
the previous value as argument.
pipeuseCallValue .pipecontext.calladd10 ).resolveSync0; // returns 10
Functions
Array functions
Array functions are under the array
module.
;
applyEach
Applies the result of a pipeline to each element in an array of another pipeline.
Note: invoking a pipeline using this function with a sync method will throw an error.
.pipesum2 .pipemultiplyBy3; pipeuseCallValue .pipeapplyEachdoMath .resolve // Promise([36, 66, 96])
applyEachSync
Is the same of applyEach, except it does not work with async functions
Note: invoking a pipeline using this function with an async method will throw an error.
.pipesum2 .pipemultiplyBy3; pipeuseCallValue .pipeapplyEachdoMath .resolveSync // [36, 66, 96]
concat
Concatenates previous value with another array.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipeconcat .resolveSync // [1,2,3,4,5,6]
filter
Filters the previous value with a given callback. The callback must return a boolean value.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipefiltera > 2 .resolveSync // [3]
filterWith
Filters the previous value with a given value.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipefilterWith2 .resolveSync // [2,2,2]
find
Finds a value as specified by a find callback. The callback must return true
.
If the value is not found, the pipe will return an undefined
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipefindarg === 1 .resolveSync // 1
findExact
Finds an exacts value.
If the value is not found, the pipe will return an undefined
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipefind1 .resolveSync // 1
join
Joins the previous value with a given char.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipejoin'*' .resolveSync // '1*2*3'
length
Returns the length of the previous value.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipelength .resolveSync // 3
nth
Returns the nth element in the previous value.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipenth3 .resolveSync // 12
reverse
Reverses the previous value.
If the previous value is not an array an error will be thrown
pipeuseCallValue .pipereverse .resolveSync // [3,2,1]
Boolean functions
Boolean functions are under the boolean
module.
;
F
Puts a false
value.
pipeF.resolveSyncundefined // false
T
Puts a true
value.
pipeT.resolveSyncundefined // true
inverse
Inverts previous value.
Previous value must be boolean.
pipeuseCallValue.pipeinverse.resolveSynctrue // falsepipeuseCallValue.pipeinverse.resolveSyncfalse // true
Math functions
Math functions are under the math
module.
;
add
Sums a value to the previous one.
pipeuseCallValue.pipeadd1.resolveSync10 // 11
changeSign
Changes previous value sign, from positive to negative and vice-versa.
pipeput-123.pipechangeSign // 123
decrement
Decrements the previous value by one.
pipeuseCallValue.pipedecrement.resolve44 // 41
divideBy
Divides the previous value by the passed one.
pipeuseCallValue.pipedivideBy2.resolve44 // 22
increment
Increments the previous value by one.
pipeuseCallValue.pipeincrement.resolve44 // 45
isNegative
Checks if previous value is negative.
pipeuseCallValue.pipeisNegative.resolveSync1 // falsepipeuseCallValue.pipeisNegative.resolveSync-1 // true
isPositive
Checks if previous value is positive.
pipeuseCallValue.pipeisPositive.resolveSync1 // truepipeuseCallValue.pipeisPositive.resolveSync-1 // false
multiplyBy
Multiplies the previous value by the given one
pipeuseCallValue.pipemultiplyBy2.resolve44 // 88
negative
Converts previous' value from positive sign to negative unless is already negative.
pipeuseCallValue.pipenegative.resolve44 // -44pipeuseCallValue.pipenegative.resolve-12 // -12
positive
Converts previous' value from negative sign to positive unless is already positive.
pipeuseCallValue.pipepositive.resolve44 // 44pipeuseCallValue.pipepositive.resolve-12 // 12
pow
Raises to power the previous value by a given exponent
pipeuseCallValue.pipepow4.resolve2 // 16pipeuseCallValue.pipepow2.resolve-2 // 4
root
Extracts the root of the previous value by a given exponent
pipeuseCallValue.piperoot2.resolve4 // 2pipeuseCallValue.piperoot2.resolve9 // 3
subtract
Subtracts the previous value by the given one
pipeuseCallValue.pipesubtract2.resolve9 // 7
takeBetween
Takes all numbers in a number array between two values (inclusive)
pipeuseCallValue.pipetakeBetween5, 7.resolve // [5, 6, 7]
takeGreater
Returns the greater number in a number array
pipeuseCallValue.pipetakeGreater.resolve // 44
takeGreaterThan
Takes all numbers in a number array greater than a given value.
pipeuseCallValue.pipetakeGreaterThan8.resolve // [44]
This function accepts a second parameter (boolean) to include also the same value
pipeuseCallValue.pipetakeGreaterThan8, true.resolve // [8, 44]
takeLower
Returns the lower number in a number array
pipetakeLower.pipetakeGreater.resolve // 4
takeLowerThan
Takes all numbers in a number array lower than a given value.
pipeuseCallValue.pipetakeLowerThan5.resolve // [4]
This function accepts a second parameter (boolean) to include also the same value
pipeuseCallValue.pipetakeLowerThan8, true.resolve // [4, 5, 6, 7, 8]
takeOuter
Takes all numbers in a number array lower than the first passed value or greater than the second passed value. Matching elements are discarded.
pipeuseCallValue.pipetakeOuter5, 10.resolveSync // [3, 4, 11]
Logical operators functions
Logical operators functions are under the logical
module.
;
createSwitch
Is the same of the switch
construct.
// silly example: checking if a string is inside an array of strings .pipe createSwitch createSwitchDefault'City not found', createSwitchOption'Munich', 'Beerfest!', createSwitchOption'Rome', 'We love carbonara', createSwitchOption'London', 'God save the queen', .toSyncFunction; cities'Munich' // 'Beerfest!'cities'Rome' // 'We love carbonara'cities'London' // 'God save the queen'cities'Casalpusterlengo' // 'City not found'
To create the default, you can use the createSwitchDefault
method, whilst using createSwitchOption
you can add a switch case.
fold
This function is the same of the if/else
statement.
It takes two arguments, the left
and the right
part. The left part is intended as the false
comparison result, while the right
is the true
.
.pipeisGreaterThan144 .pipefold'', 'Maximum character' .toSyncFunction; smsLengthCheck'lorem' // ''smsLengthCheck'lorem'.repeat2000 // 'Maximum character'
ifElse
This function works like the if/else
statement.
It requires three arguments:
- a Condition (a
function
which returns aboolean
) - a Left, which can be a value or another
pipe
. If is a pipe, it will be resolved using the context's async/sync flow - a Right, which can be a value or another
pipe
. If is a pipe, it will be resolved using the context's async/sync flow
.pipe logical.ifElsearg > 5, 'lower than 5', 'greater than 5' .toSyncFunction; .pipe logical.ifElsearg > 5, pipeuseCallValue.pipemath.pow2, pipeuseCallValue.pipemath.divideBy2, .toSyncFunction; simple4 // lower than 5simple10 // greater than 5complex4 // 14complex10 // 5
Object functions
Object functions are under the object
module.
;
exclude
Returns previous value except for the given keys. This applies only to objects.
pipeuseCallValue .pipeexclude'foo' .resolveSync; // { bar: 'baz' }
hasProperty
Returns if an object has a owned property
pipeuseCallValue .pipehasProperty'foo' .resolveSync // true
keys
Returns previous's value keys. Works only for objects
pipeuseCallValue .pipekeys .resolveSync // ['bar', 'foo']
maybe
Returns a property key value by a given path. This applies only to objects.
pipeuseCallValue .pipemaybe'foo.bar' .resolveSync // 100
You can provide a fallback value or a fallback pipeline if the path does not match the object schema.
If you start you pipeline with the useCallValue
function, the monad will be invoked with an undefined
value.
pipeuseCallValue .pipemaybe'foo.bar.baz', 123 .resolveSync // 123 // or; pipeuseCallValue .pipemaybe'foo.bar.baz', fallback .resolveSync // undefined // or; pipeuseCallValue .pipemaybe'foo.bar.baz', fallback .resolveSync // 10
merge
Merges the previous object with the given one
pipeuseCallValue .pipemerge .resolveSync // { foo: 'bar', bar: 'baz' }
pick
Returns a new object (previous value) with the given keys. This applies only to objects.
pipeuseCallValue .pipepick'foo' .resolveSync; // { foo: 123 }
Misc functions
Misc functions are under the misc
module.
;
adapt
A simple currying function which adapts a function
with two arguments in order to be used with the pipe
method.
Can adapt both a sync or an async function.
;; pipeuseCallValue .pipeadaptedMyFn'john' .resolveSync'snow'; // 'john snow' pipeuseCallValue .pipeadaptedMyFnAsync'john' .resolve'snow'; // Promise('john snow')
apply
Applies a pipeline using the async resolve
method.
Note: invoking a pipeline using this function with a sync method will throw an error.
.pipefunctions.add10; .pipefunctions.applyinjectedPipeline .pipefunctions.multiplyBy2; testPipeline.resolve2 // Promise(24)
applySync
Applies a pipeline using the sync resolveSync
method.
Note: invoking a pipeline using this function with an async method will throw an error.
.pipefunctions.add10; .pipefunctions.applySyncinjectedPipeline .pipefunctions.multiplyBy2; testPipeline.resolve2 // 24
callWith
Calls previous value with a specific argument.
Works both with async and sync flows, and the argument can be both a value or a pipeline.
It will throw a TypeError if the previous value is not a function.
; pipeuseCallValue .pipecallWith2 .resolveSyncarg * 2 // 4 pipeuseCallValue .pipecallWith2 .resolvearg * 2 // Promise(4)
put
Use this function to put a value at the beginning of the pipeline
pipeput10.resolveSync0 // 10
safeCall
Use this function to perform a safe function call (will not throw) with the previous value as argument
pipeuseCallValue .pipesafeCallthrow new Error'hello world' .resolveSync100 // will not throw, instead it will return 100
useCallValue
Use this function at the beginning of your pipeline to use the passed value to resolve
/resolveSync
and to function invokation
; p.resolve200 // Promise(300)p.resolveSync10 // 110p.toFunction123 // Promise(223)p.toSyncFunction1000 // 1100
useValue
Use this function to return the previous pipeline value
pipeuseCallValue .pipeadd10 .pipeuseValue .resolveSync10 // 20
String functions
String functions are under the string
module.
;
camelCase
Returns previous value in camel-case. Previous value must be a string.
pipeuseCallValue .pipecamelCase .resolveSync'hello world' // 'helloWorld'
chars
Returns previous value as an array of chars. Previous value must be a string.
pipeuseCallValue .pipechars .resolveSync'hello' // returns ['h', 'e', 'l', 'l', 'o']
concat
Concatenate previous value with another string. Previous value must be a string.
pipeuseCallValue .pipeconcat'world' .resolveSync'hello' // 'helloworld'
includes
Returns if the previous value contains a portion of text. Previous value must be a string.
pipeuseCallValue .pipeincludes'llo' .resolveSync'hello' // true
length
Returns previous value length. Previous value must be a string.
pipeuseCallValue .pipelength .resolveSync'hello' // 5
lowercase
Returns previous value in lower case. Previous value must be a string.
pipeuseCallValue .pipelowercase .resolveSync'HELLO' // 'hello'
pascalCase
Returns previous value in pascal-case. Previous value must be a string.
pipeuseCallValue .pipepascalCase .resolveSync'hello world' // 'HelloWorld'
repeat
Repeats previous value a number of times. Previous value must be a string.
pipeuseCallValue .piperepeat .resolveSync'hello' // hellohello pipeuseCallValue .piperepeat2 .resolveSync'hello' // hellohellohello
replaceAll
Replaces all occurencies from the previous value. Previous value must be a string.
pipeuseCallValue .pipereplaceAll'l', '1' .resolveSync'hello' // he110
toBinaryArray
Returns previous value in a binary representation. Previous value must be a string.
pipeuseCallValue .pipetoBinary .resolveSync'hello world' // [ '1101000', '1100101', '1101100', '1101100', '1101111', '100000', '1110111', '1101111', '1110010', '1101100', '1100100' ]
uppercase
Returns previous value in upper case. Previous value must be a string.
pipeuseCallValue .pipeuppercase .resolveSync'hello' // 'HELLO'
Type functions
Type functions are under the type
module.
;
exactTypeOf
Throws if the previous value is not of the same type expected.
TypeName is the second portion of a Object.prototype.toString
call in lowerCase:
[object TypeName] -->
typename
pipeuseCallValue .pipeexactTypeOf'date' .resolveSync123 // throws! pipeuseCallValue .pipeexactTypeOf'date' .resolveSyncnew Date // 2019-03-26T02:17:000Z
ofType
Throws if the previous value is not of the same type expected.
Internally uses the typeof
operator.
pipeuseCallValue .pipeexactTypeOf'number' .resolveSync123 // 123 pipeuseCallValue .pipeexactTypeOf'number' .resolveSync`hello world!` // throws!
toArray
Converts previous value to an array.
pipeuseCallValue.pipetoArray.resolveSync10 // [10]
toBoolean
Converts previous value to a boolean value.
pipeuseCallValue.pipetoBoolean.resolveSync10 // truepipeuseCallValue.pipetoBoolean.resolveSync0 // falsepipeuseCallValue.pipetoBoolean.resolveSyncnull // falsepipeuseCallValue.pipetoBoolean.resolveSyncundefined // falsepipeuseCallValue.pipetoBoolean.resolveSync'' // falsepipeuseCallValue.pipetoBoolean.resolveSync'123' // true
toDate
Converts previous value to a Date instance.
pipeuseCallValue .pipetoDate .resolveSync`2019-01-01T00:00:000Z` // Date(2019, 0, 1, 0, 0, 0)
toNumber
Converts previous value to a number.
pipeuseCallValue .pipetoNumber .resolveSync'12000' // 12000
toSet
Converts previous value to a set. Previous value must be an array.
toString
Converts previous value to a string.
pipeuseCallValue .pipetoString .resolveSync // "1,2,3"
Contributing
Every contribution is welcome! Before creating pull-request or opening issues, ensure you have read the contribution guidelines
Licence
This library is released under the MIT licence