gcanti / tom

Elmish type-safe state and side effect manager using RxJS

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sébastien Lorber's problem

gcanti opened this issue · comments

Reference: evancz/elm-architecture-tutorial#50

We need 3 ingredients:

  • a base app (i.e. a simple counter)
  • a compose(app1, app2) function in order to compose 2 apps
  • a new component that will display a value based on the following rule:
    • The value should increment by one on any counter increment
    • The value should decrement by one on any counter decrement
    • The value should never be more than 3 and less than 0 (if we increment with value 3, the value stays 3)

Prelude: tom typings

interface IState<Model, Effect> {
  model: Model;
  effect?: ?Effect;
}

type Dispatch<Event> = (event: Event) => void;

interface IConfig<Model, Effect, Event, View> {
  init: () => IState<Model, Effect>;
  update: (model: Model, event: Event) => IState<Model, Effect>;
  view: (model: Model, dispatch: Dispatch<Event>) => View;
  run?: (effect: Effect, event$: Observable<Event>) => ?Observable<Event>;
}

#1. The base app: a simple counter

Implementation

Typings

type CounterModel = number;
type CounterEffect = void;
type CounterEvent = 'INCREMENT_REQUEST' | 'DECREMENT_REQUEST';
type CounterView = React.Element;

counter: IConfig<CounterModel, CounterEffect, CounterEvent, CounterView>

#2. The compose function

Implementation

Typings

declare function compose<Mx, My, Effx, Effy, Ex, Ey, View>(x: IConfig<Mx, Effx, Ex, View>, y: IConfig<My, Effy, Ey, View>): IConfig<[Mx, My], [?Effx, ?Effy], [?Ex, ?Ey], View>;

#3. The top level component

Implementation

Typings

// these typings come from the `compose` function
type PairModel = [CounterModel, CounterModel];
type PairEffect = [?CounterEffect, ?CounterEffect];
type PairEvent = [?CounterEvent, ?CounterEvent];
const pair: IConfig<PairModel, PairEffect, PairEvent, CounterView> = compose(counter, counter)

type TopModel = {
  count: number;
  pair: PairModel;
};
type TopConfig = IConfig<TopModel, PairEffect, PairEvent, CounterView>;

/cc @slorber