@2112-lab/central-plant 0.3.58 → 0.3.59

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.
Files changed (27) hide show
  1. package/dist/bundle/index.js +1635 -32
  2. package/dist/cjs/src/core/centralPlant.js +80 -11
  3. package/dist/cjs/src/core/centralPlantInternals.js +4 -0
  4. package/dist/cjs/src/core/centralPlantValidator.js +10 -6
  5. package/dist/cjs/src/core/stateEngine.js +733 -0
  6. package/dist/cjs/src/core/stateEngineScene.js +97 -0
  7. package/dist/cjs/src/index.js +10 -0
  8. package/dist/cjs/src/managers/pathfinding/PathFlowManager.js +94 -13
  9. package/dist/cjs/src/managers/pathfinding/PathRenderingManager.js +15 -0
  10. package/dist/cjs/src/managers/scene/componentTooltipManager.js +7 -1
  11. package/dist/cjs/src/managers/scene/controlPanelManager.js +377 -0
  12. package/dist/cjs/src/managers/scene/sceneExportManager.js +10 -1
  13. package/dist/cjs/src/managers/state/EffectiveVisualManager.js +270 -0
  14. package/dist/esm/src/core/centralPlant.js +80 -11
  15. package/dist/esm/src/core/centralPlantInternals.js +4 -0
  16. package/dist/esm/src/core/centralPlantValidator.js +10 -6
  17. package/dist/esm/src/core/stateEngine.js +725 -0
  18. package/dist/esm/src/core/stateEngineScene.js +90 -0
  19. package/dist/esm/src/index.js +2 -0
  20. package/dist/esm/src/managers/pathfinding/PathFlowManager.js +94 -13
  21. package/dist/esm/src/managers/pathfinding/PathRenderingManager.js +15 -0
  22. package/dist/esm/src/managers/scene/componentTooltipManager.js +7 -1
  23. package/dist/esm/src/managers/scene/controlPanelManager.js +352 -0
  24. package/dist/esm/src/managers/scene/sceneExportManager.js +10 -1
  25. package/dist/esm/src/managers/state/EffectiveVisualManager.js +266 -0
  26. package/dist/index.d.ts +85 -0
  27. package/package.json +5 -2
@@ -7,6 +7,8 @@ import '../rendering/modelPreloader.js';
7
7
  import { scanSceneIoEndpoints, applyCrossComponentBehaviors, loadCrossComponentBehaviors, reregisterSceneBehaviors } from '../utils/behaviorSceneUtils.js';
8
8
  import { getScopedAttachmentKey } from '../utils/behaviorDispatch.js';
9
9
  import { computeFilteredBoundingBox } from '../utils/boundingBoxUtils.js';
10
+ import { StateEngine } from './stateEngine.js';
11
+ import { ioAddress, parseIoAddress, extractDeclaration } from './stateEngineScene.js';
10
12
 
11
13
  // ─────────────────────────────────────────────────────────────────────────────
12
14
  // Flow-direction compatibility helper (module-level, no class dependency)
@@ -34,7 +36,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
34
36
  * Initialize the CentralPlant manager
35
37
  *
36
38
  * @constructor
37
- * @version 0.3.58
39
+ * @version 0.3.59
38
40
  * @updated 2025-10-22
39
41
  *
40
42
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -73,6 +75,14 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
73
75
  // Initialize internals handler
74
76
  _this.internals = new CentralPlantInternals(_this);
75
77
 
78
+ // Portable State Engine: single source of truth for desired/effective state
79
+ // (plant/group/object/pipe). Owned here; the write door and scene load/save
80
+ // route through it. The 3D layer/store mirror its output (Framework §12–§13).
81
+ _this.stateEngine = new StateEngine();
82
+ _this._unsubscribeStateEngine = _this.stateEngine.subscribe(function (change) {
83
+ return _this._onEngineStateChange(change);
84
+ });
85
+
76
86
  // Optional cache primer function (dependency injection)
77
87
  _this.cachePrimer = null;
78
88
 
@@ -249,6 +259,16 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
249
259
  timestamp: new Date().toISOString()
250
260
  });
251
261
 
262
+ // Load plant / groups / chains / stateRegistry into the State Engine. v3.0
263
+ // scenes carry these; legacy v2.3 scenes load with safe defaults (§15).
264
+ if (this.stateEngine) {
265
+ try {
266
+ this.stateEngine.load(extractDeclaration(sceneData));
267
+ } catch (err) {
268
+ console.warn('⚠️ setImportedSceneData(): stateEngine.load() failed:', err);
269
+ }
270
+ }
271
+
252
272
  // Scene behaviors loaded
253
273
 
254
274
  // Cross-component behaviors are registered by sceneOperationsManager.loadSceneData()
@@ -1197,12 +1217,32 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
1197
1217
  }
1198
1218
 
1199
1219
  /**
1200
- * Internal single path for I/O state changes: persist, animate, link, emit.
1220
+ * Internal single path for I/O state changes. Routes the write through the
1221
+ * State Engine (the one write door, Framework §12); the engine subscription
1222
+ * ({@link CentralPlant#_onEngineStateChange}) mirrors to the state adapter,
1223
+ * animates meshes, and emits. Falls back to a direct write only if the engine
1224
+ * is unavailable.
1201
1225
  * @private
1202
1226
  */
1203
1227
  }, {
1204
1228
  key: "_dispatchIoState",
1205
1229
  value: function _dispatchIoState(attachmentId, stateId, value, parentUuid) {
1230
+ if (this.stateEngine) {
1231
+ this.stateEngine.setDesired(ioAddress(attachmentId, stateId, parentUuid), value);
1232
+ return;
1233
+ }
1234
+ this._dispatchIoStateDirect(attachmentId, stateId, value, parentUuid);
1235
+ }
1236
+
1237
+ /**
1238
+ * Persist to the state adapter, animate meshes, and emit for one I/O data
1239
+ * point. This is the mirror side of the engine (driven from desired, since I/O
1240
+ * data points are ungated) and the legacy fallback when no engine is present.
1241
+ * @private
1242
+ */
1243
+ }, {
1244
+ key: "_dispatchIoStateDirect",
1245
+ value: function _dispatchIoStateDirect(attachmentId, stateId, value, parentUuid) {
1206
1246
  var _this$managers, _this$sceneViewer5, _this$sceneViewer6, _this$managers2, _this$sceneViewer7, _this$sceneViewer8, _this$sceneViewer9;
1207
1247
  var tooltipMgr = ((_this$managers = this.managers) === null || _this$managers === void 0 ? void 0 : _this$managers.componentTooltipManager) || ((_this$sceneViewer5 = this.sceneViewer) === null || _this$sceneViewer5 === void 0 ? void 0 : _this$sceneViewer5.componentTooltipManager) || ((_this$sceneViewer6 = this.sceneViewer) === null || _this$sceneViewer6 === void 0 || (_this$sceneViewer6 = _this$sceneViewer6.managers) === null || _this$sceneViewer6 === void 0 ? void 0 : _this$sceneViewer6.componentTooltipManager);
1208
1248
  var stateAdapter = tooltipMgr === null || tooltipMgr === void 0 ? void 0 : tooltipMgr._stateAdapter;
@@ -1226,6 +1266,25 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
1226
1266
  });
1227
1267
  }
1228
1268
 
1269
+ /**
1270
+ * State Engine subscriber: fan a committed registry change out to the 3D/store
1271
+ * layer. I/O device data points (3-part addresses) mirror to the adapter and
1272
+ * animate; every change (incl. plant/group/object/pipe effective) is surfaced
1273
+ * as `engine-state-changed` for gating-aware visual subscribers (§13).
1274
+ * @private
1275
+ * @param {{ address: string, desired: *, effective: * }} change
1276
+ */
1277
+ }, {
1278
+ key: "_onEngineStateChange",
1279
+ value: function _onEngineStateChange(change) {
1280
+ var _this$sceneViewer0;
1281
+ var io = parseIoAddress(change.address);
1282
+ if (io) {
1283
+ this._dispatchIoStateDirect(io.attachmentId, io.stateId, change.desired, io.parentUuid);
1284
+ }
1285
+ (_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 || _this$sceneViewer0.emit('engine-state-changed', change);
1286
+ }
1287
+
1229
1288
  /**
1230
1289
  * Configure the state adapter on both tooltip and behavior managers.
1231
1290
  * @param {{ getState: Function, setState: Function }} stateAdapter
@@ -1233,16 +1292,16 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
1233
1292
  }, {
1234
1293
  key: "configureStateAdapter",
1235
1294
  value: function configureStateAdapter(stateAdapter) {
1236
- var _this$managers3, _this$sceneViewer0, _this$managers4, _this$sceneViewer10, _this$sceneViewer11;
1237
- var tooltipMgr = ((_this$managers3 = this.managers) === null || _this$managers3 === void 0 ? void 0 : _this$managers3.componentTooltipManager) || ((_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 ? void 0 : _this$sceneViewer0.componentTooltipManager);
1295
+ var _this$managers3, _this$sceneViewer1, _this$managers4, _this$sceneViewer11, _this$sceneViewer12;
1296
+ var tooltipMgr = ((_this$managers3 = this.managers) === null || _this$managers3 === void 0 ? void 0 : _this$managers3.componentTooltipManager) || ((_this$sceneViewer1 = this.sceneViewer) === null || _this$sceneViewer1 === void 0 ? void 0 : _this$sceneViewer1.componentTooltipManager);
1238
1297
  if (tooltipMgr !== null && tooltipMgr !== void 0 && tooltipMgr.configure) {
1239
- var _this$sceneViewer1;
1298
+ var _this$sceneViewer10;
1240
1299
  tooltipMgr.configure(stateAdapter);
1241
- if ((_this$sceneViewer1 = this.sceneViewer) !== null && _this$sceneViewer1 !== void 0 && _this$sceneViewer1.managers) {
1300
+ if ((_this$sceneViewer10 = this.sceneViewer) !== null && _this$sceneViewer10 !== void 0 && _this$sceneViewer10.managers) {
1242
1301
  this.sceneViewer.managers.componentTooltipManager = tooltipMgr;
1243
1302
  }
1244
1303
  }
1245
- var ioBehavMgr = ((_this$managers4 = this.managers) === null || _this$managers4 === void 0 ? void 0 : _this$managers4.ioBehaviorManager) || ((_this$sceneViewer10 = this.sceneViewer) === null || _this$sceneViewer10 === void 0 || (_this$sceneViewer10 = _this$sceneViewer10.managers) === null || _this$sceneViewer10 === void 0 ? void 0 : _this$sceneViewer10.ioBehaviorManager) || ((_this$sceneViewer11 = this.sceneViewer) === null || _this$sceneViewer11 === void 0 ? void 0 : _this$sceneViewer11.ioBehaviorManager);
1304
+ var ioBehavMgr = ((_this$managers4 = this.managers) === null || _this$managers4 === void 0 ? void 0 : _this$managers4.ioBehaviorManager) || ((_this$sceneViewer11 = this.sceneViewer) === null || _this$sceneViewer11 === void 0 || (_this$sceneViewer11 = _this$sceneViewer11.managers) === null || _this$sceneViewer11 === void 0 ? void 0 : _this$sceneViewer11.ioBehaviorManager) || ((_this$sceneViewer12 = this.sceneViewer) === null || _this$sceneViewer12 === void 0 ? void 0 : _this$sceneViewer12.ioBehaviorManager);
1246
1305
  if (ioBehavMgr !== null && ioBehavMgr !== void 0 && ioBehavMgr.configure) {
1247
1306
  ioBehavMgr.configure(stateAdapter);
1248
1307
  }
@@ -1277,8 +1336,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
1277
1336
  }, {
1278
1337
  key: "getSceneAttachments",
1279
1338
  value: function getSceneAttachments() {
1280
- var _this$sceneViewer12;
1281
- var scene = (_this$sceneViewer12 = this.sceneViewer) === null || _this$sceneViewer12 === void 0 ? void 0 : _this$sceneViewer12.scene;
1339
+ var _this$sceneViewer13;
1340
+ var scene = (_this$sceneViewer13 = this.sceneViewer) === null || _this$sceneViewer13 === void 0 ? void 0 : _this$sceneViewer13.scene;
1282
1341
  if (!scene) return [];
1283
1342
  var results = [];
1284
1343
  scene.traverse(function (obj) {
@@ -3059,12 +3118,14 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
3059
3118
  }, {
3060
3119
  key: "clearScene",
3061
3120
  value: function clearScene() {
3062
- var _this$sceneViewer13;
3121
+ var _this$sceneViewer14, _this$stateEngine;
3063
3122
  this.importedSceneData = null;
3064
- var ioBehavMgr = (_this$sceneViewer13 = this.sceneViewer) === null || _this$sceneViewer13 === void 0 || (_this$sceneViewer13 = _this$sceneViewer13.managers) === null || _this$sceneViewer13 === void 0 ? void 0 : _this$sceneViewer13.ioBehaviorManager;
3123
+ var ioBehavMgr = (_this$sceneViewer14 = this.sceneViewer) === null || _this$sceneViewer14 === void 0 || (_this$sceneViewer14 = _this$sceneViewer14.managers) === null || _this$sceneViewer14 === void 0 ? void 0 : _this$sceneViewer14.ioBehaviorManager;
3065
3124
  if (ioBehavMgr) {
3066
3125
  ioBehavMgr.setCrossComponentBehaviors([]);
3067
3126
  }
3127
+ // Reset the registry so pipe/object keys from the old scene don't linger (§15).
3128
+ (_this$stateEngine = this.stateEngine) === null || _this$stateEngine === void 0 || _this$stateEngine.reset();
3068
3129
  if (this.sceneViewer && this.sceneViewer.scene) {
3069
3130
  this.sceneViewer.scene.clear();
3070
3131
  }
@@ -3115,8 +3176,16 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
3115
3176
  }, {
3116
3177
  key: "_doDispose",
3117
3178
  value: function _doDispose() {
3179
+ var _this$stateEngine2;
3118
3180
  console.log('🧹 Disposing CentralPlant using enhanced disposal patterns...');
3119
3181
 
3182
+ // Tear down the State Engine subscription and registry.
3183
+ if (this._unsubscribeStateEngine) {
3184
+ this._unsubscribeStateEngine();
3185
+ this._unsubscribeStateEngine = null;
3186
+ }
3187
+ (_this$stateEngine2 = this.stateEngine) === null || _this$stateEngine2 === void 0 || _this$stateEngine2.reset();
3188
+
3120
3189
  // Use batch disposal for all managers
3121
3190
  var managers = Object.values(this.managers).filter(function (manager) {
3122
3191
  return manager && typeof manager.dispose === 'function';
@@ -26,6 +26,8 @@ import { ComponentTooltipManager } from '../managers/scene/componentTooltipManag
26
26
  import { Viewport2DManager } from '../managers/scene/viewport2DManager.js';
27
27
  import { IoBehaviorManager } from '../managers/behaviors/IoBehaviorManager.js';
28
28
  import { IoOutlineManager } from '../managers/behaviors/IoOutlineManager.js';
29
+ import { EffectiveVisualManager } from '../managers/state/EffectiveVisualManager.js';
30
+ import { ControlPanelManager } from '../managers/scene/controlPanelManager.js';
29
31
  import { generateUuidFromName, getHardcodedUuid, findObjectByHardcodedUuid, generateUniqueComponentId } from '../utils/nameUtils.js';
30
32
  import { attachIODevicesToComponent } from '../utils/ioDeviceUtils.js';
31
33
  import { computeFilteredBoundingBoxCached } from '../utils/boundingBoxUtils.js';
@@ -154,6 +156,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
154
156
  this.centralPlant.managers.viewport2DManager = new Viewport2DManager(this.centralPlant.sceneViewer);
155
157
  this.centralPlant.managers.ioBehaviorManager = new IoBehaviorManager(this.centralPlant.sceneViewer);
156
158
  this.centralPlant.managers.ioOutlineManager = new IoOutlineManager(this.centralPlant.sceneViewer);
159
+ this.centralPlant.managers.effectiveVisualManager = new EffectiveVisualManager(this.centralPlant.sceneViewer);
160
+ this.centralPlant.managers.controlPanelManager = new ControlPanelManager(this.centralPlant.sceneViewer);
157
161
 
158
162
  // All managers are now stored in the managers collection and will be attached via attachToComponent()
159
163
  }
@@ -817,20 +817,24 @@ var CentralPlantValidator = /*#__PURE__*/function () {
817
817
  key: "validateImportedSceneData",
818
818
  value: function validateImportedSceneData(sceneData) {
819
819
  var results = [];
820
- var hardcodedVersion = "2.3";
821
820
 
822
- // Version validation - MUST be the value of hardcodedVersion
823
- if (!sceneData.version || sceneData.version !== hardcodedVersion) {
821
+ // Supported scene formats: 2.3 (legacy I/O behaviors) and 3.0 (State Engine:
822
+ // adds plant/groups/chains/stateRegistry). Both load; older scenes keep working.
823
+ var supportedVersions = ["2.3", "3.0"];
824
+
825
+ // Version validation - MUST be one of the supported versions
826
+ if (!sceneData.version || !supportedVersions.includes(sceneData.version)) {
824
827
  var providedVersion = sceneData.version || 'unknown';
825
- alert("The central-plant requires the input file to be version ".concat(hardcodedVersion));
828
+ var supportedList = supportedVersions.join(' or ');
829
+ alert("The central-plant requires the input file to be version ".concat(supportedList));
826
830
  results.push({
827
831
  isValid: false,
828
832
  severity: ValidationSeverity.ERROR,
829
- message: "Invalid version: \"".concat(providedVersion, "\". Required version is \"").concat(hardcodedVersion, "\""),
833
+ message: "Invalid version: \"".concat(providedVersion, "\". Supported versions are ").concat(supportedList),
830
834
  code: 'INVALID_VERSION',
831
835
  metadata: {
832
836
  providedVersion: providedVersion,
833
- requiredVersion: hardcodedVersion
837
+ supportedVersions: supportedVersions
834
838
  }
835
839
  });
836
840
  return this._combineValidationResults(results, 'scene_import_validation');