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/active-uix/README.md

116 lines
6.2 KiB

# ActiveUix
`active-uix` es la raiz de composicion de UIX. Su responsabilidad no es ser
otra capa de comportamiento, sino entregar a `morfo`, `soma`, `sema` y `eidos`
los servicios minimos que necesitan sin que los componentes conozcan
`ActiveApp` directamente.
## Handoff 2026-05-14
La regla de ownership queda cerrada:
> Solo los composition roots crean servicios compartidos. Si hay `ActiveApp`,
> `attachActiveUix(app)` consume sus servicios y falla si falta alguno
> requerido. Si no hay app, `createActiveUix(...)` es el composition root local
> y crea los servicios/prefs de UIX. `morfo`, `soma`, `sema`, `eidos` y los
> componentes no crean `dom`, `langs`, `prefs`, `format` ni equivalentes.
La revision de naming queda cerrada asi: `events` es el nombre publico del
motor perceptivo en `ActiveUix` y tambien el nombre del servicio que
`defineUixServices(...)` registra en `ActiveApp`. `semantic` queda reservado
para el payload declarativo de `morfo.events[].semantic`, no para servicios
runtime. `morfo.translations` queda como catalogo declarativo owned por el
componente. `prefs` es el unico nombre para preferencias: `ActiveUix` expone
el `ActivePrefs` bruto y las capas inferiores consumen vistas acotadas cuando
no deben mutar.
## Boot paths actuales
`createActiveUix(options)` compone un runtime standalone:
- crea `logger`, `timers`, `bus` y `prefs`;
- el `bus` usa `createSvelteEngineBus({ logger, clock: timers.clock })`,
igual que `ActiveApp`, para que los listeners corran bajo `untrack`;
- crea `langs`, `dom` o `disabledDom`, `format` y `events` segun opciones;
- conserva `portal` como target generico de portales para que cada capa lo
adapte a su API sin acoplar `active-uix` a esa capa;
- registra traducciones comunes y `morfo.translations`.
`attachActiveUix(app, options)` se adjunta a un `ActiveApp` externo:
- reutiliza `app.prefs`, `app.langs`, `app.dom` y `app.format` si existe;
- exige `app.langs` y `app.dom`; si faltan, lanza error de configuracion;
- no vuelve a suscribir `langs` a `prefs.language`: esa conexion pertenece
a `defineActiveLangs` dentro de `ActiveApp`;
- registra traducciones comunes y `morfo.translations`;
- no posee el lifecycle del `app`.
## Contratos actuales
| Modulo | Minimo requerido | Opcional | Fallback si falta | Error si falta |
| ------------------------ | ----------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------ | ------------------------------------------------- |
| `ActiveUix` standalone | `langs` config | `format`, `events`, `portal`, `dom:false` | crea `prefs`, core services y, si `dom:false`, `disabledDom` local | falta config `langs` |
| `ActiveUix` attach | `ActiveApp` core + services `langs`, `dom` | `app.format`, app event engine, `portal` | ninguno para servicios requeridos | falta `langs` o `dom` en app |
| `SomaRuntime` | `dom` desde `ActiveUix` | event engine, `langs`, `format` | ninguno propio | morfo/event/part inexistente |
| `Sema` desde `ActiveUix` | `dom/projector` inyectado por `ActiveUix` | `sound`, `haptic` | ninguno propio de servicios UIX | por definir para uso directo fuera de `ActiveUix` |
| `Eidos` | `dom` si `applyDom` | `langs`, `format`, `prefs`, mode/density sources | `applyDom:false` permite render/serializar sin DOM | falta `dom` con `applyDom` activo; componentes visuales fallan si leen un servicio no inyectado |
| `ADom` | superficie `ActiveDom` | breakpoints/window | `disabledDom` en UIX | por definir fuera de UIX |
## Decisiones cerradas y riesgos abiertos
1. `dom:false` solo degrada en standalone: `ActiveUix` expone un
`disabledDom` local y no deja a Sema/events caer a escrituras directas.
2. En attach mode no hay creacion compensatoria: si la app no tiene `dom`,
`attachActiveUix(app)` falla.
3. Standalone usa el mismo bus Svelte-aware que `ActiveApp`.
4. Attach mode no duplica la suscripcion `prefs.language -> langs`.
5. `langs` no es `locale`: `prefs.language` alimenta traducciones;
`prefs.locale` alimenta formatos.
6. `prefs.direction` es la preferencia efectiva de direccion; `html[dir]` es
solo su proyeccion DOM.
7. Los wrappers/componentes no deben ser el lugar donde se resuelvan estas
politicas. Primero se cierra el contrato de la raiz activa.
8. `frontend` no es capa obligatoria de UIX. Queda como servicio legacy
opt-in de `ActiveApp`. `ActiveUix` no proyecta preferencias al DOM:
`arts/prefs` proyecta lo transversal y `ActiveEidos` proyecta lo visual.
9. `ActiveUix` no crea ni conoce `Soma` ni `Eidos`: `Soma.create(...)` crea
su scope y `Soma.runtime(...)`; `ActiveEidos.create(...)` crea el scope
visual si la app necesita CSS runtime.
## Boot de una shell UIX
Una shell que usa componentes visuales debe cablear tres piezas de forma
explicita:
```ts
const uix = createActiveUix({ langs, prefs: { schema } });
setActiveUix(uix);
Soma.create();
const prefsProjection = createActivePrefsDomProjection({
prefs: uix.prefs,
dom: uix.dom
});
const eidos = ActiveEidos.create({
theme: 'base',
modeSource,
applyDom: true
});
```
`prefsProjection` es el dueño de `dir`, `data-motion`, `data-sound` y
`data-haptic`. `ActiveEidos` es el dueño de `data-theme`, `data-mode` y
`data-density`. No escribir `uix.prefs.setIntent('theme', ...)`: `theme` no
existe en el preset core de UIX y provocara `prefs::unknown_dimension`.
## Regla de trabajo vigente
Tras cerrar P1, siguen vigentes estas restricciones:
- no tocar `src/uix/eidos/components/*`;
- no crear nuevas fachadas internas;
- no introducir `Engine*`/`Active*` por simetria decorativa;
- cualquier cambio debe justificar que contrato minimo aclara.

Powered by TurnKey Linux.