thurview 0.17.1 → 0.18.0

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.
@@ -1,171 +1,3 @@
1
- /**
2
- * The interface delta: what the change did to the surfaces other code can reach.
3
- *
4
- * A capability becomes real when it becomes visible, so the honest answer to
5
- * "what does this pull request do" is what it added to, changed in, or took out
6
- * of the exported surface. That is derived here from the code graph at both
7
- * pinned commits rather than asserted by the author, so it cannot go stale: a
8
- * symbol the diff touched is an interface entry only when it is visible outside
9
- * its file on one side or the other, and only when its declaration moved.
10
- * Everything else is counted as internal, which is a finding of its own.
11
- */
12
- import { languageFor } from "./highlight.js";
13
- import { catFiles } from "./symbols.js";
14
- import { LANGUAGES } from "./graph.js";
15
- const FAMILY = {
16
- typescript: "js",
17
- tsx: "js",
18
- javascript: "js",
19
- jsx: "js",
20
- python: "python",
21
- go: "go",
22
- rust: "rust",
23
- java: "java",
24
- elixir: "elixir",
25
- };
26
- /** Kinds whose body is part of the surface: a field added to an exported type is a change. */
27
- const BODY_IS_SURFACE = new Set(["interface", "type"]);
28
- const MAX_SURFACE_LINES = 60;
29
- const MAX_DECLARATION_LINES = 12;
30
- const MAX_DECLARATION_CHARS = 240;
31
- /** `export { audit, check as verify }` makes the local names visible outside the file. */
32
- function reexportedNames(text) {
33
- const out = new Set();
34
- for (const m of text.matchAll(/\bexport\s*\{([^}]*)\}/g))
35
- for (const part of m[1].split(",")) {
36
- const local = part
37
- .split(/\s+as\s+/)[0]
38
- .replace(/\btype\b/, "")
39
- .trim();
40
- if (local)
41
- out.add(local);
42
- }
43
- return out;
44
- }
45
- /**
46
- * The declaration a consumer reads: the definition's head, without its opening
47
- * brace. The parameter list is followed to its close before a brace can end the
48
- * declaration, so an object parameter does not cut the signature in half.
49
- */
50
- function declarationOf(lines, s) {
51
- const parts = [];
52
- const last = Math.min(s.end, s.line + MAX_DECLARATION_LINES - 1);
53
- let open = 0;
54
- let whole = false;
55
- for (let n = s.line; n <= last && !whole; n++) {
56
- const line = lines[n - 1] ?? "";
57
- parts.push(line.trim());
58
- for (const c of line)
59
- open += c === "(" ? 1 : c === ")" ? -1 : 0;
60
- const t = line.trim();
61
- // `do` closes a declaration the way `{` does elsewhere. Without it an Elixir
62
- // declaration runs to the line cap and swallows the body, so editing a single
63
- // statement inside a function reads as the function's surface having moved.
64
- whole =
65
- open <= 0 &&
66
- (/[{;]/.test(line) || /:\s*$/.test(t) || /(^|\s)do:?$/.test(t) || /,\s*do:\s/.test(t));
67
- }
68
- const text = parts
69
- .join(" ")
70
- .replace(/\s+/g, " ")
71
- .replace(/\s*[{;]\s*$/, "")
72
- .trim();
73
- const cut = text.length > MAX_DECLARATION_CHARS;
74
- return cut ? `${text.slice(0, MAX_DECLARATION_CHARS)} ...` : whole ? text : `${text} ...`;
75
- }
76
- /** The text compared to decide whether the surface moved. */
77
- function surfaceOf(lines, s) {
78
- if (!BODY_IS_SURFACE.has(s.kind))
79
- return declarationOf(lines, s);
80
- return lines
81
- .slice(s.line - 1, Math.min(s.end, s.line + MAX_SURFACE_LINES - 1))
82
- .join(" ")
83
- .replace(/\s+/g, " ")
84
- .trim();
85
- }
86
- function qualifiedOf(s) {
87
- return s.id.slice(s.file.length + 1).replace(/#\d+$/, "");
88
- }
89
- /** Symbol ids visible outside their own file, for the files the diff touched. */
90
- function visibleIds(graph, texts) {
91
- const out = new Set();
92
- const byFile = new Map();
93
- for (const s of graph.symbols) {
94
- if (!texts.has(s.file))
95
- continue;
96
- const list = byFile.get(s.file);
97
- if (list)
98
- list.push(s);
99
- else
100
- byFile.set(s.file, [s]);
101
- }
102
- for (const [file, syms] of byFile) {
103
- const family = FAMILY[languageFor(file)];
104
- if (!family)
105
- continue;
106
- const text = texts.get(file);
107
- const lines = text.split("\n");
108
- const reexported = family === "js" ? reexportedNames(text) : new Set();
109
- // parents first, so a method can ask whether the type holding it is visible
110
- const exported = new Set();
111
- for (const s of [...syms].sort((a, b) => a.line - b.line)) {
112
- const decl = (lines[s.line - 1] ?? "").trim();
113
- const declares = () => {
114
- switch (family) {
115
- case "js":
116
- return /^export\b/.test(decl) || reexported.has(s.name);
117
- case "python":
118
- return !s.name.startsWith("_") || /^__\w+__$/.test(s.name);
119
- case "go":
120
- return /^[A-Z]/.test(s.name);
121
- case "rust":
122
- return /^pub(\s|\()/.test(decl);
123
- case "java":
124
- return /\bpublic\b/.test(decl);
125
- case "elixir":
126
- // the private forms are the same words with a `p`: defp, defmacrop, defguardp
127
- return /^def(?:module|protocol|macro|delegate|guard|n)?(?=[\s(])/.test(decl);
128
- }
129
- };
130
- const q = qualifiedOf(s);
131
- const parent = q.includes(".") ? q.slice(0, q.lastIndexOf(".")) : "";
132
- let visible;
133
- if (!parent)
134
- visible = declares();
135
- // a method rides on its type's visibility, except where the line already says it:
136
- // Rust puts `pub` there, and Elixir has no private module and marks the function
137
- // itself - and its module names hold dots of their own, so the parent of
138
- // `Chat.Repo.fetch` is not a symbol to look up
139
- else if (family === "rust" || family === "elixir")
140
- visible = declares();
141
- else if (family === "js")
142
- visible =
143
- exported.has(parent) && s.kind === "method" && !/^(private|protected|#)/.test(decl);
144
- else
145
- visible = exported.has(parent) && declares();
146
- if (!visible)
147
- continue;
148
- exported.add(q);
149
- out.add(s.id);
150
- }
151
- }
152
- return out;
153
- }
154
- function verdictOf(entries, internal, unreadable) {
155
- const counts = ["removed", "changed", "added"]
156
- .map((c) => [c, entries.filter((e) => e.change === c).length])
157
- .filter(([, n]) => n > 0)
158
- .map(([c, n]) => `${n} ${c}`);
159
- const head = counts.length
160
- ? `${counts.join(", ")}.`
161
- : internal
162
- ? `No interface moved. ${internal} symbol${internal > 1 ? "s" : ""} changed inside, with no visible surface.`
163
- : "No interface moved.";
164
- const tail = unreadable
165
- ? ` ${unreadable} changed file${unreadable > 1 ? "s are" : " is"} outside the code graph.`
166
- : "";
167
- return head + tail;
168
- }
169
1
  const RANK = { removed: 0, changed: 1, added: 2 };
170
2
  /** Removed first: it is the entry a reviewer must not miss. */
171
3
  export function sortEntries(entries) {
@@ -174,81 +6,12 @@ export function sortEntries(entries) {
174
6
  a.line - b.line ||
175
7
  a.name.localeCompare(b.name));
176
8
  }
177
- /** Re-derive the verdict after authored entries joined the derived ones. */
178
- export function withVerdict(delta) {
179
- sortEntries(delta.entries);
180
- delta.verdict = verdictOf(delta.entries, delta.internal, delta.unreadable.length);
181
- return delta;
182
- }
183
- /** What the change did to the surfaces other code can reach, at the pinned commits. */
184
- export async function interfaceDelta(input) {
185
- const headSyms = new Map(input.head.symbols.map((s) => [s.id, s]));
186
- const baseSyms = new Map(input.base.symbols.map((s) => [s.id, s]));
187
- const headPaths = new Set();
188
- const basePaths = new Set();
189
- for (const row of input.impact.changed) {
190
- if (row.change === "removed")
191
- basePaths.add(row.file);
192
- else {
193
- headPaths.add(row.file);
194
- basePaths.add(input.changes.get(row.file)?.oldPath ?? row.file);
195
- }
196
- }
197
- const [headText, baseText] = await Promise.all([
198
- catFiles(input.cwd, input.pins.head, [...headPaths]),
199
- catFiles(input.cwd, input.pins.base, [...basePaths]),
200
- ]);
201
- const headVisible = visibleIds(input.head, headText);
202
- const baseVisible = visibleIds(input.base, baseText);
203
- const entries = [];
204
- let internal = 0;
205
- for (const row of input.impact.changed) {
206
- const oldPath = row.change === "removed" ? row.file : input.changes.get(row.file)?.oldPath;
207
- const baseId = row.change === "removed"
208
- ? row.id
209
- : oldPath
210
- ? `${oldPath}${row.id.slice(row.file.length)}`
211
- : row.id;
212
- const headSym = row.change === "removed" ? undefined : headSyms.get(row.id);
213
- const baseSym = baseSyms.get(baseId);
214
- const wasVisible = !!baseSym && baseVisible.has(baseId);
215
- const isVisible = !!headSym && headVisible.has(row.id);
216
- if (!wasVisible && !isVisible) {
217
- internal++;
218
- continue;
219
- }
220
- const entry = (change, sym, lines, was) => entries.push({
221
- id: change === "removed" ? baseId : row.id,
222
- change,
223
- name: declarationOf(lines, sym),
224
- was,
225
- kind: sym.kind,
226
- file: sym.file,
227
- line: sym.line,
228
- graph: change === "removed" ? "base" : "head",
229
- });
230
- const headLines = headSym ? (headText.get(headSym.file) ?? "").split("\n") : [];
231
- const baseLines = baseSym ? (baseText.get(baseSym.file) ?? "").split("\n") : [];
232
- if (!wasVisible)
233
- entry("added", headSym, headLines, "");
234
- else if (!isVisible)
235
- entry("removed", baseSym, baseLines, "");
236
- else if (surfaceOf(headLines, headSym) !== surfaceOf(baseLines, baseSym)) {
237
- const was = declarationOf(baseLines, baseSym);
238
- entry("changed", headSym, headLines, was === declarationOf(headLines, headSym) ? "" : was);
239
- }
240
- else
241
- internal++;
242
- }
243
- const unreadable = input.changed
244
- .filter((f) => !LANGUAGES.includes(languageFor(f.path)))
245
- .map((f) => f.path);
246
- return withVerdict({
247
- entries,
248
- internal,
249
- unreadable,
250
- verdict: "",
251
- truncated: input.impact.truncated,
252
- });
9
+ /** The counts per change, removed first, or null when there is no entry. */
10
+ export function countsOf(entries) {
11
+ const counts = ["removed", "changed", "added"]
12
+ .map((c) => [c, entries.filter((e) => e.change === c).length])
13
+ .filter(([, n]) => n > 0)
14
+ .map(([c, n]) => `${n} ${c}`);
15
+ return counts.length ? counts.join(", ") : null;
253
16
  }
254
17
  //# sourceMappingURL=interfaces.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAoCA,MAAM,IAAI,GAA6C,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAE5F,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO,OAAO,CAAC,IAAI,CACjB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACP,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC;QAC5B,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI;QACf,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAC/B,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,OAAyB;IAChD,MAAM,MAAM,GAAI,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAW;SACtD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,MAAM,CAAU,CAAC;SACtE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;SACxB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClD,CAAC"}
package/dist/ui/app.css CHANGED
@@ -1110,6 +1110,12 @@ kbd {
1110
1110
  width: 100%;
1111
1111
  height: auto;
1112
1112
  }
1113
+ .seq-scroll {
1114
+ overflow-x: auto;
1115
+ }
1116
+ .diagram svg.seq {
1117
+ margin: 0 auto;
1118
+ }
1113
1119
  .seq text {
1114
1120
  font: 12px var(--font-mono);
1115
1121
  fill: var(--fg);
@@ -1128,11 +1134,22 @@ kbd {
1128
1134
  }
1129
1135
  .seq .msg text {
1130
1136
  fill: var(--link);
1137
+ /* A label crosses the lifelines between its two ends; a halo in the frame's
1138
+ colour keeps the dashes from striking through the words. */
1139
+ paint-order: stroke;
1140
+ stroke: var(--bg2);
1141
+ stroke-width: 4px;
1142
+ stroke-linejoin: round;
1131
1143
  cursor: pointer;
1132
1144
  }
1133
- .seq .msg text:hover {
1145
+ .seq .msg text:hover,
1146
+ .seq .msg text:focus-visible {
1134
1147
  text-decoration: underline;
1135
1148
  }
1149
+ .seq .msg text:focus-visible {
1150
+ outline: 2px solid var(--accent);
1151
+ outline-offset: 2px;
1152
+ }
1136
1153
  .flow text {
1137
1154
  font: 12px var(--font-mono);
1138
1155
  fill: var(--fg);
@@ -1921,6 +1938,9 @@ kbd {
1921
1938
  .cov-seg.placed {
1922
1939
  background: var(--accent-bg);
1923
1940
  }
1941
+ .cov-seg.searched {
1942
+ background: var(--line);
1943
+ }
1924
1944
  .cov-seg.uncovered {
1925
1945
  background: var(--bg3);
1926
1946
  }
@@ -1949,6 +1969,9 @@ kbd {
1949
1969
  .cov-dot.placed {
1950
1970
  background: var(--accent-bg);
1951
1971
  }
1972
+ .cov-dot.searched {
1973
+ background: var(--line);
1974
+ }
1952
1975
  .cov-dot.uncovered {
1953
1976
  background: var(--bg3);
1954
1977
  }
@@ -1989,13 +2012,6 @@ kbd {
1989
2012
  .cov-label {
1990
2013
  font-weight: 600;
1991
2014
  }
1992
- .cov-hubs {
1993
- font-size: 12px;
1994
- margin-top: 6px;
1995
- }
1996
- .cov-hubs code {
1997
- margin-right: 6px;
1998
- }
1999
2015
  .cov-files {
2000
2016
  display: flex;
2001
2017
  flex-wrap: wrap;
@@ -2018,13 +2034,16 @@ kbd {
2018
2034
  border-color: var(--accent);
2019
2035
  background: var(--accent-bg);
2020
2036
  }
2037
+ .cov-b-searched {
2038
+ color: var(--fg2);
2039
+ border-color: var(--line);
2040
+ }
2021
2041
  .cov-b-uncovered {
2022
2042
  color: var(--muted);
2023
2043
  border-color: var(--line);
2024
2044
  background: var(--bg3);
2025
2045
  }
2026
- .cov-links,
2027
- .cov-shared {
2046
+ .cov-links {
2028
2047
  display: flex;
2029
2048
  flex-direction: column;
2030
2049
  border: 1px solid var(--line);