-
Notifications
You must be signed in to change notification settings - Fork 32
/
implementation.js
112 lines (97 loc) · 2.57 KB
/
implementation.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
110
111
112
var pathToRegexp = Npm.require('path-to-regexp');
var Fiber = Npm.require('fibers');
var urlParse = Npm.require('url').parse;
PickerImp = function(filterFunction) {
this.filterFunction = filterFunction;
this.routes = [];
this.subRouters = [];
this.middlewares = [];
}
PickerImp.prototype.middleware = function(callback) {
this.middlewares.push(callback);
};
PickerImp.prototype.route = function(path, callback) {
var regExp = pathToRegexp(path);
regExp.callback = callback;
this.routes.push(regExp);
return this;
};
PickerImp.prototype.filter = function(callback) {
var subRouter = new PickerImp(callback);
this.subRouters.push(subRouter);
return subRouter;
};
PickerImp.prototype._dispatch = function(req, res, bypass) {
var self = this;
var currentRoute = 0;
var currentSubRouter = 0;
var currentMiddleware = 0;
if(this.filterFunction) {
var result = this.filterFunction(req, res);
if(!result) {
return bypass();
}
}
processNextMiddleware();
function processNextMiddleware () {
var middleware = self.middlewares[currentMiddleware++];
if(middleware) {
self._processMiddleware(middleware, req, res, processNextMiddleware);
} else {
processNextRoute();
}
}
function processNextRoute () {
var route = self.routes[currentRoute++];
if(route) {
var uri = req.url.replace(/\?.*/, '');
var m = uri.match(route);
if(m) {
var params = self._buildParams(route.keys, m);
params.query = urlParse(req.url, true).query;
self._processRoute(route.callback, params, req, res, bypass);
} else {
processNextRoute();
}
} else {
processNextSubRouter();
}
}
function processNextSubRouter () {
var subRouter = self.subRouters[currentSubRouter++];
if(subRouter) {
subRouter._dispatch(req, res, processNextSubRouter);
} else {
bypass();
}
}
};
PickerImp.prototype._buildParams = function(keys, m) {
var params = {};
for(var lc=1; lc<m.length; lc++) {
var key = keys[lc-1].name;
var value = m[lc];
params[key] = value;
}
return params;
};
PickerImp.prototype._processRoute = function(callback, params, req, res, next) {
if(Fiber.current) {
doCall();
} else {
new Fiber(doCall).run();
}
function doCall () {
callback.call(null, params, req, res, next);
}
};
PickerImp.prototype._processMiddleware = function(middleware, req, res, next) {
if(Fiber.current) {
doCall();
} else {
new Fiber(doCall).run();
}
function doCall() {
middleware.call(null, req, res, next);
}
};