@2112-lab/central-plant 0.3.48 → 0.3.49

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.
@@ -12060,11 +12060,10 @@ var SceneExportManager = /*#__PURE__*/function () {
12060
12060
  };
12061
12061
  }
12062
12062
 
12063
- // For components: only export child connectors if they were manually added/defined.
12064
- // Most connectors are injected from dictionary at import time, but some (like manually placed ones)
12065
- // need to be persisted to maintain connections in the exported scene.
12063
+ // Only manual segments persist their connector children here.
12064
+ // Component connectors are NOT exported they are regenerated from the
12065
+ // component dictionary on load (see note below), keeping the scene JSON minimal.
12066
12066
  if (threeObject.children && threeObject.children.length > 0) {
12067
- var _threeObject$userData11;
12068
12067
  var exportableChildren = [];
12069
12068
  if (isManualSegment) {
12070
12069
  // For manual segments, export their connector children
@@ -12078,30 +12077,15 @@ var SceneExportManager = /*#__PURE__*/function () {
12078
12077
  }
12079
12078
  }
12080
12079
  });
12081
- } else if (((_threeObject$userData11 = threeObject.userData) === null || _threeObject$userData11 === void 0 ? void 0 : _threeObject$userData11.objectType) === 'component') {
12082
- // For components, export all connectors (including deep children within GLFs)
12083
- threeObject.traverse(function (child) {
12084
- var _child$userData2;
12085
- if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'connector') {
12086
- // Calculate position relative to component root
12087
- var componentMatrixWorldInverse = threeObject.matrixWorld.clone().invert();
12088
- var childWorldPos = new THREE__namespace.Vector3();
12089
- child.getWorldPosition(childWorldPos);
12090
- var relativePos = childWorldPos.applyMatrix4(componentMatrixWorldInverse);
12091
- exportableChildren.push({
12092
- uuid: child.uuid,
12093
- name: child.name,
12094
- type: 'Mesh',
12095
- position: {
12096
- x: roundIfClose(relativePos.x),
12097
- y: roundIfClose(relativePos.y),
12098
- z: roundIfClose(relativePos.z)
12099
- },
12100
- userData: _objectSpread2({}, child.userData)
12101
- });
12102
- }
12103
- });
12104
12080
  }
12081
+ // NOTE: Component connectors are intentionally NOT exported.
12082
+ // They are defined in the component dictionary and regenerated on load by
12083
+ // sceneOperationsManager._injectConnectorChildrenFromDictionary using the
12084
+ // matching uuid scheme (`${componentUuid}_${dictConnectorUuid}`), and the
12085
+ // pathfinder rebuilds their world positions/bounding boxes on every run
12086
+ // (computeConnectorBoundingBoxes). Connections still resolve because the
12087
+ // regenerated connector uuids match the connection endpoints.
12088
+
12105
12089
  if (exportableChildren.length > 0) {
12106
12090
  jsonObject.children = exportableChildren;
12107
12091
  }
@@ -12115,9 +12099,9 @@ var SceneExportManager = /*#__PURE__*/function () {
12115
12099
  // Extract main scene objects (components and standalone connectors)
12116
12100
  var sceneChildren = [];
12117
12101
  this.sceneViewer.scene.children.forEach(function (child) {
12118
- var _child$userData3;
12102
+ var _child$userData2;
12119
12103
  // Only export components and connectors; skip segments, gateways, polylines, etc.
12120
- var objectType = (_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType;
12104
+ var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
12121
12105
  if (objectType !== 'component' && objectType !== 'connector') {
12122
12106
  return;
12123
12107
  }
@@ -12281,14 +12265,14 @@ var SceneExportManager = /*#__PURE__*/function () {
12281
12265
  BufferGeometryUtils$1 = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
12282
12266
  exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
12283
12267
  shouldExport = function shouldExport(child) {
12284
- var _child$name, _child$userData4, _child$userData5, _child$userData6, _child$userData7;
12268
+ var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
12285
12269
  if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
12286
12270
  if (child.name === 'fogPlane') return false; // Skip fog plane
12287
- if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBrickWall) return false; // Skip environment
12288
- if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGround) return false; // Skip environment
12289
- if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isBaseGrid) return false; // Skip environment
12271
+ if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
12272
+ if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
12273
+ if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
12290
12274
  if (child.isLight) return false; // Skip lights
12291
- if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.isTransformControls) return false; // Skip transform controls
12275
+ if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
12292
12276
  if (child.isTransformControls) return false; // Skip transform controls
12293
12277
  if (child.type && child.type.includes('TransformControls')) return false;
12294
12278
  if (child.type && child.type.includes('Helper')) return false; // Skip helpers
@@ -33855,6 +33839,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
33855
33839
  if (!(data !== null && data !== void 0 && (_data$scene2 = data.scene) !== null && _data$scene2 !== void 0 && _data$scene2.children) || !componentDictionary) {
33856
33840
  return;
33857
33841
  }
33842
+
33843
+ // Collect every connector uuid referenced by the scene's connections so we
33844
+ // can inject connectors under the SAME uuid scheme the scene actually uses.
33845
+ // Two schemes exist in the wild:
33846
+ // - Preferred (runtime add path + minimal export): `${componentUuid}_${dictConnectorUuid}`
33847
+ // - Legacy (older hand-authored scenes): `${componentUuid}-CONNECTOR-${index+1}`
33848
+ var connectionEndpoints = new Set();
33849
+ if (Array.isArray(data.connections)) {
33850
+ data.connections.forEach(function (conn) {
33851
+ if (conn !== null && conn !== void 0 && conn.from) connectionEndpoints.add(conn.from);
33852
+ if (conn !== null && conn !== void 0 && conn.to) connectionEndpoints.add(conn.to);
33853
+ });
33854
+ }
33858
33855
  var componentsProcessed = 0;
33859
33856
  var connectorsInjected = 0;
33860
33857
  data.scene.children.forEach(function (child) {
@@ -33877,9 +33874,18 @@ var SceneOperationsManager = /*#__PURE__*/function () {
33877
33874
 
33878
33875
  // Deep clone the connector children from the dictionary
33879
33876
  child.children = dictEntry.children.map(function (connector, index) {
33880
- // Generate unique UUID for this connector instance
33881
- // Format: COMPONENT-UUID-CONNECTOR-INDEX
33882
- var connectorUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
33877
+ // Choose the connector uuid that matches the scheme the scene's
33878
+ // connections reference. Prefer `${componentUuid}_${dictConnectorUuid}`
33879
+ // (sandbox add path + minimal export); fall back to the legacy
33880
+ // index-based scheme `${componentUuid}-CONNECTOR-${index+1}` when the
33881
+ // connections reference that form. If neither is referenced (e.g. an
33882
+ // unconnected connector), default to the preferred scheme.
33883
+ var legacyUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
33884
+ var preferredUuid = connector.uuid ? "".concat(child.uuid, "_").concat(connector.uuid) : legacyUuid;
33885
+ var connectorUuid = preferredUuid;
33886
+ if (!connectionEndpoints.has(preferredUuid) && connectionEndpoints.has(legacyUuid)) {
33887
+ connectorUuid = legacyUuid;
33888
+ }
33883
33889
 
33884
33890
  // Clone connector with deep copy of userData
33885
33891
  var clonedConnector = _objectSpread2(_objectSpread2({}, connector), {}, {
@@ -41119,7 +41125,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
41119
41125
  * Initialize the CentralPlant manager
41120
41126
  *
41121
41127
  * @constructor
41122
- * @version 0.3.48
41128
+ * @version 0.3.49
41123
41129
  * @updated 2025-10-22
41124
41130
  *
41125
41131
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -37,7 +37,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
37
37
  * Initialize the CentralPlant manager
38
38
  *
39
39
  * @constructor
40
- * @version 0.3.48
40
+ * @version 0.3.49
41
41
  * @updated 2025-10-22
42
42
  *
43
43
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
6
- var THREE = require('three');
6
+ require('three');
7
7
  var GLTFExporter = require('../../../node_modules/three/examples/jsm/exporters/GLTFExporter.js');
8
8
  var nameUtils = require('../../utils/nameUtils.js');
9
9
 
@@ -25,8 +25,6 @@ function _interopNamespace(e) {
25
25
  return Object.freeze(n);
26
26
  }
27
27
 
28
- var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
29
-
30
28
  var SceneExportManager = /*#__PURE__*/function () {
31
29
  function SceneExportManager(sceneViewer) {
32
30
  _rollupPluginBabelHelpers.classCallCheck(this, SceneExportManager);
@@ -248,11 +246,10 @@ var SceneExportManager = /*#__PURE__*/function () {
248
246
  };
249
247
  }
250
248
 
251
- // For components: only export child connectors if they were manually added/defined.
252
- // Most connectors are injected from dictionary at import time, but some (like manually placed ones)
253
- // need to be persisted to maintain connections in the exported scene.
249
+ // Only manual segments persist their connector children here.
250
+ // Component connectors are NOT exported they are regenerated from the
251
+ // component dictionary on load (see note below), keeping the scene JSON minimal.
254
252
  if (threeObject.children && threeObject.children.length > 0) {
255
- var _threeObject$userData11;
256
253
  var exportableChildren = [];
257
254
  if (isManualSegment) {
258
255
  // For manual segments, export their connector children
@@ -266,30 +263,15 @@ var SceneExportManager = /*#__PURE__*/function () {
266
263
  }
267
264
  }
268
265
  });
269
- } else if (((_threeObject$userData11 = threeObject.userData) === null || _threeObject$userData11 === void 0 ? void 0 : _threeObject$userData11.objectType) === 'component') {
270
- // For components, export all connectors (including deep children within GLFs)
271
- threeObject.traverse(function (child) {
272
- var _child$userData2;
273
- if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'connector') {
274
- // Calculate position relative to component root
275
- var componentMatrixWorldInverse = threeObject.matrixWorld.clone().invert();
276
- var childWorldPos = new THREE__namespace.Vector3();
277
- child.getWorldPosition(childWorldPos);
278
- var relativePos = childWorldPos.applyMatrix4(componentMatrixWorldInverse);
279
- exportableChildren.push({
280
- uuid: child.uuid,
281
- name: child.name,
282
- type: 'Mesh',
283
- position: {
284
- x: roundIfClose(relativePos.x),
285
- y: roundIfClose(relativePos.y),
286
- z: roundIfClose(relativePos.z)
287
- },
288
- userData: _rollupPluginBabelHelpers.objectSpread2({}, child.userData)
289
- });
290
- }
291
- });
292
266
  }
267
+ // NOTE: Component connectors are intentionally NOT exported.
268
+ // They are defined in the component dictionary and regenerated on load by
269
+ // sceneOperationsManager._injectConnectorChildrenFromDictionary using the
270
+ // matching uuid scheme (`${componentUuid}_${dictConnectorUuid}`), and the
271
+ // pathfinder rebuilds their world positions/bounding boxes on every run
272
+ // (computeConnectorBoundingBoxes). Connections still resolve because the
273
+ // regenerated connector uuids match the connection endpoints.
274
+
293
275
  if (exportableChildren.length > 0) {
294
276
  jsonObject.children = exportableChildren;
295
277
  }
@@ -303,9 +285,9 @@ var SceneExportManager = /*#__PURE__*/function () {
303
285
  // Extract main scene objects (components and standalone connectors)
304
286
  var sceneChildren = [];
305
287
  this.sceneViewer.scene.children.forEach(function (child) {
306
- var _child$userData3;
288
+ var _child$userData2;
307
289
  // Only export components and connectors; skip segments, gateways, polylines, etc.
308
- var objectType = (_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType;
290
+ var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
309
291
  if (objectType !== 'component' && objectType !== 'connector') {
310
292
  return;
311
293
  }
@@ -469,14 +451,14 @@ var SceneExportManager = /*#__PURE__*/function () {
469
451
  BufferGeometryUtils = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
470
452
  exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
471
453
  shouldExport = function shouldExport(child) {
472
- var _child$name, _child$userData4, _child$userData5, _child$userData6, _child$userData7;
454
+ var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
473
455
  if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
474
456
  if (child.name === 'fogPlane') return false; // Skip fog plane
475
- if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBrickWall) return false; // Skip environment
476
- if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGround) return false; // Skip environment
477
- if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isBaseGrid) return false; // Skip environment
457
+ if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
458
+ if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
459
+ if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
478
460
  if (child.isLight) return false; // Skip lights
479
- if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.isTransformControls) return false; // Skip transform controls
461
+ if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
480
462
  if (child.isTransformControls) return false; // Skip transform controls
481
463
  if (child.type && child.type.includes('TransformControls')) return false;
482
464
  if (child.type && child.type.includes('Helper')) return false; // Skip helpers
@@ -890,6 +890,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
890
890
  if (!(data !== null && data !== void 0 && (_data$scene2 = data.scene) !== null && _data$scene2 !== void 0 && _data$scene2.children) || !componentDictionary) {
891
891
  return;
892
892
  }
893
+
894
+ // Collect every connector uuid referenced by the scene's connections so we
895
+ // can inject connectors under the SAME uuid scheme the scene actually uses.
896
+ // Two schemes exist in the wild:
897
+ // - Preferred (runtime add path + minimal export): `${componentUuid}_${dictConnectorUuid}`
898
+ // - Legacy (older hand-authored scenes): `${componentUuid}-CONNECTOR-${index+1}`
899
+ var connectionEndpoints = new Set();
900
+ if (Array.isArray(data.connections)) {
901
+ data.connections.forEach(function (conn) {
902
+ if (conn !== null && conn !== void 0 && conn.from) connectionEndpoints.add(conn.from);
903
+ if (conn !== null && conn !== void 0 && conn.to) connectionEndpoints.add(conn.to);
904
+ });
905
+ }
893
906
  var componentsProcessed = 0;
894
907
  var connectorsInjected = 0;
895
908
  data.scene.children.forEach(function (child) {
@@ -912,9 +925,18 @@ var SceneOperationsManager = /*#__PURE__*/function () {
912
925
 
913
926
  // Deep clone the connector children from the dictionary
914
927
  child.children = dictEntry.children.map(function (connector, index) {
915
- // Generate unique UUID for this connector instance
916
- // Format: COMPONENT-UUID-CONNECTOR-INDEX
917
- var connectorUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
928
+ // Choose the connector uuid that matches the scheme the scene's
929
+ // connections reference. Prefer `${componentUuid}_${dictConnectorUuid}`
930
+ // (sandbox add path + minimal export); fall back to the legacy
931
+ // index-based scheme `${componentUuid}-CONNECTOR-${index+1}` when the
932
+ // connections reference that form. If neither is referenced (e.g. an
933
+ // unconnected connector), default to the preferred scheme.
934
+ var legacyUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
935
+ var preferredUuid = connector.uuid ? "".concat(child.uuid, "_").concat(connector.uuid) : legacyUuid;
936
+ var connectorUuid = preferredUuid;
937
+ if (!connectionEndpoints.has(preferredUuid) && connectionEndpoints.has(legacyUuid)) {
938
+ connectorUuid = legacyUuid;
939
+ }
918
940
 
919
941
  // Clone connector with deep copy of userData
920
942
  var clonedConnector = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, connector), {}, {
@@ -33,7 +33,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
33
33
  * Initialize the CentralPlant manager
34
34
  *
35
35
  * @constructor
36
- * @version 0.3.48
36
+ * @version 0.3.49
37
37
  * @updated 2025-10-22
38
38
  *
39
39
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -1,5 +1,5 @@
1
- import { createClass as _createClass, classCallCheck as _classCallCheck, toConsumableArray as _toConsumableArray, objectSpread2 as _objectSpread2, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
- import * as THREE from 'three';
1
+ import { createClass as _createClass, classCallCheck as _classCallCheck, toConsumableArray as _toConsumableArray, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import 'three';
3
3
  import { GLTFExporter } from '../../../node_modules/three/examples/jsm/exporters/GLTFExporter.js';
4
4
  import { getHardcodedUuid } from '../../utils/nameUtils.js';
5
5
 
@@ -224,11 +224,10 @@ var SceneExportManager = /*#__PURE__*/function () {
224
224
  };
225
225
  }
226
226
 
227
- // For components: only export child connectors if they were manually added/defined.
228
- // Most connectors are injected from dictionary at import time, but some (like manually placed ones)
229
- // need to be persisted to maintain connections in the exported scene.
227
+ // Only manual segments persist their connector children here.
228
+ // Component connectors are NOT exported they are regenerated from the
229
+ // component dictionary on load (see note below), keeping the scene JSON minimal.
230
230
  if (threeObject.children && threeObject.children.length > 0) {
231
- var _threeObject$userData11;
232
231
  var exportableChildren = [];
233
232
  if (isManualSegment) {
234
233
  // For manual segments, export their connector children
@@ -242,30 +241,15 @@ var SceneExportManager = /*#__PURE__*/function () {
242
241
  }
243
242
  }
244
243
  });
245
- } else if (((_threeObject$userData11 = threeObject.userData) === null || _threeObject$userData11 === void 0 ? void 0 : _threeObject$userData11.objectType) === 'component') {
246
- // For components, export all connectors (including deep children within GLFs)
247
- threeObject.traverse(function (child) {
248
- var _child$userData2;
249
- if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'connector') {
250
- // Calculate position relative to component root
251
- var componentMatrixWorldInverse = threeObject.matrixWorld.clone().invert();
252
- var childWorldPos = new THREE.Vector3();
253
- child.getWorldPosition(childWorldPos);
254
- var relativePos = childWorldPos.applyMatrix4(componentMatrixWorldInverse);
255
- exportableChildren.push({
256
- uuid: child.uuid,
257
- name: child.name,
258
- type: 'Mesh',
259
- position: {
260
- x: roundIfClose(relativePos.x),
261
- y: roundIfClose(relativePos.y),
262
- z: roundIfClose(relativePos.z)
263
- },
264
- userData: _objectSpread2({}, child.userData)
265
- });
266
- }
267
- });
268
244
  }
245
+ // NOTE: Component connectors are intentionally NOT exported.
246
+ // They are defined in the component dictionary and regenerated on load by
247
+ // sceneOperationsManager._injectConnectorChildrenFromDictionary using the
248
+ // matching uuid scheme (`${componentUuid}_${dictConnectorUuid}`), and the
249
+ // pathfinder rebuilds their world positions/bounding boxes on every run
250
+ // (computeConnectorBoundingBoxes). Connections still resolve because the
251
+ // regenerated connector uuids match the connection endpoints.
252
+
269
253
  if (exportableChildren.length > 0) {
270
254
  jsonObject.children = exportableChildren;
271
255
  }
@@ -279,9 +263,9 @@ var SceneExportManager = /*#__PURE__*/function () {
279
263
  // Extract main scene objects (components and standalone connectors)
280
264
  var sceneChildren = [];
281
265
  this.sceneViewer.scene.children.forEach(function (child) {
282
- var _child$userData3;
266
+ var _child$userData2;
283
267
  // Only export components and connectors; skip segments, gateways, polylines, etc.
284
- var objectType = (_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType;
268
+ var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
285
269
  if (objectType !== 'component' && objectType !== 'connector') {
286
270
  return;
287
271
  }
@@ -445,14 +429,14 @@ var SceneExportManager = /*#__PURE__*/function () {
445
429
  BufferGeometryUtils = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
446
430
  exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
447
431
  shouldExport = function shouldExport(child) {
448
- var _child$name, _child$userData4, _child$userData5, _child$userData6, _child$userData7;
432
+ var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
449
433
  if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
450
434
  if (child.name === 'fogPlane') return false; // Skip fog plane
451
- if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBrickWall) return false; // Skip environment
452
- if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGround) return false; // Skip environment
453
- if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isBaseGrid) return false; // Skip environment
435
+ if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
436
+ if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
437
+ if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
454
438
  if (child.isLight) return false; // Skip lights
455
- if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.isTransformControls) return false; // Skip transform controls
439
+ if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
456
440
  if (child.isTransformControls) return false; // Skip transform controls
457
441
  if (child.type && child.type.includes('TransformControls')) return false;
458
442
  if (child.type && child.type.includes('Helper')) return false; // Skip helpers
@@ -866,6 +866,19 @@ var SceneOperationsManager = /*#__PURE__*/function () {
866
866
  if (!(data !== null && data !== void 0 && (_data$scene2 = data.scene) !== null && _data$scene2 !== void 0 && _data$scene2.children) || !componentDictionary) {
867
867
  return;
868
868
  }
869
+
870
+ // Collect every connector uuid referenced by the scene's connections so we
871
+ // can inject connectors under the SAME uuid scheme the scene actually uses.
872
+ // Two schemes exist in the wild:
873
+ // - Preferred (runtime add path + minimal export): `${componentUuid}_${dictConnectorUuid}`
874
+ // - Legacy (older hand-authored scenes): `${componentUuid}-CONNECTOR-${index+1}`
875
+ var connectionEndpoints = new Set();
876
+ if (Array.isArray(data.connections)) {
877
+ data.connections.forEach(function (conn) {
878
+ if (conn !== null && conn !== void 0 && conn.from) connectionEndpoints.add(conn.from);
879
+ if (conn !== null && conn !== void 0 && conn.to) connectionEndpoints.add(conn.to);
880
+ });
881
+ }
869
882
  var componentsProcessed = 0;
870
883
  var connectorsInjected = 0;
871
884
  data.scene.children.forEach(function (child) {
@@ -888,9 +901,18 @@ var SceneOperationsManager = /*#__PURE__*/function () {
888
901
 
889
902
  // Deep clone the connector children from the dictionary
890
903
  child.children = dictEntry.children.map(function (connector, index) {
891
- // Generate unique UUID for this connector instance
892
- // Format: COMPONENT-UUID-CONNECTOR-INDEX
893
- var connectorUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
904
+ // Choose the connector uuid that matches the scheme the scene's
905
+ // connections reference. Prefer `${componentUuid}_${dictConnectorUuid}`
906
+ // (sandbox add path + minimal export); fall back to the legacy
907
+ // index-based scheme `${componentUuid}-CONNECTOR-${index+1}` when the
908
+ // connections reference that form. If neither is referenced (e.g. an
909
+ // unconnected connector), default to the preferred scheme.
910
+ var legacyUuid = "".concat(child.uuid, "-CONNECTOR-").concat(index + 1);
911
+ var preferredUuid = connector.uuid ? "".concat(child.uuid, "_").concat(connector.uuid) : legacyUuid;
912
+ var connectorUuid = preferredUuid;
913
+ if (!connectionEndpoints.has(preferredUuid) && connectionEndpoints.has(legacyUuid)) {
914
+ connectorUuid = legacyUuid;
915
+ }
894
916
 
895
917
  // Clone connector with deep copy of userData
896
918
  var clonedConnector = _objectSpread2(_objectSpread2({}, connector), {}, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.48",
3
+ "version": "0.3.49",
4
4
  "description": "Utility modules for the Central Plant Application",
5
5
  "main": "dist/bundle/index.js",
6
6
  "module": "dist/esm/src/index.js",