feat: update project configuration and enhance project manager functionality

This commit is contained in:
xiongxiao
2026-03-13 17:40:03 +08:00
committed by cnb
parent 1b131b3961
commit 24c8b5f923
8 changed files with 53 additions and 14 deletions

4
.npmrc
View File

@@ -1,2 +1,2 @@
//npm.xiongxiao.me/:_authToken=${ME_NPM_TOKEN} //npm.cnb.cool/kevisual/registry/-/packages/:_authToken=${CNB_API_KEY}
//registry.npmjs.org/:_authToken=${NPM_TOKEN} //registry.npmjs.org/:_authToken=${NPM_TOKEN}

View File

@@ -4,9 +4,12 @@
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"dev": "echo \"Error: no test specified\" && exit 1" "build": "bun run bun.config.ts"
}, },
"keywords": [], "keywords": [],
"files": [
"dist"
],
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)", "author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
"license": "MIT", "license": "MIT",
"packageManager": "pnpm@10.32.1", "packageManager": "pnpm@10.32.1",
@@ -26,6 +29,10 @@
"eventemitter3": "^5.0.4" "eventemitter3": "^5.0.4"
}, },
"exports": { "exports": {
".": "./dist/index.js" ".": "./dist/app.js",
"./route": "./dist/app.js"
},
"publishConfig": {
"access": "public"
} }
} }

View File

@@ -6,6 +6,7 @@ import { useKey, useContextKey } from '@kevisual/context';
export const app = useContextKey<App>('app', new App()); export const app = useContextKey<App>('app', new App());
export const manager = useContextKey<ProjectManager>('project-manager', new ProjectManager({ export const manager = useContextKey<ProjectManager>('project-manager', new ProjectManager({
meiliSearchOptions: { meiliSearchOptions: {
apiHost: 'http://localhost:7700',
apiKey: useKey('CNB_TOKEN') apiKey: useKey('CNB_TOKEN')
} }
})); }));

View File

@@ -8,8 +8,10 @@ import './routes/auth';
import './routes/project'; import './routes/project';
import './routes/search'; import './routes/search';
import './routes/file'; import './routes/file';
import { manager } from './app';
if (import.meta.main) { if (import.meta.main) {
// //
} }
await manager.init();

View File

@@ -1,6 +1,6 @@
import { ProjectManagerInterface } from "./user-interface"; import { ProjectManagerInterface } from "./user-interface";
import { ProjectSearch } from "./project-search/index"; import { ProjectSearch } from "./project-search/index";
import { ProjectStore } from "./project-store"; import { ProjectStore, ProjectDoc } from "./project-store";
import { ProjectListener } from "./project-listener/listener"; import { ProjectListener } from "./project-listener/listener";
import { EventEmitter } from "eventemitter3"; import { EventEmitter } from "eventemitter3";
import fs from 'node:fs'; import fs from 'node:fs';
@@ -17,7 +17,15 @@ type Project = {
}; };
export type ProjectInput = Omit<Project, "listener">; export type ProjectInput = Omit<Project, "listener">;
export type ProjectInfo = Omit<Project, "listener"> & { status: "active" | "inactive" }; export type ProjectInfo = Omit<Project, "listener"> & {
status: "active" | "inactive";
id?: string;
title?: string;
tags?: string[];
summary?: string;
description?: string;
link?: string;
};
type ProjectManagerOpt = { type ProjectManagerOpt = {
meiliSearchOptions?: { meiliSearchOptions?: {
@@ -131,16 +139,23 @@ export class ProjectManager implements ProjectManagerInterface {
console.log(`[ProjectManager] stopped: ${projectPath}`); console.log(`[ProjectManager] stopped: ${projectPath}`);
} }
getProjectInfo(project: Project): ProjectInfo { async getProjectInfo(project: Project): Promise<ProjectInfo> {
const { listener, ...info } = project; const { listener, ...info } = project;
const storeDoc: ProjectDoc | null = await this.projectStore.getProject(info.path).catch(() => null);
return { return {
...info, ...info,
status: listener.isWatching ? "active" : "inactive", status: listener.isWatching ? "active" : "inactive",
id: storeDoc?.id,
title: storeDoc?.title,
tags: storeDoc?.tags,
summary: storeDoc?.summary,
description: storeDoc?.description,
link: storeDoc?.link,
}; };
} }
listProjects(): ProjectInfo[] { async listProjects(): Promise<ProjectInfo[]> {
return Array.from(this.projects.values()).map(p => this.getProjectInfo(p)); return Promise.all(Array.from(this.projects.values()).map(p => this.getProjectInfo(p)));
} }
async getFile(filepath: string): Promise<{ filepath: string, content: string; type: string } | null> { async getFile(filepath: string): Promise<{ filepath: string, content: string; type: string } | null> {

View File

@@ -1,6 +1,6 @@
export interface ProjectManagerInterface { export interface ProjectManagerInterface {
removeProject(path: string): void; removeProject(path: string): void;
getProject(path: string): any; getProject(path: string): any;
listProjects(): any[]; listProjects(): any[] | Promise<any[]>;
addProject(project: any): void; addProject(project: any): void;
} }

14
src/remote.ts Normal file
View File

@@ -0,0 +1,14 @@
import { app, manager } from './index'
import { RemoteApp } from '@kevisual/remote-app'
app.createRouteList()
const remote = new RemoteApp({
app,
id: 'project-search',
username: 'root'
});
const isConnect = await remote.isConnect();
if (isConnect) {
console.log('Remote app connected successfully', isConnect);
remote.listenProxy();
}

View File

@@ -104,7 +104,7 @@ app
ctx.throw(404, '项目不存在'); ctx.throw(404, '项目不存在');
return; return;
} }
ctx.body = { success: true, data: manager.getProjectInfo(project) }; ctx.body = { data: await manager.getProjectInfo(project) };
}) })
.addTo(app); .addTo(app);
@@ -119,7 +119,7 @@ app
middleware: ['auth-admin'], middleware: ['auth-admin'],
}) })
.define(async (ctx) => { .define(async (ctx) => {
ctx.body = { list: manager.listProjects() }; ctx.body = { list: await manager.listProjects() };
}) })
.addTo(app); .addTo(app);