circuitjson-toolkit 1.0.16 → 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/AGENTS.md +15 -0
- 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
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { CircuitJsonPcbPrimitiveBuilder } from '../CircuitJsonPcbPrimitiveBuilder.mjs'
|
|
2
|
+
import { ToolkitError } from '../contracts/ToolkitError.mjs'
|
|
3
|
+
import { PcbSpatialIndex } from './PcbSpatialIndex.mjs'
|
|
4
|
+
|
|
5
|
+
const INTERACTION_CACHE = Object.freeze({
|
|
6
|
+
namespace: 'pcb',
|
|
7
|
+
key: 'interaction-primitives-v1'
|
|
8
|
+
})
|
|
9
|
+
const COMPLETE_CACHE = Object.freeze({
|
|
10
|
+
namespace: 'render',
|
|
11
|
+
key: 'pcb-primitives-v1'
|
|
12
|
+
})
|
|
13
|
+
const SPATIAL_CACHE = Object.freeze({
|
|
14
|
+
namespace: 'interaction',
|
|
15
|
+
key: 'pcb-spatial-v2'
|
|
16
|
+
})
|
|
17
|
+
const INTERACTION_OWNERS = new WeakMap()
|
|
18
|
+
const COMPLETE_OWNERS = new WeakMap()
|
|
19
|
+
const SPATIAL_OWNERS = new WeakMap()
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Owns immutable PCB primitive preparations shared by interaction and render
|
|
23
|
+
* consumers without trusting namespace strings as type brands.
|
|
24
|
+
*/
|
|
25
|
+
export class PcbPrimitivePreparation {
|
|
26
|
+
/**
|
|
27
|
+
* Returns the immutable interaction-only primitive model for one context.
|
|
28
|
+
* @param {import('./CircuitJsonDocumentContext.mjs').CircuitJsonDocumentContext} context Prepared context.
|
|
29
|
+
* @returns {Record<string, any>} Context-owned primitive model.
|
|
30
|
+
*/
|
|
31
|
+
static prepareInteraction(context) {
|
|
32
|
+
const value = context.getOrCreateDerived(
|
|
33
|
+
INTERACTION_CACHE.namespace,
|
|
34
|
+
INTERACTION_CACHE.key,
|
|
35
|
+
() => {
|
|
36
|
+
const model = CircuitJsonPcbPrimitiveBuilder.buildInteraction(
|
|
37
|
+
context.model
|
|
38
|
+
)
|
|
39
|
+
PcbPrimitivePreparation.#freeze(model)
|
|
40
|
+
INTERACTION_OWNERS.set(model, {
|
|
41
|
+
context,
|
|
42
|
+
key: INTERACTION_CACHE
|
|
43
|
+
})
|
|
44
|
+
return model
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
return PcbPrimitivePreparation.#requireOwned(
|
|
48
|
+
context,
|
|
49
|
+
INTERACTION_CACHE,
|
|
50
|
+
INTERACTION_OWNERS,
|
|
51
|
+
value
|
|
52
|
+
)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Returns the immutable complete primitive model shared with render plans.
|
|
57
|
+
* @param {import('./CircuitJsonDocumentContext.mjs').CircuitJsonDocumentContext} context Prepared context.
|
|
58
|
+
* @returns {Record<string, any>} Context-owned complete primitive model.
|
|
59
|
+
*/
|
|
60
|
+
static prepareComplete(context) {
|
|
61
|
+
const value = context.getOrCreateDerived(
|
|
62
|
+
COMPLETE_CACHE.namespace,
|
|
63
|
+
COMPLETE_CACHE.key,
|
|
64
|
+
() => {
|
|
65
|
+
const model = CircuitJsonPcbPrimitiveBuilder.buildComplete(
|
|
66
|
+
context.model,
|
|
67
|
+
PcbPrimitivePreparation.prepareInteraction(context)
|
|
68
|
+
)
|
|
69
|
+
PcbPrimitivePreparation.#freeze(model)
|
|
70
|
+
COMPLETE_OWNERS.set(model, {
|
|
71
|
+
context,
|
|
72
|
+
key: COMPLETE_CACHE
|
|
73
|
+
})
|
|
74
|
+
return model
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
return PcbPrimitivePreparation.#requireOwned(
|
|
78
|
+
context,
|
|
79
|
+
COMPLETE_CACHE,
|
|
80
|
+
COMPLETE_OWNERS,
|
|
81
|
+
value
|
|
82
|
+
)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns the immutable spatial index bound to one exact primitive model.
|
|
87
|
+
* @param {import('./CircuitJsonDocumentContext.mjs').CircuitJsonDocumentContext} context Prepared context.
|
|
88
|
+
* @param {Record<string, any>} model Owned interaction primitive model.
|
|
89
|
+
* @param {() => object[]} recordsFactory Stable spatial-record factory.
|
|
90
|
+
* @returns {PcbSpatialIndex} Context-owned spatial index.
|
|
91
|
+
*/
|
|
92
|
+
static prepareSpatial(context, model, recordsFactory) {
|
|
93
|
+
PcbPrimitivePreparation.#requireOwned(
|
|
94
|
+
context,
|
|
95
|
+
INTERACTION_CACHE,
|
|
96
|
+
INTERACTION_OWNERS,
|
|
97
|
+
model
|
|
98
|
+
)
|
|
99
|
+
const value = context.getOrCreateDerived(
|
|
100
|
+
SPATIAL_CACHE.namespace,
|
|
101
|
+
SPATIAL_CACHE.key,
|
|
102
|
+
() => {
|
|
103
|
+
const spatial = PcbSpatialIndex.create(recordsFactory())
|
|
104
|
+
SPATIAL_OWNERS.set(spatial, {
|
|
105
|
+
context,
|
|
106
|
+
key: SPATIAL_CACHE,
|
|
107
|
+
model
|
|
108
|
+
})
|
|
109
|
+
return spatial
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
const spatial = PcbPrimitivePreparation.#requireOwned(
|
|
113
|
+
context,
|
|
114
|
+
SPATIAL_CACHE,
|
|
115
|
+
SPATIAL_OWNERS,
|
|
116
|
+
value
|
|
117
|
+
)
|
|
118
|
+
if (SPATIAL_OWNERS.get(spatial).model !== model) {
|
|
119
|
+
throw PcbPrimitivePreparation.#collisionError()
|
|
120
|
+
}
|
|
121
|
+
return spatial
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Requires both the private type brand and exact context cache ownership.
|
|
126
|
+
* @param {import('./CircuitJsonDocumentContext.mjs').CircuitJsonDocumentContext} context Prepared context.
|
|
127
|
+
* @param {{ namespace: string, key: string }} key Expected cache key.
|
|
128
|
+
* @param {WeakMap<object, object>} owners Type-specific ownership map.
|
|
129
|
+
* @param {unknown} value Cache value candidate.
|
|
130
|
+
* @returns {any} Verified value.
|
|
131
|
+
*/
|
|
132
|
+
static #requireOwned(context, key, owners, value) {
|
|
133
|
+
const owner =
|
|
134
|
+
value && typeof value === 'object' ? owners.get(value) : null
|
|
135
|
+
if (
|
|
136
|
+
owner?.context !== context ||
|
|
137
|
+
owner.key !== key ||
|
|
138
|
+
!context.ownsDerived(key.namespace, key.key, value) ||
|
|
139
|
+
!Object.isFrozen(value)
|
|
140
|
+
) {
|
|
141
|
+
throw PcbPrimitivePreparation.#collisionError()
|
|
142
|
+
}
|
|
143
|
+
return value
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Deep-freezes a cyclic plain primitive graph before caching it.
|
|
148
|
+
* @param {unknown} value Root cache value.
|
|
149
|
+
* @returns {unknown} Frozen root value.
|
|
150
|
+
*/
|
|
151
|
+
static #freeze(value) {
|
|
152
|
+
if (!value || typeof value !== 'object') return value
|
|
153
|
+
const pending = [{ value, expanded: false }]
|
|
154
|
+
const visited = new WeakSet()
|
|
155
|
+
while (pending.length) {
|
|
156
|
+
const current = pending.pop()
|
|
157
|
+
if (current.expanded) {
|
|
158
|
+
Object.freeze(current.value)
|
|
159
|
+
continue
|
|
160
|
+
}
|
|
161
|
+
if (visited.has(current.value) || Object.isFrozen(current.value)) {
|
|
162
|
+
continue
|
|
163
|
+
}
|
|
164
|
+
visited.add(current.value)
|
|
165
|
+
pending.push({ value: current.value, expanded: true })
|
|
166
|
+
for (const descriptor of Object.values(
|
|
167
|
+
Object.getOwnPropertyDescriptors(current.value)
|
|
168
|
+
)) {
|
|
169
|
+
if (
|
|
170
|
+
Object.hasOwn(descriptor, 'value') &&
|
|
171
|
+
descriptor.value &&
|
|
172
|
+
typeof descriptor.value === 'object'
|
|
173
|
+
) {
|
|
174
|
+
pending.push({
|
|
175
|
+
value: descriptor.value,
|
|
176
|
+
expanded: false
|
|
177
|
+
})
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return value
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Creates a typed cache collision or transplant error.
|
|
186
|
+
* @returns {ToolkitError} Typed interaction cache error.
|
|
187
|
+
*/
|
|
188
|
+
static #collisionError() {
|
|
189
|
+
return new ToolkitError(
|
|
190
|
+
'Prepared PCB interaction encountered a cache collision or transplant.',
|
|
191
|
+
{
|
|
192
|
+
code: 'ERR_INTERACTION_CACHE_COLLISION',
|
|
193
|
+
category: 'runtime',
|
|
194
|
+
format: 'circuitjson'
|
|
195
|
+
}
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
}
|