UNPKG

@plotinus/matrix-package-observable-coordinator

Version:

Observable coordinator pattern components using IntrospectableBaseCommunicationComponent and proper presentation architecture

74 lines (73 loc) 4.08 kB
// packages/package-observable-coordinator/src/components/app/app.component.ts import { IntrospectableBaseCommunicationComponent } from '@matrix/presentation'; import { logInfo, logDebug } from '@matrix/logger'; export class AppComponent extends IntrospectableBaseCommunicationComponent { onInit() { super.onInit(); console.log(`🚀 AppComponent.onInit() called for ${this.id}`); console.log(`📊 AppComponent: this.setState available?`, typeof this.setState); console.log(`📊 AppComponent: this.state type:`, typeof this.state); console.log(`📊 AppComponent: this.eventBus available?`, !!this.eventBus); // Subscribe to our own introspection events for debugging this.eventBus.on(`cmp:${this.id}:_stateChanged`, (data) => { console.log(`🔄 App:${this.id}: *** _stateChanged EVENT RECEIVED ***:`, data.state); logInfo(`🔄 App:${this.id}: State changed:`, data.state); }); this.eventBus.on(`cmp:${this.id}:_propertyChanged`, (data) => { console.log(`📝 App:${this.id}: *** _propertyChanged EVENT RECEIVED ***:`, data); logInfo(`📝 App:${this.id}: Property ${data.propertyName} changed from ${data.oldValue} to ${data.newValue}`); }); // Initialize observable state console.log(`📊 App:${this.id}: *** ABOUT TO CALL setState() ***`); logInfo(`App:${this.id}: Setting initial state...`); try { this.setState({ coordinatorReady: false, processingStarted: false, systemCompleted: false, completedJobs: [] }); console.log(`📊 App:${this.id}: *** setState() COMPLETED SUCCESSFULLY ***`); } catch (error) { console.error(`❌ App:${this.id}: setState() FAILED:`, error); } console.log(`📊 App:${this.id}: Final state after setState():`, this.state); logInfo(`App:${this.id}: Initialized with observable state. Current state:`, this.state); } startExecution() { // BaseCommunicationComponent startExecution already logs the call logInfo(`App:${this.id}: Starting execution, waiting for Coordinator to be ready.`); // No initial command needed here, Coordinator will emit 'CoordinatorReady' // which triggers handleCoordinatorReady via DSL binding. } // DSL binding: <coordinator onCoordinatorReady="handleCoordinatorReady"> handleCoordinatorReady() { logInfo(`App:${this.id}: Coordinator is ready. Sending 'StartProcessing' command.`); logInfo(`📊 App:${this.id}: Setting coordinatorReady = true`); this.setState({ coordinatorReady: true }); logInfo(`📊 App:${this.id}: State after coordinatorReady update:`, this.state); this.sendCommand('myCoordinator', 'StartProcessing'); } // Manual start processing method for UI button handleStartProcessing() { logInfo(`App:${this.id}: Manual start processing triggered from UI.`); logInfo(`📊 App:${this.id}: Setting processingStarted = true`); this.setState({ processingStarted: true }); logInfo(`📊 App:${this.id}: State after processingStarted update:`, this.state); this.sendCommand('myCoordinator', 'StartProcessing'); } // DSL binding: <coordinator onCoordinatorDone="handleCoordinatorDone"> handleCoordinatorDone(evt) { logInfo(`App:${this.id}: Coordinator reported all jobs done.`); logDebug(`App:${this.id}: Completed job IDs`, evt.completedJobIds); logInfo(`📊 App:${this.id}: Setting systemCompleted = true and completedJobs`); this.setState({ systemCompleted: true, completedJobs: evt.completedJobIds }); logInfo(`📊 App:${this.id}: Final state after completion:`, this.state); this.emitEvent('SystemCompleted', { success: true, completedJobs: evt.completedJobIds }); } } AppComponent.dslTag = 'app-definition'; // Used by NodeFactory for registration