-
Notifications
You must be signed in to change notification settings - Fork 9
Developer Onboarding
The README.md
gives you adequate information on how to clone project files, install dependencies and launch the app.
Once you have done that, this document is intended to give you a taste of how the app works. It still assumes basic knowledge of React, Redux and react-router
.
Here's a curated list of packages that are used by the project. However, the best way to have a complete list of dependencies is to see package.json.
The particular structure of the project has been forked from react-boilerplate. The gist is:
- You will write your code in the
app
folder. This is the folder you will spend most, if not all, of your time in. - Configuration, generators and templates are in the
internals
folder. - The
server
folder contains development server configuration files.
We use the container/component architecture. containers/
contains React components which are connected to the redux store. components/
contains dumb React components which depend on containers for data. Container components care about how things work, while components care about how things look.
The app treats single pages (e.g. the Loginpage, the Homepage etc.) as containers and their small parts (e.g. the Login form, the Navigation bar) as components. These are no rigid rules. Bend the architecture to the needs of your app, nothing is set in stone!
The source code cannot be executed as-is in the web browser. It needs to pass through webpack to get converted into a form that web browsers understand.
-
internals/webpack
: We use EcmaScript 7 to write the source code of your app. webpack takes care of making it compatible with a majority of browsers. -
internals/generators
: This folder has the code to scaffold out new components, containers and routes. Read more about scaffolding in the docs. -
internals/mocks
: This folder contains mocks which Jest uses when testing your app, e.g. for images.
The other folders are mostly for the maintainers and/or the setup, and you should absolutely never need to touch them so we are going skip them for the sake of brevity.
As the name suggests, this folder contains development server configuration.
When you run npm start
, a server will be launched in your terminal for development. You can then open http://localhost:3000 to access the server and see the app. The general workflow of the app is like this:
The app starts with the app/index.html
file. React will render the app into the div#app
.
app/app.js
is that entry point to the app. Webpack will access the entire app from this file, transpile the application into ES5 and create small chunks of transpiled code to be loaded by the browser. Let's break app/app.js
down to contents:
-
babel-polyfill
is imported. This enables cool stuff like generator functions,Promise
s, etc. - A redux
store
is instantiated. - A
history
object is created, which remembers all the browsing history. This is used by the router to know which page the users visit. (very useful for analytics, by the way) - A Router is set up, with all of your routes. See
routes.js
- Hot module replacement setup.
- i18n internationalization support setup.
-
ReactDOM.render()
not only renders the root react component called<App />
, of the app, but it renders it with<Provider />
,<LanguageProvider />
and<Router />
.
-
<Provider />
connects the app with the reduxstore
. -
<LanguageProvider />
provides language translation support. -
<Router />
will have information for application routes.
The Redux store
is the heart of your application. Check out store.js
to see how we have configured the store.
The store is created with the createStore()
factory, which accepts three parameters.
- Root reducer: A master reducer combining all reducers.
- Initial state: The initial state of the app as determined by the reducers.
- Middleware/enhancers: Middlewares are third party libraries which intercept each redux action dispatched to the redux store and then... do stuff.
In our application we are using two middleware:
-
Router middleware: Keeps routes in sync with the redux
store
. - Redux saga: Is used for managing side-effects such as dispatching actions asynchronously or accessing browser data.
Reselect is a library used for slicing the redux state and providing only the relevant sub-tree to a react component. It has three key features:
- Computational power
- Memoization
- Composability
The mental model is that a saga is like a separate thread in your application that's solely responsible for side effects. redux-saga
is a redux middleware, which means this thread can be started, paused and cancelled from the main application with normal redux actions, it has access to the full redux application state and it can dispatch redux actions as well.
The table container runs the game and manages the most complex state object, the game-state. The usual game-state looks something like this:
{
dealer: 3, // position of player in lineup array that is dealing
state: 'dealing', // state of the hand
holeCards: [2, 5], // private cards the player receives in waiting/dealing state
cards: [21, 3], // optional - board cards, public
lineup: [{
address: 0x1234, // 20 bytes hex Ethereum address of player
last: ABC..=, // optional - base64 encoded byte array
cards: [2, 5], // optional - same like holeCards, after showdown
sitout: 12345, // optional - unix timestamp
exitHand: 3, // optional - handId when player will leave the table
}, ... // more players
]
}
hand state diagram: https://docs.google.com/drawings/d/12J9BZ-kj5308wgF52fiwHGrDeJr51STAwkktTnFLNrE
example state used in backend unit tests: https://github.com/acebusters/oracle-cashgame/blob/master/index.test.js#L369-L385
Receipts are binary data, which the blockchain understands (like bitcoin transactions). Different examples for receipts can be found here: https://github.com/acebusters/poker-helper/blob/develop/lib/receipt.spec.js
The poker-helper receipt lib can also be used for parsing receipts.
Lineup last:
receipts are a bit different, they can be parsed using https://www.base64decode.org/ (paste in data between first and second .
)
The web-app communicates with 5 different APIs on the backend:
- Web3 Javascript Dapp API: reading information from the blockchain. Explained here
- Pusher Websocket: receiving updates about the game-state from the backend.
- Cashgame API: sending actions to modify the game-state using receipts.
- Account API: reading and writing regarding signup, login/logout, sending transactions for fish accounts.
... to be continued