use goja for elk
This commit is contained in:
parent
b5dc40ce0f
commit
c975ddcd03
2 changed files with 21 additions and 30 deletions
|
|
@ -11,8 +11,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"rogchap.com/v8go"
|
"github.com/dop251/goja"
|
||||||
|
|
||||||
"oss.terrastruct.com/util-go/xdefer"
|
"oss.terrastruct.com/util-go/xdefer"
|
||||||
|
|
||||||
"oss.terrastruct.com/util-go/go2"
|
"oss.terrastruct.com/util-go/go2"
|
||||||
|
|
@ -88,30 +87,17 @@ type ELKLayoutOptions struct {
|
||||||
func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
|
func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
|
||||||
defer xdefer.Errorf(&err, "failed to ELK layout")
|
defer xdefer.Errorf(&err, "failed to ELK layout")
|
||||||
|
|
||||||
iso := v8go.NewIsolate()
|
vm := goja.New()
|
||||||
global := v8go.NewObjectTemplate(iso)
|
|
||||||
|
|
||||||
// setTimeout is not defined by in v8go global
|
console := vm.NewObject()
|
||||||
// As far as I can tell, it's not actually useful in elk.js
|
if err := vm.Set("console", console); err != nil {
|
||||||
// The comment above one of the instances it's used is "why do we even need this"
|
|
||||||
// and it's a timeout of 0.
|
|
||||||
// If weird things happen though, look here.
|
|
||||||
setTimeout := v8go.NewFunctionTemplate(iso, func(info *v8go.FunctionCallbackInfo) *v8go.Value {
|
|
||||||
args := info.Args()
|
|
||||||
fn, _ := args[0].AsFunction()
|
|
||||||
receiver := v8go.NewObjectTemplate(iso)
|
|
||||||
s, _ := receiver.NewInstance(info.Context())
|
|
||||||
fn.Call(s)
|
|
||||||
|
|
||||||
return s.Value
|
|
||||||
})
|
|
||||||
global.Set("setTimeout", setTimeout, v8go.ReadOnly)
|
|
||||||
|
|
||||||
v8ctx := v8go.NewContext(iso, global)
|
|
||||||
if _, err := v8ctx.RunScript(elkJS, "elk.js"); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := v8ctx.RunScript(setupJS, "setup.js"); err != nil {
|
|
||||||
|
if _, err := vm.RunString(elkJS); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := vm.RunString(setupJS); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,37 +191,41 @@ func Layout(ctx context.Context, g *d2graph.Graph) (err error) {
|
||||||
|
|
||||||
loadScript := fmt.Sprintf(`var graph = %s`, raw)
|
loadScript := fmt.Sprintf(`var graph = %s`, raw)
|
||||||
|
|
||||||
if _, err := v8ctx.RunScript(loadScript, "load.js"); err != nil {
|
if _, err := vm.RunString(loadScript); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
val, err := v8ctx.RunScript(`elk.layout(graph)
|
val, err := vm.RunString(`elk.layout(graph)
|
||||||
.then(s => s)
|
.then(s => s)
|
||||||
.catch(s => s)
|
.catch(s => s)
|
||||||
`, "layout.js")
|
`)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
promise, err := val.AsPromise()
|
p := val.Export()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for promise.State() == v8go.Pending {
|
promise := p.(*goja.Promise)
|
||||||
|
|
||||||
|
for promise.State() == goja.PromiseStatePending {
|
||||||
if err := ctx.Err(); err != nil {
|
if err := ctx.Err(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonOut, err := promise.Result().MarshalJSON()
|
jsonOut := promise.Result().Export().(map[string]interface{})
|
||||||
|
|
||||||
|
jsonBytes, err := json.Marshal(jsonOut)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.Unmarshal(jsonOut, &elkGraph)
|
err = json.Unmarshal(jsonBytes, &elkGraph)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
var setTimeout = function(f) {f()};
|
||||||
const elk = new ELK();
|
const elk = new ELK();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue