@tscircuit/capacity-autorouter 0.0.62 → 0.0.64

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.js CHANGED
@@ -3721,8 +3721,54 @@ function seededRandom(seed) {
3721
3721
  return result - Math.floor(result);
3722
3722
  };
3723
3723
  }
3724
+ var PRESHUFFLED_CASES = {
3725
+ 1: [[0]],
3726
+ 2: [
3727
+ [0, 1],
3728
+ [1, 0]
3729
+ ],
3730
+ 3: [
3731
+ [0, 1, 2],
3732
+ [2, 0, 1],
3733
+ [1, 0, 2],
3734
+ [0, 2, 1],
3735
+ [1, 2, 0],
3736
+ [2, 1, 0]
3737
+ ],
3738
+ 4: [
3739
+ [0, 1, 2, 3],
3740
+ [2, 0, 1, 3],
3741
+ [1, 3, 2, 0],
3742
+ [3, 0, 1, 2],
3743
+ [0, 2, 1, 3],
3744
+ [2, 1, 3, 0],
3745
+ [3, 0, 2, 1],
3746
+ [1, 2, 0, 3],
3747
+ [3, 1, 0, 2],
3748
+ [0, 3, 2, 1],
3749
+ [2, 3, 0, 1],
3750
+ [2, 3, 1, 0],
3751
+ [1, 2, 3, 0],
3752
+ [3, 1, 2, 0],
3753
+ [0, 1, 3, 2],
3754
+ [0, 2, 3, 1],
3755
+ [0, 3, 1, 2],
3756
+ [1, 0, 2, 3],
3757
+ [1, 0, 3, 2],
3758
+ [1, 3, 0, 2],
3759
+ [2, 0, 3, 1],
3760
+ [2, 1, 0, 3],
3761
+ [3, 2, 0, 1],
3762
+ [3, 2, 1, 0]
3763
+ ]
3764
+ };
3724
3765
  function cloneAndShuffleArray(arr, seed) {
3725
3766
  if (seed === 0) return arr;
3767
+ if (arr.length <= 4) {
3768
+ const preshuffledOptions = PRESHUFFLED_CASES[arr.length];
3769
+ const preshuffledCase = preshuffledOptions[seed % preshuffledOptions.length];
3770
+ return preshuffledCase.map((orderIndex) => arr[orderIndex]);
3771
+ }
3726
3772
  const random = seededRandom(seed);
3727
3773
  const shuffled = arr.slice();
3728
3774
  for (let i = 0; i < shuffled.length; i++) {
@@ -9639,6 +9685,30 @@ var SingleHighDensityRouteStitchSolver = class extends BaseSolver {
9639
9685
  super();
9640
9686
  this.remainingHdRoutes = [...opts.hdRoutes];
9641
9687
  this.colorMap = opts.colorMap ?? {};
9688
+ if (opts.hdRoutes.length === 0) {
9689
+ this.start = opts.start;
9690
+ this.end = opts.end;
9691
+ const routePoints = [
9692
+ { x: opts.start.x, y: opts.start.y, z: opts.start.z }
9693
+ ];
9694
+ const vias = [];
9695
+ if (opts.start.z !== opts.end.z) {
9696
+ routePoints.push({ x: opts.start.x, y: opts.start.y, z: opts.end.z });
9697
+ vias.push({ x: opts.start.x, y: opts.start.y });
9698
+ }
9699
+ routePoints.push({ x: opts.end.x, y: opts.end.y, z: opts.end.z });
9700
+ this.mergedHdRoute = {
9701
+ connectionName: opts.connectionName,
9702
+ route: routePoints,
9703
+ vias,
9704
+ viaDiameter: opts.defaultViaDiameter ?? 0.6,
9705
+ // Use default or fallback
9706
+ traceThickness: opts.defaultTraceThickness ?? 0.15
9707
+ // Use default or fallback
9708
+ };
9709
+ this.solved = true;
9710
+ return;
9711
+ }
9642
9712
  const { firstRoute } = this.getDisjointedRoute();
9643
9713
  const firstRouteToStartDist = Math.min(
9644
9714
  distance(firstRoute.route[0], opts.start),
@@ -9656,7 +9726,8 @@ var SingleHighDensityRouteStitchSolver = class extends BaseSolver {
9656
9726
  this.end = opts.start;
9657
9727
  }
9658
9728
  this.mergedHdRoute = {
9659
- connectionName: opts.connectionName ?? firstRoute.connectionName,
9729
+ connectionName: opts.connectionName,
9730
+ // Use mandatory connectionName
9660
9731
  route: [
9661
9732
  {
9662
9733
  x: this.start.x,
@@ -9821,9 +9892,18 @@ var MultipleHighDensityRouteStitchSolver = class extends BaseSolver {
9821
9892
  activeSolver = null;
9822
9893
  mergedHdRoutes = [];
9823
9894
  colorMap = {};
9895
+ defaultTraceThickness;
9896
+ defaultViaDiameter;
9824
9897
  constructor(opts) {
9825
9898
  super();
9826
9899
  this.colorMap = opts.colorMap ?? {};
9900
+ if (opts.hdRoutes.length > 0) {
9901
+ this.defaultTraceThickness = opts.hdRoutes[0].traceThickness;
9902
+ this.defaultViaDiameter = opts.hdRoutes[0].viaDiameter;
9903
+ } else {
9904
+ this.defaultTraceThickness = 0.15;
9905
+ this.defaultViaDiameter = 0.6;
9906
+ }
9827
9907
  this.unsolvedRoutes = opts.connections.map((c) => ({
9828
9908
  connectionName: c.name,
9829
9909
  hdRoutes: opts.hdRoutes.filter((r) => r.connectionName === c.name),
@@ -9860,7 +9940,9 @@ var MultipleHighDensityRouteStitchSolver = class extends BaseSolver {
9860
9940
  hdRoutes: unsolvedRoute.hdRoutes,
9861
9941
  start: unsolvedRoute.start,
9862
9942
  end: unsolvedRoute.end,
9863
- colorMap: this.colorMap
9943
+ colorMap: this.colorMap,
9944
+ defaultTraceThickness: this.defaultTraceThickness,
9945
+ defaultViaDiameter: this.defaultViaDiameter
9864
9946
  });
9865
9947
  }
9866
9948
  visualize() {
@@ -10937,6 +11019,8 @@ import objectHash from "object-hash";
10937
11019
 
10938
11020
  // lib/cache/InMemoryCache.ts
10939
11021
  var InMemoryCache = class {
11022
+ cacheHitsByPrefix = {};
11023
+ cacheMissesByPrefix = {};
10940
11024
  isSyncCache = true;
10941
11025
  cacheHits = 0;
10942
11026
  cacheMisses = 0;
@@ -11002,6 +11086,8 @@ var LocalStorageCache = class {
11002
11086
  isSyncCache = true;
11003
11087
  cacheHits = 0;
11004
11088
  cacheMisses = 0;
11089
+ cacheHitsByPrefix = {};
11090
+ cacheMissesByPrefix = {};
11005
11091
  constructor() {
11006
11092
  if (typeof localStorage === "undefined") {
11007
11093
  console.warn(
@@ -11026,14 +11112,20 @@ var LocalStorageCache = class {
11026
11112
  if (cachedItem !== null) {
11027
11113
  const solution = JSON.parse(cachedItem);
11028
11114
  this.cacheHits++;
11115
+ const prefix = cacheKey.split(":")[0];
11116
+ this.cacheHitsByPrefix[prefix] = (this.cacheHitsByPrefix[prefix] || 0) + 1;
11029
11117
  return solution;
11030
11118
  } else {
11031
11119
  this.cacheMisses++;
11120
+ const prefix = cacheKey.split(":")[0];
11121
+ this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
11032
11122
  return void 0;
11033
11123
  }
11034
11124
  } catch (error) {
11035
11125
  console.error(`Error getting cached solution sync for ${key}:`, error);
11036
11126
  this.cacheMisses++;
11127
+ const prefix = cacheKey.split(":")[0];
11128
+ this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
11037
11129
  return void 0;
11038
11130
  }
11039
11131
  }
@@ -11098,6 +11190,8 @@ var LocalStorageCache = class {
11098
11190
  } finally {
11099
11191
  this.cacheHits = 0;
11100
11192
  this.cacheMisses = 0;
11193
+ this.cacheHitsByPrefix = {};
11194
+ this.cacheMissesByPrefix = {};
11101
11195
  }
11102
11196
  }
11103
11197
  getAllCacheKeys() {
@@ -11119,6 +11213,12 @@ function getGlobalLocalStorageCache() {
11119
11213
  }
11120
11214
  return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE;
11121
11215
  }
11216
+ function getGlobalInMemoryCache() {
11217
+ if (!globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE) {
11218
+ setupGlobalCaches();
11219
+ }
11220
+ return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE;
11221
+ }
11122
11222
  function setupGlobalCaches() {
11123
11223
  globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE ??= new LocalStorageCache();
11124
11224
  globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE ??= new InMemoryCache();
@@ -12521,6 +12621,21 @@ var calculateNodeProbabilityOfFailure2 = (usedCapacity, totalCapacity, layerCoun
12521
12621
  const adjustedRatio = ratioOverTotal - 1;
12522
12622
  return 1 - Math.exp(-k * adjustedRatio);
12523
12623
  };
12624
+ var calculateSingleNodeLogSuccessProbability = (usedCapacity, totalCapacity, node) => {
12625
+ if (node._containsTarget) return 0;
12626
+ if (usedCapacity <= totalCapacity) return 0;
12627
+ const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
12628
+ usedCapacity,
12629
+ totalCapacity,
12630
+ node.availableZ.length
12631
+ );
12632
+ const probabilityOfSuccess = 1 - probabilityOfFailure;
12633
+ if (probabilityOfSuccess <= 0) {
12634
+ return -1e9;
12635
+ } else {
12636
+ return Math.log(probabilityOfSuccess);
12637
+ }
12638
+ };
12524
12639
  var computeSectionScore = ({
12525
12640
  totalNodeCapacityMap,
12526
12641
  usedNodeCapacityMap,
@@ -12534,21 +12649,13 @@ var computeSectionScore = ({
12534
12649
  if (!totalNodeCapacityMap.has(nodeId)) continue;
12535
12650
  const node = nodeMap.get(nodeId);
12536
12651
  if (!node) continue;
12537
- if (node._containsTarget) continue;
12538
12652
  const totalCapacity = totalNodeCapacityMap.get(nodeId);
12539
12653
  const usedCapacity = usedNodeCapacityMap.get(nodeId) ?? 0;
12540
- if (usedCapacity <= totalCapacity) continue;
12541
- const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
12654
+ logProbabilityOfSuccessSum += calculateSingleNodeLogSuccessProbability(
12542
12655
  usedCapacity,
12543
12656
  totalCapacity,
12544
- node.availableZ.length
12657
+ node
12545
12658
  );
12546
- const probabilityOfSuccess = 1 - probabilityOfFailure;
12547
- if (probabilityOfSuccess <= 0) {
12548
- logProbabilityOfSuccessSum += -1e9;
12549
- } else {
12550
- logProbabilityOfSuccessSum += Math.log(probabilityOfSuccess);
12551
- }
12552
12659
  }
12553
12660
  return logProbabilityOfSuccessSum;
12554
12661
  };
@@ -12729,9 +12836,9 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
12729
12836
  x: x + offset.x,
12730
12837
  y: y + offset.y
12731
12838
  })),
12732
- strokeColor: safeTransparentize(pathColor, 0.2),
12839
+ strokeColor: safeTransparentize(pathColor, 0.2)
12733
12840
  // Make solved paths semi-transparent
12734
- strokeWidth: 0.03
12841
+ // strokeWidth: 0.03,
12735
12842
  });
12736
12843
  }
12737
12844
  });
@@ -12739,6 +12846,72 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
12739
12846
  return graphics;
12740
12847
  }
12741
12848
 
12849
+ // lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
12850
+ var computeSectionNodesTerminalsAndEdges = (opts) => {
12851
+ const {
12852
+ centerNodeId,
12853
+ connectionsWithNodes,
12854
+ nodeMap,
12855
+ edges,
12856
+ nodeEdgeMap,
12857
+ expansionDegrees
12858
+ } = opts;
12859
+ const sectionNodeIds = /* @__PURE__ */ new Set();
12860
+ const queue = [
12861
+ { nodeId: centerNodeId, depth: 0 }
12862
+ ];
12863
+ sectionNodeIds.add(centerNodeId);
12864
+ let head = 0;
12865
+ while (head < queue.length) {
12866
+ const { nodeId, depth } = queue[head++];
12867
+ if (depth >= expansionDegrees) continue;
12868
+ const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
12869
+ for (const neighborId of neighbors) {
12870
+ if (!sectionNodeIds.has(neighborId)) {
12871
+ sectionNodeIds.add(neighborId);
12872
+ queue.push({ nodeId: neighborId, depth: depth + 1 });
12873
+ }
12874
+ }
12875
+ }
12876
+ const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
12877
+ const sectionEdges = edges.filter((edge) => {
12878
+ const [nodeIdA, nodeIdB] = edge.nodeIds;
12879
+ return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
12880
+ });
12881
+ const sectionConnectionTerminals = [];
12882
+ for (const conn of connectionsWithNodes) {
12883
+ if (!conn.path) continue;
12884
+ let startNodeId = null;
12885
+ let endNodeId = null;
12886
+ for (const node of conn.path) {
12887
+ if (sectionNodeIds.has(node.capacityMeshNodeId)) {
12888
+ startNodeId = node.capacityMeshNodeId;
12889
+ break;
12890
+ }
12891
+ }
12892
+ for (let i = conn.path.length - 1; i >= 0; i--) {
12893
+ const node = conn.path[i];
12894
+ if (sectionNodeIds.has(node.capacityMeshNodeId)) {
12895
+ endNodeId = node.capacityMeshNodeId;
12896
+ break;
12897
+ }
12898
+ }
12899
+ if (startNodeId && endNodeId) {
12900
+ sectionConnectionTerminals.push({
12901
+ connectionName: conn.connection.name,
12902
+ startNodeId,
12903
+ endNodeId
12904
+ });
12905
+ }
12906
+ }
12907
+ return {
12908
+ sectionConnectionTerminals,
12909
+ sectionNodes,
12910
+ sectionEdges,
12911
+ centerNodeId
12912
+ };
12913
+ };
12914
+
12742
12915
  // lib/solvers/CapacityPathingSectionSolver/CapacityPathingSingleSectionSolver.ts
12743
12916
  var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12744
12917
  GREEDY_MULTIPLIER = 1.5;
@@ -12752,7 +12925,10 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12752
12925
  colorMap;
12753
12926
  usedNodeCapacityMap;
12754
12927
  // Tracks capacity usage *within this solver's run*
12928
+ totalNodeCapacityMap;
12929
+ // Added: Stores total capacity for each node
12755
12930
  centerNodeId;
12931
+ currentSectionScore = 0;
12756
12932
  MAX_CANDIDATES_IN_MEMORY = 1e4;
12757
12933
  // A* state
12758
12934
  currentConnectionIndex = 0;
@@ -12773,14 +12949,28 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12773
12949
  this.sectionConnectionTerminals = params.sectionConnectionTerminals.map(
12774
12950
  (t) => ({ ...t, path: void 0 })
12775
12951
  );
12776
- this.nodeMap = new Map(
12777
- this.sectionNodes.map((n) => [n.capacityMeshNodeId, n])
12778
- );
12952
+ this.nodeMap = params.nodeMap ?? new Map(this.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
12779
12953
  this.nodeEdgeMap = params.nodeEdgeMap ?? getNodeEdgeMap(this.sectionEdges);
12780
12954
  this.colorMap = params.colorMap ?? {};
12781
12955
  this.usedNodeCapacityMap = new Map(
12782
12956
  this.sectionNodes.map((node) => [node.capacityMeshNodeId, 0])
12783
12957
  );
12958
+ this.totalNodeCapacityMap = new Map(
12959
+ this.sectionNodes.map((node) => [
12960
+ node.capacityMeshNodeId,
12961
+ this.getTotalCapacity(node)
12962
+ ])
12963
+ );
12964
+ const initialSectionNodeIds = new Set(
12965
+ this.sectionNodes.map((n) => n.capacityMeshNodeId)
12966
+ );
12967
+ this.currentSectionScore = computeSectionScore({
12968
+ totalNodeCapacityMap: this.totalNodeCapacityMap,
12969
+ usedNodeCapacityMap: this.usedNodeCapacityMap,
12970
+ // Reflects initial capacities
12971
+ nodeMap: this.nodeMap,
12972
+ sectionNodeIds: initialSectionNodeIds
12973
+ });
12784
12974
  if (params.hyperParameters?.SHUFFLE_SEED) {
12785
12975
  this.sectionConnectionTerminals = cloneAndShuffleArray(
12786
12976
  this.sectionConnectionTerminals,
@@ -12860,15 +13050,40 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12860
13050
  }
12861
13051
  // Adapted from CapacityPathingSolver - uses section's capacity map
12862
13052
  reduceCapacityAlongPath(path) {
12863
- for (const node of path) {
12864
- if (this.usedNodeCapacityMap.has(node.capacityMeshNodeId)) {
12865
- this.usedNodeCapacityMap.set(
12866
- node.capacityMeshNodeId,
12867
- (this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0) + 1
13053
+ for (const pathNode of path) {
13054
+ if (this.usedNodeCapacityMap.has(pathNode.capacityMeshNodeId)) {
13055
+ const nodeId = pathNode.capacityMeshNodeId;
13056
+ const nodeInSection = this.nodeMap.get(nodeId);
13057
+ if (!nodeInSection) {
13058
+ console.warn(
13059
+ `Node ${nodeId} from path not found in section's nodeMap during score update.`
13060
+ );
13061
+ continue;
13062
+ }
13063
+ const totalCapacity = this.totalNodeCapacityMap.get(nodeId);
13064
+ const oldUsedCapacity = this.usedNodeCapacityMap.get(nodeId) ?? 0;
13065
+ const oldNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
13066
+ oldUsedCapacity,
13067
+ totalCapacity,
13068
+ nodeInSection
13069
+ // Use the node object from the section's map
13070
+ );
13071
+ this.currentSectionScore -= oldNodeScoreContribution;
13072
+ const newUsedCapacity = oldUsedCapacity + 1;
13073
+ this.usedNodeCapacityMap.set(nodeId, newUsedCapacity);
13074
+ const newNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
13075
+ newUsedCapacity,
13076
+ totalCapacity,
13077
+ nodeInSection
13078
+ // Use the node object from the section's map
12868
13079
  );
13080
+ this.currentSectionScore += newNodeScoreContribution;
12869
13081
  }
12870
13082
  }
12871
13083
  }
13084
+ getSolvedSectionScore() {
13085
+ return this.currentSectionScore;
13086
+ }
12872
13087
  _step() {
12873
13088
  const currentTerminal = this.sectionConnectionTerminals[this.currentConnectionIndex];
12874
13089
  if (!currentTerminal) {
@@ -13070,6 +13285,7 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
13070
13285
  var CapacityPathingSingleSectionPathingSolver = CapacityPathingSingleSectionSolver;
13071
13286
 
13072
13287
  // lib/solvers/CapacityPathingSectionSolver/HyperCapacityPathingSingleSectionSolver.ts
13288
+ var range = (n) => Array.from({ length: n }, (_, i) => i);
13073
13289
  var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSupervisorSolver {
13074
13290
  constructorParams;
13075
13291
  winningSolver;
@@ -13078,14 +13294,24 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13078
13294
  this.MAX_ITERATIONS = 1e5;
13079
13295
  this.constructorParams = params;
13080
13296
  }
13297
+ // TODO this needs to use the section score, ideally incorporating the current best candidate
13298
+ // of the paths being explored inside the single section
13081
13299
  computeG(solver) {
13082
- return solver.iterations / 100;
13300
+ return -solver.getSolvedSectionScore();
13083
13301
  }
13084
13302
  computeH(solver) {
13085
- return solver.computeProgress();
13303
+ return 0;
13086
13304
  }
13087
13305
  getCombinationDefs() {
13088
- return [["orderings10"]];
13306
+ const numConnections = this.constructorParams.sectionConnectionTerminals.length;
13307
+ if (numConnections === 2) {
13308
+ return [["orderings2_for2"]];
13309
+ } else if (numConnections === 3) {
13310
+ return [["orderings6_for3"]];
13311
+ } else if (numConnections === 4) {
13312
+ return [["orderings24_for4"]];
13313
+ }
13314
+ return [["orderings30"]];
13089
13315
  }
13090
13316
  getFailureMessage() {
13091
13317
  return `All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`;
@@ -13093,39 +13319,28 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13093
13319
  getHyperParameterDefs() {
13094
13320
  return [
13095
13321
  {
13096
- name: "orderings10",
13097
- possibleValues: [
13098
- {
13099
- SHUFFLE_SEED: 0
13100
- },
13101
- {
13102
- SHUFFLE_SEED: 1
13103
- },
13104
- {
13105
- SHUFFLE_SEED: 2
13106
- },
13107
- {
13108
- SHUFFLE_SEED: 3
13109
- },
13110
- {
13111
- SHUFFLE_SEED: 4
13112
- },
13113
- {
13114
- SHUFFLE_SEED: 5
13115
- },
13116
- {
13117
- SHUFFLE_SEED: 6
13118
- },
13119
- {
13120
- SHUFFLE_SEED: 7
13121
- },
13122
- {
13123
- SHUFFLE_SEED: 8
13124
- },
13125
- {
13126
- SHUFFLE_SEED: 9
13127
- }
13128
- ]
13322
+ name: "orderings2_for2",
13323
+ possibleValues: range(2).map((i) => ({
13324
+ SHUFFLE_SEED: i
13325
+ }))
13326
+ },
13327
+ {
13328
+ name: "orderings6_for3",
13329
+ possibleValues: range(6).map((i) => ({
13330
+ SHUFFLE_SEED: i
13331
+ }))
13332
+ },
13333
+ {
13334
+ name: "orderings24_for4",
13335
+ possibleValues: range(24).map((i) => ({
13336
+ SHUFFLE_SEED: i
13337
+ }))
13338
+ },
13339
+ {
13340
+ name: "orderings30",
13341
+ possibleValues: range(30).map((i) => ({
13342
+ SHUFFLE_SEED: i
13343
+ }))
13129
13344
  }
13130
13345
  ];
13131
13346
  }
@@ -13154,70 +13369,320 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13154
13369
  }
13155
13370
  };
13156
13371
 
13157
- // lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
13158
- var computeSectionNodesTerminalsAndEdges = (opts) => {
13159
- const {
13160
- centerNodeId,
13161
- connectionsWithNodes,
13162
- nodeMap,
13163
- edges,
13164
- nodeEdgeMap,
13165
- expansionDegrees
13166
- } = opts;
13167
- const sectionNodeIds = /* @__PURE__ */ new Set();
13168
- const queue = [
13169
- { nodeId: centerNodeId, depth: 0 }
13170
- ];
13171
- sectionNodeIds.add(centerNodeId);
13172
- let head = 0;
13173
- while (head < queue.length) {
13174
- const { nodeId, depth } = queue[head++];
13175
- if (depth >= expansionDegrees) continue;
13176
- const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
13177
- for (const neighborId of neighbors) {
13178
- if (!sectionNodeIds.has(neighborId)) {
13179
- sectionNodeIds.add(neighborId);
13180
- queue.push({ nodeId: neighborId, depth: depth + 1 });
13181
- }
13372
+ // lib/solvers/CapacityPathingSectionSolver/CachedHyperCapacityPathingSingleSectionSolver.ts
13373
+ import objectHash2 from "object-hash";
13374
+ var roundCapacity = (capacity) => Math.floor(capacity * 10) / 10;
13375
+ var CachedHyperCapacityPathingSingleSectionSolver = class extends HyperCapacityPathingSingleSectionSolver {
13376
+ cacheHit = false;
13377
+ cacheProvider;
13378
+ hasAttemptedToUseCache = false;
13379
+ sectionNodeIdSet;
13380
+ cachedSectionConnectionTerminals = null;
13381
+ sectionScore = 0;
13382
+ constructor(params) {
13383
+ params.nodeMap = params.nodeMap ?? new Map(params.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
13384
+ super(params);
13385
+ this.sectionNodeIdSet = new Set(
13386
+ params.sectionNodes.map((sn) => sn.capacityMeshNodeId)
13387
+ );
13388
+ this.cacheProvider = params.cacheProvider === void 0 ? getGlobalInMemoryCache() : params.cacheProvider;
13389
+ }
13390
+ _step() {
13391
+ if (!this.hasAttemptedToUseCache && this.cacheProvider) {
13392
+ if (this.attemptToUseCacheSync()) return;
13393
+ }
13394
+ super._step();
13395
+ if ((this.solved || this.failed) && this.cacheProvider) {
13396
+ this.saveToCacheSync();
13182
13397
  }
13183
13398
  }
13184
- const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
13185
- const sectionEdges = edges.filter((edge) => {
13186
- const [nodeIdA, nodeIdB] = edge.nodeIds;
13187
- return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
13188
- });
13189
- const sectionConnectionTerminals = [];
13190
- for (const conn of connectionsWithNodes) {
13191
- if (!conn.path) continue;
13192
- let startNodeId = null;
13193
- let endNodeId = null;
13194
- for (const node of conn.path) {
13195
- if (sectionNodeIds.has(node.capacityMeshNodeId)) {
13196
- startNodeId = node.capacityMeshNodeId;
13197
- break;
13399
+ _computeBfsOrderingOfNodesInSection() {
13400
+ const seenNodeIds = new Set(this.constructorParams.centerNodeId);
13401
+ const ordering = [];
13402
+ const candidates = [
13403
+ {
13404
+ ancestorCapacitySum: 0,
13405
+ capacity: 0,
13406
+ g: 0,
13407
+ capacityMeshNodeId: this.constructorParams.centerNodeId
13408
+ }
13409
+ ];
13410
+ while (candidates.length > 0) {
13411
+ candidates.sort((a, b) => b.g - a.g);
13412
+ const candidate = candidates.pop();
13413
+ if (!candidate) break;
13414
+ ordering.push(candidate.capacityMeshNodeId);
13415
+ const neighborNodeIds = this.constructorParams.nodeEdgeMap.get(candidate.capacityMeshNodeId).flatMap((edge) => edge.nodeIds).filter((nodeId) => !seenNodeIds.has(nodeId)).filter((nodeId) => this.sectionNodeIdSet.has(nodeId));
13416
+ for (const neighborNodeId of neighborNodeIds) {
13417
+ seenNodeIds.add(neighborNodeId);
13418
+ const neighbor = this.constructorParams.nodeMap.get(neighborNodeId);
13419
+ const capacity = getTunedTotalCapacity1(neighbor);
13420
+ candidates.push({
13421
+ ancestorCapacitySum: candidate.g,
13422
+ capacity,
13423
+ g: candidate.g + capacity,
13424
+ capacityMeshNodeId: neighborNodeId
13425
+ });
13198
13426
  }
13199
13427
  }
13200
- for (let i = conn.path.length - 1; i >= 0; i--) {
13201
- const node = conn.path[i];
13202
- if (sectionNodeIds.has(node.capacityMeshNodeId)) {
13203
- endNodeId = node.capacityMeshNodeId;
13204
- break;
13428
+ return ordering;
13429
+ }
13430
+ computeCacheKeyAndTransform() {
13431
+ const nodeOrdering = this._computeBfsOrderingOfNodesInSection();
13432
+ const realToCacheSpaceNodeIdMap = /* @__PURE__ */ new Map();
13433
+ const cacheSpaceToRealNodeIdMap = /* @__PURE__ */ new Map();
13434
+ nodeOrdering.forEach((realNodeId, i) => {
13435
+ const cacheNodeId = `node${i}`;
13436
+ realToCacheSpaceNodeIdMap.set(realNodeId, cacheNodeId);
13437
+ cacheSpaceToRealNodeIdMap.set(cacheNodeId, realNodeId);
13438
+ });
13439
+ const node_capacity_map = {};
13440
+ for (const realNodeId of nodeOrdering) {
13441
+ const cacheNodeId = realToCacheSpaceNodeIdMap.get(realNodeId);
13442
+ const node = this.constructorParams.nodeMap.get(realNodeId);
13443
+ const capacity = getTunedTotalCapacity1(node);
13444
+ node_capacity_map[cacheNodeId] = roundCapacity(capacity).toFixed(
13445
+ 1
13446
+ );
13447
+ }
13448
+ const node_edge_map_set = /* @__PURE__ */ new Set();
13449
+ const node_edge_map = [];
13450
+ for (const realNodeId1 of nodeOrdering) {
13451
+ const cacheNodeId1 = realToCacheSpaceNodeIdMap.get(realNodeId1);
13452
+ const neighbors = this.constructorParams.nodeEdgeMap.get(realNodeId1) ?? [];
13453
+ for (const edge of neighbors) {
13454
+ const realNodeId2 = edge.nodeIds.find((id) => id !== realNodeId1);
13455
+ if (this.sectionNodeIdSet.has(realNodeId2)) {
13456
+ const cacheNodeId2 = realToCacheSpaceNodeIdMap.get(realNodeId2);
13457
+ const pair = [cacheNodeId1, cacheNodeId2].sort();
13458
+ const pairKey = `${pair[0]}-${pair[1]}`;
13459
+ if (!node_edge_map_set.has(pairKey)) {
13460
+ node_edge_map.push(pair);
13461
+ node_edge_map_set.add(pairKey);
13462
+ }
13463
+ }
13205
13464
  }
13206
13465
  }
13207
- if (startNodeId && endNodeId) {
13208
- sectionConnectionTerminals.push({
13209
- connectionName: conn.connection.name,
13210
- startNodeId,
13211
- endNodeId
13466
+ node_edge_map.sort((a, b) => {
13467
+ if (a[0] !== b[0]) return a[0].localeCompare(b[0]);
13468
+ return a[1].localeCompare(b[1]);
13469
+ });
13470
+ const terminals = {};
13471
+ const cacheSpaceToRealConnectionId = /* @__PURE__ */ new Map();
13472
+ for (const conn of this.constructorParams.sectionConnectionTerminals) {
13473
+ const cacheStartNodeId = realToCacheSpaceNodeIdMap.get(conn.startNodeId);
13474
+ const cacheEndNodeId = realToCacheSpaceNodeIdMap.get(conn.endNodeId);
13475
+ const [sortedStartId, sortedEndId] = [
13476
+ cacheStartNodeId,
13477
+ cacheEndNodeId
13478
+ ].sort();
13479
+ const cacheSpaceConnectionId = `${sortedStartId}->${sortedEndId}`;
13480
+ terminals[cacheSpaceConnectionId] = {
13481
+ start: sortedStartId,
13482
+ end: sortedEndId
13483
+ };
13484
+ cacheSpaceToRealConnectionId.set(
13485
+ cacheSpaceConnectionId,
13486
+ // Use the canonically sorted key
13487
+ conn.connectionName
13488
+ );
13489
+ }
13490
+ const cacheKeyContent = {
13491
+ node_capacity_map,
13492
+ node_edge_map,
13493
+ terminals
13494
+ };
13495
+ const cacheKey = `capacitypathing:${objectHash2(cacheKeyContent)}`;
13496
+ const cacheToSolveSpaceTransform = {
13497
+ cacheSpaceToRealConnectionId,
13498
+ cacheSpaceToRealNodeId: cacheSpaceToRealNodeIdMap
13499
+ };
13500
+ this.cacheKey = cacheKey;
13501
+ this.cacheToSolveSpaceTransform = cacheToSolveSpaceTransform;
13502
+ return { cacheKey, cacheToSolveSpaceTransform };
13503
+ }
13504
+ applyCachedSolution(cachedSolution) {
13505
+ if (!this.cacheToSolveSpaceTransform) {
13506
+ console.error(
13507
+ "Cache transform not available, cannot apply cached solution."
13508
+ );
13509
+ this.failed = true;
13510
+ return;
13511
+ }
13512
+ if (!cachedSolution.success) {
13513
+ this.failed = true;
13514
+ this.cacheHit = true;
13515
+ return;
13516
+ }
13517
+ this.cachedSectionConnectionTerminals = [];
13518
+ const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
13519
+ for (const [cacheConnId, cachePathNodeIds] of Object.entries(
13520
+ cachedSolution.solutionPaths
13521
+ )) {
13522
+ const realConnectionName = cacheSpaceToRealConnectionId.get(
13523
+ cacheConnId
13524
+ );
13525
+ if (!realConnectionName) {
13526
+ console.warn(`Could not find real connection name for ${cacheConnId}`);
13527
+ continue;
13528
+ }
13529
+ const originalTerminal = this.constructorParams.sectionConnectionTerminals.find(
13530
+ (t) => t.connectionName === realConnectionName
13531
+ );
13532
+ if (!originalTerminal) {
13533
+ console.warn(
13534
+ `Could not find original terminal for connection name ${realConnectionName}`
13535
+ );
13536
+ continue;
13537
+ }
13538
+ const realPathNodes = cachePathNodeIds.map(
13539
+ (cacheNodeId) => {
13540
+ const realNodeId = cacheSpaceToRealNodeId.get(cacheNodeId);
13541
+ if (!realNodeId) {
13542
+ throw new Error(
13543
+ `Could not map cache node ID ${cacheNodeId} to real node ID for connection ${realConnectionName}`
13544
+ );
13545
+ }
13546
+ const node = this.constructorParams.nodeMap.get(realNodeId);
13547
+ if (!node) {
13548
+ throw new Error(
13549
+ `Could not find node with ID ${realNodeId} in nodeMap for connection ${realConnectionName}`
13550
+ );
13551
+ }
13552
+ return node;
13553
+ }
13554
+ );
13555
+ this.cachedSectionConnectionTerminals.push({
13556
+ ...originalTerminal,
13557
+ path: realPathNodes
13212
13558
  });
13213
13559
  }
13560
+ this.sectionScore = cachedSolution.sectionScore;
13561
+ this.solved = true;
13562
+ this.cacheHit = true;
13563
+ }
13564
+ attemptToUseCacheSync() {
13565
+ this.hasAttemptedToUseCache = true;
13566
+ if (!this.cacheProvider?.isSyncCache) {
13567
+ console.log(
13568
+ "Cache provider is not synchronous, skipping sync cache check."
13569
+ );
13570
+ return false;
13571
+ }
13572
+ if (!this.cacheKey) {
13573
+ this.computeCacheKeyAndTransform();
13574
+ }
13575
+ if (!this.cacheKey) {
13576
+ console.error("Failed to compute cache key.");
13577
+ return false;
13578
+ }
13579
+ try {
13580
+ const cachedSolution = this.cacheProvider.getCachedSolutionSync(
13581
+ this.cacheKey
13582
+ );
13583
+ if (cachedSolution) {
13584
+ this.applyCachedSolution(
13585
+ cachedSolution
13586
+ );
13587
+ return true;
13588
+ }
13589
+ } catch (error) {
13590
+ console.error("Error attempting to use cache:", error);
13591
+ }
13592
+ return false;
13593
+ }
13594
+ saveToCacheSync() {
13595
+ if (!this.cacheKey) {
13596
+ console.error("Cannot save to cache without cache key.");
13597
+ return;
13598
+ }
13599
+ if (!this.cacheToSolveSpaceTransform) {
13600
+ console.error(
13601
+ "Cache transform not available, cannot save solution to cache."
13602
+ );
13603
+ return;
13604
+ }
13605
+ let cachedSolution;
13606
+ if (this.failed) {
13607
+ cachedSolution = { success: false };
13608
+ } else if (this.solved) {
13609
+ const solutionPathsInCacheSpace = {};
13610
+ const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
13611
+ const realToCacheSpaceNodeId = /* @__PURE__ */ new Map();
13612
+ for (const [cacheId, realId] of cacheSpaceToRealNodeId) {
13613
+ realToCacheSpaceNodeId.set(realId, cacheId);
13614
+ }
13615
+ const realToCacheSpaceConnectionId = /* @__PURE__ */ new Map();
13616
+ for (const [cacheConnId, realConnName] of cacheSpaceToRealConnectionId) {
13617
+ realToCacheSpaceConnectionId.set(realConnName, cacheConnId);
13618
+ }
13619
+ const realSolutionPaths = [];
13620
+ if (super.sectionConnectionTerminals) {
13621
+ for (const terminal of super.sectionConnectionTerminals) {
13622
+ if (terminal.path && terminal.path.length > 0) {
13623
+ const realPathNodeIds = terminal.path.map(
13624
+ (node) => node.capacityMeshNodeId
13625
+ );
13626
+ realSolutionPaths.push([terminal.connectionName, realPathNodeIds]);
13627
+ }
13628
+ }
13629
+ }
13630
+ for (const [realConnectionName, realPathNodeIds] of realSolutionPaths) {
13631
+ const cacheConnectionId = realToCacheSpaceConnectionId.get(realConnectionName);
13632
+ if (!cacheConnectionId) {
13633
+ console.warn(
13634
+ `Could not find cache space connection ID for ${realConnectionName} when saving to cache.`
13635
+ );
13636
+ continue;
13637
+ }
13638
+ const cachePathNodeIds = realPathNodeIds.map((realNodeId) => {
13639
+ const cacheNodeId = realToCacheSpaceNodeId.get(realNodeId);
13640
+ if (!cacheNodeId) {
13641
+ throw new Error(
13642
+ `Could not map real node ID ${realNodeId} to cache node ID for connection ${realConnectionName} when saving to cache.`
13643
+ );
13644
+ }
13645
+ return cacheNodeId;
13646
+ });
13647
+ solutionPathsInCacheSpace[cacheConnectionId] = cachePathNodeIds;
13648
+ }
13649
+ cachedSolution = {
13650
+ success: true,
13651
+ sectionScore: this.sectionScore,
13652
+ solutionPaths: solutionPathsInCacheSpace
13653
+ };
13654
+ } else {
13655
+ return;
13656
+ }
13657
+ try {
13658
+ this.cacheProvider?.setCachedSolutionSync(this.cacheKey, cachedSolution);
13659
+ } catch (error) {
13660
+ console.error("Error saving solution to cache:", error);
13661
+ }
13662
+ }
13663
+ get sectionConnectionTerminals() {
13664
+ if (this.cacheHit && this.solved && this.cachedSectionConnectionTerminals) {
13665
+ console.log("returning the cached section connection terminals");
13666
+ return this.cachedSectionConnectionTerminals;
13667
+ }
13668
+ return super.sectionConnectionTerminals;
13669
+ }
13670
+ visualize() {
13671
+ if (!this.cacheHit) return super.visualize();
13672
+ const graphics = visualizeSection({
13673
+ sectionNodes: this.constructorParams.sectionNodes,
13674
+ sectionEdges: this.constructorParams.sectionEdges,
13675
+ sectionConnectionTerminals: this.cachedSectionConnectionTerminals,
13676
+ completedPaths: this.cachedSectionConnectionTerminals.map((t) => ({
13677
+ connectionName: t.connectionName,
13678
+ path: t.path
13679
+ })),
13680
+ nodeMap: this.constructorParams.nodeMap,
13681
+ colorMap: this.constructorParams.colorMap,
13682
+ title: "CachedHyperCapacityPathingSingleSectionSolver"
13683
+ });
13684
+ return graphics;
13214
13685
  }
13215
- return {
13216
- sectionConnectionTerminals,
13217
- sectionNodes,
13218
- sectionEdges,
13219
- centerNodeId
13220
- };
13221
13686
  };
13222
13687
 
13223
13688
  // lib/solvers/CapacityPathingSectionSolver/CapacityPathingMultiSectionSolver.ts
@@ -13230,8 +13695,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13230
13695
  // Initialize here
13231
13696
  colorMap;
13232
13697
  initialSolver;
13698
+ cacheProvider;
13233
13699
  stage = "initialization";
13234
13700
  nodeMap = /* @__PURE__ */ new Map();
13701
+ allNodeIdsSet;
13235
13702
  usedNodeCapacityMap = /* @__PURE__ */ new Map();
13236
13703
  totalNodeCapacityMap = /* @__PURE__ */ new Map();
13237
13704
  // Added
@@ -13241,6 +13708,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13241
13708
  sectionSolver = null;
13242
13709
  currentScheduleIndex = 0;
13243
13710
  stats;
13711
+ // Adjusting this schedule is a trade-off between optimization speed and quality.
13244
13712
  OPTIMIZATION_SCHEDULE = [
13245
13713
  {
13246
13714
  MAX_ATTEMPTS_PER_NODE: 1,
@@ -13255,7 +13723,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13255
13723
  {
13256
13724
  MAX_ATTEMPTS_PER_NODE: 3,
13257
13725
  MAX_EXPANSION_DEGREES: 7,
13258
- MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.3
13726
+ MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.9
13259
13727
  }
13260
13728
  ];
13261
13729
  get currentSchedule() {
@@ -13267,6 +13735,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13267
13735
  successfulOptimizations: 0,
13268
13736
  failedOptimizations: 0,
13269
13737
  failedSectionSolvers: 0,
13738
+ startingScore: 0,
13270
13739
  scheduleScores: this.OPTIMIZATION_SCHEDULE.map(
13271
13740
  ({ MAX_EXPANSION_DEGREES }) => ({
13272
13741
  maxExpansionDegrees: MAX_EXPANSION_DEGREES,
@@ -13277,6 +13746,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13277
13746
  )
13278
13747
  };
13279
13748
  this.MAX_ITERATIONS = 1e7;
13749
+ this.cacheProvider = params.cacheProvider;
13280
13750
  this.simpleRouteJson = params.simpleRouteJson;
13281
13751
  this.nodes = params.nodes;
13282
13752
  this.edges = params.edges;
@@ -13297,6 +13767,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13297
13767
  const totalCapacity = this.initialSolver.getTotalCapacity(node);
13298
13768
  this.totalNodeCapacityMap.set(node.capacityMeshNodeId, totalCapacity);
13299
13769
  }
13770
+ this.allNodeIdsSet = new Set(this.nodes.map((n) => n.capacityMeshNodeId));
13300
13771
  }
13301
13772
  _stepInitialization() {
13302
13773
  this.initialSolver?.step();
@@ -13315,6 +13786,12 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13315
13786
  this.nodeOptimizationAttemptCountMap.set(node.capacityMeshNodeId, 0);
13316
13787
  }
13317
13788
  this.connectionsWithNodes = this.initialSolver.connectionsWithNodes;
13789
+ this.stats.startingScore = computeSectionScore({
13790
+ totalNodeCapacityMap: this.totalNodeCapacityMap,
13791
+ usedNodeCapacityMap: this.usedNodeCapacityMap,
13792
+ nodeMap: this.nodeMap,
13793
+ sectionNodeIds: this.allNodeIdsSet
13794
+ });
13318
13795
  this.stage = "section-optimization";
13319
13796
  }
13320
13797
  }
@@ -13366,9 +13843,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13366
13843
  totalNodeCapacityMap: this.totalNodeCapacityMap,
13367
13844
  usedNodeCapacityMap: this.usedNodeCapacityMap,
13368
13845
  nodeMap: this.nodeMap,
13369
- sectionNodeIds: new Set(
13370
- this.nodes.map((node) => node.capacityMeshNodeId)
13371
- )
13846
+ sectionNodeIds: this.allNodeIdsSet
13372
13847
  })
13373
13848
  };
13374
13849
  }
@@ -13396,13 +13871,17 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13396
13871
  });
13397
13872
  this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++;
13398
13873
  this.currentSection = section;
13399
- this.sectionSolver = new HyperCapacityPathingSingleSectionSolver({
13874
+ this.sectionSolver = new CachedHyperCapacityPathingSingleSectionSolver({
13400
13875
  sectionNodes: this.currentSection.sectionNodes,
13401
13876
  sectionEdges: this.currentSection.sectionEdges,
13402
13877
  sectionConnectionTerminals: this.currentSection.sectionConnectionTerminals,
13403
13878
  colorMap: this.colorMap,
13404
13879
  centerNodeId: this.currentSection.centerNodeId,
13405
- nodeEdgeMap: this.nodeEdgeMap
13880
+ nodeEdgeMap: this.nodeEdgeMap,
13881
+ hyperParameters: {
13882
+ EXPANSION_DEGREES: this.currentSchedule.MAX_EXPANSION_DEGREES
13883
+ },
13884
+ cacheProvider: this.cacheProvider
13406
13885
  });
13407
13886
  this.activeSubSolver = this.sectionSolver;
13408
13887
  this.nodeOptimizationAttemptCountMap.set(
@@ -13422,18 +13901,19 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13422
13901
  return;
13423
13902
  }
13424
13903
  if (this.sectionSolver.solved) {
13425
- const solvedSectionSolver = this.sectionSolver;
13426
- const pathingSolver = solvedSectionSolver?.activeSubSolver || solvedSectionSolver;
13904
+ const sectionConnectionTerminals = this.sectionSolver.sectionConnectionTerminals;
13905
+ const sectionNodes = this.sectionSolver.sectionNodes;
13906
+ const centerNodeId = this.sectionSolver.centerNodeId;
13427
13907
  this.sectionSolver = null;
13428
13908
  this.activeSubSolver = null;
13429
- if (!pathingSolver || !pathingSolver.solved) {
13909
+ if (!sectionConnectionTerminals) {
13430
13910
  console.warn(
13431
13911
  `Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`
13432
13912
  );
13433
13913
  return;
13434
13914
  }
13435
13915
  const sectionNodeIds = new Set(
13436
- solvedSectionSolver.sectionNodes.map((n) => n.capacityMeshNodeId)
13916
+ sectionNodes.map((n) => n.capacityMeshNodeId)
13437
13917
  );
13438
13918
  const beforeScore = computeSectionScore({
13439
13919
  totalNodeCapacityMap: this.totalNodeCapacityMap,
@@ -13442,7 +13922,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13442
13922
  sectionNodeIds
13443
13923
  });
13444
13924
  const afterUsedCapacityMap = new Map(this.usedNodeCapacityMap);
13445
- const newSectionPaths = pathingSolver.sectionConnectionTerminals;
13925
+ const newSectionPaths = sectionConnectionTerminals;
13446
13926
  for (const terminal of newSectionPaths) {
13447
13927
  const originalConnection = this.connectionsWithNodes.find(
13448
13928
  (conn) => conn.connection.name === terminal.connectionName
@@ -13479,7 +13959,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13479
13959
  });
13480
13960
  if (afterScore > beforeScore) {
13481
13961
  this.stats.successfulOptimizations++;
13482
- this._mergeSolvedSectionPaths(solvedSectionSolver);
13962
+ this._mergeSolvedSectionPaths({
13963
+ centerNodeId,
13964
+ sectionConnectionTerminals
13965
+ });
13483
13966
  this._recalculateNodeCapacityUsage();
13484
13967
  } else {
13485
13968
  this.stats.failedOptimizations++;
@@ -13490,16 +13973,11 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13490
13973
  * Merges the paths found by a successful section solver back into the main
13491
13974
  * connectionsWithNodes list.
13492
13975
  */
13493
- _mergeSolvedSectionPaths(solvedSectionSolver) {
13494
- const centerNodeId = solvedSectionSolver.centerNodeId;
13495
- if (!solvedSectionSolver || !solvedSectionSolver.solved) {
13496
- console.warn(
13497
- `Pathing sub-solver for section ${centerNodeId} did not complete successfully. Skipping merge.`
13498
- );
13499
- return;
13500
- }
13501
- const solvedTerminals = solvedSectionSolver.sectionConnectionTerminals;
13502
- for (const solvedTerminal of solvedTerminals) {
13976
+ _mergeSolvedSectionPaths({
13977
+ centerNodeId,
13978
+ sectionConnectionTerminals
13979
+ }) {
13980
+ for (const solvedTerminal of sectionConnectionTerminals) {
13503
13981
  if (!solvedTerminal.path) {
13504
13982
  console.warn(
13505
13983
  `No path found for connection ${solvedTerminal.connectionName} in section ${centerNodeId}`
@@ -13511,7 +13989,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13511
13989
  );
13512
13990
  if (!originalConnection || !originalConnection.path) {
13513
13991
  console.warn(
13514
- `Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${solvedSectionSolver.centerNodeId}`
13992
+ `Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${centerNodeId}`
13515
13993
  );
13516
13994
  continue;
13517
13995
  }
@@ -15858,7 +16336,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
15858
16336
  }
15859
16337
  this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
15860
16338
  this.colorMap = getColorMap(srj, this.connMap);
15861
- this.cacheProvider = opts.cacheProvider ?? null;
16339
+ this.cacheProvider = opts.cacheProvider === void 0 ? getGlobalInMemoryCache() : opts.cacheProvider === null ? null : opts.cacheProvider;
15862
16340
  this.startTimeOfPhase = {};
15863
16341
  this.endTimeOfPhase = {};
15864
16342
  this.timeSpentOnPhase = {};
@@ -15982,6 +16460,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
15982
16460
  nodes: cms.capacityNodes,
15983
16461
  edges: cms.edgeSolver?.edges || [],
15984
16462
  colorMap: cms.colorMap,
16463
+ cacheProvider: cms.cacheProvider,
15985
16464
  hyperParameters: {
15986
16465
  MAX_CAPACITY_FACTOR: 1
15987
16466
  }
@@ -16324,7 +16803,12 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
16324
16803
  var CapacityMeshSolver = AutoroutingPipelineSolver;
16325
16804
  export {
16326
16805
  CapacityMeshSolver,
16806
+ InMemoryCache,
16807
+ LocalStorageCache,
16327
16808
  calculateOptimalCapacityDepth,
16328
- getTunedTotalCapacity1
16809
+ getGlobalInMemoryCache,
16810
+ getGlobalLocalStorageCache,
16811
+ getTunedTotalCapacity1,
16812
+ setupGlobalCaches
16329
16813
  };
16330
16814
  //# sourceMappingURL=index.js.map