Skip to content

Commit

Permalink
Merge pull request #2293 from alixander/trim-wasm-size
Browse files Browse the repository at this point in the history
d2js: trim wasm size
  • Loading branch information
alixander authored Jan 16, 2025
2 parents fcbe464 + cbb691a commit ac7dd41
Show file tree
Hide file tree
Showing 27 changed files with 106,712 additions and 164 deletions.
28 changes: 28 additions & 0 deletions ci/peek-wasm-size.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/bin/bash

OUTPUT_FILE="main.wasm"
SOURCE_PACKAGE="./d2js"

echo "Building WASM file..."
GOOS=js GOARCH=wasm go build -ldflags='-s -w' -trimpath -o "$OUTPUT_FILE" "$SOURCE_PACKAGE"

if [ $? -eq 0 ]; then
echo "Build successful."

if [ -f "$OUTPUT_FILE" ]; then
FILE_SIZE_BYTES=$(stat -f%z "$OUTPUT_FILE")
FILE_SIZE_MB=$(echo "scale=2; $FILE_SIZE_BYTES / 1024 / 1024" | bc)

echo "File size of $OUTPUT_FILE: $FILE_SIZE_MB MB"
else
echo "File $OUTPUT_FILE not found!"
exit 1
fi

echo "Deleting $OUTPUT_FILE..."
rm "$OUTPUT_FILE"
echo "File deleted."
else
echo "Build failed."
exit 1
fi
46 changes: 46 additions & 0 deletions d2js/d2wasm/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,52 @@ func GetRefRanges(args []js.Value) (interface{}, error) {
}, nil
}

func GetELKGraph(args []js.Value) (interface{}, error) {
if len(args) < 1 {
return nil, &WASMError{Message: "missing JSON argument", Code: 400}
}
var input CompileRequest
if err := json.Unmarshal([]byte(args[0].String()), &input); err != nil {
return nil, &WASMError{Message: "invalid JSON input", Code: 400}
}

if input.FS == nil {
return nil, &WASMError{Message: "missing 'fs' field in input JSON", Code: 400}
}

if _, ok := input.FS["index"]; !ok {
return nil, &WASMError{Message: "missing 'index' file in input fs", Code: 400}
}

fs, err := memfs.New(input.FS)
if err != nil {
return nil, &WASMError{Message: fmt.Sprintf("invalid fs input: %s", err.Error()), Code: 400}
}

g, _, err := d2compiler.Compile("", strings.NewReader(input.FS["index"]), &d2compiler.CompileOptions{
UTF16Pos: true,
FS: fs,
})
if err != nil {
return nil, &WASMError{Message: err.Error(), Code: 400}
}

ruler, err := textmeasure.NewRuler()
if err != nil {
return nil, &WASMError{Message: fmt.Sprintf("text ruler cannot be initialized: %s", err.Error()), Code: 500}
}
err = g.SetDimensions(nil, ruler, nil)
if err != nil {
return nil, err
}

elk, err := d2elklayout.ConvertGraph(context.Background(), g, nil)
if err != nil {
return nil, &WASMError{Message: err.Error(), Code: 400}
}
return elk, nil
}

func Compile(args []js.Value) (interface{}, error) {
if len(args) < 1 {
return nil, &WASMError{Message: "missing JSON argument", Code: 400}
Expand Down
1 change: 1 addition & 0 deletions d2js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ func main() {
api.Register("getParentID", d2wasm.GetParentID)
api.Register("getObjOrder", d2wasm.GetObjOrder)
api.Register("getRefRanges", d2wasm.GetRefRanges)
api.Register("getELKGraph", d2wasm.GetELKGraph)
api.Register("compile", d2wasm.Compile)
api.Register("render", d2wasm.Render)
api.Register("getBoardAtPosition", d2wasm.GetBoardAtPosition)
Expand Down
1 change: 1 addition & 0 deletions d2js/js/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ async function buildAndCopy(buildType) {
resolve(ROOT_DIR, "wasm/wasm_exec.js"),
join(config.outdir, "wasm_exec.js")
);
await copyFile(resolve(ROOT_DIR, "src/elk.js"), join(config.outdir, "elk.js"));
}
}

Expand Down
47 changes: 33 additions & 14 deletions d2js/js/examples/customizable.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,16 @@
border-radius: 4px;
font-family: monospace;
}
.layout-toggle {
.options-group {
display: flex;
flex-direction: column;
gap: 12px;
padding: 12px;
border: 1px solid #eee;
border-radius: 4px;
}
.layout-toggle,
.sketch-toggle {
display: flex;
gap: 16px;
align-items: center;
Expand All @@ -33,7 +42,8 @@
display: flex;
gap: 12px;
}
.radio-label {
.radio-label,
.checkbox-label {
display: flex;
gap: 4px;
align-items: center;
Expand Down Expand Up @@ -66,16 +76,24 @@
<body>
<div class="controls">
<textarea id="input">x -> y</textarea>
<div class="layout-toggle">
<span>Layout:</span>
<div class="radio-group">
<label class="radio-label">
<input type="radio" name="layout" value="dagre" checked />
Dagre
</label>
<label class="radio-label">
<input type="radio" name="layout" value="elk" />
ELK
<div class="options-group">
<div class="layout-toggle">
<span>Layout:</span>
<div class="radio-group">
<label class="radio-label">
<input type="radio" name="layout" value="dagre" checked />
Dagre
</label>
<label class="radio-label">
<input type="radio" name="layout" value="elk" />
ELK
</label>
</div>
</div>
<div class="sketch-toggle">
<label class="checkbox-label">
<input type="checkbox" id="sketch" />
Sketch mode
</label>
</div>
</div>
Expand All @@ -88,9 +106,10 @@
window.compile = async () => {
const input = document.getElementById("input").value;
const layout = document.querySelector('input[name="layout"]:checked').value;
const sketch = document.getElementById("sketch").checked;
try {
const result = await d2.compile(input, { layout });
const svg = await d2.render(result.diagram);
const result = await d2.compile(input, { layout, sketch });
const svg = await d2.render(result.diagram, { sketch });
document.getElementById("output").innerHTML = svg;
} catch (err) {
console.error(err);
Expand Down
2 changes: 1 addition & 1 deletion d2js/js/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "@terrastruct/d2",
"author": "Terrastruct, Inc.",
"description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.",
"version": "0.1.20",
"version": "0.1.21",
"repository": {
"type": "git",
"url": "git+https://github.com/terrastruct/d2.git",
Expand Down
Loading

0 comments on commit ac7dd41

Please sign in to comment.