Skip to content

Instantly share code, notes, and snippets.

@kana-sama
Last active February 21, 2018 07:25
Show Gist options
  • Save kana-sama/86ff654694c6bb9a53a7383209893ad1 to your computer and use it in GitHub Desktop.
Save kana-sama/86ff654694c6bb9a53a7383209893ad1 to your computer and use it in GitHub Desktop.
// @flow
import { createAction, createReducer, on, onType, Action } from "transdux";
const inc: Action<void> = createAction();
const add: Action<number> = createAction();
const DEC = "DEC";
const SUB = "SUB";
const dec = () => ({ type: DEC });
const sub = (value: number) => ({ type: SUB, value });
const count = createReducer(0, [
on(inc, state => state + 1),
onType(DEC, state => state - 1),
on(add, (state, value) => state + value),
onType(SUB, (state, { value }) => state - value)
]);
console.log(
[inc(), inc(), add(10), inc(), dec(), sub(5)].reduce(count, undefined)
); // 7 (0 + 1 + 1 + 10 + 1 - 1 - 5)
// @flow
type Reducer<S> = (state: S | void, action: any) => S;
type Message<P> = { type: string, payload: P };
type Action<P> = (P => Message<P>) & { type: string };
let nextId = 0;
function createAction<P>(description?: string): Action<P> {
const id = nextId++;
const type = description == null ? `${id}` : `${description}-${id}`;
const action = payload => ({ type, payload });
action.type = type;
return action;
}
function on<S, P>(
action: Action<P>,
handle: (state: S, payload: P) => S
): (Reducer<S>) => Reducer<S> {
return reducer => (state, message: Message<P>) => {
const newState = reducer(state, message);
switch (message.type) {
case action.type:
return handle(newState, message.payload);
default:
return newState;
}
};
}
function onType<S, M: { type: string }>(
type: string,
handle: (state: S, message: M) => S
): (Reducer<S>) => Reducer<S> {
return reducer => (state, message: M) => {
const newState = reducer(state, message);
switch (message.type) {
case type:
return handle(newState, message);
default:
return newState;
}
};
}
function createIdentityReducer<S>(defaultState: S): Reducer<S> {
return (state: S = defaultState, action) => state;
}
function createReducer<S>(
defaultState: S,
transducers: ((Reducer<S>) => Reducer<S>)[]
): Reducer<S> {
return transducers.reduce(
(reducer, transducer) => transducer(reducer),
createIdentityReducer(defaultState)
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment