Files
SuperCharged-Claude-Code-Up…/dexto/packages/webui/components/providers/EventBusProvider.tsx
admin b52318eeae feat: Add intelligent auto-router and enhanced integrations
- Add intelligent-router.sh hook for automatic agent routing
- Add AUTO-TRIGGER-SUMMARY.md documentation
- Add FINAL-INTEGRATION-SUMMARY.md documentation
- Complete Prometheus integration (6 commands + 4 tools)
- Complete Dexto integration (12 commands + 5 tools)
- Enhanced Ralph with access to all agents
- Fix /clawd command (removed disable-model-invocation)
- Update hooks.json to v5 with intelligent routing
- 291 total skills now available
- All 21 commands with automatic routing

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-28 00:27:56 +04:00

200 lines
5.2 KiB
TypeScript

/**
* Event Bus Provider
*
* Provides the event bus context to the React component tree.
* Initializes middleware and provides access to the singleton event bus.
*/
import { createContext, useContext, useEffect, useMemo, type ReactNode } from 'react';
import {
ClientEventBus,
eventBus,
loggingMiddleware,
activityMiddleware,
notificationMiddleware,
setupEventHandlers,
type EventMiddleware,
} from '@/lib/events';
/**
* Event bus context value
*/
interface EventBusContextValue {
/** The event bus instance */
bus: ClientEventBus;
}
const EventBusContext = createContext<EventBusContextValue | null>(null);
/**
* Props for EventBusProvider
*/
interface EventBusProviderProps {
children: ReactNode;
/**
* Additional middleware to register (beyond default logging)
* Middleware is executed in array order
*/
middleware?: EventMiddleware[];
/**
* Enable logging middleware (default: true in development)
*/
enableLogging?: boolean;
/**
* Enable activity tracking middleware (default: true)
*/
enableActivityLogging?: boolean;
/**
* Enable notification middleware (default: true)
*/
enableNotifications?: boolean;
/**
* Custom event bus instance (for testing)
* If not provided, uses the singleton instance
*/
bus?: ClientEventBus;
}
/**
* Event Bus Provider
*
* Wraps the application with event bus context.
* Initializes default middleware on mount.
*
* @example
* ```tsx
* // Basic usage
* <EventBusProvider>
* <App />
* </EventBusProvider>
*
* // With all middleware disabled except custom
* <EventBusProvider
* enableLogging={false}
* enableActivityLogging={false}
* middleware={[customMiddleware]}
* >
* <App />
* </EventBusProvider>
*
* // For testing with isolated bus
* <EventBusProvider bus={testBus}>
* <ComponentUnderTest />
* </EventBusProvider>
* ```
*/
export function EventBusProvider({
children,
middleware = [],
enableLogging = process.env.NODE_ENV === 'development',
enableActivityLogging = true,
enableNotifications = true,
bus = eventBus,
}: EventBusProviderProps) {
// Register middleware and handlers on mount
useEffect(() => {
const registeredMiddleware: EventMiddleware[] = [];
let handlerCleanup: (() => void) | undefined;
// Register middleware in order (logging first for debugging)
if (enableLogging) {
bus.use(loggingMiddleware);
registeredMiddleware.push(loggingMiddleware);
}
if (enableActivityLogging) {
bus.use(activityMiddleware);
registeredMiddleware.push(activityMiddleware);
}
if (enableNotifications) {
bus.use(notificationMiddleware);
registeredMiddleware.push(notificationMiddleware);
}
// Add custom middleware
for (const mw of middleware) {
bus.use(mw);
registeredMiddleware.push(mw);
}
// Setup event handlers
handlerCleanup = setupEventHandlers(bus);
// Cleanup on unmount
return () => {
for (const mw of registeredMiddleware) {
bus.removeMiddleware(mw);
}
handlerCleanup?.();
};
}, [bus, enableLogging, enableActivityLogging, enableNotifications, middleware]);
// Memoize context value
const contextValue = useMemo<EventBusContextValue>(() => ({ bus }), [bus]);
return <EventBusContext.Provider value={contextValue}>{children}</EventBusContext.Provider>;
}
/**
* Hook to access the event bus
*
* @returns The event bus instance
* @throws Error if used outside EventBusProvider
*
* @example
* ```tsx
* function MyComponent() {
* const bus = useEventBus();
*
* useEffect(() => {
* const sub = bus.on('llm:response', (event) => {
* console.log('Response:', event.content);
* });
* return () => sub.unsubscribe();
* }, [bus]);
* }
* ```
*/
export function useEventBus(): ClientEventBus {
const context = useContext(EventBusContext);
if (!context) {
throw new Error('useEventBus must be used within an EventBusProvider');
}
return context.bus;
}
/**
* Hook to subscribe to events with automatic cleanup
*
* @param eventName - Event name to subscribe to
* @param handler - Handler function
*
* @example
* ```tsx
* function MessageList() {
* const [messages, setMessages] = useState<Message[]>([]);
*
* useEventSubscription('llm:response', (event) => {
* setMessages(prev => [...prev, {
* role: 'assistant',
* content: event.content,
* }]);
* });
* }
* ```
*/
export function useEventSubscription<T extends Parameters<ClientEventBus['on']>[0]>(
eventName: T,
handler: Parameters<ClientEventBus['on']>[1]
): void {
const bus = useEventBus();
useEffect(() => {
// Type assertion is needed here because the generic relationship between
// eventName and handler is complex - the EventBus.on() validates at runtime
const subscription = bus.on(eventName as any, handler as any);
return () => subscription.unsubscribe();
}, [bus, eventName, handler]);
}