func.go 1.1 KB

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