Unnamed Skill

Types package architecture for ChainGraph core definitions. THE foundation package for all development. Use when working on packages/chaingraph-types, port system, decorators, node classes, flow definitions, execution context, propagation, or any type-related code. Contains 9 port types, decorator system, compositional node architecture, execution engine. Triggers: types, port, decorator, @Node, @Input, @Output, @PortString, @PortArray, @PortObject, BaseNode, INode, IPort, IEdge, IFlow, ExecutionEngine, ExecutionContext, propagation.

$ Installer

git clone https://github.com/chaingraphlabs/chaingraph /tmp/chaingraph && cp -r /tmp/chaingraph/.claude/skills/types-architecture ~/.claude/skills/chaingraph

// tip: Run this command in your terminal to install the skill


name: types-architecture description: Types package architecture for ChainGraph core definitions. THE foundation package for all development. Use when working on packages/chaingraph-types, port system, decorators, node classes, flow definitions, execution context, propagation, or any type-related code. Contains 9 port types, decorator system, compositional node architecture, execution engine. Triggers: types, port, decorator, @Node, @Input, @Output, @PortString, @PortArray, @PortObject, BaseNode, INode, IPort, IEdge, IFlow, ExecutionEngine, ExecutionContext, propagation.

ChainGraph Types Architecture

This skill provides comprehensive architectural guidance for the @badaitech/chaingraph-types package - THE foundation package containing all core type definitions, port system, node architecture, decorators, and execution engine.

Package Overview

Location: packages/chaingraph-types/ Purpose: Core type definitions, base implementations, and execution engine Key Features: TypeScript decorators, compositional node architecture, 9 port types, propagation engine

Complete Directory Structure

packages/chaingraph-types/src/
โ”œโ”€โ”€ index.ts                        # Main entry - exports everything
โ”œโ”€โ”€ json-transformers.ts            # SuperJSON serialization
โ”‚
โ”œโ”€โ”€ decorator/                      # TypeScript decorators โญ
โ”‚   โ”œโ”€โ”€ index.ts                    # All decorator exports
โ”‚   โ”œโ”€โ”€ node.decorator.ts           # @Node() decorator
โ”‚   โ”œโ”€โ”€ port.decorator.ts           # @Port() base decorator
โ”‚   โ”œโ”€โ”€ port.decorator.types.ts     # PortDecoratorOptions, ObjectPortSchemaInput
โ”‚   โ”œโ”€โ”€ port-config.decorator.ts    # @Input(), @Output(), @Name(), @Description()
โ”‚   โ”œโ”€โ”€ port-visibility.decorator.ts # @PortVisibility() conditional visibility
โ”‚   โ”œโ”€โ”€ port-update.decorator.ts    # Port update tracking
โ”‚   โ”œโ”€โ”€ scalar.decorator.ts         # @PortString(), @PortNumber(), @PortBoolean()
โ”‚   โ”œโ”€โ”€ object.decorator.ts         # @PortObject()
โ”‚   โ”œโ”€โ”€ array.decorator.ts          # @PortArray(), @PortArrayNumber()
โ”‚   โ”œโ”€โ”€ enum.decorator.ts           # @PortEnum()
โ”‚   โ”œโ”€โ”€ stream.decorator.ts         # @PortStream()
โ”‚   โ”œโ”€โ”€ secret.decorator.ts         # @PortSecret()
โ”‚   โ”œโ”€โ”€ object-schema.decorator.ts  # Object schema definition
โ”‚   โ”œโ”€โ”€ metadata-storage.ts         # reflect-metadata storage
โ”‚   โ”œโ”€โ”€ registry.ts                 # Node type registry
โ”‚   โ””โ”€โ”€ recursive-normalization.ts  # Config normalization
โ”‚
โ”œโ”€โ”€ node/                           # Node system โญโญ
โ”‚   โ”œโ”€โ”€ index.ts                    # Node exports
โ”‚   โ”œโ”€โ”€ interface.ts                # INode interface
โ”‚   โ”œโ”€โ”€ base-node.ts                # BaseNode class
โ”‚   โ”œโ”€โ”€ base-node-compositional.ts  # Compositional implementation
โ”‚   โ”œโ”€โ”€ types.ts                    # NodeMetadata, NodeExecutionResult
โ”‚   โ”œโ”€โ”€ node-enums.ts               # NodeStatus enum
โ”‚   โ”œโ”€โ”€ category.ts                 # NodeCategory enum
โ”‚   โ”œโ”€โ”€ node-ui.ts                  # NodeUIMetadata, Position
โ”‚   โ”œโ”€โ”€ default-ports.ts            # System ports (flowIn, flowOut, error)
โ”‚   โ”œโ”€โ”€ traverse-ports.ts           # findPort() utility
โ”‚   โ”œโ”€โ”€ interfaces/                 # 10+ node interfaces
โ”‚   โ”‚   โ”œโ”€โ”€ inode-composite.ts      # INodeComposite (combines 9 interfaces)
โ”‚   โ”‚   โ”œโ”€โ”€ icore-node.ts           # Core identity/status
โ”‚   โ”‚   โ”œโ”€โ”€ iport-manager.ts        # Port CRUD
โ”‚   โ”‚   โ”œโ”€โ”€ iport-binder.ts         # Port binding
โ”‚   โ”‚   โ”œโ”€โ”€ icomplex-port-handler.ts # Complex type handling
โ”‚   โ”‚   โ”œโ”€โ”€ inode-ui.ts             # UI metadata
โ”‚   โ”‚   โ”œโ”€โ”€ inode-events.ts         # Event emission
โ”‚   โ”‚   โ”œโ”€โ”€ iserializable.ts        # Serialization
โ”‚   โ”‚   โ”œโ”€โ”€ inode-versioning.ts     # Version tracking
โ”‚   โ”‚   โ”œโ”€โ”€ inode-clonable.ts       # Cloning
โ”‚   โ”‚   โ””โ”€โ”€ i-system-port-manager.ts # System ports
โ”‚   โ””โ”€โ”€ implementations/            # Component implementations
โ”‚       โ”œโ”€โ”€ port-manager.ts
โ”‚       โ”œโ”€โ”€ indexed-port-manager.ts
โ”‚       โ”œโ”€โ”€ port-binder.ts
โ”‚       โ”œโ”€โ”€ complex-port-handler.ts
โ”‚       โ”œโ”€โ”€ node-event-manager.ts
โ”‚       โ”œโ”€โ”€ node-ui-manager.ts
โ”‚       โ”œโ”€โ”€ node-serializer.ts
โ”‚       โ”œโ”€โ”€ node-version-manager.ts
โ”‚       โ”œโ”€โ”€ system-port-manager.ts
โ”‚       โ””โ”€โ”€ port-update-collector.ts
โ”‚
โ”œโ”€โ”€ port/                           # Port system โญโญโญ
โ”‚   โ”œโ”€โ”€ index.ts                    # Port exports
โ”‚   โ”œโ”€โ”€ base/
โ”‚   โ”‚   โ”œโ”€โ”€ IPort.ts                # IPort interface (212 lines)
โ”‚   โ”‚   โ”œโ”€โ”€ BasePort.ts             # BasePort abstract class
โ”‚   โ”‚   โ”œโ”€โ”€ types.ts                # All port config types
โ”‚   โ”‚   โ”œโ”€โ”€ base-config.schema.ts   # Zod validation schemas
โ”‚   โ”‚   โ””โ”€โ”€ secret.ts               # Secret type definitions
โ”‚   โ”œโ”€โ”€ instances/                  # 9 port implementations
โ”‚   โ”‚   โ”œโ”€โ”€ StringPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ NumberPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ BooleanPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ ArrayPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ ObjectPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ StreamPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ EnumPort.ts
โ”‚   โ”‚   โ”œโ”€โ”€ AnyPort.ts
โ”‚   โ”‚   โ””โ”€โ”€ SecretPort.ts
โ”‚   โ”œโ”€โ”€ plugins/                    # Validation/serialization plugins
โ”‚   โ”‚   โ”œโ”€โ”€ PortPluginRegistry.ts
โ”‚   โ”‚   โ”œโ”€โ”€ StringPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ NumberPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ BooleanPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ ArrayPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ ObjectPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ StreamPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ EnumPortPlugin.ts
โ”‚   โ”‚   โ”œโ”€โ”€ AnyPortPlugin.ts
โ”‚   โ”‚   โ””โ”€โ”€ SecretPortPlugin.ts
โ”‚   โ”œโ”€โ”€ factory/
โ”‚   โ”‚   โ””โ”€โ”€ PortFactory.ts          # Port creation factory
โ”‚   โ”œโ”€โ”€ transfer-rules/             # Port compatibility rules
โ”‚   โ”‚   โ”œโ”€โ”€ engine.ts               # TransferEngine
โ”‚   โ”‚   โ”œโ”€โ”€ types.ts
โ”‚   โ”‚   โ”œโ”€โ”€ predicates.ts
โ”‚   โ”‚   โ”œโ”€โ”€ strategies.ts
โ”‚   โ”‚   โ””โ”€โ”€ rules/default-rules.ts
โ”‚   โ””โ”€โ”€ utils/
โ”‚       โ”œโ”€โ”€ json-schema-converter.ts
โ”‚       โ””โ”€โ”€ json-schema-types.ts
โ”‚
โ”œโ”€โ”€ edge/                           # Edge system
โ”‚   โ”œโ”€โ”€ interface.ts                # IEdge interface
โ”‚   โ”œโ”€โ”€ edge.ts                     # Edge class
โ”‚   โ”œโ”€โ”€ types.ts                    # EdgeStatus, EdgeMetadata, EdgeAnchor
โ”‚   โ””โ”€โ”€ events.ts                   # Edge events
โ”‚
โ”œโ”€โ”€ flow/                           # Flow system โญโญ
โ”‚   โ”œโ”€โ”€ interface.ts                # IFlow interface
โ”‚   โ”œโ”€โ”€ flow.ts                     # Flow class
โ”‚   โ”œโ”€โ”€ types.ts                    # FlowMetadata
โ”‚   โ”œโ”€โ”€ events.ts                   # FlowEventType (18 types)
โ”‚   โ”œโ”€โ”€ execution-events.ts         # ExecutionEventEnum (17 types)
โ”‚   โ”œโ”€โ”€ execution-engine.ts         # ExecutionEngine class
โ”‚   โ”œโ”€โ”€ execution-handlers.ts       # Event handlers
โ”‚   โ”œโ”€โ”€ debugger.ts                 # FlowDebugger
โ”‚   โ”œโ”€โ”€ debugger-types.ts           # DebuggerState, DebuggerCommand
โ”‚   โ”œโ”€โ”€ edge-transfer-service.ts    # Data transfer between ports
โ”‚   โ”œโ”€โ”€ cycleDetection.ts           # DAG validation
โ”‚   โ”œโ”€โ”€ propagation/                # Propagation engine
โ”‚   โ”‚   โ”œโ”€โ”€ PropagationEngine.ts
โ”‚   โ”‚   โ”œโ”€โ”€ types.ts                # ActionContext, PropagationAction
โ”‚   โ”‚   โ””โ”€โ”€ actions/
โ”‚   โ”‚       โ””โ”€โ”€ TransferRulesAction.ts
โ”‚   โ””โ”€โ”€ serializer/
โ”‚       โ””โ”€โ”€ flow-serializer.ts
โ”‚
โ”œโ”€โ”€ execution/                      # Execution context
โ”‚   โ”œโ”€โ”€ execution-context.ts        # ExecutionContext class
โ”‚   โ”œโ”€โ”€ emitted-event-context.ts    # Event-driven execution
โ”‚   โ”œโ”€โ”€ integration-context.ts      # Integration settings
โ”‚   โ”œโ”€โ”€ wallet-context.ts           # Wallet/crypto context
โ”‚   โ””โ”€โ”€ arch-a-i-context.ts         # AI agent context
โ”‚
โ””โ”€โ”€ utils/                          # Utilities
    โ”œโ”€โ”€ async-queue.ts              # Async queue for execution
    โ”œโ”€โ”€ event-queue.ts              # Event queue
    โ”œโ”€โ”€ semaphore.ts                # Concurrency control
    โ”œโ”€โ”€ deep-copy.ts
    โ””โ”€โ”€ deep-equal.ts

Node System Architecture

Compositional Design

Nodes use a compositional architecture with 9 specialized interfaces combined into INodeComposite:

File: src/node/interfaces/inode-composite.ts

interface INodeComposite extends
  ICoreNode,           // Core identity and status
  IPortManager,        // Port CRUD operations
  IPortBinder,         // Port binding to node
  IComplexPortHandler, // Complex type handling (Array, Object)
  INodeUI,             // UI metadata (position, dimensions)
  INodeEvents,         // Event subscription/emission
  ISerializable,       // Serialization
  INodeVersioning,     // Version tracking
  ISystemPortManager,  // System ports (flowIn, flowOut, error)
  INodeClonable        // Deep cloning
{
  // Additional methods
  initialize(portsConfig?: Map<string, IPortConfig>): void
  executeWithSystemPorts(context: ExecutionContext): Promise<NodeExecutionResult>
  startBatchUpdate(): void
  commitBatchUpdate(eventContext?: EventContext): Promise<void>
}

BaseNode Implementation

File: src/node/base-node-compositional.ts

class BaseNodeCompositional implements INodeComposite {
  // Core properties
  protected _id: string
  protected _metadata: NodeMetadata
  protected _status: NodeStatus

  // Specialized components (composition over inheritance)
  protected portManager: PortManager
  protected portBinder: PortBinder
  protected complexPortHandler: ComplexPortHandler
  protected eventManager: NodeEventManager
  protected uiManager: NodeUIManager
  protected versionManager: NodeVersionManager
  protected serializer: NodeSerializer
  protected systemPortManager: SystemPortManager
  protected portUpdateCollector: PortUpdateCollector

  // Execute method - override in subclasses
  async execute(context: ExecutionContext): Promise<NodeExecutionResult> {
    throw new Error('execute() must be implemented')
  }
}

NodeStatus Lifecycle

File: src/node/node-enums.ts

Idle โ†’ Initialized โ†’ Ready โ†’ Executing โ†’ Completed
                              โ†“            โ†“
                           Skipped       Error
                                          โ†“
                                       Disposed

NodeMetadata

File: src/node/types.ts

interface NodeMetadata {
  type: string              // Required: Node class identifier
  id?: string               // Unique node ID
  title?: string            // Display name
  category?: NodeCategory   // e.g., 'math', 'flow-control', 'ai'
  description?: string
  version?: number
  icon?: string
  tags?: string[]
  author?: string
  parentNodeId?: string     // For grouped nodes
  ui?: NodeUIMetadata       // Position, dimensions
  flowPorts?: FlowPorts     // System port configuration
}

interface FlowPorts {
  flowIn: boolean           // Has flow input port
  flowOut: boolean          // Has flow output port
  error: boolean            // Has error port
  errorMessage: boolean     // Has error message port
}

Port System (9 Types)

IPort Interface

File: src/port/base/IPort.ts (212 lines)

interface IPort<C extends IPortConfig = IPortConfig> {
  // Identity
  id: string
  key: string

  // Configuration
  getConfig(): C
  setConfig(newConfig: C): void

  // Value management
  getValue(): ExtractValue<C> | undefined
  setValue(newValue: ExtractValue<C>): void
  reset(): void
  getDefaultValue(): ExtractValue<C> | undefined

  // Validation
  validate(): boolean
  validateValue(value: ExtractValue<C>): boolean
  validateConfig(config: C): boolean

  // Serialization
  serialize(): JSONValue
  deserialize(data: JSONValue): IPort<C>
  serializeConfig(config: C): JSONValue
  serializeValue(value: ExtractValue<C>): JSONValue
  deserializeConfig(data: JSONValue): C
  deserializeValue(data: JSONValue): ExtractValue<C>

  // Cloning
  clone(): IPort<C>
  cloneWithNewId(): IPort<C>

  // System/Connection
  isSystem(): boolean
  isSystemError(): boolean
  addConnection(nodeId: string, portId: string): void
  removeConnection(nodeId: string, portId: string): void
}

Port Types and Configurations

File: src/port/base/types.ts

TypeConfig InterfaceKey Properties
stringStringPortConfigdefaultValue, minLength, maxLength, pattern, multiline
numberNumberPortConfigdefaultValue, min, max, step, integer
booleanBooleanPortConfigdefaultValue
arrayArrayPortConfig<Item>itemConfig, minLength, maxLength, isMutable
objectObjectPortConfig<Schema>schema, isSchemaMutable
streamStreamPortConfig<Value>itemConfig (for channel items)
enumEnumPortConfigoptions: EnumOption[]
secretSecretPortConfig<SecretType>secretType
anyAnyPortConfigNo constraints

Port Instances

Location: src/port/instances/

Each port type has a dedicated class extending BasePort<Config>:

// StringPort.ts
class StringPort extends BasePort<StringPortConfig> {
  validateValue(value: string): boolean {
    const { minLength, maxLength, pattern } = this.config
    // Validation logic
  }
}

// ArrayPort.ts
class ArrayPort<T> extends BasePort<ArrayPortConfig<T>> {
  // Handles nested item configs
  // Supports mutable/immutable arrays
}

// ObjectPort.ts
class ObjectPort<S> extends BasePort<ObjectPortConfig<S>> {
  // Handles object schema with nested ports
  // Supports schema mutations
}

Port Plugins

Location: src/port/plugins/

Plugins provide validation and serialization for each port type:

interface PortPlugin<C extends IPortConfig, V> {
  validateConfig(config: C): ValidationError[]
  validateValue(value: V, config: C): ValidationError[]
  serializeConfig(config: C): JSONValue
  serializeValue(value: V): JSONValue
  deserializeConfig(data: JSONValue): C
  deserializeValue(data: JSONValue): V
  getDefaultValue(config: C): V | undefined
}

Port Factory

File: src/port/factory/PortFactory.ts

class PortFactory {
  static create<T extends IPortConfig>(config: T): PortInstance {
    switch (config.type) {
      case 'string': return new StringPort(config)
      case 'number': return new NumberPort(config)
      case 'boolean': return new BooleanPort(config)
      case 'array': return new ArrayPort(config)
      case 'object': return new ObjectPort(config)
      case 'stream': return new StreamPort(config)
      case 'enum': return new EnumPort(config)
      case 'secret': return new SecretPort(config)
      case 'any': return new AnyPort(config)
    }
  }
}

Transfer Rules

Location: src/port/transfer-rules/

Rules for port type compatibility during edge connections:

// Check if two ports can connect
const engine = getDefaultTransferEngine()
const canConnect = engine.canTransfer(sourcePort, targetPort)

// Rules include:
// - Same type โ†’ direct transfer
// - Number โ†’ String โ†’ auto-convert
// - Array<T> โ†’ Array<T> โ†’ item-wise transfer
// - Object schema compatibility

Decorator System

Node Decorator

File: src/decorator/node.decorator.ts

@Node({
  type: 'my-node',           // Required: unique identifier
  title: 'My Node',          // Display name
  category: 'math',          // NodeCategory enum
  description: 'Does X',
  version: 1,
  icon: 'calculator',
  tags: ['arithmetic'],
  flowPorts: {               // System port configuration
    flowIn: true,
    flowOut: true,
    error: true,
    errorMessage: true,
  },
})
class MyNode extends BaseNode { }

Port Direction Decorators

File: src/decorator/port-config.decorator.ts

@Input()      // direction: 'input'
@Output()     // direction: 'output'
@Passthrough() // direction: 'passthrough' (bidirectional)

Port Type Decorators

Files: scalar.decorator.ts, array.decorator.ts, object.decorator.ts, etc.

// Scalar types
@PortString({ defaultValue: '', minLength: 0, maxLength: 1000 })
@PortNumber({ defaultValue: 0, min: -Infinity, max: Infinity, step: 1 })
@PortBoolean({ defaultValue: false })

// Complex types
@PortArray({ itemConfig: { type: 'string' }, minLength: 0 })
@PortObject({ schema: mySchema })
@PortStream({ itemConfig: { type: 'string' } })

// Enum types
@PortEnum({ options: [{ value: 'a', label: 'Option A' }] })

// Special types
@PortSecret({ secretType: 'api-key' })

Port Metadata Decorators

@Name('customName')           // Override port name
@Description('Port purpose')  // Add description
@Title('Display Title')       // Add title
@Id('custom-id')              // Custom port ID
@DefaultValue(42)             // Set default value
@Metadata('key', value)       // Arbitrary metadata

Port Visibility Decorator

File: src/decorator/port-visibility.decorator.ts

@PortVisibility({
  showIf: (instance: INode) => instance.getPort('mode')?.getValue() === 'advanced'
})
@Input()
@PortString()
advancedOption: string = ''

Complete Node Example

import {
  Node, Input, Output,
  PortString, PortNumber, PortBoolean, PortArray, PortObject,
  Name, Description, PortVisibility
} from '@badaitech/chaingraph-types'

@Node({
  type: 'text-processor',
  title: 'Text Processor',
  category: 'text',
  description: 'Processes text with configurable options',
})
class TextProcessorNode extends BaseNode {
  // String input with validation
  @Input()
  @PortString({ defaultValue: '', maxLength: 10000 })
  @Description('Text to process')
  text: string = ''

  // Number input with range
  @Input()
  @PortNumber({ defaultValue: 100, min: 1, max: 1000 })
  maxLength: number = 100

  // Boolean flag
  @Input()
  @PortBoolean({ defaultValue: false })
  uppercase: boolean = false

  // Conditional visibility
  @PortVisibility({ showIf: (node) => node.getPort('uppercase')?.getValue() === true })
  @Input()
  @PortString({ defaultValue: '' })
  prefix: string = ''

  // Array output
  @Output()
  @PortArray({ itemConfig: { type: 'string' } })
  words: string[] = []

  // Object output with schema
  @Output()
  @PortObject({
    schema: {
      properties: {
        processed: { type: 'string' },
        wordCount: { type: 'number' },
      }
    }
  })
  result: { processed: string, wordCount: number } = { processed: '', wordCount: 0 }

  async execute(context: ExecutionContext): Promise<NodeExecutionResult> {
    let processed = this.text.slice(0, this.maxLength)
    if (this.uppercase) {
      processed = (this.prefix + processed).toUpperCase()
    }
    this.words = processed.split(' ').filter(w => w.length > 0)
    this.result = { processed, wordCount: this.words.length }
    return {}
  }
}

Flow & Execution Engine

Flow Class

File: src/flow/flow.ts

class Flow implements IFlow {
  id: string
  metadata: FlowMetadata
  nodes: Map<string, INode>
  edges: Map<string, IEdge>

  // Internal components
  eventQueue: EventQueue<FlowEvent>
  propagationEngine: PropagationEngine

  // Node operations
  async addNode(node: INode): Promise<INode>
  async addNodes(nodes: INode[]): Promise<INode[]>
  async removeNode(nodeId: string): Promise<void>

  // Edge operations
  async addEdge(edge: IEdge): Promise<void>
  async connectPorts(sourceNodeId, sourcePortId, targetNodeId, targetPortId): Promise<IEdge>

  // Events
  onEvent(handler: (event: FlowEvent) => void): () => void

  // Validation
  async validate(): Promise<FlowValidationResult>
}

ExecutionEngine

File: src/flow/execution-engine.ts

class ExecutionEngine {
  // Execution queues
  readyQueue: AsyncQueue<() => Promise<void>>
  completedQueue: AsyncQueue<INode>

  // Tracking
  executingNodes: Set<string>
  completedNodes: Set<string>
  nodeDependencies: Map<string, number>
  dependentsMap: Map<string, INode[]>

  // Port-level resolution
  resolvedPorts: Set<string>
  sourcePortToWaitingNodes: Map<string, Set<string>>

  // Event-driven nodes
  eventListenerNodeIds: Set<string>
  eventBoundNodes: Set<string>

  // Concurrency control
  semaphore: Semaphore
  debugger: FlowDebugger | null

  constructor(
    flow: Flow,
    context: ExecutionContext,
    options?: ExecutionOptions,
    onBreakpointHit?: (node: INode) => void
  )

  async execute(): Promise<void>
}

ExecutionOptions

interface ExecutionOptions {
  execution?: {
    maxConcurrency?: number     // Default: 50
    nodeTimeoutMs?: number      // Default: 3600000 (1 hour)
    flowTimeoutMs?: number      // Default: 10800000 (3 hours)
  }
  debug?: boolean               // Enable debugger
  breakpoints?: string[]        // Node IDs to break on
}

FlowDebugger

File: src/flow/debugger.ts

class FlowDebugger implements DebuggerController {
  state: DebuggerState  // 'running' | 'paused' | 'stepping' | 'stopped'

  pause(): void
  continue(): void
  step(): void
  stop(): void
  addBreakpoint(nodeId: string): void
  removeBreakpoint(nodeId: string): void
  getState(): DebuggerState
}

PropagationEngine

File: src/flow/propagation/PropagationEngine.ts

Handles automatic data propagation when ports change:

class PropagationEngine {
  actions: PropagationAction[]

  async handleEvent(event: FlowEvent, flow: IFlow): Promise<ActionResult[]>
}

interface PropagationAction {
  name: string
  canExecute(context: ActionContext): boolean
  execute(context: ActionContext): void | Promise<void>
}

interface ActionContext {
  event: FlowEvent
  flow: IFlow
  sourcePort?: IPort
  targetPort?: IPort
  edge?: IEdge
  sourceNode?: INode
  targetNode?: INode
}

ExecutionContext

File: src/execution/execution-context.ts

class ExecutionContext {
  // Identity
  executionId: string
  rootExecutionId?: string
  parentExecutionId?: string
  flowId?: string
  userId?: string

  // Timing
  startTime: Date
  executionDepth: number  // Max 100

  // Control
  abortController: AbortController

  // Integrations
  integrations: IntegrationContext

  // Event-driven execution
  emittedEvents?: EmittedEvent[]
  eventData?: EmittedEventContext
  isChildExecution?: boolean

  // Node resolution
  getNodeById: (nodeId: string) => INode | undefined
  findNodes: (predicate: (node: INode) => boolean) => INode[]

  // Methods
  emitEvent(event: EmittedEvent): void
  getEmittedEvents(eventType?: string): EmittedEvent[]
  resolvePort(nodeId: string, portId: string): void
  isPortResolved(nodeId: string, portId: string): boolean
}

Key Files Reference

FilePurposeLines
src/port/base/IPort.tsPort interface1-212
src/port/base/types.tsPort config types1-150+
src/node/interfaces/inode-composite.tsComposite interface1-86
src/node/base-node-compositional.tsNode implementation1-100+
src/decorator/port-config.decorator.tsDirection decorators1-118
src/decorator/port-visibility.decorator.tsVisibility decorator1-138
src/decorator/metadata-storage.tsReflect metadata1-86
src/flow/execution-engine.tsExecution engine1-100+
src/flow/debugger.tsFlow debugger1-100+
src/flow/propagation/PropagationEngine.tsData propagation1-80+
src/execution/execution-context.tsRuntime context1-100+

Quick Reference

NeedWhereExport
Create a nodedecorator/node.decorator.ts@Node()
Input portdecorator/port-config.decorator.ts@Input()
Output portdecorator/port-config.decorator.ts@Output()
String portdecorator/scalar.decorator.ts@PortString()
Number portdecorator/scalar.decorator.ts@PortNumber()
Boolean portdecorator/scalar.decorator.ts@PortBoolean()
Array portdecorator/array.decorator.ts@PortArray()
Object portdecorator/object.decorator.ts@PortObject()
Stream portdecorator/stream.decorator.ts@PortStream()
Enum portdecorator/enum.decorator.ts@PortEnum()
Conditional portdecorator/port-visibility.decorator.ts@PortVisibility()
Create port instanceport/factory/PortFactory.tsPortFactory.create()
Check compatibilityport/transfer-rules/engine.tsTransferEngine

Related Skills

  • chaingraph-concepts - Core domain concepts
  • port-system - Port types deep dive (planned)
  • executor-architecture - How types are used in execution
  • frontend-architecture - How types render in UI
  • dbos-patterns - Execution context in DBOS