@2112-lab/central-plant 0.2.5 → 0.2.10

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.
@@ -5,6 +5,22 @@ import { DisposalUtilities } from '../utils/DisposalUtilities.js';
5
5
  import { CentralPlantInternals } from './centralPlantInternals.js';
6
6
  import '../rendering/modelPreloader.js';
7
7
 
8
+ // ─────────────────────────────────────────────────────────────────────────────
9
+ // Flow-direction compatibility helper (module-level, no class dependency)
10
+ // ─────────────────────────────────────────────────────────────────────────────
11
+
12
+ /**
13
+ * Returns true if the two flow directions are compatible for a connection.
14
+ * @param {string} fromFlow - 'in' | 'out' | 'bi'
15
+ * @param {string} toFlow - 'in' | 'out' | 'bi'
16
+ * @returns {boolean}
17
+ */
18
+ function _areFlowsCompatible(fromFlow, toFlow) {
19
+ if (fromFlow === 'bi' || toFlow === 'bi') return true;
20
+ // in ↔ out are compatible; in → in and out → out are not
21
+ return fromFlow !== toFlow;
22
+ }
23
+
8
24
  /**
9
25
  * CentralPlant class that manages all scene utility instances and provides public API
10
26
  *
@@ -15,7 +31,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
15
31
  * Initialize the CentralPlant manager
16
32
  *
17
33
  * @constructor
18
- * @version 0.2.5
34
+ * @version 0.2.10
19
35
  * @updated 2025-10-22
20
36
  *
21
37
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -948,6 +964,107 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
948
964
  return availableConnectorIds;
949
965
  }
950
966
 
967
+ /**
968
+ * Get available connectors with their flow direction metadata.
969
+ * Same filtering logic as getAvailableConnections() but returns objects instead of strings.
970
+ * @returns {Array<{id: string, flow: string}>} Array of connector info objects.
971
+ * flow is one of 'in', 'out', 'bi'. Defaults to 'bi' if not set in userData.
972
+ * @example
973
+ * const infos = centralPlant.getAvailableConnectionsInfo()
974
+ * // [{ id: 'PUMP-1-CONNECTOR-1', flow: 'out' }, ...]
975
+ */
976
+ }, {
977
+ key: "getAvailableConnectionsInfo",
978
+ value: function getAvailableConnectionsInfo() {
979
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
980
+ console.warn('⚠️ getAvailableConnectionsInfo(): Scene viewer or current scene data not available');
981
+ return [];
982
+ }
983
+ var sceneData = this.sceneViewer.currentSceneData;
984
+ if (!sceneData.scene || !sceneData.scene.children) {
985
+ console.warn('⚠️ getAvailableConnectionsInfo(): Invalid scene data structure');
986
+ return [];
987
+ }
988
+ var allConnectorInfos = [];
989
+ sceneData.scene.children.forEach(function (component) {
990
+ if (component.children && Array.isArray(component.children)) {
991
+ component.children.forEach(function (child) {
992
+ if (child.userData && child.userData.objectType === 'connector' && child.uuid) {
993
+ allConnectorInfos.push({
994
+ id: child.uuid,
995
+ flow: child.userData.flow || 'bi'
996
+ });
997
+ }
998
+ });
999
+ }
1000
+ });
1001
+ var existingConnections = this.getConnections();
1002
+ var usedConnectorIds = new Set();
1003
+ existingConnections.forEach(function (connection) {
1004
+ if (connection.from) usedConnectorIds.add(connection.from);
1005
+ if (connection.to) usedConnectorIds.add(connection.to);
1006
+ });
1007
+ return allConnectorInfos.filter(function (info) {
1008
+ return !usedConnectorIds.has(info.id);
1009
+ });
1010
+ }
1011
+
1012
+ /**
1013
+ * Validate all connections in the current scene for flow direction compatibility.
1014
+ * @returns {{ valid: Array<Object>, invalid: Array<{connection: Object, reason: string}> }}
1015
+ * @example
1016
+ * const result = centralPlant.validateConnections()
1017
+ * result.invalid.forEach(({ connection, reason }) => console.warn(reason, connection))
1018
+ */
1019
+ }, {
1020
+ key: "validateConnections",
1021
+ value: function validateConnections() {
1022
+ if (!this.sceneViewer || !this.sceneViewer.currentSceneData) {
1023
+ console.warn('⚠️ validateConnections(): Scene viewer or current scene data not available');
1024
+ return {
1025
+ valid: [],
1026
+ invalid: []
1027
+ };
1028
+ }
1029
+ var connections = this.getConnections();
1030
+ var sceneData = this.sceneViewer.currentSceneData;
1031
+
1032
+ // Build lookup map: connectorId → flow
1033
+ var flowMap = {};
1034
+ var scene = sceneData.scene || {};
1035
+ var children = scene.children || [];
1036
+ children.forEach(function (component) {
1037
+ if (component.children && Array.isArray(component.children)) {
1038
+ component.children.forEach(function (child) {
1039
+ if (child.userData && child.userData.objectType === 'connector' && child.uuid) {
1040
+ flowMap[child.uuid] = child.userData.flow || 'bi';
1041
+ }
1042
+ });
1043
+ }
1044
+ });
1045
+ var valid = [];
1046
+ var invalid = [];
1047
+ connections.forEach(function (connection) {
1048
+ var fromFlow = flowMap[connection.from] || 'bi';
1049
+ var toFlow = flowMap[connection.to] || 'bi';
1050
+ if (_areFlowsCompatible(fromFlow, toFlow)) {
1051
+ valid.push(connection);
1052
+ } else {
1053
+ var reason = "Incompatible flow directions: connector '".concat(connection.from, "' is '").concat(fromFlow, "' and connector '").concat(connection.to, "' is '").concat(toFlow, "' \u2014 ").concat(fromFlow, " \u2192 ").concat(toFlow, " is not allowed");
1054
+ console.warn("\u26A0\uFE0F validateConnections(): ".concat(reason));
1055
+ invalid.push({
1056
+ connection: connection,
1057
+ reason: reason
1058
+ });
1059
+ }
1060
+ });
1061
+ console.log("\u2705 validateConnections(): ".concat(valid.length, " valid, ").concat(invalid.length, " invalid connections"));
1062
+ return {
1063
+ valid: valid,
1064
+ invalid: invalid
1065
+ };
1066
+ }
1067
+
951
1068
  // ─────────────────────────────────────────────────────────────────────────
952
1069
  // BEHAVIORS API
953
1070
  // ─────────────────────────────────────────────────────────────────────────
@@ -14,6 +14,7 @@ import { SceneInitializationManager } from '../managers/scene/sceneInitializatio
14
14
  import { EnvironmentManager } from '../managers/environment/environmentManager.js';
15
15
  import { KeyboardControlsManager } from '../managers/controls/keyboardControlsManager.js';
16
16
  import { PathfindingManager } from '../managers/pathfinding/pathfindingManager.js';
17
+ import { PathFlowManager } from '../managers/pathfinding/PathFlowManager.js';
17
18
  import { BehaviorManager } from '../managers/behaviors/BehaviorManager.js';
18
19
  import { SceneOperationsManager } from '../managers/scene/sceneOperationsManager.js';
19
20
  import { AnimationManager } from '../managers/scene/animationManager.js';
@@ -26,6 +27,59 @@ import { generateUuidFromName, getHardcodedUuid, findObjectByHardcodedUuid, gene
26
27
  import { attachIODevicesToComponent } from '../utils/ioDeviceUtils.js';
27
28
  import modelPreloader from '../rendering/modelPreloader.js';
28
29
 
30
+ // ─────────────────────────────────────────────────────────────────────────────
31
+ // Flow-direction helpers (module-level)
32
+ // ─────────────────────────────────────────────────────────────────────────────
33
+
34
+ /**
35
+ * Returns the flow direction of a connector from the current scene data.
36
+ * @param {Object} sceneData - currentSceneData object
37
+ * @param {string} connectorId
38
+ * @returns {'in'|'out'|'bi'} Defaults to 'bi' if not set.
39
+ */
40
+ function _getConnectorFlow(sceneData, connectorId) {
41
+ var _sceneData$scene;
42
+ var children = (sceneData === null || sceneData === void 0 || (_sceneData$scene = sceneData.scene) === null || _sceneData$scene === void 0 ? void 0 : _sceneData$scene.children) || [];
43
+ var _iterator = _createForOfIteratorHelper(children),
44
+ _step;
45
+ try {
46
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
47
+ var component = _step.value;
48
+ var _iterator2 = _createForOfIteratorHelper(component.children || []),
49
+ _step2;
50
+ try {
51
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
52
+ var _child$userData;
53
+ var child = _step2.value;
54
+ if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector' && child.uuid === connectorId) {
55
+ return child.userData.flow || 'bi';
56
+ }
57
+ }
58
+ } catch (err) {
59
+ _iterator2.e(err);
60
+ } finally {
61
+ _iterator2.f();
62
+ }
63
+ }
64
+ } catch (err) {
65
+ _iterator.e(err);
66
+ } finally {
67
+ _iterator.f();
68
+ }
69
+ return 'bi';
70
+ }
71
+
72
+ /**
73
+ * Returns true if fromFlow → toFlow is a valid connection.
74
+ * @param {'in'|'out'|'bi'} fromFlow
75
+ * @param {'in'|'out'|'bi'} toFlow
76
+ * @returns {boolean}
77
+ */
78
+ function _areFlowsCompatible(fromFlow, toFlow) {
79
+ if (fromFlow === 'bi' || toFlow === 'bi') return true;
80
+ return fromFlow !== toFlow;
81
+ }
82
+
29
83
  /**
30
84
  * CentralPlantInternals class containing internal methods and functionality
31
85
  */
@@ -87,6 +141,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
87
141
  this.centralPlant.managers.environmentManager = new EnvironmentManager(this.centralPlant.sceneViewer);
88
142
  this.centralPlant.managers.keyboardControlsManager = new KeyboardControlsManager(this.centralPlant.sceneViewer);
89
143
  this.centralPlant.managers.pathfindingManager = new PathfindingManager(this.centralPlant.sceneViewer);
144
+ this.centralPlant.managers.pathFlowManager = new PathFlowManager(this.centralPlant.sceneViewer);
90
145
  this.centralPlant.managers.behaviorManager = new BehaviorManager(this.centralPlant.sceneViewer);
91
146
  this.centralPlant.managers.sceneOperationsManager = new SceneOperationsManager(this.centralPlant.sceneViewer);
92
147
  this.centralPlant.managers.animationManager = new AnimationManager(this.centralPlant.sceneViewer);
@@ -477,12 +532,12 @@ var CentralPlantInternals = /*#__PURE__*/function () {
477
532
  console.log("\uD83D\uDD27 Translating ".concat(selectedObjects.length, " selected object(s) on ").concat(axis, " axis by ").concat(value));
478
533
 
479
534
  // Translate each selected object using the appropriate method
480
- var _iterator = _createForOfIteratorHelper(selectedObjects),
481
- _step;
535
+ var _iterator3 = _createForOfIteratorHelper(selectedObjects),
536
+ _step3;
482
537
  try {
483
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
538
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
484
539
  var _obj$userData;
485
- var obj = _step.value;
540
+ var obj = _step3.value;
486
541
  var objectType = (_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType;
487
542
  var objectId = obj.uuid;
488
543
  var success = false;
@@ -509,9 +564,9 @@ var CentralPlantInternals = /*#__PURE__*/function () {
509
564
  }
510
565
  }
511
566
  } catch (err) {
512
- _iterator.e(err);
567
+ _iterator3.e(err);
513
568
  } finally {
514
- _iterator.f();
569
+ _iterator3.f();
515
570
  }
516
571
  result.success = result.translatedCount === result.totalCount;
517
572
  if (result.success) {
@@ -695,7 +750,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
695
750
  }, {
696
751
  key: "addConnection",
697
752
  value: function addConnection(fromConnectorId, toConnectorId) {
698
- var _this$centralPlant$sc4;
753
+ var _this$centralPlant$sc4, _this$centralPlant$sc5;
699
754
  // Use centralized validation for connection parameters
700
755
  var existingConnections = ((_this$centralPlant$sc4 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc4 === void 0 || (_this$centralPlant$sc4 = _this$centralPlant$sc4.currentSceneData) === null || _this$centralPlant$sc4 === void 0 ? void 0 : _this$centralPlant$sc4.connections) || [];
701
756
  var validation = this.validator.validateConnectionParams(fromConnectorId, toConnectorId, existingConnections);
@@ -703,6 +758,17 @@ var CentralPlantInternals = /*#__PURE__*/function () {
703
758
  return false; // Validator already logged the error
704
759
  }
705
760
 
761
+ // Validate flow direction compatibility
762
+ var sceneData = (_this$centralPlant$sc5 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc5 === void 0 ? void 0 : _this$centralPlant$sc5.currentSceneData;
763
+ if (sceneData) {
764
+ var fromFlow = _getConnectorFlow(sceneData, fromConnectorId);
765
+ var toFlow = _getConnectorFlow(sceneData, toConnectorId);
766
+ if (!_areFlowsCompatible(fromFlow, toFlow)) {
767
+ console.error("\u274C addConnection(): Incompatible flow directions \u2014 '".concat(fromConnectorId, "' is '").concat(fromFlow, "' and '").concat(toConnectorId, "' is '").concat(toFlow, "'. ") + "'".concat(fromFlow, "' \u2192 '").concat(toFlow, "' connections are not allowed."));
768
+ return false;
769
+ }
770
+ }
771
+
706
772
  // Validate scene availability
707
773
  var sceneValidation = this.validator.validateSceneViewer(this.centralPlant.sceneViewer);
708
774
  if (!sceneValidation.isValid) {
@@ -823,7 +889,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
823
889
  }, {
824
890
  key: "addComponent",
825
891
  value: function addComponent(libraryId) {
826
- var _this$centralPlant$sc5;
892
+ var _this$centralPlant$sc6;
827
893
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
828
894
  // Use centralized validation for component addition parameters
829
895
  var existingIds = this.getComponentIds();
@@ -833,7 +899,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
833
899
  }
834
900
 
835
901
  // Validate scene availability
836
- var sceneValidation = this.validator.validateSceneViewer(this.centralPlant.sceneViewer, (_this$centralPlant$sc5 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc5 === void 0 ? void 0 : _this$centralPlant$sc5.scene);
902
+ var sceneValidation = this.validator.validateSceneViewer(this.centralPlant.sceneViewer, (_this$centralPlant$sc6 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc6 === void 0 ? void 0 : _this$centralPlant$sc6.scene);
837
903
  if (!sceneValidation.isValid) {
838
904
  return false;
839
905
  }
@@ -852,7 +918,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
852
918
  return false;
853
919
  }
854
920
  try {
855
- var _componentData$childr, _componentData$childr2, _this$centralPlant$sc6, _componentData$childr3, _componentData$defaul;
921
+ var _componentData$childr, _componentData$childr2, _this$centralPlant$sc7, _componentData$childr3, _componentData$defaul;
856
922
  // Generate a unique component ID if not provided
857
923
  var componentId = options.customId || this.generateUniqueComponentId(libraryId);
858
924
 
@@ -964,7 +1030,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
964
1030
  componentModel.updateMatrixWorld(true);
965
1031
 
966
1032
  // Check if component is underground and fix if needed (based on settings)
967
- var checkUnderground = (_this$centralPlant$sc6 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc6 === void 0 || (_this$centralPlant$sc6 = _this$centralPlant$sc6.managers) === null || _this$centralPlant$sc6 === void 0 || (_this$centralPlant$sc6 = _this$centralPlant$sc6.settingsManager) === null || _this$centralPlant$sc6 === void 0 ? void 0 : _this$centralPlant$sc6.getSetting('scene', 'checkUnderground');
1033
+ var checkUnderground = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 || (_this$centralPlant$sc7 = _this$centralPlant$sc7.managers) === null || _this$centralPlant$sc7 === void 0 || (_this$centralPlant$sc7 = _this$centralPlant$sc7.settingsManager) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.getSetting('scene', 'checkUnderground');
968
1034
  if (checkUnderground) {
969
1035
  var wasFixed = this.fixUndergroundComponent(componentModel);
970
1036
  if (wasFixed) {
@@ -1062,8 +1128,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1062
1128
  // responds to tooltip-driven state changes immediately after drop.
1063
1129
  // (The scene-load path uses _processBehaviors instead, which runs on loadSceneData.)
1064
1130
  if ((_componentData$defaul = componentData.defaultBehaviors) !== null && _componentData$defaul !== void 0 && _componentData$defaul.length) {
1065
- var _this$centralPlant$sc7, _som$registerBehavior;
1066
- var som = (_this$centralPlant$sc7 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc7 === void 0 ? void 0 : _this$centralPlant$sc7.sceneOperationsManager;
1131
+ var _this$centralPlant$sc8, _som$registerBehavior;
1132
+ var som = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.sceneOperationsManager;
1067
1133
  som === null || som === void 0 || (_som$registerBehavior = som.registerBehaviorsForComponentInstance) === null || _som$registerBehavior === void 0 || _som$registerBehavior.call(som, componentData, componentId);
1068
1134
  }
1069
1135
 
@@ -1125,9 +1191,9 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1125
1191
  }, {
1126
1192
  key: "deleteComponent",
1127
1193
  value: function deleteComponent(componentId) {
1128
- var _this$centralPlant$sc8;
1194
+ var _this$centralPlant$sc9;
1129
1195
  // Check if component manager is available
1130
- var componentManager = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.componentManager;
1196
+ var componentManager = (_this$centralPlant$sc9 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc9 === void 0 ? void 0 : _this$centralPlant$sc9.componentManager;
1131
1197
  if (!componentManager) {
1132
1198
  console.error('❌ deleteComponent(): Component manager not available');
1133
1199
  return false;
@@ -1202,8 +1268,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1202
1268
  }
1203
1269
  var componentIds = [];
1204
1270
  this.centralPlant.sceneViewer.scene.traverse(function (child) {
1205
- var _child$userData;
1206
- if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'component') {
1271
+ var _child$userData2;
1272
+ if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'component') {
1207
1273
  componentIds.push(child.uuid || child.userData.originalUuid);
1208
1274
  }
1209
1275
  });
@@ -64,10 +64,19 @@ function createPathfindingRequest(startConnector, endConnector) {
64
64
  };
65
65
  }
66
66
 
67
+ /**
68
+ * The official set of flow-related attribute keys that can be set on a path.
69
+ * These attributes belong to the full path and are inherited by all segments.
70
+ *
71
+ * @type {string[]}
72
+ */
73
+ var FLOW_ATTRIBUTE_KEYS = ['flowDirection', 'flowSpeed', 'flowTemperature', 'flowMaterial'];
74
+
67
75
  /**
68
76
  * Data structure for storing path information with segments.
69
77
  * Tracks both computed and declared (manually edited) segments.
70
- *
78
+ * Also stores path-level flow attributes shared by all segments.
79
+ *
71
80
  * Business logic layer - stores coordinate data without Three.js dependencies.
72
81
  */
73
82
  var PathData = /*#__PURE__*/function () {
@@ -87,16 +96,60 @@ var PathData = /*#__PURE__*/function () {
87
96
  * @type {Array<{start: {x, y, z}, end: {x, y, z}, isDeclared: boolean, modifiedAt: number|null}>}
88
97
  */
89
98
  this.segments = [];
99
+
100
+ /**
101
+ * Path-level flow attributes shared by all segments within this path.
102
+ * Keys must come from FLOW_ATTRIBUTE_KEYS. Values are application-defined.
103
+ * @type {Record<string, any>}
104
+ */
105
+ this.flowAttributes = {};
90
106
  this.createdAt = Date.now();
91
107
  }
92
108
 
93
109
  /**
94
- * Add a computed segment (from pathfinding algorithm)
95
- *
96
- * @param {{x: number, y: number, z: number}} start - Start coordinate
97
- * @param {{x: number, y: number, z: number}} end - End coordinate
110
+ * Set a flow attribute on this path.
111
+ * All segments within this path inherit the value.
112
+ *
113
+ * @param {string} key - Attribute key (should be one of FLOW_ATTRIBUTE_KEYS)
114
+ * @param {any} value - Attribute value
98
115
  */
99
116
  return _createClass(PathData, [{
117
+ key: "setFlowAttribute",
118
+ value: function setFlowAttribute(key, value) {
119
+ this.flowAttributes[key] = value;
120
+ }
121
+
122
+ /**
123
+ * Get the declared value of a flow attribute.
124
+ * Returns null if the attribute has not been set.
125
+ *
126
+ * @param {string} key - Attribute key
127
+ * @returns {any|null}
128
+ */
129
+ }, {
130
+ key: "getFlowAttribute",
131
+ value: function getFlowAttribute(key) {
132
+ return Object.prototype.hasOwnProperty.call(this.flowAttributes, key) ? this.flowAttributes[key] : null;
133
+ }
134
+
135
+ /**
136
+ * Get a shallow copy of all declared flow attributes.
137
+ *
138
+ * @returns {Record<string, any>}
139
+ */
140
+ }, {
141
+ key: "getAllFlowAttributes",
142
+ value: function getAllFlowAttributes() {
143
+ return _objectSpread2({}, this.flowAttributes);
144
+ }
145
+
146
+ /**
147
+ * Add a computed segment (from pathfinding algorithm)
148
+ *
149
+ * @param {{x: number, y: number, z: number}} start - Start coordinate
150
+ * @param {{x: number, y: number, z: number}} end - End coordinate
151
+ */
152
+ }, {
100
153
  key: "addSegment",
101
154
  value: function addSegment(start, end) {
102
155
  this.segments.push({
@@ -173,6 +226,7 @@ var PathData = /*#__PURE__*/function () {
173
226
  segments: this.segments.map(function (seg) {
174
227
  return _objectSpread2({}, seg);
175
228
  }),
229
+ flowAttributes: _objectSpread2({}, this.flowAttributes),
176
230
  createdAt: this.createdAt
177
231
  };
178
232
  }
@@ -233,10 +287,11 @@ var PathData = /*#__PURE__*/function () {
233
287
  pathData.segments = json.segments.map(function (seg) {
234
288
  return _objectSpread2({}, seg);
235
289
  });
290
+ pathData.flowAttributes = json.flowAttributes ? _objectSpread2({}, json.flowAttributes) : {};
236
291
  pathData.createdAt = json.createdAt || Date.now();
237
292
  return pathData;
238
293
  }
239
294
  }]);
240
295
  }();
241
296
 
242
- export { PathData, createPathfindingRequest };
297
+ export { FLOW_ATTRIBUTE_KEYS, PathData, createPathfindingRequest };
@@ -98,7 +98,7 @@ var sceneViewer = /*#__PURE__*/function (_BaseDisposable) {
98
98
  this.centralPlant.attachToComponent();
99
99
 
100
100
  // Sync our managers tracking object after attachment
101
- managerKeys = ['threeJSResourceManager', 'performanceMonitorManager', 'settingsManager', 'sceneExportManager', 'componentManager', 'sceneInitializationManager', 'environmentManager', 'keyboardControlsManager', 'pathfindingManager', 'behaviorManager', 'sceneOperationsManager', 'animationManager', 'cameraControlsManager', 'componentDragManager', 'tooltipsManager', 'componentTooltipManager']; // Populate our managers tracking object
101
+ managerKeys = ['threeJSResourceManager', 'performanceMonitorManager', 'settingsManager', 'sceneExportManager', 'componentManager', 'sceneInitializationManager', 'environmentManager', 'keyboardControlsManager', 'pathfindingManager', 'pathFlowManager', 'behaviorManager', 'sceneOperationsManager', 'animationManager', 'cameraControlsManager', 'componentDragManager', 'tooltipsManager', 'componentTooltipManager']; // Populate our managers tracking object
102
102
  managerKeys.forEach(function (key) {
103
103
  if (_this2[key]) {
104
104
  _this2.managers[key] = _this2[key];
@@ -1,7 +1,7 @@
1
1
  export { default as CentralPlant } from './core/centralPlant.js';
2
2
  export { default as sceneViewer } from './core/sceneViewer.js';
3
3
  export { findObjectByHardcodedUuid, generateUniqueComponentId, generateUuidFromName, getHardcodedUuid } from './utils/nameUtils.js';
4
- export { PathData, createPathfindingRequest } from './core/pathfindingData.js';
4
+ export { FLOW_ATTRIBUTE_KEYS, PathData, createPathfindingRequest } from './core/pathfindingData.js';
5
5
  export { getObjectTypeName, getObjectsByType, isComponent, isComputed, isConnector, isDeclared, isExportable, isGateway, isSegment, markAsComputed, markAsDeclared, shouldRemoveOnRegeneration } from './utils/objectTypes.js';
6
6
  export { SceneInitializationManager } from './managers/scene/sceneInitializationManager.js';
7
7
  export { SceneOperationsManager } from './managers/scene/sceneOperationsManager.js';
@@ -13,6 +13,7 @@ export { BehaviorManager } from './managers/behaviors/BehaviorManager.js';
13
13
  export { ComponentManager } from './managers/components/componentManager.js';
14
14
  export { AnimationManager } from './managers/scene/animationManager.js';
15
15
  export { PathfindingManager } from './managers/pathfinding/pathfindingManager.js';
16
+ export { PathFlowManager } from './managers/pathfinding/PathFlowManager.js';
16
17
  export { SnapshotManager } from './managers/pathfinding/SnapshotManager.js';
17
18
  export { ComponentDataManager } from './managers/components/componentDataManager.js';
18
19
  export { createTransformControls } from './managers/controls/transformControlsManager.js';