From d4b831492eaba930108462de2a0b617fb88436f3 Mon Sep 17 00:00:00 2001 From: Ryan Hamamura <58859899+ryanhamamura@users.noreply.github.com> Date: Wed, 14 Jan 2026 02:01:18 -1000 Subject: [PATCH] refactor: simplify Datastar configuration API Flatten DatastarConfig struct into Options (DatastarContent, DatastarPath) and replace datastarHandlerRegistered bool with sync.Once for thread safety. --- configuration.go | 21 +++++++-------------- via.go | 32 ++++++++++++++------------------ via_test.go | 8 ++------ 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/configuration.go b/configuration.go index 564ccfd..75923d2 100644 --- a/configuration.go +++ b/configuration.go @@ -2,17 +2,6 @@ package via import "github.com/alexedwards/scs/v2" -// DatastarConfig configures a custom Datastar.js script. -type DatastarConfig struct { - // Content is the Datastar.js script content. - // If nil, the embedded default is used. - Content []byte - - // Path is the URL path where the script is served. - // Defaults to "/_datastar.js" if empty. - Path string -} - type LogLevel int const ( @@ -49,7 +38,11 @@ type Options struct { // passing it (lifetime, cookie settings, store, etc). SessionManager *scs.SessionManager - // Datastar configures a custom Datastar.js script. - // If nil, Via uses its embedded default. - Datastar *DatastarConfig + // DatastarContent is the Datastar.js script content. + // If nil, the embedded default is used. + DatastarContent []byte + + // DatastarPath is the URL path where the script is served. + // Defaults to "/_datastar.js" if empty. + DatastarPath string } diff --git a/via.go b/via.go index dbadd1f..1ddbcbb 100644 --- a/via.go +++ b/via.go @@ -39,10 +39,10 @@ type V struct { documentHeadIncludes []h.H documentFootIncludes []h.H devModePageInitFnMap map[string]func(*Context) - sessionManager *scs.SessionManager - datastarPath string - datastarContent []byte - datastarHandlerRegistered bool + sessionManager *scs.SessionManager + datastarPath string + datastarContent []byte + datastarOnce sync.Once } func (v *V) logFatal(format string, a ...any) { @@ -111,13 +111,11 @@ func (v *V) Config(cfg Options) { if cfg.SessionManager != nil { v.sessionManager = cfg.SessionManager } - if cfg.Datastar != nil { - if cfg.Datastar.Content != nil { - v.datastarContent = cfg.Datastar.Content - } - if cfg.Datastar.Path != "" { - v.datastarPath = cfg.Datastar.Path - } + if cfg.DatastarContent != nil { + v.datastarContent = cfg.DatastarContent + } + if cfg.DatastarPath != "" { + v.datastarPath = cfg.DatastarPath } } @@ -271,13 +269,11 @@ func (v *V) HTTPServeMux() *http.ServeMux { } func (v *V) ensureDatastarHandler() { - if v.datastarHandlerRegistered { - return - } - v.datastarHandlerRegistered = true - v.mux.HandleFunc("GET "+v.datastarPath, func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Content-Type", "application/javascript") - _, _ = w.Write(v.datastarContent) + v.datastarOnce.Do(func() { + v.mux.HandleFunc("GET "+v.datastarPath, func(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/javascript") + _, _ = w.Write(v.datastarContent) + }) }) } diff --git a/via_test.go b/via_test.go index 213bf9b..64e1b13 100644 --- a/via_test.go +++ b/via_test.go @@ -45,9 +45,7 @@ func TestCustomDatastarContent(t *testing.T) { customScript := []byte("// Custom Datastar Script") v := New() v.Config(Options{ - Datastar: &DatastarConfig{ - Content: customScript, - }, + DatastarContent: customScript, }) v.Page("/", func(c *Context) { c.View(func() h.H { return h.Div() }) @@ -65,9 +63,7 @@ func TestCustomDatastarContent(t *testing.T) { func TestCustomDatastarPath(t *testing.T) { v := New() v.Config(Options{ - Datastar: &DatastarConfig{ - Path: "/assets/datastar.js", - }, + DatastarPath: "/assets/datastar.js", }) v.Page("/test", func(c *Context) { c.View(func() h.H { return h.Div() })