@2112-lab/central-plant 0.1.21 → 0.1.22

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.
@@ -25445,6 +25445,9 @@ var CentralPlant = /*#__PURE__*/function () {
25445
25445
  lastTransform: null
25446
25446
  };
25447
25447
 
25448
+ // Add component counter for unique ID generation
25449
+ this.componentCounter = 0;
25450
+
25448
25451
  // Set default scene metadata
25449
25452
  this.setDefaultSceneMetadata();
25450
25453
 
@@ -25629,6 +25632,9 @@ var CentralPlant = /*#__PURE__*/function () {
25629
25632
  timestamp: new Date().toISOString()
25630
25633
  });
25631
25634
 
25635
+ // Reset component counter based on imported components to avoid ID conflicts
25636
+ this.resetComponentCounter();
25637
+
25632
25638
  // Set default metadata for imported scene data
25633
25639
  this.setDefaultImportedSceneMetadata(sceneData);
25634
25640
 
@@ -26643,7 +26649,7 @@ var CentralPlant = /*#__PURE__*/function () {
26643
26649
 
26644
26650
  // Perform the translation
26645
26651
  var normalizedAxis = axis.toLowerCase();
26646
- var previousPosition = component.position[normalizedAxis];
26652
+ component.position[normalizedAxis];
26647
26653
  try {
26648
26654
  // Apply the translation
26649
26655
  component.position[normalizedAxis] += value;
@@ -26709,19 +26715,6 @@ var CentralPlant = /*#__PURE__*/function () {
26709
26715
  // // Update scene data and paths after successful translation
26710
26716
  // this.updatePaths(component)
26711
26717
 
26712
- // Log successful translation
26713
- console.log("\u2705 translate(): Component ".concat(componentId, " translated ").concat(value, " units along ").concat(normalizedAxis.toUpperCase(), "-axis"), {
26714
- componentId: componentId,
26715
- axis: normalizedAxis,
26716
- value: value,
26717
- previousPosition: previousPosition,
26718
- newPosition: component.position[normalizedAxis],
26719
- totalPosition: {
26720
- x: component.position.x.toFixed(3),
26721
- y: component.position.y.toFixed(3),
26722
- z: component.position.z.toFixed(3)
26723
- }
26724
- });
26725
26718
  return component;
26726
26719
  } catch (error) {
26727
26720
  console.error("\u274C translate(): Error translating component ".concat(componentId, ":"), error);
@@ -26739,6 +26732,71 @@ var CentralPlant = /*#__PURE__*/function () {
26739
26732
  }
26740
26733
  }
26741
26734
 
26735
+ /**
26736
+ * Generate a unique component ID that doesn't conflict with existing components
26737
+ * @param {string} libraryId - The library identifier for the component type
26738
+ * @returns {string} A unique component ID
26739
+ */
26740
+ }, {
26741
+ key: "generateUniqueComponentId",
26742
+ value: function generateUniqueComponentId(libraryId) {
26743
+ // Get all existing component IDs
26744
+ var existingIds = this.getComponentIds();
26745
+ var existingIdSet = new Set(existingIds);
26746
+ var attempts = 0;
26747
+ var maxAttempts = 1000; // Safety limit to prevent infinite loops
26748
+
26749
+ while (attempts < maxAttempts) {
26750
+ // Generate a candidate ID using the current counter
26751
+ var candidateId = this.utilities.generateUuidFromName(libraryId + '-' + (this.componentCounter + 1));
26752
+
26753
+ // Check if this ID already exists
26754
+ if (!existingIdSet.has(candidateId)) {
26755
+ // ID is unique, increment counter and return it
26756
+ this.componentCounter++;
26757
+ console.log("\u2705 generateUniqueComponentId(): Generated unique ID ".concat(candidateId, " for ").concat(libraryId, " (counter: ").concat(this.componentCounter, ")"));
26758
+ return candidateId;
26759
+ }
26760
+
26761
+ // ID exists, increment counter and try again
26762
+ this.componentCounter++;
26763
+ attempts++;
26764
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): ID collision detected for ".concat(candidateId, ", trying again (attempt ").concat(attempts, ")"));
26765
+ }
26766
+
26767
+ // Fallback: use timestamp + random number if we can't find a unique ID with counter
26768
+ var fallbackId = this.utilities.generateUuidFromName(libraryId + '-' + Date.now() + '-' + Math.random().toString(36).substring(2, 8));
26769
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): Max attempts reached, using fallback ID: ".concat(fallbackId));
26770
+ return fallbackId;
26771
+ }
26772
+
26773
+ /**
26774
+ * Reset the component counter based on existing components in the scene
26775
+ * This is useful when loading scenes that already have numbered components
26776
+ */
26777
+ }, {
26778
+ key: "resetComponentCounter",
26779
+ value: function resetComponentCounter() {
26780
+ var existingIds = this.getComponentIds();
26781
+ var maxCounter = 0;
26782
+
26783
+ // Extract counter values from existing component IDs
26784
+ existingIds.forEach(function (id) {
26785
+ // Look for patterns like "PUMP-1", "CHILLER-2", etc.
26786
+ var match = id.match(/-(\d+)(?:-|$)/);
26787
+ if (match) {
26788
+ var counter = parseInt(match[1], 10);
26789
+ if (!isNaN(counter) && counter > maxCounter) {
26790
+ maxCounter = counter;
26791
+ }
26792
+ }
26793
+ });
26794
+
26795
+ // Set the counter to one more than the highest found
26796
+ this.componentCounter = maxCounter;
26797
+ console.log("\uD83D\uDD04 resetComponentCounter(): Counter reset to ".concat(this.componentCounter, " based on ").concat(existingIds.length, " existing components"));
26798
+ }
26799
+
26742
26800
  /**
26743
26801
  * Add a new component to the scene using its library ID
26744
26802
  * @param {string} libraryId - The library identifier for the component type (e.g., 'PUMP', 'CHILLER', 'COOLING-TOWER')
@@ -26780,7 +26838,16 @@ var CentralPlant = /*#__PURE__*/function () {
26780
26838
  }
26781
26839
  try {
26782
26840
  // Generate a unique component ID if not provided
26783
- var componentId = options.customId || this.utilities.generateUuidFromName(libraryId + '_' + Date.now());
26841
+ var componentId = options.customId || this.generateUniqueComponentId(libraryId);
26842
+
26843
+ // Validate that custom IDs don't conflict with existing components
26844
+ if (options.customId) {
26845
+ var existingIds = this.getComponentIds();
26846
+ if (existingIds.includes(options.customId)) {
26847
+ console.error("\u274C addComponent(): Custom ID '".concat(options.customId, "' already exists in scene. Existing IDs:"), existingIds);
26848
+ return false;
26849
+ }
26850
+ }
26784
26851
 
26785
26852
  // Set default position within scene boundaries if not provided
26786
26853
  var position = options.position || {
@@ -27107,6 +27174,102 @@ var CentralPlant = /*#__PURE__*/function () {
27107
27174
  return this.sceneViewer.currentSceneData.connections || [];
27108
27175
  }
27109
27176
 
27177
+ /**
27178
+ * Get all connector IDs from the currentSceneData
27179
+ * @returns {Array} Array of all connector ID strings, or empty array if none exist
27180
+ */
27181
+ }, {
27182
+ key: "getAllConnectorIds",
27183
+ value: function getAllConnectorIds() {
27184
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
27185
+ console.warn('⚠️ getAllConnectorIds(): Scene viewer or current scene data not available');
27186
+ return [];
27187
+ }
27188
+ var allConnectorIds = [];
27189
+ var sceneData = this.sceneViewer.currentSceneData;
27190
+
27191
+ // Check if scene data has the expected structure
27192
+ if (!sceneData.scene || !sceneData.scene.object || !sceneData.scene.object.children) {
27193
+ console.warn('⚠️ getAllConnectorIds(): Invalid scene data structure');
27194
+ return [];
27195
+ }
27196
+
27197
+ // Traverse through all components in the scene data
27198
+ sceneData.scene.object.children.forEach(function (component) {
27199
+ // Each component may have connector children
27200
+ if (component.children && Array.isArray(component.children)) {
27201
+ component.children.forEach(function (child) {
27202
+ // Check if this child is a connector
27203
+ if (child.userData && child.userData.componentType === 'connector' && child.uuid) {
27204
+ allConnectorIds.push(child.uuid);
27205
+ }
27206
+ });
27207
+ }
27208
+ });
27209
+ console.log("\uD83D\uDD0C getAllConnectorIds(): Found ".concat(allConnectorIds.length, " total connector IDs in currentSceneData"));
27210
+ return allConnectorIds;
27211
+ }
27212
+
27213
+ /**
27214
+ * Get all available connector IDs that are not currently used in connections
27215
+ * @returns {Array} Array of available connector ID strings, or empty array if none exist
27216
+ */
27217
+ }, {
27218
+ key: "getAvailableConnections",
27219
+ value: function getAvailableConnections() {
27220
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
27221
+ console.warn('⚠️ getAvailableConnections(): Scene viewer or current scene data not available');
27222
+ return [];
27223
+ }
27224
+
27225
+ // Get all connector IDs from the currentSceneData
27226
+ var allConnectorIds = this.getAllConnectorIds();
27227
+
27228
+ // Get existing connections
27229
+ var existingConnections = this.getConnections();
27230
+
27231
+ // Collect all connector IDs that are already used in connections
27232
+ var usedConnectorIds = new Set();
27233
+ existingConnections.forEach(function (connection) {
27234
+ if (connection.from) usedConnectorIds.add(connection.from);
27235
+ if (connection.to) usedConnectorIds.add(connection.to);
27236
+ });
27237
+
27238
+ // Filter out used connectors to get only available ones
27239
+ var availableConnectorIds = allConnectorIds.filter(function (id) {
27240
+ return !usedConnectorIds.has(id);
27241
+ });
27242
+ console.log("\uD83D\uDD0C getAvailableConnections(): Found ".concat(availableConnectorIds.length, " available connectors out of ").concat(allConnectorIds.length, " total connectors"));
27243
+ console.log('📋 Available connector IDs:', availableConnectorIds);
27244
+ return availableConnectorIds;
27245
+ }
27246
+
27247
+ /**
27248
+ * Get all component IDs from the scene
27249
+ * @returns {Array} Array of component ID strings, or empty array if none exist
27250
+ */
27251
+ }, {
27252
+ key: "getComponentIds",
27253
+ value: function getComponentIds() {
27254
+ if (!this.sceneViewer || !this.sceneViewer.scene) {
27255
+ console.warn('⚠️ getComponentIds(): Scene viewer or scene not available');
27256
+ return [];
27257
+ }
27258
+ var componentIds = [];
27259
+
27260
+ // Traverse the scene to find all components
27261
+ this.sceneViewer.scene.traverse(function (child) {
27262
+ if (child.userData && child.userData.componentType === 'component') {
27263
+ var id = child.uuid || child.userData.originalUuid || child.name;
27264
+ if (id) {
27265
+ componentIds.push(id);
27266
+ }
27267
+ }
27268
+ });
27269
+ console.log("\uD83D\uDCCB getComponentIds(): Found ".concat(componentIds.length, " component IDs in scene:"), componentIds);
27270
+ return componentIds;
27271
+ }
27272
+
27110
27273
  /**
27111
27274
  * Remove a connection between two connector IDs from the connections list
27112
27275
  * @param {string} fromConnectorId - The ID of the source connector
@@ -27198,6 +27361,8 @@ var CentralPlant = /*#__PURE__*/function () {
27198
27361
  }, {
27199
27362
  key: "updatePaths",
27200
27363
  value: function updatePaths() {
27364
+ var componentId = this.sceneViewer.currentSceneData.scene.object.children[0].uuid;
27365
+ this.translate(componentId, "x", 0);
27201
27366
  this.sceneViewer.updatePaths();
27202
27367
  }
27203
27368
  }]);
@@ -71,6 +71,9 @@ var CentralPlant = /*#__PURE__*/function () {
71
71
  lastTransform: null
72
72
  };
73
73
 
74
+ // Add component counter for unique ID generation
75
+ this.componentCounter = 0;
76
+
74
77
  // Set default scene metadata
75
78
  this.setDefaultSceneMetadata();
76
79
 
@@ -255,6 +258,9 @@ var CentralPlant = /*#__PURE__*/function () {
255
258
  timestamp: new Date().toISOString()
256
259
  });
257
260
 
261
+ // Reset component counter based on imported components to avoid ID conflicts
262
+ this.resetComponentCounter();
263
+
258
264
  // Set default metadata for imported scene data
259
265
  this.setDefaultImportedSceneMetadata(sceneData);
260
266
 
@@ -1269,7 +1275,7 @@ var CentralPlant = /*#__PURE__*/function () {
1269
1275
 
1270
1276
  // Perform the translation
1271
1277
  var normalizedAxis = axis.toLowerCase();
1272
- var previousPosition = component.position[normalizedAxis];
1278
+ component.position[normalizedAxis];
1273
1279
  try {
1274
1280
  // Apply the translation
1275
1281
  component.position[normalizedAxis] += value;
@@ -1335,19 +1341,6 @@ var CentralPlant = /*#__PURE__*/function () {
1335
1341
  // // Update scene data and paths after successful translation
1336
1342
  // this.updatePaths(component)
1337
1343
 
1338
- // Log successful translation
1339
- console.log("\u2705 translate(): Component ".concat(componentId, " translated ").concat(value, " units along ").concat(normalizedAxis.toUpperCase(), "-axis"), {
1340
- componentId: componentId,
1341
- axis: normalizedAxis,
1342
- value: value,
1343
- previousPosition: previousPosition,
1344
- newPosition: component.position[normalizedAxis],
1345
- totalPosition: {
1346
- x: component.position.x.toFixed(3),
1347
- y: component.position.y.toFixed(3),
1348
- z: component.position.z.toFixed(3)
1349
- }
1350
- });
1351
1344
  return component;
1352
1345
  } catch (error) {
1353
1346
  console.error("\u274C translate(): Error translating component ".concat(componentId, ":"), error);
@@ -1365,6 +1358,71 @@ var CentralPlant = /*#__PURE__*/function () {
1365
1358
  }
1366
1359
  }
1367
1360
 
1361
+ /**
1362
+ * Generate a unique component ID that doesn't conflict with existing components
1363
+ * @param {string} libraryId - The library identifier for the component type
1364
+ * @returns {string} A unique component ID
1365
+ */
1366
+ }, {
1367
+ key: "generateUniqueComponentId",
1368
+ value: function generateUniqueComponentId(libraryId) {
1369
+ // Get all existing component IDs
1370
+ var existingIds = this.getComponentIds();
1371
+ var existingIdSet = new Set(existingIds);
1372
+ var attempts = 0;
1373
+ var maxAttempts = 1000; // Safety limit to prevent infinite loops
1374
+
1375
+ while (attempts < maxAttempts) {
1376
+ // Generate a candidate ID using the current counter
1377
+ var candidateId = this.utilities.generateUuidFromName(libraryId + '-' + (this.componentCounter + 1));
1378
+
1379
+ // Check if this ID already exists
1380
+ if (!existingIdSet.has(candidateId)) {
1381
+ // ID is unique, increment counter and return it
1382
+ this.componentCounter++;
1383
+ console.log("\u2705 generateUniqueComponentId(): Generated unique ID ".concat(candidateId, " for ").concat(libraryId, " (counter: ").concat(this.componentCounter, ")"));
1384
+ return candidateId;
1385
+ }
1386
+
1387
+ // ID exists, increment counter and try again
1388
+ this.componentCounter++;
1389
+ attempts++;
1390
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): ID collision detected for ".concat(candidateId, ", trying again (attempt ").concat(attempts, ")"));
1391
+ }
1392
+
1393
+ // Fallback: use timestamp + random number if we can't find a unique ID with counter
1394
+ var fallbackId = this.utilities.generateUuidFromName(libraryId + '-' + Date.now() + '-' + Math.random().toString(36).substring(2, 8));
1395
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): Max attempts reached, using fallback ID: ".concat(fallbackId));
1396
+ return fallbackId;
1397
+ }
1398
+
1399
+ /**
1400
+ * Reset the component counter based on existing components in the scene
1401
+ * This is useful when loading scenes that already have numbered components
1402
+ */
1403
+ }, {
1404
+ key: "resetComponentCounter",
1405
+ value: function resetComponentCounter() {
1406
+ var existingIds = this.getComponentIds();
1407
+ var maxCounter = 0;
1408
+
1409
+ // Extract counter values from existing component IDs
1410
+ existingIds.forEach(function (id) {
1411
+ // Look for patterns like "PUMP-1", "CHILLER-2", etc.
1412
+ var match = id.match(/-(\d+)(?:-|$)/);
1413
+ if (match) {
1414
+ var counter = parseInt(match[1], 10);
1415
+ if (!isNaN(counter) && counter > maxCounter) {
1416
+ maxCounter = counter;
1417
+ }
1418
+ }
1419
+ });
1420
+
1421
+ // Set the counter to one more than the highest found
1422
+ this.componentCounter = maxCounter;
1423
+ console.log("\uD83D\uDD04 resetComponentCounter(): Counter reset to ".concat(this.componentCounter, " based on ").concat(existingIds.length, " existing components"));
1424
+ }
1425
+
1368
1426
  /**
1369
1427
  * Add a new component to the scene using its library ID
1370
1428
  * @param {string} libraryId - The library identifier for the component type (e.g., 'PUMP', 'CHILLER', 'COOLING-TOWER')
@@ -1406,7 +1464,16 @@ var CentralPlant = /*#__PURE__*/function () {
1406
1464
  }
1407
1465
  try {
1408
1466
  // Generate a unique component ID if not provided
1409
- var componentId = options.customId || this.utilities.generateUuidFromName(libraryId + '_' + Date.now());
1467
+ var componentId = options.customId || this.generateUniqueComponentId(libraryId);
1468
+
1469
+ // Validate that custom IDs don't conflict with existing components
1470
+ if (options.customId) {
1471
+ var existingIds = this.getComponentIds();
1472
+ if (existingIds.includes(options.customId)) {
1473
+ console.error("\u274C addComponent(): Custom ID '".concat(options.customId, "' already exists in scene. Existing IDs:"), existingIds);
1474
+ return false;
1475
+ }
1476
+ }
1410
1477
 
1411
1478
  // Set default position within scene boundaries if not provided
1412
1479
  var position = options.position || {
@@ -1733,6 +1800,102 @@ var CentralPlant = /*#__PURE__*/function () {
1733
1800
  return this.sceneViewer.currentSceneData.connections || [];
1734
1801
  }
1735
1802
 
1803
+ /**
1804
+ * Get all connector IDs from the currentSceneData
1805
+ * @returns {Array} Array of all connector ID strings, or empty array if none exist
1806
+ */
1807
+ }, {
1808
+ key: "getAllConnectorIds",
1809
+ value: function getAllConnectorIds() {
1810
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
1811
+ console.warn('⚠️ getAllConnectorIds(): Scene viewer or current scene data not available');
1812
+ return [];
1813
+ }
1814
+ var allConnectorIds = [];
1815
+ var sceneData = this.sceneViewer.currentSceneData;
1816
+
1817
+ // Check if scene data has the expected structure
1818
+ if (!sceneData.scene || !sceneData.scene.object || !sceneData.scene.object.children) {
1819
+ console.warn('⚠️ getAllConnectorIds(): Invalid scene data structure');
1820
+ return [];
1821
+ }
1822
+
1823
+ // Traverse through all components in the scene data
1824
+ sceneData.scene.object.children.forEach(function (component) {
1825
+ // Each component may have connector children
1826
+ if (component.children && Array.isArray(component.children)) {
1827
+ component.children.forEach(function (child) {
1828
+ // Check if this child is a connector
1829
+ if (child.userData && child.userData.componentType === 'connector' && child.uuid) {
1830
+ allConnectorIds.push(child.uuid);
1831
+ }
1832
+ });
1833
+ }
1834
+ });
1835
+ console.log("\uD83D\uDD0C getAllConnectorIds(): Found ".concat(allConnectorIds.length, " total connector IDs in currentSceneData"));
1836
+ return allConnectorIds;
1837
+ }
1838
+
1839
+ /**
1840
+ * Get all available connector IDs that are not currently used in connections
1841
+ * @returns {Array} Array of available connector ID strings, or empty array if none exist
1842
+ */
1843
+ }, {
1844
+ key: "getAvailableConnections",
1845
+ value: function getAvailableConnections() {
1846
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
1847
+ console.warn('⚠️ getAvailableConnections(): Scene viewer or current scene data not available');
1848
+ return [];
1849
+ }
1850
+
1851
+ // Get all connector IDs from the currentSceneData
1852
+ var allConnectorIds = this.getAllConnectorIds();
1853
+
1854
+ // Get existing connections
1855
+ var existingConnections = this.getConnections();
1856
+
1857
+ // Collect all connector IDs that are already used in connections
1858
+ var usedConnectorIds = new Set();
1859
+ existingConnections.forEach(function (connection) {
1860
+ if (connection.from) usedConnectorIds.add(connection.from);
1861
+ if (connection.to) usedConnectorIds.add(connection.to);
1862
+ });
1863
+
1864
+ // Filter out used connectors to get only available ones
1865
+ var availableConnectorIds = allConnectorIds.filter(function (id) {
1866
+ return !usedConnectorIds.has(id);
1867
+ });
1868
+ console.log("\uD83D\uDD0C getAvailableConnections(): Found ".concat(availableConnectorIds.length, " available connectors out of ").concat(allConnectorIds.length, " total connectors"));
1869
+ console.log('📋 Available connector IDs:', availableConnectorIds);
1870
+ return availableConnectorIds;
1871
+ }
1872
+
1873
+ /**
1874
+ * Get all component IDs from the scene
1875
+ * @returns {Array} Array of component ID strings, or empty array if none exist
1876
+ */
1877
+ }, {
1878
+ key: "getComponentIds",
1879
+ value: function getComponentIds() {
1880
+ if (!this.sceneViewer || !this.sceneViewer.scene) {
1881
+ console.warn('⚠️ getComponentIds(): Scene viewer or scene not available');
1882
+ return [];
1883
+ }
1884
+ var componentIds = [];
1885
+
1886
+ // Traverse the scene to find all components
1887
+ this.sceneViewer.scene.traverse(function (child) {
1888
+ if (child.userData && child.userData.componentType === 'component') {
1889
+ var id = child.uuid || child.userData.originalUuid || child.name;
1890
+ if (id) {
1891
+ componentIds.push(id);
1892
+ }
1893
+ }
1894
+ });
1895
+ console.log("\uD83D\uDCCB getComponentIds(): Found ".concat(componentIds.length, " component IDs in scene:"), componentIds);
1896
+ return componentIds;
1897
+ }
1898
+
1736
1899
  /**
1737
1900
  * Remove a connection between two connector IDs from the connections list
1738
1901
  * @param {string} fromConnectorId - The ID of the source connector
@@ -1824,6 +1987,8 @@ var CentralPlant = /*#__PURE__*/function () {
1824
1987
  }, {
1825
1988
  key: "updatePaths",
1826
1989
  value: function updatePaths() {
1990
+ var componentId = this.sceneViewer.currentSceneData.scene.object.children[0].uuid;
1991
+ this.translate(componentId, "x", 0);
1827
1992
  this.sceneViewer.updatePaths();
1828
1993
  }
1829
1994
  }]);
@@ -47,6 +47,9 @@ var CentralPlant = /*#__PURE__*/function () {
47
47
  lastTransform: null
48
48
  };
49
49
 
50
+ // Add component counter for unique ID generation
51
+ this.componentCounter = 0;
52
+
50
53
  // Set default scene metadata
51
54
  this.setDefaultSceneMetadata();
52
55
 
@@ -231,6 +234,9 @@ var CentralPlant = /*#__PURE__*/function () {
231
234
  timestamp: new Date().toISOString()
232
235
  });
233
236
 
237
+ // Reset component counter based on imported components to avoid ID conflicts
238
+ this.resetComponentCounter();
239
+
234
240
  // Set default metadata for imported scene data
235
241
  this.setDefaultImportedSceneMetadata(sceneData);
236
242
 
@@ -1245,7 +1251,7 @@ var CentralPlant = /*#__PURE__*/function () {
1245
1251
 
1246
1252
  // Perform the translation
1247
1253
  var normalizedAxis = axis.toLowerCase();
1248
- var previousPosition = component.position[normalizedAxis];
1254
+ component.position[normalizedAxis];
1249
1255
  try {
1250
1256
  // Apply the translation
1251
1257
  component.position[normalizedAxis] += value;
@@ -1311,19 +1317,6 @@ var CentralPlant = /*#__PURE__*/function () {
1311
1317
  // // Update scene data and paths after successful translation
1312
1318
  // this.updatePaths(component)
1313
1319
 
1314
- // Log successful translation
1315
- console.log("\u2705 translate(): Component ".concat(componentId, " translated ").concat(value, " units along ").concat(normalizedAxis.toUpperCase(), "-axis"), {
1316
- componentId: componentId,
1317
- axis: normalizedAxis,
1318
- value: value,
1319
- previousPosition: previousPosition,
1320
- newPosition: component.position[normalizedAxis],
1321
- totalPosition: {
1322
- x: component.position.x.toFixed(3),
1323
- y: component.position.y.toFixed(3),
1324
- z: component.position.z.toFixed(3)
1325
- }
1326
- });
1327
1320
  return component;
1328
1321
  } catch (error) {
1329
1322
  console.error("\u274C translate(): Error translating component ".concat(componentId, ":"), error);
@@ -1341,6 +1334,71 @@ var CentralPlant = /*#__PURE__*/function () {
1341
1334
  }
1342
1335
  }
1343
1336
 
1337
+ /**
1338
+ * Generate a unique component ID that doesn't conflict with existing components
1339
+ * @param {string} libraryId - The library identifier for the component type
1340
+ * @returns {string} A unique component ID
1341
+ */
1342
+ }, {
1343
+ key: "generateUniqueComponentId",
1344
+ value: function generateUniqueComponentId(libraryId) {
1345
+ // Get all existing component IDs
1346
+ var existingIds = this.getComponentIds();
1347
+ var existingIdSet = new Set(existingIds);
1348
+ var attempts = 0;
1349
+ var maxAttempts = 1000; // Safety limit to prevent infinite loops
1350
+
1351
+ while (attempts < maxAttempts) {
1352
+ // Generate a candidate ID using the current counter
1353
+ var candidateId = this.utilities.generateUuidFromName(libraryId + '-' + (this.componentCounter + 1));
1354
+
1355
+ // Check if this ID already exists
1356
+ if (!existingIdSet.has(candidateId)) {
1357
+ // ID is unique, increment counter and return it
1358
+ this.componentCounter++;
1359
+ console.log("\u2705 generateUniqueComponentId(): Generated unique ID ".concat(candidateId, " for ").concat(libraryId, " (counter: ").concat(this.componentCounter, ")"));
1360
+ return candidateId;
1361
+ }
1362
+
1363
+ // ID exists, increment counter and try again
1364
+ this.componentCounter++;
1365
+ attempts++;
1366
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): ID collision detected for ".concat(candidateId, ", trying again (attempt ").concat(attempts, ")"));
1367
+ }
1368
+
1369
+ // Fallback: use timestamp + random number if we can't find a unique ID with counter
1370
+ var fallbackId = this.utilities.generateUuidFromName(libraryId + '-' + Date.now() + '-' + Math.random().toString(36).substring(2, 8));
1371
+ console.warn("\u26A0\uFE0F generateUniqueComponentId(): Max attempts reached, using fallback ID: ".concat(fallbackId));
1372
+ return fallbackId;
1373
+ }
1374
+
1375
+ /**
1376
+ * Reset the component counter based on existing components in the scene
1377
+ * This is useful when loading scenes that already have numbered components
1378
+ */
1379
+ }, {
1380
+ key: "resetComponentCounter",
1381
+ value: function resetComponentCounter() {
1382
+ var existingIds = this.getComponentIds();
1383
+ var maxCounter = 0;
1384
+
1385
+ // Extract counter values from existing component IDs
1386
+ existingIds.forEach(function (id) {
1387
+ // Look for patterns like "PUMP-1", "CHILLER-2", etc.
1388
+ var match = id.match(/-(\d+)(?:-|$)/);
1389
+ if (match) {
1390
+ var counter = parseInt(match[1], 10);
1391
+ if (!isNaN(counter) && counter > maxCounter) {
1392
+ maxCounter = counter;
1393
+ }
1394
+ }
1395
+ });
1396
+
1397
+ // Set the counter to one more than the highest found
1398
+ this.componentCounter = maxCounter;
1399
+ console.log("\uD83D\uDD04 resetComponentCounter(): Counter reset to ".concat(this.componentCounter, " based on ").concat(existingIds.length, " existing components"));
1400
+ }
1401
+
1344
1402
  /**
1345
1403
  * Add a new component to the scene using its library ID
1346
1404
  * @param {string} libraryId - The library identifier for the component type (e.g., 'PUMP', 'CHILLER', 'COOLING-TOWER')
@@ -1382,7 +1440,16 @@ var CentralPlant = /*#__PURE__*/function () {
1382
1440
  }
1383
1441
  try {
1384
1442
  // Generate a unique component ID if not provided
1385
- var componentId = options.customId || this.utilities.generateUuidFromName(libraryId + '_' + Date.now());
1443
+ var componentId = options.customId || this.generateUniqueComponentId(libraryId);
1444
+
1445
+ // Validate that custom IDs don't conflict with existing components
1446
+ if (options.customId) {
1447
+ var existingIds = this.getComponentIds();
1448
+ if (existingIds.includes(options.customId)) {
1449
+ console.error("\u274C addComponent(): Custom ID '".concat(options.customId, "' already exists in scene. Existing IDs:"), existingIds);
1450
+ return false;
1451
+ }
1452
+ }
1386
1453
 
1387
1454
  // Set default position within scene boundaries if not provided
1388
1455
  var position = options.position || {
@@ -1709,6 +1776,102 @@ var CentralPlant = /*#__PURE__*/function () {
1709
1776
  return this.sceneViewer.currentSceneData.connections || [];
1710
1777
  }
1711
1778
 
1779
+ /**
1780
+ * Get all connector IDs from the currentSceneData
1781
+ * @returns {Array} Array of all connector ID strings, or empty array if none exist
1782
+ */
1783
+ }, {
1784
+ key: "getAllConnectorIds",
1785
+ value: function getAllConnectorIds() {
1786
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
1787
+ console.warn('⚠️ getAllConnectorIds(): Scene viewer or current scene data not available');
1788
+ return [];
1789
+ }
1790
+ var allConnectorIds = [];
1791
+ var sceneData = this.sceneViewer.currentSceneData;
1792
+
1793
+ // Check if scene data has the expected structure
1794
+ if (!sceneData.scene || !sceneData.scene.object || !sceneData.scene.object.children) {
1795
+ console.warn('⚠️ getAllConnectorIds(): Invalid scene data structure');
1796
+ return [];
1797
+ }
1798
+
1799
+ // Traverse through all components in the scene data
1800
+ sceneData.scene.object.children.forEach(function (component) {
1801
+ // Each component may have connector children
1802
+ if (component.children && Array.isArray(component.children)) {
1803
+ component.children.forEach(function (child) {
1804
+ // Check if this child is a connector
1805
+ if (child.userData && child.userData.componentType === 'connector' && child.uuid) {
1806
+ allConnectorIds.push(child.uuid);
1807
+ }
1808
+ });
1809
+ }
1810
+ });
1811
+ console.log("\uD83D\uDD0C getAllConnectorIds(): Found ".concat(allConnectorIds.length, " total connector IDs in currentSceneData"));
1812
+ return allConnectorIds;
1813
+ }
1814
+
1815
+ /**
1816
+ * Get all available connector IDs that are not currently used in connections
1817
+ * @returns {Array} Array of available connector ID strings, or empty array if none exist
1818
+ */
1819
+ }, {
1820
+ key: "getAvailableConnections",
1821
+ value: function getAvailableConnections() {
1822
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
1823
+ console.warn('⚠️ getAvailableConnections(): Scene viewer or current scene data not available');
1824
+ return [];
1825
+ }
1826
+
1827
+ // Get all connector IDs from the currentSceneData
1828
+ var allConnectorIds = this.getAllConnectorIds();
1829
+
1830
+ // Get existing connections
1831
+ var existingConnections = this.getConnections();
1832
+
1833
+ // Collect all connector IDs that are already used in connections
1834
+ var usedConnectorIds = new Set();
1835
+ existingConnections.forEach(function (connection) {
1836
+ if (connection.from) usedConnectorIds.add(connection.from);
1837
+ if (connection.to) usedConnectorIds.add(connection.to);
1838
+ });
1839
+
1840
+ // Filter out used connectors to get only available ones
1841
+ var availableConnectorIds = allConnectorIds.filter(function (id) {
1842
+ return !usedConnectorIds.has(id);
1843
+ });
1844
+ console.log("\uD83D\uDD0C getAvailableConnections(): Found ".concat(availableConnectorIds.length, " available connectors out of ").concat(allConnectorIds.length, " total connectors"));
1845
+ console.log('📋 Available connector IDs:', availableConnectorIds);
1846
+ return availableConnectorIds;
1847
+ }
1848
+
1849
+ /**
1850
+ * Get all component IDs from the scene
1851
+ * @returns {Array} Array of component ID strings, or empty array if none exist
1852
+ */
1853
+ }, {
1854
+ key: "getComponentIds",
1855
+ value: function getComponentIds() {
1856
+ if (!this.sceneViewer || !this.sceneViewer.scene) {
1857
+ console.warn('⚠️ getComponentIds(): Scene viewer or scene not available');
1858
+ return [];
1859
+ }
1860
+ var componentIds = [];
1861
+
1862
+ // Traverse the scene to find all components
1863
+ this.sceneViewer.scene.traverse(function (child) {
1864
+ if (child.userData && child.userData.componentType === 'component') {
1865
+ var id = child.uuid || child.userData.originalUuid || child.name;
1866
+ if (id) {
1867
+ componentIds.push(id);
1868
+ }
1869
+ }
1870
+ });
1871
+ console.log("\uD83D\uDCCB getComponentIds(): Found ".concat(componentIds.length, " component IDs in scene:"), componentIds);
1872
+ return componentIds;
1873
+ }
1874
+
1712
1875
  /**
1713
1876
  * Remove a connection between two connector IDs from the connections list
1714
1877
  * @param {string} fromConnectorId - The ID of the source connector
@@ -1800,6 +1963,8 @@ var CentralPlant = /*#__PURE__*/function () {
1800
1963
  }, {
1801
1964
  key: "updatePaths",
1802
1965
  value: function updatePaths() {
1966
+ var componentId = this.sceneViewer.currentSceneData.scene.object.children[0].uuid;
1967
+ this.translate(componentId, "x", 0);
1803
1968
  this.sceneViewer.updatePaths();
1804
1969
  }
1805
1970
  }]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "Utility modules for the Central Plant Application",
5
5
  "main": "dist/bundle/index.js",
6
6
  "module": "dist/esm/index.js",