Roo-Code/src/core/events/EventBusProvider.ts
hannesrudolph 2465ed26c3 refactor: comprehensive architectural overhaul for clean separation of concerns
- Introduced interfaces (IErrorHandler, IRetryStrategy, IStateManager, IRateLimitManager)
- Eliminated circular dependencies with EventBus implementation
- Split UnifiedErrorHandler into focused components following SRP
- Replaced singleton GlobalRateLimitManager with dependency injection
- Decoupled UI updates through event-driven architecture
- Added 129 new tests (3,029 total passing)
- 100% backward compatible - no breaking changes

This refactoring addresses all PR review concerns including module boundary violations,
circular dependencies, and mixed responsibilities while establishing a robust foundation
for future development.
2025-07-09 00:05:35 -06:00

88 lines
2.3 KiB
TypeScript

import { EventBus } from "./EventBus"
/**
* EventBusProvider manages EventBus instances for dependency injection.
* It ensures that components can share EventBus instances when needed
* or create isolated instances for testing.
*/
export class EventBusProvider {
private static defaultInstance: EventBus | null = null
private static testInstances: Map<string, EventBus> = new Map()
/**
* Get the default EventBus instance (singleton for production use)
*/
static getDefault(): EventBus {
if (!this.defaultInstance) {
this.defaultInstance = new EventBus()
}
return this.defaultInstance!
}
/**
* Create a new isolated EventBus instance for testing
* @param testId - Unique identifier for the test instance
*/
static createTestInstance(testId: string): EventBus {
const instance = new EventBus()
this.testInstances.set(testId, instance)
return instance
}
/**
* Get a test instance by ID
* @param testId - Unique identifier for the test instance
*/
static getTestInstance(testId: string): EventBus | undefined {
return this.testInstances.get(testId)
}
/**
* Clear a specific test instance
* @param testId - Unique identifier for the test instance
*/
static clearTestInstance(testId: string): void {
const instance = this.testInstances.get(testId)
if (instance) {
instance.removeAllListeners()
this.testInstances.delete(testId)
}
}
/**
* Clear all test instances
*/
static clearAllTestInstances(): void {
this.testInstances.forEach((instance) => {
instance.removeAllListeners()
})
this.testInstances.clear()
}
/**
* Reset the default instance (mainly for testing)
*/
static resetDefault(): void {
if (this.defaultInstance) {
this.defaultInstance.removeAllListeners()
this.defaultInstance = null
}
}
/**
* Get or create an EventBus instance based on context
* @param context - Optional context object that may contain test information
*/
static getInstance(context?: { testId?: string }): EventBus {
if (context?.testId) {
// In test context, return or create a test instance
let instance = this.testInstances.get(context.testId)
if (!instance) {
instance = this.createTestInstance(context.testId)
}
return instance
}
// In production context, return the default singleton
return this.getDefault()
}
}