-
Notifications
You must be signed in to change notification settings - Fork 499
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2278 from alixander/d2js-package
init d2.js
- Loading branch information
Showing
21 changed files
with
1,176 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
node_modules | ||
.npm | ||
bun.lockb | ||
|
||
wasm/d2.wasm | ||
dist/ | ||
|
||
.vscode/ | ||
.idea/ | ||
*.swp | ||
*.swo | ||
.DS_Store | ||
Thumbs.db | ||
|
||
logs | ||
*.log | ||
npm-debug.log* | ||
|
||
coverage/ | ||
|
||
.env | ||
.env.local | ||
.env.*.local | ||
|
||
*.tmp | ||
*.temp | ||
.cache/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Changelog | ||
|
||
All notable changes to only the d2.js package will be documented in this file. **Does not | ||
include changes to the main d2 project.** | ||
|
||
## [0.1.0] - 2025-01-12 | ||
|
||
First public release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
.POSIX: | ||
.PHONY: all | ||
all: fmt build test | ||
|
||
.PHONY: fmt | ||
fmt: node_modules | ||
prefix "$@" ../../ci/sub/bin/fmt.sh | ||
prefix "$@" rm -f yarn.lock | ||
|
||
.PHONY: build | ||
build: node_modules | ||
prefix "$@" ./ci/build.sh | ||
|
||
.PHONY: test | ||
test: build | ||
prefix "$@" bun test:all | ||
|
||
.PHONY: node_modules | ||
node_modules: | ||
prefix "$@" bun install $${CI:+--frozen-lockfile} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
# D2.js | ||
|
||
[![npm version](https://badge.fury.io/js/%40terrastruct%2Fd2.svg)](https://www.npmjs.com/package/@terrastruct/d2) | ||
[![License: MPL-2.0](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](https://mozilla.org/MPL/2.0/) | ||
|
||
D2.js is a JavaScript wrapper around D2, the modern diagram scripting language. It enables running D2 directly in browsers and Node environments through WebAssembly. | ||
|
||
## Features | ||
|
||
- 🌐 **Universal** - Works in both browser and Node environments | ||
- 🚀 **Modern** - Built with ESM modules, with CJS fallback | ||
- 🔄 **Isomorphic** - Same API everywhere | ||
- ⚡ **Fast** - Powered by WebAssembly for near-native performance | ||
- 📦 **Lightweight** - Minimal wrapper around the core D2 engine | ||
|
||
## Installation | ||
|
||
```bash | ||
# npm | ||
npm install @terrastruct/d2 | ||
|
||
# yarn | ||
yarn add @terrastruct/d2 | ||
|
||
# pnpm | ||
pnpm add @terrastruct/d2 | ||
|
||
# bun | ||
bun add @terrastruct/d2 | ||
``` | ||
|
||
## Usage | ||
|
||
### Browser | ||
|
||
```javascript | ||
import { D2 } from '@terrastruct/d2'; | ||
|
||
const d2 = new D2(); | ||
|
||
const result = await d2.compile('x -> y'); | ||
const svg = await d2.render(result.diagram); | ||
|
||
const result = await d2.compile('x -> y', { | ||
layout: 'dagre', | ||
sketch: true | ||
}); | ||
``` | ||
|
||
### Node | ||
|
||
```javascript | ||
import { D2 } from '@terrastruct/d2'; | ||
|
||
const d2 = new D2(); | ||
|
||
async function createDiagram() { | ||
const result = await d2.compile('x -> y'); | ||
const svg = await d2.render(result.diagram); | ||
console.log(svg); | ||
} | ||
|
||
createDiagram(); | ||
``` | ||
|
||
## API Reference | ||
|
||
### `new D2()` | ||
Creates a new D2 instance. | ||
|
||
### `compile(input: string, options?: CompileOptions): Promise<CompileResult>` | ||
Compiles D2 markup into an intermediate representation. | ||
|
||
Options: | ||
- `layout`: Layout engine to use ('dagre' | 'elk') [default: 'dagre'] | ||
- `sketch`: Enable sketch mode [default: false] | ||
|
||
### `render(diagram: Diagram, options?: RenderOptions): Promise<string>` | ||
Renders a compiled diagram to SVG. | ||
|
||
## Development | ||
|
||
D2.js uses Bun, so install this first. | ||
|
||
### Building from source | ||
|
||
```bash | ||
git clone https://github.com/terrastruct/d2.git | ||
cd d2/d2js/js | ||
./make.sh | ||
``` | ||
|
||
If you change the main D2 source code, you should regenerate the WASM file: | ||
```bash | ||
./make.sh build | ||
``` | ||
|
||
### Running the Development Server | ||
|
||
```bash | ||
bun run dev | ||
``` | ||
|
||
Visit `http://localhost:3000` to see the example page. | ||
|
||
## Contributing | ||
|
||
Contributions are welcome! | ||
|
||
## License | ||
|
||
This project is licensed under the Mozilla Public License Version 2.0. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { build } from "bun"; | ||
import { copyFile, mkdir } from "node:fs/promises"; | ||
import { join } from "node:path"; | ||
|
||
await mkdir("./dist/esm", { recursive: true }); | ||
await mkdir("./dist/cjs", { recursive: true }); | ||
|
||
const commonConfig = { | ||
target: "node", | ||
splitting: false, | ||
sourcemap: "external", | ||
minify: true, | ||
naming: { | ||
entry: "[dir]/[name].js", | ||
chunk: "[name]-[hash].js", | ||
asset: "[name]-[hash][ext]", | ||
}, | ||
}; | ||
|
||
async function buildAndCopy(format) { | ||
const outdir = `./dist/${format}`; | ||
|
||
await build({ | ||
...commonConfig, | ||
entrypoints: ["./src/index.js", "./src/worker.js", "./src/platform.js"], | ||
outdir, | ||
format, | ||
}); | ||
|
||
await copyFile("./wasm/d2.wasm", join(outdir, "d2.wasm")); | ||
await copyFile("./wasm/wasm_exec.js", join(outdir, "wasm_exec.js")); | ||
} | ||
|
||
await buildAndCopy("esm"); | ||
await buildAndCopy("cjs"); |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#!/bin/sh | ||
set -eu | ||
. "$(dirname "$0")/../../../ci/sub/lib.sh" | ||
cd -- "$(dirname "$0")/.." | ||
|
||
cd ../.. | ||
sh_c "GOOS=js GOARCH=wasm go build -ldflags='-s -w' -trimpath -o main.wasm ./d2js" | ||
sh_c "mv main.wasm ./d2js/js/wasm/d2.wasm" | ||
|
||
if [ ! -f ./d2js/js/wasm/d2.wasm ]; then | ||
echoerr "Error: d2.wasm is missing" | ||
exit 1 | ||
else | ||
stat --printf="Size: %s bytes\n" ./d2js/js/wasm/d2.wasm || ls -lh ./d2js/js/wasm/d2.wasm | ||
fi | ||
|
||
cd d2js/js | ||
sh_c bun run build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
const MIME_TYPES = { | ||
".html": "text/html", | ||
".js": "text/javascript", | ||
".mjs": "text/javascript", | ||
".css": "text/css", | ||
".wasm": "application/wasm", | ||
".svg": "image/svg+xml", | ||
}; | ||
|
||
const server = Bun.serve({ | ||
port: 3000, | ||
async fetch(request) { | ||
const url = new URL(request.url); | ||
let path = url.pathname; | ||
|
||
// Serve index page by default | ||
if (path === "/") { | ||
path = "/examples/basic.html"; | ||
} | ||
|
||
// Handle attempts to access files in src | ||
if (path.startsWith("/src/")) { | ||
const wasmFile = path.includes("wasm_exec.js") || path.includes("d2.wasm"); | ||
if (wasmFile) { | ||
path = path.replace("/src/", "/wasm/"); | ||
} | ||
} | ||
|
||
try { | ||
const filePath = path.slice(1); | ||
const file = Bun.file(filePath); | ||
const exists = await file.exists(); | ||
|
||
if (!exists) { | ||
return new Response(`File not found: ${path}`, { status: 404 }); | ||
} | ||
|
||
// Get file extension and corresponding MIME type | ||
const ext = "." + filePath.split(".").pop(); | ||
const mimeType = MIME_TYPES[ext] || "application/octet-stream"; | ||
|
||
return new Response(file, { | ||
headers: { | ||
"Content-Type": mimeType, | ||
"Access-Control-Allow-Origin": "*", | ||
"Cross-Origin-Opener-Policy": "same-origin", | ||
"Cross-Origin-Embedder-Policy": "require-corp", | ||
}, | ||
}); | ||
} catch (err) { | ||
console.error(`Error serving ${path}:`, err); | ||
return new Response(`Server error: ${err.message}`, { status: 500 }); | ||
} | ||
}, | ||
}); | ||
|
||
console.log(`Server running at http://localhost:3000`); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<style> | ||
body { | ||
display: flex; | ||
gap: 20px; | ||
padding: 20px; | ||
height: 100vh; | ||
margin: 0; | ||
} | ||
textarea { | ||
width: 400px; | ||
height: 300px; | ||
} | ||
#output { | ||
flex: 1; | ||
overflow: auto; | ||
} | ||
#output svg { | ||
max-width: 100%; | ||
max-height: 90vh; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div> | ||
<textarea id="input">x -> y</textarea> | ||
<button onclick="compile()">Compile</button> | ||
</div> | ||
<div id="output"></div> | ||
<script type="module"> | ||
import { D2 } from "../src/index.js"; | ||
const d2 = new D2(); | ||
window.compile = async () => { | ||
const input = document.getElementById("input").value; | ||
try { | ||
const result = await d2.compile(input); | ||
const svg = await d2.render(result.diagram); | ||
document.getElementById("output").innerHTML = svg; | ||
} catch (err) { | ||
console.error(err); | ||
document.getElementById("output").textContent = err.message; | ||
} | ||
}; | ||
compile(); | ||
</script> | ||
</body> | ||
</html> |
Oops, something went wrong.