votive 0.3.0 → 0.3.1

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/lib/bundle.js CHANGED
@@ -5,6 +5,8 @@ import readSources from "./readSources.js"
5
5
  import runJobs from "./runJobs.js"
6
6
  import writeDestinations from "./writeDestinations.js"
7
7
  import { default as createDatabase } from "./createDatabase.js"
8
+ import { stopwatch } from "./utils/index.js"
9
+ import { styleText } from "node:util"
8
10
 
9
11
  /** @import {Database} from "./createDatabase.js" */
10
12
 
@@ -17,17 +19,40 @@ import { default as createDatabase } from "./createDatabase.js"
17
19
  */
18
20
 
19
21
  /**
20
- * @typedef {object} VotiveProcessor
21
- * @property {ProcessorFilter} [filter]
22
- * @property {ProcessorSyntax} syntax
23
- * @property {ProcessorRead} [read]
24
- * @property {ProcessorWrite} [write]
22
+ * @typedef {object} VotiveProcessorCommon
23
+ * @property {string[]} extensions
24
+ * @property {ReadResource} [readResource]
25
+ * @property {ProcessorWrite} [writeFile]
26
+ * @property {ReadFolder} [readFolder]
27
+ * @property {ReadAbstract} [transformFile]
28
+ */
29
+
30
+ /**
31
+ * @typedef {VotiveProcessorCommon & {
32
+ * format: "buffer",
33
+ * readFile: ReadPath | undefined
34
+ * }} VotiveProcessorBuffer
35
+ */
36
+
37
+ /**
38
+ * @typedef {VotiveProcessorCommon & {
39
+ * format: "text",
40
+ * readFile: ReadText | undefined
41
+ * }} VotiveProcessorText
42
+ */
43
+
44
+ /**
45
+ * @typedef {VotiveProcessorBuffer | VotiveProcessorText} VotiveProcessor
46
+ */
47
+
48
+ /**
49
+ * @typedef {object} ReadResource
25
50
  */
26
51
 
27
52
  /**
28
53
  * Filter for files that the processor will read from.
29
54
  * @typedef {object} ProcessorFilter
30
- * @property {string[]} extensions
55
+ * @property {string} extensions
31
56
  */
32
57
 
33
58
  /**
@@ -56,6 +81,7 @@ import { default as createDatabase } from "./createDatabase.js"
56
81
  * @callback ReadText
57
82
  * @param {string} text
58
83
  * @param {string} filePath
84
+ * @param {string} destinationPath
59
85
  * @param {Database} database
60
86
  * @param {VotiveConfig} config
61
87
  * @returns {ReadTextResult | undefined}
@@ -103,11 +129,11 @@ import { default as createDatabase } from "./createDatabase.js"
103
129
  * @param {object} Folder
104
130
  * @param {Database} database
105
131
  * @param {VotiveConfig} config
106
- * @returns {{ jobs?: Jobs, destinations?: Destination[] }}
132
+ * @returns {{ jobs?: Jobs, targets?: Target[] }}
107
133
  */
108
134
 
109
135
  /**
110
- * @typedef {object} Destination
136
+ * @typedef {object} Target
111
137
  * @property {string} path
112
138
  * @property {object} metadata
113
139
  * @property {Abstract} abstract
@@ -144,10 +170,14 @@ import { default as createDatabase } from "./createDatabase.js"
144
170
  * @property {string} [plugin]
145
171
  */
146
172
 
173
+ /**
174
+ * @typedef {(Pick<path.ParsedPath, "root" | "base" | "ext" | "name") & { dir: string[] | string }} RouteInfo
175
+ */
176
+
147
177
  /**
148
178
  * @callback Router
149
- * @param {string} path
150
- * @returns {string | false | undefined}
179
+ * @param {RouteInfo} path
180
+ * @returns {Partial<RouteInfo> | path.ParsedPath | false}
151
181
  */
152
182
 
153
183
  /**
@@ -155,6 +185,7 @@ import { default as createDatabase } from "./createDatabase.js"
155
185
  * @property {string} sourceFolder
156
186
  * @property {string} destinationFolder
157
187
  * @property {VotivePlugin[]} plugins
188
+ * @property {boolean} verbose
158
189
  */
159
190
 
160
191
  /**
@@ -177,7 +208,6 @@ async function bundle(config, cache) {
177
208
  const processors = config.plugins
178
209
  && config.plugins.flatMap(plugin => plugin.processors && plugin.processors.map(processor => ({ plugin, processor })))
179
210
 
180
- // Create database
181
211
  const database = cache || createDatabase(path.join(config.sourceFolder, ".votive.db"))
182
212
 
183
213
  /*
@@ -191,32 +221,95 @@ async function bundle(config, cache) {
191
221
  even out.
192
222
  */
193
223
 
224
+ // database.begin()
225
+
226
+ const sourceTime = stopwatch("build", "read sources in", config.verbose)
194
227
  // Read folders and source files
195
228
  const { folders, sources } = await readSources(config, database, processors)
196
229
 
197
- // Map out jobs from source files
198
- const sourcesJobs = sources.flatMap(source => source.jobs) || []
230
+ sourceTime()
231
+
232
+ if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", `found ${sources.length} stale files`)}`)
233
+
234
+ if (sources.length) {
235
+ // Map out jobs from source files
236
+ const sourcesJobs = sources.flatMap(source => source.jobs) || []
237
+
238
+ // Process source file abstracts and map jobs
239
+ const { abstractsJobs } = readAbstracts(sources, config, database, processors)
199
240
 
200
- // Process source file abstracts and map jobs
201
- const { abstractsJobs } = readAbstracts(sources, config, database, processors)
241
+ // Scan folders and map out jobs
242
+ const foldersJobs = readFolders(folders, config, database, processors) || []
202
243
 
203
- // Scan folders and map out jobs
204
- const foldersJobs = readFolders(folders, config, database, processors) || []
244
+ const writeTime = stopwatch("build", "wrote files in", config.verbose)
245
+ // Write destination files
246
+ await writeDestinations(config, database)
205
247
 
206
- // Write destination files
207
- await writeDestinations(config, database)
248
+ const stale = database.target.getStale()
208
249
 
250
+ writeTime()
251
+
252
+ // database.commit()
253
+
254
+ await database.saveDB(sources)
255
+ }
209
256
  // Run all jobs
210
- await runJobs([
211
- ...sourcesJobs,
212
- ...abstractsJobs,
213
- ...foldersJobs
214
- ], config, database)
257
+ // await runJobs([
258
+ // ...sourcesJobs,
259
+ // ...abstractsJobs,
260
+ // ...foldersJobs
261
+ // ], config, database)
215
262
 
216
263
  // Back up database (only if in-memory first run)
217
- await database.saveDB()
218
264
 
219
265
  return database
220
266
  }
221
267
 
222
- export default bundle
268
+ /**
269
+ * @param {VotiveConfig} config
270
+ */
271
+ async function bundler(config) {
272
+ let queue = []
273
+ let cache
274
+
275
+ async function step() {
276
+ if (queue.length === 0) {
277
+ if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", "starting build")}`)
278
+ /*
279
+ If queue is empty, bundle.
280
+ */
281
+ if (!cache) {
282
+ queue.push(bundle(config))
283
+ cache = await queue[0]
284
+ } else {
285
+ queue.push(bundle(config, cache))
286
+ await queue[0]
287
+ }
288
+ queue.shift()
289
+ return cache
290
+ } else if (queue.length === 1) {
291
+ /*
292
+ If currently bundling, prepare another
293
+ bundle as cleanup.
294
+ */
295
+ if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", "queueing build")}`)
296
+
297
+ let bundling
298
+ queue.push(bundling)
299
+ bundling = await bundle(config, cache)
300
+ queue.shift()
301
+ return cache
302
+ } else {
303
+ /*
304
+ If cleanup is already queued, do nothing.
305
+ */
306
+ if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", "already queued")}`)
307
+ await Promise.all(queue)
308
+ return cache
309
+ }
310
+ }
311
+
312
+ return step
313
+ }
314
+
315
+ export default bundler