diff --git a/continue.md b/continue.md index 929c376e2..fffafeddb 100644 --- a/continue.md +++ b/continue.md @@ -107,6 +107,13 @@ Actualizacion 2026-05-16: - Guardia nueva: `src/uix/contracts.test.ts` rechaza imports internos de Soma hacia su propio alias publico, dejando `$soma/*` para consumidores externos y tests de superficie. + - Cerrado: el barrel raiz `$soma` queda limitado al scope `Soma` y su error + de contexto. Helpers como `provider`, `keyboard`, `runtime.svelte`, + `types`, `css`, `id`, `props`, `components`, `layers` y `datetime` se + consumen desde sus subpaths explicitos. + - Documentacion corregida: README, arquitectura y comentario de + `core/soma.svelte.ts` ya no recomiendan que el propio Soma importe desde + `$soma/*`. - Smoke Playwright de rutas `/uix` actuales cerrado: `/uix`, Accordion, Checkbox, Collapsible, Dialog, Drawer, Popover, RadioGroup, Switch, Tabs, Toast, Toggle y Tooltip cargan con HTTP 200, diff --git a/src/uix/contracts.test.ts b/src/uix/contracts.test.ts index 727b8133f..6ea732341 100644 --- a/src/uix/contracts.test.ts +++ b/src/uix/contracts.test.ts @@ -390,6 +390,16 @@ describe('UIX layer contracts', () => { expect(violations).toEqual([]); }); + it('guards Soma root barrel as scope-only', () => { + const source = readFileSync(join(HERE, 'soma', 'index.ts'), 'utf8'); + + expect(source).toContain("from './core/soma.svelte'"); + expect(source).toContain("from './errors'"); + expect(source).not.toMatch( + /from ['"]\.\/(?:provider|props|keyboard|typeahead|css|id|types|runtime\.svelte|components|layers|datetime|color)/ + ); + }); + it('guards Soma internals from importing their own public alias', () => { const violations = listSourceFiles(join(HERE, 'soma')) .filter((file) => { diff --git a/src/uix/soma/README.md b/src/uix/soma/README.md index 075c67728..fe6a54b56 100644 --- a/src/uix/soma/README.md +++ b/src/uix/soma/README.md @@ -95,15 +95,17 @@ al revés. Los motores reutilizables que no son comportamiento headless viven fuera de Soma: `src/libs/datagrid` para tablas, `src/libs/forms` para estado/validacion -de formularios y `src/libs/strings` para scoring/fuzzy search. Soma puede -reexportarlos cuando forman parte de la DX del componente, pero no los posee. +de formularios y `src/libs/strings` para scoring/fuzzy search. Soma no los +reexporta: los consumidores importan esos motores desde `$libs/*`, que es su +fuente canonica. ### Imports **Dentro de un componente/layer Soma**: usar paths relativos para piezas del mismo componente o de Soma. Para servicios/utilidades cross-layer usar el alias -canonico (`$libs/*`, `$uix/morfo`, `$adom`, `$soma/*`) para dejar clara la -frontera de ownership. +canonico (`$libs/*`, `$uix/morfo`, `$adom`) para dejar clara la frontera de +ownership. El alias `$soma/*` es superficie publica para consumidores, no para +imports internos del propio Soma. ```ts // Inside a component — relative @@ -119,7 +121,7 @@ import { createTable } from '$libs/datagrid'; ```ts // Consumer code — alias -import { commonLangs } from '$soma/core/langs'; +import { Soma } from '$soma'; import * as Drawer from '$soma/components/drawer'; ``` @@ -223,8 +225,7 @@ src/uix/soma/ │ ├── exports.ts ← barrel (Provider, not Root) │ └── index.ts │ -├── exports.ts ← barrel principal -└── index.ts +└── index.ts ← root scope only (`Soma`) ``` --- diff --git a/src/uix/soma/SOMA_ARCHITECTURE.md b/src/uix/soma/SOMA_ARCHITECTURE.md index 25b940fe8..488a1ce39 100644 --- a/src/uix/soma/SOMA_ARCHITECTURE.md +++ b/src/uix/soma/SOMA_ARCHITECTURE.md @@ -72,6 +72,7 @@ Los layers, el sistema reactivo, el floating engine — son implementacion inter - clases concretas de estado + `SomaRuntime` - `Soma` class para servicios - Barrel imports jerárquicos (`import { Dialog } from '$soma/components'`) +- subpaths explicitos cuando necesita helpers publicos (`$soma/provider`, `$soma/keyboard`, `$soma/runtime.svelte`) ### 3.2 Un patron, no tres @@ -612,8 +613,9 @@ CLOSING: ## 7. Soma class (component runtime scope) Soma reads `ActiveUix` from context and exposes services to components. -Components import from `$soma`, never from `$active-app`. Nestable: child -`` overrides parent. +Components import Soma internals through relative paths, never from +`$active-app` and never through their own `$soma/*` public alias. Nestable: +child `` overrides parent. ```ts class Soma { @@ -858,7 +860,7 @@ src/uix/soma/ │ │ ├── {name}-trigger.svelte │ │ └── ... │ └── index.ts ← hierarchical barrel -└── index.ts ← main barrel +└── index.ts ← root scope only (`Soma`) ``` ### File naming convention diff --git a/src/uix/soma/core/soma.svelte.ts b/src/uix/soma/core/soma.svelte.ts index 94c18ccb2..cd5d5f632 100644 --- a/src/uix/soma/core/soma.svelte.ts +++ b/src/uix/soma/core/soma.svelte.ts @@ -27,8 +27,9 @@ export interface SomaOptions { * * Reads `ActiveUix` from Svelte context (`getActiveUix()`) and exposes * services to soma components through a stable adapter surface. Soma - * components import from `$soma`, NEVER from `$active-app` directly — - * the UIX layer is decoupled from the App composition layer by design. + * components import local internals through relative paths, NEVER from + * `$active-app` directly — the UIX layer is decoupled from the App + * composition layer by design. * * The adapter exposes the services soma actually consumes: langs, DOM, * events, format slices and prefs view. diff --git a/src/uix/soma/index.ts b/src/uix/soma/index.ts index c715cb291..3de182134 100644 --- a/src/uix/soma/index.ts +++ b/src/uix/soma/index.ts @@ -1,84 +1,7 @@ -// ── Provider helpers (context + opts bridge) ──────────────────────────────── -export { - type ProviderOpts, - type WithRefOpts, - context, - type SomaContext, - bindProps, - type OptsFromProps, - type WritableSpec, - type PropsConfigEntry -} from './provider'; - -// ── Props ──────────────────────────────────────────────────────────────────── -export { mergeProps, composeHandlers } from './props'; - -// ── Keyboard ───────────────────────────────────────────────────────────────── -export { KEYS, FIRST_KEYS, LAST_KEYS, SELECTION_KEYS, getDirectionalKeys } from './keyboard'; - -// ── Typeahead ──────────────────────────────────────────────────────────────── -export { - Typeahead, - TypeaheadBuffer, - matchTypeahead, - type TypeaheadOptions, - type TypeaheadSearchOptions, - type TypeaheadText -} from './typeahead'; - -// ── CSS ────────────────────────────────────────────────────────────────────── -export { cssToStyleObj, styleToString, srOnlyStyles } from './css'; - -// ── ID ─────────────────────────────────────────────────────────────────────── -export { createId, useId } from './id'; - -// ── Types ──────────────────────────────────────────────────────────────────── -export type { - Orientation, - Direction, - OnChangeFn, - WithChild, - WithChildNoChildrenSnippetProps, - WithChildren, - Without, - SomaEvent, - SomaKeyboardEvent, - SomaMouseEvent, - SomaFocusEvent, - SomaInputEvent, - PrimitiveDivAttributes, - PrimitiveButtonAttributes, - PrimitiveInputAttributes, - PrimitiveSpanAttributes -} from './types'; - -// ── Soma (root instance) ───────────────────────────────────────────────────── +// Root scope only. Components, runtime helpers and shared utilities are +// imported from their explicit subpaths (`$soma/components`, `$soma/runtime.svelte`, +// `$soma/provider`, etc.) to avoid duplicate public surfaces. export { Soma } from './core/soma.svelte'; export type { SomaOptions } from './core/soma.svelte'; -// ── SomaRuntime (per-instance morfo interpreter) ──────────────────────────── -// Per the doctrine "morfo declares, soma executes" — the runtime that -// interprets a CompiledMorfo lives in soma. Providers consume it via the -// current `Soma` scope (`soma.runtime(morfo, sources)`); pure consumers can -// import `createSomaRuntime` directly from here. -export { - createSomaRuntime, - type SomaRuntime, - type SomaRuntimeSources, - type SomaRuntimePartBaseOpts, - type SourceMap, - type EventEngineEmitter, - type SomaRuntimePart, - type SomaRuntimePartOpts, - type TriggerOptions, - type EventHandler, - type KeyboardActionHandler -} from './runtime.svelte'; - -export { - SomaNoContextError, - SomaProviderContextNotFoundError, - SomaRuntimeEventError, - SomaRuntimePartError, - SomaRuntimeTargetError -} from './errors'; +export { SomaNoContextError } from './errors';