@2112-lab/central-plant 0.3.41 → 0.3.43

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 (29) hide show
  1. package/dist/bundle/index.js +332 -123
  2. package/dist/cjs/src/core/centralPlant.js +41 -27
  3. package/dist/cjs/src/core/centralPlantInternals.js +3 -2
  4. package/dist/cjs/src/index.js +6 -0
  5. package/dist/cjs/src/managers/behaviors/IoBehaviorManager.js +1 -12
  6. package/dist/cjs/src/managers/controls/transformControls.js +2 -2
  7. package/dist/cjs/src/managers/controls/transformControlsManager.js +4 -7
  8. package/dist/cjs/src/managers/scene/modelManager.js +2 -2
  9. package/dist/cjs/src/utils/animationTransformUtils.js +10 -7
  10. package/dist/cjs/src/utils/behaviorDispatch.js +64 -0
  11. package/dist/cjs/src/utils/behaviorRegistration.js +12 -1
  12. package/dist/cjs/src/utils/behaviorSceneUtils.js +1 -1
  13. package/dist/cjs/src/utils/behaviorSchema.js +48 -0
  14. package/dist/cjs/src/utils/demoSceneUtils.js +91 -0
  15. package/dist/esm/src/core/centralPlant.js +41 -27
  16. package/dist/esm/src/core/centralPlantInternals.js +3 -2
  17. package/dist/esm/src/index.js +3 -2
  18. package/dist/esm/src/managers/behaviors/IoBehaviorManager.js +2 -13
  19. package/dist/esm/src/managers/controls/transformControls.js +2 -2
  20. package/dist/esm/src/managers/controls/transformControlsManager.js +4 -7
  21. package/dist/esm/src/managers/scene/modelManager.js +2 -2
  22. package/dist/esm/src/utils/animationTransformUtils.js +10 -7
  23. package/dist/esm/src/utils/behaviorDispatch.js +64 -1
  24. package/dist/esm/src/utils/behaviorRegistration.js +12 -1
  25. package/dist/esm/src/utils/behaviorSceneUtils.js +1 -1
  26. package/dist/esm/src/utils/behaviorSchema.js +49 -2
  27. package/dist/esm/src/utils/demoSceneUtils.js +85 -0
  28. package/dist/index.d.ts +16 -4
  29. package/package.json +1 -1
@@ -33,7 +33,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
33
33
  * Initialize the CentralPlant manager
34
34
  *
35
35
  * @constructor
36
- * @version 0.3.41
36
+ * @version 0.3.43
37
37
  * @updated 2025-10-22
38
38
  *
39
39
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -2525,7 +2525,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2525
2525
  key: "importScene",
2526
2526
  value: (function () {
2527
2527
  var _importScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10(jsonData) {
2528
- var validation, missingIds, resolved, _t4, _t5;
2528
+ var validation, embeddedCount, missingIds, resolved, _t4, _t5;
2529
2529
  return _regenerator().w(function (_context10) {
2530
2530
  while (1) switch (_context10.n) {
2531
2531
  case 0:
@@ -2546,64 +2546,78 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2546
2546
  console.error('❌ Invalid scene data format:', validation.message);
2547
2547
  return _context10.a(2, false);
2548
2548
  case 2:
2549
+ if (!(jsonData.componentDefinitions && _typeof(jsonData.componentDefinitions) === 'object')) {
2550
+ _context10.n = 4;
2551
+ break;
2552
+ }
2553
+ embeddedCount = Object.keys(jsonData.componentDefinitions).length;
2554
+ if (!(embeddedCount > 0)) {
2555
+ _context10.n = 4;
2556
+ break;
2557
+ }
2558
+ _context10.n = 3;
2559
+ return this.extendComponentDictionary(jsonData.componentDefinitions);
2560
+ case 3:
2561
+ console.log("\uD83D\uDCE6 importScene(): Applied ".concat(embeddedCount, " embedded component definition(s)"));
2562
+ case 4:
2549
2563
  if (!this._componentDefinitionResolver) {
2550
- _context10.n = 8;
2564
+ _context10.n = 10;
2551
2565
  break;
2552
2566
  }
2553
2567
  missingIds = this.getMissingLibraryIds(jsonData);
2554
2568
  if (!(missingIds.length > 0)) {
2555
- _context10.n = 8;
2569
+ _context10.n = 10;
2556
2570
  break;
2557
2571
  }
2558
- _context10.p = 3;
2572
+ _context10.p = 5;
2559
2573
  console.log("\uD83D\uDD0D importScene(): Resolving ".concat(missingIds.length, " missing component definition(s)..."));
2560
- _context10.n = 4;
2574
+ _context10.n = 6;
2561
2575
  return this._componentDefinitionResolver(missingIds);
2562
- case 4:
2576
+ case 6:
2563
2577
  resolved = _context10.v;
2564
2578
  if (!(resolved && _typeof(resolved) === 'object' && Object.keys(resolved).length > 0)) {
2565
- _context10.n = 6;
2579
+ _context10.n = 8;
2566
2580
  break;
2567
2581
  }
2568
- _context10.n = 5;
2582
+ _context10.n = 7;
2569
2583
  return this.extendComponentDictionary(resolved);
2570
- case 5:
2584
+ case 7:
2571
2585
  console.log("\u2705 importScene(): Resolved ".concat(Object.keys(resolved).length, " component definition(s)"));
2572
- case 6:
2573
- _context10.n = 8;
2586
+ case 8:
2587
+ _context10.n = 10;
2574
2588
  break;
2575
- case 7:
2576
- _context10.p = 7;
2589
+ case 9:
2590
+ _context10.p = 9;
2577
2591
  _t4 = _context10.v;
2578
2592
  console.warn('⚠️ importScene(): Component definition resolver failed, continuing with existing dictionary:', _t4);
2579
- case 8:
2580
- _context10.n = 9;
2593
+ case 10:
2594
+ _context10.n = 11;
2581
2595
  return this.setImportedSceneData(jsonData);
2582
- case 9:
2596
+ case 11:
2583
2597
  if (!(this.sceneViewer && this.sceneViewer.sceneOperationsManager)) {
2584
- _context10.n = 11;
2598
+ _context10.n = 13;
2585
2599
  break;
2586
2600
  }
2587
- _context10.n = 10;
2601
+ _context10.n = 12;
2588
2602
  return this.sceneViewer.sceneOperationsManager.loadSceneFromData(jsonData);
2589
- case 10:
2603
+ case 12:
2590
2604
  console.log('✅ Scene imported successfully');
2591
2605
  return _context10.a(2, true);
2592
- case 11:
2606
+ case 13:
2593
2607
  console.error('❌ SceneViewer not available for scene loading');
2594
2608
  return _context10.a(2, false);
2595
- case 12:
2596
- _context10.n = 14;
2609
+ case 14:
2610
+ _context10.n = 16;
2597
2611
  break;
2598
- case 13:
2599
- _context10.p = 13;
2612
+ case 15:
2613
+ _context10.p = 15;
2600
2614
  _t5 = _context10.v;
2601
2615
  console.error('❌ Error importing scene:', _t5);
2602
2616
  return _context10.a(2, false);
2603
- case 14:
2617
+ case 16:
2604
2618
  return _context10.a(2);
2605
2619
  }
2606
- }, _callee10, this, [[3, 7], [1, 13]]);
2620
+ }, _callee10, this, [[5, 9], [1, 15]]);
2607
2621
  }));
2608
2622
  function importScene(_x6) {
2609
2623
  return _importScene.apply(this, arguments);
@@ -892,7 +892,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
892
892
  }, {
893
893
  key: "addComponent",
894
894
  value: function addComponent(libraryId) {
895
- var _this$centralPlant$sc6;
895
+ var _this$centralPlant$sc6,
896
+ _this2 = this;
896
897
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
897
898
  // Use centralized validation for component addition parameters
898
899
  var existingIds = this.getComponentIds();
@@ -1129,7 +1130,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
1129
1130
  var ioBehavMgr = (_this$centralPlant$sc8 = this.centralPlant.sceneViewer) === null || _this$centralPlant$sc8 === void 0 || (_this$centralPlant$sc8 = _this$centralPlant$sc8.managers) === null || _this$centralPlant$sc8 === void 0 ? void 0 : _this$centralPlant$sc8.ioBehaviorManager;
1130
1131
  attachIODevicesToComponent(componentModel, componentData, modelPreloader, componentId).then(function () {
1131
1132
  if (ioBehavMgr) {
1132
- registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary);
1133
+ registerBehaviorsForComponent(ioBehavMgr, componentId, componentData, componentModel, modelPreloader.componentDictionary, _this2.centralPlant);
1133
1134
  }
1134
1135
  }).catch(function (err) {
1135
1136
  console.error("\u274C Error attaching IO devices for ".concat(libraryId, ":"), err);
@@ -10,10 +10,11 @@ export { SceneTooltipsManager } from './managers/scene/sceneTooltipsManager.js';
10
10
  export { ComponentTooltipManager } from './managers/scene/componentTooltipManager.js';
11
11
  export { SceneHierarchyManager } from './managers/scene/sceneHierarchyManager.js';
12
12
  export { IoBehaviorManager } from './managers/behaviors/IoBehaviorManager.js';
13
- export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior } from './utils/behaviorSchema.js';
13
+ export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior, resolveAnimationDefaultValue } from './utils/behaviorSchema.js';
14
14
  export { registerBehaviorsForComponent, reloadBehaviorsForDeviceAsset } from './utils/behaviorRegistration.js';
15
- export { getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints } from './utils/behaviorDispatch.js';
15
+ export { applyDefaultIoDeviceStates, getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints } from './utils/behaviorDispatch.js';
16
16
  export { applyCrossComponentBehaviors, loadCrossComponentBehaviors, refreshSceneIntraBehaviors, reregisterSceneBehaviors, scanSceneIoEndpoints } from './utils/behaviorSceneUtils.js';
17
+ export { collectSceneLibraryIds, embedComponentDefinitions, getComponentDictionary } from './utils/demoSceneUtils.js';
17
18
  export { applyModelRootTranslation, applyModelRootTranslationFromWorldBase, modelOffsetToWorldDelta } from './utils/animationTransformUtils.js';
18
19
  export { ComponentManager } from './managers/components/componentManager.js';
19
20
  export { AnimationManager } from './managers/scene/animationManager.js';
@@ -1,7 +1,7 @@
1
1
  import { inherits as _inherits, createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, slicedToArray as _slicedToArray, toConsumableArray as _toConsumableArray, superPropGet as _superPropGet, classCallCheck as _classCallCheck, callSuper as _callSuper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
2
  import * as THREE from 'three';
3
3
  import { BaseDisposable } from '../../core/baseDisposable.js';
4
- import { normalizeBehavior } from '../../utils/behaviorSchema.js';
4
+ import { normalizeBehavior, resolveAnimationDefaultValue } from '../../utils/behaviorSchema.js';
5
5
  import { getScopedAttachmentKey } from '../../utils/behaviorDispatch.js';
6
6
  import { applyModelRootTranslation } from '../../utils/animationTransformUtils.js';
7
7
 
@@ -595,18 +595,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
595
595
  stateConfig.max = Math.max.apply(Math, _toConsumableArray(nums));
596
596
  }
597
597
  }
598
-
599
- // Sensible default values
600
- var defaultValue = void 0;
601
- if (stateType === 'binary') {
602
- defaultValue = 0;
603
- } else if (stateType === 'enum') {
604
- var _stateConfig$options$, _stateConfig$options;
605
- defaultValue = (_stateConfig$options$ = (_stateConfig$options = stateConfig.options) === null || _stateConfig$options === void 0 ? void 0 : _stateConfig$options[0]) !== null && _stateConfig$options$ !== void 0 ? _stateConfig$options$ : '';
606
- } else {
607
- var _stateConfig$min;
608
- defaultValue = (_stateConfig$min = stateConfig.min) !== null && _stateConfig$min !== void 0 ? _stateConfig$min : 0;
609
- }
598
+ var defaultValue = resolveAnimationDefaultValue(_anim);
610
599
  dps.push({
611
600
  id: stateVar,
612
601
  name: _anim.name || stateVar,
@@ -490,8 +490,8 @@ var transformControls = /*#__PURE__*/function (_THREE$Object3D) {
490
490
  }, {
491
491
  key: "setMode",
492
492
  value: function setMode(mode) {
493
- if (mode === 'scale') {
494
- console.warn('transformControls: Scale mode has been removed. Using translate mode instead.');
493
+ if (mode !== 'translate') {
494
+ console.warn("transformControls: ".concat(mode, " mode is disabled. Locking to translate."));
495
495
  mode = 'translate';
496
496
  }
497
497
  this.mode = mode;
@@ -415,10 +415,6 @@ var TransformControlsManager = /*#__PURE__*/function () {
415
415
  // Translate mode
416
416
  _this3.setMode('translate');
417
417
  break;
418
- case 'KeyR':
419
- // Rotate mode
420
- _this3.setMode('rotate');
421
- break;
422
418
  }
423
419
  };
424
420
  window.addEventListener('keydown', this.eventHandlers.keydown);
@@ -1438,9 +1434,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
1438
1434
  }, {
1439
1435
  key: "setMode",
1440
1436
  value: function setMode(mode) {
1441
- if (!['translate', 'rotate', 'scale'].includes(mode)) {
1442
- console.warn("\u26A0\uFE0F Invalid transform mode: ".concat(mode));
1443
- return;
1437
+ // Only allow translate mode - lock rotation and scale controls
1438
+ if (mode !== 'translate') {
1439
+ console.warn("\u26A0\uFE0F Transform mode ".concat(mode, " is disabled. Locking to translate."));
1440
+ mode = 'translate';
1444
1441
  }
1445
1442
  var previousMode = this.currentMode;
1446
1443
  this.currentMode = mode;
@@ -54,7 +54,7 @@ var ModelManager = /*#__PURE__*/function () {
54
54
  key: "loadLibraryModel",
55
55
  value: function () {
56
56
  var _loadLibraryModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
57
- var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, warmFn, _jsonEntry$userData4, _t;
57
+ var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioBehavMgr, _this$sceneViewer2, warmFn, _jsonEntry$userData4, _t;
58
58
  return _regenerator().w(function (_context) {
59
59
  while (1) switch (_context.n) {
60
60
  case 0:
@@ -99,7 +99,7 @@ var ModelManager = /*#__PURE__*/function () {
99
99
  case 4:
100
100
  ioBehavMgr = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.ioBehaviorManager;
101
101
  if (ioBehavMgr) {
102
- registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary);
102
+ registerBehaviorsForComponent(ioBehavMgr, originalProps.uuid, componentData, libraryModel, modelPreloader.componentDictionary, (_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 ? void 0 : _this$sceneViewer2.centralPlant);
103
103
  }
104
104
  case 5:
105
105
  // Replace mesh in scene
@@ -9,13 +9,14 @@ import * as THREE from 'three';
9
9
  /**
10
10
  * @param {THREE.Object3D} modelRoot
11
11
  * @param {{ x?: number, y?: number, z?: number }|THREE.Vector3} offset
12
+ * @param {THREE.Quaternion} [customQuat] - Optional override for model orientation
12
13
  * @returns {THREE.Vector3}
13
14
  */
14
- function modelOffsetToWorldDelta(modelRoot, offset) {
15
+ function modelOffsetToWorldDelta(modelRoot, offset, customQuat) {
15
16
  var _offset$x, _offset$y, _offset$z;
16
17
  var v = offset instanceof THREE.Vector3 ? offset.clone() : new THREE.Vector3((_offset$x = offset === null || offset === void 0 ? void 0 : offset.x) !== null && _offset$x !== void 0 ? _offset$x : 0, (_offset$y = offset === null || offset === void 0 ? void 0 : offset.y) !== null && _offset$y !== void 0 ? _offset$y : 0, (_offset$z = offset === null || offset === void 0 ? void 0 : offset.z) !== null && _offset$z !== void 0 ? _offset$z : 0);
17
- var q = new THREE.Quaternion();
18
- modelRoot.getWorldQuaternion(q);
18
+ var q = customQuat ? customQuat.clone() : new THREE.Quaternion();
19
+ if (!customQuat) modelRoot.getWorldQuaternion(q);
19
20
  return v.applyQuaternion(q);
20
21
  }
21
22
 
@@ -26,14 +27,15 @@ function modelOffsetToWorldDelta(modelRoot, offset) {
26
27
  * @param {THREE.Object3D} modelRoot
27
28
  * @param {THREE.Vector3} origLocalPos
28
29
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
30
+ * @param {THREE.Quaternion} [customQuat]
29
31
  */
30
- function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
32
+ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset, customQuat) {
31
33
  if (!mesh || !modelRoot || !origLocalPos) return;
32
34
  mesh.position.copy(origLocalPos);
33
35
  mesh.updateMatrixWorld(true);
34
36
  var origWorldPos = new THREE.Vector3();
35
37
  mesh.getWorldPosition(origWorldPos);
36
- var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset));
38
+ var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
37
39
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
38
40
  mesh.position.copy(newWorldPos);
39
41
  }
@@ -45,10 +47,11 @@ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
45
47
  * @param {THREE.Object3D} modelRoot
46
48
  * @param {THREE.Vector3} baseWorldPos
47
49
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
50
+ * @param {THREE.Quaternion} [customQuat]
48
51
  */
49
- function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset) {
52
+ function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset, customQuat) {
50
53
  if (!mesh || !modelRoot || !baseWorldPos) return;
51
- var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset));
54
+ var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
52
55
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
53
56
  mesh.position.copy(newWorldPos);
54
57
  }
@@ -1,3 +1,5 @@
1
+ import { createForOfIteratorHelper as _createForOfIteratorHelper } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+
1
3
  /**
2
4
  * Shared I/O device state dispatch helpers used by centralPlant and componentTooltipManager.
3
5
  */
@@ -53,4 +55,65 @@ function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager
53
55
  });
54
56
  }
55
57
 
56
- export { getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints };
58
+ /**
59
+ * Apply persisted default values for I/O device animation states in the live scene.
60
+ * Updates the state adapter (e.g. Vuex) and drives mesh animations via IoBehaviorManager.
61
+ *
62
+ * @param {Object} centralPlant
63
+ * @param {{ parentUuid?: string, attachmentId?: string }} [options]
64
+ */
65
+ function applyDefaultIoDeviceStates(centralPlant) {
66
+ var _centralPlant$sceneVi;
67
+ var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
68
+ var parentUuid = options.parentUuid,
69
+ attachmentId = options.attachmentId;
70
+ var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
71
+ var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
72
+ if (!ioBehavMgr || !scene || typeof (centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.setIoDeviceState) !== 'function') return;
73
+ var seen = new Set();
74
+ scene.traverse(function (obj) {
75
+ var _obj$userData, _obj$parent;
76
+ if (((_obj$userData = obj.userData) === null || _obj$userData === void 0 ? void 0 : _obj$userData.objectType) !== 'io-device') return;
77
+ var objParentUuid = obj.userData.parentComponentId || ((_obj$parent = obj.parent) === null || _obj$parent === void 0 ? void 0 : _obj$parent.uuid);
78
+ var objAttachmentId = obj.userData.attachmentId;
79
+ if (!objParentUuid || !objAttachmentId) return;
80
+ if (parentUuid && objParentUuid !== parentUuid) return;
81
+ if (attachmentId && objAttachmentId !== attachmentId) return;
82
+ var scopedKey = getScopedAttachmentKey(objAttachmentId, objParentUuid);
83
+ if (seen.has(scopedKey)) return;
84
+ seen.add(scopedKey);
85
+ var dps = ioBehavMgr.getAnimationDataPoints(objParentUuid, objAttachmentId) || [];
86
+ if (dps.length) {
87
+ var _iterator = _createForOfIteratorHelper(dps),
88
+ _step;
89
+ try {
90
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
91
+ var dp = _step.value;
92
+ if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
93
+ centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
94
+ }
95
+ } catch (err) {
96
+ _iterator.e(err);
97
+ } finally {
98
+ _iterator.f();
99
+ }
100
+ return;
101
+ }
102
+ var _iterator2 = _createForOfIteratorHelper(obj.userData.dataPoints || []),
103
+ _step2;
104
+ try {
105
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
106
+ var _dp = _step2.value;
107
+ var dpId = _dp.id || _dp.name;
108
+ if (!dpId || _dp.defaultValue === undefined || _dp.defaultValue === null) continue;
109
+ centralPlant.setIoDeviceState(objAttachmentId, dpId, _dp.defaultValue, objParentUuid);
110
+ }
111
+ } catch (err) {
112
+ _iterator2.e(err);
113
+ } finally {
114
+ _iterator2.f();
115
+ }
116
+ });
117
+ }
118
+
119
+ export { applyDefaultIoDeviceStates, getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints };
@@ -1,4 +1,5 @@
1
1
  import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import { applyDefaultIoDeviceStates } from './behaviorDispatch.js';
2
3
 
3
4
  /**
4
5
  * Register mesh animations and intra-component state links when a smart
@@ -9,8 +10,9 @@ import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBab
9
10
  * @param {Object} componentData - Smart component dictionary entry
10
11
  * @param {Object} componentModel - Root THREE.Object3D of the placed component
11
12
  * @param {Object} componentDictionary - modelPreloader.componentDictionary
13
+ * @param {Object} [centralPlant] - When provided, default animation states are applied after registration
12
14
  */
13
- function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary) {
15
+ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData, componentModel, componentDictionary, centralPlant) {
14
16
  var _componentData$behavi;
15
17
  if (!ioBehavMgr || !componentData || !componentModel) {
16
18
  return;
@@ -40,6 +42,11 @@ function registerBehaviorsForComponent(ioBehavMgr, componentUuid, componentData,
40
42
  } else if (componentData.isSmart) {
41
43
  ioBehavMgr.registerComponentBehaviors(componentUuid, []);
42
44
  }
45
+ if (centralPlant) {
46
+ applyDefaultIoDeviceStates(centralPlant, {
47
+ parentUuid: componentUuid
48
+ });
49
+ }
43
50
  }
44
51
 
45
52
  /**
@@ -65,6 +72,10 @@ function reloadBehaviorsForDeviceAsset(ioBehavMgr, deviceAssetId, componentDicti
65
72
  if (!parentUuid || !attachmentId) return;
66
73
  ioBehavMgr.unloadForAttachment(parentUuid, attachmentId);
67
74
  ioBehavMgr.loadBehaviors(attachmentId, deviceData.behaviorConfig, obj, parentUuid);
75
+ applyDefaultIoDeviceStates(centralPlant, {
76
+ parentUuid: parentUuid,
77
+ attachmentId: attachmentId
78
+ });
68
79
  });
69
80
  }
70
81
 
@@ -140,7 +140,7 @@ function reregisterSceneBehaviors(centralPlant) {
140
140
  if (!libraryId) return;
141
141
  var componentData = dict[libraryId];
142
142
  if (!componentData) return;
143
- registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict);
143
+ registerBehaviorsForComponent(ioBehavMgr, obj.uuid, componentData, obj, dict, centralPlant);
144
144
  });
145
145
  }
146
146
 
@@ -1,4 +1,4 @@
1
- import { objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, typeof as _typeof } from '../../_virtual/_rollupPluginBabelHelpers.js';
1
+ import { objectSpread2 as _objectSpread2, slicedToArray as _slicedToArray, typeof as _typeof, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
2
 
3
3
  /**
4
4
  * Shared behavior schema helpers for runtime normalization and UI authoring.
@@ -198,4 +198,51 @@ function parseCrossBehavior(behavior) {
198
198
  };
199
199
  }
200
200
 
201
- export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior };
201
+ /**
202
+ * Resolve the runtime default value for an animation behavior entry.
203
+ * Uses explicit `defaultValue` when present; otherwise infers from stateType and mappings.
204
+ *
205
+ * @param {Object} anim - Behavior entry from behaviorConfig
206
+ * @returns {boolean|string|number}
207
+ */
208
+ function resolveAnimationDefaultValue(anim) {
209
+ var _anim$stateConfig2, _anim$stateConfig3;
210
+ if (!anim) return null;
211
+ var rawType = (anim.stateType || '').toLowerCase();
212
+ var isBinary = rawType === 'binary' || rawType === 'boolean';
213
+ var isEnum = rawType === 'enum';
214
+ if (anim.defaultValue !== undefined && anim.defaultValue !== null) {
215
+ if (isBinary) return !!anim.defaultValue;
216
+ if (isEnum) return String(anim.defaultValue);
217
+ var n = Number(anim.defaultValue);
218
+ return Number.isNaN(n) ? 0 : n;
219
+ }
220
+ if (isBinary) return false;
221
+ if (isEnum) {
222
+ var _anim$stateConfig, _resolved$;
223
+ var _mappingValues = (anim.mappings || []).map(function (m) {
224
+ return m.stateValue;
225
+ }).filter(function (v) {
226
+ return v !== '' && v != null;
227
+ });
228
+ var options = (((_anim$stateConfig = anim.stateConfig) === null || _anim$stateConfig === void 0 ? void 0 : _anim$stateConfig.options) || []).filter(function (o) {
229
+ return o !== '';
230
+ });
231
+ var resolved = options.length ? options : _toConsumableArray(new Set(_mappingValues.map(String)));
232
+ return (_resolved$ = resolved[0]) !== null && _resolved$ !== void 0 ? _resolved$ : '';
233
+ }
234
+ var mappingValues = (anim.mappings || []).map(function (m) {
235
+ return m.stateValue;
236
+ });
237
+ var nums = mappingValues.map(Number).filter(function (n) {
238
+ return !Number.isNaN(n);
239
+ });
240
+ if (nums.length) return Math.min.apply(Math, _toConsumableArray(nums));
241
+ if (((_anim$stateConfig2 = anim.stateConfig) === null || _anim$stateConfig2 === void 0 ? void 0 : _anim$stateConfig2.min) !== undefined && ((_anim$stateConfig3 = anim.stateConfig) === null || _anim$stateConfig3 === void 0 ? void 0 : _anim$stateConfig3.min) !== null) {
242
+ var min = Number(anim.stateConfig.min);
243
+ return Number.isNaN(min) ? 0 : min;
244
+ }
245
+ return 0;
246
+ }
247
+
248
+ export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBehavior, parseIntraBehavior, resolveAnimationDefaultValue };
@@ -0,0 +1,85 @@
1
+ import { typeof as _typeof, objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+
3
+ var _excluded = ["componentDefinitions"];
4
+ /**
5
+ * Helpers for portable demo scene JSON (embedded component definitions).
6
+ */
7
+
8
+ function cloneDefinition(def) {
9
+ if (!def || _typeof(def) !== 'object') return null;
10
+ try {
11
+ return JSON.parse(JSON.stringify(def));
12
+ } catch (_unused) {
13
+ return _objectSpread2({}, def);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Collect unique library IDs referenced by scene nodes.
19
+ * @param {Object} sceneData
20
+ * @returns {string[]}
21
+ */
22
+ function collectSceneLibraryIds(sceneData) {
23
+ var _sceneData$scene;
24
+ var ids = new Set();
25
+ var _walk = function walk(nodes) {
26
+ if (!Array.isArray(nodes)) return;
27
+ nodes.forEach(function (node) {
28
+ var _node$userData;
29
+ var libraryId = node === null || node === void 0 || (_node$userData = node.userData) === null || _node$userData === void 0 ? void 0 : _node$userData.libraryId;
30
+ if (libraryId) ids.add(libraryId);
31
+ if (node.children) _walk(node.children);
32
+ });
33
+ };
34
+ _walk(sceneData === null || sceneData === void 0 || (_sceneData$scene = sceneData.scene) === null || _sceneData$scene === void 0 ? void 0 : _sceneData$scene.children);
35
+ return Array.from(ids);
36
+ }
37
+
38
+ /**
39
+ * Embed component/device definitions required by a scene into the JSON payload.
40
+ * @param {Object} sceneData
41
+ * @param {Record<string, Object>} componentDictionary
42
+ * @returns {Object}
43
+ */
44
+ function embedComponentDefinitions(sceneData) {
45
+ var componentDictionary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
46
+ if (!sceneData || _typeof(sceneData) !== 'object') return sceneData;
47
+ var libraryIds = collectSceneLibraryIds(sceneData);
48
+ var componentDefinitions = {};
49
+ var deviceIds = new Set();
50
+ libraryIds.forEach(function (libraryId) {
51
+ var def = componentDictionary[libraryId];
52
+ if (!def) return;
53
+ componentDefinitions[libraryId] = cloneDefinition(def);
54
+ var attachedDevices = def.attachedDevices;
55
+ if (!attachedDevices || _typeof(attachedDevices) !== 'object') return;
56
+ Object.values(attachedDevices).forEach(function (att) {
57
+ if (att !== null && att !== void 0 && att.deviceId) deviceIds.add(att.deviceId);
58
+ });
59
+ });
60
+ deviceIds.forEach(function (deviceId) {
61
+ if (componentDefinitions[deviceId]) return;
62
+ var deviceDef = componentDictionary[deviceId];
63
+ if (deviceDef) componentDefinitions[deviceId] = cloneDefinition(deviceDef);
64
+ });
65
+ if (!Object.keys(componentDefinitions).length) {
66
+ sceneData.componentDefinitions;
67
+ var rest = _objectWithoutProperties(sceneData, _excluded);
68
+ return rest;
69
+ }
70
+ return _objectSpread2(_objectSpread2({}, sceneData), {}, {
71
+ componentDefinitions: componentDefinitions
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Resolve the live component dictionary from a CentralPlant instance.
77
+ * @param {Object} centralPlant
78
+ * @returns {Record<string, Object>}
79
+ */
80
+ function getComponentDictionary(centralPlant) {
81
+ var _centralPlant$getUtil, _centralPlant$manager;
82
+ return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || {};
83
+ }
84
+
85
+ export { collectSceneLibraryIds, embedComponentDefinitions, getComponentDictionary };
package/dist/index.d.ts CHANGED
@@ -52,7 +52,10 @@ export interface BehaviorEntry {
52
52
  meshUuid?: string
53
53
  meshName?: string
54
54
  stateVariable: string
55
- stateType?: 'binary' | 'enum' | 'continuous' | 'number' | 'boolean'
55
+ stateType?: 'binary' | 'enum' | 'continuous' | 'number' | 'boolean' | 'range'
56
+ defaultValue?: boolean | string | number
57
+ useFormula?: boolean
58
+ stateConfig?: Record<string, unknown>
56
59
  transformTypes?: string[]
57
60
  rotAxis?: 'x' | 'y' | 'z'
58
61
  rotAxisOffset?: { x: number; y: number; z: number }
@@ -144,6 +147,7 @@ export declare function parseCrossBehavior(behavior: CrossComponentBehavior): {
144
147
  inputState: string
145
148
  outputs: Array<{ endpoint: string; state: string }>
146
149
  }
150
+ export declare function resolveAnimationDefaultValue(anim: BehaviorEntry): boolean | string | number | null
147
151
 
148
152
  export declare function getScopedAttachmentKey(attachmentId: string, parentUuid?: string | null): string
149
153
  export declare function getIoBehaviorManager(sceneViewer: any): IoBehaviorManager | null
@@ -160,7 +164,13 @@ export declare function registerBehaviorsForComponent(
160
164
  componentUuid: string,
161
165
  componentData: SmartComponentAsset,
162
166
  componentModel: any,
163
- componentDictionary: Record<string, any>
167
+ componentDictionary: Record<string, any>,
168
+ centralPlant?: any
169
+ ): void
170
+
171
+ export declare function applyDefaultIoDeviceStates(
172
+ centralPlant: any,
173
+ options?: { parentUuid?: string; attachmentId?: string }
164
174
  ): void
165
175
 
166
176
  export declare function reloadBehaviorsForDeviceAsset(
@@ -307,7 +317,8 @@ export {
307
317
  buildIntraBehavior,
308
318
  parseIntraBehavior,
309
319
  buildCrossBehavior,
310
- parseCrossBehavior
320
+ parseCrossBehavior,
321
+ resolveAnimationDefaultValue
311
322
  } from './utils/behaviorSchema.js';
312
323
  export {
313
324
  registerBehaviorsForComponent,
@@ -316,7 +327,8 @@ export {
316
327
  export {
317
328
  getScopedAttachmentKey,
318
329
  getIoBehaviorManager,
319
- resolveDataPoints
330
+ resolveDataPoints,
331
+ applyDefaultIoDeviceStates
320
332
  } from './utils/behaviorDispatch.js';
321
333
  export {
322
334
  scanSceneIoEndpoints,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.41",
3
+ "version": "0.3.43",
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",