forked from mirrorjs/mirror
-
Notifications
You must be signed in to change notification settings - Fork 0
/
model.js
82 lines (60 loc) · 1.8 KB
/
model.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
import {resolveReducers, addActions} from './actions'
export const models = []
export default function model(m) {
m = validateModel(m)
const reducer = getReducer(resolveReducers(m.name, m.reducers), m.initialState)
const _model = {
name: m.name,
reducer
}
models.push(_model)
addActions(m.name, m.reducers, m.effects)
return _model
}
function validateModel(m = {}) {
const {
name,
reducers,
effects
} = m
const isObject = target => Object.prototype.toString.call(target) === '[object Object]'
if (!name || typeof name !== 'string') {
throw new Error(`Model name must be a valid string!`)
}
if (name === 'routing') {
throw new Error(`Model name can not be "routing", it is used by react-router-redux!`)
}
if (models.find(item => item.name === name)) {
throw new Error(`Model "${name}" has been created, please select another name!`)
}
if (reducers !== undefined && !isObject(reducers)) {
throw new Error(`Model reducers must be a valid object!`)
}
if (effects !== undefined && !isObject(effects)) {
throw new Error(`Model effects must be a valid object!`)
}
m.reducers = filterReducers(reducers)
m.effects = filterReducers(effects)
return m
}
// If initialState is not specified, then set it to null
function getReducer(reducers, initialState = null) {
return (state = initialState, action) => {
if (typeof reducers[action.type] === 'function') {
return reducers[action.type](state, action.data)
}
return state
}
}
function filterReducers(reducers) {
if (!reducers) {
return reducers
}
// Filter out non-function entries
return Object.keys(reducers)
.filter(action => typeof reducers[action] === 'function')
.reduce((acc, cur) => {
acc[cur] = reducers[cur]
return acc
}, {})
}