preflight-mcp 0.1.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 +208 -0
- package/README.zh-CN.md +406 -0
- package/dist/bundle/analysis.js +91 -0
- package/dist/bundle/context7.js +301 -0
- package/dist/bundle/deepwiki.js +206 -0
- package/dist/bundle/facts.js +296 -0
- package/dist/bundle/github.js +55 -0
- package/dist/bundle/guides.js +65 -0
- package/dist/bundle/ingest.js +152 -0
- package/dist/bundle/manifest.js +14 -0
- package/dist/bundle/overview.js +222 -0
- package/dist/bundle/paths.js +29 -0
- package/dist/bundle/service.js +803 -0
- package/dist/bundle/tagging.js +206 -0
- package/dist/config.js +65 -0
- package/dist/context7/client.js +30 -0
- package/dist/context7/tools.js +58 -0
- package/dist/core/scheduler.js +166 -0
- package/dist/errors.js +150 -0
- package/dist/index.js +7 -0
- package/dist/jobs/bundle-auto-update-job.js +71 -0
- package/dist/jobs/health-check-job.js +172 -0
- package/dist/jobs/storage-cleanup-job.js +148 -0
- package/dist/logging/logger.js +311 -0
- package/dist/mcp/uris.js +45 -0
- package/dist/search/sqliteFts.js +481 -0
- package/dist/server/optimized-server.js +255 -0
- package/dist/server.js +778 -0
- package/dist/storage/compression.js +249 -0
- package/dist/storage/storage-adapter.js +316 -0
- package/dist/utils/index.js +100 -0
- package/package.json +44 -0
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import { PreflightScheduler } from '../core/scheduler.js';
|
|
2
|
+
import { BundleAutoUpdateJob } from '../jobs/bundle-auto-update-job.js';
|
|
3
|
+
import { StorageCleanupJob } from '../jobs/storage-cleanup-job.js';
|
|
4
|
+
import { HealthCheckJob } from '../jobs/health-check-job.js';
|
|
5
|
+
import { getStorageManager } from '../storage/storage-adapter.js';
|
|
6
|
+
import { compressData, decompressData, detectCompressionType } from '../storage/compression.js';
|
|
7
|
+
import { logger, createModuleLogger } from '../logging/logger.js';
|
|
8
|
+
import { getConfig } from '../config.js';
|
|
9
|
+
const moduleLogger = createModuleLogger('OptimizedServer');
|
|
10
|
+
export class OptimizedPreflightServer {
|
|
11
|
+
isInitialized = false;
|
|
12
|
+
isRunning = false;
|
|
13
|
+
async initialize() {
|
|
14
|
+
if (this.isInitialized) {
|
|
15
|
+
moduleLogger.warn('Server already initialized');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
moduleLogger.info('Initializing optimized preflight server...');
|
|
20
|
+
// 初始化存储管理器
|
|
21
|
+
const config = getConfig();
|
|
22
|
+
const storageManager = getStorageManager(config);
|
|
23
|
+
moduleLogger.info('Storage manager initialized', {
|
|
24
|
+
adapters: storageManager.listAdapters().length
|
|
25
|
+
});
|
|
26
|
+
// 设置定时任务
|
|
27
|
+
await this.setupScheduledJobs();
|
|
28
|
+
// 执行初始健康检查
|
|
29
|
+
await this.performInitialHealthCheck();
|
|
30
|
+
this.isInitialized = true;
|
|
31
|
+
moduleLogger.info('Optimized preflight server initialized successfully');
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
moduleLogger.error('Failed to initialize optimized server', error instanceof Error ? error : new Error(String(error)));
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async start() {
|
|
39
|
+
if (!this.isInitialized) {
|
|
40
|
+
await this.initialize();
|
|
41
|
+
}
|
|
42
|
+
if (this.isRunning) {
|
|
43
|
+
moduleLogger.warn('Server already running');
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
try {
|
|
47
|
+
moduleLogger.info('Starting optimized preflight server...');
|
|
48
|
+
// 启动调度器
|
|
49
|
+
await PreflightScheduler.start();
|
|
50
|
+
this.isRunning = true;
|
|
51
|
+
moduleLogger.info('Optimized preflight server started successfully');
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
moduleLogger.error('Failed to start optimized server', error instanceof Error ? error : new Error(String(error)));
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async stop() {
|
|
59
|
+
if (!this.isRunning) {
|
|
60
|
+
moduleLogger.warn('Server not running');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
moduleLogger.info('Stopping optimized preflight server...');
|
|
65
|
+
// 停止调度器
|
|
66
|
+
await PreflightScheduler.stop();
|
|
67
|
+
// 刷新日志
|
|
68
|
+
await logger.flush();
|
|
69
|
+
this.isRunning = false;
|
|
70
|
+
moduleLogger.info('Optimized preflight server stopped successfully');
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
moduleLogger.error('Failed to stop optimized server', error instanceof Error ? error : new Error(String(error)));
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
async setupScheduledJobs() {
|
|
78
|
+
moduleLogger.info('Setting up scheduled jobs...');
|
|
79
|
+
// Bundle 自动更新任务 - 每小时检查一次
|
|
80
|
+
PreflightScheduler.build(BundleAutoUpdateJob).schedule('0 * * * *');
|
|
81
|
+
moduleLogger.info('Bundle auto-update job scheduled (hourly)');
|
|
82
|
+
// 存储清理任务 - 每天凌晨2点执行
|
|
83
|
+
PreflightScheduler.build(StorageCleanupJob).schedule('0 2 * * *');
|
|
84
|
+
moduleLogger.info('Storage cleanup job scheduled (daily at 2 AM)');
|
|
85
|
+
// 健康检查任务 - 每30分钟执行一次
|
|
86
|
+
PreflightScheduler.build(HealthCheckJob).schedule('*/30 * * * *');
|
|
87
|
+
moduleLogger.info('Health check job scheduled (every 30 minutes)');
|
|
88
|
+
moduleLogger.info('All scheduled jobs configured', {
|
|
89
|
+
totalJobs: PreflightScheduler.getAllJobsStatus()
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async performInitialHealthCheck() {
|
|
93
|
+
moduleLogger.info('Performing initial health check...');
|
|
94
|
+
try {
|
|
95
|
+
const healthJob = new HealthCheckJob();
|
|
96
|
+
const healthResult = await healthJob.run();
|
|
97
|
+
if (healthResult.status === 'error') {
|
|
98
|
+
moduleLogger.warn('Initial health check revealed issues', {
|
|
99
|
+
status: healthResult.status,
|
|
100
|
+
bundles: healthResult.bundles,
|
|
101
|
+
storage: healthResult.storage,
|
|
102
|
+
scheduler: healthResult.scheduler
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
moduleLogger.info('Initial health check passed', {
|
|
107
|
+
status: healthResult.status,
|
|
108
|
+
bundles: healthResult.bundles,
|
|
109
|
+
storage: healthResult.storage,
|
|
110
|
+
scheduler: healthResult.scheduler
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
moduleLogger.error('Initial health check failed', error instanceof Error ? error : new Error(String(error)));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// 获取服务器状态
|
|
119
|
+
async getServerStatus() {
|
|
120
|
+
const storageManager = getStorageManager();
|
|
121
|
+
const jobsStatus = PreflightScheduler.getAllJobsStatus();
|
|
122
|
+
const adapterHealth = await storageManager.getAdapterHealth();
|
|
123
|
+
return {
|
|
124
|
+
initialized: this.isInitialized,
|
|
125
|
+
running: this.isRunning,
|
|
126
|
+
uptime: this.isRunning ? Date.now() - this.startTime : 0,
|
|
127
|
+
jobs: {
|
|
128
|
+
total: Object.keys(jobsStatus).length,
|
|
129
|
+
status: jobsStatus
|
|
130
|
+
},
|
|
131
|
+
storage: {
|
|
132
|
+
adapters: storageManager.listAdapters(),
|
|
133
|
+
health: adapterHealth
|
|
134
|
+
},
|
|
135
|
+
compression: {
|
|
136
|
+
enabled: true,
|
|
137
|
+
supportedTypes: ['none', 'gzip', 'br', 'deflate']
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
// 手动触发任务
|
|
142
|
+
async triggerBundleUpdate() {
|
|
143
|
+
moduleLogger.info('Manually triggering bundle update job');
|
|
144
|
+
const job = new BundleAutoUpdateJob();
|
|
145
|
+
return await job.run();
|
|
146
|
+
}
|
|
147
|
+
async triggerStorageCleanup() {
|
|
148
|
+
moduleLogger.info('Manually triggering storage cleanup job');
|
|
149
|
+
const job = new StorageCleanupJob();
|
|
150
|
+
return await job.run();
|
|
151
|
+
}
|
|
152
|
+
async triggerHealthCheck() {
|
|
153
|
+
moduleLogger.info('Manually triggering health check job');
|
|
154
|
+
const job = new HealthCheckJob();
|
|
155
|
+
return await job.run();
|
|
156
|
+
}
|
|
157
|
+
// 压缩相关功能
|
|
158
|
+
async compressData(data, options) {
|
|
159
|
+
return await compressData(data, options);
|
|
160
|
+
}
|
|
161
|
+
async decompressData(data, type) {
|
|
162
|
+
return await decompressData(data, type);
|
|
163
|
+
}
|
|
164
|
+
detectCompressionType(data) {
|
|
165
|
+
return detectCompressionType(data);
|
|
166
|
+
}
|
|
167
|
+
// 存储相关功能
|
|
168
|
+
async getStorageStats() {
|
|
169
|
+
const storageManager = getStorageManager();
|
|
170
|
+
const adapter = storageManager.getPrimaryAdapter();
|
|
171
|
+
return await adapter.getStats();
|
|
172
|
+
}
|
|
173
|
+
async getStorageHealth() {
|
|
174
|
+
const storageManager = getStorageManager();
|
|
175
|
+
return await storageManager.getAdapterHealth();
|
|
176
|
+
}
|
|
177
|
+
// 日志相关功能
|
|
178
|
+
updateLoggerConfig(config) {
|
|
179
|
+
logger.updateConfig(config);
|
|
180
|
+
moduleLogger.info('Logger configuration updated', config);
|
|
181
|
+
}
|
|
182
|
+
async getLogStats() {
|
|
183
|
+
const config = logger.getConfig();
|
|
184
|
+
return {
|
|
185
|
+
...config,
|
|
186
|
+
bufferSize: 1000, // 示例值
|
|
187
|
+
lastFlush: new Date().toISOString()
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
async flushLogs() {
|
|
191
|
+
await logger.flush();
|
|
192
|
+
moduleLogger.debug('Logs flushed manually');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// 单例实例
|
|
196
|
+
let optimizedServer = null;
|
|
197
|
+
export function getOptimizedServer() {
|
|
198
|
+
if (!optimizedServer) {
|
|
199
|
+
optimizedServer = new OptimizedPreflightServer();
|
|
200
|
+
}
|
|
201
|
+
return optimizedServer;
|
|
202
|
+
}
|
|
203
|
+
export function resetOptimizedServer() {
|
|
204
|
+
optimizedServer = null;
|
|
205
|
+
}
|
|
206
|
+
// 导出便捷函数
|
|
207
|
+
export async function initializeOptimizedServer() {
|
|
208
|
+
const server = getOptimizedServer();
|
|
209
|
+
await server.initialize();
|
|
210
|
+
}
|
|
211
|
+
export async function startOptimizedServer() {
|
|
212
|
+
const server = getOptimizedServer();
|
|
213
|
+
await server.start();
|
|
214
|
+
}
|
|
215
|
+
export async function stopOptimizedServer() {
|
|
216
|
+
const server = getOptimizedServer();
|
|
217
|
+
await server.stop();
|
|
218
|
+
}
|
|
219
|
+
// 服务器启动时的初始化流程
|
|
220
|
+
export async function bootstrapOptimizedServer() {
|
|
221
|
+
try {
|
|
222
|
+
logger.info('Bootstrapping optimized preflight server...');
|
|
223
|
+
const server = getOptimizedServer();
|
|
224
|
+
server.startTime = Date.now(); // 记录启动时间
|
|
225
|
+
await server.initialize();
|
|
226
|
+
await server.start();
|
|
227
|
+
logger.info('Optimized preflight server bootstrap completed');
|
|
228
|
+
// 设置优雅关闭
|
|
229
|
+
process.on('SIGINT', async () => {
|
|
230
|
+
logger.info('Received SIGINT, shutting down gracefully...');
|
|
231
|
+
await server.stop();
|
|
232
|
+
process.exit(0);
|
|
233
|
+
});
|
|
234
|
+
process.on('SIGTERM', async () => {
|
|
235
|
+
logger.info('Received SIGTERM, shutting down gracefully...');
|
|
236
|
+
await server.stop();
|
|
237
|
+
process.exit(0);
|
|
238
|
+
});
|
|
239
|
+
// 处理未捕获的异常
|
|
240
|
+
process.on('uncaughtException', async (error) => {
|
|
241
|
+
logger.fatal('Uncaught exception', error);
|
|
242
|
+
await server.stop();
|
|
243
|
+
process.exit(1);
|
|
244
|
+
});
|
|
245
|
+
process.on('unhandledRejection', async (reason, promise) => {
|
|
246
|
+
logger.fatal('Unhandled rejection', new Error(String(reason)), { promise });
|
|
247
|
+
await server.stop();
|
|
248
|
+
process.exit(1);
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
logger.fatal('Failed to bootstrap optimized server', error instanceof Error ? error : new Error(String(error)));
|
|
253
|
+
process.exit(1);
|
|
254
|
+
}
|
|
255
|
+
}
|