js_utils.go 3.3 KB

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