Documentation
¶
Overview ¶
Package js provides an abstraction on top of V8.
The purpose is to allow a modular approach to implementing client-side APIs, where the modules don't need to address a specific script engine; and client code can switch between script engines.
The ability to switch script engine seems like a really good idea, as you have two different priorities you might want to switch between:
- Using an engine that you know contains latest ES standards (V8) - Using a pure Go engine, simplifying the build pipeline.
Additionally, if other projects would support SpiderMonkey (Firefox) and JavaScriptCore (Safari), you could verify your code using the script engines of the different browsers. (Do note, that it is outside the scope of this project to simulate the differences of different browsers).
Index ¶
- Variables
- func AddConfigurator[T any](fact ScriptEngineFactory[T], conf ConfigurerFunc[T])
- func As[T any](val any, err error) (rtnVal T, rtnErr error)
- func ConsumeArgument[T, U any](args CallbackContext[U], name string, defaultValue func() T, ...) (result T, err error)
- func ConsumeOptionalArg[T, U any](cbCtx CallbackContext[T], name string, ...) (result U, found bool, err error)
- func ConsumeRestArguments[T, U any](args CallbackContext[U], name string, ...) (results []T, err error)
- func IsNullish[T any](v Value[T]) bool
- func ParseSetterArg[T, U any](ctx CallbackContext[T], ...) (result U, err error)
- func RegisterClass[T any, U Initializer[T], V InitializerFactory[T, U]](reg ClassBuilder[T], className, superClassName string, constructorFactory V)
- func UnhandledError[T any](scope Scope[T], err error)
- type ArgumentConsumer
- type CallbackContext
- type CallbackScope
- type Class
- type ClassBuilder
- type Configurator
- type ConfigurerFunc
- type Constructor
- type ConstructorFactory
- type Disposable
- type Error
- type Function
- type FunctionCallback
- type HandlerCallbacks
- type HandlerDeleterCallback
- type HandlerEnumeratorCallback
- type HandlerGetterCallback
- type HandlerOption
- func WithDeleterCallback[T, U any](cb HandlerDeleterCallback[T, U]) HandlerOption[T, U]
- func WithEnumeratorCallback[T, U any](cb HandlerEnumeratorCallback[T, U]) HandlerOption[T, U]
- func WithGetterCallback[T, U any](cb HandlerGetterCallback[T, U]) HandlerOption[T, U]
- func WithSetterCallback[T, U any](cb HandlerSetterCallback[T, U]) HandlerOption[T, U]
- type HandlerSetterCallback
- type IndexLenCallback
- type IndexedHandlerCallbacks
- type IndexedHandlerOption
- type Initializer
- type InitializerFactory
- type Iterator
- type Iterator2
- type NamedHandlerCallbacks
- type NamedHandlerOption
- type Object
- type Promise
- type Scope
- type ScriptEngine
- type ScriptEngineFactory
- type Value
- type ValueFactory
- type ValueResolver
Constants ¶
This section is empty.
Variables ¶
var ErrMissingArgument = errors.New("missing argument")
var ErrNoInternalValue = errors.New("object does not have an internal instance")
var NotIntercepted = errors.New("Not intercepted")
Functions ¶
func AddConfigurator ¶ added in v0.7.2
func AddConfigurator[T any](fact ScriptEngineFactory[T], conf ConfigurerFunc[T])
func ConsumeArgument ¶ added in v0.7.2
func ConsumeArgument[T, U any]( args CallbackContext[U], name string, defaultValue func() T, decoders ...func(CallbackContext[U], Value[U]) (T, error), ) (result T, err error)
ConsumeArgument pulls one of the passed arguments and tries to convert it to target type T using one of the passed decoders. The return value will be taken from the first decode that does not return an error. If no decoder is succeeds, an error is returned.
If no more arguments are present, or the next argument is undefined, the defaultValue function will be used if not nil; otherwise an error is returned.
If the function returns with an error, the name will be used in the error message. Otherwise, name has ho effect on the function.
func ConsumeOptionalArg ¶ added in v0.7.2
func ConsumeOptionalArg[T, U any]( cbCtx CallbackContext[T], name string, decoders ...func(CallbackContext[T], Value[T]) (U, error), ) (result U, found bool, err error)
func ConsumeRestArguments ¶ added in v0.7.2
func ConsumeRestArguments[T, U any]( args CallbackContext[U], name string, decoders ...func(CallbackContext[U], Value[U]) (T, error), ) (results []T, err error)
func ParseSetterArg ¶ added in v0.7.2
func ParseSetterArg[T, U any]( ctx CallbackContext[T], parsers ...func(CallbackContext[T], Value[T]) (U, error), ) (result U, err error)
ParseSetterArg parses a single argument and is intended for attribute setters, where exactly one argument must be passed by v8.
func RegisterClass ¶ added in v0.7.2
func RegisterClass[T any, U Initializer[T], V InitializerFactory[T, U]]( reg ClassBuilder[T], className, superClassName string, constructorFactory V)
func UnhandledError ¶ added in v0.7.2
Types ¶
type ArgumentConsumer ¶ added in v0.7.2
type ArgumentConsumer[T any] interface { // ConsumeArg pulls argument from the list of passed arguments. The return // value arg will contain the argument. If no argument is passed, or // the value is undefined, arg will be nil. Ok indicates whether there were // more arguments to consume, // the function returns nil. (e.g., if you call the method 3 times, but only // two arguments were passed). // // For most use cases, the client shouldn't care about the ok return value; // but treat the value as if undefined was passed. The primary use for ok is // when consuming the remaining arguments for a variadic argument list, e.g. // [Element.append] // // [Element.append]: https://developer.mozilla.org/en-US/docs/Web/API/Element/append ConsumeArg() (arg Value[T], ok bool) }
type CallbackContext ¶
type CallbackContext[T any] interface { ArgumentConsumer[T] CallbackScope[T] // ReturnWithValue(Value[T]) (Value[T], error) // ReturnWithError(error) (Value[T], error) ReturnWithTypeError(msg string) (Value[T], error) }
CallbackContext represents the execution context of a JavaScript function or handler callback. For example
- Calling a native function or constructor - Getting or setting an accessor property backed by a native function
An instance of CallbackContext can only be used inside the actual function callback.
type CallbackScope ¶ added in v0.7.2
type CallbackScope[T any] interface { Scope[T] // Instance returns the Go value that is wrapped by "this", with "this" // referring the the JavaScript value of "this". If the object does not // contain an internal Go value an [ErrNoInternalValue] error is returned. Instance() (any, error) Logger() *slog.Logger This() Object[T] }
type Class ¶ added in v0.7.2
type Class[T any] interface { CreatePrototypeMethod(name string, cb FunctionCallback[T]) CreateIteratorMethod(cb FunctionCallback[T]) CreatePrototypeAttribute(name string, getter FunctionCallback[T], setter FunctionCallback[T]) CreateInstanceAttribute(name string, getter FunctionCallback[T], setter FunctionCallback[T]) CreateIndexedHandler(getter ...IndexedHandlerOption[T]) CreateNamedHandler(opts ...NamedHandlerOption[T]) }
Class represents a JavaScript "class" that wraps a Go object.
This package has two separate abstractions for a class serving two different roles. This abstractions serves the role of configuring the methods and attributes that exists on a class. To create an instance of a class, you use the Constructor
This is independent of any actual execution context, so values in global scope can be declared before creating a JavaScript execution context.
type ClassBuilder ¶ added in v0.7.2
type ClassBuilder[T any] struct { // contains filtered or unexported fields }
func NewClassBuilder ¶ added in v0.7.2
func NewClassBuilder[T any]() ClassBuilder[T]
func (*ClassBuilder[T]) CreateGlobals ¶ added in v0.7.2
func (c *ClassBuilder[T]) CreateGlobals(host ScriptEngine[T])
CreateGlobals returns an ordered list of constructors to be created in global scope. They must be installed in "order", as base classes must be installed before subclasses
func (ClassBuilder[T]) HasClass ¶ added in v0.7.2
func (b ClassBuilder[T]) HasClass(name string) bool
func (ClassBuilder[T]) Register ¶ added in v0.7.2
func (r ClassBuilder[T]) Register( className, superClassName string, fact InitializerFactory[T, Initializer[T]], )
type Configurator ¶ added in v0.7.2
type Configurator[T any] interface{ Configure(ScriptEngine[T]) }
type ConfigurerFunc ¶ added in v0.7.2
type ConfigurerFunc[T any] func(ScriptEngine[T])
func (ConfigurerFunc[T]) Configure ¶ added in v0.7.2
func (f ConfigurerFunc[T]) Configure(e ScriptEngine[T])
type Constructor ¶ added in v0.7.2
Constructor represents a JavaScript "class" that wraps a Go object.
This package has two separate abstractions for a class serving two different roles. This abstraction is used to create instances of a class in a JavaScript execution context.
The class must previously have been configured using the Class interface.
type ConstructorFactory ¶ added in v0.7.2
type ConstructorFactory[T any] = func(ScriptEngine[T], Class[T]) Class[T]
type Disposable ¶ added in v0.7.2
type Disposable interface{ Dispose() }
disposable represents a resource that needs cleanup when a context is closed. E.g., cgo handles that need to be released.
type FunctionCallback ¶
type FunctionCallback[T any] func(CallbackContext[T]) (Value[T], error)
type HandlerCallbacks ¶ added in v0.7.2
type HandlerCallbacks[Tjs, Tkey any] struct { Getter HandlerGetterCallback[Tjs, Tkey] Setter HandlerSetterCallback[Tjs, Tkey] Deleter HandlerDeleterCallback[Tjs, Tkey] Enumerator HandlerEnumeratorCallback[Tjs, Tkey] }
type HandlerDeleterCallback ¶ added in v0.7.2
type HandlerDeleterCallback[T, U any] func(scope CallbackScope[T], key U) (bool, error)
type HandlerEnumeratorCallback ¶ added in v0.7.2
type HandlerEnumeratorCallback[T, U any] func(CallbackScope[T]) ([]U, error)
type HandlerGetterCallback ¶ added in v0.7.2
type HandlerGetterCallback[T, U any] func(scope CallbackScope[T], key U) (Value[T], error)
type HandlerOption ¶ added in v0.7.2
type HandlerOption[T, U any] = func(*HandlerCallbacks[T, U])
func WithDeleterCallback ¶ added in v0.7.2
func WithDeleterCallback[T, U any](cb HandlerDeleterCallback[T, U]) HandlerOption[T, U]
func WithEnumeratorCallback ¶ added in v0.7.2
func WithEnumeratorCallback[T, U any](cb HandlerEnumeratorCallback[T, U]) HandlerOption[T, U]
func WithGetterCallback ¶ added in v0.7.2
func WithGetterCallback[T, U any](cb HandlerGetterCallback[T, U]) HandlerOption[T, U]
func WithSetterCallback ¶ added in v0.7.2
func WithSetterCallback[T, U any](cb HandlerSetterCallback[T, U]) HandlerOption[T, U]
type HandlerSetterCallback ¶ added in v0.7.2
type HandlerSetterCallback[T, U any] func(scope CallbackScope[T], key U, value Value[T]) error
type IndexLenCallback ¶ added in v0.8.0
type IndexLenCallback[T any] func(CallbackScope[T]) (int, error)
type IndexedHandlerCallbacks ¶ added in v0.8.0
type IndexedHandlerCallbacks[T any] struct { Getter HandlerGetterCallback[T, int] Len IndexLenCallback[T] }
type IndexedHandlerOption ¶ added in v0.8.0
type IndexedHandlerOption[T any] = func(*IndexedHandlerCallbacks[T])
func WithIndexedGetterCallback ¶ added in v0.8.0
func WithIndexedGetterCallback[T any](cb HandlerGetterCallback[T, int]) IndexedHandlerOption[T]
func WithLengthCallback ¶ added in v0.8.0
func WithLengthCallback[T any](cb IndexLenCallback[T]) IndexedHandlerOption[T]
type Initializer ¶ added in v0.7.2
type Initializer[T any] interface { Constructor(CallbackContext[T]) (Value[T], error) Initialize(Class[T]) }
type InitializerFactory ¶ added in v0.7.2
type InitializerFactory[T any, U Initializer[T]] = func(ScriptEngine[T]) U
type Iterator ¶ added in v0.7.2
type Iterator[E, T any] struct { Resolver ValueResolver[E, T] }
Iterator implements the iterator protocol for a Go iter.Seq[E]. Type parameter T is the type parameter for the script engine. The field Resolver is a function that is used to generate a JavaScript value for an element of type E.
func NewIterator ¶ added in v0.7.2
func NewIterator[T, U any](entityLookup ValueResolver[T, U]) Iterator[T, U]
func (Iterator[T, U]) InstallPrototype ¶ added in v0.7.2
Method InstallPrototype creates the following prototype methods:
- Symbol iterator - implementing the iterable protocol - "entries" - which all web API implement
type Iterator2 ¶ added in v0.7.2
type Iterator2[K, V, U any] struct { // contains filtered or unexported fields }
Iterator2 is like Iterator, but implements a key/value iterator over an iter.Seq2[K,V] value.
func NewIterator2 ¶ added in v0.7.2
func NewIterator2[K, V, U any]( keyLookup ValueResolver[K, U], valueLookup ValueResolver[V, U], ) Iterator2[K, V, U]
func (Iterator2[K, V, U]) InstallPrototype ¶ added in v0.7.2
InstallPrototype creates the following prototype methods on cls.
- Symbol Iterator - "entries" - Returns the same iterator as Symbol Iterator - "keys" - Returns an iterator over all keys - "values" - Returns an iterator over all values
type NamedHandlerCallbacks ¶ added in v0.7.2
type NamedHandlerCallbacks[T any] = HandlerCallbacks[T, Value[T]]
type NamedHandlerOption ¶ added in v0.7.2
type NamedHandlerOption[T any] = func(*HandlerCallbacks[T, Value[T]])
type Object ¶ added in v0.7.2
type Object[T any] interface { Value[T] NativeValue() any SetNativeValue(any) Keys() ([]string, error) Get(name string) (Value[T], error) Set(name string, val Value[T]) error }
func AssertObjectArg ¶ added in v0.7.2
func AssertObjectArg[T any](cbCtx CallbackContext[T], v Value[T]) (Object[T], error)
AssertObject asserts that an argument is of an object type. A TypeError is returned if the value is not an object
type Promise ¶ added in v0.8.0
type Promise[T any] interface { Value[T] Resolve(Value[T]) // Reject rejects the promise with an Error instance, representing a Go // error value. This is based on two assumptions // // - You always want to reject with Error values. // - The cause will be an instance of a Go error value. // // So while you can reject with any value in JavaScript, it is best practice // to only use Error values, and this assumes that all API calls will follow // this practice. Reject(Value[T]) }
Promise represents a JavaScript promise that is controlled from Go-code.
type Scope ¶ added in v0.7.2
type Scope[T any] interface { ValueFactory[T] Window() html.Window GlobalThis() Object[T] Clock() *clock.Clock GetValue(entity.ObjectIder) (Value[T], bool) SetValue(entity.ObjectIder, Value[T]) Constructor(string) Constructor[T] }
Scope provides access to the JavaScript execution context not coupled to a specific function callback. CallbackScope is safe use outside the scope of a function callback.
One case for storing the callback scope is when JavaScript code passes a function as a callback argument, which Go code need to call at a later point in time. E.g., when adding event listeners.
type ScriptEngine ¶ added in v0.7.2
type ScriptEngine[T any] interface { CreateClass(name string, Parent Class[T], cb FunctionCallback[T]) Class[T] CreateFunction(name string, cb FunctionCallback[T]) RunScript(script, src string) }
type ScriptEngineFactory ¶ added in v0.7.2
type ScriptEngineFactory[T any] interface { AddConfigurator(Configurator[T]) }
ScriptEngineFactory constructs ScriptEngine instances. Client code can register a Configurator to define values in global JavaScript scope.
type Value ¶
type Value[T any] interface { Self() T String() string Int32() int32 Uint32() uint32 Boolean() bool IsUndefined() bool IsNull() bool IsBoolean() bool IsString() bool IsObject() bool IsFunction() bool AsFunction() (Function[T], bool) AsObject() (Object[T], bool) StrictEquals(Value[T]) bool }
Value represents a value in JavaScript. Referential equality cannot be used to check if to Value instances represent the same value in JavaScript. Use StrictEquals to check if two values are equal.
A script engine can use the method Self to return internal values.
The type parameter T is controlled by the actual script engine, permitting retriving the internal value used by the engine without type assertions, but more importantly, prevents bugs caused by misuse by client code. With the type parameter, only values produced by a script engine can be supplied to the engine, not any object that conforms to the interface.
type ValueFactory ¶
type ValueFactory[T any] interface { Undefined() Value[T] Null() Value[T] NewPromise() Promise[T] NewString(string) Value[T] NewBoolean(bool) Value[T] NewObject() Object[T] NewUint8Array([]byte) Value[T] NewUint32(uint32) Value[T] NewInt32(int32) Value[T] NewInt64(int64) Value[T] // NewArray creates a JavaScript array containing the values. If any value // is nil, it will become undefined in the resulting array. NewArray(...Value[T]) Value[T] // NewIterator returns an object implementing the [Iterator protocol] // // [Iterator protocol]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterator_protocol NewIterator(iter.Seq2[Value[T], error]) Value[T] NewTypeError(msg string) error NewError(err error) Error[T] JSONStringify(val Value[T]) string JSONParse(val string) (Value[T], error) }
ValueFactory allows creating JavaScript values from Go values