mirror of
https://github.com/syumai/workers.git
synced 2025-03-11 01:39:11 +00:00
131 lines
3.5 KiB
Go
131 lines
3.5 KiB
Go
package jsutil
|
|
|
|
import (
|
|
"fmt"
|
|
"syscall/js"
|
|
"time"
|
|
)
|
|
|
|
var (
|
|
RuntimeContext = js.Global().Get("context")
|
|
Binding = js.Global().Get("context").Get("binding")
|
|
ObjectClass = js.Global().Get("Object")
|
|
PromiseClass = js.Global().Get("Promise")
|
|
RequestClass = js.Global().Get("Request")
|
|
ResponseClass = js.Global().Get("Response")
|
|
HeadersClass = js.Global().Get("Headers")
|
|
ArrayClass = js.Global().Get("Array")
|
|
Uint8ArrayClass = js.Global().Get("Uint8Array")
|
|
ErrorClass = js.Global().Get("Error")
|
|
ReadableStreamClass = js.Global().Get("ReadableStream")
|
|
FixedLengthStreamClass = js.Global().Get("FixedLengthStream")
|
|
DateClass = js.Global().Get("Date")
|
|
Null = js.ValueOf(nil)
|
|
)
|
|
|
|
func NewObject() js.Value {
|
|
return ObjectClass.New()
|
|
}
|
|
|
|
func NewArray(size int) js.Value {
|
|
return ArrayClass.New(size)
|
|
}
|
|
|
|
func NewUint8Array(size int) js.Value {
|
|
return Uint8ArrayClass.New(size)
|
|
}
|
|
|
|
func NewPromise(fn js.Func) js.Value {
|
|
return PromiseClass.New(fn)
|
|
}
|
|
|
|
func Error(msg string) js.Value {
|
|
return ErrorClass.New(msg)
|
|
}
|
|
|
|
func Errorf(format string, args ...any) js.Value {
|
|
return ErrorClass.New(fmt.Sprintf(format, args...))
|
|
}
|
|
|
|
// 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 {
|
|
if v.IsUndefined() || v.IsNull() {
|
|
return 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 "" if the value is undefined.
|
|
func MaybeString(v js.Value) string {
|
|
if v.IsUndefined() {
|
|
return ""
|
|
}
|
|
return v.String()
|
|
}
|
|
|
|
// MaybeInt returns int value of given JavaScript value or returns nil if the value is undefined.
|
|
func MaybeInt(v js.Value) int {
|
|
if v.IsUndefined() {
|
|
return 0
|
|
}
|
|
return v.Int()
|
|
}
|
|
|
|
// 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())
|
|
}
|