├── .eslintrc.json
├── .github
└── workflows
│ └── release.yml
├── .gitignore
├── .prettierrc
├── .travis.yml
├── LICENSE
├── hero.svg
├── package.json
├── readme.md
├── release.config.js
├── rollup.config.js
├── src
└── index.ts
├── tsconfig.json
└── yarn.lock
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "node": true
6 | },
7 | "extends": [
8 | "prettier",
9 | "prettier/react",
10 | "prettier/@typescript-eslint",
11 | "plugin:prettier/recommended",
12 | "plugin:react-hooks/recommended",
13 | "plugin:import/errors",
14 | "plugin:import/warnings",
15 | "prettier",
16 | "prettier/react",
17 | "prettier/@typescript-eslint"
18 | ],
19 | "plugins": ["@typescript-eslint", "react", "react-hooks", "import", "jest", "prettier"],
20 | "parser": "@typescript-eslint/parser",
21 | "parserOptions": {
22 | "ecmaFeatures": {
23 | "jsx": true
24 | },
25 | "ecmaVersion": 2018,
26 | "sourceType": "module",
27 | "rules": {
28 | "curly": ["warn", "multi-line", "consistent"],
29 | "no-console": "off",
30 | "no-empty-pattern": "warn",
31 | "no-duplicate-imports": "error",
32 | "import/no-unresolved": "off",
33 | "import/export": "error",
34 | // https://github.com/typescript-eslint/typescript-eslint/blob/master/docs/getting-started/linting/FAQ.md#eslint-plugin-import
35 | // We recommend you do not use the following import/* rules, as TypeScript provides the same checks as part of standard type checking:
36 | "import/named": "off",
37 | "import/namespace": "off",
38 | "import/default": "off",
39 | "no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
40 | "@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
41 | "@typescript-eslint/no-use-before-define": "off",
42 | "@typescript-eslint/no-empty-function": "off",
43 | "@typescript-eslint/no-empty-interface": "off",
44 | "@typescript-eslint/no-explicit-any": "off",
45 | "jest/consistent-test-it": ["error", { "fn": "it", "withinDescribe": "it" }]
46 | }
47 | },
48 | "settings": {
49 | "react": {
50 | "version": "detect"
51 | },
52 | "import/extensions": [".js", ".jsx", ".ts", ".tsx"],
53 | "import/parsers": {
54 | "@typescript-eslint/parser": [".js", ".jsx", ".ts", ".tsx"]
55 | },
56 | "import/resolver": {
57 | "node": {
58 | "extensions": [".js", ".jsx", ".ts", ".tsx", ".json"],
59 | "paths": ["src"]
60 | },
61 | "alias": {
62 | "extensions": [".js", ".jsx", ".ts", ".tsx", ".json"],
63 | "map": [["react-three-fiber", "./src/targets/web.tsx"]]
64 | }
65 | }
66 | },
67 | "overrides": [
68 | {
69 | "files": ["src"],
70 | "parserOptions": {
71 | "project": "./tsconfig.json"
72 | }
73 | }
74 | ]
75 | }
76 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: release
2 | on:
3 | push:
4 | branches:
5 | - 'main'
6 |
7 | # Cancel any previous run (see: https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#concurrency)
8 | concurrency:
9 | group: ${{ github.workflow }}-${{ github.ref }}
10 | cancel-in-progress: true
11 |
12 | jobs:
13 | release-job:
14 | runs-on: ubuntu-latest
15 | steps:
16 | - uses: actions/checkout@v3
17 | - uses: actions/setup-node@v3
18 | with:
19 | cache: 'yarn'
20 | - id: main
21 | run: |
22 | yarn install
23 | yarn build
24 | yarn release
25 | env:
26 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
27 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # misc
2 | .DS_Store
3 | .env.local
4 | .env.development.local
5 | .env.test.local
6 | .env.production.local
7 |
8 | # Logs
9 | logs
10 | *.log
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 |
15 | # Directory for instrumented libs generated by jscoverage/JSCover
16 | lib-cov
17 |
18 | # Coverage directory used by tools like istanbul
19 | coverage
20 | *.lcov
21 |
22 | # nyc test coverage
23 | .nyc_output
24 |
25 | # Compiled binary addons (https://nodejs.org/api/addons.html)
26 | build/
27 |
28 | # Dependency directories
29 | node_modules/
30 | jspm_packages/
31 |
32 | # TypeScript cache
33 | *.tsbuildinfo
34 |
35 | # Optional eslint cache
36 | .eslintcache
37 |
38 | # Output of 'npm pack'
39 | *.tgz
40 |
41 | # Yarn Integrity file
42 | .yarn-integrity
43 |
44 | # pnpm lock
45 |
46 | pnpm-lock.yaml
47 |
48 | dist
49 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "trailingComma": "es5",
4 | "singleQuote": true,
5 | "tabWidth": 2,
6 | "printWidth": 120
7 | }
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - stable
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Paul Henschel
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.
22 |
--------------------------------------------------------------------------------
/hero.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "suspend-react",
3 | "version": "0.0.0-semantic-release",
4 | "description": "Integrate React Suspense into your apps",
5 | "main": "index.cjs.js",
6 | "module": "index.js",
7 | "types": "index.d.ts",
8 | "sideEffects": false,
9 | "keywords": [
10 | "react",
11 | "suspense",
12 | "resource",
13 | "asset"
14 | ],
15 | "author": "Paul Henschel",
16 | "license": "MIT",
17 | "repository": "pmndrs/suspend-react",
18 | "homepage": "https://github.com/pmndrs/suspend-react#readme",
19 | "husky": {
20 | "hooks": {
21 | "pre-commit": "lint-staged"
22 | }
23 | },
24 | "lint-staged": {
25 | "*.{js,jsx,ts,tsx}": [
26 | "eslint --fix"
27 | ]
28 | },
29 | "scripts": {
30 | "build": "rollup -c",
31 | "postbuild": "tsc --emitDeclarationOnly && npm run copy",
32 | "copy": "copyfiles package.json readme.md LICENSE dist && json -I -f dist/package.json -e \"this.private=false; this.devDependencies=undefined; this.optionalDependencies=undefined; this.scripts=undefined; this.husky=undefined; this.prettier=undefined; this.jest=undefined; this['lint-staged']=undefined;\"",
33 | "release": "semantic-release",
34 | "test": "echo no tests yet"
35 | },
36 | "devDependencies": {
37 | "@babel/core": "7.16.0",
38 | "@babel/plugin-proposal-class-properties": "^7.16.0",
39 | "@babel/plugin-transform-modules-commonjs": "7.16.0",
40 | "@babel/plugin-transform-parameters": "7.16.0",
41 | "@babel/plugin-transform-runtime": "7.16.0",
42 | "@babel/plugin-transform-template-literals": "7.16.0",
43 | "@babel/preset-env": "7.16.0",
44 | "@babel/preset-react": "7.16.0",
45 | "@babel/preset-typescript": "^7.16.0",
46 | "@rollup/plugin-babel": "^5.3.0",
47 | "@rollup/plugin-node-resolve": "^13.0.6",
48 | "@types/jest": "^27.0.2",
49 | "@types/node": "^16.11.6",
50 | "@types/react": "^17.0.33",
51 | "@types/react-dom": "^17.0.10",
52 | "@types/react-test-renderer": "^17.0.1",
53 | "@typescript-eslint/eslint-plugin": "^5.3.0",
54 | "@typescript-eslint/parser": "^5.3.0",
55 | "copyfiles": "^2.4.1",
56 | "eslint": "^8.1.0",
57 | "eslint-config-prettier": "^8.3.0",
58 | "eslint-import-resolver-alias": "^1.1.2",
59 | "eslint-plugin-import": "^2.25.2",
60 | "eslint-plugin-jest": "^25.2.2",
61 | "eslint-plugin-prettier": "^4.0.0",
62 | "eslint-plugin-react": "^7.26.1",
63 | "eslint-plugin-react-hooks": "^4.2.0",
64 | "husky": "^7.0.4",
65 | "json": "^11.0.0",
66 | "lint-staged": "^11.2.6",
67 | "prettier": "^2.4.1",
68 | "react": "^17.0.1",
69 | "rollup": "^2.59.0",
70 | "rollup-plugin-size-snapshot": "^0.12.0",
71 | "rollup-plugin-terser": "^7.0.2",
72 | "semantic-release": "^21.0.5",
73 | "typescript": "^4.4.4"
74 | },
75 | "peerDependencies": {
76 | "react": ">=17.0"
77 | },
78 | "dependencies": {}
79 | }
80 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | [](https://bundlephobia.com/result?p=suspend-react)
2 | [](https://www.npmjs.com/package/suspend-react)
3 |
4 |
5 |
6 |
7 |
8 |
9 | ```shell
10 | npm install suspend-react
11 | ```
12 |
13 | This library integrates your async ops into React suspense. Pending- and error-states are handled at the parental level which frees the individual component from that burden and allows for better orchestration. Think of it as async/await for components. **Works in all React versions >= 16.6**.
14 |
15 | ```jsx
16 | import { Suspense } from 'react'
17 | import { suspend } from 'suspend-react'
18 |
19 | function Post({ id, version }) {
20 | const data = suspend(async () => {
21 | const res = await fetch(`https://hacker-news.firebaseio.com/${version}/item/${id}.json`)
22 | return res.json()
23 | }, [id, version])
24 | return (
25 |