Skip to content

Commit

Permalink
docs: Adding docs
Browse files Browse the repository at this point in the history
  • Loading branch information
mnasyrov committed Aug 15, 2021
1 parent 7764afc commit 36aacaf
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 5 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ Core elements:
- `StateMutation` – a pure function which changes the state.
- `Store` – a state storage, it provides methods to update and subscribe the state.
- `Action` – an event emitter.
- `Effect` – a piece of business logic which handles the action and makes state changes and side effects.
- `Scope` – a controller-like boundary for effects and business logic
- `Effect` – a business logic which handles the action and makes state changes and side effects.
- `Controller` – a controller type for effects and business logic
- `Scope` – a controller-like boundary for effects and business logic

### Example

Expand Down
88 changes: 87 additions & 1 deletion packages/rx-effects/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,93 @@ Reactive state and effect management with RxJS.
npm install rx-effects --save
```

## Usage
## Concepts

The main idea is to use the classic MVC pattern with event-based models (state stores) and reactive controllers (actions
and effects). The view subscribes to model changes (state queries) of the controller and requests the controller to do
some actions.

<img alt="concept-diagram" src="https://raw.githubusercontent.com/mnasyrov/rx-effects/main/docs/concept-diagram.svg" width="400" />

Main elements:

- `State` – a data model.
- `StateQuery` – a getter and subscriber for data of the state.
- `StateMutation` – a pure function which changes the state.
- `Store` – a state storage, it provides methods to update and subscribe the state.
- `Action` – an event emitter.
- `Effect` – a business logic which handles the action and makes state changes and side effects.
- `Controller` – a controller type for effects and business logic
- `Scope` – a controller-like boundary for effects and business logic

## State and Store

A state is described as a type, and it can be a primitive value or an object.

```ts
type CartState = { orders: Array<string> };
```

After that, it is recommended to declare a set of `StateMutation` functions which will be used to alter the state. These
functions should be pure and return a new state or the previous one. For providing an argument use currying functions.

Actually, `StateMutation` function can change the state in place, but it is responsible for a developer to track state
changes by providing custom `stateCompare` function to a store.

```ts
const addPizzaToCart =
(name: string): StateMutation<CartState> =>
(state) => ({ ...state, orders: [...state.orders, name] });

const removePizzaFromCart =
(name: string): StateMutation<CartState> =>
(state) => ({
...state,
orders: state.orders.filter((order) => order !== name),
});
```

A store is created by `createStore()` function which takes an initial state:

```ts
const INITIAL_STATE: CartState = { orders: [] };
const cartStore: Store<CartState> = createStore(INITIAL_STATE);
```

The store can be updated by `set()` and `update()` methods:

- `set()` applies the provided `State` value to the store.
- `update()` calls the provided `StateMutation` with the current state and applies the new one to the store.

```ts
function resetCart() {
cartStore.set(INITIAL_STATE);
}

function addPizza(name: string) {
cartStore.update(addPizzaToCart(name));
}
```

There is `pipeStateMutations()` helper which can merge state updates into the single mutation. It is useful for
combining several changes and applying it at the same time:

```ts
import { pipeStateMutations } from './stateMutation';

function addPizza(name: string) {
cartStore.update(
pipeStateMutations([addPizzaToCart(name), addPizzaToCart('Bonus Pizza')]),
);
}
```

`pipeStateMutations()` can be used inside other mutations as well:

```ts
const addPizzaToCartWithBonus = (name: string): StateMutation<CartState> =>
pipeStateMutations([addPizzaToCart(name), addPizzaToCart('Bonus Pizza')]);
```

`// TODO: Documentation`

Expand Down
4 changes: 2 additions & 2 deletions packages/rx-effects/src/stateMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
* It is recommended to return a new state or the previous one.
*
* Actually, the function can change the state in place, but it is responsible
* of a developer to provide `stateCompare` function to the store which handles
* for a developer to provide `stateCompare` function to the store which handles
* the changes.
*
* For making changes use curring function to provide arguments:
* For making changes use a currying function to provide arguments:
* ```ts
* const addPizzaToCart = (name: string): StateMutation<Array<string>> =>
* (state) => ([...state, name]);
Expand Down

0 comments on commit 36aacaf

Please sign in to comment.