This commit is contained in:
2026-01-27 20:04:36 -05:00
parent c3a16c9e92
commit f9d3753806
13 changed files with 247 additions and 352 deletions

View File

@@ -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,