xPulse
🇩🇪 DE

@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:

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
de/spec.md 2026-03-30