-
-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathIndexingEngine.ts
More file actions
106 lines (87 loc) · 2.39 KB
/
IndexingEngine.ts
File metadata and controls
106 lines (87 loc) · 2.39 KB
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import { VaultAdapter } from "./adapters/VaultAdapter"
import { EmbeddingAdapter } from "./adapters/EmbeddingAdapter"
import { IndexStore } from "./adapters/IndexStore"
import { NoteChunker } from "./NoteChunker"
import { IndexQueue } from "./IndexQueue"
import { IndexResult, IndexJob } from "./types"
/**
* Coordinates the incremental indexing pipeline.
*/
export class IndexingEngine {
private vault: VaultAdapter
private embedder: EmbeddingAdapter
private store: IndexStore
private chunker: NoteChunker
private queue: IndexQueue
constructor(
vault: VaultAdapter,
embedder: EmbeddingAdapter,
store: IndexStore
) {
this.vault = vault
this.embedder = embedder
this.store = store
this.chunker = new NoteChunker()
this.queue = new IndexQueue()
}
/**
* Schedule indexing for a note.
*/
scheduleUpdate(notePath: string): Promise<void> {
const job: IndexJob = {
type: "update",
notePath,
}
this.queue.enqueue(job)
return this.queue.process(this.processJob.bind(this))
}
/**
* Schedule deletion of a note from the index.
*/
scheduleDelete(notePath: string): Promise<void> {
const job: IndexJob = {
type: "delete",
notePath,
}
this.queue.enqueue(job)
return this.queue.process(this.processJob.bind(this))
}
/**
* Process jobs coming from the queue.
*/
private async processJob(job: IndexJob) {
if (job.type === "update") {
await this.indexNote(job.notePath)
}
if (job.type === "delete") {
await this.removeNote(job.notePath)
}
}
/**
* Full indexing pipeline for a note.
*/
private async indexNote(notePath: string): Promise<IndexResult> {
const markdown = await this.vault.readNote(notePath)
const chunks = this.chunker.split(notePath, markdown)
const chunkTexts = chunks.map((c) => c.text)
const embeddings = await this.embedder.embed(chunkTexts)
if (embeddings.length !== chunks.length) {
throw new Error(
`Embedding adapter returned ${embeddings.length} embeddings for ${chunks.length} chunks`
)
}
const result: IndexResult = {
notePath,
chunks,
embeddings,
}
await this.store.saveChunks(notePath, chunks, embeddings)
return result
}
/**
* Remove a note from the index.
*/
private async removeNote(notePath: string) {
await this.store.deleteNote(notePath)
}
}