Skip to content

Commit

Permalink
Update Readme and descriptions
Browse files Browse the repository at this point in the history
  • Loading branch information
bigslycat committed Oct 19, 2018
1 parent 99b14e0 commit b2b4fac
Show file tree
Hide file tree
Showing 4 changed files with 186 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Honeycombs

WIP. Observable state manager.
State manager with built-in side-effects.

## Packages

Expand Down
2 changes: 1 addition & 1 deletion packages/es-observable/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# es-observable

WIP. ES Observable implementation
ES Observable implementation.
184 changes: 183 additions & 1 deletion packages/honeycombs/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,185 @@
# Honeycombs

WIP. Observable state manager.
State manager with built-in side-effects.

## Install

`npm i -S honeycombs` or `yarn add honeycombs`

## API

```js
import * as hc from 'honeycombs';
```

- `hc.of(initialState): Honeycomb` — creates instance of `Honeycomb`.

### `Honeycomb`

`Honeycomb` is store. Store can to create handlers (`Bee` instances) by this methods:

- `honeycomb.transform(payload => oldState => newState): Bee`

- `honeycomb.apply(payload => newState): Bee`

- `honeycomb.apply(payload => oldState => newState): Bee`

- `honeycomb.just(): Bee``Bee` just sets state to received payload value.

- `honeycomb.always(constantValue): Bee``Bee` always sets state to `constantValue`.

- `honeycomb.fromPromise(payload => Promise<newState>): Bee`

`honeycomb.fromPromise(payload => Promise<oldState => newState>): Bee`

Order of state changes depends on order of promises resolving.

- `honeycomb.awaitPromise(payload => Promise<newState>): Bee`

`honeycomb.awaitPromise(payload => Promise<oldState => newState>): Bee`

Order of state changes depends on order of `Bee` in call queue.
Resolving of this promise blocks to the queue.

- `honeycomb.fromObservable(payload => Observable<newState>): Bee`

`honeycomb.fromObservable(payload => Observable<oldState => newState>): Bee`

All values of `Observable` will change the state.
Order of state changes depends on order of `Observable` values.

- `honeycomb.awaitObservable(payload => Observable<newState>): Bee`

`honeycomb.awaitObservable(payload => Observable<oldState => newState>): Bee`

All values of `Observable` will change the state.
Awaiting of `Observable` complete blocks to the queue.

`Honeycomb` is `Observable`. You can to subscribe to store using method `subscribe`:

`honeycomb.subscribe(next [, error, complete] ): Subscription`
`honeycomb.subscribe(observer): Subscription`

`Observer` is object with optional methods:

`observer.next(newState)`
`observer.error(Error)`
`observer.complete()`

`Subscription` is object with method `unsubscribe()`;

### `Bee`

`Bee` is store handler. This is:

- Function that can receive a payload value.
- Observer that have method `next()`, receives a payload value.
- `Observable` of state values, emits only when this `Bee` was called.
So you can to subscribe to state changes, executed of specified `Bee`.

## Usage

```js
import * as hc from 'honeycombs';

const counter = hc.of(0);

const reset = counter.always(0);
const setTo = counter.just();
const increment = counter.transform(state => state + 1);
const decrement = counter.transform(state => state - 1);
const add = counter.apply(payload => state => state + payload);
const subtract = counter.apply(payload => state => state - payload);

increment(); // 1
increment(); // 2
decrement(); // 1
add(5); // 6
subtract(1); // 5
setTo(10); // 10
reset(); // 0
```

### With observable streams

```js
import * as hc from 'honeycombs';
import { from, empty, fromPromise } from 'most';

const user = hc.of({ status: 'not logged in' });

const login = user.awaitObservable((_, { username, password }) =>
fromPromise(
fetch('https://example.com/api/auth', {
method: 'POST',
body: JSON.stringify({ username, password }),
})
.then(async response => {
if (!response.ok) return { status: 'auth failed' };

const { assessToken, refreshToken } = await response.json();

return {
status: 'logged in',
username,
assessToken,
refreshToken,
};
})
.catch(() => ({ status: 'auth failed' })),
).startWith({ status: 'logging in' }),
);

const refresh = user.awaitObservable(
state =>
state.status === 'logged in'
? fromPromise(
fetch('https://example.com/api/token', {
method: 'POST',
body: JSON.stringify({ refreshToken: state.refreshToken }),
})
.then(async response => {
if (!response.ok) return { status: 'not logged in' };

const { assessToken, refreshToken } = await response.json();

return {
status: 'logged in',
username: state.username,
assessToken,
refreshToken,
};
})
.catch(() => ({ status: 'auth failed' })),
).startWith({ status: 'logging in' })
: empty(),
);

const logout = user.always({ status: 'not logged in' });

from(user)
.filter(state => state.status === 'logged in')
.merge(from(logout))
.subscribe(console.log);

login({ username: '...', password: '...' });
refresh({ refreshToken: '...' });
logout();
```

### With promises

```js
import * as hc from 'honeycombs';

const posts = hc.of();

const loadPosts = posts.fromPromise(
({ limit = 10, offset = 0 } = {}) =>
fetch(`https://example.com/api/posts?limit=${limit}&offset=${offset}`)
.then(response => response.json()),
);

loadPosts();
loadPosts({ limit: 20, offset: 50 });
```
2 changes: 1 addition & 1 deletion packages/honeycombs/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "honeycombs",
"version": "1.0.0-beta.22",
"description": "Observable finite-state machine",
"description": "State manager with built-in side-effects",
"main": "lib/index.js",
"bugs": {
"url": "https://github.com/bigslycat/honeycombs/issues",
Expand Down

0 comments on commit b2b4fac

Please sign in to comment.