-
Notifications
You must be signed in to change notification settings - Fork 12
/
counter.js
71 lines (63 loc) · 1.65 KB
/
counter.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
const { html } = require('../')
const assign = require('object-assign')
const keys = require('own-enumerable-keys')
const INCREMENT = Symbol('increment')
const DECREMENT = Symbol('decrement')
const SET = Symbol('set')
const increment = createAction(INCREMENT)
const decrement = createAction(DECREMENT)
const set = createAction(SET)
module.exports = {
init: () => ({ model: 0 }),
update: handleActions({
[INCREMENT]: (model) => ({ model: model + 1 }),
[DECREMENT]: (model) => ({ model: model - 1 }),
[SET]: (model, payload) => ({ model: payload })
}),
view: (model, dispatch) => html`
<div>
<button onclick=${(e) =>
dispatch(decrement())
}> - </button>
<input type='number'
oninput=${(ev) => {
dispatch(set(Number(ev.target.value)))
}}
value=${model}
/>
<button onclick=${(e) =>
dispatch(increment())
}> + </button>
</div>
`
}
function createAction (type, payloadCreator = identity) {
return (...args) => ({
type,
payload: payloadCreator(...args)
})
}
function handleActions (actionHandlers) {
return reduceUpdates(
keys(actionHandlers).map((actionType) => {
const update = actionHandlers[actionType]
return function (model, action) {
if (action.type === actionType) {
return update(model, action.payload)
}
return { model }
}
})
)
}
function reduceUpdates (updates) {
return function (model, action) {
return updates.reduce(
(state, update) => assign(
{}, state, update(state.model, action)
),
{ model }
)
}
}
function identity (id) { return id }