-
Notifications
You must be signed in to change notification settings - Fork 79
/
Copy pathroutes.js
129 lines (107 loc) · 3.68 KB
/
routes.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
var Fiber = Npm.require('fibers');
FastRender._onAllRoutes = [];
FastRender.frContext = new Meteor.EnvironmentVariable();
var fastRenderRoutes = Picker.filter(function(req, res) {
return IsAppUrl(req);
});
fastRenderRoutes.middleware(Npm.require('connect').cookieParser());
fastRenderRoutes.middleware(function(req, res, next) {
FastRender.handleOnAllRoutes(req, res, next);
});
// handling specific routes
FastRender.route = function route(path, callback) {
if(path.indexOf('/') !== 0){
throw new Error('Error: path (' + path + ') must begin with a leading slash "/"')
}
fastRenderRoutes.route(path, FastRender.handleRoute.bind(null, callback));
};
function setQueryDataCallback(res, next) {
return function(queryData) {
if(!queryData) return next();
var existingPayload = InjectData.getData(res, "fast-render-data");
if(!existingPayload) {
InjectData.pushData(res, "fast-render-data", queryData);
} else {
// it's possible to execute this callback twice
// the we need to merge exisitng data with the new one
_.extend(existingPayload.subscriptions, queryData.subscriptions);
_.each(queryData.collectionData, function(data, pubName) {
var existingData = existingPayload.collectionData[pubName]
if(existingData) {
data = existingData.concat(data);
}
existingPayload.collectionData[pubName] = data;
InjectData.pushData(res, 'fast-render-data', existingPayload);
});
}
next();
};
}
FastRender.handleRoute = function(processingCallback, params, req, res, next) {
var afterProcessed = setQueryDataCallback(res, next);
FastRender._processRoutes(params, req, processingCallback, afterProcessed);
};
FastRender.handleOnAllRoutes = function(req, res, next) {
var afterProcessed = setQueryDataCallback(res, next);
FastRender._processAllRoutes(req, afterProcessed);
};
FastRender.onAllRoutes = function onAllRoutes(callback) {
FastRender._onAllRoutes.push(callback);
};
FastRender._processRoutes =
function _processRoutes(params, req, routeCallback, callback) {
callback = callback || function() {};
var path = req.url;
var loginToken = req.cookies['meteor_login_token'];
var headers = req.headers;
var context = new Context(loginToken, { headers: headers });
try {
FastRender.frContext.withValue(context, function() {
routeCallback.call(context, params, path);
});
if(context.stop) {
return;
}
callback(context.getData());
} catch(err) {
handleError(err, path, callback);
}
};
FastRender._processAllRoutes =
function _processAllRoutes(req, callback) {
callback = callback || function() {};
var path = req.url;
var loginToken = req.cookies['meteor_login_token'];
var headers = req.headers;
new Fiber(function() {
var context = new Context(loginToken, { headers: headers });
try {
FastRender._onAllRoutes.forEach(function(callback) {
callback.call(context, req.url);
});
callback(context.getData());
} catch(err) {
handleError(err, path, callback);
}
}).run();
};
function handleError(err, path, callback) {
var message =
'error on fast-rendering path: ' +
path +
" ; error: " + err.stack;
console.error(message);
callback(null);
}
// adding support for null publications
FastRender.onAllRoutes(function() {
var context = this;
var nullHandlers = Meteor.default_server.universal_publish_handlers;
if(nullHandlers) {
nullHandlers.forEach(function(publishHandler) {
// universal subs have subscription ID, params, and name undefined
var publishContext = new PublishContext(context, publishHandler);
context.processPublication(publishContext);
});
}
});