UNPKG

3.95 kBJavaScriptView Raw
1const { join } = require('path');
2const { getBlocks } = require('./lib/blocks');
3const getRules = require('./lib/components/competent');
4const { loadComponents, loadElements } = require('./lib/components/load');
5
6const SPLENDID_COMPS = join(__dirname, 'components')
7const SPLENDID_ELS = join(__dirname, 'elements')
8
9/**
10 * @todo Load components/elements on demand.
11 */
12class App {
13 /**
14 * The app holds components, elements and other replacements.
15 * @param {Config} conf
16 */
17 constructor(conf, { splendidComps = true, splendidEls = true } = {}) {
18 this.conf = conf
19 /**
20 * @type {Object<string, ()}}
21 * The hashmap of elements.
22 * Elements are functions for static HTML, not published JS.
23 */
24 this.els = {}
25 /**
26 * @type {Object<string, ()}}
27 * The hashmap of components.
28 */
29 this.comps = {}
30
31 const { appDir, elements, components } = this.conf
32
33 /**
34 * The array of directories with components.
35 * @type {string[]}
36 */
37 this.componentsDirs = []
38 if (splendidComps) this.componentsDirs.push(SPLENDID_COMPS)
39 /**
40 * The array of directories with elements.
41 * @type {string[]}
42 */
43 this.elementsDirs = []
44 if (splendidEls) this.elementsDirs.push(SPLENDID_ELS)
45
46 if (components) {
47 const compDirs = Array.isArray(components) ? components : [components]
48 this.componentsDirs.push(...compDirs.map(el => join(appDir, el)))
49 }
50
51 if (elements) {
52 const elDirs = Array.isArray(elements) ? elements : [elements]
53 this.elementsDirs.push(...elDirs.map(el => join(appDir, el)))
54 }
55
56 /**
57 * Cached layouts.
58 */
59 this.layouts = {}
60 }
61 get compsAndEls() {
62 return { ...this.comps, ...this.els }
63 }
64 _updateReplacements() {
65 const replacements = getRules(this.compsAndEls)
66 /**
67 * The rule for components and elements.
68 */
69 this.replacements = replacements
70 }
71 async updateEls(skipReplacements = false) {
72 const { els, map, loaded } = await this.elementsDirs.reduce(async (acc, dir) => {
73 acc = await acc
74 const { els: e, map: m, loaded: l } = await loadElements(dir)
75 Object.assign(acc.els, e)
76 Object.assign(acc.map, m)
77 Object.assign(acc.loaded, l)
78 return acc
79 }, { els: {}, map: {}, loaded: {} })
80 this.els = els
81 this.elMap = map
82 if (!skipReplacements) this._updateReplacements()
83 return loaded
84 }
85 /**
86 * Reads the components from the given dir.
87 */
88 async updateComps() {
89 const { comps, map, loaded } = await this.componentsDirs.reduce(async (acc, dir) => {
90 acc = await acc
91 const { comps: e, map: m, loaded: l } = await loadComponents(dir, this.els, dir != SPLENDID_COMPS)
92 Object.assign(acc.comps, e)
93 Object.assign(acc.map, m)
94 Object.assign(acc.loaded, l)
95 return acc
96 }, { comps: {}, map: {}, loaded: {} })
97
98 this.comps = comps
99 this.map = map
100
101 this._updateReplacements()
102 return loaded
103 }
104 async updateBlocks() {
105 const { blocks, appDir } = this.conf
106 if (!blocks) { this.blocks = []; return }
107 const b = Array.isArray(blocks) ? blocks : [blocks]
108 const bb = await Promise.all(b.map(async (path) => {
109 const block = await getBlocks(appDir, path)
110 return block
111 }))
112 this.blocks = bb
113 }
114 async init() {
115 await this.updateEls(true)
116 await this.updateComps()
117 await this.updateBlocks()
118 const {
119 replacements: regexReplacements = [],
120 } = this.conf
121 const areaReplacements = [
122 ...this.blocks,
123 ...regexReplacements,
124 ]
125 // const replacements = [
126 // ...compsReplacements,
127 // ...elsReplacements,
128 // {
129 // re: /[\s\S]+/,
130 // replacement(m) {
131 // debugger
132 // return m
133 // },
134 // },
135 // ]
136 this.areaReplacements = areaReplacements
137 }
138}
139
140/**
141 * @typedef {import('splendid').Config} Config
142 * @typedef {import('splendid').Page} Page
143 */
144
145module.exports = App
\No newline at end of file