@tscircuit/schematic-trace-solver 0.0.166 → 0.0.167

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/dist/index.d.ts CHANGED
@@ -141,7 +141,11 @@ interface InputDirectConnection {
141
141
  interface InputNetConnection {
142
142
  netId: string;
143
143
  pinIds: Array<PinId>;
144
- /** True when the authoritative source net is electrical ground. */
144
+ /**
145
+ * Preserve explicitly wired islands on this ground net, joining the islands
146
+ * electrically through labels instead of routing between them. Nets without
147
+ * explicit traces, or without this hint, retain automatic bus routing.
148
+ */
145
149
  isGround?: boolean;
146
150
  /**
147
151
  * User-facing text to render for this net label. `netId` remains the stable
package/dist/index.js CHANGED
@@ -369,10 +369,17 @@ var MAX_LOCAL_GROUND_BRANCH_OFFSET = 1;
369
369
  var getGroundConnectionPolicy = (inputProblem) => {
370
370
  const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem);
371
371
  const groundNetId = netConnMap.getNetConnectedToId("GND");
372
- if (!groundNetId) return () => true;
373
372
  const physicalConnMap = new ConnectivityMap2({});
373
+ const explicitlyWiredGroundNetIds = /* @__PURE__ */ new Set();
374
374
  for (const connection of inputProblem.directConnections) {
375
375
  physicalConnMap.addConnections([connection.pinIds]);
376
+ const globalNetId = netConnMap.getNetConnectedToId(connection.pinIds[0]);
377
+ const isMarkedGround = inputProblem.netConnections.some(
378
+ (net) => net.isGround && netConnMap.getNetConnectedToId(net.netId) === globalNetId
379
+ );
380
+ if (globalNetId && isMarkedGround) {
381
+ explicitlyWiredGroundNetIds.add(globalNetId);
382
+ }
376
383
  }
377
384
  const pins = new Map(
378
385
  inputProblem.chips.flatMap(
@@ -388,13 +395,28 @@ var getGroundConnectionPolicy = (inputProblem) => {
388
395
  ({ pin: b }) => a.pinId !== b.pinId && Math.abs(a.y - b.y) < 1e-6 && Math.abs(a.x - b.x) > 1e-6 && physicalConnMap.getNetConnectedToId(b.pinId) === group
389
396
  );
390
397
  });
391
- if (!hasExplicitParallelGroundRail) return () => true;
398
+ const areSeparateExplicitGroundIslands = (firstPinId, secondPinId) => {
399
+ const firstGlobalNetId = netConnMap.getNetConnectedToId(firstPinId);
400
+ const secondGlobalNetId = netConnMap.getNetConnectedToId(secondPinId);
401
+ if (!firstGlobalNetId || firstGlobalNetId !== secondGlobalNetId || !explicitlyWiredGroundNetIds.has(firstGlobalNetId)) {
402
+ return false;
403
+ }
404
+ const firstPhysicalGroup = physicalConnMap.getNetConnectedToId(firstPinId) ?? `pin:${firstPinId}`;
405
+ const secondPhysicalGroup = physicalConnMap.getNetConnectedToId(secondPinId) ?? `pin:${secondPinId}`;
406
+ return firstPhysicalGroup !== secondPhysicalGroup;
407
+ };
408
+ if (!hasExplicitParallelGroundRail) {
409
+ return (firstPinId, secondPinId) => !areSeparateExplicitGroundIslands(firstPinId, secondPinId);
410
+ }
392
411
  const isGroundFacingTerminal = (pinId) => {
393
412
  const entry = pins.get(pinId);
394
413
  return entry?.chip.pins.length === 2 && !physicalConnMap.getNetConnectedToId(pinId) && (entry.pin._facingDirection ?? getPinDirection(entry.pin, entry.chip)) === "y-";
395
414
  };
396
415
  return (firstPinId, secondPinId) => {
397
- if (!groundNetId || netConnMap.getNetConnectedToId(firstPinId) !== groundNetId || netConnMap.getNetConnectedToId(secondPinId) !== groundNetId) {
416
+ const firstGlobalNetId = netConnMap.getNetConnectedToId(firstPinId);
417
+ const secondGlobalNetId = netConnMap.getNetConnectedToId(secondPinId);
418
+ if (areSeparateExplicitGroundIslands(firstPinId, secondPinId)) return false;
419
+ if (!groundNetId || firstGlobalNetId !== groundNetId || secondGlobalNetId !== groundNetId) {
398
420
  return true;
399
421
  }
400
422
  if (!isGroundFacingTerminal(firstPinId) && !isGroundFacingTerminal(secondPinId))
@@ -11,12 +11,21 @@ const MAX_LOCAL_GROUND_BRANCH_OFFSET = 1
11
11
  export const getGroundConnectionPolicy = (inputProblem: InputProblem) => {
12
12
  const { netConnMap } = getConnectivityMapsFromInputProblem(inputProblem)
13
13
  const groundNetId = netConnMap.getNetConnectedToId("GND")
14
- if (!groundNetId) return () => true
15
14
  // Net identifiers do not constitute physical edges: two separate direct
16
15
  // connections may have the same netId without requesting a wire between them.
17
16
  const physicalConnMap = new ConnectivityMap({})
17
+ const explicitlyWiredGroundNetIds = new Set<string>()
18
18
  for (const connection of inputProblem.directConnections) {
19
19
  physicalConnMap.addConnections([connection.pinIds])
20
+ const globalNetId = netConnMap.getNetConnectedToId(connection.pinIds[0])
21
+ const isMarkedGround = inputProblem.netConnections.some(
22
+ (net) =>
23
+ net.isGround &&
24
+ netConnMap.getNetConnectedToId(net.netId) === globalNetId,
25
+ )
26
+ if (globalNetId && isMarkedGround) {
27
+ explicitlyWiredGroundNetIds.add(globalNetId)
28
+ }
20
29
  }
21
30
  const pins = new Map(
22
31
  inputProblem.chips.flatMap((chip) =>
@@ -46,7 +55,29 @@ export const getGroundConnectionPolicy = (inputProblem: InputProblem) => {
46
55
  )
47
56
  )
48
57
  })
49
- if (!hasExplicitParallelGroundRail) return () => true
58
+ const areSeparateExplicitGroundIslands = (
59
+ firstPinId: PinId,
60
+ secondPinId: PinId,
61
+ ) => {
62
+ const firstGlobalNetId = netConnMap.getNetConnectedToId(firstPinId)
63
+ const secondGlobalNetId = netConnMap.getNetConnectedToId(secondPinId)
64
+ if (
65
+ !firstGlobalNetId ||
66
+ firstGlobalNetId !== secondGlobalNetId ||
67
+ !explicitlyWiredGroundNetIds.has(firstGlobalNetId)
68
+ ) {
69
+ return false
70
+ }
71
+ const firstPhysicalGroup =
72
+ physicalConnMap.getNetConnectedToId(firstPinId) ?? `pin:${firstPinId}`
73
+ const secondPhysicalGroup =
74
+ physicalConnMap.getNetConnectedToId(secondPinId) ?? `pin:${secondPinId}`
75
+ return firstPhysicalGroup !== secondPhysicalGroup
76
+ }
77
+ if (!hasExplicitParallelGroundRail) {
78
+ return (firstPinId: PinId, secondPinId: PinId) =>
79
+ !areSeparateExplicitGroundIslands(firstPinId, secondPinId)
80
+ }
50
81
  const isGroundFacingTerminal = (pinId: PinId) => {
51
82
  const entry = pins.get(pinId)
52
83
  return (
@@ -58,10 +89,13 @@ export const getGroundConnectionPolicy = (inputProblem: InputProblem) => {
58
89
  }
59
90
 
60
91
  return (firstPinId: PinId, secondPinId: PinId): boolean => {
92
+ const firstGlobalNetId = netConnMap.getNetConnectedToId(firstPinId)
93
+ const secondGlobalNetId = netConnMap.getNetConnectedToId(secondPinId)
94
+ if (areSeparateExplicitGroundIslands(firstPinId, secondPinId)) return false
61
95
  if (
62
96
  !groundNetId ||
63
- netConnMap.getNetConnectedToId(firstPinId) !== groundNetId ||
64
- netConnMap.getNetConnectedToId(secondPinId) !== groundNetId
97
+ firstGlobalNetId !== groundNetId ||
98
+ secondGlobalNetId !== groundNetId
65
99
  ) {
66
100
  return true
67
101
  }
@@ -98,7 +98,11 @@ export interface InputNetConnection {
98
98
  netId: string
99
99
  pinIds: Array<PinId>
100
100
 
101
- /** True when the authoritative source net is electrical ground. */
101
+ /**
102
+ * Preserve explicitly wired islands on this ground net, joining the islands
103
+ * electrically through labels instead of routing between them. Nets without
104
+ * explicit traces, or without this hint, retain automatic bus routing.
105
+ */
102
106
  isGround?: boolean
103
107
 
104
108
  /**
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "url": "https://github.com/tscircuit/schematic-trace-solver.git"
6
6
  },
7
7
  "main": "dist/index.js",
8
- "version": "0.0.166",
8
+ "version": "0.0.167",
9
9
  "type": "module",
10
10
  "scripts": {
11
11
  "start": "cosmos",