safejs

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 5, 2023 License: Apache-2.0 Imports: 3 Imported by: 13

README

SafeJS Go Reference CI Coverage Status

A safer, drop-in replacement for Go's syscall/js JavaScript package.

What makes it safer?

Today, syscall/js panics when the JavaScript runtime throws errors. While sensible in a JavaScript runtime, Go libraries should avoid using panic.

SafeJS provides a nearly identical API to syscall/js, but returns errors instead of panicking.

Although returned errors aren't pretty, they make it much easier to integrate with existing Go tools and code patterns.

Backward compatibility

This package uses the same backward compatibility guarantee as syscall/js.

In an effort to align with the Go standard library API, some breaking changes may become necessary and receive their own minor version bumps.

Quick start

  1. Get safejs:
go get github.com/hack-pad/safejs
  1. Import safejs:
import "github.com/hack-pad/safejs"
  1. Replace uses of syscall/js with the safejs alternative.

Before:

//go:build js && wasm

package buttons

import "syscall/js"

// InsertButton creates a new button, adds it to 'container', and returns it. Usually.
func InsertButton(container js.Value) js.Value {
    // *whisper:* There's a good chance it could panic! Eh, probably don't need to document it, right?
    dom := js.Global().Get("document") // BOOM!
    button := dom.Call("createElement", "button") // BANG!
    container.Call("appendChild", button) // BAM!
    return button
}

After:

//go:build js && wasm

package buttons

import "github.com/hack-pad/safejs"

// InsertButton creates a new button, adds it to 'container', and returns the button or the first error.
func InsertButton(container safejs.Value) (safejs.Value, error) {
    dom, err := safejs.Global().Get("document")
    if err != nil {
        return err
    }
    button, err := dom.Call("createElement", "button")
    if err != nil {
        return err
    }
    _, err = container.Call("appendChild", button)
    if err != nil {
        return err
    }
    return button, nil
}

Even safer

For additional JavaScript safety, use the jsguard linter too.

jsguard reports the locations of unsafe JavaScript calls, which should be replaced with calls to SafeJS.

# When installed without specifying a version, uses the go.mod version.
go install github.com/hack-pad/safejs/jsguard/cmd/jsguard
export GOOS=js GOARCH=wasm
jsguard ./...

It does not report use of types like js.Value -- only function calls on those types.

This makes it easy to integrate SafeJS into existing libraries which expose only standard library types.

Documentation

Rendered for js/wasm

Overview

Package safejs provides guardrails around the syscall/js package, like turning thrown exceptions into errors.

Since syscall/js is experimental, this package may have breaking changes to stay aligned with the latest versions of Go.

Index

Constants

View Source
const (
	TypeUndefined = Type(js.TypeUndefined)
	TypeNull      = Type(js.TypeNull)
	TypeBoolean   = Type(js.TypeBoolean)
	TypeNumber    = Type(js.TypeNumber)
	TypeString    = Type(js.TypeString)
	TypeSymbol    = Type(js.TypeSymbol)
	TypeObject    = Type(js.TypeObject)
	TypeFunction  = Type(js.TypeFunction)
)

Available JavaScript types

Variables

This section is empty.

Functions

func CopyBytesToGo

func CopyBytesToGo(dst []byte, src Value) (int, error)

CopyBytesToGo copies bytes from src to dst. Returns the number of bytes copied, which is the minimum of the lengths of src and dst. Returns an error if src is not an Uint8Array or Uint8ClampedArray.

func CopyBytesToJS

func CopyBytesToJS(dst Value, src []byte) (int, error)

CopyBytesToJS copies bytes from src to dst. Returns the number of bytes copied, which is the minimum of the lengths of src and dst. Returns an error if dst is not an Uint8Array or Uint8ClampedArray.

func Unsafe

func Unsafe(value Value) js.Value

Unsafe unwraps a safejs.Value back into its js.Value. Ideal for use in libraries where exposed types must match the standard library.

Types

type Error

type Error struct {
	// contains filtered or unexported fields
}

Error wraps a JavaScript error.

func (Error) Error

func (e Error) Error() string

Error implements the error interface.

type Func

type Func struct {
	// contains filtered or unexported fields
}

Func is a wrapped Go function to be called by JavaScript.

func FuncOf

func FuncOf(fn func(this Value, args []Value) any) (Func, error)

FuncOf returns a function to be used by JavaScript. See js.FuncOf for details.

func (Func) Release

func (f Func) Release()

Release frees up resources allocated for the function. The function must not be invoked after calling Release. It is allowed to call Release while the function is still running.

func (Func) Value

func (f Func) Value() Value

Value returns this Func's inner Value. For example, using value.Invoke() calls the function.

Equivalent to accessing js.Func's embedded js.Value field, only as a safejs type.

type Type

type Type int

Type represents the JavaScript type of a Value.

func (Type) String

func (t Type) String() string

type Value

type Value struct {
	// contains filtered or unexported fields
}

Value is a safer version of js.Value. Any panic returns an error instead.

func Global

func Global() Value

Global returns the JavaScript global object, usually "window" or "global".

func MustGetGlobal added in v0.1.1

func MustGetGlobal(property string) Value

MustGetGlobal fetches the given global, then verifies it is truthy. Panics on error or falsy values. This is intended for simple global variable initialization, like preparing classes for later instantiation.

For example:

var jsUint8Array = safejs.MustGetGlobal("Uint8Array")

func Null

func Null() Value

Null returns the JavaScript value of "null".

func Safe

func Safe(value js.Value) Value

Safe wraps a js.Value into a safejs.Value. Ideal for use in libraries where exposed types must match the standard library.

func Undefined

func Undefined() Value

Undefined returns the JavaScript value of "undefined".

func ValueOf

func ValueOf(value any) (Value, error)

ValueOf returns value as a JavaScript value. See js.ValueOf for details.

func (Value) Bool

func (v Value) Bool() (bool, error)

Bool attempts to convert this value into a boolean, otherwise returns an error.

func (Value) Call

func (v Value) Call(m string, args ...any) (Value, error)

Call does a JavaScript call to the method m of value v with the given arguments. The arguments are mapped to JavaScript values according to the ValueOf function. Returns an error if v has no method m, the arguments failed to map to JavaScript values, or the function throws an error.

func (Value) Delete

func (v Value) Delete(p string) error

Delete deletes the JavaScript property p of value v. Returns an error if v is not a JavaScript object.

func (Value) Equal

func (v Value) Equal(w Value) bool

Equal reports whether v and w are equal according to JavaScript's === operator.

func (Value) Float

func (v Value) Float() (float64, error)

Float returns the value v as a float64. Returns an error if v is not a JavaScript number.

func (Value) Get

func (v Value) Get(p string) (Value, error)

Get returns the JavaScript property p of value v. Returns an error if v is not a JavaScript object.

func (Value) Index

func (v Value) Index(i int) (Value, error)

Index returns JavaScript index i of value v. Returns an error if v is not a JavaScript object.

func (Value) InstanceOf

func (v Value) InstanceOf(t Value) (bool, error)

InstanceOf reports whether v is an instance of type t according to JavaScript's instanceof operator. Returns an error if v is not a constructable type.

func (Value) Int

func (v Value) Int() (int, error)

Int returns the value v truncated to an int. Returns an error if v is not a JavaScript number.

func (Value) Invoke

func (v Value) Invoke(args ...any) (Value, error)

Invoke does a JavaScript call of the value v with the given arguments. The arguments get mapped to JavaScript values according to the ValueOf function. Returns an error if v is not a JavaScript function, the arguments failed to map to JavaScript values, or the function throws an error.

func (Value) IsNaN

func (v Value) IsNaN() bool

IsNaN reports whether v is the JavaScript value "NaN".

func (Value) IsNull

func (v Value) IsNull() bool

IsNull reports whether v is the JavaScript value "null".

func (Value) IsUndefined

func (v Value) IsUndefined() bool

IsUndefined reports whether v is the JavaScript value "undefined".

func (Value) Length

func (v Value) Length() (int, error)

Length returns the JavaScript property "length" of v. Returns an error if v is not a JavaScript object.

func (Value) New

func (v Value) New(args ...any) (Value, error)

New uses JavaScript's "new" operator with value v as constructor and the given arguments. The arguments get mapped to JavaScript values according to the ValueOf function. Returns an error if v is not a JavaScript function, the arguments failed to map to JavaScript values, or the constructor throws an error.

func (Value) Set

func (v Value) Set(p string, x any) error

Set sets the JavaScript property p of value v to ValueOf(x). Returns an error if v is not a JavaScript object or x failed to map to a JavaScript value.

func (Value) SetIndex

func (v Value) SetIndex(i int, x any) error

SetIndex sets the JavaScript index i of value v to ValueOf(x). Returns an error if if v is not a JavaScript object or x failed to map to a JavaScript value.

func (Value) String

func (v Value) String() (string, error)

String returns the value v as a string. Unlike the other getters, String() does not return an error if v's Type is not TypeString. Instead, it returns a string of the form "<T>" or "<T: V>" where T is v's type and V is a string representation of v's value.

Returns an error if v is an invalid type or the string failed to load from the JavaScript runtime.

NOTE: syscall/js takes the stance that String is a special case due to Go's String method convention and avoids panicking. However, js.String() can still fail in other ways so an error is returned anyway.

func (Value) Truthy

func (v Value) Truthy() (bool, error)

Truthy returns the JavaScript "truthiness" of the value v. In JavaScript, false, 0, "", null, undefined, and NaN are "falsy", and everything else is "truthy". See https://developer.mozilla.org/en-US/docs/Glossary/Truthy.

Returns an error if v's type is invalid or if the value fails to load from the JavaScript runtime.

func (Value) Type

func (v Value) Type() Type

Type returns the JavaScript type of the value v. It is similar to JavaScript's typeof operator, except it returns TypeNull instead of TypeObject for null.

Directories

Path Synopsis
internal
assert
Package assert contains small assertion test functions to assist in writing clean tests.
Package assert contains small assertion test functions to assist in writing clean tests.
catch
Package catch runs functions and returns panic values as errors instead.
Package catch runs functions and returns panic values as errors instead.
stackerr
Package stackerr adds stack traces to verbose error messages.
Package stackerr adds stack traces to verbose error messages.
Package jsguard analyzes unsafe calls to Go's syscall/js package
Package jsguard analyzes unsafe calls to Go's syscall/js package
cmd/jsguard
Command jsguard reports unsafe calls to Go's syscall/js package
Command jsguard reports unsafe calls to Go's syscall/js package

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL