Portal Community

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:

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.