This commit is contained in:
Alexander Wang 2023-07-28 23:22:28 -07:00
parent 2795e830b0
commit 7bea22e504
No known key found for this signature in database
GPG key ID: D89FA31966BDBECE
4 changed files with 86 additions and 10 deletions

View file

@ -331,7 +331,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
ctx, cancel := timelib.WithTimeout(ctx, time.Minute*2)
defer cancel()
_, written, err := compile(ctx, ms, plugins, layoutFlag, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, *bundleFlag, *forceAppendixFlag, pw.Page)
_, written, err := compile(ctx, ms, plugins, layoutFlag, renderOpts, fontFamily, *animateIntervalFlag, inputPath, outputPath, "", *bundleFlag, *forceAppendixFlag, pw.Page)
if err != nil {
if written {
return fmt.Errorf("failed to fully compile (partial render written): %w", err)
@ -366,7 +366,7 @@ func LayoutResolver(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plu
}
}
func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, layout *string, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath string, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, layout *string, renderOpts d2svg.RenderOpts, fontFamily *d2fonts.FontFamily, animateInterval int64, inputPath, outputPath, boardPath string, bundle, forceAppendix bool, page playwright.Page) (_ []byte, written bool, _ error) {
start := time.Now()
input, err := ms.ReadPath(inputPath)
if err != nil {
@ -500,7 +500,12 @@ func compile(ctx context.Context, ms *xmain.State, plugins []d2plugin.Plugin, la
}
}
boards, err := render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, diagram)
board := diagram.GetBoard(boardPath)
if board == nil {
return nil, false, fmt.Errorf("Diagram with path %s not found", boardPath)
}
boards, err := render(ctx, ms, compileDur, plugin, renderOpts, inputPath, outputPath, bundle, forceAppendix, page, ruler, board)
if err != nil {
return nil, false, err
}

View file

@ -9,7 +9,7 @@ function init(reconnectDelay) {
const devMode = document.body.dataset.d2DevMode === "true";
const ws = new WebSocket(
`ws://${window.location.host}${window.location.pathname}watch`
`ws://${window.location.host}/watch`
);
let isInit = true;
let ratio;
@ -28,7 +28,7 @@ function init(reconnectDelay) {
// we can't just set `d2SVG.innerHTML = msg.svg` need to parse this as xml not html
const parsedXML = new DOMParser().parseFromString(msg.svg, "text/xml");
d2SVG.replaceChildren(parsedXML.documentElement);
changeFavicon("./static/favicon.ico");
changeFavicon("/static/favicon.ico");
const svgEl = d2SVG.querySelector("#d2-svg");
// just use inner SVG in watch mode
svgEl.parentElement.replaceWith(svgEl);
@ -60,7 +60,7 @@ function init(reconnectDelay) {
if (msg.err) {
d2ErrDiv.innerText = msg.err;
d2ErrDiv.style.display = "block";
changeFavicon("./static/favicon-err.ico");
changeFavicon("/static/favicon-err.ico");
d2ErrDiv.scrollIntoView();
}
};

View file

@ -12,6 +12,7 @@ import (
"os"
"path/filepath"
"runtime"
"strings"
"sync"
"time"
@ -49,6 +50,7 @@ type watcherOpts struct {
port string
inputPath string
outputPath string
boardPath string
pwd string
bundle bool
forceAppendix bool
@ -362,7 +364,7 @@ func (w *watcher) compileLoop(ctx context.Context) error {
w.pw = newPW
}
svg, _, err := compile(ctx, w.ms, w.plugins, w.layout, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, w.bundle, w.forceAppendix, w.pw.Page)
svg, _, err := compile(ctx, w.ms, w.plugins, w.layout, w.renderOpts, w.fontFamily, w.animateInterval, w.inputPath, w.outputPath, w.boardPath, w.bundle, w.forceAppendix, w.pw.Page)
errs := ""
if err != nil {
if len(svg) > 0 {
@ -430,15 +432,23 @@ func (w *watcher) handleRoot(hw http.ResponseWriter, r *http.Request) {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>%s</title>
<script src="./static/watch.js"></script>
<link rel="stylesheet" href="./static/watch.css">
<link id="favicon" rel="icon" href="./static/favicon.ico">
<script src="/static/watch.js"></script>
<link rel="stylesheet" href="/static/watch.css">
<link id="favicon" rel="icon" href="/static/favicon.ico">
</head>
<body data-d2-dev-mode=%t>
<div id="d2-err" style="display: none"></div>
<div id="d2-svg-container"></div>
</body>
</html>`, filepath.Base(w.outputPath), w.devMode)
// if path is "/x.svg", we just want "x"
split := strings.Split(strings.TrimPrefix(r.URL.Path, "/"), ".")
boardPath := strings.Join(split[:len(split)-1], ".")
if boardPath != w.boardPath {
w.boardPath = boardPath
w.requestCompile()
}
}
func (w *watcher) handleWatch(hw http.ResponseWriter, r *http.Request) error {

View file

@ -6,6 +6,7 @@ import (
"hash/fnv"
"math"
"net/url"
"os"
"strings"
"oss.terrastruct.com/util-go/go2"
@ -72,6 +73,66 @@ type Diagram struct {
Steps []*Diagram `json:"steps,omitempty"`
}
// boardPath comes in the form of "x/layers/z/scenarios/a"
// or in the form of "layers/z/scenarios/a"
func (d *Diagram) GetBoard(boardPath string) *Diagram {
path := strings.Split(boardPath, string(os.PathSeparator))
if len(path) == 0 || len(boardPath) == 0 {
return d
}
head := path[0]
if head == "index" {
return d
}
switch head {
case "layers", "scenarios", "steps":
if len(path) < 2 {
return nil
}
}
switch head {
case "layers":
for _, b := range d.Layers {
if b.Name == path[1] {
return b.GetBoard(strings.Join(path[2:], string(os.PathSeparator)))
}
}
case "scenarios":
for _, b := range d.Scenarios {
if b.Name == path[1] {
return b.GetBoard(strings.Join(path[2:], string(os.PathSeparator)))
}
}
case "steps":
for _, b := range d.Steps {
if b.Name == path[1] {
return b.GetBoard(strings.Join(path[2:], string(os.PathSeparator)))
}
}
}
for _, b := range d.Layers {
if b.Name == head {
return b.GetBoard(strings.Join(path[1:], string(os.PathSeparator)))
}
}
for _, b := range d.Scenarios {
if b.Name == head {
return b.GetBoard(strings.Join(path[1:], string(os.PathSeparator)))
}
}
for _, b := range d.Steps {
if b.Name == head {
return b.GetBoard(strings.Join(path[1:], string(os.PathSeparator)))
}
}
return nil
}
func (diagram Diagram) Bytes() ([]byte, error) {
b1, err := json.Marshal(diagram.Shapes)
if err != nil {