You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix
dev 4d26761263
docs + switch: align active docs to canon, migrate switch to eidos wrapper
5 months ago
..
active-uix active-uix: uix.runtime(morfo, sources) auto-injects dom + semantic 5 months ago
eidos docs + switch: align active docs to canon, migrate switch to eidos wrapper 5 months ago
morfo docs + switch: align active docs to canon, migrate switch to eidos wrapper 5 months ago
sema docs + switch: align active docs to canon, migrate switch to eidos wrapper 5 months ago
soma docs + switch: align active docs to canon, migrate switch to eidos wrapper 5 months ago
README.md docs: prune obsolete audits + studies, refresh remaining references 5 months ago
active_architecture.md docs + switch: align active docs to canon, migrate switch to eidos wrapper 5 months ago
types.ts uix: relocate Layer + PartRef to src/uix/types.ts 5 months ago

README.md

UIX

Documento corto de posicionamiento arquitectónico para src/uix.

Visión de conjunto: para entender las cuatro capas (morfo, soma, sema, eidos) en una sola lectura, motivaciones y articulación incluidas, ir a active_architecture.md. Este README mantiene la introducción más narrativa.

Hand-off de continuación: el estado actual de migración y los próximos pasos viven en CLAUDE.md (raíz del repo), sección "Session hand-off".

Convenciones doctrinales del API (intent ↔ color, subset por componente, soma compound vs eidos flat, sound eager-init): viven en src/docs/sema-implementation-guide.md Parte IV. Autoritativo para todo wrapper / migración nueva.

UIX no intenta ser "otra librería de componentes". La apuesta es más ambiciosa y estructural: separar capas que casi todos los frameworks actuales mantienen mezcladas.

En la mayoría de sistemas de UI, estas cosas viven pegadas:

  • contrato público del DOM
  • comportamiento headless
  • accesibilidad
  • semántica del evento
  • capa visual
  • motores modales (sound, vibra, motion)
  • integración con servicios de app

UIX intenta partir ese bloque en piezas con fronteras fuertes.


1. La idea central

UIX modela la interfaz como varias capas cooperando, no como un único componente gigante que hace todo a la vez.

App
├─ servicios transversales (active-app)
│  └─ adom, lang, frontend, format, ...
└─ componentes
   └─ capa estructural / semántica / comportamental / visual

La intuición:

  • la estructura pública del componente no es lo mismo que su comportamiento
  • la semántica de un evento no es lo mismo que su materialización
  • el DOM activo no es lo mismo que utilidades DOM puras
  • la app no debería acoplar motores modales entre sí

UIX pone nombres y contratos explícitos a esas separaciones.


2. Las capas de UIX

Morfo (src/uix/morfo/)

Contrato estructural cross-layer del componente. Define parts, data-*, ARIA, foco, teclado, eventos. No es prose ni runtime — es la forma canónica pública.

Ver: morfo/README.md

Sema (src/uix/sema/)

Vocabulario semántico y orquestación de señales perceptivas.

  • familias canónicas: contact, commit, signal, handle, emerge, shift, sustain
  • intents canónicos: neutral, affirm, fulfill, risk, threat, loss
  • SemanticEngine.emit(signal) para que el provider publique ocurrencias
  • registry de canales (VisualChannel, SoundChannel, futuro VibraChannel)
  • semántica secuencial estricta del VisualChannel: escribe data-event-*, mantiene durante el hold, limpia ANTES de resolver la Promise

Sema no decide qué ocurrió (eso lo decide el provider). Solo orquesta la ocurrencia y la despacha a los canales registrados.

Ver: sema/README.md

Soma (src/uix/soma/)

Capa headless de comportamiento: estado, contexto, a11y, keyboard / pointer / focus, emisión de eventos.

Soma no conoce la implementación concreta de los engines modales. Su trabajo es emitir hechos del componente, no materializarlos.

Ver: soma/README.md, soma/SOMA_ARCHITECTURE.md

Eidos (src/uix/eidos/)

Capa visual: tokens, themes, recipes CSS por componente, archetype rules, event reactions, wrappers Svelte sobre los providers headless de soma con las props visuales (variant, size, block, iconOnly, icon, checkMark).

Eidos lee del DOM lo que las otras capas escriben (parts, data-attrs, ARIA, event signals) — nunca importa internals de soma ni de sema.

Ver: eidos/README.md

active-uix (src/uix/active-uix/)

Composition root. Dos modos de boot:

  • createActiveUix(options) — standalone, instancia las services internamente
  • attachActiveUix(activeApp) — adjunta a un ActiveApp ya compuesto por la aplicación

Los componentes consumen ActiveUix vía getActiveUix() y no saben qué ruta de boot se usó.

adom (src/arts/adom/, alias $adom)

Runtime DOM activo de aplicación. No es semantic engine. Su única función es coordinar y sincronizar mutaciones DOM vía app.dom.apply(change) y app.dom.remove(target, names).

ADom recibe instrucciones ya resueltas. No las interpreta.

Ver: src/arts/adom/README.md

libs/dom (src/libs/dom/)

Utilidades DOM puras o casi puras (contains, getDocument, getWindow, foco, traversal, wrappers base de observers). No contiene runtime activo — ese papel es de adom.


2.bis Cómo se ejecuta un componente

La arquitectura cerrada (post-2026-04-25) define seis piezas con responsabilidades disjuntas. Ninguna invade a la siguiente.

Morfo            declara
MorfoRuntime     transcribe
Provider         aporta sources, targets y handlers
Effects          sincronizan attrs derivados
SemanticEngine   despacha señales a canales perceptivos
VisualChannel    materializa la señal en el DOM (data-event*, hold, cleanup)
ADom             aplica mutaciones DOM (commit estructural)

El reparto operativo

Morfo es DNA: un fichero por componente que declara parts, data-*, aria-*, role, keyboard, focus, events. No ejecuta nada.

MorfoRuntime (en soma/) interpreta el morfo. Una instancia por componente recibe del provider las fuentes de estado, los targets DOM y los handlers de eventos. Expone partProps(part), attachPart(part, target), keydown(part, event), trigger(eventName).

Provider aporta lo que el morfo no puede inferir: getters reactivos para states y props, getters reactivos para parts (ids dinámicos), handlers síncronos para los events, glue de layers ortogonales (Presence, Dismissal, ScrollLock — no son morfo).

Effects (registrados por el runtime al montar) escuchan cambios en los sources y aplican los attrs derivados vía dom.apply.

SemanticEngine recibe la ocurrencia desde runtime.trigger. Genera el id, despacha la señal a TODOS los canales registrados. El VisualChannel (built-in) escribe data-event-* directamente en el DOM, mantiene los attrs durante el hold configurado, los limpia y solo entonces resuelve la Promise (semántica secuencial estricta). Los canales no-visuales (sound, vibra) son fire-and-forget.

ADom solo aplica el commit estructural posterior. No interpreta. Sema y ADom son capas hermanas: el engine ya no depende de ADom.

La secuencia de runtime.trigger(eventName)

1. prewrite imperativo (transient markers como data-last-action)
2. await semantic.emit(event)
3. handler síncrono del provider muta state
4. effects derivan y aplican attrs estructurales (data-state, aria-*)

El handler muta state. Los effects ven el cambio y reescriben el DOM. ADom es el único escritor de attrs mutables.

Tres escenarios de Soma

// Cambio estructural sin señal
provider.commitState(change)
// internamente: dom.apply(change)

// Cambio estructural con señal
provider.commitState(change, event)
// internamente: await semantic.emit(event); dom.apply(change)

// Señal sin cambio estructural
provider.emitEvent(event)
// internamente: void semantic.emit(event)

Reglas operativas

  • Lo que dom.apply escribe, Svelte no lo renderiza. partProps solo emite identidad estática (id, marker, ref).
  • Los handlers de events son síncronos. Async va fuera del trigger.
  • Los guards (if (disabled) return) van en el call-site, no dentro del handler — si entran al handler, ya emitieron señal perceptiva.
  • Sema y ADom son capas hermanas: ninguna depende de la otra.
  • morfo.events.commits es descriptivo: documenta lo observable, no lo ejecuta. La cadena causal real es handler → state → effect.

3. Qué hace distinto a UIX

3.1 El contrato estructural es una capa propia

En la mayoría de librerías la estructura pública del componente está dispersa:

  • atributos en el provider
  • roles en el render
  • partes en CSS
  • selector names en docs
  • contratos en tests

UIX concentra eso en Morfo. Eso permite:

  • docs derivadas del contrato
  • validación cross-layer (linter de eidos)
  • menos drift entre headless y visual
  • tooling más fiable

3.2 La semántica no se mezcla con la ejecución

UIX separa el nombre de la ocurrencia de su materialización modal. Sonido, vibración, CSS y motores futuros usan el mismo vocabulario sin quedar pegados entre sí.

3.3 El comportamiento headless no carga con toda la modalidad

Soma no es un mega-engine que sabe de todo. No reproduce WAVs, no vibra, no decide la física perceptiva de cada canal. Soma emite. Los canales ejecutan.

3.4 El DOM activo es infraestructura de app

UIX reconoce que hay hechos transversales del DOM que varios consumidores quieren escuchar, y por eso introduce adom como servicio de app.

3.5 La app compone servicios, no "super componentes"

active-app permite que la aplicación componga lang, frontend, dom, format, semantic y los componentes los consuman vía getActiveUix().


4. Lo que UIX no es

UIX no es:

  • una colección plana de componentes visuales
  • un simple wrapper opinionated sobre primitives existentes
  • un design system clásico donde visual, comportamiento y contratos viven juntos
  • un semantic engine centralizado que ejecuta todas las modalidades
  • un EventEmitter global disfrazado de arquitectura

La originalidad de UIX no está en inventar nombres exóticos, sino en separar problemas reales que otros sistemas suelen aceptar como un único bloque.


5. Reglas de dependencia

Morfo            → declara contratos
MorfoRuntime     → interpreta morfo dentro de Soma
Provider         → aporta sources, targets, handlers
Effects          → sincronizan state → attrs
SemanticEngine   → registry + dispatch de señales a canales
VisualChannel    → materializa la señal en el DOM (data-event*, hold, cleanup)
ADom             → aplica mutaciones DOM (commit estructural)
Eidos            → materializa visualmente leyendo DOM
App              → compone servicios

Reglas duras:

  • Morfo no conoce Soma ni código de runtime
  • MorfoRuntime lee Morfo y depende de Sema
  • Provider no escribe attrs mutables al DOM directamente; los aporta como sources al runtime
  • SemanticEngine no conoce DOM. Solo registry + dispatch
  • VisualChannel accede al DOM directamente (no vía ADom); el commit estructural posterior va por ADom
  • Sema y ADom son capas hermanas
  • ADom no conoce Morfo, ni Sema, ni Soma, ni Eidos
  • Eidos consume DOM y data-*, no internals de Soma ni Sema
  • Lo que dom.apply escribe, Svelte no lo renderiza

Regla 2-de-3 para extender Morfo

Una extensión a Morfo solo se justifica si al menos dos de las tres capas (soma, sema, eidos) la consumen. Si solo soma se beneficia, el patrón es virtual prop en provider — no extender el contrato.

Extensión Soma Sema Eidos En morfo
parts[].archetype ✅ emit ✅ verbs por rol ✅ selectores transversales ✅
events[].semantic ✅ payload ✅ vocabulario ✅ tinta ✅
events[].prewrite ✅ ejecuta ✅ secuencia ✅ tinta exit ✅
firstOf value source ✅ only — — ❌
prop-not-nullish cond ✅ only — — ❌
Field-context OR — virtual prop — — ❌

Vocabularios canónicos cross-layer

  • Archetypes: clasificación de partes cross-component. Definida en src/uix/morfo/types.ts:ARCHETYPE_VOCABULARY. Emitida como data-archetype="..." por runtime.partProps.
  • Verbs: action verbs canónicos para morfo.events[].name. Definida en src/uix/sema/verbs.ts:SEMA_VERBS. Convención para composite names: {verb}-{variant} (e.g. commit-save, dismiss-outside).

6. La diferencia en una frase

Morfo declara, MorfoRuntime transcribe, Provider aporta, Effects sincronizan, Sema emite, ADom aplica.

Seis piezas, seis responsabilidades, ninguna invade a la siguiente.


7. Orden de lectura sugerido

  1. morfo/README.md — declaración, archetypes, regla 2-de-3
  2. sema/README.md — emit contract, verbs canónicos, canales
  3. eidos/README.md — qué consume eidos del DOM + wrappers
  4. soma/SOMA_ARCHITECTURE.md — runtime que transcribe morfo
  5. soma/COMPONENT_GUIDE.md — guía operativa para crear/migrar componentes
  6. src/arts/adom/README.md — dom.apply
  7. src/docs/sema-implementation-guide.md — convenciones doctrinales del API

Powered by TurnKey Linux.