'use client' import { Component, type ReactNode, type ComponentType } from 'react' import { usePlugins } from '@/hooks/use-plugins' import { getPluginComponents, type SlotName } from '@/lib/plugins/registry' interface PluginSlotProps { name: SlotName context?: Record fallback?: ReactNode } // Error boundary for individual plugin components interface ErrorBoundaryProps { pluginName: string children: ReactNode } interface ErrorBoundaryState { hasError: boolean } class PluginErrorBoundary extends Component { constructor(props: ErrorBoundaryProps) { super(props) this.state = { hasError: false } } static getDerivedStateFromError(): ErrorBoundaryState { return { hasError: true } } render() { if (this.state.hasError) { return (
Plugin “{this.props.pluginName}” encountered an error.
) } return this.props.children } } export function PluginSlot({ name, context = {}, fallback }: PluginSlotProps) { const { plugins } = usePlugins() const registrations = getPluginComponents(name) // Filter to only enabled plugins const activeRegistrations = registrations.filter((reg) => plugins.some((p) => p.name === reg.pluginName && p.enabled) ) if (activeRegistrations.length === 0) { return fallback ?? null } return ( <> {activeRegistrations.map((reg) => { const PluginComponent = reg.component as ComponentType> return ( ) })} ) }