class ChildRegistrationUtils { constructor(mainClass) { this.mainClass = mainClass; this.logger = mainClass.logger; this.registeredChildren = new Map(); } async registerChild(child, positionVsParent) { const { softwareType } = child.config.functionality; const { name, id } = child.config.general; this.logger.debug(`Registering child: ${name} (${id}) as ${softwareType} at ${positionVsParent}`); // Enhanced child setup - multiple parents if (Array.isArray(child.parent)) { child.parent.push(this.mainClass); } else { child.parent = [this.mainClass]; } child.positionVsParent = positionVsParent; // Enhanced measurement container with rich context if (child.measurements) { child.measurements.setChildId(id); child.measurements.setChildName(name); child.measurements.setParentRef(this.mainClass); } // Store child in your expected structure this._storeChild(child, softwareType); // Track registration for utilities this.registeredChildren.set(id, { child, softwareType, position: positionVsParent, registeredAt: Date.now() }); // IMPORTANT: Only call parent registration - no automatic handling and if parent has this function then try to register this child if (typeof this.mainClass.registerChild === 'function') { this.mainClass.registerChild(child, softwareType); } this.logger.info(`✅ Child ${name} registered successfully`); } _storeChild(child, softwareType) { // Maintain your existing structure if (!this.mainClass.child) this.mainClass.child = {}; if (!this.mainClass.child[softwareType]) this.mainClass.child[softwareType] = {}; const { category = "sensor" } = child.config.asset || {}; if (!this.mainClass.child[softwareType][category]) { this.mainClass.child[softwareType][category] = []; } this.mainClass.child[softwareType][category].push(child); } // NEW: Utility methods for parent to use getChildrenOfType(softwareType, category = null) { if (!this.mainClass.child[softwareType]) return []; if (category) { return this.mainClass.child[softwareType][category] || []; } // Return all children of this software type return Object.values(this.mainClass.child[softwareType]).flat(); } getChildById(childId) { return this.registeredChildren.get(childId)?.child || null; } getAllChildren() { return Array.from(this.registeredChildren.values()).map(r => r.child); } // NEW: Debugging utilities logChildStructure() { this.logger.debug('Current child structure:', JSON.stringify( Object.keys(this.mainClass.child).reduce((acc, softwareType) => { acc[softwareType] = Object.keys(this.mainClass.child[softwareType]).reduce((catAcc, category) => { catAcc[category] = this.mainClass.child[softwareType][category].map(c => ({ id: c.config.general.id, name: c.config.general.name })); return catAcc; }, {}); return acc; }, {}), null, 2 )); } } module.exports = ChildRegistrationUtils;