cloudcms-server 4.0.0-beta.2 → 4.0.0-beta.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -5
- package/cloudcms-server.iml +1 -0
- package/index.js +58 -32
- package/middleware/authentication/authentication.js +40 -12
- package/middleware/authentication/providers/saml.js +8 -4
- package/middleware/awareness/awareness.js +8 -7
- package/middleware/awareness/plugins/api_event.js +105 -0
- package/middleware/awareness/plugins/editorial.js +54 -3
- package/middleware/awareness/plugins/resources.js +13 -5
- package/middleware/config/adapter.js +0 -44
- package/middleware/deployment/deployment.js +22 -24
- package/middleware/driver/driver.js +24 -1
- package/middleware/driver-config/driver-config.js +0 -6
- package/middleware/modules/modules.js +11 -5
- package/middleware/perf/perf.js +3 -2
- package/middleware/registration/registration.js +0 -5
- package/middleware/stores/engines/empty.js +0 -4
- package/middleware/stores/engines/fs-caching-adapter.js +0 -5
- package/middleware/stores/engines/fs.js +0 -9
- package/middleware/stores/engines/s3.js +0 -5
- package/middleware/stores/engines/s3fs.js +0 -5
- package/middleware/stores/multistore.js +0 -29
- package/middleware/stores/store.js +0 -10
- package/middleware/stores/stores.js +2 -2
- package/middleware/virtual-config/virtual-config.js +253 -206
- package/middleware/virtual-files/virtual-files.js +0 -3
- package/middleware/welcome/welcome.js +0 -3
- package/notifications/notifications.js +72 -10
- package/notifications/providers/kafka.js +182 -0
- package/notifications/providers/stomp.js +4 -0
- package/package.json +40 -56
- package/server/index.js +216 -123
- package/server/standalone.js +1 -6
- package/util/auth.js +10 -4
- package/util/cloudcms.js +77 -35
- package/util/loaders.js +113 -0
- package/util/proxy-factory.js +143 -168
- package/util/request.js +6 -2
- package/util/workqueue.js +111 -0
- package/.last_command +0 -7
- package/duster/helpers/core/cloudcms/associations.js +0 -34
- package/duster/helpers/core/cloudcms/beta/markdown.js +0 -46
- package/duster/helpers/core/cloudcms/beta/nodeAttachmentText.js +0 -46
- package/duster/helpers/core/cloudcms/beta/params.js +0 -33
- package/duster/helpers/core/cloudcms/beta/processTemplate.js +0 -82
- package/duster/helpers/core/cloudcms/content.js +0 -34
- package/duster/helpers/core/cloudcms/expand.js +0 -38
- package/duster/helpers/core/cloudcms/form.js +0 -34
- package/duster/helpers/core/cloudcms/query.js +0 -34
- package/duster/helpers/core/cloudcms/queryOne.js +0 -34
- package/duster/helpers/core/cloudcms/relatives.js +0 -34
- package/duster/helpers/core/cloudcms/search.js +0 -34
- package/duster/helpers/core/cloudcms/searchOne.js +0 -34
- package/duster/helpers/core/cloudcms/wcm/dependency.js +0 -83
- package/duster/helpers/core/cloudcms/wcm/fragment.js +0 -34
- package/duster/helpers/core/dev/debug.js +0 -42
- package/duster/helpers/core/dom/block.js +0 -49
- package/duster/helpers/core/dom/include.js +0 -38
- package/duster/helpers/core/dom/layout.js +0 -49
- package/duster/helpers/core/dom/link.js +0 -81
- package/duster/helpers/core/dom/resource.js +0 -77
- package/duster/helpers/core/engine.js +0 -1580
- package/duster/helpers/core/ice/value.js +0 -65
- package/duster/helpers/core/index.js +0 -49
- package/duster/helpers/core/operators/if.js +0 -64
- package/duster/helpers/core/operators/iter.js +0 -45
- package/duster/helpers/core/operators/iterate.js +0 -129
- package/duster/helpers/sample/nyt.js +0 -114
- package/duster/index.js +0 -319
- package/duster/support.js +0 -436
- package/duster/tracker.js +0 -262
- package/middleware/authentication/providers/cas.js +0 -73
- package/middleware/authentication/providers/facebook.js +0 -120
- package/middleware/authentication/providers/github.js +0 -88
- package/middleware/authentication/providers/linkedin.js +0 -112
- package/middleware/authentication/providers/twitter.js +0 -120
- package/middleware/server-tags/server-tags.js +0 -113
- package/middleware/wcm/wcm.js +0 -1437
package/duster/support.js
DELETED
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
var async = require("async");
|
|
2
|
-
var path = require("path");
|
|
3
|
-
var fs = require("fs");
|
|
4
|
-
|
|
5
|
-
var util = require("../util/util");
|
|
6
|
-
var renditions = require("../util/renditions");
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Helper functions for Dust Tags
|
|
10
|
-
*
|
|
11
|
-
* @type {Function}
|
|
12
|
-
*/
|
|
13
|
-
exports = module.exports = function(dust)
|
|
14
|
-
{
|
|
15
|
-
var r = {};
|
|
16
|
-
|
|
17
|
-
// used to check whether a parameter is defined, meaning it has a value and the value is NON EMPTY.
|
|
18
|
-
var isDefined = r.isDefined = function(thing)
|
|
19
|
-
{
|
|
20
|
-
return ( (typeof(thing) !== "undefined") && (thing !== "") );
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Determines whether to use the fragment cache. We use this cache if we're instructed to and if we're in
|
|
25
|
-
* production model.
|
|
26
|
-
*
|
|
27
|
-
* @returns {boolean}
|
|
28
|
-
*/
|
|
29
|
-
var isFragmentCacheEnabled = r.isFragmentCacheEnabled = function()
|
|
30
|
-
{
|
|
31
|
-
if (!process.configuration.duster) {
|
|
32
|
-
process.configuration.duster = {};
|
|
33
|
-
}
|
|
34
|
-
if (!process.configuration.duster.fragments) {
|
|
35
|
-
process.configuration.duster.fragments = {};
|
|
36
|
-
}
|
|
37
|
-
if (typeof(process.configuration.duster.fragments.cache) === "undefined") {
|
|
38
|
-
process.configuration.duster.fragments.cache = true;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (process.env.FORCE_CLOUDCMS_DUST_FRAGMENT_CACHE === "true")
|
|
42
|
-
{
|
|
43
|
-
process.configuration.duster.fragments.cache = true;
|
|
44
|
-
}
|
|
45
|
-
else if (process.env.FORCE_CLOUDCMS_DUST_FRAGMENT_CACHE === "false")
|
|
46
|
-
{
|
|
47
|
-
process.configuration.duster.fragments.cache = false;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (process.env.CLOUDCMS_APPSERVER_MODE !== "production") {
|
|
51
|
-
process.configuration.duster.fragments.cache = false;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return process.configuration.duster.fragments.cache;
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
var resolveVariables = r.resolveVariables = function(variables, context, callback)
|
|
59
|
-
{
|
|
60
|
-
if (!variables) {
|
|
61
|
-
callback();
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (variables.length === 0)
|
|
66
|
-
{
|
|
67
|
-
callback(null, []);
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
var resolvedVariables = [];
|
|
72
|
-
|
|
73
|
-
var fns = [];
|
|
74
|
-
for (var i = 0; i < variables.length; i++)
|
|
75
|
-
{
|
|
76
|
-
var fn = function(variable) {
|
|
77
|
-
return function(done) {
|
|
78
|
-
|
|
79
|
-
dust.renderSource("" + variable, context, function (err, value) {
|
|
80
|
-
|
|
81
|
-
if (err) {
|
|
82
|
-
done(err);
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
value = value.trim();
|
|
87
|
-
|
|
88
|
-
resolvedVariables.push(value);
|
|
89
|
-
done();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
}(variables[i]);
|
|
94
|
-
fns.push(fn);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
async.series(fns, function(err) {
|
|
98
|
-
callback(err, resolvedVariables);
|
|
99
|
-
});
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Helper function that sets the dust cursor to flushable.
|
|
104
|
-
* This is to get around an apparent bug with dust:
|
|
105
|
-
*
|
|
106
|
-
* https://github.com/linkedin/dustjs/issues/303
|
|
107
|
-
*
|
|
108
|
-
* @param chunk
|
|
109
|
-
* @param callback
|
|
110
|
-
* @returns {*}
|
|
111
|
-
*/
|
|
112
|
-
var map = r.map = function(chunk, callback)
|
|
113
|
-
{
|
|
114
|
-
var cursor = chunk.map(function(branch) {
|
|
115
|
-
callback(branch);
|
|
116
|
-
});
|
|
117
|
-
cursor.flushable = true;
|
|
118
|
-
|
|
119
|
-
return cursor;
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Helper function to end the chunk. This is in place because it's unclear exactly what is needed to counter
|
|
124
|
-
* the issue mentioned in:
|
|
125
|
-
*
|
|
126
|
-
* https://github.com/linkedin/dustjs/issues/303
|
|
127
|
-
*
|
|
128
|
-
* At one point, it seemed that some throttling of the end() call was required. It may still be at some point.
|
|
129
|
-
* So for now, we use this helper method to end() since it lets us inject our own behaviors if needed.
|
|
130
|
-
*
|
|
131
|
-
* @param chunk
|
|
132
|
-
* @param context
|
|
133
|
-
* @param err
|
|
134
|
-
*/
|
|
135
|
-
var end = r.end = function(chunk, context, err)
|
|
136
|
-
{
|
|
137
|
-
if (err)
|
|
138
|
-
{
|
|
139
|
-
chunk.setError(err);
|
|
140
|
-
}
|
|
141
|
-
else
|
|
142
|
-
{
|
|
143
|
-
chunk.end();
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
var _MARK_INSIGHT = r._MARK_INSIGHT = function(node, result)
|
|
148
|
-
{
|
|
149
|
-
if (result)
|
|
150
|
-
{
|
|
151
|
-
result.insightNode = node.getRepositoryId() + "/" + node.getBranchId() + "/" + node.getId();
|
|
152
|
-
}
|
|
153
|
-
else
|
|
154
|
-
{
|
|
155
|
-
console.log("WARN: result node should not be null");
|
|
156
|
-
console.trace();
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
//
|
|
162
|
-
// tracker related stuff
|
|
163
|
-
//
|
|
164
|
-
|
|
165
|
-
var buildRequirements = r.buildRequirements = function(context, requirements)
|
|
166
|
-
{
|
|
167
|
-
var badKeys = [];
|
|
168
|
-
|
|
169
|
-
for (var key in requirements)
|
|
170
|
-
{
|
|
171
|
-
if (!requirements[key])
|
|
172
|
-
{
|
|
173
|
-
badKeys.push(key);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
for (var i = 0; i < badKeys.length; i++)
|
|
178
|
-
{
|
|
179
|
-
delete requirements[badKeys[i]];
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// add in stuff from request if available
|
|
183
|
-
var req = context.get("req");
|
|
184
|
-
if (req)
|
|
185
|
-
{
|
|
186
|
-
if (req.repositoryId)
|
|
187
|
-
{
|
|
188
|
-
requirements["repository"] = req.repositoryId;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if (req.branchId)
|
|
192
|
-
{
|
|
193
|
-
requirements["branch"] = req.branchId;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return requirements;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
var handleCacheFragmentRead = r.handleCacheFragmentRead = function(context, fragmentId, requirements, callback)
|
|
201
|
-
{
|
|
202
|
-
if (!isFragmentCacheEnabled())
|
|
203
|
-
{
|
|
204
|
-
return callback();
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
var req = context.get("req");
|
|
208
|
-
|
|
209
|
-
var contentStore = req.stores.content;
|
|
210
|
-
|
|
211
|
-
var fragmentsBasePath = context.get("_fragments_base_path");
|
|
212
|
-
if (!fragmentsBasePath) {
|
|
213
|
-
fragmentsBasePath = path.join("duster", "repositories", req.repositoryId, "branches", req.branchId, "fragments");
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// fragment cache key
|
|
217
|
-
var fragmentCacheKey = util.generateFragmentCacheKey(fragmentId, requirements);
|
|
218
|
-
|
|
219
|
-
// disk location
|
|
220
|
-
var fragmentFilePath = path.join(fragmentsBasePath, fragmentCacheKey, "fragment.html");
|
|
221
|
-
util.safeReadStream(contentStore, fragmentFilePath, function(err, stream) {
|
|
222
|
-
callback(err, stream, fragmentFilePath, fragmentCacheKey);
|
|
223
|
-
});
|
|
224
|
-
};
|
|
225
|
-
|
|
226
|
-
var handleCacheFragmentWrite = r.handleCacheFragmentWrite = function(context, fragmentDescriptor, fragmentDependencies, requirements, text, callback)
|
|
227
|
-
{
|
|
228
|
-
// if fragment cache not enabled, return right away
|
|
229
|
-
if (!isFragmentCacheEnabled())
|
|
230
|
-
{
|
|
231
|
-
return callback();
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
var req = context.get("req");
|
|
235
|
-
|
|
236
|
-
var contentStore = req.stores.content;
|
|
237
|
-
|
|
238
|
-
var fragmentsBasePath = context.get("_fragments_base_path");
|
|
239
|
-
if (!fragmentsBasePath) {
|
|
240
|
-
fragmentsBasePath = path.join("duster", "repositories", req.repositoryId, "branches", req.branchId, "fragments");
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
// fragment cache key
|
|
244
|
-
var fragmentCacheKey = util.generateFragmentCacheKey(fragmentDescriptor.fragmentId, requirements);
|
|
245
|
-
|
|
246
|
-
// store this
|
|
247
|
-
fragmentDescriptor.fragmentCacheKey = fragmentCacheKey;
|
|
248
|
-
|
|
249
|
-
// mark the rendition
|
|
250
|
-
if (fragmentDependencies)
|
|
251
|
-
{
|
|
252
|
-
console.log("marking rendition from dust. fragmentId: " + fragmentDescriptor.fragmentId);
|
|
253
|
-
renditions.markRendition(req, fragmentDescriptor, fragmentDependencies, function (err) {
|
|
254
|
-
|
|
255
|
-
// if we got an error writing the rendition, then we have to roll back and invalidate disk cache
|
|
256
|
-
if (err)
|
|
257
|
-
{
|
|
258
|
-
var fragmentFolderPath = path.join(fragmentsBasePath, fragmentCacheKey);
|
|
259
|
-
|
|
260
|
-
console.log("Caught error on fragment markRendition, invalidating: " + fragmentFolderPath + ", err:" + err);
|
|
261
|
-
|
|
262
|
-
_handleCacheFragmentInvalidate(contentStore, fragmentFolderPath, function() {
|
|
263
|
-
// done
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// disk location
|
|
271
|
-
var fragmentFilePath = path.join(fragmentsBasePath, fragmentCacheKey, "fragment.html");
|
|
272
|
-
contentStore.writeFile(fragmentFilePath, text, function(err) {
|
|
273
|
-
callback(err, fragmentFilePath, fragmentCacheKey);
|
|
274
|
-
});
|
|
275
|
-
};
|
|
276
|
-
|
|
277
|
-
var handleCacheFragmentInvalidate = r.handleCacheFragmentInvalidate = function(host, fragmentsBasePath, fragmentCacheKey, callback)
|
|
278
|
-
{
|
|
279
|
-
var fragmentFolderPath = path.join(fragmentsBasePath, fragmentCacheKey);
|
|
280
|
-
|
|
281
|
-
// list all of the hosts
|
|
282
|
-
var stores = require("../middleware/stores/stores");
|
|
283
|
-
stores.produce(host, function (err, stores) {
|
|
284
|
-
|
|
285
|
-
if (err) {
|
|
286
|
-
return callback(err, fragmentFolderPath);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
_handleCacheFragmentInvalidate(stores.content, fragmentFolderPath, function(err, fragmentFolderPath) {
|
|
290
|
-
return callback(null, fragmentFolderPath);
|
|
291
|
-
});
|
|
292
|
-
});
|
|
293
|
-
};
|
|
294
|
-
|
|
295
|
-
var _handleCacheFragmentInvalidate = function(contentStore, fragmentFolderPath, callback)
|
|
296
|
-
{
|
|
297
|
-
contentStore.existsDirectory(fragmentFolderPath, function (exists) {
|
|
298
|
-
|
|
299
|
-
if (!exists) {
|
|
300
|
-
return callback();
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
contentStore.removeDirectory(fragmentFolderPath, function () {
|
|
304
|
-
callback();
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
var loadFragment = r.loadFragment = function(context, fragmentId, requirements, callback)
|
|
310
|
-
{
|
|
311
|
-
if (!isFragmentCacheEnabled())
|
|
312
|
-
{
|
|
313
|
-
return callback();
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (!fragmentId)
|
|
317
|
-
{
|
|
318
|
-
return callback();
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
var req = context.get("req");
|
|
322
|
-
|
|
323
|
-
handleCacheFragmentRead(context, fragmentId, requirements, function(err, readStream, readPath, fragmentCacheKey) {
|
|
324
|
-
|
|
325
|
-
if (!err && readStream)
|
|
326
|
-
{
|
|
327
|
-
var req = context.get("req");
|
|
328
|
-
|
|
329
|
-
// yes, we found it in cache, so we'll simply pipe it back from disk
|
|
330
|
-
req.log("Fragment Cache Hit: " + req.url + "#" + fragmentCacheKey);
|
|
331
|
-
|
|
332
|
-
// read stream in
|
|
333
|
-
var bufs = [];
|
|
334
|
-
readStream.on('data', function(d){ bufs.push(d);});
|
|
335
|
-
readStream.on('end', function(){
|
|
336
|
-
|
|
337
|
-
var fragment = "" + Buffer.concat(bufs).toString();
|
|
338
|
-
|
|
339
|
-
callback(null, fragment);
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
callback({
|
|
346
|
-
"message": "Unable to read fragment: " + fragmentId
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
});
|
|
350
|
-
};
|
|
351
|
-
|
|
352
|
-
var renderFragment = r.renderFragment = function(context, fragmentId, requirements, chunk, bodies, callback)
|
|
353
|
-
{
|
|
354
|
-
if (!isFragmentCacheEnabled() || !fragmentId)
|
|
355
|
-
{
|
|
356
|
-
chunk.render(bodies.block, context);
|
|
357
|
-
end(chunk, context);
|
|
358
|
-
|
|
359
|
-
return callback();
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
var c = chunk.capture(bodies.block, context, function(text, chunk2) {
|
|
363
|
-
|
|
364
|
-
// we leave a timeout here so that things can catch up internally within Dust (more oddness!)
|
|
365
|
-
setTimeout(function() {
|
|
366
|
-
|
|
367
|
-
// for reasons that have everything to do with Dust oddness...
|
|
368
|
-
// write to "c" and be sure to end "c" then "chunk2"
|
|
369
|
-
c.write(text);
|
|
370
|
-
c.end();
|
|
371
|
-
chunk2.end();
|
|
372
|
-
// NOTE: normally, we'd expect to do something like this
|
|
373
|
-
//chunk2.write(text);
|
|
374
|
-
//end(chunk2);
|
|
375
|
-
// but this doesn't work and it has something to do with dust.map and chunk.capture intermingling weirdly
|
|
376
|
-
|
|
377
|
-
// now let's cache it
|
|
378
|
-
var fragmentDescriptor = {};
|
|
379
|
-
var pageDescriptor = context.get("_page_descriptor");
|
|
380
|
-
if (pageDescriptor) {
|
|
381
|
-
fragmentDescriptor = util.clone(pageDescriptor, true);
|
|
382
|
-
}
|
|
383
|
-
fragmentDescriptor.fragmentId = fragmentId;
|
|
384
|
-
fragmentDescriptor.scope = "FRAGMENT";
|
|
385
|
-
|
|
386
|
-
var tracker = context.get("__tracker");
|
|
387
|
-
|
|
388
|
-
var fragmentDependencies = {};
|
|
389
|
-
fragmentDependencies.requires = tracker.requires;
|
|
390
|
-
fragmentDependencies.produces = tracker.produces;
|
|
391
|
-
|
|
392
|
-
// write to cache
|
|
393
|
-
handleCacheFragmentWrite(context, fragmentDescriptor, fragmentDependencies, requirements, text, function(err, writtenPath, writtenCacheKey) {
|
|
394
|
-
|
|
395
|
-
var req = context.get("req");
|
|
396
|
-
|
|
397
|
-
if (err) {
|
|
398
|
-
req.log("Fragment Cache Write Failed for URL: " + req.url + ", err: " + JSON.stringify(err, null, " "));
|
|
399
|
-
return callback(err);
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
req.log("Fragment Cache Write: " + req.url + "#" + writtenCacheKey);
|
|
403
|
-
|
|
404
|
-
callback();
|
|
405
|
-
});
|
|
406
|
-
}, 1);
|
|
407
|
-
});
|
|
408
|
-
|
|
409
|
-
return c;
|
|
410
|
-
};
|
|
411
|
-
|
|
412
|
-
var addHelpers = r.addHelpers = function(app, dust, filepaths, callback) {
|
|
413
|
-
|
|
414
|
-
var fns = [];
|
|
415
|
-
for (var i = 0; i < filepaths.length; i++)
|
|
416
|
-
{
|
|
417
|
-
var fn = function(filepath, app, dust) {
|
|
418
|
-
return function(done) {
|
|
419
|
-
|
|
420
|
-
require(filepath)(app, dust, function() {
|
|
421
|
-
//console.log("Loaded dust helper: " + filepath);
|
|
422
|
-
done();
|
|
423
|
-
});
|
|
424
|
-
}
|
|
425
|
-
}(filepaths[i], app, dust);
|
|
426
|
-
fns.push(fn);
|
|
427
|
-
}
|
|
428
|
-
|
|
429
|
-
async.series(fns, function() {
|
|
430
|
-
callback();
|
|
431
|
-
});
|
|
432
|
-
|
|
433
|
-
};
|
|
434
|
-
|
|
435
|
-
return r;
|
|
436
|
-
};
|
package/duster/tracker.js
DELETED
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
var exports = module.exports;
|
|
2
|
-
|
|
3
|
-
var util = require("../util/util");
|
|
4
|
-
|
|
5
|
-
var trackerInstance = function(context)
|
|
6
|
-
{
|
|
7
|
-
return context.get("__tracker");
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
var getParentContext = function(context)
|
|
11
|
-
{
|
|
12
|
-
var parentContext = null;
|
|
13
|
-
|
|
14
|
-
// if this context has a parent...
|
|
15
|
-
if (context.stack && context.stack.tail && context.stack.tail.length > 0)
|
|
16
|
-
{
|
|
17
|
-
// the current tip context
|
|
18
|
-
// pop it off and "context" modifies
|
|
19
|
-
var currentContext = context.pop();
|
|
20
|
-
|
|
21
|
-
// the new tip is the parent
|
|
22
|
-
parentContext = context.current();
|
|
23
|
-
|
|
24
|
-
// restore the current context as tip
|
|
25
|
-
context.push(currentContext);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return parentContext;
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
var id = exports.id = function(context)
|
|
32
|
-
{
|
|
33
|
-
var instance = trackerInstance(context);
|
|
34
|
-
|
|
35
|
-
return instance.id;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Starts a tracker within the current context.
|
|
40
|
-
*
|
|
41
|
-
* The tracker is bound to the Dust context's push and pop methods. A "__tracker" instance holds the dependency
|
|
42
|
-
* tracker instance for that particular frame in the stack.
|
|
43
|
-
*
|
|
44
|
-
* When the context is popped, the tracker for the current frame copies some of it's dependency state from the child
|
|
45
|
-
* to the parent. Dependency state is either of type "produces" or "requires".
|
|
46
|
-
*
|
|
47
|
-
* PRODUCES
|
|
48
|
-
* --------
|
|
49
|
-
*
|
|
50
|
-
* The "produces" dependencies usually identify the content items or display assets that the current execution
|
|
51
|
-
* rendered on the screen. It identifies which objects produced the rendered view.
|
|
52
|
-
*
|
|
53
|
-
* When the context pops, these dependencies always copy from the child context to the parent. Any wrapping fragments
|
|
54
|
-
* inherit the produced dependencies of their children, all the way up to the page.
|
|
55
|
-
*
|
|
56
|
-
* That way, if a product dependency (i.e. a Cloud CMS content node) invalidates, all pages and nested fragments can be
|
|
57
|
-
* detected and invalidated at once.
|
|
58
|
-
*
|
|
59
|
-
* In this sense, it is fair to think of produced dependencies as serving the purpose of how to optimize
|
|
60
|
-
* invalidation.
|
|
61
|
-
*
|
|
62
|
-
* REQUIRES
|
|
63
|
-
* --------
|
|
64
|
-
*
|
|
65
|
-
* The "requires" dependencies identify the required state of the parent such that the cached state of the
|
|
66
|
-
* current execution context can be used.
|
|
67
|
-
*
|
|
68
|
-
* These dependencies are a list of "what must be true" about the outer variables such that we can use the cache
|
|
69
|
-
* fragment.
|
|
70
|
-
*
|
|
71
|
-
* All requires variables are local. They do not propagate up to the parent in the same way as "produces" dependencies.
|
|
72
|
-
* Rather, the nested nature of HTML ensures that outer HTML fragments will contain the HTML of inner HTML fragments.
|
|
73
|
-
*
|
|
74
|
-
* The "requires" dependencies serve as a kind of footprint that allows for a very fast pattern match against the
|
|
75
|
-
* current set of known runtime variables at any point in the execution chain. For the top-level page, these include
|
|
76
|
-
* things like the repository ID, the branchID and any other request state that was used to produce the page.
|
|
77
|
-
*
|
|
78
|
-
* All "requires" dependencies pass down to children but they do not pass back up to parents.
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* Requirements should look like:
|
|
82
|
-
*
|
|
83
|
-
* {
|
|
84
|
-
* "param1": "abc",
|
|
85
|
-
* "param2": "def"
|
|
86
|
-
* }
|
|
87
|
-
*
|
|
88
|
-
* @param childContext
|
|
89
|
-
* @param _id
|
|
90
|
-
* @param _requirements
|
|
91
|
-
*/
|
|
92
|
-
var start = exports.start = function(childContext, _id, _requirements)
|
|
93
|
-
{
|
|
94
|
-
var childTracker = {
|
|
95
|
-
"requires": {},
|
|
96
|
-
"produces": {}
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
var fc = function(parentTracker, childTracker, key)
|
|
100
|
-
{
|
|
101
|
-
if (parentTracker[key] && parentTracker[key].length > 0)
|
|
102
|
-
{
|
|
103
|
-
for (var k in parentTracker[key])
|
|
104
|
-
{
|
|
105
|
-
if (!childTracker[key][k]) {
|
|
106
|
-
childTracker[key][k] = [];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
for (var i = 0; i < parentTracker[key][k].length; i++)
|
|
110
|
-
{
|
|
111
|
-
childTracker[key][k].push(parentTracker[key][k][i]);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
// find the parent context
|
|
118
|
-
var parentContext = getParentContext(childContext);
|
|
119
|
-
if (parentContext)
|
|
120
|
-
{
|
|
121
|
-
// copy parent "requires" and "produces" into new child tracker object
|
|
122
|
-
var parentTracker = trackerInstance(parentContext);
|
|
123
|
-
if (parentTracker)
|
|
124
|
-
{
|
|
125
|
-
fc(parentTracker, childTracker, "requires");
|
|
126
|
-
fc(parentTracker, childTracker, "produces");
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (_id)
|
|
131
|
-
{
|
|
132
|
-
childTracker.id = _id;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (_requirements)
|
|
136
|
-
{
|
|
137
|
-
requirements(childContext, _requirements);
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Finishes a tracker.
|
|
143
|
-
*
|
|
144
|
-
* This hands back the tracker state. It also copies tracker dependencies up to the parent tracker.
|
|
145
|
-
*
|
|
146
|
-
* @param parentContext
|
|
147
|
-
* @param childContext
|
|
148
|
-
* @returns the tracker context
|
|
149
|
-
*/
|
|
150
|
-
var finish = exports.finish = function(childContext)
|
|
151
|
-
{
|
|
152
|
-
// child tracker
|
|
153
|
-
var childTracker = trackerInstance(childContext);
|
|
154
|
-
|
|
155
|
-
// find the parent context
|
|
156
|
-
var parentContext = getParentContext(childContext);
|
|
157
|
-
if (parentContext)
|
|
158
|
-
{
|
|
159
|
-
// parent tracker
|
|
160
|
-
var parentTracker = trackerInstance(parentContext);
|
|
161
|
-
|
|
162
|
-
// now copy stuff back up
|
|
163
|
-
if (parentTracker)
|
|
164
|
-
{
|
|
165
|
-
// any "produces" dependencies always copies up
|
|
166
|
-
for (var name in childTracker.produces)
|
|
167
|
-
{
|
|
168
|
-
var array = childTracker.produces[name];
|
|
169
|
-
if (array)
|
|
170
|
-
{
|
|
171
|
-
if (!parentTracker["produces"][name])
|
|
172
|
-
{
|
|
173
|
-
parentTracker["produces"][name] = [];
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
for (var i = 0; i < array.length; i++)
|
|
177
|
-
{
|
|
178
|
-
if (parentTracker["produces"][name].indexOf(array[i]) === -1)
|
|
179
|
-
{
|
|
180
|
-
parentTracker["produces"][name].push(array[i]);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Marks that the current rendering requires the following requirements.
|
|
191
|
-
*
|
|
192
|
-
* @param context
|
|
193
|
-
* @param requirements
|
|
194
|
-
*/
|
|
195
|
-
var requirements = exports.requirements = function(context, requirements)
|
|
196
|
-
{
|
|
197
|
-
for (var k in requirements)
|
|
198
|
-
{
|
|
199
|
-
var v = requirements[k];
|
|
200
|
-
if (v)
|
|
201
|
-
{
|
|
202
|
-
requires(context, k, v.value);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* Marks that the current rendering requires the following key=value to be in place.
|
|
209
|
-
*
|
|
210
|
-
* @param context
|
|
211
|
-
* @param key
|
|
212
|
-
* @param value
|
|
213
|
-
*/
|
|
214
|
-
var requires = exports.requires = function(context, key, value)
|
|
215
|
-
{
|
|
216
|
-
if (typeof(value) !== "undefined" && value !== null)
|
|
217
|
-
{
|
|
218
|
-
var instance = trackerInstance(context);
|
|
219
|
-
|
|
220
|
-
var requires = instance["requires"];
|
|
221
|
-
|
|
222
|
-
var array = requires[key];
|
|
223
|
-
if (!array)
|
|
224
|
-
{
|
|
225
|
-
requires[key] = array = [];
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
if (array.indexOf(value) === -1)
|
|
229
|
-
{
|
|
230
|
-
array.push(value);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
};
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* Marks that the current rendering produces a result that features the given key=value as part of its output.
|
|
237
|
-
*
|
|
238
|
-
* @param context
|
|
239
|
-
* @param key
|
|
240
|
-
* @param value
|
|
241
|
-
*/
|
|
242
|
-
var produces = exports.produces = function(context, key, value)
|
|
243
|
-
{
|
|
244
|
-
if (typeof(value) !== "undefined" && value !== null)
|
|
245
|
-
{
|
|
246
|
-
var instance = trackerInstance(context);
|
|
247
|
-
|
|
248
|
-
var produces = instance["produces"];
|
|
249
|
-
|
|
250
|
-
var array = produces[key];
|
|
251
|
-
if (!array)
|
|
252
|
-
{
|
|
253
|
-
array = [];
|
|
254
|
-
produces[key] = array;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (array.indexOf(value) === -1)
|
|
258
|
-
{
|
|
259
|
-
array.push(value);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
};
|