func.go raw

   1  //go:build js && wasm
   2  
   3  package safejs
   4  
   5  import (
   6  	"syscall/js"
   7  
   8  	"github.com/hack-pad/safejs/internal/catch"
   9  )
  10  
  11  // Func is a wrapped Go function to be called by JavaScript.
  12  type Func struct {
  13  	fn js.Func
  14  }
  15  
  16  // FuncOf returns a function to be used by JavaScript. See [js.FuncOf] for details.
  17  func FuncOf(fn func(this Value, args []Value) any) (Func, error) {
  18  	jsFunc, err := toJSFunc(fn)
  19  	return Func{
  20  		fn: jsFunc,
  21  	}, err
  22  }
  23  
  24  func toJSFunc(fn func(this Value, args []Value) any) (js.Func, error) {
  25  	jsFunc := func(this js.Value, args []js.Value) any {
  26  		result := fn(Safe(this), toValues(args))
  27  		return toJSValue(result)
  28  	}
  29  	return catch.Try(func() js.Func {
  30  		return js.FuncOf(jsFunc)
  31  	})
  32  }
  33  
  34  // Release frees up resources allocated for the function. The function must not be invoked after calling Release.
  35  // It is allowed to call Release while the function is still running.
  36  func (f Func) Release() {
  37  	f.fn.Release()
  38  }
  39  
  40  // Value returns this Func's inner Value. For example, using value.Invoke() calls the function.
  41  //
  42  // Equivalent to accessing [js.Func]'s embedded [js.Value] field, only as a safejs type.
  43  func (f Func) Value() Value {
  44  	return Safe(f.fn.Value)
  45  }
  46