# AURA im Browser

AURA kann als WebAssembly-Anwendung vollständig im Browser laufen. Der Browser-Port verwendet den bestehenden C++-Szenengraph, Skia, SDL3, Parser, Layoutcode und die Bindungen. Er übersetzt die Oberfläche nicht in HTML-Widgets. Die erste Zielplattform sind interaktive AURA-Webanwendungen; der Playground verwendet dieselbe Laufzeit.

## Drei Einstiegspunkte

| Anwendung | Was läuft im Browser? |
|---|---|
| [aura-hello](../../web/hello.html) | Das kleine Beispiel mit beim Build generiertem C++-Code und bedienbarem Zähler |
| [aura-demo](../../web/demo.html) | Die vollständige Galerie als C++-Anwendung, mit allen acht Seiten und gekennzeichneten Plattformgrenzen |
| [Playground](../playground.html) | Bearbeitbarer AURA-Quelltext neben einer interaktiven Vorschau; Änderungen laufen über den dynamischen Loader |

Die eigenständigen Beispiele prüfen den kompilierten Ausführungsweg. Der Playground prüft den dynamischen Weg mit demselben Parser und Szenengraph. C++ wird im Editor nicht kompiliert. Die kleinen Playground-Beispiele reagieren über Inline-Skripte; die Controller der vollständigen Demo sind bereits Bestandteil ihres Wasm-Builds.

Die Demo unterstützt zum Beispiel diese URLs:

```text
/web/demo.html?language=en
/web/demo.html?dynamic=1&language=en
/web/demo.html?page=motion
```

`dynamic=1` lädt die mitgelieferten `.aura`-Dateien zur Laufzeit. Die Projektdateien und C++-Controller der gesamten Galerie werden derzeit nicht im Playground bearbeitet.

## Bauen

Benötigt werden ein nativer C++20-Compiler für `aurac`, CMake, Ninja, Git, Python 3 und das aktivierte Emscripten-SDK **4.0.23**. Die Skia-Version ist auf einen konkreten Stand von **m144** festgelegt. Alle Skia- und AURA-Archive müssen mit denselben Wasm-, Thread- und Exception-Einstellungen gebaut sein; native Skia-Bibliotheken sind dafür nicht verwendbar.

Vom AURA-Checkout aus:

```bash
# SDK 4.0.23 vorher installieren und aktivieren.
# Verzeichnisse sind Beispiele und dürfen frei gewählt werden.
tools/web/build-skia.sh /path/to/emsdk /path/to/skia
tools/web/build.sh /path/to/emsdk /path/to/skia build/web
```

`build-skia.sh` lädt den festgelegten Skia-Quellstand und seine benötigten Abhängigkeiten und baut echte C++-Bibliotheken für Wasm. Der Port verwendet keine zweite CanvasKit-JavaScript-Darstellungsschicht. Ein vorhandener Skia-Checkout mit anderem Stand wird nicht automatisch umgestellt.

`build.sh` baut zunächst einen nativen Host-`aurac`, danach `aura-hello`, `aura-demo` und die dynamische Vorschau. Das Ergebnis liegt unter `build/web/web/`:

```text
hello.html
hello.js / hello.wasm / hello.data
demo.html
... zugehörige JavaScript-, Wasm- und Ressourcendateien
preview.html
... zugehörige JavaScript-, Wasm- und Ressourcendateien
```

Die genaue Aufteilung zusätzlicher Workerdateien hängt vom Emscripten-Build ab. Zum Ausliefern wird immer das gesamte Ausgabeverzeichnis benötigt, nicht nur die HTML-Dateien. `AURA_WEB_JOBS` begrenzt die parallelen Buildjobs; ohne Angabe verwendet das Skript höchstens acht.

## Lokal starten und Website einbinden

Für die eigenständigen Anwendungen:

```bash
python3 tools/web/serve.py build/web/web
```

Der Server zeigt seine lokale URL an, standardmäßig `http://127.0.0.1:8798`. Er liefert die für Browser-Threads benötigten Header mit.

Für die Website wird die vollständige Browser-Ausgabe nach `docs/website/web/` kopiert. Der Website-Build übernimmt sie nach `dist/web/`:

```bash
mkdir -p docs/website/web
cp -a build/web/web/. docs/website/web/
python3 docs/website/build.py
python3 docs/website/check.py
python3 tools/web/serve.py docs/website/dist
```

Ohne Browser-Payload bleibt die Dokumentation baubar; der Playground meldet die fehlende Runtime ausdrücklich. Er simuliert keine erfolgreiche AURA-Ausführung. Der [Playground](../playground.html) verwendet die echte Wasm-Anwendung.

## Hosting und Browser-Threads

Der erste Port verwendet Emscripten-pthreads und `SharedArrayBuffer`, unter anderem für vorhandene Hintergrundaufgaben. Deshalb benötigt die übergeordnete Website Cross-Origin-Isolation und im Produktivbetrieb HTTPS. Die ausgelieferten Antworten müssen diese Header tragen:

```text
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
```

Auch die Playground-Seite muss so ausgeliefert werden; Header nur auf der eingebetteten Vorschau genügen nicht. Ressourcen werden vom eigenen Ursprung geladen. Fremde Bilder, Skripte oder Frames müssen später mit den dafür passenden CORS-/CORP-Regeln eingebunden werden.

Der Website-Build erzeugt eine `.htaccess` für Apache mit diesen Headern und `application/wasm` als MIME-Typ. Dafür müssen `mod_headers`, `mod_mime` und die passenden `AllowOverride`-Rechte verfügbar sein. Andere Server benötigen eine entsprechende Konfiguration. Ein einfacher `python -m http.server` setzt diese Header nicht.

## Lebensdauer und Ereignisschleife

Nativ blockiert `Application::run()`, bis die Anwendung beendet wird. Im Browser registriert `run()` Frame-Callbacks und kehrt zurück. Anschließend ruft der Browser die Anwendung weiter auf. App, Kontext, Controller und die von Callbacks verwendeten UI-Objekte müssen deshalb über das Ende von `main()` hinaus leben.

Ein kleiner Einstieg kann diese Lebensdauer mit statischen Objekten sichern:

```cpp
int main()
{
    static AuraApplication app({.title = "Hello"});
    if (!app.init()) return 1;
    static AuraBasicContext<> ctx(app);
    static auto ui = views::Hello::build(app.addFrame(), ctx);
    return app.run();
}
```

Bei größeren Anwendungen hält ein gemeinsames langlebiges App-Objekt Kontext, Controller und Szene zusammen. Eine lokale Variable, deren Destruktor bei der Rückkehr aus `main()` läuft, darf nicht weiter von einem Browser-Callback verwendet werden. Die Browser-Ereignisschleife darf nicht durch eine eigene Warteschleife blockiert werden.

## Live bearbeiten

Der Playground sendet Quelldateien als Daten an einen gleichursprünglichen Vorschau-Frame. Dort prüfen der echte Parser und die semantischen Regeln die Dateien, anschließend baut der Loader einen neuen Szenenbaum. Nur ein erfolgreicher Aufbau ersetzt die bisherige Szene. Bei Syntax- oder Aufbaufehlern bleiben die letzte gültige Vorschau und ihre Eingabefähigkeit erhalten; Diagnostik zeigt Datei, Zeile und Spalte, soweit verfügbar.

Jede erfolgreiche Änderung startet den Beispielzustand neu. „Live aktualisieren“ bündelt Eingaben kurz; „Ausführen“ oder Strg/⌘+Enter startet sofort. „Beispiel zurücksetzen“ lädt den ursprünglichen Quelltext. Fehlermeldungen lassen sich anklicken, um die betroffene Stelle im Editor zu markieren. Hello, Slider und Texteingabe sind die ersten editierbaren Beispiele.

Quelltext wird nicht zur Ausführung an einen Server gesendet. JavaScript und Lua innerhalb der AURA-Handler laufen in `aura-script`, nicht über `eval` im Website-JavaScript. Die vorhandenen Skriptlimits bleiben wirksam. Der Frame prüft Nachrichtenursprung und Absender; Änderungsantworten sind sequenziert, damit alte Antworten keine neuen Fehlermeldungen überschreiben.

## Grenzen des ersten Ports

| Bereich | Browserstand |
|---|---|
| Widgets, Text, Layout, Zustände, Bindungen, Animationen | Gemeinsamer C++-Code; die Demo zeigt die verfügbaren Funktionen |
| Ressourcen | Mitgelieferte Dateien im virtuellen Dateisystem; beliebige lokale Dateipfade des Besuchers sind nicht zugänglich |
| Tasks und Timer | Browser-Thread-/Ereignisschleifen-Anbindung; kein eigener blockierender UI-Loop |
| HTTP-Client | Ein Browseradapter ist noch nicht implementiert; `aura-net` steht in diesem Port nicht zur Verfügung |
| HTTP-Server, eigene TLS-Server/Zertifikattests, Remote-HTTP-Server | Nicht verfügbar |
| Kindprozesse, SCSI, Hotplug/usbmuxd und native Systemdaten | Nicht verfügbar; Demo zeigt die Einschränkung, keine vorgetäuschten Ergebnisse |
| CEF-WebView | Nicht verfügbar; WebView ist kein Browser-im-Browser-Ersatz |
| HEIF/HEIC | In diesem Build deaktiviert |

Der Playground begrenzt ein Update auf **32 Dateien**, **256 KiB je Datei** und **1 MiB Quelltext insgesamt**. Pfade müssen gültige relative `.aura`-Pfade ohne Verzeichnis-Ausbruch sein. Zusätzlich werden Schachtelung und Komponentenexpansion auf **128 Ebenen** sowie der Quelltext auf **100.000 Tokens** begrenzt; rekursive Komponentenzyklen werden zurückgewiesen. Diese Grenzen betreffen die editierbare Vorschau, nicht die Dateigröße eines ausgelieferten Wasm-Programms.

In dieser ersten Browser-Laufzeit ist `range()` auf höchstens **10.000** Einträge begrenzt; nicht endliche Werte werden abgelehnt. Höchstens **20.000 Szenenknoten** dürfen gleichzeitig existieren, einschließlich einer neuen und der noch sichtbaren alten Vorschau. Anwendungen können die Knotengrenze beim Build über `AURA_WEB_NODE_LIMIT` anpassen. Diese Laufzeitgrenzen gelten auch für spätere Bindungs-Neuaufbauten.

Die Darstellung erfolgt im Canvas. Vollständige semantische Browser-Barrierefreiheit, browsertypische Textauswahl, umfassende mobile Tastatur-/IME-Prüfung und die Freigabe aller Browser sind noch offene Arbeiten. Ein funktionierendes Beispiel ist keine Zusage, dass sämtliche nativen APIs im Web verfügbar sind.

Jede Anwendung bringt derzeit eigene kompilierte Laufzeitdateien mit. Downloadgröße, Startzeit, Cacheverhalten und Speicherverbrauch müssen für konkrete Anwendungen gemessen werden. Serverseitige Kompression und geeignetes Caching können später ergänzt werden; dafür gibt es hier keine pauschale Leistungszusage.

Die Ausdruckstiefe wird durch `parseBounded()` bereits beim Parsen auf **128 Ebenen** begrenzt; auch lange flache Operatorfolgen und `when`-Ketten werden geprüft, bevor ein tiefer AST entsteht. [Gebündelte Lizenzhinweise](../../web/NOTICE.txt).
