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  }