02BasicsRuns offline

Pipeline

Connect three components and let the pipeline infer the endpoint.

flowchart LR
  S((start)) --> T[trim] --> U[upper] --> E[exclaim] --> R((result))

What it shows

  • addComponent(name, component) registers a component; connect('a.out', 'b.in') wires two ports.
  • With no endpoint, run() returns the output of the only terminal component.
  • Pass an endpoint such as 'upper.out' to read an intermediate value.

The program

examples/pipeline/index.ts
import { Component, Pipeline } from '@astack-tech/core';

class Trim extends Component {
  constructor() {
    super({});
  }

  override run(text: unknown): string {
    return String(text).trim();
  }
}

class Uppercase extends Component {
  constructor() {
    super({});
  }

  override run(text: unknown): string {
    return String(text).toUpperCase();
  }
}

class Exclaim extends Component {
  constructor() {
    super({});
  }

  override run(text: unknown): string {
    return `${String(text)}!`;
  }
}

// Register components by name, then connect output ports to input ports.
const pipeline = new Pipeline();
pipeline.addComponent('trim', new Trim());
pipeline.addComponent('upper', new Uppercase());
pipeline.addComponent('exclaim', new Exclaim());

pipeline.connect('trim.out', 'upper.in');
pipeline.connect('upper.out', 'exclaim.in');

// The endpoint is inferred: `exclaim` is the only component with no downstream connection.
console.log(await pipeline.run<string>('trim.in', '  hello  '));
// HELLO!

// Pass an endpoint to read an intermediate result.
console.log(await pipeline.run<string>('trim.in', '  hello  ', 'upper.out'));
// HELLO

// The topology is built once. Concurrent runs resolve in order.
console.log(await Promise.all(['a', 'b', 'c'].map(text => pipeline.run<string>('trim.in', text))));
// [ 'A!', 'B!', 'C!' ]

Run it

pnpm install && pnpm build

pnpm --filter @astack-examples/pipeline start
CONCEPTPipelinesConnect components, run a graph, and choose which output to read.View the folder on GitHub