pls
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
@@ -11,36 +12,37 @@ import (
|
||||
)
|
||||
|
||||
type Runtime struct {
|
||||
vm *quickjs.VM
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
consoleSetup bool
|
||||
vm *quickjs.VM
|
||||
ctx context.Context
|
||||
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
}
|
||||
|
||||
func New() *Runtime {
|
||||
func New(ctx context.Context) (*Runtime, error) {
|
||||
// Create VM
|
||||
vm, err := quickjs.NewVM()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vm.SetCanBlock(true)
|
||||
|
||||
r := &Runtime{vm: vm, stdout: os.Stdout, stderr: os.Stderr}
|
||||
r.setupConsole()
|
||||
// Create Runtime
|
||||
r := &Runtime{vm: vm, ctx: ctx, stdout: os.Stdout, stderr: os.Stderr}
|
||||
if err := r.populateGlobals(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
builtin.RegisterBuiltins(vm)
|
||||
return r
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (r *Runtime) setupConsole() {
|
||||
if r.consoleSetup {
|
||||
return
|
||||
}
|
||||
|
||||
func (r *Runtime) populateGlobals() error {
|
||||
// Add Helpers
|
||||
if err := r.vm.StdAddHelpers(); err != nil {
|
||||
panic(fmt.Sprintf("failed to add std helpers: %v", err))
|
||||
return err
|
||||
}
|
||||
|
||||
// Add Log Hook
|
||||
if err := r.vm.RegisterFunc("customLog", func(args ...any) {
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
@@ -50,24 +52,44 @@ func (r *Runtime) setupConsole() {
|
||||
}
|
||||
_, _ = fmt.Fprintln(r.stdout)
|
||||
}, false); err != nil {
|
||||
panic(fmt.Sprintf("failed to register customLog: %v", err))
|
||||
return err
|
||||
}
|
||||
if _, err := r.vm.Eval("console.log = customLog;", quickjs.EvalGlobal); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _ = r.vm.Eval("console.log = customLog;", quickjs.EvalGlobal)
|
||||
// Register Custom Functions
|
||||
for name, builtin := range builtin.GetBuiltins() {
|
||||
// Register Main Function
|
||||
if err := r.vm.RegisterFunc(name, builtin.WrapFn(r.ctx), false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
r.consoleSetup = true
|
||||
}
|
||||
// Wrap Exception - The QuickJS library does not allow us to throw exceptions, so we
|
||||
// wrap the function with native JS to appropriately throw on error.
|
||||
if _, err := r.vm.Eval(fmt.Sprintf(`
|
||||
(function() {
|
||||
const original = globalThis[%q];
|
||||
|
||||
globalThis[%q] = function(...args) {
|
||||
const [result, error] = original.apply(this, args);
|
||||
if (error) {
|
||||
throw new Error(error);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
})();
|
||||
`, name, name), quickjs.EvalGlobal); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Runtime) SetOutput(stdout, stderr io.Writer) {
|
||||
r.stdout = stdout
|
||||
r.stderr = stderr
|
||||
r.setupConsole()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Runtime) RunFile(filePath string, stdout, stderr io.Writer) error {
|
||||
r.stdout = stdout
|
||||
r.stderr = stderr
|
||||
r.setupConsole()
|
||||
|
||||
content, err := r.transformFile(filePath)
|
||||
if err != nil {
|
||||
@@ -95,7 +117,6 @@ func (r *Runtime) RunFile(filePath string, stdout, stderr io.Writer) error {
|
||||
func (r *Runtime) RunCode(tsCode string, stdout, stderr io.Writer) error {
|
||||
r.stdout = stdout
|
||||
r.stderr = stderr
|
||||
r.setupConsole()
|
||||
|
||||
content := r.transformCode(tsCode)
|
||||
|
||||
@@ -131,6 +152,14 @@ func (r *Runtime) transformFile(filePath string) (*transformResult, error) {
|
||||
}
|
||||
|
||||
func (r *Runtime) transformCode(tsCode string) *transformResult {
|
||||
// wrappedCode := `(async () => {
|
||||
// try {
|
||||
// ` + tsCode + `
|
||||
// } catch (err) {
|
||||
// console.error(err);
|
||||
// }
|
||||
// })()`
|
||||
|
||||
result := api.Transform(tsCode, api.TransformOptions{
|
||||
Loader: api.LoaderTS,
|
||||
Target: api.ES2022,
|
||||
|
||||
Reference in New Issue
Block a user