79 lines
2.7 KiB
JavaScript
79 lines
2.7 KiB
JavaScript
let currentPort;
|
|
let d2;
|
|
let elk;
|
|
|
|
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);
|
|
elk = new ELK();
|
|
currentPort.postMessage({ type: "ready" });
|
|
} catch (err) {
|
|
currentPort.postMessage({ type: "error", error: err.message });
|
|
}
|
|
break;
|
|
|
|
case "compile":
|
|
try {
|
|
// We use Go to get the intermediate ELK graph
|
|
// Then natively run elk layout
|
|
// This is due to elk.layout being an async function, which a
|
|
// single-threaded WASM call cannot complete without giving control back
|
|
// So we compute it, store it here, then during elk layout, instead
|
|
// of computing again, we use this variable (and unset it for next call)
|
|
// If the layout option has not been set, we generate the elk layout now
|
|
// anyway to support `layout-engine: elk` in d2-config vars
|
|
if (data.options.layout === "elk" || data.options.layout == null) {
|
|
const elkGraph = await d2.getELKGraph(JSON.stringify(data));
|
|
const response = JSON.parse(elkGraph);
|
|
if (response.error) throw new Error(response.error.message);
|
|
const elkGraph2 = response.data;
|
|
const layout = await elk.layout(elkGraph2);
|
|
globalThis.elkResult = layout;
|
|
}
|
|
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) {
|
|
const go = new Go();
|
|
const result = await WebAssembly.instantiate(wasmBinary, go.importObject);
|
|
go.run(result.instance);
|
|
return self.d2;
|
|
}
|
|
|
|
setupMessageHandler(false, self, initWasmBrowser);
|