Seiten
Inhalt
@xpulse/app – Component Spec
Status: ACCEPTED · Aktualisiert März 2026 Übergeordnet:
GLOBAL_concept-ecosystem.md
Übersicht
Einstiegspunkt für jeden xPart. Bootstrapped den gesamten Stack über einen resilienten Service Loader und stellt den App Root sowie Environment-Helpers bereit.
Zwei Aufgaben: Stack bootstrappen + App Root bereitstellen – nicht mehr.
@xpulse/app ist der einzige erlaubte Ort im Ökosystem der "alles kennt".
Alle anderen Packages bleiben vollständig entkoppelt.
Dependencies
Zwei harte Dependencies die immer benötigt werden:
@xpulse/event— Event Bus (ADR-010)@xpulse/config— lädtxpulse.json+.env
Der Standard-Stack wird als Dependencies mitgeliefert und vom Service Loader
zur Laufzeit auto-discovert:
@xpulse/logger, @xpulse/http, @xpulse/router,
@xpulse/template, @xpulse/theme, @xpulse/controller.
@xpulse/debug und @xpulse/dev sind optional — kein Fehler wenn nicht installiert.
Feature-Packages (@xpulse/doc etc.) werden von der App selbst installiert.
API
app.init(env?)
Bootstrapped den gesamten Stack über den resilienten Service Loader. Immer alles – kein selektives Laden.
| import app from '@xpulse/app'; |
| // env aus APP_ENV → NODE_ENV → null |
| await app.init(); |
| // env explizit |
| await app.init('stage'); |
| await app.init('production'); |
app.start() / app.stop()
| app.start(); // blockierend |
| await app.stop(); // graceful shutdown |
Typische index.js
| import app from '@xpulse/app'; |
| await app.init(); |
| app.start(); |
| process.on('SIGTERM', () => app.stop()); |
| process.on('SIGINT', () => app.stop()); |
Environments
| Wert | Beschreibung |
|---|---|
development |
Lokale Entwicklung |
stage |
Staging-Umgebung – RC Testing |
production |
Produktiv-Umgebung |
Weitere Environments sind erlaubt aber undokumentiert.
APP_ENV hat Vorrang vor NODE_ENV.
App Root
Das Verzeichnis in dem xpulse.json liegt – in der Regel process.cwd().
Wird beim ersten app.init() gesetzt und ist danach unveränderlich.
Alle Pfade im Ökosystem sind relativ zum App Root definiert.
Helper Methoden
app.root()
Gibt den absoluten App Root Pfad zurück.
| app.root() |
| // → '/var/www/my-app' |
app.path(relative)
Löst einen relativen Pfad ausgehend vom App Root auf.
| app.path('src/templates') // → '/var/www/my-app/src/templates' |
| app.path('var/cache/template') // → '/var/www/my-app/var/cache/template' |
| app.path('var/log') // → '/var/www/my-app/var/log' |
app.env
Das aktuelle Environment.
| app.env // → 'stage' | 'production' | 'development' | null |
app.isDev()
| app.isDev() // → true wenn env === 'development' |
app.isProd()
| app.isProd() // → true wenn env === 'production' |
app.isStage()
| app.isStage() // → true wenn env === 'stage' |
Bootstrap-Reihenfolge
app.init() arbeitet über einen Auto-Discovery Service Loader —
Packages deklarieren ihre Abhängigkeiten in xpulse.json, der Loader
ermittelt die richtige Init-Reihenfolge per Topological Sort. Siehe service-loader.md.
| 1. App Root + config.load() ← xpulse.json + .env laden |
| 2. debug.bootstrapDebug() ← nur wenn debug.enabled |
| läuft vor dem Loader damit alles debuggbar ist |
| 3. Service Loader ← auto-discovert alle installierten @xpulse/*-Packages |
| mit service-Section in ihrer xpulse.json |
| Topological Sort nach depends[] |
| resilient: fehlende oder deaktivierte Packages werden übersprungen |
@xpulse/event braucht kein init() — zero-dependencies, funktioniert sofort beim Import.
@xpulse/dev ist ein eigenes System — klinkt sich von außen ein, Loader ignoriert es.
Graceful Shutdown
| 1. Keine neuen Requests mehr annehmen |
| 2. Laufende Requests abschließen (Timeout: 30s) |
| 3. @xpulse/logger flushen |
| 4. process.exit(0) |
Gefeuerte Events
| Event | Payload | Wann |
|---|---|---|
app:init |
{ env, root } |
Bootstrap beginnt |
app:ready |
{ env, root, uptime } |
Gesamter Stack bereit |
app:stopping |
{ signal } |
SIGTERM / SIGINT empfangen |
app:stopped |
{ uptime, exitCode } |
Shutdown abgeschlossen |
app:service:ready |
{ service } |
Service erfolgreich initialisiert |
app:service:skipped |
{ service, reason } |
Nicht installiert oder load: false |
app:service:error |
{ service, error } |
Init hat geworfen, Loader macht weiter |
Die vollständige Event-Referenz aller Packages ist in GLOBAL_adr-010-event-driven.md.
Receipt
@xpulse/app bringt ein Receipt mit das bei npm install automatisch ausgeführt wird.
receipt/up.js legt an (nur wenn nicht vorhanden):
| Datei | Inhalt |
|---|---|
src/index.js |
Minimale lauffähige App |
xpulse.json |
Minimale Konfiguration (name, type) |
.npmrc |
Registry-Verweis auf npm.xpulse.one |
.env.example |
Dokumentierte Beispiel-Variablen |
receipt/down.js: Warnung – keine automatische Löschung.
.env.example Inhalt
| # xPulse App – Environment Variables |
| # Kopiere diese Datei nach .env und passe die Werte an |
| # Server |
| PORT=3000 |
| # Environment: development | stage | production |
| APP_ENV=development |
| # Logging |
| LOG=true |
| DEBUG=false |
Paket-Struktur
| @xpulse/app/ |
| src/ |
| index.js ← default export: app-Objekt |
| bootstrap/ |
| app.js ← App Root + config.load() |
| services.js ← Auto-Discovery Service Loader (liest xpulse.json, Topo-Sort) |
| receipt/ |
| up.js |
| down.js |
| files/ |
| src/ |
| index.js |
| xpulse.json |
| .npmrc |
| .env.example |
| test/ |
| app.test.js |
| docs/ |
| index.md |
| de/ index, guide, api |
| en/ index, guide, api |
| Dockerfile |
| Makefile |
| README.md |
| package.json |
| xpulse.json |