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