altium-toolkit 1.4.17 → 1.4.19

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/docs/api.md CHANGED
@@ -619,3 +619,13 @@ Each script reads one input file and writes text, CSV, or JSON to stdout. The
619
619
  corpus smoke script reads a caller-provided directory and can include aggregate
620
620
  parser coverage and field-gap counters. The scripts are examples of library
621
621
  usage, not installed package binaries.
622
+
623
+ ## Loaded queries and retained native models
624
+
625
+ `LoadedDesignNetlistService` also accepts canonical document envelopes whose
626
+ explicit `extensions.altium.native` field retains the normalized source model.
627
+ The library resolves that model before design discovery, component/net queries,
628
+ and traversal, preserving session ids and active selection. Callers do not need
629
+ to unwrap documents or add legacy properties to the canonical envelope.
630
+ Canonical documents without a retained native model should use the shared
631
+ `QueryService` from `altium-toolkit/query` instead of this native query API.
@@ -640,3 +640,13 @@ Focused machine-readable schemas are available under
640
640
  `docs/schemas/altium_toolkit/` for the normalized root plus focused project,
641
641
  netlist, SVG, PCB review, layer-stack, Draftsman, library, parser QA,
642
642
  inspection, unsupported-feature, and CI/reporting contracts.
643
+
644
+ ## Loaded net-name queries
645
+
646
+ The `LoadedDesignNetlistService` extension lists and searches declared names in
647
+ `schematic.nets` and `pcb.nets`, including named nets without component pins.
648
+ Names are trimmed, deduplicated, and sorted. Retained native document envelopes
649
+ use the same lookup. Missing net names still produce a missing-data error.
650
+
651
+ Net listing does not create schematic connectivity: `hasConnectivity`, component
652
+ pin queries, and extended-net traversal continue to use the schematic pin graph.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "altium-toolkit",
3
- "version": "1.4.17",
3
+ "version": "1.4.19",
4
4
  "description": "Altium document parsing and non-interactive rendering utilities",
5
5
  "keywords": [
6
6
  "altium",
@@ -2,6 +2,7 @@
2
2
  //
3
3
  // SPDX-License-Identifier: GPL-3.0-or-later
4
4
 
5
+ import { AltiumExtensionResolver } from '../../convergence/AltiumExtensionResolver.mjs'
5
6
  import { ComponentGrouping, MPN_MISSING_NOTE } from './ComponentGrouping.mjs'
6
7
  import { CircuitTraversal } from './CircuitTraversal.mjs'
7
8
  import { QueryNetlistBuilder } from './QueryNetlistBuilder.mjs'
@@ -95,13 +96,20 @@ export class LoadedDesignNetlistService {
95
96
  * @returns {{ nets: string[] } | { error: string }}
96
97
  */
97
98
  listNets(args = {}) {
98
- const resolved = this.#resolveDesignWithConnectivity(args.design)
99
+ const resolved = this.#resolveDesign(args.design)
99
100
  if (resolved.error) return resolved
100
101
 
102
+ const netNames = LoadedDesignNetlistService.#netNames(
103
+ resolved.entry.documentModel
104
+ )
105
+ if (!netNames.length) {
106
+ return {
107
+ error: 'No schematic connectivity is available for this loaded design.'
108
+ }
109
+ }
110
+
101
111
  return {
102
- nets: Object.keys(resolved.netlist.nets).sort((left, right) =>
103
- left.localeCompare(right)
104
- )
112
+ nets: netNames.sort((left, right) => left.localeCompare(right))
105
113
  }
106
114
  }
107
115
 
@@ -111,13 +119,22 @@ export class LoadedDesignNetlistService {
111
119
  * @returns {{ results: Record<string, string[]>, notes?: string[] } | { error: string }}
112
120
  */
113
121
  searchNets(args = {}) {
114
- const resolved = this.#resolveDesignWithConnectivity(args.design)
122
+ const resolved = this.#resolveDesign(args.design)
115
123
  if (resolved.error) return resolved
116
124
 
125
+ const netNames = LoadedDesignNetlistService.#netNames(
126
+ resolved.entry.documentModel
127
+ )
128
+ if (!netNames.length) {
129
+ return {
130
+ error: 'No schematic connectivity is available for this loaded design.'
131
+ }
132
+ }
133
+
117
134
  const parsed = RegexPattern.parse(args.pattern)
118
135
  if (parsed.error) return parsed
119
136
 
120
- const allNets = Object.keys(resolved.netlist.nets)
137
+ const allNets = netNames
121
138
  if (RegexPattern.rejectsBroadMatch(args.pattern, allNets)) {
122
139
  return {
123
140
  error: 'Pattern matches every net. Use list_nets for full net lists.'
@@ -388,6 +405,24 @@ export class LoadedDesignNetlistService {
388
405
  return response
389
406
  }
390
407
 
408
+ /**
409
+ * Lists declared net names independently of schematic pin connectivity.
410
+ * @param {object} documentModel Resolved native document model.
411
+ * @returns {string[]} Unique nonempty net names.
412
+ */
413
+ static #netNames(documentModel) {
414
+ // Listing names does not require the pin graph used for traversal.
415
+ return [
416
+ ...new Set(
417
+ [documentModel?.schematic?.nets, documentModel?.pcb?.nets]
418
+ .filter(Array.isArray)
419
+ .flatMap((nets) => nets)
420
+ .map((net) => String(net?.name || '').trim())
421
+ .filter(Boolean)
422
+ )
423
+ ]
424
+ }
425
+
391
426
  /**
392
427
  * Resolves one design and requires schematic connectivity.
393
428
  * @param {string | undefined} design Design selector.
@@ -571,7 +606,10 @@ export class LoadedDesignNetlistService {
571
606
  * @returns {object}
572
607
  */
573
608
  static #normalizeEntry(entry) {
574
- const documentModel = entry?.documentModel || entry
609
+ const sourceDocument = entry?.documentModel || entry
610
+ const documentModel =
611
+ AltiumExtensionResolver.nativeModel(sourceDocument) ||
612
+ sourceDocument
575
613
  return {
576
614
  id: String(entry?.id || documentModel?.id || ''),
577
615
  active: entry?.active === true,