Comparing version 1.0.2 to 1.0.3
{ | ||
"name": "js-awe", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -9,3 +9,4 @@ export * from './anonymize.js'; | ||
export * from './ramdaExt.js'; | ||
export * from './plan.js' | ||
export * from './sanitizer.js'; | ||
export * from './streamUtils.js'; |
@@ -31,2 +31,12 @@ 'use strict' | ||
} | ||
map(func) { | ||
return this | ||
} | ||
chain(func) { | ||
return this | ||
} | ||
static of=CustomError | ||
} | ||
@@ -39,3 +49,15 @@ // try { | ||
// } | ||
// | ||
// mapping a function to CustomError should return the CustomError without exeecuting the function | ||
// import { pipeWithChain, R } from './ramdaExt.js' | ||
// let divide = (dividend, divisor) => | ||
// divisor !== 0 | ||
// ? dividend/divisor | ||
// : new CustomError('ZERO_DIVISION_EXC','Division by zero',{dividend,divisor}) | ||
// R.map(a => { | ||
// console.log(`It shouldn't print this`) | ||
// return a +2 | ||
// })(divide(8,0)) //? | ||
class Enum { | ||
@@ -42,0 +64,0 @@ |
// ts-check | ||
import * as R from 'ramda'; | ||
import { sorterByPaths, repeat } from './jsUtils.js' | ||
import { fork, reject, resolve, after, both, pap, chain, map, parallel } from 'fluture'; | ||
import { sorterByPaths } from './jsUtils.js' | ||
import { reject, resolve, parallel as RParallel, isFuture } from 'fluture'; | ||
// Only needed for testing | ||
// import { after, both, chain, map, fork } from 'fluture'; | ||
// import { repeat, CustomError } from './jsUtils.js' | ||
@@ -33,17 +36,17 @@ const RE = {} | ||
RE.groupByWithCalc = groupByWithCalc | ||
RE.groupByWithCalc( | ||
(row) => row.date, | ||
{ | ||
total:(l,r) => (l??0) + r, | ||
count:(l,r) => (l??0) + 1 | ||
}, | ||
)( | ||
[ | ||
{date:'2020-01-02', total:6}, | ||
{date:'2020-01-03', total:5}, | ||
{date:'2020-01-02', total:11}, | ||
{date:'2020-01-03', total:6}, | ||
{date:'2020-01-02', total:-5} | ||
] | ||
)//? | ||
// RE.groupByWithCalc( | ||
// (row) => row.date, | ||
// { | ||
// total:(l,r) => (l??0) + r, | ||
// count:(l,r) => (l??0) + 1 | ||
// }, | ||
// )( | ||
// [ | ||
// {date:'2020-01-02', total:6}, | ||
// {date:'2020-01-03', total:5}, | ||
// {date:'2020-01-02', total:11}, | ||
// {date:'2020-01-03', total:6}, | ||
// {date:'2020-01-02', total:-5} | ||
// ] | ||
// )//? | ||
@@ -74,6 +77,6 @@ const innerRightJoinWithUnc = (joinCond, transform = (k, l, r) => r, left, right) => { | ||
// : r, | ||
// [{date:'2020-01-02', total:6}, {date:'2020-01-03', total:5}] | ||
// [{date:'2020-01-02', total:6}, {date:'2020-01-08', total:8}, {date:'2020-01-03', total:5}] | ||
// ) | ||
// ( | ||
// [{date:'2020-01-02', total:11}, {date:'2020-01-03', total:6}] | ||
// [{date:'2020-01-02', total:11}, {date:'2020-01-09', total:9}, {date:'2020-01-03', total:6}] | ||
// )//? | ||
@@ -338,2 +341,7 @@ | ||
/* Returns: | ||
[ { fun: 'applySpec', sign: '(object)(object)' }, | ||
{ fun: 'juxt', sign: '(object)(object)' } ] | ||
*/ | ||
//findSolution([{a:2},{a:2,b:2}, 7], something(R)([obj=>obj,obj=>({...obj, b:2}), obj=>obj.a+5], {a:2})) //? | ||
@@ -350,2 +358,10 @@ /* | ||
//findSolution(7, Rsomething(4, 3)) //? | ||
// | ||
// findSolution( | ||
// [[true,false],[1,{a:2},3]], | ||
// something(R)( | ||
// (elem)=> typeof elem === 'boolean'?0:1, | ||
// [true, 1, {a:2},false,3] | ||
// ) | ||
// ) //? [ { fun: 'collectBy', sign: '(function,object)' } ] | ||
@@ -364,2 +380,28 @@ function findSolution(solutionToFind, solutions) { | ||
function partialAtPos(fun, pos) { | ||
return (...paramValues) => { | ||
let funAcum = fun | ||
let count = 0 | ||
if (pos === 0) return funAcum(...paramValues) | ||
const iteFun = (...params) => { | ||
if (count >= pos) return funAcum(...paramValues)(...params) | ||
funAcum = funAcum(...params) | ||
count = count + params.length | ||
if (count >= pos) return funAcum(...paramValues) | ||
return iteFun | ||
} | ||
return iteFun | ||
} | ||
} | ||
RE.partialAtPos = partialAtPos | ||
// const nestedFun = (a,b) => c => (d,e) => f => console.log(a,b,c,d,e,f) | ||
// partialAtPos(nestedFun, 3)('jose','Luchi')('a','b')('c')('d') | ||
// partialAtPos(nestedFun, 5)('jose')('a','b')('c')('d','e') | ||
function uncurry(withLog = false) { | ||
@@ -509,3 +551,3 @@ return function uncurryWithOrWithoutLog(funcParam) { | ||
// )(5, 6) | ||
// .pipe(fork(log('pipeWithChain-Ex1-Err: '))(log('pipeWithChain-Ex1-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex1-Err: '))(RLog('pipeWithChain-Ex1-OK: '))) | ||
@@ -532,3 +574,3 @@ // // // | ||
// )(resolve([1,2,3,4,56])) | ||
// .pipe(fork(log('pipeWithChain-Ex2-Err: '))(log('pipeWithChain-Ex2-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex2-Err: '))(RLog('pipeWithChain-Ex2-OK: '))) | ||
@@ -542,3 +584,3 @@ // // Example with error | ||
// )(5, 6) | ||
// .pipe(fork(log('pipeWithChain-Ex3-Err: '))(log('pipeWithChain-Ex3-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex3-Err: '))(RLog('pipeWithChain-Ex3-OK: '))) | ||
@@ -556,3 +598,3 @@ // RE.pipeWithChain( | ||
// )(5, 6) | ||
// .pipe(fork(log('pipeWithChain-Ex4-Err: '))(log('pipeWithChain-Ex4-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex4-Err: '))(RLog('pipeWithChain-Ex4-OK: '))) | ||
@@ -567,3 +609,3 @@ // // Example with throw error | ||
// )(5, 6) | ||
// .pipe(fork(log('pipeWithChain-Ex5-Err: '))(log('pipeWithChain-Ex5-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex5-Err: '))(RLog('pipeWithChain-Ex5-OK: '))) | ||
@@ -575,3 +617,3 @@ // // Example with throw error | ||
// )(5, reject(10)) | ||
// .pipe(fork(log('pipeWithChain-Ex6-Err: '))(log('pipeWithChain-Ex6-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex6-Err: '))(RLog('pipeWithChain-Ex6-OK: '))) | ||
@@ -583,3 +625,3 @@ // // Passing a Future as a parameter. Remember this must be the last one. | ||
// )('the value after 5ms is: ', after(5)('5')) | ||
// .pipe(fork(log('pipeWithChain-Ex7-Err: '))(log('pipeWithChain-Ex7-OK: '))) | ||
// .pipe(fork(RLog('pipeWithChain-Ex7-Err: '))(RLog('pipeWithChain-Ex7-OK: '))) | ||
@@ -592,16 +634,162 @@ // // Example with throw error | ||
const runFunctionsInParallel = | ||
(numberOfThreads = Infinity) => | ||
functionsToRunInParallel => | ||
data => { | ||
// // Note!: Arrays passing through each function of the pipeWithChain will be flatmap | ||
// RLog | ||
// ('pipe doesnt apply flatmap to arrays: ') | ||
// ( | ||
// RE.pipe( | ||
// R.identity | ||
// )([['a','b'], ['c','d']]) | ||
// ) | ||
return parallel | ||
(numberOfThreads) | ||
( | ||
R.map | ||
(funToRunInParallel => funToRunInParallel(data)) | ||
(functionsToRunInParallel) | ||
// Same as pipe with chain but arrays are not chainable: | ||
const pipe = function (...func) { | ||
return function (...params) { | ||
return func.reduce( | ||
// iterate over functions to call in a specific way with the acum value. | ||
(acum, currentPipeFunc, index) => { | ||
let chainFun | ||
let pipeFunc = currentPipeFunc | ||
// First function accepts multiVariant function... but there must meet certain condition. | ||
if (index === 0 && acum.length > 1) { | ||
const numberOfFutures = acum.filter(param => param?.constructor?.name === 'Future').length | ||
if (numberOfFutures > 1) | ||
acum[acum.length - 1] = reject(new Error('Only one Future allowed...')) | ||
else | ||
if (numberOfFutures === 1 && R.last(acum)?.constructor?.name !== 'Future') | ||
acum[acum.length - 1] = reject(new Error('Future param must be the last param of the function')) | ||
else | ||
//Apply all the parameters to convert it to a unary function. | ||
pipeFunc = currentPipeFunc.bind(undefined, ...acum.slice(0, acum.length - 1)) | ||
} | ||
// Then extract last parameter | ||
if (index === 0) { | ||
acum = acum[acum.length - 1] | ||
} | ||
if (acum instanceof Error) { | ||
return acum | ||
} | ||
// Try to find a chain kind of method for the accumlated drag value | ||
if (typeof acum?.chain === 'function') | ||
chainFun = acum.chain | ||
else if (typeof acum?.['fantasy-land/chain'] === 'function') | ||
chainFun = acum['fantasy-land/chain'].bind(acum) | ||
//else if (typeof acum?.flatMap === 'function') | ||
// chainFun = acum.flatMap.bind(acum) | ||
// if acum is a chain type the pipeFunc will be executed inside the chain. | ||
if (chainFun) { | ||
return chainFun( | ||
(elem) => { | ||
if (isAcumAFutureAndElemAnError(acum, elem)) { | ||
return createReject(acum, elem) | ||
} | ||
let result | ||
// For flutures we try catch so there will be transformed in a reject, | ||
if (acum?.constructor?.name === 'Future') { | ||
try { | ||
result = pipeFunc(elem) | ||
} catch (e) { | ||
result = e | ||
} | ||
} else result = pipeFunc(elem) | ||
if (isAcumAFutureAndElemAnError(acum, result)) { | ||
return createReject(acum, result) | ||
} | ||
// inside chainFun the return needs to be of the same type as the original acum drag value. | ||
// else we wrap the result using the constructor. | ||
if (result?.constructor?.name === acum?.constructor?.name) | ||
return result | ||
else { | ||
if (typeof acum?.constructor?.of === 'function') return acum.constructor.of(result) | ||
if (typeof acum?.constructor?.['fantasy-land/of'] === 'function') return acum.constructor['fantasy-land/of'](result) | ||
return result | ||
} | ||
} | ||
) | ||
} | ||
// If acum drag value is not chainable we execute pipeFunc in a normal way. | ||
return pipeFunc(acum) | ||
} | ||
, params | ||
) | ||
} | ||
} | ||
RE.pipe = pipe | ||
// RLog | ||
// ('pipe doesnt apply flatmap to arrays: ') | ||
// ( | ||
// RE.pipe( | ||
// R.identity | ||
// )([['a','b'], ['c','d']]) | ||
// ) | ||
// RE.pipe( | ||
// R.identity, | ||
// RLog('RLog print the whole array in one go. RLog is not iterated as it would in pipeWithChain ') | ||
// )([['a','b'], ['c','d']]) | ||
const pipeWhile = (funCond, ini) => (...funcs) => (...inputs) => { | ||
if( | ||
typeof funCond !== 'function' || | ||
funcs.some(func => typeof func !== 'function') || | ||
( ini !== undefined && typeof ini !== 'function') | ||
) | ||
{ | ||
const dataErrorString = | ||
`funCond: ${typeof funCond} ${ini===undefined?'':'ini: '+ typeof ini} funcs: ${funcs.map(el=>typeof el)}` | ||
throw new Error(`pipeWhile was called without funcfion/s in funCond or pipe functions ${dataErrorString}`) | ||
} | ||
if(typeof ini === 'function') ini(...inputs) | ||
let finalReturn = inputs | ||
while(funCond(...finalReturn)) { | ||
finalReturn = funcs.reduce( | ||
(acum, func) => [func(...acum)], | ||
finalReturn | ||
) | ||
} | ||
return R.last(finalReturn) | ||
} | ||
RE.pipeWhile = pipeWhile | ||
// pipeWhile(x => x < 20) | ||
// ( | ||
// x => x + 2 | ||
// )(2) //? | ||
const parallel = | ||
(numberOfthreads=Infinity) => | ||
(futuresOrValues) => | ||
RParallel | ||
(numberOfthreads) | ||
(futuresOrValues.map(elem => isFuture(elem)? elem: resolve(elem)) ) | ||
RE.parallel = parallel | ||
const runFunctionsInParallel = | ||
(numberOfThreads=Infinity) => | ||
(functionsToRunInParallel) => | ||
data => | ||
RE.parallel(numberOfThreads) | ||
( | ||
functionsToRunInParallel.map(fun => fun(data)) | ||
) | ||
RE.runFunctionsInParallel = runFunctionsInParallel | ||
@@ -617,3 +805,3 @@ | ||
// ] | ||
// )(5).pipe(fork(log('1: Err runFunctionsInParallel'))(log('1: OK runFunctionsInParallel'))) | ||
// )(5).pipe(fork(RLog('1: Err runFunctionsInParallel'))(RLog('1: OK runFunctionsInParallel'))) | ||
@@ -631,89 +819,33 @@ // example of race to update variable | ||
// ), | ||
// )(resolve({ varToRaceChanges: 5 })).pipe(fork(log('2: Err runFunctionsInParallel'))(log('2: OK runFunctionsInParallel'))) | ||
// )(resolve({ varToRaceChanges: 5 })).pipe(fork(RLog('2: Err runFunctionsInParallel'))(RLog('2: OK runFunctionsInParallel'))) | ||
// | ||
// Mixing Futures with non Futures. | ||
// runFunctionsInParallel | ||
// () | ||
// ( | ||
// [ | ||
// (data) => after(15)(data + 2), //7 | ||
// data => data + 3, //8 | ||
// (data) => after(15)(data + 4), //9 | ||
// ] | ||
// )(5).pipe(fork(RLog('1: Err runFunctionsInParallel'))(RLog('1: OK runFunctionsInParallel'))) | ||
const runFunctionsSyncOrParallel = | ||
(numberOfThreads=Infinity) => | ||
(functionsToRun) => | ||
data => | ||
{ | ||
let futureOrValues = functionsToRun.map(fun => fun(data)) | ||
/** | ||
* Create a plan of execution. | ||
* @param {(function | undefined)} piper function used to pipe. If undefined it uses pipeWithChain | ||
*/ | ||
function plan(piper = pipeWithChain) { | ||
return function (...callValues) { | ||
return planBivariate(piper, callValues) | ||
} | ||
} | ||
function planBivariate(piper, callValues) { | ||
const listOfFuncToExecute = [] | ||
const toReturn = { | ||
pipe, | ||
fork: go | ||
} | ||
return toReturn | ||
/** | ||
* pipe functions and it returns a future that can be executed with fork | ||
* @param { ...(function | Object.<string, any>)} funcs functions to be chained | ||
*/ | ||
function pipe(...funcs) { | ||
funcs.forEach( | ||
funcDef => { | ||
if (typeof funcDef === 'function' && funcDef.name !== undefined) { | ||
listOfFuncToExecute.push({ [funcDef.name]: funcDef }) | ||
return | ||
} | ||
if (typeof funcDef === 'function') { | ||
listOfFuncToExecute.push({ [listOfFuncToExecute.length]: funcDef }) | ||
return | ||
} | ||
listOfFuncToExecute.push(funcDef) | ||
if(futureOrValues.some(isFuture)) { | ||
return RE.parallel | ||
(numberOfThreads) | ||
( futureOrValues ) | ||
} | ||
) | ||
return toReturn | ||
} | ||
return futureOrValues | ||
} | ||
RE.runFunctionsSyncOrParallel = runFunctionsSyncOrParallel | ||
/** | ||
* @typedef { import("fluture").RejectFunction } RejectFunction | ||
* @typedef { import("fluture").ResolveFunction } ResolveFunction | ||
*/ | ||
/** | ||
* fork execution of chained functions, substituting when corresponds with mock values. | ||
* @param { RejectFunction } ko KO function | ||
* @param { ResolveFunction} ok OK function | ||
* @param {(Object.<string, any> | undefined)} mocks Replace function with value... | ||
*/ | ||
function go(ko, ok, mocks) { | ||
listOfFuncToExecute | ||
const planList = listOfFuncToExecute.map( | ||
(funcDef, index) => { | ||
const funcKey = Object.keys(funcDef)[0] | ||
if (mocks?.[funcKey] !== undefined) return () => mocks[funcKey] | ||
return funcDef[funcKey] | ||
} | ||
) | ||
return fork | ||
(ko) | ||
(ok) | ||
(piper(...planList)(...callValues)) | ||
} | ||
} | ||
// plan()(3, after(100)(2)) | ||
// .pipe( | ||
// { sum:(a,b)=> a+b }, | ||
// { by2: a=>after(100)(a*2) }, | ||
// { minus3: a=>a-3 } | ||
// ).fork(log('plan Err'), log('plan OK'), {by2:8}) // plan OK 5 | ||
// //.fork(log('plan Err'), log('plan OK')) // plan OK 7 | ||
function pickPathsUnc(pickTransformations, obj) { | ||
@@ -791,3 +923,3 @@ | ||
function Rlog(prefix) { | ||
function RLog(prefix) { | ||
return (...obj) => { | ||
@@ -799,3 +931,3 @@ console.log(prefix, ...obj) | ||
RE.log = Rlog | ||
RE.RLog = RLog | ||
RE.findSolution = findSolution | ||
@@ -819,4 +951,8 @@ RE.something = something | ||
pipeWithChain, | ||
pipe, | ||
pipeWhile, | ||
parallel, | ||
runFunctionsInParallel, | ||
Rlog, | ||
runFunctionsSyncOrParallel, | ||
RLog, | ||
findSolution, | ||
@@ -826,4 +962,5 @@ something, | ||
mergeArrayOfObjectsRenamingProps, | ||
uncurry | ||
uncurry, | ||
partialAtPos | ||
} | ||
@@ -9,4 +9,5 @@ export * from "./anonymize.js"; | ||
export * from "./ramdaExt.js"; | ||
export * from "./plan.js"; | ||
export * from "./sanitizer.js"; | ||
export * from "./streamUtils.js"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -12,7 +12,12 @@ export namespace RE { | ||
export { mapWithPrevious }; | ||
export { partialAtPos }; | ||
export { pipeWithChain }; | ||
export { pipe }; | ||
export { pipeWhile }; | ||
export { parallel }; | ||
export { runFunctionsInParallel }; | ||
export { runFunctionsSyncOrParallel }; | ||
export { pickPaths }; | ||
export { mergeArrayOfObjectsRenamingProps }; | ||
export { Rlog }; | ||
export { RLog }; | ||
export { findSolution }; | ||
@@ -48,7 +53,66 @@ export { something }; | ||
calc:objCalc | ||
):([]) => [] | ||
):(data:any[]) => any[] | ||
export { groupByWithCalc } | ||
export const innerRightJoinWith: any; | ||
/** | ||
* Returns true if records need to be merged | ||
* @param leftRow row form left data to match | ||
* @param rightRow row from right data to match | ||
* @return true if merge is required | ||
*/ | ||
declare function leftRightMatchingD(leftRow?:any, rightRow?:any):boolean | ||
/** | ||
* update matched records | ||
* @param key each of the fields for a match record | ||
* @param leftValue left value of the key | ||
* @param rightValue right value of the key | ||
* @return the new value to be assigned to the key | ||
*/ | ||
declare function updateD(key?:string, leftValue?:any, rightValue?:any):any | ||
/** | ||
* introduce the rightData to join | ||
* @param rightData each of the fields for a match record | ||
* @return the final result for the innerRightJoinWith | ||
*/ | ||
declare function injectRightDataD(rightData:any[]):any[] | ||
declare function injectLeftData(leftData:any[]):typeof injectRightDataD | ||
/** | ||
* Right join using condition and merge function by keys. | ||
* last chain function call is to introduce right Data. | ||
* It keeps records from the right and update with | ||
* the left data | ||
* @param leftRightMatching matchinf function | ||
* @param update update function | ||
* @param leftData leftData | ||
* @return a function ready to receive rightData | ||
*/ | ||
declare function innerRightJoinWith( | ||
leftRightMatching:typeof leftRightMatchingD, | ||
update:typeof updateD, | ||
leftData:any[] | ||
):typeof injectRightDataD | ||
/** | ||
* Right join using condition and merge function by keys. | ||
* Data is introduce calling in sequence 3 times first | ||
* the params 2nd with left data and 3rd with right data. | ||
* @param leftRightMatching matchinf function | ||
* @param update update function | ||
* @return a function ready to receive rightData that when | ||
* invoke returns a function ready to receive leftData. Last | ||
* invaction with leftData will get the final result. | ||
*/ | ||
declare function innerRightJoinWith( | ||
leftRightMatching:typeof leftRightMatchingD, | ||
update:typeof updateD | ||
):typeof injectLeftData | ||
export { innerRightJoinWith } | ||
export const unionWithHashKeys: any; | ||
@@ -63,4 +127,8 @@ export const updateWithHashKeys: any; | ||
export function pipeWithChain(...func: any[]): (...params: any[]) => any; | ||
export function pipe(...func: any[]): (...params: any[]) => any; | ||
export function pipeWhile(funCond: any, ini: any): (...funcs: any[]) => (...inputs: any[]) => any; | ||
export function parallel(numberOfthreads?: number): (futuresOrValues: any) => import("fluture").FutureInstance<any, any[]>; | ||
export function runFunctionsInParallel(numberOfThreads?: number): (functionsToRunInParallel: any) => (data: any) => import("fluture").FutureInstance<any, any[]>; | ||
export function Rlog(prefix: any): (...obj: any[]) => any; | ||
export function runFunctionsSyncOrParallel(numberOfThreads?: number): (functionsToRun: any) => (data: any) => any; | ||
export function RLog(prefix: any): (...obj: any[]) => any; | ||
export function findSolution(solutionToFind: any, solutions: any): any; | ||
@@ -71,4 +139,5 @@ export function something(lib: any): (...args: any[]) => any; | ||
export function uncurry(withLog?: boolean): (funcParam: any) => (...args: any[]) => any; | ||
export function partialAtPos(fun: any, pos: any): (...paramValues: any[]) => any; | ||
import * as R from 'ramda'; | ||
export { R }; | ||
//# sourceMappingURL=ramdaExt.d.ts.map |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
153438
47
4621