package jsrunner
import (
"context"
"errors"
"fmt"
"os"
"github.com/dop251/goja"
)
type gojaRunner struct {
vm *goja .Runtime
}
type gojaValue struct {
val goja .Value
vm *goja .Runtime
}
func NewJSRunner () JSRunner {
return &gojaRunner {vm : goja .New ()}
}
func (g *gojaRunner ) MustGet (key string ) (JSValue , error ) {
return nil , nil
}
func (g *gojaRunner ) Engine () Engine {
return Goja
}
func (g *gojaRunner ) RunString (code string ) (JSValue , error ) {
val , err := g .vm .RunString (code )
if err != nil {
return nil , err
}
return &gojaValue {val : val , vm : g .vm }, nil
}
func (v *gojaValue ) String () string {
return v .val .String ()
}
func (v *gojaValue ) Export () interface {} {
return v .val .Export ()
}
func (g *gojaRunner ) NewObject () JSObject {
return &gojaValue {val : g .vm .NewObject (), vm : g .vm }
}
func (g *gojaRunner ) Set (name string , value interface {}) error {
if name == "console" {
console , err := g .createConsole ()
if err != nil {
return err
}
return g .vm .Set (name , console )
}
return g .vm .Set (name , value )
}
func (g *gojaRunner ) WaitPromise (ctx context .Context , val JSValue ) (interface {}, error ) {
gVal := val .(*gojaValue )
p := gVal .val .Export ()
promise := p .(*goja .Promise )
for promise .State () == goja .PromiseStatePending {
if err := ctx .Err (); err != nil {
return nil , err
}
continue
}
if promise .State () == goja .PromiseStateRejected {
return nil , errors .New ("Promise rejected" )
}
return promise .Result ().Export (), nil
}
func (g *gojaRunner ) createConsole () (*goja .Object , error ) {
vm := g .vm
console := vm .NewObject ()
if err := console .Set ("log" , vm .ToValue (func (call goja .FunctionCall ) goja .Value {
args := make ([]interface {}, len (call .Arguments ))
for i , arg := range call .Arguments {
args [i ] = arg .Export ()
}
fmt .Println (args ...)
return nil
})); err != nil {
return nil , err
}
if err := console .Set ("error" , vm .ToValue (func (call goja .FunctionCall ) goja .Value {
args := make ([]interface {}, len (call .Arguments ))
for i , arg := range call .Arguments {
args [i ] = arg .Export ()
}
fmt .Fprintln (os .Stderr , args ...)
return nil
})); err != nil {
return nil , err
}
return console , nil
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .