Skip to content

Instantly share code, notes, and snippets.

@ferealqq

ferealqq/main.go Secret

Created May 30, 2022 17:09
Show Gist options
  • Save ferealqq/23ccb13aa93f551a63d245bf63919690 to your computer and use it in GitHub Desktop.
Save ferealqq/23ccb13aa93f551a63d245bf63919690 to your computer and use it in GitHub Desktop.
Vecty: AddScript function manual test.
package main
import (
"errors"
"sync"
"syscall/js"
"time"
"github.com/hexops/vecty"
"github.com/hexops/vecty/elem"
)
func main() {
vecty.SetTitle("Hello Vecty!")
vecty.RenderBody(&PageView{})
}
// PageView is our main page component.
type PageView struct {
vecty.Core
}
// Render implements the vecty.Component interface.
func (p *PageView) Render() vecty.ComponentOrHTML {
if AddScript(
"https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js",
time.Millisecond*30000,
make(map[string]interface{}),
) == nil {
println("bootstrap works like a dream")
}
if err := AddScript(
"http://localhost:8000/slow.js",
time.Millisecond*3,
make(map[string]interface{}),
); err != nil {
println("error throwing like a dream")
println(err.Error())
if errors.Is(err, ErrTimeout) {
println("yes box")
}
}
return elem.Body(
vecty.Text("Hello Vecty!"),
)
}
var ErrTimeout = errors.New("timeout while obtaining script from URL")
var ErrTimeoutGreaterThan = errors.New("timeout value has to be greater than zero")
func AddScript(url string, timeout time.Duration, attributes map[string]interface{}) error {
if timeout <= 0 {
return ErrTimeoutGreaterThan
}
script := js.Global().Get("document").Call("createElement", "script")
script.Set("src", url)
for k, v := range attributes {
script.Set(k, v)
}
quitCh := make(chan struct{})
var f js.Func
f = js.FuncOf(func(this js.Value, args []js.Value) interface{} {
defer f.Release()
close(quitCh)
script.Delete("onload")
return nil
})
script.Set("onload", f)
js.Global().Get("document").Get("head").Call("appendChild", script)
var err error
var wg sync.WaitGroup
wg.Add(1)
go func(t time.Duration) {
tic := time.NewTicker(10 * time.Millisecond)
start := time.Now()
loop:
for {
select {
case <-quitCh:
wg.Done()
break loop
case <-tic.C:
if time.Since(start) > t {
err = ErrTimeout
wg.Done()
break loop
}
}
}
}(timeout)
wg.Wait()
return err
}
package main
import (
"log"
"net/http"
"time"
)
func main() {
http.HandleFunc("/slow.js", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(time.Second * 2)
http.ServeFile(w, r, "test.js")
})
log.Println("listening to connections: 8000")
log.Fatal(http.ListenAndServe(":8000", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment