import type { CSSProperties } from 'react'; import type { ComponentDefinition } from './types'; /** * Centralized registry for all component definitions. * Singleton pattern ensures a single source of truth. */ class ComponentRegistryClass { private definitions: Map = new Map(); /** * Register a component definition * @param definition The component definition to register * @throws Error if component type is already registered */ register(definition: ComponentDefinition): void { if (this.definitions.has(definition.type)) { console.warn(`Component type "${definition.type}" is already registered. Overwriting.`); } this.definitions.set(definition.type, definition); } /** * Get a component definition by type * @param type The component type to look up * @returns The component definition or undefined if not found */ get(type: string): ComponentDefinition | undefined { return this.definitions.get(type); } /** * Check if a component type is registered * @param type The component type to check */ has(type: string): boolean { return this.definitions.has(type); } /** * Get all registered component definitions * @returns Array of all component definitions */ getAll(): ComponentDefinition[] { return Array.from(this.definitions.values()); } /** * Get component definitions filtered by category * @param category 'container' or 'leaf' */ getByCategory(category: 'container' | 'leaf'): ComponentDefinition[] { return this.getAll().filter((def) => def.category === category); } /** * Get default styles for a component type * @param type The component type * @returns Default styles or empty object if not found */ getDefaultStyles(type: string): CSSProperties { const definition = this.get(type); return definition?.defaultStyles ?? {}; } /** * Get default props for a component type * @param type The component type * @returns Default props or empty object if not found */ getDefaultProps(type: string): Record { const definition = this.get(type); return definition?.defaultProps ?? {}; } /** * Check if a component type can have children * @param type The component type * @returns true if component can have children, false otherwise */ canHaveChildren(type: string): boolean { const definition = this.get(type); return definition?.canHaveChildren ?? false; } /** * Get icon component for a component type * @param type The component type * @returns Icon component or undefined if not found */ getIcon(type: string): React.ComponentType | undefined { const definition = this.get(type); return definition?.icon; } /** * Get all registered component types * @returns Array of component type strings */ getTypes(): string[] { return Array.from(this.definitions.keys()); } /** * Clear all registered components (useful for testing) */ clear(): void { this.definitions.clear(); } } // Export singleton instance export const ComponentRegistry = new ComponentRegistryClass();