@ttsc/graph 0.27.0 → 0.28.1

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 (82) hide show
  1. package/README.md +3 -1
  2. package/lib/index.d.ts +1 -1
  3. package/lib/index.js +15 -3
  4. package/lib/index.js.map +1 -1
  5. package/lib/model/TtscGraphMemory.d.ts +26 -0
  6. package/lib/model/TtscGraphMemory.js +121 -2
  7. package/lib/model/TtscGraphMemory.js.map +1 -1
  8. package/lib/model/TtscGraphSession.d.ts +23 -0
  9. package/lib/model/TtscGraphSession.js +248 -96
  10. package/lib/model/TtscGraphSession.js.map +1 -1
  11. package/lib/model/TtscGraphShardStore.js +6 -1
  12. package/lib/model/TtscGraphShardStore.js.map +1 -1
  13. package/lib/model/TtscLintDaemon.d.ts +54 -0
  14. package/lib/model/TtscLintDaemon.js +166 -0
  15. package/lib/model/TtscLintDaemon.js.map +1 -0
  16. package/lib/model/loadGraph.d.ts +8 -1
  17. package/lib/model/loadGraph.js +144 -72
  18. package/lib/model/loadGraph.js.map +1 -1
  19. package/lib/model/publishedArtifacts.d.ts +142 -0
  20. package/lib/model/publishedArtifacts.js +403 -0
  21. package/lib/model/publishedArtifacts.js.map +1 -0
  22. package/lib/reduce.js +20 -7
  23. package/lib/reduce.js.map +1 -1
  24. package/lib/server/createServer.js +38 -2
  25. package/lib/server/createServer.js.map +1 -1
  26. package/lib/server/runDetails.d.ts +15 -0
  27. package/lib/server/runDetails.js +48 -0
  28. package/lib/server/runDetails.js.map +1 -1
  29. package/lib/server/runEntrypoints.js +7 -1
  30. package/lib/server/runEntrypoints.js.map +1 -1
  31. package/lib/server/runLookup.js +129 -11
  32. package/lib/server/runLookup.js.map +1 -1
  33. package/lib/structures/ITtscGraphApplication.d.ts +3 -1
  34. package/lib/structures/ITtscGraphDetails.d.ts +12 -0
  35. package/lib/structures/ITtscGraphDocTag.d.ts +44 -0
  36. package/lib/structures/ITtscGraphDocTag.js +3 -0
  37. package/lib/structures/ITtscGraphDocTag.js.map +1 -0
  38. package/lib/structures/ITtscGraphDump.d.ts +23 -4
  39. package/lib/structures/ITtscGraphLookup.d.ts +29 -0
  40. package/lib/structures/ITtscGraphNode.d.ts +25 -0
  41. package/lib/structures/TtscGraphArtifactNodeKind.d.ts +23 -0
  42. package/lib/structures/TtscGraphArtifactNodeKind.js +37 -0
  43. package/lib/structures/TtscGraphArtifactNodeKind.js.map +1 -0
  44. package/lib/structures/TtscGraphDumpEdgeKind.d.ts +1 -1
  45. package/lib/structures/TtscGraphDumpNodeKind.d.ts +10 -2
  46. package/lib/structures/TtscGraphEdgeKind.d.ts +8 -1
  47. package/lib/structures/TtscGraphNodeKind.d.ts +1 -1
  48. package/lib/structures/index.d.ts +2 -0
  49. package/lib/structures/index.js +2 -0
  50. package/lib/structures/index.js.map +1 -1
  51. package/lib/view.js +17 -1
  52. package/lib/view.js.map +1 -1
  53. package/lib/viewer/index.html +5 -13
  54. package/lib/viewer/viewer.js +190 -190
  55. package/package.json +5 -5
  56. package/src/index.ts +23 -6
  57. package/src/model/TtscGraphMemory.ts +118 -2
  58. package/src/model/TtscGraphSession.ts +112 -2
  59. package/src/model/TtscGraphShardStore.ts +6 -1
  60. package/src/model/TtscLintDaemon.ts +179 -0
  61. package/src/model/loadGraph.ts +29 -5
  62. package/src/model/publishedArtifacts.ts +548 -0
  63. package/src/reduce.ts +20 -7
  64. package/src/server/runDetails.ts +52 -1
  65. package/src/server/runEntrypoints.ts +7 -1
  66. package/src/server/runLookup.ts +139 -14
  67. package/src/structures/ITtscGraphApplication.ts +3 -1
  68. package/src/structures/ITtscGraphDetails.ts +13 -0
  69. package/src/structures/ITtscGraphDocTag.ts +45 -0
  70. package/src/structures/ITtscGraphDump.ts +25 -4
  71. package/src/structures/ITtscGraphLookup.ts +31 -0
  72. package/src/structures/ITtscGraphNode.ts +27 -0
  73. package/src/structures/TtscGraphArtifactNodeKind.ts +35 -0
  74. package/src/structures/TtscGraphDumpEdgeKind.ts +1 -0
  75. package/src/structures/TtscGraphDumpNodeKind.ts +16 -2
  76. package/src/structures/TtscGraphEdgeKind.ts +8 -0
  77. package/src/structures/TtscGraphNodeKind.ts +7 -1
  78. package/src/structures/index.ts +2 -0
  79. package/src/view.ts +17 -1
  80. package/src/viewer/index.html +5 -13
  81. package/src/viewer/legend.ts +107 -0
  82. package/src/viewer/main.ts +19 -21
@@ -0,0 +1,107 @@
1
+ // The bundled viewer's display vocabulary and the legend it renders from it.
2
+ //
3
+ // Separate from `main.ts` because that module fetches and renders on import, so
4
+ // nothing can read its constants or exercise its legend without a browser. The
5
+ // legend is the surface this file exists to protect: it used to be literal
6
+ // markup in `index.html` with each colour repeated in a `style` attribute, and a
7
+ // new family shipped into the graph with no entry beside it until someone opened
8
+ // both files.
9
+
10
+ /** The slice of the DOM the legend needs, so a test can drive it without one. */
11
+ export interface LegendElement {
12
+ className: string;
13
+ style: { background: string };
14
+ // `unknown[]`, because the real `Document` types these as `(Node | string)[]`
15
+ // and a narrower parameter is not assignable to it. `src/viewer` is excluded
16
+ // from the declaration build, so nothing would have reported that.
17
+ append(...nodes: unknown[]): void;
18
+ prepend(...nodes: unknown[]): void;
19
+ }
20
+
21
+ /** The slice of `document` the legend needs. */
22
+ export interface LegendDocument {
23
+ getElementById(id: string): LegendElement | null;
24
+ createElement(tag: string): LegendElement;
25
+ }
26
+
27
+ /**
28
+ * Node colour per declaration kind.
29
+ *
30
+ * Total over the kinds a dump can carry (`TtscGraphDumpNodeKind`). `module` was
31
+ * missing, and because the fallback below was the same string as `variable`, a
32
+ * module was not merely unnamed — it was drawn as a variable.
33
+ */
34
+ export const NODE_COLORS: Record<string, string> = {
35
+ // The artifacts. They are one hue family on purpose: a reader tells a document
36
+ // from a declaration at a glance, and tells the artifacts apart within it.
37
+ markdown_document: "#e8b4b8",
38
+ markdown_section: "#d99ba0",
39
+ prisma_model: "#b8a3e8",
40
+ prisma_column: "#a08fd0",
41
+ prisma_relation: "#8a76c0",
42
+ swagger_operation: "#e8d9a0",
43
+ module: "#d0d7de",
44
+ class: "#36e2ee",
45
+ interface: "#6ea8ff",
46
+ function: "#3fb950",
47
+ method: "#2bb673",
48
+ type: "#f5b042",
49
+ enum: "#c792ea",
50
+ variable: "#8b97a8",
51
+ };
52
+
53
+ /**
54
+ * Edge colour per display family.
55
+ *
56
+ * One definition: the edge colour, the legend swatch, and the legend name all
57
+ * read this map. `exports` is neutral because it is a structural relation
58
+ * rather than a use, and it is opaque so it stays apart from the translucent
59
+ * fallback.
60
+ */
61
+ export const LINK_COLORS: Record<string, string> = {
62
+ "value-call": "#3fb950",
63
+ "type-ref": "#f5b042",
64
+ "doc-ref": "#c07de0",
65
+ heritage: "#6ea8ff",
66
+ exports: "#7d8590",
67
+ };
68
+
69
+ /**
70
+ * What an unrecognized node kind is drawn in.
71
+ *
72
+ * It has to differ from every value in {@link NODE_COLORS}, or "I do not know
73
+ * this kind" and "this is a variable" are the same picture.
74
+ */
75
+ export const UNKNOWN_NODE_COLOR = "#565f6b";
76
+
77
+ /** What an unrecognized edge kind is drawn in; translucent, unlike a family. */
78
+ export const UNKNOWN_LINK_COLOR = "#ffffff55";
79
+
80
+ /** Elements whose legend is already built, so a second call adds nothing. */
81
+ const rendered = new WeakSet<LegendElement>();
82
+
83
+ /**
84
+ * Fill the footer legend from {@link LINK_COLORS}, so a family cannot be drawn
85
+ * without being named.
86
+ *
87
+ * The swatches are prepended, which puts them ahead of the static note the
88
+ * markup keeps — the order the hand-written markup had. The website viewer has
89
+ * always derived its legend this way
90
+ * (`website/src/components/graph/TtscWebsiteGraphViewer3D.tsx`).
91
+ */
92
+ export function renderLegend(host: LegendDocument): void {
93
+ const legend = host.getElementById("legend");
94
+ if (legend === null || rendered.has(legend)) return;
95
+ rendered.add(legend);
96
+ legend.prepend(
97
+ ...Object.entries(LINK_COLORS).map(([kind, color]) => {
98
+ const dot = host.createElement("span");
99
+ dot.className = "dot";
100
+ const swatch = host.createElement("span");
101
+ swatch.className = "swatch";
102
+ swatch.style.background = color;
103
+ dot.append(swatch, kind);
104
+ return dot;
105
+ }),
106
+ );
107
+ }
@@ -1,11 +1,21 @@
1
1
  // Vanilla 3D code-graph viewer bundled into @ttsc/graph by esbuild and served by
2
- // `ttsc-graph view`. Mirrors website/src/components/graph/GraphViewer3D.tsx, but
3
- // standalone (no React): fetch the reduced graph the CLI serves, render it on
4
- // three.js + three-forcegraph, and let the user orbit it.
2
+ // `ttsc-graph view`. Mirrors website/src/components/graph/TtscWebsiteGraphViewer3D.tsx,
3
+ // but standalone (no React): fetch the reduced graph the CLI serves, render it on
4
+ // three.js + three-forcegraph, and let the user orbit it. The display vocabulary
5
+ // and the legend live in ./legend, which this module has no side effects to hide
6
+ // from a test.
5
7
  import * as THREE from "three";
6
8
  import ThreeForceGraph from "three-forcegraph";
7
9
  import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
8
10
 
11
+ import {
12
+ LINK_COLORS,
13
+ NODE_COLORS,
14
+ UNKNOWN_LINK_COLOR,
15
+ UNKNOWN_NODE_COLOR,
16
+ renderLegend,
17
+ } from "./legend";
18
+
9
19
  interface GNode {
10
20
  id: string;
11
21
  name: string;
@@ -27,22 +37,6 @@ interface Payload {
27
37
  links: GLink[];
28
38
  }
29
39
 
30
- const NODE_COLORS: Record<string, string> = {
31
- class: "#36e2ee",
32
- interface: "#6ea8ff",
33
- function: "#3fb950",
34
- method: "#2bb673",
35
- type: "#f5b042",
36
- enum: "#c792ea",
37
- variable: "#8b97a8",
38
- };
39
-
40
- const LINK_COLORS: Record<string, string> = {
41
- "value-call": "#3fb950",
42
- "type-ref": "#f5b042",
43
- heritage: "#6ea8ff",
44
- };
45
-
46
40
  function escapeHtml(value: string): string {
47
41
  return value
48
42
  .replace(/&/g, "&amp;")
@@ -56,6 +50,10 @@ function setText(id: string, text: string): void {
56
50
  }
57
51
 
58
52
  async function main(): Promise<void> {
53
+ // Before the fetch, so a graph that fails to load still shows the legend the
54
+ // static markup used to guarantee.
55
+ renderLegend(document);
56
+
59
57
  const container = document.getElementById("graph");
60
58
  if (!container) return;
61
59
 
@@ -103,8 +101,8 @@ async function main(): Promise<void> {
103
101
  .nodeResolution(12)
104
102
  .nodeOpacity(0.95)
105
103
  .nodeVal((node) => 1 + Math.sqrt(node.degree))
106
- .nodeColor((node) => NODE_COLORS[node.kind] ?? "#8b97a8")
107
- .linkColor((link) => LINK_COLORS[link.kind] ?? "#ffffff55")
104
+ .nodeColor((node) => NODE_COLORS[node.kind] ?? UNKNOWN_NODE_COLOR)
105
+ .linkColor((link) => LINK_COLORS[link.kind] ?? UNKNOWN_LINK_COLOR)
108
106
  .linkOpacity(0.4)
109
107
  .linkWidth(0)
110
108
  .warmupTicks(20)