Flow Studio
FlowObserverPanelEngine
FlowObserverPanelEngine is the central coordinator of the Observer Panel. It manages tab registration, routes incoming execution events to the correct tabs, and exposes the panel lifecycle API.
Engine API
// flow-observer-core/src/engine/FlowObserverPanelEngine.ts
export class FlowObserverPanelEngine {
// Register a tab — can be called before or after panel mount
registerTab(descriptor: TabDescriptor): void;
// Unregister a tab by ID
unregisterTab(tabId: string): void;
// Switch the active tab
activateTab(tabId: string): void;
// Push a raw execution event — distributed to all tabs that care
pushExecutionEvent(event: ExecutionEvent): void;
// Set a badge count on a tab
setTabBadge(tabId: string, count: number | null): void;
// Clear all execution data (called when a new execution starts)
clear(): void;
// Open / close the panel
open(): void;
close(): void;
}
Event Routing
pushExecutionEvent() is the central intake for all SignalR events. Internally the engine dispatches each event to a set of registered handlers. Tabs declare interest by providing an onEvent handler in their TabDescriptor:
// Extended TabDescriptor with event handler (internal)
export interface TabDescriptor {
// ...
onEvent?: (event: ExecutionEvent) => void;
}
// Example: LogsTab registers interest in NodeLogEmitted events
engine.registerTab({
id: 'logs',
label: 'Logs',
component: ExecutionLogsTabContent,
order: 30,
onEvent: (event) => {
if (event.type === 'NodeLogEmitted') {
logsStore.appendLog(event);
}
}
});
Lifecycle: clear()
engine.clear() is called when a new execution begins. It:
- Resets the log buffer in
flowObserverPanelStore - Clears all tab badges
- Resets node status entries in the Node List tab
- Switches the active tab back to
execution-status - Hides the Log Detail tab
Using the Engine in React
// Access the singleton engine via context hook
import { useFlowObserverPanelEngine } from 'flow-observer-core';
function MyComponent() {
const engine = useFlowObserverPanelEngine();
const handleFocus = () => {
engine.activateTab('node-inspector');
};
return <button onClick={handleFocus}>Inspect Selected Node</button>;
}
Singleton per Panel Instance
Each
FlowObserverPanel mount creates its own engine instance, stored in a React context. If you embed two Observer Panels on the same page (unusual but supported), they operate independently with separate engines and stores.