@schemd/core 0.2.1 → 0.3.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,64 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@schemd/core` are recorded here. Dates describe actual npm publication dates; unpublished versions deliberately use `Unreleased`.
4
+
5
+ ## [0.3.1] - 07/20/2026
6
+
7
+ ### Fixed
8
+
9
+ - Orthogonal routing no longer fails diagrams whose components sit closer than twice the 12-unit clearance margin. The post-routing guard now rejects only physical body clips; escape stubs may legitimately pass through a neighbor's clearance ring, so densely packed parallel wires route as straight traces instead of throwing `Orthogonal route intersects … after routing.`
10
+ - Empty `qgate` detail rows (`parameter=""`, `phase=""`, `matrix=""`) no longer reserve blank text space: layout and renderer now agree that empty details are absent, so such gates keep the canonical shared quantum shell.
11
+ - `embedded-css` output no longer emits keyboard-focusable component and wire groups beneath its `role="img"` root, which flattened them for assistive technology while leaving unlabeled tab stops. Internal `tabindex`/ARIA semantics are now exclusive to `full` mode, and every `full`-mode root is `role="group"` regardless of which semantic hooks are enabled.
12
+
13
+ ### Changed
14
+
15
+ - `renderSchematic` skips the redundant geometry revalidation pass when the parser's route cache proves the same frozen document already validated against identical bounds, and computes the AST-serializing signature hash only when no `idPrefix` is supplied. Rendered output is byte-identical; hosts that pass `idPrefix` (such as compile endpoints) no longer pay an `O(document)` serialization per render.
16
+
17
+ ### Verified release-candidate measurements
18
+
19
+ - Compiler bundle: 90,294 B minified, 26,479 B gzip — 4,241 B below the 30,720 B gate and 33 B smaller than 0.3.0.
20
+ - Coverage: 100% statements, branches, functions, and lines across 123 tests, including new regressions for sub-clearance routing, single-track barriers, and empty quantum detail rows.
21
+ - Runtime dependencies: zero. No public API, grammar, or geometry contracts changed; no migration is required.
22
+
23
+ ## [0.3.0] - 07/19/2026
24
+
25
+ ### Added
26
+
27
+ - Exact quarter-turn component orientation through `orientation=right|down|left|up`, including rotated ports, outward normals, AABBs, text extents, obstacle routing, and four-turn identity.
28
+ - Electrical sources, native junctions/test points/connectors, power symbols, switch and protection families, amplifiers, resonators, meters, loads, expanded passive/diode/transistor variants, and side-aware IC orientation.
29
+ - Digital buffers, logic states, clocks, latches/flip-flops, mux/demux blocks, encoders, decoders, registers, counters, half/full adders, comparators, and bus primitives.
30
+ - Named and parameterized quantum gates, preparation/reset/measurement, control and swap structures, generalized controlled gates, barriers/delays, and classical result nodes.
31
+ - First-class UML structure, deployment, activity, interaction, and state-machine primitives plus synchronous, asynchronous, return, control-flow, object-flow, assembly, and delegation relations.
32
+ - Public vocabulary registries and discriminated AST contracts for every new family, signal domain, output mode, semantic hook, and UML relation.
33
+
34
+ ### Changed
35
+
36
+ - `qgate` now uses the same high-fidelity shell, typography, sizing discipline, orientation path, and semantic metadata quality as `hadamard`, while retaining optional `parameter`, `phase`, and `matrix` detail rows.
37
+ - Orthogonal routing consumes rotated component obstacles and terminates at exact rotated semantic ports.
38
+ - Repeated canonical geometry is amortized through diagram-local `<symbol>`/`<use>` reuse; unused families emit no definitions.
39
+ - The hard compiler budget is now exactly 30,720 B gzip and fails at 30,721 B.
40
+
41
+ ### Compatibility and migration
42
+
43
+ - Existing syntax without orientation remains valid; omitted orientation is byte-for-byte equivalent to `orientation=right` where compatibility is promised.
44
+ - Existing component kinds, public entry points, port aliases, `hadamard`, `cnot`, `qgate`, IC, diode/transistor, logic, and UML documents remain supported.
45
+ - New public AST members are additive. TypeScript consumers with exhaustive switches over `SchematicComponent['kind']` must add the 0.3.0 discriminants.
46
+ - See [the 0.2.x migration guide](./docs/MIGRATION-0.3.md) for exact changes.
47
+
48
+ ### Verified release-candidate measurements
49
+
50
+ - Compiler grew from 59,363 B minified / 18,181 B gzip in 0.2.1 to 90,714 B minified / 26,398 B gzip in 0.3.0. The candidate retains 4,322 B below the 30,720 B gate.
51
+ - Coverage: 100% statements, branches, functions, and lines.
52
+ - Runtime dependencies: zero.
53
+ - On Node.js 26.4.0 / Apple Silicon, the Phase 5 warm medians were 0.202 ms for the representative RC compile, 6.583 ms for 512 rotated components, and 2.982 ms for the dense 16×16 routing fixture. Their SVG outputs were 6,019 B, 279,243 B, and 44,604 B respectively.
54
+ - The repeated-symbol fixture emitted 1,353 B for one resistor and 35,463 B for 64 mixed-orientation instances: 541.429 B per additional labeled instance after the shared symbol definition. Re-run `bun run benchmark` on the release commit for machine-specific latency confirmation.
55
+
56
+ ### Known limits
57
+
58
+ - Quarter-turn orientation is intentionally rejected for rotationally symmetric UML/electrical nodes where it would have no semantic effect.
59
+ - Standards options implement documented visual subsets; this package does not claim IEEE, IEC, OpenQASM, or OMG certification.
60
+ - Text sizing remains deterministic and SSR-safe rather than font-engine exact. Hosts using materially different fonts should preserve the supplied SVG typography or allocate additional label space.
61
+
62
+ ## [0.2.1]
63
+
64
+ - Last 0.2.x release. Historical documentation remains at [the official 0.2.1 route](https://schemd.johnowolabiidogun.dev/docs/0.2.1/overview).
package/README.md CHANGED
@@ -1,70 +1,122 @@
1
1
  <p align="center">
2
- <img src="./assets/brand/schemd-logo.svg" alt="Schemd — engineering vectors" width="640" />
2
+ <img src="https://github.com/schemd/web/blob/main/src/lib/assets/brand/schemd-logo.svg" alt="Schemd — engineering vectors" width="640" />
3
3
  </p>
4
4
 
5
5
  # @schemd/core
6
6
 
7
- Write schematics and UML as text. Get accessible, deterministic SVG.
7
+ `schemd`—pronounced like “skemd” (`/skɛmd/`)—is a strict, deterministic text-to-SVG compiler for electrical, digital, quantum, and UML diagrams. It has zero runtime dependencies and does not use a DOM, Canvas, browser layout, external fonts, raster assets, or `getBBox()`.
8
8
 
9
- Schemd has no runtime dependencies, browser layout pass, or DOM requirement. It works on a server or during a build.
9
+ Version 0.3.0 requires Node.js 24 or newer. The complete compiler bundle is 90,714 B minified and 26,398 B gzip, leaving 4,322 B below the enforced 30 KiB ceiling.
10
10
 
11
11
  ## Install
12
12
 
13
13
  ```sh
14
- npm i @schemd/core # bun i @schemd/core
14
+ npm install --save-exact @schemd/core@0.3.0
15
15
  ```
16
16
 
17
- Node.js 24+ is required.
18
-
19
- ## Quick start
17
+ ## Compile
20
18
 
21
19
  ```ts
22
- import { compileSchematic, parseSchematicFence } from "@schemd/core";
20
+ import { compileSchematic, parseSchematicFence } from '@schemd/core';
23
21
 
24
22
  const fence = parseSchematicFence(
25
- 'schemd bounds="640x260" title="Sensor input"',
23
+ 'schemd bounds="760x460" title="RC low-pass filter"',
26
24
  )!;
27
25
 
28
- const { svg, document, metrics } = compileSchematic(`
29
- port:VIN "Input" at (60, 130) #blue
30
- resistor:R1 "10 k\\Omega" at (220, 130) #amber
31
- capacitor:C1 "100 nF" at (400, 130) #cyan
32
-
33
- VIN.out -> R1.in #blue [ortho]
34
- R1.out -> C1.in #amber [ortho]
35
- `, fence);
26
+ const result = compileSchematic(
27
+ `source:VIN "AC" at (90, 150) #blue [type=voltage-ac]
28
+ resistor:R1 "1 k\\Omega" at (280, 150) #amber
29
+ junction:VOUT "V_{out}" at (470, 150) #cyan
30
+ capacitor:C1 "100 nF" at (470, 290) #cyan [orientation=down]
31
+ junction:RETURN "return" at (470, 380) #slate
32
+ ground:GND "0 V" at (650, 380) #slate
33
+
34
+ VIN.positive -> R1.in #blue [line]
35
+ R1.out -> VOUT.node #amber [line]
36
+ VOUT.node -> C1.in #cyan [ortho]
37
+ C1.out -> RETURN.node #slate [line]
38
+ VIN.negative -> RETURN.node #slate [ortho]
39
+ RETURN.node -> GND.in #slate [line]`,
40
+ { ...fence, mode: 'full', semanticHooks: ['nodes', 'ports', 'wires'] },
41
+ );
42
+
43
+ console.log(result.svg, result.metrics);
36
44
  ```
37
45
 
38
- The DSL is intentionally small:
46
+ Declarations and connections are line-oriented:
39
47
 
40
48
  ```text
41
49
  kind:ID "label" at (x, y) color [options]
42
- ID.port -> ID.port color [line|bezier|ortho]
50
+ SOURCE.port -> TARGET.port color [line|bezier|ortho options]
43
51
  ```
44
52
 
45
- It includes electrical parts, analog devices, logic and quantum gates, configurable ICs, math labels, collision-aware routing, and wire bridges.
53
+ Invalid component variants, duplicate options, unsupported rotations, bad ports, incompatible bus widths, unsafe colors, malformed markup, and out-of-bounds geometry fail with stable diagnostics before SVG emission.
54
+
55
+ ## Component inventory
56
+
57
+ - Electrical: passives, diode and transistor families, ports, grounds, sources, junctions, test points, connectors, power symbols, switches, protection, amplifiers, resonators, meters, loads, and arbitrary side-pinned ICs.
58
+ - Digital: IEEE/ANSI- or IEC-style gates, buffers, logic states, clocks, latches and flip-flops, mux/demux blocks, encoders, decoders, registers, counters, adders, comparators, and bus taps/splitters/joiners.
59
+ - Quantum: Hadamard, polished general `qgate`, named single-qubit gates, measurement, reset, preparation, controls, swaps, controlled operators, barriers, delays, and classical bit/register nodes.
60
+ - UML: structural, component/deployment, activity, sequence/interaction, and state-machine nodes with first-class relation semantics.
46
61
 
47
- UML nodes and relations use the same syntax:
62
+ The exhaustive variants and stable port names are in the [component reference](./docs/COMPONENTS.md). Grammar/options, quarter-turn behavior, conventions, output modes, and migration details are documented separately:
63
+
64
+ - [Grammar and options](./docs/GRAMMAR.md)
65
+ - [Orientation and geometry](./docs/ORIENTATION.md)
66
+ - [Standards and conventions](./docs/STANDARDS.md)
67
+ - [SVG output modes](./docs/OUTPUT-MODES.md)
68
+ - [Performance and size](./docs/PERFORMANCE.md)
69
+ - [Migration from 0.2.x](./docs/MIGRATION-0.3.md)
70
+
71
+ ## Digital example
48
72
 
49
73
  ```text
50
- class:User "User" at (160, 120) #slate [attributes="- id: UUID" operations="+ save(): void"]
51
- class:Admin "Admin" at (460, 120) #blue
74
+ port:DIN "D[7:0]" at (80, 130) #blue [width=8]
75
+ register:REG "Q[7:0]" at (390, 130) #purple [width=8]
76
+ clock:CLK "CLK" at (390, 300) #amber
77
+ port:OUT "Q[7:0]" at (720, 130) #emerald [width=8 orientation=left]
78
+
79
+ DIN.out -> REG.in #blue [digital width=8]
80
+ CLK.out -> REG.clock #amber [digital ortho]
81
+ REG.out -> OUT.in #emerald [digital width=8]
82
+ ```
52
83
 
53
- Admin.left -> User.right #blue [ortho generalization]
84
+ ## Quantum example
85
+
86
+ `qgate` uses the same calibrated shell, centered operator typography, port geometry, upright labels, and semantic hooks as `hadamard`; optional parameter, phase, and matrix rows expand it deterministically.
87
+
88
+ ```text
89
+ prepare:Q0 "|0\\rangle" at (80, 150) #blue
90
+ hadamard:H "H" at (260, 150) #cyan
91
+ qgate:U "U" at (480, 150) #purple [parameter="\\theta" phase="\\pi/2" matrix="[[a,b],[c,d]]"]
92
+ measure:M "M" at (720, 150) #emerald
93
+
94
+ Q0.out -> H.in #blue [quantum]
95
+ H.out -> U.in #cyan [quantum]
96
+ U.out -> M.in #purple [quantum]
54
97
  ```
55
98
 
56
- Class, actor, use-case, state, lifeline, note, package, initial, and final nodes are built in. Relations include association, dependency, generalization, realization, aggregation, composition, message, transition, include, and extend.
99
+ ## UML example
57
100
 
58
- Use `mode: "embedded-css"` for built-in styling or `mode: "full"` for interaction metadata. The default output stays compact and static.
101
+ ```text
102
+ device:EDGE "Edge device" at (170, 140) #blue [width=180 height=100]
103
+ artifact:FW "firmware.bin" at (480, 140) #amber [width=170 height=90]
104
+ action:DEPLOY "Deploy" at (480, 340) #cyan [width=150 height=70]
105
+
106
+ EDGE.right -> FW.left #blue [assembly]
107
+ DEPLOY.top -> FW.bottom #cyan [control-flow]
108
+ ```
59
109
 
60
- On a colored surface, set `--schematic-surface` to that background color so hollow UML markers and connector-label halos match it.
110
+ ## Output modes
61
111
 
62
- Markdown belongs at the host boundary. Detect `schemd` fences in your server-side Markdown renderer and pass their text to `compileSchematic`; core does not ship or require a Markdown parser.
112
+ - `default`: compact, accessible, static SVG.
113
+ - `embedded-css`: the same geometry plus isolated built-in styles and state classes.
114
+ - `full`: node, port, wire, source-line, and topology metadata for delegated interaction.
63
115
 
64
- ## Roadmap
116
+ All modes are deterministic and use diagram-local IDs. Hosts should use a unique `idPrefix` when more than one generated SVG can share a document.
65
117
 
66
- **Now: topology and routing** → **Next: visual precision** → **Later: language and footprint**
118
+ ## Compatibility
67
119
 
68
- Known limits and contributor-sized work live in the [active roadmap](./ROADMAP.md). Pick an item, open its claim link, and agree on the approach before starting a large change. Completed items are removed after merge.
120
+ Omitting `orientation` is byte-identical to the explicit legacy default `orientation=right`. Existing 0.2.x declarations, port aliases, UML stereotypes, output modes, and compiler entry points continue to work. New AST members are additive; consumers with exhaustive component-kind switches must handle the new discriminants.
69
121
 
70
- [Documentation](https://johnowolabiidogun.dev/tools/schemd/docs/overview) · [Roadmap](./ROADMAP.md) · [Issues](https://github.com/Sirneij/schemd/issues) · [MIT](https://github.com/Sirneij/schemd/blob/main/LICENSE)
122
+ [Official versioned documentation](https://schemd.johnowolabiidogun.dev/docs/0.3.0/overview) · [Changelog](./CHANGELOG.md) · [Roadmap](./ROADMAP.md) · [Issues](https://github.com/schemd/core/issues) · [MIT](./LICENSE)
@@ -6,11 +6,50 @@ export interface SchematicCompilationMetrics {
6
6
  readonly connections: number;
7
7
  readonly svgBytes: number;
8
8
  }
9
+ /** One component's declaration site, keyed by its document-unique id. */
10
+ export interface SchematicNodeSource {
11
+ /** Document-unique component identifier (matches `data-node-id`). */
12
+ readonly id: string;
13
+ /** One-based source line that declared the component. */
14
+ readonly line: number;
15
+ }
16
+ /** One connection's declaration site, keyed by its endpoint pair. */
17
+ export interface SchematicWireSource {
18
+ /** Source endpoint `id.port` (matches `data-wire-source`). */
19
+ readonly source: string;
20
+ /** Target endpoint `id.port` (matches `data-wire-target`). */
21
+ readonly target: string;
22
+ /** One-based source line that declared the connection. */
23
+ readonly line: number;
24
+ }
25
+ /**
26
+ * A JSON-serializable map from rendered vectors back to their source lines.
27
+ *
28
+ * Both arrays are in source order, so a host can build whichever lookup it
29
+ * needs (line → vector, or vector → line) without re-parsing the DSL. In
30
+ * `full`-mode SVG the same lines are also emitted as `data-source-line`
31
+ * attributes on each node and wire group.
32
+ */
33
+ export interface SchematicSourceMap {
34
+ readonly nodes: readonly SchematicNodeSource[];
35
+ readonly wires: readonly SchematicWireSource[];
36
+ }
9
37
  /** Validated AST, rendered SVG, and useful host-side counters. */
10
38
  export interface SchematicCompilation {
11
39
  readonly document: SchematicDocument;
12
40
  readonly svg: string;
13
41
  readonly metrics: SchematicCompilationMetrics;
42
+ readonly sourceMap: SchematicSourceMap;
14
43
  }
44
+ /**
45
+ * Derive the source map from an already-parsed document.
46
+ *
47
+ * Runs in one linear pass with no parsing, so hosts holding a document (for
48
+ * example after {@link renderSchematic}) can obtain declaration lines cheaply.
49
+ *
50
+ * @param document - Immutable document returned by the parser.
51
+ * @returns Source-ordered node and wire declaration sites.
52
+ */
53
+ export declare function schematicSourceMap(document: SchematicDocument): SchematicSourceMap;
15
54
  /** Parse and render a schematic with one stable public call. */
16
55
  export declare function compileSchematic(source: string, options: CompileSchematicOptions): SchematicCompilation;
package/dist/compiler.js CHANGED
@@ -1,6 +1,21 @@
1
1
  import { utf8ByteLength } from './limits.js';
2
2
  import { parseSchematic } from './parser.js';
3
3
  import { renderSchematic } from './renderer.js';
4
+ export function schematicSourceMap(document) {
5
+ const nodes = [];
6
+ for (const component of document.components) {
7
+ nodes.push({ id: component.id, line: component.line });
8
+ }
9
+ const wires = [];
10
+ for (const connection of document.connections) {
11
+ wires.push({
12
+ source: `${connection.from.componentId}.${connection.from.port}`,
13
+ target: `${connection.to.componentId}.${connection.to.port}`,
14
+ line: connection.line
15
+ });
16
+ }
17
+ return { nodes, wires };
18
+ }
4
19
  export function compileSchematic(source, options) {
5
20
  const document = parseSchematic(source, options);
6
21
  const svg = renderSchematic(document, options);
@@ -12,6 +27,7 @@ export function compileSchematic(source, options) {
12
27
  components: document.components.length,
13
28
  connections: document.connections.length,
14
29
  svgBytes: utf8ByteLength(svg)
15
- }
30
+ },
31
+ sourceMap: schematicSourceMap(document)
16
32
  };
17
33
  }
package/dist/index.d.ts CHANGED
@@ -7,8 +7,8 @@
7
7
  */
8
8
  export { parseSchematic, parseSchematicColor, parseSchematicFence } from './parser.js';
9
9
  export { renderSchematic } from './renderer.js';
10
- export { compileSchematic, type SchematicCompilation, type SchematicCompilationMetrics } from './compiler.js';
10
+ export { compileSchematic, schematicSourceMap, type SchematicCompilation, type SchematicCompilationMetrics, type SchematicSourceMap, type SchematicNodeSource, type SchematicWireSource } from './compiler.js';
11
11
  export { mathLabelGlyphLength, mathLabelTextWidth, mathLabelText, parseMathLabel, renderMathLabelTspans, type MathLabelSegment, type MathLabelSegmentKind } from './math-label.js';
12
12
  export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_WIRE_CROSSINGS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
13
- export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, resolvePortGeometry, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry, type RoutedConnection, type ComponentTextAnchors, type ComponentPort, type IcPinSide, type SchematicRectangle } from './layout.js';
14
- export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SCHEMD_SEMANTIC_HOOKS, SchematicSyntaxError, type AnalogKind, type CompileSchematicOptions, type ClassicalGateComponent, type ClassicalGateKind, type ComponentKind, type DiodeComponent, type DiodeType, type GroundComponent, type GroundStyle, type IcComponent, type IntegratedCircuitComponent, type IntegratedCircuitPins, type PassiveComponent, type PassiveKind, type PortComponent, type SemanticColor, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicColor, type SchematicDocument, type SchematicEndpoint, type SchematicFence, type SchematicSignalMarker, type SchematicSemanticHook, type SchematicPoint, type SchemdOutputMode, type TransistorComponent, type TransistorType, type QuantumGateComponent, type QuantumGateKind, type SchematicRelationKind, type UmlActorComponent, type UmlClassComponent, type UmlComponent, type UmlComponentKind, type UmlPseudostateComponent, type UmlRelationKind, type UmlSizedComponent, type UmlStateComponent } from './types.js';
13
+ export { classicalGateHeight, composeQuarterTurns, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, quantumGateDimensions, orientationQuarterTurn, inverseQuarterTurn, resolvePortPoint, resolvePortGeometry, rotateQuarterExtents, rotateQuarterPoint, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry, type RoutedConnection, type ComponentTextAnchors, type ComponentPort, type IcPinSide, type SchematicHalfExtents, type SchematicRectangle } from './layout.js';
14
+ export { ANALOG_KINDS, ADDER_TYPES, AMPLIFIER_TYPES, BUFFER_TYPES, BUS_TYPES, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIGITAL_COMPONENT_KINDS, DIODE_TYPES, ELECTRICAL_COMPONENT_KINDS, FLIPFLOP_TYPES, GROUND_STYLES, LOAD_TYPES, LOGIC_STATES, METER_TYPES, MUX_TYPES, NAMED_QUANTUM_GATE_KINDS, PASSIVE_KINDS, PASSIVE_TYPES, POWER_TYPES, PROTECTION_TYPES, QUANTUM_GATE_KINDS, QUANTUM_SPECIAL_KINDS, RESONATOR_TYPES, SCHEMATIC_ORIENTATIONS, SCHEMATIC_SIGNAL_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, SOURCE_TYPES, SWITCH_TYPES, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SCHEMD_SEMANTIC_HOOKS, SchematicSyntaxError, type AnalogKind, type AdderType, type AmplifierType, type BufferType, type BusType, type CompileSchematicOptions, type ClassicalGateComponent, type ClassicalGateKind, type DigitalComponent, type DigitalComponentKind, type ElectricalComponent, type ElectricalComponentKind, type ElectricalVariant, type ComponentKind, type DiodeComponent, type DirectionalComponentBase, type DiodeType, type GroundComponent, type GroundStyle, type FlipFlopType, type IcComponent, type IntegratedCircuitComponent, type IntegratedCircuitPins, type PassiveComponent, type PassiveKind, type PassiveType, type LoadType, type LogicState, type MeterType, type MuxType, type PowerType, type ProtectionType, type PortComponent, type SemanticColor, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicColor, type SchematicDocument, type SchematicEndpoint, type SchematicFence, type SchematicOrientation, type SchematicSignalMarker, type SchematicSemanticHook, type SchematicPoint, type SchematicQuarterTurn, type SchemdOutputMode, type TransistorComponent, type TransistorType, type QuantumGateComponent, type QuantumGateKind, type QuantumSpecialComponent, type QuantumSpecialKind, type NamedQuantumGateKind, type ResonatorType, type SchematicSignalKind, type SourceType, type SwitchType, type SchematicRelationKind, type UmlActorComponent, type UmlClassComponent, type UmlComponent, type UmlComponentKind, type UmlPseudostateComponent, type UmlRelationKind, type UmlSizedComponent, type UmlStateComponent } from './types.js';
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  export { parseSchematic, parseSchematicColor, parseSchematicFence } from './parser.js';
2
2
  export { renderSchematic } from './renderer.js';
3
- export { compileSchematic } from './compiler.js';
3
+ export { compileSchematic, schematicSourceMap } from './compiler.js';
4
4
  export { mathLabelGlyphLength, mathLabelTextWidth, mathLabelText, parseMathLabel, renderMathLabelTspans } from './math-label.js';
5
5
  export { MAX_SCHEMATIC_COMPONENTS, MAX_SCHEMATIC_CONNECTIONS, MAX_SCHEMATIC_WIRE_CROSSINGS, MAX_SCHEMATIC_SOURCE_CHARACTERS, MAX_SCHEMATIC_SVG_OUTPUT_BYTES, SCHEMATIC_LIMITS } from './limits.js';
6
- export { classicalGateHeight, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, resolvePortPoint, resolvePortGeometry, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry } from './layout.js';
7
- export { ANALOG_KINDS, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIODE_TYPES, GROUND_STYLES, PASSIVE_KINDS, QUANTUM_GATE_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SCHEMD_SEMANTIC_HOOKS, SchematicSyntaxError } from './types.js';
6
+ export { classicalGateHeight, composeQuarterTurns, componentObstacleRectangle, componentRectangle, componentTextAnchors, distributedCoordinate, enumerateComponentPorts, positionIcPin, PORT_HOTSPOT_RADIUS, quantumGateDimensions, orientationQuarterTurn, inverseQuarterTurn, resolvePortPoint, resolvePortGeometry, rotateQuarterExtents, rotateQuarterPoint, routeConnections, routeConnection, SCHEMATIC_BRIDGE_RADIUS, SCHEMATIC_OBSTACLE_CLEARANCE, validateDocumentGeometry } from './layout.js';
7
+ export { ANALOG_KINDS, ADDER_TYPES, AMPLIFIER_TYPES, BUFFER_TYPES, BUS_TYPES, COMPONENT_KINDS, CLASSICAL_GATE_KINDS, DIGITAL_COMPONENT_KINDS, DIODE_TYPES, ELECTRICAL_COMPONENT_KINDS, FLIPFLOP_TYPES, GROUND_STYLES, LOAD_TYPES, LOGIC_STATES, METER_TYPES, MUX_TYPES, NAMED_QUANTUM_GATE_KINDS, PASSIVE_KINDS, PASSIVE_TYPES, POWER_TYPES, PROTECTION_TYPES, QUANTUM_GATE_KINDS, QUANTUM_SPECIAL_KINDS, RESONATOR_TYPES, SCHEMATIC_ORIENTATIONS, SCHEMATIC_SIGNAL_KINDS, SCHEMATIC_SIGNAL_MARKERS, SEMANTIC_COLORS, SOURCE_TYPES, SWITCH_TYPES, TRANSISTOR_TYPES, UML_COMPONENT_KINDS, UML_RELATION_KINDS, SCHEMD_OUTPUT_MODES, SCHEMD_SEMANTIC_HOOKS, SchematicSyntaxError } from './types.js';
package/dist/layout.d.ts CHANGED
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * @packageDocumentation
10
10
  */
11
- import { type ClassicalGateComponent, type IntegratedCircuitComponent, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicDocument, type SchematicFence, type SchematicPoint } from './types.js';
11
+ import { type ClassicalGateComponent, type IntegratedCircuitComponent, type QuantumGateComponent, type SchematicBounds, type SchematicComponent, type SchematicConnection, type SchematicDocument, type SchematicFence, type SchematicOrientation, type SchematicPoint, type SchematicQuarterTurn } from './types.js';
12
12
  /** Axis-aligned rectangle expressed in absolute schematic coordinates. */
13
13
  export interface SchematicRectangle {
14
14
  /** Inclusive left extent. */
@@ -20,6 +20,13 @@ export interface SchematicRectangle {
20
20
  /** Inclusive bottom extent. */
21
21
  maxY: number;
22
22
  }
23
+ /** Axis-aligned half-extents around a component origin. */
24
+ export interface SchematicHalfExtents {
25
+ /** Non-negative horizontal distance from the origin to either side. */
26
+ halfWidth: number;
27
+ /** Non-negative vertical distance from the origin to either side. */
28
+ halfHeight: number;
29
+ }
23
30
  /** Render-ready connection path and the points used for bounds validation. */
24
31
  export interface RoutedConnection {
25
32
  /** Original routing strategy; crossing passes must never infer it from control points. */
@@ -57,6 +64,40 @@ export declare const PORT_HOTSPOT_RADIUS = 4;
57
64
  export declare const SCHEMATIC_OBSTACLE_CLEARANCE = 12;
58
65
  /** Radius of the engineering crossover arc inserted at non-junction wire crossings. */
59
66
  export declare const SCHEMATIC_BRIDGE_RADIUS = 5;
67
+ /**
68
+ * Normalize the public direction vocabulary to a compact clockwise quarter turn.
69
+ *
70
+ * @param orientation - Validated author-facing orientation.
71
+ * @returns Zero for right, one for down, two for left, or three for up.
72
+ */
73
+ export declare function orientationQuarterTurn(orientation: SchematicOrientation): SchematicQuarterTurn;
74
+ /**
75
+ * Compose two clockwise quarter turns without floating-point angle arithmetic.
76
+ *
77
+ * @param first - Turn applied first.
78
+ * @param second - Turn applied second.
79
+ * @returns Canonical combined turn modulo four.
80
+ */
81
+ export declare function composeQuarterTurns(first: SchematicQuarterTurn, second: SchematicQuarterTurn): SchematicQuarterTurn;
82
+ /** Return the exact quarter turn that reverses the supplied rotation. */
83
+ export declare function inverseQuarterTurn(turn: SchematicQuarterTurn): SchematicQuarterTurn;
84
+ /**
85
+ * Rotate a local point or unit vector clockwise around the origin using only
86
+ * coordinate swaps and sign changes.
87
+ *
88
+ * @param point - Local coordinate or vector.
89
+ * @param turn - Clockwise quarter-turn count.
90
+ * @returns Newly allocated exact coordinate with no negative zero.
91
+ */
92
+ export declare function rotateQuarterPoint(point: SchematicPoint, turn: SchematicQuarterTurn): SchematicPoint;
93
+ /**
94
+ * Rotate axis-aligned half-extents; odd turns swap axes and even turns retain them.
95
+ *
96
+ * @param extents - Canonical unrotated component half-extents.
97
+ * @param turn - Clockwise quarter-turn count.
98
+ * @returns Exact axis-aligned extents of the rotated component.
99
+ */
100
+ export declare function rotateQuarterExtents(extents: SchematicHalfExtents, turn: SchematicQuarterTurn): SchematicHalfExtents;
60
101
  /**
61
102
  * Evenly distribute a terminal within a centered span while preserving edge clearance.
62
103
  *
@@ -66,6 +107,18 @@ export declare const SCHEMATIC_BRIDGE_RADIUS = 5;
66
107
  * @returns Relative coordinate between negative and positive half-span.
67
108
  */
68
109
  export declare function distributedCoordinate(index: number, count: number, span: number): number;
110
+ /** Total centered height of a quantum glyph carrying `tracks` qubit lines. */
111
+ export declare function quantumTrackSpan(tracks: number): number;
112
+ /**
113
+ * Vertical offset of quantum track `index` within a `tracks`-line glyph.
114
+ *
115
+ * Unlike {@link distributedCoordinate}, tracks are spread *edge-to-edge* so the
116
+ * outermost rails land exactly at ±span/2 — where the connecting bar and body
117
+ * extent terminate. That keeps control dots, targets, and swap crosses on rails
118
+ * a full pitch apart instead of collapsing a two-qubit swap into an overlapped
119
+ * star. Renderer and port geometry both call this, so marks and wires align.
120
+ */
121
+ export declare function quantumTrackCoordinate(index: number, tracks: number): number;
69
122
  /**
70
123
  * Compute a classical gate height that scales with its busiest terminal side.
71
124
  *
@@ -73,6 +126,12 @@ export declare function distributedCoordinate(index: number, count: number, span
73
126
  * @returns Height in viewBox units, never smaller than 48.
74
127
  */
75
128
  export declare function classicalGateHeight(component: ClassicalGateComponent): number;
129
+ /** Deterministic shared shell dimensions for native and custom single-qubit gates. */
130
+ export declare function quantumGateDimensions(component: QuantumGateComponent): {
131
+ bodyWidth: number;
132
+ bodyHeight: number;
133
+ stubExtent: number;
134
+ };
76
135
  /**
77
136
  * Position an already-indexed IC pin in O(1), without scanning any side list.
78
137
  *