├── examples ├── preact │ └── counter │ │ ├── .gitignore │ │ ├── assets │ │ ├── icon.png │ │ └── favicon.ico │ │ ├── store.js │ │ ├── actions.js │ │ ├── style.css │ │ ├── index.js │ │ ├── manifest.json │ │ ├── Counter.js │ │ └── package.json ├── react-native │ └── counter │ │ ├── .babelrc │ │ ├── app.json │ │ ├── android │ │ ├── settings.gradle │ │ ├── app │ │ │ ├── src │ │ │ │ └── main │ │ │ │ │ ├── res │ │ │ │ │ ├── values │ │ │ │ │ │ ├── strings.xml │ │ │ │ │ │ └── styles.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ └── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── counter │ │ │ │ │ │ ├── MainActivity.java │ │ │ │ │ │ └── MainApplication.java │ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── BUCK │ │ │ └── proguard-rules.pro │ │ ├── keystores │ │ │ ├── debug.keystore.properties │ │ │ └── BUCK │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ ├── gradle-wrapper.jar │ │ │ │ └── gradle-wrapper.properties │ │ ├── build.gradle │ │ ├── gradle.properties │ │ └── gradlew.bat │ │ ├── README.md │ │ ├── index.js │ │ ├── app │ │ ├── actions.js │ │ ├── store.js │ │ ├── index.js │ │ └── Counter.js │ │ ├── ios │ │ ├── counter │ │ │ ├── AppDelegate.h │ │ │ ├── main.m │ │ │ ├── Images.xcassets │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ └── Contents.json │ │ │ ├── AppDelegate.m │ │ │ ├── Info.plist │ │ │ └── Base.lproj │ │ │ │ └── LaunchScreen.xib │ │ ├── counterTests │ │ │ ├── Info.plist │ │ │ └── counterTests.m │ │ ├── counter-tvOSTests │ │ │ └── Info.plist │ │ └── counter-tvOS │ │ │ └── Info.plist │ │ ├── package.json │ │ └── .gitignore ├── react │ ├── chat │ │ ├── mock │ │ │ └── db.json │ │ ├── src │ │ │ ├── modules │ │ │ │ ├── user │ │ │ │ │ ├── index.js │ │ │ │ │ ├── apiRoutes.js │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ ├── apiRoutes.spec.js.snap │ │ │ │ │ │ ├── page.spec.js.snap │ │ │ │ │ │ └── pageContent.spec.js.snap │ │ │ │ │ ├── apiRoutes.spec.js │ │ │ │ │ ├── actions.js │ │ │ │ │ ├── services.js │ │ │ │ │ ├── page.js │ │ │ │ │ ├── pageContent.js │ │ │ │ │ ├── actions.spec.js │ │ │ │ │ ├── pageContent.spec.js │ │ │ │ │ ├── services.spec.js │ │ │ │ │ └── page.spec.js │ │ │ │ ├── message │ │ │ │ │ ├── index.js │ │ │ │ │ ├── apiRoutes.js │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ └── apiRoutes.spec.js.snap │ │ │ │ │ ├── apiRoutes.spec.js │ │ │ │ │ ├── components │ │ │ │ │ │ ├── messageListItem.js │ │ │ │ │ │ ├── messageList.js │ │ │ │ │ │ ├── __snapshots__ │ │ │ │ │ │ │ ├── message.spec.js.snap │ │ │ │ │ │ │ ├── messageListItem.spec.js.snap │ │ │ │ │ │ │ ├── messageForm.spec.js.snap │ │ │ │ │ │ │ └── messageList.spec.js.snap │ │ │ │ │ │ ├── message.spec.js │ │ │ │ │ │ ├── message.js │ │ │ │ │ │ ├── messageForm.js │ │ │ │ │ │ ├── messageList.spec.js │ │ │ │ │ │ ├── messageListItem.spec.js │ │ │ │ │ │ └── messageForm.spec.js │ │ │ │ │ ├── page.js │ │ │ │ │ ├── actions.js │ │ │ │ │ ├── services.js │ │ │ │ │ ├── page.spec.js │ │ │ │ │ ├── actions.spec.js │ │ │ │ │ └── services.spec.js │ │ │ │ ├── shared │ │ │ │ │ ├── index.js │ │ │ │ │ └── apiClient.js │ │ │ │ └── index.js │ │ │ ├── utils │ │ │ │ ├── dateFormatter.js │ │ │ │ ├── localStorage.js │ │ │ │ ├── functional.js │ │ │ │ ├── index.js │ │ │ │ ├── dateFormatter.spec.js │ │ │ │ ├── object.js │ │ │ │ ├── functional.spec.js │ │ │ │ ├── localStorage.spec.js │ │ │ │ └── object.spec.js │ │ │ ├── setupTests.js │ │ │ ├── routes.spec.js │ │ │ ├── index.js │ │ │ ├── __snapshots__ │ │ │ │ └── routes.spec.js.snap │ │ │ ├── routes.js │ │ │ ├── store.js │ │ │ └── store.spec.js │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── .editorconfig │ │ ├── .gitignore │ │ ├── README.md │ │ └── package.json │ ├── counter │ │ ├── README.md │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── store.js │ │ │ ├── index.js │ │ │ ├── actions.js │ │ │ ├── App.js │ │ │ └── Counter.js │ │ ├── .gitignore │ │ └── package.json │ ├── counter-hooks │ │ ├── README.md │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── store.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ └── Counter.js │ │ ├── .gitignore │ │ └── package.json │ ├── material-ui-counter │ │ ├── public │ │ │ ├── favicon.ico │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── README.md │ │ ├── src │ │ │ ├── store.js │ │ │ ├── actions.js │ │ │ ├── App.js │ │ │ ├── index.js │ │ │ └── Counter.js │ │ ├── .gitignore │ │ └── package.json │ ├── react-router │ │ ├── src │ │ │ ├── store.js │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ ├── components │ │ │ │ ├── Route1.js │ │ │ │ └── Route2.js │ │ │ ├── App.js │ │ │ └── createServiceWorker.js │ │ ├── README.md │ │ ├── public │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── .gitignore │ │ └── package.json │ └── ssr │ │ ├── src │ │ ├── app │ │ │ ├── actions.js │ │ │ ├── App.js │ │ │ └── Counter.js │ │ ├── client │ │ │ └── index.js │ │ ├── server │ │ │ ├── util.js │ │ │ └── index.js │ │ └── run.js │ │ ├── webpack │ │ ├── common.config.js │ │ ├── paths.js │ │ ├── server.config.js │ │ └── client.config.js │ │ ├── babelConfig.js │ │ ├── package.json │ │ └── README.md ├── svelte │ └── counter │ │ ├── README.md │ │ ├── src │ │ ├── main.ts │ │ ├── typings │ │ │ ├── svelte-shims.d.ts │ │ │ └── svelte.d.ts │ │ ├── store.ts │ │ ├── actions.ts │ │ ├── App.html │ │ └── components │ │ │ └── Counter.html │ │ ├── public │ │ └── index.html │ │ ├── .gitignore │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── rollup.config.js └── vue │ └── counter │ ├── actions.js │ ├── store.js │ ├── app.js │ ├── public │ └── index.html │ ├── .gitignore │ ├── package.json │ ├── Counter.vue │ └── rollup.config.js ├── .npmrc ├── src ├── devtools │ └── index.ts ├── vue │ ├── index.ts │ └── components │ │ ├── connect.ts │ │ └── connect.spec.ts ├── index.ts ├── middleware │ ├── index.ts │ ├── applyMiddleware.ts │ └── applyMiddleware.spec.ts ├── svelte │ ├── index.ts │ └── components │ │ ├── connect.ts │ │ └── svelte.spec.ts ├── utils │ ├── index.ts │ ├── shallowEqual.ts │ ├── set.tsx │ ├── combineActions.ts │ ├── propsValidation.ts │ ├── bindAction.ts │ ├── getDiff.ts │ ├── bindActions.ts │ ├── combineActions.spec.ts │ ├── bindAction.spec.ts │ └── bindActions.spec.ts ├── preact │ ├── index.ts │ ├── components │ │ ├── Provider.tsx │ │ ├── Provider.spec.tsx │ │ └── Connect.tsx │ └── tsconfig.json ├── interfaces │ ├── Props.ts │ └── Store.ts ├── react │ ├── hooks │ │ ├── useStore.ts │ │ ├── useAction.ts │ │ ├── useStore.spec.tsx │ │ ├── useSelector.spec.tsx │ │ ├── useAction.spec.tsx │ │ └── useSelector.ts │ ├── components │ │ ├── Context.tsx │ │ ├── Provider.tsx │ │ ├── Provider.spec.tsx │ │ └── connect.tsx │ └── index.ts ├── types │ └── index.ts └── store │ ├── createStore.ts │ └── createStore.spec.ts ├── .editorconfig ├── .travis.yml ├── config ├── preprocessor.js └── testSetup.js ├── CONTRIBUTING.md ├── tsconfig.json ├── .gitignore ├── tslint.json ├── LICENSE ├── rollup.config.js ├── package.json └── CODE_OF_CONDUCT.md /examples/preact/counter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry=http://registry.npmjs.org/ 2 | save-exact=true 3 | -------------------------------------------------------------------------------- /src/devtools/index.ts: -------------------------------------------------------------------------------- 1 | export { connect } from "./devtoolsMiddleware"; 2 | -------------------------------------------------------------------------------- /examples/react-native/counter/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/react/chat/mock/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "messages": [ 3 | ], 4 | "users": [ 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /src/vue/index.ts: -------------------------------------------------------------------------------- 1 | import { connect } from "./components/connect"; 2 | 3 | export { connect }; 4 | -------------------------------------------------------------------------------- /examples/react-native/counter/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter", 3 | "displayName": "counter" 4 | } -------------------------------------------------------------------------------- /examples/react/counter/README.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | A simple app built with react using redux-zero. 4 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import createStore from "./store/createStore"; 2 | 3 | export default createStore; 4 | -------------------------------------------------------------------------------- /src/middleware/index.ts: -------------------------------------------------------------------------------- 1 | import applyMiddleware from "./applyMiddleware"; 2 | export { applyMiddleware }; 3 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'counter' 2 | 3 | include ':app' 4 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/README.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | A simple app built with react using redux-zero. 4 | -------------------------------------------------------------------------------- /examples/react-native/counter/README.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | A simple app built with react-native using redux-zero. 4 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/index.js: -------------------------------------------------------------------------------- 1 | import page from './page'; 2 | 3 | export default { 4 | page 5 | }; 6 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/index.js: -------------------------------------------------------------------------------- 1 | import page from './page'; 2 | 3 | export default { 4 | page, 5 | }; 6 | -------------------------------------------------------------------------------- /src/svelte/index.ts: -------------------------------------------------------------------------------- 1 | import { connect, getActions } from "./components/connect"; 2 | 3 | export { connect, getActions }; 4 | -------------------------------------------------------------------------------- /examples/react/chat/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react/chat/public/favicon.ico -------------------------------------------------------------------------------- /examples/preact/counter/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/preact/counter/assets/icon.png -------------------------------------------------------------------------------- /examples/react/chat/src/modules/shared/index.js: -------------------------------------------------------------------------------- 1 | import apiClient from './apiClient'; 2 | 3 | export default { 4 | apiClient, 5 | }; 6 | -------------------------------------------------------------------------------- /examples/preact/counter/assets/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/preact/counter/assets/favicon.ico -------------------------------------------------------------------------------- /examples/react/chat/src/utils/dateFormatter.js: -------------------------------------------------------------------------------- 1 | export function format(date) { 2 | return new Date(parseInt(date)).toLocaleString(); 3 | } 4 | -------------------------------------------------------------------------------- /examples/react/counter/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react/counter/public/favicon.ico -------------------------------------------------------------------------------- /examples/svelte/counter/README.md: -------------------------------------------------------------------------------- 1 | # Counter 2 | 3 | A simple counter built with [Svelte](https://svelte.technology/) using redux-zero. 4 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/main.ts: -------------------------------------------------------------------------------- 1 | import App from './App.html'; 2 | 3 | const app = new App({ 4 | target: document.querySelector('#app'), 5 | }); -------------------------------------------------------------------------------- /examples/react/counter-hooks/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react/counter-hooks/public/favicon.ico -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | counter 3 | 4 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/typings/svelte-shims.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.html" { 2 | // import Svelte from "svelte"; 3 | export default Svelte; 4 | } -------------------------------------------------------------------------------- /examples/react/material-ui-counter/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react/material-ui-counter/public/favicon.ico -------------------------------------------------------------------------------- /examples/react/react-router/src/store.js: -------------------------------------------------------------------------------- 1 | import createStore from 'redux-zero'; 2 | 3 | const store = createStore({ count: 1 }); 4 | 5 | export default store; 6 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import bindActions from "./bindActions"; 2 | import combineActions from "./combineActions"; 3 | 4 | export { bindActions, combineActions }; 5 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/index.js: -------------------------------------------------------------------------------- 1 | import user from './user'; 2 | import message from './message'; 3 | 4 | export default { 5 | user, 6 | message, 7 | } 8 | -------------------------------------------------------------------------------- /examples/preact/counter/store.js: -------------------------------------------------------------------------------- 1 | import createStore from "redux-zero"; 2 | 3 | const initialState = { count: 1 }; 4 | 5 | export default createStore(initialState); 6 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/README.md: -------------------------------------------------------------------------------- 1 | # Material-UI Counter 2 | 3 | A simple app built with react using redux-zero and [http://www.material-ui.com/](Material-UI). 4 | -------------------------------------------------------------------------------- /src/preact/index.ts: -------------------------------------------------------------------------------- 1 | import connect, { Connect } from "./components/Connect"; 2 | import Provider from "./components/Provider"; 3 | 4 | export { connect, Provider, Connect }; 5 | -------------------------------------------------------------------------------- /examples/react-native/counter/index.js: -------------------------------------------------------------------------------- 1 | import { AppRegistry } from 'react-native'; 2 | import App from './app/index'; 3 | 4 | AppRegistry.registerComponent('counter', () => App); 5 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/shared/apiClient.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export default axios.create({ 4 | baseURL: process.env.REACT_APP_API_BASE_URL, 5 | }); 6 | -------------------------------------------------------------------------------- /examples/react/react-router/src/actions.js: -------------------------------------------------------------------------------- 1 | export default { 2 | decrement: ({ count }) => ({ count: count - 1 }), 3 | increment: ({ count }) => ({ count: count + 1 }), 4 | }; 5 | -------------------------------------------------------------------------------- /src/interfaces/Props.ts: -------------------------------------------------------------------------------- 1 | import Store from "./Store"; 2 | 3 | export default interface Props { 4 | store: Store; 5 | children: JSX.Element[] | JSX.Element; 6 | } 7 | -------------------------------------------------------------------------------- /examples/preact/counter/actions.js: -------------------------------------------------------------------------------- 1 | export default store => ({ 2 | decrement: state => ({ count: state.count - 1 }), 3 | increment: state => ({ count: state.count + 1 }) 4 | }); 5 | -------------------------------------------------------------------------------- /examples/vue/counter/actions.js: -------------------------------------------------------------------------------- 1 | export const actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }) 4 | }); -------------------------------------------------------------------------------- /examples/vue/counter/store.js: -------------------------------------------------------------------------------- 1 | import createStore from "redux-zero"; 2 | 3 | const initialState = { count: 0 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_size = 2 7 | indent_style = space 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /examples/react-native/counter/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/apiRoutes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | get index() { return '/users' }, 3 | get lastUser() { return `${this.index}?_sort=id&_order=desc&_limit=1` }, 4 | }; 5 | -------------------------------------------------------------------------------- /examples/react/counter/src/store.js: -------------------------------------------------------------------------------- 1 | import createStore from "redux-zero"; 2 | 3 | const initialState = { count: 1 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; 7 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react-native/counter/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /examples/react/counter-hooks/src/store.js: -------------------------------------------------------------------------------- 1 | import createStore from "redux-zero"; 2 | 3 | const initialState = { count: 1 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; 7 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/store.ts: -------------------------------------------------------------------------------- 1 | import createStore from 'redux-zero'; 2 | 3 | const initialState = { count: 0 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; -------------------------------------------------------------------------------- /examples/react-native/counter/app/actions.js: -------------------------------------------------------------------------------- 1 | export default actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }) 4 | }); 5 | -------------------------------------------------------------------------------- /examples/react-native/counter/app/store.js: -------------------------------------------------------------------------------- 1 | import createStore from "redux-zero"; 2 | 3 | const initialState = { count: 0 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; 7 | -------------------------------------------------------------------------------- /examples/react/counter/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import App from './App'; 5 | 6 | ReactDOM.render(, document.getElementById('root')); 7 | -------------------------------------------------------------------------------- /examples/svelte/counter/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/actions.ts: -------------------------------------------------------------------------------- 1 | export const actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }) 4 | }); 5 | -------------------------------------------------------------------------------- /examples/react/chat/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true -------------------------------------------------------------------------------- /examples/react/counter-hooks/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | import App from './App'; 5 | 6 | ReactDOM.render(, document.getElementById('root')); 7 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/src/store.js: -------------------------------------------------------------------------------- 1 | import createStore from 'redux-zero'; 2 | 3 | const initialState = { count: 1 }; 4 | const store = createStore(initialState); 5 | 6 | export default store; 7 | -------------------------------------------------------------------------------- /examples/react/ssr/src/app/actions.js: -------------------------------------------------------------------------------- 1 | const actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }) 4 | }) 5 | 6 | export default actions -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react-native/counter/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react-native/counter/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react-native/counter/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /examples/react/counter/src/actions.js: -------------------------------------------------------------------------------- 1 | const actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }) 4 | }); 5 | 6 | export default actions; 7 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redux-zero/redux-zero/HEAD/examples/react-native/counter/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /src/utils/shallowEqual.ts: -------------------------------------------------------------------------------- 1 | export default function shallowEqual(a: object, b: object) { 2 | for (const i in a) if (a[i] !== b[i]) return false; 3 | for (const i in b) if (!(i in a)) return false; 4 | return true; 5 | } 6 | -------------------------------------------------------------------------------- /examples/react/react-router/README.md: -------------------------------------------------------------------------------- 1 | # react-router 2 | 3 | A simple app built with react using redux-zero and react-router. 4 | 5 | Started from [rmlSardinha/redux-zero-router](https://github.com/rmlSardinha/redux-zero-router) -------------------------------------------------------------------------------- /examples/react-native/counter/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = "debug", 3 | properties = "debug.keystore.properties", 4 | store = "debug.keystore", 5 | visibility = [ 6 | "PUBLIC", 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/src/actions.js: -------------------------------------------------------------------------------- 1 | const actions = store => ({ 2 | increment: state => ({ count: state.count + 1 }), 3 | decrement: state => ({ count: state.count - 1 }), 4 | }); 5 | 6 | export default actions; 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - "8" 5 | branches: 6 | only: 7 | - master 8 | before_install: 9 | - npm i -g npm@^5.4.2 10 | before_script: 11 | - npm prune 12 | script: 13 | - npm run build 14 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/apiRoutes.js: -------------------------------------------------------------------------------- 1 | export default { 2 | allMessagesFromDate(datetime) { 3 | return `/messages?createdAt_gte=${datetime}` 4 | }, 5 | get createMessage() { 6 | return '/messages'; 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /examples/vue/counter/app.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Counter from './Counter.vue' 3 | import store from './store' 4 | 5 | Vue.prototype.$store = store; 6 | 7 | new Vue({ 8 | el: '#app', 9 | render: h => h(Counter) 10 | }); -------------------------------------------------------------------------------- /src/react/hooks/useStore.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import Context from "../components/Context"; 3 | import Store from "../../interfaces/Store"; 4 | 5 | export function useStore(): Store { 6 | return useContext(Context); 7 | } 8 | -------------------------------------------------------------------------------- /src/interfaces/Store.ts: -------------------------------------------------------------------------------- 1 | export default interface Store { 2 | middleware(...args: any[]): void; 3 | setState(f: ((state: S) => Partial) | Partial): void; 4 | subscribe(f: Function): () => void; 5 | getState(): S; 6 | reset(): void; 7 | } 8 | -------------------------------------------------------------------------------- /src/utils/set.tsx: -------------------------------------------------------------------------------- 1 | import Store from "../interfaces/Store"; 2 | 3 | export default function set(store: Store, ret: any): Promise | void { 4 | if (ret != null) { 5 | if (ret.then) return ret.then(store.setState); 6 | store.setState(ret); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/preact/counter/style.css: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | font: 14px/1.21 "Helvetica Neue", arial, sans-serif; 4 | font-weight: 400; 5 | } 6 | 7 | body { 8 | display: flex; 9 | justify-content: center; 10 | } 11 | 12 | h1 { 13 | text-align: center; 14 | } 15 | -------------------------------------------------------------------------------- /src/utils/combineActions.ts: -------------------------------------------------------------------------------- 1 | export default (...actions: any[]) => (...actionsParams: any[]) => 2 | actions.reduce( 3 | (acc, action) => ({ 4 | ...acc, 5 | ...(typeof action === "function" ? action(...actionsParams) : action) 6 | }), 7 | {} 8 | ); 9 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/localStorage.js: -------------------------------------------------------------------------------- 1 | export function setJSONData(key, data) { 2 | localStorage.setItem(key, JSON.stringify(data)); 3 | return data; 4 | } 5 | 6 | export function getJSONData(key) { 7 | return JSON.parse(localStorage.getItem(key) || '{}'); 8 | } 9 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/App.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 14 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip 6 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/functional.js: -------------------------------------------------------------------------------- 1 | export function compose(...args) { 2 | return args.reduce((accumulator, currentFunction) => (...params) => { 3 | const result = currentFunction(...params); 4 | return result.then ? result.then(accumulator) : accumulator(result); 5 | }); 6 | } 7 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/__snapshots__/apiRoutes.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test API Routes unit Check if structure keeps equal 1`] = ` 4 | Object { 5 | "index": "/users", 6 | "lastUser": "/users?_sort=id&_order=desc&_limit=1", 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /examples/preact/counter/index.js: -------------------------------------------------------------------------------- 1 | import "./style"; 2 | 3 | import { Provider } from "redux-zero/preact"; 4 | 5 | import store from "./store"; 6 | 7 | import Counter from "./Counter"; 8 | 9 | export default () => ( 10 | 11 | 12 | 13 | ); 14 | -------------------------------------------------------------------------------- /examples/react/ssr/src/app/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Provider } from 'redux-zero/react' 3 | 4 | import Counter from 'Counter' 5 | 6 | function App(store){ 7 | return( 8 | 9 | 10 | 11 | ) 12 | } 13 | 14 | export default App -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/__snapshots__/page.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Page container unit Connect should map props correctly 1`] = ` 4 | Object { 5 | "currentUser": Object { 6 | "name": "", 7 | }, 8 | "userName": " ", 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /src/utils/propsValidation.ts: -------------------------------------------------------------------------------- 1 | export default function propsValidation( 2 | props: object, 3 | propName: string, 4 | componentName: string 5 | ) { 6 | if (typeof props === "object") { 7 | return null; 8 | } 9 | return new Error(`Invalid prop ${propName} supplied to ${componentName}`); 10 | } 11 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/__snapshots__/apiRoutes.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test API Routes unit Check if structure keeps equal 1`] = ` 4 | Object { 5 | "allMessagesFromDate": "/messages?createdAt_gte=undefined", 6 | "createMessage": "/messages", 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /src/react/components/Context.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | let Context; 4 | 5 | if ("createContext" in React) { 6 | Context = React.createContext(undefined); 7 | } else { 8 | Context = { 9 | Provider: ({ children }) => React.Children.only(children) 10 | }; 11 | } 12 | 13 | export default Context; 14 | -------------------------------------------------------------------------------- /examples/react/counter/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from "redux-zero/react"; 3 | 4 | import store from "./store"; 5 | 6 | import Counter from "./Counter"; 7 | 8 | const App = () => ( 9 | 10 | 11 | 12 | ); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from "redux-zero/react"; 3 | 4 | import store from "./store"; 5 | 6 | import Counter from "./Counter"; 7 | 8 | const App = () => ( 9 | 10 | 11 | 12 | ); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /examples/react/ssr/webpack/common.config.js: -------------------------------------------------------------------------------- 1 | const PATHS = require('./paths') 2 | 3 | const commonConfig = { 4 | context: PATHS.SRC, 5 | resolve: { 6 | extensions: [".js", ".css", ".less", ".jsx", ".json"], 7 | modules: [PATHS.APP, PATHS.CLIENT, PATHS.SERVER, PATHS.NODE_MODULES] 8 | } 9 | } 10 | 11 | module.exports = commonConfig -------------------------------------------------------------------------------- /examples/react-native/counter/app/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from "redux-zero/react"; 3 | import Counter from './Counter'; 4 | import store from './store'; 5 | 6 | export default function App() { 7 | return ( 8 | 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/index.js: -------------------------------------------------------------------------------- 1 | import * as dateFormatter from './dateFormatter'; 2 | import * as localStorage from './localStorage'; 3 | import * as object from './object'; 4 | import * as functional from './functional'; 5 | 6 | export default { 7 | dateFormatter, 8 | localStorage, 9 | object, 10 | functional, 11 | }; 12 | -------------------------------------------------------------------------------- /examples/react/chat/src/setupTests.js: -------------------------------------------------------------------------------- 1 | import { configure } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | 4 | configure({ adapter: new Adapter() }); 5 | 6 | const localStorageMock = { 7 | getItem: jest.fn(), 8 | setItem: jest.fn(), 9 | clear: jest.fn() 10 | }; 11 | 12 | global.localStorage = localStorageMock 13 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/dateFormatter.spec.js: -------------------------------------------------------------------------------- 1 | import { format } from './dateFormatter'; 2 | 3 | describe('Test dateFormatter utility script unit', () => { 4 | it('Check if dateFormatter works correctly', () => { 5 | const now = new Date(); 6 | 7 | expect(format(now.getTime())).toBe(now.toLocaleString()); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/object.js: -------------------------------------------------------------------------------- 1 | import { mapValues, isFunction, isObject } from 'lodash'; 2 | 3 | export function generateNewObjectWithAllFunctionsInvoked(object) { 4 | return mapValues(object, value => isFunction(value) 5 | ? value() 6 | : isObject(value) ? generateNewObjectWithAllFunctionsInvoked(value) : value 7 | ); 8 | } 9 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/src/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from 'redux-zero/react'; 3 | 4 | import store from './store'; 5 | 6 | import Counter from './Counter'; 7 | 8 | const App = () => ( 9 | 10 | 11 | 12 | ); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /src/react/index.ts: -------------------------------------------------------------------------------- 1 | import connect, { Connect } from "./components/connect"; 2 | import Provider from "./components/Provider"; 3 | import { useStore } from "./hooks/useStore"; 4 | import { useSelector } from "./hooks/useSelector"; 5 | import { useAction } from "./hooks/useAction"; 6 | 7 | export { connect, Provider, Connect, useStore, useSelector, useAction }; 8 | -------------------------------------------------------------------------------- /examples/react/chat/src/routes.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow } from 'enzyme'; 3 | 4 | import Routes from './routes'; 5 | 6 | describe('Test route wrapper unit', () => { 7 | it('Should match with snapshot', () => { 8 | const wrapper = shallow(); 9 | 10 | expect(wrapper).toMatchSnapshot(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /examples/react/react-router/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from 'react-dom'; 3 | import { Provider } from 'redux-zero/react'; 4 | 5 | import store from './store'; 6 | import App from './App'; 7 | 8 | render( 9 | 10 | 11 | , 12 | document.getElementById('root') 13 | ); 14 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/apiRoutes.spec.js: -------------------------------------------------------------------------------- 1 | import apiRoutes from './apiRoutes'; 2 | 3 | import utils from '../../utils'; 4 | 5 | describe('Test API Routes unit', () => { 6 | it('Check if structure keeps equal', () => { 7 | expect(utils.object.generateNewObjectWithAllFunctionsInvoked(apiRoutes)) 8 | .toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'; 4 | 5 | import App from './App'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root') 12 | ); 13 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/apiRoutes.spec.js: -------------------------------------------------------------------------------- 1 | import apiRoutes from './apiRoutes'; 2 | 3 | import utils from '../../utils'; 4 | 5 | describe('Test API Routes unit', () => { 6 | it('Check if structure keeps equal', () => { 7 | expect(utils.object.generateNewObjectWithAllFunctionsInvoked(apiRoutes)) 8 | .toMatchSnapshot(); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /config/preprocessor.js: -------------------------------------------------------------------------------- 1 | const tsc = require("typescript"); 2 | 3 | module.exports = { 4 | process(src, path) { 5 | const config = /preact/.test(path) 6 | ? require("../src/preact/tsconfig.json") 7 | : require("../tsconfig.json"); 8 | 9 | return /\.tsx?$/.test(path) 10 | ? tsc.transpile(src, config.compilerOptions, path, []) 11 | : src; 12 | } 13 | }; 14 | -------------------------------------------------------------------------------- /examples/preact/counter/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Preact CLI App", 3 | "short_name": "Preact CLI App", 4 | "start_url": "/", 5 | "display": "standalone", 6 | "orientation": "portrait", 7 | "background_color": "#fff", 8 | "theme_color": "#673ab8", 9 | "icons": [{ 10 | "src": "/assets/icon.png", 11 | "type": "image/png", 12 | "sizes": "512x512" 13 | }] 14 | } 15 | -------------------------------------------------------------------------------- /examples/react/ssr/src/client/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { hydrate,render } from 'react-dom' 3 | import createStore from 'redux-zero' 4 | 5 | import App from 'app/App' 6 | 7 | //Hyderate the client side store using the state sent from the server 8 | const store = createStore(window.__INITIAL_STATE__) 9 | 10 | hydrate(,document.getElementById('root')) 11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/react/react-router/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "192x192", 8 | "type": "image/png" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/vue/counter/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | redux-zero counter example 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | -------------------------------------------------------------------------------- /examples/react/chat/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { Provider } from 'redux-zero/react'; 4 | 5 | import Routes from './routes' 6 | import store from './store'; 7 | 8 | import 'tachyons/css/tachyons.min.css'; 9 | 10 | ReactDOM.render( 11 | 12 | 13 | , 14 | document.getElementById('root') 15 | ); 16 | -------------------------------------------------------------------------------- /examples/react/counter/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/react/ssr/webpack/paths.js: -------------------------------------------------------------------------------- 1 | const { join,sep } = require('path') 2 | const pathJoin = p => join(__dirname,'..',p) 3 | 4 | module.exports = { 5 | NODE_MODULES: pathJoin('node_modules'), 6 | CLIENT: pathJoin(`src${sep}client`), 7 | SERVER: pathJoin(`src${sep}server`), 8 | SRC: pathJoin('src'), 9 | APP: pathJoin(`src${sep}app`), 10 | PUBLIC: pathJoin(`public`), 11 | SERVER_BUILD: pathJoin(`build`) 12 | } -------------------------------------------------------------------------------- /examples/react/chat/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/react/react-router/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/react/counter/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | To contribute to the project, please follow these steps: 4 | 5 | 1. Fork the repo 6 | 2. Make a branch for your change 7 | 3. Run `yarn install` 8 | 4. Make your changes 9 | 5. Run `yarn run check` 10 | 6. Test your changes 11 | 7. Run `git add -A` to add your changes 12 | 8. Run `git commit` - with a helpful message 13 | 9. Push your changes with `git push` 14 | 10. Create a Pull Request 15 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": "./index.html", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /examples/react/chat/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | 23 | #VSCode 24 | /.vscode 25 | -------------------------------------------------------------------------------- /src/utils/bindAction.ts: -------------------------------------------------------------------------------- 1 | import set from "./set"; 2 | import Store from "../interfaces/Store"; 3 | import { Action } from "../types"; 4 | 5 | export default function bindAction(action: Action, store: Store) { 6 | return (...args: any[]) => { 7 | if (typeof store.middleware === "function") { 8 | return store.middleware(store, action, args); 9 | } 10 | 11 | return set(store, action(store.getState(), ...args)); 12 | }; 13 | } 14 | -------------------------------------------------------------------------------- /examples/react/chat/src/__snapshots__/routes.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test route wrapper unit Should match with snapshot 1`] = ` 4 | 5 | 6 | 11 | 16 | 17 | 18 | `; 19 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/user/actions.js: -------------------------------------------------------------------------------- 1 | import { isEmpty } from 'lodash'; 2 | import services from './services'; 3 | 4 | async function createUser(userName) { 5 | try { 6 | return { currentUser: await services.createUser(userName) }; 7 | } catch(err) { 8 | alert(err.message); 9 | } 10 | } 11 | 12 | export default (store) => ({ 13 | createUser: state => createUser(state.userName), 14 | setUsername: (state, userName) => ({ userName }), 15 | }); 16 | -------------------------------------------------------------------------------- /examples/react/chat/src/routes.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; 3 | 4 | import modules from './modules'; 5 | 6 | const Routes = () => ( 7 | 8 | 9 | 10 | 11 | 12 | 13 | ); 14 | 15 | export default Routes; 16 | -------------------------------------------------------------------------------- /examples/react/counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.0.0", 7 | "react-dom": "^16.0.0", 8 | "react-scripts": "1.0.17", 9 | "redux-zero": "^4.3.0" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test --env=jsdom", 15 | "eject": "react-scripts eject" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/react/ssr/src/app/Counter.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { connect } from 'redux-zero/react' 3 | 4 | import actions from 'actions' 5 | 6 | const mapToProps = ({ count }) => ({ count }) 7 | 8 | export default connect(mapToProps, actions)(({ count, increment, decrement }) => ( 9 |
10 |

{count}

11 |
12 | 13 | 14 |
15 |
16 | )); -------------------------------------------------------------------------------- /src/react/hooks/useAction.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useStore } from "./useStore"; 3 | import bindAction from "../../utils/bindAction"; 4 | import { Action } from "../../types"; 5 | 6 | export function useAction( 7 | action: Action 8 | ): (...args: any[]) => Promise | void { 9 | const store = useStore(); 10 | 11 | return useMemo( 12 | () => { 13 | return bindAction(action, store); 14 | }, 15 | [store, action] 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter-hooks", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.8.6", 7 | "react-dom": "^16.8.6", 8 | "react-scripts": "3.0.1", 9 | "redux-zero": "^5.0.4" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test --env=jsdom", 15 | "eject": "react-scripts eject" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/react-native/counter/android/app/src/main/java/com/counter/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.counter; 2 | 3 | import com.facebook.react.ReactActivity; 4 | 5 | public class MainActivity extends ReactActivity { 6 | 7 | /** 8 | * Returns the name of the main component registered from JavaScript. 9 | * This is used to schedule rendering of the component. 10 | */ 11 | @Override 12 | protected String getMainComponentName() { 13 | return "counter"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/preact/components/Provider.tsx: -------------------------------------------------------------------------------- 1 | import { Component } from "preact"; 2 | 3 | import Props from "../../interfaces/Props"; 4 | import Store from "../../interfaces/Store"; 5 | 6 | export default class Provider extends Component, {}> { 7 | getChildContext() { 8 | return { store: this.props.store }; 9 | } 10 | render() { 11 | return ( 12 | (this.props.children && this.props.children[0]) || 13 | (this.props.children as JSX.Element) 14 | ); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/react/counter/src/Counter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { connect } from "redux-zero/react"; 3 | 4 | import actions from "./actions"; 5 | 6 | const mapToProps = ({ count }) => ({ count }); 7 | 8 | export default connect(mapToProps, actions)(({ count, increment, decrement }) => ( 9 |
10 |

{count}

11 |
12 | 13 | 14 |
15 |
16 | )); 17 | -------------------------------------------------------------------------------- /examples/react/chat/src/store.js: -------------------------------------------------------------------------------- 1 | import createStore from 'redux-zero'; 2 | import { applyMiddleware } from 'redux-zero/middleware'; 3 | import { connect } from 'redux-zero/devtools'; 4 | 5 | import utils from './utils' 6 | 7 | const INITIAL_STATE = { 8 | users: [], 9 | messages: [], 10 | currentUser: utils.localStorage.getJSONData('currentUser'), 11 | }; 12 | 13 | const middlewares = connect ? applyMiddleware(connect(INITIAL_STATE)) : []; 14 | 15 | export default createStore(INITIAL_STATE, middlewares); 16 | -------------------------------------------------------------------------------- /config/testSetup.js: -------------------------------------------------------------------------------- 1 | const ReactTestRenderer = require("react-test-renderer"); 2 | const Enzyme = require("enzyme"); 3 | const Adapter = require("enzyme-adapter-react-16"); 4 | 5 | Enzyme.configure({ adapter: new Adapter() }); 6 | 7 | global.shallow = Enzyme.shallow; 8 | global.render = Enzyme.render; 9 | global.mount = Enzyme.mount; 10 | 11 | global.requestAnimationFrame = function(callback) { 12 | setTimeout(callback, 0); 13 | }; 14 | 15 | console.error = message => { 16 | throw new Error(message); 17 | }; 18 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/messageListItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import utils from '../../../utils'; 4 | 5 | const MessageListItem = ({ createdAt, content, userName }) => { 6 | return ( 7 |
8 |

{ userName }

9 | { utils.dateFormatter.format(createdAt) } 10 |

{ content }

11 |
12 | ); 13 | }; 14 | 15 | export default MessageListItem; 16 | -------------------------------------------------------------------------------- /examples/react/material-ui-counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "material-ui": "^0.20.0", 7 | "react": "^16.0.0", 8 | "react-dom": "^16.0.0", 9 | "react-scripts": "1.0.17", 10 | "redux-zero": "^4.3.0" 11 | }, 12 | "scripts": { 13 | "start": "react-scripts start", 14 | "build": "react-scripts build", 15 | "test": "react-scripts test --env=jsdom", 16 | "eject": "react-scripts eject" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/messageList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import MessageListItem from './messageListItem'; 4 | 5 | const renderItems = (messages) => 6 | messages.map((it, i) => ); 7 | 8 | const MessageList = ({ className, messages = [] }) => { 9 | return ( 10 |
11 | { renderItems(messages) } 12 |
13 | ); 14 | }; 15 | 16 | export default MessageList; 17 | -------------------------------------------------------------------------------- /examples/react/ssr/babelConfig.js: -------------------------------------------------------------------------------- 1 | module.exports = () => { 2 | return { 3 | presets: [ 4 | [ 5 | "env", 6 | { 7 | targets: { 8 | browsers: ["> 5%"], 9 | node: "8.7.0" 10 | }, 11 | modules: false 12 | } 13 | ], 14 | "react" 15 | ], 16 | plugins:[ 17 | [ 18 | "module-resolver", 19 | { 20 | root: ["./src"] 21 | } 22 | ] 23 | ], 24 | env: { 25 | production: { 26 | plugins: ["transform-react-remove-prop-types"] 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/__snapshots__/message.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Message component unit Should render component with correct structure 1`] = ` 4 |
7 | 11 | 17 |
18 | `; 19 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/__snapshots__/messageListItem.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test MessageListItem component unit Should render component with correct structure 1`] = ` 4 |
7 |

10 | Test username 11 |

12 | 15 | Date formatted 16 | 17 |

18 | Test Content 19 |

20 |
21 | `; 22 | -------------------------------------------------------------------------------- /examples/vue/counter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .vs/ 4 | npm-debug.* 5 | obj/ 6 | *.suo 7 | [Bb]in 8 | [Dd]ebug*/ 9 | *.sbr 10 | obj/ 11 | [Rr]elease*/ 12 | _ReSharper*/ 13 | public/bundle.* 14 | dist/* 15 | **/build/js/* 16 | **/packages/* 17 | # except build/, which is used as an MSBuild target. 18 | !**/packages/build/ 19 | # Uncomment if necessary however generally it will be regenerated when needed 20 | #!**/packages/repositories.config 21 | **/node_modules/* 22 | **/bower_components/* 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/message.spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { shallow } from 'enzyme'; 3 | 4 | import Message from './message'; 5 | 6 | describe('Message component unit', () => { 7 | it('Should render component with correct structure', () => { 8 | const wrapper = shallow(); 14 | 15 | expect(wrapper).toMatchSnapshot(); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/svelte/counter/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | .vs/ 4 | npm-debug.* 5 | obj/ 6 | *.suo 7 | [Bb]in 8 | [Dd]ebug*/ 9 | *.sbr 10 | obj/ 11 | [Rr]elease*/ 12 | _ReSharper*/ 13 | public/bundle.js 14 | dist/* 15 | **/build/js/* 16 | **/packages/* 17 | # except build/, which is used as an MSBuild target. 18 | !**/packages/build/ 19 | # Uncomment if necessary however generally it will be regenerated when needed 20 | #!**/packages/repositories.config 21 | **/node_modules/* 22 | **/bower_components/* 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /src/preact/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react", 4 | "jsxFactory": "h", 5 | "module": "commonjs", 6 | "declaration": true, 7 | "noImplicitAny": false, 8 | "suppressImplicitAnyIndexErrors": true, 9 | "removeComments": false, 10 | "sourceMap": false, 11 | "target": "ES5", 12 | "outDir": "./dist" 13 | }, 14 | "include": [ 15 | "**/*.ts", 16 | "**/*.tsx" 17 | ], 18 | "exclude": [ 19 | "node_modules", 20 | "**/*.spec.ts", 21 | "**/*.spec.tsx" 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /examples/react/react-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-router", 3 | "description": "", 4 | "version": "0.0.1", 5 | "dependencies": { 6 | "redux-zero": "^4.3.0", 7 | "react-router-dom": "4.2.2", 8 | "react-dom": "16.1.1", 9 | "react": "16.1.1" 10 | }, 11 | "devDependencies": { 12 | "react-scripts": "1.0.0" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "test": "react-scripts test --env=jsdom", 18 | "eject": "react-scripts eject" 19 | } 20 | } -------------------------------------------------------------------------------- /examples/react-native/counter/ios/counter/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /examples/preact/counter/Counter.js: -------------------------------------------------------------------------------- 1 | import { Connect } from "redux-zero/preact"; 2 | 3 | import actions from "./actions"; 4 | 5 | const mapToProps = ({ count }) => ({ count }); 6 | 7 | export default () => ( 8 | 9 | {({ count, increment, decrement }) => ( 10 |
11 |

{count}

12 |
13 | 14 | 15 |
16 |
17 | )} 18 |
19 | ); 20 | -------------------------------------------------------------------------------- /examples/react/react-router/src/components/Route1.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { connect } from 'redux-zero/react'; 4 | import actions from '../actions'; 5 | 6 | const mapToProps = ({ count }) => ({ count }); 7 | 8 | export default connect(mapToProps, actions)( 9 | ({ count, decrement, increment }) => ( 10 |
11 |

Route 1 | State -> {count}

12 |
13 | 14 | 15 |
16 |
17 | ) 18 | ); 19 | -------------------------------------------------------------------------------- /examples/react/react-router/src/components/Route2.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { connect } from 'redux-zero/react'; 4 | import actions from '../actions'; 5 | 6 | const mapToProps = ({ count }) => ({ count }); 7 | 8 | export default connect(mapToProps, actions)( 9 | ({ count, decrement, increment }) => ( 10 |
11 |

Route 2 | State -> {count}

12 |
13 | 14 | 15 |
16 |
17 | ) 18 | ); 19 | -------------------------------------------------------------------------------- /examples/svelte/counter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es2015", 5 | "declaration": true, 6 | "noImplicitAny": false, 7 | "allowJs": false, 8 | "sourceMap": true, 9 | "outDir": "build/js/", 10 | "noImplicitReturns": true, 11 | "allowSyntheticDefaultImports": true, 12 | "lib": [ "dom", "es2015" ], 13 | "typeRoots": [ 14 | "./node_modules/@types" 15 | ] 16 | }, 17 | "exclude": [ 18 | "node_modules", 19 | "public" 20 | ], 21 | "include": [ 22 | "src/**/*.ts" 23 | ] 24 | } -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/message.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import MessageForm from './messageForm'; 4 | import MessageList from './messageList'; 5 | 6 | export default ({ messages = [], createMessage, setMessageContent, messageContent }) => ( 7 |
8 | 9 | 15 |
16 | ) 17 | -------------------------------------------------------------------------------- /examples/react-native/counter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "counter", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest" 8 | }, 9 | "dependencies": { 10 | "react": "16.0.0-beta.5", 11 | "react-native": "0.49.3", 12 | "redux-zero": "^4.2.0" 13 | }, 14 | "devDependencies": { 15 | "babel-jest": "21.2.0", 16 | "babel-preset-react-native": "4.0.0", 17 | "jest": "21.2.1", 18 | "react-test-renderer": "16.0.0-beta.5" 19 | }, 20 | "jest": { 21 | "preset": "react-native" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /examples/react/chat/src/utils/functional.spec.js: -------------------------------------------------------------------------------- 1 | import { compose } from './functional'; 2 | 3 | import { add, multiply } from 'lodash'; 4 | 5 | describe('Funcional test', () => { 6 | it('Compose without promises', () => { 7 | const composedFn = compose(multiply.bind(this, 1), add); 8 | expect(composedFn(10, 10)).toBe(20); 9 | }); 10 | 11 | it('Compose with promises', () => { 12 | const asyncMultiply = (val) => Promise.resolve(multiply.call(this, 1, val)); 13 | const composedFn = compose(asyncMultiply, add); 14 | 15 | expect(composedFn(10, 10)).resolves.toBe(20); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /examples/react/counter-hooks/src/Counter.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useSelector, useAction } from "redux-zero/react"; 3 | 4 | export default () => { 5 | const count = useSelector(({ count }) => count) 6 | 7 | const increment = useAction(({ count }) => ({ count: count + 1 })) 8 | const decrement = useAction(({ count }) => ({ count: count - 1 })) 9 | 10 | return ( 11 |
12 |

{count}

13 |
14 | 15 | 16 |
17 |
18 | ) 19 | }; 20 | -------------------------------------------------------------------------------- /src/types/index.ts: -------------------------------------------------------------------------------- 1 | import Store from "../interfaces/Store"; 2 | 3 | export type Action = (state: S, ...args: any[]) => Promise> | Partial; 4 | export type FuncTypeWithoutFirstArg< 5 | T extends (...args: any[]) => any 6 | > = T extends (arg1: infer U, ...args: infer V) => infer Q 7 | ? (...args: V) => void 8 | : any; 9 | export type ActionsObject = { [action: string]: Action }; 10 | export type Actions = (store: Store) => ActionsObject; 11 | export type BoundActions> = { 12 | [P in keyof ReturnType]: FuncTypeWithoutFirstArg[P]> 13 | }; 14 | -------------------------------------------------------------------------------- /examples/react-native/counter/ios/counter/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /examples/svelte/counter/src/typings/svelte.d.ts: -------------------------------------------------------------------------------- 1 | declare class Svelte { 2 | constructor(options: { target: Element, data?: any }); 3 | 4 | get(name: string); 5 | set(data: any); 6 | 7 | on( 8 | eventName: string, 9 | callback?: (event?: any) => any) 10 | : () => { cancel: () => any }; 11 | 12 | fire(eventName: string, event?: any); 13 | 14 | observe( 15 | name: string, 16 | callback: (newValue?, oldValue?) => any, 17 | options?: { init?: boolean, defer?: boolean }) 18 | : () => { cancel: () => any }; 19 | 20 | teardown(); 21 | } 22 | -------------------------------------------------------------------------------- /examples/react/chat/src/modules/message/components/__snapshots__/messageForm.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Test MessageForm component unit Should render component with correct structure 1`] = ` 4 |
7 |
11 |