1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
|
//go:build js && wasm
// +build js,wasm
package webrtc
import (
"fmt"
"syscall/js"
)
// awaitPromise accepts a js.Value representing a Promise. If the promise
// resolves, it returns (result, nil). If the promise rejects, it returns
// (js.Undefined, error). awaitPromise has a synchronous-like API but does not
// block the JavaScript event loop.
func awaitPromise(promise js.Value) (js.Value, error) {
resultsChan := make(chan js.Value)
errChan := make(chan js.Error)
thenFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
resultsChan <- args[0]
}()
return js.Undefined()
})
defer thenFunc.Release()
catchFunc := js.FuncOf(func(this js.Value, args []js.Value) interface{} {
go func() {
errChan <- js.Error{args[0]}
}()
return js.Undefined()
})
defer catchFunc.Release()
promise.Call("then", thenFunc).Call("catch", catchFunc)
select {
case result := <-resultsChan:
return result, nil
case err := <-errChan:
return js.Undefined(), err
}
}
func valueToUint16Pointer(val js.Value) *uint16 {
if val.IsNull() || val.IsUndefined() {
return nil
}
convertedVal := uint16(val.Int())
return &convertedVal
}
func valueToStringPointer(val js.Value) *string {
if val.IsNull() || val.IsUndefined() {
return nil
}
stringVal := val.String()
return &stringVal
}
func stringToValueOrUndefined(val string) js.Value {
if val == "" {
return js.Undefined()
}
return js.ValueOf(val)
}
func uint8ToValueOrUndefined(val uint8) js.Value {
if val == 0 {
return js.Undefined()
}
return js.ValueOf(val)
}
func interfaceToValueOrUndefined(val interface{}) js.Value {
if val == nil {
return js.Undefined()
}
return js.ValueOf(val)
}
func valueToStringOrZero(val js.Value) string {
if val.IsUndefined() || val.IsNull() {
return ""
}
return val.String()
}
func valueToUint8OrZero(val js.Value) uint8 {
if val.IsUndefined() || val.IsNull() {
return 0
}
return uint8(val.Int())
}
func valueToUint16OrZero(val js.Value) uint16 {
if val.IsNull() || val.IsUndefined() {
return 0
}
return uint16(val.Int())
}
func valueToUint32OrZero(val js.Value) uint32 {
if val.IsNull() || val.IsUndefined() {
return 0
}
return uint32(val.Int())
}
func valueToStrings(val js.Value) []string {
result := make([]string, val.Length())
for i := 0; i < val.Length(); i++ {
result[i] = val.Index(i).String()
}
return result
}
func stringPointerToValue(val *string) js.Value {
if val == nil {
return js.Undefined()
}
return js.ValueOf(*val)
}
func uint16PointerToValue(val *uint16) js.Value {
if val == nil {
return js.Undefined()
}
return js.ValueOf(*val)
}
func boolPointerToValue(val *bool) js.Value {
if val == nil {
return js.Undefined()
}
return js.ValueOf(*val)
}
func stringsToValue(strings []string) js.Value {
val := make([]interface{}, len(strings))
for i, s := range strings {
val[i] = s
}
return js.ValueOf(val)
}
func stringEnumToValueOrUndefined(s string) js.Value {
if s == "unknown" {
return js.Undefined()
}
return js.ValueOf(s)
}
// Converts the return value of recover() to an error.
func recoveryToError(e interface{}) error {
switch e := e.(type) {
case error:
return e
default:
return fmt.Errorf("recovered with non-error value: (%T) %s", e, e)
}
}
func uint8ArrayValueToBytes(val js.Value) []byte {
result := make([]byte, val.Length())
js.CopyBytesToGo(result, val)
return result
}
|