Skip to content

Commit

Permalink
feat: Adding Functional programming support
Browse files Browse the repository at this point in the history
  • Loading branch information
yisraelx committed Mar 17, 2018
1 parent 2b6ba1c commit c801b97
Show file tree
Hide file tree
Showing 62 changed files with 1,035 additions and 49 deletions.
53 changes: 40 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![Codecov](https://codecov.io/gh/yisraelx/promises/branch/master/graph/badge.svg)](https://codecov.io/gh/yisraelx/promises)
[![MIT License](https://img.shields.io/npm/l/@promises/core.svg)](https://github.com/yisraelx/promises/blob/master/LICENSE)
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
[![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/)
[![Lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff.svg)](https://lernajs.io/)

## Packages structure
##### The code is divided into many small modules and each module is a package in itself ([Packages List](https://github.com/yisraelx/promises/blob/master/PACKAGES.md)).
Expand Down Expand Up @@ -38,6 +38,20 @@ import '@promises/-rxjs';
import '@promises/-parallel';
import Promises from '@promises/core';
```
Or import only the module you need
```ts
import Promises from '@promises/core';
import '@promises/map-series/add';
import '@promises/sleep/add';
```
import all models that have Functional programming support
```ts
import * as FP from '@promises/-fp';
```
Or import only the module you need
```ts
import filterSeries from '@promises/filter-series/fp';
```

## Install
__Installation of all packages in scoop @promises__
Expand All @@ -64,31 +78,44 @@ map.then((result: number[]) => {
#### wrapper
```ts
import { Promises } from '@promises/-all';
let array: number[] = [1, 2, 3];
let promises: Promises<number[]> = Promises.resolve(array);
let filter: Promises<number[]> = promises.filterParallel((value: number) => value % 2 !== 0);
let map: Promises<number[]> = filter.mapParallel((value: number, index: number) => value + index);
let delay: Promises<number[]> = map.delay(1000);
delay.then((result: number[]) => {
console.log(result) // => [1, 4]
});
```
Or
```ts
import Promises from '@promises/core';
import '@promises/filter-parallel/add';
import '@promises/map-parallel/add';
import '@promises/delay/add';

import '@promises/sleep/add';
```
```ts
let array: number[] = [1, 2, 3];
let promises: Promises<number[]> = Promises.resolve(array);
let filter: Promises<number[]> = promises.filterParallel((value: number) => value % 2 !== 0);
let map: Promises<number[]> = filter.mapParallel((value: number, index: number) => value + index);
let delay: Promises<number[]> = map.delay(1000);
delay.then((result: number[]) => {
let sleep: Promises<number[]> = map.sleep(1000);
sleep.then((result: number[]) => {
console.log(result) // => [1, 4]
});
```
#### Functional programming
```ts
import filterParallel from '@promises/filter-parallel/fp';
import mapParallel from '@promises/map-parallel/fp';
import { sleep } from '@promises/-fp';

let array: number[] = [1, 2, 3];
let filterOdd = filterParallel((value: number) => value % 2 !== 0)(Infinity);
let sleepSecond = sleep(1000);

Promise
.resolve(array)
.then(filterOdd)
.then(mapParallel((value: number, index: number) => value + index, void 0))
.then(sleepSecond)
.then((result: number[]) => {
console.log(result) // => [1, 4]
});

```

## Behavior
```typescript
Expand Down
31 changes: 31 additions & 0 deletions modules/-fp/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* @module @promises/-fp
* @copyright © 2017 Yisrael Eliav <yisraelx@gmail.com> (https://github.com/yisraelx)
* @license MIT
*/

export { default as error } from '@promises/error/fp';
export { default as everyParallel } from '@promises/every-parallel/fp';
export { default as everySeries } from '@promises/every-series/fp';
export { default as filterParallel } from '@promises/filter-parallel/fp';
export { default as filterSeries } from '@promises/filter-series/fp';
export { default as finally } from '@promises/finally/fp';
export { default as forEachParallel } from '@promises/for-each-parallel/fp';
export { default as forEachRightSeries } from '@promises/for-each-right-series/fp';
export { default as forEachSeries } from '@promises/for-each-series/fp';
export * from '@promises/interfaces';
export { default as mapParallel } from '@promises/map-parallel/fp';
export { default as mapSeries } from '@promises/map-series/fp';
export { default as next } from '@promises/next/fp';
export { default as reduceRightSeries } from '@promises/reduce-right-series/fp';
export { default as reduceSeries } from '@promises/reduce-series/fp';
export { default as rejectParallel } from '@promises/reject-parallel/fp';
export { default as rejectSeries } from '@promises/reject-series/fp';
export { default as reset } from '@promises/reset/fp';
export { default as sleep } from '@promises/sleep/fp';
export { default as someParallel } from '@promises/some-parallel/fp';
export { default as someSeries } from '@promises/some-series/fp';
export { default as timesParallel } from '@promises/times-parallel/fp';
export { default as timesSeries } from '@promises/times-series/fp';
export { default as toCallback } from '@promises/to-callback/fp';
export { default as wait } from '@promises/wait/fp';
61 changes: 61 additions & 0 deletions modules/-fp/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
{
"name": "@promises/-fp",
"version": "NEXT-PLACEHOLDER",
"description": "FP is a group of packages of Promises library",
"main": "es5.js",
"browser": "umd.min.js",
"module": "index.js",
"es2015": "index.js",
"typings": "index.d.ts",
"bundle": "bundle.min.js",
"author": {
"name": "Yisrael Eliev",
"url": "https://github.com/yisraelx",
"email": "yisraelx@gmail.com"
},
"license": "MIT",
"keywords": [
"promise",
"promises",
"utility",
"modules",
"async",
"await",
"deferred"
],
"homepage": "https://github.com/yisraelx/promises#readme",
"repository": {
"type": "git",
"url": "https://github.com/yisraelx/promises.git"
},
"bugs": {
"url": "https://github.com/yisraelx/promises/issues"
},
"dependencies": {
"@promises/error": "^0.3.1",
"@promises/every-parallel": "^0.3.1",
"@promises/every-series": "^0.3.1",
"@promises/filter-parallel": "^0.3.1",
"@promises/filter-series": "^0.3.1",
"@promises/finally": "^0.3.1",
"@promises/for-each-parallel": "^0.3.1",
"@promises/for-each-right-series": "^0.3.1",
"@promises/for-each-series": "^0.3.1",
"@promises/interfaces": "^0.3.0",
"@promises/map-parallel": "^0.3.1",
"@promises/map-series": "^0.3.1",
"@promises/next": "^0.3.1",
"@promises/reduce-right-series": "^0.3.1",
"@promises/reduce-series": "^0.3.1",
"@promises/reject-parallel": "^0.3.1",
"@promises/reject-series": "^0.3.1",
"@promises/reset": "^0.3.1",
"@promises/sleep": "^0.3.1",
"@promises/some-parallel": "^0.3.1",
"@promises/some-series": "^0.3.1",
"@promises/times-parallel": "^0.3.1",
"@promises/times-series": "^0.3.1",
"@promises/to-callback": "^0.3.1",
"@promises/wait": "^0.3.1"
}
}
32 changes: 32 additions & 0 deletions modules/_curry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @module @promises/_curry
* @copyright © 2017 Yisrael Eliav <yisraelx@gmail.com> (https://github.com/yisraelx)
* @license MIT
*/

export interface ICurryOptions {
length?: number;
order?: number[];
}

export default function _curry(fn: Function, { length = fn.length, order}: ICurryOptions = {}) {
order = Array.isArray(order) ? order : [length - 1].concat(Array.apply(null, Array(length - 1)).map((v, i) => i));

let next = (allArgs: any[]) => {
if (allArgs.length >= length) {
let execArgs = Array(length);
for (let i = 0; i < length; i++) {
let index = order[i];
let value = allArgs[index];
execArgs[i] = value;
}
return fn.apply(null, execArgs);
}
return (...currentArgs: any[]) => {
allArgs = allArgs.concat(currentArgs);
return next(allArgs);
};
};

return next([]);
}
34 changes: 34 additions & 0 deletions modules/_curry/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@promises/_curry",
"version": "0.3.0",
"description": "Curry is a internal package from Promises library",
"main": "es5.js",
"browser": "umd.min.js",
"module": "index.js",
"es2015": "index.js",
"typings": "index.d.ts",
"bundle": "bundle.min.js",
"author": {
"name": "Yisrael Eliev",
"url": "https://github.com/yisraelx",
"email": "yisraelx@gmail.com"
},
"license": "MIT",
"keywords": [
"promise",
"promises",
"utility",
"modules",
"async",
"await",
"deferred"
],
"homepage": "https://github.com/yisraelx/promises#readme",
"repository": {
"type": "git",
"url": "https://github.com/yisraelx/promises.git"
},
"bugs": {
"url": "https://github.com/yisraelx/promises/issues"
}
}
28 changes: 28 additions & 0 deletions modules/error/fp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import _curry from '@promises/_curry';
import { IOptionalPromise } from '@promises/interfaces';
import error from './';

export interface IError {
<R>(newValue: IOptionalPromise<any>, value: IOptionalPromise<R>): Promise<R>;
<R>(newValue: IOptionalPromise<any>): (value: IOptionalPromise<R>) => Promise<R>;
}

/**
* @example
*
* ```typescript
* let promise: Promise<string> = Promise.reject<string>('foo');
* error('bar')()(promise).catch((error: string) => {
* console.log(error); // => 'bar'
* });
* ```
* @example
*
* ```typescript
* let promise: Promise<string> = Promise.resolve<string>('foo');
* error('bar', promise).catch((error: string) => {
* console.log(error); // => 'bar'
* });
* ```
*/
export default _curry(error, {length: 2}) as IError;
1 change: 1 addition & 0 deletions modules/error/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@promises/core": "^0.3.1"
},
"dependencies": {
"@promises/_curry": "NEXT-PLACEHOLDER",
"@promises/interfaces": "^0.3.0"
}
}
29 changes: 29 additions & 0 deletions modules/every-parallel/fp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import _curry from '@promises/_curry';
import { IOptionalPromise, IOptionalPromiseDictionary } from '@promises/interfaces';
import everyParallel from './';

export interface IEveryParallel {
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>, limit: number, array: IOptionalPromise<T>): Promise<boolean>;
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>, limit: number): (array: IOptionalPromise<T>) => Promise<boolean>;
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>): (limit: number) => (array: IOptionalPromise<T>) => Promise<boolean>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>, limit: number, object: IOptionalPromiseDictionary<T>): Promise<boolean>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>, limit: number): (object: IOptionalPromiseDictionary<T>) => Promise<boolean>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>): (limit: number) => (object: IOptionalPromiseDictionary<T>) => Promise<boolean>;
}

/**
* @example
*
* ```typescript
* let comparator = (value) => {
* return Promise.resolve(Boolean(value))
* };
*
* let array: any[] = [true, 1, Promise.resolve(null), 'yes'];
*
* everyParallel(comparator)(Infinity)(array).then((result: boolean)=>{
* console.log(result) // result => false
* });
* ```
*/
export default _curry(everyParallel, {length: 3}) as IEveryParallel;
3 changes: 2 additions & 1 deletion modules/every-parallel/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@
"@promises/core": "^0.3.1"
},
"dependencies": {
"@promises/_create-checks-boolean": "^0.3.0",
"@promises/_create-checks-boolean": "^0.3.0",
"@promises/_curry": "NEXT-PLACEHOLDER",
"@promises/for-each-parallel": "^0.3.1",
"@promises/interfaces": "^0.3.0"
}
Expand Down
27 changes: 27 additions & 0 deletions modules/every-series/fp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import _curry from '@promises/_curry';
import { IOptionalPromise, IOptionalPromiseDictionary } from '@promises/interfaces';
import everySeries from './';

export interface IEverySeries {
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>, array: IOptionalPromise<T>): Promise<boolean>;
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>): (array: IOptionalPromise<T>) => Promise<boolean>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>, object: IOptionalPromiseDictionary<T>): Promise<boolean>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>): (object: IOptionalPromiseDictionary<T>) => Promise<boolean>;
}

/**
* @example
*
* ```typescript
* let comparator = (value) => {
* return Promise.resolve(Boolean(value))
* };
*
* let array: any[] = [true, 1, Promise.resolve(null), 'yes'];
*
* everySeries(comparator)(array).then((result: boolean)=>{
* console.log(result) // result => false
* });
* ```
*/
export default _curry(everySeries, {length: 2}) as IEverySeries;
3 changes: 2 additions & 1 deletion modules/every-series/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
},
"dependencies": {
"@promises/_create-checks-boolean": "^0.3.0",
"@promises/_curry": "NEXT-PLACEHOLDER",
"@promises/for-each-series": "^0.3.1",
"@promises/interfaces": "^0.3.0"
}
}
}
29 changes: 29 additions & 0 deletions modules/filter-parallel/fp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import _curry from '@promises/_curry';
import { IOptionalPromise, IOptionalPromiseDictionary } from '@promises/interfaces';
import filterParallel from './';

export interface IFilterParallel {
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>, limit: number, array: IOptionalPromise<T>): Promise<T>;
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>, limit: number): (array: IOptionalPromise<T>) => Promise<T>;
<T extends ArrayLike<any>>(iteratee: (value: T[keyof T & number], index: number, array: T) => IOptionalPromise<boolean>): (limit: number) => (array: IOptionalPromise<T>) => Promise<T>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>, limit: number, object: IOptionalPromiseDictionary<T>): Promise<T>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>, limit: number): (object: IOptionalPromiseDictionary<T>) => Promise<T>;
<T>(iteratee: (value: T[keyof T], key: keyof T, object: T) => IOptionalPromise<boolean>): (limit: number) => (object: IOptionalPromiseDictionary<T>) => Promise<T>;
}

/**
* @example
*
* ```typescript
* let comparator = (value: number) => {
* return value % 2 === 0;
* };
*
* let array = Array.from({length:5}, (value, index) => index);
*
* filterParallel(comparator)(void 0, array).then((result: number[])=>{
* console.log(result); // result => [0, 2, 4]
* });
* ```
*/
export default _curry(filterParallel, {length: 3}) as IFilterParallel;
Loading

0 comments on commit c801b97

Please sign in to comment.