UNPKG

7.21 kBJavaScriptView Raw
1const
2 path = require('path'),
3 FakeDataLoader = require('./dataLoader/FakeDataLoader'),
4 sgUtil = require('./util');
5
6class CollectorStore {
7 constructor({conf}) {
8 this.globOptions = conf.get('globOptions');
9 this.htmlExt = conf.get('htmlExt');
10 this.dataExt = conf.get('dataExt');
11 this.c = conf.get('logLevel', 0);
12 this.sectionOrder = conf.get('sections').map(({title}) => title);
13
14 this.sections = new Map();
15 this.files = new Map();
16
17 this.setSection = this.setSection.bind(this);
18 this.setFile = this.setFile.bind(this);
19 this.unsetFile = this.unsetFile.bind(this);
20 this.updateTimestamp = this.updateTimestamp.bind(this);
21 this.setGroupedFile = this.setGroupedFile.bind(this);
22 this.unsetGroupedFile = this.unsetGroupedFile.bind(this);
23 this.getSection = this.getSection.bind(this);
24 this.getFiles = this.getFiles.bind(this);
25 this.getSections = this.getSections.bind(this);
26 this.getSectionFilesData = this.getSectionFilesData.bind(this);
27 this.getUrls = this.getUrls.bind(this);
28 this.getCollectedData = this.getCollectedData.bind(this);
29 }
30
31 static getGroupPaths(filename, url = false) {
32 const {dir, name} = path.parse(filename);
33 const parentName = path.basename(dir);
34 const base = `${dir}/${parentName}`;
35 const groupUrl = url ? `${url.dirname}/${parentName}${url.extname}` : null;
36
37 return {
38 base,
39 groupUrl,
40 name,
41 parentName
42 };
43 }
44
45 static getPageTitle(filename, title, name, parentName) {
46 return (name === 'index' || name === parentName) ? title : sgUtil.getTitleFromFoldername(filename);
47 }
48
49 getCollectedData() {
50 return [...this.getSections().values()]
51 .map(section => {
52
53 const needsUpdate = section.getFiles()
54 .filter(({exclude}) => !exclude)
55 .some(({timestamp, _data = {}}) => !section._timestamp || !timestamp || !_data.timestamp || timestamp > section._timestamp || _data.timestamp > section._timestamp);
56
57 if (needsUpdate) {
58 section._files = this.getSectionFilesData(section);
59 section._timestamp = Date.now();
60 sgUtil.log(`Section: \u001b[1m${section.title} (${section._files.length})\u001b[22m collected.`, 'info');
61 }
62
63 return {
64 files: section._files,
65 collector: section.collector,
66 route: section.route,
67 title: section.title,
68 url: section.url
69 };
70 }).sort((a, b) => {
71 return this.sectionOrder.indexOf(a.title) - this.sectionOrder.indexOf(b.title);
72 });
73 }
74
75 getFile(filename) {
76 return this.files.get(sgUtil.removeFileExtension(filename));
77 }
78
79 getFiles() {
80 return this.files;
81 }
82
83 getFilesOfSection() {
84 const {files, destDir} = this;
85 return [...files.values()].filter(file => destDir === file.destDir);
86 }
87
88 getSection(destDir) {
89 const {sections} = this;
90
91 return sections.get(destDir);
92 }
93
94 getSectionFilesData({getFiles}) {
95 const {htmlExt, dataExt} = this;
96 const files = getFiles();
97
98 return getFiles()
99 .filter(({exclude}) => !exclude)
100 .map(({filename, title, componentName, collector, orderValue, url, sectionPath, exclude}) => {
101
102 if (this.logLevel > 2) {
103 sgUtil.log(`Get Section Files Data: \u001b[1m${componentName}\u001b[22m added.`);
104 }
105
106 const asyncContentUrls = {
107 source: sgUtil.replaceFileExtension(url, `source.${htmlExt}`),
108 locals: sgUtil.replaceFileExtension(url, dataExt),
109 schema: sgUtil.replaceFileExtension(url, `schema.${dataExt}`)
110 };
111
112 files
113 .filter((file) => file.componentName.indexOf(`${componentName}\.`) !== -1)
114 .map(({componentName, url}) => {
115 const [, type] = componentName.split('.');
116 asyncContentUrls[type] = sgUtil.replaceFileExtension(url, `source.${htmlExt}`);
117 });
118
119 return {
120 title,
121 filename,
122 componentName,
123 collector,
124 url,
125 exclude,
126 orderValue,
127 path: sectionPath,
128 asyncContentUrls,
129 dirname: path.dirname(filename)
130 };
131 });
132 }
133
134 getSections() {
135 return this.sections;
136 }
137
138 getUrls() {
139 const urls = new Map();
140
141 this.files.forEach(file => urls.set(sgUtil.removeFileExtension(file.url), file));
142 return urls;
143 }
144
145 setFile(file) {
146 this.files.set(sgUtil.removeFileExtension(file.filename), file);
147 file.copySource();
148 return file;
149 }
150
151 setGroupedFile(file) {
152 const
153 {urls, files, constructor} = this,
154 {getGroupPaths, getPageTitle} = constructor,
155 {filename, url, collector, title, destDir, orderValue} = file,
156 {base, groupUrl, name, parentName} = getGroupPaths(filename, url),
157 pageTitle = file.pageTitle = getPageTitle(filename, title, name, parentName);
158
159 if (name === 'index' || name === parentName || !urls.get(base)) {
160 urls.set(base, {
161 url: groupUrl,
162 title: pageTitle,
163 collector,
164 destDir,
165 orderValue
166 });
167 }
168
169 if (files.get(groupUrl) === undefined) {
170 files.set(groupUrl, new Map());
171 }
172 files.get(groupUrl).set(name, file);
173
174 return files.get(groupUrl);
175 }
176
177 setSection(section) {
178 const {sections, files, constructor, getFilesOfSection} = this;
179 const {destDir} = section;
180
181 section.getFiles = getFilesOfSection.bind({
182 destDir,
183 files,
184 constructor
185 });
186
187 sections.set(destDir, section);
188 }
189
190 unsetFile(filename) {
191 this.updateTimestamp(filename);
192 this.files.delete(sgUtil.removeFileExtension(filename));
193 }
194
195 unsetGroupedFile(filename) {
196 const
197 {constructor, urls, files} = this,
198 {base, name} = constructor.getGroupPaths(filename);
199
200 files.get(filename).delete(name);
201
202 const {size = 0} = files.get(filename);
203
204 if (size === 0) {
205 urls.delete(base);
206 files.delete(filename);
207 }
208 }
209
210 updateFile(filename) {
211 const {copySource} = this.getFile(filename) || {};
212 if (copySource) {
213 copySource();
214 }
215 }
216
217 updateTimestamp(filename, newTimestamp = Date.now()) {
218 const file = this.getFile(filename) || this.getFile(`${path.dirname(filename)}/_${path.basename(filename)}`);
219 const {componentName, timestamp, parentComponents} = file || {};
220
221 if (!componentName) {
222 if (this.logLevel > 2) {
223 sgUtil.log(`Update Timestamp: no file object for filename ${filename}`, 'warn');
224 }
225 return false;
226 }
227
228 if (timestamp === newTimestamp) {
229 if (this.logLevel > 3) {
230 sgUtil.log(`Update Timestamp: ${componentName} was already updated`, 'notice');
231 }
232
233 return false;
234 }
235
236 file.timestamp = newTimestamp;
237
238 if (this.logLevel > 3) {
239 sgUtil.log(`Update Timestamp: ${componentName} updated`, 'info');
240 }
241
242 if (FakeDataLoader.getCache()[componentName]) {
243 delete FakeDataLoader.getCache()[componentName];
244 }
245
246 if (file._data) {
247 file._data.timestamp = 0;
248 }
249
250 return parentComponents.reduce((carry, {filename}) => {
251 return carry.concat(this.updateTimestamp(filename, newTimestamp) || []);
252 }, [componentName]);
253 }
254}
255
256module.exports = CollectorStore;