JavaScript

The same converter, compiled to WebAssembly. It has one function, it gives back a plain object, and it does not use the network. The demo on this site uses it.

The binding

import init, { convert } from "./pkg/accent_draw_wasm.js";

await init();

const { xml, diagnostics } = convert(svgText);

init() downloads and starts the module. Call convert only after init() is complete. convert takes the SVG as a string and gives back a plain JavaScript object. The binding makes the object directly. It does not write JSON and read it again.

The result

{
  xml: "<mxfile …>",           // the draw.io document
  diagnostics: [               // in document order
    { code: "picture", message: "a <filter> is drawn as a picture" },
  ],
}

xml is the full .drawio file. You can save it or give it to draw.io. diagnostics lists the parts that did not become a draw.io cell. The code of each entry is short and does not change, so you can find an entry by its code. The message is for a person. An empty list tells you that the full drawing became part of the diagram.

Errors

convert throws an error. It does not give back an empty diagram:

try {
  const { xml } = convert(text);
} catch (e) {
  // e.message is the same sentence the command line prints
}

The message tells you one of these problems:

  • The file is not well-formed XML.
  • Its root element is not <svg>.
  • It contains nothing to show.
  • It contains a draw.io diagram that accent-draw cannot read.

The error for a file with nothing to show is intentional. A message is better than an empty diagram.

Build the package

wasm-pack build --target web --release crates/accent-draw-wasm

This command writes crates/accent-draw-wasm/pkg/: the .wasm file, the JavaScript that loads it, and the type declarations. There is no published npm package yet.

The JavaScript finds accent_draw_wasm_bg.wasm from its own URL when it runs. The name is in a string that wasm-pack writes, and a build tool cannot change it. If your bundler gives assets new names from their content, do not apply it to these two files. If you do, the module downloads a file that does not exist. For this reason, this site does not change the names of its assets.

Size

The .wasm file is about 890 KB. With gzip, it is about 370 KB, and a server sends this size. The browser downloads it one time. For each change, a test measures the size against a limit. We change the limit only as a decision, and we write the measurement next to it. A converter that becomes three times larger without a decision is not useful in a web page.

Where it runs

The library does not use files, the clock, random numbers or threads. A lint makes sure of this. Thus it compiles for wasm32-unknown-unknown without shims. The result is important: the browser and the command line give the same output. For each change, a test converts the full corpus with both and compares the bytes.

The binding does not open a socket. If your page sends an SVG file to a server, your page does it, not this module.

A page around it

The demo on this site is one example. The repository has a smaller page in web/, with the drop target, the notes, the download, and the draw.io editor in an iframe. One module decides the parts that do not need a DOM. These parts are the name of the download, the summary of the diagram, and the origin that the editor loads from. This module has its own tests. The demo on this site uses the same file, not a copy.