-
Notifications
You must be signed in to change notification settings - Fork 10
/
reduxActionRouter.js
66 lines (59 loc) · 1.77 KB
/
reduxActionRouter.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
import urlMapper from 'url-mapper';
import querystring from 'querystring';
import hashchangeSupport from './hashchangeSupport.js';
let urlSupport;
export default function createActionRouterMiddleware(routes, opts) {
const options = Object.assign({
dispatcher,
actionHandler,
urlSupport: hashchangeSupport,
}, opts);
if (urlSupport) {
urlSupport.cleanUp();
}
const urlActionMap = routes;
const mapper = urlMapper({});
const middleware = (store) => {
function onChange(url) {
if (!url) {
return;
}
const [path, query] = url.split('?');
const matched = mapper.map(path, urlActionMap);
if (matched) {
let { values } = matched;
const { match } = matched;
if (query) {
const parsedQuery = querystring.parse(query);
values = Object.assign({}, parsedQuery, values);
}
options.dispatcher(store, match, values, path);
}
}
urlSupport = options.urlSupport(onChange);
return next => action => options.actionHandler(store, next, action);
};
return middleware;
}
export function processCurrentUrl() {
return urlSupport.processUrl();
}
export function actionHandler(store, next, action) {
if (action && action.type === 'setUrl') {
urlSupport.setUrl(action.url);
} else if (action && action.type === 'setUrlRoute') {
urlSupport.setUrl(action.url);
processCurrentUrl();
}
return next(action);
}
export function dispatcher(store, match, values, path) {
store.dispatch({ type: 'urlChange', values, path });
const typeOfMatch = typeof match;
if (typeOfMatch === 'function') {
const actionCreatorResult = match(values);
store.dispatch(actionCreatorResult);
} else {
throw new Error('Routes must be to action creator functions');
}
}