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.
- package/NOTICE.md +31 -0
- package/README.md +267 -107
- package/docs/api.md +501 -96
- package/docs/capabilities.md +70 -0
- package/docs/migration/behaviors.md +45 -0
- package/docs/migration/parser.md +60 -0
- package/docs/migration/renderers.md +515 -0
- package/docs/migration/root.md +740 -0
- package/docs/migration.md +120 -0
- package/docs/model-format.md +175 -57
- package/docs/provenance.md +206 -0
- package/docs/release-notes-v1.1.0.md +154 -0
- package/docs/testing.md +117 -7
- package/package.json +31 -5
- package/spec/api-baseline-v1.0.17.json +1 -0
- package/spec/baseline-provenance-v1.0.17.json +7 -0
- package/spec/circuitjson-schema-snapshot.json +321 -0
- package/spec/circuitjson-schema-source.json +28 -0
- package/spec/feature-preservation.json +1 -0
- package/spec/library-scope.md +27 -20
- package/src/capabilities.mjs +1 -0
- package/src/core/ArchiveEntryPath.mjs +93 -0
- package/src/core/ArchiveLimits.mjs +31 -0
- package/src/core/ArchiveLimitsValidator.mjs +107 -0
- package/src/core/AsyncInputOwnership.mjs +56 -0
- package/src/core/AttachedValueLimits.mjs +67 -0
- package/src/core/CircuitJsonDiagnosticIndexer.mjs +184 -0
- package/src/core/CircuitJsonDocument.mjs +19 -61
- package/src/core/CircuitJsonElementTypes.mjs +10 -0
- package/src/core/CircuitJsonElementValidator.mjs +98 -847
- package/src/core/CircuitJsonIndexer.mjs +274 -194
- package/src/core/CircuitJsonManufacturingBuilder.mjs +167 -164
- package/src/core/CircuitJsonParser.mjs +75 -13
- package/src/core/CircuitJsonPcbClearanceDiagnostics.mjs +12 -6
- package/src/core/CircuitJsonPcbHolePrimitiveModel.mjs +108 -10
- package/src/core/CircuitJsonPcbPadPrimitiveModel.mjs +1 -1
- package/src/core/CircuitJsonPcbPrimitiveArtwork.mjs +44 -38
- package/src/core/CircuitJsonPcbPrimitiveBuilder.mjs +146 -28
- package/src/core/CircuitJsonPcbPrimitiveFields.mjs +70 -4
- package/src/core/CircuitJsonPcbPrimitiveIndex.mjs +18 -2
- package/src/core/CircuitJsonPcbPrimitiveOverlays.mjs +26 -9
- package/src/core/CircuitJsonPcbZonePrimitiveBuilder.mjs +7 -6
- package/src/core/CircuitJsonSerializedInputAudit.mjs +87 -0
- package/src/core/CircuitJsonSourceMetadata.mjs +5 -1
- package/src/core/CircuitJsonSupportMatrixBuilder.mjs +3 -1
- package/src/core/CircuitJsonToolkitElementSchema.mjs +218 -0
- package/src/core/CircuitJsonUnitParsers.mjs +101 -0
- package/src/core/CircuitJsonUnits.mjs +13 -87
- package/src/core/CircuitJsonUpstreamSchema.mjs +9 -0
- package/src/core/CircuitJsonUpstreamValidator.mjs +418 -0
- package/src/core/CircuitJsonValidationUnits.mjs +6 -0
- package/src/core/ManufacturingService.mjs +323 -0
- package/src/core/Parser.mjs +343 -0
- package/src/core/ParserOptions.mjs +333 -0
- package/src/core/PcbBoundsSelectionModel.mjs +55 -19
- package/src/core/PcbDiagnosticFocusModel.mjs +42 -11
- package/src/core/PcbInteractionIndex.mjs +368 -0
- package/src/core/PcbInteractionPrimitiveModel.mjs +393 -62
- package/src/core/ProjectAsyncInputOwner.mjs +70 -0
- package/src/core/ProjectLoader.mjs +975 -0
- package/src/core/SimulationService.mjs +790 -0
- package/src/core/ToolkitCapabilities.mjs +130 -0
- package/src/core/ZipArchiveInspector.mjs +649 -0
- package/src/core/context/BinaryDataSnapshot.mjs +217 -0
- package/src/core/context/CircuitJsonContextIndexes.mjs +96 -0
- package/src/core/context/CircuitJsonDerivedCache.mjs +114 -0
- package/src/core/context/CircuitJsonDocumentContext.mjs +353 -0
- package/src/core/context/CircuitJsonLegacyModel.mjs +147 -0
- package/src/core/context/CircuitJsonLegacyNormalizer.mjs +847 -0
- package/src/core/context/CircuitJsonMetadataBoundary.mjs +76 -0
- package/src/core/context/CircuitJsonModelFreezeTraversal.mjs +179 -0
- package/src/core/context/CircuitJsonReadOnlyDocument.mjs +920 -0
- package/src/core/context/CircuitJsonSchematicTableNormalizer.mjs +314 -0
- package/src/core/context/CircuitJsonValidationAuthority.mjs +39 -0
- package/src/core/context/CircuitJsonValidationProof.mjs +217 -0
- package/src/core/context/PcbPrimitivePreparation.mjs +198 -0
- package/src/core/context/PcbSpatialIndex.mjs +701 -0
- package/src/core/context/ProtectedExtensionBinaryBoundary.mjs +128 -0
- package/src/core/context/StructuredDataSnapshot.mjs +683 -0
- package/src/core/contracts/DocumentResult.mjs +198 -0
- package/src/core/contracts/ProjectResult.mjs +96 -0
- package/src/core/contracts/RuntimeProxyBoundary.mjs +48 -0
- package/src/core/contracts/ToolkitAsset.mjs +493 -0
- package/src/core/contracts/ToolkitDiagnostic.mjs +38 -0
- package/src/core/contracts/ToolkitError.mjs +176 -0
- package/src/core/contracts/ToolkitProgress.mjs +89 -0
- package/src/core/interaction/CanonicalInteractionOptions.mjs +246 -0
- package/src/core/interaction/PcbInteractionBounds.mjs +167 -0
- package/src/core/query/CircuitTraversal.mjs +343 -0
- package/src/core/query/ComponentGrouping.mjs +275 -0
- package/src/core/query/QueryNetlistBuilder.mjs +306 -0
- package/src/core/query/QueryService.mjs +435 -0
- package/src/core/query/RegexPattern.mjs +75 -0
- package/src/core/rendering/CanonicalBomOrder.mjs +81 -0
- package/src/core/rendering/CanonicalBomRows.mjs +92 -0
- package/src/core/rendering/CanonicalRenderOptions.mjs +498 -0
- package/src/core/rendering/CanonicalSvgDocument.mjs +102 -0
- package/src/core/rendering/PcbRenderPlan.mjs +429 -0
- package/src/core/rendering/SchematicSheetSelector.mjs +335 -0
- package/src/core/scene3d/PcbScene3dBuilder.mjs +906 -0
- package/src/core/scene3d/PcbScene3dPreparator.mjs +47 -0
- package/src/core/scene3d/Scene3dAssetIndex.mjs +284 -0
- package/src/core/scene3d/Scene3dBoardModel.mjs +596 -0
- package/src/core/scene3d/Scene3dDocumentMetadata.mjs +167 -0
- package/src/core/scene3d/Scene3dFreeze.mjs +37 -0
- package/src/core/scene3d/Scene3dIdRegistry.mjs +34 -0
- package/src/core/scene3d/Scene3dInputPreflight.mjs +193 -0
- package/src/core/scene3d/Scene3dMaterials.mjs +58 -0
- package/src/core/scene3d/Scene3dModelReference.mjs +134 -0
- package/src/core/scene3d/Scene3dOptions.mjs +363 -0
- package/src/core/scene3d/SceneAssetResolver.mjs +441 -0
- package/src/core/simulation/SimulationParameterCloner.mjs +543 -0
- package/src/core/worker/ParserWorkerClient.mjs +997 -0
- package/src/core/worker/ToolkitWorkerProtocol.mjs +412 -0
- package/src/core/worker/WorkerRequestData.mjs +623 -0
- package/src/core/worker/WorkerResponseData.mjs +905 -0
- package/src/extensions.mjs +37 -0
- package/src/index.mjs +14 -9
- package/src/interaction.mjs +2 -0
- package/src/manufacturing.mjs +1 -0
- package/src/parser.mjs +12 -2
- package/src/project.mjs +5 -0
- package/src/query.mjs +1 -0
- package/src/renderers.mjs +3 -29
- package/src/scene3d.mjs +3 -0
- package/src/simulation.mjs +1 -0
- package/src/styles/renderers.css +24 -0
- package/src/testing/ToolkitContractFixtures.mjs +124 -0
- package/src/testing/ToolkitLoopbackWorker.mjs +174 -0
- package/src/testing/runToolkitContract.mjs +705 -0
- package/src/testing.mjs +3 -0
- package/src/ui/BomTableRenderer.mjs +304 -0
- package/src/ui/CircuitJsonPcbBoardSvgRenderer.mjs +80 -0
- package/src/ui/CircuitJsonPcbPrimitiveAttributeRenderer.mjs +3 -5
- package/src/ui/CircuitJsonPcbSvgRenderer.mjs +63 -43
- package/src/ui/CircuitJsonPcbViaSvgRenderer.mjs +3 -5
- package/src/ui/CircuitJsonSchematicDebugRenderer.mjs +164 -0
- package/src/ui/CircuitJsonSchematicImageSvgRenderer.mjs +210 -0
- package/src/ui/CircuitJsonSchematicLineRenderer.mjs +86 -0
- package/src/ui/CircuitJsonSchematicSheetSymbolSvgRenderer.mjs +98 -0
- package/src/ui/CircuitJsonSchematicSvgArcPath.mjs +117 -17
- package/src/ui/CircuitJsonSchematicSvgPortMetadata.mjs +67 -20
- package/src/ui/CircuitJsonSchematicSvgPrimitiveAttributes.mjs +45 -9
- package/src/ui/CircuitJsonSchematicSvgRenderer.mjs +151 -148
- package/src/ui/CircuitJsonSchematicTableSvgRenderer.mjs +4 -292
- package/src/ui/PcbSvgRenderer.mjs +41 -0
- package/src/ui/SafeSvgPaint.mjs +26 -0
- package/src/ui/SafeXmlText.mjs +60 -0
- package/src/ui/SchematicGeometryBounds.mjs +540 -0
- package/src/ui/SchematicSvgRenderer.mjs +110 -0
- package/src/ui/SchematicTableGeometry.mjs +319 -0
- package/src/ui/SchematicTextAnchor.mjs +55 -0
- package/src/ui/SchematicTextBounds.mjs +98 -0
- package/src/workers/parser.worker.mjs +59 -0
package/docs/api.md
CHANGED
|
@@ -1,143 +1,548 @@
|
|
|
1
|
-
|
|
1
|
+
<!--
|
|
2
|
+
SPDX-FileCopyrightText: 2026 André Fiedler
|
|
3
|
+
SPDX-License-Identifier: CC-BY-SA-4.0
|
|
4
|
+
-->
|
|
2
5
|
|
|
3
|
-
|
|
4
|
-
|
|
6
|
+
# Canonical API
|
|
7
|
+
|
|
8
|
+
Version 1.1.0 exposes one common API contract for `circuitjson-toolkit`,
|
|
9
|
+
`gerber-toolkit`, `altium-toolkit`, and `kicad-toolkit`. CircuitJSON is the
|
|
10
|
+
shared immutable model. Every common service accepts a canonical
|
|
11
|
+
`DocumentResult`, its `model` array, or a prepared `CircuitJsonDocumentContext`
|
|
12
|
+
unless a narrower input is stated below.
|
|
13
|
+
|
|
14
|
+
The 1.1.0 convergence is intentionally breaking. Use the canonical classes in
|
|
15
|
+
this document for new code. Thirty-seven previous CircuitJSON-specific classes
|
|
16
|
+
remain under `circuitjson-toolkit/extensions`; the three documented viewer
|
|
17
|
+
compatibility classes remain on the root. See [migration.md](migration.md).
|
|
18
|
+
|
|
19
|
+
## Common conventions
|
|
20
|
+
|
|
21
|
+
### Document input
|
|
22
|
+
|
|
23
|
+
Parser calls use an input record:
|
|
24
|
+
|
|
25
|
+
```js
|
|
26
|
+
{
|
|
27
|
+
fileName: 'board.json',
|
|
28
|
+
data: string | ArrayBuffer | Uint8Array,
|
|
29
|
+
assets?: object[]
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`Parser.parse()` and `Parser.parseAsync()` return the exact
|
|
34
|
+
`ecad-toolkit.document.v1` envelope:
|
|
35
|
+
|
|
36
|
+
```js
|
|
37
|
+
{
|
|
38
|
+
schema: 'ecad-toolkit.document.v1',
|
|
39
|
+
id: 'document-...',
|
|
40
|
+
modelSchema: { name: 'circuit-json', version: '0.0.446' },
|
|
41
|
+
model: [],
|
|
42
|
+
source: { format: 'circuitjson', fileName: 'board.json', fileType: 'circuitjson' },
|
|
43
|
+
extensions: {},
|
|
44
|
+
assets: [],
|
|
45
|
+
diagnostics: [],
|
|
46
|
+
statistics: {}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The shared fields have the same names and meanings in every source toolkit.
|
|
51
|
+
Source-only facts belong in `extensions.<format>` and are never discarded to
|
|
52
|
+
make the common shape smaller.
|
|
53
|
+
|
|
54
|
+
Validated source documents own selected extension values as one deeply
|
|
55
|
+
immutable, descriptor-safe snapshot. This uses a distinct 128 MiB payload and
|
|
56
|
+
2,000,000-item ceiling so large native renderer graphs do not inherit the
|
|
57
|
+
compact metadata limit. The shared worker protocol applies the same ownership
|
|
58
|
+
boundary after structured cloning and retains its 250 MB whole-result ceiling.
|
|
59
|
+
Binary values preserve their `ArrayBuffer`/typed-view shape behind defensive
|
|
60
|
+
copy access, so payload bytes do not inflate into one JavaScript number per
|
|
61
|
+
byte.
|
|
62
|
+
|
|
63
|
+
### Errors
|
|
64
|
+
|
|
65
|
+
Public failures are `ToolkitError` instances. The stable serialized fields are
|
|
66
|
+
`name`, `message`, `code`, `category`, `format`, `source`, `details`, and
|
|
67
|
+
`cause`. `error.toJSON()` produces a clone-safe record. `ToolkitError.from()`
|
|
68
|
+
normalizes an unknown failure without invoking hostile accessors.
|
|
69
|
+
|
|
70
|
+
### Progress, cancellation, and workers
|
|
71
|
+
|
|
72
|
+
Asynchronous parser and project calls accept:
|
|
73
|
+
|
|
74
|
+
- `signal`: an `AbortSignal`;
|
|
75
|
+
- `onProgress(progress)`: ordered clone-safe progress rows;
|
|
76
|
+
- `worker`: `false`, `true`, or `'auto'`;
|
|
77
|
+
- `transferInput`: explicit permission to detach transferable caller input.
|
|
78
|
+
|
|
79
|
+
`worker: 'auto'` falls back to direct work only when worker construction is
|
|
80
|
+
unavailable. Protocol, post-message, parser, and runtime errors stay visible.
|
|
81
|
+
Worker and direct results have the same serialized shape.
|
|
82
|
+
|
|
83
|
+
`retainSource` is exactly `'none' | 'reference'` and defaults to `'none'`.
|
|
84
|
+
`'reference'` is an in-process parser option: the returned document has a
|
|
85
|
+
non-enumerable `sourceReference` property whose value is the exact caller input
|
|
86
|
+
object. The toolkit neither freezes nor copies that caller object, and
|
|
87
|
+
serialization or structured cloning intentionally omits the reference.
|
|
88
|
+
`worker: true` rejects this mode because cross-thread caller identity cannot be
|
|
89
|
+
preserved; `worker: 'auto'` selects the direct path instead.
|
|
90
|
+
|
|
91
|
+
### Reusing work
|
|
92
|
+
|
|
93
|
+
Prepare a context once when several operations use the same document:
|
|
94
|
+
|
|
95
|
+
```js
|
|
96
|
+
const context = CircuitJsonDocumentContext.prepare(document, {
|
|
97
|
+
indexes: ['elements', 'relations', 'connectivity', 'spatial']
|
|
98
|
+
})
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Validation, indexes, render primitives, and other derived values are cached by
|
|
102
|
+
the context. Public outputs remain detached or immutable; a caller cannot
|
|
103
|
+
mutate later results through a returned object.
|
|
104
|
+
|
|
105
|
+
## Root entrypoint
|
|
106
|
+
|
|
107
|
+
`circuitjson-toolkit` has an exact 17-class root. The 14 canonical classes are:
|
|
108
|
+
|
|
109
|
+
- `Parser`
|
|
110
|
+
- `ProjectLoader`
|
|
111
|
+
- `CircuitJsonDocumentContext`
|
|
112
|
+
- `PcbSvgRenderer`
|
|
113
|
+
- `SchematicSvgRenderer`
|
|
114
|
+
- `BomTableRenderer`
|
|
115
|
+
- `PcbInteractionIndex`
|
|
116
|
+
- `QueryService`
|
|
117
|
+
- `ManufacturingService`
|
|
118
|
+
- `SimulationService`
|
|
119
|
+
- `PcbScene3dBuilder`
|
|
120
|
+
- `PcbScene3dPreparator`
|
|
121
|
+
- `ToolkitCapabilities`
|
|
122
|
+
- `ToolkitError`
|
|
123
|
+
|
|
124
|
+
`CircuitJsonDocument`, `CircuitJsonIndexer`, and `CircuitJsonUnits` remain
|
|
125
|
+
temporarily on the root for viewer compatibility. All other former root
|
|
126
|
+
exports are explicitly retained by `/extensions`.
|
|
127
|
+
|
|
128
|
+
### `CircuitJsonDocument.normalizeModel(model, options?)`
|
|
129
|
+
|
|
130
|
+
Projects supported pre-union aliases onto the canonical element union. The
|
|
131
|
+
default copy-on-write call preserves the exact input and element identities
|
|
132
|
+
when no projection is needed. `{ owned: true }` may update a toolkit-owned
|
|
133
|
+
mutable model in place before its single validation/proof pass.
|
|
134
|
+
|
|
135
|
+
The canonical union is the pinned upstream schema plus the source-neutral
|
|
136
|
+
`schematic_image` and `schematic_sheet_symbol` contracts. Use
|
|
137
|
+
`CircuitJsonElementValidator.knownElementTypes()` for the exact upstream
|
|
138
|
+
snapshot, `canonicalElementTypes()` for all accepted types, and
|
|
139
|
+
`extensionElementTypes()` for the toolkit-owned additions.
|
|
140
|
+
|
|
141
|
+
The projection covers legacy schematic table row/column/span geometry, PCB
|
|
142
|
+
artwork `points`/`width` paths, pad-clearance diagnostic relations, courtyard
|
|
143
|
+
line/path/polygon forms, outer-layer aliases, and retained stroke dash fields.
|
|
144
|
+
It derives geometry from the supplied data and does not recognize filenames,
|
|
145
|
+
fixtures, vendors, or application state.
|
|
146
|
+
|
|
147
|
+
### `CircuitJsonPcbHolePrimitiveModel.build(element, center)`
|
|
148
|
+
|
|
149
|
+
Normalizes circular, rectangular, pill, and polygon-plated holes for shared
|
|
150
|
+
rendering and interaction consumers. Polygon `pad_outline` points determine
|
|
151
|
+
rotation-local outer width and height; pill drill width, height, diameter, and
|
|
152
|
+
board-space rotation remain distinct from outer-pad rotation. Legal
|
|
153
|
+
`outer_width`, `outer_height`, `rect_ccw_rotation`, and `hole_ccw_rotation`
|
|
154
|
+
variants are preserved. Import this retained source-neutral helper from
|
|
155
|
+
`circuitjson-toolkit/extensions`.
|
|
156
|
+
|
|
157
|
+
Packed release checks reject any missing or additional root export.
|
|
5
158
|
|
|
6
159
|
## Parser
|
|
7
160
|
|
|
8
|
-
|
|
161
|
+
Import from the root or `circuitjson-toolkit/parser`.
|
|
9
162
|
|
|
10
|
-
|
|
163
|
+
### `Parser.parse(input, options?)`
|
|
11
164
|
|
|
12
|
-
|
|
165
|
+
Synchronously detects, decodes, validates, and returns one canonical document.
|
|
166
|
+
Synchronous calls reject `worker: true`.
|
|
13
167
|
|
|
14
|
-
|
|
168
|
+
### `Parser.parseAsync(input, options?)`
|
|
15
169
|
|
|
16
|
-
|
|
170
|
+
Asynchronous equivalent with progress, cancellation, and worker support.
|
|
171
|
+
Direct execution snapshots binary input windows and selected assets before the
|
|
172
|
+
first progress callback. A callback may mutate caller buffers without changing
|
|
173
|
+
the in-flight result. Worker inputs rely on the already isolated protocol copy
|
|
174
|
+
and are not copied again in the receiver.
|
|
17
175
|
|
|
18
|
-
|
|
19
|
-
- `fileType: 'circuitjson'`
|
|
20
|
-
- `kind`
|
|
21
|
-
- `sourceFormat: 'circuitjson'`
|
|
176
|
+
### `Parser.tryParse(input, options?)`
|
|
22
177
|
|
|
23
|
-
|
|
24
|
-
|
|
178
|
+
Returns either `{ ok: true, value }` or
|
|
179
|
+
`{ ok: false, error, diagnostics }` instead of throwing a public parse failure.
|
|
25
180
|
|
|
26
|
-
### `
|
|
181
|
+
### `Parser.supports(input)`
|
|
27
182
|
|
|
28
|
-
|
|
183
|
+
Performs bounded format detection and returns a boolean.
|
|
29
184
|
|
|
30
|
-
|
|
185
|
+
The parser subpath additionally exports `ParserWorkerClient`,
|
|
186
|
+
`ToolkitWorkerProtocol`, and the `TOOLKIT_WORKER_PROTOCOL` version constant for
|
|
187
|
+
hosts that own a custom worker lifecycle.
|
|
31
188
|
|
|
32
|
-
### `
|
|
189
|
+
### `ToolkitAsset.measure(asset)`
|
|
33
190
|
|
|
34
|
-
Returns
|
|
35
|
-
|
|
191
|
+
Returns the exact resident payload byte length without copying. Binary lengths
|
|
192
|
+
come from intrinsic platform slots and text uses a non-allocating UTF-8 scan.
|
|
36
193
|
|
|
37
|
-
### `
|
|
194
|
+
### `ToolkitAsset.prepare(asset, options?)`
|
|
38
195
|
|
|
39
|
-
|
|
40
|
-
|
|
196
|
+
Accepts `mode: 'none' | 'metadata' | 'full'`. `none` validates and measures but
|
|
197
|
+
returns `null`; `metadata` returns canonical metadata with `data: null` and
|
|
198
|
+
makes no payload copy; `full` creates exactly one protected payload snapshot.
|
|
199
|
+
The optional `acceptPayload(byteLength, identity)` callback runs before payload
|
|
200
|
+
allocation. Accessors, custom prototypes, and hidden fields are rejected
|
|
201
|
+
without executing accessors. When `mediaType` is omitted, standard ECAD model,
|
|
202
|
+
image, JSON, PDF, and ZIP suffixes are inferred from `name`; an explicit
|
|
203
|
+
`mediaType` always wins. WRL and VRML resolve to `model/vrml`, while STEP and
|
|
204
|
+
STP resolve to `model/step`.
|
|
41
205
|
|
|
42
|
-
### `
|
|
206
|
+
### `ToolkitAsset.prepareAll(assets, options?)`
|
|
43
207
|
|
|
44
|
-
|
|
208
|
+
Applies the same contract to an exact dense asset array. Privately branded
|
|
209
|
+
prepared assets are idempotent, so parser/project/result boundaries do not
|
|
210
|
+
copy a full payload again.
|
|
45
211
|
|
|
46
|
-
### `
|
|
212
|
+
### `ParserWorkerClient` instance attempts
|
|
47
213
|
|
|
48
|
-
|
|
214
|
+
`client.parseAttempt(input, options?)` and
|
|
215
|
+
`client.loadProjectAttempt(entries, options?)` return `{ ok: true, value }` on
|
|
216
|
+
success or `{ ok: false, error, unavailable }` on failure. `unavailable` is true
|
|
217
|
+
only when that exact request's locally injected worker factory or construction
|
|
218
|
+
boundary fails. The authorization is consumed by that result and cannot be
|
|
219
|
+
replayed by throwing the returned error from another request.
|
|
49
220
|
|
|
50
|
-
|
|
221
|
+
Source toolkits can use these methods to implement `worker: 'auto'` without
|
|
222
|
+
hiding failures: fall back to direct execution only for `unavailable: true`;
|
|
223
|
+
input validation, post-message, remote parser, protocol, cancellation, queue,
|
|
224
|
+
disposed-client, and worker runtime failures all return `unavailable: false`.
|
|
51
225
|
|
|
52
|
-
|
|
53
|
-
array.
|
|
226
|
+
## Projects
|
|
54
227
|
|
|
55
|
-
|
|
228
|
+
Import from the root or `circuitjson-toolkit/project`.
|
|
56
229
|
|
|
57
|
-
### `
|
|
230
|
+
### `ProjectLoader.load(entries, options?)`
|
|
58
231
|
|
|
59
|
-
|
|
232
|
+
Synchronously loads a bounded dense array of `{ name, data, assets? }` entries
|
|
233
|
+
and returns an `ecad-toolkit.project.v1` envelope. Unsupported entries are
|
|
234
|
+
classified consistently; archive limits and duplicate paths are validated
|
|
235
|
+
before parsing.
|
|
60
236
|
|
|
61
|
-
|
|
237
|
+
Attached `entry.assets` payload bytes are included in `maxEntryBytes` and
|
|
238
|
+
`maxTotalBytes` before parsing in every decode mode. Direct and worker paths use
|
|
239
|
+
the same `ToolkitAsset` preparation and accounting pass.
|
|
62
240
|
|
|
63
|
-
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
241
|
+
The loader captures one bounded, known-field snapshot before callbacks, host
|
|
242
|
+
yields, or worker dispatch. `maxEntries` is enforced from the array length
|
|
243
|
+
before any entry record is inspected. Later caller mutation cannot change
|
|
244
|
+
classification, accounting, or direct/worker behavior, and unknown hidden or
|
|
245
|
+
symbol entry fields are ignored consistently.
|
|
68
246
|
|
|
69
|
-
|
|
70
|
-
component, source net, and source port identifiers.
|
|
247
|
+
### `ProjectLoader.loadAsync(entries, options?)`
|
|
71
248
|
|
|
72
|
-
|
|
249
|
+
Asynchronous equivalent with common progress, cancellation, and worker
|
|
250
|
+
behavior.
|
|
73
251
|
|
|
74
|
-
### `
|
|
252
|
+
### `ProjectLoader.tryLoad(entries, options?)`
|
|
75
253
|
|
|
76
|
-
|
|
77
|
-
|
|
254
|
+
Returns a discriminated success or failure record without throwing public load
|
|
255
|
+
failures.
|
|
78
256
|
|
|
79
|
-
### `
|
|
257
|
+
### `ProjectLoader.supports(entries)`
|
|
80
258
|
|
|
81
|
-
|
|
259
|
+
Returns whether the bounded entry collection contains supported project input.
|
|
82
260
|
|
|
83
|
-
|
|
261
|
+
### `ZipArchiveInspector.inspect(data, options?)`
|
|
84
262
|
|
|
85
|
-
|
|
263
|
+
Preflights bounded ZIP central and local records before inflation, including
|
|
264
|
+
exact local/central filename agreement. Entry rows
|
|
265
|
+
include `crc32`, compressed/uncompressed sizes, `localOffset`, and
|
|
266
|
+
`payloadOffset`; fixed local metadata must exactly match the central directory,
|
|
267
|
+
while data-descriptor fields must be zero or matching.
|
|
268
|
+
`maxCompressionRatio` compares total declared uncompressed member bytes with
|
|
269
|
+
total compressed member bytes, independent of ZIP comments or container
|
|
270
|
+
padding. Empty archives use ratio zero; a nonempty declared output with zero
|
|
271
|
+
compressed bytes is rejected as an infinite ratio.
|
|
86
272
|
|
|
87
|
-
|
|
88
|
-
current preprocessor handles resistor `TC=` pairs and boolean caret operators
|
|
89
|
-
inside compatible `VALUE` expression blocks.
|
|
273
|
+
### `ZipArchiveInspector.verifyExtractedBytes(entry, data)`
|
|
90
274
|
|
|
91
|
-
|
|
275
|
+
Checks the exact extracted byte length and CRC32 against an entry returned by
|
|
276
|
+
`inspect()`. It returns `true` or throws `ToolkitError` with
|
|
277
|
+
`ERR_ARCHIVE_INVALID` and expected/actual integrity details.
|
|
92
278
|
|
|
93
|
-
|
|
279
|
+
## Prepared document context
|
|
94
280
|
|
|
95
|
-
|
|
96
|
-
elements.
|
|
97
|
-
- `simulationCircuitJson`: a complete CircuitJSON element set containing the
|
|
98
|
-
`simulation_experiment` element with `experiment_type:
|
|
99
|
-
'spice_transient_analysis'` followed by its graph elements.
|
|
100
|
-
- `graphSummary`: a deterministic summary of graph ids, names, point counts,
|
|
101
|
-
time bounds, and min/max values for renderer tests and UI previews.
|
|
102
|
-
- `diagnostics`: non-fatal simulation diagnostics.
|
|
281
|
+
### `CircuitJsonDocumentContext.prepare(document, options?)`
|
|
103
282
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
the `.tran` time grid when transient step and stop parameters are available.
|
|
109
|
-
Probe metadata comments may use `circuitjson_voltage_probe`,
|
|
110
|
-
`simulation_voltage_probe`, `circuitjson_current_probe`, or
|
|
111
|
-
`simulation_current_probe` markers to preserve graph ids, names, source nodes,
|
|
112
|
-
and source trace/component references.
|
|
113
|
-
External `.lib` and `.include` directives, PWL REPEAT source syntax, selected
|
|
114
|
-
PSPICE compatibility patterns, and requested `.PRINT TRAN` vectors that cannot
|
|
115
|
-
be matched to simulator output are reported as warnings for callers that need a
|
|
116
|
-
full simulator path.
|
|
117
|
-
Malformed probe metadata comments are also reported as warnings. Invalid JSON
|
|
118
|
-
uses `spice_probe_metadata_invalid_json`; parsed comments missing required
|
|
119
|
-
string fields use `spice_probe_metadata_invalid_shape`.
|
|
283
|
+
Validates once and returns an immutable request-scoped context. `options.indexes`
|
|
284
|
+
may request `elements`, `identifiers`, `relations`, `connectivity`, and
|
|
285
|
+
`spatial` indexes. The compact `identifiers` index exposes an `elementsById`
|
|
286
|
+
set without duplicating the element graph.
|
|
120
287
|
|
|
121
|
-
|
|
288
|
+
The class constructor is not a public construction path. It throws before
|
|
289
|
+
observing caller input; use `prepare()` so every context carries a
|
|
290
|
+
validation-bound authority that downstream viewers and applications can trust.
|
|
122
291
|
|
|
123
|
-
|
|
292
|
+
### `context.getIndex(name)` and `context.hasIndex(name)`
|
|
124
293
|
|
|
125
|
-
|
|
126
|
-
import {
|
|
127
|
-
CircuitJsonDocument,
|
|
128
|
-
CircuitJsonIndexer,
|
|
129
|
-
CircuitJsonParser,
|
|
130
|
-
CircuitJsonUnits,
|
|
131
|
-
SpiceCompatibilityPreprocessor,
|
|
132
|
-
SpiceSimulationService
|
|
133
|
-
} from 'circuitjson-toolkit'
|
|
134
|
-
```
|
|
294
|
+
Access a prepared index or check its presence.
|
|
135
295
|
|
|
136
|
-
|
|
296
|
+
### `context.getOrCreateDerived(namespace, key, factory)`
|
|
137
297
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
298
|
+
Creates a derived value once per context and stable namespace/key pair. This is
|
|
299
|
+
the common extension point for services that need to share expensive work.
|
|
300
|
+
|
|
301
|
+
### `context.statistics`
|
|
302
|
+
|
|
303
|
+
Returns stable validation, index-build, and derived-build counters.
|
|
304
|
+
|
|
305
|
+
## Renderers
|
|
306
|
+
|
|
307
|
+
Import from the root or `circuitjson-toolkit/renderers`. Renderer output is
|
|
308
|
+
deterministic, local, and independent of DOM APIs.
|
|
309
|
+
|
|
310
|
+
### `PcbSvgRenderer.render(document, options?)`
|
|
311
|
+
|
|
312
|
+
Returns one SVG string. Common options include `side`, selected/hidden layers,
|
|
313
|
+
hidden object categories, viewport controls, and shared style controls.
|
|
314
|
+
|
|
315
|
+
### `PcbSvgRenderer.renderLayers(document, options?)`
|
|
316
|
+
|
|
317
|
+
Returns `{ schema, items, diagnostics, statistics }`. Every item contains
|
|
318
|
+
`id`, `side`, `layerIds`, and `svg`. All layers share one primitive preparation.
|
|
319
|
+
|
|
320
|
+
### `SchematicSvgRenderer.render(document, options?)`
|
|
321
|
+
|
|
322
|
+
Returns one schematic SVG. Sheet selection and table/debug presentation use
|
|
323
|
+
the same option names across toolkits. Canonical `schematic_image` rows resolve
|
|
324
|
+
their exact `asset_id` from `document.assets`; full asset mode renders the
|
|
325
|
+
payload, while metadata-only or unresolved assets are omitted without a
|
|
326
|
+
placeholder. `schematic_sheet_symbol` renders a hierarchical child box and is
|
|
327
|
+
never treated as a selectable `schematic_sheet` page.
|
|
328
|
+
|
|
329
|
+
### `BomTableRenderer.render(document, options?)`
|
|
330
|
+
|
|
331
|
+
Returns deterministic BOM HTML from standard source-component fields. Legacy
|
|
332
|
+
prepared row input is retained only as a compatibility path.
|
|
333
|
+
|
|
334
|
+
The optional stylesheet is available at
|
|
335
|
+
`circuitjson-toolkit/styles/renderers.css`.
|
|
336
|
+
|
|
337
|
+
## PCB interaction
|
|
338
|
+
|
|
339
|
+
Import from the root or `circuitjson-toolkit/interaction`.
|
|
340
|
+
|
|
341
|
+
### `PcbInteractionIndex.create(document, options?)`
|
|
342
|
+
|
|
343
|
+
Creates a reusable exact interaction service. Common defaults are `side`,
|
|
344
|
+
`tolerance`, `hiddenLayers`, and `hiddenObjects`.
|
|
345
|
+
|
|
346
|
+
### `index.hitTest(point, options?)`
|
|
347
|
+
|
|
348
|
+
Returns ordered exact hits after spatial broad-phase filtering. Every row uses
|
|
349
|
+
the common fields `elementId`, `primitiveId`, `kind`, `side`, `layerId`,
|
|
350
|
+
`bounds`, `distance`, `componentId`, `componentKey`, `netName`, `groupIds`, and
|
|
351
|
+
`source`.
|
|
352
|
+
|
|
353
|
+
### `index.pick(point, options?)`
|
|
354
|
+
|
|
355
|
+
Returns the first exact hit or `null`.
|
|
356
|
+
|
|
357
|
+
### `index.selectBounds(bounds, options?)`
|
|
358
|
+
|
|
359
|
+
Returns the normalized selection bounds, center point, candidates, selected
|
|
360
|
+
candidate, component keys, and net names.
|
|
361
|
+
|
|
362
|
+
### `index.selectArea(bounds, options?)`
|
|
363
|
+
|
|
364
|
+
Returns the same normalized selection as `selectBounds`. `selectArea` is the
|
|
365
|
+
shared alias used by source toolkits.
|
|
366
|
+
|
|
367
|
+
### `index.selectionAt(point, options?)`
|
|
368
|
+
|
|
369
|
+
Returns point selection candidates and stable component-first/net-first
|
|
370
|
+
selection state.
|
|
371
|
+
|
|
372
|
+
### `index.snap(point, options?)`
|
|
373
|
+
|
|
374
|
+
Returns `{ snapped, point }` for the nearest prepared anchor inside tolerance.
|
|
375
|
+
|
|
376
|
+
### `index.resolveLayers()`
|
|
377
|
+
|
|
378
|
+
Returns clone-safe `{ physicalLayers, virtualLayers }`.
|
|
379
|
+
|
|
380
|
+
### `index.resolveDiagnosticFocus(diagnosticId)`
|
|
381
|
+
|
|
382
|
+
Returns `{ id, point, bounds, relatedPrimitiveIds }` or `null`.
|
|
383
|
+
|
|
384
|
+
`PcbSpatialIndex` is also exported from the interaction subpath for bounded,
|
|
385
|
+
immutable spatial record indexing.
|
|
386
|
+
|
|
387
|
+
## Queries
|
|
388
|
+
|
|
389
|
+
Import from the root or `circuitjson-toolkit/query`.
|
|
390
|
+
|
|
391
|
+
### `QueryService.create(document, options?)`
|
|
392
|
+
|
|
393
|
+
Returns a service bound to reusable element, relation, and connectivity
|
|
394
|
+
indexes.
|
|
395
|
+
|
|
396
|
+
### `service.query(request, options?)`
|
|
397
|
+
|
|
398
|
+
`request.select` is `components` or `nets`; `request.where` accepts `field`,
|
|
399
|
+
`pattern`, `match`, `flags`, and `caseSensitive`. The result is
|
|
400
|
+
`{ schema: 'ecad-toolkit.query.v1', items, diagnostics, statistics }`.
|
|
401
|
+
|
|
402
|
+
### `service.findComponents(criteria?, options?)`
|
|
403
|
+
|
|
404
|
+
Returns matching common component records.
|
|
405
|
+
|
|
406
|
+
### `service.findNets(criteria?, options?)`
|
|
407
|
+
|
|
408
|
+
Returns matching common net records.
|
|
409
|
+
|
|
410
|
+
### `service.traceConnectivity(request, options?)`
|
|
411
|
+
|
|
412
|
+
Returns ordered connectivity records from canonical source identifiers with
|
|
413
|
+
bounded traversal controls.
|
|
414
|
+
|
|
415
|
+
### `service.buildNetlist(options?)`
|
|
416
|
+
|
|
417
|
+
Returns a detached canonical query netlist.
|
|
418
|
+
|
|
419
|
+
### `service.statistics`
|
|
420
|
+
|
|
421
|
+
Reports validation, index, and netlist build counts.
|
|
422
|
+
|
|
423
|
+
## Manufacturing
|
|
424
|
+
|
|
425
|
+
Import from the root or `circuitjson-toolkit/manufacturing`.
|
|
426
|
+
|
|
427
|
+
### `ManufacturingService.inspect(document, options?)`
|
|
428
|
+
|
|
429
|
+
Returns `{ schema, placements, fabricationNotes, exports, diagnostics,
|
|
430
|
+
statistics }`.
|
|
431
|
+
|
|
432
|
+
### `ManufacturingService.listExports(document, options?)`
|
|
433
|
+
|
|
434
|
+
Returns availability rows for `fabrication-notes-json`, `pick-place-csv`, and
|
|
435
|
+
`routing-dsn`. An unavailable export remains discoverable with a reason.
|
|
436
|
+
|
|
437
|
+
### `ManufacturingService.export(document, request, options?)`
|
|
438
|
+
|
|
439
|
+
Builds a requested available export and returns
|
|
440
|
+
`{ fileName, mediaType, data: Uint8Array, diagnostics }`.
|
|
441
|
+
|
|
442
|
+
## Simulation
|
|
443
|
+
|
|
444
|
+
Import from the root or `circuitjson-toolkit/simulation`.
|
|
445
|
+
|
|
446
|
+
### `SimulationService.build(document, options?)`
|
|
447
|
+
|
|
448
|
+
Builds the common simulation description and capability status from canonical
|
|
449
|
+
simulation elements.
|
|
450
|
+
|
|
451
|
+
### `SimulationService.export(document, request, options?)`
|
|
452
|
+
|
|
453
|
+
Runs an explicitly injected engine or export adapter. No simulator, process,
|
|
454
|
+
filesystem, or network access is implicit. Unsupported analyses remain
|
|
455
|
+
discoverable and fail with `ERR_CAPABILITY_UNAVAILABLE` when invoked.
|
|
456
|
+
|
|
457
|
+
The previous `SpiceSimulationService` remains in `/extensions`.
|
|
458
|
+
|
|
459
|
+
## PCB 3D scene data
|
|
460
|
+
|
|
461
|
+
Import from the root or `circuitjson-toolkit/scene3d`.
|
|
462
|
+
|
|
463
|
+
### `PcbScene3dBuilder.build(document, options?)`
|
|
464
|
+
|
|
465
|
+
Synchronously returns a data-only `ecad-toolkit.scene3d.v1` scene in
|
|
466
|
+
millimeters, using a right-handed Z-up coordinate system. It performs no asset
|
|
467
|
+
I/O and has no Three.js dependency.
|
|
468
|
+
|
|
469
|
+
### `PcbScene3dPreparator.prepare(document, options?)`
|
|
470
|
+
|
|
471
|
+
Asynchronously builds the same canonical scene and resolves only explicitly
|
|
472
|
+
requested assets through `options.resolveAsset(request, { signal })`.
|
|
473
|
+
Prepared assets are immutable and safe to reuse. `signal` cancels outstanding
|
|
474
|
+
work; resolution and concurrency limits are bounded.
|
|
475
|
+
|
|
476
|
+
Runtime rendering belongs to `pcb-scene3d-viewer`, not this package.
|
|
477
|
+
|
|
478
|
+
## Capabilities
|
|
479
|
+
|
|
480
|
+
Import from the root or `circuitjson-toolkit/capabilities`.
|
|
481
|
+
|
|
482
|
+
### `ToolkitCapabilities.inventory()`
|
|
483
|
+
|
|
484
|
+
Returns fresh clone-safe rows in stable id order. Each row has `id`,
|
|
485
|
+
`category`, `operation`, `status`, `entrypoint`, `summary`, `reason`, `tested`,
|
|
486
|
+
and `documented`. See [capabilities.md](capabilities.md) for the full table.
|
|
487
|
+
|
|
488
|
+
## Extension API
|
|
489
|
+
|
|
490
|
+
`circuitjson-toolkit/extensions` exports exactly 37 retained noncanonical
|
|
491
|
+
1.0.17 symbols. This includes `CircuitJsonParser`, specialized CircuitJSON renderers,
|
|
492
|
+
manufacturing builders, archive utilities, selected-part export, and the SPICE
|
|
493
|
+
compatibility service. The exact migration mapping is generated from the
|
|
494
|
+
verified feature ledger in [migration.md](migration.md) and its split
|
|
495
|
+
[appendix pages](migration/root.md).
|
|
496
|
+
|
|
497
|
+
These helpers consume source-neutral CircuitJSON. Their ledger availability is
|
|
498
|
+
therefore `shared` or `derived` for every toolkit, never falsely
|
|
499
|
+
source-unavailable.
|
|
500
|
+
|
|
501
|
+
`CircuitJsonPcbSvgRenderer.renderSides(model, sides?)` is an extension-only
|
|
502
|
+
migration helper that renders several sides after one legacy primitive build.
|
|
503
|
+
|
|
504
|
+
## Testing API
|
|
505
|
+
|
|
506
|
+
`circuitjson-toolkit/testing` exports:
|
|
507
|
+
|
|
508
|
+
- `ToolkitContractFixtures`: small synthetic, source-format-specific fixtures;
|
|
509
|
+
- `ToolkitLoopbackWorker`: a real structured-clone/transfer loopback worker
|
|
510
|
+
constructor for cross-toolkit worker parity tests;
|
|
511
|
+
- `runToolkitContract(adapter)`: the packed downstream conformance harness.
|
|
512
|
+
|
|
513
|
+
A source toolkit adapter supplies its package name, parser, project loader,
|
|
514
|
+
canonical services, capability inventory, and any native source fixture. The
|
|
515
|
+
harness verifies observable parser/project shapes, direct/worker equivalence,
|
|
516
|
+
context reuse, renderers, interaction, query, manufacturing, simulation, 3D
|
|
517
|
+
scene data, errors, and capability identifiers. Optional operations are invoked
|
|
518
|
+
according to their capability row: available statuses must return the
|
|
519
|
+
canonical shape, while `unavailable` must throw
|
|
520
|
+
`ERR_CAPABILITY_UNAVAILABLE`.
|
|
521
|
+
|
|
522
|
+
## Worker module
|
|
523
|
+
|
|
524
|
+
`circuitjson-toolkit/workers/parser.worker.mjs` implements
|
|
525
|
+
`ecad-toolkit.worker.v1` for both parser and project operations. Hosts normally
|
|
526
|
+
select it through `worker: true` or `worker: 'auto'`; importing the module
|
|
527
|
+
directly is reserved for custom worker construction.
|
|
528
|
+
|
|
529
|
+
## Package export map
|
|
530
|
+
|
|
531
|
+
The complete supported subpath list is:
|
|
532
|
+
|
|
533
|
+
```text
|
|
534
|
+
circuitjson-toolkit
|
|
535
|
+
circuitjson-toolkit/parser
|
|
536
|
+
circuitjson-toolkit/project
|
|
537
|
+
circuitjson-toolkit/renderers
|
|
538
|
+
circuitjson-toolkit/interaction
|
|
539
|
+
circuitjson-toolkit/query
|
|
540
|
+
circuitjson-toolkit/manufacturing
|
|
541
|
+
circuitjson-toolkit/simulation
|
|
542
|
+
circuitjson-toolkit/scene3d
|
|
543
|
+
circuitjson-toolkit/capabilities
|
|
544
|
+
circuitjson-toolkit/extensions
|
|
545
|
+
circuitjson-toolkit/testing
|
|
546
|
+
circuitjson-toolkit/workers/parser.worker.mjs
|
|
547
|
+
circuitjson-toolkit/styles/renderers.css
|
|
143
548
|
```
|