-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
82 lines (70 loc) · 1.85 KB
/
index.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
function noop() {}
function segmentUri(uri) {
return uri.slice(1).split('/').filter(x => !!x);
}
function route(uri, enter = noop, update = noop, exit = noop) {
return {
path: uri,
segments: segmentUri(uri),
enter,
update,
exit
};
}
const emptyURI = "";
function wildcardRoute(enter = noop, update = noop, exit = noop) {
return route(emptyURI, enter, update, exit);
}
function match(segments, uri) {
const uriSegments = segmentUri(uri);
if (segments.length !== uriSegments.length) {
return [false, []];
}
const params = {};
for (let x = 0; x < segments.length; x++) {
let param = segments[x][0] === ':';
let segment = param ? segments[x].slice(1) : segments[x];
if (param) {
params[segment] = uriSegments[x];
} else if (segment !== uriSegments[x]) {
return [false, []];
}
}
return [true, params];
}
function matchRoute(routes, uri, wildcard) {
for (let route of routes) {
const [matched, params] = match(route.segments, uri);
if (matched) {
return [route, params];
}
}
return wildcard ? [wildcard, {}] : [];
}
const ENTER = 0;
const UPDATE = 3;
const EXIT = 1;
function router(wildcard, ...routes) {
let currentRoute = null;
let currentParams = null;
return function (uri) {
const [route, params] = matchRoute(routes, uri, wildcard);
let state = +(Boolean(currentRoute)) +
(+(Boolean(currentRoute && currentRoute.path === route.path)) * 2);
switch (state) {
case EXIT: (
currentRoute && currentRoute.exit(currentParams),
currentRoute = null,
currentParams = null
);
case ENTER: return (
route.enter(params),
currentRoute = route,
currentParams = params,
null
);
case UPDATE: currentRoute.update(currentParams);
}
};
}
module.exports = { router, route, wildcardRoute };