mirror of
https://github.com/syumai/workers.git
synced 2025-03-11 01:39:11 +00:00
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package workers
|
|
|
|
import (
|
|
"fmt"
|
|
"syscall/js"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
global = js.Global()
|
|
objectClass = global.Get("Object")
|
|
promiseClass = global.Get("Promise")
|
|
responseClass = global.Get("Response")
|
|
headersClass = global.Get("Headers")
|
|
arrayClass = global.Get("Array")
|
|
uint8ArrayClass = global.Get("Uint8Array")
|
|
errorClass = global.Get("Error")
|
|
readableStreamClass = global.Get("ReadableStream")
|
|
dateClass = global.Get("Date")
|
|
)
|
|
|
|
func newObject() js.Value {
|
|
return objectClass.New()
|
|
}
|
|
|
|
func newUint8Array(size int) js.Value {
|
|
return uint8ArrayClass.New(size)
|
|
}
|
|
|
|
func newPromise(fn js.Func) js.Value {
|
|
return promiseClass.New(fn)
|
|
}
|
|
|
|
// arrayFrom calls Array.from to given argument and returns result Array.
|
|
func arrayFrom(v js.Value) js.Value {
|
|
return arrayClass.Call("from", v)
|
|
}
|
|
|
|
func awaitPromise(promiseVal js.Value) (js.Value, error) {
|
|
resultCh := make(chan js.Value)
|
|
errCh := make(chan error)
|
|
var then, catch js.Func
|
|
then = js.FuncOf(func(_ js.Value, args []js.Value) any {
|
|
defer then.Release()
|
|
result := args[0]
|
|
resultCh <- result
|
|
return js.Undefined()
|
|
})
|
|
catch = js.FuncOf(func(_ js.Value, args []js.Value) any {
|
|
defer catch.Release()
|
|
result := args[0]
|
|
errCh <- fmt.Errorf("failed on promise: %s", result.Call("toString").String())
|
|
return js.Undefined()
|
|
})
|
|
promiseVal.Call("then", then).Call("catch", catch)
|
|
select {
|
|
case result := <-resultCh:
|
|
return result, nil
|
|
case err := <-errCh:
|
|
return js.Value{}, err
|
|
}
|
|
}
|
|
|
|
// strRecordToMap converts JavaScript side's Record<string, string> into map[string]string.
|
|
func strRecordToMap(v js.Value) map[string]string {
|
|
entries := objectClass.Call("entries", v)
|
|
entriesLen := entries.Get("length").Int()
|
|
result := make(map[string]string, entriesLen)
|
|
for i := 0; i < entriesLen; i++ {
|
|
entry := entries.Index(i)
|
|
key := entry.Index(0).String()
|
|
value := entry.Index(1).String()
|
|
result[key] = value
|
|
}
|
|
return result
|
|
}
|
|
|
|
// maybeString returns string value of given JavaScript value or returns nil if the value is undefined.
|
|
func maybeString(v js.Value) string {
|
|
if v.IsUndefined() {
|
|
return ""
|
|
}
|
|
return v.String()
|
|
}
|
|
|
|
// maybeDate returns time.Time value of given JavaScript Date value or returns nil if the value is undefined.
|
|
func maybeDate(v js.Value) (time.Time, error) {
|
|
if v.IsUndefined() {
|
|
return time.Time{}, nil
|
|
}
|
|
return dateToTime(v)
|
|
}
|
|
|
|
// dateToTime converts JavaScript side's Data object into time.Time.
|
|
func dateToTime(v js.Value) (time.Time, error) {
|
|
milli := v.Call("getTime").Float()
|
|
return time.UnixMilli(int64(milli)), nil
|
|
}
|
|
|
|
// timeToDate converts Go side's time.Time into Date object.
|
|
func timeToDate(t time.Time) js.Value {
|
|
return dateClass.New(t.UnixMilli())
|
|
}
|