/** * Runtime Visualizer * * Renders the runtime microservice graph (services + inferred Z -> X edges, * each labeled with the api(s) they flow over) to DOT + interactive HTML in * tmp/webpieces/runtime-architecture.{dot,html}. * * Each service node names the contracts it IMPLEMENTS. That list used to be * collapsed into a server/client boolean and thrown away — leaving an api that a * server serves but nothing in-repo calls completely invisible, and making a * correct api design look like a detection failure. What a service USES is NOT * listed: every use already draws an outgoing arrow labeled with the same * contract, so repeating it in the box only made every box wider. * * Shape says what a node IS and line style says what a call IS. Solid = rpc: the * request follows the arrow and the response flows back. Dashed = event: it flows * in the arrow's direction and returns once it is queued. A queue is a sideways * cylinder, a datastore an upright one. A queue box lists ONE LINE PER QUEUE: the * unit underneath is still the METHOD (what Terraform creates, and what * runtime-dependencies.json records), but queues of one contract sharing the same * producers and consumers are drawn together instead of as adjacent near-identical * boxes — every queue is still named, only the node count drops. * * Calls that leave the repo (a contract NOTHING in-repo implements — firestore, * gmail, ...) are drawn as terminal nodes, so the vendor systems that actually * page you at 3am stop being missing from the picture. One that DECLARES what it * is, via an `@externalSystem` JSDoc tag or an `external:` nx tag, gets the shape * of the thing it is; the rest stay generic dashed boxes. They are RENDER-ONLY: * derivation, levels and cycle detection never see them. * * The same is true in the other direction for endpoints nothing in-repo CALLS: a * `cron` method hangs off a clock and an `external` method off a box naming the * CALLER that posts to it (`twilio`), in the same id space as the outbound * systems, so a vendor we both call and are called by is ONE box. Those are the * entry points that wake a service up at 3am, and a graph built only from in-repo * callers cannot show them at all. * * EVERY node on the rendered page is clickable and opens the SHARED floating menu * (graph-node-menu.ts — one implementation, also used by architecture/dependencies.html * and every project's design.html). Its only item is Lock/Unlock: locking dims every * other node and every edge and lights the locked box alone. There is no "View Design" * item here — a node is a running service, queue, datastore or third-party system, not * an nx project, so no design.html exists to point at and the item is absent rather than * dead. This page has no lock dropdown, so the menu is the one and only lock control. */ import type { RuntimeGraph } from './runtime-graph'; /** Render options for the runtime graph. */ export declare class RuntimeVizOptions { /** * Draw the dashed terminal nodes for contracts nothing in-repo implements. On by default; * a repo whose external surface is noisy can turn them off in webpieces.config.json * (runtime-architecture.showExternalNodes). */ readonly showExternalNodes: boolean; constructor( /** * Draw the dashed terminal nodes for contracts nothing in-repo implements. On by default; * a repo whose external surface is noisy can turn them off in webpieces.config.json * (runtime-architecture.showExternalNodes). */ showExternalNodes?: boolean); } /** Build the Graphviz DOT for the runtime service graph. */ export declare function generateRuntimeDot(graph: RuntimeGraph, title?: string, options?: RuntimeVizOptions): string; /** * The runtime-architecture HTML page: its styles, the shared floating node menu, the graph host * and the legend. * * A CLASS rather than a bag of module functions so the client-text seam can be a constructor * parameter the way GraphVisualizer's is: the default reads the COMPILED sibling, which exists in * dist and in the published tarball but NOT in a source checkout, and a unit test running from * source hands in the text itself instead of requiring the package to have been built first. */ export declare class RuntimeHtmlPage { private readonly clientJs; /** The ONE floating-node-menu implementation, shared with dependencies.html and every design.html. */ private readonly nodeMenu; constructor(clientJs?: () => string); render(dot: string, title: string): string; /** * The browser half lives in runtime-visualizer.client.ts (matching graph-visualizer.client.ts) * rather than in a template literal here: it renders with @viz-js/viz v3, redraws every queue * node as a true horizontal cylinder, and wires the shared node menu onto every box — more * logic than belongs inline in a .ts string. The substitution is a blind split/join, so the * placeholder must appear EXACTLY ONCE in the client. */ private script; /** * Page styles, including the shared menu stylesheet: the clickable cursor + blue glow on every * box, and the dim/undim rules the lock toggles, scoped to this page's `#graph` host. Those two * blocks are shared verbatim with architecture/dependencies.html and every design.html. * * The legend swatches are hand-drawn inline SVG on purpose: the alternative is shelling out to * Graphviz at generate time, which would make writing the HTML depend on a `dot` binary being * installed — a dependency this tool does not otherwise have, since rendering is client-side. */ private styles; } export interface RuntimeVisualizationPaths { dotPath: string; htmlPath: string; } /** Write the DOT + HTML renderings to tmp/webpieces/. */ export declare function writeRuntimeVisualization(graph: RuntimeGraph, workspaceRoot: string, title?: string, options?: RuntimeVizOptions): RuntimeVisualizationPaths;