circuitjson-toolkit 1.0.17 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/NOTICE.md +31 -0
  2. package/README.md +267 -107
  3. package/docs/api.md +501 -96
  4. package/docs/capabilities.md +70 -0
  5. package/docs/migration/behaviors.md +45 -0
  6. package/docs/migration/parser.md +60 -0
  7. package/docs/migration/renderers.md +515 -0
  8. package/docs/migration/root.md +740 -0
  9. package/docs/migration.md +120 -0
  10. package/docs/model-format.md +175 -57
  11. package/docs/provenance.md +206 -0
  12. package/docs/release-notes-v1.1.0.md +154 -0
  13. package/docs/testing.md +117 -7
  14. package/package.json +31 -5
  15. package/spec/api-baseline-v1.0.17.json +1 -0
  16. package/spec/baseline-provenance-v1.0.17.json +7 -0
  17. package/spec/circuitjson-schema-snapshot.json +321 -0
  18. package/spec/circuitjson-schema-source.json +28 -0
  19. package/spec/feature-preservation.json +1 -0
  20. package/spec/library-scope.md +27 -20
  21. package/src/capabilities.mjs +1 -0
  22. package/src/core/ArchiveEntryPath.mjs +93 -0
  23. package/src/core/ArchiveLimits.mjs +31 -0
  24. package/src/core/ArchiveLimitsValidator.mjs +107 -0
  25. package/src/core/AsyncInputOwnership.mjs +56 -0
  26. package/src/core/AttachedValueLimits.mjs +67 -0
  27. package/src/core/CircuitJsonDiagnosticIndexer.mjs +184 -0
  28. package/src/core/CircuitJsonDocument.mjs +19 -61
  29. package/src/core/CircuitJsonElementTypes.mjs +10 -0
  30. package/src/core/CircuitJsonElementValidator.mjs +98 -847
  31. package/src/core/CircuitJsonIndexer.mjs +274 -194
  32. package/src/core/CircuitJsonManufacturingBuilder.mjs +167 -164
  33. package/src/core/CircuitJsonParser.mjs +75 -13
  34. package/src/core/CircuitJsonPcbClearanceDiagnostics.mjs +12 -6
  35. package/src/core/CircuitJsonPcbHolePrimitiveModel.mjs +108 -10
  36. package/src/core/CircuitJsonPcbPadPrimitiveModel.mjs +1 -1
  37. package/src/core/CircuitJsonPcbPrimitiveArtwork.mjs +44 -38
  38. package/src/core/CircuitJsonPcbPrimitiveBuilder.mjs +146 -28
  39. package/src/core/CircuitJsonPcbPrimitiveFields.mjs +70 -4
  40. package/src/core/CircuitJsonPcbPrimitiveIndex.mjs +18 -2
  41. package/src/core/CircuitJsonPcbPrimitiveOverlays.mjs +26 -9
  42. package/src/core/CircuitJsonPcbZonePrimitiveBuilder.mjs +7 -6
  43. package/src/core/CircuitJsonSerializedInputAudit.mjs +87 -0
  44. package/src/core/CircuitJsonSourceMetadata.mjs +5 -1
  45. package/src/core/CircuitJsonSupportMatrixBuilder.mjs +3 -1
  46. package/src/core/CircuitJsonToolkitElementSchema.mjs +218 -0
  47. package/src/core/CircuitJsonUnitParsers.mjs +101 -0
  48. package/src/core/CircuitJsonUnits.mjs +13 -87
  49. package/src/core/CircuitJsonUpstreamSchema.mjs +9 -0
  50. package/src/core/CircuitJsonUpstreamValidator.mjs +418 -0
  51. package/src/core/CircuitJsonValidationUnits.mjs +6 -0
  52. package/src/core/ManufacturingService.mjs +323 -0
  53. package/src/core/Parser.mjs +343 -0
  54. package/src/core/ParserOptions.mjs +333 -0
  55. package/src/core/PcbBoundsSelectionModel.mjs +55 -19
  56. package/src/core/PcbDiagnosticFocusModel.mjs +42 -11
  57. package/src/core/PcbInteractionIndex.mjs +368 -0
  58. package/src/core/PcbInteractionPrimitiveModel.mjs +393 -62
  59. package/src/core/ProjectAsyncInputOwner.mjs +70 -0
  60. package/src/core/ProjectLoader.mjs +975 -0
  61. package/src/core/SimulationService.mjs +790 -0
  62. package/src/core/ToolkitCapabilities.mjs +130 -0
  63. package/src/core/ZipArchiveInspector.mjs +649 -0
  64. package/src/core/context/BinaryDataSnapshot.mjs +217 -0
  65. package/src/core/context/CircuitJsonContextIndexes.mjs +96 -0
  66. package/src/core/context/CircuitJsonDerivedCache.mjs +114 -0
  67. package/src/core/context/CircuitJsonDocumentContext.mjs +353 -0
  68. package/src/core/context/CircuitJsonLegacyModel.mjs +147 -0
  69. package/src/core/context/CircuitJsonLegacyNormalizer.mjs +847 -0
  70. package/src/core/context/CircuitJsonMetadataBoundary.mjs +76 -0
  71. package/src/core/context/CircuitJsonModelFreezeTraversal.mjs +179 -0
  72. package/src/core/context/CircuitJsonReadOnlyDocument.mjs +920 -0
  73. package/src/core/context/CircuitJsonSchematicTableNormalizer.mjs +314 -0
  74. package/src/core/context/CircuitJsonValidationAuthority.mjs +39 -0
  75. package/src/core/context/CircuitJsonValidationProof.mjs +217 -0
  76. package/src/core/context/PcbPrimitivePreparation.mjs +198 -0
  77. package/src/core/context/PcbSpatialIndex.mjs +701 -0
  78. package/src/core/context/ProtectedExtensionBinaryBoundary.mjs +128 -0
  79. package/src/core/context/StructuredDataSnapshot.mjs +683 -0
  80. package/src/core/contracts/DocumentResult.mjs +198 -0
  81. package/src/core/contracts/ProjectResult.mjs +96 -0
  82. package/src/core/contracts/RuntimeProxyBoundary.mjs +48 -0
  83. package/src/core/contracts/ToolkitAsset.mjs +493 -0
  84. package/src/core/contracts/ToolkitDiagnostic.mjs +38 -0
  85. package/src/core/contracts/ToolkitError.mjs +176 -0
  86. package/src/core/contracts/ToolkitProgress.mjs +89 -0
  87. package/src/core/interaction/CanonicalInteractionOptions.mjs +246 -0
  88. package/src/core/interaction/PcbInteractionBounds.mjs +167 -0
  89. package/src/core/query/CircuitTraversal.mjs +343 -0
  90. package/src/core/query/ComponentGrouping.mjs +275 -0
  91. package/src/core/query/QueryNetlistBuilder.mjs +306 -0
  92. package/src/core/query/QueryService.mjs +435 -0
  93. package/src/core/query/RegexPattern.mjs +75 -0
  94. package/src/core/rendering/CanonicalBomOrder.mjs +81 -0
  95. package/src/core/rendering/CanonicalBomRows.mjs +92 -0
  96. package/src/core/rendering/CanonicalRenderOptions.mjs +498 -0
  97. package/src/core/rendering/CanonicalSvgDocument.mjs +102 -0
  98. package/src/core/rendering/PcbRenderPlan.mjs +429 -0
  99. package/src/core/rendering/SchematicSheetSelector.mjs +335 -0
  100. package/src/core/scene3d/PcbScene3dBuilder.mjs +906 -0
  101. package/src/core/scene3d/PcbScene3dPreparator.mjs +47 -0
  102. package/src/core/scene3d/Scene3dAssetIndex.mjs +284 -0
  103. package/src/core/scene3d/Scene3dBoardModel.mjs +596 -0
  104. package/src/core/scene3d/Scene3dDocumentMetadata.mjs +167 -0
  105. package/src/core/scene3d/Scene3dFreeze.mjs +37 -0
  106. package/src/core/scene3d/Scene3dIdRegistry.mjs +34 -0
  107. package/src/core/scene3d/Scene3dInputPreflight.mjs +193 -0
  108. package/src/core/scene3d/Scene3dMaterials.mjs +58 -0
  109. package/src/core/scene3d/Scene3dModelReference.mjs +134 -0
  110. package/src/core/scene3d/Scene3dOptions.mjs +363 -0
  111. package/src/core/scene3d/SceneAssetResolver.mjs +441 -0
  112. package/src/core/simulation/SimulationParameterCloner.mjs +543 -0
  113. package/src/core/worker/ParserWorkerClient.mjs +997 -0
  114. package/src/core/worker/ToolkitWorkerProtocol.mjs +412 -0
  115. package/src/core/worker/WorkerRequestData.mjs +623 -0
  116. package/src/core/worker/WorkerResponseData.mjs +905 -0
  117. package/src/extensions.mjs +37 -0
  118. package/src/index.mjs +14 -9
  119. package/src/interaction.mjs +2 -0
  120. package/src/manufacturing.mjs +1 -0
  121. package/src/parser.mjs +12 -2
  122. package/src/project.mjs +5 -0
  123. package/src/query.mjs +1 -0
  124. package/src/renderers.mjs +3 -29
  125. package/src/scene3d.mjs +3 -0
  126. package/src/simulation.mjs +1 -0
  127. package/src/styles/renderers.css +24 -0
  128. package/src/testing/ToolkitContractFixtures.mjs +124 -0
  129. package/src/testing/ToolkitLoopbackWorker.mjs +174 -0
  130. package/src/testing/runToolkitContract.mjs +705 -0
  131. package/src/testing.mjs +3 -0
  132. package/src/ui/BomTableRenderer.mjs +304 -0
  133. package/src/ui/CircuitJsonPcbBoardSvgRenderer.mjs +80 -0
  134. package/src/ui/CircuitJsonPcbPrimitiveAttributeRenderer.mjs +3 -5
  135. package/src/ui/CircuitJsonPcbSvgRenderer.mjs +63 -43
  136. package/src/ui/CircuitJsonPcbViaSvgRenderer.mjs +3 -5
  137. package/src/ui/CircuitJsonSchematicDebugRenderer.mjs +164 -0
  138. package/src/ui/CircuitJsonSchematicImageSvgRenderer.mjs +210 -0
  139. package/src/ui/CircuitJsonSchematicLineRenderer.mjs +86 -0
  140. package/src/ui/CircuitJsonSchematicSheetSymbolSvgRenderer.mjs +98 -0
  141. package/src/ui/CircuitJsonSchematicSvgArcPath.mjs +117 -17
  142. package/src/ui/CircuitJsonSchematicSvgPortMetadata.mjs +67 -20
  143. package/src/ui/CircuitJsonSchematicSvgPrimitiveAttributes.mjs +45 -9
  144. package/src/ui/CircuitJsonSchematicSvgRenderer.mjs +151 -148
  145. package/src/ui/CircuitJsonSchematicTableSvgRenderer.mjs +4 -292
  146. package/src/ui/PcbSvgRenderer.mjs +41 -0
  147. package/src/ui/SafeSvgPaint.mjs +26 -0
  148. package/src/ui/SafeXmlText.mjs +60 -0
  149. package/src/ui/SchematicGeometryBounds.mjs +540 -0
  150. package/src/ui/SchematicSvgRenderer.mjs +110 -0
  151. package/src/ui/SchematicTableGeometry.mjs +319 -0
  152. package/src/ui/SchematicTextAnchor.mjs +55 -0
  153. package/src/ui/SchematicTextBounds.mjs +98 -0
  154. package/src/workers/parser.worker.mjs +59 -0
@@ -0,0 +1,154 @@
1
+ # circuitjson-toolkit 1.1.0
2
+
3
+ ## Breaking API convergence
4
+
5
+ This minor release intentionally changes public names, parameters, return
6
+ shapes, and package layout so CircuitJSON, Gerber, Altium, and KiCad toolkits
7
+ can expose the same API.
8
+
9
+ The root is an exact 17-class contract: the 14 canonical classes plus temporary
10
+ `CircuitJsonDocument`, `CircuitJsonIndexer`, and `CircuitJsonUnits` viewer
11
+ compatibility exports. Exactly 37 previous CircuitJSON-specific classes remain
12
+ available from `circuitjson-toolkit/extensions`; they were not removed and are
13
+ classified as shared or derived for all four toolkits.
14
+
15
+ Key changes:
16
+
17
+ - `Parser.parse({ fileName, data }, options)` replaces filename/text-specific
18
+ parser calls and returns `ecad-toolkit.document.v1`.
19
+ - `ProjectLoader` returns `ecad-toolkit.project.v1` with canonical document
20
+ envelopes. It now captures one bounded stable entry snapshot, enforces
21
+ `maxEntries` before inspecting entries, and gives direct and worker paths the
22
+ same known-field behavior.
23
+ - Parser failures use `ToolkitError`; `tryParse` and `tryLoad` return exact
24
+ success/failure discriminants.
25
+ - `retainSource` is now the explicit `'none' | 'reference'` contract.
26
+ Reference mode preserves exact caller identity only on direct parser calls,
27
+ exposes it non-enumerably, and never serializes or freezes the caller input.
28
+ - PCB, schematic, BOM, interaction, query, manufacturing, simulation, and 3D
29
+ services consume either a document result, a CircuitJSON model, or a reused
30
+ `CircuitJsonDocumentContext`.
31
+ - Canonical schematic graphics now include asset-backed `schematic_image`
32
+ rows and hierarchical `schematic_sheet_symbol` rows. Images keep payloads
33
+ in ToolkitAsset records, and child sheet symbols no longer masquerade as
34
+ selectable pages or hide unowned root graphics.
35
+ - `PcbScene3dBuilder` and `PcbScene3dPreparator` return data-only,
36
+ millimeter-based, right-handed Z-up scenes. The package does not depend on
37
+ Three.js and never fetches assets implicitly.
38
+ - `ecad-toolkit.worker.v1` provides equivalent parse/project results, ordered
39
+ progress, cancellation, strict clone-safe errors, opt-in input transfer, and
40
+ worker-owned output transfer.
41
+ - `ParserWorkerClient.parseAttempt()` and `loadProjectAttempt()` give source
42
+ toolkits request-scoped automatic-worker fallback: only local construction
43
+ failure sets `unavailable: true`; parser, protocol, and runtime failures stay
44
+ visible.
45
+ - Canonical subpaths now include `/parser`, `/project`, `/renderers`,
46
+ `/interaction`, `/query`, `/manufacturing`, `/simulation`, `/scene3d`,
47
+ `/capabilities`, `/extensions`, and `/testing`.
48
+ - Shared validation proofs, indexes, render preparation, queries, and scene
49
+ preparation are request-scoped and reused to avoid repeated parsing,
50
+ validation, cloning, and spatial work.
51
+ - Validated source extensions are captured once as immutable owned data under
52
+ a separate 128 MiB payload and 2,000,000-item ceiling. Realistic large native
53
+ graphs now survive direct and worker results; over-limit graphs fail visibly
54
+ and the worker keeps its 250 MB whole-result ceiling. Binary extension values
55
+ stay byte-backed behind defensive-copy access rather than expanding into
56
+ plain number arrays.
57
+ - `CircuitJsonDocumentContext` can now only be created through `prepare()`;
58
+ direct construction fails before reading input so viewers and applications
59
+ can consume the same validation-bound context without adapter workarounds.
60
+ - `CircuitJsonDocument.normalizeModel(model, { owned })` is the shared
61
+ copy-on-write compatibility boundary for legacy table geometry, PCB artwork
62
+ paths, pad diagnostics, courtyards, layer aliases, and stroke dash fields.
63
+ Toolkits normalize owned projections before one validation pass; viewers no
64
+ longer need application-side repair code.
65
+ - The complete serialized-input validator is compiled from the pinned
66
+ development dependency `circuit-json@0.0.446`. It preserves upstream
67
+ refinement, pipeline, and SI-unit transform rejection behavior while keeping
68
+ the published browser runtime dependency-free.
69
+ - Compiler provenance now also verifies and records the exact lock integrity
70
+ and distribution entry SHA-256 for `format-si-unit@0.0.7` and `zod@3.25.76`.
71
+ - Full compatibility parsing canonicalizes legacy Gerber/KiCad outer-layer
72
+ aliases (`1`/`32`, `F.*`/`B.*`, and descriptor `layer.name`), fills via layer
73
+ defaults, converts legacy trace vias, and retains silkscreen circle/oval and
74
+ courtyard geometry for viewers without app-side adapters.
75
+ - `CircuitJsonPcbHolePrimitiveModel` now measures polygon `pad_outline` in the
76
+ pad's rotation-local coordinate system and retains pill drill width, height,
77
+ diameter, and independent board-space rotation. Legal `outer_width`,
78
+ `outer_height`, `rect_ccw_rotation`, and `hole_ccw_rotation` variants are
79
+ preserved. Downstream viewers no longer need format-specific plated-slot
80
+ sizing logic.
81
+ - Legal square `pcb_hole` rows normalize to equal-width rectangular apertures
82
+ rather than circular fallbacks.
83
+ - `extensions: 'none'` now has the exact common return shape `{}` for native
84
+ documents and projects instead of a source-namespaced placeholder.
85
+ - `ZipArchiveInspector` now validates exact local/central filenames, CRC32, and
86
+ size metadata and exposes `verifyExtractedBytes()` so stored and deflated
87
+ corruption is rejected after bounded inflation. Compression ratios use
88
+ compressed and uncompressed member payload totals, so ZIP comments or other
89
+ container padding cannot bypass expansion limits.
90
+ - `/testing` now exports `ToolkitLoopbackWorker` alongside the contract fixtures
91
+ and runner so all toolkits share one real structured-clone worker regression
92
+ boundary.
93
+ - Direct async parser/project paths now snapshot exact binary windows and
94
+ selected assets before progress callbacks. Worker-received inputs reuse their
95
+ structured-clone ownership boundary, and direct companion assets are prepared
96
+ once, closing callback mutation races without redundant receiver/result copies.
97
+ - `npm run sync:schema -- --check` is a read-only drift gate that recompiles the
98
+ live pinned union and checks exact contract, provenance, snapshot, and
99
+ generated-module equality.
100
+ - Validation now freezes each proven model once, the legacy parser hands its
101
+ already-built index to the next consumer, multi-side legacy rendering shares
102
+ one primitive preparation, and compact identifier indexes avoid cloning
103
+ duplicate element graphs.
104
+ - `ToolkitAsset.measure()`, `prepare()`, and `prepareAll()` provide one
105
+ descriptor-safe asset boundary. Metadata mode copies no payload; full mode
106
+ copies once; project limits include attached assets in direct and worker
107
+ execution. Missing media types are inferred consistently for common ECAD
108
+ model and image suffixes, including `model/vrml` for WRL/VRML and
109
+ `model/step` for STEP/STP, while explicit values remain authoritative.
110
+ - Canonical schematic rendering preserves explicit multi-value dash patterns,
111
+ accepts only safe SVG line-cap values, and honors `show_label: false` in both
112
+ component markup and bounds. Source toolkits can retain native styles and
113
+ hidden designators without renderer or application workarounds.
114
+ - The release benchmark runner enforces the frozen 1.0.17 workloads: both
115
+ primary cases must be at least 20% faster, non-primary regressions are
116
+ bounded, and the duplicate index graph must be at least 25% smaller. Timing
117
+ uses three independent processes. Every process imports toolkit modules from
118
+ the freshly extracted npm tarball candidate and records an execution marker
119
+ that reconciles its package version and source digest with candidate
120
+ provenance.
121
+ - The retained Node 20 / Apple M3 Max result passes every timing and clone
122
+ gate, including at least 20% faster for both primary workloads and 85.32%
123
+ fewer duplicate-index clone bytes. See
124
+ `benchmarks/results-v1.1.0.json` for samples and checksums.
125
+ - Gerber, Altium, and KiCad packages now consume CircuitJSON Toolkit as their
126
+ shared runtime; their license terms do not replace this package's AGPL or
127
+ separately granted commercial terms.
128
+
129
+ Before:
130
+
131
+ ```js
132
+ import { CircuitJsonParser } from 'circuitjson-toolkit'
133
+
134
+ const model = CircuitJsonParser.parseText(text, {
135
+ fileName: 'board.json'
136
+ })
137
+ ```
138
+
139
+ After:
140
+
141
+ ```js
142
+ import { Parser } from 'circuitjson-toolkit'
143
+
144
+ const document = Parser.parse({
145
+ fileName: 'board.json',
146
+ data: text
147
+ })
148
+
149
+ console.log(document.model)
150
+ ```
151
+
152
+ See [migration.md](migration.md) and its generated
153
+ [appendix pages](migration/root.md) for the exhaustive 1.0.17 feature mapping,
154
+ and [capabilities.md](capabilities.md) for host-side capability gating.
package/docs/testing.md CHANGED
@@ -1,16 +1,126 @@
1
- # Testing
1
+ # Testing and downstream conformance
2
2
 
3
- Run the full test suite with:
3
+ ## Repository gates
4
4
 
5
5
  ```bash
6
+ npm ci
6
7
  npm test
8
+ npm run check:format
9
+ npm run sync:schema -- --check
10
+ npm run check:features -- --strict
11
+ npm run benchmark -- --compare benchmarks/baseline-v1.0.17.json
12
+ npm pack --dry-run
13
+ npm run check:packed-entrypoints
14
+ npm run check:browser-dependencies
7
15
  ```
8
16
 
9
- Check formatting with:
17
+ `sync:schema -- --check` recompiles the complete element union from the pinned
18
+ development dependency `circuit-json@0.0.446` and compares its contract hash,
19
+ schema snapshot, provenance, and browser-neutral generated validator with the
20
+ checked-in artifacts. Check mode is read-only. It also preserves upstream
21
+ transform rejection boundaries, including malformed SI-unit strings that the
22
+ upstream schema rejects by throwing instead of returning a failed parse.
10
23
 
11
- ```bash
12
- npm run check:format
24
+ The schema differential suite samples every upstream union leaf, compares
25
+ required-field failures, exercises transform-owned resistor, capacitor,
26
+ inductor, current-source, and crystal fields, and verifies that a fresh compile
27
+ is exactly equal to the generated runtime contract. Unsupported future Zod
28
+ constructs fail the compiler closed.
29
+
30
+ `check:features -- --strict` packs the package, imports its public entrypoints,
31
+ checks every 1.0.17 ledger row against the capability inventory, and verifies
32
+ all referenced test and documentation paths.
33
+
34
+ The benchmark comparison freezes historical workload semantics, fixtures,
35
+ expected results, clone bytes, environment metadata, samples, medians, and
36
+ checksums. Candidate timing is the median of at least three independent Node
37
+ processes. Each process imports the toolkit runtime from the freshly extracted
38
+ npm package candidate rather than the live worktree. Its execution marker must
39
+ match the candidate package version and packed-source digest; candidate
40
+ provenance additionally records the fresh tarball SHA-256.
41
+ Primary convergence cases must improve by the release threshold; unchanged
42
+ cases may not exceed their regression budgets. The enforced limits are 20%
43
+ faster for both primary cases, at most 5% regression for other large cases, at
44
+ most 10% for small cases, and at least 25% fewer clone bytes for the duplicate
45
+ index graph.
46
+
47
+ The two packed checks always create and install a fresh npm pack in isolated
48
+ fixtures. If an explicit tarball is supplied, its digest must equal that fresh
49
+ pack, so a stale retained candidate cannot pass. The
50
+ entrypoint gate imports every documented subpath and runs the complete shared
51
+ contract. The browser graph gate starts at every JavaScript, worker, and CSS
52
+ export, follows packed relative imports, and rejects Node built-ins,
53
+ `circuit-json`, undeclared packages, and development-only runtime edges.
54
+
55
+ ## Shared toolkit contract
56
+
57
+ Source toolkits consume the packed harness:
58
+
59
+ ```js
60
+ import {
61
+ ToolkitContractFixtures,
62
+ runToolkitContract
63
+ } from 'circuitjson-toolkit/testing'
64
+ import * as toolkit from 'gerber-toolkit'
65
+
66
+ const report = await runToolkitContract(toolkit, {
67
+ fixtures: ToolkitContractFixtures.gerber()
68
+ })
69
+
70
+ assert.deepEqual(report.failures, [])
13
71
  ```
14
72
 
15
- Use only small fake CircuitJSON samples in tests. Do not add customer, vendor,
16
- or source project files to this repository.
73
+ Fixtures are available for CircuitJSON, Gerber, Altium, and KiCad. The harness
74
+ checks the exact canonical class list, parser and project success/failure
75
+ paths, synchronous/asynchronous equivalence, document result shapes, context
76
+ reuse, top/bottom rendering, interaction, query, manufacturing, simulation,
77
+ 3D scenes, typed errors, and common capability ids.
78
+
79
+ Worker checks install an in-memory `ecad-toolkit.worker.v1` loopback with real
80
+ structured-clone and transfer boundaries, then require `worker: true`. A direct
81
+ fallback cannot satisfy these checks.
82
+
83
+ Extension ownership tests use a realistic native graph above the former
84
+ compact-metadata item ceiling. They require one bounded immutable capture,
85
+ mutation isolation, a direct capture under two seconds, exact worker-result
86
+ round-trip behavior, and visible rejection beyond the separate 128 MiB
87
+ extension payload ceiling. A 3 MiB binary regression additionally requires
88
+ byte-backed `Uint8Array` shape, defensive-copy mutation isolation, direct and
89
+ worker parity, bounded elapsed time, and bounded JavaScript heap growth.
90
+
91
+ Variant-geometry tests also lock rotation-local polygon-plated pad extents and
92
+ pill drill dimensions, independent outer/drill rotations, and every legal
93
+ outer-size field so Gerber, KiCad, Altium, and viewers share the same hole
94
+ primitive contract. Legal square holes remain rectangular apertures.
95
+
96
+ ZIP tests reject local/central filename, CRC32, and size disagreements, then
97
+ verify extracted bytes for both stored and deflated members. A same-length
98
+ payload bit flip must fail CRC32 verification instead of reaching a format
99
+ parser.
100
+
101
+ Async ownership tests mutate exact-window `SharedArrayBuffer` parser/project
102
+ bytes, attached assets, and companion assets from the first progress callback.
103
+ Sync, direct async, and structured-clone worker results must remain identical,
104
+ and prepared companion assets must not be copied a second time at result build.
105
+
106
+ The harness reads capability status before invoking optional behavior. A
107
+ `shared`, `native`, or `derived` operation must return its canonical result; an
108
+ `unavailable` operation must throw `ToolkitError` with
109
+ `ERR_CAPABILITY_UNAVAILABLE`. This lets a source format explicitly reject work
110
+ it cannot represent instead of returning an invented empty success.
111
+
112
+ Each source repository also owns format-specific differential, worker,
113
+ cancellation, transfer, native-fidelity, extension, and performance tests.
114
+
115
+ Core convergence tests additionally exercise copy-on-write and owned legacy
116
+ normalization, exact geometry preservation, singular/plural diagnostic
117
+ relations, and worker-received native extensions. Performance gates cover
118
+ 50,000-element parse and index preparation, repeated hit testing, multi-side
119
+ rendering, and clone allocation so compatibility does not add an
120
+ application-visible slow path.
121
+
122
+ ## Fixture policy
123
+
124
+ Use only small synthetic, obfuscated, repository-owned samples. Never commit
125
+ customer, vendor, or source project files. Fixes must derive from the format,
126
+ schema, or protocol rather than sample names or known text.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "circuitjson-toolkit",
3
- "version": "1.0.17",
4
- "description": "Dependency-free CircuitJSON parsing, validation, indexing, and utility helpers",
3
+ "version": "1.1.0",
4
+ "description": "Canonical CircuitJSON parsing, project, rendering, query, manufacturing, simulation, and scene contracts",
5
5
  "keywords": [
6
6
  "circuitjson",
7
7
  "circuit-json",
@@ -29,12 +29,28 @@
29
29
  "exports": {
30
30
  ".": "./src/index.mjs",
31
31
  "./parser": "./src/parser.mjs",
32
- "./renderers": "./src/renderers.mjs"
32
+ "./project": "./src/project.mjs",
33
+ "./renderers": "./src/renderers.mjs",
34
+ "./interaction": "./src/interaction.mjs",
35
+ "./query": "./src/query.mjs",
36
+ "./manufacturing": "./src/manufacturing.mjs",
37
+ "./simulation": "./src/simulation.mjs",
38
+ "./scene3d": "./src/scene3d.mjs",
39
+ "./capabilities": "./src/capabilities.mjs",
40
+ "./extensions": "./src/extensions.mjs",
41
+ "./testing": "./src/testing.mjs",
42
+ "./workers/parser.worker.mjs": "./src/workers/parser.worker.mjs",
43
+ "./styles/renderers.css": "./src/styles/renderers.css"
33
44
  },
34
45
  "files": [
35
46
  "src",
36
47
  "docs/api.md",
48
+ "docs/capabilities.md",
49
+ "docs/migration.md",
50
+ "docs/migration",
37
51
  "docs/model-format.md",
52
+ "docs/provenance.md",
53
+ "docs/release-notes-v1.1.0.md",
38
54
  "docs/testing.md",
39
55
  "spec",
40
56
  "LICENSE",
@@ -49,10 +65,20 @@
49
65
  "scripts": {
50
66
  "test": "node --test",
51
67
  "format": "prettier --write .",
52
- "check:format": "prettier --check ."
68
+ "check:format": "prettier --check .",
69
+ "sync:schema": "node scripts/sync-circuit-json-schema.mjs",
70
+ "sync:migration": "node scripts/generate-migration-doc.mjs",
71
+ "capture:api": "node scripts/capture-api-baseline.mjs",
72
+ "check:features": "node scripts/check-feature-preservation.mjs",
73
+ "check:packed-entrypoints": "node scripts/check-packed-entrypoints.mjs",
74
+ "check:browser-dependencies": "node scripts/check-browser-dependency-graph.mjs",
75
+ "benchmark": "node --expose-gc scripts/run-benchmarks.mjs --compare benchmarks/baseline-v1.0.17.json"
53
76
  },
54
77
  "devDependencies": {
55
- "prettier": "^3.4.2"
78
+ "circuit-json": "0.0.446",
79
+ "format-si-unit": "0.0.7",
80
+ "prettier": "^3.4.2",
81
+ "zod": "3.25.76"
56
82
  },
57
83
  "engines": {
58
84
  "node": ">=20"