Skip to content

Commit e763c6f

Browse files
committed
render-promise
The renderPromise function accepts a component and wraps it in a function that returns a Promise. When this function is called, the component is rendered within an AsyncRoot. The component receives two special props: resolve and reject. * When the resolve prop is called within the component, the component will be unmounted and the Promise will be resolved with the provided value. * If the reject prop is called within the component, the Promise will be rejected with the provided error. This allows for easy rendering of components asynchronously, with the ability to control the flow of execution through Promise resolution and rejection.
0 parents  commit e763c6f

33 files changed

+12516
-0
lines changed

.eslintrc.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"extends": ["airbnb-base", "airbnb-typescript/base", "prettier"],
3+
"parserOptions": {
4+
"project": "./tsconfig.json"
5+
},
6+
"ignorePatterns": [".eslintrc.js", "jest.config.js", "jest.setup.js"],
7+
"plugins": ["prettier"],
8+
"rules": {
9+
"prefer-regex-literals": 0,
10+
"max-classes-per-file": 0,
11+
"no-plusplus": 0,
12+
"generator-star-spacing": 0,
13+
"no-restricted-exports": 0,
14+
"no-restricted-syntax": 0,
15+
"no-param-reassign": 0,
16+
"no-underscore-dangle": 0,
17+
"no-continue": 0,
18+
"no-await-in-loop": 0,
19+
"import/no-cycle": 0,
20+
"no-bitwise": 0
21+
}
22+
}

.github/workflows/main.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: CI
2+
on: [push]
3+
jobs:
4+
build:
5+
name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }}
6+
7+
runs-on: ${{ matrix.os }}
8+
strategy:
9+
matrix:
10+
node: ['18.x', '20.x']
11+
os: [ubuntu-latest, windows-latest, macOS-latest]
12+
13+
steps:
14+
- name: Checkout repo
15+
uses: actions/checkout@v2
16+
17+
- name: Use Node ${{ matrix.node }}
18+
uses: actions/setup-node@v1
19+
with:
20+
node-version: ${{ matrix.node }}
21+
22+
- name: Install deps and build (with cache)
23+
uses: bahmutov/npm-install@v1
24+
25+
- name: Lint
26+
run: yarn lint
27+
28+
- name: Test
29+
run: yarn test --ci --coverage --maxWorkers=2
30+
31+
- name: Build
32+
run: yarn build

.github/workflows/size.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name: size
2+
on: [pull_request]
3+
jobs:
4+
size:
5+
runs-on: ubuntu-latest
6+
env:
7+
CI_JOB_NUMBER: 1
8+
steps:
9+
- uses: actions/checkout@v1
10+
- uses: andresz1/size-limit-action@v1
11+
with:
12+
github_token: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.log
2+
.DS_Store
3+
node_modules
4+
.cache
5+
dist

.prettierrc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"trailingComma": "es5",
8+
"bracketSpacing": true,
9+
"jsxSingleQuote": false,
10+
"arrowParens": "always",
11+
"proseWrap": "never",
12+
"htmlWhitespaceSensitivity": "strict",
13+
"endOfLine": "lf"
14+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 qkudev
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# `render-promise`
2+
3+
`render-promise` is a lightweight JavaScript library that simplifies the process of rendering components asynchronously by wrapping them in a function that returns a Promise.
4+
5+
## Installation
6+
7+
You can install render-promise via npm:
8+
9+
```
10+
npm install @qkudev/render-promise
11+
```
12+
13+
Usage
14+
To use `render-promise`, simply import it into your project:
15+
16+
```
17+
import { renderPromise } from 'render-promise';
18+
```
19+
20+
Then, you can use the `renderPromise` function to render your component asynchronously:
21+
22+
```
23+
const myComponent = (props) => {
24+
return (
25+
<div>
26+
{/_ Your component JSX _/}
27+
</div>
28+
);
29+
};
30+
31+
const [asyncFunction, Component] = renderPromise(myComponent);
32+
33+
asyncFunction({ /_ props _/ })
34+
.then(value => {
35+
// Handle success
36+
})
37+
.catch(error => {
38+
// Handle error
39+
});
40+
```
41+
42+
## How It Works
43+
44+
The `renderPromise` function accepts a component and wraps it in a function that returns a Promise. When this function is called, the component is rendered within an `AsyncRoot`. The component receives two special props: `resolve` and `reject`.
45+
46+
- When the resolve prop is called within the component, the component will be unmounted and the Promise will be resolved with the provided value.
47+
- If the reject prop is called within the component, the Promise will be rejected with the provided error.
48+
49+
This allows for easy rendering of components asynchronously, with the ability to control the flow of execution through Promise resolution and rejection.
50+
51+
## Example
52+
53+
```
54+
import renderPromise from 'render-promise';
55+
56+
const AreYourSure = ({ resolve }) => {
57+
const onAccept = () => {
58+
resolve(true)
59+
}
60+
61+
const onCancel = () => {
62+
resolve(false)
63+
}
64+
65+
66+
return (
67+
<Modal>
68+
<p>Are You sure?</p>
69+
<button type="button" onClick={onAccept}>Yes</button>
70+
<button type="button" onClick={onCancel}>No</button>
71+
</Modal>
72+
);
73+
};
74+
75+
const [areYouSure, AsyncAreYouSure] = renderPromise<boolean>(AreYouSure);
76+
77+
// Render `<AsyncAreYouSure/>` and later in thunk/saga/etc.
78+
79+
const deleteUser = createAsyncThunk('deleteUser', async () => {
80+
// call the component render as async function
81+
const sure = await areYouSure();
82+
if (!sure) {
83+
return;
84+
}
85+
86+
// do the effect ...
87+
})
88+
```
89+
90+
## License
91+
92+
This project is licensed under the MIT License - see the `LICENSE` file for details.
93+
94+
Feel free to extend or modify this `README` according to your preferences!

example/.eslintrc.cjs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
root: true,
3+
env: { browser: true, es2020: true },
4+
extends: [
5+
'eslint:recommended',
6+
'plugin:@typescript-eslint/recommended',
7+
'plugin:react-hooks/recommended',
8+
],
9+
ignorePatterns: ['dist', '.eslintrc.cjs'],
10+
parser: '@typescript-eslint/parser',
11+
plugins: ['react-refresh'],
12+
rules: {
13+
'react-refresh/only-export-components': [
14+
'warn',
15+
{ allowConstantExport: true },
16+
],
17+
},
18+
}

example/.gitignore

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

example/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# React + TypeScript + Vite
2+
3+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4+
5+
Currently, two official plugins are available:
6+
7+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
9+
10+
## Expanding the ESLint configuration
11+
12+
If you are developing a production application, we recommend updating the configuration to enable type aware lint rules:
13+
14+
- Configure the top-level `parserOptions` property like this:
15+
16+
```js
17+
export default {
18+
// other rules...
19+
parserOptions: {
20+
ecmaVersion: 'latest',
21+
sourceType: 'module',
22+
project: ['./tsconfig.json', './tsconfig.node.json'],
23+
tsconfigRootDir: __dirname,
24+
},
25+
}
26+
```
27+
28+
- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked`
29+
- Optionally add `plugin:@typescript-eslint/stylistic-type-checked`
30+
- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list

0 commit comments

Comments
 (0)