218 lines
5.4 KiB
TypeScript
218 lines
5.4 KiB
TypeScript
/**
|
|
* Handler Registry Implementation
|
|
* Manages handler metadata and configuration without circular dependencies
|
|
*/
|
|
|
|
import type { JobHandler, ScheduledJob } from '@stock-bot/types';
|
|
import type { HandlerConfiguration, HandlerMetadata, RegistryStats } from './types';
|
|
|
|
export class HandlerRegistry {
|
|
private handlers = new Map<string, HandlerMetadata>();
|
|
private configurations = new Map<string, HandlerConfiguration>();
|
|
private handlerServices = new Map<string, string>();
|
|
|
|
/**
|
|
* Register handler metadata
|
|
*/
|
|
registerMetadata(metadata: HandlerMetadata): void {
|
|
this.handlers.set(metadata.name, metadata);
|
|
|
|
if (metadata.service) {
|
|
this.handlerServices.set(metadata.name, metadata.service);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Register handler configuration with operation implementations
|
|
*/
|
|
registerConfiguration(config: HandlerConfiguration): void {
|
|
this.configurations.set(config.name, config);
|
|
}
|
|
|
|
/**
|
|
* Register both metadata and configuration
|
|
*/
|
|
register(metadata: HandlerMetadata, config: HandlerConfiguration): void {
|
|
this.registerMetadata(metadata);
|
|
this.registerConfiguration(config);
|
|
}
|
|
|
|
/**
|
|
* Get handler metadata
|
|
*/
|
|
getMetadata(handlerName: string): HandlerMetadata | undefined {
|
|
return this.handlers.get(handlerName);
|
|
}
|
|
|
|
/**
|
|
* Get handler configuration
|
|
*/
|
|
getConfiguration(handlerName: string): HandlerConfiguration | undefined {
|
|
return this.configurations.get(handlerName);
|
|
}
|
|
|
|
/**
|
|
* Get a specific operation handler
|
|
*/
|
|
getOperation(handlerName: string, operationName: string): JobHandler | undefined {
|
|
const config = this.configurations.get(handlerName);
|
|
return config?.operations[operationName];
|
|
}
|
|
|
|
/**
|
|
* Get all handler metadata
|
|
*/
|
|
getAllMetadata(): Map<string, HandlerMetadata> {
|
|
return new Map(this.handlers);
|
|
}
|
|
|
|
/**
|
|
* Get all handler names
|
|
*/
|
|
getHandlerNames(): string[] {
|
|
return Array.from(this.handlers.keys());
|
|
}
|
|
|
|
/**
|
|
* Check if a handler is registered
|
|
*/
|
|
hasHandler(handlerName: string): boolean {
|
|
return this.handlers.has(handlerName);
|
|
}
|
|
|
|
/**
|
|
* Set service ownership for a handler
|
|
*/
|
|
setHandlerService(handlerName: string, serviceName: string): void {
|
|
this.handlerServices.set(handlerName, serviceName);
|
|
|
|
// Update metadata if it exists
|
|
const metadata = this.handlers.get(handlerName);
|
|
if (metadata) {
|
|
metadata.service = serviceName;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the service that owns a handler
|
|
*/
|
|
getHandlerService(handlerName: string): string | undefined {
|
|
return this.handlerServices.get(handlerName);
|
|
}
|
|
|
|
/**
|
|
* Get all handlers for a specific service
|
|
*/
|
|
getServiceHandlers(serviceName: string): HandlerMetadata[] {
|
|
const handlers: HandlerMetadata[] = [];
|
|
for (const [handlerName, metadata] of this.handlers) {
|
|
if (
|
|
this.handlerServices.get(handlerName) === serviceName ||
|
|
metadata.service === serviceName
|
|
) {
|
|
handlers.push(metadata);
|
|
}
|
|
}
|
|
return handlers;
|
|
}
|
|
|
|
/**
|
|
* Get scheduled jobs for a handler
|
|
*/
|
|
getScheduledJobs(handlerName: string): ScheduledJob[] {
|
|
const config = this.configurations.get(handlerName);
|
|
return config?.scheduledJobs || [];
|
|
}
|
|
|
|
/**
|
|
* Get all handlers with their scheduled jobs
|
|
*/
|
|
getAllHandlersWithSchedule(): Map<
|
|
string,
|
|
{ metadata: HandlerMetadata; scheduledJobs: ScheduledJob[] }
|
|
> {
|
|
const result = new Map<string, { metadata: HandlerMetadata; scheduledJobs: ScheduledJob[] }>();
|
|
|
|
for (const [name, metadata] of this.handlers) {
|
|
const config = this.configurations.get(name);
|
|
result.set(name, {
|
|
metadata,
|
|
scheduledJobs: config?.scheduledJobs || [],
|
|
});
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Get registry statistics
|
|
*/
|
|
getStats(): RegistryStats {
|
|
let operationCount = 0;
|
|
let scheduledJobCount = 0;
|
|
const services = new Set<string>();
|
|
|
|
for (const metadata of this.handlers.values()) {
|
|
operationCount += metadata.operations.length;
|
|
scheduledJobCount += metadata.schedules?.length || 0;
|
|
|
|
if (metadata.service) {
|
|
services.add(metadata.service);
|
|
}
|
|
}
|
|
|
|
return {
|
|
handlers: this.handlers.size,
|
|
operations: operationCount,
|
|
scheduledJobs: scheduledJobCount,
|
|
services: services.size,
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Clear all registrations (useful for testing)
|
|
*/
|
|
clear(): void {
|
|
this.handlers.clear();
|
|
this.configurations.clear();
|
|
this.handlerServices.clear();
|
|
}
|
|
|
|
/**
|
|
* Export registry data for debugging or persistence
|
|
*/
|
|
export(): {
|
|
handlers: Array<[string, HandlerMetadata]>;
|
|
configurations: Array<[string, HandlerConfiguration]>;
|
|
services: Array<[string, string]>;
|
|
} {
|
|
return {
|
|
handlers: Array.from(this.handlers.entries()),
|
|
configurations: Array.from(this.configurations.entries()),
|
|
services: Array.from(this.handlerServices.entries()),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Import registry data
|
|
*/
|
|
import(data: {
|
|
handlers: Array<[string, HandlerMetadata]>;
|
|
configurations: Array<[string, HandlerConfiguration]>;
|
|
services: Array<[string, string]>;
|
|
}): void {
|
|
this.clear();
|
|
|
|
for (const [name, metadata] of data.handlers) {
|
|
this.handlers.set(name, metadata);
|
|
}
|
|
|
|
for (const [name, config] of data.configurations) {
|
|
this.configurations.set(name, config);
|
|
}
|
|
|
|
for (const [handler, service] of data.services) {
|
|
this.handlerServices.set(handler, service);
|
|
}
|
|
}
|
|
}
|