Added a webservice static JS library

This commit is contained in:
Magnus Åhall 2024-01-07 16:18:49 +01:00
parent 2938da6d5a
commit 7c5eaa74d9
4 changed files with 93 additions and 25 deletions

View File

@ -5,15 +5,28 @@ import (
"embed"
"fmt"
"net/http"
"regexp"
)
var (
//go:embed static/js
embedded embed.FS
pathMatcher *regexp.Regexp = regexp.MustCompile("^/_js/v[0-9]+/(.*)$")
)
func staticJSWebsocket(w http.ResponseWriter, r *http.Request) {
contents, err := embedded.ReadFile("static/js/websocket.js")
func (service *Service) staticJSHandler(w http.ResponseWriter, r *http.Request) {
var path string
if comp := pathMatcher.FindStringSubmatch(r.URL.Path); comp != nil {
path = fmt.Sprintf("static/js/%s", comp[1])
} else {
service.logger.Debug("webservice", "request", r.URL.Path)
return
}
service.logger.Debug("webservice", "request", r.URL.Path, "path", path)
w.Header().Add("Content-Type", "text/javascript")
contents, err := embedded.ReadFile(path)
if err != nil {
fmt.Println(err)
return

2
pkg.go
View File

@ -106,7 +106,7 @@ func New(configFilename, version string, logger *slog.Logger) (service *Service,
http.HandleFunc("/_ws", service.websocketHandler)
http.HandleFunc("/_ws/css_update", service.cssUpdateHandler)
http.HandleFunc("/_js/websocket.js", staticJSWebsocket)
http.HandleFunc("/_js/", service.staticJSHandler)
return
} // }}}

View File

@ -1,22 +0,0 @@
package webservice
import (
// Standard
"embed"
"fmt"
"net/http"
)
var (
//go:embed foo.txt
embedded embed.FS
)
func staticJSWebsocket(w http.ResponseWriter, r *http.Request) {
contents, err := embedded.ReadFile("foo.txt")
if err != nil {
fmt.Println(err)
return
}
w.Write(contents)
}

77
static/js/websocket.mjs Normal file
View File

@ -0,0 +1,77 @@
export class Websocket {
constructor() {//{{{
this.websocket = null
this.websocket_int_ping = null
this.websocket_int_reconnect = null
this.hooks = {
open: [],
message: [],
error: [],
close: [],
}
}//}}}
register(event, fn) {//{{{
this.hooks[event].push(fn)
}//}}}
start() {//{{{
this.connect()
//this.loop()
}//}}}
loop() {//{{{
setInterval(() => {
if (this.websocket === null) {
console.log("websocket loop connect")
this.connect()
}
}, 1000)
}//}}}
connect() {//{{{
const protocol = location.protocol;
const domain = location.hostname;
const port = location.port;
let wsProtocol = 'wss'
if (protocol == 'http:')
wsProtocol = 'ws'
const websocketURI = `${wsProtocol}://${domain}:${port}/_ws`
this.websocket = new WebSocket(websocketURI)
this.websocket.onopen = (evt) => this.open(evt)
this.websocket.onmessage = (evt) => this.message(evt)
this.websocket.onerror = (evt) => this.error(evt)
this.websocket.onclose = (evt) => this.close(evt)
}//}}}
open() {//{{{
this.hooks.open.forEach(fn=>fn())
// A ping interval to implement a rudimentary keep-alive.
}//}}}
close() {//{{{
this.websocket = null
this.hooks.close.forEach(fn=>fn())
}//}}}
error(evt) {//{{{
this.websocket = null;
this.hooks.error.forEach(fn=>fn(evt))
}//}}}
message(evt) {//{{{
const msg = JSON.parse(evt.data)
if (msg.ID == '' && msg.Op == 'css_reload')
this.refreshCSS()
this.hooks.message.forEach(fn=>fn(evt.data))
return
}//}}}
refreshCSS() {//{{{
let links = document.getElementsByTagName('link')
Array.from(links).forEach(l=>{
if (l.rel == 'stylesheet' && !l.hasAttribute('x-no-reload')) {
l.href = l.href.replace(/\?.*/, '') + `?cache=${Date.now()}`
console.log(l.href)
}
})
}//}}}
}