-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.js
109 lines (90 loc) · 2.62 KB
/
main.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import xs from 'xstream'
import Cycle from '@cycle/xstream-run';
import {div, label, button, input, hr, ul, li, a, makeDOMDriver} from '@cycle/dom';
import {makeRouterDriver} from 'cyclic-router';
import {createHistory} from 'history';
import Immutable from 'immutable'
import switchPath from 'switch-path'
export function noop() {}
export const noopListener = {
next: noop,
error: noop,
complete: noop
}
function root(sources, inputs) {
return {
DOM: inputs.props$.map(props => {
return div(`.root`, [
div([`Root`]),
div([`Current count: ${props.count}`]),
div([a({props: {href: `/page1`}}, [`Go to page 1`])]),
div([a({props: {href: `/page2`}}, [`Go to page 2`])])
])
}),
change$: xs.never()
}
}
function childIntent(sources) {
const inc$ = sources.DOM.select(`.inc`).events(`click`).mapTo(1)
const dec$ = sources.DOM.select(`.dec`).events(`click`).mapTo(-1)
return {
change$: xs.merge(inc$, dec$)
}
}
function child(sources, inputs) {
const actions = childIntent(sources)
return {
DOM: inputs.props$.map(props => inputs.parentState$.map(state => div(`.child`, [
div([`${props.title}`]),
div([`Current count: ${state.count}`]),
button(`.inc`, [`+`]),
button(`.dec`, [`-`]),
div([a({props: {href: `/`}}, [`Back to root`])])
]))).flatten(),
change$: actions.change$
}
}
function reducers(actions, inputs) {
const changeReducer$ = inputs.change$.map(val => state => {
return state.update(`count`, count => count + val)
})
return xs.merge(changeReducer$)
}
function model(actions, inputs) {
const reducer$ = reducers(actions, inputs)
return reducer$
.fold((acc, reducer) => reducer(acc), Immutable.Map({
count: 0
}))
.map(x => x.toObject())
.debug()
.remember()
}
function main(sources) {
const change$ = xs.create()
const state$ = model({}, {change$})
const routes = {
'/': () => root(sources, {props$: state$}),
'/page1': () => child(sources, {props$: xs.of({title: `Page 1`}), parentState$: state$}),
'/page2': () => child(sources, {props$: xs.of({title: `Page 2`}), parentState$: state$})
}
const component$ = sources.Router.define(routes)
.debug(`from router...`)
.map(route => route.value)
.map(value => {
return value()
})
.remember()
change$.imitate(component$.map(x => x.change$).flatten())
return {
DOM: component$
.map(x => x.DOM)
.flatten(),
Router: xs.never()
}
}
const drivers = {
DOM: makeDOMDriver('#app'),
Router: makeRouterDriver(createHistory(), switchPath, {capture: true}),
};
Cycle.run(main, drivers);