import { getLogger } from '@stock-bot/logger'; export interface JobHandler { (payload: any): Promise; } export interface JobData { type?: string; provider: string; operation: string; payload: any; priority?: number; immediately?: boolean; } export interface ScheduledJob { type: string; operation: string; payload: any; cronPattern: string; priority?: number; description?: string; immediately?: boolean; } export interface ProviderConfig { name: string; operations: Record; scheduledJobs?: ScheduledJob[]; } export interface ProviderRegistry { registerProvider: (config: ProviderConfig) => void; getHandler: (provider: string, operation: string) => JobHandler | null; getAllScheduledJobs: () => Array<{ provider: string; job: ScheduledJob }>; getProviders: () => Array<{ key: string; config: ProviderConfig }>; hasProvider: (provider: string) => boolean; clear: () => void; } /** * Create a new provider registry instance */ export function createProviderRegistry(): ProviderRegistry { const logger = getLogger('provider-registry'); const providers = new Map(); /** * Register a provider with its operations */ function registerProvider(config: ProviderConfig): void { providers.set(config.name, config); logger.info(`Registered provider: ${config.name}`, { operations: Object.keys(config.operations), scheduledJobs: config.scheduledJobs?.length || 0, }); } /** * Get a job handler for a specific provider and operation */ function getHandler(provider: string, operation: string): JobHandler | null { const providerConfig = providers.get(provider); if (!providerConfig) { logger.warn(`Provider not found: ${provider}`); return null; } const handler = providerConfig.operations[operation]; if (!handler) { logger.warn(`Operation not found: ${operation} in provider ${provider}`); return null; } return handler; } /** * Get all scheduled jobs from all providers */ function getAllScheduledJobs(): Array<{ provider: string; job: ScheduledJob }> { const allJobs: Array<{ provider: string; job: ScheduledJob }> = []; for (const [, config] of providers) { if (config.scheduledJobs) { for (const job of config.scheduledJobs) { allJobs.push({ provider: config.name, job, }); } } } return allJobs; } /** * Get all registered providers with their configurations */ function getProviders(): Array<{ key: string; config: ProviderConfig }> { return Array.from(providers.entries()).map(([key, config]) => ({ key, config, })); } /** * Check if a provider exists */ function hasProvider(provider: string): boolean { return providers.has(provider); } /** * Clear all providers (useful for testing) */ function clear(): void { providers.clear(); logger.info('All providers cleared'); } return { registerProvider, getHandler, getAllScheduledJobs, getProviders, hasProvider, clear, }; } // Create the default shared registry instance export const providerRegistry = createProviderRegistry();