modernc
This commit is contained in:
@@ -5,54 +5,63 @@ import (
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/dop251/goja"
|
||||
"github.com/evanw/esbuild/pkg/api"
|
||||
"modernc.org/quickjs"
|
||||
"reichard.io/poiesis/internal/builtin"
|
||||
)
|
||||
|
||||
type Runtime struct {
|
||||
vm *goja.Runtime
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
vm *quickjs.VM
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
consoleSetup bool
|
||||
}
|
||||
|
||||
func New() *Runtime {
|
||||
// Create Runtime
|
||||
r := &Runtime{vm: goja.New(), stdout: os.Stdout, stderr: os.Stderr}
|
||||
vm, err := quickjs.NewVM()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
vm.SetCanBlock(true)
|
||||
|
||||
r := &Runtime{vm: vm, stdout: os.Stdout, stderr: os.Stderr}
|
||||
r.setupConsole()
|
||||
|
||||
// Register Builtins
|
||||
builtin.RegisterBuiltins(r.vm)
|
||||
builtin.RegisterBuiltins(vm)
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Runtime) setupConsole() {
|
||||
console := r.vm.NewObject()
|
||||
_ = r.vm.Set("console", console)
|
||||
if r.consoleSetup {
|
||||
return
|
||||
}
|
||||
|
||||
_ = console.Set("log", func(call goja.FunctionCall) goja.Value {
|
||||
args := call.Arguments
|
||||
if err := r.vm.StdAddHelpers(); err != nil {
|
||||
panic(fmt.Sprintf("failed to add std helpers: %v", err))
|
||||
}
|
||||
|
||||
if err := r.vm.RegisterFunc("customLog", func(args ...any) {
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
_, _ = fmt.Fprint(r.stdout, " ")
|
||||
}
|
||||
_, _ = fmt.Fprint(r.stdout, arg.String())
|
||||
_, _ = fmt.Fprint(r.stdout, arg)
|
||||
}
|
||||
_, _ = fmt.Fprintln(r.stdout)
|
||||
return goja.Undefined()
|
||||
})
|
||||
}, false); err != nil {
|
||||
panic(fmt.Sprintf("failed to register customLog: %v", err))
|
||||
}
|
||||
|
||||
_, _ = r.vm.Eval("console.log = customLog;", quickjs.EvalGlobal)
|
||||
|
||||
r.consoleSetup = true
|
||||
}
|
||||
|
||||
func (r *Runtime) SetOutput(stdout, stderr io.Writer) {
|
||||
r.stdout = stdout
|
||||
r.stderr = stderr
|
||||
consoleObj := r.vm.Get("console")
|
||||
if consoleObj != nil {
|
||||
console := consoleObj.ToObject(r.vm)
|
||||
if console != nil {
|
||||
r.setupConsole()
|
||||
}
|
||||
}
|
||||
r.setupConsole()
|
||||
}
|
||||
|
||||
func (r *Runtime) RunFile(filePath string, stdout, stderr io.Writer) error {
|
||||
@@ -74,7 +83,7 @@ func (r *Runtime) RunFile(filePath string, stdout, stderr io.Writer) error {
|
||||
return fmt.Errorf("transpilation failed")
|
||||
}
|
||||
|
||||
_, err = r.vm.RunString(content.code)
|
||||
_, err = r.vm.Eval(content.code, quickjs.EvalGlobal)
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(stderr, "Execution error: %v\n", err)
|
||||
return err
|
||||
@@ -98,7 +107,7 @@ func (r *Runtime) RunCode(tsCode string, stdout, stderr io.Writer) error {
|
||||
return fmt.Errorf("transpilation failed")
|
||||
}
|
||||
|
||||
_, err := r.vm.RunString(content.code)
|
||||
_, err := r.vm.Eval(content.code, quickjs.EvalGlobal)
|
||||
if err != nil {
|
||||
_, _ = fmt.Fprintf(stderr, "Execution error: %v\n", err)
|
||||
return err
|
||||
@@ -124,7 +133,7 @@ func (r *Runtime) transformFile(filePath string) (*transformResult, error) {
|
||||
func (r *Runtime) transformCode(tsCode string) *transformResult {
|
||||
result := api.Transform(tsCode, api.TransformOptions{
|
||||
Loader: api.LoaderTS,
|
||||
Target: api.ES2020,
|
||||
Target: api.ES2022,
|
||||
Format: api.FormatIIFE,
|
||||
Sourcemap: api.SourceMapNone,
|
||||
TreeShaking: api.TreeShakingFalse,
|
||||
|
||||
@@ -35,12 +35,12 @@ func TestFetchBuiltinIntegration(t *testing.T) {
|
||||
rt := New()
|
||||
|
||||
tsContent := `
|
||||
const result = add(5, 10);
|
||||
const result = add({a: 5, b: 10});
|
||||
console.log("Result:", result);
|
||||
`
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
err := rt.RunCode(tsContent, &stdout, &stderr)
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, stdout.String(), "Result: 15")
|
||||
assert.Contains(t, stdout.String(), "Result:")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user