@tscircuit/capacity-autorouter 0.0.38 → 0.0.40

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
@@ -503,6 +503,7 @@ type FutureConnection = {
503
503
  points: {
504
504
  x: number;
505
505
  y: number;
506
+ z: number;
506
507
  }[];
507
508
  };
508
509
  declare class SingleHighDensityRouteSolver extends BaseSolver {
@@ -619,9 +620,10 @@ declare class IntraNodeRouteSolver extends BaseSolver {
619
620
  failedSubSolvers: SingleHighDensityRouteSolver[];
620
621
  hyperParameters: Partial<HighDensityHyperParameters>;
621
622
  minDistBetweenEnteringPoints: number;
622
- activeSolver: SingleHighDensityRouteSolver | null;
623
+ activeSubSolver: SingleHighDensityRouteSolver | null;
623
624
  connMap?: ConnectivityMap;
624
625
  get failedSolvers(): SingleHighDensityRouteSolver[];
626
+ get activeSolver(): SingleHighDensityRouteSolver | null;
625
627
  constructor(params: {
626
628
  nodeWithPortPoints: NodeWithPortPoints;
627
629
  colorMap?: Record<string, string>;
package/dist/index.js CHANGED
@@ -2454,7 +2454,7 @@ var SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost = class extends Singl
2454
2454
  let closestPoint = null;
2455
2455
  for (const futureConnection of this.futureConnections) {
2456
2456
  for (const point of futureConnection.points) {
2457
- const dist = distance(node, point);
2457
+ const dist = distance(node, point) + (node.z !== point.z ? this.viaPenaltyDistance : 0);
2458
2458
  if (dist < minDist) {
2459
2459
  minDist = dist;
2460
2460
  closestPoint = point;
@@ -2568,6 +2568,9 @@ var getMinDistBetweenEnteringPoints = (node) => {
2568
2568
  const points = node.portPoints;
2569
2569
  for (let i = 0; i < points.length; i++) {
2570
2570
  for (let j = i + 1; j < points.length; j++) {
2571
+ if (points[i].z !== points[j].z) {
2572
+ continue;
2573
+ }
2571
2574
  const p1 = points[i];
2572
2575
  const p2 = points[j];
2573
2576
  const dist = Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2);
@@ -2587,12 +2590,16 @@ var IntraNodeRouteSolver = class extends BaseSolver {
2587
2590
  failedSubSolvers;
2588
2591
  hyperParameters;
2589
2592
  minDistBetweenEnteringPoints;
2590
- activeSolver = null;
2593
+ activeSubSolver = null;
2591
2594
  connMap;
2592
2595
  // Legacy compat
2593
2596
  get failedSolvers() {
2594
2597
  return this.failedSubSolvers;
2595
2598
  }
2599
+ // Legacy compat
2600
+ get activeSolver() {
2601
+ return this.activeSubSolver;
2602
+ }
2596
2603
  constructor(params) {
2597
2604
  const { nodeWithPortPoints, colorMap } = params;
2598
2605
  super();
@@ -2651,18 +2658,18 @@ var IntraNodeRouteSolver = class extends BaseSolver {
2651
2658
  // this.unsolvedConnections = []
2652
2659
  // }
2653
2660
  computeProgress() {
2654
- return (this.solvedRoutes.length + (this.activeSolver?.progress || 0)) / this.totalConnections;
2661
+ return (this.solvedRoutes.length + (this.activeSubSolver?.progress || 0)) / this.totalConnections;
2655
2662
  }
2656
2663
  _step() {
2657
- if (this.activeSolver) {
2658
- this.activeSolver.step();
2664
+ if (this.activeSubSolver) {
2665
+ this.activeSubSolver.step();
2659
2666
  this.progress = this.computeProgress();
2660
- if (this.activeSolver.solved) {
2661
- this.solvedRoutes.push(this.activeSolver.solvedPath);
2662
- this.activeSolver = null;
2663
- } else if (this.activeSolver.failed) {
2664
- this.failedSubSolvers.push(this.activeSolver);
2665
- this.activeSolver = null;
2667
+ if (this.activeSubSolver.solved) {
2668
+ this.solvedRoutes.push(this.activeSubSolver.solvedPath);
2669
+ this.activeSubSolver = null;
2670
+ } else if (this.activeSubSolver.failed) {
2671
+ this.failedSubSolvers.push(this.activeSubSolver);
2672
+ this.activeSubSolver = null;
2666
2673
  this.error = this.failedSubSolvers.map((s) => s.error).join("\n");
2667
2674
  this.failed = true;
2668
2675
  }
@@ -2684,7 +2691,7 @@ var IntraNodeRouteSolver = class extends BaseSolver {
2684
2691
  }
2685
2692
  }
2686
2693
  const { connectionName, points } = unsolvedConnection;
2687
- this.activeSolver = new SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost({
2694
+ this.activeSubSolver = new SingleHighDensityRouteSolver6_VertHorzLayer_FutureCost({
2688
2695
  connectionName,
2689
2696
  minDistBetweenEnteringPoints: this.minDistBetweenEnteringPoints,
2690
2697
  bounds: getBoundsFromNodeWithPortPoints(this.nodeWithPortPoints),
@@ -5115,47 +5122,72 @@ var UnravelSectionSolver = class extends BaseSolver {
5115
5122
  const Bmutable = this.unravelSection.mutableSegmentIds.has(B.segmentId);
5116
5123
  const Cmutable = this.unravelSection.mutableSegmentIds.has(C.segmentId);
5117
5124
  const Dmutable = this.unravelSection.mutableSegmentIds.has(D.segmentId);
5125
+ const aSegment = this.dedupedSegmentMap.get(A.segmentId);
5126
+ const bSegment = this.dedupedSegmentMap.get(B.segmentId);
5127
+ const cSegment = this.dedupedSegmentMap.get(C.segmentId);
5128
+ const dSegment = this.dedupedSegmentMap.get(D.segmentId);
5129
+ const isNewZAvailableForAll = (segmentObjects, newZ) => {
5130
+ return segmentObjects.every((seg) => seg.availableZ.includes(newZ));
5131
+ };
5118
5132
  if (Amutable && Bmutable) {
5119
- operations.push({
5120
- type: "change_layer",
5121
- newZ: A.z === 0 ? 1 : 0,
5122
- segmentPointIds: [APointId, BPointId]
5123
- });
5133
+ const newZ = A.z === 0 ? 1 : 0;
5134
+ if (isNewZAvailableForAll([aSegment, bSegment], newZ)) {
5135
+ operations.push({
5136
+ type: "change_layer",
5137
+ newZ,
5138
+ segmentPointIds: [APointId, BPointId]
5139
+ });
5140
+ }
5124
5141
  }
5125
5142
  if (Cmutable && Dmutable) {
5126
- operations.push({
5127
- type: "change_layer",
5128
- newZ: C.z === 0 ? 1 : 0,
5129
- segmentPointIds: [CPointId, DPointId]
5130
- });
5143
+ const newZ = C.z === 0 ? 1 : 0;
5144
+ if (isNewZAvailableForAll([cSegment, dSegment], newZ)) {
5145
+ operations.push({
5146
+ type: "change_layer",
5147
+ newZ,
5148
+ segmentPointIds: [CPointId, DPointId]
5149
+ });
5150
+ }
5131
5151
  }
5132
5152
  if (Amutable) {
5133
- operations.push({
5134
- type: "change_layer",
5135
- newZ: A.z === 0 ? 1 : 0,
5136
- segmentPointIds: [APointId]
5137
- });
5153
+ const newZ = A.z === 0 ? 1 : 0;
5154
+ if (aSegment.availableZ.includes(newZ)) {
5155
+ operations.push({
5156
+ type: "change_layer",
5157
+ newZ,
5158
+ segmentPointIds: [APointId]
5159
+ });
5160
+ }
5138
5161
  }
5139
5162
  if (Bmutable) {
5140
- operations.push({
5141
- type: "change_layer",
5142
- newZ: B.z === 0 ? 1 : 0,
5143
- segmentPointIds: [BPointId]
5144
- });
5163
+ const newZ = B.z === 0 ? 1 : 0;
5164
+ if (bSegment.availableZ.includes(newZ)) {
5165
+ operations.push({
5166
+ type: "change_layer",
5167
+ newZ,
5168
+ segmentPointIds: [BPointId]
5169
+ });
5170
+ }
5145
5171
  }
5146
5172
  if (Cmutable) {
5147
- operations.push({
5148
- type: "change_layer",
5149
- newZ: C.z === 0 ? 1 : 0,
5150
- segmentPointIds: [CPointId]
5151
- });
5173
+ const newZ = C.z === 0 ? 1 : 0;
5174
+ if (cSegment.availableZ.includes(newZ)) {
5175
+ operations.push({
5176
+ type: "change_layer",
5177
+ newZ,
5178
+ segmentPointIds: [CPointId]
5179
+ });
5180
+ }
5152
5181
  }
5153
5182
  if (Dmutable) {
5154
- operations.push({
5155
- type: "change_layer",
5156
- newZ: D.z === 0 ? 1 : 0,
5157
- segmentPointIds: [DPointId]
5158
- });
5183
+ const newZ = D.z === 0 ? 1 : 0;
5184
+ if (dSegment.availableZ.includes(newZ)) {
5185
+ operations.push({
5186
+ type: "change_layer",
5187
+ newZ,
5188
+ segmentPointIds: [DPointId]
5189
+ });
5190
+ }
5159
5191
  }
5160
5192
  }
5161
5193
  return operations;
@@ -5844,6 +5876,7 @@ var createRectFromCapacityNode = (node, opts = {}) => {
5844
5876
  "0": "rgba(0,200,200, 0.1)",
5845
5877
  "1": "rgba(0,0,200, 0.1)"
5846
5878
  }[node.availableZ.join(",")] ?? "rgba(0,200,200,0.1)",
5879
+ layer: `z${node.availableZ.join(",")}`,
5847
5880
  label: [
5848
5881
  node.capacityMeshNodeId,
5849
5882
  `availableZ: ${node.availableZ.join(",")}`,
@@ -6033,6 +6066,7 @@ var CapacityPathingSolver = class extends BaseSolver {
6033
6066
  this.currentConnectionIndex++;
6034
6067
  this.candidates = null;
6035
6068
  this.visitedNodes = null;
6069
+ this.failed = true;
6036
6070
  return;
6037
6071
  }
6038
6072
  if (this.isConnectedToEndGoal(currentCandidate.node, end)) {
@@ -6091,11 +6125,14 @@ var CapacityPathingSolver = class extends BaseSolver {
6091
6125
  for (let i = 0; i < this.connectionsWithNodes.length; i++) {
6092
6126
  const conn = this.connectionsWithNodes[i];
6093
6127
  if (conn.path && conn.path.length > 0) {
6094
- const pathPoints = conn.path.map(({ center: { x, y }, width }) => ({
6095
- // slight offset to allow viewing overlapping paths
6096
- x: x + (i % 10 + i % 19) * (5e-3 * width),
6097
- y: y + (i % 10 + i % 19) * (5e-3 * width)
6098
- }));
6128
+ const pathPoints = conn.path.map(
6129
+ ({ center: { x, y }, width, availableZ }) => ({
6130
+ // slight offset to allow viewing overlapping paths
6131
+ x: x + (i % 10 + i % 19) * (5e-3 * width),
6132
+ y: y + (i % 10 + i % 19) * (5e-3 * width),
6133
+ availableZ
6134
+ })
6135
+ );
6099
6136
  graphics.lines.push({
6100
6137
  points: pathPoints,
6101
6138
  strokeColor: this.colorMap[conn.connection.name]
@@ -6107,7 +6144,8 @@ var CapacityPathingSolver = class extends BaseSolver {
6107
6144
  y: point.y,
6108
6145
  label: [
6109
6146
  `conn: ${conn.connection.name}`,
6110
- `node: ${conn.path[u].capacityMeshNodeId}`
6147
+ `node: ${conn.path[u].capacityMeshNodeId}`,
6148
+ `z: ${point.availableZ.join(",")}`
6111
6149
  ].join("\n")
6112
6150
  });
6113
6151
  }
@@ -6194,7 +6232,20 @@ var CapacityPathingSolver5 = class extends CapacityPathingSolver {
6194
6232
  * Penalty you pay for using this node
6195
6233
  */
6196
6234
  getNodeCapacityPenalty(node) {
6197
- return 0.05;
6235
+ const MAX_PENALTY = node.width + node.height;
6236
+ const MIN_PENALTY = 0.05;
6237
+ const START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW = 2;
6238
+ const totalCapacity = this.getTotalCapacity(node);
6239
+ const usedCapacity = this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0;
6240
+ const remainingCapacity = totalCapacity - usedCapacity;
6241
+ if (remainingCapacity > START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW) {
6242
+ return MIN_PENALTY;
6243
+ }
6244
+ const penalty = (MAX_PENALTY - MIN_PENALTY) * Math.max(
6245
+ 1,
6246
+ (START_PENALIZING_CAPACITY_WHEN_IT_DROPS_BELOW - remainingCapacity) / (MAX_PENALTY - MIN_PENALTY)
6247
+ ) + MIN_PENALTY;
6248
+ return penalty;
6198
6249
  }
6199
6250
  /**
6200
6251
  * We're rewarding travel into big nodes.
@@ -6210,7 +6261,7 @@ var CapacityPathingSolver5 = class extends CapacityPathingSolver {
6210
6261
  return prevCandidate.g + this.getDistanceBetweenNodes(prevCandidate.node, node) + this.getNodeCapacityPenalty(node);
6211
6262
  }
6212
6263
  computeH(prevCandidate, node, endGoal) {
6213
- return this.getDistanceBetweenNodes(node, endGoal);
6264
+ return this.getDistanceBetweenNodes(node, endGoal) + this.getNodeCapacityPenalty(node);
6214
6265
  }
6215
6266
  };
6216
6267
 
@@ -6355,7 +6406,7 @@ var StrawSolver = class extends BaseSolver {
6355
6406
  this.solved = true;
6356
6407
  return;
6357
6408
  }
6358
- if (rootNode.width < this.strawSize * 5 && rootNode.height < this.strawSize * 5) {
6409
+ if (rootNode.width < this.strawSize && rootNode.height < this.strawSize) {
6359
6410
  this.skippedNodes.push(rootNode);
6360
6411
  return;
6361
6412
  }