@webpieces/nx-webpieces-rules 0.4.919 โ 0.4.921
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.
- package/package.json +7 -7
- package/src/executors/generate/executor.d.ts +7 -0
- package/src/executors/generate/executor.js +13 -5
- package/src/executors/generate/executor.js.map +1 -1
- package/src/executors/validate-architecture-unchanged/executor.d.ts +1 -20
- package/src/executors/validate-architecture-unchanged/executor.js +2 -45
- package/src/executors/validate-architecture-unchanged/executor.js.map +1 -1
- package/src/executors/visualize/executor.d.ts +8 -1
- package/src/executors/visualize/executor.js +11 -3
- package/src/executors/visualize/executor.js.map +1 -1
- package/src/executors/visualize-runtime/executor.js +2 -1
- package/src/executors/visualize-runtime/executor.js.map +1 -1
- package/src/executors/visualize-runtime-goal/executor.js +2 -1
- package/src/executors/visualize-runtime-goal/executor.js.map +1 -1
- package/src/lib/current-architecture.d.ts +26 -0
- package/src/lib/current-architecture.js +56 -0
- package/src/lib/current-architecture.js.map +1 -0
- package/src/lib/graph-color-modes.d.ts +29 -11
- package/src/lib/graph-color-modes.js +40 -14
- package/src/lib/graph-color-modes.js.map +1 -1
- package/src/lib/graph-edge-diff.d.ts +115 -0
- package/src/lib/graph-edge-diff.js +263 -0
- package/src/lib/graph-edge-diff.js.map +1 -0
- package/src/lib/graph-impact-reasons.d.ts +160 -0
- package/src/lib/graph-impact-reasons.js +412 -0
- package/src/lib/graph-impact-reasons.js.map +1 -0
- package/src/lib/graph-impact.d.ts +100 -48
- package/src/lib/graph-impact.js +176 -105
- package/src/lib/graph-impact.js.map +1 -1
- package/src/lib/graph-legend.d.ts +9 -2
- package/src/lib/graph-legend.js +31 -4
- package/src/lib/graph-legend.js.map +1 -1
- package/src/lib/graph-mode-state.client.d.ts +96 -2
- package/src/lib/graph-mode-state.client.js +343 -3
- package/src/lib/graph-mode-state.client.js.map +1 -1
- package/src/lib/graph-navigation.js +4 -2
- package/src/lib/graph-navigation.js.map +1 -1
- package/src/lib/graph-page-shell.d.ts +5 -3
- package/src/lib/graph-page-shell.js +7 -4
- package/src/lib/graph-page-shell.js.map +1 -1
- package/src/lib/graph-visualizer.client.d.ts +4 -0
- package/src/lib/graph-visualizer.client.js +36 -9
- package/src/lib/graph-visualizer.client.js.map +1 -1
- package/src/lib/runtime-html-page.js +2 -2
- package/src/lib/runtime-html-page.js.map +1 -1
- package/src/lib/runtime-viewer-adapter.js +1 -1
- package/src/lib/runtime-viewer-adapter.js.map +1 -1
- package/src/native-actions.js +1 -1
- package/src/native-actions.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/visualize-runtime-goal/executor.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/nx-webpieces-rules/src/executors/visualize-runtime-goal/executor.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Visualize Runtime Goal Executor (#1239)\n *\n * Renders the hand-authored runtime PROPOSAL, architecture/runtime-dependencies-goal.json, with the\n * same shared runtime renderer as visualize-runtime, into its own files:\n * tmp/webpieces/runtime-architecture-goal.{dot,html}. It never generates anything from source first,\n * never writes either JSON input, and never overwrites the current page.\n *\n * The page carries Goal vs Current when the saved current graph is usable; otherwise that mode says\n * why. A missing goal fails with its expected path and how to start one โ the current graph is never\n * rendered in its place.\n *\n * `--prepare` is the one explicit, WRITING step: it recomputes the goal's derived levels, self-queue\n * flags, contract queues and maxLevel with the generator's own level machinery, saves the goal, and\n * then views it.\n *\n * Usage: nx run architecture:visualize-runtime-goal [--prepare]\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ExecutorContext } from '@nx/devkit';\nimport { RuleFailError, renderRuleFailForHuman } from '@webpieces/rules-config';\nimport { DEFAULT_GRAPH_PATH } from '../../lib/graph-loader';\nimport { ImpactRefresh, ImpactSidecar, VISUALIZE_IMPACT_KINDS } from '../../lib/graph-impact';\nimport { LiveGraphSource } from '../../lib/graph-edge-diff';\nimport { SavedSnapshot } from '../../lib/saved-snapshot';\nimport { writeRuntimeVisualization, RuntimeVizOptions, RuntimePageKind } from '../../lib/runtime-visualizer';\nimport { loadRuntimeConfig } from '../../lib/runtime-config';\nimport { GraphVisualizer } from '../../lib/graph-visualizer';\nimport { RuntimeComparisonInputs } from '../../lib/runtime-goal-view';\nimport { RuntimeGoalFile, RuntimeGoalProvenance, RUNTIME_GOAL_PREPARE_COMMAND } from '../../lib/runtime-goal-file';\nimport type { RuntimeGraph } from '../../lib/runtime-graph-model';\nimport { toError } from '../../toError';\n\nexport interface VisualizeRuntimeGoalOptions {\n /** Recompute and SAVE the goal's derived levels before viewing. Viewing alone never writes. */\n prepare?: boolean;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\n// webpieces-disable no-function-outside-class -- Nx executor entry point: Nx requires a default-exported function\nexport default async function runExecutor(\n options: VisualizeRuntimeGoalOptions,\n context: ExecutorContext,\n): Promise<ExecutorResult> {\n const workspaceRoot = context.root;\n const goalFile = new RuntimeGoalFile();\n const snapshot = new SavedSnapshot();\n\n console.log('\\n๐ฏ Runtime Goal Visualization\\n');\n console.log(new RuntimeGoalProvenance().message());\n\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions -- Nx command rendering boundary; success:false propagates failure to Nx\n try {\n const goal = options.prepare === true ? prepared(goalFile, workspaceRoot) : goalFile.load(workspaceRoot);\n reportDrift(goalFile, goal);\n const config = loadRuntimeConfig(workspaceRoot);\n const projects = fs.existsSync(path.join(workspaceRoot, DEFAULT_GRAPH_PATH)) ? snapshot.loadProjects(workspaceRoot, DEFAULT_GRAPH_PATH).projects : null;\n const vizOptions = new RuntimeVizOptions(config.showExternalNodes, projects, workspaceRoot, RuntimePageKind.GOAL);\n const inputs = new RuntimeComparisonInputs(snapshot, goalFile);\n const comparison = inputs.view(inputs.current(workspaceRoot), goal, vizOptions);\n console.log(comparison.available ? `Goal vs Current: ${comparison.summary}` : `Goal vs Current unavailable: ${comparison.reason}`);\n const vizPaths = writeRuntimeVisualization(goal, workspaceRoot, 'Goal / Proposed Runtime Architecture', vizOptions, comparison);\n console.log(`โ
Generated: ${vizPaths.dotPath}`);\n console.log(`โ
Generated: ${vizPaths.htmlPath}`);\n if (projects !== null) console.log(await new ImpactRefresh().run(path.dirname(vizPaths.htmlPath), workspaceRoot, projects, VISUALIZE_IMPACT_KINDS, new LiveGraphSource()));\n else { new ImpactSidecar().remove(path.dirname(vizPaths.htmlPath)); console.log('Impact and framework metadata unavailable: no saved project graph. Proposed services carry their goal facts only.'); }\n\n console.log('\\n๐ Opening visualization in browser...');\n if (new GraphVisualizer().openVisualization(vizPaths.htmlPath)) console.log('โ
Browser opened');\n else console.log(`โ ๏ธ Could not auto-open. Open manually: ${vizPaths.htmlPath}`);\n return { success: true };\n } catch (err: unknown) {\n const error = toError(err);\n const rendered = error instanceof RuleFailError ? renderRuleFailForHuman(error) : error.message;\n console.error(`โ Runtime goal visualization failed for ${goalFile.goalPath}:`, rendered);\n return { success: false };\n }\n}\n\n// webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor\nfunction prepared(goalFile: RuntimeGoalFile, workspaceRoot: string): RuntimeGraph {\n const preparation = goalFile.prepare(workspaceRoot);\n if (!preparation.written) console.log(`โ
${goalFile.goalPath} derived facts already consistent; nothing written.`);\n else if (preparation.changes.length === 0) console.log(`โ๏ธ Prepared ${goalFile.goalPath}: rewrote explanatory levelBecause text only.`);\n else console.log(`โ๏ธ Prepared ${goalFile.goalPath}:\\n ${preparation.changes.join('\\n ')}`);\n return preparation.graph;\n}\n\n// webpieces-disable no-function-outside-class -- executor step helper, sibling of runExecutor\nfunction reportDrift(goalFile: RuntimeGoalFile, goal: RuntimeGraph): void {\n const drift = goalFile.drift(goal);\n if (drift.cycle !== null) {\n console.warn(`โ ๏ธ ${drift.cycle}\\n Rendered with its saved levels. ${goalFile.cycleOption().text}`);\n return;\n }\n if (drift.differences.length === 0) return;\n console.warn(\n `โ ๏ธ ${goalFile.goalPath} saves derived facts that disagree with its relationships (rendered as saved):\\n ` +\n `${drift.differences.join('\\n ')}\\n Recompute them explicitly: ${RUNTIME_GOAL_PREPARE_COMMAND}`,\n );\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The architecture graph as the CURRENT source says it is, built live by the same pipeline
|
|
3
|
+
* `architecture:generate` runs โ never read back from the committed architecture/*.json. Shared by
|
|
4
|
+
* `validate-architecture-unchanged` (which diffs it against the committed file) and the Impact view's
|
|
5
|
+
* edge changes (#1264, which diff it against the fork point's committed file).
|
|
6
|
+
*/
|
|
7
|
+
import type { EnhancedGraph } from './graph-sorter';
|
|
8
|
+
import type { ExternalSystemDecls } from './api-usage/api-relations';
|
|
9
|
+
import type { ApiContractFileRefs } from './api-contract-files';
|
|
10
|
+
import type { RemoteServices } from './remote-services';
|
|
11
|
+
/**
|
|
12
|
+
* Build the current dependency graph exactly as the generator does: reduce the nx
|
|
13
|
+
* graph, sort into levels, enrich with metadata, and attach the derived
|
|
14
|
+
* apiRelations โ so this validator compares like-for-like against the committed file.
|
|
15
|
+
*/
|
|
16
|
+
export declare class CurrentGraphBuilder {
|
|
17
|
+
build(workspaceRoot: string, graphPath?: string): Promise<CurrentArchitecture>;
|
|
18
|
+
}
|
|
19
|
+
/** The regenerated graph plus the tables beside it โ everything dependencies.json holds. */
|
|
20
|
+
export declare class CurrentArchitecture {
|
|
21
|
+
readonly graph: EnhancedGraph;
|
|
22
|
+
readonly apiContractFiles: ApiContractFileRefs;
|
|
23
|
+
readonly externalSystems: ExternalSystemDecls;
|
|
24
|
+
readonly remoteServices: RemoteServices;
|
|
25
|
+
constructor(graph: EnhancedGraph, apiContractFiles: ApiContractFileRefs, externalSystems: ExternalSystemDecls, remoteServices: RemoteServices);
|
|
26
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The architecture graph as the CURRENT source says it is, built live by the same pipeline
|
|
4
|
+
* `architecture:generate` runs โ never read back from the committed architecture/*.json. Shared by
|
|
5
|
+
* `validate-architecture-unchanged` (which diffs it against the committed file) and the Impact view's
|
|
6
|
+
* edge changes (#1264, which diff it against the fork point's committed file).
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.CurrentArchitecture = exports.CurrentGraphBuilder = void 0;
|
|
10
|
+
const rules_config_1 = require("@webpieces/rules-config");
|
|
11
|
+
const graph_generator_1 = require("./graph-generator");
|
|
12
|
+
const graph_sorter_1 = require("./graph-sorter");
|
|
13
|
+
const graph_loader_1 = require("./graph-loader");
|
|
14
|
+
const graph_metadata_1 = require("./graph-metadata");
|
|
15
|
+
const tag_truth_1 = require("./tag-truth");
|
|
16
|
+
const approved_graph_1 = require("./runtime-wiring/approved-graph");
|
|
17
|
+
/**
|
|
18
|
+
* Build the current dependency graph exactly as the generator does: reduce the nx
|
|
19
|
+
* graph, sort into levels, enrich with metadata, and attach the derived
|
|
20
|
+
* apiRelations โ so this validator compares like-for-like against the committed file.
|
|
21
|
+
*/
|
|
22
|
+
class CurrentGraphBuilder {
|
|
23
|
+
async build(workspaceRoot, graphPath) {
|
|
24
|
+
console.log('๐ Generating current dependency graph...');
|
|
25
|
+
const reducedGraph = await (0, graph_generator_1.generateReducedGraph)();
|
|
26
|
+
console.log('๐ Computing topological layers...');
|
|
27
|
+
const currentGraph = (0, graph_sorter_1.sortGraphTopologically)(reducedGraph);
|
|
28
|
+
console.log('๐ท๏ธ Enriching graph with framework + responsibilities metadata...');
|
|
29
|
+
const projectInfos = await (0, graph_metadata_1.collectProjectInfo)();
|
|
30
|
+
(0, graph_metadata_1.enrichGraph)(currentGraph, projectInfos, workspaceRoot);
|
|
31
|
+
new tag_truth_1.TagTruthCheck().assertTrue(currentGraph, projectInfos, workspaceRoot);
|
|
32
|
+
new approved_graph_1.ApprovedWiringGraph().attach(workspaceRoot, currentGraph, projectInfos, graphPath);
|
|
33
|
+
const saved = (0, graph_loader_1.loadBlessedGraph)(workspaceRoot, graphPath);
|
|
34
|
+
if (saved === null)
|
|
35
|
+
throw new rules_config_1.RuleFailError('validate-runtime-architecture', 'Missing approved graph.', undefined, undefined, [
|
|
36
|
+
new rules_config_1.Option('Migrate src/wiring.ts and review runtime-deps.json and API contract approvals.', true),
|
|
37
|
+
]);
|
|
38
|
+
return new CurrentArchitecture(currentGraph, saved.apiContractFiles, saved.externalSystems, saved.remoteServices);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.CurrentGraphBuilder = CurrentGraphBuilder;
|
|
42
|
+
/** The regenerated graph plus the tables beside it โ everything dependencies.json holds. */
|
|
43
|
+
class CurrentArchitecture {
|
|
44
|
+
graph;
|
|
45
|
+
apiContractFiles;
|
|
46
|
+
externalSystems;
|
|
47
|
+
remoteServices;
|
|
48
|
+
constructor(graph, apiContractFiles, externalSystems, remoteServices) {
|
|
49
|
+
this.graph = graph;
|
|
50
|
+
this.apiContractFiles = apiContractFiles;
|
|
51
|
+
this.externalSystems = externalSystems;
|
|
52
|
+
this.remoteServices = remoteServices;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
exports.CurrentArchitecture = CurrentArchitecture;
|
|
56
|
+
//# sourceMappingURL=current-architecture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-architecture.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/current-architecture.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,0DAAgE;AAChE,uDAAyD;AACzD,iDAAwD;AAExD,iDAAkD;AAClD,qDAAmE;AACnE,2CAA4C;AAC5C,oEAAsE;AAKtE;;;;GAIG;AACH,MAAa,mBAAmB;IAC5B,KAAK,CAAC,KAAK,CAAC,aAAqB,EAAE,SAAkB;QACjD,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,MAAM,YAAY,GAAG,MAAM,IAAA,sCAAoB,GAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QAClD,MAAM,YAAY,GAAG,IAAA,qCAAsB,EAAC,YAAY,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC;QAClF,MAAM,YAAY,GAAG,MAAM,IAAA,mCAAkB,GAAE,CAAC;QAChD,IAAA,4BAAW,EAAC,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QACvD,IAAI,yBAAa,EAAE,CAAC,UAAU,CAAC,YAAY,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC;QAC1E,IAAI,oCAAmB,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;QACvF,MAAM,KAAK,GAAG,IAAA,+BAAgB,EAAC,aAAa,EAAE,SAAS,CAAC,CAAC;QACzD,IAAI,KAAK,KAAK,IAAI;YACd,MAAM,IAAI,4BAAa,CACnB,+BAA+B,EAC/B,yBAAyB,EACzB,SAAS,EACT,SAAS,EACT;gBACI,IAAI,qBAAM,CACN,gFAAgF,EAChF,IAAI,CACP;aACJ,CACJ,CAAC;QACN,OAAO,IAAI,mBAAmB,CAC1B,YAAY,EACZ,KAAK,CAAC,gBAAgB,EACtB,KAAK,CAAC,eAAe,EACrB,KAAK,CAAC,cAAc,CACvB,CAAC;IACN,CAAC;CACJ;AAhCD,kDAgCC;AAED,4FAA4F;AAC5F,MAAa,mBAAmB;IAER;IACA;IACA;IACA;IAJpB,YACoB,KAAoB,EACpB,gBAAqC,EACrC,eAAoC,EACpC,cAA8B;QAH9B,UAAK,GAAL,KAAK,CAAe;QACpB,qBAAgB,GAAhB,gBAAgB,CAAqB;QACrC,oBAAe,GAAf,eAAe,CAAqB;QACpC,mBAAc,GAAd,cAAc,CAAgB;IAC/C,CAAC;CACP;AAPD,kDAOC","sourcesContent":["/**\n * The architecture graph as the CURRENT source says it is, built live by the same pipeline\n * `architecture:generate` runs โ never read back from the committed architecture/*.json. Shared by\n * `validate-architecture-unchanged` (which diffs it against the committed file) and the Impact view's\n * edge changes (#1264, which diff it against the fork point's committed file).\n */\n\nimport { Option, RuleFailError } from '@webpieces/rules-config';\nimport { generateReducedGraph } from './graph-generator';\nimport { sortGraphTopologically } from './graph-sorter';\nimport type { EnhancedGraph } from './graph-sorter';\nimport { loadBlessedGraph } from './graph-loader';\nimport { collectProjectInfo, enrichGraph } from './graph-metadata';\nimport { TagTruthCheck } from './tag-truth';\nimport { ApprovedWiringGraph } from './runtime-wiring/approved-graph';\nimport type { ExternalSystemDecls } from './api-usage/api-relations';\nimport type { ApiContractFileRefs } from './api-contract-files';\nimport type { RemoteServices } from './remote-services';\n\n/**\n * Build the current dependency graph exactly as the generator does: reduce the nx\n * graph, sort into levels, enrich with metadata, and attach the derived\n * apiRelations โ so this validator compares like-for-like against the committed file.\n */\nexport class CurrentGraphBuilder {\n async build(workspaceRoot: string, graphPath?: string): Promise<CurrentArchitecture> {\n console.log('๐ Generating current dependency graph...');\n const reducedGraph = await generateReducedGraph();\n console.log('๐ Computing topological layers...');\n const currentGraph = sortGraphTopologically(reducedGraph);\n console.log('๐ท๏ธ Enriching graph with framework + responsibilities metadata...');\n const projectInfos = await collectProjectInfo();\n enrichGraph(currentGraph, projectInfos, workspaceRoot);\n new TagTruthCheck().assertTrue(currentGraph, projectInfos, workspaceRoot);\n new ApprovedWiringGraph().attach(workspaceRoot, currentGraph, projectInfos, graphPath);\n const saved = loadBlessedGraph(workspaceRoot, graphPath);\n if (saved === null)\n throw new RuleFailError(\n 'validate-runtime-architecture',\n 'Missing approved graph.',\n undefined,\n undefined,\n [\n new Option(\n 'Migrate src/wiring.ts and review runtime-deps.json and API contract approvals.',\n true,\n ),\n ],\n );\n return new CurrentArchitecture(\n currentGraph,\n saved.apiContractFiles,\n saved.externalSystems,\n saved.remoteServices,\n );\n }\n}\n\n/** The regenerated graph plus the tables beside it โ everything dependencies.json holds. */\nexport class CurrentArchitecture {\n constructor(\n public readonly graph: EnhancedGraph,\n public readonly apiContractFiles: ApiContractFileRefs,\n public readonly externalSystems: ExternalSystemDecls,\n public readonly remoteServices: RemoteServices,\n ) {}\n}\n"]}
|
|
@@ -14,14 +14,18 @@
|
|
|
14
14
|
* dependency rule becomes visual: a box may depend on a box carrying every color it has.
|
|
15
15
|
* - ARCHITECTURE "servers ยท clients ยท APIs". A solid fill by ROLE; framework color is not shown.
|
|
16
16
|
* - IMPACT "what changed" โ on this branch, or in the last commit (graph-impact.ts).
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* not
|
|
17
|
+
* The affected set is split by WHY nx included it (#1264, graph-impact-reasons.ts):
|
|
18
|
+
* owning a changed file is solid amber ("changed"); reached over dependency edges
|
|
19
|
+
* from one is light amber with an amber border ("dependent"); a `{workspaceRoot}`
|
|
20
|
+
* input glob match is violet hatching ("implicitly touched"); a lockfile /
|
|
21
|
+
* package.json / tsconfig.base.json / nx.json change is teal ("root-file touched");
|
|
22
|
+
* anything nothing could explain is light amber with a dashed grey border
|
|
23
|
+
* ("unexplained" โ never drawn as a dependent). Every transitive dependency of the
|
|
24
|
+
* affected set that is not itself affected is light slate with a dashed border
|
|
25
|
+
* ("build input": compiled or restored from cache, unchanged); everything else is
|
|
26
|
+
* grey. Which box is which is only known per checkout, so every box carries every
|
|
27
|
+
* variant and the page picks one from the sidecar (graph-impact.ts). The state is
|
|
28
|
+
* never written on the box: color + legend + the "why" panel a click opens.
|
|
25
29
|
* - PRODUCT "which products it belongs to" (#1179, graph-products.ts). One product is a solid
|
|
26
30
|
* fill in that product's palette color; two or more (but not all) are the same
|
|
27
31
|
* vertical stripes the multi-runtime box uses, one per product; a box shared by EVERY
|
|
@@ -103,7 +107,16 @@ export declare class RoleStyle {
|
|
|
103
107
|
export declare const ROLE_STYLES: readonly RoleStyle[];
|
|
104
108
|
/** The four impact shades (graph-impact.ts decides which box gets which). */
|
|
105
109
|
export declare const IMPACT_TOUCHED = "#f5a524";
|
|
106
|
-
export declare const
|
|
110
|
+
export declare const IMPACT_DEPENDENT = "#fde3b0";
|
|
111
|
+
/** Implicitly touched (#1264): violet HATCHING โ thin alternating stripes โ with a violet border. */
|
|
112
|
+
export declare const IMPACT_IMPLICIT = "#cdb8f4";
|
|
113
|
+
export declare const IMPACT_IMPLICIT_GAP = "#f5f0fd";
|
|
114
|
+
export declare const IMPACT_IMPLICIT_BORDER = "#7e57c2";
|
|
115
|
+
/** Root-file touched (#1264): teal, with a teal border. */
|
|
116
|
+
export declare const IMPACT_ROOT_FILE = "#bfe6e0";
|
|
117
|
+
export declare const IMPACT_ROOT_FILE_BORDER = "#1a8f86";
|
|
118
|
+
/** Unexplained (#1264): the dependent fill with a dashed grey border, so it never reads as a dependent. */
|
|
119
|
+
export declare const IMPACT_UNEXPLAINED_BORDER = "#8a8f9c";
|
|
107
120
|
export declare const IMPACT_BUILD_INPUT = "#e3e9f2";
|
|
108
121
|
export declare const IMPACT_BUILD_INPUT_BORDER = "#7c8aa3";
|
|
109
122
|
export declare const IMPACT_UNTOUCHED = "#eef0f4";
|
|
@@ -126,11 +139,14 @@ export declare class NodeModeDots {
|
|
|
126
139
|
readonly runtime: string;
|
|
127
140
|
readonly architecture: string;
|
|
128
141
|
readonly touched: string;
|
|
129
|
-
readonly
|
|
142
|
+
readonly dependent: string;
|
|
143
|
+
readonly implicit: string;
|
|
144
|
+
readonly rootFile: string;
|
|
145
|
+
readonly unexplained: string;
|
|
130
146
|
readonly buildInput: string;
|
|
131
147
|
readonly untouched: string;
|
|
132
148
|
readonly product: string;
|
|
133
|
-
constructor(runtime: string, architecture: string, touched: string,
|
|
149
|
+
constructor(runtime: string, architecture: string, touched: string, dependent: string, implicit: string, rootFile: string, unexplained: string, buildInput: string, untouched: string, product: string);
|
|
134
150
|
}
|
|
135
151
|
/** How many drawn boxes one product holds, and how many of them no other product does. */
|
|
136
152
|
export declare class ProductCount {
|
|
@@ -178,6 +194,8 @@ export declare class NodeModeStyler {
|
|
|
178
194
|
/** The specialization drawn inside `base`, if the set carries one. */
|
|
179
195
|
specialization(base: KnownFramework, frameworks: string[]): FrameworkStyle | undefined;
|
|
180
196
|
dots(facts: NodeFacts, palette: ProductPalette): NodeModeDots;
|
|
197
|
+
/** Implicitly touched: thin alternating violet stripes (a hatch), so it never reads as amber. */
|
|
198
|
+
private hatched;
|
|
181
199
|
/** Fold one drawn box into the legend facts. */
|
|
182
200
|
record(legend: LegendFacts, facts: NodeFacts, palette: ProductPalette): void;
|
|
183
201
|
/** The Product section's counts: per product (total, and only-this-product), shared-by-all, none. */
|
|
@@ -15,14 +15,18 @@
|
|
|
15
15
|
* dependency rule becomes visual: a box may depend on a box carrying every color it has.
|
|
16
16
|
* - ARCHITECTURE "servers ยท clients ยท APIs". A solid fill by ROLE; framework color is not shown.
|
|
17
17
|
* - IMPACT "what changed" โ on this branch, or in the last commit (graph-impact.ts).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* not
|
|
18
|
+
* The affected set is split by WHY nx included it (#1264, graph-impact-reasons.ts):
|
|
19
|
+
* owning a changed file is solid amber ("changed"); reached over dependency edges
|
|
20
|
+
* from one is light amber with an amber border ("dependent"); a `{workspaceRoot}`
|
|
21
|
+
* input glob match is violet hatching ("implicitly touched"); a lockfile /
|
|
22
|
+
* package.json / tsconfig.base.json / nx.json change is teal ("root-file touched");
|
|
23
|
+
* anything nothing could explain is light amber with a dashed grey border
|
|
24
|
+
* ("unexplained" โ never drawn as a dependent). Every transitive dependency of the
|
|
25
|
+
* affected set that is not itself affected is light slate with a dashed border
|
|
26
|
+
* ("build input": compiled or restored from cache, unchanged); everything else is
|
|
27
|
+
* grey. Which box is which is only known per checkout, so every box carries every
|
|
28
|
+
* variant and the page picks one from the sidecar (graph-impact.ts). The state is
|
|
29
|
+
* never written on the box: color + legend + the "why" panel a click opens.
|
|
26
30
|
* - PRODUCT "which products it belongs to" (#1179, graph-products.ts). One product is a solid
|
|
27
31
|
* fill in that product's palette color; two or more (but not all) are the same
|
|
28
32
|
* vertical stripes the multi-runtime box uses, one per product; a box shared by EVERY
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
* products' boxes; this mode keeps every box and makes ownership visible.
|
|
32
36
|
*/
|
|
33
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.NodeModeStyler = exports.LegendFacts = exports.ProductCount = exports.NodeModeDots = exports.NodeFacts = exports.IMPACT_UNTOUCHED = exports.IMPACT_BUILD_INPUT_BORDER = exports.IMPACT_BUILD_INPUT = exports.
|
|
38
|
+
exports.NodeModeStyler = exports.LegendFacts = exports.ProductCount = exports.NodeModeDots = exports.NodeFacts = exports.IMPACT_UNTOUCHED = exports.IMPACT_BUILD_INPUT_BORDER = exports.IMPACT_BUILD_INPUT = exports.IMPACT_UNEXPLAINED_BORDER = exports.IMPACT_ROOT_FILE_BORDER = exports.IMPACT_ROOT_FILE = exports.IMPACT_IMPLICIT_BORDER = exports.IMPACT_IMPLICIT_GAP = exports.IMPACT_IMPLICIT = exports.IMPACT_DEPENDENT = exports.IMPACT_TOUCHED = exports.ROLE_STYLES = exports.RoleStyle = exports.STRIPED_CLASS = exports.NO_RUNTIME_COLOR = exports.FRAMEWORK_ORDER = exports.BASE_ORDER = exports.FRAMEWORK_STYLES = exports.FrameworkStyle = exports.LIGHT_TEXT = exports.DARK_TEXT = exports.RUNTIME_GRAPH_MODES = exports.GRAPH_MODES = exports.ModeInfo = exports.GraphMode = void 0;
|
|
35
39
|
const rules_sdk_1 = require("@webpieces/rules-sdk");
|
|
36
40
|
const dot_syntax_1 = require("./dot-syntax");
|
|
37
41
|
const graph_products_1 = require("./graph-products");
|
|
@@ -162,7 +166,18 @@ exports.ROLE_STYLES = [
|
|
|
162
166
|
];
|
|
163
167
|
/** The four impact shades (graph-impact.ts decides which box gets which). */
|
|
164
168
|
exports.IMPACT_TOUCHED = '#f5a524';
|
|
165
|
-
exports.
|
|
169
|
+
exports.IMPACT_DEPENDENT = '#fde3b0';
|
|
170
|
+
/** Implicitly touched (#1264): violet HATCHING โ thin alternating stripes โ with a violet border. */
|
|
171
|
+
exports.IMPACT_IMPLICIT = '#cdb8f4';
|
|
172
|
+
exports.IMPACT_IMPLICIT_GAP = '#f5f0fd';
|
|
173
|
+
exports.IMPACT_IMPLICIT_BORDER = '#7e57c2';
|
|
174
|
+
/** Root-file touched (#1264): teal, with a teal border. */
|
|
175
|
+
exports.IMPACT_ROOT_FILE = '#bfe6e0';
|
|
176
|
+
exports.IMPACT_ROOT_FILE_BORDER = '#1a8f86';
|
|
177
|
+
/** Unexplained (#1264): the dependent fill with a dashed grey border, so it never reads as a dependent. */
|
|
178
|
+
exports.IMPACT_UNEXPLAINED_BORDER = '#8a8f9c';
|
|
179
|
+
/** How many hatch stripes an implicitly-touched box gets. */
|
|
180
|
+
const HATCH_STRIPES = 12;
|
|
166
181
|
exports.IMPACT_BUILD_INPUT = '#e3e9f2';
|
|
167
182
|
exports.IMPACT_BUILD_INPUT_BORDER = '#7c8aa3';
|
|
168
183
|
exports.IMPACT_UNTOUCHED = '#eef0f4';
|
|
@@ -194,15 +209,21 @@ class NodeModeDots {
|
|
|
194
209
|
runtime;
|
|
195
210
|
architecture;
|
|
196
211
|
touched;
|
|
197
|
-
|
|
212
|
+
dependent;
|
|
213
|
+
implicit;
|
|
214
|
+
rootFile;
|
|
215
|
+
unexplained;
|
|
198
216
|
buildInput;
|
|
199
217
|
untouched;
|
|
200
218
|
product;
|
|
201
|
-
constructor(runtime, architecture, touched,
|
|
219
|
+
constructor(runtime, architecture, touched, dependent, implicit, rootFile, unexplained, buildInput, untouched, product) {
|
|
202
220
|
this.runtime = runtime;
|
|
203
221
|
this.architecture = architecture;
|
|
204
222
|
this.touched = touched;
|
|
205
|
-
this.
|
|
223
|
+
this.dependent = dependent;
|
|
224
|
+
this.implicit = implicit;
|
|
225
|
+
this.rootFile = rootFile;
|
|
226
|
+
this.unexplained = unexplained;
|
|
206
227
|
this.buildInput = buildInput;
|
|
207
228
|
this.untouched = untouched;
|
|
208
229
|
this.product = product;
|
|
@@ -287,7 +308,12 @@ class NodeModeStyler {
|
|
|
287
308
|
return undefined;
|
|
288
309
|
}
|
|
289
310
|
dots(facts, palette) {
|
|
290
|
-
return new NodeModeDots(this.runtime(facts), this.plain(facts, this.roleStyle(facts.role).fill, this.roleStyle(facts.role).fontColor, ''), this.plain(facts, exports.IMPACT_TOUCHED, exports.DARK_TEXT, ''), this.plain(facts, exports.
|
|
311
|
+
return new NodeModeDots(this.runtime(facts), this.plain(facts, this.roleStyle(facts.role).fill, this.roleStyle(facts.role).fontColor, ''), this.plain(facts, exports.IMPACT_TOUCHED, exports.DARK_TEXT, ''), this.plain(facts, exports.IMPACT_DEPENDENT, exports.DARK_TEXT, `, color="${exports.IMPACT_TOUCHED}", penwidth=2`), this.hatched(facts), this.plain(facts, exports.IMPACT_ROOT_FILE, exports.DARK_TEXT, `, color="${exports.IMPACT_ROOT_FILE_BORDER}", penwidth=2`), this.plain(facts, exports.IMPACT_DEPENDENT, exports.DARK_TEXT, `, color="${exports.IMPACT_UNEXPLAINED_BORDER}", penwidth=1.5`, 'filled,dashed'), this.plain(facts, exports.IMPACT_BUILD_INPUT, exports.DARK_TEXT, `, color="${exports.IMPACT_BUILD_INPUT_BORDER}", penwidth=1.5`, 'filled,dashed'), this.plain(facts, exports.IMPACT_UNTOUCHED, IMPACT_UNTOUCHED_TEXT, ', color="#b4b9c4"'), this.product(facts, palette));
|
|
312
|
+
}
|
|
313
|
+
/** Implicitly touched: thin alternating violet stripes (a hatch), so it never reads as amber. */
|
|
314
|
+
hatched(facts) {
|
|
315
|
+
const colors = Array.from({ length: HATCH_STRIPES }, (_, index) => index % 2 === 0 ? exports.IMPACT_IMPLICIT : exports.IMPACT_IMPLICIT_GAP);
|
|
316
|
+
return this.statement(facts, `${this.stripes(colors)}, fontcolor="${exports.DARK_TEXT}", color="${exports.IMPACT_IMPLICIT_BORDER}", penwidth=2`, this.labelText(facts, exports.DARK_TEXT));
|
|
291
317
|
}
|
|
292
318
|
/** Fold one drawn box into the legend facts. */
|
|
293
319
|
record(legend, facts, palette) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-color-modes.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-color-modes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Graph color modes (#1155, restyled by #1158)\n *\n * The architecture graph answers ONE question at a time instead of asking every box to encode two\n * (fill = framework AND border = role). Each box is emitted once per mode, so the page can switch\n * modes and re-render without regenerating anything. Every mode writes the SAME three lines on a box\n * (level + name, role, every framework tag); only the color changes:\n *\n * - RUNTIME \"where the code can run\". One runtime is a solid fill. One runtime plus a\n * specialization (angular/react inside browser, express inside node) is NESTED: an\n * outer frame in the base color around an inner rounded box in the specialization's\n * color, carrying the text. Several runtimes are full-height vertical stripes in the\n * fixed order browser | node | react-native, with the text written across them. The\n * dependency rule becomes visual: a box may depend on a box carrying every color it has.\n * - ARCHITECTURE \"servers ยท clients ยท APIs\". A solid fill by ROLE; framework color is not shown.\n * - IMPACT \"what changed\" โ on this branch, or in the last commit (graph-impact.ts).\n * Projects owning a changed file are solid amber (\"touched\"); the rest of nx's affected set is light amber (\"affected\": their ci\n * re-runs); every transitive dependency of the affected set that is not itself\n * affected is light slate with a dashed border (\"build input\": compiled or restored\n * from cache, unchanged); everything else is grey. Which box is which is only known\n * per checkout, so every box carries all four variants and the page picks one from the\n * sidecar (graph-impact.ts). The state is never written on the box: color + legend.\n * The words are the Filter's: changed ยท dependent ยท dependency (built, unchanged) ยท\n * not in this build.\n * - PRODUCT \"which products it belongs to\" (#1179, graph-products.ts). One product is a solid\n * fill in that product's palette color; two or more (but not all) are the same\n * vertical stripes the multi-runtime box uses, one per product; a box shared by EVERY\n * product is one neutral fill (otherwise a shared foundation would be four-stripe\n * noise); a box in no product is white with a dashed border. The Filter HIDES other\n * products' boxes; this mode keeps every box and makes ownership visible.\n */\n\nimport { KNOWN_FRAMEWORKS, KnownFramework } from '@webpieces/rules-sdk';\nimport { dotValue, htmlLabelText } from './dot-syntax';\nimport { PRODUCT_NONE_BORDER, PRODUCT_NONE_FILL, PRODUCT_SHARED_FILL, ProductColor, ProductPalette } from './graph-products';\nimport type { ProductDependencyEntry } from '../configs/tag-truth-configs';\n\nexport enum GraphMode {\n RUNTIME = 'runtime',\n ARCHITECTURE = 'architecture',\n IMPACT = 'impact',\n PRODUCT = 'product',\n /** Runtime pages only (#1239): the saved goal compared with the saved current graph. */\n GOAL = 'goal',\n}\n\n/** One selectable mode as the drawer's Color-by pulldown shows it. */\nexport class ModeInfo {\n constructor(\n public readonly mode: GraphMode,\n public readonly name: string,\n public readonly subtitle: string,\n ) {}\n}\n\n/** In key order: `1` selects the first, `2` the second, `3` the third, `4` the fourth. */\nexport const GRAPH_MODES: readonly ModeInfo[] = [\n new ModeInfo(GraphMode.RUNTIME, 'Runtime', 'where the code can run'),\n new ModeInfo(GraphMode.ARCHITECTURE, 'Architecture', 'servers ยท clients ยท APIs'),\n new ModeInfo(GraphMode.IMPACT, 'Impact', 'what changed'),\n new ModeInfo(GraphMode.PRODUCT, 'Product', 'which products it belongs to'),\n];\n\n/**\n * The runtime page's Color-by menu: the four shared modes plus Goal vs Current (#1239), key `5`. The\n * build-dependency and DI viewers never list it.\n */\nexport const RUNTIME_GRAPH_MODES: readonly ModeInfo[] = [\n ...GRAPH_MODES,\n new ModeInfo(GraphMode.GOAL, 'Goal vs Current', 'Current โ Goal proposal'),\n];\n\n/** Text on a light fill. */\nexport const DARK_TEXT = '#1a1c22';\n/** Text on a dark fill. */\nexport const LIGHT_TEXT = '#ffffff';\n\n/**\n * A framework value's color, the text color that reads on it, and the BASE runtime it is drawn\n * inside (itself, for a base).\n */\nexport class FrameworkStyle {\n constructor(\n public readonly framework: KnownFramework,\n public readonly base: KnownFramework,\n public readonly color: string,\n public readonly fontColor: string,\n public readonly description: string,\n ) {}\n\n isBase(): boolean {\n return this.framework === this.base;\n }\n}\n\n/**\n * Keyed by the shared vocabulary, so a framework added to KNOWN_FRAMEWORKS without a color here is a\n * COMPILE error โ not a box silently painted grey and missing from the legend, which is exactly how\n * react-native shipped (#1155). Every base is mid-light, so dark text reads on every stripe.\n */\nexport const FRAMEWORK_STYLES: Record<KnownFramework, FrameworkStyle> = {\n browser: new FrameworkStyle('browser', 'browser', '#7d8cf2', DARK_TEXT, 'browser base runtime'),\n node: new FrameworkStyle('node', 'node', '#6fcf8a', DARK_TEXT, 'node base runtime'),\n 'react-native': new FrameworkStyle(\n 'react-native',\n 'react-native',\n '#34b8a6',\n DARK_TEXT,\n 'its own runtime, not a browser',\n ),\n angular: new FrameworkStyle('angular', 'browser', '#c8243f', LIGHT_TEXT, 'inside browser'),\n react: new FrameworkStyle('react', 'browser', '#7fd8ff', DARK_TEXT, 'inside browser'),\n express: new FrameworkStyle('express', 'node', '#2e7d4f', LIGHT_TEXT, 'inside node'),\n};\n\n/** Stripe order, left to right. Fixed, so the same set always reads the same way. */\nexport const BASE_ORDER: readonly KnownFramework[] = ['browser', 'node', 'react-native'];\n\n/**\n * The Filter popover's Runtime chips, and the order line 3 of a box lists framework tags in: the\n * bases first, then the specializations.\n */\nexport const FRAMEWORK_ORDER: readonly KnownFramework[] = [\n 'browser',\n 'node',\n 'react-native',\n 'angular',\n 'react',\n 'express',\n];\n\n/** A box with no known framework tag. */\nexport const NO_RUNTIME_COLOR = '#e4e6ec';\n\n/** The class Graphviz stamps on a multi-runtime box's `<g>`: its outline is its LAST shape. */\nexport const STRIPED_CLASS = 'wp-striped';\n\n/** Margin of base color around a specialization's inner box. */\nconst NEST_PAD = 5;\n/** Padding between the inner box's edge and its text. */\nconst INNER_PAD = 6;\n\n/** A role's solid fill and the text color that stays readable on it. */\nexport class RoleStyle {\n constructor(\n public readonly role: string,\n public readonly fill: string,\n public readonly fontColor: string,\n public readonly description: string,\n ) {}\n}\n\n/**\n * Every role role-resolver knows, in legend order (runnable things first) โ also the Filter popover's\n * Role chips. `bundle` is indigo so no box color equals the page's violet accent.\n */\nexport const ROLE_STYLES: readonly RoleStyle[] = [\n new RoleStyle('server', '#4caf50', LIGHT_TEXT, 'runnable server'),\n new RoleStyle('client', '#e5533d', LIGHT_TEXT, 'browser or mobile client app'),\n new RoleStyle('app', '#1e88e5', LIGHT_TEXT, 'runnable non-HTTP app'),\n new RoleStyle('bundle', '#4b44c8', LIGHT_TEXT, 'bundles several apps'),\n new RoleStyle('api-lib', '#f08a24', DARK_TEXT, 'contract + DTOs'),\n new RoleStyle('api-client', '#1a9aa6', LIGHT_TEXT, 'contract + SDK implementation'),\n new RoleStyle('designed-lib', '#7d8597', LIGHT_TEXT, 'library with a generated design'),\n new RoleStyle('lib', '#d7dae2', DARK_TEXT, 'plain library'),\n];\n\n/** The four impact shades (graph-impact.ts decides which box gets which). */\nexport const IMPACT_TOUCHED = '#f5a524';\nexport const IMPACT_AFFECTED = '#fde3b0';\nexport const IMPACT_BUILD_INPUT = '#e3e9f2';\nexport const IMPACT_BUILD_INPUT_BORDER = '#7c8aa3';\nexport const IMPACT_UNTOUCHED = '#eef0f4';\nconst IMPACT_UNTOUCHED_TEXT = '#6b7180';\n\n/** What a box's per-mode rendering โ and the page's Filter โ is computed from. */\nexport class NodeFacts {\n constructor(\n public readonly nodeId: string,\n public readonly shortName: string,\n public readonly level: number,\n public readonly role: string,\n public readonly frameworks: string[],\n /** The products the project belongs to (dependencies.json `products`), sorted; empty for none. */\n public readonly products: string[],\n public readonly summary: string = '',\n ) {}\n}\n\n/** One box's DOT statement for every mode (and for each impact state). */\nexport class NodeModeDots {\n constructor(\n public readonly runtime: string,\n public readonly architecture: string,\n public readonly touched: string,\n public readonly affected: string,\n public readonly buildInput: string,\n public readonly untouched: string,\n public readonly product: string,\n ) {}\n}\n\n/** How many drawn boxes one product holds, and how many of them no other product does. */\nexport class ProductCount {\n constructor(\n public readonly product: string,\n public total: number,\n public only: number,\n ) {}\n}\n\n/** Which colors and roles the drawn projects actually use, so the legend lists exactly those. */\nexport class LegendFacts {\n frameworks: string[] = [];\n roles: string[] = [];\n multiRuntime = false;\n noRuntime = false;\n /** One count per declared product, in palette (sorted-name) order; empty when none is declared. */\n products: ProductCount[] = [];\n /**\n * The ONE palette every box was painted with (#1244), built over the full declared product set.\n * The legend, the Filter's product chips and the crossing edges read their colors from it, never\n * from a palette of their own: collision resolution depends on the set, so a second palette built\n * from a subset could disagree with the boxes.\n */\n palette: ProductPalette = new ProductPalette([]);\n /** Boxes shared by every product (two or more declared). */\n sharedByAll = 0;\n /** Boxes in no product. */\n noProduct = 0;\n /** Some box belongs to two or more products, but not to every one: it is striped. */\n multiProduct = false;\n /** Dependency edges crossing into another product (#1204), drawn dashed in the Product mode. */\n crossProductEdges = 0;\n /**\n * The `product-tags` rule's matrix (#1204), listed in the Product legend; null when the rule is\n * OFF or the page was drawn without it.\n */\n productDependencies: ProductDependencyEntry[] | null = null;\n}\n\nexport class NodeModeStyler {\n styleOf(framework: string): FrameworkStyle | undefined {\n if (!(KNOWN_FRAMEWORKS as readonly string[]).includes(framework)) return undefined;\n return FRAMEWORK_STYLES[framework as KnownFramework];\n }\n\n roleStyle(role: string): RoleStyle {\n const style = ROLE_STYLES.find((candidate: RoleStyle): boolean => candidate.role === role);\n return style ?? (ROLE_STYLES.find((s: RoleStyle): boolean => s.role === 'lib') as RoleStyle);\n }\n\n /** Every role the renderer styles; a spec asserts this covers role-resolver's KNOWN_ROLES. */\n styledRoles(): string[] {\n return ROLE_STYLES.map((style: RoleStyle): string => style.role);\n }\n\n /** The base runtimes of a framework set, in stripe order (a specialization implies its base). */\n bases(frameworks: string[]): KnownFramework[] {\n const present = new Set<KnownFramework>();\n for (const framework of frameworks) {\n const style = this.styleOf(framework);\n if (style !== undefined) present.add(style.base);\n }\n return BASE_ORDER.filter((base: KnownFramework): boolean => present.has(base));\n }\n\n /** The specialization drawn inside `base`, if the set carries one. */\n specialization(base: KnownFramework, frameworks: string[]): FrameworkStyle | undefined {\n for (const framework of KNOWN_FRAMEWORKS) {\n const style = FRAMEWORK_STYLES[framework];\n if (style.isBase() || style.base !== base) continue;\n if (frameworks.includes(framework)) return style;\n }\n return undefined;\n }\n\n dots(facts: NodeFacts, palette: ProductPalette): NodeModeDots {\n return new NodeModeDots(\n this.runtime(facts),\n this.plain(facts, this.roleStyle(facts.role).fill, this.roleStyle(facts.role).fontColor, ''),\n this.plain(facts, IMPACT_TOUCHED, DARK_TEXT, ''),\n this.plain(facts, IMPACT_AFFECTED, DARK_TEXT, `, color=\"${IMPACT_TOUCHED}\", penwidth=2`),\n this.plain(\n facts,\n IMPACT_BUILD_INPUT,\n DARK_TEXT,\n `, color=\"${IMPACT_BUILD_INPUT_BORDER}\", penwidth=1.5`,\n 'filled,dashed',\n ),\n this.plain(facts, IMPACT_UNTOUCHED, IMPACT_UNTOUCHED_TEXT, ', color=\"#b4b9c4\"'),\n this.product(facts, palette),\n );\n }\n\n /** Fold one drawn box into the legend facts. */\n record(legend: LegendFacts, facts: NodeFacts, palette: ProductPalette): void {\n this.recordProducts(legend, facts, palette);\n for (const framework of facts.frameworks) {\n if (this.styleOf(framework) !== undefined && !legend.frameworks.includes(framework))\n legend.frameworks.push(framework);\n }\n const role = this.roleStyle(facts.role).role;\n if (!legend.roles.includes(role)) legend.roles.push(role);\n const bases = this.bases(facts.frameworks);\n if (bases.length > 1) legend.multiRuntime = true;\n if (bases.length === 0) legend.noRuntime = true;\n }\n\n /** The Product section's counts: per product (total, and only-this-product), shared-by-all, none. */\n private recordProducts(legend: LegendFacts, facts: NodeFacts, palette: ProductPalette): void {\n legend.palette = palette;\n if (legend.products.length === 0 && palette.colors.length > 0) {\n legend.products = palette.names().map((product: string): ProductCount => new ProductCount(product, 0, 0));\n }\n if (facts.products.length === 0) legend.noProduct++;\n if (palette.sharedByAll(facts.products)) legend.sharedByAll++;\n else if (facts.products.length > 1) legend.multiProduct = true;\n for (const count of legend.products) {\n if (!facts.products.includes(count.product)) continue;\n count.total++;\n if (facts.products.length === 1) count.only++;\n }\n }\n\n /**\n * Line 3 of every box: every framework tag, bases before specializations, any tag outside the\n * shared vocabulary last (it still runs somewhere somebody declared).\n */\n frameworkLine(frameworks: string[]): string {\n if (frameworks.length === 0) return 'no framework tag';\n const known = FRAMEWORK_ORDER.filter((framework: KnownFramework): boolean =>\n frameworks.includes(framework),\n );\n const unknown = frameworks.filter((framework: string): boolean => this.styleOf(framework) === undefined);\n return [...known, ...unknown].join(' ยท ');\n }\n\n /**\n * The three lines, identical in every mode: `L3 name` (level dimmed, name bold), the role, and\n * the framework tags. The level is dimmed by giving its text color an alpha channel, which\n * Graphviz writes as `fill-opacity`, so it dims on any fill.\n */\n labelText(facts: NodeFacts, fontColor: string): string {\n return (\n `<FONT COLOR=\"${fontColor}99\">L${facts.level}</FONT>  <B>${htmlLabelText(facts.shortName)}</B>` +\n `<BR/>${htmlLabelText(facts.role)}<BR/>${htmlLabelText(this.frameworkLine(facts.frameworks))}` +\n (facts.summary === '' ? '' : `<BR/>${htmlLabelText(facts.summary)}`)\n );\n }\n\n /** `filled` for one runtime; equal `striped` weights for several (the last takes the remainder). */\n stripeAttrs(bases: KnownFramework[]): string {\n return this.stripes(bases.map((base: KnownFramework): string => FRAMEWORK_STYLES[base].color));\n }\n\n /**\n * One equal vertical stripe per color โ the renderer the multi-runtime box and the multi-product\n * box share. A single color is a plain fill.\n */\n stripes(colors: string[]): string {\n if (colors.length === 1) return `style=\"filled\", fillcolor=\"${colors[0]}\"`;\n const share = (1 / colors.length).toFixed(3);\n const weighted = colors.map((color: string, index: number): string =>\n index === colors.length - 1 ? color : `${color};${share}`,\n );\n return `style=\"striped\", fillcolor=\"${weighted.join(':')}\", class=\"${STRIPED_CLASS}\"`;\n }\n\n private statement(facts: NodeFacts, attrs: string, label: string): string {\n return ` \"${dotValue(facts.nodeId)}\" [${attrs}, label=<${label}>];\\n`;\n }\n\n /** A solid fill, the three lines on it. `extra` carries border attributes. */\n private plain(facts: NodeFacts, fill: string, fontColor: string, extra: string, style = 'filled'): string {\n return this.statement(\n facts,\n `style=\"${style}\", fillcolor=\"${fill}\", fontcolor=\"${fontColor}\"${extra}`,\n this.labelText(facts, fontColor),\n );\n }\n\n /**\n * Product mode (#1179): one product solid in its color; several (not all) striped, one stripe per\n * product; every product the neutral shared fill; no product a white box with a dashed border.\n */\n private product(facts: NodeFacts, palette: ProductPalette): string {\n if (facts.products.length === 0)\n return this.plain(facts, PRODUCT_NONE_FILL, DARK_TEXT, `, color=\"${PRODUCT_NONE_BORDER}\", penwidth=1.5`, 'filled,dashed');\n if (palette.sharedByAll(facts.products)) return this.plain(facts, PRODUCT_SHARED_FILL, DARK_TEXT, '');\n const colors = facts.products.map((product: string): ProductColor => palette.colorOf(product));\n if (colors.length === 1) return this.plain(facts, colors[0].color, colors[0].fontColor, '');\n return this.statement(\n facts,\n `${this.stripes(colors.map((color: ProductColor): string => color.color))}, fontcolor=\"${DARK_TEXT}\"`,\n this.labelText(facts, DARK_TEXT),\n );\n }\n\n /**\n * Runtime mode. No runtime, or one runtime with no specialization: a solid fill. One runtime with a\n * specialization: NESTED. Several runtimes: full-height stripes with the text across them (a\n * specialization on such a box shows in line 3 only).\n */\n private runtime(facts: NodeFacts): string {\n const bases = this.bases(facts.frameworks);\n if (bases.length === 0) return this.plain(facts, NO_RUNTIME_COLOR, DARK_TEXT, '');\n if (bases.length > 1)\n return this.statement(\n facts,\n `${this.stripeAttrs(bases)}, fontcolor=\"${DARK_TEXT}\"`,\n this.labelText(facts, DARK_TEXT),\n );\n const base = FRAMEWORK_STYLES[bases[0]];\n const inner = this.specialization(bases[0], facts.frameworks);\n if (inner === undefined) return this.plain(facts, base.color, base.fontColor, '');\n return this.statement(\n facts,\n `style=\"filled\", fillcolor=\"${base.color}\", fontcolor=\"${inner.fontColor}\", margin=0`,\n this.nestedTable(base.color, inner, this.labelText(facts, inner.fontColor)),\n );\n }\n\n /**\n * An outer cell in the base color whose padding is the visible frame, holding an inner ROUNDED\n * table in the specialization's color that carries the text. The node's own polygon stays its\n * FIRST shape, so the hover glow and the lock outline land on the outer box only.\n */\n private nestedTable(base: string, inner: FrameworkStyle, text: string): string {\n return (\n '<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">' +\n `<TR><TD BGCOLOR=\"${base}\" CELLPADDING=\"${NEST_PAD}\">` +\n `<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"${INNER_PAD}\" BGCOLOR=\"${inner.color}\" STYLE=\"rounded\">` +\n `<TR><TD>${text}</TD></TR></TABLE></TD></TR></TABLE>`\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"graph-color-modes.js","sourceRoot":"","sources":["../../../../../../packages/tooling/nx-webpieces-rules/src/lib/graph-color-modes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Graph color modes (#1155, restyled by #1158)\n *\n * The architecture graph answers ONE question at a time instead of asking every box to encode two\n * (fill = framework AND border = role). Each box is emitted once per mode, so the page can switch\n * modes and re-render without regenerating anything. Every mode writes the SAME three lines on a box\n * (level + name, role, every framework tag); only the color changes:\n *\n * - RUNTIME \"where the code can run\". One runtime is a solid fill. One runtime plus a\n * specialization (angular/react inside browser, express inside node) is NESTED: an\n * outer frame in the base color around an inner rounded box in the specialization's\n * color, carrying the text. Several runtimes are full-height vertical stripes in the\n * fixed order browser | node | react-native, with the text written across them. The\n * dependency rule becomes visual: a box may depend on a box carrying every color it has.\n * - ARCHITECTURE \"servers ยท clients ยท APIs\". A solid fill by ROLE; framework color is not shown.\n * - IMPACT \"what changed\" โ on this branch, or in the last commit (graph-impact.ts).\n * The affected set is split by WHY nx included it (#1264, graph-impact-reasons.ts):\n * owning a changed file is solid amber (\"changed\"); reached over dependency edges\n * from one is light amber with an amber border (\"dependent\"); a `{workspaceRoot}`\n * input glob match is violet hatching (\"implicitly touched\"); a lockfile /\n * package.json / tsconfig.base.json / nx.json change is teal (\"root-file touched\");\n * anything nothing could explain is light amber with a dashed grey border\n * (\"unexplained\" โ never drawn as a dependent). Every transitive dependency of the\n * affected set that is not itself affected is light slate with a dashed border\n * (\"build input\": compiled or restored from cache, unchanged); everything else is\n * grey. Which box is which is only known per checkout, so every box carries every\n * variant and the page picks one from the sidecar (graph-impact.ts). The state is\n * never written on the box: color + legend + the \"why\" panel a click opens.\n * - PRODUCT \"which products it belongs to\" (#1179, graph-products.ts). One product is a solid\n * fill in that product's palette color; two or more (but not all) are the same\n * vertical stripes the multi-runtime box uses, one per product; a box shared by EVERY\n * product is one neutral fill (otherwise a shared foundation would be four-stripe\n * noise); a box in no product is white with a dashed border. The Filter HIDES other\n * products' boxes; this mode keeps every box and makes ownership visible.\n */\n\nimport { KNOWN_FRAMEWORKS, KnownFramework } from '@webpieces/rules-sdk';\nimport { dotValue, htmlLabelText } from './dot-syntax';\nimport { PRODUCT_NONE_BORDER, PRODUCT_NONE_FILL, PRODUCT_SHARED_FILL, ProductColor, ProductPalette } from './graph-products';\nimport type { ProductDependencyEntry } from '../configs/tag-truth-configs';\n\nexport enum GraphMode {\n RUNTIME = 'runtime',\n ARCHITECTURE = 'architecture',\n IMPACT = 'impact',\n PRODUCT = 'product',\n /** Runtime pages only (#1239): the saved goal compared with the saved current graph. */\n GOAL = 'goal',\n}\n\n/** One selectable mode as the drawer's Color-by pulldown shows it. */\nexport class ModeInfo {\n constructor(\n public readonly mode: GraphMode,\n public readonly name: string,\n public readonly subtitle: string,\n ) {}\n}\n\n/** In key order: `1` selects the first, `2` the second, `3` the third, `4` the fourth. */\nexport const GRAPH_MODES: readonly ModeInfo[] = [\n new ModeInfo(GraphMode.RUNTIME, 'Runtime', 'where the code can run'),\n new ModeInfo(GraphMode.ARCHITECTURE, 'Architecture', 'servers ยท clients ยท APIs'),\n new ModeInfo(GraphMode.IMPACT, 'Impact', 'what changed'),\n new ModeInfo(GraphMode.PRODUCT, 'Product', 'which products it belongs to'),\n];\n\n/**\n * The runtime page's Color-by menu: the four shared modes plus Goal vs Current (#1239), key `5`. The\n * build-dependency and DI viewers never list it.\n */\nexport const RUNTIME_GRAPH_MODES: readonly ModeInfo[] = [\n ...GRAPH_MODES,\n new ModeInfo(GraphMode.GOAL, 'Goal vs Current', 'Current โ Goal proposal'),\n];\n\n/** Text on a light fill. */\nexport const DARK_TEXT = '#1a1c22';\n/** Text on a dark fill. */\nexport const LIGHT_TEXT = '#ffffff';\n\n/**\n * A framework value's color, the text color that reads on it, and the BASE runtime it is drawn\n * inside (itself, for a base).\n */\nexport class FrameworkStyle {\n constructor(\n public readonly framework: KnownFramework,\n public readonly base: KnownFramework,\n public readonly color: string,\n public readonly fontColor: string,\n public readonly description: string,\n ) {}\n\n isBase(): boolean {\n return this.framework === this.base;\n }\n}\n\n/**\n * Keyed by the shared vocabulary, so a framework added to KNOWN_FRAMEWORKS without a color here is a\n * COMPILE error โ not a box silently painted grey and missing from the legend, which is exactly how\n * react-native shipped (#1155). Every base is mid-light, so dark text reads on every stripe.\n */\nexport const FRAMEWORK_STYLES: Record<KnownFramework, FrameworkStyle> = {\n browser: new FrameworkStyle('browser', 'browser', '#7d8cf2', DARK_TEXT, 'browser base runtime'),\n node: new FrameworkStyle('node', 'node', '#6fcf8a', DARK_TEXT, 'node base runtime'),\n 'react-native': new FrameworkStyle(\n 'react-native',\n 'react-native',\n '#34b8a6',\n DARK_TEXT,\n 'its own runtime, not a browser',\n ),\n angular: new FrameworkStyle('angular', 'browser', '#c8243f', LIGHT_TEXT, 'inside browser'),\n react: new FrameworkStyle('react', 'browser', '#7fd8ff', DARK_TEXT, 'inside browser'),\n express: new FrameworkStyle('express', 'node', '#2e7d4f', LIGHT_TEXT, 'inside node'),\n};\n\n/** Stripe order, left to right. Fixed, so the same set always reads the same way. */\nexport const BASE_ORDER: readonly KnownFramework[] = ['browser', 'node', 'react-native'];\n\n/**\n * The Filter popover's Runtime chips, and the order line 3 of a box lists framework tags in: the\n * bases first, then the specializations.\n */\nexport const FRAMEWORK_ORDER: readonly KnownFramework[] = [\n 'browser',\n 'node',\n 'react-native',\n 'angular',\n 'react',\n 'express',\n];\n\n/** A box with no known framework tag. */\nexport const NO_RUNTIME_COLOR = '#e4e6ec';\n\n/** The class Graphviz stamps on a multi-runtime box's `<g>`: its outline is its LAST shape. */\nexport const STRIPED_CLASS = 'wp-striped';\n\n/** Margin of base color around a specialization's inner box. */\nconst NEST_PAD = 5;\n/** Padding between the inner box's edge and its text. */\nconst INNER_PAD = 6;\n\n/** A role's solid fill and the text color that stays readable on it. */\nexport class RoleStyle {\n constructor(\n public readonly role: string,\n public readonly fill: string,\n public readonly fontColor: string,\n public readonly description: string,\n ) {}\n}\n\n/**\n * Every role role-resolver knows, in legend order (runnable things first) โ also the Filter popover's\n * Role chips. `bundle` is indigo so no box color equals the page's violet accent.\n */\nexport const ROLE_STYLES: readonly RoleStyle[] = [\n new RoleStyle('server', '#4caf50', LIGHT_TEXT, 'runnable server'),\n new RoleStyle('client', '#e5533d', LIGHT_TEXT, 'browser or mobile client app'),\n new RoleStyle('app', '#1e88e5', LIGHT_TEXT, 'runnable non-HTTP app'),\n new RoleStyle('bundle', '#4b44c8', LIGHT_TEXT, 'bundles several apps'),\n new RoleStyle('api-lib', '#f08a24', DARK_TEXT, 'contract + DTOs'),\n new RoleStyle('api-client', '#1a9aa6', LIGHT_TEXT, 'contract + SDK implementation'),\n new RoleStyle('designed-lib', '#7d8597', LIGHT_TEXT, 'library with a generated design'),\n new RoleStyle('lib', '#d7dae2', DARK_TEXT, 'plain library'),\n];\n\n/** The four impact shades (graph-impact.ts decides which box gets which). */\nexport const IMPACT_TOUCHED = '#f5a524';\nexport const IMPACT_DEPENDENT = '#fde3b0';\n/** Implicitly touched (#1264): violet HATCHING โ thin alternating stripes โ with a violet border. */\nexport const IMPACT_IMPLICIT = '#cdb8f4';\nexport const IMPACT_IMPLICIT_GAP = '#f5f0fd';\nexport const IMPACT_IMPLICIT_BORDER = '#7e57c2';\n/** Root-file touched (#1264): teal, with a teal border. */\nexport const IMPACT_ROOT_FILE = '#bfe6e0';\nexport const IMPACT_ROOT_FILE_BORDER = '#1a8f86';\n/** Unexplained (#1264): the dependent fill with a dashed grey border, so it never reads as a dependent. */\nexport const IMPACT_UNEXPLAINED_BORDER = '#8a8f9c';\n/** How many hatch stripes an implicitly-touched box gets. */\nconst HATCH_STRIPES = 12;\nexport const IMPACT_BUILD_INPUT = '#e3e9f2';\nexport const IMPACT_BUILD_INPUT_BORDER = '#7c8aa3';\nexport const IMPACT_UNTOUCHED = '#eef0f4';\nconst IMPACT_UNTOUCHED_TEXT = '#6b7180';\n\n/** What a box's per-mode rendering โ and the page's Filter โ is computed from. */\nexport class NodeFacts {\n constructor(\n public readonly nodeId: string,\n public readonly shortName: string,\n public readonly level: number,\n public readonly role: string,\n public readonly frameworks: string[],\n /** The products the project belongs to (dependencies.json `products`), sorted; empty for none. */\n public readonly products: string[],\n public readonly summary: string = '',\n ) {}\n}\n\n/** One box's DOT statement for every mode (and for each impact state). */\nexport class NodeModeDots {\n constructor(\n public readonly runtime: string,\n public readonly architecture: string,\n public readonly touched: string,\n public readonly dependent: string,\n public readonly implicit: string,\n public readonly rootFile: string,\n public readonly unexplained: string,\n public readonly buildInput: string,\n public readonly untouched: string,\n public readonly product: string,\n ) {}\n}\n\n/** How many drawn boxes one product holds, and how many of them no other product does. */\nexport class ProductCount {\n constructor(\n public readonly product: string,\n public total: number,\n public only: number,\n ) {}\n}\n\n/** Which colors and roles the drawn projects actually use, so the legend lists exactly those. */\nexport class LegendFacts {\n frameworks: string[] = [];\n roles: string[] = [];\n multiRuntime = false;\n noRuntime = false;\n /** One count per declared product, in palette (sorted-name) order; empty when none is declared. */\n products: ProductCount[] = [];\n /**\n * The ONE palette every box was painted with (#1244), built over the full declared product set.\n * The legend, the Filter's product chips and the crossing edges read their colors from it, never\n * from a palette of their own: collision resolution depends on the set, so a second palette built\n * from a subset could disagree with the boxes.\n */\n palette: ProductPalette = new ProductPalette([]);\n /** Boxes shared by every product (two or more declared). */\n sharedByAll = 0;\n /** Boxes in no product. */\n noProduct = 0;\n /** Some box belongs to two or more products, but not to every one: it is striped. */\n multiProduct = false;\n /** Dependency edges crossing into another product (#1204), drawn dashed in the Product mode. */\n crossProductEdges = 0;\n /**\n * The `product-tags` rule's matrix (#1204), listed in the Product legend; null when the rule is\n * OFF or the page was drawn without it.\n */\n productDependencies: ProductDependencyEntry[] | null = null;\n}\n\nexport class NodeModeStyler {\n styleOf(framework: string): FrameworkStyle | undefined {\n if (!(KNOWN_FRAMEWORKS as readonly string[]).includes(framework)) return undefined;\n return FRAMEWORK_STYLES[framework as KnownFramework];\n }\n\n roleStyle(role: string): RoleStyle {\n const style = ROLE_STYLES.find((candidate: RoleStyle): boolean => candidate.role === role);\n return style ?? (ROLE_STYLES.find((s: RoleStyle): boolean => s.role === 'lib') as RoleStyle);\n }\n\n /** Every role the renderer styles; a spec asserts this covers role-resolver's KNOWN_ROLES. */\n styledRoles(): string[] {\n return ROLE_STYLES.map((style: RoleStyle): string => style.role);\n }\n\n /** The base runtimes of a framework set, in stripe order (a specialization implies its base). */\n bases(frameworks: string[]): KnownFramework[] {\n const present = new Set<KnownFramework>();\n for (const framework of frameworks) {\n const style = this.styleOf(framework);\n if (style !== undefined) present.add(style.base);\n }\n return BASE_ORDER.filter((base: KnownFramework): boolean => present.has(base));\n }\n\n /** The specialization drawn inside `base`, if the set carries one. */\n specialization(base: KnownFramework, frameworks: string[]): FrameworkStyle | undefined {\n for (const framework of KNOWN_FRAMEWORKS) {\n const style = FRAMEWORK_STYLES[framework];\n if (style.isBase() || style.base !== base) continue;\n if (frameworks.includes(framework)) return style;\n }\n return undefined;\n }\n\n dots(facts: NodeFacts, palette: ProductPalette): NodeModeDots {\n return new NodeModeDots(\n this.runtime(facts),\n this.plain(facts, this.roleStyle(facts.role).fill, this.roleStyle(facts.role).fontColor, ''),\n this.plain(facts, IMPACT_TOUCHED, DARK_TEXT, ''),\n this.plain(facts, IMPACT_DEPENDENT, DARK_TEXT, `, color=\"${IMPACT_TOUCHED}\", penwidth=2`),\n this.hatched(facts),\n this.plain(facts, IMPACT_ROOT_FILE, DARK_TEXT, `, color=\"${IMPACT_ROOT_FILE_BORDER}\", penwidth=2`),\n this.plain(facts, IMPACT_DEPENDENT, DARK_TEXT, `, color=\"${IMPACT_UNEXPLAINED_BORDER}\", penwidth=1.5`, 'filled,dashed'),\n this.plain(\n facts,\n IMPACT_BUILD_INPUT,\n DARK_TEXT,\n `, color=\"${IMPACT_BUILD_INPUT_BORDER}\", penwidth=1.5`,\n 'filled,dashed',\n ),\n this.plain(facts, IMPACT_UNTOUCHED, IMPACT_UNTOUCHED_TEXT, ', color=\"#b4b9c4\"'),\n this.product(facts, palette),\n );\n }\n\n /** Implicitly touched: thin alternating violet stripes (a hatch), so it never reads as amber. */\n private hatched(facts: NodeFacts): string {\n const colors = Array.from({ length: HATCH_STRIPES }, (_: undefined, index: number): string =>\n index % 2 === 0 ? IMPACT_IMPLICIT : IMPACT_IMPLICIT_GAP,\n );\n return this.statement(\n facts,\n `${this.stripes(colors)}, fontcolor=\"${DARK_TEXT}\", color=\"${IMPACT_IMPLICIT_BORDER}\", penwidth=2`,\n this.labelText(facts, DARK_TEXT),\n );\n }\n\n /** Fold one drawn box into the legend facts. */\n record(legend: LegendFacts, facts: NodeFacts, palette: ProductPalette): void {\n this.recordProducts(legend, facts, palette);\n for (const framework of facts.frameworks) {\n if (this.styleOf(framework) !== undefined && !legend.frameworks.includes(framework))\n legend.frameworks.push(framework);\n }\n const role = this.roleStyle(facts.role).role;\n if (!legend.roles.includes(role)) legend.roles.push(role);\n const bases = this.bases(facts.frameworks);\n if (bases.length > 1) legend.multiRuntime = true;\n if (bases.length === 0) legend.noRuntime = true;\n }\n\n /** The Product section's counts: per product (total, and only-this-product), shared-by-all, none. */\n private recordProducts(legend: LegendFacts, facts: NodeFacts, palette: ProductPalette): void {\n legend.palette = palette;\n if (legend.products.length === 0 && palette.colors.length > 0) {\n legend.products = palette.names().map((product: string): ProductCount => new ProductCount(product, 0, 0));\n }\n if (facts.products.length === 0) legend.noProduct++;\n if (palette.sharedByAll(facts.products)) legend.sharedByAll++;\n else if (facts.products.length > 1) legend.multiProduct = true;\n for (const count of legend.products) {\n if (!facts.products.includes(count.product)) continue;\n count.total++;\n if (facts.products.length === 1) count.only++;\n }\n }\n\n /**\n * Line 3 of every box: every framework tag, bases before specializations, any tag outside the\n * shared vocabulary last (it still runs somewhere somebody declared).\n */\n frameworkLine(frameworks: string[]): string {\n if (frameworks.length === 0) return 'no framework tag';\n const known = FRAMEWORK_ORDER.filter((framework: KnownFramework): boolean =>\n frameworks.includes(framework),\n );\n const unknown = frameworks.filter((framework: string): boolean => this.styleOf(framework) === undefined);\n return [...known, ...unknown].join(' ยท ');\n }\n\n /**\n * The three lines, identical in every mode: `L3 name` (level dimmed, name bold), the role, and\n * the framework tags. The level is dimmed by giving its text color an alpha channel, which\n * Graphviz writes as `fill-opacity`, so it dims on any fill.\n */\n labelText(facts: NodeFacts, fontColor: string): string {\n return (\n `<FONT COLOR=\"${fontColor}99\">L${facts.level}</FONT>  <B>${htmlLabelText(facts.shortName)}</B>` +\n `<BR/>${htmlLabelText(facts.role)}<BR/>${htmlLabelText(this.frameworkLine(facts.frameworks))}` +\n (facts.summary === '' ? '' : `<BR/>${htmlLabelText(facts.summary)}`)\n );\n }\n\n /** `filled` for one runtime; equal `striped` weights for several (the last takes the remainder). */\n stripeAttrs(bases: KnownFramework[]): string {\n return this.stripes(bases.map((base: KnownFramework): string => FRAMEWORK_STYLES[base].color));\n }\n\n /**\n * One equal vertical stripe per color โ the renderer the multi-runtime box and the multi-product\n * box share. A single color is a plain fill.\n */\n stripes(colors: string[]): string {\n if (colors.length === 1) return `style=\"filled\", fillcolor=\"${colors[0]}\"`;\n const share = (1 / colors.length).toFixed(3);\n const weighted = colors.map((color: string, index: number): string =>\n index === colors.length - 1 ? color : `${color};${share}`,\n );\n return `style=\"striped\", fillcolor=\"${weighted.join(':')}\", class=\"${STRIPED_CLASS}\"`;\n }\n\n private statement(facts: NodeFacts, attrs: string, label: string): string {\n return ` \"${dotValue(facts.nodeId)}\" [${attrs}, label=<${label}>];\\n`;\n }\n\n /** A solid fill, the three lines on it. `extra` carries border attributes. */\n private plain(facts: NodeFacts, fill: string, fontColor: string, extra: string, style = 'filled'): string {\n return this.statement(\n facts,\n `style=\"${style}\", fillcolor=\"${fill}\", fontcolor=\"${fontColor}\"${extra}`,\n this.labelText(facts, fontColor),\n );\n }\n\n /**\n * Product mode (#1179): one product solid in its color; several (not all) striped, one stripe per\n * product; every product the neutral shared fill; no product a white box with a dashed border.\n */\n private product(facts: NodeFacts, palette: ProductPalette): string {\n if (facts.products.length === 0)\n return this.plain(facts, PRODUCT_NONE_FILL, DARK_TEXT, `, color=\"${PRODUCT_NONE_BORDER}\", penwidth=1.5`, 'filled,dashed');\n if (palette.sharedByAll(facts.products)) return this.plain(facts, PRODUCT_SHARED_FILL, DARK_TEXT, '');\n const colors = facts.products.map((product: string): ProductColor => palette.colorOf(product));\n if (colors.length === 1) return this.plain(facts, colors[0].color, colors[0].fontColor, '');\n return this.statement(\n facts,\n `${this.stripes(colors.map((color: ProductColor): string => color.color))}, fontcolor=\"${DARK_TEXT}\"`,\n this.labelText(facts, DARK_TEXT),\n );\n }\n\n /**\n * Runtime mode. No runtime, or one runtime with no specialization: a solid fill. One runtime with a\n * specialization: NESTED. Several runtimes: full-height stripes with the text across them (a\n * specialization on such a box shows in line 3 only).\n */\n private runtime(facts: NodeFacts): string {\n const bases = this.bases(facts.frameworks);\n if (bases.length === 0) return this.plain(facts, NO_RUNTIME_COLOR, DARK_TEXT, '');\n if (bases.length > 1)\n return this.statement(\n facts,\n `${this.stripeAttrs(bases)}, fontcolor=\"${DARK_TEXT}\"`,\n this.labelText(facts, DARK_TEXT),\n );\n const base = FRAMEWORK_STYLES[bases[0]];\n const inner = this.specialization(bases[0], facts.frameworks);\n if (inner === undefined) return this.plain(facts, base.color, base.fontColor, '');\n return this.statement(\n facts,\n `style=\"filled\", fillcolor=\"${base.color}\", fontcolor=\"${inner.fontColor}\", margin=0`,\n this.nestedTable(base.color, inner, this.labelText(facts, inner.fontColor)),\n );\n }\n\n /**\n * An outer cell in the base color whose padding is the visible frame, holding an inner ROUNDED\n * table in the specialization's color that carries the text. The node's own polygon stays its\n * FIRST shape, so the hover glow and the lock outline land on the outer box only.\n */\n private nestedTable(base: string, inner: FrameworkStyle, text: string): string {\n return (\n '<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"0\">' +\n `<TR><TD BGCOLOR=\"${base}\" CELLPADDING=\"${NEST_PAD}\">` +\n `<TABLE BORDER=\"0\" CELLBORDER=\"0\" CELLSPACING=\"0\" CELLPADDING=\"${INNER_PAD}\" BGCOLOR=\"${inner.color}\" STYLE=\"rounded\">` +\n `<TR><TD>${text}</TD></TR></TABLE></TD></TR></TABLE>`\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge changes against the base (#1264): which dependency and runtime edges this branch GAINED or
|
|
3
|
+
* LOST, so "why is this building?" is answerable for a project whose only change is an edge.
|
|
4
|
+
*
|
|
5
|
+
* BASE is the FORK POINT โ the branch comparison's `git merge-base HEAD origin/main` โ read as
|
|
6
|
+
* `git show <forkPoint>:architecture/dependencies.json` and `โฆ:architecture/runtime-dependencies.json`.
|
|
7
|
+
* Main keeps both regenerated and validated (`validate-architecture-unchanged`), so the fork point's
|
|
8
|
+
* copies are trustworthy.
|
|
9
|
+
*
|
|
10
|
+
* CURRENT is the graph computed LIVE when the page is refreshed (`LiveGraphSource`: the same pipeline
|
|
11
|
+
* `architecture:generate` runs), NEVER HEAD's committed architecture/*.json. Whether or not the branch
|
|
12
|
+
* already regenerated and committed those files must not matter: comparing against HEAD's committed
|
|
13
|
+
* copy would show no change at all once it had been regenerated.
|
|
14
|
+
*
|
|
15
|
+
* Neither file at the fork point (first adoption) is an answer, not an error: no edge diff, and the
|
|
16
|
+
* page says why. Nothing here ever throws into generation.
|
|
17
|
+
*/
|
|
18
|
+
import type { EnhancedGraph } from './graph-sorter';
|
|
19
|
+
import type { RuntimeGraph } from './runtime-graph-model';
|
|
20
|
+
export declare enum EdgeChangeKind {
|
|
21
|
+
GAINED = "gained",
|
|
22
|
+
LOST = "lost"
|
|
23
|
+
}
|
|
24
|
+
export declare enum EdgeRelation {
|
|
25
|
+
/** A build dependency (architecture/dependencies.json `dependsOn`). */
|
|
26
|
+
DEPENDS = "depends",
|
|
27
|
+
/** A runtime call (architecture/runtime-dependencies.json `runtimeEdges`). */
|
|
28
|
+
CALLS = "calls"
|
|
29
|
+
}
|
|
30
|
+
/** One gained or lost edge, `from` โ `to` (node ids), with the words the page shows for it. */
|
|
31
|
+
export declare class EdgeChange {
|
|
32
|
+
readonly from: string;
|
|
33
|
+
readonly to: string;
|
|
34
|
+
readonly change: EdgeChangeKind;
|
|
35
|
+
readonly relation: EdgeRelation;
|
|
36
|
+
/** CALLS: the APIs gained or lost on this edge, sorted. Empty for DEPENDS. */
|
|
37
|
+
readonly apis: string[];
|
|
38
|
+
/** "new on this branch: a now depends on b" / "a no longer calls b (SaveApi)". */
|
|
39
|
+
readonly text: string;
|
|
40
|
+
constructor(from: string, to: string, change: EdgeChangeKind, relation: EdgeRelation,
|
|
41
|
+
/** CALLS: the APIs gained or lost on this edge, sorted. Empty for DEPENDS. */
|
|
42
|
+
apis: string[],
|
|
43
|
+
/** "new on this branch: a now depends on b" / "a no longer calls b (SaveApi)". */
|
|
44
|
+
text: string);
|
|
45
|
+
}
|
|
46
|
+
/** The edge changes of the dependency graph and of the runtime graph, or why each is not shown. */
|
|
47
|
+
export declare class EdgeDiffReport {
|
|
48
|
+
/** The fork point's short sha ('' when there is none). */
|
|
49
|
+
readonly base: string;
|
|
50
|
+
/** '' when `dependency` was computed; otherwise why the page shows no dependency edge changes. */
|
|
51
|
+
readonly dependencyReason: string;
|
|
52
|
+
readonly dependency: EdgeChange[];
|
|
53
|
+
/** '' when `runtime` was computed; otherwise why the page shows no runtime edge changes. */
|
|
54
|
+
readonly runtimeReason: string;
|
|
55
|
+
readonly runtime: EdgeChange[];
|
|
56
|
+
constructor(
|
|
57
|
+
/** The fork point's short sha ('' when there is none). */
|
|
58
|
+
base: string,
|
|
59
|
+
/** '' when `dependency` was computed; otherwise why the page shows no dependency edge changes. */
|
|
60
|
+
dependencyReason: string, dependency: EdgeChange[],
|
|
61
|
+
/** '' when `runtime` was computed; otherwise why the page shows no runtime edge changes. */
|
|
62
|
+
runtimeReason: string, runtime: EdgeChange[]);
|
|
63
|
+
}
|
|
64
|
+
/** The two graphs the branch has NOW, computed live. `runtime` null when it could not be derived. */
|
|
65
|
+
export declare class LiveGraphs {
|
|
66
|
+
readonly projects: EnhancedGraph;
|
|
67
|
+
readonly runtime: RuntimeGraph | null;
|
|
68
|
+
/** Why `runtime` is null ('' otherwise). */
|
|
69
|
+
readonly runtimeReason: string;
|
|
70
|
+
constructor(projects: EnhancedGraph, runtime: RuntimeGraph | null,
|
|
71
|
+
/** Why `runtime` is null ('' otherwise). */
|
|
72
|
+
runtimeReason?: string);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Computes the live graphs: `CurrentGraphBuilder` (generate's own pipeline, writing nothing) and the
|
|
76
|
+
* runtime graph derived from it exactly as generate derives it. `architecture:generate` passes the
|
|
77
|
+
* graphs it just built instead (`FixedLiveGraphs`), so nothing is computed twice.
|
|
78
|
+
*/
|
|
79
|
+
export declare class LiveGraphSource {
|
|
80
|
+
graphs(workspaceRoot: string): Promise<LiveGraphs>;
|
|
81
|
+
}
|
|
82
|
+
/** The graphs a caller already holds (architecture:generate just built them). */
|
|
83
|
+
export declare class FixedLiveGraphs extends LiveGraphSource {
|
|
84
|
+
private readonly live;
|
|
85
|
+
constructor(live: LiveGraphs);
|
|
86
|
+
graphs(): Promise<LiveGraphs>;
|
|
87
|
+
}
|
|
88
|
+
/** A committed file as it was at a commit. Injected so specs never spawn git. */
|
|
89
|
+
export declare class GitFileAt {
|
|
90
|
+
/** The file's text at `sha`; null when it did not exist there (or git cannot answer). */
|
|
91
|
+
read(workspaceRoot: string, sha: string, file: string): string | null;
|
|
92
|
+
}
|
|
93
|
+
/** Diffs base against live; pure. */
|
|
94
|
+
export declare class EdgeDiffer {
|
|
95
|
+
dependency(base: EnhancedGraph, live: EnhancedGraph): EdgeChange[];
|
|
96
|
+
runtime(base: RuntimeGraph, live: RuntimeGraph): EdgeChange[];
|
|
97
|
+
private dependencyEdges;
|
|
98
|
+
private runtimeEdges;
|
|
99
|
+
/** Per edge: gained when absent at base; lost when absent now; for a call, the APIs that came or went. */
|
|
100
|
+
private compare;
|
|
101
|
+
private change;
|
|
102
|
+
}
|
|
103
|
+
/** Reads the fork point's committed graphs and diffs them against the live ones. Never throws. */
|
|
104
|
+
export declare class EdgeChangeScanner {
|
|
105
|
+
private readonly git;
|
|
106
|
+
private readonly differ;
|
|
107
|
+
constructor(git?: GitFileAt, differ?: EdgeDiffer);
|
|
108
|
+
scan(workspaceRoot: string, forkPoint: string | null, source: LiveGraphSource): Promise<EdgeDiffReport>;
|
|
109
|
+
/** No edge changes to show, with the one reason the page says instead. */
|
|
110
|
+
private none;
|
|
111
|
+
/** dependencies.json's `projects` at the fork point; null when absent or not that shape. */
|
|
112
|
+
private projectsAt;
|
|
113
|
+
private runtimeAt;
|
|
114
|
+
private parse;
|
|
115
|
+
}
|