minified browser build

This commit is contained in:
Alexander Wang 2025-01-14 11:31:57 -07:00
parent a416253a05
commit 4775c1fa34
No known key found for this signature in database
GPG key ID: BE3937D0D52D8927
8 changed files with 113 additions and 68 deletions

View file

@ -5,3 +5,4 @@ d2renderers/d2latex/polyfills.js
d2renderers/d2latex/setup.js d2renderers/d2latex/setup.js
d2renderers/d2sketch/rough.js d2renderers/d2sketch/rough.js
lib/png/generate_png.js lib/png/generate_png.js
d2js

1
d2js/js/.prettierignore Normal file
View file

@ -0,0 +1 @@
src/platform.browser.js

View file

@ -23,7 +23,6 @@ await writeFile(
); );
const commonConfig = { const commonConfig = {
sourcemap: "external",
minify: true, minify: true,
}; };
@ -54,10 +53,7 @@ async function buildAndCopy(buildType) {
format: "esm", format: "esm",
target: "browser", target: "browser",
platform: "browser", platform: "browser",
loader: { entrypoints: [resolve(SRC_DIR, "index.js")],
".js": "jsx",
},
entrypoints: [resolve(SRC_DIR, "index.js"), resolve(SRC_DIR, "worker.js")],
}, },
"node-esm": { "node-esm": {
outdir: resolve(ROOT_DIR, "dist/node-esm"), outdir: resolve(ROOT_DIR, "dist/node-esm"),
@ -86,7 +82,9 @@ async function buildAndCopy(buildType) {
}); });
if (!result.outputs || result.outputs.length === 0) { if (!result.outputs || result.outputs.length === 0) {
throw new Error(`No outputs generated for ${buildType} build`); throw new Error(
`No outputs generated for ${buildType} build. Result: ${JSON.stringify(result)}`
);
} }
if (buildType !== "browser") { if (buildType !== "browser") {

View file

@ -2,7 +2,7 @@
"name": "@terrastruct/d2", "name": "@terrastruct/d2",
"author": "Terrastruct, Inc.", "author": "Terrastruct, Inc.",
"description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.", "description": "D2.js is a wrapper around the WASM build of D2, the modern text-to-diagram language.",
"version": "0.1.19", "version": "0.1.20",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/terrastruct/d2.git", "url": "git+https://github.com/terrastruct/d2.git",

View file

@ -1,4 +1,5 @@
import { wasmBinary, wasmExecJs } from "./wasm-loader.browser.js"; import { wasmBinary, wasmExecJs } from "./wasm-loader.browser.js";
import workerScript from "./worker.js" with { type: "text" };
export async function loadFile(path) { export async function loadFile(path) {
if (path === "./d2.wasm") { if (path === "./d2.wasm") {
@ -11,13 +12,6 @@ export async function loadFile(path) {
} }
export async function createWorker() { export async function createWorker() {
let response = await fetch(new URL("./worker.js", import.meta.url));
if (!response.ok)
throw new Error(
`Failed to load worker.js: ${response.status} ${response.statusText}`
);
let workerScript = await response.text();
let blob = new Blob([wasmExecJs, workerScript], { let blob = new Blob([wasmExecJs, workerScript], {
type: "text/javascript;charset=utf-8", type: "text/javascript;charset=utf-8",
}); });

View file

@ -1,4 +1,55 @@
import { setupMessageHandler } from "./worker.shared.js"; let currentPort;
let d2;
export function setupMessageHandler(isNode, port, initWasm) {
currentPort = port;
const handleMessage = async (e) => {
const { type, data } = e;
switch (type) {
case "init":
try {
if (isNode) {
eval(data.wasmExecContent);
}
d2 = await initWasm(data.wasm);
currentPort.postMessage({ type: "ready" });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "compile":
try {
const result = await d2.compile(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: response.data });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "render":
try {
const result = await d2.render(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: atob(response.data) });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
}
};
if (isNode) {
port.on("message", handleMessage);
} else {
port.onmessage = (e) => handleMessage(e.data);
}
}
async function initWasmBrowser(wasmBinary) { async function initWasmBrowser(wasmBinary) {
const go = new Go(); const go = new Go();

View file

@ -1,5 +1,57 @@
import { parentPort } from "node:worker_threads"; import { parentPort } from "node:worker_threads";
import { setupMessageHandler } from "./worker.shared.js";
let currentPort;
let d2;
export function setupMessageHandler(isNode, port, initWasm) {
currentPort = port;
const handleMessage = async (e) => {
const { type, data } = e;
switch (type) {
case "init":
try {
if (isNode) {
eval(data.wasmExecContent);
}
d2 = await initWasm(data.wasm);
currentPort.postMessage({ type: "ready" });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "compile":
try {
const result = await d2.compile(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: response.data });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "render":
try {
const result = await d2.render(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: atob(response.data) });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
}
};
if (isNode) {
port.on("message", handleMessage);
} else {
port.onmessage = (e) => handleMessage(e.data);
}
}
async function initWasmNode(wasmBinary) { async function initWasmNode(wasmBinary) {
const go = new Go(); const go = new Go();

View file

@ -1,52 +0,0 @@
let currentPort;
let d2;
export function setupMessageHandler(isNode, port, initWasm) {
currentPort = port;
const handleMessage = async (e) => {
const { type, data } = e;
switch (type) {
case "init":
try {
if (isNode) {
eval(data.wasmExecContent);
}
d2 = await initWasm(data.wasm);
currentPort.postMessage({ type: "ready" });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "compile":
try {
const result = await d2.compile(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: response.data });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
case "render":
try {
const result = await d2.render(JSON.stringify(data));
const response = JSON.parse(result);
if (response.error) throw new Error(response.error.message);
currentPort.postMessage({ type: "result", data: atob(response.data) });
} catch (err) {
currentPort.postMessage({ type: "error", error: err.message });
}
break;
}
};
if (isNode) {
port.on("message", handleMessage);
} else {
port.onmessage = (e) => handleMessage(e.data);
}
}