huge refactor to remove depenencie hell and add typesafe container
This commit is contained in:
parent
28b9822d55
commit
843a7b9b9b
148 changed files with 3603 additions and 2378 deletions
14
libs/core/handler-registry/src/index.ts
Normal file
14
libs/core/handler-registry/src/index.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/**
|
||||
* Handler Registry Package
|
||||
* Provides centralized handler registration without circular dependencies
|
||||
*/
|
||||
|
||||
export { HandlerRegistry } from './registry';
|
||||
export type {
|
||||
HandlerMetadata,
|
||||
OperationMetadata,
|
||||
ScheduleMetadata,
|
||||
HandlerConfiguration,
|
||||
RegistryStats,
|
||||
HandlerDiscoveryResult,
|
||||
} from './types';
|
||||
226
libs/core/handler-registry/src/registry.ts
Normal file
226
libs/core/handler-registry/src/registry.ts
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
/**
|
||||
* Handler Registry Implementation
|
||||
* Manages handler metadata and configuration without circular dependencies
|
||||
*/
|
||||
|
||||
import type { JobHandler, ScheduledJob } from '@stock-bot/types';
|
||||
import type {
|
||||
HandlerConfiguration,
|
||||
HandlerMetadata,
|
||||
OperationMetadata,
|
||||
RegistryStats,
|
||||
ScheduleMetadata,
|
||||
} 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get handlers for a specific service
|
||||
*/
|
||||
getServiceHandlers(serviceName: string): HandlerMetadata[] {
|
||||
const handlers: HandlerMetadata[] = [];
|
||||
|
||||
for (const [handlerName, service] of this.handlerServices) {
|
||||
if (service === serviceName) {
|
||||
const metadata = this.handlers.get(handlerName);
|
||||
if (metadata) {
|
||||
handlers.push(metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
libs/core/handler-registry/src/types.ts
Normal file
66
libs/core/handler-registry/src/types.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* Handler Registry Types
|
||||
* Pure types for handler metadata and registration
|
||||
*/
|
||||
|
||||
import type { JobHandler, ScheduledJob } from '@stock-bot/types';
|
||||
|
||||
/**
|
||||
* Metadata for a single operation within a handler
|
||||
*/
|
||||
export interface OperationMetadata {
|
||||
name: string;
|
||||
method: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Metadata for a scheduled operation
|
||||
*/
|
||||
export interface ScheduleMetadata {
|
||||
operation: string;
|
||||
cronPattern: string;
|
||||
priority?: number;
|
||||
immediately?: boolean;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete metadata for a handler
|
||||
*/
|
||||
export interface HandlerMetadata {
|
||||
name: string;
|
||||
service?: string;
|
||||
operations: OperationMetadata[];
|
||||
schedules?: ScheduleMetadata[];
|
||||
version?: string;
|
||||
description?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler configuration with operation implementations
|
||||
*/
|
||||
export interface HandlerConfiguration {
|
||||
name: string;
|
||||
operations: Record<string, JobHandler>;
|
||||
scheduledJobs?: ScheduledJob[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registry statistics
|
||||
*/
|
||||
export interface RegistryStats {
|
||||
handlers: number;
|
||||
operations: number;
|
||||
scheduledJobs: number;
|
||||
services: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler discovery result
|
||||
*/
|
||||
export interface HandlerDiscoveryResult {
|
||||
handler: HandlerMetadata;
|
||||
constructor: any;
|
||||
filePath?: string;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue