Export for Screens and the Asset Export panel's Export encoded and wrote
every file on the UI thread, so the window stopped responding until the
last file was written. For 50 artboards in PNG at 1x, 2x and 3x, PDF and
SVG (250 files, 47 MiB), the dialog's OK took a median of 43.8 s in a
release build on Windows.
With Enable Background Export on (Preferences › File Handling), OK now
checks the settings, remembers them and takes a snapshot of the
document, and the dialog closes. The thread that writes background
saves and exports then encodes the files and writes them into the
folder, or one ZIP in it, and the export progress dialog's Cancel stops
it before the next file. The same OK takes under 0.001 s, and the files
have the same names and bytes. With the preference off, without a
folder, on the web and over MCP and scripts (document.exportForScreens
and assets.export), the files are made at once with the same reply as
before.
Both commands report one progress step per file, so the progress dialog
shows "File 3 of 250" and MCP progress notifications count the files in
place of the encoders' artboards and pages.
Docs: docs/target-app-parity.md, docs/control-protocol.md, docs/mcp.md.
The MCP server read one line, ran it and answered it before reading the next,
so notifications/cancelled was never seen during a call and every request
(even ping) waited behind a running export.
- vectorcraft_doc::cancel: a thread-local cancel token and progress sink that
long work polls. Checkpoints: PDF pages, PDF flattening, geometry bake,
raster-effect flattening, drawing objects, raster artboards, and before any
file is written. A cancelled command returns EngineError::Cancelled and
changes nothing.
- Server::serve reads on its own thread: notifications/cancelled drops a
queued request or stops the running one (no reply, as the MCP spec says),
engine-free requests (ping, the list methods, prompts/get) are answered at
once, a request that would wait behind a call running for 2 s is refused
with -32003 naming that call, and _meta.progressToken gets
notifications/progress (page n of m). Queue and output are bounded.
- The remote backend stops waiting for the app when the call is cancelled.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>