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 executorname: human-readable display namedescription: optional summary shown in UIs and listingsversions: versions the pipeline can processinputs: source definitions that provide filesroutes: route definitions that parse and resolve those filesinclude: optional pipeline-wide file filter applied before route matchingstrict: whentrue, unmatched files without a fallback are treated as errorsconcurrency: maximum number of route executions processed in parallelfallback: optional handler for unmatched fileshooks: optional lifecycle callbacks for side effects around executiontags: 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:
| Hook | Fires around |
|---|---|
pipeline | the full pipeline execution |
version | each Unicode version |
route | each matched route execution, including fallback as __fallback__ |
parse | parser and transform consumption for a route |
resolve | resolver execution for a route |
output | output 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 listucd pipelines run- local and remote loading through
@ucdjs/pipeline-loader