/** * Graph Sorter * * Performs topological sorting on the dependency graph to: * 1. Detect circular dependencies (fails if cycle found) * 2. Assign level numbers to each project (level 0 = no deps, level 1 = depends on level 0, etc.) * 3. Group projects into layers for deterministic ordering */ import type { ProjectApiRelations } from './api-usage/api-relations'; /** * Graph entry with level metadata plus AI-oriented metadata filled in by * enrichGraph() (lib/graph-metadata.ts) before the graph is saved: * - framework: the project's libType — the SET of runtime environments it is * validated to run in, drawn from browser | react | angular | node | express * (e.g. ["browser","node"]); from its `framework:` nx tags (source of truth) * or inferred from package.json deps * - shortDescription: summary extracted from the project's responsibilities.md * - responsibilitiesFile: repo-relative path to the FULL responsibilities doc * - designFile: repo-relative path to the generated DI design.json (only for * project.json projects) * - apiRelations: for each api-lib in `dependsOn`, WHY the edge exists — the * APIs this project implements (serves) and/or uses (calls), each with its * transport (rpc | pubsub). Derived by scanning source (see api-usage/). */ export interface GraphEntry { level: number; dependsOn: string[]; framework?: string[]; role?: string; /** * The name CLIENTS address this app by at runtime (`new ClientConfig('helper-fsdb')`) — its * deployed service name, DECLARED in project.json as metadata.webpieces.serviceName. Absent for * anything nothing calls by name (libraries, browser apps). See service-name-resolver.ts. */ serviceName?: string; /** * The service(s) this project's clients call when the call site cannot carry a literal * `ClientConfig` — the symmetric half of `serviceName`. DECLARED in project.json as * metadata.webpieces.callsService, either a single service name (every untargeted `uses` aims * there) or an `{ apiClassName: serviceName }` map (a client that calls several). Absent for a * project that never calls anything, or one whose call sites all carry literals. * See service-name-resolver.ts. */ callsService?: string | Record; /** * When false, the project is hidden from the rendered architecture graphs * (its box AND every edge touching it are omitted from dependencies.html and * the runtime graph). It stays in this JSON so the data view is complete. * Absent means drawn (the default). From the project's `drawOnGraph:` nx tag. */ drawOnGraph?: boolean; shortDescription?: string; responsibilitiesFile?: string; designFile?: string; apiRelations?: ProjectApiRelations; /** * The @webpieces runtime packages this project's OWN package.json declares — http-routing, * http-server, http-client-node, http-client-browser, cloudtasks-client. Omitted when it * declares none, so TOTAL absence across the file means the file predates this field and * nothing is auto-hidden (see runtime-graph.ts). Core/util/logging packages are deliberately * not markers; see runtime-participant-resolver.ts for why. * * The runtime graph ORs this over a node's library closure: a server whose whole webpieces * stack comes from a shared bootstrap lib participates even though it declares nothing itself. */ webpiecesRuntime?: string[]; } /** * Enhanced graph format with level information */ export type EnhancedGraph = Record; /** * Compute topological layers for dependency graph using Kahn's algorithm * * Projects are grouped into layers where each layer only depends on previous layers. * Throws an error if a circular dependency is detected. * * @param graph - Dependency graph { project: [deps] } * @returns Array of layers, each containing sorted project names */ export declare function computeTopologicalLayers(graph: Record): string[][]; /** * Sort graph in topological order with alphabetical sorting within layers * Returns enhanced format with level metadata * * @param graph - Unsorted dependency graph { project: [deps] } * @returns Sorted graph with level metadata { project: { level: number, dependsOn: [deps] } } */ export declare function sortGraphTopologically(graph: Record): EnhancedGraph;