2.7 KiB
pipeline-events-constants — runtime constants for PipelineEventsBus
Purpose
@suaveplan/api-types is types-only — adding a runtime export there breaks the byte-size invariant CI enforces. The PipelineEventsBus contract still needs runtime constants for the canonical stage order tuple (so consumers can iterate / assert without re-listing the names) and for the per-stage event-name strings (so OTel bridges can name events without re-deriving them). Those constants live here, in @suaveplan/api-host, where runtime exports are expected.
Features
PIPELINE_STAGE_ORDERfrozen tuple — canonical §6 execution order matching thePipelineStageunion.PIPELINE_EVENT_NAMEliteral — log-grep friendly namespace prefix (api-host.pipeline.stage).PIPELINE_STAGE_EVENT_NAMESper-stage map — concatenated${PIPELINE_EVENT_NAME}.<stage>strings for OTel span-event naming.
Usage: Basic
import { PIPELINE_STAGE_ORDER } from "@suaveplan/api-host";
for (const stage of PIPELINE_STAGE_ORDER) {
console.log(stage); // request-id, route-match, tenant, auth, ...
}
Usage: Advanced
Build a per-stage histogram dashboard by indexing the per-stage event-name map:
import { PIPELINE_STAGE_EVENT_NAMES } from "@suaveplan/api-host";
import type { PipelineStage } from "@suaveplan/api-types/pipeline-events";
const histograms = new Map<PipelineStage, number[]>();
for (const stage of Object.keys(PIPELINE_STAGE_EVENT_NAMES) as PipelineStage[]) {
histograms.set(stage, []);
}
bus.subscribe((event) => {
if (event.outcome === "completed" || event.outcome === "rejected") {
histograms.get(event.stage)?.push(event.durationMs ?? 0);
}
});
API Reference
export const PIPELINE_STAGE_ORDER: readonly PipelineStage[];
export const PIPELINE_EVENT_NAME: "api-host.pipeline.stage";
export const PIPELINE_STAGE_EVENT_NAMES: Readonly<Record<PipelineStage, string>>;
Implementation Notes
The constants are typed as readonly PipelineStage[] (tuple) and Readonly<Record<PipelineStage, string>> (map). The map's value type is string rather than the specific literal because TypeScript widens nested string literals through Readonly<Record<...>>. Consumers that need the literal narrowing import the PIPELINE_STAGE_EVENT_NAMES constant directly — TypeScript preserves the literal types on the const expression.
The tuple MUST stay in lock-step with the PipelineStage union in @suaveplan/api-types/pipeline-events. A satisfies check at the type-test level catches any drift between the two; the conformance harness's order invariant also catches drift at runtime by comparing the actual emit order against this tuple.