cloudflare-workers/jsutil.go

104 lines
2.7 KiB
Go
Raw Normal View History

2022-05-18 00:04:37 +09:00
package workers
2022-05-29 10:02:40 +09:00
import (
"fmt"
"syscall/js"
"time"
)
2022-05-18 00:04:37 +09:00
var (
2022-09-13 23:15:47 +09:00
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")
2022-05-18 00:04:37 +09:00
)
2022-09-13 23:15:47 +09:00
func NewObject() js.Value {
return ObjectClass.New()
2022-05-18 00:04:37 +09:00
}
2022-09-13 23:15:47 +09:00
func NewUint8Array(size int) js.Value {
return Uint8ArrayClass.New(size)
2022-05-18 00:04:37 +09:00
}
2022-09-13 23:15:47 +09:00
func NewPromise(fn js.Func) js.Value {
return PromiseClass.New(fn)
2022-05-18 00:04:37 +09:00
}
2022-09-13 23:15:47 +09:00
// ArrayFrom calls Array.from to given argument and returns result Array.
func ArrayFrom(v js.Value) js.Value {
return ArrayClass.Call("from", v)
2022-05-18 00:04:37 +09:00
}
2022-05-29 10:02:40 +09:00
2022-09-13 23:15:47 +09:00
func AwaitPromise(promiseVal js.Value) (js.Value, error) {
2022-05-29 10:02:40 +09:00
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
}
}
2022-09-13 23:15:47 +09:00
// 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)
2022-05-29 10:02:40 +09:00
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
}
2022-09-13 23:15:47 +09:00
// MaybeString returns string value of given JavaScript value or returns nil if the value is undefined.
func MaybeString(v js.Value) string {
2022-05-29 10:02:40 +09:00
if v.IsUndefined() {
2022-05-29 11:14:27 +09:00
return ""
2022-05-29 10:02:40 +09:00
}
2022-05-29 11:14:27 +09:00
return v.String()
2022-05-29 10:02:40 +09:00
}
2022-09-13 23:15:47 +09:00
// 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) {
2022-05-29 10:02:40 +09:00
if v.IsUndefined() {
2022-05-29 11:14:27 +09:00
return time.Time{}, nil
2022-05-29 10:02:40 +09:00
}
2022-09-13 23:15:47 +09:00
return DateToTime(v)
2022-05-29 10:02:40 +09:00
}
2022-09-13 23:15:47 +09:00
// 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
2022-05-29 10:02:40 +09:00
}
2022-05-29 11:14:27 +09:00
2022-09-13 23:15:47 +09:00
// TimeToDate converts Go side's time.Time into Date object.
func TimeToDate(t time.Time) js.Value {
return DateClass.New(t.UnixMilli())
2022-05-29 11:14:27 +09:00
}