votive 0.2.0 → 0.3.0

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 CHANGED
@@ -1,18 +1,11 @@
1
1
  # Votive
2
2
 
3
- *File processor*
4
-
5
- - Powers [Voot](https://github.com/samlfair/voot)
6
- - Bundles [Vowel](https://github.com/samlfair/vowel)
7
-
8
3
  ## Roadmap
9
4
 
5
+ - [ ] ReadPaths
10
6
  - [ ] Flesh out job runners
11
- - [ ] Rename jobs and paths
12
- - [ ] Better dependency tracking
13
- - [ ] Better query filters
14
- - [x] File deletion handling
7
+ - [ ] Destination query filters
15
8
 
16
- ## Project: Jobs
9
+ ## Helpers
17
10
 
18
- Jobs was originally a generic concept, but after working it's clear that there are two main categories of jobs: async writes and data fetching. We can probably handle async writes with inbuilt logic. So, instead of a "job", we should have "read uri"? That way we can cache all the uris.
11
+ - Read
package/lib/bundle.js CHANGED
@@ -5,8 +5,6 @@ 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"
10
8
 
11
9
  /** @import {Database} from "./createDatabase.js" */
12
10
 
@@ -19,40 +17,17 @@ import { styleText } from "node:util"
19
17
  */
20
18
 
21
19
  /**
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
20
+ * @typedef {object} VotiveProcessor
21
+ * @property {ProcessorFilter} [filter]
22
+ * @property {ProcessorSyntax} syntax
23
+ * @property {ProcessorRead} [read]
24
+ * @property {ProcessorWrite} [write]
50
25
  */
51
26
 
52
27
  /**
53
28
  * Filter for files that the processor will read from.
54
29
  * @typedef {object} ProcessorFilter
55
- * @property {string} extensions
30
+ * @property {string[]} extensions
56
31
  */
57
32
 
58
33
  /**
@@ -81,7 +56,6 @@ import { styleText } from "node:util"
81
56
  * @callback ReadText
82
57
  * @param {string} text
83
58
  * @param {string} filePath
84
- * @param {string} destinationPath
85
59
  * @param {Database} database
86
60
  * @param {VotiveConfig} config
87
61
  * @returns {ReadTextResult | undefined}
@@ -129,11 +103,11 @@ import { styleText } from "node:util"
129
103
  * @param {object} Folder
130
104
  * @param {Database} database
131
105
  * @param {VotiveConfig} config
132
- * @returns {{ jobs?: Jobs, targets?: Target[] }}
106
+ * @returns {{ jobs?: Jobs, destinations?: Destination[] }}
133
107
  */
134
108
 
135
109
  /**
136
- * @typedef {object} Target
110
+ * @typedef {object} Destination
137
111
  * @property {string} path
138
112
  * @property {object} metadata
139
113
  * @property {Abstract} abstract
@@ -170,14 +144,10 @@ import { styleText } from "node:util"
170
144
  * @property {string} [plugin]
171
145
  */
172
146
 
173
- /**
174
- * @typedef {(Pick<path.ParsedPath, "root" | "base" | "ext" | "name") & { dir: string[] | string }} RouteInfo
175
- */
176
-
177
147
  /**
178
148
  * @callback Router
179
- * @param {RouteInfo} path
180
- * @returns {Partial<RouteInfo> | path.ParsedPath | false}
149
+ * @param {string} path
150
+ * @returns {string | false | undefined}
181
151
  */
182
152
 
183
153
  /**
@@ -185,7 +155,6 @@ import { styleText } from "node:util"
185
155
  * @property {string} sourceFolder
186
156
  * @property {string} destinationFolder
187
157
  * @property {VotivePlugin[]} plugins
188
- * @property {boolean} verbose
189
158
  */
190
159
 
191
160
  /**
@@ -208,6 +177,7 @@ async function bundle(config, cache) {
208
177
  const processors = config.plugins
209
178
  && config.plugins.flatMap(plugin => plugin.processors && plugin.processors.map(processor => ({ plugin, processor })))
210
179
 
180
+ // Create database
211
181
  const database = cache || createDatabase(path.join(config.sourceFolder, ".votive.db"))
212
182
 
213
183
  /*
@@ -221,95 +191,32 @@ async function bundle(config, cache) {
221
191
  even out.
222
192
  */
223
193
 
224
- // database.begin()
225
-
226
- const sourceTime = stopwatch("build", "read sources in", config.verbose)
227
194
  // Read folders and source files
228
195
  const { folders, sources } = await readSources(config, database, processors)
229
196
 
230
- console.log(123)
231
- sourceTime()
232
-
233
- if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", `found ${sources.length} stale files`)}`)
234
-
235
- if (sources.length) {
236
- // Map out jobs from source files
237
- const sourcesJobs = sources.flatMap(source => source.jobs) || []
197
+ // Map out jobs from source files
198
+ const sourcesJobs = sources.flatMap(source => source.jobs) || []
238
199
 
239
- // Process source file abstracts and map jobs
240
- const { abstractsJobs } = readAbstracts(sources, config, database, processors)
200
+ // Process source file abstracts and map jobs
201
+ const { abstractsJobs } = readAbstracts(sources, config, database, processors)
241
202
 
242
- // Scan folders and map out jobs
243
- const foldersJobs = readFolders(folders, config, database, processors) || []
203
+ // Scan folders and map out jobs
204
+ const foldersJobs = readFolders(folders, config, database, processors) || []
244
205
 
245
- const writeTime = stopwatch("build", "wrote files in", config.verbose)
246
- // Write destination files
247
- await writeDestinations(config, database)
206
+ // Write destination files
207
+ await writeDestinations(config, database)
248
208
 
249
- writeTime()
250
-
251
- // database.commit()
252
-
253
- await database.saveDB(sources)
254
- }
255
209
  // Run all jobs
256
- // await runJobs([
257
- // ...sourcesJobs,
258
- // ...abstractsJobs,
259
- // ...foldersJobs
260
- // ], config, database)
210
+ await runJobs([
211
+ ...sourcesJobs,
212
+ ...abstractsJobs,
213
+ ...foldersJobs
214
+ ], config, database)
261
215
 
262
216
  // Back up database (only if in-memory first run)
217
+ await database.saveDB()
263
218
 
264
219
  return database
265
220
  }
266
221
 
267
- /**
268
- * @param {VotiveConfig} config
269
- */
270
- async function bundler(config) {
271
- let queue = []
272
- let cache
273
-
274
- async function step() {
275
- if (queue.length === 0) {
276
- if(config.verbose) console.info(`${styleText("dim", "build:")} ${styleText("magenta", "starting build")}`)
277
- /*
278
- If queue is empty, bundle.
279
- */
280
- if (!cache) {
281
- queue.push(bundle(config))
282
- cache = await queue[0]
283
- } else {
284
- "cache"
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
222
+ export default bundle
@@ -0,0 +1,32 @@
1
+ import { readdir, rm } from "node:fs/promises"
2
+ import path from "node:path"
3
+
4
+ /** @import {Abstract, Abstracts, VotiveConfig} from "./bundle.js" */
5
+ /** @import {Database} from "./createDatabase.js" */
6
+
7
+
8
+ /**
9
+ * @param {VotiveConfig} config
10
+ * @param {Database} database
11
+ */
12
+ async function cleanDeletions(config, database) {
13
+ // Must remove from sources first??
14
+ const dirents = new Set((await readdir(config.destinationFolder, {
15
+ recursive: true,
16
+ withFileTypes: true
17
+ })).map(d => d.isFile() && path.relative(config.destinationFolder, path.join(d.parentPath, d.name)))
18
+ .filter(a => a)
19
+ )
20
+
21
+ const targets = new Set(database.target.getAll().map(t => t.path))
22
+
23
+ const deletions = dirents.difference(targets)
24
+
25
+ deletions.forEach(async deletion => {
26
+ const deletionPath = path.join(config.destinationFolder, deletion)
27
+ await rm(deletionPath)
28
+ })
29
+
30
+ }
31
+
32
+ export default cleanDeletions