├── .babelrc ├── .circleci └── config.yml ├── .codeclimate.yml ├── .editorconfig ├── .eslintrc ├── .flowconfig ├── .gitignore ├── .prettierrc ├── .sample.env ├── .stylelintrc ├── CONTRIBUTING.md ├── LICENCE ├── README.md ├── bin ├── server.dev.js └── server.prod.js ├── flow-typed ├── hotModule.js.flow └── npm │ ├── redux-observable_v0.14.x.js │ ├── redux_v3.x.x.js │ └── rxjs_v5.0.x.js ├── package-lock.json ├── package.json ├── src ├── client.js ├── components │ ├── GithubButton │ │ └── GithubButton.js │ ├── Loading │ │ └── Loading.js │ ├── Menu │ │ ├── Menu.js │ │ └── Menu.scss │ ├── RouterStatus │ │ ├── RedirectWithStatus.js │ │ └── Status.js │ ├── SelectField │ │ └── SelectField.js │ ├── TextField │ │ └── TextField.js │ └── TypicalForm │ │ ├── TypicalForm.js │ │ └── TypicalValidation.js ├── config.js ├── containers │ ├── App │ │ ├── App.js │ │ └── App.scss │ ├── Examples │ │ ├── Examples.js │ │ └── index.js │ ├── Hero │ │ ├── Hero.js │ │ ├── Hero.scss │ │ ├── github.svg │ │ └── logo.svg │ ├── Home │ │ ├── Home.js │ │ └── index.js │ └── NotFound │ │ ├── NotFound.js │ │ └── index.js ├── helpers │ ├── Api.js │ └── Html.js ├── redux │ ├── configureStore.js │ ├── neo │ │ ├── actions.js │ │ ├── index.js │ │ ├── reducer.js │ │ └── types.js │ └── reducers.js ├── server │ ├── index.js │ └── render.js ├── sw.js └── utils │ └── validation.js ├── static ├── android-chrome-192x192.png ├── android-chrome-512x512.png ├── apple-touch-icon-precomposed.png ├── apple-touch-icon.png ├── browserconfig.xml ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon.ico ├── favicon.svg ├── manifest.json ├── mstile-144x144.png ├── mstile-150x150.png ├── mstile-310x150.png ├── mstile-310x310.png ├── mstile-70x70.png └── safari-pinned-tab.svg └── webpack ├── client.dev.js ├── client.prod.js ├── server.dev.js └── server.prod.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "modules": false, 7 | "targets": { 8 | "browsers": [ 9 | "last 3 versions", 10 | "safari >= 7" 11 | ] 12 | } 13 | } 14 | ], 15 | "@babel/preset-react", 16 | "@babel/preset-flow" 17 | ], 18 | "plugins": [ 19 | "universal-import", 20 | "@babel/plugin-syntax-dynamic-import", 21 | "@babel/plugin-syntax-import-meta", 22 | "@babel/plugin-proposal-class-properties", 23 | "@babel/plugin-proposal-json-strings", 24 | [ 25 | "@babel/plugin-proposal-decorators", 26 | { 27 | "legacy": true 28 | } 29 | ], 30 | "@babel/plugin-proposal-function-sent", 31 | "@babel/plugin-proposal-export-namespace-from", 32 | "@babel/plugin-proposal-numeric-separator", 33 | "@babel/plugin-proposal-throw-expressions" 34 | ], 35 | "env": { 36 | "production": { 37 | "only": [ 38 | "src" 39 | ], 40 | "plugins": [ 41 | "@babel/plugin-transform-react-constant-elements", 42 | "@babel/plugin-transform-react-inline-elements" 43 | ] 44 | }, 45 | "development": { 46 | "plugins": [ 47 | "react-hot-loader/babel" 48 | ] 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | jobs: 3 | build: 4 | working_directory: ~/reactivity 5 | docker: 6 | - image: circleci/node:8.2.1 7 | steps: 8 | - checkout 9 | - run: 10 | name: install lock 11 | command: 'sudo npm install -g greenkeeper-lockfile@1' 12 | - restore_cache: 13 | key: dependency-cache-{{ checksum "package.json" }} 14 | - run: 15 | name: Install npm 16 | command: npm install 17 | - save_cache: 18 | key: dependency-cache-{{ checksum "package.json" }} 19 | paths: 20 | - node_modules 21 | - run: 22 | name: Update Lock file 23 | command: greenkeeper-lockfile-update 24 | - run: 25 | name: Build 26 | command: npm run build 27 | - run: 28 | name: Lint 29 | command: npm test 30 | - run: 31 | name: Upload Lock file 32 | command: greenkeeper-lockfile-upload 33 | 34 | deploy_dev: 35 | working_directory: ~/reactivity 36 | docker: 37 | - image: circleci/node:8.2.1 38 | steps: 39 | - checkout 40 | - run: 41 | name: Install now 42 | command: sudo npm install -g now 43 | - run: 44 | name: Install now-purge 45 | command: sudo npm install -g now-purge 46 | - run: 47 | name: Deploy Development 48 | command: URL=$(now -t ${NOW_TOKEN} --public --dotenv=.sample.env) 49 | now -t ${NOW_TOKEN} alias set ${URL} reactivity-dev.now.sh 50 | - run: 51 | name: Purge Now.sh 52 | command: now-purge -t ${NOW_TOKEN} -n reactivity 53 | 54 | deploy_prod: 55 | working_directory: ~/reactivity 56 | docker: 57 | - image: circleci/node:8.2.1 58 | steps: 59 | - checkout 60 | - run: 61 | name: Install now 62 | command: sudo npm install -g now 63 | - run: 64 | name: Install now-purge 65 | command: sudo npm install -g now-purge 66 | - run: 67 | name: Deploy Production 68 | command: | 69 | URL=$(now -t ${NOW_TOKEN} --public --dotenv=.sample.env) 70 | now -t ${NOW_TOKEN} alias set ${URL} reactivity.now.sh 71 | - run: 72 | name: Purge Now.sh 73 | command: now-purge -t ${NOW_TOKEN} -n reactivity 74 | 75 | workflows: 76 | version: 2 77 | build: 78 | jobs: 79 | - build 80 | 81 | deploy_development: 82 | jobs: 83 | - build 84 | - deploy_dev: 85 | requires: 86 | - build 87 | filters: 88 | branches: 89 | only: dev 90 | 91 | deploy_production: 92 | jobs: 93 | - build 94 | - deploy_prod: 95 | requires: 96 | - build 97 | filters: 98 | branches: 99 | only: master 100 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | --- 2 | engines: 3 | duplication: 4 | enabled: true 5 | config: 6 | languages: 7 | javascript: 8 | mass_threshold: 60 9 | eslint: 10 | enabled: true 11 | checks: 12 | import/no-unresolved: 13 | enabled: false 14 | fixme: 15 | enabled: true 16 | ratings: 17 | paths: 18 | - "src/**/*" 19 | exclude_paths: 20 | - "webpack/*" 21 | - "node_modules/**/*" 22 | - "build/**/*" 23 | - "bin/*" 24 | - "flow-typed/**/*" 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | indent_style = space 3 | end_of_line = lf 4 | indent_size = 2 5 | charset = utf-8 6 | trim_trailing_whitespace = true 7 | 8 | [*.md] 9 | max_line_length = 0 10 | trim_trailing_whitespace = false 11 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "airbnb", 4 | "plugin:flowtype/recommended", 5 | "prettier", 6 | "prettier/react", 7 | "prettier/flowtype" 8 | ], 9 | "env": { 10 | "es6": true, 11 | "browser": true, 12 | "node": true 13 | }, 14 | "rules": { 15 | "global-require": "off", 16 | "comma-dangle": "off", 17 | "no-console": "off", 18 | "no-underscore-dangle": "off", 19 | "react/no-danger": "off", 20 | "no-bitwise": "off", 21 | "semi": [2, "never"], 22 | "react/destructuring-assignment": "warn", 23 | "jsx-a11y/label-has-for": "warn", 24 | "import/no-extraneous-dependencies": [ 25 | "error", 26 | { 27 | "devDependencies": ["webpack/**", "bin/*.dev.js"] 28 | } 29 | ], 30 | "react/jsx-filename-extension": [ 31 | 2, 32 | { 33 | "extensions": [".jsx", ".js"] 34 | } 35 | ], 36 | "prettier/prettier": 2, 37 | "no-restricted-globals": ["error", "event", "fdescribe"], 38 | "jsx-a11y/anchor-is-valid": [ 39 | "error", 40 | { 41 | "components": ["Link"], 42 | "specialLink": ["to"] 43 | } 44 | ] 45 | }, 46 | "parser": "babel-eslint", 47 | "plugins": ["flowtype", "react", "import", "prettier"], 48 | "parserOptions": { 49 | "ecmaVersion": 2016, 50 | "sourceType": "module", 51 | "ecmaFeatures": { 52 | "jsx": true 53 | } 54 | }, 55 | "settings": { 56 | "import/resolver": { 57 | "webpack": { 58 | "config": "./webpack/client.prod.js" 59 | }, 60 | "node": { 61 | "paths": ["node_modules", "src", "components", "reducers"] 62 | }, 63 | "flowtype": { 64 | "onlyFilesWithFlowAnnotation": true 65 | } 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | .*/node_modules/flow-bin/.* 3 | .*/node_modules/react-universal-component/.* 4 | .*/node_modules/serviceworker-webpack-plugin/.* 5 | .*/node_modules/webpack-flush-chunks/.* 6 | .*/node_modules/stylelint/.* 7 | .*/build/.* 8 | 9 | [include] 10 | ./flow-typed/ 11 | 12 | [libs] 13 | 14 | [lints] 15 | 16 | [options] 17 | module.name_mapper='.*\(.s?css\)' -> 'empty/object' 18 | module.name_mapper='^components' ->'/src/components' 19 | module.name_mapper='^reducers' ->'/src/redux' 20 | 21 | [version] 22 | ^0.80.0 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/* 2 | !.vscode/settings.json 3 | !.vscode/tasks.json 4 | !.vscode/launch.json 5 | !.vscode/extensions.json 6 | 7 | *.DS_Store 8 | .AppleDouble 9 | .LSOverride 10 | 11 | # Icon must end with two \r 12 | Icon 13 | 14 | 15 | # Thumbnails 16 | ._* 17 | 18 | # Files that might appear in the root of a volume 19 | .DocumentRevisions-V100 20 | .fseventsd 21 | .Spotlight-V100 22 | .TemporaryItems 23 | .Trashes 24 | .VolumeIcon.icns 25 | .com.apple.timemachine.donotpresent 26 | 27 | # Directories potentially created on remote AFP share 28 | .AppleDB 29 | .AppleDesktop 30 | Network Trash Folder 31 | Temporary Items 32 | .apdisk 33 | 34 | # Logs 35 | logs 36 | *.log 37 | npm-debug.log* 38 | yarn-debug.log* 39 | yarn-error.log* 40 | 41 | # Runtime data 42 | pids 43 | *.pid 44 | *.seed 45 | *.pid.lock 46 | 47 | # Directory for instrumented libs generated by jscoverage/JSCover 48 | lib-cov 49 | 50 | # Coverage directory used by tools like istanbul 51 | coverage 52 | 53 | # nyc test coverage 54 | .nyc_output 55 | 56 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 57 | .grunt 58 | 59 | # Bower dependency directory (https://bower.io/) 60 | bower_components 61 | 62 | # node-waf configuration 63 | .lock-wscript 64 | 65 | # Compiled binary addons (http://nodejs.org/api/addons.html) 66 | build/Release 67 | 68 | # Dependency directories 69 | node_modules/ 70 | jspm_packages/ 71 | 72 | # Typescript v1 declaration files 73 | typings/ 74 | 75 | # Optional npm cache directory 76 | .npm 77 | 78 | # Optional eslint cache 79 | .eslintcache 80 | 81 | # Optional REPL history 82 | .node_repl_history 83 | 84 | # Output of 'npm pack' 85 | *.tgz 86 | 87 | # Yarn Integrity file 88 | .yarn-integrity 89 | 90 | # dotenv environment variables file 91 | .env 92 | 93 | #App 94 | .build 95 | .favicon 96 | dist 97 | ./index.html 98 | build 99 | 100 | .vscode 101 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 80, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "semi": false, 6 | "parser": "flow" 7 | } 8 | -------------------------------------------------------------------------------- /.sample.env: -------------------------------------------------------------------------------- 1 | APP_HOST=http://localhost 2 | APP_PORT=3000 3 | API_URL=https://api.nasa.gov/neo/rest/v1 4 | ENABLE_SW=true 5 | API_KEY=DEMO_KEY 6 | # NODE_ENV=production 7 | -------------------------------------------------------------------------------- /.stylelintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["stylelint-config-standard", "stylelint-config-css-modules"] 3 | } 4 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | When contributing to this repository, please first discuss the change you wish to make via issue, 4 | email, or any other method with the owners of this repository before making a change. 5 | 6 | Please note we have a code of conduct, please follow it in all your interactions with the project. 7 | 8 | ## Pull Request Process 9 | 10 | 1. Ensure any install or build dependencies are removed before the end of the layer when doing a 11 | build. 12 | 2. Update the README.md with details of changes to the interface, this includes new environment 13 | variables, exposed ports, useful file locations and container parameters. 14 | 3. Increase the version numbers in any examples files and the README.md to the new version that this 15 | Pull Request would represent. The versioning scheme we use is [SemVer](http://semver.org/). 16 | 4. You may merge the Pull Request in once you have the sign-off of two other developers, or if you 17 | do not have permission to do that, you may request the second reviewer to merge it for you. 18 | 19 | ## Code of Conduct 20 | 21 | ### Our Pledge 22 | 23 | In the interest of fostering an open and welcoming environment, we as 24 | contributors and maintainers pledge to making participation in our project and 25 | our community a harassment-free experience for everyone, regardless of age, body 26 | size, disability, ethnicity, gender identity and expression, level of experience, 27 | nationality, personal appearance, race, religion, or sexual identity and 28 | orientation. 29 | 30 | ### Our Standards 31 | 32 | Examples of behavior that contributes to creating a positive environment 33 | include: 34 | 35 | * Using welcoming and inclusive language 36 | * Being respectful of differing viewpoints and experiences 37 | * Gracefully accepting constructive criticism 38 | * Focusing on what is best for the community 39 | * Showing empathy towards other community members 40 | 41 | Examples of unacceptable behavior by participants include: 42 | 43 | * The use of sexualized language or imagery and unwelcome sexual attention or 44 | advances 45 | * Trolling, insulting/derogatory comments, and personal or political attacks 46 | * Public or private harassment 47 | * Publishing others' private information, such as a physical or electronic 48 | address, without explicit permission 49 | * Other conduct which could reasonably be considered inappropriate in a 50 | professional setting 51 | 52 | ### Our Responsibilities 53 | 54 | Project maintainers are responsible for clarifying the standards of acceptable 55 | behavior and are expected to take appropriate and fair corrective action in 56 | response to any instances of unacceptable behavior. 57 | 58 | Project maintainers have the right and responsibility to remove, edit, or 59 | reject comments, commits, code, wiki edits, issues, and other contributions 60 | that are not aligned to this Code of Conduct, or to ban temporarily or 61 | permanently any contributor for other behaviors that they deem inappropriate, 62 | threatening, offensive, or harmful. 63 | 64 | ### Scope 65 | 66 | This Code of Conduct applies both within project spaces and in public spaces 67 | when an individual is representing the project or its community. Examples of 68 | representing a project or community include using an official project e-mail 69 | address, posting via an official social media account, or acting as an appointed 70 | representative at an online or offline event. Representation of a project may be 71 | further defined and clarified by project maintainers. 72 | 73 | ### Enforcement 74 | 75 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 76 | reported by contacting the project team at [INSERT EMAIL ADDRESS]. All 77 | complaints will be reviewed and investigated and will result in a response that 78 | is deemed necessary and appropriate to the circumstances. The project team is 79 | obligated to maintain confidentiality with regard to the reporter of an incident. 80 | Further details of specific enforcement policies may be posted separately. 81 | 82 | Project maintainers who do not follow or enforce the Code of Conduct in good 83 | faith may face temporary or permanent repercussions as determined by other 84 | members of the project's leadership. 85 | 86 | ### Attribution 87 | 88 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 89 | available at [http://contributor-covenant.org/version/1/4][version] 90 | 91 | [homepage]: http://contributor-covenant.org 92 | [version]: http://contributor-covenant.org/version/1/4/ 93 | -------------------------------------------------------------------------------- /LICENCE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2017 MADE Code PTY Ltd. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Reactivity 2 | 3 | A Bleeding Edge React Universal Boilerplate for Power Users. 4 | 5 | [![Code Climate](https://codeclimate.com/repos/598770109f7dbb02640013d9/badges/dac168d1b640d9ab7e3e/gpa.svg)](https://codeclimate.com/repos/598770109f7dbb02640013d9/feed) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](CONTRIBUTING.md#pull-request-process) [![Dependency Status](https://david-dm.org/madeagency/reactivity.svg)](https://david-dm.org/madeagency/reactivity) [![devDependency Status](https://david-dm.org/madeagency/reactivity/dev-status.svg)](https://david-dm.org/madeagency/reactivity#info=devDependencies) [![Greenkeeper badge](https://badges.greenkeeper.io/madeagency/reactivity.svg?token=ddba641b3d2a0d2bf1c8abc674cebd3b48a8383755bb7b02fd3cf1878f86de9a&ts=1502800234197)](https://greenkeeper.io/) 6 | 7 | What is Reactivity? Well at its most basic definition it is how easily an atom has a chemical reaction with another element. Our goal is to achieve stable valence levels, a full valence shell if you will. 8 | 9 | But really it's just a boilerplate. 10 | 11 | Because that's what's missing in the React realm right? 12 | 13 | Well see we need a boilerplate for people who want to be able to tweak every atom of an application and a simple boilerplate that doesn't contain any magic or code generation that takes pages of documentation to learn how to override, it's a boilerplate for power users. 14 | 15 | #### View our [Example App Here](https://reactivity.now.sh) 16 | 17 | Deployed using [now](https://zeit.co/now) like so `now --public --dotenv=.env` 18 | 19 | ## Features 20 | 21 | You will find that this boilerplate covers all the expected areas such as SEO, Hot Reloading and all the other things typically covered in a boilerplate, check out our pull requests to see what's coming up. 22 | 23 | Whats unique about this boilerplate however is: 24 | 25 | - Universal Rendering with Code Splitting - *(thanks to [react-universal-component](https://github.com/faceyspacey/react-universal-component))* 26 | - RXJS for action side effects. - *(thanks to [react-redux-epic](https://github.com/BerkeleyTrue/react-redux-epic))* 27 | - PWA Ready. 28 | - No scaffolding tools. 29 | - No Automated service worker generation, you get to write your own. - *(thanks to [serviceworker-webpack-plugin](https://github.com/oliviertassinari/serviceworker-webpack-plugin))* 30 | 31 | ## Getting Started 32 | 33 | If you haven't yet start by installing [yarn](https://yarnpkg.com/en/). 34 | 35 | 1. Clone this repo using `git clone --depth=1 https://github.com/madeagency/reactivity.git` 36 | 2. Move to the appropriate directory: `cd reactivity`. 37 | 3. Copy the `.sample.env` to `.env` and change any details as required. 38 | 4. Run `yarn install` in order to install dependencies. 39 | 5. Run `yarn dev` for development mode or `yarn prod` for production mode and you will see the app running at `http://localhost:[PORT_SPECIFIED_IN_.ENV]`. 40 | 41 | ## Development suggestions 42 | 43 | 1. set `ENABLE_SW` to `false` to disable the service worker during development. 44 | 2. set `NODE_ENV` to `development` to enable hot reloading. 45 | 46 | ## Deployment 47 | 48 | This will largely vary however heres a super simple overview. 49 | 50 | 1. Run `yarn build` 51 | 2. Run either `yarn start` or `node bin/server.prod.js` to start the application. 52 | 53 | You could also run `start:prod` after step one to immediately launch the app after its been built. 54 | 55 | ## Contributing 56 | 57 | Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details on our code of conduct, and the process for submitting pull requests to us. 58 | 59 | ## Authors 60 | 61 | * **Dawid** - *Initial work* - [dawidvdh](https://github.com/dawidvdh) 62 | * **Ross** - *Initial work* - [rocbear](https://github.com/rocbear) 63 | 64 | See also the list of [contributors](https://github.com/madeagency/reactivity/graphs/contributors) who participated in this project. 65 | 66 | License 67 | ------- 68 | 69 | Reactivity is © 2017 MADE Code PTY Ltd. 70 | It is free software, and may be redistributed under the terms specified in the [LICENSE] file. 71 | 72 | [LICENSE]: LICENSE 73 | 74 | Maintained by 75 | ---------------- 76 | 77 | [![madeagency](https://www.made.co.za/logo.png)](https://www.made.co.za?utm_source=github) 78 | 79 | Reactivity was created and is maintained MADE Agency PTY Ltd. 80 | The names and logos for MADE Code are trademarks of MADE Code PTY Ltd. 81 | 82 | We love open source software. See our [Github Profile](https://github.com/madeagency) for more. 83 | 84 | We're always looking for talented people who love programming. [Get in touch] with us. 85 | 86 | [Get in touch]: https://www.madecode.co.za?utm_source=github 87 | -------------------------------------------------------------------------------- /bin/server.dev.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | const webpack = require('webpack') 3 | const webpackDevMiddleware = require('webpack-dev-middleware') 4 | const webpackHotMiddleware = require('webpack-hot-middleware') 5 | const webpackHotServerMiddleware = require('webpack-hot-server-middleware') 6 | const { app } = require('../src/server') 7 | 8 | const clientConfig = require('../webpack/client.dev') 9 | const serverConfig = require('../webpack/server.dev') 10 | 11 | const { 12 | output: { publicPath } 13 | } = clientConfig 14 | const compiler = webpack([clientConfig, serverConfig]) 15 | const clientCompiler = compiler.compilers[0] 16 | const options = { publicPath, stats: { colors: true } } 17 | const devMiddleware = webpackDevMiddleware(compiler, options) 18 | 19 | app.use(devMiddleware) 20 | app.use(webpackHotMiddleware(clientCompiler)) 21 | app.use(webpackHotServerMiddleware(compiler)) 22 | 23 | let isBuilt = false 24 | 25 | devMiddleware.waitUntilValid( 26 | () => 27 | !isBuilt && 28 | app.listen(process.env.APP_PORT, () => { 29 | isBuilt = true 30 | console.log(`Listening @ http://localhost:${process.env.APP_PORT}/`) 31 | }) 32 | ) 33 | -------------------------------------------------------------------------------- /bin/server.prod.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config() 2 | const express = require('express') 3 | const compression = require('compression') 4 | const zlib = require('zlib') 5 | const { app } = require('../src/server') 6 | const clientConfig = require('../webpack/client.prod') 7 | 8 | const { 9 | output: { publicPath } 10 | } = clientConfig 11 | const outputPath = clientConfig.output.path 12 | 13 | const clientStats = require('../build/stats.json') // eslint-disable-line 14 | const serverRender = require('../build/server.js').default 15 | 16 | app.use(publicPath, express.static(outputPath)) 17 | app.use( 18 | compression({ flush: zlib.constants.Z_PARTIAL_FLUSH }), 19 | serverRender({ clientStats }) 20 | ) 21 | 22 | app.listen(process.env.APP_PORT, () => { 23 | console.log(`Listening @ http://localhost:${process.env.APP_PORT}/`) 24 | }) 25 | -------------------------------------------------------------------------------- /flow-typed/hotModule.js.flow: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | declare var module: { 4 | hot: { 5 | accept(path: string, callback: () => void): void 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /flow-typed/npm/redux-observable_v0.14.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 97888e093de45f01ade721f04ec3dd42 2 | // flow-typed version: b43dff3e0e/redux-observable_v0.14.x/flow_>=v0.47.x 3 | 4 | import { Observable } from 'rxjs'; 5 | 6 | declare module 'redux-observable' { 7 | import type { MiddlewareAPI, Dispatch } from 'redux'; 8 | 9 | declare export type Epic = (action$: ActionsObservable, store: MiddlewareAPI, dependencies: D) => Observable; 10 | 11 | declare export type EpicMiddlewareAdapter = { 12 | input: Observable => Observable, 13 | output: Observable => Observable 14 | }; 15 | declare export type EpicMiddlewareOptions = { 16 | adapter?: EpicMiddlewareAdapter, 17 | dependencies?: D 18 | }; 19 | declare export type EpicMiddleware = { 20 | (api: MiddlewareAPI): (next: Dispatch) => Dispatch; 21 | replaceEpic(epic: Epic): void; 22 | } 23 | 24 | declare export class ActionsObservable }> extends Observable { 25 | static of(...actions: Array): ActionsObservable; 26 | static from(actions: Iterable, scheduler: rxjs$SchedulerClass): ActionsObservable; 27 | constructor(actionsSubject: Observable): void; 28 | lift(operator: Function): ActionsObservable; 29 | ofType(...keys: Array<$PropertyType>): ActionsObservable; 30 | } 31 | 32 | declare export function combineEpics(...epics: Array>): Epic; 33 | 34 | declare export function createEpicMiddleware(epic: Epic, options?: EpicMiddlewareOptions): EpicMiddleware; 35 | 36 | declare export var EPIC_END: '@@redux-observable/EPIC_END'; 37 | } -------------------------------------------------------------------------------- /flow-typed/npm/redux_v3.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 33b83b6284653250e74578cf4dbe6124 2 | // flow-typed version: e282e4128f/redux_v3.x.x/flow_>=v0.33.x 3 | 4 | declare module 'redux' { 5 | 6 | /* 7 | 8 | S = State 9 | A = Action 10 | D = Dispatch 11 | 12 | */ 13 | 14 | declare export type DispatchAPI = (action: A) => A; 15 | declare export type Dispatch }> = DispatchAPI; 16 | 17 | declare export type MiddlewareAPI> = { 18 | dispatch: D; 19 | getState(): S; 20 | }; 21 | 22 | declare export type Store> = { 23 | // rewrite MiddlewareAPI members in order to get nicer error messages (intersections produce long messages) 24 | dispatch: D; 25 | getState(): S; 26 | subscribe(listener: () => void): () => void; 27 | replaceReducer(nextReducer: Reducer): void 28 | }; 29 | 30 | declare export type Reducer = (state: S, action: A) => S; 31 | 32 | declare export type CombinedReducer = (state: $Shape & {} | void, action: A) => S; 33 | 34 | declare export type Middleware> = 35 | (api: MiddlewareAPI) => 36 | (next: D) => D; 37 | 38 | declare export type StoreCreator> = { 39 | (reducer: Reducer, enhancer?: StoreEnhancer): Store; 40 | (reducer: Reducer, preloadedState: S, enhancer?: StoreEnhancer): Store; 41 | }; 42 | 43 | declare export type StoreEnhancer> = (next: StoreCreator) => StoreCreator; 44 | 45 | declare export function createStore(reducer: Reducer, enhancer?: StoreEnhancer): Store; 46 | declare export function createStore(reducer: Reducer, preloadedState: S, enhancer?: StoreEnhancer): Store; 47 | 48 | declare export function applyMiddleware(...middlewares: Array>): StoreEnhancer; 49 | 50 | declare export type ActionCreator = (...args: Array) => A; 51 | declare export type ActionCreators = { [key: K]: ActionCreator }; 52 | 53 | declare export function bindActionCreators, D: DispatchAPI>(actionCreator: C, dispatch: D): C; 54 | declare export function bindActionCreators, D: DispatchAPI>(actionCreators: C, dispatch: D): C; 55 | 56 | declare export function combineReducers(reducers: O): CombinedReducer<$ObjMap(r: Reducer) => S>, A>; 57 | 58 | declare export function compose(ab: (a: A) => B): (a: A) => B 59 | declare export function compose( 60 | bc: (b: B) => C, 61 | ab: (a: A) => B 62 | ): (a: A) => C 63 | declare export function compose( 64 | cd: (c: C) => D, 65 | bc: (b: B) => C, 66 | ab: (a: A) => B 67 | ): (a: A) => D 68 | declare export function compose( 69 | de: (d: D) => E, 70 | cd: (c: C) => D, 71 | bc: (b: B) => C, 72 | ab: (a: A) => B 73 | ): (a: A) => E 74 | declare export function compose( 75 | ef: (e: E) => F, 76 | de: (d: D) => E, 77 | cd: (c: C) => D, 78 | bc: (b: B) => C, 79 | ab: (a: A) => B 80 | ): (a: A) => F 81 | declare export function compose( 82 | fg: (f: F) => G, 83 | ef: (e: E) => F, 84 | de: (d: D) => E, 85 | cd: (c: C) => D, 86 | bc: (b: B) => C, 87 | ab: (a: A) => B 88 | ): (a: A) => G 89 | declare export function compose( 90 | gh: (g: G) => H, 91 | fg: (f: F) => G, 92 | ef: (e: E) => F, 93 | de: (d: D) => E, 94 | cd: (c: C) => D, 95 | bc: (b: B) => C, 96 | ab: (a: A) => B 97 | ): (a: A) => H 98 | declare export function compose( 99 | hi: (h: H) => I, 100 | gh: (g: G) => H, 101 | fg: (f: F) => G, 102 | ef: (e: E) => F, 103 | de: (d: D) => E, 104 | cd: (c: C) => D, 105 | bc: (b: B) => C, 106 | ab: (a: A) => B 107 | ): (a: A) => I 108 | 109 | } 110 | -------------------------------------------------------------------------------- /flow-typed/npm/rxjs_v5.0.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f998e895a1b69a158bfdbd4c08f89006 2 | // flow-typed version: 8b9804dad4/rxjs_v5.0.x/flow_>=v0.34.x 3 | 4 | // FIXME(samgoldman) Remove top-level interface once Babel supports 5 | // `declare interface` syntax. 6 | // FIXME(samgoldman) Remove this once rxjs$Subject can mixin rxjs$Observer 7 | interface rxjs$IObserver<-T> { 8 | closed?: boolean, 9 | next(value: T): mixed, 10 | error(error: any): mixed, 11 | complete(): mixed 12 | } 13 | 14 | type rxjs$PartialObserver<-T> = 15 | | { 16 | +next: (value: T) => mixed, 17 | +error?: (error: any) => mixed, 18 | +complete?: () => mixed 19 | } 20 | | { 21 | +next?: (value: T) => mixed, 22 | +error: (error: any) => mixed, 23 | +complete?: () => mixed 24 | } 25 | | { 26 | +next?: (value: T) => mixed, 27 | +error?: (error: any) => mixed, 28 | +complete: () => mixed 29 | }; 30 | 31 | interface rxjs$ISubscription { 32 | unsubscribe(): void 33 | } 34 | 35 | type rxjs$TeardownLogic = rxjs$ISubscription | (() => void); 36 | 37 | type rxjs$EventListenerOptions = 38 | | { 39 | capture?: boolean, 40 | passive?: boolean, 41 | once?: boolean 42 | } 43 | | boolean; 44 | 45 | declare class rxjs$Observable<+T> { 46 | static bindCallback( 47 | callbackFunc: (callback: (_: void) => any) => any, 48 | selector?: void, 49 | scheduler?: rxjs$SchedulerClass 50 | ): () => rxjs$Observable, 51 | static bindCallback( 52 | callbackFunc: (callback: (result: U) => any) => any, 53 | selector?: void, 54 | scheduler?: rxjs$SchedulerClass 55 | ): () => rxjs$Observable, 56 | static bindCallback( 57 | callbackFunc: (v1: T, callback: (result: U) => any) => any, 58 | selector?: void, 59 | scheduler?: rxjs$SchedulerClass 60 | ): (v1: T) => rxjs$Observable, 61 | static bindCallback( 62 | callbackFunc: (v1: T, v2: T2, callback: (result: U) => any) => any, 63 | selector?: void, 64 | scheduler?: rxjs$SchedulerClass 65 | ): (v1: T, v2: T2) => rxjs$Observable, 66 | static bindCallback( 67 | callbackFunc: (v1: T, v2: T2, v3: T3, callback: (result: U) => any) => any, 68 | selector?: void, 69 | scheduler?: rxjs$SchedulerClass 70 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable, 71 | static bindCallback( 72 | callbackFunc: ( 73 | v1: T, 74 | v2: T2, 75 | v3: T3, 76 | v4: T4, 77 | callback: (result: U) => any 78 | ) => any, 79 | selector?: void, 80 | scheduler?: rxjs$SchedulerClass 81 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable, 82 | static bindCallback( 83 | callbackFunc: ( 84 | v1: T, 85 | v2: T2, 86 | v3: T3, 87 | v4: T4, 88 | v5: T5, 89 | callback: (result: U) => any 90 | ) => any, 91 | selector?: void, 92 | scheduler?: rxjs$SchedulerClass 93 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable, 94 | static bindCallback( 95 | callbackFunc: ( 96 | v1: T, 97 | v2: T2, 98 | v3: T3, 99 | v4: T4, 100 | v5: T5, 101 | v6: T6, 102 | callback: (result: U) => any 103 | ) => any, 104 | selector?: void, 105 | scheduler?: rxjs$SchedulerClass 106 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable, 107 | static bindCallback( 108 | callbackFunc: (callback: (...args: Array) => any) => any, 109 | selector: (...args: Array) => U, 110 | scheduler?: rxjs$SchedulerClass 111 | ): () => rxjs$Observable, 112 | static bindCallback( 113 | callbackFunc: (v1: T, callback: (...args: Array) => any) => any, 114 | selector: (...args: Array) => U, 115 | scheduler?: rxjs$SchedulerClass 116 | ): (v1: T) => rxjs$Observable, 117 | static bindCallback( 118 | callbackFunc: ( 119 | v1: T, 120 | v2: T2, 121 | callback: (...args: Array) => any 122 | ) => any, 123 | selector: (...args: Array) => U, 124 | scheduler?: rxjs$SchedulerClass 125 | ): (v1: T, v2: T2) => rxjs$Observable, 126 | static bindCallback( 127 | callbackFunc: ( 128 | v1: T, 129 | v2: T2, 130 | v3: T3, 131 | callback: (...args: Array) => any 132 | ) => any, 133 | selector: (...args: Array) => U, 134 | scheduler?: rxjs$SchedulerClass 135 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable, 136 | static bindCallback( 137 | callbackFunc: ( 138 | v1: T, 139 | v2: T2, 140 | v3: T3, 141 | v4: T4, 142 | callback: (...args: Array) => any 143 | ) => any, 144 | selector: (...args: Array) => U, 145 | scheduler?: rxjs$SchedulerClass 146 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable, 147 | static bindCallback( 148 | callbackFunc: ( 149 | v1: T, 150 | v2: T2, 151 | v3: T3, 152 | v4: T4, 153 | v5: T5, 154 | callback: (...args: Array) => any 155 | ) => any, 156 | selector: (...args: Array) => U, 157 | scheduler?: rxjs$SchedulerClass 158 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable, 159 | static bindCallback( 160 | callbackFunc: ( 161 | v1: T, 162 | v2: T2, 163 | v3: T3, 164 | v4: T4, 165 | v5: T5, 166 | v6: T6, 167 | callback: (...args: Array) => any 168 | ) => any, 169 | selector: (...args: Array) => U, 170 | scheduler?: rxjs$SchedulerClass 171 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable, 172 | static bindCallback( 173 | callbackFunc: Function, 174 | selector?: void, 175 | scheduler?: rxjs$SchedulerClass 176 | ): (...args: Array) => rxjs$Observable, 177 | static bindCallback( 178 | callbackFunc: Function, 179 | selector?: (...args: Array) => T, 180 | scheduler?: rxjs$SchedulerClass 181 | ): (...args: Array) => rxjs$Observable, 182 | 183 | static bindNodeCallback( 184 | callbackFunc: (callback: (err: any, result: U) => any) => any, 185 | selector?: void, 186 | scheduler?: rxjs$SchedulerClass 187 | ): () => rxjs$Observable, 188 | static bindNodeCallback( 189 | callbackFunc: (v1: T, callback: (err: any, result: U) => any) => any, 190 | selector?: void, 191 | scheduler?: rxjs$SchedulerClass 192 | ): (v1: T) => rxjs$Observable, 193 | static bindNodeCallback( 194 | callbackFunc: ( 195 | v1: T, 196 | v2: T2, 197 | callback: (err: any, result: U) => any 198 | ) => any, 199 | selector?: void, 200 | scheduler?: rxjs$SchedulerClass 201 | ): (v1: T, v2: T2) => rxjs$Observable, 202 | static bindNodeCallback( 203 | callbackFunc: ( 204 | v1: T, 205 | v2: T2, 206 | v3: T3, 207 | callback: (err: any, result: U) => any 208 | ) => any, 209 | selector?: void, 210 | scheduler?: rxjs$SchedulerClass 211 | ): (v1: T, v2: T2, v3: T3) => rxjs$Observable, 212 | static bindNodeCallback( 213 | callbackFunc: ( 214 | v1: T, 215 | v2: T2, 216 | v3: T3, 217 | v4: T4, 218 | callback: (err: any, result: U) => any 219 | ) => any, 220 | selector?: void, 221 | scheduler?: rxjs$SchedulerClass 222 | ): (v1: T, v2: T2, v3: T3, v4: T4) => rxjs$Observable, 223 | static bindNodeCallback( 224 | callbackFunc: ( 225 | v1: T, 226 | v2: T2, 227 | v3: T3, 228 | v4: T4, 229 | v5: T5, 230 | callback: (err: any, result: U) => any 231 | ) => any, 232 | selector?: void, 233 | scheduler?: rxjs$SchedulerClass 234 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5) => rxjs$Observable, 235 | static bindNodeCallback( 236 | callbackFunc: ( 237 | v1: T, 238 | v2: T2, 239 | v3: T3, 240 | v4: T4, 241 | v5: T5, 242 | v6: T6, 243 | callback: (err: any, result: U) => any 244 | ) => any, 245 | selector?: void, 246 | scheduler?: rxjs$SchedulerClass 247 | ): (v1: T, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6) => rxjs$Observable, 248 | static bindNodeCallback( 249 | callbackFunc: Function, 250 | selector?: void, 251 | scheduler?: rxjs$SchedulerClass 252 | ): (...args: Array) => rxjs$Observable, 253 | static bindNodeCallback( 254 | callbackFunc: Function, 255 | selector?: (...args: Array) => T, 256 | scheduler?: rxjs$SchedulerClass 257 | ): (...args: Array) => rxjs$Observable, 258 | 259 | static concat(...sources: rxjs$Observable[]): rxjs$Observable, 260 | 261 | static create( 262 | subscribe: ( 263 | observer: rxjs$Observer 264 | ) => rxjs$ISubscription | Function | void 265 | ): rxjs$Observable, 266 | 267 | static defer( 268 | observableFactory: () => rxjs$Observable | Promise 269 | ): rxjs$Observable, 270 | 271 | static from(iterable: Iterable): rxjs$Observable, 272 | 273 | static fromEvent( 274 | element: any, 275 | eventName: string, 276 | ...none: Array 277 | ): rxjs$Observable, 278 | static fromEvent( 279 | element: any, 280 | eventName: string, 281 | options: rxjs$EventListenerOptions, 282 | ...none: Array 283 | ): rxjs$Observable, 284 | static fromEvent( 285 | element: any, 286 | eventName: string, 287 | selector: () => T, 288 | ...none: Array 289 | ): rxjs$Observable, 290 | static fromEvent( 291 | element: any, 292 | eventName: string, 293 | options: rxjs$EventListenerOptions, 294 | selector: () => T 295 | ): rxjs$Observable, 296 | 297 | static fromEventPattern( 298 | addHandler: (handler: (item: T) => void) => void, 299 | removeHandler: (handler: (item: T) => void) => void, 300 | selector?: () => T 301 | ): rxjs$Observable, 302 | 303 | static fromPromise(promise: Promise): rxjs$Observable, 304 | 305 | static empty(): rxjs$Observable, 306 | 307 | static interval(period: number): rxjs$Observable, 308 | 309 | static timer( 310 | initialDelay: number | Date, 311 | period?: number, 312 | scheduler?: rxjs$SchedulerClass 313 | ): rxjs$Observable, 314 | 315 | static merge( 316 | source0: rxjs$Observable, 317 | source1: rxjs$Observable 318 | ): rxjs$Observable, 319 | static merge( 320 | source0: rxjs$Observable, 321 | source1: rxjs$Observable, 322 | source2: rxjs$Observable 323 | ): rxjs$Observable, 324 | static merge(...sources: rxjs$Observable[]): rxjs$Observable, 325 | 326 | static never(): rxjs$Observable, 327 | 328 | static of(...values: T[]): rxjs$Observable, 329 | 330 | static throw(error: any): rxjs$Observable, 331 | 332 | audit( 333 | durationSelector: (value: T) => rxjs$Observable | Promise 334 | ): rxjs$Observable, 335 | 336 | race(other: rxjs$Observable): rxjs$Observable, 337 | 338 | repeat(count?: number): rxjs$Observable, 339 | 340 | buffer(bufferBoundaries: rxjs$Observable): rxjs$Observable>, 341 | 342 | bufferCount(bufferSize: number, startBufferEvery?: number): rxjs$Observable>; 343 | 344 | catch( 345 | selector: (err: any, caught: rxjs$Observable) => rxjs$Observable 346 | ): rxjs$Observable, 347 | 348 | concat(...sources: rxjs$Observable[]): rxjs$Observable, 349 | 350 | concatAll(): rxjs$Observable, 351 | 352 | concatMap( 353 | f: (value: T) => rxjs$Observable | Promise | Iterable 354 | ): rxjs$Observable, 355 | 356 | debounceTime( 357 | dueTime: number, 358 | scheduler?: rxjs$SchedulerClass 359 | ): rxjs$Observable, 360 | 361 | delay(dueTime: number, scheduler?: rxjs$SchedulerClass): rxjs$Observable, 362 | 363 | distinctUntilChanged(compare?: (x: T, y: T) => boolean): rxjs$Observable, 364 | 365 | distinct( 366 | keySelector?: (value: T) => U, 367 | flushes?: rxjs$Observable 368 | ): rxjs$Observable, 369 | 370 | distinctUntilKeyChanged( 371 | key: string, 372 | compare?: (x: mixed, y: mixed) => boolean 373 | ): rxjs$Observable, 374 | 375 | elementAt(index: number, defaultValue?: T): rxjs$Observable, 376 | 377 | expand( 378 | project: (value: T, index: number) => rxjs$Observable, 379 | concurrent?: number, 380 | scheduler?: rxjs$SchedulerClass 381 | ): rxjs$Observable, 382 | 383 | filter( 384 | predicate: (value: T, index: number) => boolean, 385 | thisArg?: any 386 | ): rxjs$Observable, 387 | 388 | finally(f: () => mixed): rxjs$Observable, 389 | 390 | first( 391 | predicate?: (value: T, index: number, source: rxjs$Observable) => boolean 392 | ): rxjs$Observable, 393 | first( 394 | predicate: ?( 395 | value: T, 396 | index: number, 397 | source: rxjs$Observable 398 | ) => boolean, 399 | resultSelector: (value: T, index: number) => U 400 | ): rxjs$Observable, 401 | first( 402 | predicate: ?( 403 | value: T, 404 | index: number, 405 | source: rxjs$Observable 406 | ) => boolean, 407 | resultSelector: ?(value: T, index: number) => U, 408 | defaultValue: U 409 | ): rxjs$Observable, 410 | 411 | groupBy( 412 | keySelector: (value: T) => mixed, 413 | elementSelector?: (value: T) => T, 414 | compare?: (x: T, y: T) => boolean 415 | ): rxjs$Observable>, 416 | 417 | ignoreElements(): rxjs$Observable, 418 | 419 | let( 420 | project: (self: rxjs$Observable) => rxjs$Observable 421 | ): rxjs$Observable, 422 | 423 | // Alias for `let` 424 | letBind( 425 | project: (self: rxjs$Observable) => rxjs$Observable 426 | ): rxjs$Observable, 427 | 428 | switch(): T, // assumption: T is Observable 429 | 430 | // Alias for `mergeMap` 431 | flatMap( 432 | project: (value: T) => rxjs$Observable | Promise | Iterable, 433 | index?: number 434 | ): rxjs$Observable, 435 | 436 | flatMapTo(innerObservable: rxjs$Observable): rxjs$Observable, 437 | 438 | flatMapTo( 439 | innerObservable: rxjs$Observable, 440 | resultSelector: ( 441 | outerValue: T, 442 | innerValue: U, 443 | outerIndex: number, 444 | innerIndex: number 445 | ) => V, 446 | concurrent?: number 447 | ): rxjs$Observable, 448 | 449 | switchMap( 450 | project: (value: T) => rxjs$Observable | Promise | Iterable, 451 | index?: number 452 | ): rxjs$Observable, 453 | 454 | switchMapTo(innerObservable: rxjs$Observable): rxjs$Observable, 455 | 456 | map(f: (value: T) => U): rxjs$Observable, 457 | 458 | mapTo(value: U): rxjs$Observable, 459 | 460 | merge(other: rxjs$Observable): rxjs$Observable, 461 | 462 | mergeAll(): rxjs$Observable, 463 | 464 | mergeMap( 465 | project: ( 466 | value: T, 467 | index?: number 468 | ) => rxjs$Observable | Promise | Iterable, 469 | index?: number 470 | ): rxjs$Observable, 471 | 472 | mergeMapTo(innerObservable: rxjs$Observable): rxjs$Observable, 473 | 474 | mergeMapTo( 475 | innerObservable: rxjs$Observable, 476 | resultSelector: ( 477 | outerValue: T, 478 | innerValue: U, 479 | outerIndex: number, 480 | innerIndex: number 481 | ) => V, 482 | concurrent?: number 483 | ): rxjs$Observable, 484 | 485 | multicast( 486 | subjectOrSubjectFactory: rxjs$Subject | (() => rxjs$Subject) 487 | ): rxjs$ConnectableObservable, 488 | 489 | observeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable, 490 | 491 | pairwise(): rxjs$Observable<[T, T]>, 492 | 493 | publish(): rxjs$ConnectableObservable, 494 | 495 | publishLast(): rxjs$ConnectableObservable, 496 | 497 | reduce( 498 | accumulator: ( 499 | acc: U, 500 | currentValue: T, 501 | index: number, 502 | source: rxjs$Observable 503 | ) => U, 504 | seed: U 505 | ): rxjs$Observable, 506 | 507 | sample(notifier: rxjs$Observable): rxjs$Observable, 508 | 509 | sampleTime( 510 | delay: number, 511 | scheduler?: rxjs$SchedulerClass 512 | ): rxjs$Observable, 513 | 514 | publishReplay( 515 | bufferSize?: number, 516 | windowTime?: number, 517 | scheduler?: rxjs$SchedulerClass 518 | ): rxjs$ConnectableObservable, 519 | 520 | retry(retryCount: ?number): rxjs$Observable, 521 | 522 | retryWhen( 523 | notifier: (errors: rxjs$Observable) => rxjs$Observable 524 | ): rxjs$Observable, 525 | 526 | scan(f: (acc: U, value: T) => U, initialValue: U): rxjs$Observable, 527 | 528 | share(): rxjs$Observable, 529 | 530 | skip(count: number): rxjs$Observable, 531 | 532 | skipUntil(other: rxjs$Observable | Promise): rxjs$Observable, 533 | 534 | skipWhile( 535 | predicate: (value: T, index: number) => boolean 536 | ): rxjs$Observable, 537 | 538 | startWith(...values: Array): rxjs$Observable, 539 | 540 | subscribeOn(scheduler: rxjs$SchedulerClass): rxjs$Observable, 541 | 542 | take(count: number): rxjs$Observable, 543 | 544 | takeUntil(other: rxjs$Observable): rxjs$Observable, 545 | 546 | takeWhile( 547 | predicate: (value: T, index: number) => boolean 548 | ): rxjs$Observable, 549 | 550 | do( 551 | onNext?: (value: T) => mixed, 552 | onError?: (error: any) => mixed, 553 | onCompleted?: () => mixed 554 | ): rxjs$Observable, 555 | do(observer: { 556 | next?: (value: T) => mixed, 557 | error?: (error: any) => mixed, 558 | complete?: () => mixed 559 | }): rxjs$Observable, 560 | 561 | throttleTime(duration: number): rxjs$Observable, 562 | 563 | timeout(due: number | Date, _: void): rxjs$Observable, 564 | 565 | toArray(): rxjs$Observable, 566 | 567 | toPromise(): Promise, 568 | 569 | subscribe(observer: rxjs$PartialObserver): rxjs$Subscription, 570 | subscribe( 571 | onNext: ?(value: T) => mixed, 572 | onError: ?(error: any) => mixed, 573 | onCompleted: ?() => mixed 574 | ): rxjs$Subscription, 575 | 576 | static combineLatest( 577 | a: rxjs$Observable, 578 | resultSelector: (a: A) => B 579 | ): rxjs$Observable, 580 | 581 | static combineLatest( 582 | a: rxjs$Observable, 583 | b: rxjs$Observable, 584 | resultSelector: (a: A, b: B) => C 585 | ): rxjs$Observable, 586 | 587 | static combineLatest( 588 | a: rxjs$Observable, 589 | b: rxjs$Observable, 590 | c: rxjs$Observable, 591 | resultSelector: (a: A, b: B, c: C) => D 592 | ): rxjs$Observable, 593 | 594 | static combineLatest( 595 | a: rxjs$Observable, 596 | b: rxjs$Observable, 597 | c: rxjs$Observable, 598 | d: rxjs$Observable, 599 | resultSelector: (a: A, b: B, c: C, d: D) => E 600 | ): rxjs$Observable, 601 | 602 | static combineLatest( 603 | a: rxjs$Observable, 604 | b: rxjs$Observable, 605 | c: rxjs$Observable, 606 | d: rxjs$Observable, 607 | e: rxjs$Observable, 608 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 609 | ): rxjs$Observable, 610 | 611 | static combineLatest( 612 | a: rxjs$Observable, 613 | b: rxjs$Observable, 614 | c: rxjs$Observable, 615 | d: rxjs$Observable, 616 | e: rxjs$Observable, 617 | f: rxjs$Observable, 618 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 619 | ): rxjs$Observable, 620 | 621 | static combineLatest( 622 | a: rxjs$Observable, 623 | b: rxjs$Observable, 624 | c: rxjs$Observable, 625 | d: rxjs$Observable, 626 | e: rxjs$Observable, 627 | f: rxjs$Observable, 628 | g: rxjs$Observable, 629 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 630 | ): rxjs$Observable, 631 | 632 | static combineLatest( 633 | a: rxjs$Observable, 634 | _: void, 635 | ): rxjs$Observable<[A]>; 636 | 637 | static combineLatest( 638 | a: rxjs$Observable, 639 | b: rxjs$Observable, 640 | _: void 641 | ): rxjs$Observable<[A, B]>, 642 | 643 | static combineLatest( 644 | a: rxjs$Observable, 645 | b: rxjs$Observable, 646 | c: rxjs$Observable, 647 | _: void 648 | ): rxjs$Observable<[A, B, C]>, 649 | 650 | static combineLatest( 651 | a: rxjs$Observable, 652 | b: rxjs$Observable, 653 | c: rxjs$Observable, 654 | d: rxjs$Observable, 655 | _: void 656 | ): rxjs$Observable<[A, B, C, D]>, 657 | 658 | static combineLatest( 659 | a: rxjs$Observable, 660 | b: rxjs$Observable, 661 | c: rxjs$Observable, 662 | d: rxjs$Observable, 663 | e: rxjs$Observable, 664 | _: void 665 | ): rxjs$Observable<[A, B, C, D, E]>, 666 | 667 | static combineLatest( 668 | a: rxjs$Observable, 669 | b: rxjs$Observable, 670 | c: rxjs$Observable, 671 | d: rxjs$Observable, 672 | e: rxjs$Observable, 673 | f: rxjs$Observable, 674 | _: void 675 | ): rxjs$Observable<[A, B, C, D, E, F]>, 676 | 677 | static combineLatest( 678 | a: rxjs$Observable, 679 | b: rxjs$Observable, 680 | c: rxjs$Observable, 681 | d: rxjs$Observable, 682 | e: rxjs$Observable, 683 | f: rxjs$Observable, 684 | g: rxjs$Observable, 685 | _: void 686 | ): rxjs$Observable<[A, B, C, D, E, F, G]>, 687 | 688 | static combineLatest( 689 | a: rxjs$Observable, 690 | b: rxjs$Observable, 691 | c: rxjs$Observable, 692 | d: rxjs$Observable, 693 | e: rxjs$Observable, 694 | f: rxjs$Observable, 695 | g: rxjs$Observable, 696 | h: rxjs$Observable, 697 | _: void 698 | ): rxjs$Observable<[A, B, C, D, E, F, G, H]>, 699 | 700 | combineLatest(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>, 701 | 702 | combineLatest( 703 | a: rxjs$Observable, 704 | resultSelector: (a: A) => B 705 | ): rxjs$Observable, 706 | 707 | combineLatest( 708 | a: rxjs$Observable, 709 | b: rxjs$Observable, 710 | resultSelector: (a: A, b: B) => C 711 | ): rxjs$Observable, 712 | 713 | combineLatest( 714 | a: rxjs$Observable, 715 | b: rxjs$Observable, 716 | c: rxjs$Observable, 717 | resultSelector: (a: A, b: B, c: C) => D 718 | ): rxjs$Observable, 719 | 720 | combineLatest( 721 | a: rxjs$Observable, 722 | b: rxjs$Observable, 723 | c: rxjs$Observable, 724 | d: rxjs$Observable, 725 | resultSelector: (a: A, b: B, c: C, d: D) => E 726 | ): rxjs$Observable, 727 | 728 | combineLatest( 729 | a: rxjs$Observable, 730 | b: rxjs$Observable, 731 | c: rxjs$Observable, 732 | d: rxjs$Observable, 733 | e: rxjs$Observable, 734 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 735 | ): rxjs$Observable, 736 | 737 | combineLatest( 738 | a: rxjs$Observable, 739 | b: rxjs$Observable, 740 | c: rxjs$Observable, 741 | d: rxjs$Observable, 742 | e: rxjs$Observable, 743 | f: rxjs$Observable, 744 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 745 | ): rxjs$Observable, 746 | 747 | combineLatest( 748 | a: rxjs$Observable, 749 | b: rxjs$Observable, 750 | c: rxjs$Observable, 751 | d: rxjs$Observable, 752 | e: rxjs$Observable, 753 | f: rxjs$Observable, 754 | g: rxjs$Observable, 755 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 756 | ): rxjs$Observable, 757 | 758 | static forkJoin( 759 | a: rxjs$Observable, 760 | resultSelector: (a: A) => B 761 | ): rxjs$Observable, 762 | 763 | static forkJoin( 764 | a: rxjs$Observable, 765 | b: rxjs$Observable, 766 | resultSelector: (a: A, b: B) => C 767 | ): rxjs$Observable, 768 | 769 | static forkJoin( 770 | a: rxjs$Observable, 771 | b: rxjs$Observable, 772 | c: rxjs$Observable, 773 | resultSelector: (a: A, b: B, c: C) => D 774 | ): rxjs$Observable, 775 | 776 | static forkJoin( 777 | a: rxjs$Observable, 778 | b: rxjs$Observable, 779 | c: rxjs$Observable, 780 | d: rxjs$Observable, 781 | resultSelector: (a: A, b: B, c: C, d: D) => E 782 | ): rxjs$Observable, 783 | 784 | static forkJoin( 785 | a: rxjs$Observable, 786 | b: rxjs$Observable, 787 | c: rxjs$Observable, 788 | d: rxjs$Observable, 789 | e: rxjs$Observable, 790 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 791 | ): rxjs$Observable, 792 | 793 | static forkJoin( 794 | a: rxjs$Observable, 795 | b: rxjs$Observable, 796 | c: rxjs$Observable, 797 | d: rxjs$Observable, 798 | e: rxjs$Observable, 799 | f: rxjs$Observable, 800 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 801 | ): rxjs$Observable, 802 | 803 | static forkJoin( 804 | a: rxjs$Observable, 805 | b: rxjs$Observable, 806 | c: rxjs$Observable, 807 | d: rxjs$Observable, 808 | e: rxjs$Observable, 809 | f: rxjs$Observable, 810 | g: rxjs$Observable, 811 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 812 | ): rxjs$Observable, 813 | 814 | static forkJoin( 815 | a: rxjs$Observable, 816 | b: rxjs$Observable, 817 | _: void 818 | ): rxjs$Observable<[A, B]>, 819 | 820 | static forkJoin( 821 | a: rxjs$Observable, 822 | b: rxjs$Observable, 823 | c: rxjs$Observable, 824 | _: void 825 | ): rxjs$Observable<[A, B, C]>, 826 | 827 | static forkJoin( 828 | a: rxjs$Observable, 829 | b: rxjs$Observable, 830 | c: rxjs$Observable, 831 | d: rxjs$Observable, 832 | _: void 833 | ): rxjs$Observable<[A, B, C, D]>, 834 | 835 | static forkJoin( 836 | a: rxjs$Observable, 837 | b: rxjs$Observable, 838 | c: rxjs$Observable, 839 | d: rxjs$Observable, 840 | e: rxjs$Observable, 841 | _: void 842 | ): rxjs$Observable<[A, B, C, D, E]>, 843 | 844 | static forkJoin( 845 | a: rxjs$Observable, 846 | b: rxjs$Observable, 847 | c: rxjs$Observable, 848 | d: rxjs$Observable, 849 | e: rxjs$Observable, 850 | f: rxjs$Observable, 851 | _: void 852 | ): rxjs$Observable<[A, B, C, D, E, F]>, 853 | 854 | static forkJoin( 855 | a: rxjs$Observable, 856 | b: rxjs$Observable, 857 | c: rxjs$Observable, 858 | d: rxjs$Observable, 859 | e: rxjs$Observable, 860 | f: rxjs$Observable, 861 | g: rxjs$Observable, 862 | _: void 863 | ): rxjs$Observable<[A, B, C, D, E, F, G]>, 864 | 865 | static forkJoin( 866 | a: rxjs$Observable, 867 | b: rxjs$Observable, 868 | c: rxjs$Observable, 869 | d: rxjs$Observable, 870 | e: rxjs$Observable, 871 | f: rxjs$Observable, 872 | g: rxjs$Observable, 873 | h: rxjs$Observable, 874 | _: void 875 | ): rxjs$Observable<[A, B, C, D, E, F, G, H]>, 876 | 877 | withLatestFrom(a: rxjs$Observable, _: void): rxjs$Observable<[T, A]>, 878 | 879 | withLatestFrom( 880 | a: rxjs$Observable, 881 | resultSelector: (a: A) => B 882 | ): rxjs$Observable, 883 | 884 | withLatestFrom( 885 | a: rxjs$Observable, 886 | b: rxjs$Observable, 887 | resultSelector: (a: A, b: B) => C 888 | ): rxjs$Observable, 889 | 890 | withLatestFrom( 891 | a: rxjs$Observable, 892 | b: rxjs$Observable, 893 | c: rxjs$Observable, 894 | resultSelector: (a: A, b: B, c: C) => D 895 | ): rxjs$Observable, 896 | 897 | withLatestFrom( 898 | a: rxjs$Observable, 899 | b: rxjs$Observable, 900 | c: rxjs$Observable, 901 | d: rxjs$Observable, 902 | resultSelector: (a: A, b: B, c: C, d: D) => E 903 | ): rxjs$Observable, 904 | 905 | withLatestFrom( 906 | a: rxjs$Observable, 907 | b: rxjs$Observable, 908 | c: rxjs$Observable, 909 | d: rxjs$Observable, 910 | e: rxjs$Observable, 911 | resultSelector: (a: A, b: B, c: C, d: D, e: E) => F 912 | ): rxjs$Observable, 913 | 914 | withLatestFrom( 915 | a: rxjs$Observable, 916 | b: rxjs$Observable, 917 | c: rxjs$Observable, 918 | d: rxjs$Observable, 919 | e: rxjs$Observable, 920 | f: rxjs$Observable, 921 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F) => G 922 | ): rxjs$Observable, 923 | 924 | withLatestFrom( 925 | a: rxjs$Observable, 926 | b: rxjs$Observable, 927 | c: rxjs$Observable, 928 | d: rxjs$Observable, 929 | e: rxjs$Observable, 930 | f: rxjs$Observable, 931 | g: rxjs$Observable, 932 | resultSelector: (a: A, b: B, c: C, d: D, e: E, f: F, g: G) => H 933 | ): rxjs$Observable, 934 | 935 | static using( 936 | resourceFactory: () => ?R, 937 | observableFactory: (resource: R) => rxjs$Observable | Promise | void 938 | ): rxjs$Observable, 939 | 940 | _subscribe(observer: rxjs$Subscriber): rxjs$Subscription, 941 | 942 | _isScalar: boolean, 943 | source: ?rxjs$Observable, 944 | operator: ?rxjs$Operator 945 | } 946 | 947 | declare class rxjs$ConnectableObservable extends rxjs$Observable { 948 | connect(): rxjs$Subscription, 949 | refCount(): rxjs$Observable 950 | } 951 | 952 | declare class rxjs$Observer { 953 | next(value: T): mixed, 954 | 955 | error(error: any): mixed, 956 | 957 | complete(): mixed 958 | } 959 | 960 | declare interface rxjs$Operator { 961 | call(subscriber: rxjs$Subscriber, source: any): rxjs$TeardownLogic 962 | } 963 | 964 | // FIXME(samgoldman) should be `mixins rxjs$Observable, rxjs$Observer` 965 | // once Babel parsing support exists: https://phabricator.babeljs.io/T6821 966 | declare class rxjs$Subject extends rxjs$Observable { 967 | asObservable(): rxjs$Observable, 968 | 969 | observers: Array>, 970 | 971 | unsubscribe(): void, 972 | 973 | // Copied from rxjs$Observer 974 | next(value: T): mixed, 975 | error(error: any): mixed, 976 | complete(): mixed, 977 | 978 | // For use in subclasses only: 979 | _next(value: T): void 980 | } 981 | 982 | declare class rxjs$AnonymousSubject extends rxjs$Subject { 983 | source: ?rxjs$Observable, 984 | destination: ?rxjs$Observer, 985 | 986 | constructor( 987 | destination?: rxjs$IObserver, 988 | source?: rxjs$Observable 989 | ): void, 990 | next(value: T): void, 991 | error(err: any): void, 992 | complete(): void 993 | } 994 | 995 | declare class rxjs$BehaviorSubject extends rxjs$Subject { 996 | constructor(initialValue: T): void, 997 | 998 | getValue(): T 999 | } 1000 | 1001 | declare class rxjs$ReplaySubject extends rxjs$Subject { 1002 | constructor( 1003 | bufferSize?: number, 1004 | windowTime?: number, 1005 | scheduler?: rxjs$SchedulerClass 1006 | ): void 1007 | } 1008 | 1009 | declare class rxjs$Subscription { 1010 | unsubscribe(): void, 1011 | add(teardown: rxjs$TeardownLogic): rxjs$Subscription 1012 | } 1013 | 1014 | declare class rxjs$Subscriber extends rxjs$Subscription { 1015 | static create( 1016 | next?: (x?: T) => void, 1017 | error?: (e?: any) => void, 1018 | complete?: () => void 1019 | ): rxjs$Subscriber, 1020 | 1021 | constructor( 1022 | destinationOrNext?: rxjs$PartialObserver | ((value: T) => void), 1023 | error?: (e?: any) => void, 1024 | complete?: () => void 1025 | ): void, 1026 | next(value?: T): void, 1027 | error(err?: any): void, 1028 | complete(): void, 1029 | unsubscribe(): void 1030 | } 1031 | 1032 | declare class rxjs$SchedulerClass { 1033 | schedule( 1034 | work: (state?: T) => void, 1035 | delay?: number, 1036 | state?: T 1037 | ): rxjs$Subscription 1038 | } 1039 | 1040 | declare class rxjs$TimeoutError extends Error {} 1041 | 1042 | declare module "rxjs" { 1043 | declare module.exports: { 1044 | Observable: typeof rxjs$Observable, 1045 | Observer: typeof rxjs$Observer, 1046 | ConnectableObservable: typeof rxjs$ConnectableObservable, 1047 | Subject: typeof rxjs$Subject, 1048 | Subscriber: typeof rxjs$Subscriber, 1049 | AnonymousSubject: typeof rxjs$AnonymousSubject, 1050 | BehaviorSubject: typeof rxjs$BehaviorSubject, 1051 | ReplaySubject: typeof rxjs$ReplaySubject, 1052 | Scheduler: { 1053 | asap: rxjs$SchedulerClass, 1054 | queue: rxjs$SchedulerClass, 1055 | animationFrame: rxjs$SchedulerClass, 1056 | async: rxjs$SchedulerClass 1057 | }, 1058 | Subscription: typeof rxjs$Subscription, 1059 | TimeoutError: typeof rxjs$TimeoutError 1060 | }; 1061 | } 1062 | 1063 | declare module "rxjs/Observable" { 1064 | declare module.exports: { 1065 | Observable: typeof rxjs$Observable 1066 | }; 1067 | } 1068 | 1069 | declare module "rxjs/Observer" { 1070 | declare module.exports: { 1071 | Observer: typeof rxjs$Observer 1072 | }; 1073 | } 1074 | 1075 | declare module "rxjs/BehaviorSubject" { 1076 | declare module.exports: { 1077 | BehaviorSubject: typeof rxjs$BehaviorSubject 1078 | }; 1079 | } 1080 | 1081 | declare module "rxjs/ReplaySubject" { 1082 | declare module.exports: { 1083 | ReplaySubject: typeof rxjs$ReplaySubject 1084 | }; 1085 | } 1086 | 1087 | declare module "rxjs/Subject" { 1088 | declare module.exports: { 1089 | Subject: typeof rxjs$Subject, 1090 | AnonymousSubject: typeof rxjs$AnonymousSubject 1091 | }; 1092 | } 1093 | 1094 | declare module "rxjs/Subscriber" { 1095 | declare module.exports: { 1096 | Subscriber: typeof rxjs$Subscriber 1097 | }; 1098 | } 1099 | 1100 | declare module "rxjs/Subscription" { 1101 | declare module.exports: { 1102 | Subscription: typeof rxjs$Subscription 1103 | }; 1104 | } 1105 | 1106 | declare module "rxjs/testing/TestScheduler" { 1107 | declare module.exports: { 1108 | TestScheduler: typeof rxjs$SchedulerClass 1109 | }; 1110 | } 1111 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reactivity", 3 | "version": "0.2.0", 4 | "description": "A Bleeding Edge React Universal Boilerplate for Power Users.", 5 | "main": "index.js", 6 | "repository": "https://github.com/madeagency/reactivity.git", 7 | "private": true, 8 | "author": "Made Code", 9 | "license": "MIT", 10 | "devDependencies": { 11 | "@babel/core": "^7.0.0", 12 | "@babel/plugin-proposal-class-properties": "^7.0.0", 13 | "@babel/plugin-proposal-decorators": "^7.0.0", 14 | "@babel/plugin-proposal-export-namespace-from": "^7.0.0", 15 | "@babel/plugin-proposal-function-sent": "^7.0.0", 16 | "@babel/plugin-proposal-json-strings": "^7.0.0", 17 | "@babel/plugin-proposal-numeric-separator": "^7.0.0", 18 | "@babel/plugin-proposal-throw-expressions": "^7.0.0", 19 | "@babel/plugin-syntax-dynamic-import": "^7.0.0", 20 | "@babel/plugin-syntax-import-meta": "^7.0.0", 21 | "@babel/plugin-transform-react-constant-elements": "^7.0.0", 22 | "@babel/plugin-transform-react-inline-elements": "^7.0.0", 23 | "@babel/preset-env": "^7.0.0", 24 | "@babel/preset-flow": "^7.0.0", 25 | "@babel/preset-react": "^7.0.0", 26 | "autoprefixer": "^9.1.3", 27 | "babel-eslint": "^9.0.0", 28 | "babel-loader": "^8.0.0", 29 | "babel-plugin-universal-import": "^3.0.1", 30 | "babel-watch": "^2.0.7", 31 | "css-loader": "^1.0.0", 32 | "dotenv-webpack": "^1.5.7", 33 | "empty": "^0.10.1", 34 | "eslint": "^5.5.0", 35 | "eslint-config-airbnb": "^17.1.0", 36 | "eslint-config-prettier": "^3.0.1", 37 | "eslint-import-resolver-webpack": "^0.10.1", 38 | "eslint-plugin-flowtype": "^2.50.0", 39 | "eslint-plugin-import": "^2.14.0", 40 | "eslint-plugin-jsx-a11y": "^6.1.1", 41 | "eslint-plugin-prettier": "^2.6.2", 42 | "eslint-plugin-react": "^7.11.1", 43 | "extract-css-chunks-webpack-plugin": "^3.1.1", 44 | "file-loader": "^2.0.0", 45 | "flow-bin": "^0.80.0", 46 | "node-sass": "^4.9.3", 47 | "prettier": "^1.14.2", 48 | "rimraf": "^2.6.2", 49 | "sass-loader": "^7.1.0", 50 | "style-loader": "^0.23.0", 51 | "stylelint": "^9.5.0", 52 | "stylelint-config-css-modules": "^1.3.0", 53 | "stylelint-config-standard": "^18.2.0", 54 | "url-loader": "^1.1.1", 55 | "webpack": "^4.17.1", 56 | "webpack-bundle-analyzer": "^2.13.1", 57 | "webpack-cli": "^3.1.0", 58 | "webpack-dev-middleware": "^3.2.0", 59 | "webpack-hot-middleware": "^2.23.0", 60 | "webpack-hot-server-middleware": "^0.5.0", 61 | "write-file-webpack-plugin": "^4.3.2" 62 | }, 63 | "dependencies": { 64 | "compression": "^1.7.3", 65 | "dotenv": "^6.0.0", 66 | "express": "^4.16.3", 67 | "http-proxy": "^1.17.0", 68 | "isomorphic-fetch": "^2.2.1", 69 | "lru-memoize": "^1.0.2", 70 | "postcss-loader": "^3.0.0", 71 | "react": "^16.4.2", 72 | "react-dom": "^16.4.2", 73 | "react-helmet": "^5.2.0", 74 | "react-hot-loader": "^4.3.5", 75 | "react-redux": "^5.0.7", 76 | "react-redux-epic": "^1.1.0", 77 | "react-router-dom": "^4.3.1", 78 | "react-universal-component": "^3.0.0", 79 | "redux": "^4.0.0", 80 | "redux-form": "^7.3.0", 81 | "redux-observable": "^0.18.0", 82 | "rxjs": "^5.5.10", 83 | "serialize-javascript": "^1.5.0", 84 | "serviceworker-webpack-plugin": "^1.0.1", 85 | "webpack-flush-chunks": "^2.0.1" 86 | }, 87 | "scripts": { 88 | "start": "node bin/server.prod.js", 89 | "prod": "npm run build && node bin/server.prod.js", 90 | "dev": "node bin/server.dev.js", 91 | "prebuild": "rimraf build", 92 | "build": "npm run build:client && npm run build:server", 93 | "build:client": "webpack --progress -p --config webpack/client.prod.js", 94 | "build:server": "webpack --progress --config webpack/server.prod.js", 95 | "clean": "rimraf buildClient buildServer", 96 | "format": "prettier --write \"src/**/*.js\"", 97 | "eslint": "eslint -c .eslintrc src", 98 | "stylelint": "stylelint \"src/**/*.scss\" --config .stylelintrc", 99 | "lint": "npm run eslint && npm run stylelint", 100 | "test": "npm run lint && npm run flow:status", 101 | "flow:start": "flow start", 102 | "flow:stop": "flow stop", 103 | "flow:status": "flow status", 104 | "flow:coverage": "flow coverage" 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/client.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { hydrate } from 'react-dom' 3 | import { Provider } from 'react-redux' 4 | import { AppContainer } from 'react-hot-loader' 5 | import BrowserRouter from 'react-router-dom/BrowserRouter' 6 | import runtime from 'serviceworker-webpack-plugin/lib/runtime' 7 | import configureStore from './redux/configureStore' 8 | import App from './containers/App/App' 9 | 10 | const supportsHistory = 'pushState' in window.history 11 | const { store } = configureStore(f => f, window.__data) 12 | 13 | const renderApp = TheApp => 14 | hydrate( 15 | 16 | 17 | 18 | 19 | 20 | 21 | , 22 | document.getElementById('root') 23 | ) 24 | 25 | if (module.hot) { 26 | module.hot.accept('./containers/App/App.js', () => { 27 | const theApp = require('./containers/App/App').default 28 | renderApp(theApp) 29 | }) 30 | } 31 | 32 | if ('serviceWorker' in navigator && process.env.ENABLE_SW === 'true') { 33 | runtime.register() 34 | } 35 | 36 | renderApp(App) 37 | -------------------------------------------------------------------------------- /src/components/GithubButton/GithubButton.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from 'react' 4 | 5 | type Props = { 6 | title: string, 7 | user: string, 8 | repo: string, 9 | type: 'star' | 'watch' | 'fork' | 'follow', 10 | width: number, 11 | height: number, 12 | count?: boolean, 13 | large?: boolean 14 | } 15 | 16 | const GithubButton = (props: Props) => { 17 | const { title, user, repo, type, width, height, count, large } = props 18 | let options = `?user=${user}&repo=${repo}&type=${type}` 19 | if (count) options += '&count=true' 20 | if (large) options += '&size=large' 21 | 22 | return ( 23 |