@plotinus/matrix-package-observable-coordinator
Version:
Observable coordinator pattern components using IntrospectableBaseCommunicationComponent and proper presentation architecture
74 lines (73 loc) • 4.08 kB
JavaScript
// 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