-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch_index_pipeline.js
67 lines (55 loc) · 1.99 KB
/
search_index_pipeline.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import { readSync } from "to-vfile"
import { createRetextPipeline, logger, toSlug } from "./unify_pipelines.js"
import { saveJSON } from "./note_preprocessor.js"
import path from 'path';
export class SearchIndexPipeline {
constructor(config) {
this.config = config
this.retextPipepline = createRetextPipeline({ noteRoot: config.noteRoot })
this.index = new Map()
}
async on(events, previousResults) {
const indexPromises = []
for (const { eventType, targetPath } of events) {
if (eventType === 'add' || eventType === 'change') {
//'content' is changed almost always, therefore, re-indexing makes
//sense
indexPromises.push(this.indexNote(targetPath))
} else if (eventType == 'unlink') {
const slug = toSlug(targetPath)
this.unindexNote(slug)
}
}
await Promise.all(indexPromises)
// We can rebuild the index as a whole or just incrementally change it:
// - if note is changed, retrieve its index, insert different object
// instead of it
// - if note is deleted, insert null instead of it, when # of nulls
// reaches half of the index, we rebuild it, amortized cost is still
// O(1)
//
// Incremental updates would make sense in case of a large index. But we
// still will change the file, requiring sveltekit to reload it and read it
// whole again, so it might not make sense even for large indices.
await this.generateIndex()
return previousResults
}
async indexNote(notePath) {
const file = await this.retextPipepline.process(readSync(notePath))
const slug = file.data.slug
this.index.set(slug, {
slug,
title: file.data.title,
content: file.value,
matter: { ...file.data.matter },
})
}
unindexNote(slug) {
this.index.delete(slug)
}
async generateIndex() {
const index = [...this.index.values()]
const indexPath = path.join(this.config.savePath, '__search.json')
await saveJSON(indexPath, index)
}
}