# Host Package Static file server optimized for serving Iris WASM applications. ## Basic Setup ```go package main import ( "log" "net/http" "git.flowmade.one/flowmade-one/iris/host" ) func main() { server := host.New("public", "index.html") log.Println("Server running on http://localhost:8080") log.Fatal(http.ListenAndServe(":8080", server)) } ``` ## Directory Structure ``` myapp/ ├── server.go # Server code (above) └── public/ ├── index.html # Entry point ├── app.wasm # Compiled WASM binary └── wasm_exec.js # Go WASM runtime ``` ## Serving Static Files The server serves files from the specified public directory. Any request path maps directly to files: - `/` -> `public/index.html` - `/app.wasm` -> `public/app.wasm` - `/styles.css` -> `public/styles.css` **SPA Fallback**: Unknown paths and directories fall back to `index.html`, enabling client-side routing. ## WASM MIME Types The server automatically sets correct MIME types for all common file types: | Extension | MIME Type | |-----------|-----------| | `.wasm` | `application/wasm` | | `.html` | `text/html; charset=utf-8` | | `.js` | `application/javascript` | | `.css` | `text/css` | | `.json` | `application/json` | | `.svg` | `image/svg+xml` | This ensures browsers load WASM files correctly without manual configuration. ## Compression Gzip compression is automatically applied to compressible content types when the client supports it: - HTML, CSS, JavaScript - JSON - WASM binaries - SVG images Binary assets (PNG, JPEG, etc.) are served uncompressed since they're already compressed. ## Hot Reload (Development) The `DevServer` provides automatic rebuild and browser reload during development: ```go package main import ( "git.flowmade.one/flowmade-one/iris/host" ) func main() { // Create dev server with hot reload dev := host.NewDevServer( "public", // Static files directory "index.html", // Index file ".", // Source directory to watch "public/app.wasm", // WASM output path ) // Start watching and serving dev.ListenAndServe(":8080") } ``` ### How It Works 1. **File Watcher**: Monitors `.go` files in the source directory for changes 2. **Auto Build**: Runs `GOOS=js GOARCH=wasm go build` when changes are detected 3. **Browser Reload**: Injects a WebSocket client into HTML pages that triggers reload on build success ### Directory Structure for Development ``` myapp/ ├── main.go # WASM application entry point ├── server/ │ └── main.go # Dev server (code above) └── public/ ├── index.html ├── app.wasm # Generated by dev server └── wasm_exec.js ``` ### Workflow 1. Start the dev server: `go run ./server` 2. Open `http://localhost:8080` in your browser 3. Edit your Go source files 4. Save - the browser automatically reloads with your changes ### Custom Watch Configuration ```go // Watch additional file types watcher := host.NewWatcher( ".", onChangeCallback, host.WithExtensions(".go", ".html", ".css"), host.WithInterval(100*time.Millisecond), ) ``` ### Manual Components For advanced use cases, you can use the individual components: ```go // File watcher watcher := host.NewWatcher(".", func() { log.Println("Files changed") }) watcher.Start() defer watcher.Stop() // WASM builder builder := host.NewBuilder(".", "public/app.wasm") result := builder.Build() if result.Success { log.Println("Build succeeded") } // Live reload (WebSocket notifications) lr := host.NewLiveReload() http.Handle("/__livereload", lr) lr.NotifyReload() // Triggers reload in all connected browsers ``` ## Production For production, use the standard `Server` instead of `DevServer`: ```go func main() { server := host.New("public", "index.html") log.Fatal(http.ListenAndServe(":8080", server)) } ``` Compile and deploy: ```bash go build -o server ./server ./server ``` Consider adding: - TLS termination (via reverse proxy or `http.ListenAndServeTLS`) - Environment-based port configuration - Graceful shutdown handling Example with TLS: ```go func main() { server := host.New("public", "index.html") log.Fatal(http.ListenAndServeTLS(":443", "cert.pem", "key.pem", server)) } ``` Example with reverse proxy (nginx): ```nginx server { listen 443 ssl; server_name example.com; location / { proxy_pass http://localhost:8080; proxy_set_header Host $host; } } ```