@webpieces/nx-webpieces-rules 0.4.946 → 0.4.948

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/README.md +20 -11
  2. package/package.json +7 -7
  3. package/src/executors/validate-no-file-import-cycles/executor.js +7 -4
  4. package/src/executors/validate-no-file-import-cycles/executor.js.map +1 -1
  5. package/src/index.d.ts +1 -1
  6. package/src/index.js +3 -1
  7. package/src/index.js.map +1 -1
  8. package/src/lib/graph-color-modes.d.ts +18 -12
  9. package/src/lib/graph-color-modes.js +18 -20
  10. package/src/lib/graph-color-modes.js.map +1 -1
  11. package/src/lib/graph-legend.d.ts +11 -3
  12. package/src/lib/graph-legend.js +25 -9
  13. package/src/lib/graph-legend.js.map +1 -1
  14. package/src/lib/graph-mode-state.client.d.ts +2 -1
  15. package/src/lib/graph-mode-state.client.js +3 -1
  16. package/src/lib/graph-mode-state.client.js.map +1 -1
  17. package/src/lib/graph-page-shell.js +2 -2
  18. package/src/lib/graph-page-shell.js.map +1 -1
  19. package/src/lib/graph-page-styles.js +4 -1
  20. package/src/lib/graph-page-styles.js.map +1 -1
  21. package/src/lib/graph-product-paint.client.d.ts +92 -0
  22. package/src/lib/graph-product-paint.client.js +196 -0
  23. package/src/lib/graph-product-paint.client.js.map +1 -0
  24. package/src/lib/graph-products.d.ts +54 -6
  25. package/src/lib/graph-products.js +62 -9
  26. package/src/lib/graph-products.js.map +1 -1
  27. package/src/lib/graph-render-model.d.ts +12 -12
  28. package/src/lib/graph-render-model.js +12 -14
  29. package/src/lib/graph-render-model.js.map +1 -1
  30. package/src/lib/graph-visualizer.client.d.ts +13 -1
  31. package/src/lib/graph-visualizer.client.js +27 -4
  32. package/src/lib/graph-visualizer.client.js.map +1 -1
  33. package/src/lib/graph-visualizer.d.ts +3 -3
  34. package/src/lib/graph-visualizer.js +13 -12
  35. package/src/lib/graph-visualizer.js.map +1 -1
  36. package/src/lib/runtime-goal-comparison.js +1 -1
  37. package/src/lib/runtime-goal-comparison.js.map +1 -1
  38. package/src/lib/runtime-html-page.js +3 -2
  39. package/src/lib/runtime-html-page.js.map +1 -1
  40. package/src/lib/runtime-layout.js +1 -1
  41. package/src/lib/runtime-layout.js.map +1 -1
  42. package/src/lib/runtime-viewer-adapter.d.ts +4 -1
  43. package/src/lib/runtime-viewer-adapter.js +6 -13
  44. package/src/lib/runtime-viewer-adapter.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"graph-render-model.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-render-model.ts"],"names":[],"mappings":"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","sourcesContent":["import { dotValue } from './dot-syntax';\nimport { LevelBand } from './graph-level-bands';\nimport { LegendFacts, NodeFacts, NodeModeDots } from './graph-color-modes';\n\n/**\n * Renderer-owned records, captured while emitting DOT, never recovered by parsing labels.\n *\n * `dot` is the statement `fullDot` carries. `modes` carries per-mode statements in both viewers; `tags` carries declared service/project\n * metadata. Runtime auxiliary entities leave tags null so facets count services and retain context\n * separately.\n *\n * `products` is set on BOTH graphs (#1179): the products a box belongs to, which each page's product\n * filter matches on. Empty for a box in no product.\n */\nexport class RenderNode {\n constructor(\n public readonly id: string,\n public readonly dot: string,\n public readonly modes: NodeModeDots | null,\n public readonly tags: NodeTags | null,\n public readonly products: string[],\n public readonly queueKeys: string[] = [],\n ) {}\n}\n\n/** What the architecture page's Filter matches a box on: its level, role and framework tags. */\nexport class NodeTags {\n constructor(\n public readonly level: number,\n public readonly role: string,\n public readonly frameworks: string[],\n ) {}\n}\n\nexport class RenderEdge {\n constructor(\n public readonly from: string,\n public readonly to: string,\n public readonly dot: string,\n public readonly id: string,\n /**\n * The statement the architecture page's Product color mode draws instead of `dot` (#1204): a\n * dependency crossing into another product, dashed in that product's color. Null for every\n * other edge, which draws `dot` in every mode.\n */\n public readonly productDot: string | null = null,\n ) {}\n}\n\n/** The immutable drawable snapshot carried by a generated page. */\nexport class GraphRenderModel {\n viewer: 'architecture' | 'runtime' = 'architecture';\n readonly nodes: RenderNode[] = [];\n readonly edges: RenderEdge[] = [];\n bands: LevelBand[] = [];\n fullDot = '';\n header = '';\n footer = '';\n /** The colors and roles in use, so the page's legend lists exactly those (architecture graph). */\n legend = new LegendFacts();\n /** Runtime pages only (#1239): the Goal vs Current overlay, or why it is unavailable. */\n comparison: RuntimeComparisonView | null = null;\n\n node(id: string, dot: string, products: string[] = [], queueKeys: string[] = []): string {\n this.nodes.push(new RenderNode(id, dot, null, null, products, queueKeys));\n return dot;\n }\n\n /**\n * Every product a declared box (a queue, a cron trigger, an external system) inherits from the\n * services its edges touch (#1179): it belongs to whichever product's services it is attached to.\n * Called by the runtime graph once every edge is emitted; RenderNode is immutable, so a node gains\n * its products by being replaced.\n */\n attachProducts(isService: (id: string) => boolean): void {\n const byId = new Map<string, RenderNode>();\n for (const node of this.nodes) byId.set(node.id, node);\n for (let index = 0; index < this.nodes.length; index++) {\n const node = this.nodes[index];\n if (isService(node.id)) continue;\n const inherited = new Set<string>();\n for (const edge of this.edges) {\n const other =\n edge.from === node.id ? edge.to : edge.to === node.id ? edge.from : null;\n if (other === null || !isService(other)) continue;\n for (const product of byId.get(other)?.products ?? []) inherited.add(product);\n }\n if (inherited.size === 0) continue;\n this.nodes[index] = new RenderNode(\n node.id,\n node.dot,\n node.modes,\n node.tags,\n [...inherited].sort(),\n node.queueKeys,\n );\n }\n }\n\n /** A box drawn differently per color mode; `fullDot` carries its RUNTIME statement. */\n styledNode(facts: NodeFacts, modes: NodeModeDots): string {\n this.nodes.push(\n new RenderNode(\n facts.nodeId,\n modes.runtime,\n modes,\n new NodeTags(facts.level, facts.role, facts.frameworks),\n facts.products,\n ),\n );\n return modes.runtime;\n }\n\n completeEndpoints(): void {\n const ids = new Set(this.nodes.map((node) => node.id));\n for (const edge of this.edges) {\n for (const id of [edge.from, edge.to]) {\n if (ids.has(id)) continue;\n ids.add(id);\n this.node(id, ` \"${dotValue(id)}\";\\n`);\n }\n }\n }\n\n /**\n * One edge. `productAttrs`, when not empty, is the attribute list the Product color mode adds to\n * the statement (a later list overrides an earlier one in DOT), e.g. a cross-product dependency's\n * dash and color; `fullDot` always carries the plain statement.\n */\n edge(from: string, to: string, dot: string, productAttrs: string = ''): string {\n const id = `wp-real-edge-${this.edges.length}`;\n const base = `${dot.slice(0, -2)} [id=\"${id}\"]`;\n const statement = `${base};\\n`;\n const productDot = productAttrs === '' ? null : `${base} [${productAttrs}];\\n`;\n this.edges.push(new RenderEdge(from, to, statement, id, productDot));\n return statement;\n }\n}\n\n/**\n * What a runtime page carries for its Goal vs Current color mode (#1239), serialized into the page\n * with the render model so it works opened straight from disk (`file://`, no fetch).\n *\n * Never a silent \"no differences\": an unavailable comparison says why (a missing or unusable input,\n * naming its path and repair), and identical inputs say so explicitly with the normal graph context.\n */\nexport class RuntimeComparisonView {\n constructor(\n public readonly available: boolean,\n /** Why the mode is unavailable; '' when available. */\n public readonly reason: string,\n /** Always \"Current → Goal\": the direction every added/removed word is read in. */\n public readonly direction: string,\n /** One line: counts per status, or the explicit no-differences result. */\n public readonly summary: string,\n /** The overlay drawn in this mode; null when unavailable. */\n public readonly model: GraphRenderModel | null,\n /** Overlay render-node id -> before/after detail lines. */\n public readonly nodeDetails: Record<string, string[]>,\n /** Overlay render-edge id (`wp-real-edge-N`) -> before/after detail lines. */\n public readonly edgeDetails: Record<string, string[]>,\n /** Every added, removed and changed fact, one line each, for the legend. */\n public readonly differences: string[],\n ) {}\n}\n\n/** Shared filter chrome and script-safe JSON for pages opened directly from disk. */\nexport class GraphFilterAssets {\n json<T>(value: T): string {\n return JSON.stringify(value).replace(/</g, '\\\\u003c');\n }\n\n html(): string {\n return (\n '<p id=\"wp-filter-status\" hidden>Filtering: <strong id=\"wp-filter-anchor\"></strong> ' +\n '<button id=\"wp-filter-off\" type=\"button\">Turn off Filter</button></p>' +\n '<p id=\"wp-graph-error\" role=\"alert\" hidden></p>'\n );\n }\n\n styles(): string {\n return (\n '#wp-filter-status { text-align:center; } #wp-graph-error { color:#b71c1c; } ' +\n '#graph .wp-filter-anchor polygon, #graph .wp-filter-anchor path, ' +\n '#graph .wp-filter-anchor ellipse { stroke:#8b3cf0; stroke-width:3; }'\n );\n }\n}\n"]}
1
+ {"version":3,"file":"graph-render-model.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-render-model.ts"],"names":[],"mappings":"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","sourcesContent":["import { dotValue } from './dot-syntax';\nimport { LevelBand } from './graph-level-bands';\nimport { LegendFacts, NodeFacts, NodeModeDots } from './graph-color-modes';\n\n/**\n * Renderer-owned records, captured while emitting DOT, never recovered by parsing labels.\n *\n * `dot` is the statement `fullDot` carries. `modes` carries per-mode statements in both viewers; `tags` carries declared service/project\n * metadata. Runtime auxiliary entities leave tags null so facets count services and retain context\n * separately.\n *\n * `products` is set on BOTH graphs (#1179): the products a box belongs to, which each page's product\n * filter matches on. Empty for a box in no product.\n */\nexport class RenderNode {\n constructor(\n public readonly id: string,\n public readonly dot: string,\n public readonly modes: NodeModeDots | null,\n public readonly tags: NodeTags | null,\n public readonly products: string[],\n public readonly queueKeys: string[] = [],\n ) {}\n}\n\n/** What the architecture page's Filter matches a box on: its level, role and framework tags. */\nexport class NodeTags {\n constructor(\n public readonly level: number,\n public readonly role: string,\n public readonly frameworks: string[],\n ) {}\n}\n\nexport class RenderEdge {\n constructor(\n public readonly from: string,\n public readonly to: string,\n public readonly dot: string,\n public readonly id: string,\n /**\n * The products a dependency crosses into (#1204, ProductBoundary), in the target's order. The\n * page's Product color mode draws the edge dashed in the first one that is ON (#1319); empty\n * for every other edge, which draws `dot` in every mode.\n */\n public readonly crossesInto: string[] = [],\n ) {}\n}\n\n/** The immutable drawable snapshot carried by a generated page. */\nexport class GraphRenderModel {\n viewer: 'architecture' | 'runtime' = 'architecture';\n readonly nodes: RenderNode[] = [];\n readonly edges: RenderEdge[] = [];\n bands: LevelBand[] = [];\n fullDot = '';\n header = '';\n footer = '';\n /** The colors and roles in use, so the page's legend lists exactly those (architecture graph). */\n legend = new LegendFacts();\n /** Runtime pages only (#1239): the Goal vs Current overlay, or why it is unavailable. */\n comparison: RuntimeComparisonView | null = null;\n\n node(id: string, dot: string, products: string[] = [], queueKeys: string[] = []): string {\n this.nodes.push(new RenderNode(id, dot, null, null, products, queueKeys));\n return dot;\n }\n\n /**\n * Every product a declared box (a queue, a cron trigger, an external system) inherits from the\n * services its edges touch (#1179): it belongs to whichever product's services it is attached to.\n * Called by the runtime graph once every edge is emitted; RenderNode is immutable, so a node gains\n * its products by being replaced.\n */\n attachProducts(isService: (id: string) => boolean): void {\n const byId = new Map<string, RenderNode>();\n for (const node of this.nodes) byId.set(node.id, node);\n for (let index = 0; index < this.nodes.length; index++) {\n const node = this.nodes[index];\n if (isService(node.id)) continue;\n const inherited = new Set<string>();\n for (const edge of this.edges) {\n const other =\n edge.from === node.id ? edge.to : edge.to === node.id ? edge.from : null;\n if (other === null || !isService(other)) continue;\n for (const product of byId.get(other)?.products ?? []) inherited.add(product);\n }\n if (inherited.size === 0) continue;\n this.nodes[index] = new RenderNode(\n node.id,\n node.dot,\n node.modes,\n node.tags,\n [...inherited].sort(),\n node.queueKeys,\n );\n }\n }\n\n /** A box drawn differently per color mode; `fullDot` carries its RUNTIME statement. */\n styledNode(facts: NodeFacts, modes: NodeModeDots): string {\n this.nodes.push(\n new RenderNode(\n facts.nodeId,\n modes.runtime,\n modes,\n new NodeTags(facts.level, facts.role, facts.frameworks),\n facts.products,\n ),\n );\n return modes.runtime;\n }\n\n completeEndpoints(): void {\n const ids = new Set(this.nodes.map((node) => node.id));\n for (const edge of this.edges) {\n for (const id of [edge.from, edge.to]) {\n if (ids.has(id)) continue;\n ids.add(id);\n this.node(id, ` \"${dotValue(id)}\";\\n`);\n }\n }\n }\n\n /**\n * One edge. `crossesInto`, when not empty, names the products a cross-product dependency crosses\n * into: the page's Product color mode dashes it in the first ON one; `fullDot` always carries the\n * plain statement.\n */\n edge(from: string, to: string, dot: string, crossesInto: string[] = []): string {\n const id = `wp-real-edge-${this.edges.length}`;\n const statement = `${dot.slice(0, -2)} [id=\"${id}\"];\\n`;\n this.edges.push(new RenderEdge(from, to, statement, id, crossesInto));\n return statement;\n }\n}\n\n/**\n * What a runtime page carries for its Goal vs Current color mode (#1239), serialized into the page\n * with the render model so it works opened straight from disk (`file://`, no fetch).\n *\n * Never a silent \"no differences\": an unavailable comparison says why (a missing or unusable input,\n * naming its path and repair), and identical inputs say so explicitly with the normal graph context.\n */\nexport class RuntimeComparisonView {\n constructor(\n public readonly available: boolean,\n /** Why the mode is unavailable; '' when available. */\n public readonly reason: string,\n /** Always \"Current → Goal\": the direction every added/removed word is read in. */\n public readonly direction: string,\n /** One line: counts per status, or the explicit no-differences result. */\n public readonly summary: string,\n /** The overlay drawn in this mode; null when unavailable. */\n public readonly model: GraphRenderModel | null,\n /** Overlay render-node id -> before/after detail lines. */\n public readonly nodeDetails: Record<string, string[]>,\n /** Overlay render-edge id (`wp-real-edge-N`) -> before/after detail lines. */\n public readonly edgeDetails: Record<string, string[]>,\n /** Every added, removed and changed fact, one line each, for the legend. */\n public readonly differences: string[],\n ) {}\n}\n\n/** Shared filter chrome and script-safe JSON for pages opened directly from disk. */\nexport class GraphFilterAssets {\n json<T>(value: T): string {\n return JSON.stringify(value).replace(/</g, '\\\\u003c');\n }\n\n html(): string {\n return (\n '<p id=\"wp-filter-status\" hidden>Filtering: <strong id=\"wp-filter-anchor\"></strong> ' +\n '<button id=\"wp-filter-off\" type=\"button\">Turn off Filter</button></p>' +\n '<p id=\"wp-graph-error\" role=\"alert\" hidden></p>'\n );\n }\n\n styles(): string {\n return (\n '#wp-filter-status { text-align:center; } #wp-graph-error { color:#b71c1c; } ' +\n '#graph .wp-filter-anchor polygon, #graph .wp-filter-anchor path, ' +\n '#graph .wp-filter-anchor ellipse { stroke:#8b3cf0; stroke-width:3; }'\n );\n }\n}\n"]}
@@ -127,6 +127,13 @@ declare class GraphPage extends WpFilterPage {
127
127
  private readonly drawer;
128
128
  private readonly why;
129
129
  private readonly edges;
130
+ /**
131
+ * The products switched ON in the Product legend (#1319): the first two in legend order at EVERY
132
+ * load. Never persisted — no storage, no hash — so the page stays stateless.
133
+ */
134
+ private readonly toggles;
135
+ private readonly productsOn;
136
+ private painter;
130
137
  /** In Impact mode a box's menu leads with WHY it is in the build, and its edge changes (#1264). */
131
138
  impactItems(name: string, node: SVGGElement): WpNodeMenuItem[];
132
139
  protected captureBinding(_svg: SVGSVGElement | null): () => void;
@@ -136,7 +143,10 @@ declare class GraphPage extends WpFilterPage {
136
143
  /** Goal vs Current draws its overlay topology; every other mode draws the page's own graph. */
137
144
  private syncModel;
138
145
  protected nodeDot(node: RenderNodeJson): string;
139
- /** Product mode dashes a dependency that crosses into another product (#1204); every other mode draws it plain. */
146
+ /**
147
+ * Product mode dashes a dependency that crosses into another product (#1204) while that product is
148
+ * ON (#1319); every other mode draws it plain.
149
+ */
140
150
  protected edgeDot(edge: RenderEdgeJson): string;
141
151
  protected usesFullDot(): boolean;
142
152
  protected narrow(retained: Set<string>): Set<string>;
@@ -155,6 +165,8 @@ declare class GraphPage extends WpFilterPage {
155
165
  setLock(name: string | null): void;
156
166
  clearSelection(): void;
157
167
  setMode(mode: string): void;
168
+ /** A product legend toggle (#1319): repaint at once from the new ON set. */
169
+ setProductOn(product: string, on: boolean): void;
158
170
  /** Switch the active Impact scan: Impact recolours and an active change-scope filter re-applies. */
159
171
  setImpactKind(kind: string): void;
160
172
  /** The drawer's "Hide unconnected": filter to the locked box's chain, or turn the filter off. */
@@ -673,6 +673,13 @@ class GraphPage extends WpFilterPage {
673
673
  drawer = new GraphDrawer(this);
674
674
  why = new ImpactWhyPanel();
675
675
  edges = new WpEdgeOverlay(this.modes);
676
+ /**
677
+ * The products switched ON in the Product legend (#1319): the first two in legend order at EVERY
678
+ * load. Never persisted — no storage, no hash — so the page stays stateless.
679
+ */
680
+ toggles = new WpProductToggles();
681
+ productsOn = new WpProductSelection().initialOn(this.toggles.products());
682
+ painter = this.toggles.painter(this.base.legend.palette.colors, this.productsOn);
676
683
  /** In Impact mode a box's menu leads with WHY it is in the build, and its edge changes (#1264). */
677
684
  impactItems(name, node) {
678
685
  if (this.modes.mode !== 'impact')
@@ -698,6 +705,7 @@ class GraphPage extends WpFilterPage {
698
705
  wireControls() {
699
706
  this.syncModel();
700
707
  this.drawer.wire();
708
+ this.toggles.wire((product, on) => this.setProductOn(product, on));
701
709
  this.syncControls();
702
710
  }
703
711
  /** '' when this page can show Goal vs Current, else why not. */
@@ -729,13 +737,16 @@ class GraphPage extends WpFilterPage {
729
737
  if (this.modes.mode === 'impact')
730
738
  return modes[this.modes.status(node.id)];
731
739
  if (this.modes.mode === 'product')
732
- return modes.product;
740
+ return this.painter.nodeDot(modes.product, node.products);
733
741
  return modes.runtime;
734
742
  }
735
- /** Product mode dashes a dependency that crosses into another product (#1204); every other mode draws it plain. */
743
+ /**
744
+ * Product mode dashes a dependency that crosses into another product (#1204) while that product is
745
+ * ON (#1319); every other mode draws it plain.
746
+ */
736
747
  edgeDot(edge) {
737
- if (this.modes.mode === 'product' && edge.productDot !== null)
738
- return edge.productDot;
748
+ if (this.modes.mode === 'product')
749
+ return this.painter.edgeDot(edge);
739
750
  if (this.modes.mode === 'impact')
740
751
  return this.edges.edgeDot(edge) ?? edge.dot;
741
752
  return edge.dot;
@@ -803,6 +814,17 @@ class GraphPage extends WpFilterPage {
803
814
  this.syncControls();
804
815
  this.redraw();
805
816
  }
817
+ /** A product legend toggle (#1319): repaint at once from the new ON set. */
818
+ setProductOn(product, on) {
819
+ if (on)
820
+ this.productsOn.add(product);
821
+ else
822
+ this.productsOn.delete(product);
823
+ this.painter = this.toggles.painter(this.base.legend.palette.colors, this.productsOn);
824
+ this.syncControls();
825
+ if (this.modes.mode === 'product')
826
+ this.redraw();
827
+ }
806
828
  /** Switch the active Impact scan: Impact recolours and an active change-scope filter re-applies. */
807
829
  setImpactKind(kind) {
808
830
  if (kind === this.modes.kind || !this.modes.setKind(kind))
@@ -858,6 +880,7 @@ class GraphPage extends WpFilterPage {
858
880
  syncControls() {
859
881
  document.body.dataset['wpMode'] = this.modes.mode;
860
882
  this.drawer.sync(this.modes, this.locked, this.anchor !== null, this.applied);
883
+ this.toggles.sync(this.productsOn);
861
884
  const count = this.model.nodes.filter(node => this.retained.has(node.id) && this.projects.isService(node)).length;
862
885
  const empty = document.getElementById('wp-empty');
863
886
  if (empty !== null)
@@ -1 +1 @@
1
- {"version":3,"file":"graph-visualizer.client.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-visualizer.client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One state of the Filter popover: a change scope plus the selected Runtime, Role and Product chips.\n * The page holds the APPLIED one; the popover edits a copy until \"Show N projects\".\n */\nclass WpFilterChoice {\n scope = 'everything';\n readonly runtimes = new Set<string>();\n readonly roles = new Set<string>();\n readonly products = new Set<string>();\n\n copy(): WpFilterChoice {\n const copy = new WpFilterChoice();\n copy.scope = this.scope;\n for (const runtime of this.runtimes) copy.runtimes.add(runtime);\n for (const role of this.roles) copy.roles.add(role);\n for (const product of this.products) copy.products.add(product);\n return copy;\n }\n\n /** How many filters are active: the drawer button's badge. */\n count(): number {\n return (this.scope === 'everything' ? 0 : 1) + this.runtimes.size + this.roles.size + this.products.size;\n }\n\n /** The chip set a `data-wp-chip-group` (or a pill's group) names. */\n group(name: string): Set<string> {\n if (name === 'role') return this.roles;\n if (name === 'product') return this.products;\n return this.runtimes;\n }\n}\n\n/**\n * The Filter popover's four groups, INTERSECTED: a box stays when it is in the change scope, AND has\n * any selected runtime chip (when one is selected), AND has any selected role chip (likewise), AND\n * belongs to any selected product (likewise — several products are the UNION of their closures).\n */\nclass WpProjectFilter {\n constructor(\n private readonly model: RenderModelJson,\n private readonly modes: WpModeState,\n ) {}\n\n /** The node ids a change scope keeps; null for \"everything\" (and whenever Impact is unavailable). */\n scopeSet(scope: string): Set<string> | null {\n const impact = this.modes.impact;\n if (scope === 'everything' || impact === null || this.modes.impactReason() !== '') return null;\n if (scope === 'edges') return this.modes.edgeEnds();\n const ids: string[] = [...impact.touched];\n if (scope === 'dependents' || scope === 'build') ids.push(...this.modes.affected());\n if (scope === 'dependencies') ids.push(...impact.dependencies);\n if (scope === 'build') ids.push(...impact.buildInputs);\n return new Set(ids);\n }\n\n /** How many drawn projects a scope keeps on its own: the count beside each option. */\n scopeCount(scope: string): number {\n const set = this.scopeSet(scope);\n return this.model.nodes.filter((node: RenderNodeJson): boolean => this.isService(node) && (set === null || set.has(node.id))).length;\n }\n\n /** `base` (everything, or the Hide-unconnected chain) narrowed by `choice`. */\n apply(base: Set<string>, choice: WpFilterChoice): Set<string> {\n const scope = this.scopeSet(choice.scope);\n const kept = new Set<string>();\n for (const node of this.model.nodes) {\n if (!base.has(node.id) || !this.isService(node)) continue;\n if (scope !== null && !scope.has(node.id)) continue;\n if (!this.anyOf(choice.runtimes, node.tags?.frameworks ?? [])) continue;\n if (!this.anyOf(choice.roles, node.tags === null ? [] : [node.tags.role])) continue;\n if (!this.anyOf(choice.products, node.products)) continue;\n kept.add(node.id);\n }\n if (this.model.viewer === 'runtime') {\n for (const node of this.model.nodes) {\n if (node.tags !== null || !base.has(node.id)) continue;\n if (this.model.edges.some(edge => (edge.from === node.id && kept.has(edge.to)) || (edge.to === node.id && kept.has(edge.from)))) kept.add(node.id);\n }\n }\n return kept;\n }\n\n isService(node: RenderNodeJson): boolean { return this.model.viewer !== 'runtime' || node.tags !== null; }\n\n /** An empty chip group matches every box; otherwise the box must carry one of the chips. */\n private anyOf(selected: Set<string>, carried: string[]): boolean {\n return selected.size === 0 || carried.some((value: string): boolean => selected.has(value));\n }\n}\n\n/** Architecture interactions bind to each new SVG; logical Lock/Filter state belongs to the page. */\nclass GraphHighlighter {\n private readonly nodeByName = new Map<string, SVGGElement>();\n private hovered: string | null = null;\n\n constructor(\n private readonly svg: SVGSVGElement,\n private readonly chain: WpGraphChain,\n private readonly model: RenderModelJson,\n private readonly page: GraphPage,\n ) {}\n\n wire(): void {\n this.svg.querySelectorAll<SVGGElement>('g.node').forEach((g: SVGGElement) => {\n if (g.classList.contains('wp-layout')) return;\n const name = g.querySelector('title')?.textContent;\n if (name !== null && name !== undefined) this.nodeByName.set(name, g);\n });\n this.wireHover();\n this.wireMenu();\n this.relight();\n }\n\n private clear(): void {\n this.svg.classList.remove('wp-dim');\n this.svg.querySelectorAll('.wp-focus, .wp-neighbor, .wp-hl, .wp-locked').forEach((el: Element) => {\n el.classList.remove('wp-focus', 'wp-neighbor', 'wp-hl', 'wp-locked');\n });\n }\n\n relight(): void {\n this.clear();\n const locked = this.page.lockSelection();\n if (locked !== null) this.nodeByName.get(locked)?.classList.add('wp-locked');\n // A filtered-out Lock is suspended, including its otherwise visible relatives.\n const anchors = [locked, this.hovered].filter(\n (name: string | null): name is string => name !== null && this.nodeByName.has(name),\n );\n if (anchors.length === 0) return;\n const lit = new Set<string>();\n for (const name of anchors) {\n this.nodeByName.get(name)?.classList.add('wp-focus');\n for (const id of this.chain.nodes(name)) {\n if (this.nodeByName.has(id)) lit.add(id);\n }\n }\n this.svg.classList.add('wp-dim');\n for (const id of lit) this.nodeByName.get(id)?.classList.add('wp-neighbor');\n for (const edge of this.model.edges) {\n if (lit.has(edge.from) && lit.has(edge.to)) {\n this.svg.querySelector(`[id=\"${edge.id}\"]`)?.classList.add('wp-hl');\n }\n }\n }\n\n private wireHover(): void {\n this.nodeByName.forEach((g: SVGGElement, name: string) => {\n g.addEventListener('mouseenter', () => {\n this.hovered = name;\n this.relight();\n });\n g.addEventListener('mouseleave', () => {\n this.hovered = null;\n this.relight();\n });\n });\n }\n\n private wireMenu(): void {\n const designs = new Map<string, string>();\n for (const link of __DESIGN_LINKS__) designs.set(link.nodeId, link.href);\n WpNodeMenu.wire(this.svg, (name: string, node: SVGGElement): WpNodeMenuItem[] => {\n const items: WpNodeMenuItem[] = [];\n const href = designs.get(name);\n if (href !== undefined)\n items.push(new WpNodeMenuItem('View Design', () => window.open(href, '_blank')));\n const locked = this.page.lockSelection() === name;\n items.push(\n new WpNodeMenuItem(locked ? 'Unlock' : 'Lock', () =>\n locked ? this.page.clearSelection() : this.page.setLock(name),\n ),\n );\n items.push(this.page.filterItem(name));\n items.unshift(...this.page.impactItems(name, node));\n const implemented = window.__WP_RUNTIME__?.implementsItem(name, node);\n if (implemented) items.push(implemented);\n const goal = window.__WP_GOAL__?.item(name, node);\n if (goal) items.push(goal);\n return items;\n });\n }\n}\n\n/**\n * The Filter popover: edits a COPY of the page's applied filter, shows what each choice would keep,\n * and hands the copy to the page on \"Show N projects\". Closing it any other way discards the edit.\n */\nclass GraphFilterPopover {\n private draft = new WpFilterChoice();\n\n constructor(private readonly page: GraphPage) {}\n\n wire(): void {\n this.byId('wp-filter-open')?.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n if (this.isOpen()) this.close();\n else this.open();\n });\n this.byId('wp-filter-close')?.addEventListener('click', () => this.close());\n this.byId('wp-filter-clear')?.addEventListener('click', () => {\n this.draft = new WpFilterChoice();\n this.paint();\n });\n this.byId('wp-filter-apply')?.addEventListener('click', () => {\n this.page.applyFilter(this.draft.copy());\n this.close();\n });\n document.querySelectorAll<HTMLInputElement>('input[name=\"wp-scope\"]').forEach((radio: HTMLInputElement) => {\n radio.addEventListener('change', () => {\n if (!radio.checked) return;\n this.draft.scope = radio.value;\n this.paint();\n });\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-chip[data-wp-chip]').forEach((chip: HTMLButtonElement) => {\n chip.addEventListener('click', () => {\n const set = this.draft.group(chip.dataset['wpChipGroup'] ?? '');\n const value = chip.dataset['wpChip'] ?? '';\n if (set.has(value)) set.delete(value);\n else set.add(value);\n this.paint();\n });\n });\n }\n\n isOpen(): boolean {\n return this.byId('wp-filter-pop')?.hidden === false;\n }\n\n /** The active Impact scan changed: an open popover's counts and labels follow it. */\n refresh(): void {\n if (this.isOpen()) this.paint();\n }\n\n open(): void {\n const pop = this.byId('wp-filter-pop');\n if (pop === null) return;\n this.draft = this.page.appliedFilter().copy();\n this.paint();\n pop.hidden = false;\n this.byId('wp-filter-open')?.setAttribute('aria-expanded', 'true');\n }\n\n close(): void {\n const pop = this.byId('wp-filter-pop');\n if (pop === null || pop.hidden) return;\n pop.hidden = true;\n this.byId('wp-filter-open')?.setAttribute('aria-expanded', 'false');\n }\n\n /** Repaint the controls from the draft: checked scope, pressed chips, counts and the footer. */\n private paint(): void {\n const reason = this.page.scopeReason();\n const group = this.byId('wp-scope-group') as HTMLFieldSetElement | null;\n if (group !== null) group.disabled = reason !== '';\n const reasonEl = this.byId('wp-scope-reason');\n if (reasonEl !== null) {\n reasonEl.textContent = reason;\n reasonEl.hidden = reason === '';\n }\n document.querySelectorAll<HTMLInputElement>('input[name=\"wp-scope\"]').forEach((radio: HTMLInputElement) => {\n radio.checked = radio.value === this.draft.scope;\n });\n document.querySelectorAll<HTMLElement>('[data-wp-scope-count]').forEach((count: HTMLElement) => {\n count.textContent = reason === '' ? String(this.page.scopeCount(count.dataset['wpScopeCount'] ?? '')) : '';\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-chip[data-wp-chip]').forEach((chip: HTMLButtonElement) => {\n const set = this.draft.group(chip.dataset['wpChipGroup'] ?? '');\n chip.setAttribute('aria-pressed', String(set.has(chip.dataset['wpChip'] ?? '')));\n });\n const apply = this.byId('wp-filter-apply');\n if (apply !== null) {\n const shown = this.page.preview(this.draft);\n apply.textContent = `Show ${shown} ${this.page.noun()}${shown === 1 ? '' : 's'}`;\n }\n }\n\n private byId(id: string): HTMLElement | null {\n return document.getElementById(id);\n }\n}\n\n/**\n * The drawer and its floating panels: every control outside the graph itself. Holds no graph state —\n * each control calls back into the page, and `sync()` repaints the controls from the page's state.\n */\nclass GraphDrawer {\n readonly popover: GraphFilterPopover;\n private readonly openers = new Map<string, HTMLElement>();\n\n constructor(private readonly page: GraphPage) {\n this.popover = new GraphFilterPopover(page);\n }\n\n wire(): void {\n this.wireModeMenu();\n this.popover.wire();\n this.wireImpactKinds();\n this.wireLock();\n this.byId('wp-lock-toggle')?.addEventListener('click', () => this.page.toggleLock());\n this.byId('wp-filter-toggle')?.addEventListener('click', () => this.page.toggleFilter());\n this.toggles('wp-collapse', 'wp-shell', true);\n this.toggles('wp-help-btn', 'wp-help', false);\n this.toggles('wp-help-close', 'wp-help', false);\n this.toggles('wp-legend-pop', 'wp-legend-popout', false);\n this.toggles('wp-legend-close', 'wp-legend-popout', false);\n this.toggles('wp-resp-open', 'wp-resp-panel', false);\n this.toggles('wp-resp-close', 'wp-resp-panel', false);\n this.toggles('wp-snapshot-open', 'wp-snapshot', false);\n window.addEventListener('keydown', (ev: KeyboardEvent) => this.onKey(ev), true);\n window.addEventListener('hashchange', () => this.page.setMode(location.hash.slice(1)));\n document.addEventListener('click', (ev: MouseEvent) => {\n const target = ev.target;\n if (target instanceof Node && this.byId('wp-mode-menu')?.parentElement?.contains(target)) return;\n this.closeModeMenu(false);\n this.dismissOutside(target);\n });\n }\n\n /** \"Color by\": the pill trigger opens the menu of four; picking one switches and closes it. */\n private wireModeMenu(): void {\n this.byId('wp-mode-trigger')?.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n const menu = this.byId('wp-mode-menu');\n if (menu === null) return;\n if (!menu.hidden) {\n this.closeModeMenu(false);\n return;\n }\n menu.hidden = false;\n this.byId('wp-mode-trigger')?.setAttribute('aria-expanded', 'true');\n menu.querySelector<HTMLButtonElement>('.wp-mode[aria-checked=\"true\"]')?.focus({ preventScroll: true });\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-mode[data-wp-mode]').forEach((button: HTMLButtonElement) => {\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.closeModeMenu(true);\n this.page.setMode(button.dataset['wpMode'] ?? 'runtime');\n });\n });\n }\n\n /** The \"Changed on this branch\" / \"Last commit\" toggle, in the drawer and in the Filter popover. */\n private wireImpactKinds(): void {\n document.querySelectorAll<HTMLButtonElement>('[data-wp-impact-kind]').forEach((button: HTMLButtonElement) => {\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.page.setImpactKind(button.dataset['wpImpactKind'] ?? '');\n this.popover.refresh();\n });\n });\n }\n\n /** Shown only when two scans exist; the drawer's copy only while Impact colors the graph. */\n private syncImpactKinds(modes: WpModeState): void {\n document.querySelectorAll<HTMLElement>('[data-wp-impact-kinds]').forEach((group: HTMLElement) => {\n const inDrawer = group.dataset['wpImpactKinds'] === 'drawer';\n group.hidden = modes.scans.length < 2 || (inDrawer && modes.mode !== 'impact');\n });\n document.querySelectorAll<HTMLButtonElement>('[data-wp-impact-kind]').forEach((button: HTMLButtonElement) => {\n const kind = button.dataset['wpImpactKind'] ?? '';\n button.setAttribute('aria-pressed', String(kind === modes.kind));\n button.disabled = !modes.kindAvailable(kind);\n const scan = modes.scans.find((candidate: ImpactJson): boolean => candidate.kind === kind);\n button.title = scan === undefined ? '' : scan.available ? scan.label : scan.reason;\n });\n const legend = this.byId('wp-scope-legend');\n if (legend !== null) legend.textContent = modes.impact?.label ?? 'Changes on this branch';\n }\n\n private closeModeMenu(returnFocus: boolean): void {\n const menu = this.byId('wp-mode-menu');\n if (menu === null || menu.hidden) return;\n menu.hidden = true;\n const trigger = this.byId('wp-mode-trigger');\n trigger?.setAttribute('aria-expanded', 'false');\n if (returnFocus) trigger?.focus({ preventScroll: true });\n }\n\n /** Type-to-search lock: an exact project id (or a unique short name) locks, empty or Esc unlocks. */\n private wireLock(): void {\n const input = this.lockInput();\n if (input === null) return;\n input.addEventListener('input', () => {\n const value = input.value.trim();\n if (value === '') this.page.clearSelection();\n else if (this.page.hasNode(value)) this.page.setLock(value);\n });\n input.addEventListener('change', () => {\n const match = this.page.resolveName(input.value.trim());\n if (match !== null) this.page.setLock(match);\n else input.value = this.page.lockSelection() ?? '';\n });\n input.addEventListener('keydown', (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return;\n ev.preventDefault();\n input.value = '';\n this.page.clearSelection();\n input.blur();\n });\n }\n\n /**\n * Page keys, in the CAPTURE phase so the open/closed state of the node menu is read before the\n * menu's own Escape handler closes it: Esc with a menu open only closes the menu. Esc closes an\n * open Color-by menu or Filter popover first, too.\n */\n private onKey(ev: KeyboardEvent): void {\n if (ev.altKey || ev.ctrlKey || ev.metaKey) return;\n if (ev.key === 'Escape' && this.byId('wp-mode-menu')?.hidden === false) {\n this.closeModeMenu(true);\n return;\n }\n if (ev.key === 'Escape' && this.popover.isOpen()) {\n this.popover.close();\n return;\n }\n if (ev.key === 'Escape' && this.dismissOverlay()) return;\n const target = ev.target;\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) return;\n const menuOpen = document.getElementById('wp-node-menu') !== null || document.querySelector('.wp-graph-details:not([hidden]), .wp-goal-details:not([hidden]), .wp-impact-why:not([hidden])') !== null;\n if (ev.key === '/') {\n this.byId('wp-shell')?.classList.remove('wp-collapsed');\n this.byId('wp-collapse')?.setAttribute('aria-expanded', 'true');\n ev.preventDefault();\n this.lockInput()?.focus();\n return;\n }\n const index = ['1', '2', '3', '4', '5'].indexOf(ev.key);\n if (index >= 0 && !menuOpen) {\n this.page.setMode(WpModeState.MODES[index]);\n return;\n }\n if (ev.key === 'Escape' && !menuOpen && this.page.lockSelection() !== null) this.page.setLock(null);\n }\n\n /** `button` shows/hides `target`; for the drawer itself it toggles the collapsed class instead. */\n private toggles(buttonId: string, targetId: string, collapse: boolean): void {\n const button = this.byId(buttonId);\n const target = this.byId(targetId);\n if (button === null || target === null) return;\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n let expanded: boolean;\n if (collapse) {\n expanded = !target.classList.toggle('wp-collapsed');\n } else {\n target.hidden = !target.hidden;\n expanded = !target.hidden;\n if (expanded) this.openers.set(targetId, button);\n else this.openers.get(targetId)?.focus({ preventScroll: true });\n }\n document.querySelectorAll(`[aria-controls=\"${targetId}\"], #${buttonId}[aria-expanded]`).forEach(\n (el: Element) => el.setAttribute('aria-expanded', String(expanded)),\n );\n });\n }\n\n private dismissOverlay(): boolean {\n for (const id of ['wp-help', 'wp-legend-popout', 'wp-snapshot', 'wp-resp-panel']) {\n const panel = this.byId(id);\n if (!panel || panel.hidden) continue;\n panel.hidden = true;\n this.openers.get(id)?.focus({ preventScroll: true });\n this.openers.get(id)?.setAttribute('aria-expanded', 'false');\n return true;\n }\n return false;\n }\n\n private dismissOutside(target: EventTarget | null): void {\n if (!(target instanceof Node)) return;\n const filter = this.byId('wp-filter-pop');\n if (this.popover.isOpen() && !filter?.contains(target) && !this.byId('wp-filter-open')?.contains(target)) this.popover.close();\n for (const entry of this.openers) {\n const id = entry[0];\n const opener = entry[1];\n const panel = this.byId(id);\n if (panel && !panel.hidden && !panel.contains(target) && !opener.contains(target)) {\n panel.hidden = true;\n opener.setAttribute('aria-expanded', 'false');\n }\n }\n }\n\n /** Repaint every control from the page's state. */\n sync(modes: WpModeState, locked: string | null, filtering: boolean, filter: WpFilterChoice): void {\n const reason = modes.impactReason();\n document.querySelectorAll<HTMLButtonElement>('.wp-mode[data-wp-mode]').forEach((button: HTMLButtonElement) => {\n const mode = button.dataset['wpMode'] ?? '';\n button.setAttribute('aria-checked', String(mode === modes.mode));\n button.disabled = !modes.available(mode);\n if (mode === 'impact') button.title = reason === '' ? 'Key 3' : reason;\n if (mode === 'product') button.title = modes.productReason() === '' ? 'Key 4' : modes.productReason();\n if (mode === 'goal') {\n // Unavailable is said in the menu itself, never shown as \"no differences\" (#1239).\n button.title = modes.goalReason() === '' ? 'Key 5' : modes.goalReason();\n const sub = button.querySelector('.wp-mode-sub');\n if (sub !== null) sub.textContent = modes.goalReason() === '' ? modes.subtitle(mode) : `Unavailable: ${modes.goalReason()}`;\n }\n });\n this.text('wp-mode-current', modes.name(modes.mode));\n this.text('wp-mode-current-sub', modes.subtitle(modes.mode));\n const reasonEl = this.byId('wp-impact-reason');\n if (reasonEl !== null) {\n reasonEl.textContent = reason;\n reasonEl.hidden = reason === '';\n }\n document.querySelectorAll<HTMLElement>('[data-wp-legend-mode]').forEach((section: HTMLElement) => {\n section.hidden = section.dataset['wpLegendMode'] !== modes.mode;\n });\n document.querySelectorAll<HTMLElement>('[data-wp-impact-note]').forEach((note: HTMLElement) => {\n note.textContent = this.impactNote(modes);\n });\n // \"unexplained\" is a row only when the active scan has one.\n document.querySelectorAll<HTMLElement>('[data-wp-legend=\"unexplained\"]').forEach((row: HTMLElement) => {\n row.hidden = (modes.impact?.unexplained.length ?? 0) === 0;\n });\n this.syncImpactKinds(modes);\n const title = this.byId('wp-legend-pop-title');\n if (title !== null) title.textContent = `Legend · ${modes.name(modes.mode)}`;\n const input = this.lockInput();\n if (input !== null && document.activeElement !== input) input.value = this.page.focusSelection() ?? '';\n const lockToggle = this.byId('wp-lock-toggle') as HTMLButtonElement | null;\n if (lockToggle !== null) {\n lockToggle.setAttribute('aria-pressed', String(locked !== null));\n lockToggle.disabled = locked === null && this.page.focusSelection() === null;\n lockToggle.title = lockToggle.disabled ? 'Select a node in Focus first' : '';\n }\n this.syncFilterToggle(locked, filtering);\n this.syncFilter(filter);\n this.crumb(modes.name(modes.mode), locked);\n }\n\n private syncFilterToggle(locked: string | null, filtering: boolean): void {\n const toggle = this.byId('wp-filter-toggle') as HTMLButtonElement | null;\n if (toggle === null) return;\n toggle.setAttribute('aria-pressed', String(filtering));\n toggle.disabled = !filtering && locked === null;\n toggle.title = toggle.disabled ? 'Lock a project first' : '';\n }\n\n /** The drawer button's count badge, and one removable pill per active filter in the top bar. */\n private syncFilter(filter: WpFilterChoice): void {\n const badge = this.byId('wp-filter-badge');\n if (badge !== null) {\n badge.textContent = String(filter.count());\n badge.hidden = filter.count() === 0;\n }\n const pills = this.byId('wp-filter-pills');\n if (pills === null) return;\n const items: HTMLElement[] = [];\n if (filter.scope !== 'everything') items.push(this.pill(this.scopeLabel(filter.scope), 'scope', filter.scope));\n for (const runtime of filter.runtimes) items.push(this.pill(runtime, 'runtime', runtime));\n for (const role of filter.roles) items.push(this.pill(role, 'role', role));\n for (const product of filter.products) items.push(this.pill(`product: ${product}`, 'product', product));\n pills.replaceChildren(...items);\n }\n\n /** A change scope's name, read from the Filter popover's markup: the shell owns the ONE copy. */\n private scopeLabel(scope: string): string {\n return document.querySelector(`[data-wp-scope-label=\"${scope}\"]`)?.textContent ?? scope;\n }\n\n /** A pill, built with text nodes so no value is parsed as HTML. */\n private pill(label: string, group: string, value: string): HTMLElement {\n const pill = document.createElement('span');\n pill.className = 'wp-pill';\n pill.dataset['wpPill'] = `${group}:${value}`;\n pill.append(label);\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.textContent = '✕';\n remove.setAttribute('aria-label', `Remove filter ${label}`);\n remove.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.page.removeFilter(group, value);\n });\n pill.append(remove);\n return pill;\n }\n\n private impactNote(modes: WpModeState): string {\n const impact = modes.impact;\n if (impact === null || !impact.available) return '';\n // An available scan with a note is an EMPTY one, e.g. \"Nothing changed on this branch yet\".\n if (impact.reason !== '') return `${impact.label}: ${impact.reason}.`;\n const stats = `${impact.label}: ${new WpImpactWhy().counts(impact)} — nx affected, ${impact.changedFiles} changed files.`;\n const cause = this.globalCause(impact, modes.affected().length);\n return [cause === '' ? '' : `${cause}.`, stats, modes.edgeNote()].filter((part: string): boolean => part !== '').join(' ');\n }\n\n /**\n * When files changed but no project owns one, everything nx affected is affected by a\n * workspace-global input (a lockfile, the workspace manifest). That is correct for CI, and\n * baffling on a graph, so the note names the cause.\n */\n private globalCause(impact: ImpactJson, affected: number): string {\n if (impact.touched.length > 0 || impact.changedFiles === 0) return '';\n const who = affected >= this.page.projectCount() ? 'Every project affected' : `${affected} projects affected`;\n const files = impact.globalFiles;\n if (files.length === 0)\n return `${who}: ${impact.changedFiles} changed files that no project owns (workspace-global input)`;\n const named = files.slice(0, 2).join(', ') + (files.length > 2 ? ` and ${files.length - 2} more` : '');\n return `${who}: ${named} changed (workspace-global input${files.length > 1 ? 's' : ''})`;\n }\n\n /** \"Mode: <b>Runtime</b> · Locked: <b>x</b>\", built with text nodes so no name is parsed as HTML. */\n private crumb(mode: string, locked: string | null): void {\n const crumb = this.byId('wp-crumb');\n if (crumb === null) return;\n const bold = (text: string): HTMLElement => {\n const b = document.createElement('b');\n b.textContent = text;\n return b;\n };\n const parts: (string | Node)[] = ['Mode: ', bold(mode)];\n if (locked !== null) parts.push(' · Locked: ', bold(locked));\n crumb.replaceChildren(...parts);\n }\n\n private text(id: string, value: string): void {\n const el = this.byId(id);\n if (el !== null) el.textContent = value;\n }\n\n private lockInput(): HTMLInputElement | null {\n return document.getElementById('wp-lock') as HTMLInputElement | null;\n }\n\n private byId(id: string): HTMLElement | null {\n return document.getElementById(id);\n }\n}\n\nclass GraphPage extends WpFilterPage {\n private highlighter: GraphHighlighter | null = null;\n private selected: string | null = null;\n /** The page's own graph; Goal vs Current swaps in its overlay and back (#1239). */\n private readonly base: RenderModelJson = this.model;\n private readonly modes = new WpModeState(\n this.model.nodes.some((node: RenderNodeJson): boolean => node.products.length > 0),\n this.model.viewer ?? 'architecture',\n this.goalUnavailable(),\n );\n private projects = new WpProjectFilter(this.model, this.modes);\n private applied = new WpFilterChoice();\n private readonly drawer = new GraphDrawer(this);\n private readonly why = new ImpactWhyPanel();\n\n private readonly edges = new WpEdgeOverlay(this.modes);\n\n /** In Impact mode a box's menu leads with WHY it is in the build, and its edge changes (#1264). */\n impactItems(name: string, node: SVGGElement): WpNodeMenuItem[] {\n if (this.modes.mode !== 'impact') return [];\n const items: WpNodeMenuItem[] = [];\n const reason = this.modes.reason(name);\n const title = reason === null ? '' : (WpImpactWhy.TITLES[reason.kind] ?? reason.kind).toLowerCase();\n if (reason !== null) items.push(new WpNodeMenuItem(`Why in this build? (${title})`, () => this.why.open(node, reason)));\n const lines = this.edges.nodeLines(name);\n if (lines.length > 0) items.push(new WpNodeMenuItem(`Edge changes (${lines.length})`, () => this.why.show(node, `Edge changes: ${name}`, lines)));\n return items;\n }\n\n protected override captureBinding(_svg: SVGSVGElement | null): () => void {\n const previous = this.highlighter;\n return (): void => {\n this.highlighter = previous;\n this.filterCards();\n this.syncControls();\n };\n }\n\n protected override wireControls(): void {\n this.syncModel();\n this.drawer.wire();\n this.syncControls();\n }\n\n /** '' when this page can show Goal vs Current, else why not. */\n private goalUnavailable(): string {\n if (this.model.viewer !== 'runtime') return 'Goal vs Current compares runtime architecture only.';\n const comparison = this.model.comparison;\n if (comparison === undefined || comparison === null)\n return 'This page carries no Goal vs Current data. Re-open it with pnpm nx run architecture:visualize-runtime.';\n return comparison.available ? '' : comparison.reason;\n }\n\n /** Goal vs Current draws its overlay topology; every other mode draws the page's own graph. */\n private syncModel(): void {\n const overlay = this.base.comparison?.model ?? null;\n let next = this.modes.mode === 'goal' && overlay !== null ? overlay : this.base;\n if (this.modes.mode === 'impact' && this.edges.any()) next = this.edges.model(this.base);\n if (next === this.model) return;\n this.useModel(next);\n this.projects = new WpProjectFilter(next, this.modes);\n }\n\n protected override nodeDot(node: RenderNodeJson): string {\n const modes = node.modes;\n if (modes === null) return node.dot;\n if (this.modes.mode === 'architecture') return modes.architecture;\n if (this.modes.mode === 'impact') return modes[this.modes.status(node.id)];\n if (this.modes.mode === 'product') return modes.product;\n return modes.runtime;\n }\n\n /** Product mode dashes a dependency that crosses into another product (#1204); every other mode draws it plain. */\n protected override edgeDot(edge: RenderEdgeJson): string {\n if (this.modes.mode === 'product' && edge.productDot !== null) return edge.productDot;\n if (this.modes.mode === 'impact') return this.edges.edgeDot(edge) ?? edge.dot;\n return edge.dot;\n }\n\n protected override usesFullDot(): boolean {\n return (this.modes.mode === 'runtime' || this.modes.mode === 'goal') && this.applied.count() === 0;\n }\n\n protected override narrow(retained: Set<string>): Set<string> {\n return this.projects.apply(retained, this.applied);\n }\n\n /** Filtering keeps every box in its own L-row: an emptied level stays as a thin labeled band. */\n protected override keepsEmptyLevels(): boolean {\n return true;\n }\n\n protected override prepareSvg(svg: SVGSVGElement): void { window.__WP_RUNTIME__?.prepare(svg); }\n\n protected wireSvg(svg: SVGSVGElement): void {\n this.highlighter = new GraphHighlighter(svg, this.chain, this.model, this);\n this.highlighter.wire();\n if (this.modes.mode === 'impact') this.edges.decorate(svg, this.why);\n this.filterCards();\n this.syncControls();\n svg.querySelectorAll<SVGGElement>('g.node').forEach((node: SVGGElement) => {\n if (node.querySelector('title')?.textContent === this.anchor)\n node.classList.add('wp-filter-anchor');\n });\n }\n\n lockSelection(): string | null {\n return this.locked;\n }\n\n hasNode(id: string): boolean {\n return this.model.nodes.some((node: RenderNodeJson): boolean => node.id === id);\n }\n\n noun(): string { return this.model.viewer === 'runtime' ? 'service' : 'project'; }\n\n projectCount(): number { return this.model.nodes.filter(node => this.projects.isService(node)).length; }\n\n focusSelection(): string | null { return this.selected; }\n\n toggleLock(): void {\n if (this.locked !== null) this.setLock(null);\n else if (this.selected !== null) this.setLock(this.selected);\n }\n\n /** An exact id, else the one id whose short name (after any scope) is `text`; null if none or several. */\n resolveName(text: string): string | null {\n if (text === '') return null;\n if (this.hasNode(text)) return text;\n const matches = this.model.nodes.filter(\n (node: RenderNodeJson): boolean => node.id.split('/').pop() === text,\n );\n return matches.length === 1 ? matches[0].id : null;\n }\n\n setLock(name: string | null): void {\n this.locked = name;\n if (name !== null) this.selected = name;\n this.highlighter?.relight();\n this.filterCards();\n this.syncControls();\n }\n\n clearSelection(): void { this.selected = null; this.setLock(null); }\n\n setMode(mode: string): void {\n if (mode === this.modes.mode || !this.modes.set(mode)) return;\n this.syncModel();\n this.syncControls();\n this.redraw();\n }\n\n /** Switch the active Impact scan: Impact recolours and an active change-scope filter re-applies. */\n setImpactKind(kind: string): void {\n if (kind === this.modes.kind || !this.modes.setKind(kind)) return;\n this.syncControls();\n this.redraw();\n }\n\n /** The drawer's \"Hide unconnected\": filter to the locked box's chain, or turn the filter off. */\n toggleFilter(): void {\n if (this.anchor !== null) this.filter(null);\n else if (this.locked !== null) this.filter(this.locked);\n }\n\n appliedFilter(): WpFilterChoice {\n return this.applied;\n }\n\n /** '' when the change-scope group can be used, else Impact's reason (the group is disabled). */\n scopeReason(): string {\n return this.modes.impactReason();\n }\n\n scopeCount(scope: string): number {\n if (this.model.viewer !== 'runtime') return this.projects.scopeCount(scope);\n const choice = new WpFilterChoice(); choice.scope = scope;\n return this.preview(choice);\n }\n\n /** How many boxes `choice` would show, with the current Hide-unconnected chain. */\n preview(choice: WpFilterChoice): number {\n const base =\n this.anchor === null\n ? new Set(this.model.nodes.map((node: RenderNodeJson): string => node.id))\n : this.chain.nodes(this.anchor);\n const kept = this.projects.apply(base, choice);\n return this.model.nodes.filter(node => kept.has(node.id) && this.projects.isService(node)).length;\n }\n\n applyFilter(choice: WpFilterChoice): void {\n if (this.scopeReason() !== '') choice.scope = 'everything';\n this.applied = choice;\n this.syncControls();\n this.redraw();\n }\n\n /** A top-bar pill's ✕. */\n removeFilter(group: string, value: string): void {\n const next = this.applied.copy();\n if (group === 'scope') next.scope = 'everything';\n else next.group(group).delete(value);\n this.applyFilter(next);\n }\n\n private syncControls(): void {\n document.body.dataset['wpMode'] = this.modes.mode;\n this.drawer.sync(this.modes, this.locked, this.anchor !== null, this.applied);\n const count = this.model.nodes.filter(node => this.retained.has(node.id) && this.projects.isService(node)).length;\n const empty = document.getElementById('wp-empty');\n if (empty !== null) empty.hidden = count !== 0;\n const context = document.getElementById('wp-context-count');\n if (context !== null) context.textContent = `${count} services · ${this.retained.size - count} contextual nodes`;\n this.syncLegend();\n }\n\n private syncLegend(): void {\n document.querySelectorAll<HTMLElement>('[data-wp-legend-value]').forEach(row => {\n const group = row.dataset['wpLegendGroup'];\n const value = row.dataset['wpLegendValue'] ?? '';\n row.hidden = !this.model.nodes.some(node => this.retained.has(node.id) &&\n (group === 'runtime' ? (value === 'unknown' ? node.tags !== null && node.tags.frameworks.length === 0 : node.tags?.frameworks.includes(value)) : group === 'role' ? node.tags?.role === value : node.products.includes(value)));\n });\n }\n\n private filterCards(): void {\n const lit = this.locked === null ? this.retained : this.chain.nodes(this.locked);\n document.querySelectorAll('.wp-resp-card').forEach((card: Element) => {\n const name = card.getAttribute('data-node');\n card.classList.toggle(\n 'wp-hidden',\n name === null || !this.retained.has(name) || !lit.has(name),\n );\n });\n }\n}\n\nnew GraphPage(__RENDER_MODEL__).render();\n"]}
1
+ {"version":3,"file":"graph-visualizer.client.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-visualizer.client.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * One state of the Filter popover: a change scope plus the selected Runtime, Role and Product chips.\n * The page holds the APPLIED one; the popover edits a copy until \"Show N projects\".\n */\nclass WpFilterChoice {\n scope = 'everything';\n readonly runtimes = new Set<string>();\n readonly roles = new Set<string>();\n readonly products = new Set<string>();\n\n copy(): WpFilterChoice {\n const copy = new WpFilterChoice();\n copy.scope = this.scope;\n for (const runtime of this.runtimes) copy.runtimes.add(runtime);\n for (const role of this.roles) copy.roles.add(role);\n for (const product of this.products) copy.products.add(product);\n return copy;\n }\n\n /** How many filters are active: the drawer button's badge. */\n count(): number {\n return (this.scope === 'everything' ? 0 : 1) + this.runtimes.size + this.roles.size + this.products.size;\n }\n\n /** The chip set a `data-wp-chip-group` (or a pill's group) names. */\n group(name: string): Set<string> {\n if (name === 'role') return this.roles;\n if (name === 'product') return this.products;\n return this.runtimes;\n }\n}\n\n/**\n * The Filter popover's four groups, INTERSECTED: a box stays when it is in the change scope, AND has\n * any selected runtime chip (when one is selected), AND has any selected role chip (likewise), AND\n * belongs to any selected product (likewise — several products are the UNION of their closures).\n */\nclass WpProjectFilter {\n constructor(\n private readonly model: RenderModelJson,\n private readonly modes: WpModeState,\n ) {}\n\n /** The node ids a change scope keeps; null for \"everything\" (and whenever Impact is unavailable). */\n scopeSet(scope: string): Set<string> | null {\n const impact = this.modes.impact;\n if (scope === 'everything' || impact === null || this.modes.impactReason() !== '') return null;\n if (scope === 'edges') return this.modes.edgeEnds();\n const ids: string[] = [...impact.touched];\n if (scope === 'dependents' || scope === 'build') ids.push(...this.modes.affected());\n if (scope === 'dependencies') ids.push(...impact.dependencies);\n if (scope === 'build') ids.push(...impact.buildInputs);\n return new Set(ids);\n }\n\n /** How many drawn projects a scope keeps on its own: the count beside each option. */\n scopeCount(scope: string): number {\n const set = this.scopeSet(scope);\n return this.model.nodes.filter((node: RenderNodeJson): boolean => this.isService(node) && (set === null || set.has(node.id))).length;\n }\n\n /** `base` (everything, or the Hide-unconnected chain) narrowed by `choice`. */\n apply(base: Set<string>, choice: WpFilterChoice): Set<string> {\n const scope = this.scopeSet(choice.scope);\n const kept = new Set<string>();\n for (const node of this.model.nodes) {\n if (!base.has(node.id) || !this.isService(node)) continue;\n if (scope !== null && !scope.has(node.id)) continue;\n if (!this.anyOf(choice.runtimes, node.tags?.frameworks ?? [])) continue;\n if (!this.anyOf(choice.roles, node.tags === null ? [] : [node.tags.role])) continue;\n if (!this.anyOf(choice.products, node.products)) continue;\n kept.add(node.id);\n }\n if (this.model.viewer === 'runtime') {\n for (const node of this.model.nodes) {\n if (node.tags !== null || !base.has(node.id)) continue;\n if (this.model.edges.some(edge => (edge.from === node.id && kept.has(edge.to)) || (edge.to === node.id && kept.has(edge.from)))) kept.add(node.id);\n }\n }\n return kept;\n }\n\n isService(node: RenderNodeJson): boolean { return this.model.viewer !== 'runtime' || node.tags !== null; }\n\n /** An empty chip group matches every box; otherwise the box must carry one of the chips. */\n private anyOf(selected: Set<string>, carried: string[]): boolean {\n return selected.size === 0 || carried.some((value: string): boolean => selected.has(value));\n }\n}\n\n/** Architecture interactions bind to each new SVG; logical Lock/Filter state belongs to the page. */\nclass GraphHighlighter {\n private readonly nodeByName = new Map<string, SVGGElement>();\n private hovered: string | null = null;\n\n constructor(\n private readonly svg: SVGSVGElement,\n private readonly chain: WpGraphChain,\n private readonly model: RenderModelJson,\n private readonly page: GraphPage,\n ) {}\n\n wire(): void {\n this.svg.querySelectorAll<SVGGElement>('g.node').forEach((g: SVGGElement) => {\n if (g.classList.contains('wp-layout')) return;\n const name = g.querySelector('title')?.textContent;\n if (name !== null && name !== undefined) this.nodeByName.set(name, g);\n });\n this.wireHover();\n this.wireMenu();\n this.relight();\n }\n\n private clear(): void {\n this.svg.classList.remove('wp-dim');\n this.svg.querySelectorAll('.wp-focus, .wp-neighbor, .wp-hl, .wp-locked').forEach((el: Element) => {\n el.classList.remove('wp-focus', 'wp-neighbor', 'wp-hl', 'wp-locked');\n });\n }\n\n relight(): void {\n this.clear();\n const locked = this.page.lockSelection();\n if (locked !== null) this.nodeByName.get(locked)?.classList.add('wp-locked');\n // A filtered-out Lock is suspended, including its otherwise visible relatives.\n const anchors = [locked, this.hovered].filter(\n (name: string | null): name is string => name !== null && this.nodeByName.has(name),\n );\n if (anchors.length === 0) return;\n const lit = new Set<string>();\n for (const name of anchors) {\n this.nodeByName.get(name)?.classList.add('wp-focus');\n for (const id of this.chain.nodes(name)) {\n if (this.nodeByName.has(id)) lit.add(id);\n }\n }\n this.svg.classList.add('wp-dim');\n for (const id of lit) this.nodeByName.get(id)?.classList.add('wp-neighbor');\n for (const edge of this.model.edges) {\n if (lit.has(edge.from) && lit.has(edge.to)) {\n this.svg.querySelector(`[id=\"${edge.id}\"]`)?.classList.add('wp-hl');\n }\n }\n }\n\n private wireHover(): void {\n this.nodeByName.forEach((g: SVGGElement, name: string) => {\n g.addEventListener('mouseenter', () => {\n this.hovered = name;\n this.relight();\n });\n g.addEventListener('mouseleave', () => {\n this.hovered = null;\n this.relight();\n });\n });\n }\n\n private wireMenu(): void {\n const designs = new Map<string, string>();\n for (const link of __DESIGN_LINKS__) designs.set(link.nodeId, link.href);\n WpNodeMenu.wire(this.svg, (name: string, node: SVGGElement): WpNodeMenuItem[] => {\n const items: WpNodeMenuItem[] = [];\n const href = designs.get(name);\n if (href !== undefined)\n items.push(new WpNodeMenuItem('View Design', () => window.open(href, '_blank')));\n const locked = this.page.lockSelection() === name;\n items.push(\n new WpNodeMenuItem(locked ? 'Unlock' : 'Lock', () =>\n locked ? this.page.clearSelection() : this.page.setLock(name),\n ),\n );\n items.push(this.page.filterItem(name));\n items.unshift(...this.page.impactItems(name, node));\n const implemented = window.__WP_RUNTIME__?.implementsItem(name, node);\n if (implemented) items.push(implemented);\n const goal = window.__WP_GOAL__?.item(name, node);\n if (goal) items.push(goal);\n return items;\n });\n }\n}\n\n/**\n * The Filter popover: edits a COPY of the page's applied filter, shows what each choice would keep,\n * and hands the copy to the page on \"Show N projects\". Closing it any other way discards the edit.\n */\nclass GraphFilterPopover {\n private draft = new WpFilterChoice();\n\n constructor(private readonly page: GraphPage) {}\n\n wire(): void {\n this.byId('wp-filter-open')?.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n if (this.isOpen()) this.close();\n else this.open();\n });\n this.byId('wp-filter-close')?.addEventListener('click', () => this.close());\n this.byId('wp-filter-clear')?.addEventListener('click', () => {\n this.draft = new WpFilterChoice();\n this.paint();\n });\n this.byId('wp-filter-apply')?.addEventListener('click', () => {\n this.page.applyFilter(this.draft.copy());\n this.close();\n });\n document.querySelectorAll<HTMLInputElement>('input[name=\"wp-scope\"]').forEach((radio: HTMLInputElement) => {\n radio.addEventListener('change', () => {\n if (!radio.checked) return;\n this.draft.scope = radio.value;\n this.paint();\n });\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-chip[data-wp-chip]').forEach((chip: HTMLButtonElement) => {\n chip.addEventListener('click', () => {\n const set = this.draft.group(chip.dataset['wpChipGroup'] ?? '');\n const value = chip.dataset['wpChip'] ?? '';\n if (set.has(value)) set.delete(value);\n else set.add(value);\n this.paint();\n });\n });\n }\n\n isOpen(): boolean {\n return this.byId('wp-filter-pop')?.hidden === false;\n }\n\n /** The active Impact scan changed: an open popover's counts and labels follow it. */\n refresh(): void {\n if (this.isOpen()) this.paint();\n }\n\n open(): void {\n const pop = this.byId('wp-filter-pop');\n if (pop === null) return;\n this.draft = this.page.appliedFilter().copy();\n this.paint();\n pop.hidden = false;\n this.byId('wp-filter-open')?.setAttribute('aria-expanded', 'true');\n }\n\n close(): void {\n const pop = this.byId('wp-filter-pop');\n if (pop === null || pop.hidden) return;\n pop.hidden = true;\n this.byId('wp-filter-open')?.setAttribute('aria-expanded', 'false');\n }\n\n /** Repaint the controls from the draft: checked scope, pressed chips, counts and the footer. */\n private paint(): void {\n const reason = this.page.scopeReason();\n const group = this.byId('wp-scope-group') as HTMLFieldSetElement | null;\n if (group !== null) group.disabled = reason !== '';\n const reasonEl = this.byId('wp-scope-reason');\n if (reasonEl !== null) {\n reasonEl.textContent = reason;\n reasonEl.hidden = reason === '';\n }\n document.querySelectorAll<HTMLInputElement>('input[name=\"wp-scope\"]').forEach((radio: HTMLInputElement) => {\n radio.checked = radio.value === this.draft.scope;\n });\n document.querySelectorAll<HTMLElement>('[data-wp-scope-count]').forEach((count: HTMLElement) => {\n count.textContent = reason === '' ? String(this.page.scopeCount(count.dataset['wpScopeCount'] ?? '')) : '';\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-chip[data-wp-chip]').forEach((chip: HTMLButtonElement) => {\n const set = this.draft.group(chip.dataset['wpChipGroup'] ?? '');\n chip.setAttribute('aria-pressed', String(set.has(chip.dataset['wpChip'] ?? '')));\n });\n const apply = this.byId('wp-filter-apply');\n if (apply !== null) {\n const shown = this.page.preview(this.draft);\n apply.textContent = `Show ${shown} ${this.page.noun()}${shown === 1 ? '' : 's'}`;\n }\n }\n\n private byId(id: string): HTMLElement | null {\n return document.getElementById(id);\n }\n}\n\n/**\n * The drawer and its floating panels: every control outside the graph itself. Holds no graph state —\n * each control calls back into the page, and `sync()` repaints the controls from the page's state.\n */\nclass GraphDrawer {\n readonly popover: GraphFilterPopover;\n private readonly openers = new Map<string, HTMLElement>();\n\n constructor(private readonly page: GraphPage) {\n this.popover = new GraphFilterPopover(page);\n }\n\n wire(): void {\n this.wireModeMenu();\n this.popover.wire();\n this.wireImpactKinds();\n this.wireLock();\n this.byId('wp-lock-toggle')?.addEventListener('click', () => this.page.toggleLock());\n this.byId('wp-filter-toggle')?.addEventListener('click', () => this.page.toggleFilter());\n this.toggles('wp-collapse', 'wp-shell', true);\n this.toggles('wp-help-btn', 'wp-help', false);\n this.toggles('wp-help-close', 'wp-help', false);\n this.toggles('wp-legend-pop', 'wp-legend-popout', false);\n this.toggles('wp-legend-close', 'wp-legend-popout', false);\n this.toggles('wp-resp-open', 'wp-resp-panel', false);\n this.toggles('wp-resp-close', 'wp-resp-panel', false);\n this.toggles('wp-snapshot-open', 'wp-snapshot', false);\n window.addEventListener('keydown', (ev: KeyboardEvent) => this.onKey(ev), true);\n window.addEventListener('hashchange', () => this.page.setMode(location.hash.slice(1)));\n document.addEventListener('click', (ev: MouseEvent) => {\n const target = ev.target;\n if (target instanceof Node && this.byId('wp-mode-menu')?.parentElement?.contains(target)) return;\n this.closeModeMenu(false);\n this.dismissOutside(target);\n });\n }\n\n /** \"Color by\": the pill trigger opens the menu of four; picking one switches and closes it. */\n private wireModeMenu(): void {\n this.byId('wp-mode-trigger')?.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n const menu = this.byId('wp-mode-menu');\n if (menu === null) return;\n if (!menu.hidden) {\n this.closeModeMenu(false);\n return;\n }\n menu.hidden = false;\n this.byId('wp-mode-trigger')?.setAttribute('aria-expanded', 'true');\n menu.querySelector<HTMLButtonElement>('.wp-mode[aria-checked=\"true\"]')?.focus({ preventScroll: true });\n });\n document.querySelectorAll<HTMLButtonElement>('.wp-mode[data-wp-mode]').forEach((button: HTMLButtonElement) => {\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.closeModeMenu(true);\n this.page.setMode(button.dataset['wpMode'] ?? 'runtime');\n });\n });\n }\n\n /** The \"Changed on this branch\" / \"Last commit\" toggle, in the drawer and in the Filter popover. */\n private wireImpactKinds(): void {\n document.querySelectorAll<HTMLButtonElement>('[data-wp-impact-kind]').forEach((button: HTMLButtonElement) => {\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.page.setImpactKind(button.dataset['wpImpactKind'] ?? '');\n this.popover.refresh();\n });\n });\n }\n\n /** Shown only when two scans exist; the drawer's copy only while Impact colors the graph. */\n private syncImpactKinds(modes: WpModeState): void {\n document.querySelectorAll<HTMLElement>('[data-wp-impact-kinds]').forEach((group: HTMLElement) => {\n const inDrawer = group.dataset['wpImpactKinds'] === 'drawer';\n group.hidden = modes.scans.length < 2 || (inDrawer && modes.mode !== 'impact');\n });\n document.querySelectorAll<HTMLButtonElement>('[data-wp-impact-kind]').forEach((button: HTMLButtonElement) => {\n const kind = button.dataset['wpImpactKind'] ?? '';\n button.setAttribute('aria-pressed', String(kind === modes.kind));\n button.disabled = !modes.kindAvailable(kind);\n const scan = modes.scans.find((candidate: ImpactJson): boolean => candidate.kind === kind);\n button.title = scan === undefined ? '' : scan.available ? scan.label : scan.reason;\n });\n const legend = this.byId('wp-scope-legend');\n if (legend !== null) legend.textContent = modes.impact?.label ?? 'Changes on this branch';\n }\n\n private closeModeMenu(returnFocus: boolean): void {\n const menu = this.byId('wp-mode-menu');\n if (menu === null || menu.hidden) return;\n menu.hidden = true;\n const trigger = this.byId('wp-mode-trigger');\n trigger?.setAttribute('aria-expanded', 'false');\n if (returnFocus) trigger?.focus({ preventScroll: true });\n }\n\n /** Type-to-search lock: an exact project id (or a unique short name) locks, empty or Esc unlocks. */\n private wireLock(): void {\n const input = this.lockInput();\n if (input === null) return;\n input.addEventListener('input', () => {\n const value = input.value.trim();\n if (value === '') this.page.clearSelection();\n else if (this.page.hasNode(value)) this.page.setLock(value);\n });\n input.addEventListener('change', () => {\n const match = this.page.resolveName(input.value.trim());\n if (match !== null) this.page.setLock(match);\n else input.value = this.page.lockSelection() ?? '';\n });\n input.addEventListener('keydown', (ev: KeyboardEvent) => {\n if (ev.key !== 'Escape') return;\n ev.preventDefault();\n input.value = '';\n this.page.clearSelection();\n input.blur();\n });\n }\n\n /**\n * Page keys, in the CAPTURE phase so the open/closed state of the node menu is read before the\n * menu's own Escape handler closes it: Esc with a menu open only closes the menu. Esc closes an\n * open Color-by menu or Filter popover first, too.\n */\n private onKey(ev: KeyboardEvent): void {\n if (ev.altKey || ev.ctrlKey || ev.metaKey) return;\n if (ev.key === 'Escape' && this.byId('wp-mode-menu')?.hidden === false) {\n this.closeModeMenu(true);\n return;\n }\n if (ev.key === 'Escape' && this.popover.isOpen()) {\n this.popover.close();\n return;\n }\n if (ev.key === 'Escape' && this.dismissOverlay()) return;\n const target = ev.target;\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) return;\n const menuOpen = document.getElementById('wp-node-menu') !== null || document.querySelector('.wp-graph-details:not([hidden]), .wp-goal-details:not([hidden]), .wp-impact-why:not([hidden])') !== null;\n if (ev.key === '/') {\n this.byId('wp-shell')?.classList.remove('wp-collapsed');\n this.byId('wp-collapse')?.setAttribute('aria-expanded', 'true');\n ev.preventDefault();\n this.lockInput()?.focus();\n return;\n }\n const index = ['1', '2', '3', '4', '5'].indexOf(ev.key);\n if (index >= 0 && !menuOpen) {\n this.page.setMode(WpModeState.MODES[index]);\n return;\n }\n if (ev.key === 'Escape' && !menuOpen && this.page.lockSelection() !== null) this.page.setLock(null);\n }\n\n /** `button` shows/hides `target`; for the drawer itself it toggles the collapsed class instead. */\n private toggles(buttonId: string, targetId: string, collapse: boolean): void {\n const button = this.byId(buttonId);\n const target = this.byId(targetId);\n if (button === null || target === null) return;\n button.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n let expanded: boolean;\n if (collapse) {\n expanded = !target.classList.toggle('wp-collapsed');\n } else {\n target.hidden = !target.hidden;\n expanded = !target.hidden;\n if (expanded) this.openers.set(targetId, button);\n else this.openers.get(targetId)?.focus({ preventScroll: true });\n }\n document.querySelectorAll(`[aria-controls=\"${targetId}\"], #${buttonId}[aria-expanded]`).forEach(\n (el: Element) => el.setAttribute('aria-expanded', String(expanded)),\n );\n });\n }\n\n private dismissOverlay(): boolean {\n for (const id of ['wp-help', 'wp-legend-popout', 'wp-snapshot', 'wp-resp-panel']) {\n const panel = this.byId(id);\n if (!panel || panel.hidden) continue;\n panel.hidden = true;\n this.openers.get(id)?.focus({ preventScroll: true });\n this.openers.get(id)?.setAttribute('aria-expanded', 'false');\n return true;\n }\n return false;\n }\n\n private dismissOutside(target: EventTarget | null): void {\n if (!(target instanceof Node)) return;\n const filter = this.byId('wp-filter-pop');\n if (this.popover.isOpen() && !filter?.contains(target) && !this.byId('wp-filter-open')?.contains(target)) this.popover.close();\n for (const entry of this.openers) {\n const id = entry[0];\n const opener = entry[1];\n const panel = this.byId(id);\n if (panel && !panel.hidden && !panel.contains(target) && !opener.contains(target)) {\n panel.hidden = true;\n opener.setAttribute('aria-expanded', 'false');\n }\n }\n }\n\n /** Repaint every control from the page's state. */\n sync(modes: WpModeState, locked: string | null, filtering: boolean, filter: WpFilterChoice): void {\n const reason = modes.impactReason();\n document.querySelectorAll<HTMLButtonElement>('.wp-mode[data-wp-mode]').forEach((button: HTMLButtonElement) => {\n const mode = button.dataset['wpMode'] ?? '';\n button.setAttribute('aria-checked', String(mode === modes.mode));\n button.disabled = !modes.available(mode);\n if (mode === 'impact') button.title = reason === '' ? 'Key 3' : reason;\n if (mode === 'product') button.title = modes.productReason() === '' ? 'Key 4' : modes.productReason();\n if (mode === 'goal') {\n // Unavailable is said in the menu itself, never shown as \"no differences\" (#1239).\n button.title = modes.goalReason() === '' ? 'Key 5' : modes.goalReason();\n const sub = button.querySelector('.wp-mode-sub');\n if (sub !== null) sub.textContent = modes.goalReason() === '' ? modes.subtitle(mode) : `Unavailable: ${modes.goalReason()}`;\n }\n });\n this.text('wp-mode-current', modes.name(modes.mode));\n this.text('wp-mode-current-sub', modes.subtitle(modes.mode));\n const reasonEl = this.byId('wp-impact-reason');\n if (reasonEl !== null) {\n reasonEl.textContent = reason;\n reasonEl.hidden = reason === '';\n }\n document.querySelectorAll<HTMLElement>('[data-wp-legend-mode]').forEach((section: HTMLElement) => {\n section.hidden = section.dataset['wpLegendMode'] !== modes.mode;\n });\n document.querySelectorAll<HTMLElement>('[data-wp-impact-note]').forEach((note: HTMLElement) => {\n note.textContent = this.impactNote(modes);\n });\n // \"unexplained\" is a row only when the active scan has one.\n document.querySelectorAll<HTMLElement>('[data-wp-legend=\"unexplained\"]').forEach((row: HTMLElement) => {\n row.hidden = (modes.impact?.unexplained.length ?? 0) === 0;\n });\n this.syncImpactKinds(modes);\n const title = this.byId('wp-legend-pop-title');\n if (title !== null) title.textContent = `Legend · ${modes.name(modes.mode)}`;\n const input = this.lockInput();\n if (input !== null && document.activeElement !== input) input.value = this.page.focusSelection() ?? '';\n const lockToggle = this.byId('wp-lock-toggle') as HTMLButtonElement | null;\n if (lockToggle !== null) {\n lockToggle.setAttribute('aria-pressed', String(locked !== null));\n lockToggle.disabled = locked === null && this.page.focusSelection() === null;\n lockToggle.title = lockToggle.disabled ? 'Select a node in Focus first' : '';\n }\n this.syncFilterToggle(locked, filtering);\n this.syncFilter(filter);\n this.crumb(modes.name(modes.mode), locked);\n }\n\n private syncFilterToggle(locked: string | null, filtering: boolean): void {\n const toggle = this.byId('wp-filter-toggle') as HTMLButtonElement | null;\n if (toggle === null) return;\n toggle.setAttribute('aria-pressed', String(filtering));\n toggle.disabled = !filtering && locked === null;\n toggle.title = toggle.disabled ? 'Lock a project first' : '';\n }\n\n /** The drawer button's count badge, and one removable pill per active filter in the top bar. */\n private syncFilter(filter: WpFilterChoice): void {\n const badge = this.byId('wp-filter-badge');\n if (badge !== null) {\n badge.textContent = String(filter.count());\n badge.hidden = filter.count() === 0;\n }\n const pills = this.byId('wp-filter-pills');\n if (pills === null) return;\n const items: HTMLElement[] = [];\n if (filter.scope !== 'everything') items.push(this.pill(this.scopeLabel(filter.scope), 'scope', filter.scope));\n for (const runtime of filter.runtimes) items.push(this.pill(runtime, 'runtime', runtime));\n for (const role of filter.roles) items.push(this.pill(role, 'role', role));\n for (const product of filter.products) items.push(this.pill(`product: ${product}`, 'product', product));\n pills.replaceChildren(...items);\n }\n\n /** A change scope's name, read from the Filter popover's markup: the shell owns the ONE copy. */\n private scopeLabel(scope: string): string {\n return document.querySelector(`[data-wp-scope-label=\"${scope}\"]`)?.textContent ?? scope;\n }\n\n /** A pill, built with text nodes so no value is parsed as HTML. */\n private pill(label: string, group: string, value: string): HTMLElement {\n const pill = document.createElement('span');\n pill.className = 'wp-pill';\n pill.dataset['wpPill'] = `${group}:${value}`;\n pill.append(label);\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.textContent = '✕';\n remove.setAttribute('aria-label', `Remove filter ${label}`);\n remove.addEventListener('click', (ev: MouseEvent) => {\n ev.stopPropagation();\n this.page.removeFilter(group, value);\n });\n pill.append(remove);\n return pill;\n }\n\n private impactNote(modes: WpModeState): string {\n const impact = modes.impact;\n if (impact === null || !impact.available) return '';\n // An available scan with a note is an EMPTY one, e.g. \"Nothing changed on this branch yet\".\n if (impact.reason !== '') return `${impact.label}: ${impact.reason}.`;\n const stats = `${impact.label}: ${new WpImpactWhy().counts(impact)} — nx affected, ${impact.changedFiles} changed files.`;\n const cause = this.globalCause(impact, modes.affected().length);\n return [cause === '' ? '' : `${cause}.`, stats, modes.edgeNote()].filter((part: string): boolean => part !== '').join(' ');\n }\n\n /**\n * When files changed but no project owns one, everything nx affected is affected by a\n * workspace-global input (a lockfile, the workspace manifest). That is correct for CI, and\n * baffling on a graph, so the note names the cause.\n */\n private globalCause(impact: ImpactJson, affected: number): string {\n if (impact.touched.length > 0 || impact.changedFiles === 0) return '';\n const who = affected >= this.page.projectCount() ? 'Every project affected' : `${affected} projects affected`;\n const files = impact.globalFiles;\n if (files.length === 0)\n return `${who}: ${impact.changedFiles} changed files that no project owns (workspace-global input)`;\n const named = files.slice(0, 2).join(', ') + (files.length > 2 ? ` and ${files.length - 2} more` : '');\n return `${who}: ${named} changed (workspace-global input${files.length > 1 ? 's' : ''})`;\n }\n\n /** \"Mode: <b>Runtime</b> · Locked: <b>x</b>\", built with text nodes so no name is parsed as HTML. */\n private crumb(mode: string, locked: string | null): void {\n const crumb = this.byId('wp-crumb');\n if (crumb === null) return;\n const bold = (text: string): HTMLElement => {\n const b = document.createElement('b');\n b.textContent = text;\n return b;\n };\n const parts: (string | Node)[] = ['Mode: ', bold(mode)];\n if (locked !== null) parts.push(' · Locked: ', bold(locked));\n crumb.replaceChildren(...parts);\n }\n\n private text(id: string, value: string): void {\n const el = this.byId(id);\n if (el !== null) el.textContent = value;\n }\n\n private lockInput(): HTMLInputElement | null {\n return document.getElementById('wp-lock') as HTMLInputElement | null;\n }\n\n private byId(id: string): HTMLElement | null {\n return document.getElementById(id);\n }\n}\n\nclass GraphPage extends WpFilterPage {\n private highlighter: GraphHighlighter | null = null;\n private selected: string | null = null;\n /** The page's own graph; Goal vs Current swaps in its overlay and back (#1239). */\n private readonly base: RenderModelJson = this.model;\n private readonly modes = new WpModeState(\n this.model.nodes.some((node: RenderNodeJson): boolean => node.products.length > 0),\n this.model.viewer ?? 'architecture',\n this.goalUnavailable(),\n );\n private projects = new WpProjectFilter(this.model, this.modes);\n private applied = new WpFilterChoice();\n private readonly drawer = new GraphDrawer(this);\n private readonly why = new ImpactWhyPanel();\n\n private readonly edges = new WpEdgeOverlay(this.modes);\n /**\n * The products switched ON in the Product legend (#1319): the first two in legend order at EVERY\n * load. Never persisted — no storage, no hash — so the page stays stateless.\n */\n private readonly toggles = new WpProductToggles();\n private readonly productsOn: Set<string> = new WpProductSelection().initialOn(this.toggles.products());\n private painter: WpProductPainter = this.toggles.painter(this.base.legend.palette.colors, this.productsOn);\n\n /** In Impact mode a box's menu leads with WHY it is in the build, and its edge changes (#1264). */\n impactItems(name: string, node: SVGGElement): WpNodeMenuItem[] {\n if (this.modes.mode !== 'impact') return [];\n const items: WpNodeMenuItem[] = [];\n const reason = this.modes.reason(name);\n const title = reason === null ? '' : (WpImpactWhy.TITLES[reason.kind] ?? reason.kind).toLowerCase();\n if (reason !== null) items.push(new WpNodeMenuItem(`Why in this build? (${title})`, () => this.why.open(node, reason)));\n const lines = this.edges.nodeLines(name);\n if (lines.length > 0) items.push(new WpNodeMenuItem(`Edge changes (${lines.length})`, () => this.why.show(node, `Edge changes: ${name}`, lines)));\n return items;\n }\n\n protected override captureBinding(_svg: SVGSVGElement | null): () => void {\n const previous = this.highlighter;\n return (): void => {\n this.highlighter = previous;\n this.filterCards();\n this.syncControls();\n };\n }\n\n protected override wireControls(): void {\n this.syncModel();\n this.drawer.wire();\n this.toggles.wire((product: string, on: boolean): void => this.setProductOn(product, on));\n this.syncControls();\n }\n\n /** '' when this page can show Goal vs Current, else why not. */\n private goalUnavailable(): string {\n if (this.model.viewer !== 'runtime') return 'Goal vs Current compares runtime architecture only.';\n const comparison = this.model.comparison;\n if (comparison === undefined || comparison === null)\n return 'This page carries no Goal vs Current data. Re-open it with pnpm nx run architecture:visualize-runtime.';\n return comparison.available ? '' : comparison.reason;\n }\n\n /** Goal vs Current draws its overlay topology; every other mode draws the page's own graph. */\n private syncModel(): void {\n const overlay = this.base.comparison?.model ?? null;\n let next = this.modes.mode === 'goal' && overlay !== null ? overlay : this.base;\n if (this.modes.mode === 'impact' && this.edges.any()) next = this.edges.model(this.base);\n if (next === this.model) return;\n this.useModel(next);\n this.projects = new WpProjectFilter(next, this.modes);\n }\n\n protected override nodeDot(node: RenderNodeJson): string {\n const modes = node.modes;\n if (modes === null) return node.dot;\n if (this.modes.mode === 'architecture') return modes.architecture;\n if (this.modes.mode === 'impact') return modes[this.modes.status(node.id)];\n if (this.modes.mode === 'product') return this.painter.nodeDot(modes.product, node.products);\n return modes.runtime;\n }\n\n /**\n * Product mode dashes a dependency that crosses into another product (#1204) while that product is\n * ON (#1319); every other mode draws it plain.\n */\n protected override edgeDot(edge: RenderEdgeJson): string {\n if (this.modes.mode === 'product') return this.painter.edgeDot(edge);\n if (this.modes.mode === 'impact') return this.edges.edgeDot(edge) ?? edge.dot;\n return edge.dot;\n }\n\n protected override usesFullDot(): boolean {\n return (this.modes.mode === 'runtime' || this.modes.mode === 'goal') && this.applied.count() === 0;\n }\n\n protected override narrow(retained: Set<string>): Set<string> {\n return this.projects.apply(retained, this.applied);\n }\n\n /** Filtering keeps every box in its own L-row: an emptied level stays as a thin labeled band. */\n protected override keepsEmptyLevels(): boolean {\n return true;\n }\n\n protected override prepareSvg(svg: SVGSVGElement): void { window.__WP_RUNTIME__?.prepare(svg); }\n\n protected wireSvg(svg: SVGSVGElement): void {\n this.highlighter = new GraphHighlighter(svg, this.chain, this.model, this);\n this.highlighter.wire();\n if (this.modes.mode === 'impact') this.edges.decorate(svg, this.why);\n this.filterCards();\n this.syncControls();\n svg.querySelectorAll<SVGGElement>('g.node').forEach((node: SVGGElement) => {\n if (node.querySelector('title')?.textContent === this.anchor)\n node.classList.add('wp-filter-anchor');\n });\n }\n\n lockSelection(): string | null {\n return this.locked;\n }\n\n hasNode(id: string): boolean {\n return this.model.nodes.some((node: RenderNodeJson): boolean => node.id === id);\n }\n\n noun(): string { return this.model.viewer === 'runtime' ? 'service' : 'project'; }\n\n projectCount(): number { return this.model.nodes.filter(node => this.projects.isService(node)).length; }\n\n focusSelection(): string | null { return this.selected; }\n\n toggleLock(): void {\n if (this.locked !== null) this.setLock(null);\n else if (this.selected !== null) this.setLock(this.selected);\n }\n\n /** An exact id, else the one id whose short name (after any scope) is `text`; null if none or several. */\n resolveName(text: string): string | null {\n if (text === '') return null;\n if (this.hasNode(text)) return text;\n const matches = this.model.nodes.filter(\n (node: RenderNodeJson): boolean => node.id.split('/').pop() === text,\n );\n return matches.length === 1 ? matches[0].id : null;\n }\n\n setLock(name: string | null): void {\n this.locked = name;\n if (name !== null) this.selected = name;\n this.highlighter?.relight();\n this.filterCards();\n this.syncControls();\n }\n\n clearSelection(): void { this.selected = null; this.setLock(null); }\n\n setMode(mode: string): void {\n if (mode === this.modes.mode || !this.modes.set(mode)) return;\n this.syncModel();\n this.syncControls();\n this.redraw();\n }\n\n /** A product legend toggle (#1319): repaint at once from the new ON set. */\n setProductOn(product: string, on: boolean): void {\n if (on) this.productsOn.add(product);\n else this.productsOn.delete(product);\n this.painter = this.toggles.painter(this.base.legend.palette.colors, this.productsOn);\n this.syncControls();\n if (this.modes.mode === 'product') this.redraw();\n }\n\n /** Switch the active Impact scan: Impact recolours and an active change-scope filter re-applies. */\n setImpactKind(kind: string): void {\n if (kind === this.modes.kind || !this.modes.setKind(kind)) return;\n this.syncControls();\n this.redraw();\n }\n\n /** The drawer's \"Hide unconnected\": filter to the locked box's chain, or turn the filter off. */\n toggleFilter(): void {\n if (this.anchor !== null) this.filter(null);\n else if (this.locked !== null) this.filter(this.locked);\n }\n\n appliedFilter(): WpFilterChoice {\n return this.applied;\n }\n\n /** '' when the change-scope group can be used, else Impact's reason (the group is disabled). */\n scopeReason(): string {\n return this.modes.impactReason();\n }\n\n scopeCount(scope: string): number {\n if (this.model.viewer !== 'runtime') return this.projects.scopeCount(scope);\n const choice = new WpFilterChoice(); choice.scope = scope;\n return this.preview(choice);\n }\n\n /** How many boxes `choice` would show, with the current Hide-unconnected chain. */\n preview(choice: WpFilterChoice): number {\n const base =\n this.anchor === null\n ? new Set(this.model.nodes.map((node: RenderNodeJson): string => node.id))\n : this.chain.nodes(this.anchor);\n const kept = this.projects.apply(base, choice);\n return this.model.nodes.filter(node => kept.has(node.id) && this.projects.isService(node)).length;\n }\n\n applyFilter(choice: WpFilterChoice): void {\n if (this.scopeReason() !== '') choice.scope = 'everything';\n this.applied = choice;\n this.syncControls();\n this.redraw();\n }\n\n /** A top-bar pill's ✕. */\n removeFilter(group: string, value: string): void {\n const next = this.applied.copy();\n if (group === 'scope') next.scope = 'everything';\n else next.group(group).delete(value);\n this.applyFilter(next);\n }\n\n private syncControls(): void {\n document.body.dataset['wpMode'] = this.modes.mode;\n this.drawer.sync(this.modes, this.locked, this.anchor !== null, this.applied);\n this.toggles.sync(this.productsOn);\n const count = this.model.nodes.filter(node => this.retained.has(node.id) && this.projects.isService(node)).length;\n const empty = document.getElementById('wp-empty');\n if (empty !== null) empty.hidden = count !== 0;\n const context = document.getElementById('wp-context-count');\n if (context !== null) context.textContent = `${count} services · ${this.retained.size - count} contextual nodes`;\n this.syncLegend();\n }\n\n private syncLegend(): void {\n document.querySelectorAll<HTMLElement>('[data-wp-legend-value]').forEach(row => {\n const group = row.dataset['wpLegendGroup'];\n const value = row.dataset['wpLegendValue'] ?? '';\n row.hidden = !this.model.nodes.some(node => this.retained.has(node.id) &&\n (group === 'runtime' ? (value === 'unknown' ? node.tags !== null && node.tags.frameworks.length === 0 : node.tags?.frameworks.includes(value)) : group === 'role' ? node.tags?.role === value : node.products.includes(value)));\n });\n }\n\n private filterCards(): void {\n const lit = this.locked === null ? this.retained : this.chain.nodes(this.locked);\n document.querySelectorAll('.wp-resp-card').forEach((card: Element) => {\n const name = card.getAttribute('data-node');\n card.classList.toggle(\n 'wp-hidden',\n name === null || !this.retained.has(name) || !lit.has(name),\n );\n });\n }\n}\n\nnew GraphPage(__RENDER_MODEL__).render();\n"]}
@@ -125,10 +125,10 @@ export declare class GraphVisualizer {
125
125
  private dotNodes;
126
126
  private dotEdges;
127
127
  /**
128
- * The Product color mode's extra attributes for one dependency: dashed, thicker and in the color
129
- * of the product it crosses into, or '' for an edge that stays inside its source's products.
128
+ * The products one dependency crosses into, counted for the legend; empty for an edge that stays
129
+ * inside its source's products. The page dashes it in the first ON one's color (#1319).
130
130
  */
131
- private crossProductAttrs;
131
+ private crossesInto;
132
132
  /**
133
133
  * Generate the interactive page: the drawer shell around a viz.js-rendered graph.
134
134
  *