@tscircuit/capacity-autorouter 0.0.61 → 0.0.63

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++) {
@@ -3897,7 +3943,12 @@ var IntraNodeRouteSolver = class extends BaseSolver {
3897
3943
  y: points[points.length - 1].y,
3898
3944
  z: points[points.length - 1].z
3899
3945
  },
3900
- obstacleRoutes: this.solvedRoutes,
3946
+ obstacleRoutes: this.connMap ? this.solvedRoutes.filter(
3947
+ (sr) => !this.connMap.areIdsConnected(
3948
+ sr.connectionName,
3949
+ connectionName
3950
+ )
3951
+ ) : this.solvedRoutes,
3901
3952
  futureConnections: this.unsolvedConnections,
3902
3953
  layerCount: 2,
3903
3954
  hyperParameters: this.hyperParameters,
@@ -8837,9 +8888,11 @@ var HyperSingleIntraNodeSolver = class extends HyperParameterSupervisorSolver {
8837
8888
  constructorParams;
8838
8889
  solvedRoutes = [];
8839
8890
  nodeWithPortPoints;
8891
+ connMap;
8840
8892
  constructor(opts) {
8841
8893
  super();
8842
8894
  this.nodeWithPortPoints = opts.nodeWithPortPoints;
8895
+ this.connMap = opts.connMap;
8843
8896
  this.constructorParams = opts;
8844
8897
  this.MAX_ITERATIONS = 25e4;
8845
8898
  this.GREEDY_MULTIPLIER = 5;
@@ -8983,6 +9036,7 @@ var HyperSingleIntraNodeSolver = class extends HyperParameterSupervisorSolver {
8983
9036
  if (hyperParameters.MULTI_HEAD_POLYLINE_SOLVER) {
8984
9037
  return new MultiHeadPolyLineIntraNodeSolver3({
8985
9038
  nodeWithPortPoints: this.nodeWithPortPoints,
9039
+ connMap: this.connMap,
8986
9040
  hyperParameters
8987
9041
  });
8988
9042
  }
@@ -9071,7 +9125,7 @@ var HighDensitySolver = class extends BaseSolver {
9071
9125
  if (this.failedSolvers.length > 0) {
9072
9126
  this.solved = false;
9073
9127
  this.failed = true;
9074
- this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((fs) => fs.nodeWithPortPoints.capacityMeshNodeId)}`;
9128
+ this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((fs) => fs.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`;
9075
9129
  return;
9076
9130
  }
9077
9131
  this.solved = true;
@@ -10929,6 +10983,8 @@ import objectHash from "object-hash";
10929
10983
 
10930
10984
  // lib/cache/InMemoryCache.ts
10931
10985
  var InMemoryCache = class {
10986
+ cacheHitsByPrefix = {};
10987
+ cacheMissesByPrefix = {};
10932
10988
  isSyncCache = true;
10933
10989
  cacheHits = 0;
10934
10990
  cacheMisses = 0;
@@ -10994,6 +11050,8 @@ var LocalStorageCache = class {
10994
11050
  isSyncCache = true;
10995
11051
  cacheHits = 0;
10996
11052
  cacheMisses = 0;
11053
+ cacheHitsByPrefix = {};
11054
+ cacheMissesByPrefix = {};
10997
11055
  constructor() {
10998
11056
  if (typeof localStorage === "undefined") {
10999
11057
  console.warn(
@@ -11018,14 +11076,20 @@ var LocalStorageCache = class {
11018
11076
  if (cachedItem !== null) {
11019
11077
  const solution = JSON.parse(cachedItem);
11020
11078
  this.cacheHits++;
11079
+ const prefix = cacheKey.split(":")[0];
11080
+ this.cacheHitsByPrefix[prefix] = (this.cacheHitsByPrefix[prefix] || 0) + 1;
11021
11081
  return solution;
11022
11082
  } else {
11023
11083
  this.cacheMisses++;
11084
+ const prefix = cacheKey.split(":")[0];
11085
+ this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
11024
11086
  return void 0;
11025
11087
  }
11026
11088
  } catch (error) {
11027
11089
  console.error(`Error getting cached solution sync for ${key}:`, error);
11028
11090
  this.cacheMisses++;
11091
+ const prefix = cacheKey.split(":")[0];
11092
+ this.cacheMissesByPrefix[prefix] = (this.cacheMissesByPrefix[prefix] || 0) + 1;
11029
11093
  return void 0;
11030
11094
  }
11031
11095
  }
@@ -11090,6 +11154,8 @@ var LocalStorageCache = class {
11090
11154
  } finally {
11091
11155
  this.cacheHits = 0;
11092
11156
  this.cacheMisses = 0;
11157
+ this.cacheHitsByPrefix = {};
11158
+ this.cacheMissesByPrefix = {};
11093
11159
  }
11094
11160
  }
11095
11161
  getAllCacheKeys() {
@@ -11111,6 +11177,12 @@ function getGlobalLocalStorageCache() {
11111
11177
  }
11112
11178
  return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE;
11113
11179
  }
11180
+ function getGlobalInMemoryCache() {
11181
+ if (!globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE) {
11182
+ setupGlobalCaches();
11183
+ }
11184
+ return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE;
11185
+ }
11114
11186
  function setupGlobalCaches() {
11115
11187
  globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE ??= new LocalStorageCache();
11116
11188
  globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE ??= new InMemoryCache();
@@ -12513,6 +12585,21 @@ var calculateNodeProbabilityOfFailure2 = (usedCapacity, totalCapacity, layerCoun
12513
12585
  const adjustedRatio = ratioOverTotal - 1;
12514
12586
  return 1 - Math.exp(-k * adjustedRatio);
12515
12587
  };
12588
+ var calculateSingleNodeLogSuccessProbability = (usedCapacity, totalCapacity, node) => {
12589
+ if (node._containsTarget) return 0;
12590
+ if (usedCapacity <= totalCapacity) return 0;
12591
+ const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
12592
+ usedCapacity,
12593
+ totalCapacity,
12594
+ node.availableZ.length
12595
+ );
12596
+ const probabilityOfSuccess = 1 - probabilityOfFailure;
12597
+ if (probabilityOfSuccess <= 0) {
12598
+ return -1e9;
12599
+ } else {
12600
+ return Math.log(probabilityOfSuccess);
12601
+ }
12602
+ };
12516
12603
  var computeSectionScore = ({
12517
12604
  totalNodeCapacityMap,
12518
12605
  usedNodeCapacityMap,
@@ -12526,21 +12613,13 @@ var computeSectionScore = ({
12526
12613
  if (!totalNodeCapacityMap.has(nodeId)) continue;
12527
12614
  const node = nodeMap.get(nodeId);
12528
12615
  if (!node) continue;
12529
- if (node._containsTarget) continue;
12530
12616
  const totalCapacity = totalNodeCapacityMap.get(nodeId);
12531
12617
  const usedCapacity = usedNodeCapacityMap.get(nodeId) ?? 0;
12532
- if (usedCapacity <= totalCapacity) continue;
12533
- const probabilityOfFailure = calculateNodeProbabilityOfFailure2(
12618
+ logProbabilityOfSuccessSum += calculateSingleNodeLogSuccessProbability(
12534
12619
  usedCapacity,
12535
12620
  totalCapacity,
12536
- node.availableZ.length
12621
+ node
12537
12622
  );
12538
- const probabilityOfSuccess = 1 - probabilityOfFailure;
12539
- if (probabilityOfSuccess <= 0) {
12540
- logProbabilityOfSuccessSum += -1e9;
12541
- } else {
12542
- logProbabilityOfSuccessSum += Math.log(probabilityOfSuccess);
12543
- }
12544
12623
  }
12545
12624
  return logProbabilityOfSuccessSum;
12546
12625
  };
@@ -12721,9 +12800,9 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
12721
12800
  x: x + offset.x,
12722
12801
  y: y + offset.y
12723
12802
  })),
12724
- strokeColor: safeTransparentize(pathColor, 0.2),
12803
+ strokeColor: safeTransparentize(pathColor, 0.2)
12725
12804
  // Make solved paths semi-transparent
12726
- strokeWidth: 0.03
12805
+ // strokeWidth: 0.03,
12727
12806
  });
12728
12807
  }
12729
12808
  });
@@ -12731,6 +12810,72 @@ ${percent}% (Pf: ${(probabilityOfFailure * 100).toFixed(1)}%)`;
12731
12810
  return graphics;
12732
12811
  }
12733
12812
 
12813
+ // lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
12814
+ var computeSectionNodesTerminalsAndEdges = (opts) => {
12815
+ const {
12816
+ centerNodeId,
12817
+ connectionsWithNodes,
12818
+ nodeMap,
12819
+ edges,
12820
+ nodeEdgeMap,
12821
+ expansionDegrees
12822
+ } = opts;
12823
+ const sectionNodeIds = /* @__PURE__ */ new Set();
12824
+ const queue = [
12825
+ { nodeId: centerNodeId, depth: 0 }
12826
+ ];
12827
+ sectionNodeIds.add(centerNodeId);
12828
+ let head = 0;
12829
+ while (head < queue.length) {
12830
+ const { nodeId, depth } = queue[head++];
12831
+ if (depth >= expansionDegrees) continue;
12832
+ const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
12833
+ for (const neighborId of neighbors) {
12834
+ if (!sectionNodeIds.has(neighborId)) {
12835
+ sectionNodeIds.add(neighborId);
12836
+ queue.push({ nodeId: neighborId, depth: depth + 1 });
12837
+ }
12838
+ }
12839
+ }
12840
+ const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
12841
+ const sectionEdges = edges.filter((edge) => {
12842
+ const [nodeIdA, nodeIdB] = edge.nodeIds;
12843
+ return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
12844
+ });
12845
+ const sectionConnectionTerminals = [];
12846
+ for (const conn of connectionsWithNodes) {
12847
+ if (!conn.path) continue;
12848
+ let startNodeId = null;
12849
+ let endNodeId = null;
12850
+ for (const node of conn.path) {
12851
+ if (sectionNodeIds.has(node.capacityMeshNodeId)) {
12852
+ startNodeId = node.capacityMeshNodeId;
12853
+ break;
12854
+ }
12855
+ }
12856
+ for (let i = conn.path.length - 1; i >= 0; i--) {
12857
+ const node = conn.path[i];
12858
+ if (sectionNodeIds.has(node.capacityMeshNodeId)) {
12859
+ endNodeId = node.capacityMeshNodeId;
12860
+ break;
12861
+ }
12862
+ }
12863
+ if (startNodeId && endNodeId) {
12864
+ sectionConnectionTerminals.push({
12865
+ connectionName: conn.connection.name,
12866
+ startNodeId,
12867
+ endNodeId
12868
+ });
12869
+ }
12870
+ }
12871
+ return {
12872
+ sectionConnectionTerminals,
12873
+ sectionNodes,
12874
+ sectionEdges,
12875
+ centerNodeId
12876
+ };
12877
+ };
12878
+
12734
12879
  // lib/solvers/CapacityPathingSectionSolver/CapacityPathingSingleSectionSolver.ts
12735
12880
  var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12736
12881
  GREEDY_MULTIPLIER = 1.5;
@@ -12744,7 +12889,10 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12744
12889
  colorMap;
12745
12890
  usedNodeCapacityMap;
12746
12891
  // Tracks capacity usage *within this solver's run*
12892
+ totalNodeCapacityMap;
12893
+ // Added: Stores total capacity for each node
12747
12894
  centerNodeId;
12895
+ currentSectionScore = 0;
12748
12896
  MAX_CANDIDATES_IN_MEMORY = 1e4;
12749
12897
  // A* state
12750
12898
  currentConnectionIndex = 0;
@@ -12765,14 +12913,28 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12765
12913
  this.sectionConnectionTerminals = params.sectionConnectionTerminals.map(
12766
12914
  (t) => ({ ...t, path: void 0 })
12767
12915
  );
12768
- this.nodeMap = new Map(
12769
- this.sectionNodes.map((n) => [n.capacityMeshNodeId, n])
12770
- );
12916
+ this.nodeMap = params.nodeMap ?? new Map(this.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
12771
12917
  this.nodeEdgeMap = params.nodeEdgeMap ?? getNodeEdgeMap(this.sectionEdges);
12772
12918
  this.colorMap = params.colorMap ?? {};
12773
12919
  this.usedNodeCapacityMap = new Map(
12774
12920
  this.sectionNodes.map((node) => [node.capacityMeshNodeId, 0])
12775
12921
  );
12922
+ this.totalNodeCapacityMap = new Map(
12923
+ this.sectionNodes.map((node) => [
12924
+ node.capacityMeshNodeId,
12925
+ this.getTotalCapacity(node)
12926
+ ])
12927
+ );
12928
+ const initialSectionNodeIds = new Set(
12929
+ this.sectionNodes.map((n) => n.capacityMeshNodeId)
12930
+ );
12931
+ this.currentSectionScore = computeSectionScore({
12932
+ totalNodeCapacityMap: this.totalNodeCapacityMap,
12933
+ usedNodeCapacityMap: this.usedNodeCapacityMap,
12934
+ // Reflects initial capacities
12935
+ nodeMap: this.nodeMap,
12936
+ sectionNodeIds: initialSectionNodeIds
12937
+ });
12776
12938
  if (params.hyperParameters?.SHUFFLE_SEED) {
12777
12939
  this.sectionConnectionTerminals = cloneAndShuffleArray(
12778
12940
  this.sectionConnectionTerminals,
@@ -12852,15 +13014,40 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
12852
13014
  }
12853
13015
  // Adapted from CapacityPathingSolver - uses section's capacity map
12854
13016
  reduceCapacityAlongPath(path) {
12855
- for (const node of path) {
12856
- if (this.usedNodeCapacityMap.has(node.capacityMeshNodeId)) {
12857
- this.usedNodeCapacityMap.set(
12858
- node.capacityMeshNodeId,
12859
- (this.usedNodeCapacityMap.get(node.capacityMeshNodeId) ?? 0) + 1
13017
+ for (const pathNode of path) {
13018
+ if (this.usedNodeCapacityMap.has(pathNode.capacityMeshNodeId)) {
13019
+ const nodeId = pathNode.capacityMeshNodeId;
13020
+ const nodeInSection = this.nodeMap.get(nodeId);
13021
+ if (!nodeInSection) {
13022
+ console.warn(
13023
+ `Node ${nodeId} from path not found in section's nodeMap during score update.`
13024
+ );
13025
+ continue;
13026
+ }
13027
+ const totalCapacity = this.totalNodeCapacityMap.get(nodeId);
13028
+ const oldUsedCapacity = this.usedNodeCapacityMap.get(nodeId) ?? 0;
13029
+ const oldNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
13030
+ oldUsedCapacity,
13031
+ totalCapacity,
13032
+ nodeInSection
13033
+ // Use the node object from the section's map
12860
13034
  );
13035
+ this.currentSectionScore -= oldNodeScoreContribution;
13036
+ const newUsedCapacity = oldUsedCapacity + 1;
13037
+ this.usedNodeCapacityMap.set(nodeId, newUsedCapacity);
13038
+ const newNodeScoreContribution = calculateSingleNodeLogSuccessProbability(
13039
+ newUsedCapacity,
13040
+ totalCapacity,
13041
+ nodeInSection
13042
+ // Use the node object from the section's map
13043
+ );
13044
+ this.currentSectionScore += newNodeScoreContribution;
12861
13045
  }
12862
13046
  }
12863
13047
  }
13048
+ getSolvedSectionScore() {
13049
+ return this.currentSectionScore;
13050
+ }
12864
13051
  _step() {
12865
13052
  const currentTerminal = this.sectionConnectionTerminals[this.currentConnectionIndex];
12866
13053
  if (!currentTerminal) {
@@ -13062,6 +13249,7 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
13062
13249
  var CapacityPathingSingleSectionPathingSolver = CapacityPathingSingleSectionSolver;
13063
13250
 
13064
13251
  // lib/solvers/CapacityPathingSectionSolver/HyperCapacityPathingSingleSectionSolver.ts
13252
+ var range = (n) => Array.from({ length: n }, (_, i) => i);
13065
13253
  var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSupervisorSolver {
13066
13254
  constructorParams;
13067
13255
  winningSolver;
@@ -13070,14 +13258,24 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13070
13258
  this.MAX_ITERATIONS = 1e5;
13071
13259
  this.constructorParams = params;
13072
13260
  }
13261
+ // TODO this needs to use the section score, ideally incorporating the current best candidate
13262
+ // of the paths being explored inside the single section
13073
13263
  computeG(solver) {
13074
- return solver.iterations / 100;
13264
+ return -solver.getSolvedSectionScore();
13075
13265
  }
13076
13266
  computeH(solver) {
13077
- return solver.computeProgress();
13267
+ return 0;
13078
13268
  }
13079
13269
  getCombinationDefs() {
13080
- return [["orderings10"]];
13270
+ const numConnections = this.constructorParams.sectionConnectionTerminals.length;
13271
+ if (numConnections === 2) {
13272
+ return [["orderings2_for2"]];
13273
+ } else if (numConnections === 3) {
13274
+ return [["orderings6_for3"]];
13275
+ } else if (numConnections === 4) {
13276
+ return [["orderings24_for4"]];
13277
+ }
13278
+ return [["orderings30"]];
13081
13279
  }
13082
13280
  getFailureMessage() {
13083
13281
  return `All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`;
@@ -13085,39 +13283,28 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13085
13283
  getHyperParameterDefs() {
13086
13284
  return [
13087
13285
  {
13088
- name: "orderings10",
13089
- possibleValues: [
13090
- {
13091
- SHUFFLE_SEED: 0
13092
- },
13093
- {
13094
- SHUFFLE_SEED: 1
13095
- },
13096
- {
13097
- SHUFFLE_SEED: 2
13098
- },
13099
- {
13100
- SHUFFLE_SEED: 3
13101
- },
13102
- {
13103
- SHUFFLE_SEED: 4
13104
- },
13105
- {
13106
- SHUFFLE_SEED: 5
13107
- },
13108
- {
13109
- SHUFFLE_SEED: 6
13110
- },
13111
- {
13112
- SHUFFLE_SEED: 7
13113
- },
13114
- {
13115
- SHUFFLE_SEED: 8
13116
- },
13117
- {
13118
- SHUFFLE_SEED: 9
13119
- }
13120
- ]
13286
+ name: "orderings2_for2",
13287
+ possibleValues: range(2).map((i) => ({
13288
+ SHUFFLE_SEED: i
13289
+ }))
13290
+ },
13291
+ {
13292
+ name: "orderings6_for3",
13293
+ possibleValues: range(6).map((i) => ({
13294
+ SHUFFLE_SEED: i
13295
+ }))
13296
+ },
13297
+ {
13298
+ name: "orderings24_for4",
13299
+ possibleValues: range(24).map((i) => ({
13300
+ SHUFFLE_SEED: i
13301
+ }))
13302
+ },
13303
+ {
13304
+ name: "orderings30",
13305
+ possibleValues: range(30).map((i) => ({
13306
+ SHUFFLE_SEED: i
13307
+ }))
13121
13308
  }
13122
13309
  ];
13123
13310
  }
@@ -13146,70 +13333,320 @@ var HyperCapacityPathingSingleSectionSolver = class extends HyperParameterSuperv
13146
13333
  }
13147
13334
  };
13148
13335
 
13149
- // lib/solvers/CapacityPathingSectionSolver/computeSectionNodesTerminalsAndEdges.ts
13150
- var computeSectionNodesTerminalsAndEdges = (opts) => {
13151
- const {
13152
- centerNodeId,
13153
- connectionsWithNodes,
13154
- nodeMap,
13155
- edges,
13156
- nodeEdgeMap,
13157
- expansionDegrees
13158
- } = opts;
13159
- const sectionNodeIds = /* @__PURE__ */ new Set();
13160
- const queue = [
13161
- { nodeId: centerNodeId, depth: 0 }
13162
- ];
13163
- sectionNodeIds.add(centerNodeId);
13164
- let head = 0;
13165
- while (head < queue.length) {
13166
- const { nodeId, depth } = queue[head++];
13167
- if (depth >= expansionDegrees) continue;
13168
- const neighbors = nodeEdgeMap.get(nodeId)?.flatMap((edge) => edge.nodeIds.filter((id) => id !== nodeId)) ?? [];
13169
- for (const neighborId of neighbors) {
13170
- if (!sectionNodeIds.has(neighborId)) {
13171
- sectionNodeIds.add(neighborId);
13172
- queue.push({ nodeId: neighborId, depth: depth + 1 });
13173
- }
13336
+ // lib/solvers/CapacityPathingSectionSolver/CachedHyperCapacityPathingSingleSectionSolver.ts
13337
+ import objectHash2 from "object-hash";
13338
+ var roundCapacity = (capacity) => Math.floor(capacity * 10) / 10;
13339
+ var CachedHyperCapacityPathingSingleSectionSolver = class extends HyperCapacityPathingSingleSectionSolver {
13340
+ cacheHit = false;
13341
+ cacheProvider;
13342
+ hasAttemptedToUseCache = false;
13343
+ sectionNodeIdSet;
13344
+ cachedSectionConnectionTerminals = null;
13345
+ sectionScore = 0;
13346
+ constructor(params) {
13347
+ params.nodeMap = params.nodeMap ?? new Map(params.sectionNodes.map((n) => [n.capacityMeshNodeId, n]));
13348
+ super(params);
13349
+ this.sectionNodeIdSet = new Set(
13350
+ params.sectionNodes.map((sn) => sn.capacityMeshNodeId)
13351
+ );
13352
+ this.cacheProvider = params.cacheProvider === void 0 ? getGlobalInMemoryCache() : params.cacheProvider;
13353
+ }
13354
+ _step() {
13355
+ if (!this.hasAttemptedToUseCache && this.cacheProvider) {
13356
+ if (this.attemptToUseCacheSync()) return;
13357
+ }
13358
+ super._step();
13359
+ if ((this.solved || this.failed) && this.cacheProvider) {
13360
+ this.saveToCacheSync();
13174
13361
  }
13175
13362
  }
13176
- const sectionNodes = Array.from(sectionNodeIds).map((id) => nodeMap.get(id));
13177
- const sectionEdges = edges.filter((edge) => {
13178
- const [nodeIdA, nodeIdB] = edge.nodeIds;
13179
- return sectionNodeIds.has(nodeIdA) && sectionNodeIds.has(nodeIdB);
13180
- });
13181
- const sectionConnectionTerminals = [];
13182
- for (const conn of connectionsWithNodes) {
13183
- if (!conn.path) continue;
13184
- let startNodeId = null;
13185
- let endNodeId = null;
13186
- for (const node of conn.path) {
13187
- if (sectionNodeIds.has(node.capacityMeshNodeId)) {
13188
- startNodeId = node.capacityMeshNodeId;
13189
- break;
13363
+ _computeBfsOrderingOfNodesInSection() {
13364
+ const seenNodeIds = new Set(this.constructorParams.centerNodeId);
13365
+ const ordering = [];
13366
+ const candidates = [
13367
+ {
13368
+ ancestorCapacitySum: 0,
13369
+ capacity: 0,
13370
+ g: 0,
13371
+ capacityMeshNodeId: this.constructorParams.centerNodeId
13372
+ }
13373
+ ];
13374
+ while (candidates.length > 0) {
13375
+ candidates.sort((a, b) => b.g - a.g);
13376
+ const candidate = candidates.pop();
13377
+ if (!candidate) break;
13378
+ ordering.push(candidate.capacityMeshNodeId);
13379
+ const neighborNodeIds = this.constructorParams.nodeEdgeMap.get(candidate.capacityMeshNodeId).flatMap((edge) => edge.nodeIds).filter((nodeId) => !seenNodeIds.has(nodeId)).filter((nodeId) => this.sectionNodeIdSet.has(nodeId));
13380
+ for (const neighborNodeId of neighborNodeIds) {
13381
+ seenNodeIds.add(neighborNodeId);
13382
+ const neighbor = this.constructorParams.nodeMap.get(neighborNodeId);
13383
+ const capacity = getTunedTotalCapacity1(neighbor);
13384
+ candidates.push({
13385
+ ancestorCapacitySum: candidate.g,
13386
+ capacity,
13387
+ g: candidate.g + capacity,
13388
+ capacityMeshNodeId: neighborNodeId
13389
+ });
13190
13390
  }
13191
13391
  }
13192
- for (let i = conn.path.length - 1; i >= 0; i--) {
13193
- const node = conn.path[i];
13194
- if (sectionNodeIds.has(node.capacityMeshNodeId)) {
13195
- endNodeId = node.capacityMeshNodeId;
13196
- break;
13392
+ return ordering;
13393
+ }
13394
+ computeCacheKeyAndTransform() {
13395
+ const nodeOrdering = this._computeBfsOrderingOfNodesInSection();
13396
+ const realToCacheSpaceNodeIdMap = /* @__PURE__ */ new Map();
13397
+ const cacheSpaceToRealNodeIdMap = /* @__PURE__ */ new Map();
13398
+ nodeOrdering.forEach((realNodeId, i) => {
13399
+ const cacheNodeId = `node${i}`;
13400
+ realToCacheSpaceNodeIdMap.set(realNodeId, cacheNodeId);
13401
+ cacheSpaceToRealNodeIdMap.set(cacheNodeId, realNodeId);
13402
+ });
13403
+ const node_capacity_map = {};
13404
+ for (const realNodeId of nodeOrdering) {
13405
+ const cacheNodeId = realToCacheSpaceNodeIdMap.get(realNodeId);
13406
+ const node = this.constructorParams.nodeMap.get(realNodeId);
13407
+ const capacity = getTunedTotalCapacity1(node);
13408
+ node_capacity_map[cacheNodeId] = roundCapacity(capacity).toFixed(
13409
+ 1
13410
+ );
13411
+ }
13412
+ const node_edge_map_set = /* @__PURE__ */ new Set();
13413
+ const node_edge_map = [];
13414
+ for (const realNodeId1 of nodeOrdering) {
13415
+ const cacheNodeId1 = realToCacheSpaceNodeIdMap.get(realNodeId1);
13416
+ const neighbors = this.constructorParams.nodeEdgeMap.get(realNodeId1) ?? [];
13417
+ for (const edge of neighbors) {
13418
+ const realNodeId2 = edge.nodeIds.find((id) => id !== realNodeId1);
13419
+ if (this.sectionNodeIdSet.has(realNodeId2)) {
13420
+ const cacheNodeId2 = realToCacheSpaceNodeIdMap.get(realNodeId2);
13421
+ const pair = [cacheNodeId1, cacheNodeId2].sort();
13422
+ const pairKey = `${pair[0]}-${pair[1]}`;
13423
+ if (!node_edge_map_set.has(pairKey)) {
13424
+ node_edge_map.push(pair);
13425
+ node_edge_map_set.add(pairKey);
13426
+ }
13427
+ }
13197
13428
  }
13198
13429
  }
13199
- if (startNodeId && endNodeId) {
13200
- sectionConnectionTerminals.push({
13201
- connectionName: conn.connection.name,
13202
- startNodeId,
13203
- endNodeId
13430
+ node_edge_map.sort((a, b) => {
13431
+ if (a[0] !== b[0]) return a[0].localeCompare(b[0]);
13432
+ return a[1].localeCompare(b[1]);
13433
+ });
13434
+ const terminals = {};
13435
+ const cacheSpaceToRealConnectionId = /* @__PURE__ */ new Map();
13436
+ for (const conn of this.constructorParams.sectionConnectionTerminals) {
13437
+ const cacheStartNodeId = realToCacheSpaceNodeIdMap.get(conn.startNodeId);
13438
+ const cacheEndNodeId = realToCacheSpaceNodeIdMap.get(conn.endNodeId);
13439
+ const [sortedStartId, sortedEndId] = [
13440
+ cacheStartNodeId,
13441
+ cacheEndNodeId
13442
+ ].sort();
13443
+ const cacheSpaceConnectionId = `${sortedStartId}->${sortedEndId}`;
13444
+ terminals[cacheSpaceConnectionId] = {
13445
+ start: sortedStartId,
13446
+ end: sortedEndId
13447
+ };
13448
+ cacheSpaceToRealConnectionId.set(
13449
+ cacheSpaceConnectionId,
13450
+ // Use the canonically sorted key
13451
+ conn.connectionName
13452
+ );
13453
+ }
13454
+ const cacheKeyContent = {
13455
+ node_capacity_map,
13456
+ node_edge_map,
13457
+ terminals
13458
+ };
13459
+ const cacheKey = `capacitypathing:${objectHash2(cacheKeyContent)}`;
13460
+ const cacheToSolveSpaceTransform = {
13461
+ cacheSpaceToRealConnectionId,
13462
+ cacheSpaceToRealNodeId: cacheSpaceToRealNodeIdMap
13463
+ };
13464
+ this.cacheKey = cacheKey;
13465
+ this.cacheToSolveSpaceTransform = cacheToSolveSpaceTransform;
13466
+ return { cacheKey, cacheToSolveSpaceTransform };
13467
+ }
13468
+ applyCachedSolution(cachedSolution) {
13469
+ if (!this.cacheToSolveSpaceTransform) {
13470
+ console.error(
13471
+ "Cache transform not available, cannot apply cached solution."
13472
+ );
13473
+ this.failed = true;
13474
+ return;
13475
+ }
13476
+ if (!cachedSolution.success) {
13477
+ this.failed = true;
13478
+ this.cacheHit = true;
13479
+ return;
13480
+ }
13481
+ this.cachedSectionConnectionTerminals = [];
13482
+ const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
13483
+ for (const [cacheConnId, cachePathNodeIds] of Object.entries(
13484
+ cachedSolution.solutionPaths
13485
+ )) {
13486
+ const realConnectionName = cacheSpaceToRealConnectionId.get(
13487
+ cacheConnId
13488
+ );
13489
+ if (!realConnectionName) {
13490
+ console.warn(`Could not find real connection name for ${cacheConnId}`);
13491
+ continue;
13492
+ }
13493
+ const originalTerminal = this.constructorParams.sectionConnectionTerminals.find(
13494
+ (t) => t.connectionName === realConnectionName
13495
+ );
13496
+ if (!originalTerminal) {
13497
+ console.warn(
13498
+ `Could not find original terminal for connection name ${realConnectionName}`
13499
+ );
13500
+ continue;
13501
+ }
13502
+ const realPathNodes = cachePathNodeIds.map(
13503
+ (cacheNodeId) => {
13504
+ const realNodeId = cacheSpaceToRealNodeId.get(cacheNodeId);
13505
+ if (!realNodeId) {
13506
+ throw new Error(
13507
+ `Could not map cache node ID ${cacheNodeId} to real node ID for connection ${realConnectionName}`
13508
+ );
13509
+ }
13510
+ const node = this.constructorParams.nodeMap.get(realNodeId);
13511
+ if (!node) {
13512
+ throw new Error(
13513
+ `Could not find node with ID ${realNodeId} in nodeMap for connection ${realConnectionName}`
13514
+ );
13515
+ }
13516
+ return node;
13517
+ }
13518
+ );
13519
+ this.cachedSectionConnectionTerminals.push({
13520
+ ...originalTerminal,
13521
+ path: realPathNodes
13204
13522
  });
13205
13523
  }
13524
+ this.sectionScore = cachedSolution.sectionScore;
13525
+ this.solved = true;
13526
+ this.cacheHit = true;
13527
+ }
13528
+ attemptToUseCacheSync() {
13529
+ this.hasAttemptedToUseCache = true;
13530
+ if (!this.cacheProvider?.isSyncCache) {
13531
+ console.log(
13532
+ "Cache provider is not synchronous, skipping sync cache check."
13533
+ );
13534
+ return false;
13535
+ }
13536
+ if (!this.cacheKey) {
13537
+ this.computeCacheKeyAndTransform();
13538
+ }
13539
+ if (!this.cacheKey) {
13540
+ console.error("Failed to compute cache key.");
13541
+ return false;
13542
+ }
13543
+ try {
13544
+ const cachedSolution = this.cacheProvider.getCachedSolutionSync(
13545
+ this.cacheKey
13546
+ );
13547
+ if (cachedSolution) {
13548
+ this.applyCachedSolution(
13549
+ cachedSolution
13550
+ );
13551
+ return true;
13552
+ }
13553
+ } catch (error) {
13554
+ console.error("Error attempting to use cache:", error);
13555
+ }
13556
+ return false;
13557
+ }
13558
+ saveToCacheSync() {
13559
+ if (!this.cacheKey) {
13560
+ console.error("Cannot save to cache without cache key.");
13561
+ return;
13562
+ }
13563
+ if (!this.cacheToSolveSpaceTransform) {
13564
+ console.error(
13565
+ "Cache transform not available, cannot save solution to cache."
13566
+ );
13567
+ return;
13568
+ }
13569
+ let cachedSolution;
13570
+ if (this.failed) {
13571
+ cachedSolution = { success: false };
13572
+ } else if (this.solved) {
13573
+ const solutionPathsInCacheSpace = {};
13574
+ const { cacheSpaceToRealNodeId, cacheSpaceToRealConnectionId } = this.cacheToSolveSpaceTransform;
13575
+ const realToCacheSpaceNodeId = /* @__PURE__ */ new Map();
13576
+ for (const [cacheId, realId] of cacheSpaceToRealNodeId) {
13577
+ realToCacheSpaceNodeId.set(realId, cacheId);
13578
+ }
13579
+ const realToCacheSpaceConnectionId = /* @__PURE__ */ new Map();
13580
+ for (const [cacheConnId, realConnName] of cacheSpaceToRealConnectionId) {
13581
+ realToCacheSpaceConnectionId.set(realConnName, cacheConnId);
13582
+ }
13583
+ const realSolutionPaths = [];
13584
+ if (super.sectionConnectionTerminals) {
13585
+ for (const terminal of super.sectionConnectionTerminals) {
13586
+ if (terminal.path && terminal.path.length > 0) {
13587
+ const realPathNodeIds = terminal.path.map(
13588
+ (node) => node.capacityMeshNodeId
13589
+ );
13590
+ realSolutionPaths.push([terminal.connectionName, realPathNodeIds]);
13591
+ }
13592
+ }
13593
+ }
13594
+ for (const [realConnectionName, realPathNodeIds] of realSolutionPaths) {
13595
+ const cacheConnectionId = realToCacheSpaceConnectionId.get(realConnectionName);
13596
+ if (!cacheConnectionId) {
13597
+ console.warn(
13598
+ `Could not find cache space connection ID for ${realConnectionName} when saving to cache.`
13599
+ );
13600
+ continue;
13601
+ }
13602
+ const cachePathNodeIds = realPathNodeIds.map((realNodeId) => {
13603
+ const cacheNodeId = realToCacheSpaceNodeId.get(realNodeId);
13604
+ if (!cacheNodeId) {
13605
+ throw new Error(
13606
+ `Could not map real node ID ${realNodeId} to cache node ID for connection ${realConnectionName} when saving to cache.`
13607
+ );
13608
+ }
13609
+ return cacheNodeId;
13610
+ });
13611
+ solutionPathsInCacheSpace[cacheConnectionId] = cachePathNodeIds;
13612
+ }
13613
+ cachedSolution = {
13614
+ success: true,
13615
+ sectionScore: this.sectionScore,
13616
+ solutionPaths: solutionPathsInCacheSpace
13617
+ };
13618
+ } else {
13619
+ return;
13620
+ }
13621
+ try {
13622
+ this.cacheProvider?.setCachedSolutionSync(this.cacheKey, cachedSolution);
13623
+ } catch (error) {
13624
+ console.error("Error saving solution to cache:", error);
13625
+ }
13626
+ }
13627
+ get sectionConnectionTerminals() {
13628
+ if (this.cacheHit && this.solved && this.cachedSectionConnectionTerminals) {
13629
+ console.log("returning the cached section connection terminals");
13630
+ return this.cachedSectionConnectionTerminals;
13631
+ }
13632
+ return super.sectionConnectionTerminals;
13633
+ }
13634
+ visualize() {
13635
+ if (!this.cacheHit) return super.visualize();
13636
+ const graphics = visualizeSection({
13637
+ sectionNodes: this.constructorParams.sectionNodes,
13638
+ sectionEdges: this.constructorParams.sectionEdges,
13639
+ sectionConnectionTerminals: this.cachedSectionConnectionTerminals,
13640
+ completedPaths: this.cachedSectionConnectionTerminals.map((t) => ({
13641
+ connectionName: t.connectionName,
13642
+ path: t.path
13643
+ })),
13644
+ nodeMap: this.constructorParams.nodeMap,
13645
+ colorMap: this.constructorParams.colorMap,
13646
+ title: "CachedHyperCapacityPathingSingleSectionSolver"
13647
+ });
13648
+ return graphics;
13206
13649
  }
13207
- return {
13208
- sectionConnectionTerminals,
13209
- sectionNodes,
13210
- sectionEdges,
13211
- centerNodeId
13212
- };
13213
13650
  };
13214
13651
 
13215
13652
  // lib/solvers/CapacityPathingSectionSolver/CapacityPathingMultiSectionSolver.ts
@@ -13222,8 +13659,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13222
13659
  // Initialize here
13223
13660
  colorMap;
13224
13661
  initialSolver;
13662
+ cacheProvider;
13225
13663
  stage = "initialization";
13226
13664
  nodeMap = /* @__PURE__ */ new Map();
13665
+ allNodeIdsSet;
13227
13666
  usedNodeCapacityMap = /* @__PURE__ */ new Map();
13228
13667
  totalNodeCapacityMap = /* @__PURE__ */ new Map();
13229
13668
  // Added
@@ -13233,16 +13672,22 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13233
13672
  sectionSolver = null;
13234
13673
  currentScheduleIndex = 0;
13235
13674
  stats;
13675
+ // Adjusting this schedule is a trade-off between optimization speed and quality.
13236
13676
  OPTIMIZATION_SCHEDULE = [
13237
13677
  {
13238
13678
  MAX_ATTEMPTS_PER_NODE: 1,
13239
- MAX_EXPANSION_DEGREES: 5,
13240
- MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.1
13679
+ MAX_EXPANSION_DEGREES: 3,
13680
+ MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.05
13241
13681
  },
13242
13682
  {
13243
13683
  MAX_ATTEMPTS_PER_NODE: 2,
13244
- MAX_EXPANSION_DEGREES: 3,
13245
- MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.05
13684
+ MAX_EXPANSION_DEGREES: 5,
13685
+ MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.2
13686
+ },
13687
+ {
13688
+ MAX_ATTEMPTS_PER_NODE: 3,
13689
+ MAX_EXPANSION_DEGREES: 7,
13690
+ MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE: 0.9
13246
13691
  }
13247
13692
  ];
13248
13693
  get currentSchedule() {
@@ -13254,6 +13699,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13254
13699
  successfulOptimizations: 0,
13255
13700
  failedOptimizations: 0,
13256
13701
  failedSectionSolvers: 0,
13702
+ startingScore: 0,
13257
13703
  scheduleScores: this.OPTIMIZATION_SCHEDULE.map(
13258
13704
  ({ MAX_EXPANSION_DEGREES }) => ({
13259
13705
  maxExpansionDegrees: MAX_EXPANSION_DEGREES,
@@ -13264,6 +13710,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13264
13710
  )
13265
13711
  };
13266
13712
  this.MAX_ITERATIONS = 1e7;
13713
+ this.cacheProvider = params.cacheProvider;
13267
13714
  this.simpleRouteJson = params.simpleRouteJson;
13268
13715
  this.nodes = params.nodes;
13269
13716
  this.edges = params.edges;
@@ -13284,6 +13731,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13284
13731
  const totalCapacity = this.initialSolver.getTotalCapacity(node);
13285
13732
  this.totalNodeCapacityMap.set(node.capacityMeshNodeId, totalCapacity);
13286
13733
  }
13734
+ this.allNodeIdsSet = new Set(this.nodes.map((n) => n.capacityMeshNodeId));
13287
13735
  }
13288
13736
  _stepInitialization() {
13289
13737
  this.initialSolver?.step();
@@ -13302,6 +13750,12 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13302
13750
  this.nodeOptimizationAttemptCountMap.set(node.capacityMeshNodeId, 0);
13303
13751
  }
13304
13752
  this.connectionsWithNodes = this.initialSolver.connectionsWithNodes;
13753
+ this.stats.startingScore = computeSectionScore({
13754
+ totalNodeCapacityMap: this.totalNodeCapacityMap,
13755
+ usedNodeCapacityMap: this.usedNodeCapacityMap,
13756
+ nodeMap: this.nodeMap,
13757
+ sectionNodeIds: this.allNodeIdsSet
13758
+ });
13305
13759
  this.stage = "section-optimization";
13306
13760
  }
13307
13761
  }
@@ -13353,9 +13807,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13353
13807
  totalNodeCapacityMap: this.totalNodeCapacityMap,
13354
13808
  usedNodeCapacityMap: this.usedNodeCapacityMap,
13355
13809
  nodeMap: this.nodeMap,
13356
- sectionNodeIds: new Set(
13357
- this.nodes.map((node) => node.capacityMeshNodeId)
13358
- )
13810
+ sectionNodeIds: this.allNodeIdsSet
13359
13811
  })
13360
13812
  };
13361
13813
  }
@@ -13383,13 +13835,17 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13383
13835
  });
13384
13836
  this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++;
13385
13837
  this.currentSection = section;
13386
- this.sectionSolver = new HyperCapacityPathingSingleSectionSolver({
13838
+ this.sectionSolver = new CachedHyperCapacityPathingSingleSectionSolver({
13387
13839
  sectionNodes: this.currentSection.sectionNodes,
13388
13840
  sectionEdges: this.currentSection.sectionEdges,
13389
13841
  sectionConnectionTerminals: this.currentSection.sectionConnectionTerminals,
13390
13842
  colorMap: this.colorMap,
13391
13843
  centerNodeId: this.currentSection.centerNodeId,
13392
- nodeEdgeMap: this.nodeEdgeMap
13844
+ nodeEdgeMap: this.nodeEdgeMap,
13845
+ hyperParameters: {
13846
+ EXPANSION_DEGREES: this.currentSchedule.MAX_EXPANSION_DEGREES
13847
+ },
13848
+ cacheProvider: this.cacheProvider
13393
13849
  });
13394
13850
  this.activeSubSolver = this.sectionSolver;
13395
13851
  this.nodeOptimizationAttemptCountMap.set(
@@ -13409,18 +13865,19 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13409
13865
  return;
13410
13866
  }
13411
13867
  if (this.sectionSolver.solved) {
13412
- const solvedSectionSolver = this.sectionSolver;
13413
- const pathingSolver = solvedSectionSolver?.activeSubSolver || solvedSectionSolver;
13868
+ const sectionConnectionTerminals = this.sectionSolver.sectionConnectionTerminals;
13869
+ const sectionNodes = this.sectionSolver.sectionNodes;
13870
+ const centerNodeId = this.sectionSolver.centerNodeId;
13414
13871
  this.sectionSolver = null;
13415
13872
  this.activeSubSolver = null;
13416
- if (!pathingSolver || !pathingSolver.solved) {
13873
+ if (!sectionConnectionTerminals) {
13417
13874
  console.warn(
13418
13875
  `Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`
13419
13876
  );
13420
13877
  return;
13421
13878
  }
13422
13879
  const sectionNodeIds = new Set(
13423
- solvedSectionSolver.sectionNodes.map((n) => n.capacityMeshNodeId)
13880
+ sectionNodes.map((n) => n.capacityMeshNodeId)
13424
13881
  );
13425
13882
  const beforeScore = computeSectionScore({
13426
13883
  totalNodeCapacityMap: this.totalNodeCapacityMap,
@@ -13429,7 +13886,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13429
13886
  sectionNodeIds
13430
13887
  });
13431
13888
  const afterUsedCapacityMap = new Map(this.usedNodeCapacityMap);
13432
- const newSectionPaths = pathingSolver.sectionConnectionTerminals;
13889
+ const newSectionPaths = sectionConnectionTerminals;
13433
13890
  for (const terminal of newSectionPaths) {
13434
13891
  const originalConnection = this.connectionsWithNodes.find(
13435
13892
  (conn) => conn.connection.name === terminal.connectionName
@@ -13466,7 +13923,10 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13466
13923
  });
13467
13924
  if (afterScore > beforeScore) {
13468
13925
  this.stats.successfulOptimizations++;
13469
- this._mergeSolvedSectionPaths(solvedSectionSolver);
13926
+ this._mergeSolvedSectionPaths({
13927
+ centerNodeId,
13928
+ sectionConnectionTerminals
13929
+ });
13470
13930
  this._recalculateNodeCapacityUsage();
13471
13931
  } else {
13472
13932
  this.stats.failedOptimizations++;
@@ -13477,16 +13937,11 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13477
13937
  * Merges the paths found by a successful section solver back into the main
13478
13938
  * connectionsWithNodes list.
13479
13939
  */
13480
- _mergeSolvedSectionPaths(solvedSectionSolver) {
13481
- const centerNodeId = solvedSectionSolver.centerNodeId;
13482
- if (!solvedSectionSolver || !solvedSectionSolver.solved) {
13483
- console.warn(
13484
- `Pathing sub-solver for section ${centerNodeId} did not complete successfully. Skipping merge.`
13485
- );
13486
- return;
13487
- }
13488
- const solvedTerminals = solvedSectionSolver.sectionConnectionTerminals;
13489
- for (const solvedTerminal of solvedTerminals) {
13940
+ _mergeSolvedSectionPaths({
13941
+ centerNodeId,
13942
+ sectionConnectionTerminals
13943
+ }) {
13944
+ for (const solvedTerminal of sectionConnectionTerminals) {
13490
13945
  if (!solvedTerminal.path) {
13491
13946
  console.warn(
13492
13947
  `No path found for connection ${solvedTerminal.connectionName} in section ${centerNodeId}`
@@ -13498,7 +13953,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
13498
13953
  );
13499
13954
  if (!originalConnection || !originalConnection.path) {
13500
13955
  console.warn(
13501
- `Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${solvedSectionSolver.centerNodeId}`
13956
+ `Original connection or path not found for ${solvedTerminal.connectionName} while merging section ${centerNodeId}`
13502
13957
  );
13503
13958
  continue;
13504
13959
  }
@@ -15845,7 +16300,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
15845
16300
  }
15846
16301
  this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
15847
16302
  this.colorMap = getColorMap(srj, this.connMap);
15848
- this.cacheProvider = opts.cacheProvider ?? null;
16303
+ this.cacheProvider = opts.cacheProvider === void 0 ? getGlobalInMemoryCache() : opts.cacheProvider === null ? null : opts.cacheProvider;
15849
16304
  this.startTimeOfPhase = {};
15850
16305
  this.endTimeOfPhase = {};
15851
16306
  this.timeSpentOnPhase = {};
@@ -15969,6 +16424,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
15969
16424
  nodes: cms.capacityNodes,
15970
16425
  edges: cms.edgeSolver?.edges || [],
15971
16426
  colorMap: cms.colorMap,
16427
+ cacheProvider: cms.cacheProvider,
15972
16428
  hyperParameters: {
15973
16429
  MAX_CAPACITY_FACTOR: 1
15974
16430
  }
@@ -16311,7 +16767,12 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
16311
16767
  var CapacityMeshSolver = AutoroutingPipelineSolver;
16312
16768
  export {
16313
16769
  CapacityMeshSolver,
16770
+ InMemoryCache,
16771
+ LocalStorageCache,
16314
16772
  calculateOptimalCapacityDepth,
16315
- getTunedTotalCapacity1
16773
+ getGlobalInMemoryCache,
16774
+ getGlobalLocalStorageCache,
16775
+ getTunedTotalCapacity1,
16776
+ setupGlobalCaches
16316
16777
  };
16317
16778
  //# sourceMappingURL=index.js.map