commonjs

package module
v0.1.11 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2023 License: Apache-2.0 Imports: 22 Imported by: 8

README

CommonJS for Goja

Use the Goja JavaScript engine in a CommonJS-style modular environment. Supports require, exports, and more, following the Node.js implementation as much as possible.

Features:

  • Customize the environment with your own special APIs. Useful optional APIs are provided.
  • Automatically converts Go field names to dromedary case for a more idiomatic JavaScript experience, e.g. .DoTheThing becomes .doTheThing.
  • By default require supports full URLs and can resolve paths relative to the current module's location. But this can be customized to support your own special resolution and loading method (e.g. loading modules from a database).
  • Optional support for watching changes to all resolved JavaScript files if they are in the local filesystem, allowing your application to restart or otherwise respond to live code updates.
  • Optional support for bind, which is similar to require but exports the JavaScript objects, including functions, into a new goja.Runtime. This is useful for multi-threaded Go environments because a single goja.Runtime cannot be used simulatenously by more than one thread. Two variations exist: early binding, which creates the Runtime when bind is called (lower concurrency, higher performance), and late binding, which creates the Runtime every time the bound object is unbound (higher concurrency, lower performance).

Example

start.go:

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/tliron/commonjs-goja"
    "github.com/tliron/exturl"
    "github.com/dop251/goja"
)

func main() {
    urlContext := exturl.NewContext()
    defer urlContext.Release()

    wd, _ := urlContext.NewWorkingDirFileURL()

    environment := commonjs.NewEnvironment(urlContext, []exturl.URL{wd})
    defer environment.Release()

    // Support a "console.log" API
    environment.Extensions = append(environment.Extensions, commonjs.Extension{
        Name: "console",
        Create: func(context *commonjs.Context) goja.Value {
            return context.Environment.Runtime.ToValue(ConsoleAPI{})
        },
    })

    // Support a "bind" API (using late binding)
    environment.Extensions = append(environment.Extensions, commonjs.Extension{
        Name:   "bind",
        Create: commonjs.CreateLateBindExtension,
    })

    // Start!
    environment.RequireID("./start")
}

type ConsoleAPI struct{}

func (self ConsoleAPI) Log(message string) {
    fmt.Println(message)
}

start.js:

const hello = require('./lib/hello');

hello.sayit();

lib/hello.js:

exports.sayit = function() {
    console.log('hi!');
};

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DromedaryCaseMapper dromedaryCaseMapper

Functions

func Call

func Call(runtime *goja.Runtime, function JavaScriptFunc, this any, arguments ...any) (value any, err error)

func CreateEarlyBindExtension

func CreateEarlyBindExtension(context *Context) goja.Value

(CreateExtensionFunc signature)

func CreateLateBindExtension

func CreateLateBindExtension(context *Context) goja.Value

(CreateExtensionFunc signature)

func GetAndCall added in v0.1.10

func GetAndCall(runtime *goja.Runtime, object *goja.Object, name string, this any, arguments ...any) (value any, err error)

func HandlePanic added in v0.1.11

func HandlePanic(r any) error

Call with a recover() value. If it's an error, then it will be returned. A *goja.Exception will be unwrapped and returned.

Otherwise, will re-panic the value.

This function is useful for cases in which Goja indicates errors by panicing instead of returning an error.

Usage:

func MyFunc() (err error) {
	defer func() {
		if err_ := HandlePanic(recover()); err_ != nil {
			err = err_
		}
	}()
	// do something that can panic
}

func ToObject added in v0.1.10

func ToObject(runtime *goja.Runtime, value any) *goja.Object

func ToObjectFromValue added in v0.1.10

func ToObjectFromValue(runtime *goja.Runtime, value goja.Value) *goja.Object

Types

type Bind

type Bind interface {
	Unbind() (any, *Context, error)
}

type Context

type Context struct {
	Environment *Environment
	Parent      *Context
	Module      *Module
	Resolve     ResolveFunc
	Extensions  []goja.Value
}

type CreateExtensionFunc

type CreateExtensionFunc func(context *Context) goja.Value

type CreateResolverFunc

type CreateResolverFunc func(url exturl.URL, context *Context) ResolveFunc

func NewDefaultResolverCreator

func NewDefaultResolverCreator(urlContext *exturl.Context, basePaths []exturl.URL, defaultExtension string, allowFilePaths bool) CreateResolverFunc

type EarlyBind

type EarlyBind struct {
	Value   any
	Context *Context
}

func (EarlyBind) Unbind

func (self EarlyBind) Unbind() (any, *Context, error)

(Bind interface)

type Environment

type Environment struct {
	Runtime        *goja.Runtime
	URLContext     *exturl.Context
	BasePaths      []exturl.URL
	Extensions     []Extension
	Modules        *goja.Object
	Precompile     PrecompileFunc
	CreateResolver CreateResolverFunc
	OnFileModified OnFileModifiedFunc
	Log            commonlog.Logger
	Lock           sync.Mutex
	// contains filtered or unexported fields
}

func NewEnvironment

func NewEnvironment(urlContext *exturl.Context, basePaths []exturl.URL) *Environment

func (*Environment) AddModule

func (self *Environment) AddModule(url exturl.URL, module *Module)

func (*Environment) Call

func (self *Environment) Call(function JavaScriptFunc, this any, arguments ...any) (any, error)

func (*Environment) ClearCache

func (self *Environment) ClearCache()

func (*Environment) GetAndCall added in v0.1.10

func (self *Environment) GetAndCall(object *goja.Object, name string, this any, arguments ...any) (any, error)

func (*Environment) NewChild

func (self *Environment) NewChild() *Environment

func (*Environment) NewContext

func (self *Environment) NewContext(url exturl.URL, parent *Context) *Context

func (*Environment) NewModule

func (self *Environment) NewModule() *Module

func (*Environment) Release

func (self *Environment) Release() error

func (*Environment) RequireID

func (self *Environment) RequireID(id string) (*goja.Object, error)

func (*Environment) RequireURL

func (self *Environment) RequireURL(url exturl.URL) (*goja.Object, error)

func (*Environment) StartWatcher added in v0.1.10

func (self *Environment) StartWatcher() error

func (*Environment) StopWatcher

func (self *Environment) StopWatcher() error

func (*Environment) Watch

func (self *Environment) Watch(path string) error

type Extension

type Extension struct {
	Name   string
	Create CreateExtensionFunc
}

type FileAPI

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

func NewFileAPI

func NewFileAPI(context *exturl.Context) FileAPI

func (FileAPI) Download

func (self FileAPI) Download(sourceUrl string, targetPath string) error

func (FileAPI) Exec

func (self FileAPI) Exec(name string, arguments ...string) (string, error)

func (FileAPI) JoinFilePath

func (self FileAPI) JoinFilePath(elements ...string) string

func (FileAPI) TemporaryDirectory

func (self FileAPI) TemporaryDirectory(pattern string, directory string) (string, error)

func (FileAPI) TemporaryFile

func (self FileAPI) TemporaryFile(pattern string, directory string) (string, error)

type JavaScriptFunc

type JavaScriptFunc = func(goja.FunctionCall) goja.Value

This is returned type when calling Export() on a goja.FunctionCall.

type LateBind

type LateBind struct {
	URL        exturl.URL
	ExportName string
	Context    *Context
}

func (LateBind) Unbind

func (self LateBind) Unbind() (value any, context *Context, err error)

(Bind interface)

type Module

type Module struct {
	Id           string
	Children     []*Module
	Filename     string
	Path         string
	Paths        []string
	Exports      *goja.Object
	Require      *goja.Object
	IsPreloading bool
	Loaded       bool
}

type OnFileModifiedFunc added in v0.1.10

type OnFileModifiedFunc func(id string, module *Module)

type PrecompileFunc

type PrecompileFunc func(url exturl.URL, script string, context *Context) (string, error)

type ResolveFunc

type ResolveFunc func(context contextpkg.Context, id string, raw bool) (exturl.URL, error)

type ThreadSafeObject

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

func NewThreadSafeObject

func NewThreadSafeObject() *ThreadSafeObject

func (*ThreadSafeObject) Delete

func (self *ThreadSafeObject) Delete(key string) bool

(goja.DynamicObject interface)

func (*ThreadSafeObject) Get

func (self *ThreadSafeObject) Get(key string) goja.Value

(goja.DynamicObject interface)

func (*ThreadSafeObject) Has

func (self *ThreadSafeObject) Has(key string) bool

(goja.DynamicObject interface)

func (*ThreadSafeObject) Keys

func (self *ThreadSafeObject) Keys() []string

(goja.DynamicObject interface)

func (*ThreadSafeObject) NewDynamicObject

func (self *ThreadSafeObject) NewDynamicObject(runtime *goja.Runtime) *goja.Object

func (*ThreadSafeObject) Set

func (self *ThreadSafeObject) Set(key string, value goja.Value) bool

(goja.DynamicObject interface)

type TranscribeAPI

type TranscribeAPI struct{}

func (TranscribeAPI) Atob

func (self TranscribeAPI) Atob(b64 string) ([]byte, error)

Decode base64 to bytes

func (TranscribeAPI) Btoa

func (self TranscribeAPI) Btoa(bytes []byte) string

Encode bytes as base64

func (TranscribeAPI) BytesToString

func (self TranscribeAPI) BytesToString(bytes []byte) string

Another way to achieve this in JavaScript: String.fromCharCode.apply(null, bytes)

func (TranscribeAPI) Decode

func (self TranscribeAPI) Decode(code []byte, format string, all bool) (ard.Value, error)

func (TranscribeAPI) Encode

func (self TranscribeAPI) Encode(value any, format string, indent string, writer io.Writer) (string, error)

func (TranscribeAPI) NewXMLDocument

func (self TranscribeAPI) NewXMLDocument() *etree.Document

func (TranscribeAPI) StringToBytes

func (self TranscribeAPI) StringToBytes(string_ string) []byte

func (TranscribeAPI) ValidateFormat

func (self TranscribeAPI) ValidateFormat(code []byte, format string) error

type UtilAPI

type UtilAPI struct{}

func (UtilAPI) DeepCopy

func (self UtilAPI) DeepCopy(value ard.Value) ard.Value

func (UtilAPI) DeepEquals

func (self UtilAPI) DeepEquals(a ard.Value, b ard.Value) bool

func (UtilAPI) Go

func (self UtilAPI) Go(value goja.Value) error

Goroutine

func (UtilAPI) Hash

func (self UtilAPI) Hash(value ard.Value) (string, error)

func (UtilAPI) IsType

func (self UtilAPI) IsType(value ard.Value, type_ string) (bool, error)

func (UtilAPI) Mutex

func (self UtilAPI) Mutex() util.RWLocker

func (UtilAPI) Now

func (self UtilAPI) Now() time.Time

func (UtilAPI) Once

func (self UtilAPI) Once(name string, value goja.Value) error

func (UtilAPI) Printf

func (self UtilAPI) Printf(format string, args ...any)

func (UtilAPI) Sprintf

func (self UtilAPI) Sprintf(format string, args ...any) string

Jump to

Keyboard shortcuts

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