├── .editorconfig ├── .github └── workflows │ └── ci.yaml ├── .gitignore ├── .node-version ├── LICENSE ├── README.md ├── docs ├── api-form │ ├── FormActions.md │ └── createForm.md ├── api-router │ ├── Link.md │ ├── RouterActions.md │ ├── createUseRouter.md │ └── getRouterState.md ├── api │ ├── ChainedReducer.md │ ├── Epic.md │ ├── Handle.md │ ├── createModule.md │ ├── createSelector.md │ ├── rx.md │ ├── useActions.md │ ├── useMappedState.md │ └── useSelector.md ├── introduction │ ├── examples.md │ ├── motivation.md │ ├── quick-start.md │ ├── roadmap.md │ └── starter-kits.md └── using-typeless │ ├── actions.md │ ├── code-splitting.md │ └── hmr.md ├── examples ├── .gitignore ├── README.md ├── package.json ├── src │ ├── basic-form │ │ ├── components │ │ │ └── FormInput.tsx │ │ ├── features │ │ │ └── example │ │ │ │ ├── form.ts │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ ├── index.html │ │ └── index.tsx │ ├── basic-hmr │ │ ├── components │ │ │ └── App.tsx │ │ ├── features │ │ │ └── counter │ │ │ │ ├── components │ │ │ │ └── Counter.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ ├── index.html │ │ └── index.tsx │ ├── basic-routing │ │ ├── index.html │ │ ├── index.tsx │ │ └── router.ts │ ├── code-splitting │ │ ├── features │ │ │ ├── main │ │ │ │ ├── components │ │ │ │ │ └── MainView.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ │ ├── subA │ │ │ │ ├── components │ │ │ │ │ └── SubAView.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ │ ├── subB │ │ │ │ ├── components │ │ │ │ │ └── SubBView.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ │ └── subC │ │ │ │ ├── components │ │ │ │ └── SubCView.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ ├── index.html │ │ └── index.tsx │ ├── counter │ │ ├── index.html │ │ └── index.tsx │ ├── libraries.d.ts │ ├── real-api │ │ ├── features │ │ │ └── cat │ │ │ │ ├── components │ │ │ │ └── CatView.tsx │ │ │ │ ├── interface.ts │ │ │ │ ├── module.tsx │ │ │ │ └── symbol.ts │ │ ├── index.html │ │ └── index.tsx │ └── socket-hmr │ │ ├── components │ │ └── App.tsx │ │ ├── features │ │ └── socket │ │ │ ├── components │ │ │ └── SocketView.tsx │ │ │ ├── interface.ts │ │ │ ├── module.tsx │ │ │ └── symbol.ts │ │ ├── index.html │ │ ├── index.tsx │ │ └── socket.tsx ├── tsconfig.json └── yarn.lock ├── lerna.json ├── package.json ├── packages ├── tsconfig.base.json ├── typeless-form │ ├── .prettierignore │ ├── README.md │ ├── __tests__ │ │ ├── type │ │ │ ├── TypeTester.ts │ │ │ ├── createForm.test.ts │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.notStrict.json │ │ └── unit │ │ │ ├── empty.test.ts │ │ │ └── tsconfig.json │ ├── package.json │ ├── src │ │ ├── FormContext.ts │ │ ├── createForm.tsx │ │ └── index.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.json │ └── tslint.json ├── typeless-router │ ├── .babelrc │ ├── .prettierignore │ ├── README.md │ ├── __tests__ │ │ ├── type │ │ │ ├── TypeTester.ts │ │ │ ├── routing.test.ts │ │ │ ├── tsconfig.json │ │ │ └── tsconfig.notStrict.json │ │ └── unit │ │ │ ├── routing.test.tsx │ │ │ └── tsconfig.json │ ├── package.json │ ├── src │ │ ├── Link.tsx │ │ ├── index.ts │ │ ├── module.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.json │ └── tslint.json └── typeless │ ├── .babelrc │ ├── .prettierignore │ ├── README.md │ ├── __tests__ │ ├── type │ │ ├── Epic.test.ts │ │ ├── TypeTester.ts │ │ ├── createModule.test.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.notStrict.json │ │ └── useMappedState.test.ts │ └── unit │ │ ├── ChainedReducer.test.ts │ │ ├── createModule.test.tsx │ │ ├── createSelector.test.ts │ │ ├── custom-scheduler.test.tsx │ │ ├── epic-hmr.test.tsx │ │ ├── epic-ignore.test.tsx │ │ ├── epic-order.test.tsx │ │ ├── epic-unit.test.ts │ │ ├── helpers.tsx │ │ ├── integration.test.tsx │ │ ├── lib.d.ts │ │ ├── registry.test.ts │ │ ├── tsconfig.json │ │ ├── useMappedState.test.tsx │ │ ├── useSelector.test.tsx │ │ └── util.test.ts │ ├── package.json │ ├── rx │ └── package.json │ ├── src │ ├── ChainedReducer.ts │ ├── Epic.ts │ ├── Notify.ts │ ├── Registry.ts │ ├── StateLogger.ts │ ├── Store.ts │ ├── TypelessContext.tsx │ ├── createModule.ts │ ├── createSelector.ts │ ├── index.ts │ ├── onHmr.tsx │ ├── rx │ │ ├── ofType.ts │ │ ├── rx.ts │ │ └── waitForType.ts │ ├── types.ts │ ├── useActions.ts │ ├── useMappedState.ts │ ├── useRegistry.ts │ ├── useSelector.ts │ └── utils.ts │ ├── tsconfig.cjs.json │ ├── tsconfig.json │ └── tslint.json ├── prettier.config.js ├── tsconfig.json ├── tsconfig.prod.json ├── website ├── README.md ├── core │ └── Footer.js ├── i18n │ └── en.json ├── package.json ├── pages │ └── en │ │ ├── help.js │ │ ├── index.js │ │ └── users.js ├── sidebars.json ├── siteConfig.js ├── static │ ├── css │ │ ├── code-block-buttons.css │ │ └── custom.css │ ├── img │ │ ├── dev │ │ │ ├── 001-analysis.svg │ │ │ ├── 002-architecture.svg │ │ │ ├── 003-bug.svg │ │ │ ├── 004-cloud.svg │ │ │ ├── 005-database.svg │ │ │ ├── 006-deployment.svg │ │ │ ├── 007-graphic-design.svg │ │ │ ├── 008-developer.svg │ │ │ ├── 009-development.svg │ │ │ ├── 010-dynamic.svg │ │ │ ├── 011-ecommerce.svg │ │ │ ├── 012-encryption.svg │ │ │ ├── 013-engineering.svg │ │ │ ├── 014-information.svg │ │ │ ├── 015-injection.svg │ │ │ ├── 016-intelligent.svg │ │ │ ├── 017-interaction.svg │ │ │ ├── 018-launch.svg │ │ │ ├── 019-layout.svg │ │ │ ├── 020-mining.svg │ │ │ ├── 021-network.svg │ │ │ ├── 022-platform.svg │ │ │ ├── 023-programming.svg │ │ │ ├── 024-requirement.svg │ │ │ ├── 025-security.svg │ │ │ ├── 026-seo-and-web.svg │ │ │ ├── 027-server.svg │ │ │ ├── 028-server-1.svg │ │ │ ├── 029-server-2.svg │ │ │ ├── 030-support.svg │ │ │ ├── 031-testing.svg │ │ │ ├── 032-ux.svg │ │ │ ├── 033-web.svg │ │ │ ├── 034-website.svg │ │ │ ├── 035-wireframe.svg │ │ │ └── 036-writing.svg │ │ ├── docusaurus.svg │ │ ├── favicon.png │ │ ├── favicon │ │ │ └── favicon.ico │ │ ├── github-brands.svg │ │ ├── logo-white.svg │ │ ├── logo.svg │ │ └── oss_logo.png │ └── js │ │ └── code-block-buttons.js └── yarn.lock └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | #root = true 2 | 3 | [*] 4 | indent_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | max_line_length = 80 10 | indent_size = 2 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.github/workflows/ci.yaml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | pull_request: 5 | branches: [master] 6 | push: 7 | branches: [master] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Get yarn cache directory path 17 | id: yarn-cache-dir-path 18 | run: echo "::set-output name=dir::$(yarn cache dir)" 19 | 20 | - uses: actions/cache@v1 21 | id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) 22 | with: 23 | path: ${{ steps.yarn-cache-dir-path.outputs.dir }} 24 | key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} 25 | restore-keys: | 26 | ${{ runner.os }}-yarn- 27 | 28 | - name: Use Node.js 12 29 | uses: actions/setup-node@v1 30 | with: 31 | node-version: 12.x 32 | 33 | - name: install yarn 34 | run: yarn install --frozen-lockfile 35 | 36 | - name: test 37 | run: yarn run test 38 | 39 | - name: report coverage 40 | run: bash <(curl -s https://codecov.io/bash) 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | coverage 3 | .nyc_output 4 | .DS_Store 5 | *.log 6 | .vscode 7 | .idea 8 | dist 9 | compiled 10 | .awcache 11 | .rpt2_cache 12 | website/build 13 | *.tsbuildinfo 14 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 12.16.3 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2018 Łukasz Sentkiewicz 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # typeless 2 | 3 | TypeScript + React Hooks + RxJS = 😻 4 | 5 |  6 | [](https://www.npmjs.org/package/typeless) 7 | 8 | ## Installation 9 | 10 | Required peer dependencies: `react@^16.8` and `rxjs^@6` 11 | 12 | ```bash 13 | npm i typeless 14 | yarn add typeless 15 | ``` 16 | 17 | ## Why Typeless? 18 | 19 | Creating scalable React apps with TypeScript can be painful. There are many small libraries that can be combined, but none of them provide a complete solution for building complex applications. 20 | `typeless` provide all building blocks: actions creators, reducers, epics with a minimal overhead of type annotation. 21 | 22 | ## Features 23 | 24 | - Designed for TypeScript and type safety. Only minimal type annotations are required, all types are inferred where possible. 25 | - Simple and developer friendly syntax with React hooks. 26 | - Event-driven architecture using RxJS. 27 | - Reducers and epics are loaded dynamically in React components. There is no single `reducers.ts` or `epics.ts` file. 28 | - Code splitting for reducers and epics work out of the box. 29 | - HMR works out of the box. 30 | 31 | ## Quick start 32 | 33 | [https://typeless.js.org/introduction/quick-start](https://typeless.js.org/introduction/quick-start) 34 | 35 | ## License 36 | 37 | MIT 38 | -------------------------------------------------------------------------------- /docs/api-form/FormActions.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: FormActions 3 | title: FormActions 4 | hide_title: true 5 | sidebar_label: FormActions 6 | --- 7 | 8 | 9 | 10 | # FormActions 11 | The actions creators for form module. 12 | 13 | ## Actions 14 | #### Your application can dispatch below actions. 15 | 1. `blur: (field: string)` mark field as touched 16 | 2. `change: (field: string, value: any)` update the field value 17 | 3. `changeMany: (values: object)` update multiple values, if a field is not defined in`values` it won't be set to undefined 18 | 4. `replace: (values: object)` replace all values with the provided values 19 | 5. `touchAll` mark all fields as touched 20 | 6. `submit` validate data and trigger setSubmitFailed/setSubmitSucceeded 21 | 7. `reset` reset the module, clear values, errors and touched status 22 | 8. `resetTouched` reset touched status 23 | 24 | #### Your application should not dispatch below actions, they are used only internally. 25 | 1. `setErrors: (errors: object)` set validation errors (result from `validate` function) 26 | 2. `setSubmitSucceeded` dispatched if submit was successful 27 | 3. `setSubmitFailed` dispatched if submit was not successful (there are validation errors) 28 | 4. `validate` trigger validation -------------------------------------------------------------------------------- /docs/api-router/Link.md: -------------------------------------------------------------------------------- 1 | --- 2 | id: Link 3 | title: Link 4 | hide_title: true 5 | sidebar_label: Link 6 | --- 7 | 8 | 9 | 10 | # Link 11 | A basic react component for navigation. It has exactly the same props as a native `` component. 12 | 13 | #### Example 14 | 15 | ```tsx 16 | import { Link } from 'typeless-router'; 17 | 18 | 19 | export function Foo() { 20 | return ( 21 |
HMR reloads ignored
13 | 14 |HMR reloads handled
17 | 18 |
21 | HMR reloads handled
Start/stop socket
22 |
src/features/components/module.tsx
and edit{' '}
33 | CHANGE_ME
to trigger HMR. This project is maintained by a dedicated group of people.
47 |This project is used by many folks
35 |Are you using this project?
38 | 39 | Add your company 40 | 41 |