Skip to content

Commit b6f2752

Browse files
Merge pull request #764 from pattern-lab/dev-3.0-async
Dev 3.0 async
2 parents 316a7b4 + 3a83116 commit b6f2752

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+5460
-4704
lines changed

core/index.js

+103-80
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,13 @@ const updateNotifier = require('update-notifier');
1818
const logger = require('./lib/log');
1919
const PatternGraph = require('./lib/pattern_graph').PatternGraph;
2020
const CompileState = require('./lib/object_factory').CompileState;
21-
const pa = require('./lib/pattern_assembler');
2221
const pe = require('./lib/pattern_exporter');
2322
const lh = require('./lib/lineage_hunter');
23+
const markModifiedPatterns = require('./lib/markModifiedPatterns');
24+
const parseAllLinks = require('./lib/parseAllLinks');
25+
const processMetaPattern = require('./lib/processMetaPattern');
26+
const render = require('./lib/render');
27+
const Pattern = require('./lib/object_factory').Pattern;
2428

2529
const defaultConfig = require('../patternlab-config.json');
2630

@@ -30,7 +34,6 @@ let assetCopier = require('./lib/asset_copy'); // eslint-disable-line
3034
let pattern_exporter = new pe(); // eslint-disable-line
3135
let serve = require('./lib/serve'); // eslint-disable-line
3236

33-
const pattern_assembler = new pa();
3437
const lineage_hunter = new lh();
3538

3639
//bootstrap update notifier
@@ -39,7 +42,6 @@ updateNotifier({
3942
updateCheckInterval: 1000 * 60 * 60 * 24 // notify at most once a day
4043
}).notify();
4144

42-
4345
/**
4446
* Returns the standardized default config
4547
*
@@ -136,7 +138,7 @@ const patternlab_module = function (config) {
136138

137139
function cleanBuildDirectory(incrementalBuildsEnabled) {
138140
if (incrementalBuildsEnabled) {
139-
logger.log.info("Incremental builds enabled.");
141+
logger.info("Incremental builds enabled.");
140142
} else {
141143
// needs to be done BEFORE processing patterns
142144
fs.removeSync(paths.public.patterns);
@@ -153,7 +155,7 @@ const patternlab_module = function (config) {
153155
const graph = patternlab.graph = loadPatternGraph(deletePatternDir);
154156
const graphNeedsUpgrade = !PatternGraph.checkVersion(graph);
155157
if (graphNeedsUpgrade) {
156-
logger.log.info("Due to an upgrade, a complete rebuild is required and the public/patterns directory was deleted. " +
158+
logger.info("Due to an upgrade, a complete rebuild is required and the public/patterns directory was deleted. " +
157159
"Incremental build is available again on the next successful run.");
158160

159161
// Ensure that the freshly built graph has the latest version again.
@@ -177,79 +179,97 @@ const patternlab_module = function (config) {
177179

178180
//now that all the main patterns are known, look for any links that might be within data and expand them
179181
//we need to do this before expanding patterns & partials into extendedTemplates, otherwise we could lose the data -> partial reference
180-
pattern_assembler.parse_data_links(patternlab);
182+
parseAllLinks(patternlab);
181183

182184
//diveSync again to recursively include partials, filling out the
183185
//extendedTemplate property of the patternlab.patterns elements
184186
// TODO we can reduce the time needed by only processing changed patterns and their partials
185187
patternlab.processAllPatternsRecursive(paths.source.patterns, patternlab);
186188

187189
//take the user defined head and foot and process any data and patterns that apply
188-
// GTP: should these really be invoked from outside?
189-
patternlab.processHeadPattern();
190-
patternlab.processFootPattern();
191-
192-
//cascade any patternStates
193-
lineage_hunter.cascade_pattern_states(patternlab);
194-
195-
//set pattern-specific header if necessary
196-
let head;
197-
if (patternlab.userHead) {
198-
head = patternlab.userHead;
199-
} else {
200-
head = patternlab.header;
201-
}
190+
const headPatternPromise = processMetaPattern(`_00-head.${patternlab.config.patternExtension}`, 'userHead', patternlab);
191+
const footPatternPromise = processMetaPattern(`_01-foot.${patternlab.config.patternExtension}`, 'userFoot', patternlab);
202192

203-
//set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header
204-
patternlab.data.patternLabHead = pattern_assembler.renderPattern(patternlab.header, {
205-
cacheBuster: patternlab.cacheBuster
206-
});
193+
return Promise.all([headPatternPromise, footPatternPromise]).then(() => {
207194

208-
// If deletePatternDir == true or graph needs to be updated
209-
// rebuild all patterns
210-
let patternsToBuild = null;
195+
//cascade any patternStates
196+
lineage_hunter.cascade_pattern_states(patternlab);
211197

212-
// If deletePatternDir == true or graph needs to be updated
213-
// rebuild all patterns
214-
patternsToBuild = null;
215-
216-
if (patternlab.incrementalBuildsEnabled) {
217-
// When the graph was loaded from file, some patterns might have been moved/deleted between runs
218-
// so the graph data become out of sync
219-
patternlab.graph.sync().forEach(n => {
220-
logger.log.info("[Deleted/Moved] " + n);
221-
});
222-
223-
// TODO Find created or deleted files
224-
const now = new Date().getTime();
225-
pattern_assembler.mark_modified_patterns(now, patternlab);
226-
patternsToBuild = patternlab.graph.compileOrder();
227-
} else {
228-
// build all patterns, mark all to be rebuilt
229-
patternsToBuild = patternlab.patterns;
230-
for (const p of patternsToBuild) {
231-
p.compileState = CompileState.NEEDS_REBUILD;
198+
//set pattern-specific header if necessary
199+
let head;
200+
if (patternlab.userHead) {
201+
head = patternlab.userHead;
202+
} else {
203+
head = patternlab.header;
232204
}
233-
}
234205

235-
//render all patterns last, so lineageR works
236-
return patternsToBuild
237-
.reduce((previousPromise, pattern) => {
238-
return previousPromise.then(() => patternlab.renderSinglePattern(pattern, head));
239-
}, Promise.resolve())
240-
.then(() => {
241-
// Saves the pattern graph when all files have been compiled
242-
PatternGraph.storeToFile(patternlab);
243-
if (patternlab.config.exportToGraphViz) {
244-
PatternGraph.exportToDot(patternlab, "dependencyGraph.dot");
245-
logger.log.info(`Exported pattern graph to ${path.join(config.paths.public.root, "dependencyGraph.dot")}`);
206+
//set the pattern-specific header by compiling the general-header with data, and then adding it to the meta header
207+
return render(Pattern.createEmpty({extendedTemplate: patternlab.header}), {
208+
cacheBuster: patternlab.cacheBuster
209+
}).then((results) => {
210+
patternlab.data.patternLabHead = results;
211+
212+
// If deletePatternDir == true or graph needs to be updated
213+
// rebuild all patterns
214+
let patternsToBuild = null;
215+
216+
// If deletePatternDir == true or graph needs to be updated
217+
// rebuild all patterns
218+
patternsToBuild = null;
219+
220+
if (patternlab.incrementalBuildsEnabled) {
221+
// When the graph was loaded from file, some patterns might have been moved/deleted between runs
222+
// so the graph data become out of sync
223+
patternlab.graph.sync().forEach(n => {
224+
logger.info("[Deleted/Moved] " + n);
225+
});
226+
227+
// TODO Find created or deleted files
228+
const now = new Date().getTime();
229+
markModifiedPatterns(now, patternlab);
230+
patternsToBuild = patternlab.graph.compileOrder();
231+
} else {
232+
// build all patterns, mark all to be rebuilt
233+
patternsToBuild = patternlab.patterns;
234+
for (const p of patternsToBuild) {
235+
p.compileState = CompileState.NEEDS_REBUILD;
236+
}
246237
}
247238

248-
//export patterns if necessary
249-
pattern_exporter.export_patterns(patternlab);
239+
//render all patterns last, so lineageR works
240+
return patternsToBuild
241+
.reduce((previousPromise, pattern) => {
242+
return previousPromise.then(() => patternlab.renderSinglePattern(pattern, head));
243+
}, Promise.resolve())
244+
.then(() => {
245+
// Saves the pattern graph when all files have been compiled
246+
PatternGraph.storeToFile(patternlab);
247+
if (patternlab.config.exportToGraphViz) {
248+
PatternGraph.exportToDot(patternlab, "dependencyGraph.dot");
249+
logger.info(`Exported pattern graph to ${path.join(config.paths.public.root, "dependencyGraph.dot")}`);
250+
}
251+
252+
//export patterns if necessary
253+
pattern_exporter.export_patterns(patternlab);
254+
255+
}).catch(reason => {
256+
console.log(reason);
257+
logger.error('Error rendering patterns');
258+
});
259+
260+
}).catch(reason => {
261+
console.log(reason);
262+
logger.error('Error rendering pattern lab header');
250263
});
251-
}).catch((err) => {
252-
logger.info('Error in buildPatterns():', err);
264+
265+
}).catch(reason => {
266+
console.log(reason);
267+
logger.error('Error processing meta patterns');
268+
});
269+
270+
}).catch(reason => {
271+
console.log(reason);
272+
logger.error('Error in buildPatterns()');
253273
});
254274
}
255275

@@ -286,26 +306,28 @@ const patternlab_module = function (config) {
286306
patternlab.isBusy = true;
287307
return buildPatterns(options.cleanPublic).then(() => {
288308

289-
new ui_builder().buildFrontend(patternlab);
290-
assetCopier().copyAssets(patternlab.config.paths, patternlab, options);
309+
return new ui_builder().buildFrontend(patternlab).then(() => {
291310

292-
this.events.on('patternlab-pattern-change', () => {
293-
if (!patternlab.isBusy) {
294-
options.cleanPublic = false;
295-
return this.build(options);
296-
}
297-
return Promise.resolve();
298-
});
311+
assetCopier().copyAssets(patternlab.config.paths, patternlab, options);
299312

300-
this.events.on('patternlab-global-change', () => {
301-
if (!patternlab.isBusy) {
302-
options.cleanPublic = true; //rebuild everything
303-
return this.build(options);
304-
}
305-
return Promise.resolve();
306-
});
313+
this.events.on('patternlab-pattern-change', () => {
314+
if (!patternlab.isBusy) {
315+
options.cleanPublic = false;
316+
return this.build(options);
317+
}
318+
return Promise.resolve();
319+
});
307320

308-
patternlab.isBusy = false;
321+
this.events.on('patternlab-global-change', () => {
322+
if (!patternlab.isBusy) {
323+
options.cleanPublic = true; //rebuild everything
324+
return this.build(options);
325+
}
326+
return Promise.resolve();
327+
});
328+
329+
patternlab.isBusy = false;
330+
});
309331
});
310332
},
311333

@@ -384,6 +406,7 @@ const patternlab_module = function (config) {
384406
options.watch = true;
385407
return this.build(options).then(function () {
386408
serve(patternlab);
409+
return Promise.resolve();
387410
});
388411
},
389412

core/lib/addPattern.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"use strict";
2+
3+
const _ = require('lodash');
4+
5+
const logger = require('./log');
6+
7+
module.exports = function (pattern, patternlab) {
8+
//add the link to the global object
9+
if (!patternlab.data.link) {
10+
patternlab.data.link = {};
11+
}
12+
patternlab.data.link[pattern.patternPartial] = '/patterns/' + pattern.patternLink;
13+
14+
//only push to array if the array doesn't contain this pattern
15+
var isNew = true;
16+
for (var i = 0; i < patternlab.patterns.length; i++) {
17+
//so we need the identifier to be unique, which patterns[i].relPath is
18+
if (pattern.relPath === patternlab.patterns[i].relPath) {
19+
//if relPath already exists, overwrite that element
20+
patternlab.patterns[i] = pattern;
21+
patternlab.partials[pattern.patternPartial] = pattern.extendedTemplate || pattern.template;
22+
isNew = false;
23+
break;
24+
}
25+
}
26+
27+
// if the pattern is new, we must register it with various data structures!
28+
if (isNew) {
29+
30+
logger.debug(`found new pattern ${pattern.patternPartial}`);
31+
32+
// do global registration
33+
if (pattern.isPattern) {
34+
patternlab.partials[pattern.patternPartial] = pattern.extendedTemplate || pattern.template;
35+
36+
// do plugin-specific registration
37+
pattern.registerPartial();
38+
} else {
39+
patternlab.partials[pattern.patternPartial] = pattern.patternDesc;
40+
}
41+
42+
//patterns sorted by name so the patterntype and patternsubtype is adhered to for menu building
43+
patternlab.patterns.splice(_.sortedIndexBy(patternlab.patterns, pattern, 'name'), 0, pattern);
44+
patternlab.graph.add(pattern);
45+
}
46+
};

core/lib/buildFooter.js

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
"use strict";
2+
3+
const jsonCopy = require('./json_copy');
4+
const logger = require('./log');
5+
const of = require('./object_factory');
6+
const Pattern = of.Pattern;
7+
8+
let render = require('./render'); //eslint-disable-line prefer-const
9+
10+
/**
11+
* Builds footer HTML from the general footer and user-defined footer
12+
* @param patternlab - global data store
13+
* @param patternPartial - the partial key to build this for, either viewall-patternPartial or a viewall-patternType-all
14+
* @returns A promise which resolves with the HTML
15+
*/
16+
module.exports = function (patternlab, patternPartial) {
17+
//first render the general footer
18+
return render(Pattern.createEmpty({extendedTemplate: patternlab.footer}), {
19+
patternData: JSON.stringify({
20+
patternPartial: patternPartial,
21+
}),
22+
cacheBuster: patternlab.cacheBuster
23+
}).then(footerPartial => {
24+
25+
let allFooterData;
26+
try {
27+
allFooterData = jsonCopy(patternlab.data, 'config.paths.source.data plus patterns data');
28+
} catch (err) {
29+
logger.warning('There was an error parsing JSON for patternlab.data');
30+
logger.warning(err);
31+
}
32+
allFooterData.patternLabFoot = footerPartial;
33+
34+
return render(Pattern.createEmpty({extendedTemplate: patternlab.userFoot}), allFooterData);
35+
}).catch(reason => {
36+
console.log(reason);
37+
logger.error('Error building buildFooterHTML');
38+
});
39+
};

core/lib/buildListItems.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"use strict";
2+
3+
const _ = require('lodash');
4+
5+
module.exports = function (container) {
6+
//combine all list items into one structure
7+
var list = [];
8+
for (var item in container.listitems) {
9+
if (container.listitems.hasOwnProperty(item)) {
10+
list.push(container.listitems[item]);
11+
}
12+
}
13+
container.listItemArray = _.shuffle(list);
14+
15+
for (var i = 1; i <= container.listItemArray.length; i++) {
16+
var tempItems = [];
17+
if (i === 1) {
18+
tempItems.push(container.listItemArray[0]);
19+
container.listitems['' + i ] = tempItems;
20+
} else {
21+
for (var c = 1; c <= i; c++) {
22+
tempItems.push(container.listItemArray[c - 1]);
23+
container.listitems['' + i ] = tempItems;
24+
}
25+
}
26+
}
27+
};

0 commit comments

Comments
 (0)