// Package webui embeds the built frontend SPA (frontend/web/dist) into the // single Cyrene binary and exposes it as a filesystem. It is the default asset // source for the gateway's static server; a deployer may still drop an external // dist directory next to the process to override it (see internal/services/ // gateway and cmd/cyrene). // // The embedded tree is rooted at the dist directory, so index.html and // assets/* appear at the filesystem root. Build the frontend with // `cd frontend/web && npm run build` (which also syncs dist into this package) // before running `go build ./...`; the //go:embed directive fails to compile // when the dist directory is absent. package webui import ( "embed" "io/fs" ) // dist holds the built SPA. It is generated by the frontend build and must // exist for the package to compile. // //go:embed all:dist var dist embed.FS // Assets returns the embedded dist as an fs.FS rooted at the dist directory. // The returned FS is read-only and safe for concurrent use. func Assets() fs.FS { sub, err := fs.Sub(dist, "dist") if err != nil { // The embed directive guarantees dist exists, so this cannot fail; a // panic here is a programming error, not a runtime condition. panic("webui: dist embed missing: " + err.Error()) } return sub } // Open opens a file under the dist root by its slash-separated (or // filesystem) name. It is a convenience over Assets().Open. func Open(name string) (fs.File, error) { return Assets().Open(name) } // Exists reports whether a file or directory exists within the embedded dist. func Exists(path string) bool { _, err := fs.Stat(Assets(), path) return err == nil }