Skip to content

Commit ee85095

Browse files
committed
多知识库结构初步
1 parent bf2dd62 commit ee85095

File tree

3 files changed

+104
-78
lines changed

3 files changed

+104
-78
lines changed

packages/core/src/DocBase.ts

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -256,20 +256,7 @@ export class DocBase {
256256

257257
// 初始化监视器扫描器
258258
console.info("Initializing watcher and scanner...");
259-
const { watcher, scanner } = FSLayer({
260-
filter: (path: string) => {
261-
const ext = getExtFromPath(path);
262-
return this.#docExtToLoaderName.has(ext);
263-
},
264-
upsert: (path: string) => {
265-
this.#watcherTaskCache.set(path, "upsert");
266-
this.#doWatcherTask();
267-
},
268-
remove: (path: string) => {
269-
this.#watcherTaskCache.set(path, "remove");
270-
this.#doWatcherTask();
271-
},
272-
});
259+
const { watcher, scanner } = FSLayer();
273260
this.#docWatcher = watcher;
274261
this.#docScanner = scanner;
275262
console.info("Watcher and scanner initialized successfully.");
@@ -278,43 +265,63 @@ export class DocBase {
278265
console.info("Initializing DocManager...");
279266
const docLoader = (input: DocLoaderInput) => this.#hyperDocLoader(input)
280267
const docSplitter = (content: AsyncIterable<Content>) => this.#docSplitter.func(content)
268+
const filter = (path: string) => {
269+
const ext = getExtFromPath(path);
270+
return this.#docExtToLoaderName.has(ext);
271+
}
281272
const base = await db.base.get()
282273

283-
base.map(async ({ path, id }) => {
284-
const docm = new DocManager({
285-
indexPrefix: id,
286-
meiliSearch: this.#meiliSearch,
287-
docLoader,
288-
docSplitter,
289-
});
290-
await docm.init()
291-
// 扫描目录
292-
await this.#scan([path]);
293-
// 监视目录
294-
this.#docWatcher.watch(path)
295-
return docm
296-
})
297-
console.info("DocManager initialized successfully.");
298-
299-
// 扫描加载默认目录下文档
300-
// console.info("Scanning initial directories...");
301-
// console.info("Initial directories scanned successfully.");
302-
303-
// 开启监视,同步变动文档
304-
// console.info("Starting to watch directories...");
305-
// initPaths.map((initPath) => this.#docWatcher.watch(initPath));
306-
// console.info("Directories are being watched.");
274+
const result = await Promise.allSettled(
275+
base.map(async ({ path, id }) => {
276+
console.info(`Init base ${id}...`);
277+
const docm = new DocManager({
278+
indexPrefix: id,
279+
meiliSearch: this.#meiliSearch,
280+
docLoader,
281+
docSplitter,
282+
});
283+
await docm.init()
284+
this.#docManagers.set(id, docm)
285+
console.info(`Base ${id} init successfully.`);
286+
287+
// 扫描目录
288+
console.info(`Scanning base ${id}...`);
289+
await this.#scan(id, [path]);
290+
console.info(`Base ${id} scanned successfully.`);
291+
292+
// 监视目录
293+
this.#docWatcher.watch(path, {
294+
filter,
295+
upsert: (path: string) => {
296+
this.#watcherTaskCache.set(path, { docManagerId: id, type: "upsert" });
297+
this.#doWatcherTask();
298+
},
299+
remove: (path: string) => {
300+
this.#watcherTaskCache.set(path, { docManagerId: id, type: "remove" });
301+
this.#doWatcherTask();
302+
},
303+
})
304+
console.info(`Base ${id} directories are being watched.`);
305+
})
306+
)
307+
308+
// TODO 打印表格
309+
console.info("DocManager initialized successfully.", result);
310+
307311
console.info("DocBase started successfully.");
308312
};
309313

314+
// TODO 新安装插件立即扫描所有目录
310315
/**
311316
* 立即扫描所有目录
312317
*/
313-
scanAllNow = async (id: string) => {
314-
console.info("Starting to scan all directories immediately...");
315-
await this.#scan(this.dirs);
316-
console.info("All directories scanned immediately.");
317-
};
318+
// scanAllNow = async (id: string) => {
319+
// console.info("Starting to scan all directories immediately...");
320+
// await this.#scan(id, this.dirs);
321+
// console.info("All directories scanned immediately.");
322+
// };
323+
324+
// TODO 增加、删除、查询 知识库
318325

319326
/**
320327
* 卸载文档加载器插件
@@ -463,7 +470,8 @@ export class DocBase {
463470
knowledgeId: string;
464471
}) => {
465472
console.info(`Searching for documents with query: ${params.q}`);
466-
const results = await this.#docManager.search(query, opt);
473+
const docManager = this.#docManagers.get(params.knowledgeId)
474+
const results = await docManager.search(params);
467475
console.info(`Search completed. Found ${results.length} documents.`);
468476
return results;
469477
};

packages/core/src/DocManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,9 +550,9 @@ export class DocManager {
550550
* @param hybrid - 启用向量搜索
551551
* @returns 返回搜索结果
552552
*/
553-
search = async (query: string, opts?: SearchParams) => {
554-
console.debug(`Searching for query: ${query}`);
555-
const result = await this.#docChunkIndex.search(query, opts);
553+
search = async (opts: SearchParams) => {
554+
console.debug(`Searching for query: ${opts.q}`);
555+
const result = await this.#docChunkIndex.search(opts.q, opts);
556556
const hits = result.hits;
557557

558558
// 查询后校验结果中引用到的本地文档是否存在,不存在则删除知识库内文档

packages/core/src/FSlayer.ts

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,48 @@ export type Scanner = (params: {
1515
load: (paths: string[]) => Promise<void>;
1616
}) => Promise<void>;
1717

18-
// 监视器
19-
export type Watcher = Pick<
20-
DirectoryWatcher,
21-
"getWatchedPaths" | "unwatch" | "watch"
22-
>;
23-
24-
export const FSLayer = ({
25-
filter,
26-
upsert,
27-
remove,
28-
}: {
18+
interface WatchAction {
2919
filter: (path: string) => boolean;
3020
upsert: (path: string) => void;
3121
remove: (path: string) => void;
32-
}) => {
22+
}
23+
24+
// 监视器
25+
export type Watcher = {
26+
getWatchedPaths: () => string[];
27+
unwatch: (path: string) => boolean;
28+
watch: (path: string, actions: WatchAction) => void;
29+
}
30+
31+
/**
32+
* 文件系统监视勾子
33+
* @param event
34+
* @param actions
35+
*/
36+
const eventHook = (event: string, actions: WatchAction) => {
37+
const { filter, upsert, remove } = actions
38+
try {
39+
const e = JSON.parse(event);
40+
const type = e.event.type;
41+
const path = e.event.paths[0];
42+
43+
// 过滤需要的路径
44+
if (filter(path)) {
45+
console.info(`[${type}] ${path}`);
46+
if (type === "create" || type === "modify") {
47+
upsert(slash(path));
48+
} else if (type === "remove") {
49+
remove(slash(path));
50+
}
51+
}
52+
} catch (parseError) {
53+
console.error(`Error parsing event data: ${parseError}`);
54+
}
55+
}
56+
57+
export const FSLayer = () => {
3358
const fd = new fdir().withBasePath();
59+
const watchers = new Map<string, Watcher>();
3460

3561
// 扫描器
3662
const scanner: Scanner = async ({ dirs, exts, load }) => {
@@ -48,26 +74,18 @@ export const FSLayer = ({
4874
}
4975
};
5076

51-
// 监视器
52-
const watcher: DirectoryWatcher = DirectoryWatcher.new((_err, event) => {
53-
try {
54-
const e = JSON.parse(event);
55-
const type = e.event.type;
56-
const path = e.event.paths[0];
57-
58-
// 过滤需要的路径
59-
if (filter(path)) {
60-
console.info(`[${type}] ${path}`);
61-
if (type === "create" || type === "modify") {
62-
upsert(slash(path));
63-
} else if (type === "remove") {
64-
remove(slash(path));
65-
}
66-
}
67-
} catch (parseError) {
68-
console.error(`Error parsing event data: ${parseError}`);
77+
const watcher = {
78+
getWatchedPaths: () => watchers.keys().toArray(),
79+
unwatch: (path: string) => {
80+
watchers.get(path)?.unwatch(path)
81+
return watchers.delete(path)
82+
},
83+
watch: (path: string, actions: WatchAction) => {
84+
const watcher = DirectoryWatcher.new((_err, event) => eventHook(event, actions));
85+
watcher.watch(path);
86+
watchers.set(path, watcher)
6987
}
70-
});
88+
}
7189

7290
return { watcher, scanner };
7391
};

0 commit comments

Comments
 (0)