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 Das kleine Beispiel mit beim Build generiertem C++-Code und bedienbarem Zähler
aura-demo Die vollständige Galerie als C++-Anwendung, mit allen acht Seiten und gekennzeichneten Plattformgrenzen
Playground 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 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.

Dokumentationsquelle: tools/web, tools/aura-web · Markdown herunterladen

Suche nach Themen, Widgets oder APIs.