circuitjson-toolkit 1.1.0
circuitjson-toolkit 1.1.0
Breaking API convergence
This minor release intentionally changes public names, parameters, return
shapes, and package layout so CircuitJSON, Gerber, Altium, and KiCad toolkits
can expose the same API.
The root is an exact 17-class contract: the 14 canonical classes plus temporary
CircuitJsonDocument, CircuitJsonIndexer, and CircuitJsonUnits viewer
compatibility exports. Exactly 37 previous CircuitJSON-specific classes remain
available from circuitjson-toolkit/extensions; they were not removed and are
classified as shared or derived for all four toolkits.
Key changes:
Parser.parse({ fileName, data }, options)replaces filename/text-specific
parser calls and returnsecad-toolkit.document.v1.ProjectLoaderreturnsecad-toolkit.project.v1with canonical document
envelopes. It now captures one bounded stable entry snapshot, enforces
maxEntriesbefore inspecting entries, and gives direct and worker paths the
same known-field behavior.- Parser failures use
ToolkitError;tryParseandtryLoadreturn exact
success/failure discriminants. retainSourceis now the explicit'none' | 'reference'contract.
Reference mode preserves exact caller identity only on direct parser calls,
exposes it non-enumerably, and never serializes or freezes the caller input.- PCB, schematic, BOM, interaction, query, manufacturing, simulation, and 3D
services consume either a document result, a CircuitJSON model, or a reused
CircuitJsonDocumentContext. - Canonical schematic graphics now include asset-backed
schematic_image
rows and hierarchicalschematic_sheet_symbolrows. Images keep payloads
in ToolkitAsset records, and child sheet symbols no longer masquerade as
selectable pages or hide unowned root graphics. PcbScene3dBuilderandPcbScene3dPreparatorreturn data-only,
millimeter-based, right-handed Z-up scenes. The package does not depend on
Three.js and never fetches assets implicitly.ecad-toolkit.worker.v1provides equivalent parse/project results, ordered
progress, cancellation, strict clone-safe errors, opt-in input transfer, and
worker-owned output transfer.ParserWorkerClient.parseAttempt()andloadProjectAttempt()give source
toolkits request-scoped automatic-worker fallback: only local construction
failure setsunavailable: true; parser, protocol, and runtime failures stay
visible.- Canonical subpaths now include
/parser,/project,/renderers,
/interaction,/query,/manufacturing,/simulation,/scene3d,
/capabilities,/extensions, and/testing. - Shared validation proofs, indexes, render preparation, queries, and scene
preparation are request-scoped and reused to avoid repeated parsing,
validation, cloning, and spatial work. - Validated source extensions are captured once as immutable owned data under
a separate 128 MiB payload and 2,000,000-item ceiling. Realistic large native
graphs now survive direct and worker results; over-limit graphs fail visibly
and the worker keeps its 250 MB whole-result ceiling. Binary extension values
stay byte-backed behind defensive-copy access rather than expanding into
plain number arrays. CircuitJsonDocumentContextcan now only be created throughprepare();
direct construction fails before reading input so viewers and applications
can consume the same validation-bound context without adapter workarounds.CircuitJsonDocument.normalizeModel(model, { owned })is the shared
copy-on-write compatibility boundary for legacy table geometry, PCB artwork
paths, pad diagnostics, courtyards, layer aliases, and stroke dash fields.
Toolkits normalize owned projections before one validation pass; viewers no
longer need application-side repair code.- The complete serialized-input validator is compiled from the pinned
development dependencycircuit-json@0.0.446. It preserves upstream
refinement, pipeline, and SI-unit transform rejection behavior while keeping
the published browser runtime dependency-free. - Compiler provenance now also verifies and records the exact lock integrity
and distribution entry SHA-256 forformat-si-unit@0.0.7andzod@3.25.76. - Full compatibility parsing canonicalizes legacy Gerber/KiCad outer-layer
aliases (1/32,F.*/B.*, and descriptorlayer.name), fills via layer
defaults, converts legacy trace vias, and retains silkscreen circle/oval and
courtyard geometry for viewers without app-side adapters. CircuitJsonPcbHolePrimitiveModelnow measures polygonpad_outlinein the
pad's rotation-local coordinate system and retains pill drill width, height,
diameter, and independent board-space rotation. Legalouter_width,
outer_height,rect_ccw_rotation, andhole_ccw_rotationvariants are
preserved. Downstream viewers no longer need format-specific plated-slot
sizing logic.- Legal square
pcb_holerows normalize to equal-width rectangular apertures
rather than circular fallbacks. extensions: 'none'now has the exact common return shape{}for native
documents and projects instead of a source-namespaced placeholder.ZipArchiveInspectornow validates exact local/central filenames, CRC32, and
size metadata and exposesverifyExtractedBytes()so stored and deflated
corruption is rejected after bounded inflation. Compression ratios use
compressed and uncompressed member payload totals, so ZIP comments or other
container padding cannot bypass expansion limits./testingnow exportsToolkitLoopbackWorkeralongside the contract fixtures
and runner so all toolkits share one real structured-clone worker regression
boundary.- Direct async parser/project paths now snapshot exact binary windows and
selected assets before progress callbacks. Worker-received inputs reuse their
structured-clone ownership boundary, and direct companion assets are prepared
once, closing callback mutation races without redundant receiver/result copies. npm run sync:schema -- --checkis a read-only drift gate that recompiles the
live pinned union and checks exact contract, provenance, snapshot, and
generated-module equality.- Validation now freezes each proven model once, the legacy parser hands its
already-built index to the next consumer, multi-side legacy rendering shares
one primitive preparation, and compact identifier indexes avoid cloning
duplicate element graphs. ToolkitAsset.measure(),prepare(), andprepareAll()provide one
descriptor-safe asset boundary. Metadata mode copies no payload; full mode
copies once; project limits include attached assets in direct and worker
execution. Missing media types are inferred consistently for common ECAD
model and image suffixes, includingmodel/vrmlfor WRL/VRML and
model/stepfor STEP/STP, while explicit values remain authoritative.- Canonical schematic rendering preserves explicit multi-value dash patterns,
accepts only safe SVG line-cap values, and honorsshow_label: falsein both
component markup and bounds. Source toolkits can retain native styles and
hidden designators without renderer or application workarounds. - The release benchmark runner enforces the frozen 1.0.17 workloads: both
primary cases must be at least 20% faster, non-primary regressions are
bounded, and the duplicate index graph must be at least 25% smaller. Timing
uses three independent processes. Every process imports toolkit modules from
the freshly extracted npm tarball candidate and records an execution marker
that reconciles its package version and source digest with candidate
provenance. - The retained Node 20 / Apple M3 Max result passes every timing and clone
gate, including at least 20% faster for both primary workloads and 85.32%
fewer duplicate-index clone bytes. See
benchmarks/results-v1.1.0.jsonfor samples and checksums. - Gerber, Altium, and KiCad packages now consume CircuitJSON Toolkit as their
shared runtime; their license terms do not replace this package's AGPL or
separately granted commercial terms.
Before:
import { CircuitJsonParser } from 'circuitjson-toolkit'
const model = CircuitJsonParser.parseText(text, {
fileName: 'board.json'
})After:
import { Parser } from 'circuitjson-toolkit'
const document = Parser.parse({
fileName: 'board.json',
data: text
})
console.log(document.model)See migration.md and its generated
appendix pages for the exhaustive 1.0.17 feature mapping,
and capabilities.md for host-side capability gating.