altium-toolkit 1.1.41 → 1.2.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 (58) hide show
  1. package/README.md +113 -19
  2. package/docs/api.md +224 -18
  3. package/docs/capabilities.md +65 -0
  4. package/docs/migration/legacy-001.md +309 -0
  5. package/docs/migration/legacy-002.md +309 -0
  6. package/docs/migration/legacy-003.md +309 -0
  7. package/docs/migration/legacy-004.md +309 -0
  8. package/docs/migration/legacy-005.md +111 -0
  9. package/docs/migration.md +20 -0
  10. package/docs/model-format.md +28 -3
  11. package/docs/release-notes-v1.2.0.md +147 -0
  12. package/docs/testing.md +43 -1
  13. package/examples/arduino-uno/PcbThreeSceneRenderer.mjs +1 -1
  14. package/examples/arduino-uno/example.mjs +1 -1
  15. package/examples/cli-utils.mjs +1 -1
  16. package/examples/corpus-smoke.mjs +1 -1
  17. package/examples/inspect-board.mjs +1 -1
  18. package/examples/library-catalog.mjs +1 -1
  19. package/examples/validate-library.mjs +1 -1
  20. package/package.json +20 -5
  21. package/spec/api-baseline-v1.1.41.json +1 -0
  22. package/spec/asset-baseline-v1.1.41.json +1 -0
  23. package/spec/feature-preservation.json +1 -0
  24. package/spec/library-scope.md +14 -4
  25. package/spec/native-source-manifest-v1.1.41.json +1 -0
  26. package/src/capabilities.mjs +4 -0
  27. package/src/convergence/AltiumCircuitJsonProjection.mjs +230 -0
  28. package/src/convergence/AltiumDocumentBuilder.mjs +167 -0
  29. package/src/convergence/AltiumExtensionResolver.mjs +98 -0
  30. package/src/convergence/AltiumProjectDocumentResolver.mjs +324 -0
  31. package/src/convergence/AltiumSchematicCoordinateProjection.mjs +130 -0
  32. package/src/convergence/AltiumWorkerClient.mjs +95 -0
  33. package/src/convergence/Parser.mjs +285 -0
  34. package/src/convergence/ParserInput.mjs +282 -0
  35. package/src/convergence/ProjectLoader.mjs +916 -0
  36. package/src/convergence/SchematicSvgRenderer.mjs +126 -0
  37. package/src/convergence/ToolkitCapabilities.mjs +49 -0
  38. package/src/core/circuit-json/CircuitJsonSchematicDocumentGraphicBuilder.mjs +785 -0
  39. package/src/core/circuit-json/CircuitJsonSchematicGraphicBuilder.mjs +909 -0
  40. package/src/core/circuit-json/CircuitJsonSchematicImageProjection.mjs +277 -0
  41. package/src/core/circuit-json/CircuitJsonSchematicStrokeStyle.mjs +47 -0
  42. package/src/extensions.mjs +11 -0
  43. package/src/index.mjs +20 -4
  44. package/src/interaction.mjs +7 -0
  45. package/src/legacy-netlist-query.mjs +11 -0
  46. package/src/legacy-parser.mjs +141 -0
  47. package/src/legacy-renderers.mjs +25 -0
  48. package/src/legacy-scene3d.mjs +10 -0
  49. package/src/manufacturing.mjs +4 -0
  50. package/src/parser.mjs +12 -138
  51. package/src/project.mjs +11 -0
  52. package/src/query.mjs +4 -0
  53. package/src/renderers.mjs +4 -22
  54. package/src/scene3d.mjs +5 -8
  55. package/src/simulation.mjs +4 -0
  56. package/src/styles/renderers.css +27 -0
  57. package/src/testing.mjs +8 -0
  58. package/src/workers/parser.worker.mjs +37 -0
@@ -0,0 +1,126 @@
1
+ // SPDX-FileCopyrightText: 2026 André Fiedler
2
+ // SPDX-License-Identifier: GPL-3.0-or-later
3
+
4
+ import { SchematicSvgRenderer as LegacySchematicSvgRenderer } from '../ui/SchematicSvgRenderer.mjs'
5
+
6
+ /**
7
+ * Renders native Altium schematic models through the preserved historical
8
+ * renderer while applying convergence-owned visibility semantics.
9
+ */
10
+ export class SchematicSvgRenderer {
11
+ static #frozenRenderDocuments = new WeakMap()
12
+
13
+ /**
14
+ * Renders one native Altium schematic document as SVG markup.
15
+ * @param {Record<string, any>} documentModel Native renderer document.
16
+ * @param {Record<string, any>} [options] Historical renderer options.
17
+ * @returns {string} Rendered SVG panel markup.
18
+ */
19
+ static render(documentModel, options = {}) {
20
+ return LegacySchematicSvgRenderer.render(
21
+ SchematicSvgRenderer.#visibilityAwareDocument(documentModel),
22
+ options
23
+ )
24
+ }
25
+
26
+ /**
27
+ * Builds a shallow render view that prevents hidden source designators from
28
+ * being synthesized as fallback labels by the historical renderer.
29
+ * @param {Record<string, any>} documentModel Native renderer document.
30
+ * @returns {Record<string, any>} Visibility-aware render document.
31
+ */
32
+ static #visibilityAwareDocument(documentModel) {
33
+ const components = documentModel?.schematic?.components
34
+ if (!Array.isArray(components)) return documentModel
35
+
36
+ const cached =
37
+ SchematicSvgRenderer.#frozenRenderDocuments.get(documentModel)
38
+ if (cached) return cached
39
+
40
+ const firstHiddenIndex = components.findIndex(
41
+ (component) => component?.schematicDesignatorVisible === false
42
+ )
43
+ const renderDocument =
44
+ firstHiddenIndex < 0
45
+ ? documentModel
46
+ : SchematicSvgRenderer.#withoutHiddenDesignators(
47
+ documentModel,
48
+ components,
49
+ firstHiddenIndex
50
+ )
51
+
52
+ if (
53
+ SchematicSvgRenderer.#hasImmutableVisibilityInputs(
54
+ documentModel,
55
+ components
56
+ )
57
+ ) {
58
+ SchematicSvgRenderer.#frozenRenderDocuments.set(
59
+ documentModel,
60
+ renderDocument
61
+ )
62
+ }
63
+ return renderDocument
64
+ }
65
+
66
+ /**
67
+ * Returns true only when every container and row that controls the
68
+ * visibility rewrite is immutable for the lifetime of a cache entry.
69
+ * @param {Record<string, any>} documentModel Native renderer document.
70
+ * @param {Record<string, any>[]} components Native schematic components.
71
+ * @returns {boolean} Whether the visibility-aware view can be cached.
72
+ */
73
+ static #hasImmutableVisibilityInputs(documentModel, components) {
74
+ if (
75
+ !Object.isFrozen(documentModel) ||
76
+ !Object.isFrozen(documentModel.schematic) ||
77
+ !Object.isFrozen(components)
78
+ ) {
79
+ return false
80
+ }
81
+ for (const component of components) {
82
+ if (
83
+ !component ||
84
+ typeof component !== 'object' ||
85
+ !Object.isFrozen(component)
86
+ ) {
87
+ return false
88
+ }
89
+ }
90
+ return true
91
+ }
92
+
93
+ /**
94
+ * Copies only the document path and component rows affected by hidden
95
+ * designator visibility, leaving every other native object shared.
96
+ * @param {Record<string, any>} documentModel Native renderer document.
97
+ * @param {Record<string, any>[]} components Native schematic components.
98
+ * @param {number} firstHiddenIndex First component requiring adaptation.
99
+ * @returns {Record<string, any>} Render-only native document view.
100
+ */
101
+ static #withoutHiddenDesignators(
102
+ documentModel,
103
+ components,
104
+ firstHiddenIndex
105
+ ) {
106
+ const renderComponents = components.slice()
107
+ for (
108
+ let index = firstHiddenIndex;
109
+ index < renderComponents.length;
110
+ index += 1
111
+ ) {
112
+ const component = renderComponents[index]
113
+ if (component?.schematicDesignatorVisible === false) {
114
+ renderComponents[index] = { ...component, designator: '' }
115
+ }
116
+ }
117
+
118
+ return {
119
+ ...documentModel,
120
+ schematic: {
121
+ ...documentModel.schematic,
122
+ components: renderComponents
123
+ }
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,49 @@
1
+ // SPDX-FileCopyrightText: 2026 André Fiedler
2
+ // SPDX-License-Identifier: GPL-3.0-or-later
3
+
4
+ import { ToolkitCapabilities as SharedCapabilities } from 'circuitjson-toolkit'
5
+
6
+ const NATIVE = new Map([
7
+ [
8
+ 'export.selected-part',
9
+ 'Export selected Altium parts through the retained native adapters.'
10
+ ],
11
+ ['parse.document', 'Parse native Altium documents into CircuitJSON.'],
12
+ ['project.load', 'Load native Altium project entries.'],
13
+ [
14
+ 'worker.load-project',
15
+ 'Load Altium projects through the shared protocol.'
16
+ ],
17
+ ['worker.parse', 'Parse Altium documents through the shared protocol.']
18
+ ])
19
+
20
+ /**
21
+ * Reports common and Altium-native capability availability.
22
+ */
23
+ export class ToolkitCapabilities {
24
+ /**
25
+ * Returns fresh clone-safe capability rows in stable id order.
26
+ * @returns {Record<string, any>[]} Capability inventory.
27
+ */
28
+ static inventory() {
29
+ return SharedCapabilities.inventory().map((row) => {
30
+ const summary = NATIVE.get(row.id)
31
+ if (!summary) return { ...row }
32
+ return {
33
+ ...row,
34
+ status: 'native',
35
+ entrypoint:
36
+ row.id === 'export.selected-part'
37
+ ? 'altium-toolkit/extensions'
38
+ : row.id.startsWith('worker.')
39
+ ? 'altium-toolkit/workers/parser.worker.mjs'
40
+ : row.entrypoint,
41
+ summary,
42
+ reason: summary
43
+ }
44
+ })
45
+ }
46
+ }
47
+
48
+ Object.freeze(ToolkitCapabilities.prototype)
49
+ Object.freeze(ToolkitCapabilities)