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/sema/exports.ts

56 lines
1.3 KiB

export type {
SemaValencedFamily,
SemaTransitionalFamily,
SemaFamily,
SemaIntent,
SemaMode,
SemaRegime,
SemaScope,
SemaCause,
SemaEventLabel,
SemaIntentBinding,
SemaEvent,
SemaActionEvent,
SemaAttrWrite,
SemaCommit
} from './types'
export {
SEMA_VALENCED_FAMILIES,
SEMA_TRANSITIONAL_FAMILIES,
SEMA_INTENTS,
SEMA_EVENT_LABELS,
isSemaFamily,
isSemaValencedFamily,
isSemaTransitionalFamily,
isSemaIntent,
isSemaEventLabel,
isSemaIntentBinding,
isSemaEvent,
parseSemaEventLabel,
resolveSemaIntent,
normalizeSemaEvent,
toSemaEventLabel
} from './event'
sema: refactor into channel modules — engine becomes registry + dispatch Reorganización estructural según el spec acordado: cada canal perceptivo vive como módulo simétrico dentro de `chans/`. El engine queda mínimo (registry + dispatch); la lógica de escribir `data-event*` al DOM, mantener hold y retirar pasa al `VisualChannel`. La API pública que ven los providers (`semantic.emit(signal)`) se mantiene idéntica. Estructura nueva src/uix/sema/ ├── engine.ts registry + dispatch (ya no conoce DOM ni hold) ├── signal.ts SemanticSignal + nuevo campo opcional `id?` ├── exports.ts barrel actualizado (chans + drop publish + drop perception) └── chans/ ├── types.ts interfaz Channel { id, handle, dispose? } ├── visual.ts VisualChannel — escribe data-event*, hold, cleanup ├── visual.test.ts 9 tests del canal aislado ├── sound.ts SoundChannel placeholder (V1 no-op) └── vibra.ts VibraChannel placeholder (V1 no-op) Cambios al engine - Constructor: `new SemanticEngine(opts?)`. `opts.visual` controla el built-in (false / VisualChannelOptions / Channel custom). `opts.dom` desaparece — ya no es responsabilidad del engine. - Métodos: `register(channel)`, `getChannel(id)`, `emit(signal)`, `destroy()`. Nada más. - emit despacha a TODOS los canales registrados: - Canales no-visuales (sound, vibra, futuros): fire-and-forget. Errores se loguean pero no propagan (Sema es ornamental). - Canal visual: el único cuya Promise se awaitea — comparte plano DOM con el commit estructural posterior. - emit genera el `id` de la ocurrencia y lo pasa a todos los canales, garantizando coherencia cross-canal para tooling futuro. Cambios al VisualChannel (lógica heredada del emit() anterior) - 5 atributos: `data-event` + `data-event-id` + `data-event-phase` (siempre) + `data-event-family` y `data-intent` (opcionales si vienen en el signal). Los opcionales son la proyección al DOM de la metadata semántica que Eidos consume. - Hold defaults internos por familia (no exportados): emerge/commit/handle: 240ms · alert/sustain: 600ms · contact: 120ms Justificación técnica (rangos típicos de CSS transitions), no escala perceptiva universal. Override per signal vía `signal.hold` o global vía `new SemanticEngine({ visual: { defaultHold } })`. - Semántica secuencial estricta: cleanup ANTES del resolve. Eliminado - `src/uix/sema/perception.ts` — escalas perceptivas no son concepto cross-canal. La tabla de defaults por familia se movió al VisualChannel como detalle interno con justificación técnica. - `engine.publish()` y todo el sistema legacy: - `SemanticEventDecl`, `SemanticComponentContract`, `SemanticPublishContext`, `PublishedSemanticEvent`, `SemanticEventFilter` - `onEvent()` y subscribers - `applyPrewrites()` interno - dependencia opcional de `ActiveDom` por construcción - Tests de `publish()` reemplazados por tests del nuevo registry/dispatch. Bootstrap (App + defaults) - `src/lib/ext/app/app.svelte.ts:52` — `new SemanticEngine({ dom: this.dom })` → `new SemanticEngine()` - `src/lib/ext/app/defaults.ts:45` — mismo cambio Tests - emit.test.ts ajustado: sin createActiveDom, sin SEMA_PERCEPTION/HOLD_DEFAULTS, test "throws without dom" eliminado, números literales (240, 600). Añadido test "resolves immediately when visual: false". 7 tests. - engine.test.ts reescrito: register / getChannel / emit dispatch a múltiples canales / id propagation / id override / fire-and-forget para non-visual / error en canal no aborta dispatch / visual: false desactiva built-in / custom Channel reemplaza built-in / destroy. 13 tests. - chans/visual.test.ts nuevo: 5 attrs vs 3 / signal.hold respetado / family default fallback / global default fallback / constructor defaultHold / cleanup / sequential strict (resolve tras cleanup) / id field. 9 tests. - 39 tests sema verdes en total. Documentación - src/uix/sema/README.md — reescrito alrededor del modelo de canales - src/uix/eidos/events.css — comentario actualizado, referencia a chans/visual.ts - src/uix/active_architecture.md — sección Sema reescrita Componentes NO requieren cambios — la API `semantic.emit(signal)` es idéntica externamente. Toast / runtime.trigger / providers funcionan igual. Verificación - 121/121 tests focused suite (sema 39 + adom + lib/dom + morfo + soma/morfo) - 66/66 morfo-check - 68/68 smoke routes - svelte-check: 155 errors (baseline, sin nuevos) Pendientes en doc del spec marcados como "no-objetivos": - Implementación real de SoundChannel / VibraChannel (placeholders V1) - Arbitraje propio del VisualChannel (deuda heredada del emit anterior) - Cancelación si el target se desconecta durante el hold
6 months ago
export type { SemanticEngineOpts } from './engine'
export { SemanticEngine } from './engine'
export type { SemanticSignal } from './signal'
sema: refactor into channel modules — engine becomes registry + dispatch Reorganización estructural según el spec acordado: cada canal perceptivo vive como módulo simétrico dentro de `chans/`. El engine queda mínimo (registry + dispatch); la lógica de escribir `data-event*` al DOM, mantener hold y retirar pasa al `VisualChannel`. La API pública que ven los providers (`semantic.emit(signal)`) se mantiene idéntica. Estructura nueva src/uix/sema/ ├── engine.ts registry + dispatch (ya no conoce DOM ni hold) ├── signal.ts SemanticSignal + nuevo campo opcional `id?` ├── exports.ts barrel actualizado (chans + drop publish + drop perception) └── chans/ ├── types.ts interfaz Channel { id, handle, dispose? } ├── visual.ts VisualChannel — escribe data-event*, hold, cleanup ├── visual.test.ts 9 tests del canal aislado ├── sound.ts SoundChannel placeholder (V1 no-op) └── vibra.ts VibraChannel placeholder (V1 no-op) Cambios al engine - Constructor: `new SemanticEngine(opts?)`. `opts.visual` controla el built-in (false / VisualChannelOptions / Channel custom). `opts.dom` desaparece — ya no es responsabilidad del engine. - Métodos: `register(channel)`, `getChannel(id)`, `emit(signal)`, `destroy()`. Nada más. - emit despacha a TODOS los canales registrados: - Canales no-visuales (sound, vibra, futuros): fire-and-forget. Errores se loguean pero no propagan (Sema es ornamental). - Canal visual: el único cuya Promise se awaitea — comparte plano DOM con el commit estructural posterior. - emit genera el `id` de la ocurrencia y lo pasa a todos los canales, garantizando coherencia cross-canal para tooling futuro. Cambios al VisualChannel (lógica heredada del emit() anterior) - 5 atributos: `data-event` + `data-event-id` + `data-event-phase` (siempre) + `data-event-family` y `data-intent` (opcionales si vienen en el signal). Los opcionales son la proyección al DOM de la metadata semántica que Eidos consume. - Hold defaults internos por familia (no exportados): emerge/commit/handle: 240ms · alert/sustain: 600ms · contact: 120ms Justificación técnica (rangos típicos de CSS transitions), no escala perceptiva universal. Override per signal vía `signal.hold` o global vía `new SemanticEngine({ visual: { defaultHold } })`. - Semántica secuencial estricta: cleanup ANTES del resolve. Eliminado - `src/uix/sema/perception.ts` — escalas perceptivas no son concepto cross-canal. La tabla de defaults por familia se movió al VisualChannel como detalle interno con justificación técnica. - `engine.publish()` y todo el sistema legacy: - `SemanticEventDecl`, `SemanticComponentContract`, `SemanticPublishContext`, `PublishedSemanticEvent`, `SemanticEventFilter` - `onEvent()` y subscribers - `applyPrewrites()` interno - dependencia opcional de `ActiveDom` por construcción - Tests de `publish()` reemplazados por tests del nuevo registry/dispatch. Bootstrap (App + defaults) - `src/lib/ext/app/app.svelte.ts:52` — `new SemanticEngine({ dom: this.dom })` → `new SemanticEngine()` - `src/lib/ext/app/defaults.ts:45` — mismo cambio Tests - emit.test.ts ajustado: sin createActiveDom, sin SEMA_PERCEPTION/HOLD_DEFAULTS, test "throws without dom" eliminado, números literales (240, 600). Añadido test "resolves immediately when visual: false". 7 tests. - engine.test.ts reescrito: register / getChannel / emit dispatch a múltiples canales / id propagation / id override / fire-and-forget para non-visual / error en canal no aborta dispatch / visual: false desactiva built-in / custom Channel reemplaza built-in / destroy. 13 tests. - chans/visual.test.ts nuevo: 5 attrs vs 3 / signal.hold respetado / family default fallback / global default fallback / constructor defaultHold / cleanup / sequential strict (resolve tras cleanup) / id field. 9 tests. - 39 tests sema verdes en total. Documentación - src/uix/sema/README.md — reescrito alrededor del modelo de canales - src/uix/eidos/events.css — comentario actualizado, referencia a chans/visual.ts - src/uix/active_architecture.md — sección Sema reescrita Componentes NO requieren cambios — la API `semantic.emit(signal)` es idéntica externamente. Toast / runtime.trigger / providers funcionan igual. Verificación - 121/121 tests focused suite (sema 39 + adom + lib/dom + morfo + soma/morfo) - 66/66 morfo-check - 68/68 smoke routes - svelte-check: 155 errors (baseline, sin nuevos) Pendientes en doc del spec marcados como "no-objetivos": - Implementación real de SoundChannel / VibraChannel (placeholders V1) - Arbitraje propio del VisualChannel (deuda heredada del emit anterior) - Cancelación si el target se desconecta durante el hold
6 months ago
// ── Channels ───────────────────────────────────────────────────────────────
export type { Channel } from './chans/types'
export { VisualChannel, type VisualChannelOptions } from './chans/visual'
export { SoundChannel } from './chans/sound'
export { VibraChannel } from './chans/vibra'
sema: perceptually-anchored hold + sequential strict emit semantics Two architectural fixes surfaced by the eidos demo: 1. The previous default hold (1 rAF + 1 hold frame, ~30ms) was a technical timing decision — invisible to humans. Signals must be anchored to perceptual scales so they can actually be perceived. 2. The previous lifecycle resolved emit AFTER 1 rAF (caller's structural change ran in parallel with cleanup, ~30ms later). That's an implicit parallelism between event and state. The author has no way to say "wait for the announcement to be perceived before changing state". Sequential strict semantics (NEW) - emit writes the signal, awaits the full author-specified hold, cleans up, then resolves. State change happens AFTER cleanup — strictly sequential. - `signal.hold` is in milliseconds anchored to `SEMA_PERCEPTION` scales: subliminal 50ms below conscious threshold glimpse 120ms minimum perceptible without effort brief 240ms comfortable acknowledgement noticed 600ms sustained signal insistent 1200ms demands attention persistent 3000ms until acknowledged - Defaults per family in `SEMA_HOLD_DEFAULTS`: emerge: brief sustain: noticed contact: glimpse commit: brief alert: noticed handle: brief - Authors override per event via `SemanticSignal.hold` based on: - their CSS animation duration (so it completes before cleanup) - the perceptual scale they want - critical attention requirements (use insistent/persistent) Files - src/uix/sema/perception.ts (new) — SEMA_PERCEPTION + SEMA_HOLD_DEFAULTS + SEMA_OBSERVE_FRAME_MS constants with rationale anchored on Bloch's law, Material/Apple HIG motion guidelines, toast UX literature. - src/uix/sema/signal.ts — `hold` JSDoc updated to explain ms semantics + defaults + override pattern. - src/uix/sema/engine.ts — emit() refactored from rAF chain to setTimeout(holdMs); cleanup happens BEFORE resolve (sequential strict); `nextFrame()` helper removed; `resolveHoldMs(signal)` added with the 3-tier fallback (signal.hold → family default → SEMA_PERCEPTION.brief). - src/uix/sema/exports.ts — re-exports SEMA_PERCEPTION + SEMA_HOLD_DEFAULTS + SEMA_OBSERVE_FRAME_MS + SemaPerception type. - src/uix/sema/emit.test.ts — rewritten around fakeTimers + setTimeout (no more rAF queue); new test verifies cleanup runs BEFORE resolve. 7/7 tests green. - src/uix/sema/README.md — new "Duración del signal" section with the full perception scale + per-family defaults tables + override pattern. - src/uix/eidos/events.css — comment updated to explain the new hold windows; rule `[data-event^='dismiss']` etc. clarified. - src/uix/active_architecture.md — replaced "~13ms" prose with explicit perception-anchored scales; added explanation of "perceptual by design, not framerate". - src/uix/soma/components/toast/toast-provider.svelte.ts — new $effect that fires `present` + `announce` events when item ref attaches (one-shot guarded), so toasts emit signals on appear. The flash on /test/eidos is now visible thanks to (a) the perceptual hold and (b) the wired events. Channel parallelism note - Hold is the DOM channel duration only. - Future sound / vibra / motion engines subscribe to sema events independently; each owns its own timing relative to the event id. - Sema does not coordinate cross-channel sync — that's an integrator decision per app. Verification - 22/22 sema tests green. - 22/22 morfo runtime tests green. - 66/66 morfo-check + 68/68 smoke (verified before commit). - Probe shows announce signal on toast appear lasting ~600ms (alert family default) — visible in DevTools attribute panel. - svelte-check unchanged at 155. Pre-existing failure in src/uix/air/internal/canvas/layout.test.ts (`bun:test` import) is in the dead-branch air layer and unrelated.
6 months ago
sema: canonical action verb vocabulary (SEMA_VERBS) Cross-component verb names that morfo `events[].name` should preferably align with. Lets sema / sound / vibra engines subscribe by verb instead of by component-specific event name, and lets eidos write transversal selectors like `[data-event^="dismiss"]`. Vocabulary (24 verbs, grouped by family alignment) - emerge: present, dismiss, open, close, expand, collapse - commit: commit, cancel, confirm, submit, reset, fail - alert: announce, alert - contact: activate, select, toggle - handle: acknowledge, edit, drag, resize - sustain: tick, progress Composite event names follow `{verb}-{variant}` (e.g. `commit-save`, `dismiss-outside`). The verb is the head; the rest is component-specific nuance the validator extracts and reports separately. `validateEventName(name)` returns `{ name, head, matchesCanonical, variant }`. Advisory — doesn't reject morfos, just surfaces drift for tooling / review (a future `sema:vocabulary` script can use it to flag composite event names whose head isn't canonical). Existing event names already align well - Toast: `present`, `announce`, `dismiss` — all canonical bare verbs. - Dialog: `open`, `close-save`, `close-cancel`, `close-dismiss`, `close-dismiss-outside`, `close-after-fail` — all canonical heads (`open`, `close`) with variants. Tests: 10 unit tests covering vocabulary integrity, isSemaVerb guard, validateEventName splitting/matching, and a snapshot of current dialog + toast event names against the catalog (all match). This is the second extension justified under the "2-of-3 rule": verbs are consumed by sema (subscription routing) AND eidos (selector generation), with the original morfo authoring as the third producer.
6 months ago
export {
SEMA_VERBS,
validateEventName,
isSemaVerb,
type SemaVerb,
type VerbValidation
} from './verbs'
export { SemaInvariantError, validateSemaEvent, validateSemaIntentBinding } from './validation'

Powered by TurnKey Linux.