Phase 3 - Widget I/O + Data Pipeline

Enable widgets to accept inputs/outputs and create data flow with Singularity

Phase 3: Widget I/O + Data Pipeline

Priority: P1 - HIGH
Duration: 3-4 days
Status: ๐ŸŸข STARTING
Started: October 28, 2025


๐ŸŽฏ Objectives

Transform widgets from static UI elements into dynamic, data-driven components that can:

Problems Being Solved

  1. Widgets are static - No way to pass data into or out of widgets
  2. No data flow - Can't connect widget outputs to flow inputs
  3. Manual wiring - No visual way to configure widget I/O
  4. Flow isolation - Flows execute but can't interact with widgets

๐Ÿ“‹ Architecture Overview

Widget I/O Contract

interface WidgetIOContract {
  inputs: {
    [key: string]: WidgetInputDefinition;
  };
  outputs: {
    [key: string]: WidgetOutputDefinition;
  };
}

interface WidgetInputDefinition {
  name: string;
  type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'any';
  required: boolean;
  default?: any;
  description?: string;
  source?: WidgetInputSource;
}

interface WidgetInputSource {
  type: 'flow' | 'widget' | 'page' | 'static' | 'user';
  flowId?: string;
  widgetId?: string;
  propertyPath?: string;
  staticValue?: any;
}

interface WidgetOutputDefinition {
  name: string;
  type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'event' | 'any';
  description?: string;
  targets?: WidgetOutputTarget[];
}

interface WidgetOutputTarget {
  type: 'flow' | 'widget' | 'page';
  flowId?: string;
  widgetId?: string;
  propertyPath?: string;
}

Data Pipeline Service

The DataPipelineService orchestrates data flow between:

@Injectable({ providedIn: 'root' })
export class DataPipelineService {
  // Configure widget inputs
  async setWidgetInput(widgetId: string, inputName: string, source: WidgetInputSource): Promise<void>
  
  // Configure widget outputs
  async setWidgetOutput(widgetId: string, outputName: string, targets: WidgetOutputTarget[]): Promise<void>
  
  // Execute flow and pipe output to widget
  async executeFlowToWidget(flowId: string, targetWidgetId: string, inputMapping: Record<string, string>): Promise<void>
  
  // Listen to widget output and pipe to flow
  async pipeWidgetOutputToFlow(widgetId: string, outputName: string, flowId: string, inputMapping: Record<string, string>): Promise<void>
  
  // Get widget's current input values (resolved from sources)
  getWidgetInputs(widgetId: string): Signal<Record<string, any>>
  
  // Subscribe to widget output events
  subscribeToWidgetOutput(widgetId: string, outputName: string, callback: (value: any) => void): Subscription
}

๐Ÿ—๏ธ Implementation Plan

Step 1: Define Widget I/O Contracts (1 day)

Files to Create:

  1. libs/core-models/src/lib/types/widget-io.types.ts

    • Widget I/O type definitions
    • Input/output source/target interfaces
    • Data type definitions
  2. libs/core-models/src/lib/interfaces/widget-io-contract.interface.ts

    • Widget I/O contract interface
    • Methods for widgets to implement

Files to Modify: 3. libs/core-models/src/lib/types/widget.types.ts

Step 2: Create DataPipelineService (1 day)

Files to Create: 4. libs/core-angular/src/lib/services/data-pipeline.service.ts

  1. libs/core-angular/src/lib/types/data-pipeline.types.ts
    • Pipeline configuration types
    • Data transformation types
    • Connection metadata

Files to Modify: 6. libs/core-angular/src/lib/services/index.ts

Step 3: Update Widget Base Classes (1 day)

Files to Modify: 7. libs/widgets/src/lib/base/widget-module-base.ts

  1. libs/widgets/src/lib/widgets/button/button-widget.module.ts (Example)

    • Define I/O contract (outputs: 'click' event)
    • Emit output on button click
  2. libs/widgets/src/lib/widgets/text-display/text-display-widget.module.ts (Example)

    • Define I/O contract (inputs: 'text', 'style')
    • Accept input data

Step 4: Flow Execution Integration (1 day)

Files to Create: 10. libs/core-angular/src/lib/services/flow-execution.service.ts - Wrap Singularity execution engine - Handle flowโ†’widget data transfer - Handle widgetโ†’flow data transfer

Files to Modify: 11. libs/core-angular/src/lib/services/flow-attachment.service.ts - Use FlowExecutionService for execution - Integrate with DataPipelineService - Pass widget context to flows

Step 5: Editor UI for Widget I/O (1-2 days)

Files to Create: 12. libs/editor-ui/src/lib/components/widget-io-config/widget-io-config.component.ts - UI for configuring widget inputs/outputs - Visual source/target selector - Data mapping editor

  1. libs/editor-ui/src/lib/components/widget-io-config/input-source-selector.component.ts

    • Dropdown/picker for input sources
    • Browse flows, widgets, page context
  2. libs/editor-ui/src/lib/components/widget-io-config/output-target-selector.component.ts

    • Dropdown/picker for output targets
    • Browse flows, widgets

Files to Modify: 15. libs/editor-ui/src/lib/components/properties-panel/properties-panel-new.component.ts - Add "I/O" tab to properties panel - Show widget-io-config component


โœ… Acceptance Criteria

Widget I/O Contract

Data Pipeline

Flow Execution

Editor UI

Examples Working


๐Ÿงช Testing Plan

Unit Tests

describe('DataPipelineService', () => {
  it('should resolve static input value', () => {
    service.setWidgetInput('widget-1', 'text', {
      type: 'static',
      staticValue: 'Hello World'
    });
    expect(service.getWidgetInputs('widget-1')()['text']).toBe('Hello World');
  });
  
  it('should pipe flow output to widget input', async () => {
    await service.executeFlowToWidget('flow-1', 'widget-1', { result: 'text' });
    // Verify widget received data
  });
});

Integration Tests

  1. Create page with button widget
  2. Attach flow to button click
  3. Flow outputs text
  4. Text display widget receives and shows text
  5. Verify end-to-end data flow

Manual Testing

  1. Open Editor
  2. Add Button widget
  3. Configure output: 'click' โ†’ flow-1
  4. Add Text Display widget
  5. Configure input: 'text' โ† flow-1.result
  6. Test: Click button โ†’ See text update

๐Ÿ“Š Progress Tracking

Phase 3 Checklist

Overall Progress: 0%


๐Ÿ› Known Issues & Blockers

None yet - just starting implementation


๐Ÿ“ Notes & Learnings


Last Updated: October 28, 2025 - Starting implementation
Next Checkpoint: Widget I/O contracts defined