# Arquitectura Reactiva - Documentación ## 🏗️ Estructura Híbrida La arquitectura separa **estado agnóstico del framework** de los **adapters específicos**: ``` src/ ├── state/ # ← Estado puro (sin framework) │ ├── SelectionState.ts │ ├── ValidationState.ts │ └── ConfigurationState.ts │ └── adapters/ # ← Adapters por framework └── svelte/ ├── stores/ # Wrappers Svelte └── components/ # Componentes UI ``` --- ## 📦 Capa 1: Estado Agnóstico (`/state`) ### `SelectionState.ts` Gestiona qué opciones están seleccionadas. **Responsabilidades:** - Almacenar selecciones: `Record` - Notificar cambios via listeners - Historial de cambios (undo/redo) - Persistencia (toJSON/fromJSON) **API:** ```typescript const selection = new SelectionState(); // Establecer valor selection.set('at:suelo', 'op:parquet'); // Obtener valor selection.get('at:suelo'); // → 'op:parquet' // Limpiar selection.clear('at:suelo'); // Suscribirse a cambios const unsubscribe = selection.subscribe((event) => { console.log(`${event.attrId} cambió a ${event.newValue}`); }); // Deshacer selection.undo(); ``` --- ### `ValidationState.ts` Gestiona validaciones y violaciones usando el `RuleEngine`. **Responsabilidades:** - Validar selecciones contra reglas - Detectar violaciones (errores/warnings) - Verificar valores permitidos/prohibidos - Determinar atributos requeridos **API:** ```typescript const validation = new ValidationState(); // Configurar reglas validation.setRules(catalog.rules); // Validar estado const result = validation.validate(selectionState); console.log(result.isValid); // → boolean console.log(result.violations); // → Violation[] // Helpers validation.isValueAllowed('at:suelo', 'op:marmol', state); validation.getAllowedValues('at:suelo', state); validation.isRequired('at:material', state); ``` --- ### `ConfigurationState.ts` **Orquestador principal** que coordina todo. **Responsabilidades:** - Gestionar catálogo y objeto - Coordinar SelectionState + ValidationState - Navegación (sección/vista actual) - Auto-validación en cambios - Persistencia completa **API:** ```typescript const config = new ConfigurationState({ catalog: CATALOGO_VIVIENDAS, objectId: 'ob:apartamento', autoValidate: true }); // Selección config.selectOption('at:suelo', 'op:parquet'); config.getSelection('at:suelo'); // Navegación config.setCurrentSection('sc:salon'); config.setCurrentView('vw:front'); // Validación config.validate(); config.isValid(); config.getViolationsForAttribute('at:suelo'); // Helpers config.getAllowedValues('at:suelo'); config.isRequired('at:material'); // Persistencia const saved = config.toJSON(); config.fromJSON(saved); // Utils config.reset(); config.undo(); ``` --- ## 🔌 Capa 2: Adapters Svelte (`/adapters/svelte`) ### `stores/configuration.ts` Wrapper que convierte `ConfigurationState` en Svelte store. **Características:** - ✅ Reactivo automático (subscribe) - ✅ API idéntica a ConfigurationState - ✅ Derived stores para valores específicos - ✅ Type-safe **Uso:** ```typescript import { createConfigurationStore } from '@/adapters/svelte/stores'; const config = createConfigurationStore({ catalog: CATALOGO_VIVIENDAS, objectId: 'ob:apartamento' }); // En componentes Svelte $: selection = $config.selection; $: isValid = $config.isValid; $: currentSection = $config.currentSection; // Acciones config.selectOption('at:suelo', 'op:parquet'); config.setCurrentSection('sc:salon'); ``` **Derived stores:** ```typescript const currentSection = deriveCurrentSection(config); const validation = deriveValidation(config); const isValid = deriveIsValid(config); ``` --- ## 🎨 Capa 3: Componentes UI (`/adapters/svelte/components`) ### `Configurator.svelte` Componente principal de ejemplo. **Features:** - ✅ Navegación de secciones - ✅ Selector de vistas - ✅ Panel de atributos - ✅ Preview visual - ✅ Validación en tiempo real - ✅ Undo/Reset **Uso:** ```svelte ``` --- ## 🔄 Flujo de Datos ``` User Action (click) ↓ Component Handler ↓ Store Action (config.selectOption) ↓ ConfigurationState ↓ SelectionState.set() ↓ Notifica listeners ↓ ValidationState.validate() (si autoValidate) ↓ Notifica cambio ↓ Svelte Store actualiza ↓ UI re-renderiza (reactive $config) ``` --- ## ✅ Ventajas de esta arquitectura ### 1. **Separación de concerns** - Estado = Lógica de negocio (testeable sin UI) - Adapter = Integración con framework - Components = Solo presentación ### 2. **Framework agnostic** El 90% del código está en `/state` y no depende de Svelte. Añadir React es fácil: ``` /adapters/react/ └── hooks/ └── useConfiguration.ts ← Wrapper con useState/useEffect ``` ### 3. **Testing simple** ```typescript // Test estado SIN montar componentes const config = new ConfigurationState({...}); config.selectOption('at:suelo', 'op:parquet'); expect(config.getSelection('at:suelo')).toBe('op:parquet'); ``` ### 4. **Type-safety completo** Todo tipado con TypeScript. El editor te ayuda en cada paso. ### 5. **Reactivo por defecto** Cambias el estado → UI se actualiza automáticamente. --- ## 📝 Ejemplo completo ```svelte

{$config.object.name.es}

{#if !isValid}
{#each violations as v}

{v.rule.message.es}

{/each}
{/if}
``` --- ## 🚀 Próximos pasos 1. ✅ Estado agnóstico implementado 2. ✅ Adapter Svelte implementado 3. ✅ Componente de ejemplo creado 4. ⏳ Implementar renderizado de imágenes 5. ⏳ Añadir precio dinámico 6. ⏳ Implementar más componentes (AttributePanel, ValidationPanel, etc.) 7. ⏳ Testing de stores 8. ⏳ Documentación de componentes --- ## 📚 Archivos clave - `/state/ConfigurationState.ts` - Orquestador principal - `/adapters/svelte/stores/configuration.ts` - Svelte store - `/adapters/svelte/components/Configurator.svelte` - Componente ejemplo - `/docs/ARCHITECTURE.md` - Este archivo