Skip to content

Instantly share code, notes, and snippets.

@buddy-sandidge
Last active September 30, 2025 18:11
Show Gist options
  • Select an option

  • Save buddy-sandidge/68f526ea54a98941ee1755a0a4dbbafd to your computer and use it in GitHub Desktop.

Select an option

Save buddy-sandidge/68f526ea54a98941ee1755a0a4dbbafd to your computer and use it in GitHub Desktop.
Data-star SSE no reconnect
module gist.github.com/buddy-sandidge/68f526ea54a98941ee1755a0a4dbbafd.git
go 1.25.0
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>No SSE Reconnect</title>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<script type="module" src="https://cdn.jsdelivr.net/gh/starfederation/[email protected]/bundles/datastar.js"></script>
</head>
<body>
<main>
<p>From Datastar</p>
<div data-on-load="@get('/now')"></div>
<div id=ts></div>
<hr/>
<p>From SSE</p>
<div id=sse_ts></div>
</main>
<script>
const sse = new EventSource('/now');
sse.addEventListener("datastar-patch-elements", function (e) {
const el = document.createElement("div")
el.innerHTML = e.data.substring('elements '.length)
document.getElementById("sse_ts").innerHTML = el.firstChild.innerHTML
})
</script>
</body>
</html>
package main
import (
"context"
_ "embed"
"errors"
"flag"
"fmt"
"net/http"
"os"
"os/signal"
"time"
)
//go:embed index.html
var indexHtml string
func main() {
ctx, cancel := context.WithCancel(context.Background())
err := run(ctx)
cancel()
if err != nil {
os.Stderr.WriteString("ERROR: " + err.Error() + "\n")
os.Exit(1)
}
}
func run(ctx context.Context) error {
var port int
flag.IntVar(&port, "port", 8081, "port to listen on")
flag.Parse()
ctx, cancel := context.WithCancel(ctx)
shutdown := make(chan struct{})
mux := http.NewServeMux()
mux.HandleFunc("/now", func(resp http.ResponseWriter, req *http.Request) {
fmt.Println("handling /now")
resp.Header().Set("Cache-Control", "no-cache")
resp.Header().Set("Content-Type", "text/event-stream")
if req.ProtoMajor == 1 {
resp.Header().Set("Connection", "keep-alive")
}
rc := http.NewResponseController(resp)
resp.Write([]byte("event: datastar-patch-elements\n"))
resp.Write([]byte("data: elements <div id=ts>" + time.Now().Round(time.Second).Format(time.RFC3339) + "</div>\n\n"))
rc.Flush()
t := time.NewTicker(1 * time.Second)
defer t.Stop()
for {
select {
case <-shutdown:
fmt.Println("shutting down")
return
case <-req.Context().Done():
fmt.Println("request cancelled")
return
case <-t.C:
ts := time.Now().Round(time.Second).Format(time.RFC3339)
resp.Write([]byte("event: datastar-patch-elements\n"))
resp.Write([]byte("data: elements <div id=ts>" + ts + "</div>\n\n"))
rc.Flush()
}
}
})
mux.HandleFunc("/", func(resp http.ResponseWriter, req *http.Request) {
if req.URL.Path == "/" {
resp.Write([]byte(indexHtml))
} else {
http.NotFound(resp, req)
}
})
server := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: mux,
}
server.RegisterOnShutdown(func() {
close(shutdown)
})
ret := make(chan error)
go func() {
fmt.Printf("starting http server: http://localhost%s/\n", server.Addr)
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
cancel()
ret <- fmt.Errorf("running server: %w", err)
} else {
ret <- nil
cancel()
}
}()
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt)
select {
case <-ctx.Done():
case <-sig:
}
if err := server.Shutdown(ctx); err != nil {
return fmt.Errorf("shutting down server: %w", err)
}
return <-ret
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment