github.com/0chain/gosdk@v1.17.11/wasmsdk/jsbridge/sync.go (about) 1 //go:build js && wasm 2 // +build js,wasm 3 4 package jsbridge 5 6 import ( 7 "reflect" 8 "syscall/js" 9 ) 10 11 type SyncInvoker func(fn reflect.Value, in []reflect.Value) js.Value 12 13 func Sync(funcType reflect.Type) (SyncInvoker, error) { 14 outputBinder, err := NewOutputBuilder(funcType).Build() 15 if err != nil { 16 return nil, err 17 } 18 19 switch funcType.NumOut() { 20 case 0: 21 return func(fn reflect.Value, in []reflect.Value) (result js.Value) { 22 23 defer func() { 24 if r := recover(); r != nil { 25 result = NewJsError(r) 26 } 27 }() 28 29 fn.Call(in) 30 31 return 32 33 }, nil 34 case 1: 35 outputType := funcType.Out(0) 36 //func(...)error 37 if outputType.String() == TypeError { 38 return func(fn reflect.Value, in []reflect.Value) (result js.Value) { 39 40 defer func() { 41 if r := recover(); r != nil { 42 result = NewJsError(r) 43 } 44 }() 45 46 err := fn.Call(in)[0] 47 48 // err != nil 49 if !err.IsNil() { 50 result = NewJsError(err.Interface()) 51 } 52 53 return 54 }, nil 55 } else { //func(...) T 56 return func(fn reflect.Value, in []reflect.Value) (result js.Value) { 57 58 defer func() { 59 if r := recover(); r != nil { 60 result = NewJsError(r) 61 } 62 }() 63 64 output := fn.Call(in) 65 66 result = outputBinder(output)[0] 67 68 return 69 70 }, nil 71 } 72 case 2: 73 74 errOutputType := funcType.Out(1) 75 76 if errOutputType.String() != TypeError { 77 return nil, ErrFuncNotSupported 78 } 79 //func(...) (T,error) 80 return func(fn reflect.Value, in []reflect.Value) (result js.Value) { 81 defer func() { 82 if r := recover(); r != nil { 83 result = NewJsError(r) 84 } 85 }() 86 output := fn.Call(in) 87 88 err := output[1] 89 90 // err == nil 91 if err.IsNil() { 92 result = outputBinder(output)[0] 93 } else { 94 result = NewJsError(err.Interface()) 95 } 96 97 return 98 }, nil 99 100 default: 101 return nil, ErrFuncNotSupported 102 } 103 }