├── src ├── index.ts └── lift-p │ ├── index.ts │ └── __tests__ │ └── liftp.spec.ts ├── babel.config.js ├── .gitignore ├── jest.config.ts ├── tsconfig.json ├── LICENSE ├── package.json └── README.markdown /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './lift-p' 2 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | [ '@babel/preset-env', { targets: { node: 'current' } } ], 4 | '@babel/preset-typescript' 5 | ], 6 | }; 7 | -------------------------------------------------------------------------------- /src/lift-p/index.ts: -------------------------------------------------------------------------------- 1 | export const liftP = (fn: (...values: TParameters[]) => TReturn) => async (...args: Promise[]) => { 2 | return Promise.all(args).then(values => fn(...values)) 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | media_ressources 4 | /dist 5 | /coverage 6 | 7 | # local env files 8 | .env.local 9 | .env.*.local 10 | 11 | # Log files 12 | npm-debug.log* 13 | yarn-debug.log* 14 | yarn-error.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw* 24 | -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | coverageDirectory: "coverage", 3 | testEnvironment: "node", 4 | testMatch: [ "**/__tests__/**/*spec.ts", "**/?(*.)+(spec|test).ts" ], 5 | collectCoverageFrom: [ 6 | "src/**/*.ts", 7 | "!**/node_modules", 8 | "!**/__tests__/**", 9 | "!**/__mocks__/**", 10 | ], 11 | collectCoverage: true, 12 | coverageThreshold: { 13 | "global": { 14 | "statements": 60 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/lift-p/__tests__/liftp.spec.ts: -------------------------------------------------------------------------------- 1 | import { liftP } from "../" 2 | 3 | describe('Lift promise', () => { 4 | let add: (x: number, y: number) => number 5 | let promise1: Promise 6 | let promise2: Promise 7 | 8 | beforeAll(() => { 9 | promise1 = Promise.resolve(1) 10 | promise2 = Promise.resolve(2) 11 | add = (numberX: number, numberY: number) => numberX + numberY 12 | }) 13 | 14 | test('Compare with non-async function result', async () => { 15 | const addFunctionResult = add(1, 2) 16 | const addP = liftP(add) 17 | const result = await addP(promise1, promise2) 18 | 19 | expect(result).toBe(addFunctionResult) 20 | }) 21 | 22 | }) 23 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "src/**/*.ts" 4 | ], 5 | "exclude": [ 6 | "**/node_modules/**", 7 | "**/__tests__/**" 8 | ], 9 | "compilerOptions": { 10 | "outDir": "dist", 11 | "declaration": true, 12 | "target": "ES2016", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ 13 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ 14 | "strict": true, /* Enable all strict type-checking options. */ 15 | "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Code-Oz 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "liftp-js", 3 | "version": "1.1.1", 4 | "description": "Transform parameters of a function to handle promise parameters", 5 | "main": "dist/index.js", 6 | "typings": "dist/index.d.ts", 7 | "files": [ 8 | "dist/" 9 | ], 10 | "scripts": { 11 | "publishVersion": "npm run test && npm run build && npm publish", 12 | "test": "jest --color", 13 | "build": "tsc", 14 | "prod": "node dist/index.js", 15 | "dev": "nodemon src/index.ts" 16 | }, 17 | "author": "Ozanne Thomas codeoz.pro@gmail.com", 18 | "license": "MIT", 19 | "private": false, 20 | "devDependencies": { 21 | "@types/jest": "^26.0.15", 22 | "@babel/core": "^7.14.3", 23 | "@babel/preset-env": "^7.14.4", 24 | "@babel/preset-typescript": "^7.13.0", 25 | "babel-jest": "^27.0.2", 26 | "jest": "^26.6.3", 27 | "nodemon": "^2.0.7", 28 | "ts-jest": "^26.4.4", 29 | "ts-node": "^10.0.0", 30 | "typescript": "^4.1.3" 31 | }, 32 | "homepage": "https://github.com/Code-Oz/lift-promise", 33 | "repository": { 34 | "type": "git", 35 | "url": "https://github.com/Code-Oz/lift-promise.git" 36 | }, 37 | "keywords": [ 38 | "lift", 39 | "async", 40 | "await", 41 | "js", 42 | "promise", 43 | "javascript", 44 | "ts", 45 | "typescript" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | 2 | ![GitHub followers](https://img.shields.io/github/followers/Code-Oz?style=social) 3 | 4 | ![GitHub Repo stars](https://img.shields.io/github/stars/Code-Oz/lift-promise?style=social) 5 | 6 | ## **liftP function** 7 | 8 | ## What is and why ? 9 | 10 | Use lifP when you want to modify a sync function into an async function without manage parameters ! 11 | 12 | Use it if you have the folowing example 13 | 14 | ## Examples of usage 15 | 16 | Let's compare the following case: 17 | 18 | 1) Bad Solution: 19 | 20 | ```ts 21 | // Solution Async / Await 22 | 23 | const add = (x: string, y: number) => x + y 24 | const compute = async () => { 25 | const value1 = await Promise.resolve(3) 26 | const value2 = await Promise.resolve(4) 27 | return add(value1, value2) 28 | } 29 | 30 | // We are unboxing values and reboxing them again since async function 31 | ``` 32 | 33 | And why don't directly manipulate promise? 34 | 35 | Yes but you have to rewrite `add` function 36 | 37 | Why not use the lifP function? This will transform the function for manipulating promise as parameters ! 38 | 39 | 2) Good Solution: 40 | 41 | ```ts 42 | // Solution liftP 43 | 44 | const add = (x: string, y: number) => x + y 45 | // Lift add function for change params to promise 46 | const addP = liftP(add) 47 | ​ 48 | const compute = () => { 49 | const promise1 = Promise.resolve(3) 50 | const promise2 = Promise.resolve(4) 51 | 52 | return addP(promise1, promise2) 53 | } 54 | // Here we are not unbox value ! We are currently working with promise as synchronous code ! 55 | ``` 56 | 57 | Summarize: 58 | 59 | Promise Lifting changes the focus from converting our values to work with our functions, to converting the functions to work with our values. 60 | 61 | ​ 62 | Promise Lifted code appears structurally similar to synchronous code. 63 | 64 | ​ 65 | Boxed values are no longer unboxed and then reboxed. 66 | 67 | ​ 68 | From https://blog.bitsrc.io/out-with-async-await-and-in-with-promise-lifting-c42882a474fd 69 | 70 | Github => https://github.com/Code-Oz/lift-promise 71 | --------------------------------------------------------------------------------