UCD.js Docs

Definitions

Define versions, sources, routes, and execution options for a pipeline

Pipeline Definitions

A pipeline definition is the object returned by definePipeline(...). It ties together versions, sources, routes, and execution settings into one typed unit.

The core shape

import { definePipeline } from "@ucdjs/pipeline-core";

export const myPipeline = definePipeline({
  id: "my-pipeline",
  name: "My Pipeline",
  description: "Example pipeline definition",
  versions: ["1.0.0"],
  inputs: [mySource],
  routes: [myRoute],
  include: undefined,
  strict: false,
  concurrency: 4,
  fallback: undefined,
  hooks: undefined,
});

Key fields

  • id: stable pipeline identifier used by the CLI and executor
  • name: human-readable display name
  • description: optional summary shown in UIs and listings
  • versions: versions the pipeline can process
  • inputs: source definitions that provide files
  • routes: route definitions that parse and resolve those files
  • include: optional pipeline-wide file filter applied before route matching
  • strict: when true, unmatched files without a fallback are treated as errors
  • concurrency: maximum number of route executions processed in parallel
  • fallback: optional handler for unmatched files
  • hooks: optional lifecycle callbacks for side effects around execution
  • tags: optional metadata for classification and tooling

DAG validation happens at definition time

When you call definePipeline(...), the core package builds the route DAG immediately from declared route dependencies.

If the dependency graph is invalid, pipeline creation fails early. That means authoring mistakes such as unknown route dependencies or dependency cycles surface before execution.

Example with multiple routes

export const dependentRoutesPipeline = definePipeline({
  id: "dependent-routes",
  name: "Dependent Routes",
  versions: ["1.0.0"],
  inputs: [colorsSource, sizesSource],
  routes: [colorsRoute, sizesAfterColorsRoute],
});

In that example, sizesAfterColorsRoute depends on colorsRoute, so the DAG forces the colors route to finish before the dependent route resolves.

Fallback behavior

fallback is for files that pass the pipeline-wide include filter but do not match any route. It has its own parser and resolver and is useful when you want a controlled catch-all instead of ignoring unmatched files.

Lifecycle hooks

Use hooks when a pipeline should run side effects around execution lifecycle points. Hooks receive a context object with phase: "start" | "end", so a single hook can handle both sides of the lifecycle.

export const hookedPipeline = definePipeline({
  id: "hooked-pipeline",
  name: "Hooked Pipeline",
  versions: ["1.0.0"],
  inputs: [mySource],
  routes: [myRoute],
  hooks: {
    resolve(ctx) {
      if (ctx.phase === "start") {
        ctx.logger.info("Resolve started", {
          routeId: ctx.routeId,
          file: ctx.file.path,
        });
      }

      if (ctx.phase === "end") {
        ctx.logger.info("Resolve finished", {
          routeId: ctx.routeId,
          outputs: ctx.outputs?.length ?? 0,
          failed: ctx.error != null,
        });
      }
    },
  },
});

Available hooks are:

HookFires around
pipelinethe full pipeline execution
versioneach Unicode version
routeeach matched route execution, including fallback as __fallback__
parseparser and transform consumption for a route
resolveresolver execution for a route
outputoutput materialization and writes

Hooks are best for side effects such as metrics, custom logging, notifications, or lightweight bookkeeping. If a hook throws, the executor logs the hook failure and continues; hook failures do not change the pipeline result.

Loading Pipelines

The loader discovers files matching **/*.ucd-pipeline.ts and imports any named exports that are real pipeline definitions.

That discovery model powers:

  • ucd pipelines list
  • ucd pipelines run
  • local and remote loading through @ucdjs/pipeline-loader

On this page