Move NATS subscription and chat room management into a dedicated GameService, following the portigo service pattern. Handlers now receive the service and call its methods instead of managing NATS connections directly.
77 lines
2.0 KiB
Go
77 lines
2.0 KiB
Go
// Package router wires feature routes and middleware into the central chi mux.
|
|
package router
|
|
|
|
import (
|
|
"embed"
|
|
"io/fs"
|
|
"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/config"
|
|
"github.com/ryanhamamura/games/connect4"
|
|
"github.com/ryanhamamura/games/db/repository"
|
|
"github.com/ryanhamamura/games/features/auth"
|
|
"github.com/ryanhamamura/games/features/c4game"
|
|
"github.com/ryanhamamura/games/features/c4game/services"
|
|
"github.com/ryanhamamura/games/features/lobby"
|
|
"github.com/ryanhamamura/games/features/snakegame"
|
|
"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,
|
|
assets embed.FS,
|
|
) {
|
|
// Static assets
|
|
subFS, _ := fs.Sub(assets, "assets")
|
|
router.Handle("/assets/*", http.StripPrefix("/assets/", http.FileServerFS(subFS)))
|
|
|
|
// Hot-reload for development
|
|
if config.Global.Environment == config.Dev {
|
|
setupReload(router)
|
|
}
|
|
|
|
// Services
|
|
c4Svc := services.NewGameService(nc, queries)
|
|
|
|
auth.SetupRoutes(router, queries, sessions)
|
|
lobby.SetupRoutes(router, queries, sessions, store, snakeStore)
|
|
c4game.SetupRoutes(router, store, c4Svc, sessions)
|
|
snakegame.SetupRoutes(router, snakeStore, nc, 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
|
|
})
|
|
}
|