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.
101 lines
5.1 KiB
101 lines
5.1 KiB
# ActiveUix
|
|
|
|
`active-uix` es la raíz de composición de UIX. Su responsabilidad no es ser otra
|
|
capa de comportamiento, sino entregar a `morfo`, `soma`, `sema` y `eidos` los
|
|
servicios mínimos que necesitan, sin que los componentes conozcan `ActiveApp`
|
|
directamente.
|
|
|
|
> **Arquitectura de conjunto**: [`../active_architecture.md`](../active_architecture.md).
|
|
> **Contrato ejecutable**: [`contracts.ts`](../contracts.ts), validado en
|
|
> [`contracts.test.ts`](../contracts.test.ts).
|
|
|
|
## Dos modos de arranque
|
|
|
|
`createActiveUix(options)` — **standalone**. Compone un runtime propio:
|
|
|
|
- crea `logger`, `timers`, `bus` y `prefs`;
|
|
- el `bus` usa `createSvelteEngineBus({ logger, clock: timers.clock })`, igual que
|
|
`ActiveApp`, para que los listeners corran bajo `untrack` y no creen
|
|
dependencias reactivas accidentales;
|
|
- crea `langs`, `dom` (o `disabledDom` si `dom:false`), `clipboard`, `format` y
|
|
`events` según opciones;
|
|
- conserva `portal` como target genérico de portales, para que cada capa lo
|
|
adapte a su API (`portalTo`) sin acoplar `active-uix` a esa capa;
|
|
- registra las traducciones comunes y las `morfo.translations`.
|
|
|
|
`attachActiveUix(app, options)` — **attach** a un `ActiveApp` externo:
|
|
|
|
- reutiliza `app.prefs`, `app.langs`, `app.dom`, `app.clipboard` y `app.format`
|
|
cuando existen;
|
|
- **exige** `app.langs` y `app.dom`; si faltan, lanza error de configuración;
|
|
- no vuelve a suscribir `langs` a `prefs.language` (esa conexión pertenece a
|
|
`defineActiveLangs` dentro de `ActiveApp`);
|
|
- registra las traducciones comunes y las `morfo.translations`;
|
|
- no posee el lifecycle del `app`.
|
|
|
|
## Contratos mínimos por módulo
|
|
|
|
> Fuente ejecutable: [`contracts.ts`](../contracts.ts).
|
|
|
|
| Módulo | Mínimo requerido | Opcional | Fallback si falta | Error si falta |
|
|
| --- | --- | --- | --- | --- |
|
|
| `ActiveUix` standalone | `langs` config | `clipboard:false`, `format`, `events`, `portal`, `dom:false` | crea `prefs`, core services y, si `dom:false`, `disabledDom` local | falta config `langs` |
|
|
| `ActiveUix` attach | `ActiveApp` core + servicios `langs`, `dom` | `app.clipboard`, `app.format`, motor de eventos, `portal` | ninguno para servicios requeridos | falta `langs` o `dom` en app; el getter de un servicio opcional ausente falla explícito |
|
|
| `SomaRuntime` | `dom` desde `ActiveUix` | motor de eventos, `langs`, `format` | ninguno propio | morfo/event/part inexistente |
|
|
| `Sema` directo | `dom` o `projector` si `visual` activo | `sound`, `haptic`, `visual:false` | ninguno propio de servicios UIX | `SemaConfigError` sin `dom/projector` con visual activo |
|
|
| `Eidos` | `dom` si `applyDom` | `langs`, `format`, `prefs`, fuentes mode/density | `applyDom:false` permite render/serializar sin DOM | falta `dom` con `applyDom` activo |
|
|
| `ADom` directo | target/window/document del caller | breakpoints/window | `disabledDom` solo si el caller lo pide | errores propios de ADom sin DOM real |
|
|
|
|
## Reglas de ownership y degradación
|
|
|
|
1. **Solo los composition roots crean servicios compartidos.** `morfo`, `soma`,
|
|
`sema`, `eidos` y los componentes nunca crean `dom`, `langs`, `prefs`,
|
|
`format`, `clipboard` ni equivalentes: los reciben de `ActiveUix`.
|
|
2. **`dom:false` solo degrada en standalone.** `ActiveUix` expone un
|
|
`disabledDom` local y se lo pasa también a `EngineSemantic`; Sema/events no
|
|
caen a escrituras DOM directas. En attach no hay creación compensatoria: si la
|
|
app no tiene `dom`, `attachActiveUix(app)` falla.
|
|
3. **`langs` no es `locale`.** `prefs.language` alimenta las traducciones;
|
|
`prefs.locale` alimenta los formatos. No se mezclan.
|
|
4. **`clipboard` es un servicio de capacidad, no DOM visual.** Standalone lo crea
|
|
salvo `clipboard:false`; attach lo consume de `app.clipboard` cuando una capa
|
|
lo pide, y falla con error explícito si no se declaró.
|
|
5. **`prefs.direction` es la preferencia efectiva de dirección**; `html[dir]` es
|
|
solo su proyección DOM.
|
|
6. **`ActiveUix` no auto-proyecta preferencias al DOM.** `arts/prefs` proyecta lo
|
|
transversal (`dir`, `data-motion`, `data-sound`, `data-haptic`) vía
|
|
`createActivePrefsDomProjection`; `ActiveEidos` proyecta lo visual
|
|
(`data-theme`, `data-mode`, `data-density`). El artefacto `frontend` fue
|
|
retirado y no debe reaparecer como fuente de `locale`.
|
|
7. **`ActiveUix` no crea ni conoce `Soma` ni `Eidos`.** `Soma.create(...)` crea su
|
|
propio scope y `Soma.runtime(...)`; `ActiveEidos.create(...)` crea el scope
|
|
visual cuando la app necesita CSS runtime.
|
|
|
|
## Arrancar una shell UIX
|
|
|
|
Una shell que usa componentes visuales cablea tres piezas de forma explícita:
|
|
|
|
```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`. El modo claro/oscuro se pasa a `ActiveEidos.modeSource`, no a
|
|
`prefs.theme` — `theme` no forma parte del preset core de UIX y escribirlo
|
|
provoca `prefs::unknown_dimension`.
|