Files
pigo/wasm/detector/fetch.go
2020-10-21 11:03:06 +03:00

81 lines
1.9 KiB
Go

package detector
import (
"errors"
"fmt"
"syscall/js"
)
// Detector struct holds the main components of the fetching operation.
type Detector struct {
respChan chan []uint8
errChan chan error
done chan struct{}
window js.Value
}
// NewDetector initializes a new constructor function.
func NewDetector() *Detector {
var d Detector
d.window = js.Global()
return &d
}
// FetchCascade retrive the cascade file through a JS http connection.
// It should return the binary data as uint8 integers or err in case of an error.
func (d *Detector) FetchCascade(url string) ([]byte, error) {
d.respChan = make(chan []uint8)
d.errChan = make(chan error)
promise := js.Global().Call("fetch", url)
promise.Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
response := args[0]
if !response.Get("ok").Bool() {
errorMsg := response.Get("statusText").String()
d.errChan <- errors.New(errorMsg)
}
}()
return nil
}))
success := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
response := args[0]
response.Call("arrayBuffer").Call("then", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
buffer := args[0]
uint8Array := js.Global().Get("Uint8Array").New(buffer)
jsbuf := make([]byte, uint8Array.Get("length").Int())
js.CopyBytesToGo(jsbuf, uint8Array)
d.respChan <- jsbuf
}()
return nil
}))
return nil
})
failure := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
err := fmt.Errorf("unable to fetch the cascade file: %s", args[0].String())
d.errChan <- err
}()
return nil
})
promise.Call("then", success, failure)
select {
case resp := <-d.respChan:
return resp, nil
case err := <-d.errChan:
return nil, err
}
}
// Log calls the `console.log` Javascript function
func (d *Detector) Log(args ...interface{}) {
d.window.Get("console").Call("log", args...)
}