mirror of
https://github.com/samanhappy/mcphub.git
synced 2025-12-24 02:39:19 -05:00
feat: implement lazy loading for data service and enhance service registration (#233)
This commit is contained in:
@@ -17,7 +17,14 @@ const defaultConfig = {
|
||||
mcpHubVersion: getPackageVersion(),
|
||||
};
|
||||
|
||||
const dataService: DataService = getDataService();
|
||||
let dataService: DataService | null = null;
|
||||
|
||||
const getDataServiceInstance = (): DataService => {
|
||||
if (!dataService) {
|
||||
dataService = getDataService();
|
||||
}
|
||||
return dataService;
|
||||
};
|
||||
|
||||
// Settings cache
|
||||
let settingsCache: McpSettings | null = null;
|
||||
@@ -54,13 +61,16 @@ export const loadOriginalSettings = (): McpSettings => {
|
||||
};
|
||||
|
||||
export const loadSettings = (): McpSettings => {
|
||||
return dataService.filterSettings!(loadOriginalSettings());
|
||||
return getDataServiceInstance().filterSettings!(loadOriginalSettings());
|
||||
};
|
||||
|
||||
export const saveSettings = (settings: McpSettings): boolean => {
|
||||
const settingsPath = getSettingsPath();
|
||||
try {
|
||||
const mergedSettings = dataService.mergeSettings!(loadOriginalSettings(), settings);
|
||||
const mergedSettings = getDataServiceInstance().mergeSettings!(
|
||||
loadOriginalSettings(),
|
||||
settings,
|
||||
);
|
||||
fs.writeFileSync(settingsPath, JSON.stringify(mergedSettings, null, 2), 'utf8');
|
||||
|
||||
// Update cache after successful save
|
||||
@@ -78,6 +88,7 @@ export const saveSettings = (settings: McpSettings): boolean => {
|
||||
*/
|
||||
export const clearSettingsCache = (): void => {
|
||||
settingsCache = null;
|
||||
dataService = null; // Also clear the data service cache
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
} from './services/sseService.js';
|
||||
import { initializeDefaultUser } from './models/User.js';
|
||||
import { sseUserContextMiddleware } from './middlewares/userContext.js';
|
||||
import { initializeServices } from './services/services.js';
|
||||
|
||||
// Get the current working directory (will be project root in most cases)
|
||||
const currentFileDir = process.cwd() + '/src';
|
||||
@@ -31,6 +32,9 @@ export class AppServer {
|
||||
|
||||
async initialize(): Promise<void> {
|
||||
try {
|
||||
// Initialize services
|
||||
await initializeServices();
|
||||
|
||||
// Initialize default admin user if no users exist
|
||||
await initializeDefaultUser();
|
||||
|
||||
|
||||
@@ -8,10 +8,10 @@ interface Service<T> {
|
||||
const registry = new Map<string, Service<any>>();
|
||||
const instances = new Map<string, unknown>();
|
||||
|
||||
export function registerService<T>(key: string, entry: Service<T>) {
|
||||
export async function registerService<T>(key: string, entry: Service<T>) {
|
||||
// Try to load override immediately during registration
|
||||
const overridePath = './' + key + 'x.js';
|
||||
import(overridePath)
|
||||
await import(overridePath)
|
||||
.then((mod) => {
|
||||
const override = mod[key.charAt(0).toUpperCase() + key.slice(1) + 'x'];
|
||||
if (typeof override === 'function') {
|
||||
|
||||
@@ -1,10 +1,31 @@
|
||||
import { registerService, getService } from './registry.js';
|
||||
import { DataService, DataServiceImpl } from './dataService.js';
|
||||
|
||||
registerService('dataService', {
|
||||
defaultImpl: DataServiceImpl,
|
||||
});
|
||||
let initialized = false;
|
||||
let tempDataService: DataService | null = null;
|
||||
|
||||
async function initializeServices() {
|
||||
if (initialized) return;
|
||||
|
||||
await registerService('dataService', {
|
||||
defaultImpl: DataServiceImpl,
|
||||
});
|
||||
|
||||
initialized = true;
|
||||
tempDataService = null; // Clear temp service once real one is ready
|
||||
}
|
||||
|
||||
export function getDataService(): DataService {
|
||||
return getService<DataService>('dataService');
|
||||
if (initialized) {
|
||||
return getService<DataService>('dataService');
|
||||
}
|
||||
|
||||
// Return temporary service for cases where services haven't been initialized yet
|
||||
// This allows module loading to work even before server initialization
|
||||
if (!tempDataService) {
|
||||
tempDataService = new DataServiceImpl();
|
||||
}
|
||||
return tempDataService;
|
||||
}
|
||||
|
||||
export { initializeServices };
|
||||
|
||||
Reference in New Issue
Block a user