Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/render.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
- run: bun run example:compare
- run: bun run example:overviews
- run: bun run example:design
- run: bun run example:images
- name: Consume the reviewed Git package through Bun
env:
RENDER_REVISION: ${{ github.event.pull_request.head.sha || github.sha }}
Expand All @@ -54,4 +55,4 @@ jobs:
cd "$render_consumer"
bun init -y
bun add "@deterministic-engineering/render@git+https://github.com/hardenedlinux/deterministic-engineering.git#$RENDER_REVISION"
bun -e 'import metadata from "@deterministic-engineering/render/package.json"; import {compileModel} from "@deterministic-engineering/render"; if(metadata.version!==process.env.RENDER_EXPECTED_VERSION)throw new Error("Wrong Git package version"); const compiled=await compileModel({"consumer.d2":"Library -> Consumer"},"consumer.d2"); if(compiled.model.relations.length!==1)throw new Error("Git-installed worker did not compile the consumer model");'
bun -e 'import metadata from "@deterministic-engineering/render/package.json"; import {compileModel} from "@deterministic-engineering/render"; import {encodeWebP} from "@deterministic-engineering/render/export"; if(metadata.version!==process.env.RENDER_EXPECTED_VERSION)throw new Error("Wrong Git package version"); const compiled=await compileModel({"consumer.d2":"Library -> Consumer"},"consumer.d2"); if(compiled.model.relations.length!==1)throw new Error("Git-installed worker did not compile the consumer model"); const webp=await encodeWebP(Buffer.from("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAACXBIWXMAAAPoAAAD6AG1e1JrAAAADklEQVQImWP4DwUMMAYAj4IP8cvlVgcAAAAASUVORK5CYII=","base64")); if(Buffer.from(webp.bytes).toString("ascii",8,12)!=="WEBP")throw new Error("Git-installed native WebP encoder failed");'
4 changes: 3 additions & 1 deletion README.org
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ measure actual browser text/fonts/images and return artifacts plus rendering fac

The package reuses D2 model compilation, ELK.js scene layout/routing, parse5 HTML parsing, Rough.js
options/primitives, XYFlow connector paths and Playwright export. It has no
interactive whiteboard or React runtime. A node diagram or swimlane is one example,
interactive whiteboard or React runtime. Sharp encodes lossless PNG/WebP;
=preferredRaster= selects the smaller actual raster with its MIME type, while SVG
remains the vector output. Lossy compression is an explicit export choice. A node diagram or swimlane is one example,
not the framework's entire diagram vocabulary.

** Real Library / Profile / Scenario Case
Expand Down
64 changes: 63 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,34 @@ mixed artifacts must reject; re-rendering cannot stand in for recovery acceptanc
Neither vendor, manual receipts, an additional publisher nor a Release URL is used.
The upstream and downstream CI results qualify their respective revisions separately;
a release tag alone grants neither model publication nor Aitia review authority.


* Image compression and measured format choice

Sharp (pinned in root package.json) owns native PNG/WebP encoding after the existing
browser screenshot. Both default paths are lossless. The export returns compatible
PNG, optional WebP and a preferredRaster selected by actual encoded byte count;
format and MIME accompany the selected bytes. Native encoder settings and final
hashes are retained in the existing receipt. Models, D2/SysML identity, Questions,
fonts, dimensions and SVG composition do not select a hardcoded image format.
A host may disable WebP, bypass PNG re-encoding or explicitly opt into lossy
WebP/palette PNG. It must publish with the correct extension and actual receipt.
There is no new image publisher, file watcher, optimizer subprocess or global
resource configuration. Browser CI keeps its two workers.

Local corpus observation (2026-11-05): 38 existing repository PNGs totalled
15,313,994 bytes. Default lossless PNG retained 15,010,083 bytes (1.98% reduction);
lossless WebP produced 7,874,400 bytes (48.58% reduction). RGBA decode comparison
was identical for every original/WebP pair in this corpus. Explicit palette PNG
(quality 95, effort 7) produced 6,002,680 bytes (60.80% reduction), with a nonzero
mean absolute channel error; it must not be described as lossless. Ordered local
encoding totals were 10.61/19.28/14.10 seconds respectively, not an isolated or
cross-platform throughput benchmark. Source images were not replaced in-place.
These results guide a per-image choice, not a universal WebP or PNG preference.

Controls cover exact RGBA/dimensions/partial-alpha preservation, original retention
when PNG grows, explicit codec bypass, invalid/corrupted inputs, lossy opt-in,
real browser/region hashes and MIME/byte selection. SVG remains a separate vector
output: embedded fonts and zoom semantics make bytes alone an insufficient reason
to replace it. Lossless WebP may canonicalize invisible colour under alpha zero;
no pixel-perfect hidden-colour guarantee is inferred beyond the measured corpus.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"example:case": "bun packages/render/examples/library-case.ts",
"example:compare": "bun packages/render/examples/comparison.ts",
"example:overviews": "bun packages/render/examples/overviews.ts",
"example:design": "bun packages/render/examples/design-choices.ts"
"example:design": "bun packages/render/examples/design-choices.ts",
"example:images": "bun packages/render/examples/raster-comparison.ts"
},
"dependencies": {
"@fontsource/inter": "5.3.0",
Expand All @@ -20,6 +21,7 @@
"elkjs": "0.12.1",
"parse5": "8.0.1",
"roughjs": "4.6.6",
"sharp": "0.35.5",
"valibot": "1.2.0",
"web-worker": "1.5.0"
},
Expand Down
Loading
Loading