Skip to content

Developer Onboarding

Alex Lunyov edited this page Dec 19, 2017 · 13 revisions

Local Development Environment

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.

Tech Stack

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.

Core

Unit Testing

Linting

Project Structure

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.

app/

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!

internals/

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.

server/

As the name suggests, this folder contains development server configuration.

Basic Building Blocks

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:

application workflow

How does the application boot up?

The app starts with the app/index.html file. React will render the app into the div#app .

app/app.js:

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, Promises, 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 redux store.
  • <LanguageProvider /> provides language translation support.
  • <Router /> will have information for application routes.

Redux

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.

  1. Root reducer: A master reducer combining all reducers.
  2. Initial state: The initial state of the app as determined by the reducers.
  3. 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:

  1. Router middleware: Keeps routes in sync with the redux store.
  2. Redux saga: Is used for managing side-effects such as dispatching actions asynchronously or accessing browser data.

Reselect

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:

  1. Computational power
  2. Memoization
  3. Composability

Redux Saga

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.

Table State

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

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 .)

Backend

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.

infrastructure diagram

... to be continued

Clone this wiki locally