Runtime, Events & Actions
Die Browser-Runtime macht serverseitig gerenderte Seiten interaktiv — nach klaren Verträgen.
Lifecycle
Invisible.mount(root) instanziiert für jedes Element mit Client-Controller dessen Klasse (WeakMap — keine Doppel-Initialisierung) und ruft mount(root, context). destroy() löst alle Listener (AbortController-Signal für async). Kein MutationObserver — wer DOM einsetzt, mountet explizit.
Semantische Events → Actions
Controller/Element: emit('activate') — meldet BEDEUTUNG, kennt keine Folgen
Surface-JSON: "on": { "activate": { "action": "action.notify.show",
"params": { "title": "…" } } }
Dispatcher: validiert Action + Params → routet zum Service
Service: führt aus (navigation | window | notify)
Der Dispatcher ist bewusst begrenzt: nur registrierte Actions, validierte Parameter (Typen, Enums, URL-Schemata), eine Action pro Event, $bind-Auflösung gegen den read-only Datenkontext — keine JS-Strings, keine Ketten. Übernimmt keine Action, bleibt das native Verhalten (Progressive Enhancement).
| Service | Zuständig für |
|---|---|
| Navigation | action.navigation.goto — URL-Schema bereits validiert |
| Window (Desktop) | Fenster-Zustand (offen/aktiv/minimiert, z-Index über layer.window), action.app.open, Legacy-Bridge openwindow() |
| Notification | Toast-Stapel — Invisible.notify.show(); baut Markup/Styles selbst (token-basiert), da Toasts keine Surface-Nodes sind |