// Package spaserver provides a lifecycle-managed HTTP server for serving // single-page applications (SPA) and progressive web apps (PWA) from a // container. // // # Overview // // The server delivers static assets from a configurable directory and falls // back to index.html for any request path that does not map to an existing // file — the standard SPA routing contract. A health endpoint is included // at /health with the same JSON wire format used across all Einherjar modules. // // # Lifecycle // // [NewServer] returns a [lifecycle.Component] that integrates directly with // [launcher.New]. [Server.OnInit] builds the HTTP mux. [Server.OnStart] // begins serving in a goroutine. [Server.OnStop] performs a graceful shutdown. // // cfg := spaserver.DefaultConfig() // srv := spaserver.NewServer(logger, cfg) // // lc := launcher.New(logger) // lc.Append(srv) // if err := lc.Run(); err != nil { // log.Fatal(err) // } // // # Configuration // // All fields are read from environment variables: // // - EINHERJAR_SPA_PORT — listen port (default: 8080) // - EINHERJAR_SPA_STATIC_DIR — path to the directory containing index.html and assets (default: /srv/www) // - EINHERJAR_LOG_LEVEL — log level: DEBUG, INFO, WARN, ERROR (default: INFO) // // # Container usage // // The module ships as a ready-to-use base image. A downstream SPA Dockerfile // only needs to copy the built assets: // // FROM code.nochebuena.dev/einherjar/spa-server:v1.0.0 // COPY dist/ /srv/www/ package spaserver