- Add assets package with dev/prod build tags - Dev: serve from filesystem with Cache-Control: no-store - Prod: use hashfs for cache-busting URLs - Add LiveClock component to show SSE connection status - Update templates to use StaticPath for asset URLs
76 lines
2.1 KiB
Go
76 lines
2.1 KiB
Go
// Package router wires feature routes and middleware into the central chi mux.
|
|
package router
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
|
|
"github.com/alexedwards/scs/v2"
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/nats-io/nats.go"
|
|
"github.com/starfederation/datastar-go/datastar"
|
|
|
|
"github.com/ryanhamamura/games/assets"
|
|
"github.com/ryanhamamura/games/config"
|
|
"github.com/ryanhamamura/games/connect4"
|
|
"github.com/ryanhamamura/games/db/repository"
|
|
"github.com/ryanhamamura/games/features/auth"
|
|
"github.com/ryanhamamura/games/features/c4game"
|
|
c4services "github.com/ryanhamamura/games/features/c4game/services"
|
|
"github.com/ryanhamamura/games/features/lobby"
|
|
"github.com/ryanhamamura/games/features/snakegame"
|
|
snakeservices "github.com/ryanhamamura/games/features/snakegame/services"
|
|
"github.com/ryanhamamura/games/snake"
|
|
)
|
|
|
|
func SetupRoutes(
|
|
router chi.Router,
|
|
queries *repository.Queries,
|
|
sessions *scs.SessionManager,
|
|
nc *nats.Conn,
|
|
store *connect4.Store,
|
|
snakeStore *snake.SnakeStore,
|
|
) {
|
|
// Static assets
|
|
router.Handle("/assets/*", assets.Handler())
|
|
|
|
// Hot-reload for development
|
|
if config.Global.Environment == config.Dev {
|
|
setupReload(router)
|
|
}
|
|
|
|
// Services
|
|
c4Svc := c4services.NewGameService(nc, queries)
|
|
snakeSvc := snakeservices.NewGameService(nc)
|
|
|
|
auth.SetupRoutes(router, queries, sessions)
|
|
lobby.SetupRoutes(router, queries, sessions, store, snakeStore)
|
|
c4game.SetupRoutes(router, store, c4Svc, sessions)
|
|
snakegame.SetupRoutes(router, snakeStore, snakeSvc, sessions)
|
|
}
|
|
|
|
func setupReload(router chi.Router) {
|
|
reloadChan := make(chan struct{}, 1)
|
|
var hotReloadOnce sync.Once
|
|
|
|
router.Get("/reload", func(w http.ResponseWriter, r *http.Request) {
|
|
sse := datastar.NewSSE(w, r)
|
|
reload := func() { sse.ExecuteScript("window.location.reload()") } //nolint:errcheck // dev-only
|
|
hotReloadOnce.Do(reload)
|
|
select {
|
|
case <-reloadChan:
|
|
reload()
|
|
case <-r.Context().Done():
|
|
}
|
|
})
|
|
|
|
router.Get("/hotreload", func(w http.ResponseWriter, r *http.Request) {
|
|
select {
|
|
case reloadChan <- struct{}{}:
|
|
default:
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
w.Write([]byte("OK")) //nolint:errcheck // dev-only
|
|
})
|
|
}
|